aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2008-01-30 19:25:51 -0500
committerPaul Mackerras <paulus@samba.org>2008-01-30 19:25:51 -0500
commitbd45ac0c5daae35e7c71138172e63df5cf644cf6 (patch)
tree5eb5a599bf6a9d7a8a34e802db932aa9e9555de4 /arch
parent4eece4ccf997c0e6d8fdad3d842e37b16b8d705f (diff)
parent5bdeae46be6dfe9efa44a548bd622af325f4bdb4 (diff)
Merge branch 'linux-2.6'
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/kernel/vmlinux.lds.S8
-rw-r--r--arch/alpha/lib/dec_and_lock.c3
-rw-r--r--arch/arm/Kconfig62
-rw-r--r--arch/arm/Kconfig.debug6
-rw-r--r--arch/arm/Kconfig.instrumentation10
-rw-r--r--arch/arm/Makefile2
-rw-r--r--arch/arm/boot/compressed/Makefile4
-rw-r--r--arch/arm/boot/compressed/head-at91rm9200.S81
-rw-r--r--arch/arm/boot/compressed/head.S15
-rw-r--r--arch/arm/common/rtctime.c1
-rw-r--r--arch/arm/configs/at91cap9adk_defconfig1143
-rw-r--r--arch/arm/configs/colibri_defconfig1481
-rw-r--r--arch/arm/configs/collie_defconfig1
-rw-r--r--arch/arm/configs/eseries_pxa_defconfig1499
-rw-r--r--arch/arm/configs/iop13xx_defconfig156
-rw-r--r--arch/arm/configs/iop32x_defconfig207
-rw-r--r--arch/arm/configs/iop33x_defconfig154
-rw-r--r--arch/arm/configs/littleton_defconfig (renamed from arch/sh64/configs/harp_defconfig)502
-rw-r--r--arch/arm/configs/msm_defconfig895
-rw-r--r--arch/arm/configs/orion_defconfig1384
-rw-r--r--arch/arm/configs/pcm027_defconfig1096
-rw-r--r--arch/arm/kernel/Makefile1
-rw-r--r--arch/arm/kernel/dma-isa.c2
-rw-r--r--arch/arm/kernel/entry-armv.S63
-rw-r--r--arch/arm/kernel/entry-common.S2
-rw-r--r--arch/arm/kernel/kprobes-decode.c1529
-rw-r--r--arch/arm/kernel/kprobes.c447
-rw-r--r--arch/arm/kernel/time.c17
-rw-r--r--arch/arm/kernel/traps.c21
-rw-r--r--arch/arm/kernel/vmlinux.lds.S11
-rw-r--r--arch/arm/mach-aaec2000/core.c4
-rw-r--r--arch/arm/mach-at91/Kconfig38
-rw-r--r--arch/arm/mach-at91/Makefile23
-rw-r--r--arch/arm/mach-at91/Makefile.boot7
-rw-r--r--arch/arm/mach-at91/at91cap9.c365
-rw-r--r--arch/arm/mach-at91/at91cap9_devices.c1066
-rw-r--r--arch/arm/mach-at91/at91rm9200.c30
-rw-r--r--arch/arm/mach-at91/at91rm9200_devices.c350
-rw-r--r--arch/arm/mach-at91/at91sam9260.c28
-rw-r--r--arch/arm/mach-at91/at91sam9260_devices.c315
-rw-r--r--arch/arm/mach-at91/at91sam9261.c28
-rw-r--r--arch/arm/mach-at91/at91sam9261_devices.c366
-rw-r--r--arch/arm/mach-at91/at91sam9263.c30
-rw-r--r--arch/arm/mach-at91/at91sam9263_devices.c382
-rw-r--r--arch/arm/mach-at91/at91sam9rl_devices.c346
-rw-r--r--arch/arm/mach-at91/board-cap9adk.c359
-rw-r--r--arch/arm/mach-at91/board-csb337.c85
-rw-r--r--arch/arm/mach-at91/board-dk.c10
-rw-r--r--arch/arm/mach-at91/board-ek.c21
-rw-r--r--arch/arm/mach-at91/board-sam9261ek.c84
-rw-r--r--arch/arm/mach-at91/board-sam9263ek.c80
-rw-r--r--arch/arm/mach-at91/clock.c2
-rw-r--r--arch/arm/mach-at91/generic.h2
-rw-r--r--arch/arm/mach-at91/gpio.c62
-rw-r--r--arch/arm/mach-at91/leds.c68
-rw-r--r--arch/arm/mach-at91/pm.c5
-rw-r--r--arch/arm/mach-clps711x/time.c2
-rw-r--r--arch/arm/mach-clps7500/core.c4
-rw-r--r--arch/arm/mach-ebsa110/core.c4
-rw-r--r--arch/arm/mach-ep93xx/core.c262
-rw-r--r--arch/arm/mach-footbridge/dc21285-timer.c4
-rw-r--r--arch/arm/mach-footbridge/isa-timer.c2
-rw-r--r--arch/arm/mach-h720x/cpu-h7201.c4
-rw-r--r--arch/arm/mach-h720x/cpu-h7202.c2
-rw-r--r--arch/arm/mach-imx/Makefile3
-rw-r--r--arch/arm/mach-integrator/core.c4
-rw-r--r--arch/arm/mach-integrator/integrator_ap.c2
-rw-r--r--arch/arm/mach-integrator/pci_v3.c8
-rw-r--r--arch/arm/mach-iop32x/glantank.c15
-rw-r--r--arch/arm/mach-ixp2000/core.c4
-rw-r--r--arch/arm/mach-ixp23xx/core.c1
-rw-r--r--arch/arm/mach-ixp23xx/espresso.c2
-rw-r--r--arch/arm/mach-ixp23xx/ixdp2351.c2
-rw-r--r--arch/arm/mach-ixp23xx/roadrunner.c2
-rw-r--r--arch/arm/mach-ixp4xx/avila-setup.c14
-rw-r--r--arch/arm/mach-ixp4xx/dsmg600-setup.c13
-rw-r--r--arch/arm/mach-ixp4xx/ixdp425-setup.c14
-rw-r--r--arch/arm/mach-ixp4xx/nas100d-setup.c14
-rw-r--r--arch/arm/mach-ixp4xx/nslu2-power.c1
-rw-r--r--arch/arm/mach-ixp4xx/nslu2-setup.c14
-rw-r--r--arch/arm/mach-ks8695/Makefile2
-rw-r--r--arch/arm/mach-ks8695/board-micrel.c2
-rw-r--r--arch/arm/mach-ks8695/gpio.c83
-rw-r--r--arch/arm/mach-ks8695/pci.c326
-rw-r--r--arch/arm/mach-ks8695/time.c3
-rw-r--r--arch/arm/mach-lh7a40x/time.c4
-rw-r--r--arch/arm/mach-msm/Kconfig18
-rw-r--r--arch/arm/mach-msm/Makefile7
-rw-r--r--arch/arm/mach-msm/Makefile.boot3
-rw-r--r--arch/arm/mach-msm/board-halibut.c114
-rw-r--r--arch/arm/mach-msm/common.c116
-rw-r--r--arch/arm/mach-msm/dma.c214
-rw-r--r--arch/arm/mach-msm/idle.S36
-rw-r--r--arch/arm/mach-msm/io.c85
-rw-r--r--arch/arm/mach-msm/irq.c154
-rw-r--r--arch/arm/mach-msm/timer.c205
-rw-r--r--arch/arm/mach-mx3/time.c4
-rw-r--r--arch/arm/mach-netx/Makefile3
-rw-r--r--arch/arm/mach-netx/time.c4
-rw-r--r--arch/arm/mach-omap1/board-fsample.c2
-rw-r--r--arch/arm/mach-omap1/board-h2.c4
-rw-r--r--arch/arm/mach-omap1/board-h3.c4
-rw-r--r--arch/arm/mach-omap1/board-innovator.c4
-rw-r--r--arch/arm/mach-omap1/board-nokia770.c1
-rw-r--r--arch/arm/mach-omap1/board-osk.c6
-rw-r--r--arch/arm/mach-omap1/board-palmtt.c1
-rw-r--r--arch/arm/mach-omap1/board-palmz71.c1
-rw-r--r--arch/arm/mach-omap1/board-perseus2.c2
-rw-r--r--arch/arm/mach-omap1/board-voiceblue.c2
-rw-r--r--arch/arm/mach-omap1/leds-osk.c2
-rw-r--r--arch/arm/mach-omap1/pm.c25
-rw-r--r--arch/arm/mach-omap2/board-2430sdp.c2
-rw-r--r--arch/arm/mach-omap2/board-apollon.c3
-rw-r--r--arch/arm/mach-omap2/timer-gp.c4
-rw-r--r--arch/arm/mach-orion/Kconfig41
-rw-r--r--arch/arm/mach-orion/Makefile6
-rw-r--r--arch/arm/mach-orion/Makefile.boot3
-rw-r--r--arch/arm/mach-orion/addr-map.c484
-rw-r--r--arch/arm/mach-orion/common.c315
-rw-r--r--arch/arm/mach-orion/common.h78
-rw-r--r--arch/arm/mach-orion/db88f5281-setup.c364
-rw-r--r--arch/arm/mach-orion/dns323-setup.c322
-rw-r--r--arch/arm/mach-orion/gpio.c225
-rw-r--r--arch/arm/mach-orion/irq.c241
-rw-r--r--arch/arm/mach-orion/kurobox_pro-setup.c234
-rw-r--r--arch/arm/mach-orion/pci.c557
-rw-r--r--arch/arm/mach-orion/rd88f5182-setup.c306
-rw-r--r--arch/arm/mach-orion/time.c181
-rw-r--r--arch/arm/mach-orion/ts209-setup.c335
-rw-r--r--arch/arm/mach-pnx4008/time.c4
-rw-r--r--arch/arm/mach-pxa/Kconfig73
-rw-r--r--arch/arm/mach-pxa/Makefile15
-rw-r--r--arch/arm/mach-pxa/akita-ioexp.c2
-rw-r--r--arch/arm/mach-pxa/cm-x270.c9
-rw-r--r--arch/arm/mach-pxa/colibri.c134
-rw-r--r--arch/arm/mach-pxa/corgi.c189
-rw-r--r--arch/arm/mach-pxa/corgi_lcd.c299
-rw-r--r--arch/arm/mach-pxa/corgi_ssp.c1
-rw-r--r--arch/arm/mach-pxa/cpu-pxa.c294
-rw-r--r--arch/arm/mach-pxa/devices.c662
-rw-r--r--arch/arm/mach-pxa/devices.h12
-rw-r--r--arch/arm/mach-pxa/eseries.c101
-rw-r--r--arch/arm/mach-pxa/generic.c251
-rw-r--r--arch/arm/mach-pxa/idp.c2
-rw-r--r--arch/arm/mach-pxa/littleton.c325
-rw-r--r--arch/arm/mach-pxa/lpd270.c3
-rw-r--r--arch/arm/mach-pxa/lubbock.c32
-rw-r--r--arch/arm/mach-pxa/magician.c218
-rw-r--r--arch/arm/mach-pxa/mainstone.c81
-rw-r--r--arch/arm/mach-pxa/mfp.c261
-rw-r--r--arch/arm/mach-pxa/pcm027.c216
-rw-r--r--arch/arm/mach-pxa/pcm990-baseboard.c330
-rw-r--r--arch/arm/mach-pxa/pm.c33
-rw-r--r--arch/arm/mach-pxa/poodle.c6
-rw-r--r--arch/arm/mach-pxa/pxa25x.c31
-rw-r--r--arch/arm/mach-pxa/pxa27x.c65
-rw-r--r--arch/arm/mach-pxa/pxa3xx.c243
-rw-r--r--arch/arm/mach-pxa/sharpsl.h19
-rw-r--r--arch/arm/mach-pxa/sleep.S9
-rw-r--r--arch/arm/mach-pxa/spitz.c112
-rw-r--r--arch/arm/mach-pxa/ssp.c386
-rw-r--r--arch/arm/mach-pxa/standby.S83
-rw-r--r--arch/arm/mach-pxa/time.c84
-rw-r--r--arch/arm/mach-pxa/tosa.c11
-rw-r--r--arch/arm/mach-pxa/trizeps4.c7
-rw-r--r--arch/arm/mach-pxa/zylonite.c96
-rw-r--r--arch/arm/mach-pxa/zylonite_pxa300.c65
-rw-r--r--arch/arm/mach-pxa/zylonite_pxa320.c45
-rw-r--r--arch/arm/mach-realview/core.c4
-rw-r--r--arch/arm/mach-s3c2410/mach-bast.c3
-rw-r--r--arch/arm/mach-s3c2410/mach-vr1000.c1
-rw-r--r--arch/arm/mach-s3c2410/s3c2410.c2
-rw-r--r--arch/arm/mach-s3c2410/usb-simtec.c2
-rw-r--r--arch/arm/mach-s3c2412/Kconfig1
-rw-r--r--arch/arm/mach-s3c2412/Makefile3
-rw-r--r--arch/arm/mach-s3c2412/clock.c54
-rw-r--r--arch/arm/mach-s3c2412/dma.c48
-rw-r--r--arch/arm/mach-s3c2412/gpio.c60
-rw-r--r--arch/arm/mach-s3c2412/irq.c24
-rw-r--r--arch/arm/mach-s3c2412/pm.c18
-rw-r--r--arch/arm/mach-s3c2412/s3c2412.c4
-rw-r--r--arch/arm/mach-s3c2412/sleep.S68
-rw-r--r--arch/arm/mach-s3c2440/clock.c22
-rw-r--r--arch/arm/mach-s3c2440/mach-osiris.c2
-rw-r--r--arch/arm/mach-s3c2442/clock.c22
-rw-r--r--arch/arm/mach-s3c2443/s3c2443.c2
-rw-r--r--arch/arm/mach-sa1100/irq.c2
-rw-r--r--arch/arm/mach-sa1100/ssp.c3
-rw-r--r--arch/arm/mach-sa1100/time.c42
-rw-r--r--arch/arm/mach-shark/core.c2
-rw-r--r--arch/arm/mm/Kconfig32
-rw-r--r--arch/arm/mm/Makefile1
-rw-r--r--arch/arm/mm/fault.c31
-rw-r--r--arch/arm/mm/proc-feroceon.S506
-rw-r--r--arch/arm/oprofile/common.c2
-rw-r--r--arch/arm/plat-omap/debug-devices.c2
-rw-r--r--arch/arm/plat-omap/gpio.c2
-rw-r--r--arch/arm/plat-omap/mailbox.c18
-rw-r--r--arch/arm/plat-omap/mcbsp.c20
-rw-r--r--arch/arm/plat-s3c24xx/Makefile1
-rw-r--r--arch/arm/plat-s3c24xx/clock.c19
-rw-r--r--arch/arm/plat-s3c24xx/dma.c49
-rw-r--r--arch/arm/plat-s3c24xx/gpio.c29
-rw-r--r--arch/arm/plat-s3c24xx/irq.c2
-rw-r--r--arch/arm/plat-s3c24xx/pm.c247
-rw-r--r--arch/arm/plat-s3c24xx/s3c244x-clock.c137
-rw-r--r--arch/arm/plat-s3c24xx/s3c244x.c4
-rw-r--r--arch/arm/tools/mach-types258
-rw-r--r--arch/arm/vfp/vfp.h4
-rw-r--r--arch/arm/vfp/vfphw.S60
-rw-r--r--arch/arm/vfp/vfpinstr.h6
-rw-r--r--arch/arm/vfp/vfpmodule.c98
-rw-r--r--arch/avr32/Kconfig47
-rw-r--r--arch/avr32/Kconfig.debug10
-rw-r--r--arch/avr32/Makefile3
-rw-r--r--arch/avr32/boards/atngw100/setup.c2
-rw-r--r--arch/avr32/boards/atstk1000/Kconfig58
-rw-r--r--arch/avr32/boards/atstk1000/Makefile2
-rw-r--r--arch/avr32/boards/atstk1000/atstk1000.h2
-rw-r--r--arch/avr32/boards/atstk1000/atstk1002.c106
-rw-r--r--arch/avr32/boards/atstk1000/atstk1003.c162
-rw-r--r--arch/avr32/boards/atstk1000/atstk1004.c147
-rw-r--r--arch/avr32/boards/atstk1000/setup.c64
-rw-r--r--arch/avr32/configs/atngw100_defconfig418
-rw-r--r--arch/avr32/configs/atstk1002_defconfig637
-rw-r--r--arch/avr32/configs/atstk1003_defconfig1015
-rw-r--r--arch/avr32/configs/atstk1004_defconfig621
-rw-r--r--arch/avr32/kernel/Makefile3
-rw-r--r--arch/avr32/kernel/cpu.c96
-rw-r--r--arch/avr32/kernel/irq.c11
-rw-r--r--arch/avr32/kernel/kprobes.c5
-rw-r--r--arch/avr32/kernel/nmi_debug.c82
-rw-r--r--arch/avr32/kernel/ocd.c163
-rw-r--r--arch/avr32/kernel/process.c5
-rw-r--r--arch/avr32/kernel/ptrace.c5
-rw-r--r--arch/avr32/kernel/signal.c7
-rw-r--r--arch/avr32/kernel/time.c2
-rw-r--r--arch/avr32/kernel/traps.c21
-rw-r--r--arch/avr32/kernel/vmlinux.lds.S8
-rw-r--r--arch/avr32/mach-at32ap/Kconfig12
-rw-r--r--arch/avr32/mach-at32ap/Makefile4
-rw-r--r--arch/avr32/mach-at32ap/at32ap700x.c (renamed from arch/avr32/mach-at32ap/at32ap7000.c)15
-rw-r--r--arch/avr32/mach-at32ap/extint.c59
-rw-r--r--arch/avr32/mm/dma-coherent.c7
-rw-r--r--arch/avr32/mm/tlb.c2
-rw-r--r--arch/avr32/oprofile/Makefile8
-rw-r--r--arch/avr32/oprofile/op_model_avr32.c235
-rw-r--r--arch/blackfin/Kconfig131
-rw-r--r--arch/blackfin/Makefile12
-rw-r--r--arch/blackfin/configs/BF527-EZKIT_defconfig17
-rw-r--r--arch/blackfin/configs/BF533-EZKIT_defconfig17
-rw-r--r--arch/blackfin/configs/BF533-STAMP_defconfig39
-rw-r--r--arch/blackfin/configs/BF537-STAMP_defconfig50
-rw-r--r--arch/blackfin/configs/BF548-EZKIT_defconfig90
-rw-r--r--arch/blackfin/configs/BF561-EZKIT_defconfig32
-rw-r--r--arch/blackfin/kernel/Makefile2
-rw-r--r--arch/blackfin/kernel/bfin_dma_5xx.c4
-rw-r--r--arch/blackfin/kernel/bfin_gpio.c171
-rw-r--r--arch/blackfin/kernel/cplb-mpu/Makefile8
-rw-r--r--arch/blackfin/kernel/cplb-mpu/cacheinit.c62
-rw-r--r--arch/blackfin/kernel/cplb-mpu/cplbinfo.c144
-rw-r--r--arch/blackfin/kernel/cplb-mpu/cplbinit.c91
-rw-r--r--arch/blackfin/kernel/cplb-mpu/cplbmgr.c338
-rw-r--r--arch/blackfin/kernel/cplb-nompu/Makefile8
-rw-r--r--arch/blackfin/kernel/cplb-nompu/cacheinit.c (renamed from arch/blackfin/kernel/cacheinit.c)2
-rw-r--r--arch/blackfin/kernel/cplb-nompu/cplbhdlr.S (renamed from arch/blackfin/mach-common/cplbhdlr.S)0
-rw-r--r--arch/blackfin/kernel/cplb-nompu/cplbinfo.c (renamed from arch/blackfin/mach-common/cplbinfo.c)0
-rw-r--r--arch/blackfin/kernel/cplb-nompu/cplbinit.c (renamed from arch/blackfin/kernel/cplbinit.c)0
-rw-r--r--arch/blackfin/kernel/cplb-nompu/cplbmgr.S (renamed from arch/blackfin/mach-common/cplbmgr.S)37
-rw-r--r--arch/blackfin/kernel/early_printk.c4
-rw-r--r--arch/blackfin/kernel/process.c32
-rw-r--r--arch/blackfin/kernel/reboot.c13
-rw-r--r--arch/blackfin/kernel/setup.c13
-rw-r--r--arch/blackfin/kernel/time.c70
-rw-r--r--arch/blackfin/kernel/traps.c212
-rw-r--r--arch/blackfin/kernel/vmlinux.lds.S8
-rw-r--r--arch/blackfin/lib/memcpy.S8
-rw-r--r--arch/blackfin/mach-bf527/Kconfig2
-rw-r--r--arch/blackfin/mach-bf527/boards/ezkit.c107
-rw-r--r--arch/blackfin/mach-bf533/boards/H8606.c83
-rw-r--r--arch/blackfin/mach-bf533/boards/ezkit.c52
-rw-r--r--arch/blackfin/mach-bf533/boards/stamp.c103
-rw-r--r--arch/blackfin/mach-bf537/boards/Kconfig6
-rw-r--r--arch/blackfin/mach-bf537/boards/Makefile1
-rw-r--r--arch/blackfin/mach-bf537/boards/cm_bf537.c11
-rw-r--r--arch/blackfin/mach-bf537/boards/generic_board.c11
-rw-r--r--arch/blackfin/mach-bf537/boards/minotaur.c317
-rw-r--r--arch/blackfin/mach-bf537/boards/pnav10.c9
-rw-r--r--arch/blackfin/mach-bf537/boards/stamp.c80
-rw-r--r--arch/blackfin/mach-bf548/Kconfig2
-rw-r--r--arch/blackfin/mach-bf548/boards/ezkit.c96
-rw-r--r--arch/blackfin/mach-bf548/head.S55
-rw-r--r--arch/blackfin/mach-bf548/ints-priority.c4
-rw-r--r--arch/blackfin/mach-bf561/boards/cm_bf561.c11
-rw-r--r--arch/blackfin/mach-bf561/boards/ezkit.c96
-rw-r--r--arch/blackfin/mach-bf561/coreb.c12
-rw-r--r--arch/blackfin/mach-common/Makefile3
-rw-r--r--arch/blackfin/mach-common/dpmc.S74
-rw-r--r--arch/blackfin/mach-common/entry.S26
-rw-r--r--arch/blackfin/mach-common/interrupt.S48
-rw-r--r--arch/blackfin/mach-common/ints-priority-dc.c10
-rw-r--r--arch/blackfin/mach-common/ints-priority-sc.c84
-rw-r--r--arch/blackfin/mach-common/irqpanic.c50
-rw-r--r--arch/blackfin/mach-common/pm.c16
-rw-r--r--arch/blackfin/mm/init.c33
-rw-r--r--arch/cris/arch-v10/vmlinux.lds.S8
-rw-r--r--arch/cris/arch-v32/boot/compressed/Makefile2
-rw-r--r--arch/cris/arch-v32/drivers/iop_fw_load.c11
-rw-r--r--arch/cris/arch-v32/vmlinux.lds.S8
-rw-r--r--arch/frv/boot/Makefile8
-rw-r--r--arch/frv/kernel/gdb-stub.c2
-rw-r--r--arch/frv/kernel/vmlinux.lds.S14
-rw-r--r--arch/h8300/kernel/vmlinux.lds.S8
-rw-r--r--arch/ia64/Kconfig8
-rw-r--r--arch/ia64/hp/sim/simeth.c5
-rw-r--r--arch/ia64/hp/sim/simscsi.c1
-rw-r--r--arch/ia64/ia32/binfmt_elf32.c3
-rw-r--r--arch/ia64/kernel/module.c2
-rw-r--r--arch/ia64/kernel/setup.c4
-rw-r--r--arch/ia64/kernel/time.c27
-rw-r--r--arch/ia64/kernel/topology.c26
-rw-r--r--arch/ia64/kernel/vmlinux.lds.S8
-rw-r--r--arch/ia64/sn/kernel/setup.c11
-rw-r--r--arch/m32r/Kconfig5
-rw-r--r--arch/m32r/kernel/vmlinux.lds.S12
-rw-r--r--arch/m68k/kernel/vmlinux-std.lds8
-rw-r--r--arch/m68k/kernel/vmlinux-sun3.lds8
-rw-r--r--arch/m68knommu/kernel/vmlinux.lds.S8
-rw-r--r--arch/mips/Kconfig186
-rw-r--r--arch/mips/Makefile40
-rw-r--r--arch/mips/au1000/common/au1xxx_irqmap.c21
-rw-r--r--arch/mips/au1000/common/dbdma.c2
-rw-r--r--arch/mips/au1000/common/platform.c21
-rw-r--r--arch/mips/au1000/db1x00/init.c11
-rw-r--r--arch/mips/au1000/mtx-1/init.c2
-rw-r--r--arch/mips/au1000/mtx-1/platform.c27
-rw-r--r--arch/mips/au1000/pb1000/init.c2
-rw-r--r--arch/mips/au1000/pb1100/init.c2
-rw-r--r--arch/mips/au1000/pb1200/init.c2
-rw-r--r--arch/mips/au1000/pb1500/init.c2
-rw-r--r--arch/mips/au1000/pb1550/init.c2
-rw-r--r--arch/mips/au1000/xxs1500/init.c2
-rw-r--r--arch/mips/basler/excite/Kconfig9
-rw-r--r--arch/mips/basler/excite/excite_iodev.c2
-rw-r--r--arch/mips/basler/excite/excite_prom.c2
-rw-r--r--arch/mips/cobalt/reset.c24
-rw-r--r--arch/mips/configs/atlas_defconfig2
-rw-r--r--arch/mips/configs/bigsur_defconfig2
-rw-r--r--arch/mips/configs/capcella_defconfig2
-rw-r--r--arch/mips/configs/cobalt_defconfig2
-rw-r--r--arch/mips/configs/db1000_defconfig2
-rw-r--r--arch/mips/configs/db1100_defconfig2
-rw-r--r--arch/mips/configs/db1200_defconfig2
-rw-r--r--arch/mips/configs/db1500_defconfig2
-rw-r--r--arch/mips/configs/db1550_defconfig2
-rw-r--r--arch/mips/configs/decstation_defconfig2
-rw-r--r--arch/mips/configs/e55_defconfig2
-rw-r--r--arch/mips/configs/emma2rh_defconfig2
-rw-r--r--arch/mips/configs/excite_defconfig2
-rw-r--r--arch/mips/configs/fulong_defconfig2
-rw-r--r--arch/mips/configs/ip22_defconfig2
-rw-r--r--arch/mips/configs/ip27_defconfig2
-rw-r--r--arch/mips/configs/ip32_defconfig2
-rw-r--r--arch/mips/configs/jazz_defconfig2
-rw-r--r--arch/mips/configs/jmr3927_defconfig17
-rw-r--r--arch/mips/configs/lasat_defconfig2
-rw-r--r--arch/mips/configs/malta_defconfig2
-rw-r--r--arch/mips/configs/mipssim_defconfig2
-rw-r--r--arch/mips/configs/mpc30x_defconfig2
-rw-r--r--arch/mips/configs/msp71xx_defconfig2
-rw-r--r--arch/mips/configs/mtx1_defconfig3
-rw-r--r--arch/mips/configs/pb1100_defconfig2
-rw-r--r--arch/mips/configs/pb1500_defconfig2
-rw-r--r--arch/mips/configs/pb1550_defconfig2
-rw-r--r--arch/mips/configs/pnx8550-jbs_defconfig2
-rw-r--r--arch/mips/configs/pnx8550-stb810_defconfig2
-rw-r--r--arch/mips/configs/qemu_defconfig2
-rw-r--r--arch/mips/configs/rbhma4200_defconfig17
-rw-r--r--arch/mips/configs/rbhma4500_defconfig17
-rw-r--r--arch/mips/configs/rm200_defconfig2
-rw-r--r--arch/mips/configs/sb1250-swarm_defconfig2
-rw-r--r--arch/mips/configs/sead_defconfig2
-rw-r--r--arch/mips/configs/tb0219_defconfig2
-rw-r--r--arch/mips/configs/tb0226_defconfig2
-rw-r--r--arch/mips/configs/tb0287_defconfig2
-rw-r--r--arch/mips/configs/workpad_defconfig2
-rw-r--r--arch/mips/configs/wrppmc_defconfig2
-rw-r--r--arch/mips/configs/yosemite_defconfig2
-rw-r--r--arch/mips/dec/time.c1
-rw-r--r--arch/mips/defconfig2
-rw-r--r--arch/mips/fw/arc/cmdline.c2
-rw-r--r--arch/mips/fw/arc/init.c8
-rw-r--r--arch/mips/fw/cfe/cfe_api.c184
-rw-r--r--arch/mips/fw/cfe/cfe_api_int.h186
-rw-r--r--arch/mips/fw/lib/Makefile5
-rw-r--r--arch/mips/fw/lib/call_o32.S97
-rw-r--r--arch/mips/fw/sni/Makefile5
-rw-r--r--arch/mips/fw/sni/sniprom.c151
-rw-r--r--arch/mips/gt64120/wrppmc/setup.c2
-rw-r--r--arch/mips/jazz/setup.c7
-rw-r--r--arch/mips/jmr3927/rbhma3100/init.c4
-rw-r--r--arch/mips/jmr3927/rbhma3100/setup.c60
-rw-r--r--arch/mips/kernel/cpu-bugs64.c47
-rw-r--r--arch/mips/kernel/cpu-probe.c9
-rw-r--r--arch/mips/kernel/genex.S8
-rw-r--r--arch/mips/kernel/i8253.c12
-rw-r--r--arch/mips/kernel/i8259.c2
-rw-r--r--arch/mips/kernel/kspd.c3
-rw-r--r--arch/mips/kernel/linux32.c30
-rw-r--r--arch/mips/kernel/mips-mt-fpaff.c10
-rw-r--r--arch/mips/kernel/mips-mt.c1
-rw-r--r--arch/mips/kernel/pcspeaker.c28
-rw-r--r--arch/mips/kernel/proc.c3
-rw-r--r--arch/mips/kernel/rtlx.c1
-rw-r--r--arch/mips/kernel/setup.c7
-rw-r--r--arch/mips/kernel/smp-mt.c193
-rw-r--r--arch/mips/kernel/smp.c53
-rw-r--r--arch/mips/kernel/smtc-proc.c1
-rw-r--r--arch/mips/kernel/smtc.c1
-rw-r--r--arch/mips/kernel/time.c2
-rw-r--r--arch/mips/kernel/vmlinux.lds.S8
-rw-r--r--arch/mips/kernel/vpe.c1
-rw-r--r--arch/mips/lasat/picvue.c2
-rw-r--r--arch/mips/lasat/picvue.h3
-rw-r--r--arch/mips/lasat/picvue_proc.c18
-rw-r--r--arch/mips/lemote/lm2e/pci.c3
-rw-r--r--arch/mips/lemote/lm2e/prom.c2
-rw-r--r--arch/mips/lib/csum_partial.S275
-rw-r--r--arch/mips/lib/memcpy-inatomic.S141
-rw-r--r--arch/mips/lib/memcpy.S250
-rw-r--r--arch/mips/lib/memset.S44
-rw-r--r--arch/mips/lib/strlen_user.S6
-rw-r--r--arch/mips/lib/strncpy_user.S15
-rw-r--r--arch/mips/lib/strnlen_user.S7
-rw-r--r--arch/mips/lib/uncached.c12
-rw-r--r--arch/mips/mips-boards/atlas/atlas_setup.c6
-rw-r--r--arch/mips/mips-boards/generic/init.c8
-rw-r--r--arch/mips/mips-boards/malta/malta_int.c129
-rw-r--r--arch/mips/mips-boards/malta/malta_setup.c210
-rw-r--r--arch/mips/mips-boards/malta/malta_smtc.c68
-rw-r--r--arch/mips/mips-boards/sead/sead_setup.c2
-rw-r--r--arch/mips/mipssim/Makefile2
-rw-r--r--arch/mips/mipssim/sim_setup.c16
-rw-r--r--arch/mips/mipssim/sim_smtc.c (renamed from arch/mips/mipssim/sim_smp.c)92
-rw-r--r--arch/mips/mm/c-r4k.c17
-rw-r--r--arch/mips/mm/dma-default.c2
-rw-r--r--arch/mips/mm/pg-r4k.c66
-rw-r--r--arch/mips/mm/tlbex.c252
-rw-r--r--arch/mips/oprofile/op_model_mipsxx.c2
-rw-r--r--arch/mips/pci/pci-bcm1480.c4
-rw-r--r--arch/mips/pci/pci-bcm1480ht.c4
-rw-r--r--arch/mips/philips/pnx8550/common/setup.c2
-rw-r--r--arch/mips/philips/pnx8550/common/time.c35
-rw-r--r--arch/mips/philips/pnx8550/jbs/init.c3
-rw-r--r--arch/mips/philips/pnx8550/stb810/prom_init.c2
-rw-r--r--arch/mips/pmc-sierra/yosemite/i2c-yosemite.h96
-rw-r--r--arch/mips/pmc-sierra/yosemite/prom.c7
-rw-r--r--arch/mips/pmc-sierra/yosemite/smp.c149
-rw-r--r--arch/mips/qemu/Makefile10
-rw-r--r--arch/mips/qemu/q-console.c26
-rw-r--r--arch/mips/qemu/q-firmware.c24
-rw-r--r--arch/mips/qemu/q-irq.c37
-rw-r--r--arch/mips/qemu/q-mem.c5
-rw-r--r--arch/mips/qemu/q-reset.c33
-rw-r--r--arch/mips/qemu/q-setup.c22
-rw-r--r--arch/mips/qemu/q-smp.c55
-rw-r--r--arch/mips/sgi-ip22/Makefile8
-rw-r--r--arch/mips/sgi-ip22/ip22-mc.c4
-rw-r--r--arch/mips/sgi-ip22/ip28-berr.c502
-rw-r--r--arch/mips/sgi-ip27/ip27-init.c1
-rw-r--r--arch/mips/sgi-ip27/ip27-klnuma.c1
-rw-r--r--arch/mips/sgi-ip27/ip27-smp.c109
-rw-r--r--arch/mips/sibyte/bcm1480/smp.c101
-rw-r--r--arch/mips/sibyte/cfe/Makefile1
-rw-r--r--arch/mips/sibyte/cfe/setup.c14
-rw-r--r--arch/mips/sibyte/cfe/smp.c110
-rw-r--r--arch/mips/sibyte/sb1250/smp.c100
-rw-r--r--arch/mips/sni/Makefile2
-rw-r--r--arch/mips/sni/a20r.c13
-rw-r--r--arch/mips/sni/eisa.c50
-rw-r--r--arch/mips/sni/irq.c4
-rw-r--r--arch/mips/sni/pcit.c7
-rw-r--r--arch/mips/sni/rm200.c326
-rw-r--r--arch/mips/sni/setup.c143
-rw-r--r--arch/mips/sni/sniprom.c251
-rw-r--r--arch/mips/sni/time.c1
-rw-r--r--arch/mips/tx4927/common/Makefile6
-rw-r--r--arch/mips/tx4927/common/tx4927_setup.c186
-rw-r--r--arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c96
-rw-r--r--arch/mips/tx4938/common/Makefile6
-rw-r--r--arch/mips/tx4938/common/setup.c45
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/Makefile4
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/prom.c1
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/setup.c31
-rw-r--r--arch/mips/vr41xx/common/init.c4
-rw-r--r--arch/mips/vr41xx/nec-cmbvr4133/setup.c4
-rw-r--r--arch/parisc/Kconfig5
-rw-r--r--arch/parisc/kernel/vmlinux.lds.S8
-rw-r--r--arch/powerpc/Kconfig8
-rw-r--r--arch/powerpc/boot/Makefile2
-rw-r--r--arch/powerpc/kernel/ptrace.c52
-rw-r--r--arch/powerpc/kernel/sysfs.c2
-rw-r--r--arch/powerpc/kernel/vio.c13
-rw-r--r--arch/powerpc/kernel/vmlinux.lds.S10
-rw-r--r--arch/powerpc/oprofile/op_model_power4.c6
-rw-r--r--arch/powerpc/platforms/cell/spu_base.c2
-rw-r--r--arch/powerpc/platforms/pasemi/Makefile2
-rw-r--r--arch/powerpc/platforms/pasemi/dma_lib.c488
-rw-r--r--arch/powerpc/platforms/pasemi/pasemi.h1
-rw-r--r--arch/powerpc/platforms/powermac/pic.c2
-rw-r--r--arch/powerpc/platforms/pseries/hotplug-cpu.c8
-rw-r--r--arch/powerpc/platforms/pseries/power.c32
-rw-r--r--arch/powerpc/platforms/pseries/rtasd.c8
-rw-r--r--arch/powerpc/sysdev/ipic.c2
-rw-r--r--arch/powerpc/sysdev/mpic.c2
-rw-r--r--arch/powerpc/sysdev/mv64x60_dev.c6
-rw-r--r--arch/powerpc/sysdev/qe_lib/qe_ic.c2
-rw-r--r--arch/ppc/8260_io/enet.c4
-rw-r--r--arch/ppc/8260_io/fcc_enet.c4
-rw-r--r--arch/ppc/kernel/ppc_htab.c1
-rw-r--r--arch/ppc/kernel/vmlinux.lds.S8
-rw-r--r--arch/ppc/platforms/katana.c21
-rw-r--r--arch/ppc/syslib/mv64x60.c1
-rw-r--r--arch/ppc/syslib/open_pic.c2
-rw-r--r--arch/ppc/syslib/open_pic2.c2
-rw-r--r--arch/s390/Kconfig3
-rw-r--r--arch/s390/crypto/Kconfig60
-rw-r--r--arch/s390/crypto/aes_s390.c229
-rw-r--r--arch/s390/crypto/prng.c4
-rw-r--r--arch/s390/hypfs/inode.c13
-rw-r--r--arch/s390/kernel/Makefile4
-rw-r--r--arch/s390/kernel/early.c2
-rw-r--r--arch/s390/kernel/head64.S2
-rw-r--r--arch/s390/kernel/ipl.c1035
-rw-r--r--arch/s390/kernel/process.c18
-rw-r--r--arch/s390/kernel/ptrace.c15
-rw-r--r--arch/s390/kernel/setup.c139
-rw-r--r--arch/s390/kernel/signal.c20
-rw-r--r--arch/s390/kernel/smp.c575
-rw-r--r--arch/s390/kernel/time.c2
-rw-r--r--arch/s390/kernel/traps.c20
-rw-r--r--arch/s390/kernel/vmlinux.lds.S20
-rw-r--r--arch/s390/lib/spinlock.c35
-rw-r--r--arch/s390/mm/extmem.c2
-rw-r--r--arch/s390/mm/vmem.c26
-rw-r--r--arch/sh/Kconfig366
-rw-r--r--arch/sh/Kconfig.cpu115
-rw-r--r--arch/sh/Kconfig.debug51
-rw-r--r--arch/sh/Makefile103
-rw-r--r--arch/sh/boards/cayman/Makefile5
-rw-r--r--arch/sh/boards/cayman/irq.c (renamed from arch/sh64/mach-cayman/irq.c)26
-rw-r--r--arch/sh/boards/cayman/led.c (renamed from arch/sh64/mach-cayman/led.c)2
-rw-r--r--arch/sh/boards/cayman/setup.c (renamed from arch/sh64/mach-cayman/setup.c)94
-rw-r--r--arch/sh/boards/dreamcast/irq.c2
-rw-r--r--arch/sh/boards/dreamcast/setup.c8
-rw-r--r--arch/sh/boards/landisk/gio.c2
-rw-r--r--arch/sh/boards/renesas/hs7751rvoip/Kconfig12
-rw-r--r--arch/sh/boards/renesas/hs7751rvoip/Makefile8
-rw-r--r--arch/sh/boards/renesas/hs7751rvoip/io.c283
-rw-r--r--arch/sh/boards/renesas/hs7751rvoip/irq.c116
-rw-r--r--arch/sh/boards/renesas/hs7751rvoip/pci.c149
-rw-r--r--arch/sh/boards/renesas/hs7751rvoip/setup.c105
-rw-r--r--arch/sh/boards/renesas/r7780rp/Makefile2
-rw-r--r--arch/sh/boards/renesas/r7780rp/irq-r7780mp.c2
-rw-r--r--arch/sh/boards/renesas/r7780rp/irq-r7780rp.c52
-rw-r--r--arch/sh/boards/renesas/r7780rp/irq-r7785rp.c45
-rw-r--r--arch/sh/boards/renesas/r7780rp/irq.c51
-rw-r--r--arch/sh/boards/renesas/r7780rp/setup.c10
-rw-r--r--arch/sh/boards/renesas/rts7751r2d/irq.c8
-rw-r--r--arch/sh/boards/renesas/rts7751r2d/setup.c161
-rw-r--r--arch/sh/boards/renesas/sdk7780/Kconfig23
-rw-r--r--arch/sh/boards/renesas/sdk7780/Makefile5
-rw-r--r--arch/sh/boards/renesas/sdk7780/irq.c46
-rw-r--r--arch/sh/boards/renesas/sdk7780/setup.c109
-rw-r--r--arch/sh/boot/Makefile18
-rw-r--r--arch/sh/boot/compressed/Makefile46
-rw-r--r--arch/sh/boot/compressed/Makefile_3243
-rw-r--r--arch/sh/boot/compressed/Makefile_64 (renamed from arch/sh64/boot/compressed/Makefile)25
-rw-r--r--arch/sh/boot/compressed/cache.c12
-rw-r--r--arch/sh/boot/compressed/head_32.S (renamed from arch/sh/boot/compressed/head.S)0
-rw-r--r--arch/sh/boot/compressed/head_64.S (renamed from arch/sh64/boot/compressed/head.S)29
-rw-r--r--arch/sh/boot/compressed/misc_32.c (renamed from arch/sh/boot/compressed/misc.c)5
-rw-r--r--arch/sh/boot/compressed/misc_64.c (renamed from arch/sh64/boot/compressed/misc.c)2
-rw-r--r--arch/sh/boot/compressed/vmlinux_64.lds (renamed from arch/sh64/boot/compressed/vmlinux.lds.S)0
-rw-r--r--arch/sh/cchips/voyagergx/Makefile9
-rw-r--r--arch/sh/cchips/voyagergx/consistent.c121
-rw-r--r--arch/sh/cchips/voyagergx/irq.c101
-rw-r--r--arch/sh/cchips/voyagergx/setup.c37
-rw-r--r--arch/sh/configs/cayman_defconfig (renamed from arch/sh64/configs/cayman_defconfig)270
-rw-r--r--arch/sh/configs/hs7751rvoip_defconfig908
-rw-r--r--arch/sh/configs/r7785rp_defconfig13
-rw-r--r--arch/sh/configs/sdk7780_defconfig (renamed from arch/sh/configs/r7780rp_defconfig)1088
-rw-r--r--arch/sh/configs/se7712_defconfig2
-rw-r--r--arch/sh/drivers/dma/Kconfig2
-rw-r--r--arch/sh/drivers/dma/dma-sh.c2
-rw-r--r--arch/sh/drivers/dma/dma-sysfs.c2
-rw-r--r--arch/sh/drivers/pci/Makefile7
-rw-r--r--arch/sh/drivers/pci/dma-dreamcast.c70
-rw-r--r--arch/sh/drivers/pci/fixups-dreamcast.c10
-rw-r--r--arch/sh/drivers/pci/fixups-sdk7780.c59
-rw-r--r--arch/sh/drivers/pci/ops-cayman.c94
-rw-r--r--arch/sh/drivers/pci/ops-r7780rp.c16
-rw-r--r--arch/sh/drivers/pci/ops-sdk7780.c73
-rw-r--r--arch/sh/drivers/pci/ops-sh5.c93
-rw-r--r--arch/sh/drivers/pci/pci-auto.c2
-rw-r--r--arch/sh/drivers/pci/pci-sh4.h4
-rw-r--r--arch/sh/drivers/pci/pci-sh5.c228
-rw-r--r--arch/sh/drivers/pci/pci-sh5.h (renamed from arch/sh64/kernel/pci_sh5.h)10
-rw-r--r--arch/sh/drivers/pci/pci-sh7780.c1
-rw-r--r--arch/sh/drivers/pci/pci-sh7780.h1
-rw-r--r--arch/sh/drivers/pci/pci.c2
-rw-r--r--arch/sh/kernel/Makefile30
-rw-r--r--arch/sh/kernel/Makefile_3226
-rw-r--r--arch/sh/kernel/Makefile_6422
-rw-r--r--arch/sh/kernel/cpu/Makefile6
-rw-r--r--arch/sh/kernel/cpu/init.c74
-rw-r--r--arch/sh/kernel/cpu/irq/Makefile4
-rw-r--r--arch/sh/kernel/cpu/irq/intc-sh5.c (renamed from arch/sh64/kernel/irq_intc.c)33
-rw-r--r--arch/sh/kernel/cpu/irq/intc.c31
-rw-r--r--arch/sh/kernel/cpu/sh2/entry.S19
-rw-r--r--arch/sh/kernel/cpu/sh2/setup-sh7619.c2
-rw-r--r--arch/sh/kernel/cpu/sh2a/Makefile4
-rw-r--r--arch/sh/kernel/cpu/sh2a/clock-sh7203.c89
-rw-r--r--arch/sh/kernel/cpu/sh2a/fpu.c633
-rw-r--r--arch/sh/kernel/cpu/sh2a/probe.c22
-rw-r--r--arch/sh/kernel/cpu/sh2a/setup-sh7203.c319
-rw-r--r--arch/sh/kernel/cpu/sh2a/setup-sh7206.c2
-rw-r--r--arch/sh/kernel/cpu/sh3/Makefile2
-rw-r--r--arch/sh/kernel/cpu/sh3/clock-sh7712.c71
-rw-r--r--arch/sh/kernel/cpu/sh3/entry.S24
-rw-r--r--arch/sh/kernel/cpu/sh3/ex.S2
-rw-r--r--arch/sh/kernel/cpu/sh3/probe.c9
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7705.c10
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh770x.c11
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7710.c16
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7720.c78
-rw-r--r--arch/sh/kernel/cpu/sh4/Makefile2
-rw-r--r--arch/sh/kernel/cpu/sh4/fpu.c537
-rw-r--r--arch/sh/kernel/cpu/sh4/probe.c2
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh7750.c18
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh7760.c13
-rw-r--r--arch/sh/kernel/cpu/sh4/softfloat.c892
-rw-r--r--arch/sh/kernel/cpu/sh4/sq.c13
-rw-r--r--arch/sh/kernel/cpu/sh4a/Makefile2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7763.c126
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7722.c10
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7763.c390
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7780.c13
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7785.c19
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-shx3.c14
-rw-r--r--arch/sh/kernel/cpu/sh5/Makefile7
-rw-r--r--arch/sh/kernel/cpu/sh5/entry.S (renamed from arch/sh64/kernel/entry.S)51
-rw-r--r--arch/sh/kernel/cpu/sh5/fpu.c (renamed from arch/sh64/kernel/fpu.c)30
-rw-r--r--arch/sh/kernel/cpu/sh5/probe.c76
-rw-r--r--arch/sh/kernel/cpu/sh5/switchto.S (renamed from arch/sh64/kernel/switchto.S)2
-rw-r--r--arch/sh/kernel/cpu/sh5/unwind.c (renamed from arch/sh64/kernel/unwind.c)2
-rw-r--r--arch/sh/kernel/dump_task.c31
-rw-r--r--arch/sh/kernel/early_printk.c12
-rw-r--r--arch/sh/kernel/entry-common.S27
-rw-r--r--arch/sh/kernel/head_32.S (renamed from arch/sh/kernel/head.S)6
-rw-r--r--arch/sh/kernel/head_64.S (renamed from arch/sh64/kernel/head.S)50
-rw-r--r--arch/sh/kernel/init_task.c4
-rw-r--r--arch/sh/kernel/io.c67
-rw-r--r--arch/sh/kernel/module.c62
-rw-r--r--arch/sh/kernel/process_32.c (renamed from arch/sh/kernel/process.c)93
-rw-r--r--arch/sh/kernel/process_64.c (renamed from arch/sh64/kernel/process.c)90
-rw-r--r--arch/sh/kernel/ptrace_32.c (renamed from arch/sh/kernel/ptrace.c)21
-rw-r--r--arch/sh/kernel/ptrace_64.c (renamed from arch/sh64/kernel/ptrace.c)51
-rw-r--r--arch/sh/kernel/setup.c39
-rw-r--r--arch/sh/kernel/sh_ksyms_32.c (renamed from arch/sh/kernel/sh_ksyms.c)0
-rw-r--r--arch/sh/kernel/sh_ksyms_64.c (renamed from arch/sh64/kernel/sh_ksyms.c)15
-rw-r--r--arch/sh/kernel/signal_32.c (renamed from arch/sh/kernel/signal.c)18
-rw-r--r--arch/sh/kernel/signal_64.c (renamed from arch/sh64/kernel/signal.c)29
-rw-r--r--arch/sh/kernel/sys_sh.c100
-rw-r--r--arch/sh/kernel/sys_sh32.c84
-rw-r--r--arch/sh/kernel/sys_sh64.c66
-rw-r--r--arch/sh/kernel/syscalls_32.S (renamed from arch/sh/kernel/syscalls.S)0
-rw-r--r--arch/sh/kernel/syscalls_64.S (renamed from arch/sh64/kernel/syscalls.S)2
-rw-r--r--arch/sh/kernel/time_32.c (renamed from arch/sh/kernel/time.c)2
-rw-r--r--arch/sh/kernel/time_64.c (renamed from arch/sh64/kernel/time.c)230
-rw-r--r--arch/sh/kernel/timers/timer-cmt.c4
-rw-r--r--arch/sh/kernel/timers/timer-tmu.c1
-rw-r--r--arch/sh/kernel/traps.c949
-rw-r--r--arch/sh/kernel/traps_32.c919
-rw-r--r--arch/sh/kernel/traps_64.c (renamed from arch/sh64/kernel/traps.c)27
-rw-r--r--arch/sh/kernel/vmlinux.lds.S139
-rw-r--r--arch/sh/kernel/vmlinux_32.lds.S152
-rw-r--r--arch/sh/kernel/vmlinux_64.lds.S164
-rw-r--r--arch/sh/lib/Makefile5
-rw-r--r--arch/sh/lib/clear_page.S (renamed from arch/sh/mm/clear_page.S)8
-rw-r--r--arch/sh/lib/copy_page.S (renamed from arch/sh/mm/copy_page.S)9
-rw-r--r--arch/sh/lib/io.c82
-rw-r--r--arch/sh/lib64/.gitignore (renamed from arch/sh64/lib/.gitignore)0
-rw-r--r--arch/sh/lib64/Makefile15
-rw-r--r--arch/sh/lib64/c-checksum.c (renamed from arch/sh64/lib/c-checksum.c)5
-rw-r--r--arch/sh/lib64/clear_page.S (renamed from arch/sh64/lib/page_clear.S)4
-rw-r--r--arch/sh/lib64/copy_page.S (renamed from arch/sh64/lib/page_copy.S)56
-rw-r--r--arch/sh/lib64/copy_user_memcpy.S (renamed from arch/sh64/lib/copy_user_memcpy.S)0
-rw-r--r--arch/sh/lib64/dbg.c (renamed from arch/sh64/lib/dbg.c)2
-rw-r--r--arch/sh/lib64/memcpy.c (renamed from arch/sh64/lib/memcpy.c)0
-rw-r--r--arch/sh/lib64/panic.c (renamed from arch/sh64/lib/panic.c)2
-rw-r--r--arch/sh/lib64/udelay.c (renamed from arch/sh64/lib/udelay.c)9
-rw-r--r--arch/sh/mm/Kconfig222
-rw-r--r--arch/sh/mm/Makefile40
-rw-r--r--arch/sh/mm/Makefile_3236
-rw-r--r--arch/sh/mm/Makefile_64 (renamed from arch/sh64/mm/Makefile)32
-rw-r--r--arch/sh/mm/cache-debugfs.c9
-rw-r--r--arch/sh/mm/cache-sh4.c14
-rw-r--r--arch/sh/mm/cache-sh5.c (renamed from arch/sh64/mm/cache.c)15
-rw-r--r--arch/sh/mm/cache-sh7705.c12
-rw-r--r--arch/sh/mm/consistent.c174
-rw-r--r--arch/sh/mm/extable_32.c (renamed from arch/sh/mm/extable.c)0
-rw-r--r--arch/sh/mm/extable_64.c (renamed from arch/sh64/mm/extable.c)28
-rw-r--r--arch/sh/mm/fault_32.c (renamed from arch/sh/mm/fault.c)2
-rw-r--r--arch/sh/mm/fault_64.c (renamed from arch/sh64/mm/tlbmiss.c)150
-rw-r--r--arch/sh/mm/init.c68
-rw-r--r--arch/sh/mm/ioremap_32.c (renamed from arch/sh/mm/ioremap.c)0
-rw-r--r--arch/sh/mm/ioremap_64.c (renamed from arch/sh64/mm/ioremap.c)52
-rw-r--r--arch/sh/mm/pg-nommu.c4
-rw-r--r--arch/sh/mm/pmb.c26
-rw-r--r--arch/sh/mm/tlb-nommu.c10
-rw-r--r--arch/sh/mm/tlb-sh4.c7
-rw-r--r--arch/sh/mm/tlb-sh5.c (renamed from arch/sh64/mm/tlb.c)4
-rw-r--r--arch/sh/mm/tlbflush_32.c (renamed from arch/sh/mm/tlb-flush.c)0
-rw-r--r--arch/sh/mm/tlbflush_64.c (renamed from arch/sh64/mm/fault.c)205
-rw-r--r--arch/sh/tools/mach-types2
-rw-r--r--arch/sh64/Kconfig295
-rw-r--r--arch/sh64/Kconfig.debug33
-rw-r--r--arch/sh64/Makefile111
-rw-r--r--arch/sh64/boot/Makefile20
-rw-r--r--arch/sh64/boot/compressed/cache.c39
-rw-r--r--arch/sh64/boot/compressed/install.sh56
-rw-r--r--arch/sh64/configs/sim_defconfig558
-rw-r--r--arch/sh64/kernel/Makefile36
-rw-r--r--arch/sh64/kernel/alphanum.c43
-rw-r--r--arch/sh64/kernel/asm-offsets.c33
-rw-r--r--arch/sh64/kernel/dma.c297
-rw-r--r--arch/sh64/kernel/early_printk.c99
-rw-r--r--arch/sh64/kernel/init_task.c46
-rw-r--r--arch/sh64/kernel/irq.c115
-rw-r--r--arch/sh64/kernel/led.c40
-rw-r--r--arch/sh64/kernel/module.c161
-rw-r--r--arch/sh64/kernel/pci_sh5.c536
-rw-r--r--arch/sh64/kernel/pcibios.c168
-rw-r--r--arch/sh64/kernel/semaphore.c140
-rw-r--r--arch/sh64/kernel/setup.c379
-rw-r--r--arch/sh64/kernel/sys_sh64.c304
-rw-r--r--arch/sh64/kernel/vmlinux.lds.S140
-rw-r--r--arch/sh64/lib/Makefile19
-rw-r--r--arch/sh64/lib/io.c128
-rw-r--r--arch/sh64/lib/iomap.c54
-rw-r--r--arch/sh64/mach-cayman/Makefile11
-rw-r--r--arch/sh64/mach-cayman/iomap.c22
-rw-r--r--arch/sh64/mach-harp/Makefile1
-rw-r--r--arch/sh64/mach-harp/setup.c129
-rw-r--r--arch/sh64/mach-sim/Makefile1
-rw-r--r--arch/sh64/mach-sim/setup.c126
-rw-r--r--arch/sh64/mm/consistent.c53
-rw-r--r--arch/sh64/mm/hugetlbpage.c105
-rw-r--r--arch/sh64/mm/init.c189
-rw-r--r--arch/sh64/oprofile/Makefile12
-rw-r--r--arch/sh64/oprofile/op_model_null.c23
-rw-r--r--arch/sparc/kernel/setup.c2
-rw-r--r--arch/sparc/kernel/vmlinux.lds.S8
-rw-r--r--arch/sparc64/Kconfig8
-rw-r--r--arch/sparc64/kernel/pci_fire.c8
-rw-r--r--arch/sparc64/kernel/pci_psycho.c6
-rw-r--r--arch/sparc64/kernel/pci_sabre.c7
-rw-r--r--arch/sparc64/kernel/pci_schizo.c17
-rw-r--r--arch/sparc64/kernel/pci_sun4v.c5
-rw-r--r--arch/sparc64/kernel/setup.c2
-rw-r--r--arch/sparc64/kernel/unaligned.c2
-rw-r--r--arch/sparc64/kernel/vio.c2
-rw-r--r--arch/sparc64/kernel/vmlinux.lds.S8
-rw-r--r--arch/um/drivers/ubd_kern.c16
-rw-r--r--arch/um/include/init.h26
-rw-r--r--arch/um/kernel/dyn.lds.S4
-rw-r--r--arch/um/kernel/ksyms.c4
-rw-r--r--arch/um/kernel/uml.lds.S4
-rw-r--r--arch/um/sys-i386/signal.c50
-rw-r--r--arch/um/sys-x86_64/signal.c70
-rw-r--r--arch/v850/kernel/vmlinux.lds.S10
-rw-r--r--arch/x86/Kconfig314
-rw-r--r--arch/x86/Kconfig.cpu65
-rw-r--r--arch/x86/Kconfig.debug129
-rw-r--r--arch/x86/Makefile249
-rw-r--r--arch/x86/Makefile_32175
-rw-r--r--arch/x86/Makefile_64144
-rw-r--r--arch/x86/boot/Makefile10
-rw-r--r--arch/x86/boot/apm.c3
-rw-r--r--arch/x86/boot/boot.h17
-rw-r--r--arch/x86/boot/cmdline.c65
-rw-r--r--arch/x86/boot/compressed/Makefile62
-rw-r--r--arch/x86/boot/compressed/Makefile_3250
-rw-r--r--arch/x86/boot/compressed/Makefile_6430
-rw-r--r--arch/x86/boot/compressed/misc.c (renamed from arch/x86/boot/compressed/misc_32.c)77
-rw-r--r--arch/x86/boot/compressed/misc_64.c371
-rw-r--r--arch/x86/boot/compressed/relocs.c7
-rw-r--r--arch/x86/boot/compressed/vmlinux.scr (renamed from arch/x86/boot/compressed/vmlinux_64.scr)2
-rw-r--r--arch/x86/boot/compressed/vmlinux_32.lds10
-rw-r--r--arch/x86/boot/compressed/vmlinux_32.scr10
-rw-r--r--arch/x86/boot/compressed/vmlinux_64.lds12
-rw-r--r--arch/x86/boot/edd.c13
-rw-r--r--arch/x86/boot/header.S5
-rw-r--r--arch/x86/boot/main.c31
-rw-r--r--arch/x86/boot/pm.c6
-rw-r--r--arch/x86/boot/pmjump.S54
-rw-r--r--arch/x86/boot/video-bios.c3
-rw-r--r--arch/x86/boot/video-vesa.c26
-rw-r--r--arch/x86/boot/video-vga.c20
-rw-r--r--arch/x86/boot/video.c33
-rw-r--r--arch/x86/boot/video.h3
-rw-r--r--arch/x86/boot/voyager.c4
-rw-r--r--arch/x86/configs/i386_defconfig4
-rw-r--r--arch/x86/configs/x86_64_defconfig9
-rw-r--r--arch/x86/crypto/Makefile12
-rw-r--r--arch/x86/crypto/aes-i586-asm_32.S89
-rw-r--r--arch/x86/crypto/aes-x86_64-asm_64.S68
-rw-r--r--arch/x86/crypto/aes_32.c515
-rw-r--r--arch/x86/crypto/aes_64.c336
-rw-r--r--arch/x86/crypto/aes_glue.c57
-rw-r--r--arch/x86/crypto/salsa20-i586-asm_32.S1114
-rw-r--r--arch/x86/crypto/salsa20-x86_64-asm_64.S920
-rw-r--r--arch/x86/crypto/salsa20_glue.c129
-rw-r--r--arch/x86/crypto/twofish_64.c97
-rw-r--r--arch/x86/crypto/twofish_glue.c (renamed from arch/x86/crypto/twofish_32.c)8
-rw-r--r--arch/x86/ia32/Makefile41
-rw-r--r--arch/x86/ia32/audit.c2
-rw-r--r--arch/x86/ia32/fpu32.c183
-rw-r--r--arch/x86/ia32/ia32_aout.c246
-rw-r--r--arch/x86/ia32/ia32_binfmt.c285
-rw-r--r--arch/x86/ia32/ia32_signal.c472
-rw-r--r--arch/x86/ia32/ia32entry.S11
-rw-r--r--arch/x86/ia32/ipc32.c30
-rw-r--r--arch/x86/ia32/mmap32.c79
-rw-r--r--arch/x86/ia32/ptrace32.c404
-rw-r--r--arch/x86/ia32/sys_ia32.c504
-rw-r--r--arch/x86/ia32/syscall32.c83
-rw-r--r--arch/x86/ia32/syscall32_syscall.S17
-rw-r--r--arch/x86/ia32/tls32.c163
-rw-r--r--arch/x86/ia32/vsyscall-sigreturn.S143
-rw-r--r--arch/x86/ia32/vsyscall-sysenter.S95
-rw-r--r--arch/x86/ia32/vsyscall.lds80
-rw-r--r--arch/x86/kernel/Makefile96
-rw-r--r--arch/x86/kernel/Makefile_3288
-rw-r--r--arch/x86/kernel/Makefile_6445
-rw-r--r--arch/x86/kernel/acpi/Makefile2
-rw-r--r--arch/x86/kernel/acpi/sleep.c87
-rw-r--r--arch/x86/kernel/acpi/sleep_32.c70
-rw-r--r--arch/x86/kernel/acpi/sleep_64.c117
-rw-r--r--arch/x86/kernel/acpi/wakeup_32.S2
-rw-r--r--arch/x86/kernel/acpi/wakeup_64.S32
-rw-r--r--arch/x86/kernel/alternative.c40
-rw-r--r--arch/x86/kernel/aperture_64.c374
-rw-r--r--arch/x86/kernel/apic_32.c158
-rw-r--r--arch/x86/kernel/apic_64.c1259
-rw-r--r--arch/x86/kernel/apm_32.c379
-rw-r--r--arch/x86/kernel/asm-offsets_32.c65
-rw-r--r--arch/x86/kernel/asm-offsets_64.c56
-rw-r--r--arch/x86/kernel/bootflag.c50
-rw-r--r--arch/x86/kernel/bugs_64.c1
-rw-r--r--arch/x86/kernel/cpu/addon_cpuid_features.c2
-rw-r--r--arch/x86/kernel/cpu/amd.c23
-rw-r--r--arch/x86/kernel/cpu/bugs.c5
-rw-r--r--arch/x86/kernel/cpu/common.c179
-rw-r--r--arch/x86/kernel/cpu/cpu.h3
-rw-r--r--arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c25
-rw-r--r--arch/x86/kernel/cpu/cpufreq/longhaul.c2
-rw-r--r--arch/x86/kernel/cpu/cpufreq/powernow-k8.c12
-rw-r--r--arch/x86/kernel/cpu/cyrix.c6
-rw-r--r--arch/x86/kernel/cpu/intel.c39
-rw-r--r--arch/x86/kernel/cpu/intel_cacheinfo.c24
-rw-r--r--arch/x86/kernel/cpu/mcheck/k7.c25
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce.h2
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_32.c4
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_64.c47
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_amd_64.c49
-rw-r--r--arch/x86/kernel/cpu/mcheck/p4.c35
-rw-r--r--arch/x86/kernel/cpu/mcheck/p5.c2
-rw-r--r--arch/x86/kernel/cpu/mcheck/p6.c23
-rw-r--r--arch/x86/kernel/cpu/mcheck/winchip.c2
-rw-r--r--arch/x86/kernel/cpu/mtrr/amd.c2
-rw-r--r--arch/x86/kernel/cpu/mtrr/cyrix.c3
-rw-r--r--arch/x86/kernel/cpu/mtrr/generic.c27
-rw-r--r--arch/x86/kernel/cpu/mtrr/if.c23
-rw-r--r--arch/x86/kernel/cpu/mtrr/main.c155
-rw-r--r--arch/x86/kernel/cpu/mtrr/mtrr.h9
-rw-r--r--arch/x86/kernel/cpu/mtrr/state.c3
-rw-r--r--arch/x86/kernel/cpu/perfctr-watchdog.c1
-rw-r--r--arch/x86/kernel/cpu/proc.c2
-rw-r--r--arch/x86/kernel/cpuid.c8
-rw-r--r--arch/x86/kernel/doublefault_32.c19
-rw-r--r--arch/x86/kernel/ds.c464
-rw-r--r--arch/x86/kernel/e820_32.c241
-rw-r--r--arch/x86/kernel/e820_64.c428
-rw-r--r--arch/x86/kernel/early-quirks.c127
-rw-r--r--arch/x86/kernel/efi.c512
-rw-r--r--arch/x86/kernel/efi_32.c618
-rw-r--r--arch/x86/kernel/efi_64.c134
-rw-r--r--arch/x86/kernel/efi_stub_64.S109
-rw-r--r--arch/x86/kernel/entry_32.S26
-rw-r--r--arch/x86/kernel/entry_64.S107
-rw-r--r--arch/x86/kernel/genapic_64.c15
-rw-r--r--arch/x86/kernel/geode_32.c48
-rw-r--r--arch/x86/kernel/head64.c63
-rw-r--r--arch/x86/kernel/head_32.S17
-rw-r--r--arch/x86/kernel/head_64.S48
-rw-r--r--arch/x86/kernel/hpet.c60
-rw-r--r--arch/x86/kernel/i386_ksyms_32.c7
-rw-r--r--arch/x86/kernel/i387.c479
-rw-r--r--arch/x86/kernel/i387_32.c544
-rw-r--r--arch/x86/kernel/i387_64.c150
-rw-r--r--arch/x86/kernel/i8237.c2
-rw-r--r--arch/x86/kernel/i8253.c72
-rw-r--r--arch/x86/kernel/i8259_32.c26
-rw-r--r--arch/x86/kernel/i8259_64.c162
-rw-r--r--arch/x86/kernel/init_task.c1
-rw-r--r--arch/x86/kernel/io_apic_32.c15
-rw-r--r--arch/x86/kernel/io_apic_64.c114
-rw-r--r--arch/x86/kernel/io_delay.c114
-rw-r--r--arch/x86/kernel/ioport.c (renamed from arch/x86/kernel/ioport_32.c)85
-rw-r--r--arch/x86/kernel/ioport_64.c117
-rw-r--r--arch/x86/kernel/irq_32.c22
-rw-r--r--arch/x86/kernel/irq_64.c30
-rw-r--r--arch/x86/kernel/kdebugfs.c65
-rw-r--r--arch/x86/kernel/kprobes.c1066
-rw-r--r--arch/x86/kernel/kprobes_32.c756
-rw-r--r--arch/x86/kernel/kprobes_64.c749
-rw-r--r--arch/x86/kernel/ldt.c (renamed from arch/x86/kernel/ldt_32.c)112
-rw-r--r--arch/x86/kernel/ldt_64.c250
-rw-r--r--arch/x86/kernel/machine_kexec_32.c4
-rw-r--r--arch/x86/kernel/machine_kexec_64.c5
-rw-r--r--arch/x86/kernel/mfgpt_32.c15
-rw-r--r--arch/x86/kernel/microcode.c28
-rw-r--r--arch/x86/kernel/mpparse_32.c39
-rw-r--r--arch/x86/kernel/mpparse_64.c28
-rw-r--r--arch/x86/kernel/msr.c6
-rw-r--r--arch/x86/kernel/nmi_32.c16
-rw-r--r--arch/x86/kernel/nmi_64.c101
-rw-r--r--arch/x86/kernel/numaq_32.c2
-rw-r--r--arch/x86/kernel/paravirt.c (renamed from arch/x86/kernel/paravirt_32.c)96
-rw-r--r--arch/x86/kernel/paravirt_patch_32.c49
-rw-r--r--arch/x86/kernel/paravirt_patch_64.c57
-rw-r--r--arch/x86/kernel/pci-calgary_64.c5
-rw-r--r--arch/x86/kernel/pci-dma_64.c3
-rw-r--r--arch/x86/kernel/pci-gart_64.c510
-rw-r--r--arch/x86/kernel/pci-swiotlb_64.c1
-rw-r--r--arch/x86/kernel/pmtimer_64.c4
-rw-r--r--arch/x86/kernel/process_32.c419
-rw-r--r--arch/x86/kernel/process_64.c342
-rw-r--r--arch/x86/kernel/ptrace.c1545
-rw-r--r--arch/x86/kernel/ptrace_32.c717
-rw-r--r--arch/x86/kernel/ptrace_64.c621
-rw-r--r--arch/x86/kernel/quirks.c2
-rw-r--r--arch/x86/kernel/reboot.c (renamed from arch/x86/kernel/reboot_32.c)284
-rw-r--r--arch/x86/kernel/reboot_64.c176
-rw-r--r--arch/x86/kernel/reboot_fixups_32.c14
-rw-r--r--arch/x86/kernel/rtc.c204
-rw-r--r--arch/x86/kernel/setup64.c59
-rw-r--r--arch/x86/kernel/setup_32.c285
-rw-r--r--arch/x86/kernel/setup_64.c555
-rw-r--r--arch/x86/kernel/signal_32.c228
-rw-r--r--arch/x86/kernel/signal_64.c136
-rw-r--r--arch/x86/kernel/smp_32.c15
-rw-r--r--arch/x86/kernel/smp_64.c91
-rw-r--r--arch/x86/kernel/smpboot_32.c61
-rw-r--r--arch/x86/kernel/smpboot_64.c79
-rw-r--r--arch/x86/kernel/smpcommon_32.c7
-rw-r--r--arch/x86/kernel/srat_32.c8
-rw-r--r--arch/x86/kernel/stacktrace.c33
-rw-r--r--arch/x86/kernel/step.c203
-rw-r--r--arch/x86/kernel/suspend_64.c30
-rw-r--r--arch/x86/kernel/suspend_asm_64.S32
-rw-r--r--arch/x86/kernel/sys_x86_64.c98
-rw-r--r--arch/x86/kernel/test_nx.c176
-rw-r--r--arch/x86/kernel/test_rodata.c86
-rw-r--r--arch/x86/kernel/time_32.c114
-rw-r--r--arch/x86/kernel/time_64.c187
-rw-r--r--arch/x86/kernel/tls.c213
-rw-r--r--arch/x86/kernel/tls.h21
-rw-r--r--arch/x86/kernel/topology.c23
-rw-r--r--arch/x86/kernel/traps_32.c341
-rw-r--r--arch/x86/kernel/traps_64.c367
-rw-r--r--arch/x86/kernel/tsc_32.c62
-rw-r--r--arch/x86/kernel/tsc_64.c100
-rw-r--r--arch/x86/kernel/tsc_sync.c30
-rw-r--r--arch/x86/kernel/vm86_32.c115
-rw-r--r--arch/x86/kernel/vmi_32.c126
-rw-r--r--arch/x86/kernel/vmiclock_32.c3
-rw-r--r--arch/x86/kernel/vmlinux_32.lds.S22
-rw-r--r--arch/x86/kernel/vmlinux_64.lds.S42
-rw-r--r--arch/x86/kernel/vsmp_64.c11
-rw-r--r--arch/x86/kernel/vsyscall_32.S15
-rw-r--r--arch/x86/kernel/vsyscall_32.lds.S67
-rw-r--r--arch/x86/kernel/vsyscall_64.c11
-rw-r--r--arch/x86/kernel/x8664_ksyms_64.c13
-rw-r--r--arch/x86/kvm/Kconfig57
-rw-r--r--arch/x86/kvm/Makefile14
-rw-r--r--arch/x86/kvm/i8259.c450
-rw-r--r--arch/x86/kvm/irq.c78
-rw-r--r--arch/x86/kvm/irq.h88
-rw-r--r--arch/x86/kvm/kvm_svm.h45
-rw-r--r--arch/x86/kvm/lapic.c1154
-rw-r--r--arch/x86/kvm/lapic.h50
-rw-r--r--arch/x86/kvm/mmu.c1885
-rw-r--r--arch/x86/kvm/mmu.h44
-rw-r--r--arch/x86/kvm/paging_tmpl.h484
-rw-r--r--arch/x86/kvm/segment_descriptor.h29
-rw-r--r--arch/x86/kvm/svm.c1731
-rw-r--r--arch/x86/kvm/svm.h325
-rw-r--r--arch/x86/kvm/vmx.c2679
-rw-r--r--arch/x86/kvm/vmx.h324
-rw-r--r--arch/x86/kvm/x86.c3287
-rw-r--r--arch/x86/kvm/x86_emulate.c1912
-rw-r--r--arch/x86/lguest/Kconfig1
-rw-r--r--arch/x86/lguest/boot.c62
-rw-r--r--arch/x86/lib/Makefile26
-rw-r--r--arch/x86/lib/Makefile_3211
-rw-r--r--arch/x86/lib/Makefile_6413
-rw-r--r--arch/x86/lib/memcpy_32.c4
-rw-r--r--arch/x86/lib/memmove_64.c4
-rw-r--r--arch/x86/lib/semaphore_32.S22
-rw-r--r--arch/x86/lib/thunk_64.S2
-rw-r--r--arch/x86/mach-rdc321x/Makefile5
-rw-r--r--arch/x86/mach-rdc321x/gpio.c91
-rw-r--r--arch/x86/mach-rdc321x/platform.c68
-rw-r--r--arch/x86/mach-rdc321x/wdt.c275
-rw-r--r--arch/x86/mach-visws/mpparse.c16
-rw-r--r--arch/x86/mach-voyager/setup.c34
-rw-r--r--arch/x86/mach-voyager/voyager_basic.c132
-rw-r--r--arch/x86/mach-voyager/voyager_cat.c601
-rw-r--r--arch/x86/mach-voyager/voyager_smp.c690
-rw-r--r--arch/x86/mach-voyager/voyager_thread.c52
-rw-r--r--arch/x86/math-emu/errors.c882
-rw-r--r--arch/x86/math-emu/exception.h9
-rw-r--r--arch/x86/math-emu/fpu_arith.c150
-rw-r--r--arch/x86/math-emu/fpu_asm.h1
-rw-r--r--arch/x86/math-emu/fpu_aux.c211
-rw-r--r--arch/x86/math-emu/fpu_emu.h67
-rw-r--r--arch/x86/math-emu/fpu_entry.c1230
-rw-r--r--arch/x86/math-emu/fpu_etc.c185
-rw-r--r--arch/x86/math-emu/fpu_proto.h28
-rw-r--r--arch/x86/math-emu/fpu_tags.c94
-rw-r--r--arch/x86/math-emu/fpu_trig.c2884
-rw-r--r--arch/x86/math-emu/get_address.c650
-rw-r--r--arch/x86/math-emu/load_store.c448
-rw-r--r--arch/x86/math-emu/poly.h69
-rw-r--r--arch/x86/math-emu/poly_2xm1.c199
-rw-r--r--arch/x86/math-emu/poly_atan.c353
-rw-r--r--arch/x86/math-emu/poly_l2.c376
-rw-r--r--arch/x86/math-emu/poly_sin.c599
-rw-r--r--arch/x86/math-emu/poly_tan.c338
-rw-r--r--arch/x86/math-emu/reg_add_sub.c563
-rw-r--r--arch/x86/math-emu/reg_compare.c567
-rw-r--r--arch/x86/math-emu/reg_constant.c73
-rw-r--r--arch/x86/math-emu/reg_convert.c57
-rw-r--r--arch/x86/math-emu/reg_divide.c301
-rw-r--r--arch/x86/math-emu/reg_ld_str.c2147
-rw-r--r--arch/x86/math-emu/reg_mul.c163
-rw-r--r--arch/x86/math-emu/status_w.h8
-rw-r--r--arch/x86/mm/Makefile_323
-rw-r--r--arch/x86/mm/Makefile_643
-rw-r--r--arch/x86/mm/boot_ioremap_32.c100
-rw-r--r--arch/x86/mm/discontig_32.c110
-rw-r--r--arch/x86/mm/extable.c62
-rw-r--r--arch/x86/mm/extable_32.c35
-rw-r--r--arch/x86/mm/extable_64.c34
-rw-r--r--arch/x86/mm/fault.c986
-rw-r--r--arch/x86/mm/fault_32.c659
-rw-r--r--arch/x86/mm/fault_64.c623
-rw-r--r--arch/x86/mm/highmem_32.c47
-rw-r--r--arch/x86/mm/hugetlbpage.c3
-rw-r--r--arch/x86/mm/init_32.c425
-rw-r--r--arch/x86/mm/init_64.c418
-rw-r--r--arch/x86/mm/ioremap.c501
-rw-r--r--arch/x86/mm/ioremap_32.c274
-rw-r--r--arch/x86/mm/ioremap_64.c210
-rw-r--r--arch/x86/mm/k8topology_64.c173
-rw-r--r--arch/x86/mm/mmap.c (renamed from arch/x86/mm/mmap_32.c)86
-rw-r--r--arch/x86/mm/mmap_64.c29
-rw-r--r--arch/x86/mm/numa_64.c274
-rw-r--r--arch/x86/mm/pageattr-test.c224
-rw-r--r--arch/x86/mm/pageattr.c564
-rw-r--r--arch/x86/mm/pageattr_32.c278
-rw-r--r--arch/x86/mm/pageattr_64.c255
-rw-r--r--arch/x86/mm/pgtable_32.c145
-rw-r--r--arch/x86/mm/srat_64.c95
-rw-r--r--arch/x86/oprofile/backtrace.c12
-rw-r--r--arch/x86/oprofile/nmi_int.c214
-rw-r--r--arch/x86/pci/common.c17
-rw-r--r--arch/x86/pci/fixup.c30
-rw-r--r--arch/x86/pci/irq.c20
-rw-r--r--arch/x86/power/cpu.c18
-rw-r--r--arch/x86/vdso/.gitignore5
-rw-r--r--arch/x86/vdso/Makefile132
-rw-r--r--arch/x86/vdso/vclock_gettime.c1
-rw-r--r--arch/x86/vdso/vdso-layout.lds.S64
-rw-r--r--arch/x86/vdso/vdso-start.S2
-rw-r--r--arch/x86/vdso/vdso.lds.S94
-rw-r--r--arch/x86/vdso/vdso32-setup.c (renamed from arch/x86/kernel/sysenter_32.c)164
-rw-r--r--arch/x86/vdso/vdso32.S19
-rw-r--r--arch/x86/vdso/vdso32/.gitignore1
-rw-r--r--arch/x86/vdso/vdso32/int80.S (renamed from arch/x86/kernel/vsyscall-int80_32.S)21
-rw-r--r--arch/x86/vdso/vdso32/note.S (renamed from arch/x86/kernel/vsyscall-note_32.S)5
-rw-r--r--arch/x86/vdso/vdso32/sigreturn.S (renamed from arch/x86/kernel/vsyscall-sigreturn_32.S)87
-rw-r--r--arch/x86/vdso/vdso32/syscall.S (renamed from arch/x86/ia32/vsyscall-syscall.S)22
-rw-r--r--arch/x86/vdso/vdso32/sysenter.S (renamed from arch/x86/kernel/vsyscall-sysenter_32.S)42
-rw-r--r--arch/x86/vdso/vdso32/vdso32.lds.S37
-rw-r--r--arch/x86/vdso/vgetcpu.c4
-rw-r--r--arch/x86/vdso/vma.c18
-rw-r--r--arch/x86/vdso/voffset.h1
-rw-r--r--arch/x86/xen/Kconfig1
-rw-r--r--arch/x86/xen/enlighten.c104
-rw-r--r--arch/x86/xen/events.c4
-rw-r--r--arch/x86/xen/mmu.c23
-rw-r--r--arch/x86/xen/setup.c9
-rw-r--r--arch/x86/xen/smp.c8
-rw-r--r--arch/x86/xen/time.c2
-rw-r--r--arch/x86/xen/xen-head.S6
-rw-r--r--arch/xtensa/kernel/vmlinux.lds.S9
-rw-r--r--arch/xtensa/mm/Makefile4
-rw-r--r--arch/xtensa/platform-iss/Makefile5
1122 files changed, 85275 insertions, 43126 deletions
diff --git a/arch/alpha/kernel/vmlinux.lds.S b/arch/alpha/kernel/vmlinux.lds.S
index 55c05b511f4c..f13249be17c5 100644
--- a/arch/alpha/kernel/vmlinux.lds.S
+++ b/arch/alpha/kernel/vmlinux.lds.S
@@ -46,11 +46,11 @@ SECTIONS
46 __init_begin = .; 46 __init_begin = .;
47 .init.text : { 47 .init.text : {
48 _sinittext = .; 48 _sinittext = .;
49 *(.init.text) 49 INIT_TEXT
50 _einittext = .; 50 _einittext = .;
51 } 51 }
52 .init.data : { 52 .init.data : {
53 *(.init.data) 53 INIT_DATA
54 } 54 }
55 55
56 . = ALIGN(16); 56 . = ALIGN(16);
@@ -136,8 +136,8 @@ SECTIONS
136 136
137 /* Sections to be discarded */ 137 /* Sections to be discarded */
138 /DISCARD/ : { 138 /DISCARD/ : {
139 *(.exit.text) 139 EXIT_TEXT
140 *(.exit.data) 140 EXIT_DATA
141 *(.exitcall.exit) 141 *(.exitcall.exit)
142 } 142 }
143 143
diff --git a/arch/alpha/lib/dec_and_lock.c b/arch/alpha/lib/dec_and_lock.c
index 6ae2500a9d9e..0f5520d2f45f 100644
--- a/arch/alpha/lib/dec_and_lock.c
+++ b/arch/alpha/lib/dec_and_lock.c
@@ -30,8 +30,7 @@ _atomic_dec_and_lock: \n\
30 .previous \n\ 30 .previous \n\
31 .end _atomic_dec_and_lock"); 31 .end _atomic_dec_and_lock");
32 32
33static int __attribute_used__ 33static int __used atomic_dec_and_lock_1(atomic_t *atomic, spinlock_t *lock)
34atomic_dec_and_lock_1(atomic_t *atomic, spinlock_t *lock)
35{ 34{
36 /* Slow path */ 35 /* Slow path */
37 spin_lock(lock); 36 spin_lock(lock);
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a04f507e7f2c..77201d3f7479 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -91,6 +91,11 @@ config GENERIC_IRQ_PROBE
91 bool 91 bool
92 default y 92 default y
93 93
94config GENERIC_LOCKBREAK
95 bool
96 default y
97 depends on SMP && PREEMPT
98
94config RWSEM_GENERIC_SPINLOCK 99config RWSEM_GENERIC_SPINLOCK
95 bool 100 bool
96 default y 101 default y
@@ -180,8 +185,8 @@ config ARCH_AT91
180 bool "Atmel AT91" 185 bool "Atmel AT91"
181 select GENERIC_GPIO 186 select GENERIC_GPIO
182 help 187 help
183 This enables support for systems based on the Atmel AT91RM9200 188 This enables support for systems based on the Atmel AT91RM9200,
184 and AT91SAM9xxx processors. 189 AT91SAM9 and AT91CAP9 processors.
185 190
186config ARCH_CLPS7500 191config ARCH_CLPS7500
187 bool "Cirrus CL-PS7500FE" 192 bool "Cirrus CL-PS7500FE"
@@ -217,6 +222,7 @@ config ARCH_EP93XX
217 bool "EP93xx-based" 222 bool "EP93xx-based"
218 select ARM_AMBA 223 select ARM_AMBA
219 select ARM_VIC 224 select ARM_VIC
225 select GENERIC_GPIO
220 help 226 help
221 This enables support for the Cirrus EP93xx series of CPUs. 227 This enables support for the Cirrus EP93xx series of CPUs.
222 228
@@ -333,6 +339,16 @@ config ARCH_MXC
333 help 339 help
334 Support for Freescale MXC/iMX-based family of processors 340 Support for Freescale MXC/iMX-based family of processors
335 341
342config ARCH_ORION
343 bool "Marvell Orion"
344 depends on MMU
345 select PCI
346 select GENERIC_GPIO
347 select GENERIC_TIME
348 select GENERIC_CLOCKEVENTS
349 help
350 Support for Marvell Orion System on Chip family.
351
336config ARCH_PNX4008 352config ARCH_PNX4008
337 bool "Philips Nexperia PNX4008 Mobile" 353 bool "Philips Nexperia PNX4008 Mobile"
338 help 354 help
@@ -345,6 +361,7 @@ config ARCH_PXA
345 select GENERIC_GPIO 361 select GENERIC_GPIO
346 select GENERIC_TIME 362 select GENERIC_TIME
347 select GENERIC_CLOCKEVENTS 363 select GENERIC_CLOCKEVENTS
364 select TICK_ONESHOT
348 help 365 help
349 Support for Intel/Marvell's PXA2xx/PXA3xx processor line. 366 Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
350 367
@@ -366,6 +383,7 @@ config ARCH_SA1100
366 select ARCH_DISCONTIGMEM_ENABLE 383 select ARCH_DISCONTIGMEM_ENABLE
367 select ARCH_MTD_XIP 384 select ARCH_MTD_XIP
368 select GENERIC_GPIO 385 select GENERIC_GPIO
386 select GENERIC_TIME
369 help 387 help
370 Support for StrongARM 11x0 based boards. 388 Support for StrongARM 11x0 based boards.
371 389
@@ -409,6 +427,17 @@ config ARCH_OMAP
409 help 427 help
410 Support for TI's OMAP platform (OMAP1 and OMAP2). 428 Support for TI's OMAP platform (OMAP1 and OMAP2).
411 429
430config ARCH_MSM7X00A
431 bool "Qualcomm MSM7X00A"
432 select GENERIC_TIME
433 select GENERIC_CLOCKEVENTS
434 help
435 Support for Qualcomm MSM7X00A based systems. This runs on the ARM11
436 apps processor of the MSM7X00A and depends on a shared memory
437 interface to the ARM9 modem processor which runs the baseband stack
438 and controls some vital subsystems (clock and power control, etc).
439 <http://www.cdmatech.com/products/msm7200_chipset_solution.jsp>
440
412endchoice 441endchoice
413 442
414source "arch/arm/mach-clps711x/Kconfig" 443source "arch/arm/mach-clps711x/Kconfig"
@@ -441,6 +470,8 @@ source "arch/arm/mach-omap1/Kconfig"
441 470
442source "arch/arm/mach-omap2/Kconfig" 471source "arch/arm/mach-omap2/Kconfig"
443 472
473source "arch/arm/mach-orion/Kconfig"
474
444source "arch/arm/plat-s3c24xx/Kconfig" 475source "arch/arm/plat-s3c24xx/Kconfig"
445source "arch/arm/plat-s3c/Kconfig" 476source "arch/arm/plat-s3c/Kconfig"
446 477
@@ -477,6 +508,8 @@ source "arch/arm/mach-davinci/Kconfig"
477 508
478source "arch/arm/mach-ks8695/Kconfig" 509source "arch/arm/mach-ks8695/Kconfig"
479 510
511source "arch/arm/mach-msm/Kconfig"
512
480# Definitions to make life easier 513# Definitions to make life easier
481config ARCH_ACORN 514config ARCH_ACORN
482 bool 515 bool
@@ -657,6 +690,7 @@ config HZ
657 default 128 if ARCH_L7200 690 default 128 if ARCH_L7200
658 default 200 if ARCH_EBSA110 || ARCH_S3C2410 691 default 200 if ARCH_EBSA110 || ARCH_S3C2410
659 default OMAP_32K_TIMER_HZ if ARCH_OMAP && OMAP_32K_TIMER 692 default OMAP_32K_TIMER_HZ if ARCH_OMAP && OMAP_32K_TIMER
693 default AT91_TIMER_HZ if ARCH_AT91
660 default 100 694 default 100
661 695
662config AEABI 696config AEABI
@@ -716,7 +750,7 @@ config LEDS
716 ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || \ 750 ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || \
717 ARCH_SA1100 || ARCH_SHARK || ARCH_VERSATILE || \ 751 ARCH_SA1100 || ARCH_SHARK || ARCH_VERSATILE || \
718 ARCH_AT91 || MACH_TRIZEPS4 || ARCH_DAVINCI || \ 752 ARCH_AT91 || MACH_TRIZEPS4 || ARCH_DAVINCI || \
719 ARCH_KS8695 753 ARCH_KS8695 || MACH_RD88F5182
720 help 754 help
721 If you say Y here, the LEDs on your machine will be used 755 If you say Y here, the LEDs on your machine will be used
722 to provide useful information about your current system status. 756 to provide useful information about your current system status.
@@ -867,7 +901,7 @@ config KEXEC
867 901
868endmenu 902endmenu
869 903
870if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX ) 904if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX || ARCH_PXA)
871 905
872menu "CPU Frequency scaling" 906menu "CPU Frequency scaling"
873 907
@@ -903,6 +937,12 @@ config CPU_FREQ_IMX
903 937
904 If in doubt, say N. 938 If in doubt, say N.
905 939
940config CPU_FREQ_PXA
941 bool
942 depends on CPU_FREQ && ARCH_PXA && PXA25x
943 default y
944 select CPU_FREQ_DEFAULT_GOV_USERSPACE
945
906endmenu 946endmenu
907 947
908endif 948endif
@@ -951,7 +991,7 @@ config FPE_FASTFPE
951 991
952config VFP 992config VFP
953 bool "VFP-format floating point maths" 993 bool "VFP-format floating point maths"
954 depends on CPU_V6 || CPU_ARM926T 994 depends on CPU_V6 || CPU_ARM926T || CPU_V7 || CPU_FEROCEON
955 help 995 help
956 Say Y to include VFP support code in the kernel. This is needed 996 Say Y to include VFP support code in the kernel. This is needed
957 if your hardware includes a VFP unit. 997 if your hardware includes a VFP unit.
@@ -961,6 +1001,18 @@ config VFP
961 1001
962 Say N if your target does not have VFP hardware. 1002 Say N if your target does not have VFP hardware.
963 1003
1004config VFPv3
1005 bool
1006 depends on VFP
1007 default y if CPU_V7
1008
1009config NEON
1010 bool "Advanced SIMD (NEON) Extension support"
1011 depends on VFPv3 && CPU_V7
1012 help
1013 Say Y to include support code for NEON, the ARMv7 Advanced SIMD
1014 Extension.
1015
964endmenu 1016endmenu
965 1017
966menu "Userspace binary formats" 1018menu "Userspace binary formats"
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 18101f5f5f24..192ee01a9ba2 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -43,6 +43,12 @@ config DEBUG_ERRORS
43 you are concerned with the code size or don't want to see these 43 you are concerned with the code size or don't want to see these
44 messages. 44 messages.
45 45
46config DEBUG_STACK_USAGE
47 bool "Enable stack utilization instrumentation"
48 depends on DEBUG_KERNEL
49 help
50 Enables the display of the minimum amount of free stack which each
51 task has ever had available in the sysrq-T output.
46 52
47# These options are only for real kernel hackers who want to get their hands dirty. 53# These options are only for real kernel hackers who want to get their hands dirty.
48config DEBUG_LL 54config DEBUG_LL
diff --git a/arch/arm/Kconfig.instrumentation b/arch/arm/Kconfig.instrumentation
index 63b8c6d5606a..453ad8e15d69 100644
--- a/arch/arm/Kconfig.instrumentation
+++ b/arch/arm/Kconfig.instrumentation
@@ -43,6 +43,16 @@ config OPROFILE_MPCORE
43config OPROFILE_ARM11_CORE 43config OPROFILE_ARM11_CORE
44 bool 44 bool
45 45
46config KPROBES
47 bool "Kprobes"
48 depends on KALLSYMS && MODULES && !UML && !XIP_KERNEL
49 help
50 Kprobes allows you to trap at almost any kernel address and
51 execute a callback function. register_kprobe() establishes
52 a probepoint and specifies the callback. Kprobes is useful
53 for kernel debugging, non-intrusive instrumentation and testing.
54 If in doubt, say "N".
55
46config MARKERS 56config MARKERS
47 bool "Activate markers" 57 bool "Activate markers"
48 help 58 help
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 35e56c99ad1d..7b8ff66febe1 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -139,6 +139,8 @@ endif
139 machine-$(CONFIG_ARCH_KS8695) := ks8695 139 machine-$(CONFIG_ARCH_KS8695) := ks8695
140 incdir-$(CONFIG_ARCH_MXC) := mxc 140 incdir-$(CONFIG_ARCH_MXC) := mxc
141 machine-$(CONFIG_ARCH_MX3) := mx3 141 machine-$(CONFIG_ARCH_MX3) := mx3
142 machine-$(CONFIG_ARCH_ORION) := orion
143 machine-$(CONFIG_ARCH_MSM7X00A) := msm
142 144
143ifeq ($(CONFIG_ARCH_EBSA110),y) 145ifeq ($(CONFIG_ARCH_EBSA110),y)
144# This is what happens if you forget the IOCS16 line. 146# This is what happens if you forget the IOCS16 line.
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 5fde99f9d9f9..de9d9ee50958 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -44,10 +44,6 @@ ifeq ($(CONFIG_PXA_SHARPSL),y)
44OBJS += head-sharpsl.o 44OBJS += head-sharpsl.o
45endif 45endif
46 46
47ifeq ($(CONFIG_ARCH_AT91RM9200),y)
48OBJS += head-at91rm9200.o
49endif
50
51ifeq ($(CONFIG_CPU_BIG_ENDIAN),y) 47ifeq ($(CONFIG_CPU_BIG_ENDIAN),y)
52ifeq ($(CONFIG_CPU_CP15),y) 48ifeq ($(CONFIG_CPU_CP15),y)
53OBJS += big-endian.o 49OBJS += big-endian.o
diff --git a/arch/arm/boot/compressed/head-at91rm9200.S b/arch/arm/boot/compressed/head-at91rm9200.S
deleted file mode 100644
index 11782ccd93a1..000000000000
--- a/arch/arm/boot/compressed/head-at91rm9200.S
+++ /dev/null
@@ -1,81 +0,0 @@
1/*
2 * linux/arch/arm/boot/compressed/head-at91rm9200.S
3 *
4 * Copyright (C) 2003 SAN People
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 */
12#include <asm/mach-types.h>
13
14 .section ".start", "ax"
15
16 @ Atmel AT91RM9200-DK : 262
17 mov r3, #(MACH_TYPE_AT91RM9200DK & 0xff)
18 orr r3, r3, #(MACH_TYPE_AT91RM9200DK & 0xff00)
19 cmp r7, r3
20 beq 99f
21
22 @ Cogent CSB337 : 399
23 mov r3, #(MACH_TYPE_CSB337 & 0xff)
24 orr r3, r3, #(MACH_TYPE_CSB337 & 0xff00)
25 cmp r7, r3
26 beq 99f
27
28 @ Cogent CSB637 : 648
29 mov r3, #(MACH_TYPE_CSB637 & 0xff)
30 orr r3, r3, #(MACH_TYPE_CSB637 & 0xff00)
31 cmp r7, r3
32 beq 99f
33
34 @ Atmel AT91RM9200-EK : 705
35 mov r3, #(MACH_TYPE_AT91RM9200EK & 0xff)
36 orr r3, r3, #(MACH_TYPE_AT91RM9200EK & 0xff00)
37 cmp r7, r3
38 beq 99f
39
40 @ Conitec Carmeva : 769
41 mov r3, #(MACH_TYPE_CARMEVA & 0xff)
42 orr r3, r3, #(MACH_TYPE_CARMEVA & 0xff00)
43 cmp r7, r3
44 beq 99f
45
46 @ KwikByte KB920x : 612
47 mov r3, #(MACH_TYPE_KB9200 & 0xff)
48 orr r3, r3, #(MACH_TYPE_KB9200 & 0xff00)
49 cmp r7, r3
50 beq 99f
51
52 @ Embest ATEB9200 : 923
53 mov r3, #(MACH_TYPE_ATEB9200 & 0xff)
54 orr r3, r3, #(MACH_TYPE_ATEB9200 & 0xff00)
55 cmp r7, r3
56 beq 99f
57
58 @ Sperry-Sun KAFA : 662
59 mov r3, #(MACH_TYPE_KAFA & 0xff)
60 orr r3, r3, #(MACH_TYPE_KAFA & 0xff00)
61 cmp r7, r3
62 beq 99f
63
64 @ picotux 200 : 963
65 mov r3, #(MACH_TYPE_PICOTUX2XX & 0xff)
66 orr r3, r3, #(MACH_TYPE_PICOTUX2XX & 0xff00)
67 cmp r7, r3
68 beq 99f
69
70 @ Ajeco 1ARM : 1075
71 mov r3, #(MACH_TYPE_ONEARM & 0xff)
72 orr r3, r3, #(MACH_TYPE_ONEARM & 0xff00)
73 cmp r7, r3
74 beq 99f
75
76 @ Unknown board, use the AT91RM9200DK board
77 @ mov r7, #MACH_TYPE_AT91RM9200
78 mov r7, #(MACH_TYPE_AT91RM9200DK & 0xff)
79 orr r7, r7, #(MACH_TYPE_AT91RM9200DK & 0xff00)
80
8199:
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 5cac46a19bb7..3c2c8f2a1dc4 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -623,6 +623,12 @@ proc_types:
623 b __armv4_mmu_cache_off 623 b __armv4_mmu_cache_off
624 b __armv4_mmu_cache_flush 624 b __armv4_mmu_cache_flush
625 625
626 .word 0x56055310 @ Feroceon
627 .word 0xfffffff0
628 b __armv4_mmu_cache_on
629 b __armv4_mmu_cache_off
630 b __armv5tej_mmu_cache_flush
631
626 @ These match on the architecture ID 632 @ These match on the architecture ID
627 633
628 .word 0x00020000 @ ARMv4T 634 .word 0x00020000 @ ARMv4T
@@ -641,7 +647,7 @@ proc_types:
641 .word 0x000f0000 647 .word 0x000f0000
642 b __armv4_mmu_cache_on 648 b __armv4_mmu_cache_on
643 b __armv4_mmu_cache_off 649 b __armv4_mmu_cache_off
644 b __armv4_mmu_cache_flush 650 b __armv5tej_mmu_cache_flush
645 651
646 .word 0x0007b000 @ ARMv6 652 .word 0x0007b000 @ ARMv6
647 .word 0x000ff000 653 .word 0x000ff000
@@ -821,6 +827,13 @@ iflush:
821 mcr p15, 0, r10, c7, c10, 4 @ drain WB 827 mcr p15, 0, r10, c7, c10, 4 @ drain WB
822 mov pc, lr 828 mov pc, lr
823 829
830__armv5tej_mmu_cache_flush:
8311: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate D cache
832 bne 1b
833 mcr p15, 0, r0, c7, c5, 0 @ flush I cache
834 mcr p15, 0, r0, c7, c10, 4 @ drain WB
835 mov pc, lr
836
824__armv4_mmu_cache_flush: 837__armv4_mmu_cache_flush:
825 mov r2, #64*1024 @ default: 32K dcache size (*2) 838 mov r2, #64*1024 @ default: 32K dcache size (*2)
826 mov r11, #32 @ default: 32 byte line size 839 mov r11, #32 @ default: 32 byte line size
diff --git a/arch/arm/common/rtctime.c b/arch/arm/common/rtctime.c
index bf1075e1f571..f53bca46e23c 100644
--- a/arch/arm/common/rtctime.c
+++ b/arch/arm/common/rtctime.c
@@ -20,7 +20,6 @@
20#include <linux/capability.h> 20#include <linux/capability.h>
21#include <linux/device.h> 21#include <linux/device.h>
22#include <linux/mutex.h> 22#include <linux/mutex.h>
23#include <linux/rtc.h>
24 23
25#include <asm/rtc.h> 24#include <asm/rtc.h>
26#include <asm/semaphore.h> 25#include <asm/semaphore.h>
diff --git a/arch/arm/configs/at91cap9adk_defconfig b/arch/arm/configs/at91cap9adk_defconfig
new file mode 100644
index 000000000000..e32e73648129
--- /dev/null
+++ b/arch/arm/configs/at91cap9adk_defconfig
@@ -0,0 +1,1143 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.24-rc8
4# Wed Jan 23 22:55:57 2008
5#
6CONFIG_ARM=y
7CONFIG_SYS_SUPPORTS_APM_EMULATION=y
8CONFIG_GENERIC_GPIO=y
9# CONFIG_GENERIC_TIME is not set
10# CONFIG_GENERIC_CLOCKEVENTS is not set
11CONFIG_MMU=y
12# CONFIG_NO_IOPORT is not set
13CONFIG_GENERIC_HARDIRQS=y
14CONFIG_STACKTRACE_SUPPORT=y
15CONFIG_LOCKDEP_SUPPORT=y
16CONFIG_TRACE_IRQFLAGS_SUPPORT=y
17CONFIG_HARDIRQS_SW_RESEND=y
18CONFIG_GENERIC_IRQ_PROBE=y
19CONFIG_RWSEM_GENERIC_SPINLOCK=y
20# CONFIG_ARCH_HAS_ILOG2_U32 is not set
21# CONFIG_ARCH_HAS_ILOG2_U64 is not set
22CONFIG_GENERIC_HWEIGHT=y
23CONFIG_GENERIC_CALIBRATE_DELAY=y
24CONFIG_ZONE_DMA=y
25CONFIG_VECTORS_BASE=0xffff0000
26CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
27
28#
29# General setup
30#
31CONFIG_EXPERIMENTAL=y
32CONFIG_BROKEN_ON_SMP=y
33CONFIG_INIT_ENV_ARG_LIMIT=32
34CONFIG_LOCALVERSION=""
35# CONFIG_LOCALVERSION_AUTO is not set
36# CONFIG_SWAP is not set
37CONFIG_SYSVIPC=y
38CONFIG_SYSVIPC_SYSCTL=y
39# CONFIG_POSIX_MQUEUE is not set
40# CONFIG_BSD_PROCESS_ACCT is not set
41# CONFIG_TASKSTATS is not set
42# CONFIG_USER_NS is not set
43# CONFIG_PID_NS is not set
44# CONFIG_AUDIT is not set
45# CONFIG_IKCONFIG is not set
46CONFIG_LOG_BUF_SHIFT=14
47# CONFIG_CGROUPS is not set
48CONFIG_FAIR_GROUP_SCHED=y
49CONFIG_FAIR_USER_SCHED=y
50# CONFIG_FAIR_CGROUP_SCHED is not set
51CONFIG_SYSFS_DEPRECATED=y
52# CONFIG_RELAY is not set
53CONFIG_BLK_DEV_INITRD=y
54CONFIG_INITRAMFS_SOURCE=""
55CONFIG_CC_OPTIMIZE_FOR_SIZE=y
56CONFIG_SYSCTL=y
57# CONFIG_EMBEDDED is not set
58CONFIG_UID16=y
59CONFIG_SYSCTL_SYSCALL=y
60CONFIG_KALLSYMS=y
61# CONFIG_KALLSYMS_ALL is not set
62# CONFIG_KALLSYMS_EXTRA_PASS is not set
63CONFIG_HOTPLUG=y
64CONFIG_PRINTK=y
65CONFIG_BUG=y
66CONFIG_ELF_CORE=y
67CONFIG_BASE_FULL=y
68CONFIG_FUTEX=y
69CONFIG_ANON_INODES=y
70CONFIG_EPOLL=y
71CONFIG_SIGNALFD=y
72CONFIG_EVENTFD=y
73CONFIG_SHMEM=y
74CONFIG_VM_EVENT_COUNTERS=y
75CONFIG_SLAB=y
76# CONFIG_SLUB is not set
77# CONFIG_SLOB is not set
78CONFIG_SLABINFO=y
79CONFIG_RT_MUTEXES=y
80# CONFIG_TINY_SHMEM is not set
81CONFIG_BASE_SMALL=0
82CONFIG_MODULES=y
83CONFIG_MODULE_UNLOAD=y
84# CONFIG_MODULE_FORCE_UNLOAD is not set
85# CONFIG_MODVERSIONS is not set
86# CONFIG_MODULE_SRCVERSION_ALL is not set
87CONFIG_KMOD=y
88CONFIG_BLOCK=y
89# CONFIG_LBD is not set
90# CONFIG_BLK_DEV_IO_TRACE is not set
91# CONFIG_LSF is not set
92# CONFIG_BLK_DEV_BSG is not set
93
94#
95# IO Schedulers
96#
97CONFIG_IOSCHED_NOOP=y
98CONFIG_IOSCHED_AS=y
99# CONFIG_IOSCHED_DEADLINE is not set
100# CONFIG_IOSCHED_CFQ is not set
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"
106
107#
108# System Type
109#
110# CONFIG_ARCH_AAEC2000 is not set
111# CONFIG_ARCH_INTEGRATOR is not set
112# CONFIG_ARCH_REALVIEW is not set
113# CONFIG_ARCH_VERSATILE is not set
114CONFIG_ARCH_AT91=y
115# CONFIG_ARCH_CLPS7500 is not set
116# CONFIG_ARCH_CLPS711X is not set
117# CONFIG_ARCH_CO285 is not set
118# CONFIG_ARCH_EBSA110 is not set
119# CONFIG_ARCH_EP93XX is not set
120# CONFIG_ARCH_FOOTBRIDGE is not set
121# CONFIG_ARCH_NETX is not set
122# CONFIG_ARCH_H720X is not set
123# CONFIG_ARCH_IMX is not set
124# CONFIG_ARCH_IOP13XX is not set
125# CONFIG_ARCH_IOP32X is not set
126# CONFIG_ARCH_IOP33X is not set
127# CONFIG_ARCH_IXP23XX is not set
128# CONFIG_ARCH_IXP2000 is not set
129# CONFIG_ARCH_IXP4XX is not set
130# CONFIG_ARCH_L7200 is not set
131# CONFIG_ARCH_KS8695 is not set
132# CONFIG_ARCH_NS9XXX is not set
133# CONFIG_ARCH_MXC is not set
134# CONFIG_ARCH_PNX4008 is not set
135# CONFIG_ARCH_PXA is not set
136# CONFIG_ARCH_RPC is not set
137# CONFIG_ARCH_SA1100 is not set
138# CONFIG_ARCH_S3C2410 is not set
139# CONFIG_ARCH_SHARK is not set
140# CONFIG_ARCH_LH7A40X is not set
141# CONFIG_ARCH_DAVINCI is not set
142# CONFIG_ARCH_OMAP is not set
143
144#
145# Boot options
146#
147
148#
149# Power management
150#
151
152#
153# Atmel AT91 System-on-Chip
154#
155# CONFIG_ARCH_AT91RM9200 is not set
156# CONFIG_ARCH_AT91SAM9260 is not set
157# CONFIG_ARCH_AT91SAM9261 is not set
158# CONFIG_ARCH_AT91SAM9263 is not set
159# CONFIG_ARCH_AT91SAM9RL is not set
160CONFIG_ARCH_AT91CAP9=y
161# CONFIG_ARCH_AT91X40 is not set
162CONFIG_AT91_PMC_UNIT=y
163
164#
165# AT91CAP9 Board Type
166#
167CONFIG_MACH_AT91CAP9ADK=y
168
169#
170# AT91 Board Options
171#
172CONFIG_MTD_AT91_DATAFLASH_CARD=y
173# CONFIG_MTD_NAND_AT91_BUSWIDTH_16 is not set
174
175#
176# AT91 Feature Selections
177#
178CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
179CONFIG_AT91_TIMER_HZ=100
180
181#
182# Processor Type
183#
184CONFIG_CPU_32=y
185CONFIG_CPU_ARM926T=y
186CONFIG_CPU_32v5=y
187CONFIG_CPU_ABRT_EV5TJ=y
188CONFIG_CPU_CACHE_VIVT=y
189CONFIG_CPU_COPY_V4WB=y
190CONFIG_CPU_TLB_V4WBI=y
191CONFIG_CPU_CP15=y
192CONFIG_CPU_CP15_MMU=y
193
194#
195# Processor Features
196#
197# CONFIG_ARM_THUMB is not set
198# CONFIG_CPU_ICACHE_DISABLE is not set
199# CONFIG_CPU_DCACHE_DISABLE is not set
200# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
201# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
202# CONFIG_OUTER_CACHE is not set
203
204#
205# Bus support
206#
207# CONFIG_PCI_SYSCALL is not set
208# CONFIG_ARCH_SUPPORTS_MSI is not set
209# CONFIG_PCCARD is not set
210
211#
212# Kernel Features
213#
214# CONFIG_TICK_ONESHOT is not set
215# CONFIG_PREEMPT is not set
216# CONFIG_NO_IDLE_HZ is not set
217CONFIG_HZ=100
218CONFIG_AEABI=y
219CONFIG_OABI_COMPAT=y
220# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
221CONFIG_SELECT_MEMORY_MODEL=y
222CONFIG_FLATMEM_MANUAL=y
223# CONFIG_DISCONTIGMEM_MANUAL is not set
224# CONFIG_SPARSEMEM_MANUAL is not set
225CONFIG_FLATMEM=y
226CONFIG_FLAT_NODE_MEM_MAP=y
227# CONFIG_SPARSEMEM_STATIC is not set
228# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
229CONFIG_SPLIT_PTLOCK_CPUS=4096
230# CONFIG_RESOURCES_64BIT is not set
231CONFIG_ZONE_DMA_FLAG=1
232CONFIG_BOUNCE=y
233CONFIG_VIRT_TO_BUS=y
234CONFIG_LEDS=y
235CONFIG_LEDS_TIMER=y
236CONFIG_LEDS_CPU=y
237CONFIG_ALIGNMENT_TRAP=y
238
239#
240# Boot options
241#
242CONFIG_ZBOOT_ROM_TEXT=0x0
243CONFIG_ZBOOT_ROM_BSS=0x0
244CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/ram0 rw"
245# CONFIG_XIP_KERNEL is not set
246# CONFIG_KEXEC is not set
247
248#
249# Floating point emulation
250#
251
252#
253# At least one emulation must be selected
254#
255CONFIG_FPE_NWFPE=y
256# CONFIG_FPE_NWFPE_XP is not set
257# CONFIG_FPE_FASTFPE is not set
258# CONFIG_VFP is not set
259
260#
261# Userspace binary formats
262#
263CONFIG_BINFMT_ELF=y
264# CONFIG_BINFMT_AOUT is not set
265# CONFIG_BINFMT_MISC is not set
266
267#
268# Power management options
269#
270# CONFIG_PM is not set
271CONFIG_SUSPEND_UP_POSSIBLE=y
272
273#
274# Networking
275#
276CONFIG_NET=y
277
278#
279# Networking options
280#
281CONFIG_PACKET=y
282# CONFIG_PACKET_MMAP is not set
283CONFIG_UNIX=y
284# CONFIG_NET_KEY is not set
285CONFIG_INET=y
286# CONFIG_IP_MULTICAST is not set
287# CONFIG_IP_ADVANCED_ROUTER is not set
288CONFIG_IP_FIB_HASH=y
289CONFIG_IP_PNP=y
290# CONFIG_IP_PNP_DHCP is not set
291CONFIG_IP_PNP_BOOTP=y
292CONFIG_IP_PNP_RARP=y
293# CONFIG_NET_IPIP is not set
294# CONFIG_NET_IPGRE is not set
295# CONFIG_ARPD is not set
296# CONFIG_SYN_COOKIES is not set
297# CONFIG_INET_AH is not set
298# CONFIG_INET_ESP is not set
299# CONFIG_INET_IPCOMP is not set
300# CONFIG_INET_XFRM_TUNNEL is not set
301# CONFIG_INET_TUNNEL is not set
302# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
303# CONFIG_INET_XFRM_MODE_TUNNEL is not set
304# CONFIG_INET_XFRM_MODE_BEET is not set
305# CONFIG_INET_LRO is not set
306# CONFIG_INET_DIAG is not set
307# CONFIG_TCP_CONG_ADVANCED is not set
308CONFIG_TCP_CONG_CUBIC=y
309CONFIG_DEFAULT_TCP_CONG="cubic"
310# CONFIG_TCP_MD5SIG is not set
311# CONFIG_IPV6 is not set
312# CONFIG_INET6_XFRM_TUNNEL is not set
313# CONFIG_INET6_TUNNEL is not set
314# CONFIG_NETWORK_SECMARK is not set
315# CONFIG_NETFILTER is not set
316# CONFIG_IP_DCCP is not set
317# CONFIG_IP_SCTP is not set
318# CONFIG_TIPC is not set
319# CONFIG_ATM is not set
320# CONFIG_BRIDGE is not set
321# CONFIG_VLAN_8021Q is not set
322# CONFIG_DECNET is not set
323# CONFIG_LLC2 is not set
324# CONFIG_IPX is not set
325# CONFIG_ATALK is not set
326# CONFIG_X25 is not set
327# CONFIG_LAPB is not set
328# CONFIG_ECONET is not set
329# CONFIG_WAN_ROUTER is not set
330# CONFIG_NET_SCHED is not set
331
332#
333# Network testing
334#
335# CONFIG_NET_PKTGEN is not set
336# CONFIG_HAMRADIO is not set
337# CONFIG_IRDA is not set
338# CONFIG_BT is not set
339# CONFIG_AF_RXRPC is not set
340
341#
342# Wireless
343#
344# CONFIG_CFG80211 is not set
345# CONFIG_WIRELESS_EXT is not set
346# CONFIG_MAC80211 is not set
347# CONFIG_IEEE80211 is not set
348# CONFIG_RFKILL is not set
349# CONFIG_NET_9P is not set
350
351#
352# Device Drivers
353#
354
355#
356# Generic Driver Options
357#
358CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
359CONFIG_STANDALONE=y
360CONFIG_PREVENT_FIRMWARE_BUILD=y
361# CONFIG_FW_LOADER is not set
362# CONFIG_DEBUG_DRIVER is not set
363# CONFIG_DEBUG_DEVRES is not set
364# CONFIG_SYS_HYPERVISOR is not set
365# CONFIG_CONNECTOR is not set
366CONFIG_MTD=y
367# CONFIG_MTD_DEBUG is not set
368# CONFIG_MTD_CONCAT is not set
369CONFIG_MTD_PARTITIONS=y
370# CONFIG_MTD_REDBOOT_PARTS is not set
371CONFIG_MTD_CMDLINE_PARTS=y
372# CONFIG_MTD_AFS_PARTS is not set
373
374#
375# User Modules And Translation Layers
376#
377CONFIG_MTD_CHAR=y
378CONFIG_MTD_BLKDEVS=y
379CONFIG_MTD_BLOCK=y
380# CONFIG_FTL is not set
381# CONFIG_NFTL is not set
382# CONFIG_INFTL is not set
383# CONFIG_RFD_FTL is not set
384# CONFIG_SSFDC is not set
385# CONFIG_MTD_OOPS is not set
386
387#
388# RAM/ROM/Flash chip drivers
389#
390CONFIG_MTD_CFI=y
391CONFIG_MTD_JEDECPROBE=y
392CONFIG_MTD_GEN_PROBE=y
393# CONFIG_MTD_CFI_ADV_OPTIONS is not set
394CONFIG_MTD_MAP_BANK_WIDTH_1=y
395CONFIG_MTD_MAP_BANK_WIDTH_2=y
396CONFIG_MTD_MAP_BANK_WIDTH_4=y
397# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
398# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
399# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
400CONFIG_MTD_CFI_I1=y
401CONFIG_MTD_CFI_I2=y
402# CONFIG_MTD_CFI_I4 is not set
403# CONFIG_MTD_CFI_I8 is not set
404# CONFIG_MTD_CFI_INTELEXT is not set
405CONFIG_MTD_CFI_AMDSTD=y
406# CONFIG_MTD_CFI_STAA is not set
407CONFIG_MTD_CFI_UTIL=y
408# CONFIG_MTD_RAM is not set
409# CONFIG_MTD_ROM is not set
410# CONFIG_MTD_ABSENT is not set
411
412#
413# Mapping drivers for chip access
414#
415# CONFIG_MTD_COMPLEX_MAPPINGS is not set
416CONFIG_MTD_PHYSMAP=y
417CONFIG_MTD_PHYSMAP_START=0x0
418CONFIG_MTD_PHYSMAP_LEN=0x0
419CONFIG_MTD_PHYSMAP_BANKWIDTH=0
420# CONFIG_MTD_ARM_INTEGRATOR is not set
421# CONFIG_MTD_IMPA7 is not set
422# CONFIG_MTD_PLATRAM is not set
423
424#
425# Self-contained MTD device drivers
426#
427CONFIG_MTD_DATAFLASH=y
428# CONFIG_MTD_M25P80 is not set
429# CONFIG_MTD_SLRAM is not set
430# CONFIG_MTD_PHRAM is not set
431# CONFIG_MTD_MTDRAM is not set
432# CONFIG_MTD_BLOCK2MTD is not set
433
434#
435# Disk-On-Chip Device Drivers
436#
437# CONFIG_MTD_DOC2000 is not set
438# CONFIG_MTD_DOC2001 is not set
439# CONFIG_MTD_DOC2001PLUS is not set
440CONFIG_MTD_NAND=y
441# CONFIG_MTD_NAND_VERIFY_WRITE is not set
442# CONFIG_MTD_NAND_ECC_SMC is not set
443# CONFIG_MTD_NAND_MUSEUM_IDS is not set
444CONFIG_MTD_NAND_IDS=y
445# CONFIG_MTD_NAND_DISKONCHIP is not set
446CONFIG_MTD_NAND_AT91=y
447# CONFIG_MTD_NAND_NANDSIM is not set
448# CONFIG_MTD_NAND_PLATFORM is not set
449# CONFIG_MTD_ALAUDA is not set
450# CONFIG_MTD_ONENAND is not set
451
452#
453# UBI - Unsorted block images
454#
455# CONFIG_MTD_UBI is not set
456# CONFIG_PARPORT is not set
457CONFIG_BLK_DEV=y
458# CONFIG_BLK_DEV_COW_COMMON is not set
459CONFIG_BLK_DEV_LOOP=y
460# CONFIG_BLK_DEV_CRYPTOLOOP is not set
461# CONFIG_BLK_DEV_NBD is not set
462# CONFIG_BLK_DEV_UB is not set
463CONFIG_BLK_DEV_RAM=y
464CONFIG_BLK_DEV_RAM_COUNT=16
465CONFIG_BLK_DEV_RAM_SIZE=8192
466CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
467# CONFIG_CDROM_PKTCDVD is not set
468# CONFIG_ATA_OVER_ETH is not set
469CONFIG_MISC_DEVICES=y
470# CONFIG_EEPROM_93CX6 is not set
471CONFIG_ATMEL_SSC=y
472
473#
474# SCSI device support
475#
476# CONFIG_RAID_ATTRS is not set
477CONFIG_SCSI=y
478CONFIG_SCSI_DMA=y
479# CONFIG_SCSI_TGT is not set
480# CONFIG_SCSI_NETLINK is not set
481CONFIG_SCSI_PROC_FS=y
482
483#
484# SCSI support type (disk, tape, CD-ROM)
485#
486CONFIG_BLK_DEV_SD=y
487# CONFIG_CHR_DEV_ST is not set
488# CONFIG_CHR_DEV_OSST is not set
489# CONFIG_BLK_DEV_SR is not set
490# CONFIG_CHR_DEV_SG is not set
491# CONFIG_CHR_DEV_SCH is not set
492
493#
494# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
495#
496CONFIG_SCSI_MULTI_LUN=y
497# CONFIG_SCSI_CONSTANTS is not set
498# CONFIG_SCSI_LOGGING is not set
499# CONFIG_SCSI_SCAN_ASYNC is not set
500CONFIG_SCSI_WAIT_SCAN=m
501
502#
503# SCSI Transports
504#
505# CONFIG_SCSI_SPI_ATTRS is not set
506# CONFIG_SCSI_FC_ATTRS is not set
507# CONFIG_SCSI_ISCSI_ATTRS is not set
508# CONFIG_SCSI_SAS_LIBSAS is not set
509# CONFIG_SCSI_SRP_ATTRS is not set
510CONFIG_SCSI_LOWLEVEL=y
511# CONFIG_ISCSI_TCP is not set
512# CONFIG_SCSI_DEBUG is not set
513# CONFIG_ATA is not set
514# CONFIG_MD is not set
515CONFIG_NETDEVICES=y
516# CONFIG_NETDEVICES_MULTIQUEUE is not set
517# CONFIG_DUMMY is not set
518# CONFIG_BONDING is not set
519# CONFIG_MACVLAN is not set
520# CONFIG_EQUALIZER is not set
521# CONFIG_TUN is not set
522# CONFIG_VETH is not set
523CONFIG_PHYLIB=y
524
525#
526# MII PHY device drivers
527#
528# CONFIG_MARVELL_PHY is not set
529# CONFIG_DAVICOM_PHY is not set
530# CONFIG_QSEMI_PHY is not set
531# CONFIG_LXT_PHY is not set
532# CONFIG_CICADA_PHY is not set
533# CONFIG_VITESSE_PHY is not set
534# CONFIG_SMSC_PHY is not set
535# CONFIG_BROADCOM_PHY is not set
536# CONFIG_ICPLUS_PHY is not set
537# CONFIG_FIXED_PHY is not set
538# CONFIG_MDIO_BITBANG is not set
539CONFIG_NET_ETHERNET=y
540CONFIG_MII=y
541CONFIG_MACB=y
542# CONFIG_AX88796 is not set
543# CONFIG_SMC91X is not set
544# CONFIG_DM9000 is not set
545# CONFIG_IBM_NEW_EMAC_ZMII is not set
546# CONFIG_IBM_NEW_EMAC_RGMII is not set
547# CONFIG_IBM_NEW_EMAC_TAH is not set
548# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
549# CONFIG_B44 is not set
550# CONFIG_NETDEV_1000 is not set
551# CONFIG_NETDEV_10000 is not set
552
553#
554# Wireless LAN
555#
556# CONFIG_WLAN_PRE80211 is not set
557# CONFIG_WLAN_80211 is not set
558
559#
560# USB Network Adapters
561#
562# CONFIG_USB_CATC is not set
563# CONFIG_USB_KAWETH is not set
564# CONFIG_USB_PEGASUS is not set
565# CONFIG_USB_RTL8150 is not set
566# CONFIG_USB_USBNET is not set
567# CONFIG_WAN is not set
568# CONFIG_PPP is not set
569# CONFIG_SLIP is not set
570# CONFIG_SHAPER is not set
571# CONFIG_NETCONSOLE is not set
572# CONFIG_NETPOLL is not set
573# CONFIG_NET_POLL_CONTROLLER is not set
574# CONFIG_ISDN is not set
575
576#
577# Input device support
578#
579CONFIG_INPUT=y
580# CONFIG_INPUT_FF_MEMLESS is not set
581# CONFIG_INPUT_POLLDEV is not set
582
583#
584# Userland interfaces
585#
586CONFIG_INPUT_MOUSEDEV=y
587# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
588CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
589CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
590# CONFIG_INPUT_JOYDEV is not set
591CONFIG_INPUT_EVDEV=y
592# CONFIG_INPUT_EVBUG is not set
593
594#
595# Input Device Drivers
596#
597# CONFIG_INPUT_KEYBOARD is not set
598# CONFIG_INPUT_MOUSE is not set
599# CONFIG_INPUT_JOYSTICK is not set
600# CONFIG_INPUT_TABLET is not set
601CONFIG_INPUT_TOUCHSCREEN=y
602CONFIG_TOUCHSCREEN_ADS7846=y
603# CONFIG_TOUCHSCREEN_FUJITSU is not set
604# CONFIG_TOUCHSCREEN_GUNZE is not set
605# CONFIG_TOUCHSCREEN_ELO is not set
606# CONFIG_TOUCHSCREEN_MTOUCH is not set
607# CONFIG_TOUCHSCREEN_MK712 is not set
608# CONFIG_TOUCHSCREEN_PENMOUNT is not set
609# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
610# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
611# CONFIG_TOUCHSCREEN_UCB1400 is not set
612# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
613# CONFIG_INPUT_MISC is not set
614
615#
616# Hardware I/O ports
617#
618# CONFIG_SERIO is not set
619# CONFIG_GAMEPORT is not set
620
621#
622# Character devices
623#
624CONFIG_VT=y
625CONFIG_VT_CONSOLE=y
626CONFIG_HW_CONSOLE=y
627# CONFIG_VT_HW_CONSOLE_BINDING is not set
628# CONFIG_SERIAL_NONSTANDARD is not set
629
630#
631# Serial drivers
632#
633# CONFIG_SERIAL_8250 is not set
634
635#
636# Non-8250 serial port support
637#
638CONFIG_SERIAL_ATMEL=y
639CONFIG_SERIAL_ATMEL_CONSOLE=y
640# CONFIG_SERIAL_ATMEL_TTYAT is not set
641CONFIG_SERIAL_CORE=y
642CONFIG_SERIAL_CORE_CONSOLE=y
643CONFIG_UNIX98_PTYS=y
644CONFIG_LEGACY_PTYS=y
645CONFIG_LEGACY_PTY_COUNT=256
646# CONFIG_IPMI_HANDLER is not set
647CONFIG_HW_RANDOM=y
648# CONFIG_NVRAM is not set
649# CONFIG_R3964 is not set
650# CONFIG_RAW_DRIVER is not set
651# CONFIG_TCG_TPM is not set
652CONFIG_I2C=y
653CONFIG_I2C_BOARDINFO=y
654CONFIG_I2C_CHARDEV=y
655
656#
657# I2C Algorithms
658#
659# CONFIG_I2C_ALGOBIT is not set
660# CONFIG_I2C_ALGOPCF is not set
661# CONFIG_I2C_ALGOPCA is not set
662
663#
664# I2C Hardware Bus support
665#
666# CONFIG_I2C_GPIO is not set
667# CONFIG_I2C_OCORES is not set
668# CONFIG_I2C_PARPORT_LIGHT is not set
669# CONFIG_I2C_SIMTEC is not set
670# CONFIG_I2C_TAOS_EVM is not set
671# CONFIG_I2C_STUB is not set
672# CONFIG_I2C_TINY_USB is not set
673
674#
675# Miscellaneous I2C Chip support
676#
677# CONFIG_SENSORS_DS1337 is not set
678# CONFIG_SENSORS_DS1374 is not set
679# CONFIG_DS1682 is not set
680# CONFIG_SENSORS_EEPROM is not set
681# CONFIG_SENSORS_PCF8574 is not set
682# CONFIG_SENSORS_PCA9539 is not set
683# CONFIG_SENSORS_PCF8591 is not set
684# CONFIG_SENSORS_MAX6875 is not set
685# CONFIG_SENSORS_TSL2550 is not set
686# CONFIG_I2C_DEBUG_CORE is not set
687# CONFIG_I2C_DEBUG_ALGO is not set
688# CONFIG_I2C_DEBUG_BUS is not set
689# CONFIG_I2C_DEBUG_CHIP is not set
690
691#
692# SPI support
693#
694CONFIG_SPI=y
695# CONFIG_SPI_DEBUG is not set
696CONFIG_SPI_MASTER=y
697
698#
699# SPI Master Controller Drivers
700#
701CONFIG_SPI_ATMEL=y
702# CONFIG_SPI_BITBANG is not set
703
704#
705# SPI Protocol Masters
706#
707# CONFIG_SPI_AT25 is not set
708# CONFIG_SPI_SPIDEV is not set
709# CONFIG_SPI_TLE62X0 is not set
710# CONFIG_W1 is not set
711# CONFIG_POWER_SUPPLY is not set
712# CONFIG_HWMON is not set
713CONFIG_WATCHDOG=y
714CONFIG_WATCHDOG_NOWAYOUT=y
715
716#
717# Watchdog Device Drivers
718#
719# CONFIG_SOFT_WATCHDOG is not set
720
721#
722# USB-based Watchdog Cards
723#
724# CONFIG_USBPCWATCHDOG is not set
725
726#
727# Sonics Silicon Backplane
728#
729CONFIG_SSB_POSSIBLE=y
730# CONFIG_SSB is not set
731
732#
733# Multifunction device drivers
734#
735# CONFIG_MFD_SM501 is not set
736
737#
738# Multimedia devices
739#
740# CONFIG_VIDEO_DEV is not set
741# CONFIG_DVB_CORE is not set
742# CONFIG_DAB is not set
743
744#
745# Graphics support
746#
747# CONFIG_VGASTATE is not set
748# CONFIG_VIDEO_OUTPUT_CONTROL is not set
749CONFIG_FB=y
750# CONFIG_FIRMWARE_EDID is not set
751# CONFIG_FB_DDC is not set
752CONFIG_FB_CFB_FILLRECT=y
753CONFIG_FB_CFB_COPYAREA=y
754CONFIG_FB_CFB_IMAGEBLIT=y
755# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
756# CONFIG_FB_SYS_FILLRECT is not set
757# CONFIG_FB_SYS_COPYAREA is not set
758# CONFIG_FB_SYS_IMAGEBLIT is not set
759# CONFIG_FB_SYS_FOPS is not set
760CONFIG_FB_DEFERRED_IO=y
761# CONFIG_FB_SVGALIB is not set
762# CONFIG_FB_MACMODES is not set
763# CONFIG_FB_BACKLIGHT is not set
764# CONFIG_FB_MODE_HELPERS is not set
765# CONFIG_FB_TILEBLITTING is not set
766
767#
768# Frame buffer hardware drivers
769#
770# CONFIG_FB_S1D13XXX is not set
771CONFIG_FB_ATMEL=y
772# CONFIG_FB_VIRTUAL is not set
773# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
774
775#
776# Display device support
777#
778# CONFIG_DISPLAY_SUPPORT is not set
779
780#
781# Console display driver support
782#
783# CONFIG_VGA_CONSOLE is not set
784CONFIG_DUMMY_CONSOLE=y
785# CONFIG_FRAMEBUFFER_CONSOLE is not set
786CONFIG_LOGO=y
787# CONFIG_LOGO_LINUX_MONO is not set
788CONFIG_LOGO_LINUX_VGA16=y
789# CONFIG_LOGO_LINUX_CLUT224 is not set
790
791#
792# Sound
793#
794# CONFIG_SOUND is not set
795CONFIG_HID_SUPPORT=y
796CONFIG_HID=y
797CONFIG_HID_DEBUG=y
798# CONFIG_HIDRAW is not set
799
800#
801# USB Input Devices
802#
803# CONFIG_USB_HID is not set
804
805#
806# USB HID Boot Protocol drivers
807#
808# CONFIG_USB_KBD is not set
809# CONFIG_USB_MOUSE is not set
810CONFIG_USB_SUPPORT=y
811CONFIG_USB_ARCH_HAS_HCD=y
812CONFIG_USB_ARCH_HAS_OHCI=y
813# CONFIG_USB_ARCH_HAS_EHCI is not set
814CONFIG_USB=y
815# CONFIG_USB_DEBUG is not set
816
817#
818# Miscellaneous USB options
819#
820CONFIG_USB_DEVICEFS=y
821CONFIG_USB_DEVICE_CLASS=y
822# CONFIG_USB_DYNAMIC_MINORS is not set
823# CONFIG_USB_OTG is not set
824
825#
826# USB Host Controller Drivers
827#
828# CONFIG_USB_ISP116X_HCD is not set
829CONFIG_USB_OHCI_HCD=y
830# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
831# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
832CONFIG_USB_OHCI_LITTLE_ENDIAN=y
833# CONFIG_USB_SL811_HCD is not set
834# CONFIG_USB_R8A66597_HCD is not set
835
836#
837# USB Device Class drivers
838#
839# CONFIG_USB_ACM is not set
840# CONFIG_USB_PRINTER is not set
841
842#
843# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
844#
845
846#
847# may also be needed; see USB_STORAGE Help for more information
848#
849CONFIG_USB_STORAGE=y
850# CONFIG_USB_STORAGE_DEBUG is not set
851# CONFIG_USB_STORAGE_DATAFAB is not set
852# CONFIG_USB_STORAGE_FREECOM is not set
853# CONFIG_USB_STORAGE_ISD200 is not set
854# CONFIG_USB_STORAGE_DPCM is not set
855# CONFIG_USB_STORAGE_USBAT is not set
856# CONFIG_USB_STORAGE_SDDR09 is not set
857# CONFIG_USB_STORAGE_SDDR55 is not set
858# CONFIG_USB_STORAGE_JUMPSHOT is not set
859# CONFIG_USB_STORAGE_ALAUDA is not set
860# CONFIG_USB_STORAGE_ONETOUCH is not set
861# CONFIG_USB_STORAGE_KARMA is not set
862# CONFIG_USB_LIBUSUAL is not set
863
864#
865# USB Imaging devices
866#
867# CONFIG_USB_MDC800 is not set
868# CONFIG_USB_MICROTEK is not set
869CONFIG_USB_MON=y
870
871#
872# USB port drivers
873#
874
875#
876# USB Serial Converter support
877#
878# CONFIG_USB_SERIAL is not set
879
880#
881# USB Miscellaneous drivers
882#
883# CONFIG_USB_EMI62 is not set
884# CONFIG_USB_EMI26 is not set
885# CONFIG_USB_ADUTUX is not set
886# CONFIG_USB_AUERSWALD is not set
887# CONFIG_USB_RIO500 is not set
888# CONFIG_USB_LEGOTOWER is not set
889# CONFIG_USB_LCD is not set
890# CONFIG_USB_BERRY_CHARGE is not set
891# CONFIG_USB_LED is not set
892# CONFIG_USB_CYPRESS_CY7C63 is not set
893# CONFIG_USB_CYTHERM is not set
894# CONFIG_USB_PHIDGET is not set
895# CONFIG_USB_IDMOUSE is not set
896# CONFIG_USB_FTDI_ELAN is not set
897# CONFIG_USB_APPLEDISPLAY is not set
898# CONFIG_USB_LD is not set
899# CONFIG_USB_TRANCEVIBRATOR is not set
900# CONFIG_USB_IOWARRIOR is not set
901# CONFIG_USB_TEST is not set
902
903#
904# USB DSL modem support
905#
906
907#
908# USB Gadget Support
909#
910# CONFIG_USB_GADGET is not set
911CONFIG_MMC=y
912# CONFIG_MMC_DEBUG is not set
913# CONFIG_MMC_UNSAFE_RESUME is not set
914
915#
916# MMC/SD Card Drivers
917#
918CONFIG_MMC_BLOCK=y
919CONFIG_MMC_BLOCK_BOUNCE=y
920# CONFIG_SDIO_UART is not set
921
922#
923# MMC/SD Host Controller Drivers
924#
925CONFIG_MMC_AT91=y
926# CONFIG_MMC_SPI is not set
927# CONFIG_NEW_LEDS is not set
928CONFIG_RTC_LIB=y
929# CONFIG_RTC_CLASS is not set
930
931#
932# File systems
933#
934CONFIG_EXT2_FS=y
935# CONFIG_EXT2_FS_XATTR is not set
936# CONFIG_EXT2_FS_XIP is not set
937# CONFIG_EXT3_FS is not set
938# CONFIG_EXT4DEV_FS is not set
939# CONFIG_REISERFS_FS is not set
940# CONFIG_JFS_FS is not set
941# CONFIG_FS_POSIX_ACL is not set
942# CONFIG_XFS_FS is not set
943# CONFIG_GFS2_FS is not set
944# CONFIG_OCFS2_FS is not set
945# CONFIG_MINIX_FS is not set
946# CONFIG_ROMFS_FS is not set
947CONFIG_INOTIFY=y
948CONFIG_INOTIFY_USER=y
949# CONFIG_QUOTA is not set
950CONFIG_DNOTIFY=y
951# CONFIG_AUTOFS_FS is not set
952# CONFIG_AUTOFS4_FS is not set
953# CONFIG_FUSE_FS is not set
954
955#
956# CD-ROM/DVD Filesystems
957#
958# CONFIG_ISO9660_FS is not set
959# CONFIG_UDF_FS is not set
960
961#
962# DOS/FAT/NT Filesystems
963#
964CONFIG_FAT_FS=y
965# CONFIG_MSDOS_FS is not set
966CONFIG_VFAT_FS=y
967CONFIG_FAT_DEFAULT_CODEPAGE=437
968CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
969# CONFIG_NTFS_FS is not set
970
971#
972# Pseudo filesystems
973#
974CONFIG_PROC_FS=y
975CONFIG_PROC_SYSCTL=y
976CONFIG_SYSFS=y
977CONFIG_TMPFS=y
978# CONFIG_TMPFS_POSIX_ACL is not set
979# CONFIG_HUGETLB_PAGE is not set
980# CONFIG_CONFIGFS_FS is not set
981
982#
983# Miscellaneous filesystems
984#
985# CONFIG_ADFS_FS is not set
986# CONFIG_AFFS_FS is not set
987# CONFIG_HFS_FS is not set
988# CONFIG_HFSPLUS_FS is not set
989# CONFIG_BEFS_FS is not set
990# CONFIG_BFS_FS is not set
991# CONFIG_EFS_FS is not set
992CONFIG_JFFS2_FS=y
993CONFIG_JFFS2_FS_DEBUG=0
994CONFIG_JFFS2_FS_WRITEBUFFER=y
995# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
996# CONFIG_JFFS2_SUMMARY is not set
997# CONFIG_JFFS2_FS_XATTR is not set
998# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
999CONFIG_JFFS2_ZLIB=y
1000# CONFIG_JFFS2_LZO is not set
1001CONFIG_JFFS2_RTIME=y
1002# CONFIG_JFFS2_RUBIN is not set
1003CONFIG_CRAMFS=y
1004# CONFIG_VXFS_FS is not set
1005# CONFIG_HPFS_FS is not set
1006# CONFIG_QNX4FS_FS is not set
1007# CONFIG_SYSV_FS is not set
1008# CONFIG_UFS_FS is not set
1009CONFIG_NETWORK_FILESYSTEMS=y
1010CONFIG_NFS_FS=y
1011# CONFIG_NFS_V3 is not set
1012# CONFIG_NFS_V4 is not set
1013# CONFIG_NFS_DIRECTIO is not set
1014# CONFIG_NFSD is not set
1015CONFIG_ROOT_NFS=y
1016CONFIG_LOCKD=y
1017CONFIG_NFS_COMMON=y
1018CONFIG_SUNRPC=y
1019# CONFIG_SUNRPC_BIND34 is not set
1020# CONFIG_RPCSEC_GSS_KRB5 is not set
1021# CONFIG_RPCSEC_GSS_SPKM3 is not set
1022# CONFIG_SMB_FS is not set
1023# CONFIG_CIFS is not set
1024# CONFIG_NCP_FS is not set
1025# CONFIG_CODA_FS is not set
1026# CONFIG_AFS_FS is not set
1027
1028#
1029# Partition Types
1030#
1031# CONFIG_PARTITION_ADVANCED is not set
1032CONFIG_MSDOS_PARTITION=y
1033CONFIG_NLS=y
1034CONFIG_NLS_DEFAULT="iso8859-1"
1035CONFIG_NLS_CODEPAGE_437=y
1036# CONFIG_NLS_CODEPAGE_737 is not set
1037# CONFIG_NLS_CODEPAGE_775 is not set
1038CONFIG_NLS_CODEPAGE_850=y
1039# CONFIG_NLS_CODEPAGE_852 is not set
1040# CONFIG_NLS_CODEPAGE_855 is not set
1041# CONFIG_NLS_CODEPAGE_857 is not set
1042# CONFIG_NLS_CODEPAGE_860 is not set
1043# CONFIG_NLS_CODEPAGE_861 is not set
1044# CONFIG_NLS_CODEPAGE_862 is not set
1045# CONFIG_NLS_CODEPAGE_863 is not set
1046# CONFIG_NLS_CODEPAGE_864 is not set
1047# CONFIG_NLS_CODEPAGE_865 is not set
1048# CONFIG_NLS_CODEPAGE_866 is not set
1049# CONFIG_NLS_CODEPAGE_869 is not set
1050# CONFIG_NLS_CODEPAGE_936 is not set
1051# CONFIG_NLS_CODEPAGE_950 is not set
1052# CONFIG_NLS_CODEPAGE_932 is not set
1053# CONFIG_NLS_CODEPAGE_949 is not set
1054# CONFIG_NLS_CODEPAGE_874 is not set
1055# CONFIG_NLS_ISO8859_8 is not set
1056# CONFIG_NLS_CODEPAGE_1250 is not set
1057# CONFIG_NLS_CODEPAGE_1251 is not set
1058# CONFIG_NLS_ASCII is not set
1059CONFIG_NLS_ISO8859_1=y
1060# CONFIG_NLS_ISO8859_2 is not set
1061# CONFIG_NLS_ISO8859_3 is not set
1062# CONFIG_NLS_ISO8859_4 is not set
1063# CONFIG_NLS_ISO8859_5 is not set
1064# CONFIG_NLS_ISO8859_6 is not set
1065# CONFIG_NLS_ISO8859_7 is not set
1066# CONFIG_NLS_ISO8859_9 is not set
1067# CONFIG_NLS_ISO8859_13 is not set
1068# CONFIG_NLS_ISO8859_14 is not set
1069# CONFIG_NLS_ISO8859_15 is not set
1070# CONFIG_NLS_KOI8_R is not set
1071# CONFIG_NLS_KOI8_U is not set
1072# CONFIG_NLS_UTF8 is not set
1073# CONFIG_DLM is not set
1074CONFIG_INSTRUMENTATION=y
1075# CONFIG_PROFILING is not set
1076# CONFIG_MARKERS is not set
1077
1078#
1079# Kernel hacking
1080#
1081# CONFIG_PRINTK_TIME is not set
1082CONFIG_ENABLE_WARN_DEPRECATED=y
1083CONFIG_ENABLE_MUST_CHECK=y
1084# CONFIG_MAGIC_SYSRQ is not set
1085# CONFIG_UNUSED_SYMBOLS is not set
1086CONFIG_DEBUG_FS=y
1087# CONFIG_HEADERS_CHECK is not set
1088CONFIG_DEBUG_KERNEL=y
1089# CONFIG_DEBUG_SHIRQ is not set
1090CONFIG_DETECT_SOFTLOCKUP=y
1091CONFIG_SCHED_DEBUG=y
1092# CONFIG_SCHEDSTATS is not set
1093# CONFIG_TIMER_STATS is not set
1094# CONFIG_DEBUG_SLAB is not set
1095# CONFIG_DEBUG_RT_MUTEXES is not set
1096# CONFIG_RT_MUTEX_TESTER is not set
1097# CONFIG_DEBUG_SPINLOCK is not set
1098# CONFIG_DEBUG_MUTEXES is not set
1099# CONFIG_DEBUG_LOCK_ALLOC is not set
1100# CONFIG_PROVE_LOCKING is not set
1101# CONFIG_LOCK_STAT is not set
1102# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1103# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
1104# CONFIG_DEBUG_KOBJECT is not set
1105CONFIG_DEBUG_BUGVERBOSE=y
1106CONFIG_DEBUG_INFO=y
1107# CONFIG_DEBUG_VM is not set
1108# CONFIG_DEBUG_LIST is not set
1109# CONFIG_DEBUG_SG is not set
1110CONFIG_FRAME_POINTER=y
1111CONFIG_FORCED_INLINING=y
1112# CONFIG_BOOT_PRINTK_DELAY is not set
1113# CONFIG_RCU_TORTURE_TEST is not set
1114# CONFIG_FAULT_INJECTION is not set
1115# CONFIG_SAMPLES is not set
1116CONFIG_DEBUG_USER=y
1117# CONFIG_DEBUG_ERRORS is not set
1118# CONFIG_DEBUG_LL is not set
1119
1120#
1121# Security options
1122#
1123# CONFIG_KEYS is not set
1124# CONFIG_SECURITY is not set
1125# CONFIG_SECURITY_FILE_CAPABILITIES is not set
1126# CONFIG_CRYPTO is not set
1127
1128#
1129# Library routines
1130#
1131CONFIG_BITREVERSE=y
1132# CONFIG_CRC_CCITT is not set
1133# CONFIG_CRC16 is not set
1134# CONFIG_CRC_ITU_T is not set
1135CONFIG_CRC32=y
1136# CONFIG_CRC7 is not set
1137# CONFIG_LIBCRC32C is not set
1138CONFIG_ZLIB_INFLATE=y
1139CONFIG_ZLIB_DEFLATE=y
1140CONFIG_PLIST=y
1141CONFIG_HAS_IOMEM=y
1142CONFIG_HAS_IOPORT=y
1143CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/colibri_defconfig b/arch/arm/configs/colibri_defconfig
new file mode 100644
index 000000000000..c3e3418ed4fe
--- /dev/null
+++ b/arch/arm/configs/colibri_defconfig
@@ -0,0 +1,1481 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.24-rc3
4# Mon Dec 3 13:36:09 2007
5#
6CONFIG_ARM=y
7CONFIG_SYS_SUPPORTS_APM_EMULATION=y
8CONFIG_GENERIC_GPIO=y
9CONFIG_GENERIC_TIME=y
10CONFIG_GENERIC_CLOCKEVENTS=y
11CONFIG_MMU=y
12# CONFIG_NO_IOPORT is not set
13CONFIG_GENERIC_HARDIRQS=y
14CONFIG_STACKTRACE_SUPPORT=y
15CONFIG_LOCKDEP_SUPPORT=y
16CONFIG_TRACE_IRQFLAGS_SUPPORT=y
17CONFIG_HARDIRQS_SW_RESEND=y
18CONFIG_GENERIC_IRQ_PROBE=y
19CONFIG_RWSEM_GENERIC_SPINLOCK=y
20# CONFIG_ARCH_HAS_ILOG2_U32 is not set
21# CONFIG_ARCH_HAS_ILOG2_U64 is not set
22CONFIG_GENERIC_HWEIGHT=y
23CONFIG_GENERIC_CALIBRATE_DELAY=y
24CONFIG_ZONE_DMA=y
25CONFIG_ARCH_MTD_XIP=y
26CONFIG_VECTORS_BASE=0xffff0000
27CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
28
29#
30# General setup
31#
32CONFIG_EXPERIMENTAL=y
33CONFIG_BROKEN_ON_SMP=y
34CONFIG_LOCK_KERNEL=y
35CONFIG_INIT_ENV_ARG_LIMIT=32
36CONFIG_LOCALVERSION=""
37CONFIG_LOCALVERSION_AUTO=y
38CONFIG_SWAP=y
39CONFIG_SYSVIPC=y
40CONFIG_SYSVIPC_SYSCTL=y
41CONFIG_POSIX_MQUEUE=y
42CONFIG_BSD_PROCESS_ACCT=y
43CONFIG_BSD_PROCESS_ACCT_V3=y
44# CONFIG_TASKSTATS is not set
45# CONFIG_USER_NS is not set
46# CONFIG_PID_NS is not set
47# CONFIG_AUDIT is not set
48CONFIG_IKCONFIG=y
49CONFIG_IKCONFIG_PROC=y
50CONFIG_LOG_BUF_SHIFT=14
51# CONFIG_CGROUPS is not set
52CONFIG_FAIR_GROUP_SCHED=y
53CONFIG_FAIR_USER_SCHED=y
54# CONFIG_FAIR_CGROUP_SCHED is not set
55CONFIG_SYSFS_DEPRECATED=y
56# CONFIG_RELAY is not set
57CONFIG_BLK_DEV_INITRD=y
58CONFIG_INITRAMFS_SOURCE=""
59CONFIG_CC_OPTIMIZE_FOR_SIZE=y
60CONFIG_SYSCTL=y
61CONFIG_EMBEDDED=y
62CONFIG_UID16=y
63CONFIG_SYSCTL_SYSCALL=y
64CONFIG_KALLSYMS=y
65# CONFIG_KALLSYMS_ALL is not set
66CONFIG_KALLSYMS_EXTRA_PASS=y
67CONFIG_HOTPLUG=y
68CONFIG_PRINTK=y
69CONFIG_BUG=y
70CONFIG_ELF_CORE=y
71CONFIG_BASE_FULL=y
72CONFIG_FUTEX=y
73CONFIG_ANON_INODES=y
74CONFIG_EPOLL=y
75CONFIG_SIGNALFD=y
76CONFIG_EVENTFD=y
77CONFIG_SHMEM=y
78CONFIG_VM_EVENT_COUNTERS=y
79CONFIG_SLAB=y
80# CONFIG_SLUB is not set
81# CONFIG_SLOB is not set
82CONFIG_RT_MUTEXES=y
83# CONFIG_TINY_SHMEM is not set
84CONFIG_BASE_SMALL=0
85CONFIG_MODULES=y
86CONFIG_MODULE_UNLOAD=y
87CONFIG_MODULE_FORCE_UNLOAD=y
88CONFIG_MODVERSIONS=y
89CONFIG_MODULE_SRCVERSION_ALL=y
90CONFIG_KMOD=y
91CONFIG_BLOCK=y
92CONFIG_LBD=y
93# CONFIG_BLK_DEV_IO_TRACE is not set
94CONFIG_LSF=y
95# CONFIG_BLK_DEV_BSG is not set
96
97#
98# IO Schedulers
99#
100CONFIG_IOSCHED_NOOP=y
101CONFIG_IOSCHED_AS=y
102CONFIG_IOSCHED_DEADLINE=y
103CONFIG_IOSCHED_CFQ=y
104CONFIG_DEFAULT_AS=y
105# CONFIG_DEFAULT_DEADLINE is not set
106# CONFIG_DEFAULT_CFQ is not set
107# CONFIG_DEFAULT_NOOP is not set
108CONFIG_DEFAULT_IOSCHED="anticipatory"
109
110#
111# System Type
112#
113# CONFIG_ARCH_AAEC2000 is not set
114# CONFIG_ARCH_INTEGRATOR is not set
115# CONFIG_ARCH_REALVIEW is not set
116# CONFIG_ARCH_VERSATILE is not set
117# CONFIG_ARCH_AT91 is not set
118# CONFIG_ARCH_CLPS7500 is not set
119# CONFIG_ARCH_CLPS711X is not set
120# CONFIG_ARCH_CO285 is not set
121# CONFIG_ARCH_EBSA110 is not set
122# CONFIG_ARCH_EP93XX is not set
123# CONFIG_ARCH_FOOTBRIDGE is not set
124# CONFIG_ARCH_NETX is not set
125# CONFIG_ARCH_H720X is not set
126# CONFIG_ARCH_IMX is not set
127# CONFIG_ARCH_IOP13XX is not set
128# CONFIG_ARCH_IOP32X is not set
129# CONFIG_ARCH_IOP33X is not set
130# CONFIG_ARCH_IXP23XX is not set
131# CONFIG_ARCH_IXP2000 is not set
132# CONFIG_ARCH_IXP4XX is not set
133# CONFIG_ARCH_L7200 is not set
134# CONFIG_ARCH_KS8695 is not set
135# CONFIG_ARCH_NS9XXX is not set
136# CONFIG_ARCH_MXC is not set
137# CONFIG_ARCH_PNX4008 is not set
138CONFIG_ARCH_PXA=y
139# CONFIG_ARCH_RPC is not set
140# CONFIG_ARCH_SA1100 is not set
141# CONFIG_ARCH_S3C2410 is not set
142# CONFIG_ARCH_SHARK is not set
143# CONFIG_ARCH_LH7A40X is not set
144# CONFIG_ARCH_DAVINCI is not set
145# CONFIG_ARCH_OMAP is not set
146
147#
148# Intel PXA2xx/PXA3xx Implementations
149#
150# CONFIG_ARCH_LUBBOCK is not set
151# CONFIG_MACH_LOGICPD_PXA270 is not set
152# CONFIG_MACH_MAINSTONE is not set
153# CONFIG_ARCH_PXA_IDP is not set
154# CONFIG_PXA_SHARPSL is not set
155# CONFIG_MACH_TRIZEPS4 is not set
156# CONFIG_MACH_EM_X270 is not set
157CONFIG_MACH_COLIBRI=y
158# CONFIG_MACH_ZYLONITE is not set
159# CONFIG_MACH_ARMCORE is not set
160CONFIG_PXA27x=y
161
162#
163# Boot options
164#
165
166#
167# Power management
168#
169
170#
171# Processor Type
172#
173CONFIG_CPU_32=y
174CONFIG_CPU_XSCALE=y
175CONFIG_CPU_32v5=y
176CONFIG_CPU_ABRT_EV5T=y
177CONFIG_CPU_CACHE_VIVT=y
178CONFIG_CPU_TLB_V4WBI=y
179CONFIG_CPU_CP15=y
180CONFIG_CPU_CP15_MMU=y
181
182#
183# Processor Features
184#
185CONFIG_ARM_THUMB=y
186# CONFIG_CPU_DCACHE_DISABLE is not set
187# CONFIG_OUTER_CACHE is not set
188CONFIG_IWMMXT=y
189CONFIG_XSCALE_PMU=y
190
191#
192# Bus support
193#
194# CONFIG_PCI_SYSCALL is not set
195# CONFIG_ARCH_SUPPORTS_MSI is not set
196# CONFIG_PCCARD is not set
197
198#
199# Kernel Features
200#
201# CONFIG_TICK_ONESHOT is not set
202# CONFIG_NO_HZ is not set
203# CONFIG_HIGH_RES_TIMERS is not set
204CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
205CONFIG_PREEMPT=y
206CONFIG_HZ=100
207CONFIG_AEABI=y
208CONFIG_OABI_COMPAT=y
209# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
210CONFIG_SELECT_MEMORY_MODEL=y
211CONFIG_FLATMEM_MANUAL=y
212# CONFIG_DISCONTIGMEM_MANUAL is not set
213# CONFIG_SPARSEMEM_MANUAL is not set
214CONFIG_FLATMEM=y
215CONFIG_FLAT_NODE_MEM_MAP=y
216# CONFIG_SPARSEMEM_STATIC is not set
217# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
218CONFIG_SPLIT_PTLOCK_CPUS=4096
219# CONFIG_RESOURCES_64BIT is not set
220CONFIG_ZONE_DMA_FLAG=1
221CONFIG_BOUNCE=y
222CONFIG_VIRT_TO_BUS=y
223CONFIG_ALIGNMENT_TRAP=y
224
225#
226# Boot options
227#
228CONFIG_ZBOOT_ROM_TEXT=0
229CONFIG_ZBOOT_ROM_BSS=0
230CONFIG_CMDLINE=""
231# CONFIG_XIP_KERNEL is not set
232# CONFIG_KEXEC is not set
233
234#
235# Floating point emulation
236#
237
238#
239# At least one emulation must be selected
240#
241CONFIG_FPE_NWFPE=y
242# CONFIG_FPE_NWFPE_XP is not set
243# CONFIG_FPE_FASTFPE is not set
244
245#
246# Userspace binary formats
247#
248CONFIG_BINFMT_ELF=y
249# CONFIG_BINFMT_AOUT is not set
250# CONFIG_BINFMT_MISC is not set
251
252#
253# Power management options
254#
255CONFIG_PM=y
256# CONFIG_PM_LEGACY is not set
257# CONFIG_PM_DEBUG is not set
258CONFIG_PM_SLEEP=y
259CONFIG_SUSPEND_UP_POSSIBLE=y
260CONFIG_SUSPEND=y
261# CONFIG_APM_EMULATION is not set
262
263#
264# Networking
265#
266CONFIG_NET=y
267
268#
269# Networking options
270#
271CONFIG_PACKET=y
272CONFIG_PACKET_MMAP=y
273CONFIG_UNIX=y
274CONFIG_XFRM=y
275CONFIG_XFRM_USER=m
276# CONFIG_XFRM_SUB_POLICY is not set
277# CONFIG_XFRM_MIGRATE is not set
278CONFIG_NET_KEY=y
279# CONFIG_NET_KEY_MIGRATE is not set
280CONFIG_INET=y
281# CONFIG_IP_MULTICAST is not set
282# CONFIG_IP_ADVANCED_ROUTER is not set
283CONFIG_IP_FIB_HASH=y
284CONFIG_IP_PNP=y
285CONFIG_IP_PNP_DHCP=y
286CONFIG_IP_PNP_BOOTP=y
287# CONFIG_IP_PNP_RARP is not set
288# CONFIG_NET_IPIP is not set
289# CONFIG_NET_IPGRE is not set
290# CONFIG_ARPD is not set
291# CONFIG_SYN_COOKIES is not set
292# CONFIG_INET_AH is not set
293# CONFIG_INET_ESP is not set
294# CONFIG_INET_IPCOMP is not set
295# CONFIG_INET_XFRM_TUNNEL is not set
296# CONFIG_INET_TUNNEL is not set
297CONFIG_INET_XFRM_MODE_TRANSPORT=y
298CONFIG_INET_XFRM_MODE_TUNNEL=y
299CONFIG_INET_XFRM_MODE_BEET=y
300# CONFIG_INET_LRO is not set
301CONFIG_INET_DIAG=y
302CONFIG_INET_TCP_DIAG=y
303# CONFIG_TCP_CONG_ADVANCED is not set
304CONFIG_TCP_CONG_CUBIC=y
305CONFIG_DEFAULT_TCP_CONG="cubic"
306# CONFIG_TCP_MD5SIG is not set
307# CONFIG_IP_VS is not set
308# CONFIG_IPV6 is not set
309# CONFIG_INET6_XFRM_TUNNEL is not set
310# CONFIG_INET6_TUNNEL is not set
311# CONFIG_NETLABEL is not set
312# CONFIG_NETWORK_SECMARK is not set
313CONFIG_NETFILTER=y
314# CONFIG_NETFILTER_DEBUG is not set
315
316#
317# Core Netfilter Configuration
318#
319# CONFIG_NETFILTER_NETLINK is not set
320# CONFIG_NF_CONNTRACK_ENABLED is not set
321# CONFIG_NF_CONNTRACK is not set
322# CONFIG_NETFILTER_XTABLES is not set
323
324#
325# IP: Netfilter Configuration
326#
327CONFIG_IP_NF_QUEUE=m
328# CONFIG_IP_NF_IPTABLES is not set
329# CONFIG_IP_NF_ARPTABLES is not set
330# CONFIG_IP_DCCP is not set
331# CONFIG_IP_SCTP is not set
332# CONFIG_TIPC is not set
333# CONFIG_ATM is not set
334# CONFIG_BRIDGE is not set
335CONFIG_VLAN_8021Q=m
336# CONFIG_DECNET is not set
337# CONFIG_LLC2 is not set
338# CONFIG_IPX is not set
339# CONFIG_ATALK is not set
340# CONFIG_X25 is not set
341# CONFIG_LAPB is not set
342# CONFIG_ECONET is not set
343# CONFIG_WAN_ROUTER is not set
344# CONFIG_NET_SCHED is not set
345
346#
347# Network testing
348#
349# CONFIG_NET_PKTGEN is not set
350# CONFIG_HAMRADIO is not set
351CONFIG_IRDA=m
352
353#
354# IrDA protocols
355#
356CONFIG_IRLAN=m
357CONFIG_IRCOMM=m
358CONFIG_IRDA_ULTRA=y
359
360#
361# IrDA options
362#
363CONFIG_IRDA_CACHE_LAST_LSAP=y
364CONFIG_IRDA_FAST_RR=y
365# CONFIG_IRDA_DEBUG is not set
366
367#
368# Infrared-port device drivers
369#
370
371#
372# SIR device drivers
373#
374CONFIG_IRTTY_SIR=m
375
376#
377# Dongle support
378#
379# CONFIG_DONGLE is not set
380# CONFIG_KINGSUN_DONGLE is not set
381# CONFIG_KSDAZZLE_DONGLE is not set
382# CONFIG_KS959_DONGLE is not set
383
384#
385# Old SIR device drivers
386#
387# CONFIG_IRPORT_SIR is not set
388
389#
390# Old Serial dongle support
391#
392
393#
394# FIR device drivers
395#
396# CONFIG_USB_IRDA is not set
397# CONFIG_SIGMATEL_FIR is not set
398# CONFIG_PXA_FICP is not set
399# CONFIG_MCS_FIR is not set
400CONFIG_BT=m
401CONFIG_BT_L2CAP=m
402CONFIG_BT_SCO=m
403CONFIG_BT_RFCOMM=m
404CONFIG_BT_RFCOMM_TTY=y
405CONFIG_BT_BNEP=m
406CONFIG_BT_BNEP_MC_FILTER=y
407CONFIG_BT_BNEP_PROTO_FILTER=y
408CONFIG_BT_HIDP=m
409
410#
411# Bluetooth device drivers
412#
413# CONFIG_BT_HCIUSB is not set
414# CONFIG_BT_HCIBTUSB is not set
415# CONFIG_BT_HCIBTSDIO is not set
416# CONFIG_BT_HCIUART is not set
417# CONFIG_BT_HCIBCM203X is not set
418# CONFIG_BT_HCIBPA10X is not set
419# CONFIG_BT_HCIBFUSB is not set
420# CONFIG_BT_HCIVHCI is not set
421# CONFIG_AF_RXRPC is not set
422
423#
424# Wireless
425#
426CONFIG_CFG80211=y
427CONFIG_NL80211=y
428CONFIG_WIRELESS_EXT=y
429# CONFIG_MAC80211 is not set
430CONFIG_IEEE80211=y
431# CONFIG_IEEE80211_DEBUG is not set
432CONFIG_IEEE80211_CRYPT_WEP=y
433CONFIG_IEEE80211_CRYPT_CCMP=m
434CONFIG_IEEE80211_CRYPT_TKIP=m
435CONFIG_IEEE80211_SOFTMAC=m
436# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
437# CONFIG_RFKILL is not set
438# CONFIG_NET_9P is not set
439
440#
441# Device Drivers
442#
443
444#
445# Generic Driver Options
446#
447CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
448CONFIG_STANDALONE=y
449CONFIG_PREVENT_FIRMWARE_BUILD=y
450CONFIG_FW_LOADER=y
451# CONFIG_DEBUG_DRIVER is not set
452# CONFIG_DEBUG_DEVRES is not set
453# CONFIG_SYS_HYPERVISOR is not set
454CONFIG_CONNECTOR=y
455CONFIG_PROC_EVENTS=y
456CONFIG_MTD=y
457# CONFIG_MTD_DEBUG is not set
458CONFIG_MTD_CONCAT=y
459CONFIG_MTD_PARTITIONS=y
460# CONFIG_MTD_REDBOOT_PARTS is not set
461# CONFIG_MTD_CMDLINE_PARTS is not set
462# CONFIG_MTD_AFS_PARTS is not set
463
464#
465# User Modules And Translation Layers
466#
467CONFIG_MTD_CHAR=y
468CONFIG_MTD_BLKDEVS=y
469CONFIG_MTD_BLOCK=y
470# CONFIG_FTL is not set
471# CONFIG_NFTL is not set
472# CONFIG_INFTL is not set
473# CONFIG_RFD_FTL is not set
474# CONFIG_SSFDC is not set
475# CONFIG_MTD_OOPS is not set
476
477#
478# RAM/ROM/Flash chip drivers
479#
480CONFIG_MTD_CFI=y
481CONFIG_MTD_JEDECPROBE=y
482CONFIG_MTD_GEN_PROBE=y
483CONFIG_MTD_CFI_ADV_OPTIONS=y
484# CONFIG_MTD_CFI_NOSWAP is not set
485# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
486CONFIG_MTD_CFI_LE_BYTE_SWAP=y
487CONFIG_MTD_CFI_GEOMETRY=y
488CONFIG_MTD_MAP_BANK_WIDTH_1=y
489CONFIG_MTD_MAP_BANK_WIDTH_2=y
490CONFIG_MTD_MAP_BANK_WIDTH_4=y
491# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
492# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
493# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
494CONFIG_MTD_CFI_I1=y
495CONFIG_MTD_CFI_I2=y
496# CONFIG_MTD_CFI_I4 is not set
497# CONFIG_MTD_CFI_I8 is not set
498# CONFIG_MTD_OTP is not set
499CONFIG_MTD_CFI_INTELEXT=y
500CONFIG_MTD_CFI_AMDSTD=y
501# CONFIG_MTD_CFI_STAA is not set
502CONFIG_MTD_CFI_UTIL=y
503# CONFIG_MTD_RAM is not set
504# CONFIG_MTD_ROM is not set
505# CONFIG_MTD_ABSENT is not set
506# CONFIG_MTD_XIP is not set
507
508#
509# Mapping drivers for chip access
510#
511CONFIG_MTD_COMPLEX_MAPPINGS=y
512CONFIG_MTD_PHYSMAP=y
513CONFIG_MTD_PHYSMAP_START=0x0
514CONFIG_MTD_PHYSMAP_LEN=0x0
515CONFIG_MTD_PHYSMAP_BANKWIDTH=2
516CONFIG_MTD_PXA2XX=y
517# CONFIG_MTD_ARM_INTEGRATOR is not set
518# CONFIG_MTD_IMPA7 is not set
519# CONFIG_MTD_SHARP_SL is not set
520# CONFIG_MTD_PLATRAM is not set
521
522#
523# Self-contained MTD device drivers
524#
525# CONFIG_MTD_SLRAM is not set
526# CONFIG_MTD_PHRAM is not set
527# CONFIG_MTD_MTDRAM is not set
528CONFIG_MTD_BLOCK2MTD=y
529
530#
531# Disk-On-Chip Device Drivers
532#
533# CONFIG_MTD_DOC2000 is not set
534# CONFIG_MTD_DOC2001 is not set
535# CONFIG_MTD_DOC2001PLUS is not set
536CONFIG_MTD_NAND=y
537# CONFIG_MTD_NAND_VERIFY_WRITE is not set
538# CONFIG_MTD_NAND_ECC_SMC is not set
539# CONFIG_MTD_NAND_MUSEUM_IDS is not set
540# CONFIG_MTD_NAND_H1900 is not set
541CONFIG_MTD_NAND_IDS=y
542CONFIG_MTD_NAND_DISKONCHIP=y
543CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED=y
544CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0x4000000
545CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH=y
546CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE=y
547# CONFIG_MTD_NAND_SHARPSL is not set
548# CONFIG_MTD_NAND_NANDSIM is not set
549# CONFIG_MTD_NAND_PLATFORM is not set
550# CONFIG_MTD_ALAUDA is not set
551CONFIG_MTD_ONENAND=y
552# CONFIG_MTD_ONENAND_VERIFY_WRITE is not set
553# CONFIG_MTD_ONENAND_GENERIC is not set
554# CONFIG_MTD_ONENAND_OTP is not set
555# CONFIG_MTD_ONENAND_2X_PROGRAM is not set
556# CONFIG_MTD_ONENAND_SIM is not set
557
558#
559# UBI - Unsorted block images
560#
561# CONFIG_MTD_UBI is not set
562# CONFIG_PARPORT is not set
563CONFIG_BLK_DEV=y
564# CONFIG_BLK_DEV_COW_COMMON is not set
565CONFIG_BLK_DEV_LOOP=y
566CONFIG_BLK_DEV_CRYPTOLOOP=m
567CONFIG_BLK_DEV_NBD=y
568# CONFIG_BLK_DEV_UB is not set
569CONFIG_BLK_DEV_RAM=y
570CONFIG_BLK_DEV_RAM_COUNT=8
571CONFIG_BLK_DEV_RAM_SIZE=4096
572CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
573# CONFIG_CDROM_PKTCDVD is not set
574# CONFIG_ATA_OVER_ETH is not set
575CONFIG_MISC_DEVICES=y
576# CONFIG_EEPROM_93CX6 is not set
577CONFIG_IDE=y
578CONFIG_IDE_MAX_HWIFS=4
579CONFIG_BLK_DEV_IDE=y
580
581#
582# Please see Documentation/ide.txt for help/info on IDE drives
583#
584# CONFIG_BLK_DEV_IDE_SATA is not set
585CONFIG_BLK_DEV_IDEDISK=y
586CONFIG_IDEDISK_MULTI_MODE=y
587# CONFIG_BLK_DEV_IDECD is not set
588# CONFIG_BLK_DEV_IDETAPE is not set
589# CONFIG_BLK_DEV_IDEFLOPPY is not set
590# CONFIG_IDE_TASK_IOCTL is not set
591CONFIG_IDE_PROC_FS=y
592
593#
594# IDE chipset support/bugfixes
595#
596CONFIG_IDE_GENERIC=y
597# CONFIG_BLK_DEV_PLATFORM is not set
598# CONFIG_IDE_ARM is not set
599# CONFIG_BLK_DEV_IDEDMA is not set
600CONFIG_IDE_ARCH_OBSOLETE_INIT=y
601# CONFIG_BLK_DEV_HD is not set
602
603#
604# SCSI device support
605#
606# CONFIG_RAID_ATTRS is not set
607# CONFIG_SCSI is not set
608# CONFIG_SCSI_DMA is not set
609# CONFIG_SCSI_NETLINK is not set
610# CONFIG_ATA is not set
611# CONFIG_MD is not set
612CONFIG_NETDEVICES=y
613# CONFIG_NETDEVICES_MULTIQUEUE is not set
614# CONFIG_DUMMY is not set
615# CONFIG_BONDING is not set
616# CONFIG_MACVLAN is not set
617# CONFIG_EQUALIZER is not set
618# CONFIG_TUN is not set
619# CONFIG_VETH is not set
620CONFIG_PHYLIB=y
621
622#
623# MII PHY device drivers
624#
625# CONFIG_MARVELL_PHY is not set
626# CONFIG_DAVICOM_PHY is not set
627# CONFIG_QSEMI_PHY is not set
628# CONFIG_LXT_PHY is not set
629# CONFIG_CICADA_PHY is not set
630# CONFIG_VITESSE_PHY is not set
631# CONFIG_SMSC_PHY is not set
632# CONFIG_BROADCOM_PHY is not set
633# CONFIG_ICPLUS_PHY is not set
634# CONFIG_FIXED_PHY is not set
635# CONFIG_MDIO_BITBANG is not set
636CONFIG_NET_ETHERNET=y
637CONFIG_MII=y
638# CONFIG_AX88796 is not set
639# CONFIG_SMC91X is not set
640CONFIG_DM9000=y
641# CONFIG_SMC911X is not set
642# CONFIG_IBM_NEW_EMAC_ZMII is not set
643# CONFIG_IBM_NEW_EMAC_RGMII is not set
644# CONFIG_IBM_NEW_EMAC_TAH is not set
645# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
646# CONFIG_B44 is not set
647# CONFIG_NETDEV_1000 is not set
648# CONFIG_NETDEV_10000 is not set
649
650#
651# Wireless LAN
652#
653# CONFIG_WLAN_PRE80211 is not set
654CONFIG_WLAN_80211=y
655# CONFIG_LIBERTAS is not set
656# CONFIG_USB_ZD1201 is not set
657CONFIG_HOSTAP=y
658CONFIG_HOSTAP_FIRMWARE=y
659CONFIG_HOSTAP_FIRMWARE_NVRAM=y
660# CONFIG_ZD1211RW is not set
661
662#
663# USB Network Adapters
664#
665# CONFIG_USB_CATC is not set
666# CONFIG_USB_KAWETH is not set
667# CONFIG_USB_PEGASUS is not set
668# CONFIG_USB_RTL8150 is not set
669# CONFIG_USB_USBNET is not set
670# CONFIG_WAN is not set
671# CONFIG_PPP is not set
672# CONFIG_SLIP is not set
673# CONFIG_SHAPER is not set
674# CONFIG_NETCONSOLE is not set
675# CONFIG_NETPOLL is not set
676# CONFIG_NET_POLL_CONTROLLER is not set
677# CONFIG_ISDN is not set
678
679#
680# Input device support
681#
682CONFIG_INPUT=y
683# CONFIG_INPUT_FF_MEMLESS is not set
684# CONFIG_INPUT_POLLDEV is not set
685
686#
687# Userland interfaces
688#
689CONFIG_INPUT_MOUSEDEV=y
690CONFIG_INPUT_MOUSEDEV_PSAUX=y
691CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
692CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
693# CONFIG_INPUT_JOYDEV is not set
694CONFIG_INPUT_EVDEV=y
695# CONFIG_INPUT_EVBUG is not set
696
697#
698# Input Device Drivers
699#
700CONFIG_INPUT_KEYBOARD=y
701CONFIG_KEYBOARD_ATKBD=m
702# CONFIG_KEYBOARD_SUNKBD is not set
703# CONFIG_KEYBOARD_LKKBD is not set
704# CONFIG_KEYBOARD_XTKBD is not set
705# CONFIG_KEYBOARD_NEWTON is not set
706# CONFIG_KEYBOARD_STOWAWAY is not set
707# CONFIG_KEYBOARD_PXA27x is not set
708# CONFIG_KEYBOARD_GPIO is not set
709CONFIG_INPUT_MOUSE=y
710# CONFIG_MOUSE_PS2 is not set
711CONFIG_MOUSE_SERIAL=m
712# CONFIG_MOUSE_APPLETOUCH is not set
713# CONFIG_MOUSE_VSXXXAA is not set
714# CONFIG_MOUSE_GPIO is not set
715# CONFIG_INPUT_JOYSTICK is not set
716# CONFIG_INPUT_TABLET is not set
717CONFIG_INPUT_TOUCHSCREEN=y
718# CONFIG_TOUCHSCREEN_FUJITSU is not set
719# CONFIG_TOUCHSCREEN_GUNZE is not set
720# CONFIG_TOUCHSCREEN_ELO is not set
721# CONFIG_TOUCHSCREEN_MTOUCH is not set
722# CONFIG_TOUCHSCREEN_MK712 is not set
723# CONFIG_TOUCHSCREEN_PENMOUNT is not set
724# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
725# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
726CONFIG_TOUCHSCREEN_UCB1400=y
727# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
728CONFIG_INPUT_MISC=y
729# CONFIG_INPUT_ATI_REMOTE is not set
730# CONFIG_INPUT_ATI_REMOTE2 is not set
731# CONFIG_INPUT_KEYSPAN_REMOTE is not set
732# CONFIG_INPUT_POWERMATE is not set
733# CONFIG_INPUT_YEALINK is not set
734CONFIG_INPUT_UINPUT=m
735
736#
737# Hardware I/O ports
738#
739CONFIG_SERIO=y
740CONFIG_SERIO_SERPORT=y
741CONFIG_SERIO_LIBPS2=y
742# CONFIG_SERIO_RAW is not set
743# CONFIG_GAMEPORT is not set
744
745#
746# Character devices
747#
748CONFIG_VT=y
749CONFIG_VT_CONSOLE=y
750CONFIG_HW_CONSOLE=y
751# CONFIG_VT_HW_CONSOLE_BINDING is not set
752# CONFIG_SERIAL_NONSTANDARD is not set
753
754#
755# Serial drivers
756#
757# CONFIG_SERIAL_8250 is not set
758
759#
760# Non-8250 serial port support
761#
762CONFIG_SERIAL_PXA=y
763CONFIG_SERIAL_PXA_CONSOLE=y
764CONFIG_SERIAL_CORE=y
765CONFIG_SERIAL_CORE_CONSOLE=y
766CONFIG_UNIX98_PTYS=y
767CONFIG_LEGACY_PTYS=y
768CONFIG_LEGACY_PTY_COUNT=256
769# CONFIG_IPMI_HANDLER is not set
770CONFIG_HW_RANDOM=y
771# CONFIG_NVRAM is not set
772# CONFIG_R3964 is not set
773# CONFIG_RAW_DRIVER is not set
774# CONFIG_TCG_TPM is not set
775CONFIG_I2C=y
776CONFIG_I2C_BOARDINFO=y
777CONFIG_I2C_CHARDEV=y
778
779#
780# I2C Algorithms
781#
782# CONFIG_I2C_ALGOBIT is not set
783# CONFIG_I2C_ALGOPCF is not set
784# CONFIG_I2C_ALGOPCA is not set
785
786#
787# I2C Hardware Bus support
788#
789# CONFIG_I2C_GPIO is not set
790# CONFIG_I2C_PXA is not set
791# CONFIG_I2C_OCORES is not set
792# CONFIG_I2C_PARPORT_LIGHT is not set
793# CONFIG_I2C_SIMTEC is not set
794# CONFIG_I2C_TAOS_EVM is not set
795# CONFIG_I2C_STUB is not set
796# CONFIG_I2C_TINY_USB is not set
797
798#
799# Miscellaneous I2C Chip support
800#
801# CONFIG_SENSORS_DS1337 is not set
802# CONFIG_SENSORS_DS1374 is not set
803# CONFIG_DS1682 is not set
804# CONFIG_SENSORS_EEPROM is not set
805# CONFIG_SENSORS_PCF8574 is not set
806# CONFIG_SENSORS_PCA9539 is not set
807# CONFIG_SENSORS_PCF8591 is not set
808# CONFIG_SENSORS_MAX6875 is not set
809# CONFIG_SENSORS_TSL2550 is not set
810# CONFIG_I2C_DEBUG_CORE is not set
811# CONFIG_I2C_DEBUG_ALGO is not set
812# CONFIG_I2C_DEBUG_BUS is not set
813# CONFIG_I2C_DEBUG_CHIP is not set
814
815#
816# SPI support
817#
818# CONFIG_SPI is not set
819# CONFIG_SPI_MASTER is not set
820# CONFIG_W1 is not set
821# CONFIG_POWER_SUPPLY is not set
822CONFIG_HWMON=y
823# CONFIG_HWMON_VID is not set
824# CONFIG_SENSORS_AD7418 is not set
825# CONFIG_SENSORS_ADM1021 is not set
826# CONFIG_SENSORS_ADM1025 is not set
827# CONFIG_SENSORS_ADM1026 is not set
828# CONFIG_SENSORS_ADM1029 is not set
829# CONFIG_SENSORS_ADM1031 is not set
830# CONFIG_SENSORS_ADM9240 is not set
831# CONFIG_SENSORS_ADT7470 is not set
832# CONFIG_SENSORS_ATXP1 is not set
833# CONFIG_SENSORS_DS1621 is not set
834# CONFIG_SENSORS_F71805F is not set
835# CONFIG_SENSORS_F71882FG is not set
836# CONFIG_SENSORS_F75375S is not set
837# CONFIG_SENSORS_GL518SM is not set
838# CONFIG_SENSORS_GL520SM is not set
839# CONFIG_SENSORS_IT87 is not set
840# CONFIG_SENSORS_LM63 is not set
841# CONFIG_SENSORS_LM75 is not set
842# CONFIG_SENSORS_LM77 is not set
843# CONFIG_SENSORS_LM78 is not set
844# CONFIG_SENSORS_LM80 is not set
845# CONFIG_SENSORS_LM83 is not set
846# CONFIG_SENSORS_LM85 is not set
847# CONFIG_SENSORS_LM87 is not set
848# CONFIG_SENSORS_LM90 is not set
849# CONFIG_SENSORS_LM92 is not set
850# CONFIG_SENSORS_LM93 is not set
851# CONFIG_SENSORS_MAX1619 is not set
852# CONFIG_SENSORS_MAX6650 is not set
853# CONFIG_SENSORS_PC87360 is not set
854# CONFIG_SENSORS_PC87427 is not set
855# CONFIG_SENSORS_DME1737 is not set
856# CONFIG_SENSORS_SMSC47M1 is not set
857# CONFIG_SENSORS_SMSC47M192 is not set
858# CONFIG_SENSORS_SMSC47B397 is not set
859# CONFIG_SENSORS_THMC50 is not set
860# CONFIG_SENSORS_VT1211 is not set
861# CONFIG_SENSORS_W83781D is not set
862# CONFIG_SENSORS_W83791D is not set
863# CONFIG_SENSORS_W83792D is not set
864# CONFIG_SENSORS_W83793 is not set
865# CONFIG_SENSORS_W83L785TS is not set
866# CONFIG_SENSORS_W83627HF is not set
867# CONFIG_SENSORS_W83627EHF is not set
868# CONFIG_HWMON_DEBUG_CHIP is not set
869CONFIG_WATCHDOG=y
870# CONFIG_WATCHDOG_NOWAYOUT is not set
871
872#
873# Watchdog Device Drivers
874#
875# CONFIG_SOFT_WATCHDOG is not set
876# CONFIG_SA1100_WATCHDOG is not set
877
878#
879# USB-based Watchdog Cards
880#
881# CONFIG_USBPCWATCHDOG is not set
882
883#
884# Sonics Silicon Backplane
885#
886CONFIG_SSB_POSSIBLE=y
887# CONFIG_SSB is not set
888
889#
890# Multifunction device drivers
891#
892# CONFIG_MFD_SM501 is not set
893
894#
895# Multimedia devices
896#
897# CONFIG_VIDEO_DEV is not set
898# CONFIG_DVB_CORE is not set
899CONFIG_DAB=y
900# CONFIG_USB_DABUSB is not set
901
902#
903# Graphics support
904#
905# CONFIG_VGASTATE is not set
906# CONFIG_VIDEO_OUTPUT_CONTROL is not set
907CONFIG_FB=y
908CONFIG_FIRMWARE_EDID=y
909# CONFIG_FB_DDC is not set
910CONFIG_FB_CFB_FILLRECT=y
911CONFIG_FB_CFB_COPYAREA=y
912CONFIG_FB_CFB_IMAGEBLIT=y
913# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
914# CONFIG_FB_SYS_FILLRECT is not set
915# CONFIG_FB_SYS_COPYAREA is not set
916# CONFIG_FB_SYS_IMAGEBLIT is not set
917# CONFIG_FB_SYS_FOPS is not set
918CONFIG_FB_DEFERRED_IO=y
919# CONFIG_FB_SVGALIB is not set
920# CONFIG_FB_MACMODES is not set
921# CONFIG_FB_BACKLIGHT is not set
922# CONFIG_FB_MODE_HELPERS is not set
923# CONFIG_FB_TILEBLITTING is not set
924
925#
926# Frame buffer hardware drivers
927#
928# CONFIG_FB_UVESA is not set
929# CONFIG_FB_S1D13XXX is not set
930CONFIG_FB_PXA=y
931# CONFIG_FB_PXA_PARAMETERS is not set
932# CONFIG_FB_MBX is not set
933# CONFIG_FB_VIRTUAL is not set
934CONFIG_BACKLIGHT_LCD_SUPPORT=y
935CONFIG_LCD_CLASS_DEVICE=y
936CONFIG_BACKLIGHT_CLASS_DEVICE=y
937# CONFIG_BACKLIGHT_CORGI is not set
938
939#
940# Display device support
941#
942# CONFIG_DISPLAY_SUPPORT is not set
943
944#
945# Console display driver support
946#
947# CONFIG_VGA_CONSOLE is not set
948CONFIG_DUMMY_CONSOLE=y
949CONFIG_FRAMEBUFFER_CONSOLE=y
950# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
951CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
952CONFIG_FONTS=y
953CONFIG_FONT_8x8=y
954CONFIG_FONT_8x16=y
955# CONFIG_FONT_6x11 is not set
956# CONFIG_FONT_7x14 is not set
957# CONFIG_FONT_PEARL_8x8 is not set
958# CONFIG_FONT_ACORN_8x8 is not set
959# CONFIG_FONT_MINI_4x6 is not set
960# CONFIG_FONT_SUN8x16 is not set
961# CONFIG_FONT_SUN12x22 is not set
962# CONFIG_FONT_10x18 is not set
963CONFIG_LOGO=y
964CONFIG_LOGO_LINUX_MONO=y
965CONFIG_LOGO_LINUX_VGA16=y
966CONFIG_LOGO_LINUX_CLUT224=y
967
968#
969# Sound
970#
971# CONFIG_SOUND is not set
972CONFIG_AC97_BUS=y
973CONFIG_HID_SUPPORT=y
974CONFIG_HID=y
975# CONFIG_HID_DEBUG is not set
976# CONFIG_HIDRAW is not set
977
978#
979# USB Input Devices
980#
981# CONFIG_USB_HID is not set
982
983#
984# USB HID Boot Protocol drivers
985#
986# CONFIG_USB_KBD is not set
987# CONFIG_USB_MOUSE is not set
988CONFIG_USB_SUPPORT=y
989CONFIG_USB_ARCH_HAS_HCD=y
990CONFIG_USB_ARCH_HAS_OHCI=y
991# CONFIG_USB_ARCH_HAS_EHCI is not set
992CONFIG_USB=y
993# CONFIG_USB_DEBUG is not set
994
995#
996# Miscellaneous USB options
997#
998CONFIG_USB_DEVICEFS=y
999# CONFIG_USB_DEVICE_CLASS is not set
1000# CONFIG_USB_DYNAMIC_MINORS is not set
1001# CONFIG_USB_SUSPEND is not set
1002# CONFIG_USB_PERSIST is not set
1003# CONFIG_USB_OTG is not set
1004
1005#
1006# USB Host Controller Drivers
1007#
1008# CONFIG_USB_ISP116X_HCD is not set
1009# CONFIG_USB_OHCI_HCD is not set
1010# CONFIG_USB_SL811_HCD is not set
1011# CONFIG_USB_R8A66597_HCD is not set
1012
1013#
1014# USB Device Class drivers
1015#
1016# CONFIG_USB_ACM is not set
1017# CONFIG_USB_PRINTER is not set
1018
1019#
1020# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
1021#
1022
1023#
1024# may also be needed; see USB_STORAGE Help for more information
1025#
1026# CONFIG_USB_LIBUSUAL is not set
1027
1028#
1029# USB Imaging devices
1030#
1031# CONFIG_USB_MDC800 is not set
1032# CONFIG_USB_MON is not set
1033
1034#
1035# USB port drivers
1036#
1037
1038#
1039# USB Serial Converter support
1040#
1041CONFIG_USB_SERIAL=m
1042# CONFIG_USB_SERIAL_GENERIC is not set
1043# CONFIG_USB_SERIAL_AIRCABLE is not set
1044# CONFIG_USB_SERIAL_AIRPRIME is not set
1045# CONFIG_USB_SERIAL_ARK3116 is not set
1046# CONFIG_USB_SERIAL_BELKIN is not set
1047# CONFIG_USB_SERIAL_CH341 is not set
1048# CONFIG_USB_SERIAL_WHITEHEAT is not set
1049# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
1050# CONFIG_USB_SERIAL_CP2101 is not set
1051# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
1052# CONFIG_USB_SERIAL_EMPEG is not set
1053# CONFIG_USB_SERIAL_FTDI_SIO is not set
1054# CONFIG_USB_SERIAL_FUNSOFT is not set
1055# CONFIG_USB_SERIAL_VISOR is not set
1056# CONFIG_USB_SERIAL_IPAQ is not set
1057# CONFIG_USB_SERIAL_IR is not set
1058# CONFIG_USB_SERIAL_EDGEPORT is not set
1059# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
1060# CONFIG_USB_SERIAL_GARMIN is not set
1061# CONFIG_USB_SERIAL_IPW is not set
1062# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
1063# CONFIG_USB_SERIAL_KEYSPAN is not set
1064# CONFIG_USB_SERIAL_KLSI is not set
1065# CONFIG_USB_SERIAL_KOBIL_SCT is not set
1066# CONFIG_USB_SERIAL_MCT_U232 is not set
1067# CONFIG_USB_SERIAL_MOS7720 is not set
1068# CONFIG_USB_SERIAL_MOS7840 is not set
1069# CONFIG_USB_SERIAL_NAVMAN is not set
1070# CONFIG_USB_SERIAL_PL2303 is not set
1071# CONFIG_USB_SERIAL_OTI6858 is not set
1072# CONFIG_USB_SERIAL_HP4X is not set
1073# CONFIG_USB_SERIAL_SAFE is not set
1074# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
1075# CONFIG_USB_SERIAL_TI is not set
1076# CONFIG_USB_SERIAL_CYBERJACK is not set
1077# CONFIG_USB_SERIAL_XIRCOM is not set
1078# CONFIG_USB_SERIAL_OPTION is not set
1079# CONFIG_USB_SERIAL_OMNINET is not set
1080# CONFIG_USB_SERIAL_DEBUG is not set
1081
1082#
1083# USB Miscellaneous drivers
1084#
1085# CONFIG_USB_EMI62 is not set
1086# CONFIG_USB_EMI26 is not set
1087# CONFIG_USB_ADUTUX is not set
1088# CONFIG_USB_AUERSWALD is not set
1089# CONFIG_USB_RIO500 is not set
1090# CONFIG_USB_LEGOTOWER is not set
1091# CONFIG_USB_LCD is not set
1092# CONFIG_USB_BERRY_CHARGE is not set
1093# CONFIG_USB_LED is not set
1094# CONFIG_USB_CYPRESS_CY7C63 is not set
1095# CONFIG_USB_CYTHERM is not set
1096# CONFIG_USB_PHIDGET is not set
1097# CONFIG_USB_IDMOUSE is not set
1098# CONFIG_USB_FTDI_ELAN is not set
1099# CONFIG_USB_APPLEDISPLAY is not set
1100# CONFIG_USB_LD is not set
1101# CONFIG_USB_TRANCEVIBRATOR is not set
1102# CONFIG_USB_IOWARRIOR is not set
1103# CONFIG_USB_TEST is not set
1104
1105#
1106# USB DSL modem support
1107#
1108
1109#
1110# USB Gadget Support
1111#
1112CONFIG_USB_GADGET=m
1113# CONFIG_USB_GADGET_DEBUG is not set
1114# CONFIG_USB_GADGET_DEBUG_FILES is not set
1115# CONFIG_USB_GADGET_DEBUG_FS is not set
1116CONFIG_USB_GADGET_SELECTED=y
1117# CONFIG_USB_GADGET_AMD5536UDC is not set
1118# CONFIG_USB_GADGET_ATMEL_USBA is not set
1119# CONFIG_USB_GADGET_FSL_USB2 is not set
1120# CONFIG_USB_GADGET_NET2280 is not set
1121# CONFIG_USB_GADGET_PXA2XX is not set
1122# CONFIG_USB_GADGET_M66592 is not set
1123# CONFIG_USB_GADGET_GOKU is not set
1124# CONFIG_USB_GADGET_LH7A40X is not set
1125# CONFIG_USB_GADGET_OMAP is not set
1126# CONFIG_USB_GADGET_S3C2410 is not set
1127# CONFIG_USB_GADGET_AT91 is not set
1128CONFIG_USB_GADGET_DUMMY_HCD=y
1129CONFIG_USB_DUMMY_HCD=m
1130CONFIG_USB_GADGET_DUALSPEED=y
1131# CONFIG_USB_ZERO is not set
1132# CONFIG_USB_ETH is not set
1133# CONFIG_USB_GADGETFS is not set
1134# CONFIG_USB_FILE_STORAGE is not set
1135# CONFIG_USB_G_SERIAL is not set
1136# CONFIG_USB_MIDI_GADGET is not set
1137CONFIG_MMC=y
1138# CONFIG_MMC_DEBUG is not set
1139# CONFIG_MMC_UNSAFE_RESUME is not set
1140
1141#
1142# MMC/SD Card Drivers
1143#
1144CONFIG_MMC_BLOCK=y
1145CONFIG_MMC_BLOCK_BOUNCE=y
1146# CONFIG_SDIO_UART is not set
1147
1148#
1149# MMC/SD Host Controller Drivers
1150#
1151# CONFIG_MMC_PXA is not set
1152CONFIG_NEW_LEDS=y
1153# CONFIG_LEDS_CLASS is not set
1154
1155#
1156# LED drivers
1157#
1158
1159#
1160# LED Triggers
1161#
1162CONFIG_LEDS_TRIGGERS=y
1163CONFIG_LEDS_TRIGGER_TIMER=y
1164# CONFIG_LEDS_TRIGGER_IDE_DISK is not set
1165CONFIG_LEDS_TRIGGER_HEARTBEAT=y
1166CONFIG_RTC_LIB=y
1167CONFIG_RTC_CLASS=y
1168# CONFIG_RTC_HCTOSYS is not set
1169# CONFIG_RTC_DEBUG is not set
1170
1171#
1172# RTC interfaces
1173#
1174CONFIG_RTC_INTF_SYSFS=y
1175CONFIG_RTC_INTF_PROC=y
1176CONFIG_RTC_INTF_DEV=y
1177# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
1178# CONFIG_RTC_DRV_TEST is not set
1179
1180#
1181# I2C RTC drivers
1182#
1183# CONFIG_RTC_DRV_DS1307 is not set
1184# CONFIG_RTC_DRV_DS1374 is not set
1185# CONFIG_RTC_DRV_DS1672 is not set
1186# CONFIG_RTC_DRV_MAX6900 is not set
1187# CONFIG_RTC_DRV_RS5C372 is not set
1188# CONFIG_RTC_DRV_ISL1208 is not set
1189# CONFIG_RTC_DRV_X1205 is not set
1190# CONFIG_RTC_DRV_PCF8563 is not set
1191CONFIG_RTC_DRV_PCF8583=m
1192# CONFIG_RTC_DRV_M41T80 is not set
1193
1194#
1195# SPI RTC drivers
1196#
1197
1198#
1199# Platform RTC drivers
1200#
1201# CONFIG_RTC_DRV_CMOS is not set
1202# CONFIG_RTC_DRV_DS1553 is not set
1203# CONFIG_RTC_DRV_STK17TA8 is not set
1204# CONFIG_RTC_DRV_DS1742 is not set
1205# CONFIG_RTC_DRV_M48T86 is not set
1206# CONFIG_RTC_DRV_M48T59 is not set
1207# CONFIG_RTC_DRV_V3020 is not set
1208
1209#
1210# on-CPU RTC drivers
1211#
1212# CONFIG_RTC_DRV_SA1100 is not set
1213
1214#
1215# File systems
1216#
1217# CONFIG_EXT2_FS is not set
1218# CONFIG_EXT3_FS is not set
1219# CONFIG_EXT4DEV_FS is not set
1220# CONFIG_REISERFS_FS is not set
1221# CONFIG_JFS_FS is not set
1222CONFIG_FS_POSIX_ACL=y
1223# CONFIG_XFS_FS is not set
1224# CONFIG_GFS2_FS is not set
1225# CONFIG_OCFS2_FS is not set
1226# CONFIG_MINIX_FS is not set
1227# CONFIG_ROMFS_FS is not set
1228CONFIG_INOTIFY=y
1229CONFIG_INOTIFY_USER=y
1230# CONFIG_QUOTA is not set
1231CONFIG_DNOTIFY=y
1232# CONFIG_AUTOFS_FS is not set
1233CONFIG_AUTOFS4_FS=y
1234# CONFIG_FUSE_FS is not set
1235
1236#
1237# CD-ROM/DVD Filesystems
1238#
1239# CONFIG_ISO9660_FS is not set
1240# CONFIG_UDF_FS is not set
1241
1242#
1243# DOS/FAT/NT Filesystems
1244#
1245CONFIG_FAT_FS=m
1246CONFIG_MSDOS_FS=m
1247CONFIG_VFAT_FS=m
1248CONFIG_FAT_DEFAULT_CODEPAGE=437
1249CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-15"
1250# CONFIG_NTFS_FS is not set
1251
1252#
1253# Pseudo filesystems
1254#
1255CONFIG_PROC_FS=y
1256CONFIG_PROC_SYSCTL=y
1257CONFIG_SYSFS=y
1258CONFIG_TMPFS=y
1259# CONFIG_TMPFS_POSIX_ACL is not set
1260# CONFIG_HUGETLB_PAGE is not set
1261CONFIG_CONFIGFS_FS=y
1262
1263#
1264# Miscellaneous filesystems
1265#
1266# CONFIG_ADFS_FS is not set
1267# CONFIG_AFFS_FS is not set
1268# CONFIG_ECRYPT_FS is not set
1269# CONFIG_HFS_FS is not set
1270# CONFIG_HFSPLUS_FS is not set
1271# CONFIG_BEFS_FS is not set
1272# CONFIG_BFS_FS is not set
1273# CONFIG_EFS_FS is not set
1274CONFIG_JFFS2_FS=y
1275CONFIG_JFFS2_FS_DEBUG=1
1276CONFIG_JFFS2_FS_WRITEBUFFER=y
1277CONFIG_JFFS2_FS_WBUF_VERIFY=y
1278# CONFIG_JFFS2_SUMMARY is not set
1279# CONFIG_JFFS2_FS_XATTR is not set
1280# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
1281CONFIG_JFFS2_ZLIB=y
1282# CONFIG_JFFS2_LZO is not set
1283CONFIG_JFFS2_RTIME=y
1284# CONFIG_JFFS2_RUBIN is not set
1285# CONFIG_CRAMFS is not set
1286# CONFIG_VXFS_FS is not set
1287# CONFIG_HPFS_FS is not set
1288# CONFIG_QNX4FS_FS is not set
1289# CONFIG_SYSV_FS is not set
1290# CONFIG_UFS_FS is not set
1291CONFIG_NETWORK_FILESYSTEMS=y
1292CONFIG_NFS_FS=y
1293CONFIG_NFS_V3=y
1294# CONFIG_NFS_V3_ACL is not set
1295CONFIG_NFS_V4=y
1296# CONFIG_NFS_DIRECTIO is not set
1297CONFIG_NFSD=y
1298CONFIG_NFSD_V3=y
1299# CONFIG_NFSD_V3_ACL is not set
1300CONFIG_NFSD_V4=y
1301CONFIG_NFSD_TCP=y
1302CONFIG_ROOT_NFS=y
1303CONFIG_LOCKD=y
1304CONFIG_LOCKD_V4=y
1305CONFIG_EXPORTFS=y
1306CONFIG_NFS_COMMON=y
1307CONFIG_SUNRPC=y
1308CONFIG_SUNRPC_GSS=y
1309# CONFIG_SUNRPC_BIND34 is not set
1310CONFIG_RPCSEC_GSS_KRB5=y
1311# CONFIG_RPCSEC_GSS_SPKM3 is not set
1312# CONFIG_SMB_FS is not set
1313# CONFIG_CIFS is not set
1314# CONFIG_NCP_FS is not set
1315# CONFIG_CODA_FS is not set
1316# CONFIG_AFS_FS is not set
1317
1318#
1319# Partition Types
1320#
1321# CONFIG_PARTITION_ADVANCED is not set
1322CONFIG_MSDOS_PARTITION=y
1323CONFIG_NLS=y
1324CONFIG_NLS_DEFAULT="iso8859-15"
1325CONFIG_NLS_CODEPAGE_437=y
1326# CONFIG_NLS_CODEPAGE_737 is not set
1327# CONFIG_NLS_CODEPAGE_775 is not set
1328CONFIG_NLS_CODEPAGE_850=y
1329# CONFIG_NLS_CODEPAGE_852 is not set
1330# CONFIG_NLS_CODEPAGE_855 is not set
1331# CONFIG_NLS_CODEPAGE_857 is not set
1332# CONFIG_NLS_CODEPAGE_860 is not set
1333# CONFIG_NLS_CODEPAGE_861 is not set
1334# CONFIG_NLS_CODEPAGE_862 is not set
1335# CONFIG_NLS_CODEPAGE_863 is not set
1336# CONFIG_NLS_CODEPAGE_864 is not set
1337# CONFIG_NLS_CODEPAGE_865 is not set
1338# CONFIG_NLS_CODEPAGE_866 is not set
1339# CONFIG_NLS_CODEPAGE_869 is not set
1340# CONFIG_NLS_CODEPAGE_936 is not set
1341# CONFIG_NLS_CODEPAGE_950 is not set
1342# CONFIG_NLS_CODEPAGE_932 is not set
1343# CONFIG_NLS_CODEPAGE_949 is not set
1344# CONFIG_NLS_CODEPAGE_874 is not set
1345# CONFIG_NLS_ISO8859_8 is not set
1346# CONFIG_NLS_CODEPAGE_1250 is not set
1347# CONFIG_NLS_CODEPAGE_1251 is not set
1348CONFIG_NLS_ASCII=y
1349CONFIG_NLS_ISO8859_1=m
1350# CONFIG_NLS_ISO8859_2 is not set
1351# CONFIG_NLS_ISO8859_3 is not set
1352# CONFIG_NLS_ISO8859_4 is not set
1353# CONFIG_NLS_ISO8859_5 is not set
1354# CONFIG_NLS_ISO8859_6 is not set
1355# CONFIG_NLS_ISO8859_7 is not set
1356# CONFIG_NLS_ISO8859_9 is not set
1357# CONFIG_NLS_ISO8859_13 is not set
1358# CONFIG_NLS_ISO8859_14 is not set
1359CONFIG_NLS_ISO8859_15=m
1360# CONFIG_NLS_KOI8_R is not set
1361# CONFIG_NLS_KOI8_U is not set
1362CONFIG_NLS_UTF8=m
1363# CONFIG_DLM is not set
1364CONFIG_INSTRUMENTATION=y
1365# CONFIG_PROFILING is not set
1366# CONFIG_MARKERS is not set
1367
1368#
1369# Kernel hacking
1370#
1371CONFIG_PRINTK_TIME=y
1372CONFIG_ENABLE_WARN_DEPRECATED=y
1373CONFIG_ENABLE_MUST_CHECK=y
1374CONFIG_MAGIC_SYSRQ=y
1375# CONFIG_UNUSED_SYMBOLS is not set
1376CONFIG_DEBUG_FS=y
1377# CONFIG_HEADERS_CHECK is not set
1378CONFIG_DEBUG_KERNEL=y
1379# CONFIG_DEBUG_SHIRQ is not set
1380CONFIG_DETECT_SOFTLOCKUP=y
1381CONFIG_SCHED_DEBUG=y
1382# CONFIG_SCHEDSTATS is not set
1383# CONFIG_TIMER_STATS is not set
1384# CONFIG_DEBUG_SLAB is not set
1385CONFIG_DEBUG_PREEMPT=y
1386# CONFIG_DEBUG_RT_MUTEXES is not set
1387# CONFIG_RT_MUTEX_TESTER is not set
1388# CONFIG_DEBUG_SPINLOCK is not set
1389# CONFIG_DEBUG_MUTEXES is not set
1390# CONFIG_DEBUG_LOCK_ALLOC is not set
1391# CONFIG_PROVE_LOCKING is not set
1392# CONFIG_LOCK_STAT is not set
1393# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1394# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
1395# CONFIG_DEBUG_KOBJECT is not set
1396CONFIG_DEBUG_BUGVERBOSE=y
1397CONFIG_DEBUG_INFO=y
1398# CONFIG_DEBUG_VM is not set
1399# CONFIG_DEBUG_LIST is not set
1400# CONFIG_DEBUG_SG is not set
1401CONFIG_FRAME_POINTER=y
1402CONFIG_FORCED_INLINING=y
1403# CONFIG_BOOT_PRINTK_DELAY is not set
1404# CONFIG_RCU_TORTURE_TEST is not set
1405# CONFIG_FAULT_INJECTION is not set
1406# CONFIG_SAMPLES is not set
1407CONFIG_DEBUG_USER=y
1408CONFIG_DEBUG_ERRORS=y
1409CONFIG_DEBUG_LL=y
1410# CONFIG_DEBUG_ICEDCC is not set
1411
1412#
1413# Security options
1414#
1415CONFIG_KEYS=y
1416CONFIG_KEYS_DEBUG_PROC_KEYS=y
1417CONFIG_SECURITY=y
1418# CONFIG_SECURITY_NETWORK is not set
1419CONFIG_SECURITY_CAPABILITIES=y
1420# CONFIG_SECURITY_FILE_CAPABILITIES is not set
1421# CONFIG_SECURITY_ROOTPLUG is not set
1422CONFIG_CRYPTO=y
1423CONFIG_CRYPTO_ALGAPI=y
1424CONFIG_CRYPTO_BLKCIPHER=y
1425CONFIG_CRYPTO_MANAGER=y
1426# CONFIG_CRYPTO_HMAC is not set
1427# CONFIG_CRYPTO_XCBC is not set
1428# CONFIG_CRYPTO_NULL is not set
1429# CONFIG_CRYPTO_MD4 is not set
1430CONFIG_CRYPTO_MD5=y
1431CONFIG_CRYPTO_SHA1=m
1432CONFIG_CRYPTO_SHA256=m
1433CONFIG_CRYPTO_SHA512=m
1434# CONFIG_CRYPTO_WP512 is not set
1435# CONFIG_CRYPTO_TGR192 is not set
1436# CONFIG_CRYPTO_GF128MUL is not set
1437CONFIG_CRYPTO_ECB=y
1438CONFIG_CRYPTO_CBC=y
1439CONFIG_CRYPTO_PCBC=m
1440# CONFIG_CRYPTO_LRW is not set
1441# CONFIG_CRYPTO_XTS is not set
1442# CONFIG_CRYPTO_CRYPTD is not set
1443CONFIG_CRYPTO_DES=y
1444# CONFIG_CRYPTO_FCRYPT is not set
1445# CONFIG_CRYPTO_BLOWFISH is not set
1446# CONFIG_CRYPTO_TWOFISH is not set
1447# CONFIG_CRYPTO_SERPENT is not set
1448CONFIG_CRYPTO_AES=m
1449# CONFIG_CRYPTO_CAST5 is not set
1450# CONFIG_CRYPTO_CAST6 is not set
1451# CONFIG_CRYPTO_TEA is not set
1452CONFIG_CRYPTO_ARC4=y
1453# CONFIG_CRYPTO_KHAZAD is not set
1454# CONFIG_CRYPTO_ANUBIS is not set
1455# CONFIG_CRYPTO_SEED is not set
1456CONFIG_CRYPTO_DEFLATE=m
1457CONFIG_CRYPTO_MICHAEL_MIC=m
1458CONFIG_CRYPTO_CRC32C=y
1459# CONFIG_CRYPTO_CAMELLIA is not set
1460# CONFIG_CRYPTO_TEST is not set
1461# CONFIG_CRYPTO_AUTHENC is not set
1462CONFIG_CRYPTO_HW=y
1463
1464#
1465# Library routines
1466#
1467CONFIG_BITREVERSE=y
1468CONFIG_CRC_CCITT=y
1469CONFIG_CRC16=y
1470# CONFIG_CRC_ITU_T is not set
1471CONFIG_CRC32=y
1472# CONFIG_CRC7 is not set
1473CONFIG_LIBCRC32C=y
1474CONFIG_ZLIB_INFLATE=y
1475CONFIG_ZLIB_DEFLATE=y
1476CONFIG_REED_SOLOMON=y
1477CONFIG_REED_SOLOMON_DEC16=y
1478CONFIG_PLIST=y
1479CONFIG_HAS_IOMEM=y
1480CONFIG_HAS_IOPORT=y
1481CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/collie_defconfig b/arch/arm/configs/collie_defconfig
index 970c8c772eb7..4264e273202d 100644
--- a/arch/arm/configs/collie_defconfig
+++ b/arch/arm/configs/collie_defconfig
@@ -367,7 +367,6 @@ CONFIG_MTD_CFI_UTIL=y
367# CONFIG_MTD_RAM is not set 367# CONFIG_MTD_RAM is not set
368# CONFIG_MTD_ROM is not set 368# CONFIG_MTD_ROM is not set
369# CONFIG_MTD_ABSENT is not set 369# CONFIG_MTD_ABSENT is not set
370CONFIG_MTD_OBSOLETE_CHIPS=y
371CONFIG_MTD_SHARP=y 370CONFIG_MTD_SHARP=y
372# CONFIG_MTD_XIP is not set 371# CONFIG_MTD_XIP is not set
373 372
diff --git a/arch/arm/configs/eseries_pxa_defconfig b/arch/arm/configs/eseries_pxa_defconfig
new file mode 100644
index 000000000000..ed487b90dbed
--- /dev/null
+++ b/arch/arm/configs/eseries_pxa_defconfig
@@ -0,0 +1,1499 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.21-hh17
4# Fri Nov 9 20:23:03 2007
5#
6CONFIG_ARM=y
7CONFIG_SYS_SUPPORTS_APM_EMULATION=y
8CONFIG_GENERIC_GPIO=y
9CONFIG_GENERIC_TIME=y
10CONFIG_MMU=y
11# CONFIG_NO_IOPORT is not set
12CONFIG_GENERIC_HARDIRQS=y
13CONFIG_TRACE_IRQFLAGS_SUPPORT=y
14CONFIG_HARDIRQS_SW_RESEND=y
15CONFIG_GENERIC_IRQ_PROBE=y
16CONFIG_RWSEM_GENERIC_SPINLOCK=y
17# CONFIG_ARCH_HAS_ILOG2_U32 is not set
18# CONFIG_ARCH_HAS_ILOG2_U64 is not set
19CONFIG_GENERIC_HWEIGHT=y
20CONFIG_GENERIC_CALIBRATE_DELAY=y
21CONFIG_ZONE_DMA=y
22CONFIG_ARCH_MTD_XIP=y
23CONFIG_VECTORS_BASE=0xffff0000
24CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
25
26#
27# Code maturity level options
28#
29CONFIG_EXPERIMENTAL=y
30CONFIG_BROKEN_ON_SMP=y
31CONFIG_INIT_ENV_ARG_LIMIT=32
32
33#
34# General setup
35#
36CONFIG_LOCALVERSION=""
37CONFIG_LOCALVERSION_AUTO=y
38CONFIG_SWAP=y
39CONFIG_SYSVIPC=y
40# CONFIG_IPC_NS is not set
41CONFIG_SYSVIPC_SYSCTL=y
42# CONFIG_POSIX_MQUEUE is not set
43# CONFIG_BSD_PROCESS_ACCT is not set
44# CONFIG_TASKSTATS is not set
45# CONFIG_UTS_NS is not set
46# CONFIG_AUDIT is not set
47# CONFIG_IKCONFIG is not set
48CONFIG_SYSFS_DEPRECATED=y
49# CONFIG_RELAY is not set
50CONFIG_BLK_DEV_INITRD=y
51CONFIG_INITRAMFS_SOURCE=""
52# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
53CONFIG_SYSCTL=y
54CONFIG_EMBEDDED=y
55CONFIG_UID16=y
56CONFIG_SYSCTL_SYSCALL=y
57# CONFIG_KALLSYMS is not set
58CONFIG_HOTPLUG=y
59CONFIG_PRINTK=y
60CONFIG_BUG=y
61CONFIG_ELF_CORE=y
62CONFIG_BASE_FULL=y
63CONFIG_FUTEX=y
64CONFIG_EPOLL=y
65CONFIG_SHMEM=y
66CONFIG_SLAB=y
67CONFIG_VM_EVENT_COUNTERS=y
68CONFIG_RT_MUTEXES=y
69# CONFIG_TINY_SHMEM is not set
70CONFIG_BASE_SMALL=0
71# CONFIG_SLOB is not set
72
73#
74# Loadable module support
75#
76CONFIG_MODULES=y
77CONFIG_MODULE_UNLOAD=y
78CONFIG_MODULE_FORCE_UNLOAD=y
79# CONFIG_MODVERSIONS is not set
80# CONFIG_MODULE_SRCVERSION_ALL is not set
81CONFIG_KMOD=y
82
83#
84# Block layer
85#
86CONFIG_BLOCK=y
87# CONFIG_LBD is not set
88# CONFIG_BLK_DEV_IO_TRACE is not set
89# CONFIG_LSF is not set
90
91#
92# IO Schedulers
93#
94CONFIG_IOSCHED_NOOP=y
95CONFIG_IOSCHED_AS=y
96CONFIG_IOSCHED_DEADLINE=y
97CONFIG_IOSCHED_CFQ=y
98CONFIG_DEFAULT_AS=y
99# CONFIG_DEFAULT_DEADLINE is not set
100# CONFIG_DEFAULT_CFQ is not set
101# CONFIG_DEFAULT_NOOP is not set
102CONFIG_DEFAULT_IOSCHED="anticipatory"
103
104#
105# System Type
106#
107# CONFIG_ARCH_AAEC2000 is not set
108# CONFIG_ARCH_INTEGRATOR is not set
109# CONFIG_ARCH_REALVIEW is not set
110# CONFIG_ARCH_VERSATILE is not set
111# CONFIG_ARCH_AT91 is not set
112# CONFIG_ARCH_CLPS7500 is not set
113# CONFIG_ARCH_CLPS711X is not set
114# CONFIG_ARCH_CO285 is not set
115# CONFIG_ARCH_EBSA110 is not set
116# CONFIG_ARCH_EP93XX is not set
117# CONFIG_ARCH_FOOTBRIDGE is not set
118# CONFIG_ARCH_NETX is not set
119# CONFIG_ARCH_H720X is not set
120# CONFIG_ARCH_IMX is not set
121# CONFIG_ARCH_IOP32X is not set
122# CONFIG_ARCH_IOP33X is not set
123# CONFIG_ARCH_IOP13XX is not set
124# CONFIG_ARCH_IXP4XX is not set
125# CONFIG_ARCH_IXP2000 is not set
126# CONFIG_ARCH_IXP23XX is not set
127# CONFIG_ARCH_L7200 is not set
128# CONFIG_ARCH_NS9XXX is not set
129# CONFIG_ARCH_PNX4008 is not set
130CONFIG_ARCH_PXA=y
131# CONFIG_ARCH_RPC is not set
132# CONFIG_ARCH_SA1100 is not set
133# CONFIG_ARCH_S3C2410 is not set
134# CONFIG_ARCH_SHARK is not set
135# CONFIG_ARCH_LH7A40X is not set
136# CONFIG_ARCH_OMAP is not set
137# CONFIG_BOARD_IRQ_MAP_SMALL is not set
138CONFIG_BOARD_IRQ_MAP_BIG=y
139CONFIG_DMABOUNCE=y
140
141#
142# Intel PXA2xx Implementations
143#
144# CONFIG_ARCH_LUBBOCK is not set
145# CONFIG_MACH_LOGICPD_PXA270 is not set
146# CONFIG_MACH_MAINSTONE is not set
147# CONFIG_ARCH_PXA_IDP is not set
148CONFIG_TOSHIBA_TMIO_OHCI=y
149CONFIG_ARCH_ESERIES=y
150CONFIG_MACH_E330=y
151CONFIG_MACH_E740=y
152CONFIG_MACH_E750=y
153CONFIG_MACH_E400=y
154CONFIG_MACH_E800=y
155CONFIG_E330_LCD=y
156CONFIG_E740_LCD=y
157CONFIG_E750_LCD=y
158CONFIG_E400_LCD=y
159CONFIG_E800_LCD=y
160CONFIG_ESERIES_UDC=y
161CONFIG_E330_TC6387XB=y
162CONFIG_E740_T7L66XB=y
163CONFIG_E400_T7L66XB=y
164CONFIG_E750_E800_TC6393XB=y
165CONFIG_E740_PCMCIA=m
166CONFIG_E750_PCMCIA=m
167CONFIG_E800_PCMCIA=m
168# CONFIG_MACH_A620 is not set
169# CONFIG_MACH_A716 is not set
170# CONFIG_MACH_A730 is not set
171# CONFIG_ARCH_H1900 is not set
172# CONFIG_ARCH_H2200 is not set
173# CONFIG_MACH_H3900 is not set
174# CONFIG_MACH_H4000 is not set
175# CONFIG_MACH_H4700 is not set
176# CONFIG_MACH_HX2750 is not set
177# CONFIG_ARCH_H5400 is not set
178# CONFIG_MACH_HIMALAYA is not set
179# CONFIG_MACH_HTCUNIVERSAL is not set
180# CONFIG_MACH_HTCALPINE is not set
181# CONFIG_MACH_MAGICIAN is not set
182# CONFIG_MACH_HTCAPACHE is not set
183# CONFIG_MACH_BLUEANGEL is not set
184
185#
186# HTC_HW6X00
187#
188# CONFIG_MACH_HTCBEETLES is not set
189# CONFIG_MACH_HW6900 is not set
190# CONFIG_MACH_HTCATHENA is not set
191# CONFIG_ARCH_AXIMX3 is not set
192# CONFIG_ARCH_AXIMX5 is not set
193# CONFIG_MACH_X50 is not set
194# CONFIG_ARCH_ROVERP1 is not set
195# CONFIG_ARCH_ROVERP5P is not set
196# CONFIG_MACH_XSCALE_PALMLD is not set
197# CONFIG_MACH_T3XSCALE is not set
198# CONFIG_MACH_RECON is not set
199# CONFIG_MACH_GHI270HG is not set
200# CONFIG_MACH_GHI270 is not set
201# CONFIG_MACH_LOOXC550 is not set
202# CONFIG_PXA_SHARPSL is not set
203# CONFIG_MACH_TRIZEPS4 is not set
204CONFIG_PXA25x=y
205
206#
207# Linux As Bootloader
208#
209# CONFIG_LAB is not set
210
211#
212# Processor Type
213#
214CONFIG_CPU_32=y
215CONFIG_CPU_XSCALE=y
216CONFIG_CPU_32v5=y
217CONFIG_CPU_ABRT_EV5T=y
218CONFIG_CPU_CACHE_VIVT=y
219CONFIG_CPU_TLB_V4WBI=y
220CONFIG_CPU_CP15=y
221CONFIG_CPU_CP15_MMU=y
222
223#
224# Processor Features
225#
226# CONFIG_ARM_THUMB is not set
227# CONFIG_CPU_DCACHE_DISABLE is not set
228# CONFIG_OUTER_CACHE is not set
229CONFIG_IWMMXT=y
230CONFIG_XSCALE_PMU=y
231
232#
233# Bus support
234#
235
236#
237# PCCARD (PCMCIA/CardBus) support
238#
239CONFIG_PCCARD=m
240# CONFIG_PCMCIA_DEBUG is not set
241CONFIG_PCMCIA=m
242CONFIG_PCMCIA_LOAD_CIS=y
243CONFIG_PCMCIA_IOCTL=y
244
245#
246# PC-card bridges
247#
248CONFIG_PCMCIA_PXA2XX=m
249
250#
251# Kernel Features
252#
253# CONFIG_PREEMPT is not set
254# CONFIG_NO_IDLE_HZ is not set
255CONFIG_HZ=100
256CONFIG_AEABI=y
257CONFIG_OABI_COMPAT=y
258# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
259CONFIG_SELECT_MEMORY_MODEL=y
260CONFIG_FLATMEM_MANUAL=y
261# CONFIG_DISCONTIGMEM_MANUAL is not set
262# CONFIG_SPARSEMEM_MANUAL is not set
263CONFIG_FLATMEM=y
264CONFIG_FLAT_NODE_MEM_MAP=y
265# CONFIG_SPARSEMEM_STATIC is not set
266CONFIG_SPLIT_PTLOCK_CPUS=4096
267# CONFIG_RESOURCES_64BIT is not set
268CONFIG_ZONE_DMA_FLAG=1
269CONFIG_ALIGNMENT_TRAP=y
270
271#
272# Boot options
273#
274CONFIG_ZBOOT_ROM_TEXT=0x0
275CONFIG_ZBOOT_ROM_BSS=0x0
276CONFIG_CMDLINE=""
277# CONFIG_XIP_KERNEL is not set
278CONFIG_KEXEC=y
279# CONFIG_TXTOFFSET_DELTA is not set
280
281#
282# CPU Frequency scaling
283#
284# CONFIG_CPU_FREQ is not set
285
286#
287# Floating point emulation
288#
289
290#
291# At least one emulation must be selected
292#
293CONFIG_FPE_NWFPE=y
294# CONFIG_FPE_NWFPE_XP is not set
295# CONFIG_FPE_FASTFPE is not set
296
297#
298# Userspace binary formats
299#
300CONFIG_BINFMT_ELF=y
301# CONFIG_BINFMT_AOUT is not set
302CONFIG_BINFMT_MISC=y
303
304#
305# Power management options
306#
307CONFIG_PM=y
308CONFIG_PM_LEGACY=y
309# CONFIG_PM_DEBUG is not set
310# CONFIG_DPM_DEBUG is not set
311# CONFIG_PM_SYSFS_DEPRECATED is not set
312# CONFIG_APM_EMULATION is not set
313
314#
315# Networking
316#
317CONFIG_NET=y
318
319#
320# Networking options
321#
322# CONFIG_NETDEBUG is not set
323# CONFIG_PACKET is not set
324CONFIG_UNIX=y
325CONFIG_XFRM=y
326# CONFIG_XFRM_USER is not set
327# CONFIG_XFRM_SUB_POLICY is not set
328# CONFIG_XFRM_MIGRATE is not set
329# CONFIG_NET_KEY is not set
330CONFIG_INET=y
331# CONFIG_IP_MULTICAST is not set
332# CONFIG_IP_ADVANCED_ROUTER is not set
333CONFIG_IP_FIB_HASH=y
334# CONFIG_IP_PNP is not set
335# CONFIG_NET_IPIP is not set
336# CONFIG_NET_IPGRE is not set
337# CONFIG_ARPD is not set
338# CONFIG_SYN_COOKIES is not set
339# CONFIG_INET_AH is not set
340# CONFIG_INET_ESP is not set
341# CONFIG_INET_IPCOMP is not set
342# CONFIG_INET_XFRM_TUNNEL is not set
343# CONFIG_INET_TUNNEL is not set
344CONFIG_INET_XFRM_MODE_TRANSPORT=y
345CONFIG_INET_XFRM_MODE_TUNNEL=y
346CONFIG_INET_XFRM_MODE_BEET=y
347CONFIG_INET_DIAG=y
348CONFIG_INET_TCP_DIAG=y
349# CONFIG_TCP_CONG_ADVANCED is not set
350CONFIG_TCP_CONG_CUBIC=y
351CONFIG_DEFAULT_TCP_CONG="cubic"
352# CONFIG_TCP_MD5SIG is not set
353# CONFIG_IPV6 is not set
354# CONFIG_INET6_XFRM_TUNNEL is not set
355# CONFIG_INET6_TUNNEL is not set
356# CONFIG_NETWORK_SECMARK is not set
357# CONFIG_NETFILTER is not set
358
359#
360# DCCP Configuration (EXPERIMENTAL)
361#
362# CONFIG_IP_DCCP is not set
363
364#
365# SCTP Configuration (EXPERIMENTAL)
366#
367# CONFIG_IP_SCTP is not set
368
369#
370# TIPC Configuration (EXPERIMENTAL)
371#
372# CONFIG_TIPC is not set
373# CONFIG_ATM is not set
374# CONFIG_BRIDGE is not set
375# CONFIG_VLAN_8021Q is not set
376# CONFIG_DECNET is not set
377# CONFIG_LLC2 is not set
378# CONFIG_IPX is not set
379# CONFIG_ATALK is not set
380# CONFIG_X25 is not set
381# CONFIG_LAPB is not set
382# CONFIG_ECONET is not set
383# CONFIG_WAN_ROUTER is not set
384
385#
386# QoS and/or fair queueing
387#
388# CONFIG_NET_SCHED is not set
389
390#
391# Network testing
392#
393# CONFIG_NET_PKTGEN is not set
394# CONFIG_HAMRADIO is not set
395# CONFIG_IRDA is not set
396# CONFIG_BT is not set
397CONFIG_IEEE80211=m
398# CONFIG_IEEE80211_DEBUG is not set
399CONFIG_IEEE80211_CRYPT_WEP=m
400# CONFIG_IEEE80211_CRYPT_CCMP is not set
401# CONFIG_IEEE80211_CRYPT_TKIP is not set
402# CONFIG_IEEE80211_SOFTMAC is not set
403CONFIG_WIRELESS_EXT=y
404
405#
406# Device Drivers
407#
408
409#
410# Generic Driver Options
411#
412# CONFIG_STANDALONE is not set
413CONFIG_PREVENT_FIRMWARE_BUILD=y
414CONFIG_FW_LOADER=y
415# CONFIG_SYS_HYPERVISOR is not set
416
417#
418# Connector - unified userspace <-> kernelspace linker
419#
420# CONFIG_CONNECTOR is not set
421
422#
423# Memory Technology Devices (MTD)
424#
425CONFIG_MTD=m
426# CONFIG_MTD_DEBUG is not set
427# CONFIG_MTD_CONCAT is not set
428CONFIG_MTD_PARTITIONS=y
429# CONFIG_MTD_REDBOOT_PARTS is not set
430# CONFIG_MTD_AFS_PARTS is not set
431
432#
433# User Modules And Translation Layers
434#
435CONFIG_MTD_CHAR=m
436CONFIG_MTD_BLKDEVS=m
437CONFIG_MTD_BLOCK=m
438# CONFIG_MTD_BLOCK_RO is not set
439# CONFIG_FTL is not set
440# CONFIG_NFTL is not set
441# CONFIG_INFTL is not set
442# CONFIG_RFD_FTL is not set
443# CONFIG_SSFDC is not set
444
445#
446# RAM/ROM/Flash chip drivers
447#
448# CONFIG_MTD_CFI is not set
449# CONFIG_MTD_JEDECPROBE is not set
450CONFIG_MTD_MAP_BANK_WIDTH_1=y
451CONFIG_MTD_MAP_BANK_WIDTH_2=y
452CONFIG_MTD_MAP_BANK_WIDTH_4=y
453# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
454# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
455# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
456CONFIG_MTD_CFI_I1=y
457CONFIG_MTD_CFI_I2=y
458# CONFIG_MTD_CFI_I4 is not set
459# CONFIG_MTD_CFI_I8 is not set
460# CONFIG_MTD_RAM is not set
461# CONFIG_MTD_ROM is not set
462# CONFIG_MTD_ABSENT is not set
463# CONFIG_MTD_OBSOLETE_CHIPS is not set
464
465#
466# Mapping drivers for chip access
467#
468# CONFIG_MTD_COMPLEX_MAPPINGS is not set
469# CONFIG_MTD_SHARP_SL is not set
470# CONFIG_MTD_PLATRAM is not set
471
472#
473# Self-contained MTD device drivers
474#
475# CONFIG_MTD_SLRAM is not set
476# CONFIG_MTD_PHRAM is not set
477# CONFIG_MTD_MTDRAM is not set
478# CONFIG_MTD_BLOCK2MTD is not set
479
480#
481# Disk-On-Chip Device Drivers
482#
483# CONFIG_MTD_DOC2000 is not set
484# CONFIG_MTD_DOC2001 is not set
485# CONFIG_MTD_DOC2001PLUS is not set
486
487#
488# NAND Flash Device Drivers
489#
490CONFIG_MTD_NAND=m
491CONFIG_MTD_NAND_VERIFY_WRITE=y
492# CONFIG_MTD_NAND_ECC_SMC is not set
493# CONFIG_MTD_NAND_H1900 is not set
494CONFIG_MTD_NAND_IDS=m
495# CONFIG_MTD_NAND_DISKONCHIP is not set
496# CONFIG_MTD_NAND_SHARPSL is not set
497# CONFIG_MTD_NAND_NANDSIM is not set
498
499#
500# OneNAND Flash Device Drivers
501#
502# CONFIG_MTD_ONENAND is not set
503
504#
505# Parallel port support
506#
507# CONFIG_PARPORT is not set
508
509#
510# Plug and Play support
511#
512# CONFIG_PNPACPI is not set
513
514#
515# Block devices
516#
517# CONFIG_BLK_DEV_COW_COMMON is not set
518CONFIG_BLK_DEV_LOOP=m
519# CONFIG_BLK_DEV_CRYPTOLOOP is not set
520# CONFIG_BLK_DEV_NBD is not set
521# CONFIG_BLK_DEV_UB is not set
522CONFIG_BLK_DEV_RAM=y
523CONFIG_BLK_DEV_RAM_COUNT=16
524CONFIG_BLK_DEV_RAM_SIZE=6144
525CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
526# CONFIG_CDROM_PKTCDVD is not set
527# CONFIG_ATA_OVER_ETH is not set
528
529#
530# ATA/ATAPI/MFM/RLL support
531#
532CONFIG_IDE=m
533CONFIG_IDE_MAX_HWIFS=4
534CONFIG_BLK_DEV_IDE=m
535
536#
537# Please see Documentation/ide.txt for help/info on IDE drives
538#
539# CONFIG_BLK_DEV_IDE_SATA is not set
540CONFIG_BLK_DEV_IDEDISK=m
541# CONFIG_IDEDISK_MULTI_MODE is not set
542# CONFIG_BLK_DEV_IDECS is not set
543# CONFIG_BLK_DEV_IDECD is not set
544# CONFIG_BLK_DEV_IDETAPE is not set
545# CONFIG_BLK_DEV_IDEFLOPPY is not set
546# CONFIG_BLK_DEV_IDESCSI is not set
547# CONFIG_IDE_TASK_IOCTL is not set
548
549#
550# IDE chipset support/bugfixes
551#
552# CONFIG_IDE_GENERIC is not set
553# CONFIG_IDE_ARM is not set
554# CONFIG_BLK_DEV_IDEDMA is not set
555# CONFIG_BLK_DEV_HD is not set
556
557#
558# SCSI device support
559#
560# CONFIG_RAID_ATTRS is not set
561CONFIG_SCSI=m
562# CONFIG_SCSI_TGT is not set
563# CONFIG_SCSI_NETLINK is not set
564# CONFIG_SCSI_PROC_FS is not set
565
566#
567# SCSI support type (disk, tape, CD-ROM)
568#
569# CONFIG_BLK_DEV_SD is not set
570# CONFIG_CHR_DEV_ST is not set
571# CONFIG_CHR_DEV_OSST is not set
572# CONFIG_BLK_DEV_SR is not set
573# CONFIG_CHR_DEV_SG is not set
574# CONFIG_CHR_DEV_SCH is not set
575
576#
577# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
578#
579# CONFIG_SCSI_MULTI_LUN is not set
580# CONFIG_SCSI_CONSTANTS is not set
581# CONFIG_SCSI_LOGGING is not set
582# CONFIG_SCSI_SCAN_ASYNC is not set
583
584#
585# SCSI Transports
586#
587# CONFIG_SCSI_SPI_ATTRS is not set
588# CONFIG_SCSI_FC_ATTRS is not set
589# CONFIG_SCSI_ISCSI_ATTRS is not set
590# CONFIG_SCSI_SAS_ATTRS is not set
591# CONFIG_SCSI_SAS_LIBSAS is not set
592
593#
594# SCSI low-level drivers
595#
596# CONFIG_ISCSI_TCP is not set
597# CONFIG_SCSI_DEBUG is not set
598
599#
600# PCMCIA SCSI adapter support
601#
602# CONFIG_PCMCIA_AHA152X is not set
603# CONFIG_PCMCIA_FDOMAIN is not set
604# CONFIG_PCMCIA_NINJA_SCSI is not set
605# CONFIG_PCMCIA_QLOGIC is not set
606# CONFIG_PCMCIA_SYM53C500 is not set
607
608#
609# Serial ATA (prod) and Parallel ATA (experimental) drivers
610#
611# CONFIG_ATA is not set
612
613#
614# Multi-device support (RAID and LVM)
615#
616# CONFIG_MD is not set
617
618#
619# Fusion MPT device support
620#
621# CONFIG_FUSION is not set
622
623#
624# IEEE 1394 (FireWire) support
625#
626
627#
628# I2O device support
629#
630
631#
632# Network device support
633#
634CONFIG_NETDEVICES=y
635# CONFIG_DUMMY is not set
636# CONFIG_BONDING is not set
637# CONFIG_EQUALIZER is not set
638# CONFIG_TUN is not set
639
640#
641# PHY device support
642#
643
644#
645# Ethernet (10 or 100Mbit)
646#
647# CONFIG_NET_ETHERNET is not set
648
649#
650# Ethernet (1000 Mbit)
651#
652
653#
654# Ethernet (10000 Mbit)
655#
656
657#
658# Token Ring devices
659#
660
661#
662# Wireless LAN (non-hamradio)
663#
664CONFIG_NET_RADIO=y
665# CONFIG_NET_WIRELESS_RTNETLINK is not set
666
667#
668# Obsolete Wireless cards support (pre-802.11)
669#
670# CONFIG_STRIP is not set
671# CONFIG_PCMCIA_WAVELAN is not set
672# CONFIG_PCMCIA_NETWAVE is not set
673
674#
675# Wireless 802.11 Frequency Hopping cards support
676#
677# CONFIG_PCMCIA_RAYCS is not set
678
679#
680# Wireless 802.11b ISA/PCI cards support
681#
682# CONFIG_HERMES is not set
683# CONFIG_ATMEL is not set
684
685#
686# Wireless 802.11b Pcmcia/Cardbus cards support
687#
688# CONFIG_AIRO_CS is not set
689# CONFIG_PCMCIA_WL3501 is not set
690# CONFIG_USB_ZD1201 is not set
691CONFIG_HOSTAP=m
692# CONFIG_HOSTAP_FIRMWARE is not set
693# CONFIG_HOSTAP_CS is not set
694# CONFIG_ACX is not set
695CONFIG_NET_WIRELESS=y
696
697#
698# PCMCIA network device support
699#
700# CONFIG_NET_PCMCIA is not set
701
702#
703# Wan interfaces
704#
705# CONFIG_WAN is not set
706# CONFIG_PPP is not set
707# CONFIG_SLIP is not set
708# CONFIG_SHAPER is not set
709# CONFIG_NETCONSOLE is not set
710# CONFIG_NETPOLL is not set
711# CONFIG_NET_POLL_CONTROLLER is not set
712
713#
714# ISDN subsystem
715#
716# CONFIG_ISDN is not set
717
718#
719# Input device support
720#
721CONFIG_INPUT=y
722# CONFIG_INPUT_FF_MEMLESS is not set
723
724#
725# Userland interfaces
726#
727# CONFIG_INPUT_MOUSEDEV is not set
728# CONFIG_INPUT_JOYDEV is not set
729CONFIG_INPUT_TSDEV=m
730CONFIG_INPUT_TSDEV_SCREEN_X=240
731CONFIG_INPUT_TSDEV_SCREEN_Y=320
732CONFIG_INPUT_EVDEV=m
733# CONFIG_INPUT_EVBUG is not set
734# CONFIG_INPUT_LED_TRIGGER is not set
735
736#
737# Input Device Drivers
738#
739# CONFIG_INPUT_KEYBOARD is not set
740# CONFIG_INPUT_MOUSE is not set
741# CONFIG_INPUT_JOYSTICK is not set
742CONFIG_INPUT_TOUCHSCREEN=y
743# CONFIG_TOUCHSCREEN_GUNZE is not set
744# CONFIG_TOUCHSCREEN_ELO is not set
745# CONFIG_TOUCHSCREEN_MTOUCH is not set
746# CONFIG_TOUCHSCREEN_MK712 is not set
747CONFIG_TOUCHSCREEN_WM97XX=m
748CONFIG_TOUCHSCREEN_WM9705=y
749CONFIG_TOUCHSCREEN_WM9712=y
750CONFIG_TOUCHSCREEN_WM9713=y
751# CONFIG_TOUCHSCREEN_PENMOUNT is not set
752# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
753# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
754# CONFIG_TOUCHSCREEN_UCB1400 is not set
755# CONFIG_INPUT_MISC is not set
756
757#
758# Hardware I/O ports
759#
760# CONFIG_SERIO is not set
761# CONFIG_GAMEPORT is not set
762
763#
764# Character devices
765#
766CONFIG_VT=y
767CONFIG_VT_CONSOLE=y
768CONFIG_HW_CONSOLE=y
769# CONFIG_VT_HW_CONSOLE_BINDING is not set
770# CONFIG_SERIAL_NONSTANDARD is not set
771
772#
773# Serial drivers
774#
775# CONFIG_SERIAL_8250 is not set
776
777#
778# Non-8250 serial port support
779#
780# CONFIG_SERIAL_PXA is not set
781# CONFIG_RS232_SERIAL is not set
782CONFIG_UNIX98_PTYS=y
783# CONFIG_LEGACY_PTYS is not set
784
785#
786# IPMI
787#
788# CONFIG_IPMI_HANDLER is not set
789
790#
791# Watchdog Cards
792#
793# CONFIG_WATCHDOG is not set
794CONFIG_HW_RANDOM=m
795# CONFIG_NVRAM is not set
796# CONFIG_SA1100_RTC is not set
797# CONFIG_DTLK is not set
798# CONFIG_R3964 is not set
799# CONFIG_TIHTC is not set
800
801#
802# PCMCIA character devices
803#
804# CONFIG_SYNCLINK_CS is not set
805# CONFIG_CARDMAN_4000 is not set
806# CONFIG_CARDMAN_4040 is not set
807# CONFIG_RAW_DRIVER is not set
808
809#
810# TPM devices
811#
812# CONFIG_TCG_TPM is not set
813
814#
815# I2C support
816#
817# CONFIG_I2C is not set
818
819#
820# SPI support
821#
822# CONFIG_SPI is not set
823# CONFIG_SPI_MASTER is not set
824
825#
826# Dallas's 1-wire bus
827#
828# CONFIG_W1 is not set
829
830#
831# Hardware Monitoring support
832#
833# CONFIG_HWMON is not set
834# CONFIG_HWMON_VID is not set
835# CONFIG_POWER_SUPPLY is not set
836
837#
838# L3 serial bus support
839#
840# CONFIG_L3 is not set
841
842#
843# Misc devices
844#
845
846#
847# Multimedia Capabilities Port drivers
848#
849# CONFIG_ADC is not set
850
851#
852# Compaq/iPAQ Drivers
853#
854
855#
856# Compaq/HP iPAQ Drivers
857#
858# CONFIG_IPAQ_SLEEVE is not set
859# CONFIG_SLEEVE_DEBUG is not set
860
861#
862# Multifunction device drivers
863#
864# CONFIG_MFD_SM501 is not set
865# CONFIG_HTC_ASIC2 is not set
866# CONFIG_HTC_ASIC3 is not set
867# CONFIG_HTC_PASIC3 is not set
868# CONFIG_HTC_EGPIO is not set
869# CONFIG_HTC_BBKEYS is not set
870# CONFIG_HTC_ASIC3_DS1WM is not set
871# CONFIG_SOC_SAMCOP is not set
872# CONFIG_SOC_HAMCOP is not set
873# CONFIG_SOC_MQ11XX is not set
874CONFIG_SOC_T7L66XB=y
875# CONFIG_SOC_TC6387XB is not set
876CONFIG_SOC_TC6393XB=y
877# CONFIG_SOC_TSC2101 is not set
878# CONFIG_SOC_TSC2200 is not set
879
880#
881# LED devices
882#
883# CONFIG_NEW_LEDS is not set
884
885#
886# LED drivers
887#
888
889#
890# LED Triggers
891#
892# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
893
894#
895# Multimedia devices
896#
897# CONFIG_VIDEO_DEV is not set
898
899#
900# Digital Video Broadcasting Devices
901#
902# CONFIG_DVB is not set
903# CONFIG_USB_DABUSB is not set
904
905#
906# Graphics support
907#
908CONFIG_BACKLIGHT_LCD_SUPPORT=y
909CONFIG_BACKLIGHT_CLASS_DEVICE=y
910CONFIG_LCD_CLASS_DEVICE=y
911CONFIG_BACKLIGHT_CORGI=y
912CONFIG_FB=y
913# CONFIG_FIRMWARE_EDID is not set
914# CONFIG_FB_DDC is not set
915CONFIG_FB_CFB_FILLRECT=y
916CONFIG_FB_CFB_COPYAREA=y
917CONFIG_FB_CFB_IMAGEBLIT=y
918# CONFIG_FB_SVGALIB is not set
919# CONFIG_FB_MACMODES is not set
920# CONFIG_FB_BACKLIGHT is not set
921# CONFIG_FB_MODE_HELPERS is not set
922# CONFIG_FB_TILEBLITTING is not set
923
924#
925# Frame buffer hardware drivers
926#
927# CONFIG_FB_IMAGEON is not set
928# CONFIG_FB_S1D13XXX is not set
929CONFIG_FB_PXA=y
930# CONFIG_FB_PXA_PARAMETERS is not set
931# CONFIG_FB_MBX is not set
932CONFIG_FB_W100=y
933# CONFIG_FB_VIRTUAL is not set
934# CONFIG_FB_VSFB is not set
935
936#
937# Console display driver support
938#
939# CONFIG_VGA_CONSOLE is not set
940CONFIG_DUMMY_CONSOLE=y
941CONFIG_FRAMEBUFFER_CONSOLE=y
942# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
943CONFIG_FONTS=y
944# CONFIG_FONT_8x8 is not set
945# CONFIG_FONT_8x16 is not set
946# CONFIG_FONT_6x11 is not set
947# CONFIG_FONT_7x14 is not set
948# CONFIG_FONT_PEARL_8x8 is not set
949CONFIG_FONT_ACORN_8x8=y
950# CONFIG_FONT_MINI_4x6 is not set
951# CONFIG_FONT_SUN8x16 is not set
952# CONFIG_FONT_SUN12x22 is not set
953# CONFIG_FONT_10x18 is not set
954
955#
956# Logo configuration
957#
958CONFIG_LOGO=y
959# CONFIG_LOGO_LINUX_MONO is not set
960# CONFIG_LOGO_LINUX_VGA16 is not set
961CONFIG_LOGO_LINUX_CLUT224=y
962
963#
964# Sound
965#
966CONFIG_SOUND=y
967
968#
969# Advanced Linux Sound Architecture
970#
971CONFIG_SND=m
972CONFIG_SND_TIMER=m
973CONFIG_SND_PCM=m
974# CONFIG_SND_SEQUENCER is not set
975CONFIG_SND_OSSEMUL=y
976CONFIG_SND_MIXER_OSS=m
977CONFIG_SND_PCM_OSS=m
978CONFIG_SND_PCM_OSS_PLUGINS=y
979CONFIG_SND_DYNAMIC_MINORS=y
980CONFIG_SND_SUPPORT_OLD_API=y
981CONFIG_SND_VERBOSE_PROCFS=y
982CONFIG_SND_VERBOSE_PRINTK=y
983# CONFIG_SND_DEBUG is not set
984
985#
986# Generic devices
987#
988# CONFIG_SND_DUMMY is not set
989# CONFIG_SND_MTPAV is not set
990# CONFIG_SND_SERIAL_U16550 is not set
991# CONFIG_SND_MPU401 is not set
992
993#
994# ALSA ARM devices
995#
996# CONFIG_SND_PXA2XX_AC97 is not set
997# CONFIG_SND_RECON is not set
998
999#
1000# USB devices
1001#
1002# CONFIG_SND_USB_AUDIO is not set
1003
1004#
1005# PCMCIA devices
1006#
1007# CONFIG_SND_VXPOCKET is not set
1008# CONFIG_SND_PDAUDIOCF is not set
1009
1010#
1011# SoC audio support
1012#
1013CONFIG_SND_SOC_AC97_BUS=y
1014CONFIG_SND_SOC=m
1015
1016#
1017# SoC Platforms
1018#
1019
1020#
1021# SoC Audio for the Atmel AT91
1022#
1023
1024#
1025# SoC Audio for the Intel PXA2xx
1026#
1027CONFIG_SND_PXA2XX_SOC=m
1028CONFIG_SND_PXA2XX_SOC_AC97=m
1029CONFIG_SND_PXA2XX_SOC_E740_WM9705=m
1030CONFIG_SND_PXA2XX_SOC_E750_WM9705=m
1031CONFIG_SND_PXA2XX_SOC_E800_WM9712=m
1032# CONFIG_SND_PXA2XX_SOC_MAGICIAN is not set
1033# CONFIG_SND_PXA2XX_SOC_BLUEANGEL is not set
1034# CONFIG_SND_PXA2XX_SOC_H5000 is not set
1035
1036#
1037# SoC Audio for the Freescale i.MX
1038#
1039
1040#
1041# SoC Audio for the Samsung S3C24XX
1042#
1043# CONFIG_SND_SOC_AC97_CODEC is not set
1044# CONFIG_SND_SOC_WM8711 is not set
1045# CONFIG_SND_SOC_WM8510 is not set
1046# CONFIG_SND_SOC_WM8731 is not set
1047# CONFIG_SND_SOC_WM8750 is not set
1048# CONFIG_SND_SOC_WM8753 is not set
1049# CONFIG_SND_SOC_WM8772 is not set
1050# CONFIG_SND_SOC_WM8971 is not set
1051# CONFIG_SND_SOC_WM8956 is not set
1052# CONFIG_SND_SOC_WM8960 is not set
1053# CONFIG_SND_SOC_WM8976 is not set
1054# CONFIG_SND_SOC_WM8974 is not set
1055# CONFIG_SND_SOC_WM8980 is not set
1056CONFIG_SND_SOC_WM9705=m
1057# CONFIG_SND_SOC_WM9713 is not set
1058CONFIG_SND_SOC_WM9712=m
1059# CONFIG_SND_SOC_UDA1380 is not set
1060# CONFIG_SND_SOC_AK4535 is not set
1061
1062#
1063# Open Sound System
1064#
1065# CONFIG_SOUND_PRIME is not set
1066CONFIG_AC97_BUS=m
1067
1068#
1069# HID Devices
1070#
1071CONFIG_HID=y
1072# CONFIG_HID_DEBUG is not set
1073
1074#
1075# USB support
1076#
1077CONFIG_USB_ARCH_HAS_HCD=y
1078CONFIG_USB_ARCH_HAS_OHCI=y
1079# CONFIG_USB_ARCH_HAS_EHCI is not set
1080CONFIG_USB=m
1081CONFIG_USB_DEBUG=y
1082
1083#
1084# Miscellaneous USB options
1085#
1086CONFIG_USB_DEVICEFS=y
1087CONFIG_USB_DYNAMIC_MINORS=y
1088# CONFIG_USB_SUSPEND is not set
1089# CONFIG_USB_OTG is not set
1090
1091#
1092# USB Host Controller Drivers
1093#
1094# CONFIG_USB_ISP116X_HCD is not set
1095# CONFIG_USB_OHCI_HCD is not set
1096# CONFIG_USB_SL811_HCD is not set
1097
1098#
1099# USB Device Class drivers
1100#
1101# CONFIG_USB_ACM is not set
1102# CONFIG_USB_PRINTER is not set
1103
1104#
1105# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
1106#
1107
1108#
1109# may also be needed; see USB_STORAGE Help for more information
1110#
1111CONFIG_USB_STORAGE=m
1112# CONFIG_USB_STORAGE_DEBUG is not set
1113# CONFIG_USB_STORAGE_DATAFAB is not set
1114# CONFIG_USB_STORAGE_FREECOM is not set
1115# CONFIG_USB_STORAGE_ISD200 is not set
1116# CONFIG_USB_STORAGE_DPCM is not set
1117# CONFIG_USB_STORAGE_USBAT is not set
1118# CONFIG_USB_STORAGE_SDDR09 is not set
1119# CONFIG_USB_STORAGE_SDDR55 is not set
1120# CONFIG_USB_STORAGE_JUMPSHOT is not set
1121# CONFIG_USB_STORAGE_ALAUDA is not set
1122# CONFIG_USB_STORAGE_KARMA is not set
1123# CONFIG_USB_LIBUSUAL is not set
1124
1125#
1126# USB Input Devices
1127#
1128# CONFIG_USB_HID is not set
1129
1130#
1131# USB HID Boot Protocol drivers
1132#
1133# CONFIG_USB_KBD is not set
1134# CONFIG_USB_MOUSE is not set
1135# CONFIG_USB_AIPTEK is not set
1136# CONFIG_USB_WACOM is not set
1137# CONFIG_USB_ACECAD is not set
1138# CONFIG_USB_KBTAB is not set
1139# CONFIG_USB_POWERMATE is not set
1140# CONFIG_USB_TOUCHSCREEN is not set
1141# CONFIG_USB_YEALINK is not set
1142# CONFIG_USB_XPAD is not set
1143# CONFIG_USB_ATI_REMOTE is not set
1144# CONFIG_USB_ATI_REMOTE2 is not set
1145# CONFIG_USB_KEYSPAN_REMOTE is not set
1146# CONFIG_USB_APPLETOUCH is not set
1147# CONFIG_USB_GTCO is not set
1148
1149#
1150# USB Imaging devices
1151#
1152# CONFIG_USB_MDC800 is not set
1153# CONFIG_USB_MICROTEK is not set
1154
1155#
1156# USB Network Adapters
1157#
1158# CONFIG_USB_CATC is not set
1159# CONFIG_USB_KAWETH is not set
1160# CONFIG_USB_PEGASUS is not set
1161# CONFIG_USB_RTL8150 is not set
1162# CONFIG_USB_USBNET_MII is not set
1163# CONFIG_USB_USBNET is not set
1164# CONFIG_USB_MON is not set
1165
1166#
1167# USB port drivers
1168#
1169
1170#
1171# USB Serial Converter support
1172#
1173# CONFIG_USB_SERIAL is not set
1174
1175#
1176# USB Miscellaneous drivers
1177#
1178# CONFIG_USB_EMI62 is not set
1179# CONFIG_USB_EMI26 is not set
1180# CONFIG_USB_ADUTUX is not set
1181# CONFIG_USB_AUERSWALD is not set
1182# CONFIG_USB_RIO500 is not set
1183# CONFIG_USB_LEGOTOWER is not set
1184# CONFIG_USB_LCD is not set
1185# CONFIG_USB_BERRY_CHARGE is not set
1186# CONFIG_USB_LED is not set
1187# CONFIG_USB_CYPRESS_CY7C63 is not set
1188# CONFIG_USB_CYTHERM is not set
1189# CONFIG_USB_PHIDGET is not set
1190# CONFIG_USB_IDMOUSE is not set
1191# CONFIG_USB_FTDI_ELAN is not set
1192# CONFIG_USB_APPLEDISPLAY is not set
1193# CONFIG_USB_LD is not set
1194# CONFIG_USB_TRANCEVIBRATOR is not set
1195# CONFIG_USB_IOWARRIOR is not set
1196# CONFIG_USB_TEST is not set
1197
1198#
1199# USB DSL modem support
1200#
1201
1202#
1203# USB Gadget Support
1204#
1205CONFIG_USB_GADGET=y
1206# CONFIG_USB_GADGET_DEBUG_FILES is not set
1207CONFIG_USB_GADGET_SELECTED=y
1208# CONFIG_USB_GADGET_NET2280 is not set
1209CONFIG_USB_GADGET_PXA2XX=y
1210CONFIG_USB_PXA2XX=y
1211# CONFIG_USB_PXA2XX_SMALL is not set
1212# CONFIG_USB_GADGET_PXA27X is not set
1213# CONFIG_USB_GADGET_GOKU is not set
1214# CONFIG_USB_GADGET_MQ11XX is not set
1215# CONFIG_USB_GADGET_LH7A40X is not set
1216# CONFIG_USB_GADGET_S3C2410 is not set
1217# CONFIG_USB_GADGET_OMAP is not set
1218# CONFIG_USB_GADGET_AT91 is not set
1219# CONFIG_USB_GADGET_DUMMY_HCD is not set
1220# CONFIG_USB_GADGET_DUALSPEED is not set
1221# CONFIG_USB_ZERO is not set
1222CONFIG_USB_ETH=y
1223# CONFIG_USB_ETH_RNDIS is not set
1224# CONFIG_USB_GADGETFS is not set
1225# CONFIG_USB_FILE_STORAGE is not set
1226# CONFIG_USB_G_SERIAL is not set
1227# CONFIG_USB_MIDI_GADGET is not set
1228# CONFIG_USB_G_CHAR is not set
1229# CONFIG_USB_PXA2XX_GPIO is not set
1230
1231#
1232# MMC/SD Card support
1233#
1234CONFIG_MMC=y
1235# CONFIG_MMC_DEBUG is not set
1236CONFIG_MMC_BLOCK=y
1237# CONFIG_MMC_PXA is not set
1238CONFIG_MMC_TMIO=y
1239# CONFIG_MMC_SAMCOP is not set
1240
1241#
1242# Real Time Clock
1243#
1244CONFIG_RTC_LIB=y
1245# CONFIG_RTC_CLASS is not set
1246
1247#
1248# File systems
1249#
1250CONFIG_EXT2_FS=y
1251# CONFIG_EXT2_FS_XATTR is not set
1252# CONFIG_EXT2_FS_XIP is not set
1253# CONFIG_EXT3_FS is not set
1254# CONFIG_EXT4DEV_FS is not set
1255# CONFIG_REISERFS_FS is not set
1256# CONFIG_JFS_FS is not set
1257# CONFIG_FS_POSIX_ACL is not set
1258# CONFIG_XFS_FS is not set
1259# CONFIG_GFS2_FS is not set
1260# CONFIG_OCFS2_FS is not set
1261# CONFIG_MINIX_FS is not set
1262# CONFIG_ROMFS_FS is not set
1263CONFIG_INOTIFY=y
1264CONFIG_INOTIFY_USER=y
1265# CONFIG_QUOTA is not set
1266CONFIG_DNOTIFY=y
1267# CONFIG_AUTOFS_FS is not set
1268# CONFIG_AUTOFS4_FS is not set
1269# CONFIG_FUSE_FS is not set
1270
1271#
1272# CD-ROM/DVD Filesystems
1273#
1274# CONFIG_ISO9660_FS is not set
1275# CONFIG_UDF_FS is not set
1276
1277#
1278# DOS/FAT/NT Filesystems
1279#
1280CONFIG_FAT_FS=y
1281# CONFIG_MSDOS_FS is not set
1282CONFIG_VFAT_FS=y
1283CONFIG_FAT_DEFAULT_CODEPAGE=437
1284CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
1285# CONFIG_NTFS_FS is not set
1286
1287#
1288# Pseudo filesystems
1289#
1290CONFIG_PROC_FS=y
1291CONFIG_PROC_SYSCTL=y
1292CONFIG_SYSFS=y
1293CONFIG_TMPFS=y
1294# CONFIG_TMPFS_POSIX_ACL is not set
1295# CONFIG_HUGETLB_PAGE is not set
1296CONFIG_RAMFS=y
1297# CONFIG_CONFIGFS_FS is not set
1298
1299#
1300# Miscellaneous filesystems
1301#
1302# CONFIG_ADFS_FS is not set
1303# CONFIG_AFFS_FS is not set
1304# CONFIG_HFS_FS is not set
1305# CONFIG_HFSPLUS_FS is not set
1306# CONFIG_BEFS_FS is not set
1307# CONFIG_BFS_FS is not set
1308# CONFIG_EFS_FS is not set
1309CONFIG_JFFS2_FS=m
1310CONFIG_JFFS2_FS_DEBUG=0
1311CONFIG_JFFS2_FS_WRITEBUFFER=y
1312# CONFIG_JFFS2_SUMMARY is not set
1313# CONFIG_JFFS2_FS_XATTR is not set
1314# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
1315CONFIG_JFFS2_ZLIB=y
1316CONFIG_JFFS2_RTIME=y
1317# CONFIG_JFFS2_RUBIN is not set
1318# CONFIG_CRAMFS is not set
1319# CONFIG_VXFS_FS is not set
1320# CONFIG_HPFS_FS is not set
1321# CONFIG_QNX4FS_FS is not set
1322# CONFIG_SYSV_FS is not set
1323# CONFIG_UFS_FS is not set
1324
1325#
1326# Network File Systems
1327#
1328CONFIG_NFS_FS=y
1329CONFIG_NFS_V3=y
1330# CONFIG_NFS_V3_ACL is not set
1331# CONFIG_NFS_V4 is not set
1332# CONFIG_NFS_DIRECTIO is not set
1333# CONFIG_NFSD is not set
1334CONFIG_LOCKD=y
1335CONFIG_LOCKD_V4=y
1336CONFIG_NFS_COMMON=y
1337CONFIG_SUNRPC=y
1338# CONFIG_RPCSEC_GSS_KRB5 is not set
1339# CONFIG_RPCSEC_GSS_SPKM3 is not set
1340# CONFIG_SMB_FS is not set
1341# CONFIG_CIFS is not set
1342# CONFIG_NCP_FS is not set
1343# CONFIG_CODA_FS is not set
1344# CONFIG_AFS_FS is not set
1345# CONFIG_9P_FS is not set
1346
1347#
1348# Partition Types
1349#
1350CONFIG_PARTITION_ADVANCED=y
1351# CONFIG_ACORN_PARTITION is not set
1352# CONFIG_OSF_PARTITION is not set
1353# CONFIG_AMIGA_PARTITION is not set
1354# CONFIG_ATARI_PARTITION is not set
1355# CONFIG_MAC_PARTITION is not set
1356CONFIG_MSDOS_PARTITION=y
1357# CONFIG_BSD_DISKLABEL is not set
1358# CONFIG_MINIX_SUBPARTITION is not set
1359# CONFIG_SOLARIS_X86_PARTITION is not set
1360# CONFIG_UNIXWARE_DISKLABEL is not set
1361# CONFIG_LDM_PARTITION is not set
1362# CONFIG_SGI_PARTITION is not set
1363# CONFIG_ULTRIX_PARTITION is not set
1364# CONFIG_SUN_PARTITION is not set
1365# CONFIG_KARMA_PARTITION is not set
1366# CONFIG_EFI_PARTITION is not set
1367
1368#
1369# Native Language Support
1370#
1371CONFIG_NLS=y
1372CONFIG_NLS_DEFAULT="iso8859-1"
1373CONFIG_NLS_CODEPAGE_437=y
1374# CONFIG_NLS_CODEPAGE_737 is not set
1375# CONFIG_NLS_CODEPAGE_775 is not set
1376# CONFIG_NLS_CODEPAGE_850 is not set
1377# CONFIG_NLS_CODEPAGE_852 is not set
1378# CONFIG_NLS_CODEPAGE_855 is not set
1379# CONFIG_NLS_CODEPAGE_857 is not set
1380# CONFIG_NLS_CODEPAGE_860 is not set
1381# CONFIG_NLS_CODEPAGE_861 is not set
1382# CONFIG_NLS_CODEPAGE_862 is not set
1383# CONFIG_NLS_CODEPAGE_863 is not set
1384# CONFIG_NLS_CODEPAGE_864 is not set
1385# CONFIG_NLS_CODEPAGE_865 is not set
1386# CONFIG_NLS_CODEPAGE_866 is not set
1387# CONFIG_NLS_CODEPAGE_869 is not set
1388# CONFIG_NLS_CODEPAGE_936 is not set
1389# CONFIG_NLS_CODEPAGE_950 is not set
1390# CONFIG_NLS_CODEPAGE_932 is not set
1391# CONFIG_NLS_CODEPAGE_949 is not set
1392# CONFIG_NLS_CODEPAGE_874 is not set
1393# CONFIG_NLS_ISO8859_8 is not set
1394# CONFIG_NLS_CODEPAGE_1250 is not set
1395# CONFIG_NLS_CODEPAGE_1251 is not set
1396# CONFIG_NLS_ASCII is not set
1397CONFIG_NLS_ISO8859_1=y
1398# CONFIG_NLS_ISO8859_2 is not set
1399# CONFIG_NLS_ISO8859_3 is not set
1400# CONFIG_NLS_ISO8859_4 is not set
1401# CONFIG_NLS_ISO8859_5 is not set
1402# CONFIG_NLS_ISO8859_6 is not set
1403# CONFIG_NLS_ISO8859_7 is not set
1404# CONFIG_NLS_ISO8859_9 is not set
1405# CONFIG_NLS_ISO8859_13 is not set
1406# CONFIG_NLS_ISO8859_14 is not set
1407# CONFIG_NLS_ISO8859_15 is not set
1408# CONFIG_NLS_KOI8_R is not set
1409# CONFIG_NLS_KOI8_U is not set
1410# CONFIG_NLS_UTF8 is not set
1411
1412#
1413# Distributed Lock Manager
1414#
1415# CONFIG_DLM is not set
1416
1417#
1418# Profiling support
1419#
1420# CONFIG_PROFILING is not set
1421
1422#
1423# Kernel hacking
1424#
1425# CONFIG_PRINTK_TIME is not set
1426CONFIG_ENABLE_MUST_CHECK=y
1427# CONFIG_MAGIC_SYSRQ is not set
1428# CONFIG_UNUSED_SYMBOLS is not set
1429# CONFIG_DEBUG_FS is not set
1430# CONFIG_HEADERS_CHECK is not set
1431# CONFIG_DEBUG_KERNEL is not set
1432CONFIG_LOG_BUF_SHIFT=14
1433# CONFIG_DEBUG_BUGVERBOSE is not set
1434CONFIG_FRAME_POINTER=y
1435# CONFIG_DEBUG_USER is not set
1436
1437#
1438# Security options
1439#
1440# CONFIG_KEYS is not set
1441# CONFIG_SECURITY is not set
1442
1443#
1444# Cryptographic options
1445#
1446CONFIG_CRYPTO=y
1447CONFIG_CRYPTO_ALGAPI=m
1448CONFIG_CRYPTO_BLKCIPHER=m
1449CONFIG_CRYPTO_MANAGER=m
1450# CONFIG_CRYPTO_HMAC is not set
1451# CONFIG_CRYPTO_XCBC is not set
1452# CONFIG_CRYPTO_NULL is not set
1453# CONFIG_CRYPTO_MD4 is not set
1454# CONFIG_CRYPTO_MD5 is not set
1455# CONFIG_CRYPTO_SHA1 is not set
1456# CONFIG_CRYPTO_SHA256 is not set
1457# CONFIG_CRYPTO_SHA512 is not set
1458# CONFIG_CRYPTO_WP512 is not set
1459# CONFIG_CRYPTO_TGR192 is not set
1460# CONFIG_CRYPTO_GF128MUL is not set
1461CONFIG_CRYPTO_ECB=m
1462CONFIG_CRYPTO_CBC=m
1463CONFIG_CRYPTO_PCBC=m
1464# CONFIG_CRYPTO_LRW is not set
1465# CONFIG_CRYPTO_DES is not set
1466# CONFIG_CRYPTO_FCRYPT is not set
1467# CONFIG_CRYPTO_BLOWFISH is not set
1468# CONFIG_CRYPTO_TWOFISH is not set
1469# CONFIG_CRYPTO_SERPENT is not set
1470# CONFIG_CRYPTO_AES is not set
1471# CONFIG_CRYPTO_CAST5 is not set
1472# CONFIG_CRYPTO_CAST6 is not set
1473# CONFIG_CRYPTO_TEA is not set
1474CONFIG_CRYPTO_ARC4=m
1475# CONFIG_CRYPTO_KHAZAD is not set
1476# CONFIG_CRYPTO_ANUBIS is not set
1477# CONFIG_CRYPTO_DEFLATE is not set
1478# CONFIG_CRYPTO_MICHAEL_MIC is not set
1479# CONFIG_CRYPTO_CRC32C is not set
1480# CONFIG_CRYPTO_CAMELLIA is not set
1481# CONFIG_CRYPTO_TEST is not set
1482
1483#
1484# Hardware crypto devices
1485#
1486
1487#
1488# Library routines
1489#
1490CONFIG_BITREVERSE=y
1491# CONFIG_CRC_CCITT is not set
1492# CONFIG_CRC16 is not set
1493CONFIG_CRC32=y
1494# CONFIG_LIBCRC32C is not set
1495CONFIG_ZLIB_INFLATE=m
1496CONFIG_ZLIB_DEFLATE=m
1497CONFIG_PLIST=y
1498CONFIG_HAS_IOMEM=y
1499CONFIG_HAS_IOPORT=y
diff --git a/arch/arm/configs/iop13xx_defconfig b/arch/arm/configs/iop13xx_defconfig
index add03c9e5553..988b4d13e76f 100644
--- a/arch/arm/configs/iop13xx_defconfig
+++ b/arch/arm/configs/iop13xx_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.22 3# Linux kernel version: 2.6.24-rc5
4# Thu Jul 19 15:57:52 2007 4# Wed Dec 12 16:11:03 2007
5# 5#
6CONFIG_ARM=y 6CONFIG_ARM=y
7CONFIG_SYS_SUPPORTS_APM_EMULATION=y 7CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -26,15 +26,11 @@ CONFIG_VECTORS_BASE=0xffff0000
26CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" 26CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
27 27
28# 28#
29# Code maturity level options 29# General setup
30# 30#
31CONFIG_EXPERIMENTAL=y 31CONFIG_EXPERIMENTAL=y
32CONFIG_BROKEN_ON_SMP=y 32CONFIG_BROKEN_ON_SMP=y
33CONFIG_INIT_ENV_ARG_LIMIT=32 33CONFIG_INIT_ENV_ARG_LIMIT=32
34
35#
36# General setup
37#
38CONFIG_LOCALVERSION="" 34CONFIG_LOCALVERSION=""
39# CONFIG_LOCALVERSION_AUTO is not set 35# CONFIG_LOCALVERSION_AUTO is not set
40CONFIG_SWAP=y 36CONFIG_SWAP=y
@@ -45,10 +41,15 @@ CONFIG_BSD_PROCESS_ACCT=y
45# CONFIG_BSD_PROCESS_ACCT_V3 is not set 41# CONFIG_BSD_PROCESS_ACCT_V3 is not set
46# CONFIG_TASKSTATS is not set 42# CONFIG_TASKSTATS is not set
47# CONFIG_USER_NS is not set 43# CONFIG_USER_NS is not set
44# CONFIG_PID_NS is not set
48# CONFIG_AUDIT is not set 45# CONFIG_AUDIT is not set
49CONFIG_IKCONFIG=y 46CONFIG_IKCONFIG=y
50CONFIG_IKCONFIG_PROC=y 47CONFIG_IKCONFIG_PROC=y
51CONFIG_LOG_BUF_SHIFT=14 48CONFIG_LOG_BUF_SHIFT=14
49# CONFIG_CGROUPS is not set
50CONFIG_FAIR_GROUP_SCHED=y
51CONFIG_FAIR_USER_SCHED=y
52# CONFIG_FAIR_CGROUP_SCHED is not set
52CONFIG_SYSFS_DEPRECATED=y 53CONFIG_SYSFS_DEPRECATED=y
53# CONFIG_RELAY is not set 54# CONFIG_RELAY is not set
54CONFIG_BLK_DEV_INITRD=y 55CONFIG_BLK_DEV_INITRD=y
@@ -69,7 +70,6 @@ CONFIG_FUTEX=y
69CONFIG_ANON_INODES=y 70CONFIG_ANON_INODES=y
70CONFIG_EPOLL=y 71CONFIG_EPOLL=y
71CONFIG_SIGNALFD=y 72CONFIG_SIGNALFD=y
72CONFIG_TIMERFD=y
73CONFIG_EVENTFD=y 73CONFIG_EVENTFD=y
74CONFIG_SHMEM=y 74CONFIG_SHMEM=y
75CONFIG_VM_EVENT_COUNTERS=y 75CONFIG_VM_EVENT_COUNTERS=y
@@ -130,6 +130,7 @@ CONFIG_ARCH_IOP13XX=y
130# CONFIG_ARCH_L7200 is not set 130# CONFIG_ARCH_L7200 is not set
131# CONFIG_ARCH_KS8695 is not set 131# CONFIG_ARCH_KS8695 is not set
132# CONFIG_ARCH_NS9XXX is not set 132# CONFIG_ARCH_NS9XXX is not set
133# CONFIG_ARCH_MXC is not set
133# CONFIG_ARCH_PNX4008 is not set 134# CONFIG_ARCH_PNX4008 is not set
134# CONFIG_ARCH_PXA is not set 135# CONFIG_ARCH_PXA is not set
135# CONFIG_ARCH_RPC is not set 136# CONFIG_ARCH_RPC is not set
@@ -151,9 +152,12 @@ CONFIG_MACH_IQ81340SC=y
151CONFIG_MACH_IQ81340MC=y 152CONFIG_MACH_IQ81340MC=y
152 153
153# 154#
154# IOP13XX IMU Support 155# Boot options
156#
157
158#
159# Power management
155# 160#
156# CONFIG_IOP_IMU is not set
157CONFIG_PLAT_IOP=y 161CONFIG_PLAT_IOP=y
158 162
159# 163#
@@ -185,10 +189,7 @@ CONFIG_PCI=y
185CONFIG_PCI_SYSCALL=y 189CONFIG_PCI_SYSCALL=y
186CONFIG_ARCH_SUPPORTS_MSI=y 190CONFIG_ARCH_SUPPORTS_MSI=y
187# CONFIG_PCI_MSI is not set 191# CONFIG_PCI_MSI is not set
188 192CONFIG_PCI_LEGACY=y
189#
190# PCCARD (PCMCIA/CardBus) support
191#
192# CONFIG_PCCARD is not set 193# CONFIG_PCCARD is not set
193 194
194# 195#
@@ -207,6 +208,7 @@ CONFIG_FLATMEM_MANUAL=y
207CONFIG_FLATMEM=y 208CONFIG_FLATMEM=y
208CONFIG_FLAT_NODE_MEM_MAP=y 209CONFIG_FLAT_NODE_MEM_MAP=y
209# CONFIG_SPARSEMEM_STATIC is not set 210# CONFIG_SPARSEMEM_STATIC is not set
211# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
210CONFIG_SPLIT_PTLOCK_CPUS=4096 212CONFIG_SPLIT_PTLOCK_CPUS=4096
211# CONFIG_RESOURCES_64BIT is not set 213# CONFIG_RESOURCES_64BIT is not set
212CONFIG_ZONE_DMA_FLAG=1 214CONFIG_ZONE_DMA_FLAG=1
@@ -246,6 +248,7 @@ CONFIG_BINFMT_AOUT=y
246# Power management options 248# Power management options
247# 249#
248# CONFIG_PM is not set 250# CONFIG_PM is not set
251CONFIG_SUSPEND_UP_POSSIBLE=y
249 252
250# 253#
251# Networking 254# Networking
@@ -285,6 +288,7 @@ CONFIG_IP_PNP_BOOTP=y
285CONFIG_INET_XFRM_MODE_TRANSPORT=y 288CONFIG_INET_XFRM_MODE_TRANSPORT=y
286CONFIG_INET_XFRM_MODE_TUNNEL=y 289CONFIG_INET_XFRM_MODE_TUNNEL=y
287CONFIG_INET_XFRM_MODE_BEET=y 290CONFIG_INET_XFRM_MODE_BEET=y
291# CONFIG_INET_LRO is not set
288CONFIG_INET_DIAG=y 292CONFIG_INET_DIAG=y
289CONFIG_INET_TCP_DIAG=y 293CONFIG_INET_TCP_DIAG=y
290# CONFIG_TCP_CONG_ADVANCED is not set 294# CONFIG_TCP_CONG_ADVANCED is not set
@@ -324,10 +328,6 @@ CONFIG_IPV6=y
324# CONFIG_LAPB is not set 328# CONFIG_LAPB is not set
325# CONFIG_ECONET is not set 329# CONFIG_ECONET is not set
326# CONFIG_WAN_ROUTER is not set 330# CONFIG_WAN_ROUTER is not set
327
328#
329# QoS and/or fair queueing
330#
331# CONFIG_NET_SCHED is not set 331# CONFIG_NET_SCHED is not set
332 332
333# 333#
@@ -356,6 +356,7 @@ CONFIG_IPV6=y
356# 356#
357# Generic Driver Options 357# Generic Driver Options
358# 358#
359CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
359CONFIG_STANDALONE=y 360CONFIG_STANDALONE=y
360CONFIG_PREVENT_FIRMWARE_BUILD=y 361CONFIG_PREVENT_FIRMWARE_BUILD=y
361# CONFIG_FW_LOADER is not set 362# CONFIG_FW_LOADER is not set
@@ -383,6 +384,7 @@ CONFIG_MTD_BLOCK=y
383# CONFIG_INFTL is not set 384# CONFIG_INFTL is not set
384# CONFIG_RFD_FTL is not set 385# CONFIG_RFD_FTL is not set
385# CONFIG_SSFDC is not set 386# CONFIG_SSFDC is not set
387# CONFIG_MTD_OOPS is not set
386 388
387# 389#
388# RAM/ROM/Flash chip drivers 390# RAM/ROM/Flash chip drivers
@@ -423,6 +425,7 @@ CONFIG_MTD_PHYSMAP_START=0xfa000000
423CONFIG_MTD_PHYSMAP_LEN=0x0 425CONFIG_MTD_PHYSMAP_LEN=0x0
424CONFIG_MTD_PHYSMAP_BANKWIDTH=2 426CONFIG_MTD_PHYSMAP_BANKWIDTH=2
425# CONFIG_MTD_ARM_INTEGRATOR is not set 427# CONFIG_MTD_ARM_INTEGRATOR is not set
428# CONFIG_MTD_INTEL_VR_NOR is not set
426# CONFIG_MTD_PLATRAM is not set 429# CONFIG_MTD_PLATRAM is not set
427 430
428# 431#
@@ -463,6 +466,11 @@ CONFIG_BLK_DEV_RAM_SIZE=8192
463CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 466CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
464# CONFIG_CDROM_PKTCDVD is not set 467# CONFIG_CDROM_PKTCDVD is not set
465# CONFIG_ATA_OVER_ETH is not set 468# CONFIG_ATA_OVER_ETH is not set
469CONFIG_MISC_DEVICES=y
470# CONFIG_PHANTOM is not set
471# CONFIG_EEPROM_93CX6 is not set
472# CONFIG_SGI_IOC4 is not set
473# CONFIG_TIFM_CORE is not set
466 474
467# 475#
468# SCSI device support 476# SCSI device support
@@ -499,12 +507,9 @@ CONFIG_SCSI_WAIT_SCAN=m
499# CONFIG_SCSI_SPI_ATTRS is not set 507# CONFIG_SCSI_SPI_ATTRS is not set
500# CONFIG_SCSI_FC_ATTRS is not set 508# CONFIG_SCSI_FC_ATTRS is not set
501CONFIG_SCSI_ISCSI_ATTRS=y 509CONFIG_SCSI_ISCSI_ATTRS=y
502CONFIG_SCSI_SAS_ATTRS=y
503# CONFIG_SCSI_SAS_LIBSAS is not set 510# CONFIG_SCSI_SAS_LIBSAS is not set
504 511# CONFIG_SCSI_SRP_ATTRS is not set
505# 512CONFIG_SCSI_LOWLEVEL=y
506# SCSI low-level drivers
507#
508# CONFIG_ISCSI_TCP is not set 513# CONFIG_ISCSI_TCP is not set
509# CONFIG_BLK_DEV_3W_XXXX_RAID is not set 514# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
510# CONFIG_SCSI_3W_9XXX is not set 515# CONFIG_SCSI_3W_9XXX is not set
@@ -515,6 +520,7 @@ CONFIG_SCSI_SAS_ATTRS=y
515# CONFIG_SCSI_AIC79XX is not set 520# CONFIG_SCSI_AIC79XX is not set
516# CONFIG_SCSI_AIC94XX is not set 521# CONFIG_SCSI_AIC94XX is not set
517# CONFIG_SCSI_DPT_I2O is not set 522# CONFIG_SCSI_DPT_I2O is not set
523# CONFIG_SCSI_ADVANSYS is not set
518# CONFIG_SCSI_ARCMSR is not set 524# CONFIG_SCSI_ARCMSR is not set
519# CONFIG_MEGARAID_NEWGEN is not set 525# CONFIG_MEGARAID_NEWGEN is not set
520# CONFIG_MEGARAID_LEGACY is not set 526# CONFIG_MEGARAID_LEGACY is not set
@@ -555,14 +561,8 @@ CONFIG_BLK_DEV_DM=y
555# CONFIG_DM_ZERO is not set 561# CONFIG_DM_ZERO is not set
556# CONFIG_DM_MULTIPATH is not set 562# CONFIG_DM_MULTIPATH is not set
557# CONFIG_DM_DELAY is not set 563# CONFIG_DM_DELAY is not set
558 564# CONFIG_DM_UEVENT is not set
559#
560# Fusion MPT device support
561#
562# CONFIG_FUSION is not set 565# CONFIG_FUSION is not set
563# CONFIG_FUSION_SPI is not set
564# CONFIG_FUSION_FC is not set
565# CONFIG_FUSION_SAS is not set
566 566
567# 567#
568# IEEE 1394 (FireWire) support 568# IEEE 1394 (FireWire) support
@@ -577,6 +577,8 @@ CONFIG_NETDEVICES=y
577# CONFIG_MACVLAN is not set 577# CONFIG_MACVLAN is not set
578# CONFIG_EQUALIZER is not set 578# CONFIG_EQUALIZER is not set
579# CONFIG_TUN is not set 579# CONFIG_TUN is not set
580# CONFIG_VETH is not set
581# CONFIG_IP1000 is not set
580# CONFIG_ARCNET is not set 582# CONFIG_ARCNET is not set
581# CONFIG_NET_ETHERNET is not set 583# CONFIG_NET_ETHERNET is not set
582CONFIG_NETDEV_1000=y 584CONFIG_NETDEV_1000=y
@@ -585,6 +587,7 @@ CONFIG_NETDEV_1000=y
585CONFIG_E1000=y 587CONFIG_E1000=y
586CONFIG_E1000_NAPI=y 588CONFIG_E1000_NAPI=y
587# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set 589# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
590# CONFIG_E1000E is not set
588# CONFIG_NS83820 is not set 591# CONFIG_NS83820 is not set
589# CONFIG_HAMACHI is not set 592# CONFIG_HAMACHI is not set
590# CONFIG_YELLOWFIN is not set 593# CONFIG_YELLOWFIN is not set
@@ -592,6 +595,7 @@ CONFIG_E1000_NAPI=y
592# CONFIG_SIS190 is not set 595# CONFIG_SIS190 is not set
593# CONFIG_SKGE is not set 596# CONFIG_SKGE is not set
594# CONFIG_SKY2 is not set 597# CONFIG_SKY2 is not set
598# CONFIG_SK98LIN is not set
595# CONFIG_VIA_VELOCITY is not set 599# CONFIG_VIA_VELOCITY is not set
596# CONFIG_TIGON3 is not set 600# CONFIG_TIGON3 is not set
597# CONFIG_BNX2 is not set 601# CONFIG_BNX2 is not set
@@ -600,11 +604,14 @@ CONFIG_E1000_NAPI=y
600CONFIG_NETDEV_10000=y 604CONFIG_NETDEV_10000=y
601# CONFIG_CHELSIO_T1 is not set 605# CONFIG_CHELSIO_T1 is not set
602# CONFIG_CHELSIO_T3 is not set 606# CONFIG_CHELSIO_T3 is not set
607# CONFIG_IXGBE is not set
603# CONFIG_IXGB is not set 608# CONFIG_IXGB is not set
604# CONFIG_S2IO is not set 609# CONFIG_S2IO is not set
605# CONFIG_MYRI10GE is not set 610# CONFIG_MYRI10GE is not set
606# CONFIG_NETXEN_NIC is not set 611# CONFIG_NETXEN_NIC is not set
612# CONFIG_NIU is not set
607# CONFIG_MLX4_CORE is not set 613# CONFIG_MLX4_CORE is not set
614# CONFIG_TEHUTI is not set
608# CONFIG_TR is not set 615# CONFIG_TR is not set
609 616
610# 617#
@@ -639,7 +646,6 @@ CONFIG_INPUT_MOUSEDEV=y
639CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 646CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
640CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 647CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
641# CONFIG_INPUT_JOYDEV is not set 648# CONFIG_INPUT_JOYDEV is not set
642# CONFIG_INPUT_TSDEV is not set
643# CONFIG_INPUT_EVDEV is not set 649# CONFIG_INPUT_EVDEV is not set
644# CONFIG_INPUT_EVBUG is not set 650# CONFIG_INPUT_EVBUG is not set
645 651
@@ -688,12 +694,10 @@ CONFIG_UNIX98_PTYS=y
688CONFIG_LEGACY_PTYS=y 694CONFIG_LEGACY_PTYS=y
689CONFIG_LEGACY_PTY_COUNT=256 695CONFIG_LEGACY_PTY_COUNT=256
690# CONFIG_IPMI_HANDLER is not set 696# CONFIG_IPMI_HANDLER is not set
691# CONFIG_WATCHDOG is not set
692CONFIG_HW_RANDOM=y 697CONFIG_HW_RANDOM=y
693# CONFIG_NVRAM is not set 698# CONFIG_NVRAM is not set
694# CONFIG_R3964 is not set 699# CONFIG_R3964 is not set
695# CONFIG_APPLICOM is not set 700# CONFIG_APPLICOM is not set
696# CONFIG_DRM is not set
697# CONFIG_RAW_DRIVER is not set 701# CONFIG_RAW_DRIVER is not set
698# CONFIG_TCG_TPM is not set 702# CONFIG_TCG_TPM is not set
699CONFIG_DEVPORT=y 703CONFIG_DEVPORT=y
@@ -758,9 +762,9 @@ CONFIG_I2C_IOP3XX=y
758# CONFIG_SPI is not set 762# CONFIG_SPI is not set
759# CONFIG_SPI_MASTER is not set 763# CONFIG_SPI_MASTER is not set
760# CONFIG_W1 is not set 764# CONFIG_W1 is not set
765# CONFIG_POWER_SUPPLY is not set
761CONFIG_HWMON=y 766CONFIG_HWMON=y
762# CONFIG_HWMON_VID is not set 767# CONFIG_HWMON_VID is not set
763# CONFIG_SENSORS_ABITUGURU is not set
764# CONFIG_SENSORS_AD7418 is not set 768# CONFIG_SENSORS_AD7418 is not set
765# CONFIG_SENSORS_ADM1021 is not set 769# CONFIG_SENSORS_ADM1021 is not set
766# CONFIG_SENSORS_ADM1025 is not set 770# CONFIG_SENSORS_ADM1025 is not set
@@ -768,12 +772,13 @@ CONFIG_HWMON=y
768# CONFIG_SENSORS_ADM1029 is not set 772# CONFIG_SENSORS_ADM1029 is not set
769# CONFIG_SENSORS_ADM1031 is not set 773# CONFIG_SENSORS_ADM1031 is not set
770# CONFIG_SENSORS_ADM9240 is not set 774# CONFIG_SENSORS_ADM9240 is not set
771# CONFIG_SENSORS_ASB100 is not set 775# CONFIG_SENSORS_ADT7470 is not set
772# CONFIG_SENSORS_ATXP1 is not set 776# CONFIG_SENSORS_ATXP1 is not set
773# CONFIG_SENSORS_DS1621 is not set 777# CONFIG_SENSORS_DS1621 is not set
778# CONFIG_SENSORS_I5K_AMB is not set
774# CONFIG_SENSORS_F71805F is not set 779# CONFIG_SENSORS_F71805F is not set
775# CONFIG_SENSORS_FSCHER is not set 780# CONFIG_SENSORS_F71882FG is not set
776# CONFIG_SENSORS_FSCPOS is not set 781# CONFIG_SENSORS_F75375S is not set
777# CONFIG_SENSORS_GL518SM is not set 782# CONFIG_SENSORS_GL518SM is not set
778# CONFIG_SENSORS_GL520SM is not set 783# CONFIG_SENSORS_GL520SM is not set
779# CONFIG_SENSORS_IT87 is not set 784# CONFIG_SENSORS_IT87 is not set
@@ -787,14 +792,17 @@ CONFIG_HWMON=y
787# CONFIG_SENSORS_LM87 is not set 792# CONFIG_SENSORS_LM87 is not set
788# CONFIG_SENSORS_LM90 is not set 793# CONFIG_SENSORS_LM90 is not set
789# CONFIG_SENSORS_LM92 is not set 794# CONFIG_SENSORS_LM92 is not set
795# CONFIG_SENSORS_LM93 is not set
790# CONFIG_SENSORS_MAX1619 is not set 796# CONFIG_SENSORS_MAX1619 is not set
791# CONFIG_SENSORS_MAX6650 is not set 797# CONFIG_SENSORS_MAX6650 is not set
792# CONFIG_SENSORS_PC87360 is not set 798# CONFIG_SENSORS_PC87360 is not set
793# CONFIG_SENSORS_PC87427 is not set 799# CONFIG_SENSORS_PC87427 is not set
794# CONFIG_SENSORS_SIS5595 is not set 800# CONFIG_SENSORS_SIS5595 is not set
801# CONFIG_SENSORS_DME1737 is not set
795# CONFIG_SENSORS_SMSC47M1 is not set 802# CONFIG_SENSORS_SMSC47M1 is not set
796# CONFIG_SENSORS_SMSC47M192 is not set 803# CONFIG_SENSORS_SMSC47M192 is not set
797# CONFIG_SENSORS_SMSC47B397 is not set 804# CONFIG_SENSORS_SMSC47B397 is not set
805# CONFIG_SENSORS_THMC50 is not set
798# CONFIG_SENSORS_VIA686A is not set 806# CONFIG_SENSORS_VIA686A is not set
799# CONFIG_SENSORS_VT1211 is not set 807# CONFIG_SENSORS_VT1211 is not set
800# CONFIG_SENSORS_VT8231 is not set 808# CONFIG_SENSORS_VT8231 is not set
@@ -806,29 +814,18 @@ CONFIG_HWMON=y
806# CONFIG_SENSORS_W83627HF is not set 814# CONFIG_SENSORS_W83627HF is not set
807# CONFIG_SENSORS_W83627EHF is not set 815# CONFIG_SENSORS_W83627EHF is not set
808# CONFIG_HWMON_DEBUG_CHIP is not set 816# CONFIG_HWMON_DEBUG_CHIP is not set
809CONFIG_MISC_DEVICES=y 817# CONFIG_WATCHDOG is not set
810# CONFIG_PHANTOM is not set
811# CONFIG_EEPROM_93CX6 is not set
812# CONFIG_SGI_IOC4 is not set
813# CONFIG_TIFM_CORE is not set
814
815#
816# Multifunction device drivers
817#
818# CONFIG_MFD_SM501 is not set
819
820#
821# LED devices
822#
823# CONFIG_NEW_LEDS is not set
824 818
825# 819#
826# LED drivers 820# Sonics Silicon Backplane
827# 821#
822CONFIG_SSB_POSSIBLE=y
823# CONFIG_SSB is not set
828 824
829# 825#
830# LED Triggers 826# Multifunction device drivers
831# 827#
828# CONFIG_MFD_SM501 is not set
832 829
833# 830#
834# Multimedia devices 831# Multimedia devices
@@ -840,14 +837,16 @@ CONFIG_DAB=y
840# 837#
841# Graphics support 838# Graphics support
842# 839#
840# CONFIG_DRM is not set
841# CONFIG_VGASTATE is not set
842# CONFIG_VIDEO_OUTPUT_CONTROL is not set
843# CONFIG_FB is not set
843# CONFIG_BACKLIGHT_LCD_SUPPORT is not set 844# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
844 845
845# 846#
846# Display device support 847# Display device support
847# 848#
848# CONFIG_DISPLAY_SUPPORT is not set 849# CONFIG_DISPLAY_SUPPORT is not set
849# CONFIG_VGASTATE is not set
850# CONFIG_FB is not set
851 850
852# 851#
853# Console display driver support 852# Console display driver support
@@ -862,6 +861,7 @@ CONFIG_DUMMY_CONSOLE=y
862CONFIG_HID_SUPPORT=y 861CONFIG_HID_SUPPORT=y
863CONFIG_HID=y 862CONFIG_HID=y
864# CONFIG_HID_DEBUG is not set 863# CONFIG_HID_DEBUG is not set
864# CONFIG_HIDRAW is not set
865CONFIG_USB_SUPPORT=y 865CONFIG_USB_SUPPORT=y
866CONFIG_USB_ARCH_HAS_HCD=y 866CONFIG_USB_ARCH_HAS_HCD=y
867CONFIG_USB_ARCH_HAS_OHCI=y 867CONFIG_USB_ARCH_HAS_OHCI=y
@@ -877,16 +877,15 @@ CONFIG_USB_ARCH_HAS_EHCI=y
877# 877#
878# CONFIG_USB_GADGET is not set 878# CONFIG_USB_GADGET is not set
879# CONFIG_MMC is not set 879# CONFIG_MMC is not set
880 880# CONFIG_NEW_LEDS is not set
881#
882# Real Time Clock
883#
884CONFIG_RTC_LIB=y 881CONFIG_RTC_LIB=y
885# CONFIG_RTC_CLASS is not set 882# CONFIG_RTC_CLASS is not set
883CONFIG_DMADEVICES=y
886 884
887# 885#
888# DMA Engine support 886# DMA Devices
889# 887#
888CONFIG_INTEL_IOP_ADMA=y
890CONFIG_DMA_ENGINE=y 889CONFIG_DMA_ENGINE=y
891 890
892# 891#
@@ -895,12 +894,6 @@ CONFIG_DMA_ENGINE=y
895# CONFIG_NET_DMA is not set 894# CONFIG_NET_DMA is not set
896 895
897# 896#
898# DMA Devices
899#
900# CONFIG_INTEL_IOATDMA is not set
901CONFIG_INTEL_IOP_ADMA=y
902
903#
904# File systems 897# File systems
905# 898#
906CONFIG_EXT2_FS=y 899CONFIG_EXT2_FS=y
@@ -912,7 +905,6 @@ CONFIG_EXT3_FS_XATTR=y
912# CONFIG_EXT3_FS_SECURITY is not set 905# CONFIG_EXT3_FS_SECURITY is not set
913# CONFIG_EXT4DEV_FS is not set 906# CONFIG_EXT4DEV_FS is not set
914CONFIG_JBD=y 907CONFIG_JBD=y
915# CONFIG_JBD_DEBUG is not set
916CONFIG_FS_MBCACHE=y 908CONFIG_FS_MBCACHE=y
917# CONFIG_REISERFS_FS is not set 909# CONFIG_REISERFS_FS is not set
918# CONFIG_JFS_FS is not set 910# CONFIG_JFS_FS is not set
@@ -952,7 +944,6 @@ CONFIG_SYSFS=y
952CONFIG_TMPFS=y 944CONFIG_TMPFS=y
953# CONFIG_TMPFS_POSIX_ACL is not set 945# CONFIG_TMPFS_POSIX_ACL is not set
954# CONFIG_HUGETLB_PAGE is not set 946# CONFIG_HUGETLB_PAGE is not set
955CONFIG_RAMFS=y
956# CONFIG_CONFIGFS_FS is not set 947# CONFIG_CONFIGFS_FS is not set
957 948
958# 949#
@@ -969,10 +960,12 @@ CONFIG_ECRYPT_FS=y
969CONFIG_JFFS2_FS=y 960CONFIG_JFFS2_FS=y
970CONFIG_JFFS2_FS_DEBUG=0 961CONFIG_JFFS2_FS_DEBUG=0
971CONFIG_JFFS2_FS_WRITEBUFFER=y 962CONFIG_JFFS2_FS_WRITEBUFFER=y
963# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
972# CONFIG_JFFS2_SUMMARY is not set 964# CONFIG_JFFS2_SUMMARY is not set
973# CONFIG_JFFS2_FS_XATTR is not set 965# CONFIG_JFFS2_FS_XATTR is not set
974# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set 966# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
975CONFIG_JFFS2_ZLIB=y 967CONFIG_JFFS2_ZLIB=y
968# CONFIG_JFFS2_LZO is not set
976CONFIG_JFFS2_RTIME=y 969CONFIG_JFFS2_RTIME=y
977# CONFIG_JFFS2_RUBIN is not set 970# CONFIG_JFFS2_RUBIN is not set
978CONFIG_CRAMFS=y 971CONFIG_CRAMFS=y
@@ -981,10 +974,7 @@ CONFIG_CRAMFS=y
981# CONFIG_QNX4FS_FS is not set 974# CONFIG_QNX4FS_FS is not set
982# CONFIG_SYSV_FS is not set 975# CONFIG_SYSV_FS is not set
983# CONFIG_UFS_FS is not set 976# CONFIG_UFS_FS is not set
984 977CONFIG_NETWORK_FILESYSTEMS=y
985#
986# Network File Systems
987#
988CONFIG_NFS_FS=y 978CONFIG_NFS_FS=y
989CONFIG_NFS_V3=y 979CONFIG_NFS_V3=y
990# CONFIG_NFS_V3_ACL is not set 980# CONFIG_NFS_V3_ACL is not set
@@ -1037,10 +1027,6 @@ CONFIG_MSDOS_PARTITION=y
1037# CONFIG_KARMA_PARTITION is not set 1027# CONFIG_KARMA_PARTITION is not set
1038# CONFIG_EFI_PARTITION is not set 1028# CONFIG_EFI_PARTITION is not set
1039# CONFIG_SYSV68_PARTITION is not set 1029# CONFIG_SYSV68_PARTITION is not set
1040
1041#
1042# Native Language Support
1043#
1044CONFIG_NLS=y 1030CONFIG_NLS=y
1045CONFIG_NLS_DEFAULT="iso8859-1" 1031CONFIG_NLS_DEFAULT="iso8859-1"
1046# CONFIG_NLS_CODEPAGE_437 is not set 1032# CONFIG_NLS_CODEPAGE_437 is not set
@@ -1081,21 +1067,16 @@ CONFIG_NLS_DEFAULT="iso8859-1"
1081# CONFIG_NLS_KOI8_R is not set 1067# CONFIG_NLS_KOI8_R is not set
1082# CONFIG_NLS_KOI8_U is not set 1068# CONFIG_NLS_KOI8_U is not set
1083# CONFIG_NLS_UTF8 is not set 1069# CONFIG_NLS_UTF8 is not set
1084
1085#
1086# Distributed Lock Manager
1087#
1088# CONFIG_DLM is not set 1070# CONFIG_DLM is not set
1089 1071CONFIG_INSTRUMENTATION=y
1090#
1091# Profiling support
1092#
1093# CONFIG_PROFILING is not set 1072# CONFIG_PROFILING is not set
1073# CONFIG_MARKERS is not set
1094 1074
1095# 1075#
1096# Kernel hacking 1076# Kernel hacking
1097# 1077#
1098# CONFIG_PRINTK_TIME is not set 1078# CONFIG_PRINTK_TIME is not set
1079CONFIG_ENABLE_WARN_DEPRECATED=y
1099CONFIG_ENABLE_MUST_CHECK=y 1080CONFIG_ENABLE_MUST_CHECK=y
1100# CONFIG_MAGIC_SYSRQ is not set 1081# CONFIG_MAGIC_SYSRQ is not set
1101# CONFIG_UNUSED_SYMBOLS is not set 1082# CONFIG_UNUSED_SYMBOLS is not set
@@ -1104,6 +1085,7 @@ CONFIG_ENABLE_MUST_CHECK=y
1104# CONFIG_DEBUG_KERNEL is not set 1085# CONFIG_DEBUG_KERNEL is not set
1105CONFIG_DEBUG_BUGVERBOSE=y 1086CONFIG_DEBUG_BUGVERBOSE=y
1106CONFIG_FRAME_POINTER=y 1087CONFIG_FRAME_POINTER=y
1088# CONFIG_SAMPLES is not set
1107CONFIG_DEBUG_USER=y 1089CONFIG_DEBUG_USER=y
1108 1090
1109# 1091#
@@ -1112,6 +1094,7 @@ CONFIG_DEBUG_USER=y
1112CONFIG_KEYS=y 1094CONFIG_KEYS=y
1113CONFIG_KEYS_DEBUG_PROC_KEYS=y 1095CONFIG_KEYS_DEBUG_PROC_KEYS=y
1114# CONFIG_SECURITY is not set 1096# CONFIG_SECURITY is not set
1097# CONFIG_SECURITY_FILE_CAPABILITIES is not set
1115CONFIG_XOR_BLOCKS=y 1098CONFIG_XOR_BLOCKS=y
1116CONFIG_ASYNC_CORE=y 1099CONFIG_ASYNC_CORE=y
1117CONFIG_ASYNC_MEMCPY=y 1100CONFIG_ASYNC_MEMCPY=y
@@ -1136,6 +1119,7 @@ CONFIG_CRYPTO_ECB=y
1136CONFIG_CRYPTO_CBC=y 1119CONFIG_CRYPTO_CBC=y
1137CONFIG_CRYPTO_PCBC=m 1120CONFIG_CRYPTO_PCBC=m
1138CONFIG_CRYPTO_LRW=y 1121CONFIG_CRYPTO_LRW=y
1122# CONFIG_CRYPTO_XTS is not set
1139# CONFIG_CRYPTO_CRYPTD is not set 1123# CONFIG_CRYPTO_CRYPTD is not set
1140CONFIG_CRYPTO_DES=y 1124CONFIG_CRYPTO_DES=y
1141# CONFIG_CRYPTO_FCRYPT is not set 1125# CONFIG_CRYPTO_FCRYPT is not set
@@ -1150,11 +1134,13 @@ CONFIG_CRYPTO_TEA=y
1150CONFIG_CRYPTO_ARC4=y 1134CONFIG_CRYPTO_ARC4=y
1151CONFIG_CRYPTO_KHAZAD=y 1135CONFIG_CRYPTO_KHAZAD=y
1152CONFIG_CRYPTO_ANUBIS=y 1136CONFIG_CRYPTO_ANUBIS=y
1137# CONFIG_CRYPTO_SEED is not set
1153CONFIG_CRYPTO_DEFLATE=y 1138CONFIG_CRYPTO_DEFLATE=y
1154CONFIG_CRYPTO_MICHAEL_MIC=y 1139CONFIG_CRYPTO_MICHAEL_MIC=y
1155CONFIG_CRYPTO_CRC32C=y 1140CONFIG_CRYPTO_CRC32C=y
1156# CONFIG_CRYPTO_CAMELLIA is not set 1141# CONFIG_CRYPTO_CAMELLIA is not set
1157# CONFIG_CRYPTO_TEST is not set 1142# CONFIG_CRYPTO_TEST is not set
1143# CONFIG_CRYPTO_AUTHENC is not set
1158CONFIG_CRYPTO_HW=y 1144CONFIG_CRYPTO_HW=y
1159 1145
1160# 1146#
diff --git a/arch/arm/configs/iop32x_defconfig b/arch/arm/configs/iop32x_defconfig
index 027aef22b4d1..83f40d4041a6 100644
--- a/arch/arm/configs/iop32x_defconfig
+++ b/arch/arm/configs/iop32x_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.22 3# Linux kernel version: 2.6.24-rc5
4# Thu Jul 19 16:00:36 2007 4# Wed Dec 12 15:49:08 2007
5# 5#
6CONFIG_ARM=y 6CONFIG_ARM=y
7CONFIG_SYS_SUPPORTS_APM_EMULATION=y 7CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -26,15 +26,11 @@ CONFIG_VECTORS_BASE=0xffff0000
26CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" 26CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
27 27
28# 28#
29# Code maturity level options 29# General setup
30# 30#
31CONFIG_EXPERIMENTAL=y 31CONFIG_EXPERIMENTAL=y
32CONFIG_BROKEN_ON_SMP=y 32CONFIG_BROKEN_ON_SMP=y
33CONFIG_INIT_ENV_ARG_LIMIT=32 33CONFIG_INIT_ENV_ARG_LIMIT=32
34
35#
36# General setup
37#
38CONFIG_LOCALVERSION="" 34CONFIG_LOCALVERSION=""
39CONFIG_LOCALVERSION_AUTO=y 35CONFIG_LOCALVERSION_AUTO=y
40CONFIG_SWAP=y 36CONFIG_SWAP=y
@@ -45,9 +41,14 @@ CONFIG_BSD_PROCESS_ACCT=y
45# CONFIG_BSD_PROCESS_ACCT_V3 is not set 41# CONFIG_BSD_PROCESS_ACCT_V3 is not set
46# CONFIG_TASKSTATS is not set 42# CONFIG_TASKSTATS is not set
47# CONFIG_USER_NS is not set 43# CONFIG_USER_NS is not set
44# CONFIG_PID_NS is not set
48# CONFIG_AUDIT is not set 45# CONFIG_AUDIT is not set
49# CONFIG_IKCONFIG is not set 46# CONFIG_IKCONFIG is not set
50CONFIG_LOG_BUF_SHIFT=14 47CONFIG_LOG_BUF_SHIFT=14
48# CONFIG_CGROUPS is not set
49CONFIG_FAIR_GROUP_SCHED=y
50CONFIG_FAIR_USER_SCHED=y
51# CONFIG_FAIR_CGROUP_SCHED is not set
51CONFIG_SYSFS_DEPRECATED=y 52CONFIG_SYSFS_DEPRECATED=y
52# CONFIG_RELAY is not set 53# CONFIG_RELAY is not set
53CONFIG_BLK_DEV_INITRD=y 54CONFIG_BLK_DEV_INITRD=y
@@ -69,7 +70,6 @@ CONFIG_FUTEX=y
69CONFIG_ANON_INODES=y 70CONFIG_ANON_INODES=y
70CONFIG_EPOLL=y 71CONFIG_EPOLL=y
71CONFIG_SIGNALFD=y 72CONFIG_SIGNALFD=y
72CONFIG_TIMERFD=y
73CONFIG_EVENTFD=y 73CONFIG_EVENTFD=y
74CONFIG_SHMEM=y 74CONFIG_SHMEM=y
75CONFIG_VM_EVENT_COUNTERS=y 75CONFIG_VM_EVENT_COUNTERS=y
@@ -130,6 +130,7 @@ CONFIG_ARCH_IOP32X=y
130# CONFIG_ARCH_L7200 is not set 130# CONFIG_ARCH_L7200 is not set
131# CONFIG_ARCH_KS8695 is not set 131# CONFIG_ARCH_KS8695 is not set
132# CONFIG_ARCH_NS9XXX is not set 132# CONFIG_ARCH_NS9XXX is not set
133# CONFIG_ARCH_MXC is not set
133# CONFIG_ARCH_PNX4008 is not set 134# CONFIG_ARCH_PNX4008 is not set
134# CONFIG_ARCH_PXA is not set 135# CONFIG_ARCH_PXA is not set
135# CONFIG_ARCH_RPC is not set 136# CONFIG_ARCH_RPC is not set
@@ -153,6 +154,15 @@ CONFIG_ARCH_IQ80321=y
153CONFIG_ARCH_IQ31244=y 154CONFIG_ARCH_IQ31244=y
154CONFIG_MACH_N2100=y 155CONFIG_MACH_N2100=y
155CONFIG_IOP3XX_ATU=y 156CONFIG_IOP3XX_ATU=y
157# CONFIG_MACH_EM7210 is not set
158
159#
160# Boot options
161#
162
163#
164# Power management
165#
156CONFIG_PLAT_IOP=y 166CONFIG_PLAT_IOP=y
157 167
158# 168#
@@ -182,11 +192,8 @@ CONFIG_XSCALE_PMU=y
182CONFIG_PCI=y 192CONFIG_PCI=y
183CONFIG_PCI_SYSCALL=y 193CONFIG_PCI_SYSCALL=y
184# CONFIG_ARCH_SUPPORTS_MSI is not set 194# CONFIG_ARCH_SUPPORTS_MSI is not set
195CONFIG_PCI_LEGACY=y
185# CONFIG_PCI_DEBUG is not set 196# CONFIG_PCI_DEBUG is not set
186
187#
188# PCCARD (PCMCIA/CardBus) support
189#
190# CONFIG_PCCARD is not set 197# CONFIG_PCCARD is not set
191 198
192# 199#
@@ -205,6 +212,7 @@ CONFIG_FLATMEM_MANUAL=y
205CONFIG_FLATMEM=y 212CONFIG_FLATMEM=y
206CONFIG_FLAT_NODE_MEM_MAP=y 213CONFIG_FLAT_NODE_MEM_MAP=y
207# CONFIG_SPARSEMEM_STATIC is not set 214# CONFIG_SPARSEMEM_STATIC is not set
215# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
208CONFIG_SPLIT_PTLOCK_CPUS=4096 216CONFIG_SPLIT_PTLOCK_CPUS=4096
209# CONFIG_RESOURCES_64BIT is not set 217# CONFIG_RESOURCES_64BIT is not set
210CONFIG_ZONE_DMA_FLAG=1 218CONFIG_ZONE_DMA_FLAG=1
@@ -244,6 +252,7 @@ CONFIG_BINFMT_AOUT=y
244# Power management options 252# Power management options
245# 253#
246# CONFIG_PM is not set 254# CONFIG_PM is not set
255CONFIG_SUSPEND_UP_POSSIBLE=y
247 256
248# 257#
249# Networking 258# Networking
@@ -282,6 +291,7 @@ CONFIG_IP_PNP_BOOTP=y
282CONFIG_INET_XFRM_MODE_TRANSPORT=y 291CONFIG_INET_XFRM_MODE_TRANSPORT=y
283CONFIG_INET_XFRM_MODE_TUNNEL=y 292CONFIG_INET_XFRM_MODE_TUNNEL=y
284CONFIG_INET_XFRM_MODE_BEET=y 293CONFIG_INET_XFRM_MODE_BEET=y
294# CONFIG_INET_LRO is not set
285CONFIG_INET_DIAG=y 295CONFIG_INET_DIAG=y
286CONFIG_INET_TCP_DIAG=y 296CONFIG_INET_TCP_DIAG=y
287# CONFIG_TCP_CONG_ADVANCED is not set 297# CONFIG_TCP_CONG_ADVANCED is not set
@@ -321,10 +331,6 @@ CONFIG_IPV6=y
321# CONFIG_LAPB is not set 331# CONFIG_LAPB is not set
322# CONFIG_ECONET is not set 332# CONFIG_ECONET is not set
323# CONFIG_WAN_ROUTER is not set 333# CONFIG_WAN_ROUTER is not set
324
325#
326# QoS and/or fair queueing
327#
328# CONFIG_NET_SCHED is not set 334# CONFIG_NET_SCHED is not set
329 335
330# 336#
@@ -353,6 +359,7 @@ CONFIG_IPV6=y
353# 359#
354# Generic Driver Options 360# Generic Driver Options
355# 361#
362CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
356CONFIG_STANDALONE=y 363CONFIG_STANDALONE=y
357CONFIG_PREVENT_FIRMWARE_BUILD=y 364CONFIG_PREVENT_FIRMWARE_BUILD=y
358# CONFIG_FW_LOADER is not set 365# CONFIG_FW_LOADER is not set
@@ -382,6 +389,7 @@ CONFIG_MTD_BLOCK=y
382# CONFIG_INFTL is not set 389# CONFIG_INFTL is not set
383# CONFIG_RFD_FTL is not set 390# CONFIG_RFD_FTL is not set
384# CONFIG_SSFDC is not set 391# CONFIG_SSFDC is not set
392# CONFIG_MTD_OOPS is not set
385 393
386# 394#
387# RAM/ROM/Flash chip drivers 395# RAM/ROM/Flash chip drivers
@@ -417,6 +425,7 @@ CONFIG_MTD_PHYSMAP_START=0x0
417CONFIG_MTD_PHYSMAP_LEN=0x0 425CONFIG_MTD_PHYSMAP_LEN=0x0
418CONFIG_MTD_PHYSMAP_BANKWIDTH=1 426CONFIG_MTD_PHYSMAP_BANKWIDTH=1
419# CONFIG_MTD_ARM_INTEGRATOR is not set 427# CONFIG_MTD_ARM_INTEGRATOR is not set
428# CONFIG_MTD_INTEL_VR_NOR is not set
420# CONFIG_MTD_PLATRAM is not set 429# CONFIG_MTD_PLATRAM is not set
421 430
422# 431#
@@ -459,6 +468,11 @@ CONFIG_BLK_DEV_RAM_SIZE=8192
459CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 468CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
460# CONFIG_CDROM_PKTCDVD is not set 469# CONFIG_CDROM_PKTCDVD is not set
461# CONFIG_ATA_OVER_ETH is not set 470# CONFIG_ATA_OVER_ETH is not set
471CONFIG_MISC_DEVICES=y
472# CONFIG_PHANTOM is not set
473# CONFIG_EEPROM_93CX6 is not set
474# CONFIG_SGI_IOC4 is not set
475# CONFIG_TIFM_CORE is not set
462# CONFIG_IDE is not set 476# CONFIG_IDE is not set
463 477
464# 478#
@@ -496,12 +510,9 @@ CONFIG_SCSI_WAIT_SCAN=m
496# CONFIG_SCSI_SPI_ATTRS is not set 510# CONFIG_SCSI_SPI_ATTRS is not set
497# CONFIG_SCSI_FC_ATTRS is not set 511# CONFIG_SCSI_FC_ATTRS is not set
498# CONFIG_SCSI_ISCSI_ATTRS is not set 512# CONFIG_SCSI_ISCSI_ATTRS is not set
499# CONFIG_SCSI_SAS_ATTRS is not set
500# CONFIG_SCSI_SAS_LIBSAS is not set 513# CONFIG_SCSI_SAS_LIBSAS is not set
501 514# CONFIG_SCSI_SRP_ATTRS is not set
502# 515CONFIG_SCSI_LOWLEVEL=y
503# SCSI low-level drivers
504#
505# CONFIG_ISCSI_TCP is not set 516# CONFIG_ISCSI_TCP is not set
506# CONFIG_BLK_DEV_3W_XXXX_RAID is not set 517# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
507# CONFIG_SCSI_3W_9XXX is not set 518# CONFIG_SCSI_3W_9XXX is not set
@@ -512,6 +523,7 @@ CONFIG_SCSI_WAIT_SCAN=m
512# CONFIG_SCSI_AIC79XX is not set 523# CONFIG_SCSI_AIC79XX is not set
513# CONFIG_SCSI_AIC94XX is not set 524# CONFIG_SCSI_AIC94XX is not set
514# CONFIG_SCSI_DPT_I2O is not set 525# CONFIG_SCSI_DPT_I2O is not set
526# CONFIG_SCSI_ADVANSYS is not set
515# CONFIG_SCSI_ARCMSR is not set 527# CONFIG_SCSI_ARCMSR is not set
516# CONFIG_MEGARAID_NEWGEN is not set 528# CONFIG_MEGARAID_NEWGEN is not set
517# CONFIG_MEGARAID_LEGACY is not set 529# CONFIG_MEGARAID_LEGACY is not set
@@ -576,6 +588,7 @@ CONFIG_SATA_VITESSE=y
576# CONFIG_PATA_OLDPIIX is not set 588# CONFIG_PATA_OLDPIIX is not set
577# CONFIG_PATA_NETCELL is not set 589# CONFIG_PATA_NETCELL is not set
578# CONFIG_PATA_NS87410 is not set 590# CONFIG_PATA_NS87410 is not set
591# CONFIG_PATA_NS87415 is not set
579# CONFIG_PATA_OPTI is not set 592# CONFIG_PATA_OPTI is not set
580# CONFIG_PATA_OPTIDMA is not set 593# CONFIG_PATA_OPTIDMA is not set
581# CONFIG_PATA_PDC_OLD is not set 594# CONFIG_PATA_PDC_OLD is not set
@@ -606,14 +619,8 @@ CONFIG_BLK_DEV_DM=y
606# CONFIG_DM_ZERO is not set 619# CONFIG_DM_ZERO is not set
607# CONFIG_DM_MULTIPATH is not set 620# CONFIG_DM_MULTIPATH is not set
608# CONFIG_DM_DELAY is not set 621# CONFIG_DM_DELAY is not set
609 622# CONFIG_DM_UEVENT is not set
610#
611# Fusion MPT device support
612#
613# CONFIG_FUSION is not set 623# CONFIG_FUSION is not set
614# CONFIG_FUSION_SPI is not set
615# CONFIG_FUSION_FC is not set
616# CONFIG_FUSION_SAS is not set
617 624
618# 625#
619# IEEE 1394 (FireWire) support 626# IEEE 1394 (FireWire) support
@@ -628,6 +635,8 @@ CONFIG_NETDEVICES=y
628# CONFIG_MACVLAN is not set 635# CONFIG_MACVLAN is not set
629# CONFIG_EQUALIZER is not set 636# CONFIG_EQUALIZER is not set
630# CONFIG_TUN is not set 637# CONFIG_TUN is not set
638# CONFIG_VETH is not set
639# CONFIG_IP1000 is not set
631# CONFIG_ARCNET is not set 640# CONFIG_ARCNET is not set
632# CONFIG_PHYLIB is not set 641# CONFIG_PHYLIB is not set
633CONFIG_NET_ETHERNET=y 642CONFIG_NET_ETHERNET=y
@@ -641,13 +650,16 @@ CONFIG_MII=y
641# CONFIG_DM9000 is not set 650# CONFIG_DM9000 is not set
642# CONFIG_NET_TULIP is not set 651# CONFIG_NET_TULIP is not set
643# CONFIG_HP100 is not set 652# CONFIG_HP100 is not set
653# CONFIG_IBM_NEW_EMAC_ZMII is not set
654# CONFIG_IBM_NEW_EMAC_RGMII is not set
655# CONFIG_IBM_NEW_EMAC_TAH is not set
656# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
644CONFIG_NET_PCI=y 657CONFIG_NET_PCI=y
645# CONFIG_PCNET32 is not set 658# CONFIG_PCNET32 is not set
646# CONFIG_AMD8111_ETH is not set 659# CONFIG_AMD8111_ETH is not set
647# CONFIG_ADAPTEC_STARFIRE is not set 660# CONFIG_ADAPTEC_STARFIRE is not set
648# CONFIG_B44 is not set 661# CONFIG_B44 is not set
649# CONFIG_FORCEDETH is not set 662# CONFIG_FORCEDETH is not set
650# CONFIG_DGRS is not set
651# CONFIG_EEPRO100 is not set 663# CONFIG_EEPRO100 is not set
652CONFIG_E100=y 664CONFIG_E100=y
653# CONFIG_FEALNX is not set 665# CONFIG_FEALNX is not set
@@ -667,6 +679,7 @@ CONFIG_NETDEV_1000=y
667CONFIG_E1000=y 679CONFIG_E1000=y
668CONFIG_E1000_NAPI=y 680CONFIG_E1000_NAPI=y
669# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set 681# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
682# CONFIG_E1000E is not set
670# CONFIG_NS83820 is not set 683# CONFIG_NS83820 is not set
671# CONFIG_HAMACHI is not set 684# CONFIG_HAMACHI is not set
672# CONFIG_YELLOWFIN is not set 685# CONFIG_YELLOWFIN is not set
@@ -675,6 +688,7 @@ CONFIG_R8169=y
675# CONFIG_SIS190 is not set 688# CONFIG_SIS190 is not set
676# CONFIG_SKGE is not set 689# CONFIG_SKGE is not set
677# CONFIG_SKY2 is not set 690# CONFIG_SKY2 is not set
691# CONFIG_SK98LIN is not set
678# CONFIG_VIA_VELOCITY is not set 692# CONFIG_VIA_VELOCITY is not set
679# CONFIG_TIGON3 is not set 693# CONFIG_TIGON3 is not set
680# CONFIG_BNX2 is not set 694# CONFIG_BNX2 is not set
@@ -683,11 +697,14 @@ CONFIG_R8169=y
683CONFIG_NETDEV_10000=y 697CONFIG_NETDEV_10000=y
684# CONFIG_CHELSIO_T1 is not set 698# CONFIG_CHELSIO_T1 is not set
685# CONFIG_CHELSIO_T3 is not set 699# CONFIG_CHELSIO_T3 is not set
700# CONFIG_IXGBE is not set
686# CONFIG_IXGB is not set 701# CONFIG_IXGB is not set
687# CONFIG_S2IO is not set 702# CONFIG_S2IO is not set
688# CONFIG_MYRI10GE is not set 703# CONFIG_MYRI10GE is not set
689# CONFIG_NETXEN_NIC is not set 704# CONFIG_NETXEN_NIC is not set
705# CONFIG_NIU is not set
690# CONFIG_MLX4_CORE is not set 706# CONFIG_MLX4_CORE is not set
707# CONFIG_TEHUTI is not set
691# CONFIG_TR is not set 708# CONFIG_TR is not set
692 709
693# 710#
@@ -703,7 +720,6 @@ CONFIG_NETDEV_10000=y
703# CONFIG_USB_KAWETH is not set 720# CONFIG_USB_KAWETH is not set
704# CONFIG_USB_PEGASUS is not set 721# CONFIG_USB_PEGASUS is not set
705# CONFIG_USB_RTL8150 is not set 722# CONFIG_USB_RTL8150 is not set
706# CONFIG_USB_USBNET_MII is not set
707# CONFIG_USB_USBNET is not set 723# CONFIG_USB_USBNET is not set
708# CONFIG_WAN is not set 724# CONFIG_WAN is not set
709# CONFIG_FDDI is not set 725# CONFIG_FDDI is not set
@@ -732,7 +748,6 @@ CONFIG_INPUT_MOUSEDEV=y
732CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 748CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
733CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 749CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
734# CONFIG_INPUT_JOYDEV is not set 750# CONFIG_INPUT_JOYDEV is not set
735# CONFIG_INPUT_TSDEV is not set
736# CONFIG_INPUT_EVDEV is not set 751# CONFIG_INPUT_EVDEV is not set
737# CONFIG_INPUT_EVBUG is not set 752# CONFIG_INPUT_EVBUG is not set
738 753
@@ -781,12 +796,10 @@ CONFIG_UNIX98_PTYS=y
781CONFIG_LEGACY_PTYS=y 796CONFIG_LEGACY_PTYS=y
782CONFIG_LEGACY_PTY_COUNT=256 797CONFIG_LEGACY_PTY_COUNT=256
783# CONFIG_IPMI_HANDLER is not set 798# CONFIG_IPMI_HANDLER is not set
784# CONFIG_WATCHDOG is not set
785CONFIG_HW_RANDOM=y 799CONFIG_HW_RANDOM=y
786# CONFIG_NVRAM is not set 800# CONFIG_NVRAM is not set
787# CONFIG_R3964 is not set 801# CONFIG_R3964 is not set
788# CONFIG_APPLICOM is not set 802# CONFIG_APPLICOM is not set
789# CONFIG_DRM is not set
790# CONFIG_RAW_DRIVER is not set 803# CONFIG_RAW_DRIVER is not set
791# CONFIG_TCG_TPM is not set 804# CONFIG_TCG_TPM is not set
792CONFIG_DEVPORT=y 805CONFIG_DEVPORT=y
@@ -852,9 +865,9 @@ CONFIG_I2C_IOP3XX=y
852# CONFIG_SPI is not set 865# CONFIG_SPI is not set
853# CONFIG_SPI_MASTER is not set 866# CONFIG_SPI_MASTER is not set
854# CONFIG_W1 is not set 867# CONFIG_W1 is not set
868# CONFIG_POWER_SUPPLY is not set
855CONFIG_HWMON=y 869CONFIG_HWMON=y
856# CONFIG_HWMON_VID is not set 870# CONFIG_HWMON_VID is not set
857# CONFIG_SENSORS_ABITUGURU is not set
858# CONFIG_SENSORS_AD7418 is not set 871# CONFIG_SENSORS_AD7418 is not set
859# CONFIG_SENSORS_ADM1021 is not set 872# CONFIG_SENSORS_ADM1021 is not set
860# CONFIG_SENSORS_ADM1025 is not set 873# CONFIG_SENSORS_ADM1025 is not set
@@ -862,12 +875,13 @@ CONFIG_HWMON=y
862# CONFIG_SENSORS_ADM1029 is not set 875# CONFIG_SENSORS_ADM1029 is not set
863# CONFIG_SENSORS_ADM1031 is not set 876# CONFIG_SENSORS_ADM1031 is not set
864# CONFIG_SENSORS_ADM9240 is not set 877# CONFIG_SENSORS_ADM9240 is not set
865# CONFIG_SENSORS_ASB100 is not set 878# CONFIG_SENSORS_ADT7470 is not set
866# CONFIG_SENSORS_ATXP1 is not set 879# CONFIG_SENSORS_ATXP1 is not set
867# CONFIG_SENSORS_DS1621 is not set 880# CONFIG_SENSORS_DS1621 is not set
881# CONFIG_SENSORS_I5K_AMB is not set
868# CONFIG_SENSORS_F71805F is not set 882# CONFIG_SENSORS_F71805F is not set
869# CONFIG_SENSORS_FSCHER is not set 883# CONFIG_SENSORS_F71882FG is not set
870# CONFIG_SENSORS_FSCPOS is not set 884# CONFIG_SENSORS_F75375S is not set
871# CONFIG_SENSORS_GL518SM is not set 885# CONFIG_SENSORS_GL518SM is not set
872# CONFIG_SENSORS_GL520SM is not set 886# CONFIG_SENSORS_GL520SM is not set
873# CONFIG_SENSORS_IT87 is not set 887# CONFIG_SENSORS_IT87 is not set
@@ -881,14 +895,17 @@ CONFIG_HWMON=y
881# CONFIG_SENSORS_LM87 is not set 895# CONFIG_SENSORS_LM87 is not set
882# CONFIG_SENSORS_LM90 is not set 896# CONFIG_SENSORS_LM90 is not set
883# CONFIG_SENSORS_LM92 is not set 897# CONFIG_SENSORS_LM92 is not set
898# CONFIG_SENSORS_LM93 is not set
884# CONFIG_SENSORS_MAX1619 is not set 899# CONFIG_SENSORS_MAX1619 is not set
885# CONFIG_SENSORS_MAX6650 is not set 900# CONFIG_SENSORS_MAX6650 is not set
886# CONFIG_SENSORS_PC87360 is not set 901# CONFIG_SENSORS_PC87360 is not set
887# CONFIG_SENSORS_PC87427 is not set 902# CONFIG_SENSORS_PC87427 is not set
888# CONFIG_SENSORS_SIS5595 is not set 903# CONFIG_SENSORS_SIS5595 is not set
904# CONFIG_SENSORS_DME1737 is not set
889# CONFIG_SENSORS_SMSC47M1 is not set 905# CONFIG_SENSORS_SMSC47M1 is not set
890# CONFIG_SENSORS_SMSC47M192 is not set 906# CONFIG_SENSORS_SMSC47M192 is not set
891# CONFIG_SENSORS_SMSC47B397 is not set 907# CONFIG_SENSORS_SMSC47B397 is not set
908# CONFIG_SENSORS_THMC50 is not set
892# CONFIG_SENSORS_VIA686A is not set 909# CONFIG_SENSORS_VIA686A is not set
893# CONFIG_SENSORS_VT1211 is not set 910# CONFIG_SENSORS_VT1211 is not set
894# CONFIG_SENSORS_VT8231 is not set 911# CONFIG_SENSORS_VT8231 is not set
@@ -900,29 +917,18 @@ CONFIG_HWMON=y
900# CONFIG_SENSORS_W83627HF is not set 917# CONFIG_SENSORS_W83627HF is not set
901# CONFIG_SENSORS_W83627EHF is not set 918# CONFIG_SENSORS_W83627EHF is not set
902# CONFIG_HWMON_DEBUG_CHIP is not set 919# CONFIG_HWMON_DEBUG_CHIP is not set
903CONFIG_MISC_DEVICES=y 920# CONFIG_WATCHDOG is not set
904# CONFIG_PHANTOM is not set
905# CONFIG_EEPROM_93CX6 is not set
906# CONFIG_SGI_IOC4 is not set
907# CONFIG_TIFM_CORE is not set
908
909#
910# Multifunction device drivers
911#
912# CONFIG_MFD_SM501 is not set
913
914#
915# LED devices
916#
917# CONFIG_NEW_LEDS is not set
918 921
919# 922#
920# LED drivers 923# Sonics Silicon Backplane
921# 924#
925CONFIG_SSB_POSSIBLE=y
926# CONFIG_SSB is not set
922 927
923# 928#
924# LED Triggers 929# Multifunction device drivers
925# 930#
931# CONFIG_MFD_SM501 is not set
926 932
927# 933#
928# Multimedia devices 934# Multimedia devices
@@ -935,14 +941,16 @@ CONFIG_DAB=y
935# 941#
936# Graphics support 942# Graphics support
937# 943#
944# CONFIG_DRM is not set
945# CONFIG_VGASTATE is not set
946# CONFIG_VIDEO_OUTPUT_CONTROL is not set
947# CONFIG_FB is not set
938# CONFIG_BACKLIGHT_LCD_SUPPORT is not set 948# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
939 949
940# 950#
941# Display device support 951# Display device support
942# 952#
943# CONFIG_DISPLAY_SUPPORT is not set 953# CONFIG_DISPLAY_SUPPORT is not set
944# CONFIG_VGASTATE is not set
945# CONFIG_FB is not set
946 954
947# 955#
948# Console display driver support 956# Console display driver support
@@ -957,6 +965,7 @@ CONFIG_DUMMY_CONSOLE=y
957CONFIG_HID_SUPPORT=y 965CONFIG_HID_SUPPORT=y
958CONFIG_HID=y 966CONFIG_HID=y
959# CONFIG_HID_DEBUG is not set 967# CONFIG_HID_DEBUG is not set
968# CONFIG_HIDRAW is not set
960 969
961# 970#
962# USB Input Devices 971# USB Input Devices
@@ -1013,6 +1022,7 @@ CONFIG_USB_STORAGE=y
1013# CONFIG_USB_STORAGE_DEBUG is not set 1022# CONFIG_USB_STORAGE_DEBUG is not set
1014# CONFIG_USB_STORAGE_DATAFAB is not set 1023# CONFIG_USB_STORAGE_DATAFAB is not set
1015# CONFIG_USB_STORAGE_FREECOM is not set 1024# CONFIG_USB_STORAGE_FREECOM is not set
1025# CONFIG_USB_STORAGE_ISD200 is not set
1016# CONFIG_USB_STORAGE_DPCM is not set 1026# CONFIG_USB_STORAGE_DPCM is not set
1017# CONFIG_USB_STORAGE_USBAT is not set 1027# CONFIG_USB_STORAGE_USBAT is not set
1018# CONFIG_USB_STORAGE_SDDR09 is not set 1028# CONFIG_USB_STORAGE_SDDR09 is not set
@@ -1070,28 +1080,66 @@ CONFIG_USB_MON=y
1070# 1080#
1071# CONFIG_USB_GADGET is not set 1081# CONFIG_USB_GADGET is not set
1072# CONFIG_MMC is not set 1082# CONFIG_MMC is not set
1083# CONFIG_NEW_LEDS is not set
1084CONFIG_RTC_LIB=y
1085CONFIG_RTC_CLASS=y
1086CONFIG_RTC_HCTOSYS=y
1087CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
1088# CONFIG_RTC_DEBUG is not set
1073 1089
1074# 1090#
1075# Real Time Clock 1091# RTC interfaces
1076# 1092#
1077CONFIG_RTC_LIB=y 1093CONFIG_RTC_INTF_SYSFS=y
1078# CONFIG_RTC_CLASS is not set 1094CONFIG_RTC_INTF_PROC=y
1095CONFIG_RTC_INTF_DEV=y
1096# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
1097# CONFIG_RTC_DRV_TEST is not set
1079 1098
1080# 1099#
1081# DMA Engine support 1100# I2C RTC drivers
1082# 1101#
1083CONFIG_DMA_ENGINE=y 1102# CONFIG_RTC_DRV_DS1307 is not set
1103# CONFIG_RTC_DRV_DS1374 is not set
1104# CONFIG_RTC_DRV_DS1672 is not set
1105# CONFIG_RTC_DRV_MAX6900 is not set
1106CONFIG_RTC_DRV_RS5C372=y
1107# CONFIG_RTC_DRV_ISL1208 is not set
1108# CONFIG_RTC_DRV_X1205 is not set
1109# CONFIG_RTC_DRV_PCF8563 is not set
1110# CONFIG_RTC_DRV_PCF8583 is not set
1111# CONFIG_RTC_DRV_M41T80 is not set
1084 1112
1085# 1113#
1086# DMA Clients 1114# SPI RTC drivers
1087# 1115#
1088CONFIG_NET_DMA=y 1116
1117#
1118# Platform RTC drivers
1119#
1120# CONFIG_RTC_DRV_CMOS is not set
1121# CONFIG_RTC_DRV_DS1553 is not set
1122# CONFIG_RTC_DRV_STK17TA8 is not set
1123# CONFIG_RTC_DRV_DS1742 is not set
1124# CONFIG_RTC_DRV_M48T86 is not set
1125# CONFIG_RTC_DRV_M48T59 is not set
1126# CONFIG_RTC_DRV_V3020 is not set
1127
1128#
1129# on-CPU RTC drivers
1130#
1131CONFIG_DMADEVICES=y
1089 1132
1090# 1133#
1091# DMA Devices 1134# DMA Devices
1092# 1135#
1093# CONFIG_INTEL_IOATDMA is not set
1094CONFIG_INTEL_IOP_ADMA=y 1136CONFIG_INTEL_IOP_ADMA=y
1137CONFIG_DMA_ENGINE=y
1138
1139#
1140# DMA Clients
1141#
1142CONFIG_NET_DMA=y
1095 1143
1096# 1144#
1097# File systems 1145# File systems
@@ -1105,7 +1153,6 @@ CONFIG_EXT3_FS_XATTR=y
1105# CONFIG_EXT3_FS_SECURITY is not set 1153# CONFIG_EXT3_FS_SECURITY is not set
1106# CONFIG_EXT4DEV_FS is not set 1154# CONFIG_EXT4DEV_FS is not set
1107CONFIG_JBD=y 1155CONFIG_JBD=y
1108# CONFIG_JBD_DEBUG is not set
1109CONFIG_FS_MBCACHE=y 1156CONFIG_FS_MBCACHE=y
1110# CONFIG_REISERFS_FS is not set 1157# CONFIG_REISERFS_FS is not set
1111# CONFIG_JFS_FS is not set 1158# CONFIG_JFS_FS is not set
@@ -1145,7 +1192,6 @@ CONFIG_SYSFS=y
1145CONFIG_TMPFS=y 1192CONFIG_TMPFS=y
1146# CONFIG_TMPFS_POSIX_ACL is not set 1193# CONFIG_TMPFS_POSIX_ACL is not set
1147# CONFIG_HUGETLB_PAGE is not set 1194# CONFIG_HUGETLB_PAGE is not set
1148CONFIG_RAMFS=y
1149# CONFIG_CONFIGFS_FS is not set 1195# CONFIG_CONFIGFS_FS is not set
1150 1196
1151# 1197#
@@ -1162,10 +1208,12 @@ CONFIG_ECRYPT_FS=y
1162CONFIG_JFFS2_FS=y 1208CONFIG_JFFS2_FS=y
1163CONFIG_JFFS2_FS_DEBUG=0 1209CONFIG_JFFS2_FS_DEBUG=0
1164CONFIG_JFFS2_FS_WRITEBUFFER=y 1210CONFIG_JFFS2_FS_WRITEBUFFER=y
1211# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
1165# CONFIG_JFFS2_SUMMARY is not set 1212# CONFIG_JFFS2_SUMMARY is not set
1166# CONFIG_JFFS2_FS_XATTR is not set 1213# CONFIG_JFFS2_FS_XATTR is not set
1167# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set 1214# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
1168CONFIG_JFFS2_ZLIB=y 1215CONFIG_JFFS2_ZLIB=y
1216# CONFIG_JFFS2_LZO is not set
1169CONFIG_JFFS2_RTIME=y 1217CONFIG_JFFS2_RTIME=y
1170# CONFIG_JFFS2_RUBIN is not set 1218# CONFIG_JFFS2_RUBIN is not set
1171CONFIG_CRAMFS=y 1219CONFIG_CRAMFS=y
@@ -1174,10 +1222,7 @@ CONFIG_CRAMFS=y
1174# CONFIG_QNX4FS_FS is not set 1222# CONFIG_QNX4FS_FS is not set
1175# CONFIG_SYSV_FS is not set 1223# CONFIG_SYSV_FS is not set
1176# CONFIG_UFS_FS is not set 1224# CONFIG_UFS_FS is not set
1177 1225CONFIG_NETWORK_FILESYSTEMS=y
1178#
1179# Network File Systems
1180#
1181CONFIG_NFS_FS=y 1226CONFIG_NFS_FS=y
1182CONFIG_NFS_V3=y 1227CONFIG_NFS_V3=y
1183# CONFIG_NFS_V3_ACL is not set 1228# CONFIG_NFS_V3_ACL is not set
@@ -1224,26 +1269,17 @@ CONFIG_MSDOS_PARTITION=y
1224# CONFIG_KARMA_PARTITION is not set 1269# CONFIG_KARMA_PARTITION is not set
1225# CONFIG_EFI_PARTITION is not set 1270# CONFIG_EFI_PARTITION is not set
1226# CONFIG_SYSV68_PARTITION is not set 1271# CONFIG_SYSV68_PARTITION is not set
1227
1228#
1229# Native Language Support
1230#
1231# CONFIG_NLS is not set 1272# CONFIG_NLS is not set
1232
1233#
1234# Distributed Lock Manager
1235#
1236# CONFIG_DLM is not set 1273# CONFIG_DLM is not set
1237 1274CONFIG_INSTRUMENTATION=y
1238#
1239# Profiling support
1240#
1241# CONFIG_PROFILING is not set 1275# CONFIG_PROFILING is not set
1276# CONFIG_MARKERS is not set
1242 1277
1243# 1278#
1244# Kernel hacking 1279# Kernel hacking
1245# 1280#
1246# CONFIG_PRINTK_TIME is not set 1281# CONFIG_PRINTK_TIME is not set
1282CONFIG_ENABLE_WARN_DEPRECATED=y
1247CONFIG_ENABLE_MUST_CHECK=y 1283CONFIG_ENABLE_MUST_CHECK=y
1248CONFIG_MAGIC_SYSRQ=y 1284CONFIG_MAGIC_SYSRQ=y
1249# CONFIG_UNUSED_SYMBOLS is not set 1285# CONFIG_UNUSED_SYMBOLS is not set
@@ -1270,10 +1306,13 @@ CONFIG_DEBUG_BUGVERBOSE=y
1270# CONFIG_DEBUG_INFO is not set 1306# CONFIG_DEBUG_INFO is not set
1271# CONFIG_DEBUG_VM is not set 1307# CONFIG_DEBUG_VM is not set
1272# CONFIG_DEBUG_LIST is not set 1308# CONFIG_DEBUG_LIST is not set
1309# CONFIG_DEBUG_SG is not set
1273CONFIG_FRAME_POINTER=y 1310CONFIG_FRAME_POINTER=y
1274# CONFIG_FORCED_INLINING is not set 1311# CONFIG_FORCED_INLINING is not set
1312# CONFIG_BOOT_PRINTK_DELAY is not set
1275# CONFIG_RCU_TORTURE_TEST is not set 1313# CONFIG_RCU_TORTURE_TEST is not set
1276# CONFIG_FAULT_INJECTION is not set 1314# CONFIG_FAULT_INJECTION is not set
1315# CONFIG_SAMPLES is not set
1277CONFIG_DEBUG_USER=y 1316CONFIG_DEBUG_USER=y
1278# CONFIG_DEBUG_ERRORS is not set 1317# CONFIG_DEBUG_ERRORS is not set
1279CONFIG_DEBUG_LL=y 1318CONFIG_DEBUG_LL=y
@@ -1285,6 +1324,7 @@ CONFIG_DEBUG_LL=y
1285CONFIG_KEYS=y 1324CONFIG_KEYS=y
1286CONFIG_KEYS_DEBUG_PROC_KEYS=y 1325CONFIG_KEYS_DEBUG_PROC_KEYS=y
1287# CONFIG_SECURITY is not set 1326# CONFIG_SECURITY is not set
1327# CONFIG_SECURITY_FILE_CAPABILITIES is not set
1288CONFIG_XOR_BLOCKS=y 1328CONFIG_XOR_BLOCKS=y
1289CONFIG_ASYNC_CORE=y 1329CONFIG_ASYNC_CORE=y
1290CONFIG_ASYNC_MEMCPY=y 1330CONFIG_ASYNC_MEMCPY=y
@@ -1309,6 +1349,7 @@ CONFIG_CRYPTO_ECB=y
1309CONFIG_CRYPTO_CBC=y 1349CONFIG_CRYPTO_CBC=y
1310CONFIG_CRYPTO_PCBC=m 1350CONFIG_CRYPTO_PCBC=m
1311CONFIG_CRYPTO_LRW=y 1351CONFIG_CRYPTO_LRW=y
1352# CONFIG_CRYPTO_XTS is not set
1312# CONFIG_CRYPTO_CRYPTD is not set 1353# CONFIG_CRYPTO_CRYPTD is not set
1313CONFIG_CRYPTO_DES=y 1354CONFIG_CRYPTO_DES=y
1314# CONFIG_CRYPTO_FCRYPT is not set 1355# CONFIG_CRYPTO_FCRYPT is not set
@@ -1323,11 +1364,13 @@ CONFIG_CRYPTO_TEA=y
1323CONFIG_CRYPTO_ARC4=y 1364CONFIG_CRYPTO_ARC4=y
1324CONFIG_CRYPTO_KHAZAD=y 1365CONFIG_CRYPTO_KHAZAD=y
1325CONFIG_CRYPTO_ANUBIS=y 1366CONFIG_CRYPTO_ANUBIS=y
1367# CONFIG_CRYPTO_SEED is not set
1326CONFIG_CRYPTO_DEFLATE=y 1368CONFIG_CRYPTO_DEFLATE=y
1327CONFIG_CRYPTO_MICHAEL_MIC=y 1369CONFIG_CRYPTO_MICHAEL_MIC=y
1328CONFIG_CRYPTO_CRC32C=y 1370CONFIG_CRYPTO_CRC32C=y
1329# CONFIG_CRYPTO_CAMELLIA is not set 1371# CONFIG_CRYPTO_CAMELLIA is not set
1330# CONFIG_CRYPTO_TEST is not set 1372# CONFIG_CRYPTO_TEST is not set
1373# CONFIG_CRYPTO_AUTHENC is not set
1331CONFIG_CRYPTO_HW=y 1374CONFIG_CRYPTO_HW=y
1332 1375
1333# 1376#
diff --git a/arch/arm/configs/iop33x_defconfig b/arch/arm/configs/iop33x_defconfig
index 721ee64a13f7..917afb5ccfac 100644
--- a/arch/arm/configs/iop33x_defconfig
+++ b/arch/arm/configs/iop33x_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.22 3# Linux kernel version: 2.6.24-rc5
4# Thu Jul 19 16:05:59 2007 4# Wed Dec 12 16:11:27 2007
5# 5#
6CONFIG_ARM=y 6CONFIG_ARM=y
7CONFIG_SYS_SUPPORTS_APM_EMULATION=y 7CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -26,15 +26,11 @@ CONFIG_VECTORS_BASE=0xffff0000
26CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" 26CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
27 27
28# 28#
29# Code maturity level options 29# General setup
30# 30#
31CONFIG_EXPERIMENTAL=y 31CONFIG_EXPERIMENTAL=y
32CONFIG_BROKEN_ON_SMP=y 32CONFIG_BROKEN_ON_SMP=y
33CONFIG_INIT_ENV_ARG_LIMIT=32 33CONFIG_INIT_ENV_ARG_LIMIT=32
34
35#
36# General setup
37#
38CONFIG_LOCALVERSION="" 34CONFIG_LOCALVERSION=""
39CONFIG_LOCALVERSION_AUTO=y 35CONFIG_LOCALVERSION_AUTO=y
40CONFIG_SWAP=y 36CONFIG_SWAP=y
@@ -45,9 +41,14 @@ CONFIG_BSD_PROCESS_ACCT=y
45# CONFIG_BSD_PROCESS_ACCT_V3 is not set 41# CONFIG_BSD_PROCESS_ACCT_V3 is not set
46# CONFIG_TASKSTATS is not set 42# CONFIG_TASKSTATS is not set
47# CONFIG_USER_NS is not set 43# CONFIG_USER_NS is not set
44# CONFIG_PID_NS is not set
48# CONFIG_AUDIT is not set 45# CONFIG_AUDIT is not set
49# CONFIG_IKCONFIG is not set 46# CONFIG_IKCONFIG is not set
50CONFIG_LOG_BUF_SHIFT=14 47CONFIG_LOG_BUF_SHIFT=14
48# CONFIG_CGROUPS is not set
49CONFIG_FAIR_GROUP_SCHED=y
50CONFIG_FAIR_USER_SCHED=y
51# CONFIG_FAIR_CGROUP_SCHED is not set
51CONFIG_SYSFS_DEPRECATED=y 52CONFIG_SYSFS_DEPRECATED=y
52# CONFIG_RELAY is not set 53# CONFIG_RELAY is not set
53CONFIG_BLK_DEV_INITRD=y 54CONFIG_BLK_DEV_INITRD=y
@@ -69,7 +70,6 @@ CONFIG_FUTEX=y
69CONFIG_ANON_INODES=y 70CONFIG_ANON_INODES=y
70CONFIG_EPOLL=y 71CONFIG_EPOLL=y
71CONFIG_SIGNALFD=y 72CONFIG_SIGNALFD=y
72CONFIG_TIMERFD=y
73CONFIG_EVENTFD=y 73CONFIG_EVENTFD=y
74CONFIG_SHMEM=y 74CONFIG_SHMEM=y
75CONFIG_VM_EVENT_COUNTERS=y 75CONFIG_VM_EVENT_COUNTERS=y
@@ -130,6 +130,7 @@ CONFIG_ARCH_IOP33X=y
130# CONFIG_ARCH_L7200 is not set 130# CONFIG_ARCH_L7200 is not set
131# CONFIG_ARCH_KS8695 is not set 131# CONFIG_ARCH_KS8695 is not set
132# CONFIG_ARCH_NS9XXX is not set 132# CONFIG_ARCH_NS9XXX is not set
133# CONFIG_ARCH_MXC is not set
133# CONFIG_ARCH_PNX4008 is not set 134# CONFIG_ARCH_PNX4008 is not set
134# CONFIG_ARCH_PXA is not set 135# CONFIG_ARCH_PXA is not set
135# CONFIG_ARCH_RPC is not set 136# CONFIG_ARCH_RPC is not set
@@ -150,6 +151,14 @@ CONFIG_IOP3XX_ATU=y
150# 151#
151CONFIG_ARCH_IQ80331=y 152CONFIG_ARCH_IQ80331=y
152CONFIG_MACH_IQ80332=y 153CONFIG_MACH_IQ80332=y
154
155#
156# Boot options
157#
158
159#
160# Power management
161#
153CONFIG_PLAT_IOP=y 162CONFIG_PLAT_IOP=y
154 163
155# 164#
@@ -179,11 +188,8 @@ CONFIG_XSCALE_PMU=y
179CONFIG_PCI=y 188CONFIG_PCI=y
180CONFIG_PCI_SYSCALL=y 189CONFIG_PCI_SYSCALL=y
181# CONFIG_ARCH_SUPPORTS_MSI is not set 190# CONFIG_ARCH_SUPPORTS_MSI is not set
191CONFIG_PCI_LEGACY=y
182# CONFIG_PCI_DEBUG is not set 192# CONFIG_PCI_DEBUG is not set
183
184#
185# PCCARD (PCMCIA/CardBus) support
186#
187# CONFIG_PCCARD is not set 193# CONFIG_PCCARD is not set
188 194
189# 195#
@@ -202,6 +208,7 @@ CONFIG_FLATMEM_MANUAL=y
202CONFIG_FLATMEM=y 208CONFIG_FLATMEM=y
203CONFIG_FLAT_NODE_MEM_MAP=y 209CONFIG_FLAT_NODE_MEM_MAP=y
204# CONFIG_SPARSEMEM_STATIC is not set 210# CONFIG_SPARSEMEM_STATIC is not set
211# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
205CONFIG_SPLIT_PTLOCK_CPUS=4096 212CONFIG_SPLIT_PTLOCK_CPUS=4096
206# CONFIG_RESOURCES_64BIT is not set 213# CONFIG_RESOURCES_64BIT is not set
207CONFIG_ZONE_DMA_FLAG=1 214CONFIG_ZONE_DMA_FLAG=1
@@ -241,6 +248,7 @@ CONFIG_BINFMT_AOUT=y
241# Power management options 248# Power management options
242# 249#
243# CONFIG_PM is not set 250# CONFIG_PM is not set
251CONFIG_SUSPEND_UP_POSSIBLE=y
244 252
245# 253#
246# Networking 254# Networking
@@ -279,6 +287,7 @@ CONFIG_IP_PNP_BOOTP=y
279CONFIG_INET_XFRM_MODE_TRANSPORT=y 287CONFIG_INET_XFRM_MODE_TRANSPORT=y
280CONFIG_INET_XFRM_MODE_TUNNEL=y 288CONFIG_INET_XFRM_MODE_TUNNEL=y
281CONFIG_INET_XFRM_MODE_BEET=y 289CONFIG_INET_XFRM_MODE_BEET=y
290# CONFIG_INET_LRO is not set
282CONFIG_INET_DIAG=y 291CONFIG_INET_DIAG=y
283CONFIG_INET_TCP_DIAG=y 292CONFIG_INET_TCP_DIAG=y
284# CONFIG_TCP_CONG_ADVANCED is not set 293# CONFIG_TCP_CONG_ADVANCED is not set
@@ -318,10 +327,6 @@ CONFIG_IPV6=y
318# CONFIG_LAPB is not set 327# CONFIG_LAPB is not set
319# CONFIG_ECONET is not set 328# CONFIG_ECONET is not set
320# CONFIG_WAN_ROUTER is not set 329# CONFIG_WAN_ROUTER is not set
321
322#
323# QoS and/or fair queueing
324#
325# CONFIG_NET_SCHED is not set 330# CONFIG_NET_SCHED is not set
326 331
327# 332#
@@ -350,6 +355,7 @@ CONFIG_IPV6=y
350# 355#
351# Generic Driver Options 356# Generic Driver Options
352# 357#
358CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
353CONFIG_STANDALONE=y 359CONFIG_STANDALONE=y
354CONFIG_PREVENT_FIRMWARE_BUILD=y 360CONFIG_PREVENT_FIRMWARE_BUILD=y
355# CONFIG_FW_LOADER is not set 361# CONFIG_FW_LOADER is not set
@@ -379,6 +385,7 @@ CONFIG_MTD_BLOCK=y
379# CONFIG_INFTL is not set 385# CONFIG_INFTL is not set
380# CONFIG_RFD_FTL is not set 386# CONFIG_RFD_FTL is not set
381# CONFIG_SSFDC is not set 387# CONFIG_SSFDC is not set
388# CONFIG_MTD_OOPS is not set
382 389
383# 390#
384# RAM/ROM/Flash chip drivers 391# RAM/ROM/Flash chip drivers
@@ -419,6 +426,7 @@ CONFIG_MTD_PHYSMAP_START=0x0
419CONFIG_MTD_PHYSMAP_LEN=0x0 426CONFIG_MTD_PHYSMAP_LEN=0x0
420CONFIG_MTD_PHYSMAP_BANKWIDTH=1 427CONFIG_MTD_PHYSMAP_BANKWIDTH=1
421# CONFIG_MTD_ARM_INTEGRATOR is not set 428# CONFIG_MTD_ARM_INTEGRATOR is not set
429# CONFIG_MTD_INTEL_VR_NOR is not set
422# CONFIG_MTD_PLATRAM is not set 430# CONFIG_MTD_PLATRAM is not set
423 431
424# 432#
@@ -459,6 +467,11 @@ CONFIG_BLK_DEV_RAM_SIZE=8192
459CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 467CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
460# CONFIG_CDROM_PKTCDVD is not set 468# CONFIG_CDROM_PKTCDVD is not set
461# CONFIG_ATA_OVER_ETH is not set 469# CONFIG_ATA_OVER_ETH is not set
470CONFIG_MISC_DEVICES=y
471# CONFIG_PHANTOM is not set
472# CONFIG_EEPROM_93CX6 is not set
473# CONFIG_SGI_IOC4 is not set
474# CONFIG_TIFM_CORE is not set
462# CONFIG_IDE is not set 475# CONFIG_IDE is not set
463 476
464# 477#
@@ -496,12 +509,9 @@ CONFIG_SCSI_WAIT_SCAN=m
496# CONFIG_SCSI_SPI_ATTRS is not set 509# CONFIG_SCSI_SPI_ATTRS is not set
497# CONFIG_SCSI_FC_ATTRS is not set 510# CONFIG_SCSI_FC_ATTRS is not set
498# CONFIG_SCSI_ISCSI_ATTRS is not set 511# CONFIG_SCSI_ISCSI_ATTRS is not set
499# CONFIG_SCSI_SAS_ATTRS is not set
500# CONFIG_SCSI_SAS_LIBSAS is not set 512# CONFIG_SCSI_SAS_LIBSAS is not set
501 513# CONFIG_SCSI_SRP_ATTRS is not set
502# 514CONFIG_SCSI_LOWLEVEL=y
503# SCSI low-level drivers
504#
505# CONFIG_ISCSI_TCP is not set 515# CONFIG_ISCSI_TCP is not set
506# CONFIG_BLK_DEV_3W_XXXX_RAID is not set 516# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
507# CONFIG_SCSI_3W_9XXX is not set 517# CONFIG_SCSI_3W_9XXX is not set
@@ -512,6 +522,7 @@ CONFIG_SCSI_WAIT_SCAN=m
512# CONFIG_SCSI_AIC79XX is not set 522# CONFIG_SCSI_AIC79XX is not set
513# CONFIG_SCSI_AIC94XX is not set 523# CONFIG_SCSI_AIC94XX is not set
514# CONFIG_SCSI_DPT_I2O is not set 524# CONFIG_SCSI_DPT_I2O is not set
525# CONFIG_SCSI_ADVANSYS is not set
515# CONFIG_SCSI_ARCMSR is not set 526# CONFIG_SCSI_ARCMSR is not set
516# CONFIG_MEGARAID_NEWGEN is not set 527# CONFIG_MEGARAID_NEWGEN is not set
517# CONFIG_MEGARAID_LEGACY is not set 528# CONFIG_MEGARAID_LEGACY is not set
@@ -552,14 +563,8 @@ CONFIG_BLK_DEV_DM=y
552# CONFIG_DM_ZERO is not set 563# CONFIG_DM_ZERO is not set
553# CONFIG_DM_MULTIPATH is not set 564# CONFIG_DM_MULTIPATH is not set
554# CONFIG_DM_DELAY is not set 565# CONFIG_DM_DELAY is not set
555 566# CONFIG_DM_UEVENT is not set
556#
557# Fusion MPT device support
558#
559# CONFIG_FUSION is not set 567# CONFIG_FUSION is not set
560# CONFIG_FUSION_SPI is not set
561# CONFIG_FUSION_FC is not set
562# CONFIG_FUSION_SAS is not set
563 568
564# 569#
565# IEEE 1394 (FireWire) support 570# IEEE 1394 (FireWire) support
@@ -574,6 +579,8 @@ CONFIG_NETDEVICES=y
574# CONFIG_MACVLAN is not set 579# CONFIG_MACVLAN is not set
575# CONFIG_EQUALIZER is not set 580# CONFIG_EQUALIZER is not set
576# CONFIG_TUN is not set 581# CONFIG_TUN is not set
582# CONFIG_VETH is not set
583# CONFIG_IP1000 is not set
577# CONFIG_ARCNET is not set 584# CONFIG_ARCNET is not set
578# CONFIG_NET_ETHERNET is not set 585# CONFIG_NET_ETHERNET is not set
579CONFIG_NETDEV_1000=y 586CONFIG_NETDEV_1000=y
@@ -582,6 +589,7 @@ CONFIG_NETDEV_1000=y
582CONFIG_E1000=y 589CONFIG_E1000=y
583CONFIG_E1000_NAPI=y 590CONFIG_E1000_NAPI=y
584# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set 591# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
592# CONFIG_E1000E is not set
585# CONFIG_NS83820 is not set 593# CONFIG_NS83820 is not set
586# CONFIG_HAMACHI is not set 594# CONFIG_HAMACHI is not set
587# CONFIG_YELLOWFIN is not set 595# CONFIG_YELLOWFIN is not set
@@ -589,6 +597,7 @@ CONFIG_E1000_NAPI=y
589# CONFIG_SIS190 is not set 597# CONFIG_SIS190 is not set
590# CONFIG_SKGE is not set 598# CONFIG_SKGE is not set
591# CONFIG_SKY2 is not set 599# CONFIG_SKY2 is not set
600# CONFIG_SK98LIN is not set
592# CONFIG_VIA_VELOCITY is not set 601# CONFIG_VIA_VELOCITY is not set
593# CONFIG_TIGON3 is not set 602# CONFIG_TIGON3 is not set
594# CONFIG_BNX2 is not set 603# CONFIG_BNX2 is not set
@@ -597,11 +606,14 @@ CONFIG_E1000_NAPI=y
597CONFIG_NETDEV_10000=y 606CONFIG_NETDEV_10000=y
598# CONFIG_CHELSIO_T1 is not set 607# CONFIG_CHELSIO_T1 is not set
599# CONFIG_CHELSIO_T3 is not set 608# CONFIG_CHELSIO_T3 is not set
609# CONFIG_IXGBE is not set
600# CONFIG_IXGB is not set 610# CONFIG_IXGB is not set
601# CONFIG_S2IO is not set 611# CONFIG_S2IO is not set
602# CONFIG_MYRI10GE is not set 612# CONFIG_MYRI10GE is not set
603# CONFIG_NETXEN_NIC is not set 613# CONFIG_NETXEN_NIC is not set
614# CONFIG_NIU is not set
604# CONFIG_MLX4_CORE is not set 615# CONFIG_MLX4_CORE is not set
616# CONFIG_TEHUTI is not set
605# CONFIG_TR is not set 617# CONFIG_TR is not set
606 618
607# 619#
@@ -636,7 +648,6 @@ CONFIG_INPUT_MOUSEDEV=y
636CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 648CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
637CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 649CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
638# CONFIG_INPUT_JOYDEV is not set 650# CONFIG_INPUT_JOYDEV is not set
639# CONFIG_INPUT_TSDEV is not set
640# CONFIG_INPUT_EVDEV is not set 651# CONFIG_INPUT_EVDEV is not set
641# CONFIG_INPUT_EVBUG is not set 652# CONFIG_INPUT_EVBUG is not set
642 653
@@ -685,12 +696,10 @@ CONFIG_UNIX98_PTYS=y
685CONFIG_LEGACY_PTYS=y 696CONFIG_LEGACY_PTYS=y
686CONFIG_LEGACY_PTY_COUNT=256 697CONFIG_LEGACY_PTY_COUNT=256
687# CONFIG_IPMI_HANDLER is not set 698# CONFIG_IPMI_HANDLER is not set
688# CONFIG_WATCHDOG is not set
689CONFIG_HW_RANDOM=y 699CONFIG_HW_RANDOM=y
690# CONFIG_NVRAM is not set 700# CONFIG_NVRAM is not set
691# CONFIG_R3964 is not set 701# CONFIG_R3964 is not set
692# CONFIG_APPLICOM is not set 702# CONFIG_APPLICOM is not set
693# CONFIG_DRM is not set
694# CONFIG_RAW_DRIVER is not set 703# CONFIG_RAW_DRIVER is not set
695# CONFIG_TCG_TPM is not set 704# CONFIG_TCG_TPM is not set
696CONFIG_DEVPORT=y 705CONFIG_DEVPORT=y
@@ -755,9 +764,9 @@ CONFIG_I2C_IOP3XX=y
755# CONFIG_SPI is not set 764# CONFIG_SPI is not set
756# CONFIG_SPI_MASTER is not set 765# CONFIG_SPI_MASTER is not set
757# CONFIG_W1 is not set 766# CONFIG_W1 is not set
767# CONFIG_POWER_SUPPLY is not set
758CONFIG_HWMON=y 768CONFIG_HWMON=y
759# CONFIG_HWMON_VID is not set 769# CONFIG_HWMON_VID is not set
760# CONFIG_SENSORS_ABITUGURU is not set
761# CONFIG_SENSORS_AD7418 is not set 770# CONFIG_SENSORS_AD7418 is not set
762# CONFIG_SENSORS_ADM1021 is not set 771# CONFIG_SENSORS_ADM1021 is not set
763# CONFIG_SENSORS_ADM1025 is not set 772# CONFIG_SENSORS_ADM1025 is not set
@@ -765,12 +774,13 @@ CONFIG_HWMON=y
765# CONFIG_SENSORS_ADM1029 is not set 774# CONFIG_SENSORS_ADM1029 is not set
766# CONFIG_SENSORS_ADM1031 is not set 775# CONFIG_SENSORS_ADM1031 is not set
767# CONFIG_SENSORS_ADM9240 is not set 776# CONFIG_SENSORS_ADM9240 is not set
768# CONFIG_SENSORS_ASB100 is not set 777# CONFIG_SENSORS_ADT7470 is not set
769# CONFIG_SENSORS_ATXP1 is not set 778# CONFIG_SENSORS_ATXP1 is not set
770# CONFIG_SENSORS_DS1621 is not set 779# CONFIG_SENSORS_DS1621 is not set
780# CONFIG_SENSORS_I5K_AMB is not set
771# CONFIG_SENSORS_F71805F is not set 781# CONFIG_SENSORS_F71805F is not set
772# CONFIG_SENSORS_FSCHER is not set 782# CONFIG_SENSORS_F71882FG is not set
773# CONFIG_SENSORS_FSCPOS is not set 783# CONFIG_SENSORS_F75375S is not set
774# CONFIG_SENSORS_GL518SM is not set 784# CONFIG_SENSORS_GL518SM is not set
775# CONFIG_SENSORS_GL520SM is not set 785# CONFIG_SENSORS_GL520SM is not set
776# CONFIG_SENSORS_IT87 is not set 786# CONFIG_SENSORS_IT87 is not set
@@ -784,14 +794,17 @@ CONFIG_HWMON=y
784# CONFIG_SENSORS_LM87 is not set 794# CONFIG_SENSORS_LM87 is not set
785# CONFIG_SENSORS_LM90 is not set 795# CONFIG_SENSORS_LM90 is not set
786# CONFIG_SENSORS_LM92 is not set 796# CONFIG_SENSORS_LM92 is not set
797# CONFIG_SENSORS_LM93 is not set
787# CONFIG_SENSORS_MAX1619 is not set 798# CONFIG_SENSORS_MAX1619 is not set
788# CONFIG_SENSORS_MAX6650 is not set 799# CONFIG_SENSORS_MAX6650 is not set
789# CONFIG_SENSORS_PC87360 is not set 800# CONFIG_SENSORS_PC87360 is not set
790# CONFIG_SENSORS_PC87427 is not set 801# CONFIG_SENSORS_PC87427 is not set
791# CONFIG_SENSORS_SIS5595 is not set 802# CONFIG_SENSORS_SIS5595 is not set
803# CONFIG_SENSORS_DME1737 is not set
792# CONFIG_SENSORS_SMSC47M1 is not set 804# CONFIG_SENSORS_SMSC47M1 is not set
793# CONFIG_SENSORS_SMSC47M192 is not set 805# CONFIG_SENSORS_SMSC47M192 is not set
794# CONFIG_SENSORS_SMSC47B397 is not set 806# CONFIG_SENSORS_SMSC47B397 is not set
807# CONFIG_SENSORS_THMC50 is not set
795# CONFIG_SENSORS_VIA686A is not set 808# CONFIG_SENSORS_VIA686A is not set
796# CONFIG_SENSORS_VT1211 is not set 809# CONFIG_SENSORS_VT1211 is not set
797# CONFIG_SENSORS_VT8231 is not set 810# CONFIG_SENSORS_VT8231 is not set
@@ -803,29 +816,18 @@ CONFIG_HWMON=y
803# CONFIG_SENSORS_W83627HF is not set 816# CONFIG_SENSORS_W83627HF is not set
804# CONFIG_SENSORS_W83627EHF is not set 817# CONFIG_SENSORS_W83627EHF is not set
805# CONFIG_HWMON_DEBUG_CHIP is not set 818# CONFIG_HWMON_DEBUG_CHIP is not set
806CONFIG_MISC_DEVICES=y 819# CONFIG_WATCHDOG is not set
807# CONFIG_PHANTOM is not set
808# CONFIG_EEPROM_93CX6 is not set
809# CONFIG_SGI_IOC4 is not set
810# CONFIG_TIFM_CORE is not set
811
812#
813# Multifunction device drivers
814#
815# CONFIG_MFD_SM501 is not set
816
817#
818# LED devices
819#
820# CONFIG_NEW_LEDS is not set
821 820
822# 821#
823# LED drivers 822# Sonics Silicon Backplane
824# 823#
824CONFIG_SSB_POSSIBLE=y
825# CONFIG_SSB is not set
825 826
826# 827#
827# LED Triggers 828# Multifunction device drivers
828# 829#
830# CONFIG_MFD_SM501 is not set
829 831
830# 832#
831# Multimedia devices 833# Multimedia devices
@@ -837,14 +839,16 @@ CONFIG_DAB=y
837# 839#
838# Graphics support 840# Graphics support
839# 841#
842# CONFIG_DRM is not set
843# CONFIG_VGASTATE is not set
844# CONFIG_VIDEO_OUTPUT_CONTROL is not set
845# CONFIG_FB is not set
840# CONFIG_BACKLIGHT_LCD_SUPPORT is not set 846# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
841 847
842# 848#
843# Display device support 849# Display device support
844# 850#
845# CONFIG_DISPLAY_SUPPORT is not set 851# CONFIG_DISPLAY_SUPPORT is not set
846# CONFIG_VGASTATE is not set
847# CONFIG_FB is not set
848 852
849# 853#
850# Console display driver support 854# Console display driver support
@@ -859,6 +863,7 @@ CONFIG_DUMMY_CONSOLE=y
859CONFIG_HID_SUPPORT=y 863CONFIG_HID_SUPPORT=y
860CONFIG_HID=y 864CONFIG_HID=y
861# CONFIG_HID_DEBUG is not set 865# CONFIG_HID_DEBUG is not set
866# CONFIG_HIDRAW is not set
862CONFIG_USB_SUPPORT=y 867CONFIG_USB_SUPPORT=y
863CONFIG_USB_ARCH_HAS_HCD=y 868CONFIG_USB_ARCH_HAS_HCD=y
864CONFIG_USB_ARCH_HAS_OHCI=y 869CONFIG_USB_ARCH_HAS_OHCI=y
@@ -874,16 +879,15 @@ CONFIG_USB_ARCH_HAS_EHCI=y
874# 879#
875# CONFIG_USB_GADGET is not set 880# CONFIG_USB_GADGET is not set
876# CONFIG_MMC is not set 881# CONFIG_MMC is not set
877 882# CONFIG_NEW_LEDS is not set
878#
879# Real Time Clock
880#
881CONFIG_RTC_LIB=y 883CONFIG_RTC_LIB=y
882# CONFIG_RTC_CLASS is not set 884# CONFIG_RTC_CLASS is not set
885CONFIG_DMADEVICES=y
883 886
884# 887#
885# DMA Engine support 888# DMA Devices
886# 889#
890CONFIG_INTEL_IOP_ADMA=y
887CONFIG_DMA_ENGINE=y 891CONFIG_DMA_ENGINE=y
888 892
889# 893#
@@ -892,12 +896,6 @@ CONFIG_DMA_ENGINE=y
892CONFIG_NET_DMA=y 896CONFIG_NET_DMA=y
893 897
894# 898#
895# DMA Devices
896#
897# CONFIG_INTEL_IOATDMA is not set
898CONFIG_INTEL_IOP_ADMA=y
899
900#
901# File systems 899# File systems
902# 900#
903CONFIG_EXT2_FS=y 901CONFIG_EXT2_FS=y
@@ -909,7 +907,6 @@ CONFIG_EXT3_FS_XATTR=y
909# CONFIG_EXT3_FS_SECURITY is not set 907# CONFIG_EXT3_FS_SECURITY is not set
910# CONFIG_EXT4DEV_FS is not set 908# CONFIG_EXT4DEV_FS is not set
911CONFIG_JBD=y 909CONFIG_JBD=y
912# CONFIG_JBD_DEBUG is not set
913CONFIG_FS_MBCACHE=y 910CONFIG_FS_MBCACHE=y
914# CONFIG_REISERFS_FS is not set 911# CONFIG_REISERFS_FS is not set
915# CONFIG_JFS_FS is not set 912# CONFIG_JFS_FS is not set
@@ -949,7 +946,6 @@ CONFIG_SYSFS=y
949CONFIG_TMPFS=y 946CONFIG_TMPFS=y
950# CONFIG_TMPFS_POSIX_ACL is not set 947# CONFIG_TMPFS_POSIX_ACL is not set
951# CONFIG_HUGETLB_PAGE is not set 948# CONFIG_HUGETLB_PAGE is not set
952CONFIG_RAMFS=y
953# CONFIG_CONFIGFS_FS is not set 949# CONFIG_CONFIGFS_FS is not set
954 950
955# 951#
@@ -969,10 +965,7 @@ CONFIG_CRAMFS=y
969# CONFIG_QNX4FS_FS is not set 965# CONFIG_QNX4FS_FS is not set
970# CONFIG_SYSV_FS is not set 966# CONFIG_SYSV_FS is not set
971# CONFIG_UFS_FS is not set 967# CONFIG_UFS_FS is not set
972 968CONFIG_NETWORK_FILESYSTEMS=y
973#
974# Network File Systems
975#
976CONFIG_NFS_FS=y 969CONFIG_NFS_FS=y
977CONFIG_NFS_V3=y 970CONFIG_NFS_V3=y
978# CONFIG_NFS_V3_ACL is not set 971# CONFIG_NFS_V3_ACL is not set
@@ -1019,26 +1012,17 @@ CONFIG_MSDOS_PARTITION=y
1019# CONFIG_KARMA_PARTITION is not set 1012# CONFIG_KARMA_PARTITION is not set
1020# CONFIG_EFI_PARTITION is not set 1013# CONFIG_EFI_PARTITION is not set
1021# CONFIG_SYSV68_PARTITION is not set 1014# CONFIG_SYSV68_PARTITION is not set
1022
1023#
1024# Native Language Support
1025#
1026# CONFIG_NLS is not set 1015# CONFIG_NLS is not set
1027
1028#
1029# Distributed Lock Manager
1030#
1031# CONFIG_DLM is not set 1016# CONFIG_DLM is not set
1032 1017CONFIG_INSTRUMENTATION=y
1033#
1034# Profiling support
1035#
1036# CONFIG_PROFILING is not set 1018# CONFIG_PROFILING is not set
1019# CONFIG_MARKERS is not set
1037 1020
1038# 1021#
1039# Kernel hacking 1022# Kernel hacking
1040# 1023#
1041# CONFIG_PRINTK_TIME is not set 1024# CONFIG_PRINTK_TIME is not set
1025CONFIG_ENABLE_WARN_DEPRECATED=y
1042CONFIG_ENABLE_MUST_CHECK=y 1026CONFIG_ENABLE_MUST_CHECK=y
1043CONFIG_MAGIC_SYSRQ=y 1027CONFIG_MAGIC_SYSRQ=y
1044# CONFIG_UNUSED_SYMBOLS is not set 1028# CONFIG_UNUSED_SYMBOLS is not set
@@ -1065,10 +1049,13 @@ CONFIG_DEBUG_BUGVERBOSE=y
1065# CONFIG_DEBUG_INFO is not set 1049# CONFIG_DEBUG_INFO is not set
1066# CONFIG_DEBUG_VM is not set 1050# CONFIG_DEBUG_VM is not set
1067# CONFIG_DEBUG_LIST is not set 1051# CONFIG_DEBUG_LIST is not set
1052# CONFIG_DEBUG_SG is not set
1068CONFIG_FRAME_POINTER=y 1053CONFIG_FRAME_POINTER=y
1069# CONFIG_FORCED_INLINING is not set 1054# CONFIG_FORCED_INLINING is not set
1055# CONFIG_BOOT_PRINTK_DELAY is not set
1070# CONFIG_RCU_TORTURE_TEST is not set 1056# CONFIG_RCU_TORTURE_TEST is not set
1071# CONFIG_FAULT_INJECTION is not set 1057# CONFIG_FAULT_INJECTION is not set
1058# CONFIG_SAMPLES is not set
1072CONFIG_DEBUG_USER=y 1059CONFIG_DEBUG_USER=y
1073# CONFIG_DEBUG_ERRORS is not set 1060# CONFIG_DEBUG_ERRORS is not set
1074CONFIG_DEBUG_LL=y 1061CONFIG_DEBUG_LL=y
@@ -1079,6 +1066,7 @@ CONFIG_DEBUG_LL=y
1079# 1066#
1080# CONFIG_KEYS is not set 1067# CONFIG_KEYS is not set
1081# CONFIG_SECURITY is not set 1068# CONFIG_SECURITY is not set
1069# CONFIG_SECURITY_FILE_CAPABILITIES is not set
1082CONFIG_XOR_BLOCKS=y 1070CONFIG_XOR_BLOCKS=y
1083CONFIG_ASYNC_CORE=y 1071CONFIG_ASYNC_CORE=y
1084CONFIG_ASYNC_MEMCPY=y 1072CONFIG_ASYNC_MEMCPY=y
diff --git a/arch/sh64/configs/harp_defconfig b/arch/arm/configs/littleton_defconfig
index ba302cd0c285..1db496908052 100644
--- a/arch/sh64/configs/harp_defconfig
+++ b/arch/arm/configs/littleton_defconfig
@@ -1,21 +1,29 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.24-rc1 3# Linux kernel version: 2.6.24-rc5
4# Fri Nov 2 14:35:57 2007 4# Fri Dec 21 11:06:19 2007
5# 5#
6CONFIG_SUPERH=y 6CONFIG_ARM=y
7CONFIG_SUPERH64=y 7CONFIG_SYS_SUPPORTS_APM_EMULATION=y
8CONFIG_GENERIC_GPIO=y
9CONFIG_GENERIC_TIME=y
10CONFIG_GENERIC_CLOCKEVENTS=y
8CONFIG_MMU=y 11CONFIG_MMU=y
9CONFIG_QUICKLIST=y 12# CONFIG_NO_IOPORT is not set
10CONFIG_RWSEM_GENERIC_SPINLOCK=y
11CONFIG_GENERIC_FIND_NEXT_BIT=y
12CONFIG_GENERIC_HWEIGHT=y
13CONFIG_GENERIC_CALIBRATE_DELAY=y
14CONFIG_GENERIC_HARDIRQS=y 13CONFIG_GENERIC_HARDIRQS=y
14CONFIG_STACKTRACE_SUPPORT=y
15CONFIG_LOCKDEP_SUPPORT=y
16CONFIG_TRACE_IRQFLAGS_SUPPORT=y
17CONFIG_HARDIRQS_SW_RESEND=y
15CONFIG_GENERIC_IRQ_PROBE=y 18CONFIG_GENERIC_IRQ_PROBE=y
19CONFIG_RWSEM_GENERIC_SPINLOCK=y
16# CONFIG_ARCH_HAS_ILOG2_U32 is not set 20# CONFIG_ARCH_HAS_ILOG2_U32 is not set
17# CONFIG_ARCH_HAS_ILOG2_U64 is not set 21# CONFIG_ARCH_HAS_ILOG2_U64 is not set
18CONFIG_ARCH_NO_VIRT_TO_BUS=y 22CONFIG_GENERIC_HWEIGHT=y
23CONFIG_GENERIC_CALIBRATE_DELAY=y
24CONFIG_ZONE_DMA=y
25CONFIG_ARCH_MTD_XIP=y
26CONFIG_VECTORS_BASE=0xffff0000
19CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" 27CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
20 28
21# 29#
@@ -28,11 +36,13 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
28CONFIG_LOCALVERSION="" 36CONFIG_LOCALVERSION=""
29CONFIG_LOCALVERSION_AUTO=y 37CONFIG_LOCALVERSION_AUTO=y
30CONFIG_SWAP=y 38CONFIG_SWAP=y
31# CONFIG_SYSVIPC is not set 39CONFIG_SYSVIPC=y
32CONFIG_POSIX_MQUEUE=y 40CONFIG_SYSVIPC_SYSCTL=y
41# CONFIG_POSIX_MQUEUE is not set
33# CONFIG_BSD_PROCESS_ACCT is not set 42# CONFIG_BSD_PROCESS_ACCT is not set
34# CONFIG_TASKSTATS is not set 43# CONFIG_TASKSTATS is not set
35# CONFIG_USER_NS is not set 44# CONFIG_USER_NS is not set
45# CONFIG_PID_NS is not set
36# CONFIG_AUDIT is not set 46# CONFIG_AUDIT is not set
37# CONFIG_IKCONFIG is not set 47# CONFIG_IKCONFIG is not set
38CONFIG_LOG_BUF_SHIFT=14 48CONFIG_LOG_BUF_SHIFT=14
@@ -42,8 +52,9 @@ CONFIG_FAIR_USER_SCHED=y
42# CONFIG_FAIR_CGROUP_SCHED is not set 52# CONFIG_FAIR_CGROUP_SCHED is not set
43CONFIG_SYSFS_DEPRECATED=y 53CONFIG_SYSFS_DEPRECATED=y
44# CONFIG_RELAY is not set 54# CONFIG_RELAY is not set
45# CONFIG_BLK_DEV_INITRD is not set 55CONFIG_BLK_DEV_INITRD=y
46# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set 56CONFIG_INITRAMFS_SOURCE=""
57CONFIG_CC_OPTIMIZE_FOR_SIZE=y
47CONFIG_SYSCTL=y 58CONFIG_SYSCTL=y
48# CONFIG_EMBEDDED is not set 59# CONFIG_EMBEDDED is not set
49CONFIG_UID16=y 60CONFIG_UID16=y
@@ -69,7 +80,12 @@ CONFIG_SLAB=y
69CONFIG_RT_MUTEXES=y 80CONFIG_RT_MUTEXES=y
70# CONFIG_TINY_SHMEM is not set 81# CONFIG_TINY_SHMEM is not set
71CONFIG_BASE_SMALL=0 82CONFIG_BASE_SMALL=0
72# CONFIG_MODULES is not set 83CONFIG_MODULES=y
84CONFIG_MODULE_UNLOAD=y
85CONFIG_MODULE_FORCE_UNLOAD=y
86# CONFIG_MODVERSIONS is not set
87# CONFIG_MODULE_SRCVERSION_ALL is not set
88# CONFIG_KMOD is not set
73CONFIG_BLOCK=y 89CONFIG_BLOCK=y
74# CONFIG_LBD is not set 90# CONFIG_LBD is not set
75# CONFIG_BLK_DEV_IO_TRACE is not set 91# CONFIG_BLK_DEV_IO_TRACE is not set
@@ -90,54 +106,114 @@ CONFIG_DEFAULT_CFQ=y
90CONFIG_DEFAULT_IOSCHED="cfq" 106CONFIG_DEFAULT_IOSCHED="cfq"
91 107
92# 108#
93# System type 109# System Type
110#
111# CONFIG_ARCH_AAEC2000 is not set
112# CONFIG_ARCH_INTEGRATOR is not set
113# CONFIG_ARCH_REALVIEW is not set
114# CONFIG_ARCH_VERSATILE is not set
115# CONFIG_ARCH_AT91 is not set
116# CONFIG_ARCH_CLPS7500 is not set
117# CONFIG_ARCH_CLPS711X is not set
118# CONFIG_ARCH_CO285 is not set
119# CONFIG_ARCH_EBSA110 is not set
120# CONFIG_ARCH_EP93XX is not set
121# CONFIG_ARCH_FOOTBRIDGE is not set
122# CONFIG_ARCH_NETX is not set
123# CONFIG_ARCH_H720X is not set
124# CONFIG_ARCH_IMX is not set
125# CONFIG_ARCH_IOP13XX is not set
126# CONFIG_ARCH_IOP32X is not set
127# CONFIG_ARCH_IOP33X is not set
128# CONFIG_ARCH_IXP23XX is not set
129# CONFIG_ARCH_IXP2000 is not set
130# CONFIG_ARCH_IXP4XX is not set
131# CONFIG_ARCH_L7200 is not set
132# CONFIG_ARCH_KS8695 is not set
133# CONFIG_ARCH_NS9XXX is not set
134# CONFIG_ARCH_MXC is not set
135# CONFIG_ARCH_PNX4008 is not set
136CONFIG_ARCH_PXA=y
137# CONFIG_ARCH_RPC is not set
138# CONFIG_ARCH_SA1100 is not set
139# CONFIG_ARCH_S3C2410 is not set
140# CONFIG_ARCH_SHARK is not set
141# CONFIG_ARCH_LH7A40X is not set
142# CONFIG_ARCH_DAVINCI is not set
143# CONFIG_ARCH_OMAP is not set
144
145#
146# Intel PXA2xx/PXA3xx Implementations
147#
148
149#
150# Supported PXA3xx Processor Variants
151#
152CONFIG_CPU_PXA300=y
153CONFIG_CPU_PXA310=y
154# CONFIG_CPU_PXA320 is not set
155# CONFIG_ARCH_LUBBOCK is not set
156# CONFIG_MACH_LOGICPD_PXA270 is not set
157# CONFIG_MACH_MAINSTONE is not set
158# CONFIG_ARCH_PXA_IDP is not set
159# CONFIG_PXA_SHARPSL is not set
160# CONFIG_MACH_TRIZEPS4 is not set
161# CONFIG_MACH_EM_X270 is not set
162# CONFIG_MACH_ZYLONITE is not set
163CONFIG_MACH_LITTLETON=y
164# CONFIG_MACH_ARMCORE is not set
165CONFIG_PXA3xx=y
166CONFIG_PXA_SSP=y
167
168#
169# Boot options
94# 170#
95# CONFIG_SH_SIMULATOR is not set
96# CONFIG_SH_CAYMAN is not set
97CONFIG_SH_HARP=y
98CONFIG_CPU_SH5=y
99CONFIG_CPU_SUBTYPE_SH5_101=y
100# CONFIG_CPU_SUBTYPE_SH5_103 is not set
101CONFIG_LITTLE_ENDIAN=y
102# CONFIG_BIG_ENDIAN is not set
103CONFIG_SH_FPU=y
104# CONFIG_SH64_FPU_DENORM_FLUSH is not set
105CONFIG_SH64_PGTABLE_2_LEVEL=y
106# CONFIG_SH64_PGTABLE_3_LEVEL is not set
107CONFIG_HUGETLB_PAGE_SIZE_64K=y
108# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
109# CONFIG_HUGETLB_PAGE_SIZE_512MB is not set
110CONFIG_SH64_USER_MISALIGNED_FIXUP=y
111 171
112# 172#
113# Memory options 173# Power management
114# 174#
115CONFIG_CACHED_MEMORY_OFFSET=0x20000000
116CONFIG_MEMORY_START=0x80000000
117CONFIG_MEMORY_SIZE_IN_MB=128
118 175
119# 176#
120# Cache options 177# Processor Type
121# 178#
122CONFIG_DCACHE_WRITE_BACK=y 179CONFIG_CPU_32=y
123# CONFIG_DCACHE_WRITE_THROUGH is not set 180CONFIG_CPU_XSC3=y
124# CONFIG_DCACHE_DISABLED is not set 181CONFIG_CPU_32v5=y
125# CONFIG_ICACHE_DISABLED is not set 182CONFIG_CPU_ABRT_EV5T=y
126CONFIG_PCIDEVICE_MEMORY_START=C0000000 183CONFIG_CPU_CACHE_VIVT=y
127CONFIG_DEVICE_MEMORY_START=E0000000 184CONFIG_CPU_TLB_V4WBI=y
128CONFIG_FLASH_MEMORY_START=0x00000000 185CONFIG_CPU_CP15=y
129CONFIG_PCI_BLOCK_START=0x40000000 186CONFIG_CPU_CP15_MMU=y
187CONFIG_IO_36=y
130 188
131# 189#
132# CPU Subtype specific options 190# Processor Features
191#
192# CONFIG_ARM_THUMB is not set
193# CONFIG_CPU_DCACHE_DISABLE is not set
194# CONFIG_CPU_BPREDICT_DISABLE is not set
195# CONFIG_OUTER_CACHE is not set
196CONFIG_IWMMXT=y
197
133# 198#
134CONFIG_SH64_ID2815_WORKAROUND=y 199# Bus support
200#
201# CONFIG_PCI_SYSCALL is not set
202# CONFIG_ARCH_SUPPORTS_MSI is not set
203# CONFIG_PCCARD is not set
135 204
136# 205#
137# Misc options 206# Kernel Features
138# 207#
139# CONFIG_SH_DMA is not set 208CONFIG_TICK_ONESHOT=y
209# CONFIG_NO_HZ is not set
210# CONFIG_HIGH_RES_TIMERS is not set
211CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
140CONFIG_PREEMPT=y 212CONFIG_PREEMPT=y
213CONFIG_HZ=100
214CONFIG_AEABI=y
215CONFIG_OABI_COMPAT=y
216# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
141CONFIG_SELECT_MEMORY_MODEL=y 217CONFIG_SELECT_MEMORY_MODEL=y
142CONFIG_FLATMEM_MANUAL=y 218CONFIG_FLATMEM_MANUAL=y
143# CONFIG_DISCONTIGMEM_MANUAL is not set 219# CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -146,24 +222,52 @@ CONFIG_FLATMEM=y
146CONFIG_FLAT_NODE_MEM_MAP=y 222CONFIG_FLAT_NODE_MEM_MAP=y
147# CONFIG_SPARSEMEM_STATIC is not set 223# CONFIG_SPARSEMEM_STATIC is not set
148# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set 224# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
149CONFIG_SPLIT_PTLOCK_CPUS=4 225CONFIG_SPLIT_PTLOCK_CPUS=4096
150# CONFIG_RESOURCES_64BIT is not set 226# CONFIG_RESOURCES_64BIT is not set
151CONFIG_ZONE_DMA_FLAG=0 227CONFIG_ZONE_DMA_FLAG=1
152CONFIG_NR_QUICK=1 228CONFIG_BOUNCE=y
229CONFIG_VIRT_TO_BUS=y
230CONFIG_ALIGNMENT_TRAP=y
153 231
154# 232#
155# Bus options (PCI, PCMCIA, EISA, MCA, ISA) 233# Boot options
156# 234#
157# CONFIG_ARCH_SUPPORTS_MSI is not set 235CONFIG_ZBOOT_ROM_TEXT=0x0
158# CONFIG_PCCARD is not set 236CONFIG_ZBOOT_ROM_BSS=0x0
237CONFIG_CMDLINE="root=/dev/nfs rootfstype=nfs nfsroot=192.168.1.100:/nfsroot/ ip=192.168.1.101:192.168.1.100::255.255.255.0::eth0:on console=ttyS2,38400 mem=64M"
238# CONFIG_XIP_KERNEL is not set
239# CONFIG_KEXEC is not set
240
241#
242# CPU Frequency scaling
243#
244# CONFIG_CPU_FREQ is not set
245
246#
247# Floating point emulation
248#
249
250#
251# At least one emulation must be selected
252#
253CONFIG_FPE_NWFPE=y
254# CONFIG_FPE_NWFPE_XP is not set
255# CONFIG_FPE_FASTFPE is not set
159 256
160# 257#
161# Executable file formats 258# Userspace binary formats
162# 259#
163CONFIG_BINFMT_ELF=y 260CONFIG_BINFMT_ELF=y
261# CONFIG_BINFMT_AOUT is not set
164# CONFIG_BINFMT_MISC is not set 262# CONFIG_BINFMT_MISC is not set
165 263
166# 264#
265# Power management options
266#
267# CONFIG_PM is not set
268CONFIG_SUSPEND_UP_POSSIBLE=y
269
270#
167# Networking 271# Networking
168# 272#
169CONFIG_NET=y 273CONFIG_NET=y
@@ -254,69 +358,26 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
254# Generic Driver Options 358# Generic Driver Options
255# 359#
256CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" 360CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
257CONFIG_STANDALONE=y 361# CONFIG_STANDALONE is not set
258CONFIG_PREVENT_FIRMWARE_BUILD=y 362# CONFIG_PREVENT_FIRMWARE_BUILD is not set
259# CONFIG_FW_LOADER is not set 363CONFIG_FW_LOADER=y
260# CONFIG_DEBUG_DRIVER is not set 364# CONFIG_DEBUG_DRIVER is not set
261# CONFIG_DEBUG_DEVRES is not set 365# CONFIG_DEBUG_DEVRES is not set
262# CONFIG_SYS_HYPERVISOR is not set 366# CONFIG_SYS_HYPERVISOR is not set
263# CONFIG_CONNECTOR is not set 367# CONFIG_CONNECTOR is not set
264# CONFIG_MTD is not set 368# CONFIG_MTD is not set
265# CONFIG_PARPORT is not set 369# CONFIG_PARPORT is not set
266CONFIG_BLK_DEV=y 370# CONFIG_BLK_DEV is not set
267# CONFIG_BLK_DEV_COW_COMMON is not set 371# CONFIG_MISC_DEVICES is not set
268CONFIG_BLK_DEV_LOOP=y
269# CONFIG_BLK_DEV_CRYPTOLOOP is not set
270# CONFIG_BLK_DEV_NBD is not set
271CONFIG_BLK_DEV_RAM=y
272CONFIG_BLK_DEV_RAM_COUNT=16
273CONFIG_BLK_DEV_RAM_SIZE=4096
274CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
275# CONFIG_CDROM_PKTCDVD is not set
276# CONFIG_ATA_OVER_ETH is not set
277CONFIG_MISC_DEVICES=y
278# CONFIG_EEPROM_93CX6 is not set
279# CONFIG_IDE is not set 372# CONFIG_IDE is not set
280 373
281# 374#
282# SCSI device support 375# SCSI device support
283# 376#
284# CONFIG_RAID_ATTRS is not set 377# CONFIG_RAID_ATTRS is not set
285CONFIG_SCSI=y 378# CONFIG_SCSI is not set
286CONFIG_SCSI_DMA=y 379# CONFIG_SCSI_DMA is not set
287# CONFIG_SCSI_TGT is not set
288# CONFIG_SCSI_NETLINK is not set 380# CONFIG_SCSI_NETLINK is not set
289CONFIG_SCSI_PROC_FS=y
290
291#
292# SCSI support type (disk, tape, CD-ROM)
293#
294CONFIG_BLK_DEV_SD=y
295# CONFIG_CHR_DEV_ST is not set
296# CONFIG_CHR_DEV_OSST is not set
297# CONFIG_BLK_DEV_SR is not set
298# CONFIG_CHR_DEV_SG is not set
299# CONFIG_CHR_DEV_SCH is not set
300
301#
302# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
303#
304CONFIG_SCSI_MULTI_LUN=y
305# CONFIG_SCSI_CONSTANTS is not set
306# CONFIG_SCSI_LOGGING is not set
307# CONFIG_SCSI_SCAN_ASYNC is not set
308
309#
310# SCSI Transports
311#
312CONFIG_SCSI_SPI_ATTRS=y
313# CONFIG_SCSI_FC_ATTRS is not set
314# CONFIG_SCSI_ISCSI_ATTRS is not set
315# CONFIG_SCSI_SAS_LIBSAS is not set
316# CONFIG_SCSI_SRP_ATTRS is not set
317CONFIG_SCSI_LOWLEVEL=y
318# CONFIG_ISCSI_TCP is not set
319# CONFIG_SCSI_DEBUG is not set
320# CONFIG_ATA is not set 381# CONFIG_ATA is not set
321# CONFIG_MD is not set 382# CONFIG_MD is not set
322CONFIG_NETDEVICES=y 383CONFIG_NETDEVICES=y
@@ -329,17 +390,18 @@ CONFIG_NETDEVICES=y
329# CONFIG_VETH is not set 390# CONFIG_VETH is not set
330# CONFIG_PHYLIB is not set 391# CONFIG_PHYLIB is not set
331CONFIG_NET_ETHERNET=y 392CONFIG_NET_ETHERNET=y
332# CONFIG_MII is not set 393CONFIG_MII=y
333# CONFIG_STNIC is not set 394# CONFIG_AX88796 is not set
334# CONFIG_SMC91X is not set 395CONFIG_SMC91X=y
396# CONFIG_DM9000 is not set
335# CONFIG_SMC911X is not set 397# CONFIG_SMC911X is not set
336# CONFIG_IBM_NEW_EMAC_ZMII is not set 398# CONFIG_IBM_NEW_EMAC_ZMII is not set
337# CONFIG_IBM_NEW_EMAC_RGMII is not set 399# CONFIG_IBM_NEW_EMAC_RGMII is not set
338# CONFIG_IBM_NEW_EMAC_TAH is not set 400# CONFIG_IBM_NEW_EMAC_TAH is not set
339# CONFIG_IBM_NEW_EMAC_EMAC4 is not set 401# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
340# CONFIG_B44 is not set 402# CONFIG_B44 is not set
341CONFIG_NETDEV_1000=y 403# CONFIG_NETDEV_1000 is not set
342CONFIG_NETDEV_10000=y 404# CONFIG_NETDEV_10000 is not set
343 405
344# 406#
345# Wireless LAN 407# Wireless LAN
@@ -354,7 +416,6 @@ CONFIG_NETDEV_10000=y
354# CONFIG_NETPOLL is not set 416# CONFIG_NETPOLL is not set
355# CONFIG_NET_POLL_CONTROLLER is not set 417# CONFIG_NET_POLL_CONTROLLER is not set
356# CONFIG_ISDN is not set 418# CONFIG_ISDN is not set
357# CONFIG_PHONE is not set
358 419
359# 420#
360# Input device support 421# Input device support
@@ -407,16 +468,15 @@ CONFIG_HW_CONSOLE=y
407# 468#
408# Non-8250 serial port support 469# Non-8250 serial port support
409# 470#
410CONFIG_SERIAL_SH_SCI=y 471CONFIG_SERIAL_PXA=y
411CONFIG_SERIAL_SH_SCI_NR_UARTS=2 472CONFIG_SERIAL_PXA_CONSOLE=y
412CONFIG_SERIAL_SH_SCI_CONSOLE=y
413CONFIG_SERIAL_CORE=y 473CONFIG_SERIAL_CORE=y
414CONFIG_SERIAL_CORE_CONSOLE=y 474CONFIG_SERIAL_CORE_CONSOLE=y
415CONFIG_UNIX98_PTYS=y 475CONFIG_UNIX98_PTYS=y
416CONFIG_LEGACY_PTYS=y 476# CONFIG_LEGACY_PTYS is not set
417CONFIG_LEGACY_PTY_COUNT=256
418# CONFIG_IPMI_HANDLER is not set 477# CONFIG_IPMI_HANDLER is not set
419CONFIG_HW_RANDOM=y 478# CONFIG_HW_RANDOM is not set
479# CONFIG_NVRAM is not set
420# CONFIG_R3964 is not set 480# CONFIG_R3964 is not set
421# CONFIG_RAW_DRIVER is not set 481# CONFIG_RAW_DRIVER is not set
422# CONFIG_TCG_TPM is not set 482# CONFIG_TCG_TPM is not set
@@ -429,26 +489,8 @@ CONFIG_HW_RANDOM=y
429# CONFIG_SPI_MASTER is not set 489# CONFIG_SPI_MASTER is not set
430# CONFIG_W1 is not set 490# CONFIG_W1 is not set
431# CONFIG_POWER_SUPPLY is not set 491# CONFIG_POWER_SUPPLY is not set
432CONFIG_HWMON=y 492# CONFIG_HWMON is not set
433# CONFIG_HWMON_VID is not set 493# CONFIG_WATCHDOG is not set
434# CONFIG_SENSORS_F71805F is not set
435# CONFIG_SENSORS_F71882FG is not set
436# CONFIG_SENSORS_IT87 is not set
437# CONFIG_SENSORS_PC87360 is not set
438# CONFIG_SENSORS_PC87427 is not set
439# CONFIG_SENSORS_SMSC47M1 is not set
440# CONFIG_SENSORS_SMSC47B397 is not set
441# CONFIG_SENSORS_VT1211 is not set
442# CONFIG_SENSORS_W83627HF is not set
443# CONFIG_SENSORS_W83627EHF is not set
444# CONFIG_HWMON_DEBUG_CHIP is not set
445CONFIG_WATCHDOG=y
446# CONFIG_WATCHDOG_NOWAYOUT is not set
447
448#
449# Watchdog Device Drivers
450#
451# CONFIG_SOFT_WATCHDOG is not set
452 494
453# 495#
454# Sonics Silicon Backplane 496# Sonics Silicon Backplane
@@ -466,19 +508,19 @@ CONFIG_SSB_POSSIBLE=y
466# 508#
467# CONFIG_VIDEO_DEV is not set 509# CONFIG_VIDEO_DEV is not set
468# CONFIG_DVB_CORE is not set 510# CONFIG_DVB_CORE is not set
469CONFIG_DAB=y 511# CONFIG_DAB is not set
470 512
471# 513#
472# Graphics support 514# Graphics support
473# 515#
474# CONFIG_VGASTATE is not set 516# CONFIG_VGASTATE is not set
475CONFIG_VIDEO_OUTPUT_CONTROL=y 517# CONFIG_VIDEO_OUTPUT_CONTROL is not set
476CONFIG_FB=y 518CONFIG_FB=y
477CONFIG_FIRMWARE_EDID=y 519# CONFIG_FIRMWARE_EDID is not set
478# CONFIG_FB_DDC is not set 520# CONFIG_FB_DDC is not set
479# CONFIG_FB_CFB_FILLRECT is not set 521CONFIG_FB_CFB_FILLRECT=y
480# CONFIG_FB_CFB_COPYAREA is not set 522CONFIG_FB_CFB_COPYAREA=y
481# CONFIG_FB_CFB_IMAGEBLIT is not set 523CONFIG_FB_CFB_IMAGEBLIT=y
482# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set 524# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
483# CONFIG_FB_SYS_FILLRECT is not set 525# CONFIG_FB_SYS_FILLRECT is not set
484# CONFIG_FB_SYS_COPYAREA is not set 526# CONFIG_FB_SYS_COPYAREA is not set
@@ -488,13 +530,16 @@ CONFIG_FB_DEFERRED_IO=y
488# CONFIG_FB_SVGALIB is not set 530# CONFIG_FB_SVGALIB is not set
489# CONFIG_FB_MACMODES is not set 531# CONFIG_FB_MACMODES is not set
490# CONFIG_FB_BACKLIGHT is not set 532# CONFIG_FB_BACKLIGHT is not set
491CONFIG_FB_MODE_HELPERS=y 533# CONFIG_FB_MODE_HELPERS is not set
492# CONFIG_FB_TILEBLITTING is not set 534# CONFIG_FB_TILEBLITTING is not set
493 535
494# 536#
495# Frame buffer hardware drivers 537# Frame buffer hardware drivers
496# 538#
497# CONFIG_FB_S1D13XXX is not set 539# CONFIG_FB_S1D13XXX is not set
540CONFIG_FB_PXA=y
541# CONFIG_FB_PXA_PARAMETERS is not set
542# CONFIG_FB_MBX is not set
498# CONFIG_FB_VIRTUAL is not set 543# CONFIG_FB_VIRTUAL is not set
499# CONFIG_BACKLIGHT_LCD_SUPPORT is not set 544# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
500 545
@@ -506,6 +551,7 @@ CONFIG_FB_MODE_HELPERS=y
506# 551#
507# Console display driver support 552# Console display driver support
508# 553#
554# CONFIG_VGA_CONSOLE is not set
509CONFIG_DUMMY_CONSOLE=y 555CONFIG_DUMMY_CONSOLE=y
510CONFIG_FRAMEBUFFER_CONSOLE=y 556CONFIG_FRAMEBUFFER_CONSOLE=y
511# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set 557# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
@@ -522,70 +568,38 @@ CONFIG_FONT_8x16=y
522# CONFIG_FONT_SUN12x22 is not set 568# CONFIG_FONT_SUN12x22 is not set
523# CONFIG_FONT_10x18 is not set 569# CONFIG_FONT_10x18 is not set
524CONFIG_LOGO=y 570CONFIG_LOGO=y
525# CONFIG_LOGO_LINUX_MONO is not set 571CONFIG_LOGO_LINUX_MONO=y
526# CONFIG_LOGO_LINUX_VGA16 is not set 572CONFIG_LOGO_LINUX_VGA16=y
527# CONFIG_LOGO_LINUX_CLUT224 is not set 573CONFIG_LOGO_LINUX_CLUT224=y
528# CONFIG_LOGO_SUPERH_MONO is not set
529# CONFIG_LOGO_SUPERH_VGA16 is not set
530CONFIG_LOGO_SUPERH_CLUT224=y
531 574
532# 575#
533# Sound 576# Sound
534# 577#
535# CONFIG_SOUND is not set 578# CONFIG_SOUND is not set
536CONFIG_HID_SUPPORT=y 579# CONFIG_HID_SUPPORT is not set
537CONFIG_HID=y 580# CONFIG_USB_SUPPORT is not set
538# CONFIG_HID_DEBUG is not set
539# CONFIG_HIDRAW is not set
540CONFIG_USB_SUPPORT=y
541CONFIG_USB_ARCH_HAS_HCD=y
542# CONFIG_USB_ARCH_HAS_OHCI is not set
543# CONFIG_USB_ARCH_HAS_EHCI is not set
544# CONFIG_USB is not set
545
546#
547# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
548#
549
550#
551# USB Gadget Support
552#
553# CONFIG_USB_GADGET is not set
554# CONFIG_MMC is not set 581# CONFIG_MMC is not set
555# CONFIG_NEW_LEDS is not set 582# CONFIG_NEW_LEDS is not set
583CONFIG_RTC_LIB=y
556# CONFIG_RTC_CLASS is not set 584# CONFIG_RTC_CLASS is not set
557 585
558# 586#
559# Userspace I/O
560#
561# CONFIG_UIO is not set
562
563#
564# File systems 587# File systems
565# 588#
566CONFIG_EXT2_FS=y 589# CONFIG_EXT2_FS is not set
567# CONFIG_EXT2_FS_XATTR is not set 590# CONFIG_EXT3_FS is not set
568# CONFIG_EXT2_FS_XIP is not set
569CONFIG_EXT3_FS=y
570CONFIG_EXT3_FS_XATTR=y
571# CONFIG_EXT3_FS_POSIX_ACL is not set
572# CONFIG_EXT3_FS_SECURITY is not set
573# CONFIG_EXT4DEV_FS is not set 591# CONFIG_EXT4DEV_FS is not set
574CONFIG_JBD=y
575# CONFIG_JBD_DEBUG is not set
576CONFIG_FS_MBCACHE=y
577# CONFIG_REISERFS_FS is not set 592# CONFIG_REISERFS_FS is not set
578# CONFIG_JFS_FS is not set 593# CONFIG_JFS_FS is not set
579# CONFIG_FS_POSIX_ACL is not set 594CONFIG_FS_POSIX_ACL=y
580# CONFIG_XFS_FS is not set 595# CONFIG_XFS_FS is not set
581# CONFIG_GFS2_FS is not set 596# CONFIG_GFS2_FS is not set
582# CONFIG_OCFS2_FS is not set 597# CONFIG_OCFS2_FS is not set
583CONFIG_MINIX_FS=y 598# CONFIG_MINIX_FS is not set
584CONFIG_ROMFS_FS=y 599# CONFIG_ROMFS_FS is not set
585CONFIG_INOTIFY=y 600# CONFIG_INOTIFY is not set
586CONFIG_INOTIFY_USER=y
587# CONFIG_QUOTA is not set 601# CONFIG_QUOTA is not set
588CONFIG_DNOTIFY=y 602# CONFIG_DNOTIFY is not set
589# CONFIG_AUTOFS_FS is not set 603# CONFIG_AUTOFS_FS is not set
590# CONFIG_AUTOFS4_FS is not set 604# CONFIG_AUTOFS4_FS is not set
591# CONFIG_FUSE_FS is not set 605# CONFIG_FUSE_FS is not set
@@ -607,13 +621,10 @@ CONFIG_DNOTIFY=y
607# Pseudo filesystems 621# Pseudo filesystems
608# 622#
609CONFIG_PROC_FS=y 623CONFIG_PROC_FS=y
610CONFIG_PROC_KCORE=y
611CONFIG_PROC_SYSCTL=y 624CONFIG_PROC_SYSCTL=y
612CONFIG_SYSFS=y 625CONFIG_SYSFS=y
613CONFIG_TMPFS=y 626# CONFIG_TMPFS is not set
614# CONFIG_TMPFS_POSIX_ACL is not set 627# CONFIG_HUGETLB_PAGE is not set
615CONFIG_HUGETLBFS=y
616CONFIG_HUGETLB_PAGE=y
617# CONFIG_CONFIGFS_FS is not set 628# CONFIG_CONFIGFS_FS is not set
618 629
619# 630#
@@ -635,17 +646,19 @@ CONFIG_HUGETLB_PAGE=y
635CONFIG_NETWORK_FILESYSTEMS=y 646CONFIG_NETWORK_FILESYSTEMS=y
636CONFIG_NFS_FS=y 647CONFIG_NFS_FS=y
637CONFIG_NFS_V3=y 648CONFIG_NFS_V3=y
638# CONFIG_NFS_V3_ACL is not set 649CONFIG_NFS_V3_ACL=y
639# CONFIG_NFS_V4 is not set 650CONFIG_NFS_V4=y
640# CONFIG_NFS_DIRECTIO is not set 651CONFIG_NFS_DIRECTIO=y
641# CONFIG_NFSD is not set 652# CONFIG_NFSD is not set
642CONFIG_ROOT_NFS=y 653CONFIG_ROOT_NFS=y
643CONFIG_LOCKD=y 654CONFIG_LOCKD=y
644CONFIG_LOCKD_V4=y 655CONFIG_LOCKD_V4=y
656CONFIG_NFS_ACL_SUPPORT=y
645CONFIG_NFS_COMMON=y 657CONFIG_NFS_COMMON=y
646CONFIG_SUNRPC=y 658CONFIG_SUNRPC=y
659CONFIG_SUNRPC_GSS=y
647# CONFIG_SUNRPC_BIND34 is not set 660# CONFIG_SUNRPC_BIND34 is not set
648# CONFIG_RPCSEC_GSS_KRB5 is not set 661CONFIG_RPCSEC_GSS_KRB5=y
649# CONFIG_RPCSEC_GSS_SPKM3 is not set 662# CONFIG_RPCSEC_GSS_SPKM3 is not set
650# CONFIG_SMB_FS is not set 663# CONFIG_SMB_FS is not set
651# CONFIG_CIFS is not set 664# CONFIG_CIFS is not set
@@ -656,70 +669,55 @@ CONFIG_SUNRPC=y
656# 669#
657# Partition Types 670# Partition Types
658# 671#
659CONFIG_PARTITION_ADVANCED=y 672# CONFIG_PARTITION_ADVANCED is not set
660# CONFIG_ACORN_PARTITION is not set
661# CONFIG_OSF_PARTITION is not set
662# CONFIG_AMIGA_PARTITION is not set
663# CONFIG_ATARI_PARTITION is not set
664# CONFIG_MAC_PARTITION is not set
665CONFIG_MSDOS_PARTITION=y 673CONFIG_MSDOS_PARTITION=y
666# CONFIG_BSD_DISKLABEL is not set
667# CONFIG_MINIX_SUBPARTITION is not set
668# CONFIG_SOLARIS_X86_PARTITION is not set
669# CONFIG_UNIXWARE_DISKLABEL is not set
670# CONFIG_LDM_PARTITION is not set
671# CONFIG_SGI_PARTITION is not set
672# CONFIG_ULTRIX_PARTITION is not set
673# CONFIG_SUN_PARTITION is not set
674# CONFIG_KARMA_PARTITION is not set
675# CONFIG_EFI_PARTITION is not set
676# CONFIG_SYSV68_PARTITION is not set
677# CONFIG_NLS is not set 674# CONFIG_NLS is not set
678# CONFIG_DLM is not set 675# CONFIG_DLM is not set
679CONFIG_INSTRUMENTATION=y 676# CONFIG_INSTRUMENTATION is not set
680# CONFIG_PROFILING is not set
681# CONFIG_MARKERS is not set
682 677
683# 678#
684# Kernel hacking 679# Kernel hacking
685# 680#
686# CONFIG_PRINTK_TIME is not set 681CONFIG_PRINTK_TIME=y
687CONFIG_ENABLE_WARN_DEPRECATED=y 682CONFIG_ENABLE_WARN_DEPRECATED=y
688CONFIG_ENABLE_MUST_CHECK=y 683CONFIG_ENABLE_MUST_CHECK=y
689CONFIG_MAGIC_SYSRQ=y 684CONFIG_MAGIC_SYSRQ=y
690# CONFIG_UNUSED_SYMBOLS is not set 685# CONFIG_UNUSED_SYMBOLS is not set
691CONFIG_DEBUG_FS=y 686# CONFIG_DEBUG_FS is not set
692# CONFIG_HEADERS_CHECK is not set 687# CONFIG_HEADERS_CHECK is not set
693CONFIG_DEBUG_KERNEL=y 688CONFIG_DEBUG_KERNEL=y
694# CONFIG_DEBUG_SHIRQ is not set 689# CONFIG_DEBUG_SHIRQ is not set
695CONFIG_DETECT_SOFTLOCKUP=y 690CONFIG_DETECT_SOFTLOCKUP=y
696CONFIG_SCHED_DEBUG=y 691CONFIG_SCHED_DEBUG=y
697CONFIG_SCHEDSTATS=y 692# CONFIG_SCHEDSTATS is not set
698# CONFIG_TIMER_STATS is not set 693# CONFIG_TIMER_STATS is not set
699# CONFIG_DEBUG_SLAB is not set 694# CONFIG_DEBUG_SLAB is not set
695# CONFIG_DEBUG_PREEMPT is not set
700# CONFIG_DEBUG_RT_MUTEXES is not set 696# CONFIG_DEBUG_RT_MUTEXES is not set
701# CONFIG_RT_MUTEX_TESTER is not set 697# CONFIG_RT_MUTEX_TESTER is not set
702# CONFIG_DEBUG_SPINLOCK is not set 698# CONFIG_DEBUG_SPINLOCK is not set
703# CONFIG_DEBUG_MUTEXES is not set 699# CONFIG_DEBUG_MUTEXES is not set
700# CONFIG_DEBUG_LOCK_ALLOC is not set
701# CONFIG_PROVE_LOCKING is not set
702# CONFIG_LOCK_STAT is not set
704# CONFIG_DEBUG_SPINLOCK_SLEEP is not set 703# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
705# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set 704# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
706# CONFIG_DEBUG_KOBJECT is not set 705# CONFIG_DEBUG_KOBJECT is not set
707CONFIG_DEBUG_BUGVERBOSE=y 706CONFIG_DEBUG_BUGVERBOSE=y
708# CONFIG_DEBUG_INFO is not set 707CONFIG_DEBUG_INFO=y
709# CONFIG_DEBUG_VM is not set 708# CONFIG_DEBUG_VM is not set
710# CONFIG_DEBUG_LIST is not set 709# CONFIG_DEBUG_LIST is not set
711# CONFIG_DEBUG_SG is not set 710# CONFIG_DEBUG_SG is not set
712CONFIG_FRAME_POINTER=y 711CONFIG_FRAME_POINTER=y
713CONFIG_FORCED_INLINING=y 712CONFIG_FORCED_INLINING=y
714# CONFIG_BOOT_PRINTK_DELAY is not set 713# CONFIG_BOOT_PRINTK_DELAY is not set
714# CONFIG_RCU_TORTURE_TEST is not set
715# CONFIG_FAULT_INJECTION is not set 715# CONFIG_FAULT_INJECTION is not set
716# CONFIG_SAMPLES is not set 716# CONFIG_SAMPLES is not set
717# CONFIG_EARLY_PRINTK is not set 717CONFIG_DEBUG_USER=y
718CONFIG_SH64_PROC_TLB=y 718CONFIG_DEBUG_ERRORS=y
719CONFIG_SH64_PROC_ASIDS=y 719CONFIG_DEBUG_LL=y
720CONFIG_SH64_SR_WATCH=y 720# CONFIG_DEBUG_ICEDCC is not set
721# CONFIG_POOR_MANS_STRACE is not set
722# CONFIG_SH_NO_BSS_INIT is not set
723 721
724# 722#
725# Security options 723# Security options
@@ -727,13 +725,53 @@ CONFIG_SH64_SR_WATCH=y
727# CONFIG_KEYS is not set 725# CONFIG_KEYS is not set
728# CONFIG_SECURITY is not set 726# CONFIG_SECURITY is not set
729# CONFIG_SECURITY_FILE_CAPABILITIES is not set 727# CONFIG_SECURITY_FILE_CAPABILITIES is not set
730# CONFIG_CRYPTO is not set 728CONFIG_CRYPTO=y
729CONFIG_CRYPTO_ALGAPI=y
730CONFIG_CRYPTO_BLKCIPHER=y
731CONFIG_CRYPTO_MANAGER=y
732# CONFIG_CRYPTO_HMAC is not set
733# CONFIG_CRYPTO_XCBC is not set
734# CONFIG_CRYPTO_NULL is not set
735# CONFIG_CRYPTO_MD4 is not set
736CONFIG_CRYPTO_MD5=y
737# CONFIG_CRYPTO_SHA1 is not set
738# CONFIG_CRYPTO_SHA256 is not set
739# CONFIG_CRYPTO_SHA512 is not set
740# CONFIG_CRYPTO_WP512 is not set
741# CONFIG_CRYPTO_TGR192 is not set
742# CONFIG_CRYPTO_GF128MUL is not set
743# CONFIG_CRYPTO_ECB is not set
744CONFIG_CRYPTO_CBC=y
745# CONFIG_CRYPTO_PCBC is not set
746# CONFIG_CRYPTO_LRW is not set
747# CONFIG_CRYPTO_XTS is not set
748# CONFIG_CRYPTO_CRYPTD is not set
749CONFIG_CRYPTO_DES=y
750# CONFIG_CRYPTO_FCRYPT is not set
751# CONFIG_CRYPTO_BLOWFISH is not set
752# CONFIG_CRYPTO_TWOFISH is not set
753# CONFIG_CRYPTO_SERPENT is not set
754# CONFIG_CRYPTO_AES is not set
755# CONFIG_CRYPTO_CAST5 is not set
756# CONFIG_CRYPTO_CAST6 is not set
757# CONFIG_CRYPTO_TEA is not set
758# CONFIG_CRYPTO_ARC4 is not set
759# CONFIG_CRYPTO_KHAZAD is not set
760# CONFIG_CRYPTO_ANUBIS is not set
761# CONFIG_CRYPTO_SEED is not set
762# CONFIG_CRYPTO_DEFLATE is not set
763# CONFIG_CRYPTO_MICHAEL_MIC is not set
764# CONFIG_CRYPTO_CRC32C is not set
765# CONFIG_CRYPTO_CAMELLIA is not set
766# CONFIG_CRYPTO_TEST is not set
767# CONFIG_CRYPTO_AUTHENC is not set
768CONFIG_CRYPTO_HW=y
731 769
732# 770#
733# Library routines 771# Library routines
734# 772#
735CONFIG_BITREVERSE=y 773CONFIG_BITREVERSE=y
736# CONFIG_CRC_CCITT is not set 774CONFIG_CRC_CCITT=y
737# CONFIG_CRC16 is not set 775# CONFIG_CRC16 is not set
738# CONFIG_CRC_ITU_T is not set 776# CONFIG_CRC_ITU_T is not set
739CONFIG_CRC32=y 777CONFIG_CRC32=y
diff --git a/arch/arm/configs/msm_defconfig b/arch/arm/configs/msm_defconfig
new file mode 100644
index 000000000000..ae4c5e62086a
--- /dev/null
+++ b/arch/arm/configs/msm_defconfig
@@ -0,0 +1,895 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.23
4# Wed Nov 7 01:36:45 2007
5#
6CONFIG_ARM=y
7CONFIG_SYS_SUPPORTS_APM_EMULATION=y
8# CONFIG_GENERIC_GPIO is not set
9CONFIG_GENERIC_TIME=y
10CONFIG_GENERIC_CLOCKEVENTS=y
11CONFIG_MMU=y
12# CONFIG_NO_IOPORT is not set
13CONFIG_GENERIC_HARDIRQS=y
14CONFIG_GENERIC_GPIOS=y
15CONFIG_STACKTRACE_SUPPORT=y
16CONFIG_LOCKDEP_SUPPORT=y
17CONFIG_TRACE_IRQFLAGS_SUPPORT=y
18CONFIG_HARDIRQS_SW_RESEND=y
19CONFIG_GENERIC_IRQ_PROBE=y
20CONFIG_RWSEM_GENERIC_SPINLOCK=y
21# CONFIG_ARCH_HAS_ILOG2_U32 is not set
22# CONFIG_ARCH_HAS_ILOG2_U64 is not set
23CONFIG_GENERIC_HWEIGHT=y
24CONFIG_GENERIC_CALIBRATE_DELAY=y
25CONFIG_ZONE_DMA=y
26CONFIG_VECTORS_BASE=0xffff0000
27CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
28
29#
30# General setup
31#
32CONFIG_EXPERIMENTAL=y
33CONFIG_BROKEN_ON_SMP=y
34CONFIG_LOCK_KERNEL=y
35CONFIG_INIT_ENV_ARG_LIMIT=32
36CONFIG_LOCALVERSION=""
37CONFIG_LOCALVERSION_AUTO=y
38CONFIG_SWAP=y
39# CONFIG_SYSVIPC is not set
40# CONFIG_POSIX_MQUEUE is not set
41# CONFIG_BSD_PROCESS_ACCT is not set
42# CONFIG_TASKSTATS is not set
43# CONFIG_USER_NS is not set
44# CONFIG_AUDIT is not set
45CONFIG_IKCONFIG=y
46CONFIG_IKCONFIG_PROC=y
47CONFIG_LOG_BUF_SHIFT=17
48CONFIG_SYSFS_DEPRECATED=y
49# CONFIG_RELAY is not set
50CONFIG_BLK_DEV_INITRD=y
51CONFIG_INITRAMFS_SOURCE=""
52CONFIG_CC_OPTIMIZE_FOR_SIZE=y
53CONFIG_SYSCTL=y
54CONFIG_PANIC_TIMEOUT=0
55# CONFIG_EMBEDDED is not set
56CONFIG_UID16=y
57CONFIG_SYSCTL_SYSCALL=y
58CONFIG_KALLSYMS=y
59# CONFIG_KALLSYMS_ALL is not set
60# CONFIG_KALLSYMS_EXTRA_PASS is not set
61CONFIG_HOTPLUG=y
62CONFIG_PRINTK=y
63CONFIG_BUG=y
64CONFIG_ELF_CORE=y
65CONFIG_BASE_FULL=y
66CONFIG_FUTEX=y
67CONFIG_ANON_INODES=y
68CONFIG_EPOLL=y
69CONFIG_SIGNALFD=y
70CONFIG_EVENTFD=y
71CONFIG_SHMEM=y
72CONFIG_VM_EVENT_COUNTERS=y
73CONFIG_SLAB=y
74# CONFIG_SLUB is not set
75# CONFIG_SLOB is not set
76CONFIG_RT_MUTEXES=y
77# CONFIG_TINY_SHMEM is not set
78CONFIG_BASE_SMALL=0
79# CONFIG_MODULES is not set
80CONFIG_BLOCK=y
81# CONFIG_LBD is not set
82# CONFIG_BLK_DEV_IO_TRACE is not set
83# CONFIG_LSF is not set
84# CONFIG_BLK_DEV_BSG is not set
85
86#
87# IO Schedulers
88#
89CONFIG_IOSCHED_NOOP=y
90CONFIG_IOSCHED_AS=y
91# CONFIG_IOSCHED_DEADLINE is not set
92# CONFIG_IOSCHED_CFQ is not set
93CONFIG_DEFAULT_AS=y
94# CONFIG_DEFAULT_DEADLINE is not set
95# CONFIG_DEFAULT_CFQ is not set
96# CONFIG_DEFAULT_NOOP is not set
97CONFIG_DEFAULT_IOSCHED="anticipatory"
98
99#
100# System Type
101#
102# CONFIG_ARCH_AAEC2000 is not set
103# CONFIG_ARCH_GOLDFISH is not set
104# CONFIG_ARCH_INTEGRATOR is not set
105# CONFIG_ARCH_REALVIEW is not set
106# CONFIG_ARCH_VERSATILE is not set
107# CONFIG_ARCH_AT91 is not set
108# CONFIG_ARCH_CLPS7500 is not set
109# CONFIG_ARCH_CLPS711X is not set
110# CONFIG_ARCH_CO285 is not set
111# CONFIG_ARCH_EBSA110 is not set
112# CONFIG_ARCH_EP93XX is not set
113# CONFIG_ARCH_FOOTBRIDGE is not set
114# CONFIG_ARCH_NETX is not set
115# CONFIG_ARCH_H720X is not set
116# CONFIG_ARCH_IMX is not set
117# CONFIG_ARCH_IOP13XX is not set
118# CONFIG_ARCH_IOP32X is not set
119# CONFIG_ARCH_IOP33X is not set
120# CONFIG_ARCH_IXP23XX is not set
121# CONFIG_ARCH_IXP2000 is not set
122# CONFIG_ARCH_IXP4XX is not set
123# CONFIG_ARCH_L7200 is not set
124# CONFIG_ARCH_KS8695 is not set
125# CONFIG_ARCH_NS9XXX is not set
126# CONFIG_ARCH_MXC is not set
127# CONFIG_ARCH_PNX4008 is not set
128# CONFIG_ARCH_PXA is not set
129# CONFIG_ARCH_RPC is not set
130# CONFIG_ARCH_SA1100 is not set
131# CONFIG_ARCH_S3C2410 is not set
132# CONFIG_ARCH_SHARK is not set
133# CONFIG_ARCH_LH7A40X is not set
134# CONFIG_ARCH_DAVINCI is not set
135# CONFIG_ARCH_OMAP is not set
136CONFIG_ARCH_MSM7X00A=y
137
138#
139# Boot options
140#
141
142#
143# Power management
144#
145
146#
147# MSM7200 Board Type
148#
149CONFIG_MACH_HALIBUT=y
150CONFIG_SERIAL_MSM=y
151CONFIG_SERIAL_MSM_CONSOLE=y
152# CONFIG_SERIAL_MSM_NOINIT is not set
153CONFIG_MSM_SMD=y
154
155#
156# Processor Type
157#
158CONFIG_CPU_32=y
159CONFIG_CPU_V6=y
160# CONFIG_CPU_32v6K is not set
161CONFIG_CPU_32v6=y
162CONFIG_CPU_ABRT_EV6=y
163CONFIG_CPU_CACHE_V6=y
164CONFIG_CPU_CACHE_VIPT=y
165CONFIG_CPU_COPY_V6=y
166CONFIG_CPU_TLB_V6=y
167CONFIG_CPU_HAS_ASID=y
168CONFIG_CPU_CP15=y
169CONFIG_CPU_CP15_MMU=y
170
171#
172# Processor Features
173#
174CONFIG_ARM_THUMB=y
175# CONFIG_CPU_ICACHE_DISABLE is not set
176# CONFIG_CPU_DCACHE_DISABLE is not set
177# CONFIG_CPU_BPREDICT_DISABLE is not set
178# CONFIG_OUTER_CACHE is not set
179
180#
181# Bus support
182#
183# CONFIG_PCI_SYSCALL is not set
184# CONFIG_ARCH_SUPPORTS_MSI is not set
185
186#
187# PCCARD (PCMCIA/CardBus) support
188#
189# CONFIG_PCCARD is not set
190
191#
192# Kernel Features
193#
194CONFIG_TICK_ONESHOT=y
195CONFIG_NO_HZ=y
196CONFIG_HIGH_RES_TIMERS=y
197CONFIG_PREEMPT=y
198CONFIG_HZ=100
199CONFIG_AEABI=y
200# CONFIG_OABI_COMPAT is not set
201# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
202CONFIG_SELECT_MEMORY_MODEL=y
203CONFIG_FLATMEM_MANUAL=y
204# CONFIG_DISCONTIGMEM_MANUAL is not set
205# CONFIG_SPARSEMEM_MANUAL is not set
206CONFIG_FLATMEM=y
207CONFIG_FLAT_NODE_MEM_MAP=y
208# CONFIG_SPARSEMEM_STATIC is not set
209CONFIG_SPLIT_PTLOCK_CPUS=4
210CONFIG_RESOURCES_64BIT=y
211CONFIG_ZONE_DMA_FLAG=1
212CONFIG_BOUNCE=y
213CONFIG_VIRT_TO_BUS=y
214CONFIG_ALIGNMENT_TRAP=y
215
216#
217# Boot options
218#
219CONFIG_ZBOOT_ROM_TEXT=0x0
220CONFIG_ZBOOT_ROM_BSS=0x0
221CONFIG_CMDLINE="mem=64M console=ttyMSM,115200n8"
222# CONFIG_XIP_KERNEL is not set
223# CONFIG_KEXEC is not set
224
225#
226# Floating point emulation
227#
228
229#
230# At least one emulation must be selected
231#
232# CONFIG_VFP is not set
233
234#
235# Userspace binary formats
236#
237CONFIG_BINFMT_ELF=y
238# CONFIG_BINFMT_AOUT is not set
239# CONFIG_BINFMT_MISC is not set
240
241#
242# Power management options
243#
244CONFIG_PM=y
245CONFIG_SUSPEND_UP_POSSIBLE=y
246
247#
248# Networking
249#
250CONFIG_NET=y
251
252#
253# Networking options
254#
255# CONFIG_PACKET is not set
256CONFIG_UNIX=y
257# CONFIG_NET_KEY is not set
258CONFIG_INET=y
259# CONFIG_IP_MULTICAST is not set
260# CONFIG_IP_ADVANCED_ROUTER is not set
261CONFIG_IP_FIB_HASH=y
262# CONFIG_IP_PNP is not set
263# CONFIG_NET_IPIP is not set
264# CONFIG_NET_IPGRE is not set
265# CONFIG_ARPD is not set
266# CONFIG_SYN_COOKIES is not set
267# CONFIG_INET_AH is not set
268# CONFIG_INET_ESP is not set
269# CONFIG_INET_IPCOMP is not set
270# CONFIG_INET_XFRM_TUNNEL is not set
271# CONFIG_INET_TUNNEL is not set
272# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
273# CONFIG_INET_XFRM_MODE_TUNNEL is not set
274# CONFIG_INET_XFRM_MODE_BEET is not set
275# CONFIG_INET_DIAG is not set
276# CONFIG_TCP_CONG_ADVANCED is not set
277CONFIG_TCP_CONG_CUBIC=y
278CONFIG_DEFAULT_TCP_CONG="cubic"
279# CONFIG_TCP_MD5SIG is not set
280# CONFIG_IPV6 is not set
281# CONFIG_INET6_XFRM_TUNNEL is not set
282# CONFIG_INET6_TUNNEL is not set
283# CONFIG_NETWORK_SECMARK is not set
284# CONFIG_NETFILTER is not set
285# CONFIG_IP_DCCP is not set
286# CONFIG_IP_SCTP is not set
287# CONFIG_TIPC is not set
288# CONFIG_ATM is not set
289# CONFIG_BRIDGE is not set
290# CONFIG_VLAN_8021Q is not set
291# CONFIG_DECNET is not set
292# CONFIG_LLC2 is not set
293# CONFIG_IPX is not set
294# CONFIG_ATALK is not set
295# CONFIG_X25 is not set
296# CONFIG_LAPB is not set
297# CONFIG_ECONET is not set
298# CONFIG_WAN_ROUTER is not set
299
300#
301# QoS and/or fair queueing
302#
303# CONFIG_NET_SCHED is not set
304
305#
306# Network testing
307#
308# CONFIG_NET_PKTGEN is not set
309# CONFIG_HAMRADIO is not set
310# CONFIG_IRDA is not set
311# CONFIG_BT is not set
312# CONFIG_AF_RXRPC is not set
313
314#
315# Wireless
316#
317# CONFIG_CFG80211 is not set
318# CONFIG_WIRELESS_EXT is not set
319# CONFIG_MAC80211 is not set
320# CONFIG_IEEE80211 is not set
321# CONFIG_RFKILL is not set
322# CONFIG_NET_9P is not set
323
324#
325# Device Drivers
326#
327
328#
329# Generic Driver Options
330#
331CONFIG_STANDALONE=y
332CONFIG_PREVENT_FIRMWARE_BUILD=y
333CONFIG_FW_LOADER=y
334# CONFIG_DEBUG_DRIVER is not set
335# CONFIG_DEBUG_DEVRES is not set
336# CONFIG_SYS_HYPERVISOR is not set
337# CONFIG_CONNECTOR is not set
338CONFIG_MTD=y
339# CONFIG_MTD_DEBUG is not set
340# CONFIG_MTD_CONCAT is not set
341CONFIG_MTD_PARTITIONS=y
342# CONFIG_MTD_REDBOOT_PARTS is not set
343CONFIG_MTD_CMDLINE_PARTS=y
344# CONFIG_MTD_AFS_PARTS is not set
345
346#
347# User Modules And Translation Layers
348#
349CONFIG_MTD_CHAR=y
350CONFIG_MTD_BLKDEVS=y
351CONFIG_MTD_BLOCK=y
352# CONFIG_FTL is not set
353# CONFIG_NFTL is not set
354# CONFIG_INFTL is not set
355# CONFIG_RFD_FTL is not set
356# CONFIG_SSFDC is not set
357
358#
359# RAM/ROM/Flash chip drivers
360#
361# CONFIG_MTD_CFI is not set
362# CONFIG_MTD_JEDECPROBE is not set
363CONFIG_MTD_MAP_BANK_WIDTH_1=y
364CONFIG_MTD_MAP_BANK_WIDTH_2=y
365CONFIG_MTD_MAP_BANK_WIDTH_4=y
366# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
367# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
368# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
369CONFIG_MTD_CFI_I1=y
370CONFIG_MTD_CFI_I2=y
371# CONFIG_MTD_CFI_I4 is not set
372# CONFIG_MTD_CFI_I8 is not set
373# CONFIG_MTD_RAM is not set
374# CONFIG_MTD_ROM is not set
375# CONFIG_MTD_ABSENT is not set
376
377#
378# Mapping drivers for chip access
379#
380# CONFIG_MTD_COMPLEX_MAPPINGS is not set
381# CONFIG_MTD_PLATRAM is not set
382
383#
384# Self-contained MTD device drivers
385#
386# CONFIG_MTD_SLRAM is not set
387# CONFIG_MTD_PHRAM is not set
388# CONFIG_MTD_MTDRAM is not set
389# CONFIG_MTD_BLOCK2MTD is not set
390CONFIG_MTD_MSM_NAND=y
391
392#
393# Disk-On-Chip Device Drivers
394#
395# CONFIG_MTD_DOC2000 is not set
396# CONFIG_MTD_DOC2001 is not set
397# CONFIG_MTD_DOC2001PLUS is not set
398# CONFIG_MTD_GOLDFISH_NAND is not set
399# CONFIG_MTD_NAND is not set
400# CONFIG_MTD_ONENAND is not set
401
402#
403# UBI - Unsorted block images
404#
405# CONFIG_MTD_UBI is not set
406# CONFIG_PARPORT is not set
407CONFIG_BLK_DEV=y
408# CONFIG_BLK_DEV_COW_COMMON is not set
409# CONFIG_BLK_DEV_LOOP is not set
410# CONFIG_BLK_DEV_NBD is not set
411# CONFIG_BLK_DEV_RAM is not set
412# CONFIG_CDROM_PKTCDVD is not set
413# CONFIG_ATA_OVER_ETH is not set
414
415#
416# SCSI device support
417#
418# CONFIG_RAID_ATTRS is not set
419# CONFIG_SCSI is not set
420# CONFIG_SCSI_DMA is not set
421# CONFIG_SCSI_NETLINK is not set
422# CONFIG_ATA is not set
423# CONFIG_MD is not set
424CONFIG_NETDEVICES=y
425# CONFIG_NETDEVICES_MULTIQUEUE is not set
426CONFIG_DUMMY=y
427# CONFIG_BONDING is not set
428# CONFIG_MACVLAN is not set
429# CONFIG_EQUALIZER is not set
430# CONFIG_TUN is not set
431# CONFIG_PHYLIB is not set
432CONFIG_NET_ETHERNET=y
433CONFIG_MII=y
434# CONFIG_AX88796 is not set
435CONFIG_SMC91X=y
436# CONFIG_DM9000 is not set
437CONFIG_NETDEV_1000=y
438CONFIG_NETDEV_10000=y
439
440#
441# Wireless LAN
442#
443# CONFIG_WLAN_PRE80211 is not set
444# CONFIG_WLAN_80211 is not set
445# CONFIG_WAN is not set
446CONFIG_PPP=y
447# CONFIG_PPP_MULTILINK is not set
448# CONFIG_PPP_FILTER is not set
449CONFIG_PPP_ASYNC=y
450# CONFIG_PPP_SYNC_TTY is not set
451CONFIG_PPP_DEFLATE=y
452CONFIG_PPP_BSDCOMP=y
453# CONFIG_PPP_MPPE is not set
454# CONFIG_PPPOE is not set
455# CONFIG_PPPOL2TP is not set
456# CONFIG_SLIP is not set
457CONFIG_SLHC=y
458# CONFIG_SHAPER is not set
459# CONFIG_NETCONSOLE is not set
460CONFIG_MSM_RMNET=y
461# CONFIG_NETPOLL is not set
462# CONFIG_NET_POLL_CONTROLLER is not set
463# CONFIG_ISDN is not set
464
465#
466# Input device support
467#
468CONFIG_INPUT=y
469# CONFIG_INPUT_FF_MEMLESS is not set
470# CONFIG_INPUT_POLLDEV is not set
471
472#
473# Userland interfaces
474#
475CONFIG_INPUT_MOUSEDEV=y
476# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
477CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
478CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
479# CONFIG_INPUT_JOYDEV is not set
480# CONFIG_INPUT_TSDEV is not set
481CONFIG_INPUT_EVDEV=y
482# CONFIG_INPUT_EVBUG is not set
483
484#
485# Input Device Drivers
486#
487CONFIG_INPUT_KEYBOARD=y
488# CONFIG_KEYBOARD_ATKBD is not set
489# CONFIG_KEYBOARD_SUNKBD is not set
490# CONFIG_KEYBOARD_LKKBD is not set
491# CONFIG_KEYBOARD_XTKBD is not set
492# CONFIG_KEYBOARD_NEWTON is not set
493# CONFIG_KEYBOARD_STOWAWAY is not set
494# CONFIG_KEYBOARD_GOLDFISH_EVENTS is not set
495# CONFIG_INPUT_MOUSE is not set
496# CONFIG_INPUT_JOYSTICK is not set
497# CONFIG_INPUT_TABLET is not set
498CONFIG_INPUT_TOUCHSCREEN=y
499# CONFIG_TOUCHSCREEN_FUJITSU is not set
500# CONFIG_TOUCHSCREEN_GUNZE is not set
501# CONFIG_TOUCHSCREEN_ELO is not set
502# CONFIG_TOUCHSCREEN_MTOUCH is not set
503# CONFIG_TOUCHSCREEN_MK712 is not set
504# CONFIG_TOUCHSCREEN_PENMOUNT is not set
505# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_MEP is not set
506CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI=y
507# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
508# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
509# CONFIG_TOUCHSCREEN_UCB1400 is not set
510# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
511CONFIG_INPUT_MISC=y
512# CONFIG_INPUT_ATI_REMOTE is not set
513# CONFIG_INPUT_ATI_REMOTE2 is not set
514# CONFIG_INPUT_KEYSPAN_REMOTE is not set
515# CONFIG_INPUT_POWERMATE is not set
516# CONFIG_INPUT_YEALINK is not set
517# CONFIG_INPUT_UINPUT is not set
518CONFIG_INPUT_GPIO=y
519
520#
521# Hardware I/O ports
522#
523# CONFIG_SERIO is not set
524# CONFIG_GAMEPORT is not set
525
526#
527# Character devices
528#
529CONFIG_VT=y
530CONFIG_VT_CONSOLE=y
531CONFIG_HW_CONSOLE=y
532CONFIG_VT_HW_CONSOLE_BINDING=y
533# CONFIG_SERIAL_NONSTANDARD is not set
534
535#
536# Serial drivers
537#
538# CONFIG_SERIAL_8250 is not set
539
540#
541# Non-8250 serial port support
542#
543CONFIG_SERIAL_CORE=y
544CONFIG_SERIAL_CORE_CONSOLE=y
545CONFIG_UNIX98_PTYS=y
546# CONFIG_LEGACY_PTYS is not set
547# CONFIG_IPMI_HANDLER is not set
548# CONFIG_WATCHDOG is not set
549# CONFIG_HW_RANDOM is not set
550# CONFIG_NVRAM is not set
551# CONFIG_R3964 is not set
552# CONFIG_RAW_DRIVER is not set
553# CONFIG_TCG_TPM is not set
554CONFIG_DCC_TTY=y
555# CONFIG_GOLDFISH_TTY is not set
556CONFIG_BINDER=y
557CONFIG_I2C=y
558CONFIG_I2C_BOARDINFO=y
559# CONFIG_I2C_CHARDEV is not set
560
561#
562# I2C Algorithms
563#
564# CONFIG_I2C_ALGOBIT is not set
565# CONFIG_I2C_ALGOPCF is not set
566# CONFIG_I2C_ALGOPCA is not set
567
568#
569# I2C Hardware Bus support
570#
571CONFIG_I2C_MSM=y
572# CONFIG_I2C_OCORES is not set
573# CONFIG_I2C_PARPORT_LIGHT is not set
574# CONFIG_I2C_SIMTEC is not set
575# CONFIG_I2C_TAOS_EVM is not set
576
577#
578# Miscellaneous I2C Chip support
579#
580# CONFIG_SENSORS_DS1337 is not set
581# CONFIG_SENSORS_DS1374 is not set
582# CONFIG_DS1682 is not set
583# CONFIG_SENSORS_EEPROM is not set
584# CONFIG_SENSORS_PCF8574 is not set
585# CONFIG_SENSORS_PCA9539 is not set
586CONFIG_SENSORS_PCA9633=y
587# CONFIG_SENSORS_PCF8591 is not set
588# CONFIG_SENSORS_MAX6875 is not set
589CONFIG_SENSORS_AKM8976=y
590# CONFIG_SENSORS_TSL2550 is not set
591# CONFIG_I2C_DEBUG_CORE is not set
592# CONFIG_I2C_DEBUG_ALGO is not set
593# CONFIG_I2C_DEBUG_BUS is not set
594# CONFIG_I2C_DEBUG_CHIP is not set
595
596#
597# SPI support
598#
599# CONFIG_SPI is not set
600# CONFIG_SPI_MASTER is not set
601# CONFIG_W1 is not set
602# CONFIG_HWMON is not set
603CONFIG_MISC_DEVICES=y
604# CONFIG_EEPROM_93CX6 is not set
605CONFIG_LOW_MEMORY_KILLER=y
606
607#
608# Multifunction device drivers
609#
610# CONFIG_MFD_SM501 is not set
611CONFIG_NEW_LEDS=y
612CONFIG_LEDS_CLASS=y
613
614#
615# Multimedia devices
616#
617# CONFIG_VIDEO_DEV is not set
618# CONFIG_DVB_CORE is not set
619CONFIG_DAB=y
620
621#
622# Graphics support
623#
624# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
625
626#
627# Display device support
628#
629# CONFIG_DISPLAY_SUPPORT is not set
630# CONFIG_VGASTATE is not set
631CONFIG_VIDEO_OUTPUT_CONTROL=y
632CONFIG_FB=y
633# CONFIG_FIRMWARE_EDID is not set
634# CONFIG_FB_DDC is not set
635CONFIG_FB_CFB_FILLRECT=y
636CONFIG_FB_CFB_COPYAREA=y
637CONFIG_FB_CFB_IMAGEBLIT=y
638# CONFIG_FB_SYS_FILLRECT is not set
639# CONFIG_FB_SYS_COPYAREA is not set
640# CONFIG_FB_SYS_IMAGEBLIT is not set
641# CONFIG_FB_SYS_FOPS is not set
642CONFIG_FB_DEFERRED_IO=y
643# CONFIG_FB_SVGALIB is not set
644# CONFIG_FB_MACMODES is not set
645# CONFIG_FB_BACKLIGHT is not set
646CONFIG_FB_MODE_HELPERS=y
647CONFIG_FB_TILEBLITTING=y
648
649#
650# Frame buffer hardware drivers
651#
652# CONFIG_FB_S1D13XXX is not set
653CONFIG_FB_MSM=y
654# CONFIG_FB_GOLDFISH is not set
655# CONFIG_FB_VIRTUAL is not set
656
657#
658# Console display driver support
659#
660# CONFIG_VGA_CONSOLE is not set
661CONFIG_DUMMY_CONSOLE=y
662CONFIG_FRAMEBUFFER_CONSOLE=y
663# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
664# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
665# CONFIG_FONTS is not set
666CONFIG_FONT_8x8=y
667CONFIG_FONT_8x16=y
668# CONFIG_LOGO is not set
669
670#
671# Sound
672#
673# CONFIG_SOUND is not set
674CONFIG_HID_SUPPORT=y
675CONFIG_HID=y
676# CONFIG_HID_DEBUG is not set
677CONFIG_USB_SUPPORT=y
678CONFIG_USB_ARCH_HAS_HCD=y
679# CONFIG_USB_ARCH_HAS_OHCI is not set
680# CONFIG_USB_ARCH_HAS_EHCI is not set
681# CONFIG_USB is not set
682
683#
684# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
685#
686
687#
688# USB Gadget Support
689#
690# CONFIG_USB_GADGET is not set
691
692#
693# USB Function Support
694#
695CONFIG_USB_FUNCTION=y
696CONFIG_USB_FUNCTION_MSM_HSUSB=y
697# CONFIG_USB_FUNCTION_NULL is not set
698# CONFIG_USB_FUNCTION_ZERO is not set
699# CONFIG_USB_FUNCTION_LOOPBACK is not set
700CONFIG_USB_FUNCTION_ADB=y
701# CONFIG_MMC is not set
702CONFIG_RTC_LIB=y
703# CONFIG_RTC_CLASS is not set
704
705#
706# DMA Engine support
707#
708# CONFIG_DMA_ENGINE is not set
709
710#
711# DMA Clients
712#
713
714#
715# DMA Devices
716#
717
718#
719# Android
720#
721# CONFIG_ANDROID_GADGET is not set
722# CONFIG_ANDROID_RAM_CONSOLE is not set
723CONFIG_ANDROID_LOGGER=y
724CONFIG_ANDROID_VIBRATOR=y
725
726#
727# File systems
728#
729# CONFIG_EXT2_FS is not set
730# CONFIG_EXT3_FS is not set
731# CONFIG_EXT4DEV_FS is not set
732# CONFIG_REISERFS_FS is not set
733# CONFIG_JFS_FS is not set
734# CONFIG_FS_POSIX_ACL is not set
735# CONFIG_XFS_FS is not set
736# CONFIG_GFS2_FS is not set
737# CONFIG_OCFS2_FS is not set
738# CONFIG_MINIX_FS is not set
739# CONFIG_ROMFS_FS is not set
740CONFIG_INOTIFY=y
741CONFIG_INOTIFY_USER=y
742# CONFIG_QUOTA is not set
743CONFIG_DNOTIFY=y
744# CONFIG_AUTOFS_FS is not set
745# CONFIG_AUTOFS4_FS is not set
746# CONFIG_FUSE_FS is not set
747
748#
749# CD-ROM/DVD Filesystems
750#
751# CONFIG_ISO9660_FS is not set
752# CONFIG_UDF_FS is not set
753
754#
755# DOS/FAT/NT Filesystems
756#
757# CONFIG_MSDOS_FS is not set
758# CONFIG_VFAT_FS is not set
759# CONFIG_NTFS_FS is not set
760
761#
762# Pseudo filesystems
763#
764CONFIG_PROC_FS=y
765CONFIG_PROC_SYSCTL=y
766CONFIG_SYSFS=y
767CONFIG_TMPFS=y
768# CONFIG_TMPFS_POSIX_ACL is not set
769# CONFIG_HUGETLB_PAGE is not set
770CONFIG_RAMFS=y
771# CONFIG_CONFIGFS_FS is not set
772
773#
774# Miscellaneous filesystems
775#
776# CONFIG_ADFS_FS is not set
777# CONFIG_AFFS_FS is not set
778# CONFIG_HFS_FS is not set
779# CONFIG_HFSPLUS_FS is not set
780# CONFIG_BEFS_FS is not set
781# CONFIG_BFS_FS is not set
782# CONFIG_EFS_FS is not set
783CONFIG_YAFFS_FS=y
784CONFIG_YAFFS_YAFFS1=y
785# CONFIG_YAFFS_9BYTE_TAGS is not set
786# CONFIG_YAFFS_DOES_ECC is not set
787CONFIG_YAFFS_YAFFS2=y
788CONFIG_YAFFS_AUTO_YAFFS2=y
789# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
790CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS=10
791# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
792# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
793CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
794# CONFIG_JFFS2_FS is not set
795# CONFIG_CRAMFS is not set
796# CONFIG_VXFS_FS is not set
797# CONFIG_HPFS_FS is not set
798# CONFIG_QNX4FS_FS is not set
799# CONFIG_SYSV_FS is not set
800# CONFIG_UFS_FS is not set
801
802#
803# Network File Systems
804#
805# CONFIG_NFS_FS is not set
806# CONFIG_NFSD is not set
807# CONFIG_SMB_FS is not set
808# CONFIG_CIFS is not set
809# CONFIG_NCP_FS is not set
810# CONFIG_CODA_FS is not set
811# CONFIG_AFS_FS is not set
812
813#
814# Partition Types
815#
816# CONFIG_PARTITION_ADVANCED is not set
817CONFIG_MSDOS_PARTITION=y
818
819#
820# Native Language Support
821#
822# CONFIG_NLS is not set
823
824#
825# Distributed Lock Manager
826#
827# CONFIG_DLM is not set
828
829#
830# Profiling support
831#
832# CONFIG_PROFILING is not set
833
834#
835# Kernel hacking
836#
837# CONFIG_PRINTK_TIME is not set
838CONFIG_ENABLE_MUST_CHECK=y
839CONFIG_MAGIC_SYSRQ=y
840# CONFIG_UNUSED_SYMBOLS is not set
841# CONFIG_DEBUG_FS is not set
842# CONFIG_HEADERS_CHECK is not set
843CONFIG_DEBUG_KERNEL=y
844# CONFIG_DEBUG_SHIRQ is not set
845CONFIG_DETECT_SOFTLOCKUP=y
846CONFIG_SCHED_DEBUG=y
847CONFIG_SCHEDSTATS=y
848# CONFIG_TIMER_STATS is not set
849# CONFIG_DEBUG_SLAB is not set
850CONFIG_DEBUG_PREEMPT=y
851# CONFIG_DEBUG_RT_MUTEXES is not set
852# CONFIG_RT_MUTEX_TESTER is not set
853# CONFIG_DEBUG_SPINLOCK is not set
854CONFIG_DEBUG_MUTEXES=y
855# CONFIG_DEBUG_LOCK_ALLOC is not set
856# CONFIG_PROVE_LOCKING is not set
857# CONFIG_LOCK_STAT is not set
858CONFIG_DEBUG_SPINLOCK_SLEEP=y
859# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
860# CONFIG_DEBUG_KOBJECT is not set
861CONFIG_DEBUG_BUGVERBOSE=y
862CONFIG_DEBUG_INFO=y
863# CONFIG_DEBUG_VM is not set
864# CONFIG_DEBUG_LIST is not set
865CONFIG_FRAME_POINTER=y
866# CONFIG_FORCED_INLINING is not set
867# CONFIG_FAULT_INJECTION is not set
868# CONFIG_DEBUG_USER is not set
869# CONFIG_DEBUG_ERRORS is not set
870CONFIG_DEBUG_LL=y
871# CONFIG_DEBUG_ICEDCC is not set
872
873#
874# Security options
875#
876# CONFIG_KEYS is not set
877# CONFIG_SECURITY is not set
878# CONFIG_CRYPTO is not set
879
880#
881# Library routines
882#
883CONFIG_BITREVERSE=y
884CONFIG_CRC_CCITT=y
885# CONFIG_CRC16 is not set
886# CONFIG_CRC_ITU_T is not set
887CONFIG_CRC32=y
888# CONFIG_CRC7 is not set
889# CONFIG_LIBCRC32C is not set
890CONFIG_ZLIB_INFLATE=y
891CONFIG_ZLIB_DEFLATE=y
892CONFIG_PLIST=y
893CONFIG_HAS_IOMEM=y
894CONFIG_HAS_IOPORT=y
895CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/orion_defconfig b/arch/arm/configs/orion_defconfig
new file mode 100644
index 000000000000..17a55def1103
--- /dev/null
+++ b/arch/arm/configs/orion_defconfig
@@ -0,0 +1,1384 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.24-rc3
4# Wed Nov 28 15:13:57 2007
5#
6CONFIG_ARM=y
7CONFIG_SYS_SUPPORTS_APM_EMULATION=y
8CONFIG_GENERIC_GPIO=y
9CONFIG_GENERIC_TIME=y
10CONFIG_GENERIC_CLOCKEVENTS=y
11CONFIG_MMU=y
12# CONFIG_NO_IOPORT is not set
13CONFIG_GENERIC_HARDIRQS=y
14CONFIG_STACKTRACE_SUPPORT=y
15CONFIG_LOCKDEP_SUPPORT=y
16CONFIG_TRACE_IRQFLAGS_SUPPORT=y
17CONFIG_HARDIRQS_SW_RESEND=y
18CONFIG_GENERIC_IRQ_PROBE=y
19CONFIG_RWSEM_GENERIC_SPINLOCK=y
20# CONFIG_ARCH_HAS_ILOG2_U32 is not set
21# CONFIG_ARCH_HAS_ILOG2_U64 is not set
22CONFIG_GENERIC_HWEIGHT=y
23CONFIG_GENERIC_CALIBRATE_DELAY=y
24CONFIG_ZONE_DMA=y
25CONFIG_VECTORS_BASE=0xffff0000
26CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
27
28#
29# General setup
30#
31CONFIG_EXPERIMENTAL=y
32CONFIG_BROKEN_ON_SMP=y
33CONFIG_LOCK_KERNEL=y
34CONFIG_INIT_ENV_ARG_LIMIT=32
35CONFIG_LOCALVERSION=""
36CONFIG_LOCALVERSION_AUTO=y
37CONFIG_SWAP=y
38CONFIG_SYSVIPC=y
39CONFIG_SYSVIPC_SYSCTL=y
40# CONFIG_POSIX_MQUEUE is not set
41# CONFIG_BSD_PROCESS_ACCT is not set
42# CONFIG_TASKSTATS is not set
43# CONFIG_USER_NS is not set
44# CONFIG_PID_NS is not set
45# CONFIG_AUDIT is not set
46# CONFIG_IKCONFIG is not set
47CONFIG_LOG_BUF_SHIFT=14
48# CONFIG_CGROUPS is not set
49CONFIG_FAIR_GROUP_SCHED=y
50CONFIG_FAIR_USER_SCHED=y
51# CONFIG_FAIR_CGROUP_SCHED is not set
52CONFIG_SYSFS_DEPRECATED=y
53# CONFIG_RELAY is not set
54# CONFIG_BLK_DEV_INITRD is not set
55CONFIG_CC_OPTIMIZE_FOR_SIZE=y
56CONFIG_SYSCTL=y
57CONFIG_EMBEDDED=y
58CONFIG_UID16=y
59CONFIG_SYSCTL_SYSCALL=y
60CONFIG_KALLSYMS=y
61# CONFIG_KALLSYMS_EXTRA_PASS is not set
62CONFIG_HOTPLUG=y
63CONFIG_PRINTK=y
64CONFIG_BUG=y
65CONFIG_ELF_CORE=y
66CONFIG_BASE_FULL=y
67CONFIG_FUTEX=y
68CONFIG_ANON_INODES=y
69CONFIG_EPOLL=y
70CONFIG_SIGNALFD=y
71CONFIG_EVENTFD=y
72CONFIG_SHMEM=y
73CONFIG_VM_EVENT_COUNTERS=y
74CONFIG_SLAB=y
75# CONFIG_SLUB is not set
76# CONFIG_SLOB is not set
77CONFIG_RT_MUTEXES=y
78# CONFIG_TINY_SHMEM is not set
79CONFIG_BASE_SMALL=0
80CONFIG_MODULES=y
81CONFIG_MODULE_UNLOAD=y
82# CONFIG_MODULE_FORCE_UNLOAD is not set
83# CONFIG_MODVERSIONS is not set
84# CONFIG_MODULE_SRCVERSION_ALL is not set
85# CONFIG_KMOD is not set
86CONFIG_BLOCK=y
87# CONFIG_LBD is not set
88# CONFIG_BLK_DEV_IO_TRACE is not set
89# CONFIG_LSF is not set
90# CONFIG_BLK_DEV_BSG is not set
91
92#
93# IO Schedulers
94#
95CONFIG_IOSCHED_NOOP=y
96CONFIG_IOSCHED_AS=y
97CONFIG_IOSCHED_DEADLINE=y
98CONFIG_IOSCHED_CFQ=y
99# CONFIG_DEFAULT_AS is not set
100# CONFIG_DEFAULT_DEADLINE is not set
101CONFIG_DEFAULT_CFQ=y
102# CONFIG_DEFAULT_NOOP is not set
103CONFIG_DEFAULT_IOSCHED="cfq"
104
105#
106# System Type
107#
108# CONFIG_ARCH_AAEC2000 is not set
109# CONFIG_ARCH_INTEGRATOR is not set
110# CONFIG_ARCH_REALVIEW is not set
111# CONFIG_ARCH_VERSATILE is not set
112# CONFIG_ARCH_AT91 is not set
113# CONFIG_ARCH_CLPS7500 is not set
114# CONFIG_ARCH_CLPS711X is not set
115# CONFIG_ARCH_CO285 is not set
116# CONFIG_ARCH_EBSA110 is not set
117# CONFIG_ARCH_EP93XX is not set
118# CONFIG_ARCH_FOOTBRIDGE is not set
119# CONFIG_ARCH_NETX is not set
120# CONFIG_ARCH_H720X is not set
121# CONFIG_ARCH_IMX is not set
122# CONFIG_ARCH_IOP13XX is not set
123# CONFIG_ARCH_IOP32X is not set
124# CONFIG_ARCH_IOP33X is not set
125# CONFIG_ARCH_IXP23XX is not set
126# CONFIG_ARCH_IXP2000 is not set
127# CONFIG_ARCH_IXP4XX is not set
128# CONFIG_ARCH_L7200 is not set
129# CONFIG_ARCH_KS8695 is not set
130# CONFIG_ARCH_NS9XXX is not set
131# CONFIG_ARCH_MXC is not set
132CONFIG_ARCH_ORION=y
133# CONFIG_ARCH_PNX4008 is not set
134# CONFIG_ARCH_PXA is not set
135# CONFIG_ARCH_RPC is not set
136# CONFIG_ARCH_SA1100 is not set
137# CONFIG_ARCH_S3C2410 is not set
138# CONFIG_ARCH_SHARK is not set
139# CONFIG_ARCH_LH7A40X is not set
140# CONFIG_ARCH_DAVINCI is not set
141# CONFIG_ARCH_OMAP is not set
142
143#
144# Orion Implementations
145#
146CONFIG_MACH_DB88F5281=y
147CONFIG_MACH_RD88F5182=y
148CONFIG_MACH_KUROBOX_PRO=y
149CONFIG_MACH_DNS323=y
150CONFIG_MACH_TS209=y
151
152#
153# Boot options
154#
155
156#
157# Power management
158#
159
160#
161# Processor Type
162#
163CONFIG_CPU_32=y
164CONFIG_CPU_FEROCEON=y
165CONFIG_CPU_FEROCEON_OLD_ID=y
166CONFIG_CPU_32v5=y
167CONFIG_CPU_ABRT_EV5T=y
168CONFIG_CPU_CACHE_VIVT=y
169CONFIG_CPU_COPY_V4WB=y
170CONFIG_CPU_TLB_V4WBI=y
171CONFIG_CPU_CP15=y
172CONFIG_CPU_CP15_MMU=y
173
174#
175# Processor Features
176#
177CONFIG_ARM_THUMB=y
178# CONFIG_CPU_ICACHE_DISABLE is not set
179# CONFIG_CPU_DCACHE_DISABLE is not set
180# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
181# CONFIG_OUTER_CACHE is not set
182
183#
184# Bus support
185#
186CONFIG_PCI=y
187CONFIG_PCI_SYSCALL=y
188# CONFIG_ARCH_SUPPORTS_MSI is not set
189CONFIG_PCI_LEGACY=y
190# CONFIG_PCCARD is not set
191
192#
193# Kernel Features
194#
195CONFIG_TICK_ONESHOT=y
196CONFIG_NO_HZ=y
197CONFIG_HIGH_RES_TIMERS=y
198CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
199CONFIG_PREEMPT=y
200CONFIG_HZ=100
201CONFIG_AEABI=y
202CONFIG_OABI_COMPAT=y
203# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
204CONFIG_SELECT_MEMORY_MODEL=y
205CONFIG_FLATMEM_MANUAL=y
206# CONFIG_DISCONTIGMEM_MANUAL is not set
207# CONFIG_SPARSEMEM_MANUAL is not set
208CONFIG_FLATMEM=y
209CONFIG_FLAT_NODE_MEM_MAP=y
210# CONFIG_SPARSEMEM_STATIC is not set
211# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
212CONFIG_SPLIT_PTLOCK_CPUS=4096
213# CONFIG_RESOURCES_64BIT is not set
214CONFIG_ZONE_DMA_FLAG=1
215CONFIG_BOUNCE=y
216CONFIG_VIRT_TO_BUS=y
217CONFIG_LEDS=y
218CONFIG_LEDS_CPU=y
219CONFIG_ALIGNMENT_TRAP=y
220
221#
222# Boot options
223#
224CONFIG_ZBOOT_ROM_TEXT=0x0
225CONFIG_ZBOOT_ROM_BSS=0x0
226CONFIG_CMDLINE=""
227# CONFIG_XIP_KERNEL is not set
228# CONFIG_KEXEC is not set
229
230#
231# Floating point emulation
232#
233
234#
235# At least one emulation must be selected
236#
237CONFIG_FPE_NWFPE=y
238# CONFIG_FPE_NWFPE_XP is not set
239# CONFIG_FPE_FASTFPE is not set
240CONFIG_VFP=y
241
242#
243# Userspace binary formats
244#
245CONFIG_BINFMT_ELF=y
246# CONFIG_BINFMT_AOUT is not set
247# CONFIG_BINFMT_MISC is not set
248
249#
250# Power management options
251#
252# CONFIG_PM is not set
253CONFIG_SUSPEND_UP_POSSIBLE=y
254
255#
256# Networking
257#
258CONFIG_NET=y
259
260#
261# Networking options
262#
263CONFIG_PACKET=y
264CONFIG_PACKET_MMAP=y
265CONFIG_UNIX=y
266CONFIG_XFRM=y
267# CONFIG_XFRM_USER is not set
268# CONFIG_XFRM_SUB_POLICY is not set
269# CONFIG_XFRM_MIGRATE is not set
270# CONFIG_NET_KEY is not set
271CONFIG_INET=y
272CONFIG_IP_MULTICAST=y
273# CONFIG_IP_ADVANCED_ROUTER is not set
274CONFIG_IP_FIB_HASH=y
275CONFIG_IP_PNP=y
276CONFIG_IP_PNP_DHCP=y
277CONFIG_IP_PNP_BOOTP=y
278# CONFIG_IP_PNP_RARP is not set
279# CONFIG_NET_IPIP is not set
280# CONFIG_NET_IPGRE is not set
281# CONFIG_IP_MROUTE is not set
282# CONFIG_ARPD is not set
283# CONFIG_SYN_COOKIES is not set
284# CONFIG_INET_AH is not set
285# CONFIG_INET_ESP is not set
286# CONFIG_INET_IPCOMP is not set
287# CONFIG_INET_XFRM_TUNNEL is not set
288# CONFIG_INET_TUNNEL is not set
289CONFIG_INET_XFRM_MODE_TRANSPORT=y
290CONFIG_INET_XFRM_MODE_TUNNEL=y
291CONFIG_INET_XFRM_MODE_BEET=y
292# CONFIG_INET_LRO is not set
293CONFIG_INET_DIAG=y
294CONFIG_INET_TCP_DIAG=y
295# CONFIG_TCP_CONG_ADVANCED is not set
296CONFIG_TCP_CONG_CUBIC=y
297CONFIG_DEFAULT_TCP_CONG="cubic"
298# CONFIG_TCP_MD5SIG is not set
299# CONFIG_IPV6 is not set
300# CONFIG_INET6_XFRM_TUNNEL is not set
301# CONFIG_INET6_TUNNEL is not set
302# CONFIG_NETWORK_SECMARK is not set
303# CONFIG_NETFILTER is not set
304# CONFIG_IP_DCCP is not set
305# CONFIG_IP_SCTP is not set
306# CONFIG_TIPC is not set
307# CONFIG_ATM is not set
308# CONFIG_BRIDGE is not set
309# CONFIG_VLAN_8021Q is not set
310# CONFIG_DECNET is not set
311# CONFIG_LLC2 is not set
312# CONFIG_IPX is not set
313# CONFIG_ATALK is not set
314# CONFIG_X25 is not set
315# CONFIG_LAPB is not set
316# CONFIG_ECONET is not set
317# CONFIG_WAN_ROUTER is not set
318# CONFIG_NET_SCHED is not set
319
320#
321# Network testing
322#
323CONFIG_NET_PKTGEN=m
324# CONFIG_HAMRADIO is not set
325# CONFIG_IRDA is not set
326# CONFIG_BT is not set
327# CONFIG_AF_RXRPC is not set
328
329#
330# Wireless
331#
332# CONFIG_CFG80211 is not set
333CONFIG_WIRELESS_EXT=y
334# CONFIG_MAC80211 is not set
335# CONFIG_IEEE80211 is not set
336# CONFIG_RFKILL is not set
337# CONFIG_NET_9P is not set
338
339#
340# Device Drivers
341#
342
343#
344# Generic Driver Options
345#
346CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
347CONFIG_STANDALONE=y
348CONFIG_PREVENT_FIRMWARE_BUILD=y
349CONFIG_FW_LOADER=y
350# CONFIG_SYS_HYPERVISOR is not set
351# CONFIG_CONNECTOR is not set
352CONFIG_MTD=y
353# CONFIG_MTD_DEBUG is not set
354# CONFIG_MTD_CONCAT is not set
355CONFIG_MTD_PARTITIONS=y
356# CONFIG_MTD_REDBOOT_PARTS is not set
357CONFIG_MTD_CMDLINE_PARTS=y
358# CONFIG_MTD_AFS_PARTS is not set
359
360#
361# User Modules And Translation Layers
362#
363CONFIG_MTD_CHAR=y
364CONFIG_MTD_BLKDEVS=y
365CONFIG_MTD_BLOCK=y
366CONFIG_FTL=y
367CONFIG_NFTL=y
368# CONFIG_NFTL_RW is not set
369# CONFIG_INFTL is not set
370# CONFIG_RFD_FTL is not set
371# CONFIG_SSFDC is not set
372# CONFIG_MTD_OOPS is not set
373
374#
375# RAM/ROM/Flash chip drivers
376#
377CONFIG_MTD_CFI=y
378CONFIG_MTD_JEDECPROBE=y
379CONFIG_MTD_GEN_PROBE=y
380CONFIG_MTD_CFI_ADV_OPTIONS=y
381CONFIG_MTD_CFI_NOSWAP=y
382# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
383# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
384CONFIG_MTD_CFI_GEOMETRY=y
385CONFIG_MTD_MAP_BANK_WIDTH_1=y
386CONFIG_MTD_MAP_BANK_WIDTH_2=y
387CONFIG_MTD_MAP_BANK_WIDTH_4=y
388# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
389# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
390# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
391CONFIG_MTD_CFI_I1=y
392CONFIG_MTD_CFI_I2=y
393CONFIG_MTD_CFI_I4=y
394# CONFIG_MTD_CFI_I8 is not set
395# CONFIG_MTD_OTP is not set
396CONFIG_MTD_CFI_INTELEXT=y
397CONFIG_MTD_CFI_AMDSTD=y
398CONFIG_MTD_CFI_STAA=y
399CONFIG_MTD_CFI_UTIL=y
400# CONFIG_MTD_RAM is not set
401# CONFIG_MTD_ROM is not set
402# CONFIG_MTD_ABSENT is not set
403
404#
405# Mapping drivers for chip access
406#
407# CONFIG_MTD_COMPLEX_MAPPINGS is not set
408CONFIG_MTD_PHYSMAP=y
409CONFIG_MTD_PHYSMAP_START=0x0
410CONFIG_MTD_PHYSMAP_LEN=0x0
411CONFIG_MTD_PHYSMAP_BANKWIDTH=0
412# CONFIG_MTD_ARM_INTEGRATOR is not set
413# CONFIG_MTD_IMPA7 is not set
414# CONFIG_MTD_INTEL_VR_NOR is not set
415# CONFIG_MTD_PLATRAM is not set
416
417#
418# Self-contained MTD device drivers
419#
420# CONFIG_MTD_PMC551 is not set
421# CONFIG_MTD_SLRAM is not set
422# CONFIG_MTD_PHRAM is not set
423# CONFIG_MTD_MTDRAM is not set
424# CONFIG_MTD_BLOCK2MTD is not set
425
426#
427# Disk-On-Chip Device Drivers
428#
429# CONFIG_MTD_DOC2000 is not set
430# CONFIG_MTD_DOC2001 is not set
431# CONFIG_MTD_DOC2001PLUS is not set
432CONFIG_MTD_NAND=y
433CONFIG_MTD_NAND_VERIFY_WRITE=y
434# CONFIG_MTD_NAND_ECC_SMC is not set
435# CONFIG_MTD_NAND_MUSEUM_IDS is not set
436CONFIG_MTD_NAND_IDS=y
437# CONFIG_MTD_NAND_DISKONCHIP is not set
438# CONFIG_MTD_NAND_CAFE is not set
439# CONFIG_MTD_NAND_NANDSIM is not set
440# CONFIG_MTD_NAND_PLATFORM is not set
441# CONFIG_MTD_ALAUDA is not set
442CONFIG_MTD_NAND_ORION=y
443# CONFIG_MTD_ONENAND is not set
444
445#
446# UBI - Unsorted block images
447#
448# CONFIG_MTD_UBI is not set
449# CONFIG_PARPORT is not set
450CONFIG_BLK_DEV=y
451# CONFIG_BLK_CPQ_DA is not set
452# CONFIG_BLK_CPQ_CISS_DA is not set
453# CONFIG_BLK_DEV_DAC960 is not set
454# CONFIG_BLK_DEV_UMEM is not set
455# CONFIG_BLK_DEV_COW_COMMON is not set
456CONFIG_BLK_DEV_LOOP=y
457# CONFIG_BLK_DEV_CRYPTOLOOP is not set
458# CONFIG_BLK_DEV_NBD is not set
459# CONFIG_BLK_DEV_SX8 is not set
460# CONFIG_BLK_DEV_UB is not set
461# CONFIG_BLK_DEV_RAM is not set
462# CONFIG_CDROM_PKTCDVD is not set
463# CONFIG_ATA_OVER_ETH is not set
464CONFIG_MISC_DEVICES=y
465# CONFIG_PHANTOM is not set
466# CONFIG_EEPROM_93CX6 is not set
467# CONFIG_SGI_IOC4 is not set
468# CONFIG_TIFM_CORE is not set
469
470#
471# SCSI device support
472#
473# CONFIG_RAID_ATTRS is not set
474CONFIG_SCSI=y
475CONFIG_SCSI_DMA=y
476# CONFIG_SCSI_TGT is not set
477# CONFIG_SCSI_NETLINK is not set
478CONFIG_SCSI_PROC_FS=y
479
480#
481# SCSI support type (disk, tape, CD-ROM)
482#
483CONFIG_BLK_DEV_SD=y
484# CONFIG_CHR_DEV_ST is not set
485# CONFIG_CHR_DEV_OSST is not set
486CONFIG_BLK_DEV_SR=y
487# CONFIG_BLK_DEV_SR_VENDOR is not set
488CONFIG_CHR_DEV_SG=y
489# CONFIG_CHR_DEV_SCH is not set
490
491#
492# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
493#
494CONFIG_SCSI_MULTI_LUN=y
495# CONFIG_SCSI_CONSTANTS is not set
496# CONFIG_SCSI_LOGGING is not set
497# CONFIG_SCSI_SCAN_ASYNC is not set
498CONFIG_SCSI_WAIT_SCAN=m
499
500#
501# SCSI Transports
502#
503# CONFIG_SCSI_SPI_ATTRS is not set
504# CONFIG_SCSI_FC_ATTRS is not set
505# CONFIG_SCSI_ISCSI_ATTRS is not set
506# CONFIG_SCSI_SAS_LIBSAS is not set
507# CONFIG_SCSI_SRP_ATTRS is not set
508CONFIG_SCSI_LOWLEVEL=y
509# CONFIG_ISCSI_TCP is not set
510# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
511# CONFIG_SCSI_3W_9XXX is not set
512# CONFIG_SCSI_ACARD is not set
513# CONFIG_SCSI_AACRAID is not set
514# CONFIG_SCSI_AIC7XXX is not set
515# CONFIG_SCSI_AIC7XXX_OLD is not set
516# CONFIG_SCSI_AIC79XX is not set
517# CONFIG_SCSI_AIC94XX is not set
518# CONFIG_SCSI_DPT_I2O is not set
519# CONFIG_SCSI_ADVANSYS is not set
520# CONFIG_SCSI_ARCMSR is not set
521# CONFIG_MEGARAID_NEWGEN is not set
522# CONFIG_MEGARAID_LEGACY is not set
523# CONFIG_MEGARAID_SAS is not set
524# CONFIG_SCSI_HPTIOP is not set
525# CONFIG_SCSI_DMX3191D is not set
526# CONFIG_SCSI_FUTURE_DOMAIN is not set
527# CONFIG_SCSI_IPS is not set
528# CONFIG_SCSI_INITIO is not set
529# CONFIG_SCSI_INIA100 is not set
530# CONFIG_SCSI_STEX is not set
531CONFIG_SCSI_MVSATA=y
532
533#
534# Sata options
535#
536# CONFIG_MV_SATA_SUPPORT_ATAPI is not set
537# CONFIG_MV_SATA_ENABLE_1MB_IOS is not set
538CONFIG_SATA_NO_DEBUG=y
539# CONFIG_SATA_DEBUG_ON_ERROR is not set
540# CONFIG_SATA_FULL_DEBUG is not set
541# CONFIG_SCSI_SYM53C8XX_2 is not set
542# CONFIG_SCSI_IPR is not set
543# CONFIG_SCSI_QLOGIC_1280 is not set
544# CONFIG_SCSI_QLA_FC is not set
545# CONFIG_SCSI_QLA_ISCSI is not set
546# CONFIG_SCSI_LPFC is not set
547# CONFIG_SCSI_DC395x is not set
548# CONFIG_SCSI_DC390T is not set
549# CONFIG_SCSI_NSP32 is not set
550# CONFIG_SCSI_DEBUG is not set
551# CONFIG_SCSI_SRP is not set
552CONFIG_ATA=m
553# CONFIG_ATA_NONSTANDARD is not set
554# CONFIG_SATA_AHCI is not set
555# CONFIG_SATA_SVW is not set
556# CONFIG_ATA_PIIX is not set
557# CONFIG_SATA_MV is not set
558# CONFIG_SATA_NV is not set
559# CONFIG_PDC_ADMA is not set
560# CONFIG_SATA_QSTOR is not set
561# CONFIG_SATA_PROMISE is not set
562# CONFIG_SATA_SX4 is not set
563# CONFIG_SATA_SIL is not set
564# CONFIG_SATA_SIL24 is not set
565# CONFIG_SATA_SIS is not set
566# CONFIG_SATA_ULI is not set
567# CONFIG_SATA_VIA is not set
568# CONFIG_SATA_VITESSE is not set
569# CONFIG_SATA_INIC162X is not set
570# CONFIG_PATA_ALI is not set
571# CONFIG_PATA_AMD is not set
572# CONFIG_PATA_ARTOP is not set
573# CONFIG_PATA_ATIIXP is not set
574# CONFIG_PATA_CMD640_PCI is not set
575# CONFIG_PATA_CMD64X is not set
576# CONFIG_PATA_CS5520 is not set
577# CONFIG_PATA_CS5530 is not set
578# CONFIG_PATA_CYPRESS is not set
579# CONFIG_PATA_EFAR is not set
580# CONFIG_ATA_GENERIC is not set
581# CONFIG_PATA_HPT366 is not set
582# CONFIG_PATA_HPT37X is not set
583# CONFIG_PATA_HPT3X2N is not set
584# CONFIG_PATA_HPT3X3 is not set
585# CONFIG_PATA_IT821X is not set
586# CONFIG_PATA_IT8213 is not set
587# CONFIG_PATA_JMICRON is not set
588# CONFIG_PATA_TRIFLEX is not set
589# CONFIG_PATA_MARVELL is not set
590# CONFIG_PATA_MPIIX is not set
591# CONFIG_PATA_OLDPIIX is not set
592# CONFIG_PATA_NETCELL is not set
593# CONFIG_PATA_NS87410 is not set
594# CONFIG_PATA_NS87415 is not set
595# CONFIG_PATA_OPTI is not set
596# CONFIG_PATA_OPTIDMA is not set
597# CONFIG_PATA_PDC_OLD is not set
598# CONFIG_PATA_RADISYS is not set
599# CONFIG_PATA_RZ1000 is not set
600# CONFIG_PATA_SC1200 is not set
601# CONFIG_PATA_SERVERWORKS is not set
602# CONFIG_PATA_PDC2027X is not set
603# CONFIG_PATA_SIL680 is not set
604# CONFIG_PATA_SIS is not set
605# CONFIG_PATA_VIA is not set
606# CONFIG_PATA_WINBOND is not set
607# CONFIG_PATA_PLATFORM is not set
608# CONFIG_MD is not set
609# CONFIG_FUSION is not set
610
611#
612# IEEE 1394 (FireWire) support
613#
614# CONFIG_FIREWIRE is not set
615# CONFIG_IEEE1394 is not set
616# CONFIG_I2O is not set
617CONFIG_NETDEVICES=y
618# CONFIG_NETDEVICES_MULTIQUEUE is not set
619# CONFIG_DUMMY is not set
620# CONFIG_BONDING is not set
621# CONFIG_MACVLAN is not set
622# CONFIG_EQUALIZER is not set
623# CONFIG_TUN is not set
624# CONFIG_VETH is not set
625# CONFIG_IP1000 is not set
626# CONFIG_ARCNET is not set
627# CONFIG_PHYLIB is not set
628CONFIG_NET_ETHERNET=y
629CONFIG_MII=y
630# CONFIG_AX88796 is not set
631# CONFIG_HAPPYMEAL is not set
632# CONFIG_SUNGEM is not set
633# CONFIG_CASSINI is not set
634# CONFIG_NET_VENDOR_3COM is not set
635# CONFIG_SMC91X is not set
636# CONFIG_DM9000 is not set
637# CONFIG_NET_TULIP is not set
638# CONFIG_HP100 is not set
639# CONFIG_IBM_NEW_EMAC_ZMII is not set
640# CONFIG_IBM_NEW_EMAC_RGMII is not set
641# CONFIG_IBM_NEW_EMAC_TAH is not set
642# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
643CONFIG_NET_PCI=y
644# CONFIG_PCNET32 is not set
645# CONFIG_AMD8111_ETH is not set
646# CONFIG_ADAPTEC_STARFIRE is not set
647# CONFIG_B44 is not set
648# CONFIG_FORCEDETH is not set
649# CONFIG_EEPRO100 is not set
650CONFIG_E100=y
651# CONFIG_FEALNX is not set
652# CONFIG_NATSEMI is not set
653# CONFIG_NE2K_PCI is not set
654# CONFIG_8139CP is not set
655# CONFIG_8139TOO is not set
656# CONFIG_SIS900 is not set
657# CONFIG_EPIC100 is not set
658# CONFIG_SUNDANCE is not set
659# CONFIG_TLAN is not set
660# CONFIG_VIA_RHINE is not set
661# CONFIG_SC92031 is not set
662CONFIG_NETDEV_1000=y
663# CONFIG_ACENIC is not set
664# CONFIG_DL2K is not set
665CONFIG_E1000=y
666CONFIG_E1000_NAPI=y
667# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
668# CONFIG_E1000E is not set
669# CONFIG_NS83820 is not set
670# CONFIG_HAMACHI is not set
671# CONFIG_YELLOWFIN is not set
672# CONFIG_R8169 is not set
673# CONFIG_SIS190 is not set
674CONFIG_SKGE=y
675CONFIG_SKY2=y
676# CONFIG_SK98LIN is not set
677# CONFIG_VIA_VELOCITY is not set
678CONFIG_TIGON3=y
679# CONFIG_BNX2 is not set
680CONFIG_MV643XX_ETH=y
681# CONFIG_QLA3XXX is not set
682# CONFIG_ATL1 is not set
683CONFIG_NETDEV_10000=y
684# CONFIG_CHELSIO_T1 is not set
685# CONFIG_CHELSIO_T3 is not set
686# CONFIG_IXGBE is not set
687# CONFIG_IXGB is not set
688# CONFIG_S2IO is not set
689# CONFIG_MYRI10GE is not set
690# CONFIG_NETXEN_NIC is not set
691# CONFIG_NIU is not set
692# CONFIG_MLX4_CORE is not set
693# CONFIG_TEHUTI is not set
694# CONFIG_TR is not set
695
696#
697# Wireless LAN
698#
699# CONFIG_WLAN_PRE80211 is not set
700# CONFIG_WLAN_80211 is not set
701
702#
703# USB Network Adapters
704#
705# CONFIG_USB_CATC is not set
706# CONFIG_USB_KAWETH is not set
707# CONFIG_USB_PEGASUS is not set
708# CONFIG_USB_RTL8150 is not set
709# CONFIG_USB_USBNET is not set
710# CONFIG_WAN is not set
711# CONFIG_FDDI is not set
712# CONFIG_HIPPI is not set
713# CONFIG_PPP is not set
714# CONFIG_SLIP is not set
715# CONFIG_NET_FC is not set
716# CONFIG_SHAPER is not set
717# CONFIG_NETCONSOLE is not set
718# CONFIG_NETPOLL is not set
719# CONFIG_NET_POLL_CONTROLLER is not set
720# CONFIG_ISDN is not set
721
722#
723# Input device support
724#
725CONFIG_INPUT=y
726# CONFIG_INPUT_FF_MEMLESS is not set
727# CONFIG_INPUT_POLLDEV is not set
728
729#
730# Userland interfaces
731#
732CONFIG_INPUT_MOUSEDEV=y
733CONFIG_INPUT_MOUSEDEV_PSAUX=y
734CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
735CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
736# CONFIG_INPUT_JOYDEV is not set
737# CONFIG_INPUT_EVDEV is not set
738# CONFIG_INPUT_EVBUG is not set
739
740#
741# Input Device Drivers
742#
743# CONFIG_INPUT_KEYBOARD is not set
744# CONFIG_INPUT_MOUSE is not set
745# CONFIG_INPUT_JOYSTICK is not set
746# CONFIG_INPUT_TABLET is not set
747# CONFIG_INPUT_TOUCHSCREEN is not set
748# CONFIG_INPUT_MISC is not set
749
750#
751# Hardware I/O ports
752#
753# CONFIG_SERIO is not set
754# CONFIG_GAMEPORT is not set
755
756#
757# Character devices
758#
759CONFIG_VT=y
760CONFIG_VT_CONSOLE=y
761CONFIG_HW_CONSOLE=y
762# CONFIG_VT_HW_CONSOLE_BINDING is not set
763# CONFIG_SERIAL_NONSTANDARD is not set
764
765#
766# Serial drivers
767#
768CONFIG_SERIAL_8250=y
769CONFIG_SERIAL_8250_CONSOLE=y
770CONFIG_SERIAL_8250_PCI=y
771CONFIG_SERIAL_8250_NR_UARTS=4
772CONFIG_SERIAL_8250_RUNTIME_UARTS=2
773# CONFIG_SERIAL_8250_EXTENDED is not set
774
775#
776# Non-8250 serial port support
777#
778CONFIG_SERIAL_CORE=y
779CONFIG_SERIAL_CORE_CONSOLE=y
780# CONFIG_SERIAL_JSM is not set
781CONFIG_UNIX98_PTYS=y
782CONFIG_LEGACY_PTYS=y
783CONFIG_LEGACY_PTY_COUNT=16
784# CONFIG_IPMI_HANDLER is not set
785CONFIG_HW_RANDOM=m
786# CONFIG_NVRAM is not set
787# CONFIG_R3964 is not set
788# CONFIG_APPLICOM is not set
789# CONFIG_RAW_DRIVER is not set
790# CONFIG_TCG_TPM is not set
791CONFIG_DEVPORT=y
792CONFIG_I2C=y
793CONFIG_I2C_BOARDINFO=y
794CONFIG_I2C_CHARDEV=y
795
796#
797# I2C Algorithms
798#
799# CONFIG_I2C_ALGOBIT is not set
800# CONFIG_I2C_ALGOPCF is not set
801# CONFIG_I2C_ALGOPCA is not set
802
803#
804# I2C Hardware Bus support
805#
806# CONFIG_I2C_ALI1535 is not set
807# CONFIG_I2C_ALI1563 is not set
808# CONFIG_I2C_ALI15X3 is not set
809# CONFIG_I2C_AMD756 is not set
810# CONFIG_I2C_AMD8111 is not set
811# CONFIG_I2C_GPIO is not set
812# CONFIG_I2C_I801 is not set
813# CONFIG_I2C_I810 is not set
814# CONFIG_I2C_PIIX4 is not set
815# CONFIG_I2C_NFORCE2 is not set
816# CONFIG_I2C_OCORES is not set
817# CONFIG_I2C_PARPORT_LIGHT is not set
818# CONFIG_I2C_PROSAVAGE is not set
819# CONFIG_I2C_SAVAGE4 is not set
820# CONFIG_I2C_SIMTEC is not set
821# CONFIG_I2C_SIS5595 is not set
822# CONFIG_I2C_SIS630 is not set
823# CONFIG_I2C_SIS96X is not set
824# CONFIG_I2C_TAOS_EVM is not set
825# CONFIG_I2C_STUB is not set
826# CONFIG_I2C_TINY_USB is not set
827# CONFIG_I2C_VIA is not set
828# CONFIG_I2C_VIAPRO is not set
829# CONFIG_I2C_VOODOO3 is not set
830CONFIG_I2C_MV64XXX=y
831
832#
833# Miscellaneous I2C Chip support
834#
835# CONFIG_SENSORS_DS1337 is not set
836# CONFIG_SENSORS_DS1374 is not set
837# CONFIG_DS1682 is not set
838# CONFIG_SENSORS_EEPROM is not set
839# CONFIG_SENSORS_PCF8574 is not set
840# CONFIG_SENSORS_PCA9539 is not set
841# CONFIG_SENSORS_PCF8591 is not set
842# CONFIG_SENSORS_MAX6875 is not set
843# CONFIG_SENSORS_TSL2550 is not set
844# CONFIG_I2C_DEBUG_CORE is not set
845# CONFIG_I2C_DEBUG_ALGO is not set
846# CONFIG_I2C_DEBUG_BUS is not set
847# CONFIG_I2C_DEBUG_CHIP is not set
848
849#
850# SPI support
851#
852# CONFIG_SPI is not set
853# CONFIG_SPI_MASTER is not set
854# CONFIG_W1 is not set
855# CONFIG_POWER_SUPPLY is not set
856CONFIG_HWMON=y
857# CONFIG_HWMON_VID is not set
858# CONFIG_SENSORS_AD7418 is not set
859# CONFIG_SENSORS_ADM1021 is not set
860# CONFIG_SENSORS_ADM1025 is not set
861# CONFIG_SENSORS_ADM1026 is not set
862# CONFIG_SENSORS_ADM1029 is not set
863# CONFIG_SENSORS_ADM1031 is not set
864# CONFIG_SENSORS_ADM9240 is not set
865# CONFIG_SENSORS_ADT7470 is not set
866# CONFIG_SENSORS_ATXP1 is not set
867# CONFIG_SENSORS_DS1621 is not set
868# CONFIG_SENSORS_I5K_AMB is not set
869# CONFIG_SENSORS_F71805F is not set
870# CONFIG_SENSORS_F71882FG is not set
871# CONFIG_SENSORS_F75375S is not set
872# CONFIG_SENSORS_GL518SM is not set
873# CONFIG_SENSORS_GL520SM is not set
874# CONFIG_SENSORS_IT87 is not set
875# CONFIG_SENSORS_LM63 is not set
876# CONFIG_SENSORS_LM75 is not set
877# CONFIG_SENSORS_LM77 is not set
878# CONFIG_SENSORS_LM78 is not set
879# CONFIG_SENSORS_LM80 is not set
880# CONFIG_SENSORS_LM83 is not set
881# CONFIG_SENSORS_LM85 is not set
882# CONFIG_SENSORS_LM87 is not set
883# CONFIG_SENSORS_LM90 is not set
884# CONFIG_SENSORS_LM92 is not set
885# CONFIG_SENSORS_LM93 is not set
886# CONFIG_SENSORS_MAX1619 is not set
887# CONFIG_SENSORS_MAX6650 is not set
888# CONFIG_SENSORS_PC87360 is not set
889# CONFIG_SENSORS_PC87427 is not set
890# CONFIG_SENSORS_SIS5595 is not set
891# CONFIG_SENSORS_DME1737 is not set
892# CONFIG_SENSORS_SMSC47M1 is not set
893# CONFIG_SENSORS_SMSC47M192 is not set
894# CONFIG_SENSORS_SMSC47B397 is not set
895# CONFIG_SENSORS_THMC50 is not set
896# CONFIG_SENSORS_VIA686A is not set
897# CONFIG_SENSORS_VT1211 is not set
898# CONFIG_SENSORS_VT8231 is not set
899# CONFIG_SENSORS_W83781D is not set
900# CONFIG_SENSORS_W83791D is not set
901# CONFIG_SENSORS_W83792D is not set
902# CONFIG_SENSORS_W83793 is not set
903# CONFIG_SENSORS_W83L785TS is not set
904# CONFIG_SENSORS_W83627HF is not set
905# CONFIG_SENSORS_W83627EHF is not set
906# CONFIG_HWMON_DEBUG_CHIP is not set
907# CONFIG_WATCHDOG is not set
908
909#
910# Sonics Silicon Backplane
911#
912CONFIG_SSB_POSSIBLE=y
913# CONFIG_SSB is not set
914
915#
916# Multifunction device drivers
917#
918# CONFIG_MFD_SM501 is not set
919
920#
921# Multimedia devices
922#
923# CONFIG_VIDEO_DEV is not set
924# CONFIG_DVB_CORE is not set
925CONFIG_DAB=y
926# CONFIG_USB_DABUSB is not set
927
928#
929# Graphics support
930#
931# CONFIG_DRM is not set
932# CONFIG_VGASTATE is not set
933# CONFIG_VIDEO_OUTPUT_CONTROL is not set
934# CONFIG_FB is not set
935# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
936
937#
938# Display device support
939#
940# CONFIG_DISPLAY_SUPPORT is not set
941
942#
943# Console display driver support
944#
945# CONFIG_VGA_CONSOLE is not set
946CONFIG_DUMMY_CONSOLE=y
947
948#
949# Sound
950#
951# CONFIG_SOUND is not set
952CONFIG_HID_SUPPORT=y
953CONFIG_HID=y
954# CONFIG_HID_DEBUG is not set
955# CONFIG_HIDRAW is not set
956
957#
958# USB Input Devices
959#
960CONFIG_USB_HID=y
961# CONFIG_USB_HIDINPUT_POWERBOOK is not set
962# CONFIG_HID_FF is not set
963# CONFIG_USB_HIDDEV is not set
964CONFIG_USB_SUPPORT=y
965CONFIG_USB_ARCH_HAS_HCD=y
966CONFIG_USB_ARCH_HAS_OHCI=y
967CONFIG_USB_ARCH_HAS_EHCI=y
968CONFIG_USB=y
969# CONFIG_USB_DEBUG is not set
970
971#
972# Miscellaneous USB options
973#
974CONFIG_USB_DEVICEFS=y
975CONFIG_USB_DEVICE_CLASS=y
976# CONFIG_USB_DYNAMIC_MINORS is not set
977# CONFIG_USB_OTG is not set
978
979#
980# USB Host Controller Drivers
981#
982CONFIG_USB_EHCI_HCD=y
983CONFIG_USB_EHCI_SPLIT_ISO=y
984CONFIG_USB_EHCI_ROOT_HUB_TT=y
985CONFIG_USB_EHCI_TT_NEWSCHED=y
986# CONFIG_USB_ISP116X_HCD is not set
987CONFIG_USB_OHCI_HCD=y
988# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
989# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
990CONFIG_USB_OHCI_LITTLE_ENDIAN=y
991CONFIG_USB_UHCI_HCD=y
992CONFIG_USB_SL811_HCD=y
993# CONFIG_USB_R8A66597_HCD is not set
994
995#
996# USB Device Class drivers
997#
998# CONFIG_USB_ACM is not set
999CONFIG_USB_PRINTER=y
1000
1001#
1002# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
1003#
1004
1005#
1006# may also be needed; see USB_STORAGE Help for more information
1007#
1008CONFIG_USB_STORAGE=y
1009# CONFIG_USB_STORAGE_DEBUG is not set
1010CONFIG_USB_STORAGE_DATAFAB=y
1011CONFIG_USB_STORAGE_FREECOM=y
1012# CONFIG_USB_STORAGE_ISD200 is not set
1013CONFIG_USB_STORAGE_DPCM=y
1014# CONFIG_USB_STORAGE_USBAT is not set
1015CONFIG_USB_STORAGE_SDDR09=y
1016CONFIG_USB_STORAGE_SDDR55=y
1017CONFIG_USB_STORAGE_JUMPSHOT=y
1018# CONFIG_USB_STORAGE_ALAUDA is not set
1019# CONFIG_USB_STORAGE_KARMA is not set
1020# CONFIG_USB_LIBUSUAL is not set
1021
1022#
1023# USB Imaging devices
1024#
1025# CONFIG_USB_MDC800 is not set
1026# CONFIG_USB_MICROTEK is not set
1027# CONFIG_USB_MON is not set
1028
1029#
1030# USB port drivers
1031#
1032
1033#
1034# USB Serial Converter support
1035#
1036# CONFIG_USB_SERIAL is not set
1037
1038#
1039# USB Miscellaneous drivers
1040#
1041# CONFIG_USB_EMI62 is not set
1042# CONFIG_USB_EMI26 is not set
1043# CONFIG_USB_ADUTUX is not set
1044# CONFIG_USB_AUERSWALD is not set
1045# CONFIG_USB_RIO500 is not set
1046# CONFIG_USB_LEGOTOWER is not set
1047# CONFIG_USB_LCD is not set
1048# CONFIG_USB_BERRY_CHARGE is not set
1049# CONFIG_USB_LED is not set
1050# CONFIG_USB_CYPRESS_CY7C63 is not set
1051# CONFIG_USB_CYTHERM is not set
1052# CONFIG_USB_PHIDGET is not set
1053# CONFIG_USB_IDMOUSE is not set
1054# CONFIG_USB_FTDI_ELAN is not set
1055# CONFIG_USB_APPLEDISPLAY is not set
1056# CONFIG_USB_SISUSBVGA is not set
1057# CONFIG_USB_LD is not set
1058# CONFIG_USB_TRANCEVIBRATOR is not set
1059# CONFIG_USB_IOWARRIOR is not set
1060# CONFIG_USB_TEST is not set
1061
1062#
1063# USB DSL modem support
1064#
1065
1066#
1067# USB Gadget Support
1068#
1069# CONFIG_USB_GADGET is not set
1070# CONFIG_MMC is not set
1071CONFIG_NEW_LEDS=y
1072CONFIG_LEDS_CLASS=y
1073
1074#
1075# LED drivers
1076#
1077# CONFIG_LEDS_GPIO is not set
1078
1079#
1080# LED Triggers
1081#
1082CONFIG_LEDS_TRIGGERS=y
1083CONFIG_LEDS_TRIGGER_TIMER=y
1084CONFIG_LEDS_TRIGGER_HEARTBEAT=y
1085CONFIG_RTC_LIB=y
1086CONFIG_RTC_CLASS=y
1087CONFIG_RTC_HCTOSYS=y
1088CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
1089# CONFIG_RTC_DEBUG is not set
1090
1091#
1092# RTC interfaces
1093#
1094CONFIG_RTC_INTF_SYSFS=y
1095CONFIG_RTC_INTF_PROC=y
1096CONFIG_RTC_INTF_DEV=y
1097# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
1098# CONFIG_RTC_DRV_TEST is not set
1099
1100#
1101# I2C RTC drivers
1102#
1103CONFIG_RTC_DRV_DS1307=y
1104# CONFIG_RTC_DRV_DS1374 is not set
1105# CONFIG_RTC_DRV_DS1672 is not set
1106# CONFIG_RTC_DRV_MAX6900 is not set
1107CONFIG_RTC_DRV_RS5C372=y
1108# CONFIG_RTC_DRV_ISL1208 is not set
1109# CONFIG_RTC_DRV_X1205 is not set
1110# CONFIG_RTC_DRV_PCF8563 is not set
1111# CONFIG_RTC_DRV_PCF8583 is not set
1112CONFIG_RTC_DRV_M41T80=y
1113# CONFIG_RTC_DRV_M41T80_WDT is not set
1114
1115#
1116# SPI RTC drivers
1117#
1118
1119#
1120# Platform RTC drivers
1121#
1122# CONFIG_RTC_DRV_CMOS is not set
1123# CONFIG_RTC_DRV_DS1553 is not set
1124# CONFIG_RTC_DRV_STK17TA8 is not set
1125# CONFIG_RTC_DRV_DS1742 is not set
1126# CONFIG_RTC_DRV_M48T86 is not set
1127# CONFIG_RTC_DRV_M48T59 is not set
1128# CONFIG_RTC_DRV_V3020 is not set
1129
1130#
1131# on-CPU RTC drivers
1132#
1133
1134#
1135# File systems
1136#
1137CONFIG_EXT2_FS=y
1138# CONFIG_EXT2_FS_XATTR is not set
1139# CONFIG_EXT2_FS_XIP is not set
1140CONFIG_EXT3_FS=y
1141# CONFIG_EXT3_FS_XATTR is not set
1142# CONFIG_EXT4DEV_FS is not set
1143CONFIG_JBD=y
1144# CONFIG_REISERFS_FS is not set
1145# CONFIG_JFS_FS is not set
1146# CONFIG_FS_POSIX_ACL is not set
1147# CONFIG_XFS_FS is not set
1148# CONFIG_GFS2_FS is not set
1149# CONFIG_OCFS2_FS is not set
1150# CONFIG_MINIX_FS is not set
1151# CONFIG_ROMFS_FS is not set
1152CONFIG_INOTIFY=y
1153CONFIG_INOTIFY_USER=y
1154# CONFIG_QUOTA is not set
1155CONFIG_DNOTIFY=y
1156# CONFIG_AUTOFS_FS is not set
1157# CONFIG_AUTOFS4_FS is not set
1158# CONFIG_FUSE_FS is not set
1159
1160#
1161# CD-ROM/DVD Filesystems
1162#
1163CONFIG_ISO9660_FS=y
1164# CONFIG_JOLIET is not set
1165# CONFIG_ZISOFS is not set
1166CONFIG_UDF_FS=m
1167CONFIG_UDF_NLS=y
1168
1169#
1170# DOS/FAT/NT Filesystems
1171#
1172CONFIG_FAT_FS=y
1173CONFIG_MSDOS_FS=y
1174CONFIG_VFAT_FS=y
1175CONFIG_FAT_DEFAULT_CODEPAGE=437
1176CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
1177# CONFIG_NTFS_FS is not set
1178
1179#
1180# Pseudo filesystems
1181#
1182CONFIG_PROC_FS=y
1183CONFIG_PROC_SYSCTL=y
1184CONFIG_SYSFS=y
1185CONFIG_TMPFS=y
1186# CONFIG_TMPFS_POSIX_ACL is not set
1187# CONFIG_HUGETLB_PAGE is not set
1188# CONFIG_CONFIGFS_FS is not set
1189
1190#
1191# Miscellaneous filesystems
1192#
1193# CONFIG_ADFS_FS is not set
1194# CONFIG_AFFS_FS is not set
1195# CONFIG_HFS_FS is not set
1196# CONFIG_HFSPLUS_FS is not set
1197# CONFIG_BEFS_FS is not set
1198# CONFIG_BFS_FS is not set
1199# CONFIG_EFS_FS is not set
1200CONFIG_JFFS2_FS=y
1201CONFIG_JFFS2_FS_DEBUG=0
1202CONFIG_JFFS2_FS_WRITEBUFFER=y
1203# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
1204# CONFIG_JFFS2_SUMMARY is not set
1205# CONFIG_JFFS2_FS_XATTR is not set
1206# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
1207CONFIG_JFFS2_ZLIB=y
1208# CONFIG_JFFS2_LZO is not set
1209CONFIG_JFFS2_RTIME=y
1210# CONFIG_JFFS2_RUBIN is not set
1211CONFIG_CRAMFS=y
1212# CONFIG_VXFS_FS is not set
1213# CONFIG_HPFS_FS is not set
1214# CONFIG_QNX4FS_FS is not set
1215# CONFIG_SYSV_FS is not set
1216# CONFIG_UFS_FS is not set
1217CONFIG_NETWORK_FILESYSTEMS=y
1218CONFIG_NFS_FS=y
1219CONFIG_NFS_V3=y
1220# CONFIG_NFS_V3_ACL is not set
1221# CONFIG_NFS_V4 is not set
1222# CONFIG_NFS_DIRECTIO is not set
1223# CONFIG_NFSD is not set
1224CONFIG_ROOT_NFS=y
1225CONFIG_LOCKD=y
1226CONFIG_LOCKD_V4=y
1227CONFIG_NFS_COMMON=y
1228CONFIG_SUNRPC=y
1229# CONFIG_SUNRPC_BIND34 is not set
1230# CONFIG_RPCSEC_GSS_KRB5 is not set
1231# CONFIG_RPCSEC_GSS_SPKM3 is not set
1232# CONFIG_SMB_FS is not set
1233# CONFIG_CIFS is not set
1234# CONFIG_NCP_FS is not set
1235# CONFIG_CODA_FS is not set
1236# CONFIG_AFS_FS is not set
1237
1238#
1239# Partition Types
1240#
1241CONFIG_PARTITION_ADVANCED=y
1242# CONFIG_ACORN_PARTITION is not set
1243# CONFIG_OSF_PARTITION is not set
1244# CONFIG_AMIGA_PARTITION is not set
1245# CONFIG_ATARI_PARTITION is not set
1246# CONFIG_MAC_PARTITION is not set
1247CONFIG_MSDOS_PARTITION=y
1248CONFIG_BSD_DISKLABEL=y
1249CONFIG_MINIX_SUBPARTITION=y
1250CONFIG_SOLARIS_X86_PARTITION=y
1251CONFIG_UNIXWARE_DISKLABEL=y
1252CONFIG_LDM_PARTITION=y
1253CONFIG_LDM_DEBUG=y
1254# CONFIG_SGI_PARTITION is not set
1255# CONFIG_ULTRIX_PARTITION is not set
1256CONFIG_SUN_PARTITION=y
1257# CONFIG_KARMA_PARTITION is not set
1258# CONFIG_EFI_PARTITION is not set
1259# CONFIG_SYSV68_PARTITION is not set
1260CONFIG_NLS=y
1261CONFIG_NLS_DEFAULT="iso8859-1"
1262CONFIG_NLS_CODEPAGE_437=y
1263# CONFIG_NLS_CODEPAGE_737 is not set
1264# CONFIG_NLS_CODEPAGE_775 is not set
1265CONFIG_NLS_CODEPAGE_850=y
1266# CONFIG_NLS_CODEPAGE_852 is not set
1267# CONFIG_NLS_CODEPAGE_855 is not set
1268# CONFIG_NLS_CODEPAGE_857 is not set
1269# CONFIG_NLS_CODEPAGE_860 is not set
1270# CONFIG_NLS_CODEPAGE_861 is not set
1271# CONFIG_NLS_CODEPAGE_862 is not set
1272# CONFIG_NLS_CODEPAGE_863 is not set
1273# CONFIG_NLS_CODEPAGE_864 is not set
1274# CONFIG_NLS_CODEPAGE_865 is not set
1275# CONFIG_NLS_CODEPAGE_866 is not set
1276# CONFIG_NLS_CODEPAGE_869 is not set
1277# CONFIG_NLS_CODEPAGE_936 is not set
1278# CONFIG_NLS_CODEPAGE_950 is not set
1279# CONFIG_NLS_CODEPAGE_932 is not set
1280# CONFIG_NLS_CODEPAGE_949 is not set
1281# CONFIG_NLS_CODEPAGE_874 is not set
1282# CONFIG_NLS_ISO8859_8 is not set
1283# CONFIG_NLS_CODEPAGE_1250 is not set
1284# CONFIG_NLS_CODEPAGE_1251 is not set
1285# CONFIG_NLS_ASCII is not set
1286CONFIG_NLS_ISO8859_1=y
1287CONFIG_NLS_ISO8859_2=y
1288# CONFIG_NLS_ISO8859_3 is not set
1289# CONFIG_NLS_ISO8859_4 is not set
1290# CONFIG_NLS_ISO8859_5 is not set
1291# CONFIG_NLS_ISO8859_6 is not set
1292# CONFIG_NLS_ISO8859_7 is not set
1293# CONFIG_NLS_ISO8859_9 is not set
1294# CONFIG_NLS_ISO8859_13 is not set
1295# CONFIG_NLS_ISO8859_14 is not set
1296# CONFIG_NLS_ISO8859_15 is not set
1297# CONFIG_NLS_KOI8_R is not set
1298# CONFIG_NLS_KOI8_U is not set
1299# CONFIG_NLS_UTF8 is not set
1300# CONFIG_DLM is not set
1301CONFIG_INSTRUMENTATION=y
1302# CONFIG_PROFILING is not set
1303# CONFIG_MARKERS is not set
1304
1305#
1306# Kernel hacking
1307#
1308# CONFIG_PRINTK_TIME is not set
1309CONFIG_ENABLE_WARN_DEPRECATED=y
1310CONFIG_ENABLE_MUST_CHECK=y
1311# CONFIG_MAGIC_SYSRQ is not set
1312# CONFIG_UNUSED_SYMBOLS is not set
1313# CONFIG_DEBUG_FS is not set
1314# CONFIG_HEADERS_CHECK is not set
1315# CONFIG_DEBUG_KERNEL is not set
1316# CONFIG_DEBUG_BUGVERBOSE is not set
1317CONFIG_FRAME_POINTER=y
1318# CONFIG_SAMPLES is not set
1319CONFIG_DEBUG_USER=y
1320
1321#
1322# Security options
1323#
1324# CONFIG_KEYS is not set
1325# CONFIG_SECURITY is not set
1326# CONFIG_SECURITY_FILE_CAPABILITIES is not set
1327CONFIG_CRYPTO=y
1328CONFIG_CRYPTO_ALGAPI=m
1329CONFIG_CRYPTO_BLKCIPHER=m
1330CONFIG_CRYPTO_MANAGER=m
1331# CONFIG_CRYPTO_HMAC is not set
1332# CONFIG_CRYPTO_XCBC is not set
1333# CONFIG_CRYPTO_NULL is not set
1334# CONFIG_CRYPTO_MD4 is not set
1335# CONFIG_CRYPTO_MD5 is not set
1336# CONFIG_CRYPTO_SHA1 is not set
1337# CONFIG_CRYPTO_SHA256 is not set
1338# CONFIG_CRYPTO_SHA512 is not set
1339# CONFIG_CRYPTO_WP512 is not set
1340# CONFIG_CRYPTO_TGR192 is not set
1341# CONFIG_CRYPTO_GF128MUL is not set
1342CONFIG_CRYPTO_ECB=m
1343CONFIG_CRYPTO_CBC=m
1344CONFIG_CRYPTO_PCBC=m
1345# CONFIG_CRYPTO_LRW is not set
1346# CONFIG_CRYPTO_XTS is not set
1347# CONFIG_CRYPTO_CRYPTD is not set
1348# CONFIG_CRYPTO_DES is not set
1349# CONFIG_CRYPTO_FCRYPT is not set
1350# CONFIG_CRYPTO_BLOWFISH is not set
1351# CONFIG_CRYPTO_TWOFISH is not set
1352# CONFIG_CRYPTO_SERPENT is not set
1353# CONFIG_CRYPTO_AES is not set
1354# CONFIG_CRYPTO_CAST5 is not set
1355# CONFIG_CRYPTO_CAST6 is not set
1356# CONFIG_CRYPTO_TEA is not set
1357# CONFIG_CRYPTO_ARC4 is not set
1358# CONFIG_CRYPTO_KHAZAD is not set
1359# CONFIG_CRYPTO_ANUBIS is not set
1360# CONFIG_CRYPTO_SEED is not set
1361# CONFIG_CRYPTO_DEFLATE is not set
1362# CONFIG_CRYPTO_MICHAEL_MIC is not set
1363# CONFIG_CRYPTO_CRC32C is not set
1364# CONFIG_CRYPTO_CAMELLIA is not set
1365# CONFIG_CRYPTO_TEST is not set
1366# CONFIG_CRYPTO_AUTHENC is not set
1367CONFIG_CRYPTO_HW=y
1368
1369#
1370# Library routines
1371#
1372CONFIG_BITREVERSE=y
1373CONFIG_CRC_CCITT=y
1374CONFIG_CRC16=y
1375# CONFIG_CRC_ITU_T is not set
1376CONFIG_CRC32=y
1377# CONFIG_CRC7 is not set
1378CONFIG_LIBCRC32C=y
1379CONFIG_ZLIB_INFLATE=y
1380CONFIG_ZLIB_DEFLATE=y
1381CONFIG_PLIST=y
1382CONFIG_HAS_IOMEM=y
1383CONFIG_HAS_IOPORT=y
1384CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/pcm027_defconfig b/arch/arm/configs/pcm027_defconfig
new file mode 100644
index 000000000000..17b9b2469570
--- /dev/null
+++ b/arch/arm/configs/pcm027_defconfig
@@ -0,0 +1,1096 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.24-rc6
4# Fri Dec 21 10:52:09 2007
5#
6CONFIG_ARM=y
7CONFIG_SYS_SUPPORTS_APM_EMULATION=y
8CONFIG_GENERIC_GPIO=y
9CONFIG_GENERIC_TIME=y
10CONFIG_GENERIC_CLOCKEVENTS=y
11CONFIG_MMU=y
12# CONFIG_NO_IOPORT is not set
13CONFIG_GENERIC_HARDIRQS=y
14CONFIG_STACKTRACE_SUPPORT=y
15CONFIG_LOCKDEP_SUPPORT=y
16CONFIG_TRACE_IRQFLAGS_SUPPORT=y
17CONFIG_HARDIRQS_SW_RESEND=y
18CONFIG_GENERIC_IRQ_PROBE=y
19CONFIG_RWSEM_GENERIC_SPINLOCK=y
20# CONFIG_ARCH_HAS_ILOG2_U32 is not set
21# CONFIG_ARCH_HAS_ILOG2_U64 is not set
22CONFIG_GENERIC_HWEIGHT=y
23CONFIG_GENERIC_CALIBRATE_DELAY=y
24CONFIG_ZONE_DMA=y
25CONFIG_ARCH_MTD_XIP=y
26CONFIG_VECTORS_BASE=0xffff0000
27CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
28
29#
30# General setup
31#
32CONFIG_EXPERIMENTAL=y
33CONFIG_BROKEN_ON_SMP=y
34CONFIG_LOCK_KERNEL=y
35CONFIG_INIT_ENV_ARG_LIMIT=32
36CONFIG_LOCALVERSION=""
37CONFIG_LOCALVERSION_AUTO=y
38# CONFIG_SWAP is not set
39CONFIG_SYSVIPC=y
40CONFIG_SYSVIPC_SYSCTL=y
41CONFIG_POSIX_MQUEUE=y
42CONFIG_BSD_PROCESS_ACCT=y
43# CONFIG_BSD_PROCESS_ACCT_V3 is not set
44# CONFIG_TASKSTATS is not set
45# CONFIG_USER_NS is not set
46# CONFIG_PID_NS is not set
47# CONFIG_AUDIT is not set
48CONFIG_IKCONFIG=y
49CONFIG_IKCONFIG_PROC=y
50CONFIG_LOG_BUF_SHIFT=14
51# CONFIG_CGROUPS is not set
52CONFIG_FAIR_GROUP_SCHED=y
53CONFIG_FAIR_USER_SCHED=y
54# CONFIG_FAIR_CGROUP_SCHED is not set
55CONFIG_SYSFS_DEPRECATED=y
56# CONFIG_RELAY is not set
57# CONFIG_BLK_DEV_INITRD is not set
58# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
59CONFIG_SYSCTL=y
60CONFIG_EMBEDDED=y
61CONFIG_UID16=y
62CONFIG_SYSCTL_SYSCALL=y
63# CONFIG_KALLSYMS is not set
64CONFIG_HOTPLUG=y
65CONFIG_PRINTK=y
66CONFIG_BUG=y
67CONFIG_ELF_CORE=y
68CONFIG_BASE_FULL=y
69CONFIG_FUTEX=y
70CONFIG_ANON_INODES=y
71CONFIG_EPOLL=y
72CONFIG_SIGNALFD=y
73CONFIG_EVENTFD=y
74CONFIG_SHMEM=y
75CONFIG_VM_EVENT_COUNTERS=y
76CONFIG_SLAB=y
77# CONFIG_SLUB is not set
78# CONFIG_SLOB is not set
79CONFIG_RT_MUTEXES=y
80# CONFIG_TINY_SHMEM is not set
81CONFIG_BASE_SMALL=0
82CONFIG_MODULES=y
83CONFIG_MODULE_UNLOAD=y
84CONFIG_MODULE_FORCE_UNLOAD=y
85# CONFIG_MODVERSIONS is not set
86# CONFIG_MODULE_SRCVERSION_ALL is not set
87# CONFIG_KMOD is not set
88CONFIG_BLOCK=y
89# CONFIG_LBD is not set
90# CONFIG_BLK_DEV_IO_TRACE is not set
91# CONFIG_LSF is not set
92# CONFIG_BLK_DEV_BSG is not set
93
94#
95# IO Schedulers
96#
97CONFIG_IOSCHED_NOOP=y
98# CONFIG_IOSCHED_AS is not set
99# CONFIG_IOSCHED_DEADLINE is not set
100# CONFIG_IOSCHED_CFQ is not set
101# CONFIG_DEFAULT_AS is not set
102# CONFIG_DEFAULT_DEADLINE is not set
103# CONFIG_DEFAULT_CFQ is not set
104CONFIG_DEFAULT_NOOP=y
105CONFIG_DEFAULT_IOSCHED="noop"
106
107#
108# System Type
109#
110# CONFIG_ARCH_AAEC2000 is not set
111# CONFIG_ARCH_INTEGRATOR is not set
112# CONFIG_ARCH_REALVIEW is not set
113# CONFIG_ARCH_VERSATILE is not set
114# CONFIG_ARCH_AT91 is not set
115# CONFIG_ARCH_CLPS7500 is not set
116# CONFIG_ARCH_CLPS711X is not set
117# CONFIG_ARCH_CO285 is not set
118# CONFIG_ARCH_EBSA110 is not set
119# CONFIG_ARCH_EP93XX is not set
120# CONFIG_ARCH_FOOTBRIDGE is not set
121# CONFIG_ARCH_NETX is not set
122# CONFIG_ARCH_H720X is not set
123# CONFIG_ARCH_IMX is not set
124# CONFIG_ARCH_IOP13XX is not set
125# CONFIG_ARCH_IOP32X is not set
126# CONFIG_ARCH_IOP33X is not set
127# CONFIG_ARCH_IXP23XX is not set
128# CONFIG_ARCH_IXP2000 is not set
129# CONFIG_ARCH_IXP4XX is not set
130# CONFIG_ARCH_L7200 is not set
131# CONFIG_ARCH_KS8695 is not set
132# CONFIG_ARCH_NS9XXX is not set
133# CONFIG_ARCH_MXC is not set
134# CONFIG_ARCH_PNX4008 is not set
135CONFIG_ARCH_PXA=y
136# CONFIG_ARCH_RPC is not set
137# CONFIG_ARCH_SA1100 is not set
138# CONFIG_ARCH_S3C2410 is not set
139# CONFIG_ARCH_SHARK is not set
140# CONFIG_ARCH_LH7A40X is not set
141# CONFIG_ARCH_DAVINCI is not set
142# CONFIG_ARCH_OMAP is not set
143
144#
145# Intel PXA2xx/PXA3xx Implementations
146#
147# CONFIG_ARCH_LUBBOCK is not set
148# CONFIG_MACH_LOGICPD_PXA270 is not set
149# CONFIG_MACH_MAINSTONE is not set
150# CONFIG_ARCH_PXA_IDP is not set
151# CONFIG_PXA_SHARPSL is not set
152# CONFIG_MACH_TRIZEPS4 is not set
153# CONFIG_MACH_EM_X270 is not set
154# CONFIG_MACH_ZYLONITE is not set
155# CONFIG_MACH_ARMCORE is not set
156CONFIG_MACH_PCM027=y
157CONFIG_MACH_PCM990_BASEBOARD=y
158CONFIG_PXA27x=y
159
160#
161# Boot options
162#
163
164#
165# Power management
166#
167
168#
169# Processor Type
170#
171CONFIG_CPU_32=y
172CONFIG_CPU_XSCALE=y
173CONFIG_CPU_32v5=y
174CONFIG_CPU_ABRT_EV5T=y
175CONFIG_CPU_CACHE_VIVT=y
176CONFIG_CPU_TLB_V4WBI=y
177CONFIG_CPU_CP15=y
178CONFIG_CPU_CP15_MMU=y
179
180#
181# Processor Features
182#
183CONFIG_ARM_THUMB=y
184# CONFIG_CPU_DCACHE_DISABLE is not set
185# CONFIG_OUTER_CACHE is not set
186CONFIG_IWMMXT=y
187CONFIG_XSCALE_PMU=y
188
189#
190# Bus support
191#
192# CONFIG_PCI_SYSCALL is not set
193# CONFIG_ARCH_SUPPORTS_MSI is not set
194# CONFIG_PCCARD is not set
195
196#
197# Kernel Features
198#
199CONFIG_TICK_ONESHOT=y
200CONFIG_NO_HZ=y
201CONFIG_HIGH_RES_TIMERS=y
202CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
203CONFIG_PREEMPT=y
204CONFIG_HZ=100
205CONFIG_AEABI=y
206# CONFIG_OABI_COMPAT is not set
207# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
208CONFIG_SELECT_MEMORY_MODEL=y
209CONFIG_FLATMEM_MANUAL=y
210# CONFIG_DISCONTIGMEM_MANUAL is not set
211# CONFIG_SPARSEMEM_MANUAL is not set
212CONFIG_FLATMEM=y
213CONFIG_FLAT_NODE_MEM_MAP=y
214# CONFIG_SPARSEMEM_STATIC is not set
215# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
216CONFIG_SPLIT_PTLOCK_CPUS=4096
217# CONFIG_RESOURCES_64BIT is not set
218CONFIG_ZONE_DMA_FLAG=1
219CONFIG_BOUNCE=y
220CONFIG_VIRT_TO_BUS=y
221CONFIG_ALIGNMENT_TRAP=y
222
223#
224# Boot options
225#
226CONFIG_ZBOOT_ROM_TEXT=0x0
227CONFIG_ZBOOT_ROM_BSS=0x0
228CONFIG_CMDLINE=""
229# CONFIG_XIP_KERNEL is not set
230# CONFIG_KEXEC is not set
231
232#
233# Floating point emulation
234#
235
236#
237# At least one emulation must be selected
238#
239
240#
241# Userspace binary formats
242#
243CONFIG_BINFMT_ELF=y
244# CONFIG_BINFMT_AOUT is not set
245# CONFIG_BINFMT_MISC is not set
246
247#
248# Power management options
249#
250# CONFIG_PM is not set
251CONFIG_SUSPEND_UP_POSSIBLE=y
252
253#
254# Networking
255#
256CONFIG_NET=y
257
258#
259# Networking options
260#
261CONFIG_PACKET=y
262CONFIG_PACKET_MMAP=y
263CONFIG_UNIX=y
264# CONFIG_NET_KEY is not set
265CONFIG_INET=y
266# CONFIG_IP_MULTICAST is not set
267# CONFIG_IP_ADVANCED_ROUTER is not set
268CONFIG_IP_FIB_HASH=y
269CONFIG_IP_PNP=y
270# CONFIG_IP_PNP_DHCP is not set
271# CONFIG_IP_PNP_BOOTP is not set
272# CONFIG_IP_PNP_RARP is not set
273# CONFIG_NET_IPIP is not set
274# CONFIG_NET_IPGRE is not set
275# CONFIG_ARPD is not set
276# CONFIG_SYN_COOKIES is not set
277# CONFIG_INET_AH is not set
278# CONFIG_INET_ESP is not set
279# CONFIG_INET_IPCOMP is not set
280# CONFIG_INET_XFRM_TUNNEL is not set
281# CONFIG_INET_TUNNEL is not set
282# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
283# CONFIG_INET_XFRM_MODE_TUNNEL is not set
284# CONFIG_INET_XFRM_MODE_BEET is not set
285# CONFIG_INET_LRO is not set
286# CONFIG_INET_DIAG is not set
287# CONFIG_TCP_CONG_ADVANCED is not set
288CONFIG_TCP_CONG_CUBIC=y
289CONFIG_DEFAULT_TCP_CONG="cubic"
290# CONFIG_TCP_MD5SIG is not set
291# CONFIG_IPV6 is not set
292# CONFIG_INET6_XFRM_TUNNEL is not set
293# CONFIG_INET6_TUNNEL is not set
294# CONFIG_NETWORK_SECMARK is not set
295# CONFIG_NETFILTER is not set
296# CONFIG_IP_DCCP is not set
297# CONFIG_IP_SCTP is not set
298# CONFIG_TIPC is not set
299# CONFIG_ATM is not set
300# CONFIG_BRIDGE is not set
301# CONFIG_VLAN_8021Q is not set
302# CONFIG_DECNET is not set
303# CONFIG_LLC2 is not set
304# CONFIG_IPX is not set
305# CONFIG_ATALK is not set
306# CONFIG_X25 is not set
307# CONFIG_LAPB is not set
308# CONFIG_ECONET is not set
309# CONFIG_WAN_ROUTER is not set
310# CONFIG_NET_SCHED is not set
311
312#
313# Network testing
314#
315# CONFIG_NET_PKTGEN is not set
316# CONFIG_HAMRADIO is not set
317# CONFIG_IRDA is not set
318# CONFIG_BT is not set
319# CONFIG_AF_RXRPC is not set
320
321#
322# Wireless
323#
324# CONFIG_CFG80211 is not set
325# CONFIG_WIRELESS_EXT is not set
326# CONFIG_MAC80211 is not set
327# CONFIG_IEEE80211 is not set
328# CONFIG_RFKILL is not set
329# CONFIG_NET_9P is not set
330
331#
332# Device Drivers
333#
334
335#
336# Generic Driver Options
337#
338CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
339CONFIG_STANDALONE=y
340CONFIG_PREVENT_FIRMWARE_BUILD=y
341CONFIG_FW_LOADER=y
342# CONFIG_SYS_HYPERVISOR is not set
343# CONFIG_CONNECTOR is not set
344CONFIG_MTD=y
345# CONFIG_MTD_DEBUG is not set
346# CONFIG_MTD_CONCAT is not set
347CONFIG_MTD_PARTITIONS=y
348# CONFIG_MTD_REDBOOT_PARTS is not set
349CONFIG_MTD_CMDLINE_PARTS=y
350# CONFIG_MTD_AFS_PARTS is not set
351
352#
353# User Modules And Translation Layers
354#
355CONFIG_MTD_CHAR=y
356CONFIG_MTD_BLKDEVS=y
357CONFIG_MTD_BLOCK=y
358# CONFIG_FTL is not set
359# CONFIG_NFTL is not set
360# CONFIG_INFTL is not set
361# CONFIG_RFD_FTL is not set
362# CONFIG_SSFDC is not set
363# CONFIG_MTD_OOPS is not set
364
365#
366# RAM/ROM/Flash chip drivers
367#
368CONFIG_MTD_CFI=y
369# CONFIG_MTD_JEDECPROBE is not set
370CONFIG_MTD_GEN_PROBE=y
371# CONFIG_MTD_CFI_ADV_OPTIONS is not set
372CONFIG_MTD_MAP_BANK_WIDTH_1=y
373CONFIG_MTD_MAP_BANK_WIDTH_2=y
374CONFIG_MTD_MAP_BANK_WIDTH_4=y
375# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
376# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
377# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
378CONFIG_MTD_CFI_I1=y
379CONFIG_MTD_CFI_I2=y
380# CONFIG_MTD_CFI_I4 is not set
381# CONFIG_MTD_CFI_I8 is not set
382CONFIG_MTD_CFI_INTELEXT=y
383# CONFIG_MTD_CFI_AMDSTD is not set
384# CONFIG_MTD_CFI_STAA is not set
385CONFIG_MTD_CFI_UTIL=y
386# CONFIG_MTD_RAM is not set
387# CONFIG_MTD_ROM is not set
388# CONFIG_MTD_ABSENT is not set
389# CONFIG_MTD_XIP is not set
390
391#
392# Mapping drivers for chip access
393#
394# CONFIG_MTD_COMPLEX_MAPPINGS is not set
395CONFIG_MTD_PHYSMAP=y
396CONFIG_MTD_PHYSMAP_START=0x00000000
397CONFIG_MTD_PHYSMAP_LEN=0x0
398CONFIG_MTD_PHYSMAP_BANKWIDTH=0
399# CONFIG_MTD_PXA2XX is not set
400# CONFIG_MTD_ARM_INTEGRATOR is not set
401# CONFIG_MTD_SHARP_SL is not set
402# CONFIG_MTD_PLATRAM is not set
403
404#
405# Self-contained MTD device drivers
406#
407# CONFIG_MTD_SLRAM is not set
408# CONFIG_MTD_PHRAM is not set
409# CONFIG_MTD_MTDRAM is not set
410# CONFIG_MTD_BLOCK2MTD is not set
411
412#
413# Disk-On-Chip Device Drivers
414#
415# CONFIG_MTD_DOC2000 is not set
416# CONFIG_MTD_DOC2001 is not set
417# CONFIG_MTD_DOC2001PLUS is not set
418# CONFIG_MTD_NAND is not set
419# CONFIG_MTD_ONENAND is not set
420
421#
422# UBI - Unsorted block images
423#
424# CONFIG_MTD_UBI is not set
425# CONFIG_PARPORT is not set
426# CONFIG_BLK_DEV is not set
427# CONFIG_MISC_DEVICES is not set
428# CONFIG_IDE is not set
429
430#
431# SCSI device support
432#
433# CONFIG_RAID_ATTRS is not set
434CONFIG_SCSI=y
435CONFIG_SCSI_DMA=y
436# CONFIG_SCSI_TGT is not set
437# CONFIG_SCSI_NETLINK is not set
438CONFIG_SCSI_PROC_FS=y
439
440#
441# SCSI support type (disk, tape, CD-ROM)
442#
443CONFIG_BLK_DEV_SD=y
444# CONFIG_CHR_DEV_ST is not set
445# CONFIG_CHR_DEV_OSST is not set
446# CONFIG_BLK_DEV_SR is not set
447# CONFIG_CHR_DEV_SG is not set
448# CONFIG_CHR_DEV_SCH is not set
449
450#
451# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
452#
453# CONFIG_SCSI_MULTI_LUN is not set
454# CONFIG_SCSI_CONSTANTS is not set
455# CONFIG_SCSI_LOGGING is not set
456# CONFIG_SCSI_SCAN_ASYNC is not set
457CONFIG_SCSI_WAIT_SCAN=m
458
459#
460# SCSI Transports
461#
462# CONFIG_SCSI_SPI_ATTRS is not set
463# CONFIG_SCSI_FC_ATTRS is not set
464# CONFIG_SCSI_ISCSI_ATTRS is not set
465# CONFIG_SCSI_SAS_LIBSAS is not set
466# CONFIG_SCSI_SRP_ATTRS is not set
467# CONFIG_SCSI_LOWLEVEL is not set
468# CONFIG_ATA is not set
469# CONFIG_MD is not set
470CONFIG_NETDEVICES=y
471# CONFIG_NETDEVICES_MULTIQUEUE is not set
472# CONFIG_DUMMY is not set
473# CONFIG_BONDING is not set
474# CONFIG_MACVLAN is not set
475# CONFIG_EQUALIZER is not set
476# CONFIG_TUN is not set
477# CONFIG_VETH is not set
478# CONFIG_PHYLIB is not set
479CONFIG_NET_ETHERNET=y
480CONFIG_MII=y
481# CONFIG_AX88796 is not set
482CONFIG_SMC91X=y
483# CONFIG_DM9000 is not set
484# CONFIG_SMC911X is not set
485# CONFIG_IBM_NEW_EMAC_ZMII is not set
486# CONFIG_IBM_NEW_EMAC_RGMII is not set
487# CONFIG_IBM_NEW_EMAC_TAH is not set
488# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
489# CONFIG_B44 is not set
490# CONFIG_NETDEV_1000 is not set
491# CONFIG_NETDEV_10000 is not set
492
493#
494# Wireless LAN
495#
496# CONFIG_WLAN_PRE80211 is not set
497# CONFIG_WLAN_80211 is not set
498
499#
500# USB Network Adapters
501#
502# CONFIG_USB_CATC is not set
503# CONFIG_USB_KAWETH is not set
504# CONFIG_USB_PEGASUS is not set
505# CONFIG_USB_RTL8150 is not set
506# CONFIG_USB_USBNET is not set
507# CONFIG_WAN is not set
508# CONFIG_PPP is not set
509# CONFIG_SLIP is not set
510# CONFIG_SHAPER is not set
511# CONFIG_NETCONSOLE is not set
512# CONFIG_NETPOLL is not set
513# CONFIG_NET_POLL_CONTROLLER is not set
514# CONFIG_ISDN is not set
515
516#
517# Input device support
518#
519CONFIG_INPUT=y
520# CONFIG_INPUT_FF_MEMLESS is not set
521# CONFIG_INPUT_POLLDEV is not set
522
523#
524# Userland interfaces
525#
526CONFIG_INPUT_MOUSEDEV=y
527# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
528CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
529CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
530# CONFIG_INPUT_JOYDEV is not set
531# CONFIG_INPUT_EVDEV is not set
532# CONFIG_INPUT_EVBUG is not set
533
534#
535# Input Device Drivers
536#
537# CONFIG_INPUT_KEYBOARD is not set
538# CONFIG_INPUT_MOUSE is not set
539# CONFIG_INPUT_JOYSTICK is not set
540# CONFIG_INPUT_TABLET is not set
541# CONFIG_INPUT_TOUCHSCREEN is not set
542# CONFIG_INPUT_MISC is not set
543
544#
545# Hardware I/O ports
546#
547# CONFIG_SERIO is not set
548# CONFIG_GAMEPORT is not set
549
550#
551# Character devices
552#
553CONFIG_VT=y
554CONFIG_VT_CONSOLE=y
555CONFIG_HW_CONSOLE=y
556# CONFIG_VT_HW_CONSOLE_BINDING is not set
557# CONFIG_SERIAL_NONSTANDARD is not set
558
559#
560# Serial drivers
561#
562# CONFIG_SERIAL_8250 is not set
563
564#
565# Non-8250 serial port support
566#
567CONFIG_SERIAL_PXA=y
568CONFIG_SERIAL_PXA_CONSOLE=y
569CONFIG_SERIAL_CORE=y
570CONFIG_SERIAL_CORE_CONSOLE=y
571CONFIG_UNIX98_PTYS=y
572# CONFIG_LEGACY_PTYS is not set
573# CONFIG_IPMI_HANDLER is not set
574# CONFIG_HW_RANDOM is not set
575# CONFIG_NVRAM is not set
576# CONFIG_R3964 is not set
577# CONFIG_RAW_DRIVER is not set
578# CONFIG_TCG_TPM is not set
579CONFIG_I2C=y
580CONFIG_I2C_BOARDINFO=y
581CONFIG_I2C_CHARDEV=y
582
583#
584# I2C Algorithms
585#
586# CONFIG_I2C_ALGOBIT is not set
587# CONFIG_I2C_ALGOPCF is not set
588# CONFIG_I2C_ALGOPCA is not set
589
590#
591# I2C Hardware Bus support
592#
593# CONFIG_I2C_GPIO is not set
594CONFIG_I2C_PXA=y
595# CONFIG_I2C_PXA_SLAVE is not set
596# CONFIG_I2C_OCORES is not set
597# CONFIG_I2C_PARPORT_LIGHT is not set
598# CONFIG_I2C_SIMTEC is not set
599# CONFIG_I2C_TAOS_EVM is not set
600# CONFIG_I2C_STUB is not set
601# CONFIG_I2C_TINY_USB is not set
602
603#
604# Miscellaneous I2C Chip support
605#
606# CONFIG_SENSORS_DS1337 is not set
607# CONFIG_SENSORS_DS1374 is not set
608# CONFIG_DS1682 is not set
609CONFIG_SENSORS_EEPROM=y
610# CONFIG_SENSORS_PCF8574 is not set
611# CONFIG_SENSORS_PCA9539 is not set
612# CONFIG_SENSORS_PCF8591 is not set
613# CONFIG_SENSORS_MAX6875 is not set
614# CONFIG_SENSORS_TSL2550 is not set
615# CONFIG_I2C_DEBUG_CORE is not set
616# CONFIG_I2C_DEBUG_ALGO is not set
617# CONFIG_I2C_DEBUG_BUS is not set
618# CONFIG_I2C_DEBUG_CHIP is not set
619
620#
621# SPI support
622#
623# CONFIG_SPI is not set
624# CONFIG_SPI_MASTER is not set
625# CONFIG_W1 is not set
626# CONFIG_POWER_SUPPLY is not set
627# CONFIG_HWMON is not set
628# CONFIG_WATCHDOG is not set
629
630#
631# Sonics Silicon Backplane
632#
633CONFIG_SSB_POSSIBLE=y
634# CONFIG_SSB is not set
635
636#
637# Multifunction device drivers
638#
639# CONFIG_MFD_SM501 is not set
640
641#
642# Multimedia devices
643#
644# CONFIG_VIDEO_DEV is not set
645# CONFIG_DVB_CORE is not set
646# CONFIG_DAB is not set
647
648#
649# Graphics support
650#
651# CONFIG_VGASTATE is not set
652# CONFIG_VIDEO_OUTPUT_CONTROL is not set
653# CONFIG_FB is not set
654# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
655
656#
657# Display device support
658#
659# CONFIG_DISPLAY_SUPPORT is not set
660
661#
662# Console display driver support
663#
664# CONFIG_VGA_CONSOLE is not set
665CONFIG_DUMMY_CONSOLE=y
666
667#
668# Sound
669#
670CONFIG_SOUND=y
671
672#
673# Advanced Linux Sound Architecture
674#
675CONFIG_SND=y
676CONFIG_SND_TIMER=y
677CONFIG_SND_PCM=y
678# CONFIG_SND_SEQUENCER is not set
679CONFIG_SND_OSSEMUL=y
680CONFIG_SND_MIXER_OSS=y
681CONFIG_SND_PCM_OSS=y
682CONFIG_SND_PCM_OSS_PLUGINS=y
683# CONFIG_SND_DYNAMIC_MINORS is not set
684CONFIG_SND_SUPPORT_OLD_API=y
685CONFIG_SND_VERBOSE_PROCFS=y
686# CONFIG_SND_VERBOSE_PRINTK is not set
687# CONFIG_SND_DEBUG is not set
688
689#
690# Generic devices
691#
692CONFIG_SND_AC97_CODEC=y
693# CONFIG_SND_DUMMY is not set
694# CONFIG_SND_MTPAV is not set
695# CONFIG_SND_SERIAL_U16550 is not set
696# CONFIG_SND_MPU401 is not set
697
698#
699# ALSA ARM devices
700#
701CONFIG_SND_PXA2XX_PCM=y
702CONFIG_SND_PXA2XX_AC97=y
703
704#
705# USB devices
706#
707# CONFIG_SND_USB_AUDIO is not set
708# CONFIG_SND_USB_CAIAQ is not set
709
710#
711# System on Chip audio support
712#
713# CONFIG_SND_SOC is not set
714
715#
716# SoC Audio support for SuperH
717#
718
719#
720# Open Sound System
721#
722# CONFIG_SOUND_PRIME is not set
723CONFIG_AC97_BUS=y
724# CONFIG_HID_SUPPORT is not set
725CONFIG_USB_SUPPORT=y
726CONFIG_USB_ARCH_HAS_HCD=y
727CONFIG_USB_ARCH_HAS_OHCI=y
728# CONFIG_USB_ARCH_HAS_EHCI is not set
729CONFIG_USB=y
730# CONFIG_USB_DEBUG is not set
731
732#
733# Miscellaneous USB options
734#
735CONFIG_USB_DEVICEFS=y
736CONFIG_USB_DEVICE_CLASS=y
737# CONFIG_USB_DYNAMIC_MINORS is not set
738# CONFIG_USB_OTG is not set
739
740#
741# USB Host Controller Drivers
742#
743# CONFIG_USB_ISP116X_HCD is not set
744CONFIG_USB_OHCI_HCD=y
745# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
746# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
747CONFIG_USB_OHCI_LITTLE_ENDIAN=y
748# CONFIG_USB_SL811_HCD is not set
749# CONFIG_USB_R8A66597_HCD is not set
750
751#
752# USB Device Class drivers
753#
754# CONFIG_USB_ACM is not set
755# CONFIG_USB_PRINTER is not set
756
757#
758# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
759#
760
761#
762# may also be needed; see USB_STORAGE Help for more information
763#
764CONFIG_USB_STORAGE=y
765# CONFIG_USB_STORAGE_DEBUG is not set
766# CONFIG_USB_STORAGE_DATAFAB is not set
767# CONFIG_USB_STORAGE_FREECOM is not set
768# CONFIG_USB_STORAGE_ISD200 is not set
769# CONFIG_USB_STORAGE_DPCM is not set
770# CONFIG_USB_STORAGE_USBAT is not set
771# CONFIG_USB_STORAGE_SDDR09 is not set
772# CONFIG_USB_STORAGE_SDDR55 is not set
773# CONFIG_USB_STORAGE_JUMPSHOT is not set
774# CONFIG_USB_STORAGE_ALAUDA is not set
775# CONFIG_USB_STORAGE_KARMA is not set
776# CONFIG_USB_LIBUSUAL is not set
777
778#
779# USB Imaging devices
780#
781# CONFIG_USB_MDC800 is not set
782# CONFIG_USB_MICROTEK is not set
783# CONFIG_USB_MON is not set
784
785#
786# USB port drivers
787#
788
789#
790# USB Serial Converter support
791#
792# CONFIG_USB_SERIAL is not set
793
794#
795# USB Miscellaneous drivers
796#
797# CONFIG_USB_EMI62 is not set
798# CONFIG_USB_EMI26 is not set
799# CONFIG_USB_ADUTUX is not set
800# CONFIG_USB_AUERSWALD is not set
801# CONFIG_USB_RIO500 is not set
802# CONFIG_USB_LEGOTOWER is not set
803# CONFIG_USB_LCD is not set
804# CONFIG_USB_BERRY_CHARGE is not set
805# CONFIG_USB_LED is not set
806# CONFIG_USB_CYPRESS_CY7C63 is not set
807# CONFIG_USB_CYTHERM is not set
808# CONFIG_USB_PHIDGET is not set
809# CONFIG_USB_IDMOUSE is not set
810# CONFIG_USB_FTDI_ELAN is not set
811# CONFIG_USB_APPLEDISPLAY is not set
812# CONFIG_USB_LD is not set
813# CONFIG_USB_TRANCEVIBRATOR is not set
814# CONFIG_USB_IOWARRIOR is not set
815# CONFIG_USB_TEST is not set
816
817#
818# USB DSL modem support
819#
820
821#
822# USB Gadget Support
823#
824# CONFIG_USB_GADGET is not set
825CONFIG_MMC=y
826# CONFIG_MMC_DEBUG is not set
827# CONFIG_MMC_UNSAFE_RESUME is not set
828
829#
830# MMC/SD Card Drivers
831#
832CONFIG_MMC_BLOCK=y
833CONFIG_MMC_BLOCK_BOUNCE=y
834# CONFIG_SDIO_UART is not set
835
836#
837# MMC/SD Host Controller Drivers
838#
839CONFIG_MMC_PXA=y
840# CONFIG_NEW_LEDS is not set
841CONFIG_RTC_LIB=y
842CONFIG_RTC_CLASS=y
843CONFIG_RTC_HCTOSYS=y
844CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
845# CONFIG_RTC_DEBUG is not set
846
847#
848# RTC interfaces
849#
850CONFIG_RTC_INTF_SYSFS=y
851CONFIG_RTC_INTF_PROC=y
852CONFIG_RTC_INTF_DEV=y
853# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
854# CONFIG_RTC_DRV_TEST is not set
855
856#
857# I2C RTC drivers
858#
859# CONFIG_RTC_DRV_DS1307 is not set
860# CONFIG_RTC_DRV_DS1374 is not set
861# CONFIG_RTC_DRV_DS1672 is not set
862# CONFIG_RTC_DRV_MAX6900 is not set
863# CONFIG_RTC_DRV_RS5C372 is not set
864# CONFIG_RTC_DRV_ISL1208 is not set
865# CONFIG_RTC_DRV_X1205 is not set
866CONFIG_RTC_DRV_PCF8563=m
867# CONFIG_RTC_DRV_PCF8583 is not set
868# CONFIG_RTC_DRV_M41T80 is not set
869
870#
871# SPI RTC drivers
872#
873
874#
875# Platform RTC drivers
876#
877# CONFIG_RTC_DRV_CMOS is not set
878# CONFIG_RTC_DRV_DS1553 is not set
879# CONFIG_RTC_DRV_STK17TA8 is not set
880# CONFIG_RTC_DRV_DS1742 is not set
881# CONFIG_RTC_DRV_M48T86 is not set
882# CONFIG_RTC_DRV_M48T59 is not set
883# CONFIG_RTC_DRV_V3020 is not set
884
885#
886# on-CPU RTC drivers
887#
888CONFIG_RTC_DRV_SA1100=m
889
890#
891# File systems
892#
893CONFIG_EXT2_FS=m
894# CONFIG_EXT2_FS_XATTR is not set
895# CONFIG_EXT2_FS_XIP is not set
896CONFIG_EXT3_FS=m
897CONFIG_EXT3_FS_XATTR=y
898# CONFIG_EXT3_FS_POSIX_ACL is not set
899# CONFIG_EXT3_FS_SECURITY is not set
900# CONFIG_EXT4DEV_FS is not set
901CONFIG_JBD=m
902CONFIG_FS_MBCACHE=m
903# CONFIG_REISERFS_FS is not set
904# CONFIG_JFS_FS is not set
905# CONFIG_FS_POSIX_ACL is not set
906# CONFIG_XFS_FS is not set
907# CONFIG_GFS2_FS is not set
908# CONFIG_OCFS2_FS is not set
909# CONFIG_MINIX_FS is not set
910# CONFIG_ROMFS_FS is not set
911# CONFIG_INOTIFY is not set
912# CONFIG_QUOTA is not set
913# CONFIG_DNOTIFY is not set
914# CONFIG_AUTOFS_FS is not set
915# CONFIG_AUTOFS4_FS is not set
916# CONFIG_FUSE_FS is not set
917
918#
919# CD-ROM/DVD Filesystems
920#
921# CONFIG_ISO9660_FS is not set
922# CONFIG_UDF_FS is not set
923
924#
925# DOS/FAT/NT Filesystems
926#
927CONFIG_FAT_FS=m
928# CONFIG_MSDOS_FS is not set
929CONFIG_VFAT_FS=m
930CONFIG_FAT_DEFAULT_CODEPAGE=850
931CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-15"
932# CONFIG_NTFS_FS is not set
933
934#
935# Pseudo filesystems
936#
937CONFIG_PROC_FS=y
938CONFIG_PROC_SYSCTL=y
939CONFIG_SYSFS=y
940CONFIG_TMPFS=y
941# CONFIG_TMPFS_POSIX_ACL is not set
942# CONFIG_HUGETLB_PAGE is not set
943# CONFIG_CONFIGFS_FS is not set
944
945#
946# Miscellaneous filesystems
947#
948# CONFIG_ADFS_FS is not set
949# CONFIG_AFFS_FS is not set
950# CONFIG_HFS_FS is not set
951# CONFIG_HFSPLUS_FS is not set
952# CONFIG_BEFS_FS is not set
953# CONFIG_BFS_FS is not set
954# CONFIG_EFS_FS is not set
955CONFIG_JFFS2_FS=y
956CONFIG_JFFS2_FS_DEBUG=0
957CONFIG_JFFS2_FS_WRITEBUFFER=y
958# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
959# CONFIG_JFFS2_SUMMARY is not set
960# CONFIG_JFFS2_FS_XATTR is not set
961# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
962CONFIG_JFFS2_ZLIB=y
963# CONFIG_JFFS2_LZO is not set
964CONFIG_JFFS2_RTIME=y
965# CONFIG_JFFS2_RUBIN is not set
966# CONFIG_CRAMFS is not set
967# CONFIG_VXFS_FS is not set
968# CONFIG_HPFS_FS is not set
969# CONFIG_QNX4FS_FS is not set
970# CONFIG_SYSV_FS is not set
971# CONFIG_UFS_FS is not set
972CONFIG_NETWORK_FILESYSTEMS=y
973CONFIG_NFS_FS=y
974CONFIG_NFS_V3=y
975# CONFIG_NFS_V3_ACL is not set
976# CONFIG_NFS_V4 is not set
977CONFIG_NFS_DIRECTIO=y
978# CONFIG_NFSD is not set
979CONFIG_ROOT_NFS=y
980CONFIG_LOCKD=y
981CONFIG_LOCKD_V4=y
982CONFIG_NFS_COMMON=y
983CONFIG_SUNRPC=y
984# CONFIG_SUNRPC_BIND34 is not set
985# CONFIG_RPCSEC_GSS_KRB5 is not set
986# CONFIG_RPCSEC_GSS_SPKM3 is not set
987# CONFIG_SMB_FS is not set
988# CONFIG_CIFS is not set
989# CONFIG_NCP_FS is not set
990# CONFIG_CODA_FS is not set
991# CONFIG_AFS_FS is not set
992
993#
994# Partition Types
995#
996CONFIG_PARTITION_ADVANCED=y
997# CONFIG_ACORN_PARTITION is not set
998# CONFIG_OSF_PARTITION is not set
999# CONFIG_AMIGA_PARTITION is not set
1000# CONFIG_ATARI_PARTITION is not set
1001# CONFIG_MAC_PARTITION is not set
1002CONFIG_MSDOS_PARTITION=y
1003# CONFIG_BSD_DISKLABEL is not set
1004# CONFIG_MINIX_SUBPARTITION is not set
1005# CONFIG_SOLARIS_X86_PARTITION is not set
1006# CONFIG_UNIXWARE_DISKLABEL is not set
1007# CONFIG_LDM_PARTITION is not set
1008# CONFIG_SGI_PARTITION is not set
1009# CONFIG_ULTRIX_PARTITION is not set
1010# CONFIG_SUN_PARTITION is not set
1011# CONFIG_KARMA_PARTITION is not set
1012# CONFIG_EFI_PARTITION is not set
1013# CONFIG_SYSV68_PARTITION is not set
1014CONFIG_NLS=y
1015CONFIG_NLS_DEFAULT="iso8859-15"
1016# CONFIG_NLS_CODEPAGE_437 is not set
1017# CONFIG_NLS_CODEPAGE_737 is not set
1018# CONFIG_NLS_CODEPAGE_775 is not set
1019CONFIG_NLS_CODEPAGE_850=y
1020# CONFIG_NLS_CODEPAGE_852 is not set
1021# CONFIG_NLS_CODEPAGE_855 is not set
1022# CONFIG_NLS_CODEPAGE_857 is not set
1023# CONFIG_NLS_CODEPAGE_860 is not set
1024# CONFIG_NLS_CODEPAGE_861 is not set
1025# CONFIG_NLS_CODEPAGE_862 is not set
1026# CONFIG_NLS_CODEPAGE_863 is not set
1027# CONFIG_NLS_CODEPAGE_864 is not set
1028# CONFIG_NLS_CODEPAGE_865 is not set
1029# CONFIG_NLS_CODEPAGE_866 is not set
1030# CONFIG_NLS_CODEPAGE_869 is not set
1031# CONFIG_NLS_CODEPAGE_936 is not set
1032# CONFIG_NLS_CODEPAGE_950 is not set
1033# CONFIG_NLS_CODEPAGE_932 is not set
1034# CONFIG_NLS_CODEPAGE_949 is not set
1035# CONFIG_NLS_CODEPAGE_874 is not set
1036# CONFIG_NLS_ISO8859_8 is not set
1037# CONFIG_NLS_CODEPAGE_1250 is not set
1038# CONFIG_NLS_CODEPAGE_1251 is not set
1039# CONFIG_NLS_ASCII is not set
1040# CONFIG_NLS_ISO8859_1 is not set
1041# CONFIG_NLS_ISO8859_2 is not set
1042# CONFIG_NLS_ISO8859_3 is not set
1043# CONFIG_NLS_ISO8859_4 is not set
1044# CONFIG_NLS_ISO8859_5 is not set
1045# CONFIG_NLS_ISO8859_6 is not set
1046# CONFIG_NLS_ISO8859_7 is not set
1047# CONFIG_NLS_ISO8859_9 is not set
1048# CONFIG_NLS_ISO8859_13 is not set
1049# CONFIG_NLS_ISO8859_14 is not set
1050CONFIG_NLS_ISO8859_15=y
1051# CONFIG_NLS_KOI8_R is not set
1052# CONFIG_NLS_KOI8_U is not set
1053# CONFIG_NLS_UTF8 is not set
1054# CONFIG_DLM is not set
1055# CONFIG_INSTRUMENTATION is not set
1056
1057#
1058# Kernel hacking
1059#
1060# CONFIG_PRINTK_TIME is not set
1061CONFIG_ENABLE_WARN_DEPRECATED=y
1062CONFIG_ENABLE_MUST_CHECK=y
1063CONFIG_MAGIC_SYSRQ=y
1064# CONFIG_UNUSED_SYMBOLS is not set
1065# CONFIG_DEBUG_FS is not set
1066# CONFIG_HEADERS_CHECK is not set
1067# CONFIG_DEBUG_KERNEL is not set
1068# CONFIG_DEBUG_BUGVERBOSE is not set
1069CONFIG_FRAME_POINTER=y
1070# CONFIG_SAMPLES is not set
1071# CONFIG_DEBUG_USER is not set
1072
1073#
1074# Security options
1075#
1076# CONFIG_KEYS is not set
1077# CONFIG_SECURITY is not set
1078# CONFIG_SECURITY_FILE_CAPABILITIES is not set
1079# CONFIG_CRYPTO is not set
1080
1081#
1082# Library routines
1083#
1084CONFIG_BITREVERSE=y
1085# CONFIG_CRC_CCITT is not set
1086# CONFIG_CRC16 is not set
1087# CONFIG_CRC_ITU_T is not set
1088CONFIG_CRC32=y
1089# CONFIG_CRC7 is not set
1090# CONFIG_LIBCRC32C is not set
1091CONFIG_ZLIB_INFLATE=y
1092CONFIG_ZLIB_DEFLATE=y
1093CONFIG_PLIST=y
1094CONFIG_HAS_IOMEM=y
1095CONFIG_HAS_IOPORT=y
1096CONFIG_HAS_DMA=y
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 593b56509f4f..faa761921153 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_ISA_DMA) += dma-isa.o
19obj-$(CONFIG_PCI) += bios32.o isa.o 19obj-$(CONFIG_PCI) += bios32.o isa.o
20obj-$(CONFIG_SMP) += smp.o 20obj-$(CONFIG_SMP) += smp.o
21obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o 21obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
22obj-$(CONFIG_KPROBES) += kprobes.o kprobes-decode.o
22obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o 23obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o
23 24
24obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o 25obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o
diff --git a/arch/arm/kernel/dma-isa.c b/arch/arm/kernel/dma-isa.c
index 0a3e9ad297d8..2f080a35a2d9 100644
--- a/arch/arm/kernel/dma-isa.c
+++ b/arch/arm/kernel/dma-isa.c
@@ -216,7 +216,7 @@ void __init isa_init_dma(dma_t *dma)
216 216
217 request_dma(DMA_ISA_CASCADE, "cascade"); 217 request_dma(DMA_ISA_CASCADE, "cascade");
218 218
219 for (i = 0; i < sizeof(dma_resources) / sizeof(dma_resources[0]); i++) 219 for (i = 0; i < ARRAY_SIZE(dma_resources); i++)
220 request_resource(&ioport_resource, dma_resources + i); 220 request_resource(&ioport_resource, dma_resources + i);
221 } 221 }
222} 222}
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 29dec080a604..a46d5b456765 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -11,8 +11,8 @@
11 * 11 *
12 * Low-level vector interface routines 12 * Low-level vector interface routines
13 * 13 *
14 * Note: there is a StrongARM bug in the STMIA rn, {regs}^ instruction that causes 14 * Note: there is a StrongARM bug in the STMIA rn, {regs}^ instruction
15 * it to save wrong values... Be aware! 15 * that causes it to save wrong values... Be aware!
16 */ 16 */
17 17
18#include <asm/memory.h> 18#include <asm/memory.h>
@@ -58,6 +58,12 @@
58 58
59 .endm 59 .endm
60 60
61#ifdef CONFIG_KPROBES
62 .section .kprobes.text,"ax",%progbits
63#else
64 .text
65#endif
66
61/* 67/*
62 * Invalid mode handlers 68 * Invalid mode handlers
63 */ 69 */
@@ -112,8 +118,8 @@ common_invalid:
112#define SPFIX(code...) 118#define SPFIX(code...)
113#endif 119#endif
114 120
115 .macro svc_entry 121 .macro svc_entry, stack_hole=0
116 sub sp, sp, #S_FRAME_SIZE 122 sub sp, sp, #(S_FRAME_SIZE + \stack_hole)
117 SPFIX( tst sp, #4 ) 123 SPFIX( tst sp, #4 )
118 SPFIX( bicne sp, sp, #4 ) 124 SPFIX( bicne sp, sp, #4 )
119 stmib sp, {r1 - r12} 125 stmib sp, {r1 - r12}
@@ -121,7 +127,7 @@ common_invalid:
121 ldmia r0, {r1 - r3} 127 ldmia r0, {r1 - r3}
122 add r5, sp, #S_SP @ here for interlock avoidance 128 add r5, sp, #S_SP @ here for interlock avoidance
123 mov r4, #-1 @ "" "" "" "" 129 mov r4, #-1 @ "" "" "" ""
124 add r0, sp, #S_FRAME_SIZE @ "" "" "" "" 130 add r0, sp, #(S_FRAME_SIZE + \stack_hole)
125 SPFIX( addne r0, r0, #4 ) 131 SPFIX( addne r0, r0, #4 )
126 str r1, [sp] @ save the "real" r0 copied 132 str r1, [sp] @ save the "real" r0 copied
127 @ from the exception stack 133 @ from the exception stack
@@ -242,7 +248,14 @@ svc_preempt:
242 248
243 .align 5 249 .align 5
244__und_svc: 250__und_svc:
251#ifdef CONFIG_KPROBES
252 @ If a kprobe is about to simulate a "stmdb sp..." instruction,
253 @ it obviously needs free stack space which then will belong to
254 @ the saved context.
255 svc_entry 64
256#else
245 svc_entry 257 svc_entry
258#endif
246 259
247 @ 260 @
248 @ call emulation code, which returns using r9 if it has emulated 261 @ call emulation code, which returns using r9 if it has emulated
@@ -480,6 +493,13 @@ __und_usr:
480 * co-processor instructions. However, we have to watch out 493 * co-processor instructions. However, we have to watch out
481 * for the ARM6/ARM7 SWI bug. 494 * for the ARM6/ARM7 SWI bug.
482 * 495 *
496 * NEON is a special case that has to be handled here. Not all
497 * NEON instructions are co-processor instructions, so we have
498 * to make a special case of checking for them. Plus, there's
499 * five groups of them, so we have a table of mask/opcode pairs
500 * to check against, and if any match then we branch off into the
501 * NEON handler code.
502 *
483 * Emulators may wish to make use of the following registers: 503 * Emulators may wish to make use of the following registers:
484 * r0 = instruction opcode. 504 * r0 = instruction opcode.
485 * r2 = PC+4 505 * r2 = PC+4
@@ -488,6 +508,23 @@ __und_usr:
488 * lr = unrecognised instruction return address 508 * lr = unrecognised instruction return address
489 */ 509 */
490call_fpe: 510call_fpe:
511#ifdef CONFIG_NEON
512 adr r6, .LCneon_opcodes
5132:
514 ldr r7, [r6], #4 @ mask value
515 cmp r7, #0 @ end mask?
516 beq 1f
517 and r8, r0, r7
518 ldr r7, [r6], #4 @ opcode bits matching in mask
519 cmp r8, r7 @ NEON instruction?
520 bne 2b
521 get_thread_info r10
522 mov r7, #1
523 strb r7, [r10, #TI_USED_CP + 10] @ mark CP#10 as used
524 strb r7, [r10, #TI_USED_CP + 11] @ mark CP#11 as used
525 b do_vfp @ let VFP handler handle this
5261:
527#endif
491 tst r0, #0x08000000 @ only CDP/CPRT/LDC/STC have bit 27 528 tst r0, #0x08000000 @ only CDP/CPRT/LDC/STC have bit 27
492#if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710) 529#if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710)
493 and r8, r0, #0x0f000000 @ mask out op-code bits 530 and r8, r0, #0x0f000000 @ mask out op-code bits
@@ -537,6 +574,20 @@ call_fpe:
537 mov pc, lr @ CP#14 (Debug) 574 mov pc, lr @ CP#14 (Debug)
538 mov pc, lr @ CP#15 (Control) 575 mov pc, lr @ CP#15 (Control)
539 576
577#ifdef CONFIG_NEON
578 .align 6
579
580.LCneon_opcodes:
581 .word 0xfe000000 @ mask
582 .word 0xf2000000 @ opcode
583
584 .word 0xff100000 @ mask
585 .word 0xf4000000 @ opcode
586
587 .word 0x00000000 @ mask
588 .word 0x00000000 @ opcode
589#endif
590
540do_fpe: 591do_fpe:
541 enable_irq 592 enable_irq
542 ldr r4, .LCfp 593 ldr r4, .LCfp
@@ -555,7 +606,7 @@ do_fpe:
555 .data 606 .data
556ENTRY(fp_enter) 607ENTRY(fp_enter)
557 .word no_fp 608 .word no_fp
558 .text 609 .previous
559 610
560no_fp: mov pc, lr 611no_fp: mov pc, lr
561 612
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 33e6cc2ffd3b..6c90c50a9ee3 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -72,7 +72,7 @@ no_work_pending:
72 ldr r1, [sp, #S_PSR] @ get calling cpsr 72 ldr r1, [sp, #S_PSR] @ get calling cpsr
73 ldr lr, [sp, #S_PC]! @ get pc 73 ldr lr, [sp, #S_PC]! @ get pc
74 msr spsr_cxsf, r1 @ save in spsr_svc 74 msr spsr_cxsf, r1 @ save in spsr_svc
75 ldmdb sp, {r0 - lr}^ @ get calling r1 - lr 75 ldmdb sp, {r0 - lr}^ @ get calling r0 - lr
76 mov r0, r0 76 mov r0, r0
77 add sp, sp, #S_FRAME_SIZE - S_PC 77 add sp, sp, #S_FRAME_SIZE - S_PC
78 movs pc, lr @ return & move spsr_svc into cpsr 78 movs pc, lr @ return & move spsr_svc into cpsr
diff --git a/arch/arm/kernel/kprobes-decode.c b/arch/arm/kernel/kprobes-decode.c
new file mode 100644
index 000000000000..d51bc8b60557
--- /dev/null
+++ b/arch/arm/kernel/kprobes-decode.c
@@ -0,0 +1,1529 @@
1/*
2 * arch/arm/kernel/kprobes-decode.c
3 *
4 * Copyright (C) 2006, 2007 Motorola Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 */
15
16/*
17 * We do not have hardware single-stepping on ARM, This
18 * effort is further complicated by the ARM not having a
19 * "next PC" register. Instructions that change the PC
20 * can't be safely single-stepped in a MP environment, so
21 * we have a lot of work to do:
22 *
23 * In the prepare phase:
24 * *) If it is an instruction that does anything
25 * with the CPU mode, we reject it for a kprobe.
26 * (This is out of laziness rather than need. The
27 * instructions could be simulated.)
28 *
29 * *) Otherwise, decode the instruction rewriting its
30 * registers to take fixed, ordered registers and
31 * setting a handler for it to run the instruction.
32 *
33 * In the execution phase by an instruction's handler:
34 *
35 * *) If the PC is written to by the instruction, the
36 * instruction must be fully simulated in software.
37 * If it is a conditional instruction, the handler
38 * will use insn[0] to copy its condition code to
39 * set r0 to 1 and insn[1] to "mov pc, lr" to return.
40 *
41 * *) Otherwise, a modified form of the instruction is
42 * directly executed. Its handler calls the
43 * instruction in insn[0]. In insn[1] is a
44 * "mov pc, lr" to return.
45 *
46 * Before calling, load up the reordered registers
47 * from the original instruction's registers. If one
48 * of the original input registers is the PC, compute
49 * and adjust the appropriate input register.
50 *
51 * After call completes, copy the output registers to
52 * the original instruction's original registers.
53 *
54 * We don't use a real breakpoint instruction since that
55 * would have us in the kernel go from SVC mode to SVC
56 * mode losing the link register. Instead we use an
57 * undefined instruction. To simplify processing, the
58 * undefined instruction used for kprobes must be reserved
59 * exclusively for kprobes use.
60 *
61 * TODO: ifdef out some instruction decoding based on architecture.
62 */
63
64#include <linux/kernel.h>
65#include <linux/kprobes.h>
66
67#define sign_extend(x, signbit) ((x) | (0 - ((x) & (1 << (signbit)))))
68
69#define branch_displacement(insn) sign_extend(((insn) & 0xffffff) << 2, 25)
70
71#define PSR_fs (PSR_f|PSR_s)
72
73#define KPROBE_RETURN_INSTRUCTION 0xe1a0f00e /* mov pc, lr */
74#define SET_R0_TRUE_INSTRUCTION 0xe3a00001 /* mov r0, #1 */
75
76#define truecc_insn(insn) (((insn) & 0xf0000000) | \
77 (SET_R0_TRUE_INSTRUCTION & 0x0fffffff))
78
79typedef long (insn_0arg_fn_t)(void);
80typedef long (insn_1arg_fn_t)(long);
81typedef long (insn_2arg_fn_t)(long, long);
82typedef long (insn_3arg_fn_t)(long, long, long);
83typedef long (insn_4arg_fn_t)(long, long, long, long);
84typedef long long (insn_llret_0arg_fn_t)(void);
85typedef long long (insn_llret_3arg_fn_t)(long, long, long);
86typedef long long (insn_llret_4arg_fn_t)(long, long, long, long);
87
88union reg_pair {
89 long long dr;
90#ifdef __LITTLE_ENDIAN
91 struct { long r0, r1; };
92#else
93 struct { long r1, r0; };
94#endif
95};
96
97/*
98 * For STR and STM instructions, an ARM core may choose to use either
99 * a +8 or a +12 displacement from the current instruction's address.
100 * Whichever value is chosen for a given core, it must be the same for
101 * both instructions and may not change. This function measures it.
102 */
103
104static int str_pc_offset;
105
106static void __init find_str_pc_offset(void)
107{
108 int addr, scratch, ret;
109
110 __asm__ (
111 "sub %[ret], pc, #4 \n\t"
112 "str pc, %[addr] \n\t"
113 "ldr %[scr], %[addr] \n\t"
114 "sub %[ret], %[scr], %[ret] \n\t"
115 : [ret] "=r" (ret), [scr] "=r" (scratch), [addr] "+m" (addr));
116
117 str_pc_offset = ret;
118}
119
120/*
121 * The insnslot_?arg_r[w]flags() functions below are to keep the
122 * msr -> *fn -> mrs instruction sequences indivisible so that
123 * the state of the CPSR flags aren't inadvertently modified
124 * just before or just after the call.
125 */
126
127static inline long __kprobes
128insnslot_0arg_rflags(long cpsr, insn_0arg_fn_t *fn)
129{
130 register long ret asm("r0");
131
132 __asm__ __volatile__ (
133 "msr cpsr_fs, %[cpsr] \n\t"
134 "mov lr, pc \n\t"
135 "mov pc, %[fn] \n\t"
136 : "=r" (ret)
137 : [cpsr] "r" (cpsr), [fn] "r" (fn)
138 : "lr", "cc"
139 );
140 return ret;
141}
142
143static inline long long __kprobes
144insnslot_llret_0arg_rflags(long cpsr, insn_llret_0arg_fn_t *fn)
145{
146 register long ret0 asm("r0");
147 register long ret1 asm("r1");
148 union reg_pair fnr;
149
150 __asm__ __volatile__ (
151 "msr cpsr_fs, %[cpsr] \n\t"
152 "mov lr, pc \n\t"
153 "mov pc, %[fn] \n\t"
154 : "=r" (ret0), "=r" (ret1)
155 : [cpsr] "r" (cpsr), [fn] "r" (fn)
156 : "lr", "cc"
157 );
158 fnr.r0 = ret0;
159 fnr.r1 = ret1;
160 return fnr.dr;
161}
162
163static inline long __kprobes
164insnslot_1arg_rflags(long r0, long cpsr, insn_1arg_fn_t *fn)
165{
166 register long rr0 asm("r0") = r0;
167 register long ret asm("r0");
168
169 __asm__ __volatile__ (
170 "msr cpsr_fs, %[cpsr] \n\t"
171 "mov lr, pc \n\t"
172 "mov pc, %[fn] \n\t"
173 : "=r" (ret)
174 : "0" (rr0), [cpsr] "r" (cpsr), [fn] "r" (fn)
175 : "lr", "cc"
176 );
177 return ret;
178}
179
180static inline long __kprobes
181insnslot_2arg_rflags(long r0, long r1, long cpsr, insn_2arg_fn_t *fn)
182{
183 register long rr0 asm("r0") = r0;
184 register long rr1 asm("r1") = r1;
185 register long ret asm("r0");
186
187 __asm__ __volatile__ (
188 "msr cpsr_fs, %[cpsr] \n\t"
189 "mov lr, pc \n\t"
190 "mov pc, %[fn] \n\t"
191 : "=r" (ret)
192 : "0" (rr0), "r" (rr1),
193 [cpsr] "r" (cpsr), [fn] "r" (fn)
194 : "lr", "cc"
195 );
196 return ret;
197}
198
199static inline long __kprobes
200insnslot_3arg_rflags(long r0, long r1, long r2, long cpsr, insn_3arg_fn_t *fn)
201{
202 register long rr0 asm("r0") = r0;
203 register long rr1 asm("r1") = r1;
204 register long rr2 asm("r2") = r2;
205 register long ret asm("r0");
206
207 __asm__ __volatile__ (
208 "msr cpsr_fs, %[cpsr] \n\t"
209 "mov lr, pc \n\t"
210 "mov pc, %[fn] \n\t"
211 : "=r" (ret)
212 : "0" (rr0), "r" (rr1), "r" (rr2),
213 [cpsr] "r" (cpsr), [fn] "r" (fn)
214 : "lr", "cc"
215 );
216 return ret;
217}
218
219static inline long long __kprobes
220insnslot_llret_3arg_rflags(long r0, long r1, long r2, long cpsr,
221 insn_llret_3arg_fn_t *fn)
222{
223 register long rr0 asm("r0") = r0;
224 register long rr1 asm("r1") = r1;
225 register long rr2 asm("r2") = r2;
226 register long ret0 asm("r0");
227 register long ret1 asm("r1");
228 union reg_pair fnr;
229
230 __asm__ __volatile__ (
231 "msr cpsr_fs, %[cpsr] \n\t"
232 "mov lr, pc \n\t"
233 "mov pc, %[fn] \n\t"
234 : "=r" (ret0), "=r" (ret1)
235 : "0" (rr0), "r" (rr1), "r" (rr2),
236 [cpsr] "r" (cpsr), [fn] "r" (fn)
237 : "lr", "cc"
238 );
239 fnr.r0 = ret0;
240 fnr.r1 = ret1;
241 return fnr.dr;
242}
243
244static inline long __kprobes
245insnslot_4arg_rflags(long r0, long r1, long r2, long r3, long cpsr,
246 insn_4arg_fn_t *fn)
247{
248 register long rr0 asm("r0") = r0;
249 register long rr1 asm("r1") = r1;
250 register long rr2 asm("r2") = r2;
251 register long rr3 asm("r3") = r3;
252 register long ret asm("r0");
253
254 __asm__ __volatile__ (
255 "msr cpsr_fs, %[cpsr] \n\t"
256 "mov lr, pc \n\t"
257 "mov pc, %[fn] \n\t"
258 : "=r" (ret)
259 : "0" (rr0), "r" (rr1), "r" (rr2), "r" (rr3),
260 [cpsr] "r" (cpsr), [fn] "r" (fn)
261 : "lr", "cc"
262 );
263 return ret;
264}
265
266static inline long __kprobes
267insnslot_1arg_rwflags(long r0, long *cpsr, insn_1arg_fn_t *fn)
268{
269 register long rr0 asm("r0") = r0;
270 register long ret asm("r0");
271 long oldcpsr = *cpsr;
272 long newcpsr;
273
274 __asm__ __volatile__ (
275 "msr cpsr_fs, %[oldcpsr] \n\t"
276 "mov lr, pc \n\t"
277 "mov pc, %[fn] \n\t"
278 "mrs %[newcpsr], cpsr \n\t"
279 : "=r" (ret), [newcpsr] "=r" (newcpsr)
280 : "0" (rr0), [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
281 : "lr", "cc"
282 );
283 *cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
284 return ret;
285}
286
287static inline long __kprobes
288insnslot_2arg_rwflags(long r0, long r1, long *cpsr, insn_2arg_fn_t *fn)
289{
290 register long rr0 asm("r0") = r0;
291 register long rr1 asm("r1") = r1;
292 register long ret asm("r0");
293 long oldcpsr = *cpsr;
294 long newcpsr;
295
296 __asm__ __volatile__ (
297 "msr cpsr_fs, %[oldcpsr] \n\t"
298 "mov lr, pc \n\t"
299 "mov pc, %[fn] \n\t"
300 "mrs %[newcpsr], cpsr \n\t"
301 : "=r" (ret), [newcpsr] "=r" (newcpsr)
302 : "0" (rr0), "r" (rr1), [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
303 : "lr", "cc"
304 );
305 *cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
306 return ret;
307}
308
309static inline long __kprobes
310insnslot_3arg_rwflags(long r0, long r1, long r2, long *cpsr,
311 insn_3arg_fn_t *fn)
312{
313 register long rr0 asm("r0") = r0;
314 register long rr1 asm("r1") = r1;
315 register long rr2 asm("r2") = r2;
316 register long ret asm("r0");
317 long oldcpsr = *cpsr;
318 long newcpsr;
319
320 __asm__ __volatile__ (
321 "msr cpsr_fs, %[oldcpsr] \n\t"
322 "mov lr, pc \n\t"
323 "mov pc, %[fn] \n\t"
324 "mrs %[newcpsr], cpsr \n\t"
325 : "=r" (ret), [newcpsr] "=r" (newcpsr)
326 : "0" (rr0), "r" (rr1), "r" (rr2),
327 [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
328 : "lr", "cc"
329 );
330 *cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
331 return ret;
332}
333
334static inline long __kprobes
335insnslot_4arg_rwflags(long r0, long r1, long r2, long r3, long *cpsr,
336 insn_4arg_fn_t *fn)
337{
338 register long rr0 asm("r0") = r0;
339 register long rr1 asm("r1") = r1;
340 register long rr2 asm("r2") = r2;
341 register long rr3 asm("r3") = r3;
342 register long ret asm("r0");
343 long oldcpsr = *cpsr;
344 long newcpsr;
345
346 __asm__ __volatile__ (
347 "msr cpsr_fs, %[oldcpsr] \n\t"
348 "mov lr, pc \n\t"
349 "mov pc, %[fn] \n\t"
350 "mrs %[newcpsr], cpsr \n\t"
351 : "=r" (ret), [newcpsr] "=r" (newcpsr)
352 : "0" (rr0), "r" (rr1), "r" (rr2), "r" (rr3),
353 [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
354 : "lr", "cc"
355 );
356 *cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
357 return ret;
358}
359
360static inline long long __kprobes
361insnslot_llret_4arg_rwflags(long r0, long r1, long r2, long r3, long *cpsr,
362 insn_llret_4arg_fn_t *fn)
363{
364 register long rr0 asm("r0") = r0;
365 register long rr1 asm("r1") = r1;
366 register long rr2 asm("r2") = r2;
367 register long rr3 asm("r3") = r3;
368 register long ret0 asm("r0");
369 register long ret1 asm("r1");
370 long oldcpsr = *cpsr;
371 long newcpsr;
372 union reg_pair fnr;
373
374 __asm__ __volatile__ (
375 "msr cpsr_fs, %[oldcpsr] \n\t"
376 "mov lr, pc \n\t"
377 "mov pc, %[fn] \n\t"
378 "mrs %[newcpsr], cpsr \n\t"
379 : "=r" (ret0), "=r" (ret1), [newcpsr] "=r" (newcpsr)
380 : "0" (rr0), "r" (rr1), "r" (rr2), "r" (rr3),
381 [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
382 : "lr", "cc"
383 );
384 *cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
385 fnr.r0 = ret0;
386 fnr.r1 = ret1;
387 return fnr.dr;
388}
389
390/*
391 * To avoid the complications of mimicing single-stepping on a
392 * processor without a Next-PC or a single-step mode, and to
393 * avoid having to deal with the side-effects of boosting, we
394 * simulate or emulate (almost) all ARM instructions.
395 *
396 * "Simulation" is where the instruction's behavior is duplicated in
397 * C code. "Emulation" is where the original instruction is rewritten
398 * and executed, often by altering its registers.
399 *
400 * By having all behavior of the kprobe'd instruction completed before
401 * returning from the kprobe_handler(), all locks (scheduler and
402 * interrupt) can safely be released. There is no need for secondary
403 * breakpoints, no race with MP or preemptable kernels, nor having to
404 * clean up resources counts at a later time impacting overall system
405 * performance. By rewriting the instruction, only the minimum registers
406 * need to be loaded and saved back optimizing performance.
407 *
408 * Calling the insnslot_*_rwflags version of a function doesn't hurt
409 * anything even when the CPSR flags aren't updated by the
410 * instruction. It's just a little slower in return for saving
411 * a little space by not having a duplicate function that doesn't
412 * update the flags. (The same optimization can be said for
413 * instructions that do or don't perform register writeback)
414 * Also, instructions can either read the flags, only write the
415 * flags, or read and write the flags. To save combinations
416 * rather than for sheer performance, flag functions just assume
417 * read and write of flags.
418 */
419
420static void __kprobes simulate_bbl(struct kprobe *p, struct pt_regs *regs)
421{
422 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
423 kprobe_opcode_t insn = p->opcode;
424 long iaddr = (long)p->addr;
425 int disp = branch_displacement(insn);
426
427 if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
428 return;
429
430 if (insn & (1 << 24))
431 regs->ARM_lr = iaddr + 4;
432
433 regs->ARM_pc = iaddr + 8 + disp;
434}
435
436static void __kprobes simulate_blx1(struct kprobe *p, struct pt_regs *regs)
437{
438 kprobe_opcode_t insn = p->opcode;
439 long iaddr = (long)p->addr;
440 int disp = branch_displacement(insn);
441
442 regs->ARM_lr = iaddr + 4;
443 regs->ARM_pc = iaddr + 8 + disp + ((insn >> 23) & 0x2);
444 regs->ARM_cpsr |= PSR_T_BIT;
445}
446
447static void __kprobes simulate_blx2bx(struct kprobe *p, struct pt_regs *regs)
448{
449 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
450 kprobe_opcode_t insn = p->opcode;
451 int rm = insn & 0xf;
452 long rmv = regs->uregs[rm];
453
454 if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
455 return;
456
457 if (insn & (1 << 5))
458 regs->ARM_lr = (long)p->addr + 4;
459
460 regs->ARM_pc = rmv & ~0x1;
461 regs->ARM_cpsr &= ~PSR_T_BIT;
462 if (rmv & 0x1)
463 regs->ARM_cpsr |= PSR_T_BIT;
464}
465
466static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs)
467{
468 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
469 kprobe_opcode_t insn = p->opcode;
470 int rn = (insn >> 16) & 0xf;
471 int lbit = insn & (1 << 20);
472 int wbit = insn & (1 << 21);
473 int ubit = insn & (1 << 23);
474 int pbit = insn & (1 << 24);
475 long *addr = (long *)regs->uregs[rn];
476 int reg_bit_vector;
477 int reg_count;
478
479 if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
480 return;
481
482 reg_count = 0;
483 reg_bit_vector = insn & 0xffff;
484 while (reg_bit_vector) {
485 reg_bit_vector &= (reg_bit_vector - 1);
486 ++reg_count;
487 }
488
489 if (!ubit)
490 addr -= reg_count;
491 addr += (!pbit ^ !ubit);
492
493 reg_bit_vector = insn & 0xffff;
494 while (reg_bit_vector) {
495 int reg = __ffs(reg_bit_vector);
496 reg_bit_vector &= (reg_bit_vector - 1);
497 if (lbit)
498 regs->uregs[reg] = *addr++;
499 else
500 *addr++ = regs->uregs[reg];
501 }
502
503 if (wbit) {
504 if (!ubit)
505 addr -= reg_count;
506 addr -= (!pbit ^ !ubit);
507 regs->uregs[rn] = (long)addr;
508 }
509}
510
511static void __kprobes simulate_stm1_pc(struct kprobe *p, struct pt_regs *regs)
512{
513 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
514
515 if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
516 return;
517
518 regs->ARM_pc = (long)p->addr + str_pc_offset;
519 simulate_ldm1stm1(p, regs);
520 regs->ARM_pc = (long)p->addr + 4;
521}
522
523static void __kprobes simulate_mov_ipsp(struct kprobe *p, struct pt_regs *regs)
524{
525 regs->uregs[12] = regs->uregs[13];
526}
527
528static void __kprobes emulate_ldcstc(struct kprobe *p, struct pt_regs *regs)
529{
530 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
531 kprobe_opcode_t insn = p->opcode;
532 int rn = (insn >> 16) & 0xf;
533 long rnv = regs->uregs[rn];
534
535 /* Save Rn in case of writeback. */
536 regs->uregs[rn] = insnslot_1arg_rflags(rnv, regs->ARM_cpsr, i_fn);
537}
538
539static void __kprobes emulate_ldrd(struct kprobe *p, struct pt_regs *regs)
540{
541 insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
542 kprobe_opcode_t insn = p->opcode;
543 int rd = (insn >> 12) & 0xf;
544 int rn = (insn >> 16) & 0xf;
545 int rm = insn & 0xf; /* rm may be invalid, don't care. */
546
547 /* Not following the C calling convention here, so need asm(). */
548 __asm__ __volatile__ (
549 "ldr r0, %[rn] \n\t"
550 "ldr r1, %[rm] \n\t"
551 "msr cpsr_fs, %[cpsr]\n\t"
552 "mov lr, pc \n\t"
553 "mov pc, %[i_fn] \n\t"
554 "str r0, %[rn] \n\t" /* in case of writeback */
555 "str r2, %[rd0] \n\t"
556 "str r3, %[rd1] \n\t"
557 : [rn] "+m" (regs->uregs[rn]),
558 [rd0] "=m" (regs->uregs[rd]),
559 [rd1] "=m" (regs->uregs[rd+1])
560 : [rm] "m" (regs->uregs[rm]),
561 [cpsr] "r" (regs->ARM_cpsr),
562 [i_fn] "r" (i_fn)
563 : "r0", "r1", "r2", "r3", "lr", "cc"
564 );
565}
566
567static void __kprobes emulate_strd(struct kprobe *p, struct pt_regs *regs)
568{
569 insn_4arg_fn_t *i_fn = (insn_4arg_fn_t *)&p->ainsn.insn[0];
570 kprobe_opcode_t insn = p->opcode;
571 int rd = (insn >> 12) & 0xf;
572 int rn = (insn >> 16) & 0xf;
573 int rm = insn & 0xf;
574 long rnv = regs->uregs[rn];
575 long rmv = regs->uregs[rm]; /* rm/rmv may be invalid, don't care. */
576
577 regs->uregs[rn] = insnslot_4arg_rflags(rnv, rmv, regs->uregs[rd],
578 regs->uregs[rd+1],
579 regs->ARM_cpsr, i_fn);
580}
581
582static void __kprobes emulate_ldr(struct kprobe *p, struct pt_regs *regs)
583{
584 insn_llret_3arg_fn_t *i_fn = (insn_llret_3arg_fn_t *)&p->ainsn.insn[0];
585 kprobe_opcode_t insn = p->opcode;
586 union reg_pair fnr;
587 int rd = (insn >> 12) & 0xf;
588 int rn = (insn >> 16) & 0xf;
589 int rm = insn & 0xf;
590 long rdv;
591 long rnv = regs->uregs[rn];
592 long rmv = regs->uregs[rm]; /* rm/rmv may be invalid, don't care. */
593 long cpsr = regs->ARM_cpsr;
594
595 fnr.dr = insnslot_llret_3arg_rflags(rnv, 0, rmv, cpsr, i_fn);
596 regs->uregs[rn] = fnr.r0; /* Save Rn in case of writeback. */
597 rdv = fnr.r1;
598
599 if (rd == 15) {
600#if __LINUX_ARM_ARCH__ >= 5
601 cpsr &= ~PSR_T_BIT;
602 if (rdv & 0x1)
603 cpsr |= PSR_T_BIT;
604 regs->ARM_cpsr = cpsr;
605 rdv &= ~0x1;
606#else
607 rdv &= ~0x2;
608#endif
609 }
610 regs->uregs[rd] = rdv;
611}
612
613static void __kprobes emulate_str(struct kprobe *p, struct pt_regs *regs)
614{
615 insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
616 kprobe_opcode_t insn = p->opcode;
617 long iaddr = (long)p->addr;
618 int rd = (insn >> 12) & 0xf;
619 int rn = (insn >> 16) & 0xf;
620 int rm = insn & 0xf;
621 long rdv = (rd == 15) ? iaddr + str_pc_offset : regs->uregs[rd];
622 long rnv = (rn == 15) ? iaddr + 8 : regs->uregs[rn];
623 long rmv = regs->uregs[rm]; /* rm/rmv may be invalid, don't care. */
624
625 /* Save Rn in case of writeback. */
626 regs->uregs[rn] =
627 insnslot_3arg_rflags(rnv, rdv, rmv, regs->ARM_cpsr, i_fn);
628}
629
630static void __kprobes emulate_mrrc(struct kprobe *p, struct pt_regs *regs)
631{
632 insn_llret_0arg_fn_t *i_fn = (insn_llret_0arg_fn_t *)&p->ainsn.insn[0];
633 kprobe_opcode_t insn = p->opcode;
634 union reg_pair fnr;
635 int rd = (insn >> 12) & 0xf;
636 int rn = (insn >> 16) & 0xf;
637
638 fnr.dr = insnslot_llret_0arg_rflags(regs->ARM_cpsr, i_fn);
639 regs->uregs[rn] = fnr.r0;
640 regs->uregs[rd] = fnr.r1;
641}
642
643static void __kprobes emulate_mcrr(struct kprobe *p, struct pt_regs *regs)
644{
645 insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
646 kprobe_opcode_t insn = p->opcode;
647 int rd = (insn >> 12) & 0xf;
648 int rn = (insn >> 16) & 0xf;
649 long rnv = regs->uregs[rn];
650 long rdv = regs->uregs[rd];
651
652 insnslot_2arg_rflags(rnv, rdv, regs->ARM_cpsr, i_fn);
653}
654
655static void __kprobes emulate_sat(struct kprobe *p, struct pt_regs *regs)
656{
657 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
658 kprobe_opcode_t insn = p->opcode;
659 int rd = (insn >> 12) & 0xf;
660 int rm = insn & 0xf;
661 long rmv = regs->uregs[rm];
662
663 /* Writes Q flag */
664 regs->uregs[rd] = insnslot_1arg_rwflags(rmv, &regs->ARM_cpsr, i_fn);
665}
666
667static void __kprobes emulate_sel(struct kprobe *p, struct pt_regs *regs)
668{
669 insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
670 kprobe_opcode_t insn = p->opcode;
671 int rd = (insn >> 12) & 0xf;
672 int rn = (insn >> 16) & 0xf;
673 int rm = insn & 0xf;
674 long rnv = regs->uregs[rn];
675 long rmv = regs->uregs[rm];
676
677 /* Reads GE bits */
678 regs->uregs[rd] = insnslot_2arg_rflags(rnv, rmv, regs->ARM_cpsr, i_fn);
679}
680
681static void __kprobes emulate_none(struct kprobe *p, struct pt_regs *regs)
682{
683 insn_0arg_fn_t *i_fn = (insn_0arg_fn_t *)&p->ainsn.insn[0];
684
685 insnslot_0arg_rflags(regs->ARM_cpsr, i_fn);
686}
687
688static void __kprobes emulate_rd12(struct kprobe *p, struct pt_regs *regs)
689{
690 insn_0arg_fn_t *i_fn = (insn_0arg_fn_t *)&p->ainsn.insn[0];
691 kprobe_opcode_t insn = p->opcode;
692 int rd = (insn >> 12) & 0xf;
693
694 regs->uregs[rd] = insnslot_0arg_rflags(regs->ARM_cpsr, i_fn);
695}
696
697static void __kprobes emulate_ird12(struct kprobe *p, struct pt_regs *regs)
698{
699 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
700 kprobe_opcode_t insn = p->opcode;
701 int ird = (insn >> 12) & 0xf;
702
703 insnslot_1arg_rflags(regs->uregs[ird], regs->ARM_cpsr, i_fn);
704}
705
706static void __kprobes emulate_rn16(struct kprobe *p, struct pt_regs *regs)
707{
708 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
709 kprobe_opcode_t insn = p->opcode;
710 int rn = (insn >> 16) & 0xf;
711 long rnv = regs->uregs[rn];
712
713 insnslot_1arg_rflags(rnv, regs->ARM_cpsr, i_fn);
714}
715
716static void __kprobes emulate_rd12rm0(struct kprobe *p, struct pt_regs *regs)
717{
718 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
719 kprobe_opcode_t insn = p->opcode;
720 int rd = (insn >> 12) & 0xf;
721 int rm = insn & 0xf;
722 long rmv = regs->uregs[rm];
723
724 regs->uregs[rd] = insnslot_1arg_rflags(rmv, regs->ARM_cpsr, i_fn);
725}
726
727static void __kprobes
728emulate_rd12rn16rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
729{
730 insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
731 kprobe_opcode_t insn = p->opcode;
732 int rd = (insn >> 12) & 0xf;
733 int rn = (insn >> 16) & 0xf;
734 int rm = insn & 0xf;
735 long rnv = regs->uregs[rn];
736 long rmv = regs->uregs[rm];
737
738 regs->uregs[rd] =
739 insnslot_2arg_rwflags(rnv, rmv, &regs->ARM_cpsr, i_fn);
740}
741
742static void __kprobes
743emulate_rd16rn12rs8rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
744{
745 insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
746 kprobe_opcode_t insn = p->opcode;
747 int rd = (insn >> 16) & 0xf;
748 int rn = (insn >> 12) & 0xf;
749 int rs = (insn >> 8) & 0xf;
750 int rm = insn & 0xf;
751 long rnv = regs->uregs[rn];
752 long rsv = regs->uregs[rs];
753 long rmv = regs->uregs[rm];
754
755 regs->uregs[rd] =
756 insnslot_3arg_rwflags(rnv, rsv, rmv, &regs->ARM_cpsr, i_fn);
757}
758
759static void __kprobes
760emulate_rd16rs8rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
761{
762 insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
763 kprobe_opcode_t insn = p->opcode;
764 int rd = (insn >> 16) & 0xf;
765 int rs = (insn >> 8) & 0xf;
766 int rm = insn & 0xf;
767 long rsv = regs->uregs[rs];
768 long rmv = regs->uregs[rm];
769
770 regs->uregs[rd] =
771 insnslot_2arg_rwflags(rsv, rmv, &regs->ARM_cpsr, i_fn);
772}
773
774static void __kprobes
775emulate_rdhi16rdlo12rs8rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
776{
777 insn_llret_4arg_fn_t *i_fn = (insn_llret_4arg_fn_t *)&p->ainsn.insn[0];
778 kprobe_opcode_t insn = p->opcode;
779 union reg_pair fnr;
780 int rdhi = (insn >> 16) & 0xf;
781 int rdlo = (insn >> 12) & 0xf;
782 int rs = (insn >> 8) & 0xf;
783 int rm = insn & 0xf;
784 long rsv = regs->uregs[rs];
785 long rmv = regs->uregs[rm];
786
787 fnr.dr = insnslot_llret_4arg_rwflags(regs->uregs[rdhi],
788 regs->uregs[rdlo], rsv, rmv,
789 &regs->ARM_cpsr, i_fn);
790 regs->uregs[rdhi] = fnr.r0;
791 regs->uregs[rdlo] = fnr.r1;
792}
793
794static void __kprobes
795emulate_alu_imm_rflags(struct kprobe *p, struct pt_regs *regs)
796{
797 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
798 kprobe_opcode_t insn = p->opcode;
799 int rd = (insn >> 12) & 0xf;
800 int rn = (insn >> 16) & 0xf;
801 long rnv = (rn == 15) ? (long)p->addr + 8 : regs->uregs[rn];
802
803 regs->uregs[rd] = insnslot_1arg_rflags(rnv, regs->ARM_cpsr, i_fn);
804}
805
806static void __kprobes
807emulate_alu_imm_rwflags(struct kprobe *p, struct pt_regs *regs)
808{
809 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
810 kprobe_opcode_t insn = p->opcode;
811 int rd = (insn >> 12) & 0xf;
812 int rn = (insn >> 16) & 0xf;
813 long rnv = (rn == 15) ? (long)p->addr + 8 : regs->uregs[rn];
814
815 regs->uregs[rd] = insnslot_1arg_rwflags(rnv, &regs->ARM_cpsr, i_fn);
816}
817
818static void __kprobes
819emulate_alu_rflags(struct kprobe *p, struct pt_regs *regs)
820{
821 insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
822 kprobe_opcode_t insn = p->opcode;
823 long ppc = (long)p->addr + 8;
824 int rd = (insn >> 12) & 0xf;
825 int rn = (insn >> 16) & 0xf; /* rn/rnv/rs/rsv may be */
826 int rs = (insn >> 8) & 0xf; /* invalid, don't care. */
827 int rm = insn & 0xf;
828 long rnv = (rn == 15) ? ppc : regs->uregs[rn];
829 long rmv = (rm == 15) ? ppc : regs->uregs[rm];
830 long rsv = regs->uregs[rs];
831
832 regs->uregs[rd] =
833 insnslot_3arg_rflags(rnv, rmv, rsv, regs->ARM_cpsr, i_fn);
834}
835
836static void __kprobes
837emulate_alu_rwflags(struct kprobe *p, struct pt_regs *regs)
838{
839 insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
840 kprobe_opcode_t insn = p->opcode;
841 long ppc = (long)p->addr + 8;
842 int rd = (insn >> 12) & 0xf;
843 int rn = (insn >> 16) & 0xf; /* rn/rnv/rs/rsv may be */
844 int rs = (insn >> 8) & 0xf; /* invalid, don't care. */
845 int rm = insn & 0xf;
846 long rnv = (rn == 15) ? ppc : regs->uregs[rn];
847 long rmv = (rm == 15) ? ppc : regs->uregs[rm];
848 long rsv = regs->uregs[rs];
849
850 regs->uregs[rd] =
851 insnslot_3arg_rwflags(rnv, rmv, rsv, &regs->ARM_cpsr, i_fn);
852}
853
854static enum kprobe_insn __kprobes
855prep_emulate_ldr_str(kprobe_opcode_t insn, struct arch_specific_insn *asi)
856{
857 int ibit = (insn & (1 << 26)) ? 25 : 22;
858
859 insn &= 0xfff00fff;
860 insn |= 0x00001000; /* Rn = r0, Rd = r1 */
861 if (insn & (1 << ibit)) {
862 insn &= ~0xf;
863 insn |= 2; /* Rm = r2 */
864 }
865 asi->insn[0] = insn;
866 asi->insn_handler = (insn & (1 << 20)) ? emulate_ldr : emulate_str;
867 return INSN_GOOD;
868}
869
870static enum kprobe_insn __kprobes
871prep_emulate_rd12rm0(kprobe_opcode_t insn, struct arch_specific_insn *asi)
872{
873 insn &= 0xffff0ff0; /* Rd = r0, Rm = r0 */
874 asi->insn[0] = insn;
875 asi->insn_handler = emulate_rd12rm0;
876 return INSN_GOOD;
877}
878
879static enum kprobe_insn __kprobes
880prep_emulate_rd12(kprobe_opcode_t insn, struct arch_specific_insn *asi)
881{
882 insn &= 0xffff0fff; /* Rd = r0 */
883 asi->insn[0] = insn;
884 asi->insn_handler = emulate_rd12;
885 return INSN_GOOD;
886}
887
888static enum kprobe_insn __kprobes
889prep_emulate_rd12rn16rm0_wflags(kprobe_opcode_t insn,
890 struct arch_specific_insn *asi)
891{
892 insn &= 0xfff00ff0; /* Rd = r0, Rn = r0 */
893 insn |= 0x00000001; /* Rm = r1 */
894 asi->insn[0] = insn;
895 asi->insn_handler = emulate_rd12rn16rm0_rwflags;
896 return INSN_GOOD;
897}
898
899static enum kprobe_insn __kprobes
900prep_emulate_rd16rs8rm0_wflags(kprobe_opcode_t insn,
901 struct arch_specific_insn *asi)
902{
903 insn &= 0xfff0f0f0; /* Rd = r0, Rs = r0 */
904 insn |= 0x00000001; /* Rm = r1 */
905 asi->insn[0] = insn;
906 asi->insn_handler = emulate_rd16rs8rm0_rwflags;
907 return INSN_GOOD;
908}
909
910static enum kprobe_insn __kprobes
911prep_emulate_rd16rn12rs8rm0_wflags(kprobe_opcode_t insn,
912 struct arch_specific_insn *asi)
913{
914 insn &= 0xfff000f0; /* Rd = r0, Rn = r0 */
915 insn |= 0x00000102; /* Rs = r1, Rm = r2 */
916 asi->insn[0] = insn;
917 asi->insn_handler = emulate_rd16rn12rs8rm0_rwflags;
918 return INSN_GOOD;
919}
920
921static enum kprobe_insn __kprobes
922prep_emulate_rdhi16rdlo12rs8rm0_wflags(kprobe_opcode_t insn,
923 struct arch_specific_insn *asi)
924{
925 insn &= 0xfff000f0; /* RdHi = r0, RdLo = r1 */
926 insn |= 0x00001203; /* Rs = r2, Rm = r3 */
927 asi->insn[0] = insn;
928 asi->insn_handler = emulate_rdhi16rdlo12rs8rm0_rwflags;
929 return INSN_GOOD;
930}
931
932/*
933 * For the instruction masking and comparisons in all the "space_*"
934 * functions below, Do _not_ rearrange the order of tests unless
935 * you're very, very sure of what you are doing. For the sake of
936 * efficiency, the masks for some tests sometimes assume other test
937 * have been done prior to them so the number of patterns to test
938 * for an instruction set can be as broad as possible to reduce the
939 * number of tests needed.
940 */
941
942static enum kprobe_insn __kprobes
943space_1111(kprobe_opcode_t insn, struct arch_specific_insn *asi)
944{
945 /* CPS mmod == 1 : 1111 0001 0000 xx10 xxxx xxxx xx0x xxxx */
946 /* RFE : 1111 100x x0x1 xxxx xxxx 1010 xxxx xxxx */
947 /* SRS : 1111 100x x1x0 1101 xxxx 0101 xxxx xxxx */
948 if ((insn & 0xfff30020) == 0xf1020000 ||
949 (insn & 0xfe500f00) == 0xf8100a00 ||
950 (insn & 0xfe5f0f00) == 0xf84d0500)
951 return INSN_REJECTED;
952
953 /* PLD : 1111 01x1 x101 xxxx xxxx xxxx xxxx xxxx : */
954 if ((insn & 0xfd700000) == 0xf4500000) {
955 insn &= 0xfff0ffff; /* Rn = r0 */
956 asi->insn[0] = insn;
957 asi->insn_handler = emulate_rn16;
958 return INSN_GOOD;
959 }
960
961 /* BLX(1) : 1111 101x xxxx xxxx xxxx xxxx xxxx xxxx : */
962 if ((insn & 0xfe000000) == 0xfa000000) {
963 asi->insn_handler = simulate_blx1;
964 return INSN_GOOD_NO_SLOT;
965 }
966
967 /* SETEND : 1111 0001 0000 0001 xxxx xxxx 0000 xxxx */
968 /* CDP2 : 1111 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
969 if ((insn & 0xffff00f0) == 0xf1010000 ||
970 (insn & 0xff000010) == 0xfe000000) {
971 asi->insn[0] = insn;
972 asi->insn_handler = emulate_none;
973 return INSN_GOOD;
974 }
975
976 /* MCRR2 : 1111 1100 0100 xxxx xxxx xxxx xxxx xxxx : (Rd != Rn) */
977 /* MRRC2 : 1111 1100 0101 xxxx xxxx xxxx xxxx xxxx : (Rd != Rn) */
978 if ((insn & 0xffe00000) == 0xfc400000) {
979 insn &= 0xfff00fff; /* Rn = r0 */
980 insn |= 0x00001000; /* Rd = r1 */
981 asi->insn[0] = insn;
982 asi->insn_handler =
983 (insn & (1 << 20)) ? emulate_mrrc : emulate_mcrr;
984 return INSN_GOOD;
985 }
986
987 /* LDC2 : 1111 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
988 /* STC2 : 1111 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
989 if ((insn & 0xfe000000) == 0xfc000000) {
990 insn &= 0xfff0ffff; /* Rn = r0 */
991 asi->insn[0] = insn;
992 asi->insn_handler = emulate_ldcstc;
993 return INSN_GOOD;
994 }
995
996 /* MCR2 : 1111 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
997 /* MRC2 : 1111 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
998 insn &= 0xffff0fff; /* Rd = r0 */
999 asi->insn[0] = insn;
1000 asi->insn_handler = (insn & (1 << 20)) ? emulate_rd12 : emulate_ird12;
1001 return INSN_GOOD;
1002}
1003
1004static enum kprobe_insn __kprobes
1005space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1006{
1007 /* cccc 0001 0xx0 xxxx xxxx xxxx xxxx xxx0 xxxx */
1008 if ((insn & 0x0f900010) == 0x01000000) {
1009
1010 /* BXJ : cccc 0001 0010 xxxx xxxx xxxx 0010 xxxx */
1011 /* MSR : cccc 0001 0x10 xxxx xxxx xxxx 0000 xxxx */
1012 if ((insn & 0x0ff000f0) == 0x01200020 ||
1013 (insn & 0x0fb000f0) == 0x01200000)
1014 return INSN_REJECTED;
1015
1016 /* MRS : cccc 0001 0x00 xxxx xxxx xxxx 0000 xxxx */
1017 if ((insn & 0x0fb00010) == 0x01000000)
1018 return prep_emulate_rd12(insn, asi);
1019
1020 /* SMLALxy : cccc 0001 0100 xxxx xxxx xxxx 1xx0 xxxx */
1021 if ((insn & 0x0ff00090) == 0x01400080)
1022 return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi);
1023
1024 /* SMULWy : cccc 0001 0010 xxxx xxxx xxxx 1x10 xxxx */
1025 /* SMULxy : cccc 0001 0110 xxxx xxxx xxxx 1xx0 xxxx */
1026 if ((insn & 0x0ff000b0) == 0x012000a0 ||
1027 (insn & 0x0ff00090) == 0x01600080)
1028 return prep_emulate_rd16rs8rm0_wflags(insn, asi);
1029
1030 /* SMLAxy : cccc 0001 0000 xxxx xxxx xxxx 1xx0 xxxx : Q */
1031 /* SMLAWy : cccc 0001 0010 xxxx xxxx xxxx 0x00 xxxx : Q */
1032 return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
1033
1034 }
1035
1036 /* cccc 0001 0xx0 xxxx xxxx xxxx xxxx 0xx1 xxxx */
1037 else if ((insn & 0x0f900090) == 0x01000010) {
1038
1039 /* BKPT : 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */
1040 if ((insn & 0xfff000f0) == 0xe1200070)
1041 return INSN_REJECTED;
1042
1043 /* BLX(2) : cccc 0001 0010 xxxx xxxx xxxx 0011 xxxx */
1044 /* BX : cccc 0001 0010 xxxx xxxx xxxx 0001 xxxx */
1045 if ((insn & 0x0ff000d0) == 0x01200010) {
1046 asi->insn[0] = truecc_insn(insn);
1047 asi->insn_handler = simulate_blx2bx;
1048 return INSN_GOOD;
1049 }
1050
1051 /* CLZ : cccc 0001 0110 xxxx xxxx xxxx 0001 xxxx */
1052 if ((insn & 0x0ff000f0) == 0x01600010)
1053 return prep_emulate_rd12rm0(insn, asi);
1054
1055 /* QADD : cccc 0001 0000 xxxx xxxx xxxx 0101 xxxx :Q */
1056 /* QSUB : cccc 0001 0010 xxxx xxxx xxxx 0101 xxxx :Q */
1057 /* QDADD : cccc 0001 0100 xxxx xxxx xxxx 0101 xxxx :Q */
1058 /* QDSUB : cccc 0001 0110 xxxx xxxx xxxx 0101 xxxx :Q */
1059 return prep_emulate_rd12rn16rm0_wflags(insn, asi);
1060 }
1061
1062 /* cccc 0000 xxxx xxxx xxxx xxxx xxxx 1001 xxxx */
1063 else if ((insn & 0x0f000090) == 0x00000090) {
1064
1065 /* MUL : cccc 0000 0000 xxxx xxxx xxxx 1001 xxxx : */
1066 /* MULS : cccc 0000 0001 xxxx xxxx xxxx 1001 xxxx :cc */
1067 /* MLA : cccc 0000 0010 xxxx xxxx xxxx 1001 xxxx : */
1068 /* MLAS : cccc 0000 0011 xxxx xxxx xxxx 1001 xxxx :cc */
1069 /* UMAAL : cccc 0000 0100 xxxx xxxx xxxx 1001 xxxx : */
1070 /* UMULL : cccc 0000 1000 xxxx xxxx xxxx 1001 xxxx : */
1071 /* UMULLS : cccc 0000 1001 xxxx xxxx xxxx 1001 xxxx :cc */
1072 /* UMLAL : cccc 0000 1010 xxxx xxxx xxxx 1001 xxxx : */
1073 /* UMLALS : cccc 0000 1011 xxxx xxxx xxxx 1001 xxxx :cc */
1074 /* SMULL : cccc 0000 1100 xxxx xxxx xxxx 1001 xxxx : */
1075 /* SMULLS : cccc 0000 1101 xxxx xxxx xxxx 1001 xxxx :cc */
1076 /* SMLAL : cccc 0000 1110 xxxx xxxx xxxx 1001 xxxx : */
1077 /* SMLALS : cccc 0000 1111 xxxx xxxx xxxx 1001 xxxx :cc */
1078 if ((insn & 0x0fe000f0) == 0x00000090) {
1079 return prep_emulate_rd16rs8rm0_wflags(insn, asi);
1080 } else if ((insn & 0x0fe000f0) == 0x00200090) {
1081 return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
1082 } else {
1083 return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi);
1084 }
1085 }
1086
1087 /* cccc 000x xxxx xxxx xxxx xxxx xxxx 1xx1 xxxx */
1088 else if ((insn & 0x0e000090) == 0x00000090) {
1089
1090 /* SWP : cccc 0001 0000 xxxx xxxx xxxx 1001 xxxx */
1091 /* SWPB : cccc 0001 0100 xxxx xxxx xxxx 1001 xxxx */
1092 /* LDRD : cccc 000x xxx0 xxxx xxxx xxxx 1101 xxxx */
1093 /* STRD : cccc 000x xxx0 xxxx xxxx xxxx 1111 xxxx */
1094 /* STREX : cccc 0001 1000 xxxx xxxx xxxx 1001 xxxx */
1095 /* LDREX : cccc 0001 1001 xxxx xxxx xxxx 1001 xxxx */
1096 /* LDRH : cccc 000x xxx1 xxxx xxxx xxxx 1011 xxxx */
1097 /* STRH : cccc 000x xxx0 xxxx xxxx xxxx 1011 xxxx */
1098 /* LDRSB : cccc 000x xxx1 xxxx xxxx xxxx 1101 xxxx */
1099 /* LDRSH : cccc 000x xxx1 xxxx xxxx xxxx 1111 xxxx */
1100 if ((insn & 0x0fb000f0) == 0x01000090) {
1101 /* SWP/SWPB */
1102 return prep_emulate_rd12rn16rm0_wflags(insn, asi);
1103 } else if ((insn & 0x0e1000d0) == 0x00000d0) {
1104 /* STRD/LDRD */
1105 insn &= 0xfff00fff;
1106 insn |= 0x00002000; /* Rn = r0, Rd = r2 */
1107 if (insn & (1 << 22)) {
1108 /* I bit */
1109 insn &= ~0xf;
1110 insn |= 1; /* Rm = r1 */
1111 }
1112 asi->insn[0] = insn;
1113 asi->insn_handler =
1114 (insn & (1 << 5)) ? emulate_strd : emulate_ldrd;
1115 return INSN_GOOD;
1116 }
1117
1118 return prep_emulate_ldr_str(insn, asi);
1119 }
1120
1121 /* cccc 000x xxxx xxxx xxxx xxxx xxxx xxxx xxxx */
1122
1123 /*
1124 * ALU op with S bit and Rd == 15 :
1125 * cccc 000x xxx1 xxxx 1111 xxxx xxxx xxxx
1126 */
1127 if ((insn & 0x0e10f000) == 0x0010f000)
1128 return INSN_REJECTED;
1129
1130 /*
1131 * "mov ip, sp" is the most common kprobe'd instruction by far.
1132 * Check and optimize for it explicitly.
1133 */
1134 if (insn == 0xe1a0c00d) {
1135 asi->insn_handler = simulate_mov_ipsp;
1136 return INSN_GOOD_NO_SLOT;
1137 }
1138
1139 /*
1140 * Data processing: Immediate-shift / Register-shift
1141 * ALU op : cccc 000x xxxx xxxx xxxx xxxx xxxx xxxx
1142 * CPY : cccc 0001 1010 xxxx xxxx 0000 0000 xxxx
1143 * MOV : cccc 0001 101x xxxx xxxx xxxx xxxx xxxx
1144 * *S (bit 20) updates condition codes
1145 * ADC/SBC/RSC reads the C flag
1146 */
1147 insn &= 0xfff00ff0; /* Rn = r0, Rd = r0 */
1148 insn |= 0x00000001; /* Rm = r1 */
1149 if (insn & 0x010) {
1150 insn &= 0xfffff0ff; /* register shift */
1151 insn |= 0x00000200; /* Rs = r2 */
1152 }
1153 asi->insn[0] = insn;
1154 asi->insn_handler = (insn & (1 << 20)) ? /* S-bit */
1155 emulate_alu_rwflags : emulate_alu_rflags;
1156 return INSN_GOOD;
1157}
1158
1159static enum kprobe_insn __kprobes
1160space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1161{
1162 /*
1163 * MSR : cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx
1164 * Undef : cccc 0011 0x00 xxxx xxxx xxxx xxxx xxxx
1165 * ALU op with S bit and Rd == 15 :
1166 * cccc 001x xxx1 xxxx 1111 xxxx xxxx xxxx
1167 */
1168 if ((insn & 0x0f900000) == 0x03200000 || /* MSR & Undef */
1169 (insn & 0x0e10f000) == 0x0210f000) /* ALU s-bit, R15 */
1170 return INSN_REJECTED;
1171
1172 /*
1173 * Data processing: 32-bit Immediate
1174 * ALU op : cccc 001x xxxx xxxx xxxx xxxx xxxx xxxx
1175 * MOV : cccc 0011 101x xxxx xxxx xxxx xxxx xxxx
1176 * *S (bit 20) updates condition codes
1177 * ADC/SBC/RSC reads the C flag
1178 */
1179 insn &= 0xfff00ff0; /* Rn = r0, Rd = r0 */
1180 asi->insn[0] = insn;
1181 asi->insn_handler = (insn & (1 << 20)) ? /* S-bit */
1182 emulate_alu_imm_rwflags : emulate_alu_imm_rflags;
1183 return INSN_GOOD;
1184}
1185
1186static enum kprobe_insn __kprobes
1187space_cccc_0110__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1188{
1189 /* SEL : cccc 0110 1000 xxxx xxxx xxxx 1011 xxxx GE: !!! */
1190 if ((insn & 0x0ff000f0) == 0x068000b0) {
1191 insn &= 0xfff00ff0; /* Rd = r0, Rn = r0 */
1192 insn |= 0x00000001; /* Rm = r1 */
1193 asi->insn[0] = insn;
1194 asi->insn_handler = emulate_sel;
1195 return INSN_GOOD;
1196 }
1197
1198 /* SSAT : cccc 0110 101x xxxx xxxx xxxx xx01 xxxx :Q */
1199 /* USAT : cccc 0110 111x xxxx xxxx xxxx xx01 xxxx :Q */
1200 /* SSAT16 : cccc 0110 1010 xxxx xxxx xxxx 0011 xxxx :Q */
1201 /* USAT16 : cccc 0110 1110 xxxx xxxx xxxx 0011 xxxx :Q */
1202 if ((insn & 0x0fa00030) == 0x06a00010 ||
1203 (insn & 0x0fb000f0) == 0x06a00030) {
1204 insn &= 0xffff0ff0; /* Rd = r0, Rm = r0 */
1205 asi->insn[0] = insn;
1206 asi->insn_handler = emulate_sat;
1207 return INSN_GOOD;
1208 }
1209
1210 /* REV : cccc 0110 1011 xxxx xxxx xxxx 0011 xxxx */
1211 /* REV16 : cccc 0110 1011 xxxx xxxx xxxx 1011 xxxx */
1212 /* REVSH : cccc 0110 1111 xxxx xxxx xxxx 1011 xxxx */
1213 if ((insn & 0x0ff00070) == 0x06b00030 ||
1214 (insn & 0x0ff000f0) == 0x06f000b0)
1215 return prep_emulate_rd12rm0(insn, asi);
1216
1217 /* SADD16 : cccc 0110 0001 xxxx xxxx xxxx 0001 xxxx :GE */
1218 /* SADDSUBX : cccc 0110 0001 xxxx xxxx xxxx 0011 xxxx :GE */
1219 /* SSUBADDX : cccc 0110 0001 xxxx xxxx xxxx 0101 xxxx :GE */
1220 /* SSUB16 : cccc 0110 0001 xxxx xxxx xxxx 0111 xxxx :GE */
1221 /* SADD8 : cccc 0110 0001 xxxx xxxx xxxx 1001 xxxx :GE */
1222 /* SSUB8 : cccc 0110 0001 xxxx xxxx xxxx 1111 xxxx :GE */
1223 /* QADD16 : cccc 0110 0010 xxxx xxxx xxxx 0001 xxxx : */
1224 /* QADDSUBX : cccc 0110 0010 xxxx xxxx xxxx 0011 xxxx : */
1225 /* QSUBADDX : cccc 0110 0010 xxxx xxxx xxxx 0101 xxxx : */
1226 /* QSUB16 : cccc 0110 0010 xxxx xxxx xxxx 0111 xxxx : */
1227 /* QADD8 : cccc 0110 0010 xxxx xxxx xxxx 1001 xxxx : */
1228 /* QSUB8 : cccc 0110 0010 xxxx xxxx xxxx 1111 xxxx : */
1229 /* SHADD16 : cccc 0110 0011 xxxx xxxx xxxx 0001 xxxx : */
1230 /* SHADDSUBX : cccc 0110 0011 xxxx xxxx xxxx 0011 xxxx : */
1231 /* SHSUBADDX : cccc 0110 0011 xxxx xxxx xxxx 0101 xxxx : */
1232 /* SHSUB16 : cccc 0110 0011 xxxx xxxx xxxx 0111 xxxx : */
1233 /* SHADD8 : cccc 0110 0011 xxxx xxxx xxxx 1001 xxxx : */
1234 /* SHSUB8 : cccc 0110 0011 xxxx xxxx xxxx 1111 xxxx : */
1235 /* UADD16 : cccc 0110 0101 xxxx xxxx xxxx 0001 xxxx :GE */
1236 /* UADDSUBX : cccc 0110 0101 xxxx xxxx xxxx 0011 xxxx :GE */
1237 /* USUBADDX : cccc 0110 0101 xxxx xxxx xxxx 0101 xxxx :GE */
1238 /* USUB16 : cccc 0110 0101 xxxx xxxx xxxx 0111 xxxx :GE */
1239 /* UADD8 : cccc 0110 0101 xxxx xxxx xxxx 1001 xxxx :GE */
1240 /* USUB8 : cccc 0110 0101 xxxx xxxx xxxx 1111 xxxx :GE */
1241 /* UQADD16 : cccc 0110 0110 xxxx xxxx xxxx 0001 xxxx : */
1242 /* UQADDSUBX : cccc 0110 0110 xxxx xxxx xxxx 0011 xxxx : */
1243 /* UQSUBADDX : cccc 0110 0110 xxxx xxxx xxxx 0101 xxxx : */
1244 /* UQSUB16 : cccc 0110 0110 xxxx xxxx xxxx 0111 xxxx : */
1245 /* UQADD8 : cccc 0110 0110 xxxx xxxx xxxx 1001 xxxx : */
1246 /* UQSUB8 : cccc 0110 0110 xxxx xxxx xxxx 1111 xxxx : */
1247 /* UHADD16 : cccc 0110 0111 xxxx xxxx xxxx 0001 xxxx : */
1248 /* UHADDSUBX : cccc 0110 0111 xxxx xxxx xxxx 0011 xxxx : */
1249 /* UHSUBADDX : cccc 0110 0111 xxxx xxxx xxxx 0101 xxxx : */
1250 /* UHSUB16 : cccc 0110 0111 xxxx xxxx xxxx 0111 xxxx : */
1251 /* UHADD8 : cccc 0110 0111 xxxx xxxx xxxx 1001 xxxx : */
1252 /* UHSUB8 : cccc 0110 0111 xxxx xxxx xxxx 1111 xxxx : */
1253 /* PKHBT : cccc 0110 1000 xxxx xxxx xxxx x001 xxxx : */
1254 /* PKHTB : cccc 0110 1000 xxxx xxxx xxxx x101 xxxx : */
1255 /* SXTAB16 : cccc 0110 1000 xxxx xxxx xxxx 0111 xxxx : */
1256 /* SXTB : cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx : */
1257 /* SXTAB : cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx : */
1258 /* SXTAH : cccc 0110 1011 xxxx xxxx xxxx 0111 xxxx : */
1259 /* UXTAB16 : cccc 0110 1100 xxxx xxxx xxxx 0111 xxxx : */
1260 /* UXTAB : cccc 0110 1110 xxxx xxxx xxxx 0111 xxxx : */
1261 /* UXTAH : cccc 0110 1111 xxxx xxxx xxxx 0111 xxxx : */
1262 return prep_emulate_rd12rn16rm0_wflags(insn, asi);
1263}
1264
1265static enum kprobe_insn __kprobes
1266space_cccc_0111__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1267{
1268 /* Undef : cccc 0111 1111 xxxx xxxx xxxx 1111 xxxx */
1269 if ((insn & 0x0ff000f0) == 0x03f000f0)
1270 return INSN_REJECTED;
1271
1272 /* USADA8 : cccc 0111 1000 xxxx xxxx xxxx 0001 xxxx */
1273 /* USAD8 : cccc 0111 1000 xxxx 1111 xxxx 0001 xxxx */
1274 if ((insn & 0x0ff000f0) == 0x07800010)
1275 return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
1276
1277 /* SMLALD : cccc 0111 0100 xxxx xxxx xxxx 00x1 xxxx */
1278 /* SMLSLD : cccc 0111 0100 xxxx xxxx xxxx 01x1 xxxx */
1279 if ((insn & 0x0ff00090) == 0x07400010)
1280 return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi);
1281
1282 /* SMLAD : cccc 0111 0000 xxxx xxxx xxxx 00x1 xxxx :Q */
1283 /* SMLSD : cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx :Q */
1284 /* SMMLA : cccc 0111 0101 xxxx xxxx xxxx 00x1 xxxx : */
1285 /* SMMLS : cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx : */
1286 if ((insn & 0x0ff00090) == 0x07000010 ||
1287 (insn & 0x0ff000d0) == 0x07500010 ||
1288 (insn & 0x0ff000d0) == 0x075000d0)
1289 return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
1290
1291 /* SMUSD : cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx : */
1292 /* SMUAD : cccc 0111 0000 xxxx 1111 xxxx 00x1 xxxx :Q */
1293 /* SMMUL : cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx : */
1294 return prep_emulate_rd16rs8rm0_wflags(insn, asi);
1295}
1296
1297static enum kprobe_insn __kprobes
1298space_cccc_01xx(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1299{
1300 /* LDR : cccc 01xx x0x1 xxxx xxxx xxxx xxxx xxxx */
1301 /* LDRB : cccc 01xx x1x1 xxxx xxxx xxxx xxxx xxxx */
1302 /* LDRBT : cccc 01x0 x111 xxxx xxxx xxxx xxxx xxxx */
1303 /* LDRT : cccc 01x0 x011 xxxx xxxx xxxx xxxx xxxx */
1304 /* STR : cccc 01xx x0x0 xxxx xxxx xxxx xxxx xxxx */
1305 /* STRB : cccc 01xx x1x0 xxxx xxxx xxxx xxxx xxxx */
1306 /* STRBT : cccc 01x0 x110 xxxx xxxx xxxx xxxx xxxx */
1307 /* STRT : cccc 01x0 x010 xxxx xxxx xxxx xxxx xxxx */
1308 return prep_emulate_ldr_str(insn, asi);
1309}
1310
1311static enum kprobe_insn __kprobes
1312space_cccc_100x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1313{
1314 /* LDM(2) : cccc 100x x101 xxxx 0xxx xxxx xxxx xxxx */
1315 /* LDM(3) : cccc 100x x1x1 xxxx 1xxx xxxx xxxx xxxx */
1316 if ((insn & 0x0e708000) == 0x85000000 ||
1317 (insn & 0x0e508000) == 0x85010000)
1318 return INSN_REJECTED;
1319
1320 /* LDM(1) : cccc 100x x0x1 xxxx xxxx xxxx xxxx xxxx */
1321 /* STM(1) : cccc 100x x0x0 xxxx xxxx xxxx xxxx xxxx */
1322 asi->insn[0] = truecc_insn(insn);
1323 asi->insn_handler = ((insn & 0x108000) == 0x008000) ? /* STM & R15 */
1324 simulate_stm1_pc : simulate_ldm1stm1;
1325 return INSN_GOOD;
1326}
1327
1328static enum kprobe_insn __kprobes
1329space_cccc_101x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1330{
1331 /* B : cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */
1332 /* BL : cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */
1333 asi->insn[0] = truecc_insn(insn);
1334 asi->insn_handler = simulate_bbl;
1335 return INSN_GOOD;
1336}
1337
1338static enum kprobe_insn __kprobes
1339space_cccc_1100_010x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1340{
1341 /* MCRR : cccc 1100 0100 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */
1342 /* MRRC : cccc 1100 0101 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */
1343 insn &= 0xfff00fff;
1344 insn |= 0x00001000; /* Rn = r0, Rd = r1 */
1345 asi->insn[0] = insn;
1346 asi->insn_handler = (insn & (1 << 20)) ? emulate_mrrc : emulate_mcrr;
1347 return INSN_GOOD;
1348}
1349
1350static enum kprobe_insn __kprobes
1351space_cccc_110x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1352{
1353 /* LDC : cccc 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
1354 /* STC : cccc 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
1355 insn &= 0xfff0ffff; /* Rn = r0 */
1356 asi->insn[0] = insn;
1357 asi->insn_handler = emulate_ldcstc;
1358 return INSN_GOOD;
1359}
1360
1361static enum kprobe_insn __kprobes
1362space_cccc_111x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1363{
1364 /* BKPT : 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */
1365 /* SWI : cccc 1111 xxxx xxxx xxxx xxxx xxxx xxxx */
1366 if ((insn & 0xfff000f0) == 0xe1200070 ||
1367 (insn & 0x0f000000) == 0x0f000000)
1368 return INSN_REJECTED;
1369
1370 /* CDP : cccc 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
1371 if ((insn & 0x0f000010) == 0x0e000000) {
1372 asi->insn[0] = insn;
1373 asi->insn_handler = emulate_none;
1374 return INSN_GOOD;
1375 }
1376
1377 /* MCR : cccc 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
1378 /* MRC : cccc 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
1379 insn &= 0xffff0fff; /* Rd = r0 */
1380 asi->insn[0] = insn;
1381 asi->insn_handler = (insn & (1 << 20)) ? emulate_rd12 : emulate_ird12;
1382 return INSN_GOOD;
1383}
1384
1385/* Return:
1386 * INSN_REJECTED If instruction is one not allowed to kprobe,
1387 * INSN_GOOD If instruction is supported and uses instruction slot,
1388 * INSN_GOOD_NO_SLOT If instruction is supported but doesn't use its slot.
1389 *
1390 * For instructions we don't want to kprobe (INSN_REJECTED return result):
1391 * These are generally ones that modify the processor state making
1392 * them "hard" to simulate such as switches processor modes or
1393 * make accesses in alternate modes. Any of these could be simulated
1394 * if the work was put into it, but low return considering they
1395 * should also be very rare.
1396 */
1397enum kprobe_insn __kprobes
1398arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1399{
1400 asi->insn[1] = KPROBE_RETURN_INSTRUCTION;
1401
1402 if ((insn & 0xf0000000) == 0xf0000000) {
1403
1404 return space_1111(insn, asi);
1405
1406 } else if ((insn & 0x0e000000) == 0x00000000) {
1407
1408 return space_cccc_000x(insn, asi);
1409
1410 } else if ((insn & 0x0e000000) == 0x02000000) {
1411
1412 return space_cccc_001x(insn, asi);
1413
1414 } else if ((insn & 0x0f000010) == 0x06000010) {
1415
1416 return space_cccc_0110__1(insn, asi);
1417
1418 } else if ((insn & 0x0f000010) == 0x07000010) {
1419
1420 return space_cccc_0111__1(insn, asi);
1421
1422 } else if ((insn & 0x0c000000) == 0x04000000) {
1423
1424 return space_cccc_01xx(insn, asi);
1425
1426 } else if ((insn & 0x0e000000) == 0x08000000) {
1427
1428 return space_cccc_100x(insn, asi);
1429
1430 } else if ((insn & 0x0e000000) == 0x0a000000) {
1431
1432 return space_cccc_101x(insn, asi);
1433
1434 } else if ((insn & 0x0fe00000) == 0x0c400000) {
1435
1436 return space_cccc_1100_010x(insn, asi);
1437
1438 } else if ((insn & 0x0e000000) == 0x0c400000) {
1439
1440 return space_cccc_110x(insn, asi);
1441
1442 }
1443
1444 return space_cccc_111x(insn, asi);
1445}
1446
1447void __init arm_kprobe_decode_init(void)
1448{
1449 find_str_pc_offset();
1450}
1451
1452
1453/*
1454 * All ARM instructions listed below.
1455 *
1456 * Instructions and their general purpose registers are given.
1457 * If a particular register may not use R15, it is prefixed with a "!".
1458 * If marked with a "*" means the value returned by reading R15
1459 * is implementation defined.
1460 *
1461 * ADC/ADD/AND/BIC/CMN/CMP/EOR/MOV/MVN/ORR/RSB/RSC/SBC/SUB/TEQ
1462 * TST: Rd, Rn, Rm, !Rs
1463 * BX: Rm
1464 * BLX(2): !Rm
1465 * BX: Rm (R15 legal, but discouraged)
1466 * BXJ: !Rm,
1467 * CLZ: !Rd, !Rm
1468 * CPY: Rd, Rm
1469 * LDC/2,STC/2 immediate offset & unindex: Rn
1470 * LDC/2,STC/2 immediate pre/post-indexed: !Rn
1471 * LDM(1/3): !Rn, register_list
1472 * LDM(2): !Rn, !register_list
1473 * LDR,STR,PLD immediate offset: Rd, Rn
1474 * LDR,STR,PLD register offset: Rd, Rn, !Rm
1475 * LDR,STR,PLD scaled register offset: Rd, !Rn, !Rm
1476 * LDR,STR immediate pre/post-indexed: Rd, !Rn
1477 * LDR,STR register pre/post-indexed: Rd, !Rn, !Rm
1478 * LDR,STR scaled register pre/post-indexed: Rd, !Rn, !Rm
1479 * LDRB,STRB immediate offset: !Rd, Rn
1480 * LDRB,STRB register offset: !Rd, Rn, !Rm
1481 * LDRB,STRB scaled register offset: !Rd, !Rn, !Rm
1482 * LDRB,STRB immediate pre/post-indexed: !Rd, !Rn
1483 * LDRB,STRB register pre/post-indexed: !Rd, !Rn, !Rm
1484 * LDRB,STRB scaled register pre/post-indexed: !Rd, !Rn, !Rm
1485 * LDRT,LDRBT,STRBT immediate pre/post-indexed: !Rd, !Rn
1486 * LDRT,LDRBT,STRBT register pre/post-indexed: !Rd, !Rn, !Rm
1487 * LDRT,LDRBT,STRBT scaled register pre/post-indexed: !Rd, !Rn, !Rm
1488 * LDRH/SH/SB/D,STRH/SH/SB/D immediate offset: !Rd, Rn
1489 * LDRH/SH/SB/D,STRH/SH/SB/D register offset: !Rd, Rn, !Rm
1490 * LDRH/SH/SB/D,STRH/SH/SB/D immediate pre/post-indexed: !Rd, !Rn
1491 * LDRH/SH/SB/D,STRH/SH/SB/D register pre/post-indexed: !Rd, !Rn, !Rm
1492 * LDREX: !Rd, !Rn
1493 * MCR/2: !Rd
1494 * MCRR/2,MRRC/2: !Rd, !Rn
1495 * MLA: !Rd, !Rn, !Rm, !Rs
1496 * MOV: Rd
1497 * MRC/2: !Rd (if Rd==15, only changes cond codes, not the register)
1498 * MRS,MSR: !Rd
1499 * MUL: !Rd, !Rm, !Rs
1500 * PKH{BT,TB}: !Rd, !Rn, !Rm
1501 * QDADD,[U]QADD/16/8/SUBX: !Rd, !Rm, !Rn
1502 * QDSUB,[U]QSUB/16/8/ADDX: !Rd, !Rm, !Rn
1503 * REV/16/SH: !Rd, !Rm
1504 * RFE: !Rn
1505 * {S,U}[H]ADD{16,8,SUBX},{S,U}[H]SUB{16,8,ADDX}: !Rd, !Rn, !Rm
1506 * SEL: !Rd, !Rn, !Rm
1507 * SMLA<x><y>,SMLA{D,W<y>},SMLSD,SMML{A,S}: !Rd, !Rn, !Rm, !Rs
1508 * SMLAL<x><y>,SMLA{D,LD},SMLSLD,SMMULL,SMULW<y>: !RdHi, !RdLo, !Rm, !Rs
1509 * SMMUL,SMUAD,SMUL<x><y>,SMUSD: !Rd, !Rm, !Rs
1510 * SSAT/16: !Rd, !Rm
1511 * STM(1/2): !Rn, register_list* (R15 in reg list not recommended)
1512 * STRT immediate pre/post-indexed: Rd*, !Rn
1513 * STRT register pre/post-indexed: Rd*, !Rn, !Rm
1514 * STRT scaled register pre/post-indexed: Rd*, !Rn, !Rm
1515 * STREX: !Rd, !Rn, !Rm
1516 * SWP/B: !Rd, !Rn, !Rm
1517 * {S,U}XTA{B,B16,H}: !Rd, !Rn, !Rm
1518 * {S,U}XT{B,B16,H}: !Rd, !Rm
1519 * UM{AA,LA,UL}L: !RdHi, !RdLo, !Rm, !Rs
1520 * USA{D8,A8,T,T16}: !Rd, !Rm, !Rs
1521 *
1522 * May transfer control by writing R15 (possible mode changes or alternate
1523 * mode accesses marked by "*"):
1524 * ALU op (* with s-bit), B, BL, BKPT, BLX(1/2), BX, BXJ, CPS*, CPY,
1525 * LDM(1), LDM(2/3)*, LDR, MOV, RFE*, SWI*
1526 *
1527 * Instructions that do not take general registers, nor transfer control:
1528 * CDP/2, SETEND, SRS*
1529 */
diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c
new file mode 100644
index 000000000000..a22a98c43ca5
--- /dev/null
+++ b/arch/arm/kernel/kprobes.c
@@ -0,0 +1,447 @@
1/*
2 * arch/arm/kernel/kprobes.c
3 *
4 * Kprobes on ARM
5 *
6 * Abhishek Sagar <sagar.abhishek@gmail.com>
7 * Copyright (C) 2006, 2007 Motorola Inc.
8 *
9 * Nicolas Pitre <nico@marvell.com>
10 * Copyright (C) 2007 Marvell Ltd.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 */
21
22#include <linux/kernel.h>
23#include <linux/kprobes.h>
24#include <linux/module.h>
25#include <linux/stringify.h>
26#include <asm/traps.h>
27#include <asm/cacheflush.h>
28
29#define MIN_STACK_SIZE(addr) \
30 min((unsigned long)MAX_STACK_SIZE, \
31 (unsigned long)current_thread_info() + THREAD_START_SP - (addr))
32
33#define flush_insns(addr, cnt) \
34 flush_icache_range((unsigned long)(addr), \
35 (unsigned long)(addr) + \
36 sizeof(kprobe_opcode_t) * (cnt))
37
38/* Used as a marker in ARM_pc to note when we're in a jprobe. */
39#define JPROBE_MAGIC_ADDR 0xffffffff
40
41DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
42DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
43
44
45int __kprobes arch_prepare_kprobe(struct kprobe *p)
46{
47 kprobe_opcode_t insn;
48 kprobe_opcode_t tmp_insn[MAX_INSN_SIZE];
49 unsigned long addr = (unsigned long)p->addr;
50 int is;
51
52 if (addr & 0x3 || in_exception_text(addr))
53 return -EINVAL;
54
55 insn = *p->addr;
56 p->opcode = insn;
57 p->ainsn.insn = tmp_insn;
58
59 switch (arm_kprobe_decode_insn(insn, &p->ainsn)) {
60 case INSN_REJECTED: /* not supported */
61 return -EINVAL;
62
63 case INSN_GOOD: /* instruction uses slot */
64 p->ainsn.insn = get_insn_slot();
65 if (!p->ainsn.insn)
66 return -ENOMEM;
67 for (is = 0; is < MAX_INSN_SIZE; ++is)
68 p->ainsn.insn[is] = tmp_insn[is];
69 flush_insns(&p->ainsn.insn, MAX_INSN_SIZE);
70 break;
71
72 case INSN_GOOD_NO_SLOT: /* instruction doesn't need insn slot */
73 p->ainsn.insn = NULL;
74 break;
75 }
76
77 return 0;
78}
79
80void __kprobes arch_arm_kprobe(struct kprobe *p)
81{
82 *p->addr = KPROBE_BREAKPOINT_INSTRUCTION;
83 flush_insns(p->addr, 1);
84}
85
86void __kprobes arch_disarm_kprobe(struct kprobe *p)
87{
88 *p->addr = p->opcode;
89 flush_insns(p->addr, 1);
90}
91
92void __kprobes arch_remove_kprobe(struct kprobe *p)
93{
94 if (p->ainsn.insn) {
95 mutex_lock(&kprobe_mutex);
96 free_insn_slot(p->ainsn.insn, 0);
97 mutex_unlock(&kprobe_mutex);
98 p->ainsn.insn = NULL;
99 }
100}
101
102static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
103{
104 kcb->prev_kprobe.kp = kprobe_running();
105 kcb->prev_kprobe.status = kcb->kprobe_status;
106}
107
108static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
109{
110 __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
111 kcb->kprobe_status = kcb->prev_kprobe.status;
112}
113
114static void __kprobes set_current_kprobe(struct kprobe *p)
115{
116 __get_cpu_var(current_kprobe) = p;
117}
118
119static void __kprobes singlestep(struct kprobe *p, struct pt_regs *regs,
120 struct kprobe_ctlblk *kcb)
121{
122 regs->ARM_pc += 4;
123 p->ainsn.insn_handler(p, regs);
124}
125
126/*
127 * Called with IRQs disabled. IRQs must remain disabled from that point
128 * all the way until processing this kprobe is complete. The current
129 * kprobes implementation cannot process more than one nested level of
130 * kprobe, and that level is reserved for user kprobe handlers, so we can't
131 * risk encountering a new kprobe in an interrupt handler.
132 */
133void __kprobes kprobe_handler(struct pt_regs *regs)
134{
135 struct kprobe *p, *cur;
136 struct kprobe_ctlblk *kcb;
137 kprobe_opcode_t *addr = (kprobe_opcode_t *)regs->ARM_pc;
138
139 kcb = get_kprobe_ctlblk();
140 cur = kprobe_running();
141 p = get_kprobe(addr);
142
143 if (p) {
144 if (cur) {
145 /* Kprobe is pending, so we're recursing. */
146 switch (kcb->kprobe_status) {
147 case KPROBE_HIT_ACTIVE:
148 case KPROBE_HIT_SSDONE:
149 /* A pre- or post-handler probe got us here. */
150 kprobes_inc_nmissed_count(p);
151 save_previous_kprobe(kcb);
152 set_current_kprobe(p);
153 kcb->kprobe_status = KPROBE_REENTER;
154 singlestep(p, regs, kcb);
155 restore_previous_kprobe(kcb);
156 break;
157 default:
158 /* impossible cases */
159 BUG();
160 }
161 } else {
162 set_current_kprobe(p);
163 kcb->kprobe_status = KPROBE_HIT_ACTIVE;
164
165 /*
166 * If we have no pre-handler or it returned 0, we
167 * continue with normal processing. If we have a
168 * pre-handler and it returned non-zero, it prepped
169 * for calling the break_handler below on re-entry,
170 * so get out doing nothing more here.
171 */
172 if (!p->pre_handler || !p->pre_handler(p, regs)) {
173 kcb->kprobe_status = KPROBE_HIT_SS;
174 singlestep(p, regs, kcb);
175 if (p->post_handler) {
176 kcb->kprobe_status = KPROBE_HIT_SSDONE;
177 p->post_handler(p, regs, 0);
178 }
179 reset_current_kprobe();
180 }
181 }
182 } else if (cur) {
183 /* We probably hit a jprobe. Call its break handler. */
184 if (cur->break_handler && cur->break_handler(cur, regs)) {
185 kcb->kprobe_status = KPROBE_HIT_SS;
186 singlestep(cur, regs, kcb);
187 if (cur->post_handler) {
188 kcb->kprobe_status = KPROBE_HIT_SSDONE;
189 cur->post_handler(cur, regs, 0);
190 }
191 }
192 reset_current_kprobe();
193 } else {
194 /*
195 * The probe was removed and a race is in progress.
196 * There is nothing we can do about it. Let's restart
197 * the instruction. By the time we can restart, the
198 * real instruction will be there.
199 */
200 }
201}
202
203int kprobe_trap_handler(struct pt_regs *regs, unsigned int instr)
204{
205 kprobe_handler(regs);
206 return 0;
207}
208
209int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr)
210{
211 struct kprobe *cur = kprobe_running();
212 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
213
214 switch (kcb->kprobe_status) {
215 case KPROBE_HIT_SS:
216 case KPROBE_REENTER:
217 /*
218 * We are here because the instruction being single
219 * stepped caused a page fault. We reset the current
220 * kprobe and the PC to point back to the probe address
221 * and allow the page fault handler to continue as a
222 * normal page fault.
223 */
224 regs->ARM_pc = (long)cur->addr;
225 if (kcb->kprobe_status == KPROBE_REENTER) {
226 restore_previous_kprobe(kcb);
227 } else {
228 reset_current_kprobe();
229 }
230 break;
231
232 case KPROBE_HIT_ACTIVE:
233 case KPROBE_HIT_SSDONE:
234 /*
235 * We increment the nmissed count for accounting,
236 * we can also use npre/npostfault count for accounting
237 * these specific fault cases.
238 */
239 kprobes_inc_nmissed_count(cur);
240
241 /*
242 * We come here because instructions in the pre/post
243 * handler caused the page_fault, this could happen
244 * if handler tries to access user space by
245 * copy_from_user(), get_user() etc. Let the
246 * user-specified handler try to fix it.
247 */
248 if (cur->fault_handler && cur->fault_handler(cur, regs, fsr))
249 return 1;
250 break;
251
252 default:
253 break;
254 }
255
256 return 0;
257}
258
259int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
260 unsigned long val, void *data)
261{
262 /*
263 * notify_die() is currently never called on ARM,
264 * so this callback is currently empty.
265 */
266 return NOTIFY_DONE;
267}
268
269/*
270 * When a retprobed function returns, trampoline_handler() is called,
271 * calling the kretprobe's handler. We construct a struct pt_regs to
272 * give a view of registers r0-r11 to the user return-handler. This is
273 * not a complete pt_regs structure, but that should be plenty sufficient
274 * for kretprobe handlers which should normally be interested in r0 only
275 * anyway.
276 */
277static void __attribute__((naked)) __kprobes kretprobe_trampoline(void)
278{
279 __asm__ __volatile__ (
280 "stmdb sp!, {r0 - r11} \n\t"
281 "mov r0, sp \n\t"
282 "bl trampoline_handler \n\t"
283 "mov lr, r0 \n\t"
284 "ldmia sp!, {r0 - r11} \n\t"
285 "mov pc, lr \n\t"
286 : : : "memory");
287}
288
289/* Called from kretprobe_trampoline */
290static __used __kprobes void *trampoline_handler(struct pt_regs *regs)
291{
292 struct kretprobe_instance *ri = NULL;
293 struct hlist_head *head, empty_rp;
294 struct hlist_node *node, *tmp;
295 unsigned long flags, orig_ret_address = 0;
296 unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline;
297
298 INIT_HLIST_HEAD(&empty_rp);
299 spin_lock_irqsave(&kretprobe_lock, flags);
300 head = kretprobe_inst_table_head(current);
301
302 /*
303 * It is possible to have multiple instances associated with a given
304 * task either because multiple functions in the call path have
305 * a return probe installed on them, and/or more than one return
306 * probe was registered for a target function.
307 *
308 * We can handle this because:
309 * - instances are always inserted at the head of the list
310 * - when multiple return probes are registered for the same
311 * function, the first instance's ret_addr will point to the
312 * real return address, and all the rest will point to
313 * kretprobe_trampoline
314 */
315 hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
316 if (ri->task != current)
317 /* another task is sharing our hash bucket */
318 continue;
319
320 if (ri->rp && ri->rp->handler) {
321 __get_cpu_var(current_kprobe) = &ri->rp->kp;
322 get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
323 ri->rp->handler(ri, regs);
324 __get_cpu_var(current_kprobe) = NULL;
325 }
326
327 orig_ret_address = (unsigned long)ri->ret_addr;
328 recycle_rp_inst(ri, &empty_rp);
329
330 if (orig_ret_address != trampoline_address)
331 /*
332 * This is the real return address. Any other
333 * instances associated with this task are for
334 * other calls deeper on the call stack
335 */
336 break;
337 }
338
339 kretprobe_assert(ri, orig_ret_address, trampoline_address);
340 spin_unlock_irqrestore(&kretprobe_lock, flags);
341
342 hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
343 hlist_del(&ri->hlist);
344 kfree(ri);
345 }
346
347 return (void *)orig_ret_address;
348}
349
350/* Called with kretprobe_lock held. */
351void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
352 struct pt_regs *regs)
353{
354 ri->ret_addr = (kprobe_opcode_t *)regs->ARM_lr;
355
356 /* Replace the return addr with trampoline addr. */
357 regs->ARM_lr = (unsigned long)&kretprobe_trampoline;
358}
359
360int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
361{
362 struct jprobe *jp = container_of(p, struct jprobe, kp);
363 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
364 long sp_addr = regs->ARM_sp;
365
366 kcb->jprobe_saved_regs = *regs;
367 memcpy(kcb->jprobes_stack, (void *)sp_addr, MIN_STACK_SIZE(sp_addr));
368 regs->ARM_pc = (long)jp->entry;
369 regs->ARM_cpsr |= PSR_I_BIT;
370 preempt_disable();
371 return 1;
372}
373
374void __kprobes jprobe_return(void)
375{
376 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
377
378 __asm__ __volatile__ (
379 /*
380 * Setup an empty pt_regs. Fill SP and PC fields as
381 * they're needed by longjmp_break_handler.
382 */
383 "sub sp, %0, %1 \n\t"
384 "ldr r0, ="__stringify(JPROBE_MAGIC_ADDR)"\n\t"
385 "str %0, [sp, %2] \n\t"
386 "str r0, [sp, %3] \n\t"
387 "mov r0, sp \n\t"
388 "bl kprobe_handler \n\t"
389
390 /*
391 * Return to the context saved by setjmp_pre_handler
392 * and restored by longjmp_break_handler.
393 */
394 "ldr r0, [sp, %4] \n\t"
395 "msr cpsr_cxsf, r0 \n\t"
396 "ldmia sp, {r0 - pc} \n\t"
397 :
398 : "r" (kcb->jprobe_saved_regs.ARM_sp),
399 "I" (sizeof(struct pt_regs)),
400 "J" (offsetof(struct pt_regs, ARM_sp)),
401 "J" (offsetof(struct pt_regs, ARM_pc)),
402 "J" (offsetof(struct pt_regs, ARM_cpsr))
403 : "memory", "cc");
404}
405
406int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
407{
408 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
409 long stack_addr = kcb->jprobe_saved_regs.ARM_sp;
410 long orig_sp = regs->ARM_sp;
411 struct jprobe *jp = container_of(p, struct jprobe, kp);
412
413 if (regs->ARM_pc == JPROBE_MAGIC_ADDR) {
414 if (orig_sp != stack_addr) {
415 struct pt_regs *saved_regs =
416 (struct pt_regs *)kcb->jprobe_saved_regs.ARM_sp;
417 printk("current sp %lx does not match saved sp %lx\n",
418 orig_sp, stack_addr);
419 printk("Saved registers for jprobe %p\n", jp);
420 show_regs(saved_regs);
421 printk("Current registers\n");
422 show_regs(regs);
423 BUG();
424 }
425 *regs = kcb->jprobe_saved_regs;
426 memcpy((void *)stack_addr, kcb->jprobes_stack,
427 MIN_STACK_SIZE(stack_addr));
428 preempt_enable_no_resched();
429 return 1;
430 }
431 return 0;
432}
433
434static struct undef_hook kprobes_break_hook = {
435 .instr_mask = 0xffffffff,
436 .instr_val = KPROBE_BREAKPOINT_INSTRUCTION,
437 .cpsr_mask = MODE_MASK,
438 .cpsr_val = SVC_MODE,
439 .fn = kprobe_trap_handler,
440};
441
442int __init arch_init_kprobes()
443{
444 arm_kprobe_decode_init();
445 register_undef_hook(&kprobes_break_hook);
446 return 0;
447}
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index 1533d3ecd7a0..b5867eca1d0b 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -79,17 +79,6 @@ static unsigned long dummy_gettimeoffset(void)
79} 79}
80#endif 80#endif
81 81
82/*
83 * An implementation of printk_clock() independent from
84 * sched_clock(). This avoids non-bootable kernels when
85 * printk_clock is enabled.
86 */
87unsigned long long printk_clock(void)
88{
89 return (unsigned long long)(jiffies - INITIAL_JIFFIES) *
90 (1000000000 / HZ);
91}
92
93static unsigned long next_rtc_update; 82static unsigned long next_rtc_update;
94 83
95/* 84/*
@@ -195,7 +184,7 @@ static int leds_shutdown(struct sys_device *dev)
195} 184}
196 185
197static struct sysdev_class leds_sysclass = { 186static struct sysdev_class leds_sysclass = {
198 set_kset_name("leds"), 187 .name = "leds",
199 .shutdown = leds_shutdown, 188 .shutdown = leds_shutdown,
200 .suspend = leds_suspend, 189 .suspend = leds_suspend,
201 .resume = leds_resume, 190 .resume = leds_resume,
@@ -336,7 +325,9 @@ void timer_tick(void)
336 profile_tick(CPU_PROFILING); 325 profile_tick(CPU_PROFILING);
337 do_leds(); 326 do_leds();
338 do_set_rtc(); 327 do_set_rtc();
328 write_seqlock(&xtime_lock);
339 do_timer(1); 329 do_timer(1);
330 write_sequnlock(&xtime_lock);
340#ifndef CONFIG_SMP 331#ifndef CONFIG_SMP
341 update_process_times(user_mode(get_irq_regs())); 332 update_process_times(user_mode(get_irq_regs()));
342#endif 333#endif
@@ -369,7 +360,7 @@ static int timer_resume(struct sys_device *dev)
369#endif 360#endif
370 361
371static struct sysdev_class timer_sysclass = { 362static struct sysdev_class timer_sysclass = {
372 set_kset_name("timer"), 363 .name = "timer",
373 .suspend = timer_suspend, 364 .suspend = timer_suspend,
374 .resume = timer_resume, 365 .resume = timer_resume,
375}; 366};
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index c34db4e868fa..5595fdd75e82 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -19,6 +19,7 @@
19#include <linux/kallsyms.h> 19#include <linux/kallsyms.h>
20#include <linux/delay.h> 20#include <linux/delay.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/kprobes.h>
22 23
23#include <asm/atomic.h> 24#include <asm/atomic.h>
24#include <asm/cacheflush.h> 25#include <asm/cacheflush.h>
@@ -46,15 +47,6 @@ __setup("user_debug=", user_debug_setup);
46 47
47static void dump_mem(const char *str, unsigned long bottom, unsigned long top); 48static void dump_mem(const char *str, unsigned long bottom, unsigned long top);
48 49
49static inline int in_exception_text(unsigned long ptr)
50{
51 extern char __exception_text_start[];
52 extern char __exception_text_end[];
53
54 return ptr >= (unsigned long)&__exception_text_start &&
55 ptr < (unsigned long)&__exception_text_end;
56}
57
58void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame) 50void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame)
59{ 51{
60#ifdef CONFIG_KALLSYMS 52#ifdef CONFIG_KALLSYMS
@@ -322,6 +314,17 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
322 get_user(instr, (u32 __user *)pc); 314 get_user(instr, (u32 __user *)pc);
323 } 315 }
324 316
317#ifdef CONFIG_KPROBES
318 /*
319 * It is possible to have recursive kprobes, so we can't call
320 * the kprobe trap handler with the undef_lock held.
321 */
322 if (instr == KPROBE_BREAKPOINT_INSTRUCTION && !user_mode(regs)) {
323 kprobe_trap_handler(regs, instr);
324 return;
325 }
326#endif
327
325 spin_lock_irqsave(&undef_lock, flags); 328 spin_lock_irqsave(&undef_lock, flags);
326 list_for_each_entry(hook, &undef_hook, node) { 329 list_for_each_entry(hook, &undef_hook, node) {
327 if ((instr & hook->instr_mask) == hook->instr_val && 330 if ((instr & hook->instr_mask) == hook->instr_val &&
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 5ff5406666b4..4898bdcfe7dd 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -30,7 +30,7 @@ SECTIONS
30 } 30 }
31 31
32 .init : { /* Init code and data */ 32 .init : { /* Init code and data */
33 *(.init.text) 33 INIT_TEXT
34 _einittext = .; 34 _einittext = .;
35 __proc_info_begin = .; 35 __proc_info_begin = .;
36 *(.proc.info.init) 36 *(.proc.info.init)
@@ -70,15 +70,15 @@ SECTIONS
70 __per_cpu_end = .; 70 __per_cpu_end = .;
71#ifndef CONFIG_XIP_KERNEL 71#ifndef CONFIG_XIP_KERNEL
72 __init_begin = _stext; 72 __init_begin = _stext;
73 *(.init.data) 73 INIT_DATA
74 . = ALIGN(4096); 74 . = ALIGN(4096);
75 __init_end = .; 75 __init_end = .;
76#endif 76#endif
77 } 77 }
78 78
79 /DISCARD/ : { /* Exit code and data */ 79 /DISCARD/ : { /* Exit code and data */
80 *(.exit.text) 80 EXIT_TEXT
81 *(.exit.data) 81 EXIT_DATA
82 *(.exitcall.exit) 82 *(.exitcall.exit)
83#ifndef CONFIG_MMU 83#ifndef CONFIG_MMU
84 *(.fixup) 84 *(.fixup)
@@ -94,6 +94,7 @@ SECTIONS
94 TEXT_TEXT 94 TEXT_TEXT
95 SCHED_TEXT 95 SCHED_TEXT
96 LOCK_TEXT 96 LOCK_TEXT
97 KPROBES_TEXT
97#ifdef CONFIG_MMU 98#ifdef CONFIG_MMU
98 *(.fixup) 99 *(.fixup)
99#endif 100#endif
@@ -129,7 +130,7 @@ SECTIONS
129#ifdef CONFIG_XIP_KERNEL 130#ifdef CONFIG_XIP_KERNEL
130 . = ALIGN(4096); 131 . = ALIGN(4096);
131 __init_begin = .; 132 __init_begin = .;
132 *(.init.data) 133 INIT_DATA
133 . = ALIGN(4096); 134 . = ALIGN(4096);
134 __init_end = .; 135 __init_end = .;
135#endif 136#endif
diff --git a/arch/arm/mach-aaec2000/core.c b/arch/arm/mach-aaec2000/core.c
index 0446ef2f5bd6..b016be2b0e35 100644
--- a/arch/arm/mach-aaec2000/core.c
+++ b/arch/arm/mach-aaec2000/core.c
@@ -130,13 +130,9 @@ static irqreturn_t
130aaec2000_timer_interrupt(int irq, void *dev_id) 130aaec2000_timer_interrupt(int irq, void *dev_id)
131{ 131{
132 /* TODO: Check timer accuracy */ 132 /* TODO: Check timer accuracy */
133 write_seqlock(&xtime_lock);
134
135 timer_tick(); 133 timer_tick();
136 TIMER1_CLEAR = 1; 134 TIMER1_CLEAR = 1;
137 135
138 write_sequnlock(&xtime_lock);
139
140 return IRQ_HANDLED; 136 return IRQ_HANDLED;
141} 137}
142 138
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 05a9f8a1b45e..5b0422cdde76 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -22,6 +22,9 @@ config ARCH_AT91SAM9263
22config ARCH_AT91SAM9RL 22config ARCH_AT91SAM9RL
23 bool "AT91SAM9RL" 23 bool "AT91SAM9RL"
24 24
25config ARCH_AT91CAP9
26 bool "AT91CAP9"
27
25config ARCH_AT91X40 28config ARCH_AT91X40
26 bool "AT91x40" 29 bool "AT91x40"
27 30
@@ -178,6 +181,21 @@ endif
178 181
179# ---------------------------------------------------------- 182# ----------------------------------------------------------
180 183
184if ARCH_AT91CAP9
185
186comment "AT91CAP9 Board Type"
187
188config MACH_AT91CAP9ADK
189 bool "Atmel AT91CAP9A-DK Evaluation Kit"
190 depends on ARCH_AT91CAP9
191 help
192 Select this if you are using Atmel's AT91CAP9A-DK Evaluation Kit.
193 <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4138>
194
195endif
196
197# ----------------------------------------------------------
198
181if ARCH_AT91X40 199if ARCH_AT91X40
182 200
183comment "AT91X40 Board Type" 201comment "AT91X40 Board Type"
@@ -198,13 +216,13 @@ comment "AT91 Board Options"
198 216
199config MTD_AT91_DATAFLASH_CARD 217config MTD_AT91_DATAFLASH_CARD
200 bool "Enable DataFlash Card support" 218 bool "Enable DataFlash Card support"
201 depends on (ARCH_AT91RM9200DK || MACH_AT91RM9200EK || MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK) 219 depends on (ARCH_AT91RM9200DK || MACH_AT91RM9200EK || MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91CAP9ADK)
202 help 220 help
203 Enable support for the DataFlash card. 221 Enable support for the DataFlash card.
204 222
205config MTD_NAND_AT91_BUSWIDTH_16 223config MTD_NAND_AT91_BUSWIDTH_16
206 bool "Enable 16-bit data bus interface to NAND flash" 224 bool "Enable 16-bit data bus interface to NAND flash"
207 depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK) 225 depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91CAP9ADK)
208 help 226 help
209 On AT91SAM926x boards both types of NAND flash can be present 227 On AT91SAM926x boards both types of NAND flash can be present
210 (8 and 16 bit data bus width). 228 (8 and 16 bit data bus width).
@@ -219,6 +237,22 @@ config AT91_PROGRAMMABLE_CLOCKS
219 Select this if you need to program one or more of the PCK0..PCK3 237 Select this if you need to program one or more of the PCK0..PCK3
220 programmable clock outputs. 238 programmable clock outputs.
221 239
240config AT91_TIMER_HZ
241 int "Kernel HZ (jiffies per second)"
242 range 32 1024
243 depends on ARCH_AT91
244 default "128" if ARCH_AT91RM9200
245 default "100"
246 help
247 On AT91rm9200 chips where you're using a system clock derived
248 from the 32768 Hz hardware clock, this tick rate should divide
249 it exactly: use a power-of-two value, such as 128 or 256, to
250 reduce timing errors caused by rounding.
251
252 On AT91sam926x chips, or otherwise when using a higher precision
253 system clock (of at least several MHz), rounding is less of a
254 problem so it can be safer to use a decimal values like 100.
255
222endmenu 256endmenu
223 257
224endif 258endif
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index a21f08c64ea6..bf5f293dccf8 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -8,7 +8,6 @@ obj-n :=
8obj- := 8obj- :=
9 9
10obj-$(CONFIG_AT91_PMC_UNIT) += clock.o 10obj-$(CONFIG_AT91_PMC_UNIT) += clock.o
11obj-$(CONFIG_PM) += pm.o
12 11
13# CPU-specific support 12# CPU-specific support
14obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devices.o 13obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devices.o
@@ -16,6 +15,7 @@ obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_d
16obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o 15obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o
17obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o 16obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o
18obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o 17obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o
18obj-$(CONFIG_ARCH_AT91CAP9) += at91cap9.o at91sam926x_time.o at91cap9_devices.o
19obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o 19obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o
20 20
21# AT91RM9200 board-specific support 21# AT91RM9200 board-specific support
@@ -29,7 +29,6 @@ obj-$(CONFIG_MACH_KB9200) += board-kb9202.o
29obj-$(CONFIG_MACH_ATEB9200) += board-eb9200.o 29obj-$(CONFIG_MACH_ATEB9200) += board-eb9200.o
30obj-$(CONFIG_MACH_KAFA) += board-kafa.o 30obj-$(CONFIG_MACH_KAFA) += board-kafa.o
31obj-$(CONFIG_MACH_PICOTUX2XX) += board-picotux200.o 31obj-$(CONFIG_MACH_PICOTUX2XX) += board-picotux200.o
32obj-$(CONFIG_MACH_AT91EB01) += board-eb01.o
33 32
34# AT91SAM9260 board-specific support 33# AT91SAM9260 board-specific support
35obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o 34obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o
@@ -43,19 +42,17 @@ obj-$(CONFIG_MACH_AT91SAM9263EK) += board-sam9263ek.o
43# AT91SAM9RL board-specific support 42# AT91SAM9RL board-specific support
44obj-$(CONFIG_MACH_AT91SAM9RLEK) += board-sam9rlek.o 43obj-$(CONFIG_MACH_AT91SAM9RLEK) += board-sam9rlek.o
45 44
46# LEDs support 45# AT91CAP9 board-specific support
47led-$(CONFIG_ARCH_AT91RM9200DK) += leds.o 46obj-$(CONFIG_MACH_AT91CAP9ADK) += board-cap9adk.o
48led-$(CONFIG_MACH_AT91RM9200EK) += leds.o
49led-$(CONFIG_MACH_AT91SAM9261EK)+= leds.o
50led-$(CONFIG_MACH_CSB337) += leds.o
51led-$(CONFIG_MACH_CSB637) += leds.o
52led-$(CONFIG_MACH_KB9200) += leds.o
53led-$(CONFIG_MACH_KAFA) += leds.o
54obj-$(CONFIG_LEDS) += $(led-y)
55 47
56# VGA support 48# AT91X40 board-specific support
57#obj-$(CONFIG_FB_S1D13XXX) += ics1523.o 49obj-$(CONFIG_MACH_AT91EB01) += board-eb01.o
58 50
51# Drivers
52obj-y += leds.o
53
54# Power Management
55obj-$(CONFIG_PM) += pm.o
59 56
60ifeq ($(CONFIG_PM_DEBUG),y) 57ifeq ($(CONFIG_PM_DEBUG),y)
61CFLAGS_pm.o += -DDEBUG 58CFLAGS_pm.o += -DDEBUG
diff --git a/arch/arm/mach-at91/Makefile.boot b/arch/arm/mach-at91/Makefile.boot
index e667dcc7cd34..071a2506a69f 100644
--- a/arch/arm/mach-at91/Makefile.boot
+++ b/arch/arm/mach-at91/Makefile.boot
@@ -3,7 +3,12 @@
3# PARAMS_PHYS must be within 4MB of ZRELADDR 3# PARAMS_PHYS must be within 4MB of ZRELADDR
4# INITRD_PHYS must be in RAM 4# INITRD_PHYS must be in RAM
5 5
6ifeq ($(CONFIG_ARCH_AT91CAP9),y)
7 zreladdr-y := 0x70008000
8params_phys-y := 0x70000100
9initrd_phys-y := 0x70410000
10else
6 zreladdr-y := 0x20008000 11 zreladdr-y := 0x20008000
7params_phys-y := 0x20000100 12params_phys-y := 0x20000100
8initrd_phys-y := 0x20410000 13initrd_phys-y := 0x20410000
9 14endif
diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c
new file mode 100644
index 000000000000..48d27d8000b0
--- /dev/null
+++ b/arch/arm/mach-at91/at91cap9.c
@@ -0,0 +1,365 @@
1/*
2 * arch/arm/mach-at91/at91cap9.c
3 *
4 * Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com>
5 * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com>
6 * Copyright (C) 2007 Atmel Corporation.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 */
14
15#include <linux/module.h>
16
17#include <asm/mach/arch.h>
18#include <asm/mach/map.h>
19#include <asm/arch/at91cap9.h>
20#include <asm/arch/at91_pmc.h>
21#include <asm/arch/at91_rstc.h>
22
23#include "generic.h"
24#include "clock.h"
25
26static struct map_desc at91cap9_io_desc[] __initdata = {
27 {
28 .virtual = AT91_VA_BASE_SYS,
29 .pfn = __phys_to_pfn(AT91_BASE_SYS),
30 .length = SZ_16K,
31 .type = MT_DEVICE,
32 }, {
33 .virtual = AT91_IO_VIRT_BASE - AT91CAP9_SRAM_SIZE,
34 .pfn = __phys_to_pfn(AT91CAP9_SRAM_BASE),
35 .length = AT91CAP9_SRAM_SIZE,
36 .type = MT_DEVICE,
37 },
38};
39
40/* --------------------------------------------------------------------
41 * Clocks
42 * -------------------------------------------------------------------- */
43
44/*
45 * The peripheral clocks.
46 */
47static struct clk pioABCD_clk = {
48 .name = "pioABCD_clk",
49 .pmc_mask = 1 << AT91CAP9_ID_PIOABCD,
50 .type = CLK_TYPE_PERIPHERAL,
51};
52static struct clk mpb0_clk = {
53 .name = "mpb0_clk",
54 .pmc_mask = 1 << AT91CAP9_ID_MPB0,
55 .type = CLK_TYPE_PERIPHERAL,
56};
57static struct clk mpb1_clk = {
58 .name = "mpb1_clk",
59 .pmc_mask = 1 << AT91CAP9_ID_MPB1,
60 .type = CLK_TYPE_PERIPHERAL,
61};
62static struct clk mpb2_clk = {
63 .name = "mpb2_clk",
64 .pmc_mask = 1 << AT91CAP9_ID_MPB2,
65 .type = CLK_TYPE_PERIPHERAL,
66};
67static struct clk mpb3_clk = {
68 .name = "mpb3_clk",
69 .pmc_mask = 1 << AT91CAP9_ID_MPB3,
70 .type = CLK_TYPE_PERIPHERAL,
71};
72static struct clk mpb4_clk = {
73 .name = "mpb4_clk",
74 .pmc_mask = 1 << AT91CAP9_ID_MPB4,
75 .type = CLK_TYPE_PERIPHERAL,
76};
77static struct clk usart0_clk = {
78 .name = "usart0_clk",
79 .pmc_mask = 1 << AT91CAP9_ID_US0,
80 .type = CLK_TYPE_PERIPHERAL,
81};
82static struct clk usart1_clk = {
83 .name = "usart1_clk",
84 .pmc_mask = 1 << AT91CAP9_ID_US1,
85 .type = CLK_TYPE_PERIPHERAL,
86};
87static struct clk usart2_clk = {
88 .name = "usart2_clk",
89 .pmc_mask = 1 << AT91CAP9_ID_US2,
90 .type = CLK_TYPE_PERIPHERAL,
91};
92static struct clk mmc0_clk = {
93 .name = "mci0_clk",
94 .pmc_mask = 1 << AT91CAP9_ID_MCI0,
95 .type = CLK_TYPE_PERIPHERAL,
96};
97static struct clk mmc1_clk = {
98 .name = "mci1_clk",
99 .pmc_mask = 1 << AT91CAP9_ID_MCI1,
100 .type = CLK_TYPE_PERIPHERAL,
101};
102static struct clk can_clk = {
103 .name = "can_clk",
104 .pmc_mask = 1 << AT91CAP9_ID_CAN,
105 .type = CLK_TYPE_PERIPHERAL,
106};
107static struct clk twi_clk = {
108 .name = "twi_clk",
109 .pmc_mask = 1 << AT91CAP9_ID_TWI,
110 .type = CLK_TYPE_PERIPHERAL,
111};
112static struct clk spi0_clk = {
113 .name = "spi0_clk",
114 .pmc_mask = 1 << AT91CAP9_ID_SPI0,
115 .type = CLK_TYPE_PERIPHERAL,
116};
117static struct clk spi1_clk = {
118 .name = "spi1_clk",
119 .pmc_mask = 1 << AT91CAP9_ID_SPI1,
120 .type = CLK_TYPE_PERIPHERAL,
121};
122static struct clk ssc0_clk = {
123 .name = "ssc0_clk",
124 .pmc_mask = 1 << AT91CAP9_ID_SSC0,
125 .type = CLK_TYPE_PERIPHERAL,
126};
127static struct clk ssc1_clk = {
128 .name = "ssc1_clk",
129 .pmc_mask = 1 << AT91CAP9_ID_SSC1,
130 .type = CLK_TYPE_PERIPHERAL,
131};
132static struct clk ac97_clk = {
133 .name = "ac97_clk",
134 .pmc_mask = 1 << AT91CAP9_ID_AC97C,
135 .type = CLK_TYPE_PERIPHERAL,
136};
137static struct clk tcb_clk = {
138 .name = "tcb_clk",
139 .pmc_mask = 1 << AT91CAP9_ID_TCB,
140 .type = CLK_TYPE_PERIPHERAL,
141};
142static struct clk pwmc_clk = {
143 .name = "pwmc_clk",
144 .pmc_mask = 1 << AT91CAP9_ID_PWMC,
145 .type = CLK_TYPE_PERIPHERAL,
146};
147static struct clk macb_clk = {
148 .name = "macb_clk",
149 .pmc_mask = 1 << AT91CAP9_ID_EMAC,
150 .type = CLK_TYPE_PERIPHERAL,
151};
152static struct clk aestdes_clk = {
153 .name = "aestdes_clk",
154 .pmc_mask = 1 << AT91CAP9_ID_AESTDES,
155 .type = CLK_TYPE_PERIPHERAL,
156};
157static struct clk adc_clk = {
158 .name = "adc_clk",
159 .pmc_mask = 1 << AT91CAP9_ID_ADC,
160 .type = CLK_TYPE_PERIPHERAL,
161};
162static struct clk isi_clk = {
163 .name = "isi_clk",
164 .pmc_mask = 1 << AT91CAP9_ID_ISI,
165 .type = CLK_TYPE_PERIPHERAL,
166};
167static struct clk lcdc_clk = {
168 .name = "lcdc_clk",
169 .pmc_mask = 1 << AT91CAP9_ID_LCDC,
170 .type = CLK_TYPE_PERIPHERAL,
171};
172static struct clk dma_clk = {
173 .name = "dma_clk",
174 .pmc_mask = 1 << AT91CAP9_ID_DMA,
175 .type = CLK_TYPE_PERIPHERAL,
176};
177static struct clk udphs_clk = {
178 .name = "udphs_clk",
179 .pmc_mask = 1 << AT91CAP9_ID_UDPHS,
180 .type = CLK_TYPE_PERIPHERAL,
181};
182static struct clk ohci_clk = {
183 .name = "ohci_clk",
184 .pmc_mask = 1 << AT91CAP9_ID_UHP,
185 .type = CLK_TYPE_PERIPHERAL,
186};
187
188static struct clk *periph_clocks[] __initdata = {
189 &pioABCD_clk,
190 &mpb0_clk,
191 &mpb1_clk,
192 &mpb2_clk,
193 &mpb3_clk,
194 &mpb4_clk,
195 &usart0_clk,
196 &usart1_clk,
197 &usart2_clk,
198 &mmc0_clk,
199 &mmc1_clk,
200 &can_clk,
201 &twi_clk,
202 &spi0_clk,
203 &spi1_clk,
204 &ssc0_clk,
205 &ssc1_clk,
206 &ac97_clk,
207 &tcb_clk,
208 &pwmc_clk,
209 &macb_clk,
210 &aestdes_clk,
211 &adc_clk,
212 &isi_clk,
213 &lcdc_clk,
214 &dma_clk,
215 &udphs_clk,
216 &ohci_clk,
217 // irq0 .. irq1
218};
219
220/*
221 * The four programmable clocks.
222 * You must configure pin multiplexing to bring these signals out.
223 */
224static struct clk pck0 = {
225 .name = "pck0",
226 .pmc_mask = AT91_PMC_PCK0,
227 .type = CLK_TYPE_PROGRAMMABLE,
228 .id = 0,
229};
230static struct clk pck1 = {
231 .name = "pck1",
232 .pmc_mask = AT91_PMC_PCK1,
233 .type = CLK_TYPE_PROGRAMMABLE,
234 .id = 1,
235};
236static struct clk pck2 = {
237 .name = "pck2",
238 .pmc_mask = AT91_PMC_PCK2,
239 .type = CLK_TYPE_PROGRAMMABLE,
240 .id = 2,
241};
242static struct clk pck3 = {
243 .name = "pck3",
244 .pmc_mask = AT91_PMC_PCK3,
245 .type = CLK_TYPE_PROGRAMMABLE,
246 .id = 3,
247};
248
249static void __init at91cap9_register_clocks(void)
250{
251 int i;
252
253 for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
254 clk_register(periph_clocks[i]);
255
256 clk_register(&pck0);
257 clk_register(&pck1);
258 clk_register(&pck2);
259 clk_register(&pck3);
260}
261
262/* --------------------------------------------------------------------
263 * GPIO
264 * -------------------------------------------------------------------- */
265
266static struct at91_gpio_bank at91cap9_gpio[] = {
267 {
268 .id = AT91CAP9_ID_PIOABCD,
269 .offset = AT91_PIOA,
270 .clock = &pioABCD_clk,
271 }, {
272 .id = AT91CAP9_ID_PIOABCD,
273 .offset = AT91_PIOB,
274 .clock = &pioABCD_clk,
275 }, {
276 .id = AT91CAP9_ID_PIOABCD,
277 .offset = AT91_PIOC,
278 .clock = &pioABCD_clk,
279 }, {
280 .id = AT91CAP9_ID_PIOABCD,
281 .offset = AT91_PIOD,
282 .clock = &pioABCD_clk,
283 }
284};
285
286static void at91cap9_reset(void)
287{
288 at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
289}
290
291/* --------------------------------------------------------------------
292 * AT91CAP9 processor initialization
293 * -------------------------------------------------------------------- */
294
295void __init at91cap9_initialize(unsigned long main_clock)
296{
297 /* Map peripherals */
298 iotable_init(at91cap9_io_desc, ARRAY_SIZE(at91cap9_io_desc));
299
300 at91_arch_reset = at91cap9_reset;
301 at91_extern_irq = (1 << AT91CAP9_ID_IRQ0) | (1 << AT91CAP9_ID_IRQ1);
302
303 /* Init clock subsystem */
304 at91_clock_init(main_clock);
305
306 /* Register the processor-specific clocks */
307 at91cap9_register_clocks();
308
309 /* Register GPIO subsystem */
310 at91_gpio_init(at91cap9_gpio, 4);
311}
312
313/* --------------------------------------------------------------------
314 * Interrupt initialization
315 * -------------------------------------------------------------------- */
316
317/*
318 * The default interrupt priority levels (0 = lowest, 7 = highest).
319 */
320static unsigned int at91cap9_default_irq_priority[NR_AIC_IRQS] __initdata = {
321 7, /* Advanced Interrupt Controller (FIQ) */
322 7, /* System Peripherals */
323 1, /* Parallel IO Controller A, B, C and D */
324 0, /* MP Block Peripheral 0 */
325 0, /* MP Block Peripheral 1 */
326 0, /* MP Block Peripheral 2 */
327 0, /* MP Block Peripheral 3 */
328 0, /* MP Block Peripheral 4 */
329 5, /* USART 0 */
330 5, /* USART 1 */
331 5, /* USART 2 */
332 0, /* Multimedia Card Interface 0 */
333 0, /* Multimedia Card Interface 1 */
334 3, /* CAN */
335 6, /* Two-Wire Interface */
336 5, /* Serial Peripheral Interface 0 */
337 5, /* Serial Peripheral Interface 1 */
338 4, /* Serial Synchronous Controller 0 */
339 4, /* Serial Synchronous Controller 1 */
340 5, /* AC97 Controller */
341 0, /* Timer Counter 0, 1 and 2 */
342 0, /* Pulse Width Modulation Controller */
343 3, /* Ethernet */
344 0, /* Advanced Encryption Standard, Triple DES*/
345 0, /* Analog-to-Digital Converter */
346 0, /* Image Sensor Interface */
347 3, /* LCD Controller */
348 0, /* DMA Controller */
349 2, /* USB Device Port */
350 2, /* USB Host port */
351 0, /* Advanced Interrupt Controller (IRQ0) */
352 0, /* Advanced Interrupt Controller (IRQ1) */
353};
354
355void __init at91cap9_init_interrupts(unsigned int priority[NR_AIC_IRQS])
356{
357 if (!priority)
358 priority = at91cap9_default_irq_priority;
359
360 /* Initialize the AIC interrupt controller */
361 at91_aic_init(priority);
362
363 /* Enable GPIO interrupts */
364 at91_gpio_irq_setup();
365}
diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c
new file mode 100644
index 000000000000..c50fad9cd143
--- /dev/null
+++ b/arch/arm/mach-at91/at91cap9_devices.c
@@ -0,0 +1,1066 @@
1/*
2 * arch/arm/mach-at91/at91cap9_devices.c
3 *
4 * Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com>
5 * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com>
6 * Copyright (C) 2007 Atmel Corporation.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 */
14#include <asm/mach/arch.h>
15#include <asm/mach/map.h>
16
17#include <linux/dma-mapping.h>
18#include <linux/platform_device.h>
19#include <linux/mtd/physmap.h>
20
21#include <video/atmel_lcdc.h>
22
23#include <asm/arch/board.h>
24#include <asm/arch/gpio.h>
25#include <asm/arch/at91cap9.h>
26#include <asm/arch/at91sam926x_mc.h>
27#include <asm/arch/at91cap9_matrix.h>
28
29#include "generic.h"
30
31
32/* --------------------------------------------------------------------
33 * USB Host
34 * -------------------------------------------------------------------- */
35
36#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
37static u64 ohci_dmamask = DMA_BIT_MASK(32);
38static struct at91_usbh_data usbh_data;
39
40static struct resource usbh_resources[] = {
41 [0] = {
42 .start = AT91CAP9_UHP_BASE,
43 .end = AT91CAP9_UHP_BASE + SZ_1M - 1,
44 .flags = IORESOURCE_MEM,
45 },
46 [1] = {
47 .start = AT91CAP9_ID_UHP,
48 .end = AT91CAP9_ID_UHP,
49 .flags = IORESOURCE_IRQ,
50 },
51};
52
53static struct platform_device at91_usbh_device = {
54 .name = "at91_ohci",
55 .id = -1,
56 .dev = {
57 .dma_mask = &ohci_dmamask,
58 .coherent_dma_mask = DMA_BIT_MASK(32),
59 .platform_data = &usbh_data,
60 },
61 .resource = usbh_resources,
62 .num_resources = ARRAY_SIZE(usbh_resources),
63};
64
65void __init at91_add_device_usbh(struct at91_usbh_data *data)
66{
67 int i;
68
69 if (!data)
70 return;
71
72 /* Enable VBus control for UHP ports */
73 for (i = 0; i < data->ports; i++) {
74 if (data->vbus_pin[i])
75 at91_set_gpio_output(data->vbus_pin[i], 0);
76 }
77
78 usbh_data = *data;
79 platform_device_register(&at91_usbh_device);
80}
81#else
82void __init at91_add_device_usbh(struct at91_usbh_data *data) {}
83#endif
84
85
86/* --------------------------------------------------------------------
87 * Ethernet
88 * -------------------------------------------------------------------- */
89
90#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE)
91static u64 eth_dmamask = DMA_BIT_MASK(32);
92static struct at91_eth_data eth_data;
93
94static struct resource eth_resources[] = {
95 [0] = {
96 .start = AT91CAP9_BASE_EMAC,
97 .end = AT91CAP9_BASE_EMAC + SZ_16K - 1,
98 .flags = IORESOURCE_MEM,
99 },
100 [1] = {
101 .start = AT91CAP9_ID_EMAC,
102 .end = AT91CAP9_ID_EMAC,
103 .flags = IORESOURCE_IRQ,
104 },
105};
106
107static struct platform_device at91cap9_eth_device = {
108 .name = "macb",
109 .id = -1,
110 .dev = {
111 .dma_mask = &eth_dmamask,
112 .coherent_dma_mask = DMA_BIT_MASK(32),
113 .platform_data = &eth_data,
114 },
115 .resource = eth_resources,
116 .num_resources = ARRAY_SIZE(eth_resources),
117};
118
119void __init at91_add_device_eth(struct at91_eth_data *data)
120{
121 if (!data)
122 return;
123
124 if (data->phy_irq_pin) {
125 at91_set_gpio_input(data->phy_irq_pin, 0);
126 at91_set_deglitch(data->phy_irq_pin, 1);
127 }
128
129 /* Pins used for MII and RMII */
130 at91_set_A_periph(AT91_PIN_PB21, 0); /* ETXCK_EREFCK */
131 at91_set_A_periph(AT91_PIN_PB22, 0); /* ERXDV */
132 at91_set_A_periph(AT91_PIN_PB25, 0); /* ERX0 */
133 at91_set_A_periph(AT91_PIN_PB26, 0); /* ERX1 */
134 at91_set_A_periph(AT91_PIN_PB27, 0); /* ERXER */
135 at91_set_A_periph(AT91_PIN_PB28, 0); /* ETXEN */
136 at91_set_A_periph(AT91_PIN_PB23, 0); /* ETX0 */
137 at91_set_A_periph(AT91_PIN_PB24, 0); /* ETX1 */
138 at91_set_A_periph(AT91_PIN_PB30, 0); /* EMDIO */
139 at91_set_A_periph(AT91_PIN_PB29, 0); /* EMDC */
140
141 if (!data->is_rmii) {
142 at91_set_B_periph(AT91_PIN_PC25, 0); /* ECRS */
143 at91_set_B_periph(AT91_PIN_PC26, 0); /* ECOL */
144 at91_set_B_periph(AT91_PIN_PC22, 0); /* ERX2 */
145 at91_set_B_periph(AT91_PIN_PC23, 0); /* ERX3 */
146 at91_set_B_periph(AT91_PIN_PC27, 0); /* ERXCK */
147 at91_set_B_periph(AT91_PIN_PC20, 0); /* ETX2 */
148 at91_set_B_periph(AT91_PIN_PC21, 0); /* ETX3 */
149 at91_set_B_periph(AT91_PIN_PC24, 0); /* ETXER */
150 }
151
152 eth_data = *data;
153 platform_device_register(&at91cap9_eth_device);
154}
155#else
156void __init at91_add_device_eth(struct at91_eth_data *data) {}
157#endif
158
159
160/* --------------------------------------------------------------------
161 * MMC / SD
162 * -------------------------------------------------------------------- */
163
164#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE)
165static u64 mmc_dmamask = DMA_BIT_MASK(32);
166static struct at91_mmc_data mmc0_data, mmc1_data;
167
168static struct resource mmc0_resources[] = {
169 [0] = {
170 .start = AT91CAP9_BASE_MCI0,
171 .end = AT91CAP9_BASE_MCI0 + SZ_16K - 1,
172 .flags = IORESOURCE_MEM,
173 },
174 [1] = {
175 .start = AT91CAP9_ID_MCI0,
176 .end = AT91CAP9_ID_MCI0,
177 .flags = IORESOURCE_IRQ,
178 },
179};
180
181static struct platform_device at91cap9_mmc0_device = {
182 .name = "at91_mci",
183 .id = 0,
184 .dev = {
185 .dma_mask = &mmc_dmamask,
186 .coherent_dma_mask = DMA_BIT_MASK(32),
187 .platform_data = &mmc0_data,
188 },
189 .resource = mmc0_resources,
190 .num_resources = ARRAY_SIZE(mmc0_resources),
191};
192
193static struct resource mmc1_resources[] = {
194 [0] = {
195 .start = AT91CAP9_BASE_MCI1,
196 .end = AT91CAP9_BASE_MCI1 + SZ_16K - 1,
197 .flags = IORESOURCE_MEM,
198 },
199 [1] = {
200 .start = AT91CAP9_ID_MCI1,
201 .end = AT91CAP9_ID_MCI1,
202 .flags = IORESOURCE_IRQ,
203 },
204};
205
206static struct platform_device at91cap9_mmc1_device = {
207 .name = "at91_mci",
208 .id = 1,
209 .dev = {
210 .dma_mask = &mmc_dmamask,
211 .coherent_dma_mask = DMA_BIT_MASK(32),
212 .platform_data = &mmc1_data,
213 },
214 .resource = mmc1_resources,
215 .num_resources = ARRAY_SIZE(mmc1_resources),
216};
217
218void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
219{
220 if (!data)
221 return;
222
223 /* input/irq */
224 if (data->det_pin) {
225 at91_set_gpio_input(data->det_pin, 1);
226 at91_set_deglitch(data->det_pin, 1);
227 }
228 if (data->wp_pin)
229 at91_set_gpio_input(data->wp_pin, 1);
230 if (data->vcc_pin)
231 at91_set_gpio_output(data->vcc_pin, 0);
232
233 if (mmc_id == 0) { /* MCI0 */
234 /* CLK */
235 at91_set_A_periph(AT91_PIN_PA2, 0);
236
237 /* CMD */
238 at91_set_A_periph(AT91_PIN_PA1, 1);
239
240 /* DAT0, maybe DAT1..DAT3 */
241 at91_set_A_periph(AT91_PIN_PA0, 1);
242 if (data->wire4) {
243 at91_set_A_periph(AT91_PIN_PA3, 1);
244 at91_set_A_periph(AT91_PIN_PA4, 1);
245 at91_set_A_periph(AT91_PIN_PA5, 1);
246 }
247
248 mmc0_data = *data;
249 at91_clock_associate("mci0_clk", &at91cap9_mmc1_device.dev, "mci_clk");
250 platform_device_register(&at91cap9_mmc0_device);
251 } else { /* MCI1 */
252 /* CLK */
253 at91_set_A_periph(AT91_PIN_PA16, 0);
254
255 /* CMD */
256 at91_set_A_periph(AT91_PIN_PA17, 1);
257
258 /* DAT0, maybe DAT1..DAT3 */
259 at91_set_A_periph(AT91_PIN_PA18, 1);
260 if (data->wire4) {
261 at91_set_A_periph(AT91_PIN_PA19, 1);
262 at91_set_A_periph(AT91_PIN_PA20, 1);
263 at91_set_A_periph(AT91_PIN_PA21, 1);
264 }
265
266 mmc1_data = *data;
267 at91_clock_associate("mci1_clk", &at91cap9_mmc1_device.dev, "mci_clk");
268 platform_device_register(&at91cap9_mmc1_device);
269 }
270}
271#else
272void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
273#endif
274
275
276/* --------------------------------------------------------------------
277 * NAND / SmartMedia
278 * -------------------------------------------------------------------- */
279
280#if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE)
281static struct at91_nand_data nand_data;
282
283#define NAND_BASE AT91_CHIPSELECT_3
284
285static struct resource nand_resources[] = {
286 {
287 .start = NAND_BASE,
288 .end = NAND_BASE + SZ_256M - 1,
289 .flags = IORESOURCE_MEM,
290 }
291};
292
293static struct platform_device at91cap9_nand_device = {
294 .name = "at91_nand",
295 .id = -1,
296 .dev = {
297 .platform_data = &nand_data,
298 },
299 .resource = nand_resources,
300 .num_resources = ARRAY_SIZE(nand_resources),
301};
302
303void __init at91_add_device_nand(struct at91_nand_data *data)
304{
305 unsigned long csa, mode;
306
307 if (!data)
308 return;
309
310 csa = at91_sys_read(AT91_MATRIX_EBICSA);
311 at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA | AT91_MATRIX_EBI_VDDIOMSEL_3_3V);
312
313 /* set the bus interface characteristics */
314 at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(2) | AT91_SMC_NCS_WRSETUP_(1)
315 | AT91_SMC_NRDSETUP_(2) | AT91_SMC_NCS_RDSETUP_(1));
316
317 at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(4) | AT91_SMC_NCS_WRPULSE_(6)
318 | AT91_SMC_NRDPULSE_(4) | AT91_SMC_NCS_RDPULSE_(6));
319
320 at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(8) | AT91_SMC_NRDCYCLE_(8));
321
322 if (data->bus_width_16)
323 mode = AT91_SMC_DBW_16;
324 else
325 mode = AT91_SMC_DBW_8;
326 at91_sys_write(AT91_SMC_MODE(3), mode | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(1));
327
328 /* enable pin */
329 if (data->enable_pin)
330 at91_set_gpio_output(data->enable_pin, 1);
331
332 /* ready/busy pin */
333 if (data->rdy_pin)
334 at91_set_gpio_input(data->rdy_pin, 1);
335
336 /* card detect pin */
337 if (data->det_pin)
338 at91_set_gpio_input(data->det_pin, 1);
339
340 nand_data = *data;
341 platform_device_register(&at91cap9_nand_device);
342}
343#else
344void __init at91_add_device_nand(struct at91_nand_data *data) {}
345#endif
346
347/* --------------------------------------------------------------------
348 * TWI (i2c)
349 * -------------------------------------------------------------------- */
350
351/*
352 * Prefer the GPIO code since the TWI controller isn't robust
353 * (gets overruns and underruns under load) and can only issue
354 * repeated STARTs in one scenario (the driver doesn't yet handle them).
355 */
356#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
357
358static struct i2c_gpio_platform_data pdata = {
359 .sda_pin = AT91_PIN_PB4,
360 .sda_is_open_drain = 1,
361 .scl_pin = AT91_PIN_PB5,
362 .scl_is_open_drain = 1,
363 .udelay = 2, /* ~100 kHz */
364};
365
366static struct platform_device at91cap9_twi_device = {
367 .name = "i2c-gpio",
368 .id = -1,
369 .dev.platform_data = &pdata,
370};
371
372void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
373{
374 at91_set_GPIO_periph(AT91_PIN_PB4, 1); /* TWD (SDA) */
375 at91_set_multi_drive(AT91_PIN_PB4, 1);
376
377 at91_set_GPIO_periph(AT91_PIN_PB5, 1); /* TWCK (SCL) */
378 at91_set_multi_drive(AT91_PIN_PB5, 1);
379
380 i2c_register_board_info(0, devices, nr_devices);
381 platform_device_register(&at91cap9_twi_device);
382}
383
384#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
385
386static struct resource twi_resources[] = {
387 [0] = {
388 .start = AT91CAP9_BASE_TWI,
389 .end = AT91CAP9_BASE_TWI + SZ_16K - 1,
390 .flags = IORESOURCE_MEM,
391 },
392 [1] = {
393 .start = AT91CAP9_ID_TWI,
394 .end = AT91CAP9_ID_TWI,
395 .flags = IORESOURCE_IRQ,
396 },
397};
398
399static struct platform_device at91cap9_twi_device = {
400 .name = "at91_i2c",
401 .id = -1,
402 .resource = twi_resources,
403 .num_resources = ARRAY_SIZE(twi_resources),
404};
405
406void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
407{
408 /* pins used for TWI interface */
409 at91_set_B_periph(AT91_PIN_PB4, 0); /* TWD */
410 at91_set_multi_drive(AT91_PIN_PB4, 1);
411
412 at91_set_B_periph(AT91_PIN_PB5, 0); /* TWCK */
413 at91_set_multi_drive(AT91_PIN_PB5, 1);
414
415 i2c_register_board_info(0, devices, nr_devices);
416 platform_device_register(&at91cap9_twi_device);
417}
418#else
419void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {}
420#endif
421
422/* --------------------------------------------------------------------
423 * SPI
424 * -------------------------------------------------------------------- */
425
426#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
427static u64 spi_dmamask = DMA_BIT_MASK(32);
428
429static struct resource spi0_resources[] = {
430 [0] = {
431 .start = AT91CAP9_BASE_SPI0,
432 .end = AT91CAP9_BASE_SPI0 + SZ_16K - 1,
433 .flags = IORESOURCE_MEM,
434 },
435 [1] = {
436 .start = AT91CAP9_ID_SPI0,
437 .end = AT91CAP9_ID_SPI0,
438 .flags = IORESOURCE_IRQ,
439 },
440};
441
442static struct platform_device at91cap9_spi0_device = {
443 .name = "atmel_spi",
444 .id = 0,
445 .dev = {
446 .dma_mask = &spi_dmamask,
447 .coherent_dma_mask = DMA_BIT_MASK(32),
448 },
449 .resource = spi0_resources,
450 .num_resources = ARRAY_SIZE(spi0_resources),
451};
452
453static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA5, AT91_PIN_PA3, AT91_PIN_PD0, AT91_PIN_PD1 };
454
455static struct resource spi1_resources[] = {
456 [0] = {
457 .start = AT91CAP9_BASE_SPI1,
458 .end = AT91CAP9_BASE_SPI1 + SZ_16K - 1,
459 .flags = IORESOURCE_MEM,
460 },
461 [1] = {
462 .start = AT91CAP9_ID_SPI1,
463 .end = AT91CAP9_ID_SPI1,
464 .flags = IORESOURCE_IRQ,
465 },
466};
467
468static struct platform_device at91cap9_spi1_device = {
469 .name = "atmel_spi",
470 .id = 1,
471 .dev = {
472 .dma_mask = &spi_dmamask,
473 .coherent_dma_mask = DMA_BIT_MASK(32),
474 },
475 .resource = spi1_resources,
476 .num_resources = ARRAY_SIZE(spi1_resources),
477};
478
479static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB15, AT91_PIN_PB16, AT91_PIN_PB17, AT91_PIN_PB18 };
480
481void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
482{
483 int i;
484 unsigned long cs_pin;
485 short enable_spi0 = 0;
486 short enable_spi1 = 0;
487
488 /* Choose SPI chip-selects */
489 for (i = 0; i < nr_devices; i++) {
490 if (devices[i].controller_data)
491 cs_pin = (unsigned long) devices[i].controller_data;
492 else if (devices[i].bus_num == 0)
493 cs_pin = spi0_standard_cs[devices[i].chip_select];
494 else
495 cs_pin = spi1_standard_cs[devices[i].chip_select];
496
497 if (devices[i].bus_num == 0)
498 enable_spi0 = 1;
499 else
500 enable_spi1 = 1;
501
502 /* enable chip-select pin */
503 at91_set_gpio_output(cs_pin, 1);
504
505 /* pass chip-select pin to driver */
506 devices[i].controller_data = (void *) cs_pin;
507 }
508
509 spi_register_board_info(devices, nr_devices);
510
511 /* Configure SPI bus(es) */
512 if (enable_spi0) {
513 at91_set_B_periph(AT91_PIN_PA0, 0); /* SPI0_MISO */
514 at91_set_B_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */
515 at91_set_B_periph(AT91_PIN_PA2, 0); /* SPI0_SPCK */
516
517 at91_clock_associate("spi0_clk", &at91cap9_spi0_device.dev, "spi_clk");
518 platform_device_register(&at91cap9_spi0_device);
519 }
520 if (enable_spi1) {
521 at91_set_A_periph(AT91_PIN_PB12, 0); /* SPI1_MISO */
522 at91_set_A_periph(AT91_PIN_PB13, 0); /* SPI1_MOSI */
523 at91_set_A_periph(AT91_PIN_PB14, 0); /* SPI1_SPCK */
524
525 at91_clock_associate("spi1_clk", &at91cap9_spi1_device.dev, "spi_clk");
526 platform_device_register(&at91cap9_spi1_device);
527 }
528}
529#else
530void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {}
531#endif
532
533
534/* --------------------------------------------------------------------
535 * RTT
536 * -------------------------------------------------------------------- */
537
538static struct platform_device at91cap9_rtt_device = {
539 .name = "at91_rtt",
540 .id = -1,
541 .num_resources = 0,
542};
543
544static void __init at91_add_device_rtt(void)
545{
546 platform_device_register(&at91cap9_rtt_device);
547}
548
549
550/* --------------------------------------------------------------------
551 * Watchdog
552 * -------------------------------------------------------------------- */
553
554#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE)
555static struct platform_device at91cap9_wdt_device = {
556 .name = "at91_wdt",
557 .id = -1,
558 .num_resources = 0,
559};
560
561static void __init at91_add_device_watchdog(void)
562{
563 platform_device_register(&at91cap9_wdt_device);
564}
565#else
566static void __init at91_add_device_watchdog(void) {}
567#endif
568
569
570/* --------------------------------------------------------------------
571 * AC97
572 * -------------------------------------------------------------------- */
573
574#if defined(CONFIG_SND_AT91_AC97) || defined(CONFIG_SND_AT91_AC97_MODULE)
575static u64 ac97_dmamask = DMA_BIT_MASK(32);
576static struct atmel_ac97_data ac97_data;
577
578static struct resource ac97_resources[] = {
579 [0] = {
580 .start = AT91CAP9_BASE_AC97C,
581 .end = AT91CAP9_BASE_AC97C + SZ_16K - 1,
582 .flags = IORESOURCE_MEM,
583 },
584 [1] = {
585 .start = AT91CAP9_ID_AC97C,
586 .end = AT91CAP9_ID_AC97C,
587 .flags = IORESOURCE_IRQ,
588 },
589};
590
591static struct platform_device at91cap9_ac97_device = {
592 .name = "ac97c",
593 .id = 1,
594 .dev = {
595 .dma_mask = &ac97_dmamask,
596 .coherent_dma_mask = DMA_BIT_MASK(32),
597 .platform_data = &ac97_data,
598 },
599 .resource = ac97_resources,
600 .num_resources = ARRAY_SIZE(ac97_resources),
601};
602
603void __init at91_add_device_ac97(struct atmel_ac97_data *data)
604{
605 if (!data)
606 return;
607
608 at91_set_A_periph(AT91_PIN_PA6, 0); /* AC97FS */
609 at91_set_A_periph(AT91_PIN_PA7, 0); /* AC97CK */
610 at91_set_A_periph(AT91_PIN_PA8, 0); /* AC97TX */
611 at91_set_A_periph(AT91_PIN_PA9, 0); /* AC97RX */
612
613 /* reset */
614 if (data->reset_pin)
615 at91_set_gpio_output(data->reset_pin, 0);
616
617 ac97_data = *data;
618 platform_device_register(&at91cap9_ac97_device);
619}
620#else
621void __init at91_add_device_ac97(struct atmel_ac97_data *data) {}
622#endif
623
624
625/* --------------------------------------------------------------------
626 * LCD Controller
627 * -------------------------------------------------------------------- */
628
629#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
630static u64 lcdc_dmamask = DMA_BIT_MASK(32);
631static struct atmel_lcdfb_info lcdc_data;
632
633static struct resource lcdc_resources[] = {
634 [0] = {
635 .start = AT91CAP9_LCDC_BASE,
636 .end = AT91CAP9_LCDC_BASE + SZ_4K - 1,
637 .flags = IORESOURCE_MEM,
638 },
639 [1] = {
640 .start = AT91CAP9_ID_LCDC,
641 .end = AT91CAP9_ID_LCDC,
642 .flags = IORESOURCE_IRQ,
643 },
644};
645
646static struct platform_device at91_lcdc_device = {
647 .name = "atmel_lcdfb",
648 .id = 0,
649 .dev = {
650 .dma_mask = &lcdc_dmamask,
651 .coherent_dma_mask = DMA_BIT_MASK(32),
652 .platform_data = &lcdc_data,
653 },
654 .resource = lcdc_resources,
655 .num_resources = ARRAY_SIZE(lcdc_resources),
656};
657
658void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
659{
660 if (!data)
661 return;
662
663 at91_set_A_periph(AT91_PIN_PC1, 0); /* LCDHSYNC */
664 at91_set_A_periph(AT91_PIN_PC2, 0); /* LCDDOTCK */
665 at91_set_A_periph(AT91_PIN_PC3, 0); /* LCDDEN */
666 at91_set_B_periph(AT91_PIN_PB9, 0); /* LCDCC */
667 at91_set_A_periph(AT91_PIN_PC6, 0); /* LCDD2 */
668 at91_set_A_periph(AT91_PIN_PC7, 0); /* LCDD3 */
669 at91_set_A_periph(AT91_PIN_PC8, 0); /* LCDD4 */
670 at91_set_A_periph(AT91_PIN_PC9, 0); /* LCDD5 */
671 at91_set_A_periph(AT91_PIN_PC10, 0); /* LCDD6 */
672 at91_set_A_periph(AT91_PIN_PC11, 0); /* LCDD7 */
673 at91_set_A_periph(AT91_PIN_PC14, 0); /* LCDD10 */
674 at91_set_A_periph(AT91_PIN_PC15, 0); /* LCDD11 */
675 at91_set_A_periph(AT91_PIN_PC16, 0); /* LCDD12 */
676 at91_set_A_periph(AT91_PIN_PC17, 0); /* LCDD13 */
677 at91_set_A_periph(AT91_PIN_PC18, 0); /* LCDD14 */
678 at91_set_A_periph(AT91_PIN_PC19, 0); /* LCDD15 */
679 at91_set_A_periph(AT91_PIN_PC22, 0); /* LCDD18 */
680 at91_set_A_periph(AT91_PIN_PC23, 0); /* LCDD19 */
681 at91_set_A_periph(AT91_PIN_PC24, 0); /* LCDD20 */
682 at91_set_A_periph(AT91_PIN_PC25, 0); /* LCDD21 */
683 at91_set_A_periph(AT91_PIN_PC26, 0); /* LCDD22 */
684 at91_set_A_periph(AT91_PIN_PC27, 0); /* LCDD23 */
685
686 lcdc_data = *data;
687 platform_device_register(&at91_lcdc_device);
688}
689#else
690void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
691#endif
692
693
694/* --------------------------------------------------------------------
695 * SSC -- Synchronous Serial Controller
696 * -------------------------------------------------------------------- */
697
698#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE)
699static u64 ssc0_dmamask = DMA_BIT_MASK(32);
700
701static struct resource ssc0_resources[] = {
702 [0] = {
703 .start = AT91CAP9_BASE_SSC0,
704 .end = AT91CAP9_BASE_SSC0 + SZ_16K - 1,
705 .flags = IORESOURCE_MEM,
706 },
707 [1] = {
708 .start = AT91CAP9_ID_SSC0,
709 .end = AT91CAP9_ID_SSC0,
710 .flags = IORESOURCE_IRQ,
711 },
712};
713
714static struct platform_device at91cap9_ssc0_device = {
715 .name = "ssc",
716 .id = 0,
717 .dev = {
718 .dma_mask = &ssc0_dmamask,
719 .coherent_dma_mask = DMA_BIT_MASK(32),
720 },
721 .resource = ssc0_resources,
722 .num_resources = ARRAY_SIZE(ssc0_resources),
723};
724
725static inline void configure_ssc0_pins(unsigned pins)
726{
727 if (pins & ATMEL_SSC_TF)
728 at91_set_A_periph(AT91_PIN_PB0, 1);
729 if (pins & ATMEL_SSC_TK)
730 at91_set_A_periph(AT91_PIN_PB1, 1);
731 if (pins & ATMEL_SSC_TD)
732 at91_set_A_periph(AT91_PIN_PB2, 1);
733 if (pins & ATMEL_SSC_RD)
734 at91_set_A_periph(AT91_PIN_PB3, 1);
735 if (pins & ATMEL_SSC_RK)
736 at91_set_A_periph(AT91_PIN_PB4, 1);
737 if (pins & ATMEL_SSC_RF)
738 at91_set_A_periph(AT91_PIN_PB5, 1);
739}
740
741static u64 ssc1_dmamask = DMA_BIT_MASK(32);
742
743static struct resource ssc1_resources[] = {
744 [0] = {
745 .start = AT91CAP9_BASE_SSC1,
746 .end = AT91CAP9_BASE_SSC1 + SZ_16K - 1,
747 .flags = IORESOURCE_MEM,
748 },
749 [1] = {
750 .start = AT91CAP9_ID_SSC1,
751 .end = AT91CAP9_ID_SSC1,
752 .flags = IORESOURCE_IRQ,
753 },
754};
755
756static struct platform_device at91cap9_ssc1_device = {
757 .name = "ssc",
758 .id = 1,
759 .dev = {
760 .dma_mask = &ssc1_dmamask,
761 .coherent_dma_mask = DMA_BIT_MASK(32),
762 },
763 .resource = ssc1_resources,
764 .num_resources = ARRAY_SIZE(ssc1_resources),
765};
766
767static inline void configure_ssc1_pins(unsigned pins)
768{
769 if (pins & ATMEL_SSC_TF)
770 at91_set_A_periph(AT91_PIN_PB6, 1);
771 if (pins & ATMEL_SSC_TK)
772 at91_set_A_periph(AT91_PIN_PB7, 1);
773 if (pins & ATMEL_SSC_TD)
774 at91_set_A_periph(AT91_PIN_PB8, 1);
775 if (pins & ATMEL_SSC_RD)
776 at91_set_A_periph(AT91_PIN_PB9, 1);
777 if (pins & ATMEL_SSC_RK)
778 at91_set_A_periph(AT91_PIN_PB10, 1);
779 if (pins & ATMEL_SSC_RF)
780 at91_set_A_periph(AT91_PIN_PB11, 1);
781}
782
783/*
784 * SSC controllers are accessed through library code, instead of any
785 * kind of all-singing/all-dancing driver. For example one could be
786 * used by a particular I2S audio codec's driver, while another one
787 * on the same system might be used by a custom data capture driver.
788 */
789void __init at91_add_device_ssc(unsigned id, unsigned pins)
790{
791 struct platform_device *pdev;
792
793 /*
794 * NOTE: caller is responsible for passing information matching
795 * "pins" to whatever will be using each particular controller.
796 */
797 switch (id) {
798 case AT91CAP9_ID_SSC0:
799 pdev = &at91cap9_ssc0_device;
800 configure_ssc0_pins(pins);
801 at91_clock_associate("ssc0_clk", &pdev->dev, "ssc");
802 break;
803 case AT91CAP9_ID_SSC1:
804 pdev = &at91cap9_ssc1_device;
805 configure_ssc1_pins(pins);
806 at91_clock_associate("ssc1_clk", &pdev->dev, "ssc");
807 break;
808 default:
809 return;
810 }
811
812 platform_device_register(pdev);
813}
814
815#else
816void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
817#endif
818
819
820/* --------------------------------------------------------------------
821 * UART
822 * -------------------------------------------------------------------- */
823
824#if defined(CONFIG_SERIAL_ATMEL)
825static struct resource dbgu_resources[] = {
826 [0] = {
827 .start = AT91_VA_BASE_SYS + AT91_DBGU,
828 .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1,
829 .flags = IORESOURCE_MEM,
830 },
831 [1] = {
832 .start = AT91_ID_SYS,
833 .end = AT91_ID_SYS,
834 .flags = IORESOURCE_IRQ,
835 },
836};
837
838static struct atmel_uart_data dbgu_data = {
839 .use_dma_tx = 0,
840 .use_dma_rx = 0, /* DBGU not capable of receive DMA */
841 .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
842};
843
844static u64 dbgu_dmamask = DMA_BIT_MASK(32);
845
846static struct platform_device at91cap9_dbgu_device = {
847 .name = "atmel_usart",
848 .id = 0,
849 .dev = {
850 .dma_mask = &dbgu_dmamask,
851 .coherent_dma_mask = DMA_BIT_MASK(32),
852 .platform_data = &dbgu_data,
853 },
854 .resource = dbgu_resources,
855 .num_resources = ARRAY_SIZE(dbgu_resources),
856};
857
858static inline void configure_dbgu_pins(void)
859{
860 at91_set_A_periph(AT91_PIN_PC30, 0); /* DRXD */
861 at91_set_A_periph(AT91_PIN_PC31, 1); /* DTXD */
862}
863
864static struct resource uart0_resources[] = {
865 [0] = {
866 .start = AT91CAP9_BASE_US0,
867 .end = AT91CAP9_BASE_US0 + SZ_16K - 1,
868 .flags = IORESOURCE_MEM,
869 },
870 [1] = {
871 .start = AT91CAP9_ID_US0,
872 .end = AT91CAP9_ID_US0,
873 .flags = IORESOURCE_IRQ,
874 },
875};
876
877static struct atmel_uart_data uart0_data = {
878 .use_dma_tx = 1,
879 .use_dma_rx = 1,
880};
881
882static u64 uart0_dmamask = DMA_BIT_MASK(32);
883
884static struct platform_device at91cap9_uart0_device = {
885 .name = "atmel_usart",
886 .id = 1,
887 .dev = {
888 .dma_mask = &uart0_dmamask,
889 .coherent_dma_mask = DMA_BIT_MASK(32),
890 .platform_data = &uart0_data,
891 },
892 .resource = uart0_resources,
893 .num_resources = ARRAY_SIZE(uart0_resources),
894};
895
896static inline void configure_usart0_pins(unsigned pins)
897{
898 at91_set_A_periph(AT91_PIN_PA22, 1); /* TXD0 */
899 at91_set_A_periph(AT91_PIN_PA23, 0); /* RXD0 */
900
901 if (pins & ATMEL_UART_RTS)
902 at91_set_A_periph(AT91_PIN_PA24, 0); /* RTS0 */
903 if (pins & ATMEL_UART_CTS)
904 at91_set_A_periph(AT91_PIN_PA25, 0); /* CTS0 */
905}
906
907static struct resource uart1_resources[] = {
908 [0] = {
909 .start = AT91CAP9_BASE_US1,
910 .end = AT91CAP9_BASE_US1 + SZ_16K - 1,
911 .flags = IORESOURCE_MEM,
912 },
913 [1] = {
914 .start = AT91CAP9_ID_US1,
915 .end = AT91CAP9_ID_US1,
916 .flags = IORESOURCE_IRQ,
917 },
918};
919
920static struct atmel_uart_data uart1_data = {
921 .use_dma_tx = 1,
922 .use_dma_rx = 1,
923};
924
925static u64 uart1_dmamask = DMA_BIT_MASK(32);
926
927static struct platform_device at91cap9_uart1_device = {
928 .name = "atmel_usart",
929 .id = 2,
930 .dev = {
931 .dma_mask = &uart1_dmamask,
932 .coherent_dma_mask = DMA_BIT_MASK(32),
933 .platform_data = &uart1_data,
934 },
935 .resource = uart1_resources,
936 .num_resources = ARRAY_SIZE(uart1_resources),
937};
938
939static inline void configure_usart1_pins(unsigned pins)
940{
941 at91_set_A_periph(AT91_PIN_PD0, 1); /* TXD1 */
942 at91_set_A_periph(AT91_PIN_PD1, 0); /* RXD1 */
943
944 if (pins & ATMEL_UART_RTS)
945 at91_set_B_periph(AT91_PIN_PD7, 0); /* RTS1 */
946 if (pins & ATMEL_UART_CTS)
947 at91_set_B_periph(AT91_PIN_PD8, 0); /* CTS1 */
948}
949
950static struct resource uart2_resources[] = {
951 [0] = {
952 .start = AT91CAP9_BASE_US2,
953 .end = AT91CAP9_BASE_US2 + SZ_16K - 1,
954 .flags = IORESOURCE_MEM,
955 },
956 [1] = {
957 .start = AT91CAP9_ID_US2,
958 .end = AT91CAP9_ID_US2,
959 .flags = IORESOURCE_IRQ,
960 },
961};
962
963static struct atmel_uart_data uart2_data = {
964 .use_dma_tx = 1,
965 .use_dma_rx = 1,
966};
967
968static u64 uart2_dmamask = DMA_BIT_MASK(32);
969
970static struct platform_device at91cap9_uart2_device = {
971 .name = "atmel_usart",
972 .id = 3,
973 .dev = {
974 .dma_mask = &uart2_dmamask,
975 .coherent_dma_mask = DMA_BIT_MASK(32),
976 .platform_data = &uart2_data,
977 },
978 .resource = uart2_resources,
979 .num_resources = ARRAY_SIZE(uart2_resources),
980};
981
982static inline void configure_usart2_pins(unsigned pins)
983{
984 at91_set_A_periph(AT91_PIN_PD2, 1); /* TXD2 */
985 at91_set_A_periph(AT91_PIN_PD3, 0); /* RXD2 */
986
987 if (pins & ATMEL_UART_RTS)
988 at91_set_B_periph(AT91_PIN_PD5, 0); /* RTS2 */
989 if (pins & ATMEL_UART_CTS)
990 at91_set_B_periph(AT91_PIN_PD6, 0); /* CTS2 */
991}
992
993static struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
994struct platform_device *atmel_default_console_device; /* the serial console device */
995
996void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
997{
998 struct platform_device *pdev;
999
1000 switch (id) {
1001 case 0: /* DBGU */
1002 pdev = &at91cap9_dbgu_device;
1003 configure_dbgu_pins();
1004 at91_clock_associate("mck", &pdev->dev, "usart");
1005 break;
1006 case AT91CAP9_ID_US0:
1007 pdev = &at91cap9_uart0_device;
1008 configure_usart0_pins(pins);
1009 at91_clock_associate("usart0_clk", &pdev->dev, "usart");
1010 break;
1011 case AT91CAP9_ID_US1:
1012 pdev = &at91cap9_uart1_device;
1013 configure_usart1_pins(pins);
1014 at91_clock_associate("usart1_clk", &pdev->dev, "usart");
1015 break;
1016 case AT91CAP9_ID_US2:
1017 pdev = &at91cap9_uart2_device;
1018 configure_usart2_pins(pins);
1019 at91_clock_associate("usart2_clk", &pdev->dev, "usart");
1020 break;
1021 default:
1022 return;
1023 }
1024 pdev->id = portnr; /* update to mapped ID */
1025
1026 if (portnr < ATMEL_MAX_UART)
1027 at91_uarts[portnr] = pdev;
1028}
1029
1030void __init at91_set_serial_console(unsigned portnr)
1031{
1032 if (portnr < ATMEL_MAX_UART)
1033 atmel_default_console_device = at91_uarts[portnr];
1034 if (!atmel_default_console_device)
1035 printk(KERN_INFO "AT91: No default serial console defined.\n");
1036}
1037
1038void __init at91_add_device_serial(void)
1039{
1040 int i;
1041
1042 for (i = 0; i < ATMEL_MAX_UART; i++) {
1043 if (at91_uarts[i])
1044 platform_device_register(at91_uarts[i]);
1045 }
1046}
1047#else
1048void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
1049void __init at91_set_serial_console(unsigned portnr) {}
1050void __init at91_add_device_serial(void) {}
1051#endif
1052
1053
1054/* -------------------------------------------------------------------- */
1055/*
1056 * These devices are always present and don't need any board-specific
1057 * setup.
1058 */
1059static int __init at91_add_standard_devices(void)
1060{
1061 at91_add_device_rtt();
1062 at91_add_device_watchdog();
1063 return 0;
1064}
1065
1066arch_initcall(at91_add_standard_devices);
diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c
index 2cad2bf864be..d688c1dbd925 100644
--- a/arch/arm/mach-at91/at91rm9200.c
+++ b/arch/arm/mach-at91/at91rm9200.c
@@ -301,28 +301,28 @@ void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks
301static unsigned int at91rm9200_default_irq_priority[NR_AIC_IRQS] __initdata = { 301static unsigned int at91rm9200_default_irq_priority[NR_AIC_IRQS] __initdata = {
302 7, /* Advanced Interrupt Controller (FIQ) */ 302 7, /* Advanced Interrupt Controller (FIQ) */
303 7, /* System Peripherals */ 303 7, /* System Peripherals */
304 0, /* Parallel IO Controller A */ 304 1, /* Parallel IO Controller A */
305 0, /* Parallel IO Controller B */ 305 1, /* Parallel IO Controller B */
306 0, /* Parallel IO Controller C */ 306 1, /* Parallel IO Controller C */
307 0, /* Parallel IO Controller D */ 307 1, /* Parallel IO Controller D */
308 6, /* USART 0 */ 308 5, /* USART 0 */
309 6, /* USART 1 */ 309 5, /* USART 1 */
310 6, /* USART 2 */ 310 5, /* USART 2 */
311 6, /* USART 3 */ 311 5, /* USART 3 */
312 0, /* Multimedia Card Interface */ 312 0, /* Multimedia Card Interface */
313 4, /* USB Device Port */ 313 2, /* USB Device Port */
314 0, /* Two-Wire Interface */ 314 6, /* Two-Wire Interface */
315 6, /* Serial Peripheral Interface */ 315 5, /* Serial Peripheral Interface */
316 5, /* Serial Synchronous Controller 0 */ 316 4, /* Serial Synchronous Controller 0 */
317 5, /* Serial Synchronous Controller 1 */ 317 4, /* Serial Synchronous Controller 1 */
318 5, /* Serial Synchronous Controller 2 */ 318 4, /* Serial Synchronous Controller 2 */
319 0, /* Timer Counter 0 */ 319 0, /* Timer Counter 0 */
320 0, /* Timer Counter 1 */ 320 0, /* Timer Counter 1 */
321 0, /* Timer Counter 2 */ 321 0, /* Timer Counter 2 */
322 0, /* Timer Counter 3 */ 322 0, /* Timer Counter 3 */
323 0, /* Timer Counter 4 */ 323 0, /* Timer Counter 4 */
324 0, /* Timer Counter 5 */ 324 0, /* Timer Counter 5 */
325 3, /* USB Host port */ 325 2, /* USB Host port */
326 3, /* Ethernet MAC */ 326 3, /* Ethernet MAC */
327 0, /* Advanced Interrupt Controller (IRQ0) */ 327 0, /* Advanced Interrupt Controller (IRQ0) */
328 0, /* Advanced Interrupt Controller (IRQ1) */ 328 0, /* Advanced Interrupt Controller (IRQ1) */
diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c
index 9296833f91cc..ef6aeb86e980 100644
--- a/arch/arm/mach-at91/at91rm9200_devices.c
+++ b/arch/arm/mach-at91/at91rm9200_devices.c
@@ -13,6 +13,7 @@
13#include <asm/mach/arch.h> 13#include <asm/mach/arch.h>
14#include <asm/mach/map.h> 14#include <asm/mach/map.h>
15 15
16#include <linux/dma-mapping.h>
16#include <linux/platform_device.h> 17#include <linux/platform_device.h>
17#include <linux/i2c-gpio.h> 18#include <linux/i2c-gpio.h>
18 19
@@ -29,7 +30,7 @@
29 * -------------------------------------------------------------------- */ 30 * -------------------------------------------------------------------- */
30 31
31#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) 32#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
32static u64 ohci_dmamask = 0xffffffffUL; 33static u64 ohci_dmamask = DMA_BIT_MASK(32);
33static struct at91_usbh_data usbh_data; 34static struct at91_usbh_data usbh_data;
34 35
35static struct resource usbh_resources[] = { 36static struct resource usbh_resources[] = {
@@ -50,7 +51,7 @@ static struct platform_device at91rm9200_usbh_device = {
50 .id = -1, 51 .id = -1,
51 .dev = { 52 .dev = {
52 .dma_mask = &ohci_dmamask, 53 .dma_mask = &ohci_dmamask,
53 .coherent_dma_mask = 0xffffffff, 54 .coherent_dma_mask = DMA_BIT_MASK(32),
54 .platform_data = &usbh_data, 55 .platform_data = &usbh_data,
55 }, 56 },
56 .resource = usbh_resources, 57 .resource = usbh_resources,
@@ -125,7 +126,7 @@ void __init at91_add_device_udc(struct at91_udc_data *data) {}
125 * -------------------------------------------------------------------- */ 126 * -------------------------------------------------------------------- */
126 127
127#if defined(CONFIG_ARM_AT91_ETHER) || defined(CONFIG_ARM_AT91_ETHER_MODULE) 128#if defined(CONFIG_ARM_AT91_ETHER) || defined(CONFIG_ARM_AT91_ETHER_MODULE)
128static u64 eth_dmamask = 0xffffffffUL; 129static u64 eth_dmamask = DMA_BIT_MASK(32);
129static struct at91_eth_data eth_data; 130static struct at91_eth_data eth_data;
130 131
131static struct resource eth_resources[] = { 132static struct resource eth_resources[] = {
@@ -146,7 +147,7 @@ static struct platform_device at91rm9200_eth_device = {
146 .id = -1, 147 .id = -1,
147 .dev = { 148 .dev = {
148 .dma_mask = &eth_dmamask, 149 .dma_mask = &eth_dmamask,
149 .coherent_dma_mask = 0xffffffff, 150 .coherent_dma_mask = DMA_BIT_MASK(32),
150 .platform_data = &eth_data, 151 .platform_data = &eth_data,
151 }, 152 },
152 .resource = eth_resources, 153 .resource = eth_resources,
@@ -285,7 +286,7 @@ void __init at91_add_device_cf(struct at91_cf_data *data) {}
285 * -------------------------------------------------------------------- */ 286 * -------------------------------------------------------------------- */
286 287
287#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) 288#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE)
288static u64 mmc_dmamask = 0xffffffffUL; 289static u64 mmc_dmamask = DMA_BIT_MASK(32);
289static struct at91_mmc_data mmc_data; 290static struct at91_mmc_data mmc_data;
290 291
291static struct resource mmc_resources[] = { 292static struct resource mmc_resources[] = {
@@ -306,7 +307,7 @@ static struct platform_device at91rm9200_mmc_device = {
306 .id = -1, 307 .id = -1,
307 .dev = { 308 .dev = {
308 .dma_mask = &mmc_dmamask, 309 .dma_mask = &mmc_dmamask,
309 .coherent_dma_mask = 0xffffffff, 310 .coherent_dma_mask = DMA_BIT_MASK(32),
310 .platform_data = &mmc_data, 311 .platform_data = &mmc_data,
311 }, 312 },
312 .resource = mmc_resources, 313 .resource = mmc_resources,
@@ -375,7 +376,7 @@ static struct at91_nand_data nand_data;
375static struct resource nand_resources[] = { 376static struct resource nand_resources[] = {
376 { 377 {
377 .start = NAND_BASE, 378 .start = NAND_BASE,
378 .end = NAND_BASE + SZ_8M - 1, 379 .end = NAND_BASE + SZ_256M - 1,
379 .flags = IORESOURCE_MEM, 380 .flags = IORESOURCE_MEM,
380 } 381 }
381}; 382};
@@ -513,7 +514,7 @@ void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
513 * -------------------------------------------------------------------- */ 514 * -------------------------------------------------------------------- */
514 515
515#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) 516#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
516static u64 spi_dmamask = 0xffffffffUL; 517static u64 spi_dmamask = DMA_BIT_MASK(32);
517 518
518static struct resource spi_resources[] = { 519static struct resource spi_resources[] = {
519 [0] = { 520 [0] = {
@@ -533,7 +534,7 @@ static struct platform_device at91rm9200_spi_device = {
533 .id = 0, 534 .id = 0,
534 .dev = { 535 .dev = {
535 .dma_mask = &spi_dmamask, 536 .dma_mask = &spi_dmamask,
536 .coherent_dma_mask = 0xffffffff, 537 .coherent_dma_mask = DMA_BIT_MASK(32),
537 }, 538 },
538 .resource = spi_resources, 539 .resource = spi_resources,
539 .num_resources = ARRAY_SIZE(spi_resources), 540 .num_resources = ARRAY_SIZE(spi_resources),
@@ -557,8 +558,11 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
557 else 558 else
558 cs_pin = spi_standard_cs[devices[i].chip_select]; 559 cs_pin = spi_standard_cs[devices[i].chip_select];
559 560
560 /* enable chip-select pin */ 561 if (devices[i].chip_select == 0) /* for CS0 errata */
561 at91_set_gpio_output(cs_pin, 1); 562 at91_set_A_periph(cs_pin, 0);
563 else
564 at91_set_gpio_output(cs_pin, 1);
565
562 566
563 /* pass chip-select pin to driver */ 567 /* pass chip-select pin to driver */
564 devices[i].controller_data = (void *) cs_pin; 568 devices[i].controller_data = (void *) cs_pin;
@@ -613,24 +617,175 @@ static void __init at91_add_device_watchdog(void) {}
613 617
614 618
615/* -------------------------------------------------------------------- 619/* --------------------------------------------------------------------
616 * LEDs 620 * SSC -- Synchronous Serial Controller
617 * -------------------------------------------------------------------- */ 621 * -------------------------------------------------------------------- */
618 622
619#if defined(CONFIG_LEDS) 623#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE)
620u8 at91_leds_cpu; 624static u64 ssc0_dmamask = DMA_BIT_MASK(32);
621u8 at91_leds_timer; 625
626static struct resource ssc0_resources[] = {
627 [0] = {
628 .start = AT91RM9200_BASE_SSC0,
629 .end = AT91RM9200_BASE_SSC0 + SZ_16K - 1,
630 .flags = IORESOURCE_MEM,
631 },
632 [1] = {
633 .start = AT91RM9200_ID_SSC0,
634 .end = AT91RM9200_ID_SSC0,
635 .flags = IORESOURCE_IRQ,
636 },
637};
638
639static struct platform_device at91rm9200_ssc0_device = {
640 .name = "ssc",
641 .id = 0,
642 .dev = {
643 .dma_mask = &ssc0_dmamask,
644 .coherent_dma_mask = DMA_BIT_MASK(32),
645 },
646 .resource = ssc0_resources,
647 .num_resources = ARRAY_SIZE(ssc0_resources),
648};
649
650static inline void configure_ssc0_pins(unsigned pins)
651{
652 if (pins & ATMEL_SSC_TF)
653 at91_set_A_periph(AT91_PIN_PB0, 1);
654 if (pins & ATMEL_SSC_TK)
655 at91_set_A_periph(AT91_PIN_PB1, 1);
656 if (pins & ATMEL_SSC_TD)
657 at91_set_A_periph(AT91_PIN_PB2, 1);
658 if (pins & ATMEL_SSC_RD)
659 at91_set_A_periph(AT91_PIN_PB3, 1);
660 if (pins & ATMEL_SSC_RK)
661 at91_set_A_periph(AT91_PIN_PB4, 1);
662 if (pins & ATMEL_SSC_RF)
663 at91_set_A_periph(AT91_PIN_PB5, 1);
664}
665
666static u64 ssc1_dmamask = DMA_BIT_MASK(32);
667
668static struct resource ssc1_resources[] = {
669 [0] = {
670 .start = AT91RM9200_BASE_SSC1,
671 .end = AT91RM9200_BASE_SSC1 + SZ_16K - 1,
672 .flags = IORESOURCE_MEM,
673 },
674 [1] = {
675 .start = AT91RM9200_ID_SSC1,
676 .end = AT91RM9200_ID_SSC1,
677 .flags = IORESOURCE_IRQ,
678 },
679};
680
681static struct platform_device at91rm9200_ssc1_device = {
682 .name = "ssc",
683 .id = 1,
684 .dev = {
685 .dma_mask = &ssc1_dmamask,
686 .coherent_dma_mask = DMA_BIT_MASK(32),
687 },
688 .resource = ssc1_resources,
689 .num_resources = ARRAY_SIZE(ssc1_resources),
690};
691
692static inline void configure_ssc1_pins(unsigned pins)
693{
694 if (pins & ATMEL_SSC_TF)
695 at91_set_A_periph(AT91_PIN_PB6, 1);
696 if (pins & ATMEL_SSC_TK)
697 at91_set_A_periph(AT91_PIN_PB7, 1);
698 if (pins & ATMEL_SSC_TD)
699 at91_set_A_periph(AT91_PIN_PB8, 1);
700 if (pins & ATMEL_SSC_RD)
701 at91_set_A_periph(AT91_PIN_PB9, 1);
702 if (pins & ATMEL_SSC_RK)
703 at91_set_A_periph(AT91_PIN_PB10, 1);
704 if (pins & ATMEL_SSC_RF)
705 at91_set_A_periph(AT91_PIN_PB11, 1);
706}
707
708static u64 ssc2_dmamask = DMA_BIT_MASK(32);
709
710static struct resource ssc2_resources[] = {
711 [0] = {
712 .start = AT91RM9200_BASE_SSC2,
713 .end = AT91RM9200_BASE_SSC2 + SZ_16K - 1,
714 .flags = IORESOURCE_MEM,
715 },
716 [1] = {
717 .start = AT91RM9200_ID_SSC2,
718 .end = AT91RM9200_ID_SSC2,
719 .flags = IORESOURCE_IRQ,
720 },
721};
722
723static struct platform_device at91rm9200_ssc2_device = {
724 .name = "ssc",
725 .id = 2,
726 .dev = {
727 .dma_mask = &ssc2_dmamask,
728 .coherent_dma_mask = DMA_BIT_MASK(32),
729 },
730 .resource = ssc2_resources,
731 .num_resources = ARRAY_SIZE(ssc2_resources),
732};
733
734static inline void configure_ssc2_pins(unsigned pins)
735{
736 if (pins & ATMEL_SSC_TF)
737 at91_set_A_periph(AT91_PIN_PB12, 1);
738 if (pins & ATMEL_SSC_TK)
739 at91_set_A_periph(AT91_PIN_PB13, 1);
740 if (pins & ATMEL_SSC_TD)
741 at91_set_A_periph(AT91_PIN_PB14, 1);
742 if (pins & ATMEL_SSC_RD)
743 at91_set_A_periph(AT91_PIN_PB15, 1);
744 if (pins & ATMEL_SSC_RK)
745 at91_set_A_periph(AT91_PIN_PB16, 1);
746 if (pins & ATMEL_SSC_RF)
747 at91_set_A_periph(AT91_PIN_PB17, 1);
748}
622 749
623void __init at91_init_leds(u8 cpu_led, u8 timer_led) 750/*
751 * SSC controllers are accessed through library code, instead of any
752 * kind of all-singing/all-dancing driver. For example one could be
753 * used by a particular I2S audio codec's driver, while another one
754 * on the same system might be used by a custom data capture driver.
755 */
756void __init at91_add_device_ssc(unsigned id, unsigned pins)
624{ 757{
625 /* Enable GPIO to access the LEDs */ 758 struct platform_device *pdev;
626 at91_set_gpio_output(cpu_led, 1);
627 at91_set_gpio_output(timer_led, 1);
628 759
629 at91_leds_cpu = cpu_led; 760 /*
630 at91_leds_timer = timer_led; 761 * NOTE: caller is responsible for passing information matching
762 * "pins" to whatever will be using each particular controller.
763 */
764 switch (id) {
765 case AT91RM9200_ID_SSC0:
766 pdev = &at91rm9200_ssc0_device;
767 configure_ssc0_pins(pins);
768 at91_clock_associate("ssc0_clk", &pdev->dev, "ssc");
769 break;
770 case AT91RM9200_ID_SSC1:
771 pdev = &at91rm9200_ssc1_device;
772 configure_ssc1_pins(pins);
773 at91_clock_associate("ssc1_clk", &pdev->dev, "ssc");
774 break;
775 case AT91RM9200_ID_SSC2:
776 pdev = &at91rm9200_ssc2_device;
777 configure_ssc2_pins(pins);
778 at91_clock_associate("ssc2_clk", &pdev->dev, "ssc");
779 break;
780 default:
781 return;
782 }
783
784 platform_device_register(pdev);
631} 785}
786
632#else 787#else
633void __init at91_init_leds(u8 cpu_led, u8 timer_led) {} 788void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
634#endif 789#endif
635 790
636 791
@@ -658,12 +813,15 @@ static struct atmel_uart_data dbgu_data = {
658 .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), 813 .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
659}; 814};
660 815
816static u64 dbgu_dmamask = DMA_BIT_MASK(32);
817
661static struct platform_device at91rm9200_dbgu_device = { 818static struct platform_device at91rm9200_dbgu_device = {
662 .name = "atmel_usart", 819 .name = "atmel_usart",
663 .id = 0, 820 .id = 0,
664 .dev = { 821 .dev = {
665 .platform_data = &dbgu_data, 822 .dma_mask = &dbgu_dmamask,
666 .coherent_dma_mask = 0xffffffff, 823 .coherent_dma_mask = DMA_BIT_MASK(32),
824 .platform_data = &dbgu_data,
667 }, 825 },
668 .resource = dbgu_resources, 826 .resource = dbgu_resources,
669 .num_resources = ARRAY_SIZE(dbgu_resources), 827 .num_resources = ARRAY_SIZE(dbgu_resources),
@@ -693,28 +851,35 @@ static struct atmel_uart_data uart0_data = {
693 .use_dma_rx = 1, 851 .use_dma_rx = 1,
694}; 852};
695 853
854static u64 uart0_dmamask = DMA_BIT_MASK(32);
855
696static struct platform_device at91rm9200_uart0_device = { 856static struct platform_device at91rm9200_uart0_device = {
697 .name = "atmel_usart", 857 .name = "atmel_usart",
698 .id = 1, 858 .id = 1,
699 .dev = { 859 .dev = {
700 .platform_data = &uart0_data, 860 .dma_mask = &uart0_dmamask,
701 .coherent_dma_mask = 0xffffffff, 861 .coherent_dma_mask = DMA_BIT_MASK(32),
862 .platform_data = &uart0_data,
702 }, 863 },
703 .resource = uart0_resources, 864 .resource = uart0_resources,
704 .num_resources = ARRAY_SIZE(uart0_resources), 865 .num_resources = ARRAY_SIZE(uart0_resources),
705}; 866};
706 867
707static inline void configure_usart0_pins(void) 868static inline void configure_usart0_pins(unsigned pins)
708{ 869{
709 at91_set_A_periph(AT91_PIN_PA17, 1); /* TXD0 */ 870 at91_set_A_periph(AT91_PIN_PA17, 1); /* TXD0 */
710 at91_set_A_periph(AT91_PIN_PA18, 0); /* RXD0 */ 871 at91_set_A_periph(AT91_PIN_PA18, 0); /* RXD0 */
711 at91_set_A_periph(AT91_PIN_PA20, 0); /* CTS0 */
712 872
713 /* 873 if (pins & ATMEL_UART_CTS)
714 * AT91RM9200 Errata #39 - RTS0 is not internally connected to PA21. 874 at91_set_A_periph(AT91_PIN_PA20, 0); /* CTS0 */
715 * We need to drive the pin manually. Default is off (RTS is active low). 875
716 */ 876 if (pins & ATMEL_UART_RTS) {
717 at91_set_gpio_output(AT91_PIN_PA21, 1); 877 /*
878 * AT91RM9200 Errata #39 - RTS0 is not internally connected to PA21.
879 * We need to drive the pin manually. Default is off (RTS is active low).
880 */
881 at91_set_gpio_output(AT91_PIN_PA21, 1);
882 }
718} 883}
719 884
720static struct resource uart1_resources[] = { 885static struct resource uart1_resources[] = {
@@ -735,27 +900,37 @@ static struct atmel_uart_data uart1_data = {
735 .use_dma_rx = 1, 900 .use_dma_rx = 1,
736}; 901};
737 902
903static u64 uart1_dmamask = DMA_BIT_MASK(32);
904
738static struct platform_device at91rm9200_uart1_device = { 905static struct platform_device at91rm9200_uart1_device = {
739 .name = "atmel_usart", 906 .name = "atmel_usart",
740 .id = 2, 907 .id = 2,
741 .dev = { 908 .dev = {
742 .platform_data = &uart1_data, 909 .dma_mask = &uart1_dmamask,
743 .coherent_dma_mask = 0xffffffff, 910 .coherent_dma_mask = DMA_BIT_MASK(32),
911 .platform_data = &uart1_data,
744 }, 912 },
745 .resource = uart1_resources, 913 .resource = uart1_resources,
746 .num_resources = ARRAY_SIZE(uart1_resources), 914 .num_resources = ARRAY_SIZE(uart1_resources),
747}; 915};
748 916
749static inline void configure_usart1_pins(void) 917static inline void configure_usart1_pins(unsigned pins)
750{ 918{
751 at91_set_A_periph(AT91_PIN_PB18, 0); /* RI1 */
752 at91_set_A_periph(AT91_PIN_PB19, 0); /* DTR1 */
753 at91_set_A_periph(AT91_PIN_PB20, 1); /* TXD1 */ 919 at91_set_A_periph(AT91_PIN_PB20, 1); /* TXD1 */
754 at91_set_A_periph(AT91_PIN_PB21, 0); /* RXD1 */ 920 at91_set_A_periph(AT91_PIN_PB21, 0); /* RXD1 */
755 at91_set_A_periph(AT91_PIN_PB23, 0); /* DCD1 */ 921
756 at91_set_A_periph(AT91_PIN_PB24, 0); /* CTS1 */ 922 if (pins & ATMEL_UART_RI)
757 at91_set_A_periph(AT91_PIN_PB25, 0); /* DSR1 */ 923 at91_set_A_periph(AT91_PIN_PB18, 0); /* RI1 */
758 at91_set_A_periph(AT91_PIN_PB26, 0); /* RTS1 */ 924 if (pins & ATMEL_UART_DTR)
925 at91_set_A_periph(AT91_PIN_PB19, 0); /* DTR1 */
926 if (pins & ATMEL_UART_DCD)
927 at91_set_A_periph(AT91_PIN_PB23, 0); /* DCD1 */
928 if (pins & ATMEL_UART_CTS)
929 at91_set_A_periph(AT91_PIN_PB24, 0); /* CTS1 */
930 if (pins & ATMEL_UART_DSR)
931 at91_set_A_periph(AT91_PIN_PB25, 0); /* DSR1 */
932 if (pins & ATMEL_UART_RTS)
933 at91_set_A_periph(AT91_PIN_PB26, 0); /* RTS1 */
759} 934}
760 935
761static struct resource uart2_resources[] = { 936static struct resource uart2_resources[] = {
@@ -776,21 +951,29 @@ static struct atmel_uart_data uart2_data = {
776 .use_dma_rx = 1, 951 .use_dma_rx = 1,
777}; 952};
778 953
954static u64 uart2_dmamask = DMA_BIT_MASK(32);
955
779static struct platform_device at91rm9200_uart2_device = { 956static struct platform_device at91rm9200_uart2_device = {
780 .name = "atmel_usart", 957 .name = "atmel_usart",
781 .id = 3, 958 .id = 3,
782 .dev = { 959 .dev = {
783 .platform_data = &uart2_data, 960 .dma_mask = &uart2_dmamask,
784 .coherent_dma_mask = 0xffffffff, 961 .coherent_dma_mask = DMA_BIT_MASK(32),
962 .platform_data = &uart2_data,
785 }, 963 },
786 .resource = uart2_resources, 964 .resource = uart2_resources,
787 .num_resources = ARRAY_SIZE(uart2_resources), 965 .num_resources = ARRAY_SIZE(uart2_resources),
788}; 966};
789 967
790static inline void configure_usart2_pins(void) 968static inline void configure_usart2_pins(unsigned pins)
791{ 969{
792 at91_set_A_periph(AT91_PIN_PA22, 0); /* RXD2 */ 970 at91_set_A_periph(AT91_PIN_PA22, 0); /* RXD2 */
793 at91_set_A_periph(AT91_PIN_PA23, 1); /* TXD2 */ 971 at91_set_A_periph(AT91_PIN_PA23, 1); /* TXD2 */
972
973 if (pins & ATMEL_UART_CTS)
974 at91_set_B_periph(AT91_PIN_PA30, 0); /* CTS2 */
975 if (pins & ATMEL_UART_RTS)
976 at91_set_B_periph(AT91_PIN_PA31, 0); /* RTS2 */
794} 977}
795 978
796static struct resource uart3_resources[] = { 979static struct resource uart3_resources[] = {
@@ -811,27 +994,35 @@ static struct atmel_uart_data uart3_data = {
811 .use_dma_rx = 1, 994 .use_dma_rx = 1,
812}; 995};
813 996
997static u64 uart3_dmamask = DMA_BIT_MASK(32);
998
814static struct platform_device at91rm9200_uart3_device = { 999static struct platform_device at91rm9200_uart3_device = {
815 .name = "atmel_usart", 1000 .name = "atmel_usart",
816 .id = 4, 1001 .id = 4,
817 .dev = { 1002 .dev = {
818 .platform_data = &uart3_data, 1003 .dma_mask = &uart3_dmamask,
819 .coherent_dma_mask = 0xffffffff, 1004 .coherent_dma_mask = DMA_BIT_MASK(32),
1005 .platform_data = &uart3_data,
820 }, 1006 },
821 .resource = uart3_resources, 1007 .resource = uart3_resources,
822 .num_resources = ARRAY_SIZE(uart3_resources), 1008 .num_resources = ARRAY_SIZE(uart3_resources),
823}; 1009};
824 1010
825static inline void configure_usart3_pins(void) 1011static inline void configure_usart3_pins(unsigned pins)
826{ 1012{
827 at91_set_B_periph(AT91_PIN_PA5, 1); /* TXD3 */ 1013 at91_set_B_periph(AT91_PIN_PA5, 1); /* TXD3 */
828 at91_set_B_periph(AT91_PIN_PA6, 0); /* RXD3 */ 1014 at91_set_B_periph(AT91_PIN_PA6, 0); /* RXD3 */
1015
1016 if (pins & ATMEL_UART_CTS)
1017 at91_set_B_periph(AT91_PIN_PB1, 0); /* CTS3 */
1018 if (pins & ATMEL_UART_RTS)
1019 at91_set_B_periph(AT91_PIN_PB0, 0); /* RTS3 */
829} 1020}
830 1021
831struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ 1022static struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
832struct platform_device *atmel_default_console_device; /* the serial console device */ 1023struct platform_device *atmel_default_console_device; /* the serial console device */
833 1024
834void __init at91_init_serial(struct at91_uart_config *config) 1025void __init __deprecated at91_init_serial(struct at91_uart_config *config)
835{ 1026{
836 int i; 1027 int i;
837 1028
@@ -839,22 +1030,22 @@ void __init at91_init_serial(struct at91_uart_config *config)
839 for (i = 0; i < config->nr_tty; i++) { 1030 for (i = 0; i < config->nr_tty; i++) {
840 switch (config->tty_map[i]) { 1031 switch (config->tty_map[i]) {
841 case 0: 1032 case 0:
842 configure_usart0_pins(); 1033 configure_usart0_pins(ATMEL_UART_CTS | ATMEL_UART_RTS);
843 at91_uarts[i] = &at91rm9200_uart0_device; 1034 at91_uarts[i] = &at91rm9200_uart0_device;
844 at91_clock_associate("usart0_clk", &at91rm9200_uart0_device.dev, "usart"); 1035 at91_clock_associate("usart0_clk", &at91rm9200_uart0_device.dev, "usart");
845 break; 1036 break;
846 case 1: 1037 case 1:
847 configure_usart1_pins(); 1038 configure_usart1_pins(ATMEL_UART_CTS | ATMEL_UART_RTS | ATMEL_UART_DSR | ATMEL_UART_DTR | ATMEL_UART_DCD | ATMEL_UART_RI);
848 at91_uarts[i] = &at91rm9200_uart1_device; 1039 at91_uarts[i] = &at91rm9200_uart1_device;
849 at91_clock_associate("usart1_clk", &at91rm9200_uart1_device.dev, "usart"); 1040 at91_clock_associate("usart1_clk", &at91rm9200_uart1_device.dev, "usart");
850 break; 1041 break;
851 case 2: 1042 case 2:
852 configure_usart2_pins(); 1043 configure_usart2_pins(0);
853 at91_uarts[i] = &at91rm9200_uart2_device; 1044 at91_uarts[i] = &at91rm9200_uart2_device;
854 at91_clock_associate("usart2_clk", &at91rm9200_uart2_device.dev, "usart"); 1045 at91_clock_associate("usart2_clk", &at91rm9200_uart2_device.dev, "usart");
855 break; 1046 break;
856 case 3: 1047 case 3:
857 configure_usart3_pins(); 1048 configure_usart3_pins(0);
858 at91_uarts[i] = &at91rm9200_uart3_device; 1049 at91_uarts[i] = &at91rm9200_uart3_device;
859 at91_clock_associate("usart3_clk", &at91rm9200_uart3_device.dev, "usart"); 1050 at91_clock_associate("usart3_clk", &at91rm9200_uart3_device.dev, "usart");
860 break; 1051 break;
@@ -876,6 +1067,53 @@ void __init at91_init_serial(struct at91_uart_config *config)
876 printk(KERN_INFO "AT91: No default serial console defined.\n"); 1067 printk(KERN_INFO "AT91: No default serial console defined.\n");
877} 1068}
878 1069
1070void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
1071{
1072 struct platform_device *pdev;
1073
1074 switch (id) {
1075 case 0: /* DBGU */
1076 pdev = &at91rm9200_dbgu_device;
1077 configure_dbgu_pins();
1078 at91_clock_associate("mck", &pdev->dev, "usart");
1079 break;
1080 case AT91RM9200_ID_US0:
1081 pdev = &at91rm9200_uart0_device;
1082 configure_usart0_pins(pins);
1083 at91_clock_associate("usart0_clk", &pdev->dev, "usart");
1084 break;
1085 case AT91RM9200_ID_US1:
1086 pdev = &at91rm9200_uart1_device;
1087 configure_usart1_pins(pins);
1088 at91_clock_associate("usart1_clk", &pdev->dev, "usart");
1089 break;
1090 case AT91RM9200_ID_US2:
1091 pdev = &at91rm9200_uart2_device;
1092 configure_usart2_pins(pins);
1093 at91_clock_associate("usart2_clk", &pdev->dev, "usart");
1094 break;
1095 case AT91RM9200_ID_US3:
1096 pdev = &at91rm9200_uart3_device;
1097 configure_usart3_pins(pins);
1098 at91_clock_associate("usart3_clk", &pdev->dev, "usart");
1099 break;
1100 default:
1101 return;
1102 }
1103 pdev->id = portnr; /* update to mapped ID */
1104
1105 if (portnr < ATMEL_MAX_UART)
1106 at91_uarts[portnr] = pdev;
1107}
1108
1109void __init at91_set_serial_console(unsigned portnr)
1110{
1111 if (portnr < ATMEL_MAX_UART)
1112 atmel_default_console_device = at91_uarts[portnr];
1113 if (!atmel_default_console_device)
1114 printk(KERN_INFO "AT91: No default serial console defined.\n");
1115}
1116
879void __init at91_add_device_serial(void) 1117void __init at91_add_device_serial(void)
880{ 1118{
881 int i; 1119 int i;
@@ -886,7 +1124,9 @@ void __init at91_add_device_serial(void)
886 } 1124 }
887} 1125}
888#else 1126#else
889void __init at91_init_serial(struct at91_uart_config *config) {} 1127void __init __deprecated at91_init_serial(struct at91_uart_config *config) {}
1128void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
1129void __init at91_set_serial_console(unsigned portnr) {}
890void __init at91_add_device_serial(void) {} 1130void __init at91_add_device_serial(void) {}
891#endif 1131#endif
892 1132
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c
index e47381e8aaba..18d06612ce8a 100644
--- a/arch/arm/mach-at91/at91sam9260.c
+++ b/arch/arm/mach-at91/at91sam9260.c
@@ -327,30 +327,30 @@ void __init at91sam9260_initialize(unsigned long main_clock)
327static unsigned int at91sam9260_default_irq_priority[NR_AIC_IRQS] __initdata = { 327static unsigned int at91sam9260_default_irq_priority[NR_AIC_IRQS] __initdata = {
328 7, /* Advanced Interrupt Controller */ 328 7, /* Advanced Interrupt Controller */
329 7, /* System Peripherals */ 329 7, /* System Peripherals */
330 0, /* Parallel IO Controller A */ 330 1, /* Parallel IO Controller A */
331 0, /* Parallel IO Controller B */ 331 1, /* Parallel IO Controller B */
332 0, /* Parallel IO Controller C */ 332 1, /* Parallel IO Controller C */
333 0, /* Analog-to-Digital Converter */ 333 0, /* Analog-to-Digital Converter */
334 6, /* USART 0 */ 334 5, /* USART 0 */
335 6, /* USART 1 */ 335 5, /* USART 1 */
336 6, /* USART 2 */ 336 5, /* USART 2 */
337 0, /* Multimedia Card Interface */ 337 0, /* Multimedia Card Interface */
338 4, /* USB Device Port */ 338 2, /* USB Device Port */
339 0, /* Two-Wire Interface */ 339 6, /* Two-Wire Interface */
340 6, /* Serial Peripheral Interface 0 */ 340 5, /* Serial Peripheral Interface 0 */
341 6, /* Serial Peripheral Interface 1 */ 341 5, /* Serial Peripheral Interface 1 */
342 5, /* Serial Synchronous Controller */ 342 5, /* Serial Synchronous Controller */
343 0, 343 0,
344 0, 344 0,
345 0, /* Timer Counter 0 */ 345 0, /* Timer Counter 0 */
346 0, /* Timer Counter 1 */ 346 0, /* Timer Counter 1 */
347 0, /* Timer Counter 2 */ 347 0, /* Timer Counter 2 */
348 3, /* USB Host port */ 348 2, /* USB Host port */
349 3, /* Ethernet */ 349 3, /* Ethernet */
350 0, /* Image Sensor Interface */ 350 0, /* Image Sensor Interface */
351 6, /* USART 3 */ 351 5, /* USART 3 */
352 6, /* USART 4 */ 352 5, /* USART 4 */
353 6, /* USART 5 */ 353 5, /* USART 5 */
354 0, /* Timer Counter 3 */ 354 0, /* Timer Counter 3 */
355 0, /* Timer Counter 4 */ 355 0, /* Timer Counter 4 */
356 0, /* Timer Counter 5 */ 356 0, /* Timer Counter 5 */
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
index 3091bf47d8c9..105f8403860b 100644
--- a/arch/arm/mach-at91/at91sam9260_devices.c
+++ b/arch/arm/mach-at91/at91sam9260_devices.c
@@ -12,6 +12,7 @@
12#include <asm/mach/arch.h> 12#include <asm/mach/arch.h>
13#include <asm/mach/map.h> 13#include <asm/mach/map.h>
14 14
15#include <linux/dma-mapping.h>
15#include <linux/platform_device.h> 16#include <linux/platform_device.h>
16#include <linux/i2c-gpio.h> 17#include <linux/i2c-gpio.h>
17 18
@@ -29,7 +30,7 @@
29 * -------------------------------------------------------------------- */ 30 * -------------------------------------------------------------------- */
30 31
31#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) 32#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
32static u64 ohci_dmamask = 0xffffffffUL; 33static u64 ohci_dmamask = DMA_BIT_MASK(32);
33static struct at91_usbh_data usbh_data; 34static struct at91_usbh_data usbh_data;
34 35
35static struct resource usbh_resources[] = { 36static struct resource usbh_resources[] = {
@@ -50,7 +51,7 @@ static struct platform_device at91_usbh_device = {
50 .id = -1, 51 .id = -1,
51 .dev = { 52 .dev = {
52 .dma_mask = &ohci_dmamask, 53 .dma_mask = &ohci_dmamask,
53 .coherent_dma_mask = 0xffffffff, 54 .coherent_dma_mask = DMA_BIT_MASK(32),
54 .platform_data = &usbh_data, 55 .platform_data = &usbh_data,
55 }, 56 },
56 .resource = usbh_resources, 57 .resource = usbh_resources,
@@ -125,7 +126,7 @@ void __init at91_add_device_udc(struct at91_udc_data *data) {}
125 * -------------------------------------------------------------------- */ 126 * -------------------------------------------------------------------- */
126 127
127#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) 128#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE)
128static u64 eth_dmamask = 0xffffffffUL; 129static u64 eth_dmamask = DMA_BIT_MASK(32);
129static struct at91_eth_data eth_data; 130static struct at91_eth_data eth_data;
130 131
131static struct resource eth_resources[] = { 132static struct resource eth_resources[] = {
@@ -146,7 +147,7 @@ static struct platform_device at91sam9260_eth_device = {
146 .id = -1, 147 .id = -1,
147 .dev = { 148 .dev = {
148 .dma_mask = &eth_dmamask, 149 .dma_mask = &eth_dmamask,
149 .coherent_dma_mask = 0xffffffff, 150 .coherent_dma_mask = DMA_BIT_MASK(32),
150 .platform_data = &eth_data, 151 .platform_data = &eth_data,
151 }, 152 },
152 .resource = eth_resources, 153 .resource = eth_resources,
@@ -199,7 +200,7 @@ void __init at91_add_device_eth(struct at91_eth_data *data) {}
199 * -------------------------------------------------------------------- */ 200 * -------------------------------------------------------------------- */
200 201
201#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) 202#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE)
202static u64 mmc_dmamask = 0xffffffffUL; 203static u64 mmc_dmamask = DMA_BIT_MASK(32);
203static struct at91_mmc_data mmc_data; 204static struct at91_mmc_data mmc_data;
204 205
205static struct resource mmc_resources[] = { 206static struct resource mmc_resources[] = {
@@ -220,7 +221,7 @@ static struct platform_device at91sam9260_mmc_device = {
220 .id = -1, 221 .id = -1,
221 .dev = { 222 .dev = {
222 .dma_mask = &mmc_dmamask, 223 .dma_mask = &mmc_dmamask,
223 .coherent_dma_mask = 0xffffffff, 224 .coherent_dma_mask = DMA_BIT_MASK(32),
224 .platform_data = &mmc_data, 225 .platform_data = &mmc_data,
225 }, 226 },
226 .resource = mmc_resources, 227 .resource = mmc_resources,
@@ -289,7 +290,7 @@ static struct at91_nand_data nand_data;
289static struct resource nand_resources[] = { 290static struct resource nand_resources[] = {
290 { 291 {
291 .start = NAND_BASE, 292 .start = NAND_BASE,
292 .end = NAND_BASE + SZ_8M - 1, 293 .end = NAND_BASE + SZ_256M - 1,
293 .flags = IORESOURCE_MEM, 294 .flags = IORESOURCE_MEM,
294 } 295 }
295}; 296};
@@ -312,7 +313,7 @@ void __init at91_add_device_nand(struct at91_nand_data *data)
312 return; 313 return;
313 314
314 csa = at91_sys_read(AT91_MATRIX_EBICSA); 315 csa = at91_sys_read(AT91_MATRIX_EBICSA);
315 at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC); 316 at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA);
316 317
317 /* set the bus interface characteristics */ 318 /* set the bus interface characteristics */
318 at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0) 319 at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0)
@@ -431,7 +432,7 @@ void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
431 * -------------------------------------------------------------------- */ 432 * -------------------------------------------------------------------- */
432 433
433#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) 434#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
434static u64 spi_dmamask = 0xffffffffUL; 435static u64 spi_dmamask = DMA_BIT_MASK(32);
435 436
436static struct resource spi0_resources[] = { 437static struct resource spi0_resources[] = {
437 [0] = { 438 [0] = {
@@ -451,7 +452,7 @@ static struct platform_device at91sam9260_spi0_device = {
451 .id = 0, 452 .id = 0,
452 .dev = { 453 .dev = {
453 .dma_mask = &spi_dmamask, 454 .dma_mask = &spi_dmamask,
454 .coherent_dma_mask = 0xffffffff, 455 .coherent_dma_mask = DMA_BIT_MASK(32),
455 }, 456 },
456 .resource = spi0_resources, 457 .resource = spi0_resources,
457 .num_resources = ARRAY_SIZE(spi0_resources), 458 .num_resources = ARRAY_SIZE(spi0_resources),
@@ -477,7 +478,7 @@ static struct platform_device at91sam9260_spi1_device = {
477 .id = 1, 478 .id = 1,
478 .dev = { 479 .dev = {
479 .dma_mask = &spi_dmamask, 480 .dma_mask = &spi_dmamask,
480 .coherent_dma_mask = 0xffffffff, 481 .coherent_dma_mask = DMA_BIT_MASK(32),
481 }, 482 },
482 .resource = spi1_resources, 483 .resource = spi1_resources,
483 .num_resources = ARRAY_SIZE(spi1_resources), 484 .num_resources = ARRAY_SIZE(spi1_resources),
@@ -539,24 +540,126 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
539 540
540 541
541/* -------------------------------------------------------------------- 542/* --------------------------------------------------------------------
542 * LEDs 543 * RTT
543 * -------------------------------------------------------------------- */ 544 * -------------------------------------------------------------------- */
544 545
545#if defined(CONFIG_LEDS) 546static struct resource rtt_resources[] = {
546u8 at91_leds_cpu; 547 {
547u8 at91_leds_timer; 548 .start = AT91_BASE_SYS + AT91_RTT,
549 .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1,
550 .flags = IORESOURCE_MEM,
551 }
552};
548 553
549void __init at91_init_leds(u8 cpu_led, u8 timer_led) 554static struct platform_device at91sam9260_rtt_device = {
555 .name = "at91_rtt",
556 .id = -1,
557 .resource = rtt_resources,
558 .num_resources = ARRAY_SIZE(rtt_resources),
559};
560
561static void __init at91_add_device_rtt(void)
550{ 562{
551 /* Enable GPIO to access the LEDs */ 563 platform_device_register(&at91sam9260_rtt_device);
552 at91_set_gpio_output(cpu_led, 1); 564}
553 at91_set_gpio_output(timer_led, 1); 565
554 566
555 at91_leds_cpu = cpu_led; 567/* --------------------------------------------------------------------
556 at91_leds_timer = timer_led; 568 * Watchdog
569 * -------------------------------------------------------------------- */
570
571#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE)
572static struct platform_device at91sam9260_wdt_device = {
573 .name = "at91_wdt",
574 .id = -1,
575 .num_resources = 0,
576};
577
578static void __init at91_add_device_watchdog(void)
579{
580 platform_device_register(&at91sam9260_wdt_device);
557} 581}
558#else 582#else
559void __init at91_init_leds(u8 cpu_led, u8 timer_led) {} 583static void __init at91_add_device_watchdog(void) {}
584#endif
585
586
587/* --------------------------------------------------------------------
588 * SSC -- Synchronous Serial Controller
589 * -------------------------------------------------------------------- */
590
591#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE)
592static u64 ssc_dmamask = DMA_BIT_MASK(32);
593
594static struct resource ssc_resources[] = {
595 [0] = {
596 .start = AT91SAM9260_BASE_SSC,
597 .end = AT91SAM9260_BASE_SSC + SZ_16K - 1,
598 .flags = IORESOURCE_MEM,
599 },
600 [1] = {
601 .start = AT91SAM9260_ID_SSC,
602 .end = AT91SAM9260_ID_SSC,
603 .flags = IORESOURCE_IRQ,
604 },
605};
606
607static struct platform_device at91sam9260_ssc_device = {
608 .name = "ssc",
609 .id = 0,
610 .dev = {
611 .dma_mask = &ssc_dmamask,
612 .coherent_dma_mask = DMA_BIT_MASK(32),
613 },
614 .resource = ssc_resources,
615 .num_resources = ARRAY_SIZE(ssc_resources),
616};
617
618static inline void configure_ssc_pins(unsigned pins)
619{
620 if (pins & ATMEL_SSC_TF)
621 at91_set_A_periph(AT91_PIN_PB17, 1);
622 if (pins & ATMEL_SSC_TK)
623 at91_set_A_periph(AT91_PIN_PB16, 1);
624 if (pins & ATMEL_SSC_TD)
625 at91_set_A_periph(AT91_PIN_PB18, 1);
626 if (pins & ATMEL_SSC_RD)
627 at91_set_A_periph(AT91_PIN_PB19, 1);
628 if (pins & ATMEL_SSC_RK)
629 at91_set_A_periph(AT91_PIN_PB20, 1);
630 if (pins & ATMEL_SSC_RF)
631 at91_set_A_periph(AT91_PIN_PB21, 1);
632}
633
634/*
635 * SSC controllers are accessed through library code, instead of any
636 * kind of all-singing/all-dancing driver. For example one could be
637 * used by a particular I2S audio codec's driver, while another one
638 * on the same system might be used by a custom data capture driver.
639 */
640void __init at91_add_device_ssc(unsigned id, unsigned pins)
641{
642 struct platform_device *pdev;
643
644 /*
645 * NOTE: caller is responsible for passing information matching
646 * "pins" to whatever will be using each particular controller.
647 */
648 switch (id) {
649 case AT91SAM9260_ID_SSC:
650 pdev = &at91sam9260_ssc_device;
651 configure_ssc_pins(pins);
652 at91_clock_associate("ssc_clk", &pdev->dev, "pclk");
653 break;
654 default:
655 return;
656 }
657
658 platform_device_register(pdev);
659}
660
661#else
662void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
560#endif 663#endif
561 664
562 665
@@ -583,12 +686,15 @@ static struct atmel_uart_data dbgu_data = {
583 .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), 686 .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
584}; 687};
585 688
689static u64 dbgu_dmamask = DMA_BIT_MASK(32);
690
586static struct platform_device at91sam9260_dbgu_device = { 691static struct platform_device at91sam9260_dbgu_device = {
587 .name = "atmel_usart", 692 .name = "atmel_usart",
588 .id = 0, 693 .id = 0,
589 .dev = { 694 .dev = {
590 .platform_data = &dbgu_data, 695 .dma_mask = &dbgu_dmamask,
591 .coherent_dma_mask = 0xffffffff, 696 .coherent_dma_mask = DMA_BIT_MASK(32),
697 .platform_data = &dbgu_data,
592 }, 698 },
593 .resource = dbgu_resources, 699 .resource = dbgu_resources,
594 .num_resources = ARRAY_SIZE(dbgu_resources), 700 .num_resources = ARRAY_SIZE(dbgu_resources),
@@ -618,27 +724,37 @@ static struct atmel_uart_data uart0_data = {
618 .use_dma_rx = 1, 724 .use_dma_rx = 1,
619}; 725};
620 726
727static u64 uart0_dmamask = DMA_BIT_MASK(32);
728
621static struct platform_device at91sam9260_uart0_device = { 729static struct platform_device at91sam9260_uart0_device = {
622 .name = "atmel_usart", 730 .name = "atmel_usart",
623 .id = 1, 731 .id = 1,
624 .dev = { 732 .dev = {
625 .platform_data = &uart0_data, 733 .dma_mask = &uart0_dmamask,
626 .coherent_dma_mask = 0xffffffff, 734 .coherent_dma_mask = DMA_BIT_MASK(32),
735 .platform_data = &uart0_data,
627 }, 736 },
628 .resource = uart0_resources, 737 .resource = uart0_resources,
629 .num_resources = ARRAY_SIZE(uart0_resources), 738 .num_resources = ARRAY_SIZE(uart0_resources),
630}; 739};
631 740
632static inline void configure_usart0_pins(void) 741static inline void configure_usart0_pins(unsigned pins)
633{ 742{
634 at91_set_A_periph(AT91_PIN_PB4, 1); /* TXD0 */ 743 at91_set_A_periph(AT91_PIN_PB4, 1); /* TXD0 */
635 at91_set_A_periph(AT91_PIN_PB5, 0); /* RXD0 */ 744 at91_set_A_periph(AT91_PIN_PB5, 0); /* RXD0 */
636 at91_set_A_periph(AT91_PIN_PB26, 0); /* RTS0 */ 745
637 at91_set_A_periph(AT91_PIN_PB27, 0); /* CTS0 */ 746 if (pins & ATMEL_UART_RTS)
638 at91_set_A_periph(AT91_PIN_PB24, 0); /* DTR0 */ 747 at91_set_A_periph(AT91_PIN_PB26, 0); /* RTS0 */
639 at91_set_A_periph(AT91_PIN_PB22, 0); /* DSR0 */ 748 if (pins & ATMEL_UART_CTS)
640 at91_set_A_periph(AT91_PIN_PB23, 0); /* DCD0 */ 749 at91_set_A_periph(AT91_PIN_PB27, 0); /* CTS0 */
641 at91_set_A_periph(AT91_PIN_PB25, 0); /* RI0 */ 750 if (pins & ATMEL_UART_DTR)
751 at91_set_A_periph(AT91_PIN_PB24, 0); /* DTR0 */
752 if (pins & ATMEL_UART_DSR)
753 at91_set_A_periph(AT91_PIN_PB22, 0); /* DSR0 */
754 if (pins & ATMEL_UART_DCD)
755 at91_set_A_periph(AT91_PIN_PB23, 0); /* DCD0 */
756 if (pins & ATMEL_UART_RI)
757 at91_set_A_periph(AT91_PIN_PB25, 0); /* RI0 */
642} 758}
643 759
644static struct resource uart1_resources[] = { 760static struct resource uart1_resources[] = {
@@ -659,23 +775,29 @@ static struct atmel_uart_data uart1_data = {
659 .use_dma_rx = 1, 775 .use_dma_rx = 1,
660}; 776};
661 777
778static u64 uart1_dmamask = DMA_BIT_MASK(32);
779
662static struct platform_device at91sam9260_uart1_device = { 780static struct platform_device at91sam9260_uart1_device = {
663 .name = "atmel_usart", 781 .name = "atmel_usart",
664 .id = 2, 782 .id = 2,
665 .dev = { 783 .dev = {
666 .platform_data = &uart1_data, 784 .dma_mask = &uart1_dmamask,
667 .coherent_dma_mask = 0xffffffff, 785 .coherent_dma_mask = DMA_BIT_MASK(32),
786 .platform_data = &uart1_data,
668 }, 787 },
669 .resource = uart1_resources, 788 .resource = uart1_resources,
670 .num_resources = ARRAY_SIZE(uart1_resources), 789 .num_resources = ARRAY_SIZE(uart1_resources),
671}; 790};
672 791
673static inline void configure_usart1_pins(void) 792static inline void configure_usart1_pins(unsigned pins)
674{ 793{
675 at91_set_A_periph(AT91_PIN_PB6, 1); /* TXD1 */ 794 at91_set_A_periph(AT91_PIN_PB6, 1); /* TXD1 */
676 at91_set_A_periph(AT91_PIN_PB7, 0); /* RXD1 */ 795 at91_set_A_periph(AT91_PIN_PB7, 0); /* RXD1 */
677 at91_set_A_periph(AT91_PIN_PB28, 0); /* RTS1 */ 796
678 at91_set_A_periph(AT91_PIN_PB29, 0); /* CTS1 */ 797 if (pins & ATMEL_UART_RTS)
798 at91_set_A_periph(AT91_PIN_PB28, 0); /* RTS1 */
799 if (pins & ATMEL_UART_CTS)
800 at91_set_A_periph(AT91_PIN_PB29, 0); /* CTS1 */
679} 801}
680 802
681static struct resource uart2_resources[] = { 803static struct resource uart2_resources[] = {
@@ -696,21 +818,29 @@ static struct atmel_uart_data uart2_data = {
696 .use_dma_rx = 1, 818 .use_dma_rx = 1,
697}; 819};
698 820
821static u64 uart2_dmamask = DMA_BIT_MASK(32);
822
699static struct platform_device at91sam9260_uart2_device = { 823static struct platform_device at91sam9260_uart2_device = {
700 .name = "atmel_usart", 824 .name = "atmel_usart",
701 .id = 3, 825 .id = 3,
702 .dev = { 826 .dev = {
703 .platform_data = &uart2_data, 827 .dma_mask = &uart2_dmamask,
704 .coherent_dma_mask = 0xffffffff, 828 .coherent_dma_mask = DMA_BIT_MASK(32),
829 .platform_data = &uart2_data,
705 }, 830 },
706 .resource = uart2_resources, 831 .resource = uart2_resources,
707 .num_resources = ARRAY_SIZE(uart2_resources), 832 .num_resources = ARRAY_SIZE(uart2_resources),
708}; 833};
709 834
710static inline void configure_usart2_pins(void) 835static inline void configure_usart2_pins(unsigned pins)
711{ 836{
712 at91_set_A_periph(AT91_PIN_PB8, 1); /* TXD2 */ 837 at91_set_A_periph(AT91_PIN_PB8, 1); /* TXD2 */
713 at91_set_A_periph(AT91_PIN_PB9, 0); /* RXD2 */ 838 at91_set_A_periph(AT91_PIN_PB9, 0); /* RXD2 */
839
840 if (pins & ATMEL_UART_RTS)
841 at91_set_A_periph(AT91_PIN_PA4, 0); /* RTS2 */
842 if (pins & ATMEL_UART_CTS)
843 at91_set_A_periph(AT91_PIN_PA5, 0); /* CTS2 */
714} 844}
715 845
716static struct resource uart3_resources[] = { 846static struct resource uart3_resources[] = {
@@ -731,21 +861,29 @@ static struct atmel_uart_data uart3_data = {
731 .use_dma_rx = 1, 861 .use_dma_rx = 1,
732}; 862};
733 863
864static u64 uart3_dmamask = DMA_BIT_MASK(32);
865
734static struct platform_device at91sam9260_uart3_device = { 866static struct platform_device at91sam9260_uart3_device = {
735 .name = "atmel_usart", 867 .name = "atmel_usart",
736 .id = 4, 868 .id = 4,
737 .dev = { 869 .dev = {
738 .platform_data = &uart3_data, 870 .dma_mask = &uart3_dmamask,
739 .coherent_dma_mask = 0xffffffff, 871 .coherent_dma_mask = DMA_BIT_MASK(32),
872 .platform_data = &uart3_data,
740 }, 873 },
741 .resource = uart3_resources, 874 .resource = uart3_resources,
742 .num_resources = ARRAY_SIZE(uart3_resources), 875 .num_resources = ARRAY_SIZE(uart3_resources),
743}; 876};
744 877
745static inline void configure_usart3_pins(void) 878static inline void configure_usart3_pins(unsigned pins)
746{ 879{
747 at91_set_A_periph(AT91_PIN_PB10, 1); /* TXD3 */ 880 at91_set_A_periph(AT91_PIN_PB10, 1); /* TXD3 */
748 at91_set_A_periph(AT91_PIN_PB11, 0); /* RXD3 */ 881 at91_set_A_periph(AT91_PIN_PB11, 0); /* RXD3 */
882
883 if (pins & ATMEL_UART_RTS)
884 at91_set_B_periph(AT91_PIN_PC8, 0); /* RTS3 */
885 if (pins & ATMEL_UART_CTS)
886 at91_set_B_periph(AT91_PIN_PC10, 0); /* CTS3 */
749} 887}
750 888
751static struct resource uart4_resources[] = { 889static struct resource uart4_resources[] = {
@@ -766,12 +904,15 @@ static struct atmel_uart_data uart4_data = {
766 .use_dma_rx = 1, 904 .use_dma_rx = 1,
767}; 905};
768 906
907static u64 uart4_dmamask = DMA_BIT_MASK(32);
908
769static struct platform_device at91sam9260_uart4_device = { 909static struct platform_device at91sam9260_uart4_device = {
770 .name = "atmel_usart", 910 .name = "atmel_usart",
771 .id = 5, 911 .id = 5,
772 .dev = { 912 .dev = {
773 .platform_data = &uart4_data, 913 .dma_mask = &uart4_dmamask,
774 .coherent_dma_mask = 0xffffffff, 914 .coherent_dma_mask = DMA_BIT_MASK(32),
915 .platform_data = &uart4_data,
775 }, 916 },
776 .resource = uart4_resources, 917 .resource = uart4_resources,
777 .num_resources = ARRAY_SIZE(uart4_resources), 918 .num_resources = ARRAY_SIZE(uart4_resources),
@@ -801,12 +942,15 @@ static struct atmel_uart_data uart5_data = {
801 .use_dma_rx = 1, 942 .use_dma_rx = 1,
802}; 943};
803 944
945static u64 uart5_dmamask = DMA_BIT_MASK(32);
946
804static struct platform_device at91sam9260_uart5_device = { 947static struct platform_device at91sam9260_uart5_device = {
805 .name = "atmel_usart", 948 .name = "atmel_usart",
806 .id = 6, 949 .id = 6,
807 .dev = { 950 .dev = {
808 .platform_data = &uart5_data, 951 .dma_mask = &uart5_dmamask,
809 .coherent_dma_mask = 0xffffffff, 952 .coherent_dma_mask = DMA_BIT_MASK(32),
953 .platform_data = &uart5_data,
810 }, 954 },
811 .resource = uart5_resources, 955 .resource = uart5_resources,
812 .num_resources = ARRAY_SIZE(uart5_resources), 956 .num_resources = ARRAY_SIZE(uart5_resources),
@@ -818,10 +962,10 @@ static inline void configure_usart5_pins(void)
818 at91_set_A_periph(AT91_PIN_PB13, 0); /* RXD5 */ 962 at91_set_A_periph(AT91_PIN_PB13, 0); /* RXD5 */
819} 963}
820 964
821struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ 965static struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
822struct platform_device *atmel_default_console_device; /* the serial console device */ 966struct platform_device *atmel_default_console_device; /* the serial console device */
823 967
824void __init at91_init_serial(struct at91_uart_config *config) 968void __init __deprecated at91_init_serial(struct at91_uart_config *config)
825{ 969{
826 int i; 970 int i;
827 971
@@ -829,22 +973,22 @@ void __init at91_init_serial(struct at91_uart_config *config)
829 for (i = 0; i < config->nr_tty; i++) { 973 for (i = 0; i < config->nr_tty; i++) {
830 switch (config->tty_map[i]) { 974 switch (config->tty_map[i]) {
831 case 0: 975 case 0:
832 configure_usart0_pins(); 976 configure_usart0_pins(ATMEL_UART_CTS | ATMEL_UART_RTS | ATMEL_UART_DSR | ATMEL_UART_DTR | ATMEL_UART_DCD | ATMEL_UART_RI);
833 at91_uarts[i] = &at91sam9260_uart0_device; 977 at91_uarts[i] = &at91sam9260_uart0_device;
834 at91_clock_associate("usart0_clk", &at91sam9260_uart0_device.dev, "usart"); 978 at91_clock_associate("usart0_clk", &at91sam9260_uart0_device.dev, "usart");
835 break; 979 break;
836 case 1: 980 case 1:
837 configure_usart1_pins(); 981 configure_usart1_pins(ATMEL_UART_CTS | ATMEL_UART_RTS);
838 at91_uarts[i] = &at91sam9260_uart1_device; 982 at91_uarts[i] = &at91sam9260_uart1_device;
839 at91_clock_associate("usart1_clk", &at91sam9260_uart1_device.dev, "usart"); 983 at91_clock_associate("usart1_clk", &at91sam9260_uart1_device.dev, "usart");
840 break; 984 break;
841 case 2: 985 case 2:
842 configure_usart2_pins(); 986 configure_usart2_pins(0);
843 at91_uarts[i] = &at91sam9260_uart2_device; 987 at91_uarts[i] = &at91sam9260_uart2_device;
844 at91_clock_associate("usart2_clk", &at91sam9260_uart2_device.dev, "usart"); 988 at91_clock_associate("usart2_clk", &at91sam9260_uart2_device.dev, "usart");
845 break; 989 break;
846 case 3: 990 case 3:
847 configure_usart3_pins(); 991 configure_usart3_pins(0);
848 at91_uarts[i] = &at91sam9260_uart3_device; 992 at91_uarts[i] = &at91sam9260_uart3_device;
849 at91_clock_associate("usart3_clk", &at91sam9260_uart3_device.dev, "usart"); 993 at91_clock_associate("usart3_clk", &at91sam9260_uart3_device.dev, "usart");
850 break; 994 break;
@@ -876,6 +1020,63 @@ void __init at91_init_serial(struct at91_uart_config *config)
876 printk(KERN_INFO "AT91: No default serial console defined.\n"); 1020 printk(KERN_INFO "AT91: No default serial console defined.\n");
877} 1021}
878 1022
1023void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
1024{
1025 struct platform_device *pdev;
1026
1027 switch (id) {
1028 case 0: /* DBGU */
1029 pdev = &at91sam9260_dbgu_device;
1030 configure_dbgu_pins();
1031 at91_clock_associate("mck", &pdev->dev, "usart");
1032 break;
1033 case AT91SAM9260_ID_US0:
1034 pdev = &at91sam9260_uart0_device;
1035 configure_usart0_pins(pins);
1036 at91_clock_associate("usart0_clk", &pdev->dev, "usart");
1037 break;
1038 case AT91SAM9260_ID_US1:
1039 pdev = &at91sam9260_uart1_device;
1040 configure_usart1_pins(pins);
1041 at91_clock_associate("usart1_clk", &pdev->dev, "usart");
1042 break;
1043 case AT91SAM9260_ID_US2:
1044 pdev = &at91sam9260_uart2_device;
1045 configure_usart2_pins(pins);
1046 at91_clock_associate("usart2_clk", &pdev->dev, "usart");
1047 break;
1048 case AT91SAM9260_ID_US3:
1049 pdev = &at91sam9260_uart3_device;
1050 configure_usart3_pins(pins);
1051 at91_clock_associate("usart3_clk", &pdev->dev, "usart");
1052 break;
1053 case AT91SAM9260_ID_US4:
1054 pdev = &at91sam9260_uart4_device;
1055 configure_usart4_pins();
1056 at91_clock_associate("usart4_clk", &pdev->dev, "usart");
1057 break;
1058 case AT91SAM9260_ID_US5:
1059 pdev = &at91sam9260_uart5_device;
1060 configure_usart5_pins();
1061 at91_clock_associate("usart5_clk", &pdev->dev, "usart");
1062 break;
1063 default:
1064 return;
1065 }
1066 pdev->id = portnr; /* update to mapped ID */
1067
1068 if (portnr < ATMEL_MAX_UART)
1069 at91_uarts[portnr] = pdev;
1070}
1071
1072void __init at91_set_serial_console(unsigned portnr)
1073{
1074 if (portnr < ATMEL_MAX_UART)
1075 atmel_default_console_device = at91_uarts[portnr];
1076 if (!atmel_default_console_device)
1077 printk(KERN_INFO "AT91: No default serial console defined.\n");
1078}
1079
879void __init at91_add_device_serial(void) 1080void __init at91_add_device_serial(void)
880{ 1081{
881 int i; 1082 int i;
@@ -886,7 +1087,9 @@ void __init at91_add_device_serial(void)
886 } 1087 }
887} 1088}
888#else 1089#else
889void __init at91_init_serial(struct at91_uart_config *config) {} 1090void __init __deprecated at91_init_serial(struct at91_uart_config *config) {}
1091void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
1092void __init at91_set_serial_console(unsigned portnr) {}
890void __init at91_add_device_serial(void) {} 1093void __init at91_add_device_serial(void) {}
891#endif 1094#endif
892 1095
@@ -898,6 +1101,8 @@ void __init at91_add_device_serial(void) {}
898 */ 1101 */
899static int __init at91_add_standard_devices(void) 1102static int __init at91_add_standard_devices(void)
900{ 1103{
1104 at91_add_device_rtt();
1105 at91_add_device_watchdog();
901 return 0; 1106 return 0;
902} 1107}
903 1108
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
index dfe8c39c9fb9..90b87e1877d9 100644
--- a/arch/arm/mach-at91/at91sam9261.c
+++ b/arch/arm/mach-at91/at91sam9261.c
@@ -279,25 +279,25 @@ void __init at91sam9261_initialize(unsigned long main_clock)
279static unsigned int at91sam9261_default_irq_priority[NR_AIC_IRQS] __initdata = { 279static unsigned int at91sam9261_default_irq_priority[NR_AIC_IRQS] __initdata = {
280 7, /* Advanced Interrupt Controller */ 280 7, /* Advanced Interrupt Controller */
281 7, /* System Peripherals */ 281 7, /* System Peripherals */
282 0, /* Parallel IO Controller A */ 282 1, /* Parallel IO Controller A */
283 0, /* Parallel IO Controller B */ 283 1, /* Parallel IO Controller B */
284 0, /* Parallel IO Controller C */ 284 1, /* Parallel IO Controller C */
285 0, 285 0,
286 6, /* USART 0 */ 286 5, /* USART 0 */
287 6, /* USART 1 */ 287 5, /* USART 1 */
288 6, /* USART 2 */ 288 5, /* USART 2 */
289 0, /* Multimedia Card Interface */ 289 0, /* Multimedia Card Interface */
290 4, /* USB Device Port */ 290 2, /* USB Device Port */
291 0, /* Two-Wire Interface */ 291 6, /* Two-Wire Interface */
292 6, /* Serial Peripheral Interface 0 */ 292 5, /* Serial Peripheral Interface 0 */
293 6, /* Serial Peripheral Interface 1 */ 293 5, /* Serial Peripheral Interface 1 */
294 5, /* Serial Synchronous Controller 0 */ 294 4, /* Serial Synchronous Controller 0 */
295 5, /* Serial Synchronous Controller 1 */ 295 4, /* Serial Synchronous Controller 1 */
296 5, /* Serial Synchronous Controller 2 */ 296 4, /* Serial Synchronous Controller 2 */
297 0, /* Timer Counter 0 */ 297 0, /* Timer Counter 0 */
298 0, /* Timer Counter 1 */ 298 0, /* Timer Counter 1 */
299 0, /* Timer Counter 2 */ 299 0, /* Timer Counter 2 */
300 3, /* USB Host port */ 300 2, /* USB Host port */
301 3, /* LCD Controller */ 301 3, /* LCD Controller */
302 0, 302 0,
303 0, 303 0,
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c
index 64979a9023c2..245641263fce 100644
--- a/arch/arm/mach-at91/at91sam9261_devices.c
+++ b/arch/arm/mach-at91/at91sam9261_devices.c
@@ -13,6 +13,7 @@
13#include <asm/mach/arch.h> 13#include <asm/mach/arch.h>
14#include <asm/mach/map.h> 14#include <asm/mach/map.h>
15 15
16#include <linux/dma-mapping.h>
16#include <linux/platform_device.h> 17#include <linux/platform_device.h>
17#include <linux/i2c-gpio.h> 18#include <linux/i2c-gpio.h>
18 19
@@ -33,7 +34,7 @@
33 * -------------------------------------------------------------------- */ 34 * -------------------------------------------------------------------- */
34 35
35#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) 36#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
36static u64 ohci_dmamask = 0xffffffffUL; 37static u64 ohci_dmamask = DMA_BIT_MASK(32);
37static struct at91_usbh_data usbh_data; 38static struct at91_usbh_data usbh_data;
38 39
39static struct resource usbh_resources[] = { 40static struct resource usbh_resources[] = {
@@ -54,7 +55,7 @@ static struct platform_device at91sam9261_usbh_device = {
54 .id = -1, 55 .id = -1,
55 .dev = { 56 .dev = {
56 .dma_mask = &ohci_dmamask, 57 .dma_mask = &ohci_dmamask,
57 .coherent_dma_mask = 0xffffffff, 58 .coherent_dma_mask = DMA_BIT_MASK(32),
58 .platform_data = &usbh_data, 59 .platform_data = &usbh_data,
59 }, 60 },
60 .resource = usbh_resources, 61 .resource = usbh_resources,
@@ -106,8 +107,6 @@ static struct platform_device at91sam9261_udc_device = {
106 107
107void __init at91_add_device_udc(struct at91_udc_data *data) 108void __init at91_add_device_udc(struct at91_udc_data *data)
108{ 109{
109 unsigned long x;
110
111 if (!data) 110 if (!data)
112 return; 111 return;
113 112
@@ -116,9 +115,7 @@ void __init at91_add_device_udc(struct at91_udc_data *data)
116 at91_set_deglitch(data->vbus_pin, 1); 115 at91_set_deglitch(data->vbus_pin, 1);
117 } 116 }
118 117
119 /* Pullup pin is handled internally */ 118 /* Pullup pin is handled internally by USB device peripheral */
120 x = at91_sys_read(AT91_MATRIX_USBPUCR);
121 at91_sys_write(AT91_MATRIX_USBPUCR, x | AT91_MATRIX_USBPUCR_PUON);
122 119
123 udc_data = *data; 120 udc_data = *data;
124 platform_device_register(&at91sam9261_udc_device); 121 platform_device_register(&at91sam9261_udc_device);
@@ -132,7 +129,7 @@ void __init at91_add_device_udc(struct at91_udc_data *data) {}
132 * -------------------------------------------------------------------- */ 129 * -------------------------------------------------------------------- */
133 130
134#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) 131#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE)
135static u64 mmc_dmamask = 0xffffffffUL; 132static u64 mmc_dmamask = DMA_BIT_MASK(32);
136static struct at91_mmc_data mmc_data; 133static struct at91_mmc_data mmc_data;
137 134
138static struct resource mmc_resources[] = { 135static struct resource mmc_resources[] = {
@@ -153,7 +150,7 @@ static struct platform_device at91sam9261_mmc_device = {
153 .id = -1, 150 .id = -1,
154 .dev = { 151 .dev = {
155 .dma_mask = &mmc_dmamask, 152 .dma_mask = &mmc_dmamask,
156 .coherent_dma_mask = 0xffffffff, 153 .coherent_dma_mask = DMA_BIT_MASK(32),
157 .platform_data = &mmc_data, 154 .platform_data = &mmc_data,
158 }, 155 },
159 .resource = mmc_resources, 156 .resource = mmc_resources,
@@ -232,7 +229,7 @@ void __init at91_add_device_nand(struct at91_nand_data *data)
232 return; 229 return;
233 230
234 csa = at91_sys_read(AT91_MATRIX_EBICSA); 231 csa = at91_sys_read(AT91_MATRIX_EBICSA);
235 at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC); 232 at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA);
236 233
237 /* set the bus interface characteristics */ 234 /* set the bus interface characteristics */
238 at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0) 235 at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0)
@@ -354,7 +351,7 @@ void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
354 * -------------------------------------------------------------------- */ 351 * -------------------------------------------------------------------- */
355 352
356#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) 353#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
357static u64 spi_dmamask = 0xffffffffUL; 354static u64 spi_dmamask = DMA_BIT_MASK(32);
358 355
359static struct resource spi0_resources[] = { 356static struct resource spi0_resources[] = {
360 [0] = { 357 [0] = {
@@ -374,7 +371,7 @@ static struct platform_device at91sam9261_spi0_device = {
374 .id = 0, 371 .id = 0,
375 .dev = { 372 .dev = {
376 .dma_mask = &spi_dmamask, 373 .dma_mask = &spi_dmamask,
377 .coherent_dma_mask = 0xffffffff, 374 .coherent_dma_mask = DMA_BIT_MASK(32),
378 }, 375 },
379 .resource = spi0_resources, 376 .resource = spi0_resources,
380 .num_resources = ARRAY_SIZE(spi0_resources), 377 .num_resources = ARRAY_SIZE(spi0_resources),
@@ -400,7 +397,7 @@ static struct platform_device at91sam9261_spi1_device = {
400 .id = 1, 397 .id = 1,
401 .dev = { 398 .dev = {
402 .dma_mask = &spi_dmamask, 399 .dma_mask = &spi_dmamask,
403 .coherent_dma_mask = 0xffffffff, 400 .coherent_dma_mask = DMA_BIT_MASK(32),
404 }, 401 },
405 .resource = spi1_resources, 402 .resource = spi1_resources,
406 .num_resources = ARRAY_SIZE(spi1_resources), 403 .num_resources = ARRAY_SIZE(spi1_resources),
@@ -466,7 +463,7 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
466 * -------------------------------------------------------------------- */ 463 * -------------------------------------------------------------------- */
467 464
468#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) 465#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
469static u64 lcdc_dmamask = 0xffffffffUL; 466static u64 lcdc_dmamask = DMA_BIT_MASK(32);
470static struct atmel_lcdfb_info lcdc_data; 467static struct atmel_lcdfb_info lcdc_data;
471 468
472static struct resource lcdc_resources[] = { 469static struct resource lcdc_resources[] = {
@@ -494,7 +491,7 @@ static struct platform_device at91_lcdc_device = {
494 .id = 0, 491 .id = 0,
495 .dev = { 492 .dev = {
496 .dma_mask = &lcdc_dmamask, 493 .dma_mask = &lcdc_dmamask,
497 .coherent_dma_mask = 0xffffffff, 494 .coherent_dma_mask = DMA_BIT_MASK(32),
498 .platform_data = &lcdc_data, 495 .platform_data = &lcdc_data,
499 }, 496 },
500 .resource = lcdc_resources, 497 .resource = lcdc_resources,
@@ -507,6 +504,17 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
507 return; 504 return;
508 } 505 }
509 506
507#if defined(CONFIG_FB_ATMEL_STN)
508 at91_set_A_periph(AT91_PIN_PB0, 0); /* LCDVSYNC */
509 at91_set_A_periph(AT91_PIN_PB1, 0); /* LCDHSYNC */
510 at91_set_A_periph(AT91_PIN_PB2, 0); /* LCDDOTCK */
511 at91_set_A_periph(AT91_PIN_PB3, 0); /* LCDDEN */
512 at91_set_A_periph(AT91_PIN_PB4, 0); /* LCDCC */
513 at91_set_A_periph(AT91_PIN_PB5, 0); /* LCDD0 */
514 at91_set_A_periph(AT91_PIN_PB6, 0); /* LCDD1 */
515 at91_set_A_periph(AT91_PIN_PB7, 0); /* LCDD2 */
516 at91_set_A_periph(AT91_PIN_PB8, 0); /* LCDD3 */
517#else
510 at91_set_A_periph(AT91_PIN_PB1, 0); /* LCDHSYNC */ 518 at91_set_A_periph(AT91_PIN_PB1, 0); /* LCDHSYNC */
511 at91_set_A_periph(AT91_PIN_PB2, 0); /* LCDDOTCK */ 519 at91_set_A_periph(AT91_PIN_PB2, 0); /* LCDDOTCK */
512 at91_set_A_periph(AT91_PIN_PB3, 0); /* LCDDEN */ 520 at91_set_A_periph(AT91_PIN_PB3, 0); /* LCDDEN */
@@ -529,6 +537,7 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
529 at91_set_B_periph(AT91_PIN_PB26, 0); /* LCDD21 */ 537 at91_set_B_periph(AT91_PIN_PB26, 0); /* LCDD21 */
530 at91_set_B_periph(AT91_PIN_PB27, 0); /* LCDD22 */ 538 at91_set_B_periph(AT91_PIN_PB27, 0); /* LCDD22 */
531 at91_set_B_periph(AT91_PIN_PB28, 0); /* LCDD23 */ 539 at91_set_B_periph(AT91_PIN_PB28, 0); /* LCDD23 */
540#endif
532 541
533 lcdc_data = *data; 542 lcdc_data = *data;
534 platform_device_register(&at91_lcdc_device); 543 platform_device_register(&at91_lcdc_device);
@@ -539,24 +548,220 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
539 548
540 549
541/* -------------------------------------------------------------------- 550/* --------------------------------------------------------------------
542 * LEDs 551 * RTT
552 * -------------------------------------------------------------------- */
553
554static struct resource rtt_resources[] = {
555 {
556 .start = AT91_BASE_SYS + AT91_RTT,
557 .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1,
558 .flags = IORESOURCE_MEM,
559 }
560};
561
562static struct platform_device at91sam9261_rtt_device = {
563 .name = "at91_rtt",
564 .id = -1,
565 .resource = rtt_resources,
566 .num_resources = ARRAY_SIZE(rtt_resources),
567};
568
569static void __init at91_add_device_rtt(void)
570{
571 platform_device_register(&at91sam9261_rtt_device);
572}
573
574
575/* --------------------------------------------------------------------
576 * Watchdog
577 * -------------------------------------------------------------------- */
578
579#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE)
580static struct platform_device at91sam9261_wdt_device = {
581 .name = "at91_wdt",
582 .id = -1,
583 .num_resources = 0,
584};
585
586static void __init at91_add_device_watchdog(void)
587{
588 platform_device_register(&at91sam9261_wdt_device);
589}
590#else
591static void __init at91_add_device_watchdog(void) {}
592#endif
593
594
595/* --------------------------------------------------------------------
596 * SSC -- Synchronous Serial Controller
543 * -------------------------------------------------------------------- */ 597 * -------------------------------------------------------------------- */
544 598
545#if defined(CONFIG_LEDS) 599#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE)
546u8 at91_leds_cpu; 600static u64 ssc0_dmamask = DMA_BIT_MASK(32);
547u8 at91_leds_timer; 601
602static struct resource ssc0_resources[] = {
603 [0] = {
604 .start = AT91SAM9261_BASE_SSC0,
605 .end = AT91SAM9261_BASE_SSC0 + SZ_16K - 1,
606 .flags = IORESOURCE_MEM,
607 },
608 [1] = {
609 .start = AT91SAM9261_ID_SSC0,
610 .end = AT91SAM9261_ID_SSC0,
611 .flags = IORESOURCE_IRQ,
612 },
613};
614
615static struct platform_device at91sam9261_ssc0_device = {
616 .name = "ssc",
617 .id = 0,
618 .dev = {
619 .dma_mask = &ssc0_dmamask,
620 .coherent_dma_mask = DMA_BIT_MASK(32),
621 },
622 .resource = ssc0_resources,
623 .num_resources = ARRAY_SIZE(ssc0_resources),
624};
625
626static inline void configure_ssc0_pins(unsigned pins)
627{
628 if (pins & ATMEL_SSC_TF)
629 at91_set_A_periph(AT91_PIN_PB21, 1);
630 if (pins & ATMEL_SSC_TK)
631 at91_set_A_periph(AT91_PIN_PB22, 1);
632 if (pins & ATMEL_SSC_TD)
633 at91_set_A_periph(AT91_PIN_PB23, 1);
634 if (pins & ATMEL_SSC_RD)
635 at91_set_A_periph(AT91_PIN_PB24, 1);
636 if (pins & ATMEL_SSC_RK)
637 at91_set_A_periph(AT91_PIN_PB25, 1);
638 if (pins & ATMEL_SSC_RF)
639 at91_set_A_periph(AT91_PIN_PB26, 1);
640}
641
642static u64 ssc1_dmamask = DMA_BIT_MASK(32);
643
644static struct resource ssc1_resources[] = {
645 [0] = {
646 .start = AT91SAM9261_BASE_SSC1,
647 .end = AT91SAM9261_BASE_SSC1 + SZ_16K - 1,
648 .flags = IORESOURCE_MEM,
649 },
650 [1] = {
651 .start = AT91SAM9261_ID_SSC1,
652 .end = AT91SAM9261_ID_SSC1,
653 .flags = IORESOURCE_IRQ,
654 },
655};
656
657static struct platform_device at91sam9261_ssc1_device = {
658 .name = "ssc",
659 .id = 1,
660 .dev = {
661 .dma_mask = &ssc1_dmamask,
662 .coherent_dma_mask = DMA_BIT_MASK(32),
663 },
664 .resource = ssc1_resources,
665 .num_resources = ARRAY_SIZE(ssc1_resources),
666};
667
668static inline void configure_ssc1_pins(unsigned pins)
669{
670 if (pins & ATMEL_SSC_TF)
671 at91_set_B_periph(AT91_PIN_PA17, 1);
672 if (pins & ATMEL_SSC_TK)
673 at91_set_B_periph(AT91_PIN_PA18, 1);
674 if (pins & ATMEL_SSC_TD)
675 at91_set_B_periph(AT91_PIN_PA19, 1);
676 if (pins & ATMEL_SSC_RD)
677 at91_set_B_periph(AT91_PIN_PA20, 1);
678 if (pins & ATMEL_SSC_RK)
679 at91_set_B_periph(AT91_PIN_PA21, 1);
680 if (pins & ATMEL_SSC_RF)
681 at91_set_B_periph(AT91_PIN_PA22, 1);
682}
683
684static u64 ssc2_dmamask = DMA_BIT_MASK(32);
685
686static struct resource ssc2_resources[] = {
687 [0] = {
688 .start = AT91SAM9261_BASE_SSC2,
689 .end = AT91SAM9261_BASE_SSC2 + SZ_16K - 1,
690 .flags = IORESOURCE_MEM,
691 },
692 [1] = {
693 .start = AT91SAM9261_ID_SSC2,
694 .end = AT91SAM9261_ID_SSC2,
695 .flags = IORESOURCE_IRQ,
696 },
697};
698
699static struct platform_device at91sam9261_ssc2_device = {
700 .name = "ssc",
701 .id = 2,
702 .dev = {
703 .dma_mask = &ssc2_dmamask,
704 .coherent_dma_mask = DMA_BIT_MASK(32),
705 },
706 .resource = ssc2_resources,
707 .num_resources = ARRAY_SIZE(ssc2_resources),
708};
709
710static inline void configure_ssc2_pins(unsigned pins)
711{
712 if (pins & ATMEL_SSC_TF)
713 at91_set_B_periph(AT91_PIN_PC25, 1);
714 if (pins & ATMEL_SSC_TK)
715 at91_set_B_periph(AT91_PIN_PC26, 1);
716 if (pins & ATMEL_SSC_TD)
717 at91_set_B_periph(AT91_PIN_PC27, 1);
718 if (pins & ATMEL_SSC_RD)
719 at91_set_B_periph(AT91_PIN_PC28, 1);
720 if (pins & ATMEL_SSC_RK)
721 at91_set_B_periph(AT91_PIN_PC29, 1);
722 if (pins & ATMEL_SSC_RF)
723 at91_set_B_periph(AT91_PIN_PC30, 1);
724}
548 725
549void __init at91_init_leds(u8 cpu_led, u8 timer_led) 726/*
727 * SSC controllers are accessed through library code, instead of any
728 * kind of all-singing/all-dancing driver. For example one could be
729 * used by a particular I2S audio codec's driver, while another one
730 * on the same system might be used by a custom data capture driver.
731 */
732void __init at91_add_device_ssc(unsigned id, unsigned pins)
550{ 733{
551 /* Enable GPIO to access the LEDs */ 734 struct platform_device *pdev;
552 at91_set_gpio_output(cpu_led, 1); 735
553 at91_set_gpio_output(timer_led, 1); 736 /*
737 * NOTE: caller is responsible for passing information matching
738 * "pins" to whatever will be using each particular controller.
739 */
740 switch (id) {
741 case AT91SAM9261_ID_SSC0:
742 pdev = &at91sam9261_ssc0_device;
743 configure_ssc0_pins(pins);
744 at91_clock_associate("ssc0_clk", &pdev->dev, "pclk");
745 break;
746 case AT91SAM9261_ID_SSC1:
747 pdev = &at91sam9261_ssc1_device;
748 configure_ssc1_pins(pins);
749 at91_clock_associate("ssc1_clk", &pdev->dev, "pclk");
750 break;
751 case AT91SAM9261_ID_SSC2:
752 pdev = &at91sam9261_ssc2_device;
753 configure_ssc2_pins(pins);
754 at91_clock_associate("ssc2_clk", &pdev->dev, "pclk");
755 break;
756 default:
757 return;
758 }
554 759
555 at91_leds_cpu = cpu_led; 760 platform_device_register(pdev);
556 at91_leds_timer = timer_led;
557} 761}
762
558#else 763#else
559void __init at91_init_leds(u8 cpu_led, u8 timer_led) {} 764void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
560#endif 765#endif
561 766
562 767
@@ -584,12 +789,15 @@ static struct atmel_uart_data dbgu_data = {
584 .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), 789 .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
585}; 790};
586 791
792static u64 dbgu_dmamask = DMA_BIT_MASK(32);
793
587static struct platform_device at91sam9261_dbgu_device = { 794static struct platform_device at91sam9261_dbgu_device = {
588 .name = "atmel_usart", 795 .name = "atmel_usart",
589 .id = 0, 796 .id = 0,
590 .dev = { 797 .dev = {
591 .platform_data = &dbgu_data, 798 .dma_mask = &dbgu_dmamask,
592 .coherent_dma_mask = 0xffffffff, 799 .coherent_dma_mask = DMA_BIT_MASK(32),
800 .platform_data = &dbgu_data,
593 }, 801 },
594 .resource = dbgu_resources, 802 .resource = dbgu_resources,
595 .num_resources = ARRAY_SIZE(dbgu_resources), 803 .num_resources = ARRAY_SIZE(dbgu_resources),
@@ -619,23 +827,29 @@ static struct atmel_uart_data uart0_data = {
619 .use_dma_rx = 1, 827 .use_dma_rx = 1,
620}; 828};
621 829
830static u64 uart0_dmamask = DMA_BIT_MASK(32);
831
622static struct platform_device at91sam9261_uart0_device = { 832static struct platform_device at91sam9261_uart0_device = {
623 .name = "atmel_usart", 833 .name = "atmel_usart",
624 .id = 1, 834 .id = 1,
625 .dev = { 835 .dev = {
626 .platform_data = &uart0_data, 836 .dma_mask = &uart0_dmamask,
627 .coherent_dma_mask = 0xffffffff, 837 .coherent_dma_mask = DMA_BIT_MASK(32),
838 .platform_data = &uart0_data,
628 }, 839 },
629 .resource = uart0_resources, 840 .resource = uart0_resources,
630 .num_resources = ARRAY_SIZE(uart0_resources), 841 .num_resources = ARRAY_SIZE(uart0_resources),
631}; 842};
632 843
633static inline void configure_usart0_pins(void) 844static inline void configure_usart0_pins(unsigned pins)
634{ 845{
635 at91_set_A_periph(AT91_PIN_PC8, 1); /* TXD0 */ 846 at91_set_A_periph(AT91_PIN_PC8, 1); /* TXD0 */
636 at91_set_A_periph(AT91_PIN_PC9, 0); /* RXD0 */ 847 at91_set_A_periph(AT91_PIN_PC9, 0); /* RXD0 */
637 at91_set_A_periph(AT91_PIN_PC10, 0); /* RTS0 */ 848
638 at91_set_A_periph(AT91_PIN_PC11, 0); /* CTS0 */ 849 if (pins & ATMEL_UART_RTS)
850 at91_set_A_periph(AT91_PIN_PC10, 0); /* RTS0 */
851 if (pins & ATMEL_UART_CTS)
852 at91_set_A_periph(AT91_PIN_PC11, 0); /* CTS0 */
639} 853}
640 854
641static struct resource uart1_resources[] = { 855static struct resource uart1_resources[] = {
@@ -656,21 +870,29 @@ static struct atmel_uart_data uart1_data = {
656 .use_dma_rx = 1, 870 .use_dma_rx = 1,
657}; 871};
658 872
873static u64 uart1_dmamask = DMA_BIT_MASK(32);
874
659static struct platform_device at91sam9261_uart1_device = { 875static struct platform_device at91sam9261_uart1_device = {
660 .name = "atmel_usart", 876 .name = "atmel_usart",
661 .id = 2, 877 .id = 2,
662 .dev = { 878 .dev = {
663 .platform_data = &uart1_data, 879 .dma_mask = &uart1_dmamask,
664 .coherent_dma_mask = 0xffffffff, 880 .coherent_dma_mask = DMA_BIT_MASK(32),
881 .platform_data = &uart1_data,
665 }, 882 },
666 .resource = uart1_resources, 883 .resource = uart1_resources,
667 .num_resources = ARRAY_SIZE(uart1_resources), 884 .num_resources = ARRAY_SIZE(uart1_resources),
668}; 885};
669 886
670static inline void configure_usart1_pins(void) 887static inline void configure_usart1_pins(unsigned pins)
671{ 888{
672 at91_set_A_periph(AT91_PIN_PC12, 1); /* TXD1 */ 889 at91_set_A_periph(AT91_PIN_PC12, 1); /* TXD1 */
673 at91_set_A_periph(AT91_PIN_PC13, 0); /* RXD1 */ 890 at91_set_A_periph(AT91_PIN_PC13, 0); /* RXD1 */
891
892 if (pins & ATMEL_UART_RTS)
893 at91_set_B_periph(AT91_PIN_PA12, 0); /* RTS1 */
894 if (pins & ATMEL_UART_CTS)
895 at91_set_B_periph(AT91_PIN_PA13, 0); /* CTS1 */
674} 896}
675 897
676static struct resource uart2_resources[] = { 898static struct resource uart2_resources[] = {
@@ -691,27 +913,35 @@ static struct atmel_uart_data uart2_data = {
691 .use_dma_rx = 1, 913 .use_dma_rx = 1,
692}; 914};
693 915
916static u64 uart2_dmamask = DMA_BIT_MASK(32);
917
694static struct platform_device at91sam9261_uart2_device = { 918static struct platform_device at91sam9261_uart2_device = {
695 .name = "atmel_usart", 919 .name = "atmel_usart",
696 .id = 3, 920 .id = 3,
697 .dev = { 921 .dev = {
698 .platform_data = &uart2_data, 922 .dma_mask = &uart2_dmamask,
699 .coherent_dma_mask = 0xffffffff, 923 .coherent_dma_mask = DMA_BIT_MASK(32),
924 .platform_data = &uart2_data,
700 }, 925 },
701 .resource = uart2_resources, 926 .resource = uart2_resources,
702 .num_resources = ARRAY_SIZE(uart2_resources), 927 .num_resources = ARRAY_SIZE(uart2_resources),
703}; 928};
704 929
705static inline void configure_usart2_pins(void) 930static inline void configure_usart2_pins(unsigned pins)
706{ 931{
707 at91_set_A_periph(AT91_PIN_PC15, 0); /* RXD2 */ 932 at91_set_A_periph(AT91_PIN_PC15, 0); /* RXD2 */
708 at91_set_A_periph(AT91_PIN_PC14, 1); /* TXD2 */ 933 at91_set_A_periph(AT91_PIN_PC14, 1); /* TXD2 */
934
935 if (pins & ATMEL_UART_RTS)
936 at91_set_B_periph(AT91_PIN_PA15, 0); /* RTS2*/
937 if (pins & ATMEL_UART_CTS)
938 at91_set_B_periph(AT91_PIN_PA16, 0); /* CTS2 */
709} 939}
710 940
711struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ 941static struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
712struct platform_device *atmel_default_console_device; /* the serial console device */ 942struct platform_device *atmel_default_console_device; /* the serial console device */
713 943
714void __init at91_init_serial(struct at91_uart_config *config) 944void __init __deprecated at91_init_serial(struct at91_uart_config *config)
715{ 945{
716 int i; 946 int i;
717 947
@@ -719,17 +949,17 @@ void __init at91_init_serial(struct at91_uart_config *config)
719 for (i = 0; i < config->nr_tty; i++) { 949 for (i = 0; i < config->nr_tty; i++) {
720 switch (config->tty_map[i]) { 950 switch (config->tty_map[i]) {
721 case 0: 951 case 0:
722 configure_usart0_pins(); 952 configure_usart0_pins(ATMEL_UART_CTS | ATMEL_UART_RTS);
723 at91_uarts[i] = &at91sam9261_uart0_device; 953 at91_uarts[i] = &at91sam9261_uart0_device;
724 at91_clock_associate("usart0_clk", &at91sam9261_uart0_device.dev, "usart"); 954 at91_clock_associate("usart0_clk", &at91sam9261_uart0_device.dev, "usart");
725 break; 955 break;
726 case 1: 956 case 1:
727 configure_usart1_pins(); 957 configure_usart1_pins(0);
728 at91_uarts[i] = &at91sam9261_uart1_device; 958 at91_uarts[i] = &at91sam9261_uart1_device;
729 at91_clock_associate("usart1_clk", &at91sam9261_uart1_device.dev, "usart"); 959 at91_clock_associate("usart1_clk", &at91sam9261_uart1_device.dev, "usart");
730 break; 960 break;
731 case 2: 961 case 2:
732 configure_usart2_pins(); 962 configure_usart2_pins(0);
733 at91_uarts[i] = &at91sam9261_uart2_device; 963 at91_uarts[i] = &at91sam9261_uart2_device;
734 at91_clock_associate("usart2_clk", &at91sam9261_uart2_device.dev, "usart"); 964 at91_clock_associate("usart2_clk", &at91sam9261_uart2_device.dev, "usart");
735 break; 965 break;
@@ -751,6 +981,48 @@ void __init at91_init_serial(struct at91_uart_config *config)
751 printk(KERN_INFO "AT91: No default serial console defined.\n"); 981 printk(KERN_INFO "AT91: No default serial console defined.\n");
752} 982}
753 983
984void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
985{
986 struct platform_device *pdev;
987
988 switch (id) {
989 case 0: /* DBGU */
990 pdev = &at91sam9261_dbgu_device;
991 configure_dbgu_pins();
992 at91_clock_associate("mck", &pdev->dev, "usart");
993 break;
994 case AT91SAM9261_ID_US0:
995 pdev = &at91sam9261_uart0_device;
996 configure_usart0_pins(pins);
997 at91_clock_associate("usart0_clk", &pdev->dev, "usart");
998 break;
999 case AT91SAM9261_ID_US1:
1000 pdev = &at91sam9261_uart1_device;
1001 configure_usart1_pins(pins);
1002 at91_clock_associate("usart1_clk", &pdev->dev, "usart");
1003 break;
1004 case AT91SAM9261_ID_US2:
1005 pdev = &at91sam9261_uart2_device;
1006 configure_usart2_pins(pins);
1007 at91_clock_associate("usart2_clk", &pdev->dev, "usart");
1008 break;
1009 default:
1010 return;
1011 }
1012 pdev->id = portnr; /* update to mapped ID */
1013
1014 if (portnr < ATMEL_MAX_UART)
1015 at91_uarts[portnr] = pdev;
1016}
1017
1018void __init at91_set_serial_console(unsigned portnr)
1019{
1020 if (portnr < ATMEL_MAX_UART)
1021 atmel_default_console_device = at91_uarts[portnr];
1022 if (!atmel_default_console_device)
1023 printk(KERN_INFO "AT91: No default serial console defined.\n");
1024}
1025
754void __init at91_add_device_serial(void) 1026void __init at91_add_device_serial(void)
755{ 1027{
756 int i; 1028 int i;
@@ -761,7 +1033,9 @@ void __init at91_add_device_serial(void)
761 } 1033 }
762} 1034}
763#else 1035#else
764void __init at91_init_serial(struct at91_uart_config *config) {} 1036void __init __deprecated at91_init_serial(struct at91_uart_config *config) {}
1037void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
1038void __init at91_set_serial_console(unsigned portnr) {}
765void __init at91_add_device_serial(void) {} 1039void __init at91_add_device_serial(void) {}
766#endif 1040#endif
767 1041
@@ -774,6 +1048,8 @@ void __init at91_add_device_serial(void) {}
774 */ 1048 */
775static int __init at91_add_standard_devices(void) 1049static int __init at91_add_standard_devices(void)
776{ 1050{
1051 at91_add_device_rtt();
1052 at91_add_device_watchdog();
777 return 0; 1053 return 0;
778} 1054}
779 1055
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
index 00e27b177857..a53ba0f74351 100644
--- a/arch/arm/mach-at91/at91sam9263.c
+++ b/arch/arm/mach-at91/at91sam9263.c
@@ -304,34 +304,34 @@ void __init at91sam9263_initialize(unsigned long main_clock)
304static unsigned int at91sam9263_default_irq_priority[NR_AIC_IRQS] __initdata = { 304static unsigned int at91sam9263_default_irq_priority[NR_AIC_IRQS] __initdata = {
305 7, /* Advanced Interrupt Controller (FIQ) */ 305 7, /* Advanced Interrupt Controller (FIQ) */
306 7, /* System Peripherals */ 306 7, /* System Peripherals */
307 0, /* Parallel IO Controller A */ 307 1, /* Parallel IO Controller A */
308 0, /* Parallel IO Controller B */ 308 1, /* Parallel IO Controller B */
309 0, /* Parallel IO Controller C, D and E */ 309 1, /* Parallel IO Controller C, D and E */
310 0, 310 0,
311 0, 311 0,
312 6, /* USART 0 */ 312 5, /* USART 0 */
313 6, /* USART 1 */ 313 5, /* USART 1 */
314 6, /* USART 2 */ 314 5, /* USART 2 */
315 0, /* Multimedia Card Interface 0 */ 315 0, /* Multimedia Card Interface 0 */
316 0, /* Multimedia Card Interface 1 */ 316 0, /* Multimedia Card Interface 1 */
317 4, /* CAN */ 317 3, /* CAN */
318 0, /* Two-Wire Interface */ 318 6, /* Two-Wire Interface */
319 6, /* Serial Peripheral Interface 0 */ 319 5, /* Serial Peripheral Interface 0 */
320 6, /* Serial Peripheral Interface 1 */ 320 5, /* Serial Peripheral Interface 1 */
321 5, /* Serial Synchronous Controller 0 */ 321 4, /* Serial Synchronous Controller 0 */
322 5, /* Serial Synchronous Controller 1 */ 322 4, /* Serial Synchronous Controller 1 */
323 6, /* AC97 Controller */ 323 5, /* AC97 Controller */
324 0, /* Timer Counter 0, 1 and 2 */ 324 0, /* Timer Counter 0, 1 and 2 */
325 0, /* Pulse Width Modulation Controller */ 325 0, /* Pulse Width Modulation Controller */
326 3, /* Ethernet */ 326 3, /* Ethernet */
327 0, 327 0,
328 0, /* 2D Graphic Engine */ 328 0, /* 2D Graphic Engine */
329 3, /* USB Device Port */ 329 2, /* USB Device Port */
330 0, /* Image Sensor Interface */ 330 0, /* Image Sensor Interface */
331 3, /* LDC Controller */ 331 3, /* LDC Controller */
332 0, /* DMA Controller */ 332 0, /* DMA Controller */
333 0, 333 0,
334 3, /* USB Host port */ 334 2, /* USB Host port */
335 0, /* Advanced Interrupt Controller (IRQ0) */ 335 0, /* Advanced Interrupt Controller (IRQ0) */
336 0, /* Advanced Interrupt Controller (IRQ1) */ 336 0, /* Advanced Interrupt Controller (IRQ1) */
337}; 337};
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
index ac329a98e959..0b12e1adcc8e 100644
--- a/arch/arm/mach-at91/at91sam9263_devices.c
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -12,6 +12,7 @@
12#include <asm/mach/arch.h> 12#include <asm/mach/arch.h>
13#include <asm/mach/map.h> 13#include <asm/mach/map.h>
14 14
15#include <linux/dma-mapping.h>
15#include <linux/platform_device.h> 16#include <linux/platform_device.h>
16#include <linux/i2c-gpio.h> 17#include <linux/i2c-gpio.h>
17 18
@@ -32,7 +33,7 @@
32 * -------------------------------------------------------------------- */ 33 * -------------------------------------------------------------------- */
33 34
34#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) 35#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
35static u64 ohci_dmamask = 0xffffffffUL; 36static u64 ohci_dmamask = DMA_BIT_MASK(32);
36static struct at91_usbh_data usbh_data; 37static struct at91_usbh_data usbh_data;
37 38
38static struct resource usbh_resources[] = { 39static struct resource usbh_resources[] = {
@@ -53,7 +54,7 @@ static struct platform_device at91_usbh_device = {
53 .id = -1, 54 .id = -1,
54 .dev = { 55 .dev = {
55 .dma_mask = &ohci_dmamask, 56 .dma_mask = &ohci_dmamask,
56 .coherent_dma_mask = 0xffffffff, 57 .coherent_dma_mask = DMA_BIT_MASK(32),
57 .platform_data = &usbh_data, 58 .platform_data = &usbh_data,
58 }, 59 },
59 .resource = usbh_resources, 60 .resource = usbh_resources,
@@ -136,7 +137,7 @@ void __init at91_add_device_udc(struct at91_udc_data *data) {}
136 * -------------------------------------------------------------------- */ 137 * -------------------------------------------------------------------- */
137 138
138#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) 139#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE)
139static u64 eth_dmamask = 0xffffffffUL; 140static u64 eth_dmamask = DMA_BIT_MASK(32);
140static struct at91_eth_data eth_data; 141static struct at91_eth_data eth_data;
141 142
142static struct resource eth_resources[] = { 143static struct resource eth_resources[] = {
@@ -157,7 +158,7 @@ static struct platform_device at91sam9263_eth_device = {
157 .id = -1, 158 .id = -1,
158 .dev = { 159 .dev = {
159 .dma_mask = &eth_dmamask, 160 .dma_mask = &eth_dmamask,
160 .coherent_dma_mask = 0xffffffff, 161 .coherent_dma_mask = DMA_BIT_MASK(32),
161 .platform_data = &eth_data, 162 .platform_data = &eth_data,
162 }, 163 },
163 .resource = eth_resources, 164 .resource = eth_resources,
@@ -210,7 +211,7 @@ void __init at91_add_device_eth(struct at91_eth_data *data) {}
210 * -------------------------------------------------------------------- */ 211 * -------------------------------------------------------------------- */
211 212
212#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) 213#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE)
213static u64 mmc_dmamask = 0xffffffffUL; 214static u64 mmc_dmamask = DMA_BIT_MASK(32);
214static struct at91_mmc_data mmc0_data, mmc1_data; 215static struct at91_mmc_data mmc0_data, mmc1_data;
215 216
216static struct resource mmc0_resources[] = { 217static struct resource mmc0_resources[] = {
@@ -231,7 +232,7 @@ static struct platform_device at91sam9263_mmc0_device = {
231 .id = 0, 232 .id = 0,
232 .dev = { 233 .dev = {
233 .dma_mask = &mmc_dmamask, 234 .dma_mask = &mmc_dmamask,
234 .coherent_dma_mask = 0xffffffff, 235 .coherent_dma_mask = DMA_BIT_MASK(32),
235 .platform_data = &mmc0_data, 236 .platform_data = &mmc0_data,
236 }, 237 },
237 .resource = mmc0_resources, 238 .resource = mmc0_resources,
@@ -256,7 +257,7 @@ static struct platform_device at91sam9263_mmc1_device = {
256 .id = 1, 257 .id = 1,
257 .dev = { 258 .dev = {
258 .dma_mask = &mmc_dmamask, 259 .dma_mask = &mmc_dmamask,
259 .coherent_dma_mask = 0xffffffff, 260 .coherent_dma_mask = DMA_BIT_MASK(32),
260 .platform_data = &mmc1_data, 261 .platform_data = &mmc1_data,
261 }, 262 },
262 .resource = mmc1_resources, 263 .resource = mmc1_resources,
@@ -382,7 +383,7 @@ void __init at91_add_device_nand(struct at91_nand_data *data)
382 return; 383 return;
383 384
384 csa = at91_sys_read(AT91_MATRIX_EBI0CSA); 385 csa = at91_sys_read(AT91_MATRIX_EBI0CSA);
385 at91_sys_write(AT91_MATRIX_EBI0CSA, csa | AT91_MATRIX_EBI0_CS3A_SMC); 386 at91_sys_write(AT91_MATRIX_EBI0CSA, csa | AT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA);
386 387
387 /* set the bus interface characteristics */ 388 /* set the bus interface characteristics */
388 at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0) 389 at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0)
@@ -500,7 +501,7 @@ void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
500 * -------------------------------------------------------------------- */ 501 * -------------------------------------------------------------------- */
501 502
502#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) 503#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
503static u64 spi_dmamask = 0xffffffffUL; 504static u64 spi_dmamask = DMA_BIT_MASK(32);
504 505
505static struct resource spi0_resources[] = { 506static struct resource spi0_resources[] = {
506 [0] = { 507 [0] = {
@@ -520,7 +521,7 @@ static struct platform_device at91sam9263_spi0_device = {
520 .id = 0, 521 .id = 0,
521 .dev = { 522 .dev = {
522 .dma_mask = &spi_dmamask, 523 .dma_mask = &spi_dmamask,
523 .coherent_dma_mask = 0xffffffff, 524 .coherent_dma_mask = DMA_BIT_MASK(32),
524 }, 525 },
525 .resource = spi0_resources, 526 .resource = spi0_resources,
526 .num_resources = ARRAY_SIZE(spi0_resources), 527 .num_resources = ARRAY_SIZE(spi0_resources),
@@ -546,7 +547,7 @@ static struct platform_device at91sam9263_spi1_device = {
546 .id = 1, 547 .id = 1,
547 .dev = { 548 .dev = {
548 .dma_mask = &spi_dmamask, 549 .dma_mask = &spi_dmamask,
549 .coherent_dma_mask = 0xffffffff, 550 .coherent_dma_mask = DMA_BIT_MASK(32),
550 }, 551 },
551 .resource = spi1_resources, 552 .resource = spi1_resources,
552 .num_resources = ARRAY_SIZE(spi1_resources), 553 .num_resources = ARRAY_SIZE(spi1_resources),
@@ -612,7 +613,7 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
612 * -------------------------------------------------------------------- */ 613 * -------------------------------------------------------------------- */
613 614
614#if defined(CONFIG_SND_AT91_AC97) || defined(CONFIG_SND_AT91_AC97_MODULE) 615#if defined(CONFIG_SND_AT91_AC97) || defined(CONFIG_SND_AT91_AC97_MODULE)
615static u64 ac97_dmamask = 0xffffffffUL; 616static u64 ac97_dmamask = DMA_BIT_MASK(32);
616static struct atmel_ac97_data ac97_data; 617static struct atmel_ac97_data ac97_data;
617 618
618static struct resource ac97_resources[] = { 619static struct resource ac97_resources[] = {
@@ -633,7 +634,7 @@ static struct platform_device at91sam9263_ac97_device = {
633 .id = 1, 634 .id = 1,
634 .dev = { 635 .dev = {
635 .dma_mask = &ac97_dmamask, 636 .dma_mask = &ac97_dmamask,
636 .coherent_dma_mask = 0xffffffff, 637 .coherent_dma_mask = DMA_BIT_MASK(32),
637 .platform_data = &ac97_data, 638 .platform_data = &ac97_data,
638 }, 639 },
639 .resource = ac97_resources, 640 .resource = ac97_resources,
@@ -667,7 +668,7 @@ void __init at91_add_device_ac97(struct atmel_ac97_data *data) {}
667 * -------------------------------------------------------------------- */ 668 * -------------------------------------------------------------------- */
668 669
669#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) 670#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
670static u64 lcdc_dmamask = 0xffffffffUL; 671static u64 lcdc_dmamask = DMA_BIT_MASK(32);
671static struct atmel_lcdfb_info lcdc_data; 672static struct atmel_lcdfb_info lcdc_data;
672 673
673static struct resource lcdc_resources[] = { 674static struct resource lcdc_resources[] = {
@@ -688,7 +689,7 @@ static struct platform_device at91_lcdc_device = {
688 .id = 0, 689 .id = 0,
689 .dev = { 690 .dev = {
690 .dma_mask = &lcdc_dmamask, 691 .dma_mask = &lcdc_dmamask,
691 .coherent_dma_mask = 0xffffffff, 692 .coherent_dma_mask = DMA_BIT_MASK(32),
692 .platform_data = &lcdc_data, 693 .platform_data = &lcdc_data,
693 }, 694 },
694 .resource = lcdc_resources, 695 .resource = lcdc_resources,
@@ -732,24 +733,242 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
732 733
733 734
734/* -------------------------------------------------------------------- 735/* --------------------------------------------------------------------
735 * LEDs 736 * Image Sensor Interface
736 * -------------------------------------------------------------------- */ 737 * -------------------------------------------------------------------- */
737 738
738#if defined(CONFIG_LEDS) 739#if defined(CONFIG_VIDEO_AT91_ISI) || defined(CONFIG_VIDEO_AT91_ISI_MODULE)
739u8 at91_leds_cpu;
740u8 at91_leds_timer;
741 740
742void __init at91_init_leds(u8 cpu_led, u8 timer_led) 741struct resource isi_resources[] = {
742 [0] = {
743 .start = AT91SAM9263_BASE_ISI,
744 .end = AT91SAM9263_BASE_ISI + SZ_16K - 1,
745 .flags = IORESOURCE_MEM,
746 },
747 [1] = {
748 .start = AT91SAM9263_ID_ISI,
749 .end = AT91SAM9263_ID_ISI,
750 .flags = IORESOURCE_IRQ,
751 },
752};
753
754static struct platform_device at91sam9263_isi_device = {
755 .name = "at91_isi",
756 .id = -1,
757 .resource = isi_resources,
758 .num_resources = ARRAY_SIZE(isi_resources),
759};
760
761void __init at91_add_device_isi(void)
762{
763 at91_set_A_periph(AT91_PIN_PE0, 0); /* ISI_D0 */
764 at91_set_A_periph(AT91_PIN_PE1, 0); /* ISI_D1 */
765 at91_set_A_periph(AT91_PIN_PE2, 0); /* ISI_D2 */
766 at91_set_A_periph(AT91_PIN_PE3, 0); /* ISI_D3 */
767 at91_set_A_periph(AT91_PIN_PE4, 0); /* ISI_D4 */
768 at91_set_A_periph(AT91_PIN_PE5, 0); /* ISI_D5 */
769 at91_set_A_periph(AT91_PIN_PE6, 0); /* ISI_D6 */
770 at91_set_A_periph(AT91_PIN_PE7, 0); /* ISI_D7 */
771 at91_set_A_periph(AT91_PIN_PE8, 0); /* ISI_PCK */
772 at91_set_A_periph(AT91_PIN_PE9, 0); /* ISI_HSYNC */
773 at91_set_A_periph(AT91_PIN_PE10, 0); /* ISI_VSYNC */
774 at91_set_B_periph(AT91_PIN_PE11, 0); /* ISI_MCK (PCK3) */
775 at91_set_B_periph(AT91_PIN_PE12, 0); /* ISI_PD8 */
776 at91_set_B_periph(AT91_PIN_PE13, 0); /* ISI_PD9 */
777 at91_set_B_periph(AT91_PIN_PE14, 0); /* ISI_PD10 */
778 at91_set_B_periph(AT91_PIN_PE15, 0); /* ISI_PD11 */
779}
780#else
781void __init at91_add_device_isi(void) {}
782#endif
783
784
785/* --------------------------------------------------------------------
786 * RTT
787 * -------------------------------------------------------------------- */
788
789static struct resource rtt0_resources[] = {
790 {
791 .start = AT91_BASE_SYS + AT91_RTT0,
792 .end = AT91_BASE_SYS + AT91_RTT0 + SZ_16 - 1,
793 .flags = IORESOURCE_MEM,
794 }
795};
796
797static struct platform_device at91sam9263_rtt0_device = {
798 .name = "at91_rtt",
799 .id = 0,
800 .resource = rtt0_resources,
801 .num_resources = ARRAY_SIZE(rtt0_resources),
802};
803
804static struct resource rtt1_resources[] = {
805 {
806 .start = AT91_BASE_SYS + AT91_RTT1,
807 .end = AT91_BASE_SYS + AT91_RTT1 + SZ_16 - 1,
808 .flags = IORESOURCE_MEM,
809 }
810};
811
812static struct platform_device at91sam9263_rtt1_device = {
813 .name = "at91_rtt",
814 .id = 1,
815 .resource = rtt1_resources,
816 .num_resources = ARRAY_SIZE(rtt1_resources),
817};
818
819static void __init at91_add_device_rtt(void)
820{
821 platform_device_register(&at91sam9263_rtt0_device);
822 platform_device_register(&at91sam9263_rtt1_device);
823}
824
825
826/* --------------------------------------------------------------------
827 * Watchdog
828 * -------------------------------------------------------------------- */
829
830#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE)
831static struct platform_device at91sam9263_wdt_device = {
832 .name = "at91_wdt",
833 .id = -1,
834 .num_resources = 0,
835};
836
837static void __init at91_add_device_watchdog(void)
838{
839 platform_device_register(&at91sam9263_wdt_device);
840}
841#else
842static void __init at91_add_device_watchdog(void) {}
843#endif
844
845
846/* --------------------------------------------------------------------
847 * SSC -- Synchronous Serial Controller
848 * -------------------------------------------------------------------- */
849
850#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE)
851static u64 ssc0_dmamask = DMA_BIT_MASK(32);
852
853static struct resource ssc0_resources[] = {
854 [0] = {
855 .start = AT91SAM9263_BASE_SSC0,
856 .end = AT91SAM9263_BASE_SSC0 + SZ_16K - 1,
857 .flags = IORESOURCE_MEM,
858 },
859 [1] = {
860 .start = AT91SAM9263_ID_SSC0,
861 .end = AT91SAM9263_ID_SSC0,
862 .flags = IORESOURCE_IRQ,
863 },
864};
865
866static struct platform_device at91sam9263_ssc0_device = {
867 .name = "ssc",
868 .id = 0,
869 .dev = {
870 .dma_mask = &ssc0_dmamask,
871 .coherent_dma_mask = DMA_BIT_MASK(32),
872 },
873 .resource = ssc0_resources,
874 .num_resources = ARRAY_SIZE(ssc0_resources),
875};
876
877static inline void configure_ssc0_pins(unsigned pins)
878{
879 if (pins & ATMEL_SSC_TF)
880 at91_set_B_periph(AT91_PIN_PB0, 1);
881 if (pins & ATMEL_SSC_TK)
882 at91_set_B_periph(AT91_PIN_PB1, 1);
883 if (pins & ATMEL_SSC_TD)
884 at91_set_B_periph(AT91_PIN_PB2, 1);
885 if (pins & ATMEL_SSC_RD)
886 at91_set_B_periph(AT91_PIN_PB3, 1);
887 if (pins & ATMEL_SSC_RK)
888 at91_set_B_periph(AT91_PIN_PB4, 1);
889 if (pins & ATMEL_SSC_RF)
890 at91_set_B_periph(AT91_PIN_PB5, 1);
891}
892
893static u64 ssc1_dmamask = DMA_BIT_MASK(32);
894
895static struct resource ssc1_resources[] = {
896 [0] = {
897 .start = AT91SAM9263_BASE_SSC1,
898 .end = AT91SAM9263_BASE_SSC1 + SZ_16K - 1,
899 .flags = IORESOURCE_MEM,
900 },
901 [1] = {
902 .start = AT91SAM9263_ID_SSC1,
903 .end = AT91SAM9263_ID_SSC1,
904 .flags = IORESOURCE_IRQ,
905 },
906};
907
908static struct platform_device at91sam9263_ssc1_device = {
909 .name = "ssc",
910 .id = 1,
911 .dev = {
912 .dma_mask = &ssc1_dmamask,
913 .coherent_dma_mask = DMA_BIT_MASK(32),
914 },
915 .resource = ssc1_resources,
916 .num_resources = ARRAY_SIZE(ssc1_resources),
917};
918
919static inline void configure_ssc1_pins(unsigned pins)
920{
921 if (pins & ATMEL_SSC_TF)
922 at91_set_A_periph(AT91_PIN_PB6, 1);
923 if (pins & ATMEL_SSC_TK)
924 at91_set_A_periph(AT91_PIN_PB7, 1);
925 if (pins & ATMEL_SSC_TD)
926 at91_set_A_periph(AT91_PIN_PB8, 1);
927 if (pins & ATMEL_SSC_RD)
928 at91_set_A_periph(AT91_PIN_PB9, 1);
929 if (pins & ATMEL_SSC_RK)
930 at91_set_A_periph(AT91_PIN_PB10, 1);
931 if (pins & ATMEL_SSC_RF)
932 at91_set_A_periph(AT91_PIN_PB11, 1);
933}
934
935/*
936 * Return the device node so that board init code can use it as the
937 * parent for the device node reflecting how it's used on this board.
938 *
939 * SSC controllers are accessed through library code, instead of any
940 * kind of all-singing/all-dancing driver. For example one could be
941 * used by a particular I2S audio codec's driver, while another one
942 * on the same system might be used by a custom data capture driver.
943 */
944void __init at91_add_device_ssc(unsigned id, unsigned pins)
743{ 945{
744 /* Enable GPIO to access the LEDs */ 946 struct platform_device *pdev;
745 at91_set_gpio_output(cpu_led, 1); 947
746 at91_set_gpio_output(timer_led, 1); 948 /*
949 * NOTE: caller is responsible for passing information matching
950 * "pins" to whatever will be using each particular controller.
951 */
952 switch (id) {
953 case AT91SAM9263_ID_SSC0:
954 pdev = &at91sam9263_ssc0_device;
955 configure_ssc0_pins(pins);
956 at91_clock_associate("ssc0_clk", &pdev->dev, "pclk");
957 break;
958 case AT91SAM9263_ID_SSC1:
959 pdev = &at91sam9263_ssc1_device;
960 configure_ssc1_pins(pins);
961 at91_clock_associate("ssc1_clk", &pdev->dev, "pclk");
962 break;
963 default:
964 return;
965 }
747 966
748 at91_leds_cpu = cpu_led; 967 platform_device_register(pdev);
749 at91_leds_timer = timer_led;
750} 968}
969
751#else 970#else
752void __init at91_init_leds(u8 cpu_led, u8 timer_led) {} 971void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
753#endif 972#endif
754 973
755 974
@@ -778,12 +997,15 @@ static struct atmel_uart_data dbgu_data = {
778 .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), 997 .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
779}; 998};
780 999
1000static u64 dbgu_dmamask = DMA_BIT_MASK(32);
1001
781static struct platform_device at91sam9263_dbgu_device = { 1002static struct platform_device at91sam9263_dbgu_device = {
782 .name = "atmel_usart", 1003 .name = "atmel_usart",
783 .id = 0, 1004 .id = 0,
784 .dev = { 1005 .dev = {
785 .platform_data = &dbgu_data, 1006 .dma_mask = &dbgu_dmamask,
786 .coherent_dma_mask = 0xffffffff, 1007 .coherent_dma_mask = DMA_BIT_MASK(32),
1008 .platform_data = &dbgu_data,
787 }, 1009 },
788 .resource = dbgu_resources, 1010 .resource = dbgu_resources,
789 .num_resources = ARRAY_SIZE(dbgu_resources), 1011 .num_resources = ARRAY_SIZE(dbgu_resources),
@@ -813,23 +1035,29 @@ static struct atmel_uart_data uart0_data = {
813 .use_dma_rx = 1, 1035 .use_dma_rx = 1,
814}; 1036};
815 1037
1038static u64 uart0_dmamask = DMA_BIT_MASK(32);
1039
816static struct platform_device at91sam9263_uart0_device = { 1040static struct platform_device at91sam9263_uart0_device = {
817 .name = "atmel_usart", 1041 .name = "atmel_usart",
818 .id = 1, 1042 .id = 1,
819 .dev = { 1043 .dev = {
820 .platform_data = &uart0_data, 1044 .dma_mask = &uart0_dmamask,
821 .coherent_dma_mask = 0xffffffff, 1045 .coherent_dma_mask = DMA_BIT_MASK(32),
1046 .platform_data = &uart0_data,
822 }, 1047 },
823 .resource = uart0_resources, 1048 .resource = uart0_resources,
824 .num_resources = ARRAY_SIZE(uart0_resources), 1049 .num_resources = ARRAY_SIZE(uart0_resources),
825}; 1050};
826 1051
827static inline void configure_usart0_pins(void) 1052static inline void configure_usart0_pins(unsigned pins)
828{ 1053{
829 at91_set_A_periph(AT91_PIN_PA26, 1); /* TXD0 */ 1054 at91_set_A_periph(AT91_PIN_PA26, 1); /* TXD0 */
830 at91_set_A_periph(AT91_PIN_PA27, 0); /* RXD0 */ 1055 at91_set_A_periph(AT91_PIN_PA27, 0); /* RXD0 */
831 at91_set_A_periph(AT91_PIN_PA28, 0); /* RTS0 */ 1056
832 at91_set_A_periph(AT91_PIN_PA29, 0); /* CTS0 */ 1057 if (pins & ATMEL_UART_RTS)
1058 at91_set_A_periph(AT91_PIN_PA28, 0); /* RTS0 */
1059 if (pins & ATMEL_UART_CTS)
1060 at91_set_A_periph(AT91_PIN_PA29, 0); /* CTS0 */
833} 1061}
834 1062
835static struct resource uart1_resources[] = { 1063static struct resource uart1_resources[] = {
@@ -850,23 +1078,29 @@ static struct atmel_uart_data uart1_data = {
850 .use_dma_rx = 1, 1078 .use_dma_rx = 1,
851}; 1079};
852 1080
1081static u64 uart1_dmamask = DMA_BIT_MASK(32);
1082
853static struct platform_device at91sam9263_uart1_device = { 1083static struct platform_device at91sam9263_uart1_device = {
854 .name = "atmel_usart", 1084 .name = "atmel_usart",
855 .id = 2, 1085 .id = 2,
856 .dev = { 1086 .dev = {
857 .platform_data = &uart1_data, 1087 .dma_mask = &uart1_dmamask,
858 .coherent_dma_mask = 0xffffffff, 1088 .coherent_dma_mask = DMA_BIT_MASK(32),
1089 .platform_data = &uart1_data,
859 }, 1090 },
860 .resource = uart1_resources, 1091 .resource = uart1_resources,
861 .num_resources = ARRAY_SIZE(uart1_resources), 1092 .num_resources = ARRAY_SIZE(uart1_resources),
862}; 1093};
863 1094
864static inline void configure_usart1_pins(void) 1095static inline void configure_usart1_pins(unsigned pins)
865{ 1096{
866 at91_set_A_periph(AT91_PIN_PD0, 1); /* TXD1 */ 1097 at91_set_A_periph(AT91_PIN_PD0, 1); /* TXD1 */
867 at91_set_A_periph(AT91_PIN_PD1, 0); /* RXD1 */ 1098 at91_set_A_periph(AT91_PIN_PD1, 0); /* RXD1 */
868 at91_set_B_periph(AT91_PIN_PD7, 0); /* RTS1 */ 1099
869 at91_set_B_periph(AT91_PIN_PD8, 0); /* CTS1 */ 1100 if (pins & ATMEL_UART_RTS)
1101 at91_set_B_periph(AT91_PIN_PD7, 0); /* RTS1 */
1102 if (pins & ATMEL_UART_CTS)
1103 at91_set_B_periph(AT91_PIN_PD8, 0); /* CTS1 */
870} 1104}
871 1105
872static struct resource uart2_resources[] = { 1106static struct resource uart2_resources[] = {
@@ -887,29 +1121,35 @@ static struct atmel_uart_data uart2_data = {
887 .use_dma_rx = 1, 1121 .use_dma_rx = 1,
888}; 1122};
889 1123
1124static u64 uart2_dmamask = DMA_BIT_MASK(32);
1125
890static struct platform_device at91sam9263_uart2_device = { 1126static struct platform_device at91sam9263_uart2_device = {
891 .name = "atmel_usart", 1127 .name = "atmel_usart",
892 .id = 3, 1128 .id = 3,
893 .dev = { 1129 .dev = {
894 .platform_data = &uart2_data, 1130 .dma_mask = &uart2_dmamask,
895 .coherent_dma_mask = 0xffffffff, 1131 .coherent_dma_mask = DMA_BIT_MASK(32),
1132 .platform_data = &uart2_data,
896 }, 1133 },
897 .resource = uart2_resources, 1134 .resource = uart2_resources,
898 .num_resources = ARRAY_SIZE(uart2_resources), 1135 .num_resources = ARRAY_SIZE(uart2_resources),
899}; 1136};
900 1137
901static inline void configure_usart2_pins(void) 1138static inline void configure_usart2_pins(unsigned pins)
902{ 1139{
903 at91_set_A_periph(AT91_PIN_PD2, 1); /* TXD2 */ 1140 at91_set_A_periph(AT91_PIN_PD2, 1); /* TXD2 */
904 at91_set_A_periph(AT91_PIN_PD3, 0); /* RXD2 */ 1141 at91_set_A_periph(AT91_PIN_PD3, 0); /* RXD2 */
905 at91_set_B_periph(AT91_PIN_PD5, 0); /* RTS2 */ 1142
906 at91_set_B_periph(AT91_PIN_PD6, 0); /* CTS2 */ 1143 if (pins & ATMEL_UART_RTS)
1144 at91_set_B_periph(AT91_PIN_PD5, 0); /* RTS2 */
1145 if (pins & ATMEL_UART_CTS)
1146 at91_set_B_periph(AT91_PIN_PD6, 0); /* CTS2 */
907} 1147}
908 1148
909struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ 1149static struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
910struct platform_device *atmel_default_console_device; /* the serial console device */ 1150struct platform_device *atmel_default_console_device; /* the serial console device */
911 1151
912void __init at91_init_serial(struct at91_uart_config *config) 1152void __init __deprecated at91_init_serial(struct at91_uart_config *config)
913{ 1153{
914 int i; 1154 int i;
915 1155
@@ -917,17 +1157,17 @@ void __init at91_init_serial(struct at91_uart_config *config)
917 for (i = 0; i < config->nr_tty; i++) { 1157 for (i = 0; i < config->nr_tty; i++) {
918 switch (config->tty_map[i]) { 1158 switch (config->tty_map[i]) {
919 case 0: 1159 case 0:
920 configure_usart0_pins(); 1160 configure_usart0_pins(ATMEL_UART_CTS | ATMEL_UART_RTS);
921 at91_uarts[i] = &at91sam9263_uart0_device; 1161 at91_uarts[i] = &at91sam9263_uart0_device;
922 at91_clock_associate("usart0_clk", &at91sam9263_uart0_device.dev, "usart"); 1162 at91_clock_associate("usart0_clk", &at91sam9263_uart0_device.dev, "usart");
923 break; 1163 break;
924 case 1: 1164 case 1:
925 configure_usart1_pins(); 1165 configure_usart1_pins(ATMEL_UART_CTS | ATMEL_UART_RTS);
926 at91_uarts[i] = &at91sam9263_uart1_device; 1166 at91_uarts[i] = &at91sam9263_uart1_device;
927 at91_clock_associate("usart1_clk", &at91sam9263_uart1_device.dev, "usart"); 1167 at91_clock_associate("usart1_clk", &at91sam9263_uart1_device.dev, "usart");
928 break; 1168 break;
929 case 2: 1169 case 2:
930 configure_usart2_pins(); 1170 configure_usart2_pins(ATMEL_UART_CTS | ATMEL_UART_RTS);
931 at91_uarts[i] = &at91sam9263_uart2_device; 1171 at91_uarts[i] = &at91sam9263_uart2_device;
932 at91_clock_associate("usart2_clk", &at91sam9263_uart2_device.dev, "usart"); 1172 at91_clock_associate("usart2_clk", &at91sam9263_uart2_device.dev, "usart");
933 break; 1173 break;
@@ -949,6 +1189,48 @@ void __init at91_init_serial(struct at91_uart_config *config)
949 printk(KERN_INFO "AT91: No default serial console defined.\n"); 1189 printk(KERN_INFO "AT91: No default serial console defined.\n");
950} 1190}
951 1191
1192void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
1193{
1194 struct platform_device *pdev;
1195
1196 switch (id) {
1197 case 0: /* DBGU */
1198 pdev = &at91sam9263_dbgu_device;
1199 configure_dbgu_pins();
1200 at91_clock_associate("mck", &pdev->dev, "usart");
1201 break;
1202 case AT91SAM9263_ID_US0:
1203 pdev = &at91sam9263_uart0_device;
1204 configure_usart0_pins(pins);
1205 at91_clock_associate("usart0_clk", &pdev->dev, "usart");
1206 break;
1207 case AT91SAM9263_ID_US1:
1208 pdev = &at91sam9263_uart1_device;
1209 configure_usart1_pins(pins);
1210 at91_clock_associate("usart1_clk", &pdev->dev, "usart");
1211 break;
1212 case AT91SAM9263_ID_US2:
1213 pdev = &at91sam9263_uart2_device;
1214 configure_usart2_pins(pins);
1215 at91_clock_associate("usart2_clk", &pdev->dev, "usart");
1216 break;
1217 default:
1218 return;
1219 }
1220 pdev->id = portnr; /* update to mapped ID */
1221
1222 if (portnr < ATMEL_MAX_UART)
1223 at91_uarts[portnr] = pdev;
1224}
1225
1226void __init at91_set_serial_console(unsigned portnr)
1227{
1228 if (portnr < ATMEL_MAX_UART)
1229 atmel_default_console_device = at91_uarts[portnr];
1230 if (!atmel_default_console_device)
1231 printk(KERN_INFO "AT91: No default serial console defined.\n");
1232}
1233
952void __init at91_add_device_serial(void) 1234void __init at91_add_device_serial(void)
953{ 1235{
954 int i; 1236 int i;
@@ -960,6 +1242,8 @@ void __init at91_add_device_serial(void)
960} 1242}
961#else 1243#else
962void __init at91_init_serial(struct at91_uart_config *config) {} 1244void __init at91_init_serial(struct at91_uart_config *config) {}
1245void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
1246void __init at91_set_serial_console(unsigned portnr) {}
963void __init at91_add_device_serial(void) {} 1247void __init at91_add_device_serial(void) {}
964#endif 1248#endif
965 1249
@@ -971,6 +1255,8 @@ void __init at91_add_device_serial(void) {}
971 */ 1255 */
972static int __init at91_add_standard_devices(void) 1256static int __init at91_add_standard_devices(void)
973{ 1257{
1258 at91_add_device_rtt();
1259 at91_add_device_watchdog();
974 return 0; 1260 return 0;
975} 1261}
976 1262
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c
index 2bd60a3dc623..f43b5c33e45d 100644
--- a/arch/arm/mach-at91/at91sam9rl_devices.c
+++ b/arch/arm/mach-at91/at91sam9rl_devices.c
@@ -9,6 +9,7 @@
9#include <asm/mach/arch.h> 9#include <asm/mach/arch.h>
10#include <asm/mach/map.h> 10#include <asm/mach/map.h>
11 11
12#include <linux/dma-mapping.h>
12#include <linux/platform_device.h> 13#include <linux/platform_device.h>
13#include <linux/i2c-gpio.h> 14#include <linux/i2c-gpio.h>
14 15
@@ -29,7 +30,7 @@
29 * -------------------------------------------------------------------- */ 30 * -------------------------------------------------------------------- */
30 31
31#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) 32#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE)
32static u64 mmc_dmamask = 0xffffffffUL; 33static u64 mmc_dmamask = DMA_BIT_MASK(32);
33static struct at91_mmc_data mmc_data; 34static struct at91_mmc_data mmc_data;
34 35
35static struct resource mmc_resources[] = { 36static struct resource mmc_resources[] = {
@@ -50,7 +51,7 @@ static struct platform_device at91sam9rl_mmc_device = {
50 .id = -1, 51 .id = -1,
51 .dev = { 52 .dev = {
52 .dma_mask = &mmc_dmamask, 53 .dma_mask = &mmc_dmamask,
53 .coherent_dma_mask = 0xffffffff, 54 .coherent_dma_mask = DMA_BIT_MASK(32),
54 .platform_data = &mmc_data, 55 .platform_data = &mmc_data,
55 }, 56 },
56 .resource = mmc_resources, 57 .resource = mmc_resources,
@@ -247,7 +248,7 @@ void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
247 * -------------------------------------------------------------------- */ 248 * -------------------------------------------------------------------- */
248 249
249#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) 250#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
250static u64 spi_dmamask = 0xffffffffUL; 251static u64 spi_dmamask = DMA_BIT_MASK(32);
251 252
252static struct resource spi_resources[] = { 253static struct resource spi_resources[] = {
253 [0] = { 254 [0] = {
@@ -267,7 +268,7 @@ static struct platform_device at91sam9rl_spi_device = {
267 .id = 0, 268 .id = 0,
268 .dev = { 269 .dev = {
269 .dma_mask = &spi_dmamask, 270 .dma_mask = &spi_dmamask,
270 .coherent_dma_mask = 0xffffffff, 271 .coherent_dma_mask = DMA_BIT_MASK(32),
271 }, 272 },
272 .resource = spi_resources, 273 .resource = spi_resources,
273 .num_resources = ARRAY_SIZE(spi_resources), 274 .num_resources = ARRAY_SIZE(spi_resources),
@@ -312,7 +313,7 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
312 * -------------------------------------------------------------------- */ 313 * -------------------------------------------------------------------- */
313 314
314#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) 315#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
315static u64 lcdc_dmamask = 0xffffffffUL; 316static u64 lcdc_dmamask = DMA_BIT_MASK(32);
316static struct atmel_lcdfb_info lcdc_data; 317static struct atmel_lcdfb_info lcdc_data;
317 318
318static struct resource lcdc_resources[] = { 319static struct resource lcdc_resources[] = {
@@ -340,7 +341,7 @@ static struct platform_device at91_lcdc_device = {
340 .id = 0, 341 .id = 0,
341 .dev = { 342 .dev = {
342 .dma_mask = &lcdc_dmamask, 343 .dma_mask = &lcdc_dmamask,
343 .coherent_dma_mask = 0xffffffff, 344 .coherent_dma_mask = DMA_BIT_MASK(32),
344 .platform_data = &lcdc_data, 345 .platform_data = &lcdc_data,
345 }, 346 },
346 .resource = lcdc_resources, 347 .resource = lcdc_resources,
@@ -384,24 +385,196 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
384 385
385 386
386/* -------------------------------------------------------------------- 387/* --------------------------------------------------------------------
387 * LEDs 388 * RTC
388 * -------------------------------------------------------------------- */ 389 * -------------------------------------------------------------------- */
389 390
390#if defined(CONFIG_LEDS) 391#if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE)
391u8 at91_leds_cpu; 392static struct platform_device at91sam9rl_rtc_device = {
392u8 at91_leds_timer; 393 .name = "at91_rtc",
394 .id = -1,
395 .num_resources = 0,
396};
393 397
394void __init at91_init_leds(u8 cpu_led, u8 timer_led) 398static void __init at91_add_device_rtc(void)
395{ 399{
396 /* Enable GPIO to access the LEDs */ 400 platform_device_register(&at91sam9rl_rtc_device);
397 at91_set_gpio_output(cpu_led, 1); 401}
398 at91_set_gpio_output(timer_led, 1); 402#else
403static void __init at91_add_device_rtc(void) {}
404#endif
405
406
407/* --------------------------------------------------------------------
408 * RTT
409 * -------------------------------------------------------------------- */
410
411static struct resource rtt_resources[] = {
412 {
413 .start = AT91_BASE_SYS + AT91_RTT,
414 .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1,
415 .flags = IORESOURCE_MEM,
416 }
417};
418
419static struct platform_device at91sam9rl_rtt_device = {
420 .name = "at91_rtt",
421 .id = -1,
422 .resource = rtt_resources,
423 .num_resources = ARRAY_SIZE(rtt_resources),
424};
399 425
400 at91_leds_cpu = cpu_led; 426static void __init at91_add_device_rtt(void)
401 at91_leds_timer = timer_led; 427{
428 platform_device_register(&at91sam9rl_rtt_device);
429}
430
431
432/* --------------------------------------------------------------------
433 * Watchdog
434 * -------------------------------------------------------------------- */
435
436#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE)
437static struct platform_device at91sam9rl_wdt_device = {
438 .name = "at91_wdt",
439 .id = -1,
440 .num_resources = 0,
441};
442
443static void __init at91_add_device_watchdog(void)
444{
445 platform_device_register(&at91sam9rl_wdt_device);
402} 446}
403#else 447#else
404void __init at91_init_leds(u8 cpu_led, u8 timer_led) {} 448static void __init at91_add_device_watchdog(void) {}
449#endif
450
451
452/* --------------------------------------------------------------------
453 * SSC -- Synchronous Serial Controller
454 * -------------------------------------------------------------------- */
455
456#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE)
457static u64 ssc0_dmamask = DMA_BIT_MASK(32);
458
459static struct resource ssc0_resources[] = {
460 [0] = {
461 .start = AT91SAM9RL_BASE_SSC0,
462 .end = AT91SAM9RL_BASE_SSC0 + SZ_16K - 1,
463 .flags = IORESOURCE_MEM,
464 },
465 [1] = {
466 .start = AT91SAM9RL_ID_SSC0,
467 .end = AT91SAM9RL_ID_SSC0,
468 .flags = IORESOURCE_IRQ,
469 },
470};
471
472static struct platform_device at91sam9rl_ssc0_device = {
473 .name = "ssc",
474 .id = 0,
475 .dev = {
476 .dma_mask = &ssc0_dmamask,
477 .coherent_dma_mask = DMA_BIT_MASK(32),
478 },
479 .resource = ssc0_resources,
480 .num_resources = ARRAY_SIZE(ssc0_resources),
481};
482
483static inline void configure_ssc0_pins(unsigned pins)
484{
485 if (pins & ATMEL_SSC_TF)
486 at91_set_A_periph(AT91_PIN_PC0, 1);
487 if (pins & ATMEL_SSC_TK)
488 at91_set_A_periph(AT91_PIN_PC1, 1);
489 if (pins & ATMEL_SSC_TD)
490 at91_set_A_periph(AT91_PIN_PA15, 1);
491 if (pins & ATMEL_SSC_RD)
492 at91_set_A_periph(AT91_PIN_PA16, 1);
493 if (pins & ATMEL_SSC_RK)
494 at91_set_B_periph(AT91_PIN_PA10, 1);
495 if (pins & ATMEL_SSC_RF)
496 at91_set_B_periph(AT91_PIN_PA22, 1);
497}
498
499static u64 ssc1_dmamask = DMA_BIT_MASK(32);
500
501static struct resource ssc1_resources[] = {
502 [0] = {
503 .start = AT91SAM9RL_BASE_SSC1,
504 .end = AT91SAM9RL_BASE_SSC1 + SZ_16K - 1,
505 .flags = IORESOURCE_MEM,
506 },
507 [1] = {
508 .start = AT91SAM9RL_ID_SSC1,
509 .end = AT91SAM9RL_ID_SSC1,
510 .flags = IORESOURCE_IRQ,
511 },
512};
513
514static struct platform_device at91sam9rl_ssc1_device = {
515 .name = "ssc",
516 .id = 1,
517 .dev = {
518 .dma_mask = &ssc1_dmamask,
519 .coherent_dma_mask = DMA_BIT_MASK(32),
520 },
521 .resource = ssc1_resources,
522 .num_resources = ARRAY_SIZE(ssc1_resources),
523};
524
525static inline void configure_ssc1_pins(unsigned pins)
526{
527 if (pins & ATMEL_SSC_TF)
528 at91_set_B_periph(AT91_PIN_PA29, 1);
529 if (pins & ATMEL_SSC_TK)
530 at91_set_B_periph(AT91_PIN_PA30, 1);
531 if (pins & ATMEL_SSC_TD)
532 at91_set_B_periph(AT91_PIN_PA13, 1);
533 if (pins & ATMEL_SSC_RD)
534 at91_set_B_periph(AT91_PIN_PA14, 1);
535 if (pins & ATMEL_SSC_RK)
536 at91_set_B_periph(AT91_PIN_PA9, 1);
537 if (pins & ATMEL_SSC_RF)
538 at91_set_B_periph(AT91_PIN_PA8, 1);
539}
540
541/*
542 * Return the device node so that board init code can use it as the
543 * parent for the device node reflecting how it's used on this board.
544 *
545 * SSC controllers are accessed through library code, instead of any
546 * kind of all-singing/all-dancing driver. For example one could be
547 * used by a particular I2S audio codec's driver, while another one
548 * on the same system might be used by a custom data capture driver.
549 */
550void __init at91_add_device_ssc(unsigned id, unsigned pins)
551{
552 struct platform_device *pdev;
553
554 /*
555 * NOTE: caller is responsible for passing information matching
556 * "pins" to whatever will be using each particular controller.
557 */
558 switch (id) {
559 case AT91SAM9RL_ID_SSC0:
560 pdev = &at91sam9rl_ssc0_device;
561 configure_ssc0_pins(pins);
562 at91_clock_associate("ssc0_clk", &pdev->dev, "pclk");
563 break;
564 case AT91SAM9RL_ID_SSC1:
565 pdev = &at91sam9rl_ssc1_device;
566 configure_ssc1_pins(pins);
567 at91_clock_associate("ssc1_clk", &pdev->dev, "pclk");
568 break;
569 default:
570 return;
571 }
572
573 platform_device_register(pdev);
574}
575
576#else
577void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
405#endif 578#endif
406 579
407 580
@@ -429,12 +602,15 @@ static struct atmel_uart_data dbgu_data = {
429 .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), 602 .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
430}; 603};
431 604
605static u64 dbgu_dmamask = DMA_BIT_MASK(32);
606
432static struct platform_device at91sam9rl_dbgu_device = { 607static struct platform_device at91sam9rl_dbgu_device = {
433 .name = "atmel_usart", 608 .name = "atmel_usart",
434 .id = 0, 609 .id = 0,
435 .dev = { 610 .dev = {
436 .platform_data = &dbgu_data, 611 .dma_mask = &dbgu_dmamask,
437 .coherent_dma_mask = 0xffffffff, 612 .coherent_dma_mask = DMA_BIT_MASK(32),
613 .platform_data = &dbgu_data,
438 }, 614 },
439 .resource = dbgu_resources, 615 .resource = dbgu_resources,
440 .num_resources = ARRAY_SIZE(dbgu_resources), 616 .num_resources = ARRAY_SIZE(dbgu_resources),
@@ -464,23 +640,37 @@ static struct atmel_uart_data uart0_data = {
464 .use_dma_rx = 1, 640 .use_dma_rx = 1,
465}; 641};
466 642
643static u64 uart0_dmamask = DMA_BIT_MASK(32);
644
467static struct platform_device at91sam9rl_uart0_device = { 645static struct platform_device at91sam9rl_uart0_device = {
468 .name = "atmel_usart", 646 .name = "atmel_usart",
469 .id = 1, 647 .id = 1,
470 .dev = { 648 .dev = {
471 .platform_data = &uart0_data, 649 .dma_mask = &uart0_dmamask,
472 .coherent_dma_mask = 0xffffffff, 650 .coherent_dma_mask = DMA_BIT_MASK(32),
651 .platform_data = &uart0_data,
473 }, 652 },
474 .resource = uart0_resources, 653 .resource = uart0_resources,
475 .num_resources = ARRAY_SIZE(uart0_resources), 654 .num_resources = ARRAY_SIZE(uart0_resources),
476}; 655};
477 656
478static inline void configure_usart0_pins(void) 657static inline void configure_usart0_pins(unsigned pins)
479{ 658{
480 at91_set_A_periph(AT91_PIN_PA6, 1); /* TXD0 */ 659 at91_set_A_periph(AT91_PIN_PA6, 1); /* TXD0 */
481 at91_set_A_periph(AT91_PIN_PA7, 0); /* RXD0 */ 660 at91_set_A_periph(AT91_PIN_PA7, 0); /* RXD0 */
482 at91_set_A_periph(AT91_PIN_PA9, 0); /* RTS0 */ 661
483 at91_set_A_periph(AT91_PIN_PA10, 0); /* CTS0 */ 662 if (pins & ATMEL_UART_RTS)
663 at91_set_A_periph(AT91_PIN_PA9, 0); /* RTS0 */
664 if (pins & ATMEL_UART_CTS)
665 at91_set_A_periph(AT91_PIN_PA10, 0); /* CTS0 */
666 if (pins & ATMEL_UART_DSR)
667 at91_set_A_periph(AT91_PIN_PD14, 0); /* DSR0 */
668 if (pins & ATMEL_UART_DTR)
669 at91_set_A_periph(AT91_PIN_PD15, 0); /* DTR0 */
670 if (pins & ATMEL_UART_DCD)
671 at91_set_A_periph(AT91_PIN_PD16, 0); /* DCD0 */
672 if (pins & ATMEL_UART_RI)
673 at91_set_A_periph(AT91_PIN_PD17, 0); /* RI0 */
484} 674}
485 675
486static struct resource uart1_resources[] = { 676static struct resource uart1_resources[] = {
@@ -501,21 +691,29 @@ static struct atmel_uart_data uart1_data = {
501 .use_dma_rx = 1, 691 .use_dma_rx = 1,
502}; 692};
503 693
694static u64 uart1_dmamask = DMA_BIT_MASK(32);
695
504static struct platform_device at91sam9rl_uart1_device = { 696static struct platform_device at91sam9rl_uart1_device = {
505 .name = "atmel_usart", 697 .name = "atmel_usart",
506 .id = 2, 698 .id = 2,
507 .dev = { 699 .dev = {
508 .platform_data = &uart1_data, 700 .dma_mask = &uart1_dmamask,
509 .coherent_dma_mask = 0xffffffff, 701 .coherent_dma_mask = DMA_BIT_MASK(32),
702 .platform_data = &uart1_data,
510 }, 703 },
511 .resource = uart1_resources, 704 .resource = uart1_resources,
512 .num_resources = ARRAY_SIZE(uart1_resources), 705 .num_resources = ARRAY_SIZE(uart1_resources),
513}; 706};
514 707
515static inline void configure_usart1_pins(void) 708static inline void configure_usart1_pins(unsigned pins)
516{ 709{
517 at91_set_A_periph(AT91_PIN_PA11, 1); /* TXD1 */ 710 at91_set_A_periph(AT91_PIN_PA11, 1); /* TXD1 */
518 at91_set_A_periph(AT91_PIN_PA12, 0); /* RXD1 */ 711 at91_set_A_periph(AT91_PIN_PA12, 0); /* RXD1 */
712
713 if (pins & ATMEL_UART_RTS)
714 at91_set_B_periph(AT91_PIN_PA18, 0); /* RTS1 */
715 if (pins & ATMEL_UART_CTS)
716 at91_set_B_periph(AT91_PIN_PA19, 0); /* CTS1 */
519} 717}
520 718
521static struct resource uart2_resources[] = { 719static struct resource uart2_resources[] = {
@@ -536,21 +734,29 @@ static struct atmel_uart_data uart2_data = {
536 .use_dma_rx = 1, 734 .use_dma_rx = 1,
537}; 735};
538 736
737static u64 uart2_dmamask = DMA_BIT_MASK(32);
738
539static struct platform_device at91sam9rl_uart2_device = { 739static struct platform_device at91sam9rl_uart2_device = {
540 .name = "atmel_usart", 740 .name = "atmel_usart",
541 .id = 3, 741 .id = 3,
542 .dev = { 742 .dev = {
543 .platform_data = &uart2_data, 743 .dma_mask = &uart2_dmamask,
544 .coherent_dma_mask = 0xffffffff, 744 .coherent_dma_mask = DMA_BIT_MASK(32),
745 .platform_data = &uart2_data,
545 }, 746 },
546 .resource = uart2_resources, 747 .resource = uart2_resources,
547 .num_resources = ARRAY_SIZE(uart2_resources), 748 .num_resources = ARRAY_SIZE(uart2_resources),
548}; 749};
549 750
550static inline void configure_usart2_pins(void) 751static inline void configure_usart2_pins(unsigned pins)
551{ 752{
552 at91_set_A_periph(AT91_PIN_PA13, 1); /* TXD2 */ 753 at91_set_A_periph(AT91_PIN_PA13, 1); /* TXD2 */
553 at91_set_A_periph(AT91_PIN_PA14, 0); /* RXD2 */ 754 at91_set_A_periph(AT91_PIN_PA14, 0); /* RXD2 */
755
756 if (pins & ATMEL_UART_RTS)
757 at91_set_A_periph(AT91_PIN_PA29, 0); /* RTS2 */
758 if (pins & ATMEL_UART_CTS)
759 at91_set_A_periph(AT91_PIN_PA30, 0); /* CTS2 */
554} 760}
555 761
556static struct resource uart3_resources[] = { 762static struct resource uart3_resources[] = {
@@ -571,27 +777,35 @@ static struct atmel_uart_data uart3_data = {
571 .use_dma_rx = 1, 777 .use_dma_rx = 1,
572}; 778};
573 779
780static u64 uart3_dmamask = DMA_BIT_MASK(32);
781
574static struct platform_device at91sam9rl_uart3_device = { 782static struct platform_device at91sam9rl_uart3_device = {
575 .name = "atmel_usart", 783 .name = "atmel_usart",
576 .id = 4, 784 .id = 4,
577 .dev = { 785 .dev = {
578 .platform_data = &uart3_data, 786 .dma_mask = &uart3_dmamask,
579 .coherent_dma_mask = 0xffffffff, 787 .coherent_dma_mask = DMA_BIT_MASK(32),
788 .platform_data = &uart3_data,
580 }, 789 },
581 .resource = uart3_resources, 790 .resource = uart3_resources,
582 .num_resources = ARRAY_SIZE(uart3_resources), 791 .num_resources = ARRAY_SIZE(uart3_resources),
583}; 792};
584 793
585static inline void configure_usart3_pins(void) 794static inline void configure_usart3_pins(unsigned pins)
586{ 795{
587 at91_set_A_periph(AT91_PIN_PB0, 1); /* TXD3 */ 796 at91_set_A_periph(AT91_PIN_PB0, 1); /* TXD3 */
588 at91_set_A_periph(AT91_PIN_PB1, 0); /* RXD3 */ 797 at91_set_A_periph(AT91_PIN_PB1, 0); /* RXD3 */
798
799 if (pins & ATMEL_UART_RTS)
800 at91_set_B_periph(AT91_PIN_PD4, 0); /* RTS3 */
801 if (pins & ATMEL_UART_CTS)
802 at91_set_B_periph(AT91_PIN_PD3, 0); /* CTS3 */
589} 803}
590 804
591struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ 805static struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
592struct platform_device *atmel_default_console_device; /* the serial console device */ 806struct platform_device *atmel_default_console_device; /* the serial console device */
593 807
594void __init at91_init_serial(struct at91_uart_config *config) 808void __init __deprecated at91_init_serial(struct at91_uart_config *config)
595{ 809{
596 int i; 810 int i;
597 811
@@ -599,22 +813,22 @@ void __init at91_init_serial(struct at91_uart_config *config)
599 for (i = 0; i < config->nr_tty; i++) { 813 for (i = 0; i < config->nr_tty; i++) {
600 switch (config->tty_map[i]) { 814 switch (config->tty_map[i]) {
601 case 0: 815 case 0:
602 configure_usart0_pins(); 816 configure_usart0_pins(ATMEL_UART_CTS | ATMEL_UART_RTS);
603 at91_uarts[i] = &at91sam9rl_uart0_device; 817 at91_uarts[i] = &at91sam9rl_uart0_device;
604 at91_clock_associate("usart0_clk", &at91sam9rl_uart0_device.dev, "usart"); 818 at91_clock_associate("usart0_clk", &at91sam9rl_uart0_device.dev, "usart");
605 break; 819 break;
606 case 1: 820 case 1:
607 configure_usart1_pins(); 821 configure_usart1_pins(0);
608 at91_uarts[i] = &at91sam9rl_uart1_device; 822 at91_uarts[i] = &at91sam9rl_uart1_device;
609 at91_clock_associate("usart1_clk", &at91sam9rl_uart1_device.dev, "usart"); 823 at91_clock_associate("usart1_clk", &at91sam9rl_uart1_device.dev, "usart");
610 break; 824 break;
611 case 2: 825 case 2:
612 configure_usart2_pins(); 826 configure_usart2_pins(0);
613 at91_uarts[i] = &at91sam9rl_uart2_device; 827 at91_uarts[i] = &at91sam9rl_uart2_device;
614 at91_clock_associate("usart2_clk", &at91sam9rl_uart2_device.dev, "usart"); 828 at91_clock_associate("usart2_clk", &at91sam9rl_uart2_device.dev, "usart");
615 break; 829 break;
616 case 3: 830 case 3:
617 configure_usart3_pins(); 831 configure_usart3_pins(0);
618 at91_uarts[i] = &at91sam9rl_uart3_device; 832 at91_uarts[i] = &at91sam9rl_uart3_device;
619 at91_clock_associate("usart3_clk", &at91sam9rl_uart3_device.dev, "usart"); 833 at91_clock_associate("usart3_clk", &at91sam9rl_uart3_device.dev, "usart");
620 break; 834 break;
@@ -636,6 +850,53 @@ void __init at91_init_serial(struct at91_uart_config *config)
636 printk(KERN_INFO "AT91: No default serial console defined.\n"); 850 printk(KERN_INFO "AT91: No default serial console defined.\n");
637} 851}
638 852
853void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
854{
855 struct platform_device *pdev;
856
857 switch (id) {
858 case 0: /* DBGU */
859 pdev = &at91sam9rl_dbgu_device;
860 configure_dbgu_pins();
861 at91_clock_associate("mck", &pdev->dev, "usart");
862 break;
863 case AT91SAM9RL_ID_US0:
864 pdev = &at91sam9rl_uart0_device;
865 configure_usart0_pins(pins);
866 at91_clock_associate("usart0_clk", &pdev->dev, "usart");
867 break;
868 case AT91SAM9RL_ID_US1:
869 pdev = &at91sam9rl_uart1_device;
870 configure_usart1_pins(pins);
871 at91_clock_associate("usart1_clk", &pdev->dev, "usart");
872 break;
873 case AT91SAM9RL_ID_US2:
874 pdev = &at91sam9rl_uart2_device;
875 configure_usart2_pins(pins);
876 at91_clock_associate("usart2_clk", &pdev->dev, "usart");
877 break;
878 case AT91SAM9RL_ID_US3:
879 pdev = &at91sam9rl_uart3_device;
880 configure_usart3_pins(pins);
881 at91_clock_associate("usart3_clk", &pdev->dev, "usart");
882 break;
883 default:
884 return;
885 }
886 pdev->id = portnr; /* update to mapped ID */
887
888 if (portnr < ATMEL_MAX_UART)
889 at91_uarts[portnr] = pdev;
890}
891
892void __init at91_set_serial_console(unsigned portnr)
893{
894 if (portnr < ATMEL_MAX_UART)
895 atmel_default_console_device = at91_uarts[portnr];
896 if (!atmel_default_console_device)
897 printk(KERN_INFO "AT91: No default serial console defined.\n");
898}
899
639void __init at91_add_device_serial(void) 900void __init at91_add_device_serial(void)
640{ 901{
641 int i; 902 int i;
@@ -646,7 +907,9 @@ void __init at91_add_device_serial(void)
646 } 907 }
647} 908}
648#else 909#else
649void __init at91_init_serial(struct at91_uart_config *config) {} 910void __init __deprecated at91_init_serial(struct at91_uart_config *config) {}
911void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
912void __init at91_set_serial_console(unsigned portnr) {}
650void __init at91_add_device_serial(void) {} 913void __init at91_add_device_serial(void) {}
651#endif 914#endif
652 915
@@ -659,6 +922,9 @@ void __init at91_add_device_serial(void) {}
659 */ 922 */
660static int __init at91_add_standard_devices(void) 923static int __init at91_add_standard_devices(void)
661{ 924{
925 at91_add_device_rtc();
926 at91_add_device_rtt();
927 at91_add_device_watchdog();
662 return 0; 928 return 0;
663} 929}
664 930
diff --git a/arch/arm/mach-at91/board-cap9adk.c b/arch/arm/mach-at91/board-cap9adk.c
new file mode 100644
index 000000000000..185437131541
--- /dev/null
+++ b/arch/arm/mach-at91/board-cap9adk.c
@@ -0,0 +1,359 @@
1/*
2 * linux/arch/arm/mach-at91/board-cap9adk.c
3 *
4 * Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com>
5 * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com>
6 * Copyright (C) 2005 SAN People
7 * Copyright (C) 2007 Atmel Corporation.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include <linux/types.h>
25#include <linux/init.h>
26#include <linux/mm.h>
27#include <linux/module.h>
28#include <linux/platform_device.h>
29#include <linux/spi/spi.h>
30#include <linux/spi/ads7846.h>
31#include <linux/fb.h>
32#include <linux/mtd/physmap.h>
33
34#include <video/atmel_lcdc.h>
35
36#include <asm/hardware.h>
37#include <asm/setup.h>
38#include <asm/mach-types.h>
39#include <asm/irq.h>
40
41#include <asm/mach/arch.h>
42#include <asm/mach/map.h>
43#include <asm/mach/irq.h>
44
45#include <asm/arch/board.h>
46#include <asm/arch/gpio.h>
47#include <asm/arch/at91cap9_matrix.h>
48#include <asm/arch/at91sam926x_mc.h>
49
50#include "generic.h"
51
52
53static void __init cap9adk_map_io(void)
54{
55 /* Initialize processor: 12 MHz crystal */
56 at91cap9_initialize(12000000);
57
58 /* Setup the LEDs: USER1 and USER2 LED for cpu/timer... */
59 at91_init_leds(AT91_PIN_PA10, AT91_PIN_PA11);
60 /* ... POWER LED always on */
61 at91_set_gpio_output(AT91_PIN_PC29, 1);
62
63 /* Setup the serial ports and console */
64 at91_register_uart(0, 0, 0); /* DBGU = ttyS0 */
65 at91_set_serial_console(0);
66}
67
68static void __init cap9adk_init_irq(void)
69{
70 at91cap9_init_interrupts(NULL);
71}
72
73
74/*
75 * USB Host port
76 */
77static struct at91_usbh_data __initdata cap9adk_usbh_data = {
78 .ports = 2,
79};
80
81
82/*
83 * ADS7846 Touchscreen
84 */
85#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
86static int ads7843_pendown_state(void)
87{
88 return !at91_get_gpio_value(AT91_PIN_PC4); /* Touchscreen PENIRQ */
89}
90
91static struct ads7846_platform_data ads_info = {
92 .model = 7843,
93 .x_min = 150,
94 .x_max = 3830,
95 .y_min = 190,
96 .y_max = 3830,
97 .vref_delay_usecs = 100,
98 .x_plate_ohms = 450,
99 .y_plate_ohms = 250,
100 .pressure_max = 15000,
101 .debounce_max = 1,
102 .debounce_rep = 0,
103 .debounce_tol = (~0),
104 .get_pendown_state = ads7843_pendown_state,
105};
106
107static void __init cap9adk_add_device_ts(void)
108{
109 at91_set_gpio_input(AT91_PIN_PC4, 1); /* Touchscreen PENIRQ */
110 at91_set_gpio_input(AT91_PIN_PC5, 1); /* Touchscreen BUSY */
111}
112#else
113static void __init cap9adk_add_device_ts(void) {}
114#endif
115
116
117/*
118 * SPI devices.
119 */
120static struct spi_board_info cap9adk_spi_devices[] = {
121#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD)
122 { /* DataFlash card */
123 .modalias = "mtd_dataflash",
124 .chip_select = 0,
125 .max_speed_hz = 15 * 1000 * 1000,
126 .bus_num = 0,
127 },
128#endif
129#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
130 {
131 .modalias = "ads7846",
132 .chip_select = 3, /* can be 2 or 3, depending on J2 jumper */
133 .max_speed_hz = 125000 * 26, /* (max sample rate @ 3V) * (cmd + data + overhead) */
134 .bus_num = 0,
135 .platform_data = &ads_info,
136 .irq = AT91_PIN_PC4,
137 },
138#endif
139};
140
141
142/*
143 * MCI (SD/MMC)
144 */
145static struct at91_mmc_data __initdata cap9adk_mmc_data = {
146 .wire4 = 1,
147// .det_pin = ... not connected
148// .wp_pin = ... not connected
149// .vcc_pin = ... not connected
150};
151
152
153/*
154 * MACB Ethernet device
155 */
156static struct at91_eth_data __initdata cap9adk_macb_data = {
157 .is_rmii = 1,
158};
159
160
161/*
162 * NAND flash
163 */
164static struct mtd_partition __initdata cap9adk_nand_partitions[] = {
165 {
166 .name = "NAND partition",
167 .offset = 0,
168 .size = MTDPART_SIZ_FULL,
169 },
170};
171
172static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
173{
174 *num_partitions = ARRAY_SIZE(cap9adk_nand_partitions);
175 return cap9adk_nand_partitions;
176}
177
178static struct at91_nand_data __initdata cap9adk_nand_data = {
179 .ale = 21,
180 .cle = 22,
181// .det_pin = ... not connected
182// .rdy_pin = ... not connected
183 .enable_pin = AT91_PIN_PD15,
184 .partition_info = nand_partitions,
185#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16)
186 .bus_width_16 = 1,
187#else
188 .bus_width_16 = 0,
189#endif
190};
191
192
193/*
194 * NOR flash
195 */
196static struct mtd_partition cap9adk_nor_partitions[] = {
197 {
198 .name = "NOR partition",
199 .offset = 0,
200 .size = MTDPART_SIZ_FULL,
201 },
202};
203
204static struct physmap_flash_data cap9adk_nor_data = {
205 .width = 2,
206 .parts = cap9adk_nor_partitions,
207 .nr_parts = ARRAY_SIZE(cap9adk_nor_partitions),
208};
209
210#define NOR_BASE AT91_CHIPSELECT_0
211#define NOR_SIZE 0x800000
212
213static struct resource nor_flash_resources[] = {
214 {
215 .start = NOR_BASE,
216 .end = NOR_BASE + NOR_SIZE - 1,
217 .flags = IORESOURCE_MEM,
218 }
219};
220
221static struct platform_device cap9adk_nor_flash = {
222 .name = "physmap-flash",
223 .id = 0,
224 .dev = {
225 .platform_data = &cap9adk_nor_data,
226 },
227 .resource = nor_flash_resources,
228 .num_resources = ARRAY_SIZE(nor_flash_resources),
229};
230
231static __init void cap9adk_add_device_nor(void)
232{
233 unsigned long csa;
234
235 csa = at91_sys_read(AT91_MATRIX_EBICSA);
236 at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_VDDIOMSEL_3_3V);
237
238 /* set the bus interface characteristics */
239 at91_sys_write(AT91_SMC_SETUP(0), AT91_SMC_NWESETUP_(4) | AT91_SMC_NCS_WRSETUP_(2)
240 | AT91_SMC_NRDSETUP_(4) | AT91_SMC_NCS_RDSETUP_(2));
241
242 at91_sys_write(AT91_SMC_PULSE(0), AT91_SMC_NWEPULSE_(8) | AT91_SMC_NCS_WRPULSE_(10)
243 | AT91_SMC_NRDPULSE_(8) | AT91_SMC_NCS_RDPULSE_(10));
244
245 at91_sys_write(AT91_SMC_CYCLE(0), AT91_SMC_NWECYCLE_(16) | AT91_SMC_NRDCYCLE_(16));
246
247 at91_sys_write(AT91_SMC_MODE(0), AT91_SMC_READMODE | AT91_SMC_WRITEMODE
248 | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_WRITE
249 | AT91_SMC_DBW_16 | AT91_SMC_TDF_(1));
250
251 platform_device_register(&cap9adk_nor_flash);
252}
253
254
255/*
256 * LCD Controller
257 */
258#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
259static struct fb_videomode at91_tft_vga_modes[] = {
260 {
261 .name = "TX09D50VM1CCA @ 60",
262 .refresh = 60,
263 .xres = 240, .yres = 320,
264 .pixclock = KHZ2PICOS(4965),
265
266 .left_margin = 1, .right_margin = 33,
267 .upper_margin = 1, .lower_margin = 0,
268 .hsync_len = 5, .vsync_len = 1,
269
270 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
271 .vmode = FB_VMODE_NONINTERLACED,
272 },
273};
274
275static struct fb_monspecs at91fb_default_monspecs = {
276 .manufacturer = "HIT",
277 .monitor = "TX09D70VM1CCA",
278
279 .modedb = at91_tft_vga_modes,
280 .modedb_len = ARRAY_SIZE(at91_tft_vga_modes),
281 .hfmin = 15000,
282 .hfmax = 64000,
283 .vfmin = 50,
284 .vfmax = 150,
285};
286
287#define AT91CAP9_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \
288 | ATMEL_LCDC_DISTYPE_TFT \
289 | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE)
290
291static void at91_lcdc_power_control(int on)
292{
293 if (on)
294 at91_set_gpio_value(AT91_PIN_PC0, 0); /* power up */
295 else
296 at91_set_gpio_value(AT91_PIN_PC0, 1); /* power down */
297}
298
299/* Driver datas */
300static struct atmel_lcdfb_info __initdata cap9adk_lcdc_data = {
301 .default_bpp = 16,
302 .default_dmacon = ATMEL_LCDC_DMAEN,
303 .default_lcdcon2 = AT91CAP9_DEFAULT_LCDCON2,
304 .default_monspecs = &at91fb_default_monspecs,
305 .atmel_lcdfb_power_control = at91_lcdc_power_control,
306 .guard_time = 1,
307};
308
309#else
310static struct atmel_lcdfb_info __initdata cap9adk_lcdc_data;
311#endif
312
313
314/*
315 * AC97
316 */
317static struct atmel_ac97_data cap9adk_ac97_data = {
318// .reset_pin = ... not connected
319};
320
321
322static void __init cap9adk_board_init(void)
323{
324 /* Serial */
325 at91_add_device_serial();
326 /* USB Host */
327 set_irq_type(AT91CAP9_ID_UHP, IRQT_HIGH);
328 at91_add_device_usbh(&cap9adk_usbh_data);
329 /* SPI */
330 at91_add_device_spi(cap9adk_spi_devices, ARRAY_SIZE(cap9adk_spi_devices));
331 /* Touchscreen */
332 cap9adk_add_device_ts();
333 /* MMC */
334 at91_add_device_mmc(1, &cap9adk_mmc_data);
335 /* Ethernet */
336 at91_add_device_eth(&cap9adk_macb_data);
337 /* NAND */
338 at91_add_device_nand(&cap9adk_nand_data);
339 /* NOR Flash */
340 cap9adk_add_device_nor();
341 /* I2C */
342 at91_add_device_i2c(NULL, 0);
343 /* LCD Controller */
344 set_irq_type(AT91CAP9_ID_LCDC, IRQT_HIGH);
345 at91_add_device_lcdc(&cap9adk_lcdc_data);
346 /* AC97 */
347 at91_add_device_ac97(&cap9adk_ac97_data);
348}
349
350MACHINE_START(AT91CAP9ADK, "Atmel AT91CAP9A-DK")
351 /* Maintainer: Stelian Pop <stelian.pop@leadtechdesign.com> */
352 .phys_io = AT91_BASE_SYS,
353 .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
354 .boot_params = AT91_SDRAM_BASE + 0x100,
355 .timer = &at91sam926x_timer,
356 .map_io = cap9adk_map_io,
357 .init_irq = cap9adk_init_irq,
358 .init_machine = cap9adk_board_init,
359MACHINE_END
diff --git a/arch/arm/mach-at91/board-csb337.c b/arch/arm/mach-at91/board-csb337.c
index d0aa20c9383e..0e2a11fc5bbd 100644
--- a/arch/arm/mach-at91/board-csb337.c
+++ b/arch/arm/mach-at91/board-csb337.c
@@ -25,6 +25,8 @@
25#include <linux/platform_device.h> 25#include <linux/platform_device.h>
26#include <linux/spi/spi.h> 26#include <linux/spi/spi.h>
27#include <linux/mtd/physmap.h> 27#include <linux/mtd/physmap.h>
28#include <linux/input.h>
29#include <linux/gpio_keys.h>
28 30
29#include <asm/hardware.h> 31#include <asm/hardware.h>
30#include <asm/setup.h> 32#include <asm/setup.h>
@@ -156,6 +158,85 @@ static struct platform_device csb_flash = {
156 .num_resources = ARRAY_SIZE(csb_flash_resources), 158 .num_resources = ARRAY_SIZE(csb_flash_resources),
157}; 159};
158 160
161/*
162 * GPIO Buttons (on CSB300)
163 */
164#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
165static struct gpio_keys_button csb300_buttons[] = {
166 {
167 .gpio = AT91_PIN_PB29,
168 .code = BTN_0,
169 .desc = "sw0",
170 .active_low = 1,
171 .wakeup = 1,
172 },
173 {
174 .gpio = AT91_PIN_PB28,
175 .code = BTN_1,
176 .desc = "sw1",
177 .active_low = 1,
178 .wakeup = 1,
179 },
180 {
181 .gpio = AT91_PIN_PA21,
182 .code = BTN_2,
183 .desc = "sw2",
184 .active_low = 1,
185 .wakeup = 1,
186 }
187};
188
189static struct gpio_keys_platform_data csb300_button_data = {
190 .buttons = csb300_buttons,
191 .nbuttons = ARRAY_SIZE(csb300_buttons),
192};
193
194static struct platform_device csb300_button_device = {
195 .name = "gpio-keys",
196 .id = -1,
197 .num_resources = 0,
198 .dev = {
199 .platform_data = &csb300_button_data,
200 }
201};
202
203static void __init csb300_add_device_buttons(void)
204{
205 at91_set_gpio_input(AT91_PIN_PB29, 0); /* sw0 */
206 at91_set_deglitch(AT91_PIN_PB29, 1);
207 at91_set_gpio_input(AT91_PIN_PB28, 0); /* sw1 */
208 at91_set_deglitch(AT91_PIN_PB28, 1);
209 at91_set_gpio_input(AT91_PIN_PA21, 0); /* sw2 */
210 at91_set_deglitch(AT91_PIN_PA21, 1);
211
212 platform_device_register(&csb300_button_device);
213}
214#else
215static void __init csb300_add_device_buttons(void) {}
216#endif
217
218static struct gpio_led csb_leds[] = {
219 { /* "led0", yellow */
220 .name = "led0",
221 .gpio = AT91_PIN_PB2,
222 .active_low = 1,
223 .default_trigger = "heartbeat",
224 },
225 { /* "led1", green */
226 .name = "led1",
227 .gpio = AT91_PIN_PB1,
228 .active_low = 1,
229 .default_trigger = "mmc0",
230 },
231 { /* "led2", yellow */
232 .name = "led2",
233 .gpio = AT91_PIN_PB0,
234 .active_low = 1,
235 .default_trigger = "ide-disk",
236 },
237};
238
239
159static void __init csb337_board_init(void) 240static void __init csb337_board_init(void)
160{ 241{
161 /* Serial */ 242 /* Serial */
@@ -177,6 +258,10 @@ static void __init csb337_board_init(void)
177 at91_add_device_mmc(0, &csb337_mmc_data); 258 at91_add_device_mmc(0, &csb337_mmc_data);
178 /* NOR flash */ 259 /* NOR flash */
179 platform_device_register(&csb_flash); 260 platform_device_register(&csb_flash);
261 /* LEDs */
262 at91_gpio_leds(csb_leds, ARRAY_SIZE(csb_leds));
263 /* Switches on CSB300 */
264 csb300_add_device_buttons();
180} 265}
181 266
182MACHINE_START(CSB337, "Cogent CSB337") 267MACHINE_START(CSB337, "Cogent CSB337")
diff --git a/arch/arm/mach-at91/board-dk.c b/arch/arm/mach-at91/board-dk.c
index 40c9e4331706..0a897efeba8e 100644
--- a/arch/arm/mach-at91/board-dk.c
+++ b/arch/arm/mach-at91/board-dk.c
@@ -183,6 +183,14 @@ static struct platform_device dk_flash = {
183 .num_resources = 1, 183 .num_resources = 1,
184}; 184};
185 185
186static struct gpio_led dk_leds[] = {
187 {
188 .name = "led0",
189 .gpio = AT91_PIN_PB2,
190 .active_low = 1,
191 .default_trigger = "heartbeat",
192 }
193};
186 194
187static void __init dk_board_init(void) 195static void __init dk_board_init(void)
188{ 196{
@@ -213,6 +221,8 @@ static void __init dk_board_init(void)
213 at91_add_device_nand(&dk_nand_data); 221 at91_add_device_nand(&dk_nand_data);
214 /* NOR Flash */ 222 /* NOR Flash */
215 platform_device_register(&dk_flash); 223 platform_device_register(&dk_flash);
224 /* LEDs */
225 at91_gpio_leds(dk_leds, ARRAY_SIZE(dk_leds));
216 /* VGA */ 226 /* VGA */
217// dk_add_device_video(); 227// dk_add_device_video();
218} 228}
diff --git a/arch/arm/mach-at91/board-ek.c b/arch/arm/mach-at91/board-ek.c
index 53a5ef9e72ee..0574e50a30dd 100644
--- a/arch/arm/mach-at91/board-ek.c
+++ b/arch/arm/mach-at91/board-ek.c
@@ -141,6 +141,25 @@ static struct platform_device ek_flash = {
141 .num_resources = 1, 141 .num_resources = 1,
142}; 142};
143 143
144static struct gpio_led ek_leds[] = {
145 { /* "user led 1", DS2 */
146 .name = "green",
147 .gpio = AT91_PIN_PB0,
148 .active_low = 1,
149 .default_trigger = "mmc0",
150 },
151 { /* "user led 2", DS4 */
152 .name = "yellow",
153 .gpio = AT91_PIN_PB1,
154 .active_low = 1,
155 .default_trigger = "heartbeat",
156 },
157 { /* "user led 3", DS6 */
158 .name = "red",
159 .gpio = AT91_PIN_PB2,
160 .active_low = 1,
161 }
162};
144 163
145static void __init ek_board_init(void) 164static void __init ek_board_init(void)
146{ 165{
@@ -167,6 +186,8 @@ static void __init ek_board_init(void)
167#endif 186#endif
168 /* NOR Flash */ 187 /* NOR Flash */
169 platform_device_register(&ek_flash); 188 platform_device_register(&ek_flash);
189 /* LEDs */
190 at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
170 /* VGA */ 191 /* VGA */
171// ek_add_device_video(); 192// ek_add_device_video();
172} 193}
diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c
index 550ae59a3aca..aa29ea58ca09 100644
--- a/arch/arm/mach-at91/board-sam9261ek.c
+++ b/arch/arm/mach-at91/board-sam9261ek.c
@@ -280,6 +280,68 @@ static struct spi_board_info ek_spi_devices[] = {
280 * LCD Controller 280 * LCD Controller
281 */ 281 */
282#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) 282#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
283
284#if defined(CONFIG_FB_ATMEL_STN)
285
286/* STN */
287static struct fb_videomode at91_stn_modes[] = {
288 {
289 .name = "SP06Q002 @ 75",
290 .refresh = 75,
291 .xres = 320, .yres = 240,
292 .pixclock = KHZ2PICOS(1440),
293
294 .left_margin = 1, .right_margin = 1,
295 .upper_margin = 0, .lower_margin = 0,
296 .hsync_len = 1, .vsync_len = 1,
297
298 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
299 .vmode = FB_VMODE_NONINTERLACED,
300 },
301};
302
303static struct fb_monspecs at91fb_default_stn_monspecs = {
304 .manufacturer = "HIT",
305 .monitor = "SP06Q002",
306
307 .modedb = at91_stn_modes,
308 .modedb_len = ARRAY_SIZE(at91_stn_modes),
309 .hfmin = 15000,
310 .hfmax = 64000,
311 .vfmin = 50,
312 .vfmax = 150,
313};
314
315#define AT91SAM9261_DEFAULT_STN_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \
316 | ATMEL_LCDC_DISTYPE_STNMONO \
317 | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE \
318 | ATMEL_LCDC_IFWIDTH_4 \
319 | ATMEL_LCDC_SCANMOD_SINGLE)
320
321static void at91_lcdc_stn_power_control(int on)
322{
323 /* backlight */
324 if (on) { /* power up */
325 at91_set_gpio_value(AT91_PIN_PC14, 0);
326 at91_set_gpio_value(AT91_PIN_PC15, 0);
327 } else { /* power down */
328 at91_set_gpio_value(AT91_PIN_PC14, 1);
329 at91_set_gpio_value(AT91_PIN_PC15, 1);
330 }
331}
332
333static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
334 .default_bpp = 1,
335 .default_dmacon = ATMEL_LCDC_DMAEN,
336 .default_lcdcon2 = AT91SAM9261_DEFAULT_STN_LCDCON2,
337 .default_monspecs = &at91fb_default_stn_monspecs,
338 .atmel_lcdfb_power_control = at91_lcdc_stn_power_control,
339 .guard_time = 1,
340};
341
342#else
343
344/* TFT */
283static struct fb_videomode at91_tft_vga_modes[] = { 345static struct fb_videomode at91_tft_vga_modes[] = {
284 { 346 {
285 .name = "TX09D50VM1CCA @ 60", 347 .name = "TX09D50VM1CCA @ 60",
@@ -296,7 +358,7 @@ static struct fb_videomode at91_tft_vga_modes[] = {
296 }, 358 },
297}; 359};
298 360
299static struct fb_monspecs at91fb_default_monspecs = { 361static struct fb_monspecs at91fb_default_tft_monspecs = {
300 .manufacturer = "HIT", 362 .manufacturer = "HIT",
301 .monitor = "TX09D50VM1CCA", 363 .monitor = "TX09D50VM1CCA",
302 364
@@ -308,11 +370,11 @@ static struct fb_monspecs at91fb_default_monspecs = {
308 .vfmax = 150, 370 .vfmax = 150,
309}; 371};
310 372
311#define AT91SAM9261_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \ 373#define AT91SAM9261_DEFAULT_TFT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \
312 | ATMEL_LCDC_DISTYPE_TFT \ 374 | ATMEL_LCDC_DISTYPE_TFT \
313 | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE) 375 | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE)
314 376
315static void at91_lcdc_power_control(int on) 377static void at91_lcdc_tft_power_control(int on)
316{ 378{
317 if (on) 379 if (on)
318 at91_set_gpio_value(AT91_PIN_PA12, 0); /* power up */ 380 at91_set_gpio_value(AT91_PIN_PA12, 0); /* power up */
@@ -320,15 +382,15 @@ static void at91_lcdc_power_control(int on)
320 at91_set_gpio_value(AT91_PIN_PA12, 1); /* power down */ 382 at91_set_gpio_value(AT91_PIN_PA12, 1); /* power down */
321} 383}
322 384
323/* Driver datas */
324static struct atmel_lcdfb_info __initdata ek_lcdc_data = { 385static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
325 .default_bpp = 16, 386 .default_bpp = 16,
326 .default_dmacon = ATMEL_LCDC_DMAEN, 387 .default_dmacon = ATMEL_LCDC_DMAEN,
327 .default_lcdcon2 = AT91SAM9261_DEFAULT_LCDCON2, 388 .default_lcdcon2 = AT91SAM9261_DEFAULT_TFT_LCDCON2,
328 .default_monspecs = &at91fb_default_monspecs, 389 .default_monspecs = &at91fb_default_tft_monspecs,
329 .atmel_lcdfb_power_control = at91_lcdc_power_control, 390 .atmel_lcdfb_power_control = at91_lcdc_tft_power_control,
330 .guard_time = 1, 391 .guard_time = 1,
331}; 392};
393#endif
332 394
333#else 395#else
334static struct atmel_lcdfb_info __initdata ek_lcdc_data; 396static struct atmel_lcdfb_info __initdata ek_lcdc_data;
@@ -342,25 +404,25 @@ static struct atmel_lcdfb_info __initdata ek_lcdc_data;
342static struct gpio_keys_button ek_buttons[] = { 404static struct gpio_keys_button ek_buttons[] = {
343 { 405 {
344 .gpio = AT91_PIN_PA27, 406 .gpio = AT91_PIN_PA27,
345 .keycode = BTN_0, 407 .code = BTN_0,
346 .desc = "Button 0", 408 .desc = "Button 0",
347 .active_low = 1, 409 .active_low = 1,
348 }, 410 },
349 { 411 {
350 .gpio = AT91_PIN_PA26, 412 .gpio = AT91_PIN_PA26,
351 .keycode = BTN_1, 413 .code = BTN_1,
352 .desc = "Button 1", 414 .desc = "Button 1",
353 .active_low = 1, 415 .active_low = 1,
354 }, 416 },
355 { 417 {
356 .gpio = AT91_PIN_PA25, 418 .gpio = AT91_PIN_PA25,
357 .keycode = BTN_2, 419 .code = BTN_2,
358 .desc = "Button 2", 420 .desc = "Button 2",
359 .active_low = 1, 421 .active_low = 1,
360 }, 422 },
361 { 423 {
362 .gpio = AT91_PIN_PA24, 424 .gpio = AT91_PIN_PA24,
363 .keycode = BTN_3, 425 .code = BTN_3,
364 .desc = "Button 3", 426 .desc = "Button 3",
365 .active_low = 1, 427 .active_low = 1,
366 } 428 }
diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c
index ab9dcc075454..f09347a86e71 100644
--- a/arch/arm/mach-at91/board-sam9263ek.c
+++ b/arch/arm/mach-at91/board-sam9263ek.c
@@ -27,6 +27,8 @@
27#include <linux/spi/spi.h> 27#include <linux/spi/spi.h>
28#include <linux/spi/ads7846.h> 28#include <linux/spi/ads7846.h>
29#include <linux/fb.h> 29#include <linux/fb.h>
30#include <linux/gpio_keys.h>
31#include <linux/input.h>
30 32
31#include <video/atmel_lcdc.h> 33#include <video/atmel_lcdc.h>
32 34
@@ -163,6 +165,7 @@ static struct at91_mmc_data __initdata ek_mmc_data = {
163 * MACB Ethernet device 165 * MACB Ethernet device
164 */ 166 */
165static struct at91_eth_data __initdata ek_macb_data = { 167static struct at91_eth_data __initdata ek_macb_data = {
168 .phy_irq_pin = AT91_PIN_PE31,
166 .is_rmii = 1, 169 .is_rmii = 1,
167}; 170};
168 171
@@ -264,6 +267,55 @@ static struct atmel_lcdfb_info __initdata ek_lcdc_data;
264 267
265 268
266/* 269/*
270 * GPIO Buttons
271 */
272#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
273static struct gpio_keys_button ek_buttons[] = {
274 { /* BP1, "leftclic" */
275 .code = BTN_LEFT,
276 .gpio = AT91_PIN_PC5,
277 .active_low = 1,
278 .desc = "left_click",
279 .wakeup = 1,
280 },
281 { /* BP2, "rightclic" */
282 .code = BTN_RIGHT,
283 .gpio = AT91_PIN_PC4,
284 .active_low = 1,
285 .desc = "right_click",
286 .wakeup = 1,
287 },
288};
289
290static struct gpio_keys_platform_data ek_button_data = {
291 .buttons = ek_buttons,
292 .nbuttons = ARRAY_SIZE(ek_buttons),
293};
294
295static struct platform_device ek_button_device = {
296 .name = "gpio-keys",
297 .id = -1,
298 .num_resources = 0,
299 .dev = {
300 .platform_data = &ek_button_data,
301 }
302};
303
304static void __init ek_add_device_buttons(void)
305{
306 at91_set_GPIO_periph(AT91_PIN_PC5, 0); /* left button */
307 at91_set_deglitch(AT91_PIN_PC5, 1);
308 at91_set_GPIO_periph(AT91_PIN_PC4, 0); /* right button */
309 at91_set_deglitch(AT91_PIN_PC4, 1);
310
311 platform_device_register(&ek_button_device);
312}
313#else
314static void __init ek_add_device_buttons(void) {}
315#endif
316
317
318/*
267 * AC97 319 * AC97
268 */ 320 */
269static struct atmel_ac97_data ek_ac97_data = { 321static struct atmel_ac97_data ek_ac97_data = {
@@ -271,6 +323,30 @@ static struct atmel_ac97_data ek_ac97_data = {
271}; 323};
272 324
273 325
326/*
327 * LEDs ... these could all be PWM-driven, for variable brightness
328 */
329static struct gpio_led ek_leds[] = {
330 { /* "left" led, green, userled1, pwm1 */
331 .name = "ds1",
332 .gpio = AT91_PIN_PB8,
333 .active_low = 1,
334 .default_trigger = "mmc0",
335 },
336 { /* "right" led, green, userled2, pwm2 */
337 .name = "ds2",
338 .gpio = AT91_PIN_PC29,
339 .active_low = 1,
340 .default_trigger = "nand-disk",
341 },
342 { /* "power" led, yellow, pwm0 */
343 .name = "ds3",
344 .gpio = AT91_PIN_PB7,
345 .default_trigger = "heartbeat",
346 },
347};
348
349
274static void __init ek_board_init(void) 350static void __init ek_board_init(void)
275{ 351{
276 /* Serial */ 352 /* Serial */
@@ -294,8 +370,12 @@ static void __init ek_board_init(void)
294 at91_add_device_i2c(NULL, 0); 370 at91_add_device_i2c(NULL, 0);
295 /* LCD Controller */ 371 /* LCD Controller */
296 at91_add_device_lcdc(&ek_lcdc_data); 372 at91_add_device_lcdc(&ek_lcdc_data);
373 /* Push Buttons */
374 ek_add_device_buttons();
297 /* AC97 */ 375 /* AC97 */
298 at91_add_device_ac97(&ek_ac97_data); 376 at91_add_device_ac97(&ek_ac97_data);
377 /* LEDs */
378 at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
299} 379}
300 380
301MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK") 381MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK")
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c
index 57c3b647ce83..ec76eeaafd45 100644
--- a/arch/arm/mach-at91/clock.c
+++ b/arch/arm/mach-at91/clock.c
@@ -574,6 +574,8 @@ int __init at91_clock_init(unsigned long main_clock)
574 } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263()) { 574 } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263()) {
575 uhpck.pmc_mask = AT91SAM926x_PMC_UHP; 575 uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
576 udpck.pmc_mask = AT91SAM926x_PMC_UDP; 576 udpck.pmc_mask = AT91SAM926x_PMC_UDP;
577 } else if (cpu_is_at91cap9()) {
578 uhpck.pmc_mask = AT91CAP9_PMC_UHP;
577 } 579 }
578 at91_sys_write(AT91_CKGR_PLLBR, 0); 580 at91_sys_write(AT91_CKGR_PLLBR, 0);
579 581
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index 77d4c0a37842..b5daf7f5e011 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -15,6 +15,7 @@ extern void __init at91sam9261_initialize(unsigned long main_clock);
15extern void __init at91sam9263_initialize(unsigned long main_clock); 15extern void __init at91sam9263_initialize(unsigned long main_clock);
16extern void __init at91sam9rl_initialize(unsigned long main_clock); 16extern void __init at91sam9rl_initialize(unsigned long main_clock);
17extern void __init at91x40_initialize(unsigned long main_clock); 17extern void __init at91x40_initialize(unsigned long main_clock);
18extern void __init at91cap9_initialize(unsigned long main_clock);
18 19
19 /* Interrupts */ 20 /* Interrupts */
20extern void __init at91rm9200_init_interrupts(unsigned int priority[]); 21extern void __init at91rm9200_init_interrupts(unsigned int priority[]);
@@ -23,6 +24,7 @@ extern void __init at91sam9261_init_interrupts(unsigned int priority[]);
23extern void __init at91sam9263_init_interrupts(unsigned int priority[]); 24extern void __init at91sam9263_init_interrupts(unsigned int priority[]);
24extern void __init at91sam9rl_init_interrupts(unsigned int priority[]); 25extern void __init at91sam9rl_init_interrupts(unsigned int priority[]);
25extern void __init at91x40_init_interrupts(unsigned int priority[]); 26extern void __init at91x40_init_interrupts(unsigned int priority[]);
27extern void __init at91cap9_init_interrupts(unsigned int priority[]);
26extern void __init at91_aic_init(unsigned int priority[]); 28extern void __init at91_aic_init(unsigned int priority[]);
27 29
28 /* Timer */ 30 /* Timer */
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c
index aa2d365c93fb..6aeddd68d8af 100644
--- a/arch/arm/mach-at91/gpio.c
+++ b/arch/arm/mach-at91/gpio.c
@@ -13,6 +13,8 @@
13#include <linux/errno.h> 13#include <linux/errno.h>
14#include <linux/interrupt.h> 14#include <linux/interrupt.h>
15#include <linux/irq.h> 15#include <linux/irq.h>
16#include <linux/debugfs.h>
17#include <linux/seq_file.h>
16#include <linux/kernel.h> 18#include <linux/kernel.h>
17#include <linux/list.h> 19#include <linux/list.h>
18#include <linux/module.h> 20#include <linux/module.h>
@@ -414,6 +416,66 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
414 416
415/*--------------------------------------------------------------------------*/ 417/*--------------------------------------------------------------------------*/
416 418
419#ifdef CONFIG_DEBUG_FS
420
421static int at91_gpio_show(struct seq_file *s, void *unused)
422{
423 int bank, j;
424
425 /* print heading */
426 seq_printf(s, "Pin\t");
427 for (bank = 0; bank < gpio_banks; bank++) {
428 seq_printf(s, "PIO%c\t", 'A' + bank);
429 };
430 seq_printf(s, "\n\n");
431
432 /* print pin status */
433 for (j = 0; j < 32; j++) {
434 seq_printf(s, "%i:\t", j);
435
436 for (bank = 0; bank < gpio_banks; bank++) {
437 unsigned pin = PIN_BASE + (32 * bank) + j;
438 void __iomem *pio = pin_to_controller(pin);
439 unsigned mask = pin_to_mask(pin);
440
441 if (__raw_readl(pio + PIO_PSR) & mask)
442 seq_printf(s, "GPIO:%s", __raw_readl(pio + PIO_PDSR) & mask ? "1" : "0");
443 else
444 seq_printf(s, "%s", __raw_readl(pio + PIO_ABSR) & mask ? "B" : "A");
445
446 seq_printf(s, "\t");
447 }
448
449 seq_printf(s, "\n");
450 }
451
452 return 0;
453}
454
455static int at91_gpio_open(struct inode *inode, struct file *file)
456{
457 return single_open(file, at91_gpio_show, NULL);
458}
459
460static const struct file_operations at91_gpio_operations = {
461 .open = at91_gpio_open,
462 .read = seq_read,
463 .llseek = seq_lseek,
464 .release = single_release,
465};
466
467static int __init at91_gpio_debugfs_init(void)
468{
469 /* /sys/kernel/debug/at91_gpio */
470 (void) debugfs_create_file("at91_gpio", S_IFREG | S_IRUGO, NULL, NULL, &at91_gpio_operations);
471 return 0;
472}
473postcore_initcall(at91_gpio_debugfs_init);
474
475#endif
476
477/*--------------------------------------------------------------------------*/
478
417/* 479/*
418 * Called from the processor-specific init to enable GPIO interrupt support. 480 * Called from the processor-specific init to enable GPIO interrupt support.
419 */ 481 */
diff --git a/arch/arm/mach-at91/leds.c b/arch/arm/mach-at91/leds.c
index 0d5144973988..9cdcda500fe8 100644
--- a/arch/arm/mach-at91/leds.c
+++ b/arch/arm/mach-at91/leds.c
@@ -14,11 +14,62 @@
14#include <linux/init.h> 14#include <linux/init.h>
15 15
16#include <asm/mach-types.h> 16#include <asm/mach-types.h>
17#include <asm/leds.h>
18#include <asm/arch/board.h> 17#include <asm/arch/board.h>
19#include <asm/arch/gpio.h> 18#include <asm/arch/gpio.h>
20 19
21 20
21/* ------------------------------------------------------------------------- */
22
23#if defined(CONFIG_NEW_LEDS)
24
25#include <linux/platform_device.h>
26
27/*
28 * New cross-platform LED support.
29 */
30
31static struct gpio_led_platform_data led_data;
32
33static struct platform_device at91_leds = {
34 .name = "leds-gpio",
35 .id = -1,
36 .dev.platform_data = &led_data,
37};
38
39void __init at91_gpio_leds(struct gpio_led *leds, int nr)
40{
41 int i;
42
43 if (!nr)
44 return;
45
46 for (i = 0; i < nr; i++)
47 at91_set_gpio_output(leds[i].gpio, leds[i].active_low);
48
49 led_data.leds = leds;
50 led_data.num_leds = nr;
51 platform_device_register(&at91_leds);
52}
53
54#else
55void __init at91_gpio_leds(struct gpio_led *leds, int nr) {}
56#endif
57
58
59/* ------------------------------------------------------------------------- */
60
61#if defined(CONFIG_LEDS)
62
63#include <asm/leds.h>
64
65/*
66 * Old ARM-specific LED framework; not fully functional when generic time is
67 * in use.
68 */
69
70static u8 at91_leds_cpu;
71static u8 at91_leds_timer;
72
22static inline void at91_led_on(unsigned int led) 73static inline void at91_led_on(unsigned int led)
23{ 74{
24 at91_set_gpio_value(led, 0); 75 at91_set_gpio_value(led, 0);
@@ -93,3 +144,18 @@ static int __init leds_init(void)
93} 144}
94 145
95__initcall(leds_init); 146__initcall(leds_init);
147
148
149void __init at91_init_leds(u8 cpu_led, u8 timer_led)
150{
151 /* Enable GPIO to access the LEDs */
152 at91_set_gpio_output(cpu_led, 1);
153 at91_set_gpio_output(timer_led, 1);
154
155 at91_leds_cpu = cpu_led;
156 at91_leds_timer = timer_led;
157}
158
159#else
160void __init at91_init_leds(u8 cpu_led, u8 timer_led) {}
161#endif
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 98cb61482917..4b120cc36135 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -80,6 +80,11 @@ static int at91_pm_verify_clocks(void)
80 pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n"); 80 pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n");
81 return 0; 81 return 0;
82 } 82 }
83 } else if (cpu_is_at91cap9()) {
84 if ((scsr & AT91CAP9_PMC_UHP) != 0) {
85 pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n");
86 return 0;
87 }
83 } 88 }
84 89
85#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS 90#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS
diff --git a/arch/arm/mach-clps711x/time.c b/arch/arm/mach-clps711x/time.c
index f428af7545b4..e5dc33f1f95c 100644
--- a/arch/arm/mach-clps711x/time.c
+++ b/arch/arm/mach-clps711x/time.c
@@ -50,9 +50,7 @@ static unsigned long clps711x_gettimeoffset(void)
50static irqreturn_t 50static irqreturn_t
51p720t_timer_interrupt(int irq, void *dev_id) 51p720t_timer_interrupt(int irq, void *dev_id)
52{ 52{
53 write_seqlock(&xtime_lock);
54 timer_tick(); 53 timer_tick();
55 write_sequnlock(&xtime_lock);
56 return IRQ_HANDLED; 54 return IRQ_HANDLED;
57} 55}
58 56
diff --git a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c
index 986205ec9269..2ac63671ea5f 100644
--- a/arch/arm/mach-clps7500/core.c
+++ b/arch/arm/mach-clps7500/core.c
@@ -298,8 +298,6 @@ extern unsigned long ioc_timer_gettimeoffset(void);
298static irqreturn_t 298static irqreturn_t
299clps7500_timer_interrupt(int irq, void *dev_id) 299clps7500_timer_interrupt(int irq, void *dev_id)
300{ 300{
301 write_seqlock(&xtime_lock);
302
303 timer_tick(); 301 timer_tick();
304 302
305 /* Why not using do_leds interface?? */ 303 /* Why not using do_leds interface?? */
@@ -313,8 +311,6 @@ clps7500_timer_interrupt(int irq, void *dev_id)
313 } 311 }
314 } 312 }
315 313
316 write_sequnlock(&xtime_lock);
317
318 return IRQ_HANDLED; 314 return IRQ_HANDLED;
319} 315}
320 316
diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c
index 8c1b5690dfe8..7710e14b5268 100644
--- a/arch/arm/mach-ebsa110/core.c
+++ b/arch/arm/mach-ebsa110/core.c
@@ -178,8 +178,6 @@ ebsa110_timer_interrupt(int irq, void *dev_id)
178{ 178{
179 u32 count; 179 u32 count;
180 180
181 write_seqlock(&xtime_lock);
182
183 /* latch and read timer 1 */ 181 /* latch and read timer 1 */
184 __raw_writeb(0x40, PIT_CTRL); 182 __raw_writeb(0x40, PIT_CTRL);
185 count = __raw_readb(PIT_T1); 183 count = __raw_readb(PIT_T1);
@@ -192,8 +190,6 @@ ebsa110_timer_interrupt(int irq, void *dev_id)
192 190
193 timer_tick(); 191 timer_tick();
194 192
195 write_sequnlock(&xtime_lock);
196
197 return IRQ_HANDLED; 193 return IRQ_HANDLED;
198} 194}
199 195
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 70b2c7801110..91f6a07a51d5 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -3,6 +3,7 @@
3 * Core routines for Cirrus EP93xx chips. 3 * Core routines for Cirrus EP93xx chips.
4 * 4 *
5 * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org> 5 * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
6 * Copyright (C) 2007 Herbert Valerio Riedel <hvr@gnu.org>
6 * 7 *
7 * Thanks go to Michael Burian and Ray Lehtiniemi for their key 8 * Thanks go to Michael Burian and Ray Lehtiniemi for their key
8 * role in the ep93xx linux community. 9 * role in the ep93xx linux community.
@@ -21,7 +22,6 @@
21#include <linux/serial.h> 22#include <linux/serial.h>
22#include <linux/tty.h> 23#include <linux/tty.h>
23#include <linux/bitops.h> 24#include <linux/bitops.h>
24#include <linux/serial.h>
25#include <linux/serial_8250.h> 25#include <linux/serial_8250.h>
26#include <linux/serial_core.h> 26#include <linux/serial_core.h>
27#include <linux/device.h> 27#include <linux/device.h>
@@ -99,8 +99,6 @@ static unsigned int last_jiffy_time;
99 99
100static int ep93xx_timer_interrupt(int irq, void *dev_id) 100static int ep93xx_timer_interrupt(int irq, void *dev_id)
101{ 101{
102 write_seqlock(&xtime_lock);
103
104 __raw_writel(1, EP93XX_TIMER1_CLEAR); 102 __raw_writel(1, EP93XX_TIMER1_CLEAR);
105 while ((signed long) 103 while ((signed long)
106 (__raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time) 104 (__raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time)
@@ -109,8 +107,6 @@ static int ep93xx_timer_interrupt(int irq, void *dev_id)
109 timer_tick(); 107 timer_tick();
110 } 108 }
111 109
112 write_sequnlock(&xtime_lock);
113
114 return IRQ_HANDLED; 110 return IRQ_HANDLED;
115} 111}
116 112
@@ -157,38 +153,41 @@ static unsigned char gpio_int_enabled[3];
157static unsigned char gpio_int_type1[3]; 153static unsigned char gpio_int_type1[3];
158static unsigned char gpio_int_type2[3]; 154static unsigned char gpio_int_type2[3];
159 155
160static void update_gpio_int_params(int abf) 156/* Port ordering is: A B F */
157static const u8 int_type1_register_offset[3] = { 0x90, 0xac, 0x4c };
158static const u8 int_type2_register_offset[3] = { 0x94, 0xb0, 0x50 };
159static const u8 eoi_register_offset[3] = { 0x98, 0xb4, 0x54 };
160static const u8 int_en_register_offset[3] = { 0x9c, 0xb8, 0x5c };
161
162static void update_gpio_int_params(unsigned port)
161{ 163{
162 if (abf == 0) { 164 BUG_ON(port > 2);
163 __raw_writeb(0, EP93XX_GPIO_A_INT_ENABLE);
164 __raw_writeb(gpio_int_type2[0], EP93XX_GPIO_A_INT_TYPE2);
165 __raw_writeb(gpio_int_type1[0], EP93XX_GPIO_A_INT_TYPE1);
166 __raw_writeb(gpio_int_unmasked[0] & gpio_int_enabled[0], EP93XX_GPIO_A_INT_ENABLE);
167 } else if (abf == 1) {
168 __raw_writeb(0, EP93XX_GPIO_B_INT_ENABLE);
169 __raw_writeb(gpio_int_type2[1], EP93XX_GPIO_B_INT_TYPE2);
170 __raw_writeb(gpio_int_type1[1], EP93XX_GPIO_B_INT_TYPE1);
171 __raw_writeb(gpio_int_unmasked[1] & gpio_int_enabled[1], EP93XX_GPIO_B_INT_ENABLE);
172 } else if (abf == 2) {
173 __raw_writeb(0, EP93XX_GPIO_F_INT_ENABLE);
174 __raw_writeb(gpio_int_type2[2], EP93XX_GPIO_F_INT_TYPE2);
175 __raw_writeb(gpio_int_type1[2], EP93XX_GPIO_F_INT_TYPE1);
176 __raw_writeb(gpio_int_unmasked[2] & gpio_int_enabled[2], EP93XX_GPIO_F_INT_ENABLE);
177 } else {
178 BUG();
179 }
180}
181 165
166 __raw_writeb(0, EP93XX_GPIO_REG(int_en_register_offset[port]));
182 167
183static unsigned char data_register_offset[8] = { 168 __raw_writeb(gpio_int_type2[port],
184 0x00, 0x04, 0x08, 0x0c, 0x20, 0x30, 0x38, 0x40, 169 EP93XX_GPIO_REG(int_type2_register_offset[port]));
170
171 __raw_writeb(gpio_int_type1[port],
172 EP93XX_GPIO_REG(int_type1_register_offset[port]));
173
174 __raw_writeb(gpio_int_unmasked[port] & gpio_int_enabled[port],
175 EP93XX_GPIO_REG(int_en_register_offset[port]));
176}
177
178/* Port ordering is: A B F D E C G H */
179static const u8 data_register_offset[8] = {
180 0x00, 0x04, 0x30, 0x0c, 0x20, 0x08, 0x38, 0x40,
185}; 181};
186 182
187static unsigned char data_direction_register_offset[8] = { 183static const u8 data_direction_register_offset[8] = {
188 0x10, 0x14, 0x18, 0x1c, 0x24, 0x34, 0x3c, 0x44, 184 0x10, 0x14, 0x34, 0x1c, 0x24, 0x18, 0x3c, 0x44,
189}; 185};
190 186
191void gpio_line_config(int line, int direction) 187#define GPIO_IN 0
188#define GPIO_OUT 1
189
190static void ep93xx_gpio_set_direction(unsigned line, int direction)
192{ 191{
193 unsigned int data_direction_register; 192 unsigned int data_direction_register;
194 unsigned long flags; 193 unsigned long flags;
@@ -199,14 +198,10 @@ void gpio_line_config(int line, int direction)
199 198
200 local_irq_save(flags); 199 local_irq_save(flags);
201 if (direction == GPIO_OUT) { 200 if (direction == GPIO_OUT) {
202 if (line >= 0 && line < 16) { 201 if (line >= 0 && line <= EP93XX_GPIO_LINE_MAX_IRQ) {
203 /* Port A/B. */ 202 /* Port A/B/F */
204 gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7)); 203 gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7));
205 update_gpio_int_params(line >> 3); 204 update_gpio_int_params(line >> 3);
206 } else if (line >= 40 && line < 48) {
207 /* Port F. */
208 gpio_int_unmasked[2] &= ~(1 << (line & 7));
209 update_gpio_int_params(2);
210 } 205 }
211 206
212 v = __raw_readb(data_direction_register); 207 v = __raw_readb(data_direction_register);
@@ -219,39 +214,58 @@ void gpio_line_config(int line, int direction)
219 } 214 }
220 local_irq_restore(flags); 215 local_irq_restore(flags);
221} 216}
222EXPORT_SYMBOL(gpio_line_config);
223 217
224int gpio_line_get(int line) 218int gpio_direction_input(unsigned gpio)
219{
220 if (gpio > EP93XX_GPIO_LINE_MAX)
221 return -EINVAL;
222
223 ep93xx_gpio_set_direction(gpio, GPIO_IN);
224
225 return 0;
226}
227EXPORT_SYMBOL(gpio_direction_input);
228
229int gpio_direction_output(unsigned gpio, int value)
230{
231 if (gpio > EP93XX_GPIO_LINE_MAX)
232 return -EINVAL;
233
234 gpio_set_value(gpio, value);
235 ep93xx_gpio_set_direction(gpio, GPIO_OUT);
236
237 return 0;
238}
239EXPORT_SYMBOL(gpio_direction_output);
240
241int gpio_get_value(unsigned gpio)
225{ 242{
226 unsigned int data_register; 243 unsigned int data_register;
227 244
228 data_register = EP93XX_GPIO_REG(data_register_offset[line >> 3]); 245 data_register = EP93XX_GPIO_REG(data_register_offset[gpio >> 3]);
229 246
230 return !!(__raw_readb(data_register) & (1 << (line & 7))); 247 return !!(__raw_readb(data_register) & (1 << (gpio & 7)));
231} 248}
232EXPORT_SYMBOL(gpio_line_get); 249EXPORT_SYMBOL(gpio_get_value);
233 250
234void gpio_line_set(int line, int value) 251void gpio_set_value(unsigned gpio, int value)
235{ 252{
236 unsigned int data_register; 253 unsigned int data_register;
237 unsigned long flags; 254 unsigned long flags;
238 unsigned char v; 255 unsigned char v;
239 256
240 data_register = EP93XX_GPIO_REG(data_register_offset[line >> 3]); 257 data_register = EP93XX_GPIO_REG(data_register_offset[gpio >> 3]);
241 258
242 local_irq_save(flags); 259 local_irq_save(flags);
243 if (value == EP93XX_GPIO_HIGH) { 260 v = __raw_readb(data_register);
244 v = __raw_readb(data_register); 261 if (value)
245 v |= 1 << (line & 7); 262 v |= 1 << (gpio & 7);
246 __raw_writeb(v, data_register); 263 else
247 } else if (value == EP93XX_GPIO_LOW) { 264 v &= ~(1 << (gpio & 7));
248 v = __raw_readb(data_register); 265 __raw_writeb(v, data_register);
249 v &= ~(1 << (line & 7));
250 __raw_writeb(v, data_register);
251 }
252 local_irq_restore(flags); 266 local_irq_restore(flags);
253} 267}
254EXPORT_SYMBOL(gpio_line_set); 268EXPORT_SYMBOL(gpio_set_value);
255 269
256 270
257/************************************************************************* 271/*************************************************************************
@@ -265,47 +279,67 @@ static void ep93xx_gpio_ab_irq_handler(unsigned int irq, struct irq_desc *desc)
265 status = __raw_readb(EP93XX_GPIO_A_INT_STATUS); 279 status = __raw_readb(EP93XX_GPIO_A_INT_STATUS);
266 for (i = 0; i < 8; i++) { 280 for (i = 0; i < 8; i++) {
267 if (status & (1 << i)) { 281 if (status & (1 << i)) {
268 desc = irq_desc + IRQ_EP93XX_GPIO(0) + i; 282 int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_A(0)) + i;
269 desc_handle_irq(IRQ_EP93XX_GPIO(0) + i, desc); 283 desc = irq_desc + gpio_irq;
284 desc_handle_irq(gpio_irq, desc);
270 } 285 }
271 } 286 }
272 287
273 status = __raw_readb(EP93XX_GPIO_B_INT_STATUS); 288 status = __raw_readb(EP93XX_GPIO_B_INT_STATUS);
274 for (i = 0; i < 8; i++) { 289 for (i = 0; i < 8; i++) {
275 if (status & (1 << i)) { 290 if (status & (1 << i)) {
276 desc = irq_desc + IRQ_EP93XX_GPIO(8) + i; 291 int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_B(0)) + i;
277 desc_handle_irq(IRQ_EP93XX_GPIO(8) + i, desc); 292 desc = irq_desc + gpio_irq;
293 desc_handle_irq(gpio_irq, desc);
278 } 294 }
279 } 295 }
280} 296}
281 297
282static void ep93xx_gpio_f_irq_handler(unsigned int irq, struct irq_desc *desc) 298static void ep93xx_gpio_f_irq_handler(unsigned int irq, struct irq_desc *desc)
283{ 299{
284 int gpio_irq = IRQ_EP93XX_GPIO(16) + (((irq + 1) & 7) ^ 4); 300 /*
301 * map discontiguous hw irq range to continous sw irq range:
302 *
303 * IRQ_EP93XX_GPIO{0..7}MUX -> gpio_to_irq(EP93XX_GPIO_LINE_F({0..7})
304 */
305 int port_f_idx = ((irq + 1) & 7) ^ 4; /* {19..22,47..50} -> {0..7} */
306 int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_F(0)) + port_f_idx;
285 307
286 desc_handle_irq(gpio_irq, irq_desc + gpio_irq); 308 desc_handle_irq(gpio_irq, irq_desc + gpio_irq);
287} 309}
288 310
311static void ep93xx_gpio_irq_ack(unsigned int irq)
312{
313 int line = irq_to_gpio(irq);
314 int port = line >> 3;
315 int port_mask = 1 << (line & 7);
316
317 if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQT_BOTHEDGE) {
318 gpio_int_type2[port] ^= port_mask; /* switch edge direction */
319 update_gpio_int_params(port);
320 }
321
322 __raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
323}
324
289static void ep93xx_gpio_irq_mask_ack(unsigned int irq) 325static void ep93xx_gpio_irq_mask_ack(unsigned int irq)
290{ 326{
291 int line = irq - IRQ_EP93XX_GPIO(0); 327 int line = irq_to_gpio(irq);
292 int port = line >> 3; 328 int port = line >> 3;
329 int port_mask = 1 << (line & 7);
293 330
294 gpio_int_unmasked[port] &= ~(1 << (line & 7)); 331 if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQT_BOTHEDGE)
332 gpio_int_type2[port] ^= port_mask; /* switch edge direction */
333
334 gpio_int_unmasked[port] &= ~port_mask;
295 update_gpio_int_params(port); 335 update_gpio_int_params(port);
296 336
297 if (port == 0) { 337 __raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
298 __raw_writel(1 << (line & 7), EP93XX_GPIO_A_INT_ACK);
299 } else if (port == 1) {
300 __raw_writel(1 << (line & 7), EP93XX_GPIO_B_INT_ACK);
301 } else if (port == 2) {
302 __raw_writel(1 << (line & 7), EP93XX_GPIO_F_INT_ACK);
303 }
304} 338}
305 339
306static void ep93xx_gpio_irq_mask(unsigned int irq) 340static void ep93xx_gpio_irq_mask(unsigned int irq)
307{ 341{
308 int line = irq - IRQ_EP93XX_GPIO(0); 342 int line = irq_to_gpio(irq);
309 int port = line >> 3; 343 int port = line >> 3;
310 344
311 gpio_int_unmasked[port] &= ~(1 << (line & 7)); 345 gpio_int_unmasked[port] &= ~(1 << (line & 7));
@@ -314,7 +348,7 @@ static void ep93xx_gpio_irq_mask(unsigned int irq)
314 348
315static void ep93xx_gpio_irq_unmask(unsigned int irq) 349static void ep93xx_gpio_irq_unmask(unsigned int irq)
316{ 350{
317 int line = irq - IRQ_EP93XX_GPIO(0); 351 int line = irq_to_gpio(irq);
318 int port = line >> 3; 352 int port = line >> 3;
319 353
320 gpio_int_unmasked[port] |= 1 << (line & 7); 354 gpio_int_unmasked[port] |= 1 << (line & 7);
@@ -329,38 +363,54 @@ static void ep93xx_gpio_irq_unmask(unsigned int irq)
329 */ 363 */
330static int ep93xx_gpio_irq_type(unsigned int irq, unsigned int type) 364static int ep93xx_gpio_irq_type(unsigned int irq, unsigned int type)
331{ 365{
332 int port; 366 struct irq_desc *desc = irq_desc + irq;
333 int line; 367 const int gpio = irq_to_gpio(irq);
334 368 const int port = gpio >> 3;
335 line = irq - IRQ_EP93XX_GPIO(0); 369 const int port_mask = 1 << (gpio & 7);
336 if (line >= 0 && line < 16) { 370
337 gpio_line_config(line, GPIO_IN); 371 ep93xx_gpio_set_direction(gpio, GPIO_IN);
338 } else { 372
339 gpio_line_config(EP93XX_GPIO_LINE_F(line-16), GPIO_IN); 373 switch (type) {
374 case IRQT_RISING:
375 gpio_int_type1[port] |= port_mask;
376 gpio_int_type2[port] |= port_mask;
377 desc->handle_irq = handle_edge_irq;
378 break;
379 case IRQT_FALLING:
380 gpio_int_type1[port] |= port_mask;
381 gpio_int_type2[port] &= ~port_mask;
382 desc->handle_irq = handle_edge_irq;
383 break;
384 case IRQT_HIGH:
385 gpio_int_type1[port] &= ~port_mask;
386 gpio_int_type2[port] |= port_mask;
387 desc->handle_irq = handle_level_irq;
388 break;
389 case IRQT_LOW:
390 gpio_int_type1[port] &= ~port_mask;
391 gpio_int_type2[port] &= ~port_mask;
392 desc->handle_irq = handle_level_irq;
393 break;
394 case IRQT_BOTHEDGE:
395 gpio_int_type1[port] |= port_mask;
396 /* set initial polarity based on current input level */
397 if (gpio_get_value(gpio))
398 gpio_int_type2[port] &= ~port_mask; /* falling */
399 else
400 gpio_int_type2[port] |= port_mask; /* rising */
401 desc->handle_irq = handle_edge_irq;
402 break;
403 default:
404 pr_err("ep93xx: failed to set irq type %d for gpio %d\n",
405 type, gpio);
406 return -EINVAL;
340 } 407 }
341 408
342 port = line >> 3; 409 gpio_int_enabled[port] |= port_mask;
343 line &= 7; 410
344 411 desc->status &= ~IRQ_TYPE_SENSE_MASK;
345 if (type & IRQT_RISING) { 412 desc->status |= type & IRQ_TYPE_SENSE_MASK;
346 gpio_int_enabled[port] |= 1 << line; 413
347 gpio_int_type1[port] |= 1 << line;
348 gpio_int_type2[port] |= 1 << line;
349 } else if (type & IRQT_FALLING) {
350 gpio_int_enabled[port] |= 1 << line;
351 gpio_int_type1[port] |= 1 << line;
352 gpio_int_type2[port] &= ~(1 << line);
353 } else if (type & IRQT_HIGH) {
354 gpio_int_enabled[port] |= 1 << line;
355 gpio_int_type1[port] &= ~(1 << line);
356 gpio_int_type2[port] |= 1 << line;
357 } else if (type & IRQT_LOW) {
358 gpio_int_enabled[port] |= 1 << line;
359 gpio_int_type1[port] &= ~(1 << line);
360 gpio_int_type2[port] &= ~(1 << line);
361 } else {
362 gpio_int_enabled[port] &= ~(1 << line);
363 }
364 update_gpio_int_params(port); 414 update_gpio_int_params(port);
365 415
366 return 0; 416 return 0;
@@ -368,7 +418,8 @@ static int ep93xx_gpio_irq_type(unsigned int irq, unsigned int type)
368 418
369static struct irq_chip ep93xx_gpio_irq_chip = { 419static struct irq_chip ep93xx_gpio_irq_chip = {
370 .name = "GPIO", 420 .name = "GPIO",
371 .ack = ep93xx_gpio_irq_mask_ack, 421 .ack = ep93xx_gpio_irq_ack,
422 .mask_ack = ep93xx_gpio_irq_mask_ack,
372 .mask = ep93xx_gpio_irq_mask, 423 .mask = ep93xx_gpio_irq_mask,
373 .unmask = ep93xx_gpio_irq_unmask, 424 .unmask = ep93xx_gpio_irq_unmask,
374 .set_type = ep93xx_gpio_irq_type, 425 .set_type = ep93xx_gpio_irq_type,
@@ -377,15 +428,16 @@ static struct irq_chip ep93xx_gpio_irq_chip = {
377 428
378void __init ep93xx_init_irq(void) 429void __init ep93xx_init_irq(void)
379{ 430{
380 int irq; 431 int gpio_irq;
381 432
382 vic_init((void *)EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK); 433 vic_init((void *)EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK);
383 vic_init((void *)EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK); 434 vic_init((void *)EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK);
384 435
385 for (irq = IRQ_EP93XX_GPIO(0); irq <= IRQ_EP93XX_GPIO(23); irq++) { 436 for (gpio_irq = gpio_to_irq(0);
386 set_irq_chip(irq, &ep93xx_gpio_irq_chip); 437 gpio_irq <= gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ); ++gpio_irq) {
387 set_irq_handler(irq, handle_level_irq); 438 set_irq_chip(gpio_irq, &ep93xx_gpio_irq_chip);
388 set_irq_flags(irq, IRQF_VALID); 439 set_irq_handler(gpio_irq, handle_level_irq);
440 set_irq_flags(gpio_irq, IRQF_VALID);
389 } 441 }
390 442
391 set_irq_chained_handler(IRQ_EP93XX_GPIO_AB, ep93xx_gpio_ab_irq_handler); 443 set_irq_chained_handler(IRQ_EP93XX_GPIO_AB, ep93xx_gpio_ab_irq_handler);
diff --git a/arch/arm/mach-footbridge/dc21285-timer.c b/arch/arm/mach-footbridge/dc21285-timer.c
index 3a63941d43be..b2a21189dd81 100644
--- a/arch/arm/mach-footbridge/dc21285-timer.c
+++ b/arch/arm/mach-footbridge/dc21285-timer.c
@@ -30,14 +30,10 @@ static unsigned long timer1_gettimeoffset (void)
30static irqreturn_t 30static irqreturn_t
31timer1_interrupt(int irq, void *dev_id) 31timer1_interrupt(int irq, void *dev_id)
32{ 32{
33 write_seqlock(&xtime_lock);
34
35 *CSR_TIMER1_CLR = 0; 33 *CSR_TIMER1_CLR = 0;
36 34
37 timer_tick(); 35 timer_tick();
38 36
39 write_sequnlock(&xtime_lock);
40
41 return IRQ_HANDLED; 37 return IRQ_HANDLED;
42} 38}
43 39
diff --git a/arch/arm/mach-footbridge/isa-timer.c b/arch/arm/mach-footbridge/isa-timer.c
index d08d64139d00..a764e01d3573 100644
--- a/arch/arm/mach-footbridge/isa-timer.c
+++ b/arch/arm/mach-footbridge/isa-timer.c
@@ -64,9 +64,7 @@ static unsigned long isa_gettimeoffset(void)
64static irqreturn_t 64static irqreturn_t
65isa_timer_interrupt(int irq, void *dev_id) 65isa_timer_interrupt(int irq, void *dev_id)
66{ 66{
67 write_seqlock(&xtime_lock);
68 timer_tick(); 67 timer_tick();
69 write_sequnlock(&xtime_lock);
70 return IRQ_HANDLED; 68 return IRQ_HANDLED;
71} 69}
72 70
diff --git a/arch/arm/mach-h720x/cpu-h7201.c b/arch/arm/mach-h720x/cpu-h7201.c
index 9107b8e2ad6e..c2a431f482f0 100644
--- a/arch/arm/mach-h720x/cpu-h7201.c
+++ b/arch/arm/mach-h720x/cpu-h7201.c
@@ -29,13 +29,9 @@
29static irqreturn_t 29static irqreturn_t
30h7201_timer_interrupt(int irq, void *dev_id) 30h7201_timer_interrupt(int irq, void *dev_id)
31{ 31{
32 write_seqlock(&xtime_lock);
33
34 CPU_REG (TIMER_VIRT, TIMER_TOPSTAT); 32 CPU_REG (TIMER_VIRT, TIMER_TOPSTAT);
35 timer_tick(); 33 timer_tick();
36 34
37 write_sequnlock(&xtime_lock);
38
39 return IRQ_HANDLED; 35 return IRQ_HANDLED;
40} 36}
41 37
diff --git a/arch/arm/mach-h720x/cpu-h7202.c b/arch/arm/mach-h720x/cpu-h7202.c
index 0a1a25fb8ba8..c627fa124eb3 100644
--- a/arch/arm/mach-h720x/cpu-h7202.c
+++ b/arch/arm/mach-h720x/cpu-h7202.c
@@ -113,9 +113,7 @@ h7202_timerx_demux_handler(unsigned int irq_unused, struct irq_desc *desc)
113 mask = CPU_REG (TIMER_VIRT, TIMER_TOPSTAT); 113 mask = CPU_REG (TIMER_VIRT, TIMER_TOPSTAT);
114 114
115 if ( mask & TSTAT_T0INT ) { 115 if ( mask & TSTAT_T0INT ) {
116 write_seqlock(&xtime_lock);
117 timer_tick(); 116 timer_tick();
118 write_sequnlock(&xtime_lock);
119 if( mask == TSTAT_T0INT ) 117 if( mask == TSTAT_T0INT )
120 return; 118 return;
121 } 119 }
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 02272aa36e90..88d5e61a2e13 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -1,9 +1,6 @@
1# 1#
2# Makefile for the linux kernel. 2# Makefile for the linux kernel.
3# 3#
4# Note! Dependencies are done automagically by 'make dep', which also
5# removes any old dependencies. DON'T put your own dependencies here
6# unless it's something special (ie not a .c file).
7 4
8# Object file lists. 5# Object file lists.
9 6
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index e9c82deb791d..7fbbc17f8e8b 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -250,8 +250,6 @@ unsigned long integrator_gettimeoffset(void)
250static irqreturn_t 250static irqreturn_t
251integrator_timer_interrupt(int irq, void *dev_id) 251integrator_timer_interrupt(int irq, void *dev_id)
252{ 252{
253 write_seqlock(&xtime_lock);
254
255 /* 253 /*
256 * clear the interrupt 254 * clear the interrupt
257 */ 255 */
@@ -259,8 +257,6 @@ integrator_timer_interrupt(int irq, void *dev_id)
259 257
260 timer_tick(); 258 timer_tick();
261 259
262 write_sequnlock(&xtime_lock);
263
264 return IRQ_HANDLED; 260 return IRQ_HANDLED;
265} 261}
266 262
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 72280754354d..df37e93c6fc9 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -214,7 +214,7 @@ static int irq_resume(struct sys_device *dev)
214#endif 214#endif
215 215
216static struct sysdev_class irq_class = { 216static struct sysdev_class irq_class = {
217 set_kset_name("irq"), 217 .name = "irq",
218 .suspend = irq_suspend, 218 .suspend = irq_suspend,
219 .resume = irq_resume, 219 .resume = irq_resume,
220}; 220};
diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
index d4d8134ce567..d55fa4e9bb43 100644
--- a/arch/arm/mach-integrator/pci_v3.c
+++ b/arch/arm/mach-integrator/pci_v3.c
@@ -440,7 +440,7 @@ v3_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
440 return 1; 440 return 1;
441} 441}
442 442
443static irqreturn_t v3_irq(int irq, void *devid) 443static irqreturn_t v3_irq(int dummy, void *devid)
444{ 444{
445#ifdef CONFIG_DEBUG_LL 445#ifdef CONFIG_DEBUG_LL
446 struct pt_regs *regs = get_irq_regs(); 446 struct pt_regs *regs = get_irq_regs();
@@ -448,8 +448,10 @@ static irqreturn_t v3_irq(int irq, void *devid)
448 unsigned long instr = *(unsigned long *)pc; 448 unsigned long instr = *(unsigned long *)pc;
449 char buf[128]; 449 char buf[128];
450 450
451 sprintf(buf, "V3 int %d: pc=0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x ISTAT=%02x\n", irq, 451 sprintf(buf, "V3 int %d: pc=0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x "
452 pc, instr, __raw_readl(SC_LBFADDR), __raw_readl(SC_LBFCODE) & 255, 452 "ISTAT=%02x\n", IRQ_AP_V3INT, pc, instr,
453 __raw_readl(SC_LBFADDR),
454 __raw_readl(SC_LBFCODE) & 255,
453 v3_readb(V3_LB_ISTAT)); 455 v3_readb(V3_LB_ISTAT));
454 printascii(buf); 456 printascii(buf);
455#endif 457#endif
diff --git a/arch/arm/mach-iop32x/glantank.c b/arch/arm/mach-iop32x/glantank.c
index 2b086ab2668c..74c65ce221de 100644
--- a/arch/arm/mach-iop32x/glantank.c
+++ b/arch/arm/mach-iop32x/glantank.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Board support code for the GLAN Tank. 4 * Board support code for the GLAN Tank.
5 * 5 *
6 * Copyright (C) 2006 Martin Michlmayr <tbm@cyrius.com> 6 * Copyright (C) 2006, 2007 Martin Michlmayr <tbm@cyrius.com>
7 * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org> 7 * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify it 9 * This program is free software; you can redistribute it and/or modify it
@@ -21,6 +21,7 @@
21#include <linux/serial_core.h> 21#include <linux/serial_core.h>
22#include <linux/serial_8250.h> 22#include <linux/serial_8250.h>
23#include <linux/mtd/physmap.h> 23#include <linux/mtd/physmap.h>
24#include <linux/i2c.h>
24#include <linux/platform_device.h> 25#include <linux/platform_device.h>
25#include <asm/hardware.h> 26#include <asm/hardware.h>
26#include <asm/io.h> 27#include <asm/io.h>
@@ -118,7 +119,7 @@ subsys_initcall(glantank_pci_init);
118 * GLAN Tank machine initialization. 119 * GLAN Tank machine initialization.
119 */ 120 */
120static struct physmap_flash_data glantank_flash_data = { 121static struct physmap_flash_data glantank_flash_data = {
121 .width = 1, 122 .width = 2,
122}; 123};
123 124
124static struct resource glantank_flash_resource = { 125static struct resource glantank_flash_resource = {
@@ -166,6 +167,13 @@ static struct platform_device glantank_serial_device = {
166 .resource = &glantank_uart_resource, 167 .resource = &glantank_uart_resource,
167}; 168};
168 169
170static struct i2c_board_info __initdata glantank_i2c_devices[] = {
171 {
172 I2C_BOARD_INFO("rtc-rs5c372", 0x32),
173 .type = "rs5c372a",
174 },
175};
176
169static void glantank_power_off(void) 177static void glantank_power_off(void)
170{ 178{
171 __raw_writeb(0x01, 0xfe8d0004); 179 __raw_writeb(0x01, 0xfe8d0004);
@@ -183,6 +191,9 @@ static void __init glantank_init_machine(void)
183 platform_device_register(&iop3xx_dma_0_channel); 191 platform_device_register(&iop3xx_dma_0_channel);
184 platform_device_register(&iop3xx_dma_1_channel); 192 platform_device_register(&iop3xx_dma_1_channel);
185 193
194 i2c_register_board_info(0, glantank_i2c_devices,
195 ARRAY_SIZE(glantank_i2c_devices));
196
186 pm_power_off = glantank_power_off; 197 pm_power_off = glantank_power_off;
187} 198}
188 199
diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c
index cb6ad211887a..81cdc8267206 100644
--- a/arch/arm/mach-ixp2000/core.c
+++ b/arch/arm/mach-ixp2000/core.c
@@ -206,8 +206,6 @@ unsigned long ixp2000_gettimeoffset (void)
206 206
207static int ixp2000_timer_interrupt(int irq, void *dev_id) 207static int ixp2000_timer_interrupt(int irq, void *dev_id)
208{ 208{
209 write_seqlock(&xtime_lock);
210
211 /* clear timer 1 */ 209 /* clear timer 1 */
212 ixp2000_reg_wrb(IXP2000_T1_CLR, 1); 210 ixp2000_reg_wrb(IXP2000_T1_CLR, 1);
213 211
@@ -217,8 +215,6 @@ static int ixp2000_timer_interrupt(int irq, void *dev_id)
217 next_jiffy_time -= ticks_per_jiffy; 215 next_jiffy_time -= ticks_per_jiffy;
218 } 216 }
219 217
220 write_sequnlock(&xtime_lock);
221
222 return IRQ_HANDLED; 218 return IRQ_HANDLED;
223} 219}
224 220
diff --git a/arch/arm/mach-ixp23xx/core.c b/arch/arm/mach-ixp23xx/core.c
index 16356ffc86ae..5fea5a132939 100644
--- a/arch/arm/mach-ixp23xx/core.c
+++ b/arch/arm/mach-ixp23xx/core.c
@@ -22,7 +22,6 @@
22#include <linux/serial.h> 22#include <linux/serial.h>
23#include <linux/tty.h> 23#include <linux/tty.h>
24#include <linux/bitops.h> 24#include <linux/bitops.h>
25#include <linux/serial.h>
26#include <linux/serial_8250.h> 25#include <linux/serial_8250.h>
27#include <linux/serial_core.h> 26#include <linux/serial_core.h>
28#include <linux/device.h> 27#include <linux/device.h>
diff --git a/arch/arm/mach-ixp23xx/espresso.c b/arch/arm/mach-ixp23xx/espresso.c
index 7a85ced56718..d3a779a7a35f 100644
--- a/arch/arm/mach-ixp23xx/espresso.c
+++ b/arch/arm/mach-ixp23xx/espresso.c
@@ -19,7 +19,6 @@
19#include <linux/tty.h> 19#include <linux/tty.h>
20#include <linux/bitops.h> 20#include <linux/bitops.h>
21#include <linux/ioport.h> 21#include <linux/ioport.h>
22#include <linux/serial.h>
23#include <linux/serial_8250.h> 22#include <linux/serial_8250.h>
24#include <linux/serial_core.h> 23#include <linux/serial_core.h>
25#include <linux/device.h> 24#include <linux/device.h>
@@ -40,7 +39,6 @@
40#include <asm/mach/map.h> 39#include <asm/mach/map.h>
41#include <asm/mach/irq.h> 40#include <asm/mach/irq.h>
42#include <asm/mach/arch.h> 41#include <asm/mach/arch.h>
43#include <asm/mach/irq.h>
44#include <asm/mach/pci.h> 42#include <asm/mach/pci.h>
45 43
46static int __init espresso_pci_init(void) 44static int __init espresso_pci_init(void)
diff --git a/arch/arm/mach-ixp23xx/ixdp2351.c b/arch/arm/mach-ixp23xx/ixdp2351.c
index c41a6b5a0acc..5c5d4d66dee8 100644
--- a/arch/arm/mach-ixp23xx/ixdp2351.c
+++ b/arch/arm/mach-ixp23xx/ixdp2351.c
@@ -24,7 +24,6 @@
24#include <linux/tty.h> 24#include <linux/tty.h>
25#include <linux/bitops.h> 25#include <linux/bitops.h>
26#include <linux/ioport.h> 26#include <linux/ioport.h>
27#include <linux/serial.h>
28#include <linux/serial_8250.h> 27#include <linux/serial_8250.h>
29#include <linux/serial_core.h> 28#include <linux/serial_core.h>
30#include <linux/device.h> 29#include <linux/device.h>
@@ -44,7 +43,6 @@
44#include <asm/mach/map.h> 43#include <asm/mach/map.h>
45#include <asm/mach/irq.h> 44#include <asm/mach/irq.h>
46#include <asm/mach/arch.h> 45#include <asm/mach/arch.h>
47#include <asm/mach/irq.h>
48#include <asm/mach/pci.h> 46#include <asm/mach/pci.h>
49 47
50/* 48/*
diff --git a/arch/arm/mach-ixp23xx/roadrunner.c b/arch/arm/mach-ixp23xx/roadrunner.c
index e35644961aa4..f0f70ba1e46d 100644
--- a/arch/arm/mach-ixp23xx/roadrunner.c
+++ b/arch/arm/mach-ixp23xx/roadrunner.c
@@ -23,7 +23,6 @@
23#include <linux/tty.h> 23#include <linux/tty.h>
24#include <linux/bitops.h> 24#include <linux/bitops.h>
25#include <linux/ioport.h> 25#include <linux/ioport.h>
26#include <linux/serial.h>
27#include <linux/serial_8250.h> 26#include <linux/serial_8250.h>
28#include <linux/serial_core.h> 27#include <linux/serial_core.h>
29#include <linux/device.h> 28#include <linux/device.h>
@@ -44,7 +43,6 @@
44#include <asm/mach/map.h> 43#include <asm/mach/map.h>
45#include <asm/mach/irq.h> 44#include <asm/mach/irq.h>
46#include <asm/mach/arch.h> 45#include <asm/mach/arch.h>
47#include <asm/mach/irq.h>
48#include <asm/mach/pci.h> 46#include <asm/mach/pci.h>
49 47
50/* 48/*
diff --git a/arch/arm/mach-ixp4xx/avila-setup.c b/arch/arm/mach-ixp4xx/avila-setup.c
index d59b8dc7dc7a..e38f45fa58ae 100644
--- a/arch/arm/mach-ixp4xx/avila-setup.c
+++ b/arch/arm/mach-ixp4xx/avila-setup.c
@@ -18,6 +18,7 @@
18#include <linux/tty.h> 18#include <linux/tty.h>
19#include <linux/serial_8250.h> 19#include <linux/serial_8250.h>
20#include <linux/slab.h> 20#include <linux/slab.h>
21#include <linux/i2c-gpio.h>
21 22
22#include <asm/types.h> 23#include <asm/types.h>
23#include <asm/setup.h> 24#include <asm/setup.h>
@@ -47,18 +48,17 @@ static struct platform_device avila_flash = {
47 .resource = &avila_flash_resource, 48 .resource = &avila_flash_resource,
48}; 49};
49 50
50static struct ixp4xx_i2c_pins avila_i2c_gpio_pins = { 51static struct i2c_gpio_platform_data avila_i2c_gpio_data = {
51 .sda_pin = AVILA_SDA_PIN, 52 .sda_pin = AVILA_SDA_PIN,
52 .scl_pin = AVILA_SCL_PIN, 53 .scl_pin = AVILA_SCL_PIN,
53}; 54};
54 55
55static struct platform_device avila_i2c_controller = { 56static struct platform_device avila_i2c_gpio = {
56 .name = "IXP4XX-I2C", 57 .name = "i2c-gpio",
57 .id = 0, 58 .id = 0,
58 .dev = { 59 .dev = {
59 .platform_data = &avila_i2c_gpio_pins, 60 .platform_data = &avila_i2c_gpio_data,
60 }, 61 },
61 .num_resources = 0
62}; 62};
63 63
64static struct resource avila_uart_resources[] = { 64static struct resource avila_uart_resources[] = {
@@ -133,7 +133,7 @@ static struct platform_device avila_pata = {
133}; 133};
134 134
135static struct platform_device *avila_devices[] __initdata = { 135static struct platform_device *avila_devices[] __initdata = {
136 &avila_i2c_controller, 136 &avila_i2c_gpio,
137 &avila_flash, 137 &avila_flash,
138 &avila_uart 138 &avila_uart
139}; 139};
diff --git a/arch/arm/mach-ixp4xx/dsmg600-setup.c b/arch/arm/mach-ixp4xx/dsmg600-setup.c
index 1e75e105c4f7..c473d408aa7c 100644
--- a/arch/arm/mach-ixp4xx/dsmg600-setup.c
+++ b/arch/arm/mach-ixp4xx/dsmg600-setup.c
@@ -14,6 +14,7 @@
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/serial.h> 15#include <linux/serial.h>
16#include <linux/serial_8250.h> 16#include <linux/serial_8250.h>
17#include <linux/i2c-gpio.h>
17 18
18#include <asm/mach-types.h> 19#include <asm/mach-types.h>
19#include <asm/mach/arch.h> 20#include <asm/mach/arch.h>
@@ -37,15 +38,17 @@ static struct platform_device dsmg600_flash = {
37 .resource = &dsmg600_flash_resource, 38 .resource = &dsmg600_flash_resource,
38}; 39};
39 40
40static struct ixp4xx_i2c_pins dsmg600_i2c_gpio_pins = { 41static struct i2c_gpio_platform_data dsmg600_i2c_gpio_data = {
41 .sda_pin = DSMG600_SDA_PIN, 42 .sda_pin = DSMG600_SDA_PIN,
42 .scl_pin = DSMG600_SCL_PIN, 43 .scl_pin = DSMG600_SCL_PIN,
43}; 44};
44 45
45static struct platform_device dsmg600_i2c_controller = { 46static struct platform_device dsmg600_i2c_gpio = {
46 .name = "IXP4XX-I2C", 47 .name = "i2c-gpio",
47 .id = 0, 48 .id = 0,
48 .dev.platform_data = &dsmg600_i2c_gpio_pins, 49 .dev = {
50 .platform_data = &dsmg600_i2c_gpio_data,
51 },
49}; 52};
50 53
51#ifdef CONFIG_LEDS_CLASS 54#ifdef CONFIG_LEDS_CLASS
@@ -116,7 +119,7 @@ static struct platform_device dsmg600_uart = {
116}; 119};
117 120
118static struct platform_device *dsmg600_devices[] __initdata = { 121static struct platform_device *dsmg600_devices[] __initdata = {
119 &dsmg600_i2c_controller, 122 &dsmg600_i2c_gpio,
120 &dsmg600_flash, 123 &dsmg600_flash,
121}; 124};
122 125
diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c
index d5008d8fc9a5..e89070da28bf 100644
--- a/arch/arm/mach-ixp4xx/ixdp425-setup.c
+++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c
@@ -15,6 +15,7 @@
15#include <linux/tty.h> 15#include <linux/tty.h>
16#include <linux/serial_8250.h> 16#include <linux/serial_8250.h>
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/i2c-gpio.h>
18#include <linux/io.h> 19#include <linux/io.h>
19#include <linux/mtd/mtd.h> 20#include <linux/mtd/mtd.h>
20#include <linux/mtd/nand.h> 21#include <linux/mtd/nand.h>
@@ -120,18 +121,17 @@ static struct platform_device ixdp425_flash_nand = {
120}; 121};
121#endif /* CONFIG_MTD_NAND_PLATFORM */ 122#endif /* CONFIG_MTD_NAND_PLATFORM */
122 123
123static struct ixp4xx_i2c_pins ixdp425_i2c_gpio_pins = { 124static struct i2c_gpio_platform_data ixdp425_i2c_gpio_data = {
124 .sda_pin = IXDP425_SDA_PIN, 125 .sda_pin = IXDP425_SDA_PIN,
125 .scl_pin = IXDP425_SCL_PIN, 126 .scl_pin = IXDP425_SCL_PIN,
126}; 127};
127 128
128static struct platform_device ixdp425_i2c_controller = { 129static struct platform_device ixdp425_i2c_gpio = {
129 .name = "IXP4XX-I2C", 130 .name = "i2c-gpio",
130 .id = 0, 131 .id = 0,
131 .dev = { 132 .dev = {
132 .platform_data = &ixdp425_i2c_gpio_pins, 133 .platform_data = &ixdp425_i2c_gpio_data,
133 }, 134 },
134 .num_resources = 0
135}; 135};
136 136
137static struct resource ixdp425_uart_resources[] = { 137static struct resource ixdp425_uart_resources[] = {
@@ -178,7 +178,7 @@ static struct platform_device ixdp425_uart = {
178}; 178};
179 179
180static struct platform_device *ixdp425_devices[] __initdata = { 180static struct platform_device *ixdp425_devices[] __initdata = {
181 &ixdp425_i2c_controller, 181 &ixdp425_i2c_gpio,
182 &ixdp425_flash, 182 &ixdp425_flash,
183#if defined(CONFIG_MTD_NAND_PLATFORM) || \ 183#if defined(CONFIG_MTD_NAND_PLATFORM) || \
184 defined(CONFIG_MTD_NAND_PLATFORM_MODULE) 184 defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
diff --git a/arch/arm/mach-ixp4xx/nas100d-setup.c b/arch/arm/mach-ixp4xx/nas100d-setup.c
index 78a17413ceca..54d884fb2517 100644
--- a/arch/arm/mach-ixp4xx/nas100d-setup.c
+++ b/arch/arm/mach-ixp4xx/nas100d-setup.c
@@ -16,6 +16,7 @@
16#include <linux/serial.h> 16#include <linux/serial.h>
17#include <linux/serial_8250.h> 17#include <linux/serial_8250.h>
18#include <linux/leds.h> 18#include <linux/leds.h>
19#include <linux/i2c-gpio.h>
19 20
20#include <asm/mach-types.h> 21#include <asm/mach-types.h>
21#include <asm/mach/arch.h> 22#include <asm/mach/arch.h>
@@ -68,16 +69,17 @@ static struct platform_device nas100d_leds = {
68}; 69};
69#endif 70#endif
70 71
71static struct ixp4xx_i2c_pins nas100d_i2c_gpio_pins = { 72static struct i2c_gpio_platform_data nas100d_i2c_gpio_data = {
72 .sda_pin = NAS100D_SDA_PIN, 73 .sda_pin = NAS100D_SDA_PIN,
73 .scl_pin = NAS100D_SCL_PIN, 74 .scl_pin = NAS100D_SCL_PIN,
74}; 75};
75 76
76static struct platform_device nas100d_i2c_controller = { 77static struct platform_device nas100d_i2c_gpio = {
77 .name = "IXP4XX-I2C", 78 .name = "i2c-gpio",
78 .id = 0, 79 .id = 0,
79 .dev.platform_data = &nas100d_i2c_gpio_pins, 80 .dev = {
80 .num_resources = 0, 81 .platform_data = &nas100d_i2c_gpio_data,
82 },
81}; 83};
82 84
83static struct resource nas100d_uart_resources[] = { 85static struct resource nas100d_uart_resources[] = {
@@ -124,7 +126,7 @@ static struct platform_device nas100d_uart = {
124}; 126};
125 127
126static struct platform_device *nas100d_devices[] __initdata = { 128static struct platform_device *nas100d_devices[] __initdata = {
127 &nas100d_i2c_controller, 129 &nas100d_i2c_gpio,
128 &nas100d_flash, 130 &nas100d_flash,
129#ifdef CONFIG_LEDS_IXP4XX 131#ifdef CONFIG_LEDS_IXP4XX
130 &nas100d_leds, 132 &nas100d_leds,
diff --git a/arch/arm/mach-ixp4xx/nslu2-power.c b/arch/arm/mach-ixp4xx/nslu2-power.c
index acd71e9c38a7..6f10dc208320 100644
--- a/arch/arm/mach-ixp4xx/nslu2-power.c
+++ b/arch/arm/mach-ixp4xx/nslu2-power.c
@@ -21,7 +21,6 @@
21#include <linux/reboot.h> 21#include <linux/reboot.h>
22#include <linux/irq.h> 22#include <linux/irq.h>
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/reboot.h>
25 24
26#include <asm/mach-types.h> 25#include <asm/mach-types.h>
27 26
diff --git a/arch/arm/mach-ixp4xx/nslu2-setup.c b/arch/arm/mach-ixp4xx/nslu2-setup.c
index 9bf8ccbcaccf..77277d27fcc5 100644
--- a/arch/arm/mach-ixp4xx/nslu2-setup.c
+++ b/arch/arm/mach-ixp4xx/nslu2-setup.c
@@ -18,6 +18,7 @@
18#include <linux/serial.h> 18#include <linux/serial.h>
19#include <linux/serial_8250.h> 19#include <linux/serial_8250.h>
20#include <linux/leds.h> 20#include <linux/leds.h>
21#include <linux/i2c-gpio.h>
21 22
22#include <asm/mach-types.h> 23#include <asm/mach-types.h>
23#include <asm/mach/arch.h> 24#include <asm/mach/arch.h>
@@ -41,7 +42,7 @@ static struct platform_device nslu2_flash = {
41 .resource = &nslu2_flash_resource, 42 .resource = &nslu2_flash_resource,
42}; 43};
43 44
44static struct ixp4xx_i2c_pins nslu2_i2c_gpio_pins = { 45static struct i2c_gpio_platform_data nslu2_i2c_gpio_data = {
45 .sda_pin = NSLU2_SDA_PIN, 46 .sda_pin = NSLU2_SDA_PIN,
46 .scl_pin = NSLU2_SCL_PIN, 47 .scl_pin = NSLU2_SCL_PIN,
47}; 48};
@@ -82,11 +83,12 @@ static struct platform_device nslu2_leds = {
82}; 83};
83#endif 84#endif
84 85
85static struct platform_device nslu2_i2c_controller = { 86static struct platform_device nslu2_i2c_gpio = {
86 .name = "IXP4XX-I2C", 87 .name = "i2c-gpio",
87 .id = 0, 88 .id = 0,
88 .dev.platform_data = &nslu2_i2c_gpio_pins, 89 .dev = {
89 .num_resources = 0, 90 .platform_data = &nslu2_i2c_gpio_data,
91 },
90}; 92};
91 93
92static struct platform_device nslu2_beeper = { 94static struct platform_device nslu2_beeper = {
@@ -139,7 +141,7 @@ static struct platform_device nslu2_uart = {
139}; 141};
140 142
141static struct platform_device *nslu2_devices[] __initdata = { 143static struct platform_device *nslu2_devices[] __initdata = {
142 &nslu2_i2c_controller, 144 &nslu2_i2c_gpio,
143 &nslu2_flash, 145 &nslu2_flash,
144 &nslu2_beeper, 146 &nslu2_beeper,
145#ifdef CONFIG_LEDS_IXP4XX 147#ifdef CONFIG_LEDS_IXP4XX
diff --git a/arch/arm/mach-ks8695/Makefile b/arch/arm/mach-ks8695/Makefile
index 2a07a281fa8a..730a3af12c98 100644
--- a/arch/arm/mach-ks8695/Makefile
+++ b/arch/arm/mach-ks8695/Makefile
@@ -9,7 +9,7 @@ obj-n :=
9obj- := 9obj- :=
10 10
11# PCI support is optional 11# PCI support is optional
12#obj-$(CONFIG_PCI) += pci.o 12obj-$(CONFIG_PCI) += pci.o
13 13
14# Board-specific support 14# Board-specific support
15obj-$(CONFIG_MACH_KS8695) += board-micrel.o 15obj-$(CONFIG_MACH_KS8695) += board-micrel.o
diff --git a/arch/arm/mach-ks8695/board-micrel.c b/arch/arm/mach-ks8695/board-micrel.c
index 2feeef81d843..05ac2bd04020 100644
--- a/arch/arm/mach-ks8695/board-micrel.c
+++ b/arch/arm/mach-ks8695/board-micrel.c
@@ -40,7 +40,7 @@ static void __init micrel_init(void)
40 printk(KERN_INFO "Micrel KS8695 Development Board initializing\n"); 40 printk(KERN_INFO "Micrel KS8695 Development Board initializing\n");
41 41
42#ifdef CONFIG_PCI 42#ifdef CONFIG_PCI
43// ks8695_init_pci(&micrel_pci); 43 ks8695_init_pci(&micrel_pci);
44#endif 44#endif
45 45
46 /* Add devices */ 46 /* Add devices */
diff --git a/arch/arm/mach-ks8695/gpio.c b/arch/arm/mach-ks8695/gpio.c
index b1aa3cb3d4a3..5e46191c0af9 100644
--- a/arch/arm/mach-ks8695/gpio.c
+++ b/arch/arm/mach-ks8695/gpio.c
@@ -20,6 +20,8 @@
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/mm.h> 21#include <linux/mm.h>
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/debugfs.h>
24#include <linux/seq_file.h>
23#include <linux/module.h> 25#include <linux/module.h>
24 26
25#include <asm/io.h> 27#include <asm/io.h>
@@ -216,3 +218,84 @@ int irq_to_gpio(unsigned int irq)
216 return (irq - KS8695_IRQ_EXTERN0); 218 return (irq - KS8695_IRQ_EXTERN0);
217} 219}
218EXPORT_SYMBOL(irq_to_gpio); 220EXPORT_SYMBOL(irq_to_gpio);
221
222
223/* .... Debug interface ..................................................... */
224
225#ifdef CONFIG_DEBUG_FS
226
227static int ks8695_gpio_show(struct seq_file *s, void *unused)
228{
229 unsigned int enable[] = { IOPC_IOEINT0EN, IOPC_IOEINT1EN, IOPC_IOEINT2EN, IOPC_IOEINT3EN, IOPC_IOTIM0EN, IOPC_IOTIM1EN };
230 unsigned int intmask[] = { IOPC_IOEINT0TM, IOPC_IOEINT1TM, IOPC_IOEINT2TM, IOPC_IOEINT3TM };
231 unsigned long mode, ctrl, data;
232 int i;
233
234 mode = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM);
235 ctrl = __raw_readl(KS8695_GPIO_VA + KS8695_IOPC);
236 data = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD);
237
238 seq_printf(s, "Pin\tI/O\tFunction\tState\n\n");
239
240 for (i = KS8695_GPIO_0; i <= KS8695_GPIO_15 ; i++) {
241 seq_printf(s, "%i:\t", i);
242
243 seq_printf(s, "%s\t", (mode & IOPM_(i)) ? "Output" : "Input");
244
245 if (i <= KS8695_GPIO_3) {
246 if (ctrl & enable[i]) {
247 seq_printf(s, "EXT%i ", i);
248
249 switch ((ctrl & intmask[i]) >> (4 * i)) {
250 case IOPC_TM_LOW:
251 seq_printf(s, "(Low)"); break;
252 case IOPC_TM_HIGH:
253 seq_printf(s, "(High)"); break;
254 case IOPC_TM_RISING:
255 seq_printf(s, "(Rising)"); break;
256 case IOPC_TM_FALLING:
257 seq_printf(s, "(Falling)"); break;
258 case IOPC_TM_EDGE:
259 seq_printf(s, "(Edges)"); break;
260 }
261 }
262 else
263 seq_printf(s, "GPIO\t");
264 }
265 else if (i <= KS8695_GPIO_5) {
266 if (ctrl & enable[i])
267 seq_printf(s, "TOUT%i\t", i - KS8695_GPIO_4);
268 else
269 seq_printf(s, "GPIO\t");
270 }
271 else
272 seq_printf(s, "GPIO\t");
273
274 seq_printf(s, "\t");
275
276 seq_printf(s, "%i\n", (data & IOPD_(i)) ? 1 : 0);
277 }
278 return 0;
279}
280
281static int ks8695_gpio_open(struct inode *inode, struct file *file)
282{
283 return single_open(file, ks8695_gpio_show, NULL);
284}
285
286static const struct file_operations ks8695_gpio_operations = {
287 .open = ks8695_gpio_open,
288 .read = seq_read,
289 .llseek = seq_lseek,
290 .release = single_release,
291};
292
293static int __init ks8695_gpio_debugfs_init(void)
294{
295 /* /sys/kernel/debug/ks8695_gpio */
296 (void) debugfs_create_file("ks8695_gpio", S_IFREG | S_IRUGO, NULL, NULL, &ks8695_gpio_operations);
297 return 0;
298}
299postcore_initcall(ks8695_gpio_debugfs_init);
300
301#endif
diff --git a/arch/arm/mach-ks8695/pci.c b/arch/arm/mach-ks8695/pci.c
new file mode 100644
index 000000000000..3f4e0330cb1a
--- /dev/null
+++ b/arch/arm/mach-ks8695/pci.c
@@ -0,0 +1,326 @@
1/*
2 * arch/arm/mach-ks8695/pci.c
3 *
4 * Copyright (C) 2003, Micrel Semiconductors
5 * Copyright (C) 2006, Greg Ungerer <gerg@snapgear.com>
6 * Copyright (C) 2006, Ben Dooks
7 * Copyright (C) 2007, Andrew Victor
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include <linux/kernel.h>
25#include <linux/pci.h>
26#include <linux/mm.h>
27#include <linux/init.h>
28#include <linux/irq.h>
29#include <linux/delay.h>
30
31#include <asm/io.h>
32#include <asm/signal.h>
33#include <asm/mach/pci.h>
34#include <asm/hardware.h>
35
36#include <asm/arch/devices.h>
37#include <asm/arch/regs-pci.h>
38
39
40static int pci_dbg;
41static int pci_cfg_dbg;
42
43
44static void ks8695_pci_setupconfig(unsigned int bus_nr, unsigned int devfn, unsigned int where)
45{
46 unsigned long pbca;
47
48 pbca = PBCA_ENABLE | (where & ~3);
49 pbca |= PCI_SLOT(devfn) << 11 ;
50 pbca |= PCI_FUNC(devfn) << 8;
51 pbca |= bus_nr << 16;
52
53 if (bus_nr == 0) {
54 /* use Type-0 transaction */
55 __raw_writel(pbca, KS8695_PCI_VA + KS8695_PBCA);
56 } else {
57 /* use Type-1 transaction */
58 __raw_writel(pbca | PBCA_TYPE1, KS8695_PCI_VA + KS8695_PBCA);
59 }
60}
61
62
63/*
64 * The KS8695 datasheet prohibits anything other than 32bit accesses
65 * to the IO registers, so all our configuration must be done with
66 * 32bit operations, and the correct bit masking and shifting.
67 */
68
69static int ks8695_pci_readconfig(struct pci_bus *bus,
70 unsigned int devfn, int where, int size, u32 *value)
71{
72 ks8695_pci_setupconfig(bus->number, devfn, where);
73
74 *value = __raw_readl(KS8695_PCI_VA + KS8695_PBCD);
75
76 switch (size) {
77 case 4:
78 break;
79 case 2:
80 *value = *value >> ((where & 2) * 8);
81 *value &= 0xffff;
82 break;
83 case 1:
84 *value = *value >> ((where & 3) * 8);
85 *value &= 0xff;
86 break;
87 }
88
89 if (pci_cfg_dbg) {
90 printk("read: %d,%08x,%02x,%d: %08x (%08x)\n",
91 bus->number, devfn, where, size, *value,
92 __raw_readl(KS8695_PCI_VA + KS8695_PBCD));
93 }
94
95 return PCIBIOS_SUCCESSFUL;
96}
97
98static int ks8695_pci_writeconfig(struct pci_bus *bus,
99 unsigned int devfn, int where, int size, u32 value)
100{
101 unsigned long tmp;
102
103 if (pci_cfg_dbg) {
104 printk("write: %d,%08x,%02x,%d: %08x\n",
105 bus->number, devfn, where, size, value);
106 }
107
108 ks8695_pci_setupconfig(bus->number, devfn, where);
109
110 switch (size) {
111 case 4:
112 __raw_writel(value, KS8695_PCI_VA + KS8695_PBCD);
113 break;
114 case 2:
115 tmp = __raw_readl(KS8695_PCI_VA + KS8695_PBCD);
116 tmp &= ~(0xffff << ((where & 2) * 8));
117 tmp |= value << ((where & 2) * 8);
118
119 __raw_writel(tmp, KS8695_PCI_VA + KS8695_PBCD);
120 break;
121 case 1:
122 tmp = __raw_readl(KS8695_PCI_VA + KS8695_PBCD);
123 tmp &= ~(0xff << ((where & 3) * 8));
124 tmp |= value << ((where & 3) * 8);
125
126 __raw_writel(tmp, KS8695_PCI_VA + KS8695_PBCD);
127 break;
128 }
129
130 return PCIBIOS_SUCCESSFUL;
131}
132
133static void ks8695_local_writeconfig(int where, u32 value)
134{
135 ks8695_pci_setupconfig(0, 0, where);
136 __raw_writel(value, KS8695_PCI_VA + KS8695_PBCD);
137}
138
139static struct pci_ops ks8695_pci_ops = {
140 .read = ks8695_pci_readconfig,
141 .write = ks8695_pci_writeconfig,
142};
143
144static struct pci_bus *ks8695_pci_scan_bus(int nr, struct pci_sys_data *sys)
145{
146 return pci_scan_bus(sys->busnr, &ks8695_pci_ops, sys);
147}
148
149static struct resource pci_mem = {
150 .name = "PCI Memory space",
151 .start = KS8695_PCIMEM_PA,
152 .end = KS8695_PCIMEM_PA + (KS8695_PCIMEM_SIZE - 1),
153 .flags = IORESOURCE_MEM,
154};
155
156static struct resource pci_io = {
157 .name = "PCI IO space",
158 .start = KS8695_PCIIO_PA,
159 .end = KS8695_PCIIO_PA + (KS8695_PCIIO_SIZE - 1),
160 .flags = IORESOURCE_IO,
161};
162
163static int __init ks8695_pci_setup(int nr, struct pci_sys_data *sys)
164{
165 if (nr > 0)
166 return 0;
167
168 request_resource(&iomem_resource, &pci_mem);
169 request_resource(&ioport_resource, &pci_io);
170
171 sys->resource[0] = &pci_io;
172 sys->resource[1] = &pci_mem;
173 sys->resource[2] = NULL;
174
175 /* Assign and enable processor bridge */
176 ks8695_local_writeconfig(PCI_BASE_ADDRESS_0, KS8695_PCIMEM_PA);
177
178 /* Enable bus-master & Memory Space access */
179 ks8695_local_writeconfig(PCI_COMMAND, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
180
181 /* Set cache-line size & latency. */
182 ks8695_local_writeconfig(PCI_CACHE_LINE_SIZE, (32 << 8) | (L1_CACHE_BYTES / sizeof(u32)));
183
184 /* Reserve PCI memory space for PCI-AHB resources */
185 if (!request_mem_region(KS8695_PCIMEM_PA, SZ_64M, "PCI-AHB Bridge")) {
186 printk(KERN_ERR "Cannot allocate PCI-AHB Bridge memory.\n");
187 return -EBUSY;
188 }
189
190 return 1;
191}
192
193static inline unsigned int size_mask(unsigned long size)
194{
195 return (~size) + 1;
196}
197
198static int ks8695_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
199{
200 unsigned long pc = instruction_pointer(regs);
201 unsigned long instr = *(unsigned long *)pc;
202 unsigned long cmdstat;
203
204 cmdstat = __raw_readl(KS8695_PCI_VA + KS8695_CRCFCS);
205
206 printk(KERN_ERR "PCI abort: address = 0x%08lx fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx [%s%s%s%s%s]\n",
207 addr, fsr, regs->ARM_pc, regs->ARM_lr,
208 cmdstat & (PCI_STATUS_SIG_TARGET_ABORT << 16) ? "GenTarget" : " ",
209 cmdstat & (PCI_STATUS_REC_TARGET_ABORT << 16) ? "RecvTarget" : " ",
210 cmdstat & (PCI_STATUS_REC_MASTER_ABORT << 16) ? "MasterAbort" : " ",
211 cmdstat & (PCI_STATUS_SIG_SYSTEM_ERROR << 16) ? "SysError" : " ",
212 cmdstat & (PCI_STATUS_DETECTED_PARITY << 16) ? "Parity" : " "
213 );
214
215 __raw_writel(cmdstat, KS8695_PCI_VA + KS8695_CRCFCS);
216
217 /*
218 * If the instruction being executed was a read,
219 * make it look like it read all-ones.
220 */
221 if ((instr & 0x0c100000) == 0x04100000) {
222 int reg = (instr >> 12) & 15;
223 unsigned long val;
224
225 if (instr & 0x00400000)
226 val = 255;
227 else
228 val = -1;
229
230 regs->uregs[reg] = val;
231 regs->ARM_pc += 4;
232 return 0;
233 }
234
235 if ((instr & 0x0e100090) == 0x00100090) {
236 int reg = (instr >> 12) & 15;
237
238 regs->uregs[reg] = -1;
239 regs->ARM_pc += 4;
240 return 0;
241 }
242
243 return 1;
244}
245
246static void __init ks8695_pci_preinit(void)
247{
248 /* stage 1 initialization, subid, subdevice = 0x0001 */
249 __raw_writel(0x00010001, KS8695_PCI_VA + KS8695_CRCSID);
250
251 /* stage 2 initialization */
252 /* prefetch limits with 16 words, retry enable */
253 __raw_writel(0x40000000, KS8695_PCI_VA + KS8695_PBCS);
254
255 /* configure memory mapping */
256 __raw_writel(KS8695_PCIMEM_PA, KS8695_PCI_VA + KS8695_PMBA);
257 __raw_writel(size_mask(KS8695_PCIMEM_SIZE), KS8695_PCI_VA + KS8695_PMBAM);
258 __raw_writel(KS8695_PCIMEM_PA, KS8695_PCI_VA + KS8695_PMBAT);
259 __raw_writel(0, KS8695_PCI_VA + KS8695_PMBAC);
260
261 /* configure IO mapping */
262 __raw_writel(KS8695_PCIIO_PA, KS8695_PCI_VA + KS8695_PIOBA);
263 __raw_writel(size_mask(KS8695_PCIIO_SIZE), KS8695_PCI_VA + KS8695_PIOBAM);
264 __raw_writel(KS8695_PCIIO_PA, KS8695_PCI_VA + KS8695_PIOBAT);
265 __raw_writel(0, KS8695_PCI_VA + KS8695_PIOBAC);
266
267 /* hook in fault handlers */
268 hook_fault_code(8, ks8695_pci_fault, SIGBUS, "external abort on non-linefetch");
269 hook_fault_code(10, ks8695_pci_fault, SIGBUS, "external abort on non-linefetch");
270}
271
272static void ks8695_show_pciregs(void)
273{
274 if (!pci_dbg)
275 return;
276
277 printk(KERN_INFO "PCI: CRCFID = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCFID));
278 printk(KERN_INFO "PCI: CRCFCS = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCFCS));
279 printk(KERN_INFO "PCI: CRCFRV = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCFRV));
280 printk(KERN_INFO "PCI: CRCFLT = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCFLT));
281 printk(KERN_INFO "PCI: CRCBMA = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCBMA));
282 printk(KERN_INFO "PCI: CRCSID = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCSID));
283 printk(KERN_INFO "PCI: CRCFIT = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCFIT));
284
285 printk(KERN_INFO "PCI: PBM = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PBM));
286 printk(KERN_INFO "PCI: PBCS = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PBCS));
287
288 printk(KERN_INFO "PCI: PMBA = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PMBA));
289 printk(KERN_INFO "PCI: PMBAC = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PMBAC));
290 printk(KERN_INFO "PCI: PMBAM = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PMBAM));
291 printk(KERN_INFO "PCI: PMBAT = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PMBAT));
292
293 printk(KERN_INFO "PCI: PIOBA = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PIOBA));
294 printk(KERN_INFO "PCI: PIOBAC = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PIOBAC));
295 printk(KERN_INFO "PCI: PIOBAM = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PIOBAM));
296 printk(KERN_INFO "PCI: PIOBAT = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PIOBAT));
297}
298
299
300static struct hw_pci ks8695_pci __initdata = {
301 .nr_controllers = 1,
302 .preinit = ks8695_pci_preinit,
303 .setup = ks8695_pci_setup,
304 .scan = ks8695_pci_scan_bus,
305 .postinit = NULL,
306 .swizzle = pci_std_swizzle,
307 .map_irq = NULL,
308};
309
310void __init ks8695_init_pci(struct ks8695_pci_cfg *cfg)
311{
312 if (__raw_readl(KS8695_PCI_VA + KS8695_CRCFRV) & CFRV_GUEST) {
313 printk("PCI: KS8695 in guest mode, not initialising\n");
314 return;
315 }
316
317 printk(KERN_INFO "PCI: Initialising\n");
318 ks8695_show_pciregs();
319
320 /* set Mode */
321 __raw_writel(cfg->mode << 29, KS8695_PCI_VA + KS8695_PBM);
322
323 ks8695_pci.map_irq = cfg->map_irq; /* board-specific map_irq method */
324
325 pci_common_init(&ks8695_pci);
326}
diff --git a/arch/arm/mach-ks8695/time.c b/arch/arm/mach-ks8695/time.c
index d2c86e4a72eb..02f766b3121d 100644
--- a/arch/arm/mach-ks8695/time.c
+++ b/arch/arm/mach-ks8695/time.c
@@ -70,10 +70,7 @@ static unsigned long ks8695_gettimeoffset (void)
70 */ 70 */
71static irqreturn_t ks8695_timer_interrupt(int irq, void *dev_id) 71static irqreturn_t ks8695_timer_interrupt(int irq, void *dev_id)
72{ 72{
73 write_seqlock(&xtime_lock);
74 timer_tick(); 73 timer_tick();
75 write_sequnlock(&xtime_lock);
76
77 return IRQ_HANDLED; 74 return IRQ_HANDLED;
78} 75}
79 76
diff --git a/arch/arm/mach-lh7a40x/time.c b/arch/arm/mach-lh7a40x/time.c
index c25316d02537..e50e60b33851 100644
--- a/arch/arm/mach-lh7a40x/time.c
+++ b/arch/arm/mach-lh7a40x/time.c
@@ -41,13 +41,9 @@
41static irqreturn_t 41static irqreturn_t
42lh7a40x_timer_interrupt(int irq, void *dev_id) 42lh7a40x_timer_interrupt(int irq, void *dev_id)
43{ 43{
44 write_seqlock(&xtime_lock);
45
46 TIMER_EOI = 0; 44 TIMER_EOI = 0;
47 timer_tick(); 45 timer_tick();
48 46
49 write_sequnlock(&xtime_lock);
50
51 return IRQ_HANDLED; 47 return IRQ_HANDLED;
52} 48}
53 49
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
new file mode 100644
index 000000000000..3553babbbf05
--- /dev/null
+++ b/arch/arm/mach-msm/Kconfig
@@ -0,0 +1,18 @@
1if ARCH_MSM7X00A
2
3comment "MSM7X00A Board Type"
4 depends on ARCH_MSM7X00A
5
6config MACH_HALIBUT
7 depends on ARCH_MSM7X00A
8 default y
9 bool "Halibut Board (QCT SURF7200A)"
10 help
11 Support for the Qualcomm SURF7200A eval board.
12
13config MSM7X00A_IDLE
14 depends on ARCH_MSM7X00A
15 default y
16 bool "Idle Support for MSM7X00A"
17
18endif
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
new file mode 100644
index 000000000000..d12f23655850
--- /dev/null
+++ b/arch/arm/mach-msm/Makefile
@@ -0,0 +1,7 @@
1obj-y += io.o idle.o irq.o timer.o dma.o
2
3# Common code for board init
4obj-y += common.o
5
6obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o
7
diff --git a/arch/arm/mach-msm/Makefile.boot b/arch/arm/mach-msm/Makefile.boot
new file mode 100644
index 000000000000..24dfbf8c07c4
--- /dev/null
+++ b/arch/arm/mach-msm/Makefile.boot
@@ -0,0 +1,3 @@
1 zreladdr-y := 0x10008000
2params_phys-y := 0x10000100
3initrd_phys-y := 0x10800000
diff --git a/arch/arm/mach-msm/board-halibut.c b/arch/arm/mach-msm/board-halibut.c
new file mode 100644
index 000000000000..86dfb2b5261c
--- /dev/null
+++ b/arch/arm/mach-msm/board-halibut.c
@@ -0,0 +1,114 @@
1/* linux/arch/arm/mach-msm/board-halibut.c
2 *
3 * Copyright (C) 2007 Google, Inc.
4 * Author: Brian Swetland <swetland@google.com>
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
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 */
16
17#include <linux/kernel.h>
18#include <linux/init.h>
19#include <linux/platform_device.h>
20#include <linux/input.h>
21
22#include <asm/hardware.h>
23#include <asm/mach-types.h>
24#include <asm/mach/arch.h>
25#include <asm/mach/map.h>
26#include <asm/mach/flash.h>
27
28#include <asm/arch/board.h>
29#include <asm/arch/msm_iomap.h>
30
31#include <asm/io.h>
32#include <asm/delay.h>
33
34#include <linux/mtd/nand.h>
35#include <linux/mtd/partitions.h>
36
37static struct resource smc91x_resources[] = {
38 [0] = {
39 .start = 0x9C004300,
40 .end = 0x9C004400,
41 .flags = IORESOURCE_MEM,
42 },
43 [1] = {
44 .start = MSM_GPIO_TO_INT(49),
45 .end = MSM_GPIO_TO_INT(49),
46 .flags = IORESOURCE_IRQ,
47 },
48};
49
50static struct platform_device smc91x_device = {
51 .name = "smc91x",
52 .id = 0,
53 .num_resources = ARRAY_SIZE(smc91x_resources),
54 .resource = smc91x_resources,
55};
56
57static void mddi0_panel_power(int on)
58{
59}
60
61static struct msm_mddi_platform_data msm_mddi0_pdata = {
62 .panel_power = mddi0_panel_power,
63 .has_vsync_irq = 0,
64};
65
66static struct platform_device msm_mddi0_device = {
67 .name = "msm_mddi",
68 .id = 0,
69 .dev = {
70 .platform_data = &msm_mddi0_pdata
71 },
72};
73
74static struct platform_device msm_serial0_device = {
75 .name = "msm_serial",
76 .id = 0,
77};
78
79static struct platform_device *devices[] __initdata = {
80 &msm_serial0_device,
81 &msm_mddi0_device,
82 &smc91x_device,
83};
84
85extern struct sys_timer msm_timer;
86
87static void __init halibut_init_irq(void)
88{
89 msm_init_irq();
90}
91
92static void __init halibut_init(void)
93{
94 platform_add_devices(devices, ARRAY_SIZE(devices));
95 msm_add_devices();
96}
97
98static void __init halibut_map_io(void)
99{
100 msm_map_common_io();
101}
102
103MACHINE_START(HALIBUT, "Halibut Board (QCT SURF7200A)")
104
105/* UART for LL DEBUG */
106 .phys_io = MSM_UART1_PHYS,
107 .io_pg_offst = ((MSM_UART1_BASE) >> 18) & 0xfffc,
108
109 .boot_params = 0x10000100,
110 .map_io = halibut_map_io,
111 .init_irq = halibut_init_irq,
112 .init_machine = halibut_init,
113 .timer = &msm_timer,
114MACHINE_END
diff --git a/arch/arm/mach-msm/common.c b/arch/arm/mach-msm/common.c
new file mode 100644
index 000000000000..3f5d3362f887
--- /dev/null
+++ b/arch/arm/mach-msm/common.c
@@ -0,0 +1,116 @@
1/* linux/arch/arm/mach-msm/common.c
2 *
3 * Common setup code for MSM7K Boards
4 *
5 * Copyright (C) 2007 Google, Inc.
6 * Author: Brian Swetland <swetland@google.com>
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/platform_device.h>
22
23#include <asm/mach/flash.h>
24#include <asm/io.h>
25
26#include <asm/setup.h>
27
28#include <linux/mtd/nand.h>
29#include <linux/mtd/partitions.h>
30
31#include <asm/arch/msm_iomap.h>
32
33#include <asm/arch/board.h>
34
35struct flash_platform_data msm_nand_data = {
36 .parts = 0,
37 .nr_parts = 0,
38};
39
40static struct resource msm_nand_resources[] = {
41 [0] = {
42 .start = 7,
43 .end = 7,
44 .flags = IORESOURCE_DMA,
45 },
46};
47
48static struct platform_device msm_nand_device = {
49 .name = "msm_nand",
50 .id = -1,
51 .num_resources = ARRAY_SIZE(msm_nand_resources),
52 .resource = msm_nand_resources,
53 .dev = {
54 .platform_data = &msm_nand_data,
55 },
56};
57
58static struct platform_device msm_smd_device = {
59 .name = "msm_smd",
60 .id = -1,
61};
62
63static struct resource msm_i2c_resources[] = {
64 {
65 .start = MSM_I2C_BASE,
66 .end = MSM_I2C_BASE + MSM_I2C_SIZE - 1,
67 .flags = IORESOURCE_MEM,
68 },
69 {
70 .start = INT_PWB_I2C,
71 .end = INT_PWB_I2C,
72 .flags = IORESOURCE_IRQ,
73 },
74};
75
76static struct platform_device msm_i2c_device = {
77 .name = "msm_i2c",
78 .id = 0,
79 .num_resources = ARRAY_SIZE(msm_i2c_resources),
80 .resource = msm_i2c_resources,
81};
82
83static struct resource usb_resources[] = {
84 {
85 .start = MSM_HSUSB_PHYS,
86 .end = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE,
87 .flags = IORESOURCE_MEM,
88 },
89 {
90 .start = INT_USB_HS,
91 .end = INT_USB_HS,
92 .flags = IORESOURCE_IRQ,
93 },
94};
95
96static struct platform_device msm_hsusb_device = {
97 .name = "msm_hsusb",
98 .id = -1,
99 .num_resources = ARRAY_SIZE(usb_resources),
100 .resource = usb_resources,
101 .dev = {
102 .coherent_dma_mask = 0xffffffff,
103 },
104};
105
106static struct platform_device *devices[] __initdata = {
107 &msm_nand_device,
108 &msm_smd_device,
109 &msm_i2c_device,
110 &msm_hsusb_device,
111};
112
113void __init msm_add_devices(void)
114{
115 platform_add_devices(devices, ARRAY_SIZE(devices));
116}
diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c
new file mode 100644
index 000000000000..8b0f339b3274
--- /dev/null
+++ b/arch/arm/mach-msm/dma.c
@@ -0,0 +1,214 @@
1/* linux/arch/arm/mach-msm/dma.c
2 *
3 * Copyright (C) 2007 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
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 */
15
16#include <asm/io.h>
17#include <linux/interrupt.h>
18#include <asm/arch/dma.h>
19
20#define MSM_DMOV_CHANNEL_COUNT 16
21
22enum {
23 MSM_DMOV_PRINT_ERRORS = 1,
24 MSM_DMOV_PRINT_IO = 2,
25 MSM_DMOV_PRINT_FLOW = 4
26};
27
28static DEFINE_SPINLOCK(msm_dmov_lock);
29static struct msm_dmov_cmd active_command;
30static struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT];
31static struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT];
32unsigned int msm_dmov_print_mask = MSM_DMOV_PRINT_ERRORS;
33
34#define MSM_DMOV_DPRINTF(mask, format, args...) \
35 do { \
36 if ((mask) & msm_dmov_print_mask) \
37 printk(KERN_ERR format, args); \
38 } while (0)
39#define PRINT_ERROR(format, args...) \
40 MSM_DMOV_DPRINTF(MSM_DMOV_PRINT_ERRORS, format, args);
41#define PRINT_IO(format, args...) \
42 MSM_DMOV_DPRINTF(MSM_DMOV_PRINT_IO, format, args);
43#define PRINT_FLOW(format, args...) \
44 MSM_DMOV_DPRINTF(MSM_DMOV_PRINT_FLOW, format, args);
45
46void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
47{
48 unsigned long irq_flags;
49 unsigned int status;
50
51 spin_lock_irqsave(&msm_dmov_lock, irq_flags);
52 status = readl(DMOV_STATUS(id));
53 if (list_empty(&ready_commands[id]) &&
54 (status & DMOV_STATUS_CMD_PTR_RDY)) {
55#if 0
56 if (list_empty(&active_commands[id])) {
57 PRINT_FLOW("msm_dmov_enqueue_cmd(%d), enable interrupt\n", id);
58 writel(DMOV_CONFIG_IRQ_EN, DMOV_CONFIG(id));
59 }
60#endif
61 PRINT_IO("msm_dmov_enqueue_cmd(%d), start command, status %x\n", id, status);
62 list_add_tail(&cmd->list, &active_commands[id]);
63 writel(cmd->cmdptr, DMOV_CMD_PTR(id));
64 } else {
65 if (list_empty(&active_commands[id]))
66 PRINT_ERROR("msm_dmov_enqueue_cmd(%d), error datamover stalled, status %x\n", id, status);
67
68 PRINT_IO("msm_dmov_enqueue_cmd(%d), enqueue command, status %x\n", id, status);
69 list_add_tail(&cmd->list, &ready_commands[id]);
70 }
71 spin_unlock_irqrestore(&msm_dmov_lock, irq_flags);
72}
73
74struct msm_dmov_exec_cmdptr_cmd {
75 struct msm_dmov_cmd dmov_cmd;
76 struct completion complete;
77 unsigned id;
78 unsigned int result;
79 unsigned int flush[6];
80};
81
82static void dmov_exec_cmdptr_complete_func(struct msm_dmov_cmd *_cmd, unsigned int result)
83{
84 struct msm_dmov_exec_cmdptr_cmd *cmd = container_of(_cmd, struct msm_dmov_exec_cmdptr_cmd, dmov_cmd);
85 cmd->result = result;
86 if (result != 0x80000002) {
87 cmd->flush[0] = readl(DMOV_FLUSH0(cmd->id));
88 cmd->flush[1] = readl(DMOV_FLUSH1(cmd->id));
89 cmd->flush[2] = readl(DMOV_FLUSH2(cmd->id));
90 cmd->flush[3] = readl(DMOV_FLUSH3(cmd->id));
91 cmd->flush[4] = readl(DMOV_FLUSH4(cmd->id));
92 cmd->flush[5] = readl(DMOV_FLUSH5(cmd->id));
93 }
94 complete(&cmd->complete);
95}
96
97int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr)
98{
99 struct msm_dmov_exec_cmdptr_cmd cmd;
100
101 PRINT_FLOW("dmov_exec_cmdptr(%d, %x)\n", id, cmdptr);
102
103 cmd.dmov_cmd.cmdptr = cmdptr;
104 cmd.dmov_cmd.complete_func = dmov_exec_cmdptr_complete_func;
105 cmd.id = id;
106 init_completion(&cmd.complete);
107
108 msm_dmov_enqueue_cmd(id, &cmd.dmov_cmd);
109 wait_for_completion(&cmd.complete);
110
111 if (cmd.result != 0x80000002) {
112 PRINT_ERROR("dmov_exec_cmdptr(%d): ERROR, result: %x\n", id, cmd.result);
113 PRINT_ERROR("dmov_exec_cmdptr(%d): flush: %x %x %x %x\n",
114 id, cmd.flush[0], cmd.flush[1], cmd.flush[2], cmd.flush[3]);
115 return -EIO;
116 }
117 PRINT_FLOW("dmov_exec_cmdptr(%d, %x) done\n", id, cmdptr);
118 return 0;
119}
120
121
122static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
123{
124 unsigned int int_status, mask, id;
125 unsigned long irq_flags;
126 unsigned int ch_status;
127 unsigned int ch_result;
128 struct msm_dmov_cmd *cmd;
129
130 spin_lock_irqsave(&msm_dmov_lock, irq_flags);
131
132 int_status = readl(DMOV_ISR); /* read and clear interrupt */
133 PRINT_FLOW("msm_datamover_irq_handler: DMOV_ISR %x\n", int_status);
134
135 while (int_status) {
136 mask = int_status & -int_status;
137 id = fls(mask) - 1;
138 PRINT_FLOW("msm_datamover_irq_handler %08x %08x id %d\n", int_status, mask, id);
139 int_status &= ~mask;
140 ch_status = readl(DMOV_STATUS(id));
141 if (!(ch_status & DMOV_STATUS_RSLT_VALID)) {
142 PRINT_FLOW("msm_datamover_irq_handler id %d, result not valid %x\n", id, ch_status);
143 continue;
144 }
145 do {
146 ch_result = readl(DMOV_RSLT(id));
147 if (list_empty(&active_commands[id])) {
148 PRINT_ERROR("msm_datamover_irq_handler id %d, got result "
149 "with no active command, status %x, result %x\n",
150 id, ch_status, ch_result);
151 cmd = NULL;
152 } else
153 cmd = list_entry(active_commands[id].next, typeof(*cmd), list);
154 PRINT_FLOW("msm_datamover_irq_handler id %d, status %x, result %x\n", id, ch_status, ch_result);
155 if (ch_result & DMOV_RSLT_DONE) {
156 PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n",
157 id, ch_status);
158 PRINT_IO("msm_datamover_irq_handler id %d, got result "
159 "for %p, result %x\n", id, cmd, ch_result);
160 if (cmd) {
161 list_del(&cmd->list);
162 cmd->complete_func(cmd, ch_result);
163 }
164 }
165 if (ch_result & DMOV_RSLT_FLUSH) {
166 unsigned int flush0 = readl(DMOV_FLUSH0(id));
167 PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
168 PRINT_FLOW("msm_datamover_irq_handler id %d, flush, result %x, flush0 %x\n", id, ch_result, flush0);
169 if (cmd) {
170 list_del(&cmd->list);
171 cmd->complete_func(cmd, ch_result);
172 }
173 }
174 if (ch_result & DMOV_RSLT_ERROR) {
175 unsigned int flush0 = readl(DMOV_FLUSH0(id));
176 PRINT_ERROR("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
177 PRINT_ERROR("msm_datamover_irq_handler id %d, error, result %x, flush0 %x\n", id, ch_result, flush0);
178 if (cmd) {
179 list_del(&cmd->list);
180 cmd->complete_func(cmd, ch_result);
181 }
182 /* this does not seem to work, once we get an error */
183 /* the datamover will no longer accept commands */
184 writel(0, DMOV_FLUSH0(id));
185 }
186 ch_status = readl(DMOV_STATUS(id));
187 PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
188 if ((ch_status & DMOV_STATUS_CMD_PTR_RDY) && !list_empty(&ready_commands[id])) {
189 cmd = list_entry(ready_commands[id].next, typeof(*cmd), list);
190 list_del(&cmd->list);
191 list_add_tail(&cmd->list, &active_commands[id]);
192 PRINT_FLOW("msm_datamover_irq_handler id %d, start command\n", id);
193 writel(cmd->cmdptr, DMOV_CMD_PTR(id));
194 }
195 } while (ch_status & DMOV_STATUS_RSLT_VALID);
196 PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
197 }
198 spin_unlock_irqrestore(&msm_dmov_lock, irq_flags);
199 return IRQ_HANDLED;
200}
201
202static int __init msm_init_datamover(void)
203{
204 int i;
205 for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++) {
206 INIT_LIST_HEAD(&ready_commands[i]);
207 INIT_LIST_HEAD(&active_commands[i]);
208 writel(DMOV_CONFIG_IRQ_EN | DMOV_CONFIG_FORCE_TOP_PTR_RSLT | DMOV_CONFIG_FORCE_FLUSH_RSLT, DMOV_CONFIG(i));
209 }
210 return request_irq(INT_ADM_AARM, msm_datamover_irq_handler, 0, "msmdatamover", NULL);
211}
212
213arch_initcall(msm_init_datamover);
214
diff --git a/arch/arm/mach-msm/idle.S b/arch/arm/mach-msm/idle.S
new file mode 100644
index 000000000000..2b1cb7f16943
--- /dev/null
+++ b/arch/arm/mach-msm/idle.S
@@ -0,0 +1,36 @@
1/* linux/include/asm-arm/arch-msm/idle.S
2 *
3 * Idle processing for MSM7K - work around bugs with SWFI.
4 *
5 * Copyright (c) 2007 QUALCOMM Incorporated.
6 * Copyright (C) 2007 Google, Inc.
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#include <linux/linkage.h>
20#include <asm/assembler.h>
21
22ENTRY(arch_idle)
23#ifdef CONFIG_MSM7X00A_IDLE
24 mrc p15, 0, r1, c1, c0, 0 /* read current CR */
25 bic r0, r1, #(1 << 2) /* clear dcache bit */
26 bic r0, r0, #(1 << 12) /* clear icache bit */
27 mcr p15, 0, r0, c1, c0, 0 /* disable d/i cache */
28
29 mov r0, #0 /* prepare wfi value */
30 mcr p15, 0, r0, c7, c10, 0 /* flush the cache */
31 mcr p15, 0, r0, c7, c10, 4 /* memory barrier */
32 mcr p15, 0, r0, c7, c0, 4 /* wait for interrupt */
33
34 mcr p15, 0, r1, c1, c0, 0 /* restore d/i cache */
35#endif
36 mov pc, lr
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
new file mode 100644
index 000000000000..c39edb994a88
--- /dev/null
+++ b/arch/arm/mach-msm/io.c
@@ -0,0 +1,85 @@
1/* arch/arm/mach-msm/io.c
2 *
3 * MSM7K io support
4 *
5 * Copyright (C) 2007 Google, Inc.
6 * Author: Brian Swetland <swetland@google.com>
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#include <linux/kernel.h>
20#include <linux/init.h>
21
22#include <asm/hardware.h>
23#include <asm/io.h>
24#include <asm/page.h>
25#include <asm/arch/msm_iomap.h>
26#include <asm/mach/map.h>
27
28#include <asm/arch/board.h>
29
30#define MSM_DEVICE(name) { \
31 .virtual = MSM_##name##_BASE, \
32 .pfn = __phys_to_pfn(MSM_##name##_PHYS), \
33 .length = MSM_##name##_SIZE, \
34 .type = MT_DEVICE_NONSHARED, \
35 }
36
37static struct map_desc msm_io_desc[] __initdata = {
38 MSM_DEVICE(VIC),
39 MSM_DEVICE(CSR),
40 MSM_DEVICE(GPT),
41 MSM_DEVICE(DMOV),
42 MSM_DEVICE(UART1),
43 MSM_DEVICE(UART2),
44 MSM_DEVICE(UART3),
45 MSM_DEVICE(I2C),
46 MSM_DEVICE(GPIO1),
47 MSM_DEVICE(GPIO2),
48 MSM_DEVICE(HSUSB),
49 MSM_DEVICE(CLK_CTL),
50 MSM_DEVICE(PMDH),
51 MSM_DEVICE(EMDH),
52 MSM_DEVICE(MDP),
53 {
54 .virtual = MSM_SHARED_RAM_BASE,
55 .pfn = __phys_to_pfn(MSM_SHARED_RAM_PHYS),
56 .length = MSM_SHARED_RAM_SIZE,
57 .type = MT_DEVICE,
58 },
59};
60
61void __init msm_map_common_io(void)
62{
63 /* Make sure the peripheral register window is closed, since
64 * we will use PTE flags (TEX[1]=1,B=0,C=1) to determine which
65 * pages are peripheral interface or not.
66 */
67 asm("mcr p15, 0, %0, c15, c2, 4" : : "r" (0));
68
69 iotable_init(msm_io_desc, ARRAY_SIZE(msm_io_desc));
70}
71
72void __iomem *
73__msm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype)
74{
75 if (mtype == MT_DEVICE) {
76 /* The peripherals in the 88000000 - D0000000 range
77 * are only accessable by type MT_DEVICE_NONSHARED.
78 * Adjust mtype as necessary to make this "just work."
79 */
80 if ((phys_addr >= 0x88000000) && (phys_addr < 0xD0000000))
81 mtype = MT_DEVICE_NONSHARED;
82 }
83
84 return __arm_ioremap(phys_addr, size, mtype);
85}
diff --git a/arch/arm/mach-msm/irq.c b/arch/arm/mach-msm/irq.c
new file mode 100644
index 000000000000..24158040b789
--- /dev/null
+++ b/arch/arm/mach-msm/irq.c
@@ -0,0 +1,154 @@
1/* linux/arch/arm/mach-msm/irq.c
2 *
3 * Copyright (C) 2007 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
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 */
15
16#include <linux/init.h>
17#include <linux/module.h>
18#include <linux/sched.h>
19#include <linux/interrupt.h>
20#include <linux/ptrace.h>
21#include <linux/timer.h>
22
23#include <linux/irq.h>
24#include <asm/hardware.h>
25
26#include <asm/io.h>
27
28#include <asm/arch/msm_iomap.h>
29
30#define VIC_REG(off) (MSM_VIC_BASE + (off))
31
32#define VIC_INT_SELECT0 VIC_REG(0x0000) /* 1: FIQ, 0: IRQ */
33#define VIC_INT_SELECT1 VIC_REG(0x0004) /* 1: FIQ, 0: IRQ */
34#define VIC_INT_EN0 VIC_REG(0x0010)
35#define VIC_INT_EN1 VIC_REG(0x0014)
36#define VIC_INT_ENCLEAR0 VIC_REG(0x0020)
37#define VIC_INT_ENCLEAR1 VIC_REG(0x0024)
38#define VIC_INT_ENSET0 VIC_REG(0x0030)
39#define VIC_INT_ENSET1 VIC_REG(0x0034)
40#define VIC_INT_TYPE0 VIC_REG(0x0040) /* 1: EDGE, 0: LEVEL */
41#define VIC_INT_TYPE1 VIC_REG(0x0044) /* 1: EDGE, 0: LEVEL */
42#define VIC_INT_POLARITY0 VIC_REG(0x0050) /* 1: NEG, 0: POS */
43#define VIC_INT_POLARITY1 VIC_REG(0x0054) /* 1: NEG, 0: POS */
44#define VIC_NO_PEND_VAL VIC_REG(0x0060)
45#define VIC_INT_MASTEREN VIC_REG(0x0064) /* 1: IRQ, 2: FIQ */
46#define VIC_PROTECTION VIC_REG(0x006C) /* 1: ENABLE */
47#define VIC_CONFIG VIC_REG(0x0068) /* 1: USE ARM1136 VIC */
48#define VIC_IRQ_STATUS0 VIC_REG(0x0080)
49#define VIC_IRQ_STATUS1 VIC_REG(0x0084)
50#define VIC_FIQ_STATUS0 VIC_REG(0x0090)
51#define VIC_FIQ_STATUS1 VIC_REG(0x0094)
52#define VIC_RAW_STATUS0 VIC_REG(0x00A0)
53#define VIC_RAW_STATUS1 VIC_REG(0x00A4)
54#define VIC_INT_CLEAR0 VIC_REG(0x00B0)
55#define VIC_INT_CLEAR1 VIC_REG(0x00B4)
56#define VIC_SOFTINT0 VIC_REG(0x00C0)
57#define VIC_SOFTINT1 VIC_REG(0x00C4)
58#define VIC_IRQ_VEC_RD VIC_REG(0x00D0) /* pending int # */
59#define VIC_IRQ_VEC_PEND_RD VIC_REG(0x00D4) /* pending vector addr */
60#define VIC_IRQ_VEC_WR VIC_REG(0x00D8)
61#define VIC_IRQ_IN_SERVICE VIC_REG(0x00E0)
62#define VIC_IRQ_IN_STACK VIC_REG(0x00E4)
63#define VIC_TEST_BUS_SEL VIC_REG(0x00E8)
64
65#define VIC_VECTPRIORITY(n) VIC_REG(0x0200+((n) * 4))
66#define VIC_VECTADDR(n) VIC_REG(0x0400+((n) * 4))
67
68static void msm_irq_ack(unsigned int irq)
69{
70 unsigned reg = VIC_INT_CLEAR0 + ((irq & 32) ? 4 : 0);
71 irq = 1 << (irq & 31);
72 writel(irq, reg);
73}
74
75static void msm_irq_mask(unsigned int irq)
76{
77 unsigned reg = VIC_INT_ENCLEAR0 + ((irq & 32) ? 4 : 0);
78 writel(1 << (irq & 31), reg);
79}
80
81static void msm_irq_unmask(unsigned int irq)
82{
83 unsigned reg = VIC_INT_ENSET0 + ((irq & 32) ? 4 : 0);
84 writel(1 << (irq & 31), reg);
85}
86
87static int msm_irq_set_wake(unsigned int irq, unsigned int on)
88{
89 return -EINVAL;
90}
91
92static int msm_irq_set_type(unsigned int irq, unsigned int flow_type)
93{
94 unsigned treg = VIC_INT_TYPE0 + ((irq & 32) ? 4 : 0);
95 unsigned preg = VIC_INT_POLARITY0 + ((irq & 32) ? 4 : 0);
96 int b = 1 << (irq & 31);
97
98 if (flow_type & (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW))
99 writel(readl(preg) | b, preg);
100 if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_HIGH))
101 writel(readl(preg) & (~b), preg);
102
103 if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
104 writel(readl(treg) | b, treg);
105 set_irq_handler(irq, handle_edge_irq);
106 }
107 if (flow_type & (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW)) {
108 writel(readl(treg) & (~b), treg);
109 set_irq_handler(irq, handle_level_irq);
110 }
111 return 0;
112}
113
114static struct irq_chip msm_irq_chip = {
115 .name = "msm",
116 .ack = msm_irq_ack,
117 .mask = msm_irq_mask,
118 .unmask = msm_irq_unmask,
119 .set_wake = msm_irq_set_wake,
120 .set_type = msm_irq_set_type,
121};
122
123void __init msm_init_irq(void)
124{
125 unsigned n;
126
127 /* select level interrupts */
128 writel(0, VIC_INT_TYPE0);
129 writel(0, VIC_INT_TYPE1);
130
131 /* select highlevel interrupts */
132 writel(0, VIC_INT_POLARITY0);
133 writel(0, VIC_INT_POLARITY1);
134
135 /* select IRQ for all INTs */
136 writel(0, VIC_INT_SELECT0);
137 writel(0, VIC_INT_SELECT1);
138
139 /* disable all INTs */
140 writel(0, VIC_INT_EN0);
141 writel(0, VIC_INT_EN1);
142
143 /* don't use 1136 vic */
144 writel(0, VIC_CONFIG);
145
146 /* enable interrupt controller */
147 writel(1, VIC_INT_MASTEREN);
148
149 for (n = 0; n < NR_MSM_IRQS; n++) {
150 set_irq_chip(n, &msm_irq_chip);
151 set_irq_handler(n, handle_level_irq);
152 set_irq_flags(n, IRQF_VALID);
153 }
154}
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
new file mode 100644
index 000000000000..bd4732d1ab3e
--- /dev/null
+++ b/arch/arm/mach-msm/timer.c
@@ -0,0 +1,205 @@
1/* linux/arch/arm/mach-msm/timer.c
2 *
3 * Copyright (C) 2007 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
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 */
15
16#include <linux/init.h>
17#include <linux/time.h>
18#include <linux/interrupt.h>
19#include <linux/irq.h>
20#include <linux/clk.h>
21#include <linux/clockchips.h>
22#include <linux/delay.h>
23
24#include <asm/mach/time.h>
25#include <asm/arch/msm_iomap.h>
26
27#include <asm/io.h>
28
29#define MSM_DGT_BASE (MSM_GPT_BASE + 0x10)
30#define MSM_DGT_SHIFT (5)
31
32#define TIMER_MATCH_VAL 0x0000
33#define TIMER_COUNT_VAL 0x0004
34#define TIMER_ENABLE 0x0008
35#define TIMER_ENABLE_CLR_ON_MATCH_EN 2
36#define TIMER_ENABLE_EN 1
37#define TIMER_CLEAR 0x000C
38
39#define CSR_PROTECTION 0x0020
40#define CSR_PROTECTION_EN 1
41
42#define GPT_HZ 32768
43#define DGT_HZ 19200000 /* 19.2 MHz or 600 KHz after shift */
44
45struct msm_clock {
46 struct clock_event_device clockevent;
47 struct clocksource clocksource;
48 struct irqaction irq;
49 uint32_t regbase;
50 uint32_t freq;
51 uint32_t shift;
52};
53
54static irqreturn_t msm_timer_interrupt(int irq, void *dev_id)
55{
56 struct clock_event_device *evt = dev_id;
57 evt->event_handler(evt);
58 return IRQ_HANDLED;
59}
60
61static cycle_t msm_gpt_read(void)
62{
63 return readl(MSM_GPT_BASE + TIMER_COUNT_VAL);
64}
65
66static cycle_t msm_dgt_read(void)
67{
68 return readl(MSM_DGT_BASE + TIMER_COUNT_VAL) >> MSM_DGT_SHIFT;
69}
70
71static int msm_timer_set_next_event(unsigned long cycles,
72 struct clock_event_device *evt)
73{
74 struct msm_clock *clock = container_of(evt, struct msm_clock, clockevent);
75 uint32_t now = readl(clock->regbase + TIMER_COUNT_VAL);
76 uint32_t alarm = now + (cycles << clock->shift);
77 int late;
78
79 writel(alarm, clock->regbase + TIMER_MATCH_VAL);
80 now = readl(clock->regbase + TIMER_COUNT_VAL);
81 late = now - alarm;
82 if (late >= (-2 << clock->shift) && late < DGT_HZ*5) {
83 printk(KERN_NOTICE "msm_timer_set_next_event(%lu) clock %s, "
84 "alarm already expired, now %x, alarm %x, late %d\n",
85 cycles, clock->clockevent.name, now, alarm, late);
86 return -ETIME;
87 }
88 return 0;
89}
90
91static void msm_timer_set_mode(enum clock_event_mode mode,
92 struct clock_event_device *evt)
93{
94 struct msm_clock *clock = container_of(evt, struct msm_clock, clockevent);
95 switch (mode) {
96 case CLOCK_EVT_MODE_RESUME:
97 case CLOCK_EVT_MODE_PERIODIC:
98 break;
99 case CLOCK_EVT_MODE_ONESHOT:
100 writel(TIMER_ENABLE_EN, clock->regbase + TIMER_ENABLE);
101 break;
102 case CLOCK_EVT_MODE_UNUSED:
103 case CLOCK_EVT_MODE_SHUTDOWN:
104 writel(0, clock->regbase + TIMER_ENABLE);
105 break;
106 }
107}
108
109static struct msm_clock msm_clocks[] = {
110 {
111 .clockevent = {
112 .name = "gp_timer",
113 .features = CLOCK_EVT_FEAT_ONESHOT,
114 .shift = 32,
115 .rating = 200,
116 .set_next_event = msm_timer_set_next_event,
117 .set_mode = msm_timer_set_mode,
118 },
119 .clocksource = {
120 .name = "gp_timer",
121 .rating = 200,
122 .read = msm_gpt_read,
123 .mask = CLOCKSOURCE_MASK(32),
124 .shift = 24,
125 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
126 },
127 .irq = {
128 .name = "gp_timer",
129 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_TRIGGER_RISING,
130 .handler = msm_timer_interrupt,
131 .dev_id = &msm_clocks[0].clockevent,
132 .irq = INT_GP_TIMER_EXP
133 },
134 .regbase = MSM_GPT_BASE,
135 .freq = GPT_HZ
136 },
137 {
138 .clockevent = {
139 .name = "dg_timer",
140 .features = CLOCK_EVT_FEAT_ONESHOT,
141 .shift = 32 + MSM_DGT_SHIFT,
142 .rating = 300,
143 .set_next_event = msm_timer_set_next_event,
144 .set_mode = msm_timer_set_mode,
145 },
146 .clocksource = {
147 .name = "dg_timer",
148 .rating = 300,
149 .read = msm_dgt_read,
150 .mask = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT)),
151 .shift = 24 - MSM_DGT_SHIFT,
152 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
153 },
154 .irq = {
155 .name = "dg_timer",
156 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_TRIGGER_RISING,
157 .handler = msm_timer_interrupt,
158 .dev_id = &msm_clocks[1].clockevent,
159 .irq = INT_DEBUG_TIMER_EXP
160 },
161 .regbase = MSM_DGT_BASE,
162 .freq = DGT_HZ >> MSM_DGT_SHIFT,
163 .shift = MSM_DGT_SHIFT
164 }
165};
166
167static void __init msm_timer_init(void)
168{
169 int i;
170 int res;
171
172 for (i = 0; i < ARRAY_SIZE(msm_clocks); i++) {
173 struct msm_clock *clock = &msm_clocks[i];
174 struct clock_event_device *ce = &clock->clockevent;
175 struct clocksource *cs = &clock->clocksource;
176 writel(0, clock->regbase + TIMER_ENABLE);
177 writel(0, clock->regbase + TIMER_CLEAR);
178 writel(~0, clock->regbase + TIMER_MATCH_VAL);
179
180 ce->mult = div_sc(clock->freq, NSEC_PER_SEC, ce->shift);
181 /* allow at least 10 seconds to notice that the timer wrapped */
182 ce->max_delta_ns =
183 clockevent_delta2ns(0xf0000000 >> clock->shift, ce);
184 /* 4 gets rounded down to 3 */
185 ce->min_delta_ns = clockevent_delta2ns(4, ce);
186 ce->cpumask = cpumask_of_cpu(0);
187
188 cs->mult = clocksource_hz2mult(clock->freq, cs->shift);
189 res = clocksource_register(cs);
190 if (res)
191 printk(KERN_ERR "msm_timer_init: clocksource_register "
192 "failed for %s\n", cs->name);
193
194 res = setup_irq(clock->irq.irq, &clock->irq);
195 if (res)
196 printk(KERN_ERR "msm_timer_init: setup_irq "
197 "failed for %s\n", cs->name);
198
199 clockevents_register_device(ce);
200 }
201}
202
203struct sys_timer msm_timer = {
204 .init = msm_timer_init
205};
diff --git a/arch/arm/mach-mx3/time.c b/arch/arm/mach-mx3/time.c
index e81fb5c5d7c3..fb565c98dbfb 100644
--- a/arch/arm/mach-mx3/time.c
+++ b/arch/arm/mach-mx3/time.c
@@ -45,8 +45,6 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
45{ 45{
46 unsigned int next_match; 46 unsigned int next_match;
47 47
48 write_seqlock(&xtime_lock);
49
50 if (__raw_readl(MXC_GPT_GPTSR) & GPTSR_OF1) { 48 if (__raw_readl(MXC_GPT_GPTSR) & GPTSR_OF1) {
51 do { 49 do {
52 timer_tick(); 50 timer_tick();
@@ -57,8 +55,6 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
57 __raw_readl(MXC_GPT_GPTCNT)) <= 0); 55 __raw_readl(MXC_GPT_GPTCNT)) <= 0);
58 } 56 }
59 57
60 write_sequnlock(&xtime_lock);
61
62 return IRQ_HANDLED; 58 return IRQ_HANDLED;
63} 59}
64 60
diff --git a/arch/arm/mach-netx/Makefile b/arch/arm/mach-netx/Makefile
index 18785ff37657..7ce4ba9eb242 100644
--- a/arch/arm/mach-netx/Makefile
+++ b/arch/arm/mach-netx/Makefile
@@ -1,9 +1,6 @@
1# 1#
2# Makefile for the linux kernel. 2# Makefile for the linux kernel.
3# 3#
4# Note! Dependencies are done automagically by 'make dep', which also
5# removes any old dependencies. DON'T put your own dependencies here
6# unless it's something special (ie not a .c file).
7 4
8# Object file lists. 5# Object file lists.
9 6
diff --git a/arch/arm/mach-netx/time.c b/arch/arm/mach-netx/time.c
index 4762e207b0bf..ea07b54afa59 100644
--- a/arch/arm/mach-netx/time.c
+++ b/arch/arm/mach-netx/time.c
@@ -33,12 +33,8 @@
33static irqreturn_t 33static irqreturn_t
34netx_timer_interrupt(int irq, void *dev_id) 34netx_timer_interrupt(int irq, void *dev_id)
35{ 35{
36 write_seqlock(&xtime_lock);
37
38 timer_tick(); 36 timer_tick();
39 37
40 write_sequnlock(&xtime_lock);
41
42 /* acknowledge interrupt */ 38 /* acknowledge interrupt */
43 writel(COUNTER_BIT(0), NETX_GPIO_IRQ); 39 writel(COUNTER_BIT(0), NETX_GPIO_IRQ);
44 40
diff --git a/arch/arm/mach-omap1/board-fsample.c b/arch/arm/mach-omap1/board-fsample.c
index d5f6ea14fc7b..f550b19e1ecd 100644
--- a/arch/arm/mach-omap1/board-fsample.c
+++ b/arch/arm/mach-omap1/board-fsample.c
@@ -76,7 +76,7 @@ static struct resource smc91x_resources[] = {
76 [1] = { 76 [1] = {
77 .start = INT_730_MPU_EXT_NIRQ, 77 .start = INT_730_MPU_EXT_NIRQ,
78 .end = 0, 78 .end = 0,
79 .flags = IORESOURCE_IRQ, 79 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
80 }, 80 },
81}; 81};
82 82
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
index 130681201c19..bfa04fa25524 100644
--- a/arch/arm/mach-omap1/board-h2.c
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -27,6 +27,7 @@
27#include <linux/mtd/nand.h> 27#include <linux/mtd/nand.h>
28#include <linux/mtd/partitions.h> 28#include <linux/mtd/partitions.h>
29#include <linux/input.h> 29#include <linux/input.h>
30#include <linux/i2c/tps65010.h>
30 31
31#include <asm/hardware.h> 32#include <asm/hardware.h>
32#include <asm/gpio.h> 33#include <asm/gpio.h>
@@ -36,7 +37,6 @@
36#include <asm/mach/flash.h> 37#include <asm/mach/flash.h>
37#include <asm/mach/map.h> 38#include <asm/mach/map.h>
38 39
39#include <asm/arch/tps65010.h>
40#include <asm/arch/mux.h> 40#include <asm/arch/mux.h>
41#include <asm/arch/tc.h> 41#include <asm/arch/tc.h>
42#include <asm/arch/irda.h> 42#include <asm/arch/irda.h>
@@ -209,7 +209,7 @@ static struct resource h2_smc91x_resources[] = {
209 [1] = { 209 [1] = {
210 .start = OMAP_GPIO_IRQ(0), 210 .start = OMAP_GPIO_IRQ(0),
211 .end = OMAP_GPIO_IRQ(0), 211 .end = OMAP_GPIO_IRQ(0),
212 .flags = IORESOURCE_IRQ, 212 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
213 }, 213 },
214}; 214};
215 215
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
index 4f84ae273a1f..056519860565 100644
--- a/arch/arm/mach-omap1/board-h3.c
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -26,6 +26,7 @@
26#include <linux/mtd/nand.h> 26#include <linux/mtd/nand.h>
27#include <linux/mtd/partitions.h> 27#include <linux/mtd/partitions.h>
28#include <linux/input.h> 28#include <linux/input.h>
29#include <linux/i2c/tps65010.h>
29 30
30#include <asm/setup.h> 31#include <asm/setup.h>
31#include <asm/page.h> 32#include <asm/page.h>
@@ -37,7 +38,6 @@
37#include <asm/mach/flash.h> 38#include <asm/mach/flash.h>
38#include <asm/mach/map.h> 39#include <asm/mach/map.h>
39 40
40#include <asm/arch/tps65010.h>
41#include <asm/arch/gpioexpander.h> 41#include <asm/arch/gpioexpander.h>
42#include <asm/arch/irqs.h> 42#include <asm/arch/irqs.h>
43#include <asm/arch/mux.h> 43#include <asm/arch/mux.h>
@@ -208,7 +208,7 @@ static struct resource smc91x_resources[] = {
208 [1] = { 208 [1] = {
209 .start = OMAP_GPIO_IRQ(40), 209 .start = OMAP_GPIO_IRQ(40),
210 .end = OMAP_GPIO_IRQ(40), 210 .end = OMAP_GPIO_IRQ(40),
211 .flags = IORESOURCE_IRQ, 211 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
212 }, 212 },
213}; 213};
214 214
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index 7e63a41e37c6..7d2d8af155a3 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -202,7 +202,7 @@ static struct resource innovator1510_smc91x_resources[] = {
202 [1] = { 202 [1] = {
203 .start = OMAP1510_INT_ETHER, 203 .start = OMAP1510_INT_ETHER,
204 .end = OMAP1510_INT_ETHER, 204 .end = OMAP1510_INT_ETHER,
205 .flags = IORESOURCE_IRQ, 205 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
206 }, 206 },
207}; 207};
208 208
@@ -269,7 +269,7 @@ static struct resource innovator1610_smc91x_resources[] = {
269 [1] = { 269 [1] = {
270 .start = OMAP_GPIO_IRQ(0), 270 .start = OMAP_GPIO_IRQ(0),
271 .end = OMAP_GPIO_IRQ(0), 271 .end = OMAP_GPIO_IRQ(0),
272 .flags = IORESOURCE_IRQ, 272 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
273 }, 273 },
274}; 274};
275 275
diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c
index 182a98a9df4c..e2c8ffd75cff 100644
--- a/arch/arm/mach-omap1/board-nokia770.c
+++ b/arch/arm/mach-omap1/board-nokia770.c
@@ -32,7 +32,6 @@
32#include <asm/arch/common.h> 32#include <asm/arch/common.h>
33#include <asm/arch/dsp_common.h> 33#include <asm/arch/dsp_common.h>
34#include <asm/arch/aic23.h> 34#include <asm/arch/aic23.h>
35#include <asm/arch/gpio.h>
36#include <asm/arch/omapfb.h> 35#include <asm/arch/omapfb.h>
37#include <asm/arch/lcd_mipid.h> 36#include <asm/arch/lcd_mipid.h>
38 37
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
index 5db182da322b..84333440008c 100644
--- a/arch/arm/mach-omap1/board-osk.c
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -31,12 +31,13 @@
31#include <linux/platform_device.h> 31#include <linux/platform_device.h>
32#include <linux/interrupt.h> 32#include <linux/interrupt.h>
33#include <linux/irq.h> 33#include <linux/irq.h>
34#include <linux/interrupt.h>
35#include <linux/i2c.h> 34#include <linux/i2c.h>
36 35
37#include <linux/mtd/mtd.h> 36#include <linux/mtd/mtd.h>
38#include <linux/mtd/partitions.h> 37#include <linux/mtd/partitions.h>
39 38
39#include <linux/i2c/tps65010.h>
40
40#include <asm/hardware.h> 41#include <asm/hardware.h>
41#include <asm/gpio.h> 42#include <asm/gpio.h>
42 43
@@ -46,7 +47,6 @@
46#include <asm/mach/flash.h> 47#include <asm/mach/flash.h>
47 48
48#include <asm/arch/usb.h> 49#include <asm/arch/usb.h>
49#include <asm/arch/tps65010.h>
50#include <asm/arch/mux.h> 50#include <asm/arch/mux.h>
51#include <asm/arch/tc.h> 51#include <asm/arch/tc.h>
52#include <asm/arch/common.h> 52#include <asm/arch/common.h>
@@ -111,7 +111,7 @@ static struct resource osk5912_smc91x_resources[] = {
111 [1] = { 111 [1] = {
112 .start = OMAP_GPIO_IRQ(0), 112 .start = OMAP_GPIO_IRQ(0),
113 .end = OMAP_GPIO_IRQ(0), 113 .end = OMAP_GPIO_IRQ(0),
114 .flags = IORESOURCE_IRQ, 114 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
115 }, 115 },
116}; 116};
117 117
diff --git a/arch/arm/mach-omap1/board-palmtt.c b/arch/arm/mach-omap1/board-palmtt.c
index e47010fec275..ed7094a70064 100644
--- a/arch/arm/mach-omap1/board-palmtt.c
+++ b/arch/arm/mach-omap1/board-palmtt.c
@@ -42,7 +42,6 @@
42#include <asm/arch/common.h> 42#include <asm/arch/common.h>
43#include <asm/arch/omap-alsa.h> 43#include <asm/arch/omap-alsa.h>
44 44
45#include <linux/input.h>
46#include <linux/spi/spi.h> 45#include <linux/spi/spi.h>
47#include <linux/spi/ads7846.h> 46#include <linux/spi/ads7846.h>
48 47
diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c
index c275d517764a..a9a0f6610c3d 100644
--- a/arch/arm/mach-omap1/board-palmz71.c
+++ b/arch/arm/mach-omap1/board-palmz71.c
@@ -44,7 +44,6 @@
44#include <asm/arch/common.h> 44#include <asm/arch/common.h>
45#include <asm/arch/omap-alsa.h> 45#include <asm/arch/omap-alsa.h>
46 46
47#include <linux/input.h>
48#include <linux/spi/spi.h> 47#include <linux/spi/spi.h>
49#include <linux/spi/ads7846.h> 48#include <linux/spi/ads7846.h>
50 49
diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c
index e44437e10eef..534dcfb9d263 100644
--- a/arch/arm/mach-omap1/board-perseus2.c
+++ b/arch/arm/mach-omap1/board-perseus2.c
@@ -75,7 +75,7 @@ static struct resource smc91x_resources[] = {
75 [1] = { 75 [1] = {
76 .start = INT_730_MPU_EXT_NIRQ, 76 .start = INT_730_MPU_EXT_NIRQ,
77 .end = 0, 77 .end = 0,
78 .flags = IORESOURCE_IRQ, 78 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
79 }, 79 },
80}; 80};
81 81
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
index 214dd19889ac..c82a1cd20ad4 100644
--- a/arch/arm/mach-omap1/board-voiceblue.c
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -117,7 +117,7 @@ static struct resource voiceblue_smc91x_resources[] = {
117 [1] = { 117 [1] = {
118 .start = OMAP_GPIO_IRQ(8), 118 .start = OMAP_GPIO_IRQ(8),
119 .end = OMAP_GPIO_IRQ(8), 119 .end = OMAP_GPIO_IRQ(8),
120 .flags = IORESOURCE_IRQ, 120 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
121 }, 121 },
122}; 122};
123 123
diff --git a/arch/arm/mach-omap1/leds-osk.c b/arch/arm/mach-omap1/leds-osk.c
index 86de303ecab2..6939d5e7569a 100644
--- a/arch/arm/mach-omap1/leds-osk.c
+++ b/arch/arm/mach-omap1/leds-osk.c
@@ -5,13 +5,13 @@
5 */ 5 */
6#include <linux/init.h> 6#include <linux/init.h>
7#include <linux/workqueue.h> 7#include <linux/workqueue.h>
8#include <linux/i2c/tps65010.h>
8 9
9#include <asm/hardware.h> 10#include <asm/hardware.h>
10#include <asm/leds.h> 11#include <asm/leds.h>
11#include <asm/system.h> 12#include <asm/system.h>
12 13
13#include <asm/arch/gpio.h> 14#include <asm/arch/gpio.h>
14#include <asm/arch/tps65010.h>
15 15
16#include "leds.h" 16#include "leds.h"
17 17
diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c
index 3bf01e28df33..06b7e54a0128 100644
--- a/arch/arm/mach-omap1/pm.c
+++ b/arch/arm/mach-omap1/pm.c
@@ -69,14 +69,14 @@ static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE];
69 69
70static unsigned short enable_dyn_sleep = 1; 70static unsigned short enable_dyn_sleep = 1;
71 71
72static ssize_t omap_pm_sleep_while_idle_show(struct kset *kset, char *buf) 72static ssize_t idle_show(struct kobject *kobj, struct kobj_attribute *attr,
73 char *buf)
73{ 74{
74 return sprintf(buf, "%hu\n", enable_dyn_sleep); 75 return sprintf(buf, "%hu\n", enable_dyn_sleep);
75} 76}
76 77
77static ssize_t omap_pm_sleep_while_idle_store(struct kset *kset, 78static ssize_t idle_store(struct kobject *kobj, struct kobj_attribute *attr,
78 const char * buf, 79 const char * buf, size_t n)
79 size_t n)
80{ 80{
81 unsigned short value; 81 unsigned short value;
82 if (sscanf(buf, "%hu", &value) != 1 || 82 if (sscanf(buf, "%hu", &value) != 1 ||
@@ -88,16 +88,9 @@ static ssize_t omap_pm_sleep_while_idle_store(struct kset *kset,
88 return n; 88 return n;
89} 89}
90 90
91static struct subsys_attribute sleep_while_idle_attr = { 91static struct kobj_attribute sleep_while_idle_attr =
92 .attr = { 92 __ATTR(sleep_while_idle, 0644, idle_show, idle_store);
93 .name = __stringify(sleep_while_idle),
94 .mode = 0644,
95 },
96 .show = omap_pm_sleep_while_idle_show,
97 .store = omap_pm_sleep_while_idle_store,
98};
99 93
100extern struct kset power_subsys;
101static void (*omap_sram_idle)(void) = NULL; 94static void (*omap_sram_idle)(void) = NULL;
102static void (*omap_sram_suspend)(unsigned long r0, unsigned long r1) = NULL; 95static void (*omap_sram_suspend)(unsigned long r0, unsigned long r1) = NULL;
103 96
@@ -646,7 +639,7 @@ static void omap_pm_finish(void)
646} 639}
647 640
648 641
649static irqreturn_t omap_wakeup_interrupt(int irq, void *dev) 642static irqreturn_t omap_wakeup_interrupt(int irq, void *dev)
650{ 643{
651 return IRQ_HANDLED; 644 return IRQ_HANDLED;
652} 645}
@@ -726,9 +719,9 @@ static int __init omap_pm_init(void)
726 omap_pm_init_proc(); 719 omap_pm_init_proc();
727#endif 720#endif
728 721
729 error = subsys_create_file(&power_subsys, &sleep_while_idle_attr); 722 error = sysfs_create_file(power_kobj, &sleep_while_idle_attr);
730 if (error) 723 if (error)
731 printk(KERN_ERR "subsys_create_file failed: %d\n", error); 724 printk(KERN_ERR "sysfs_create_file failed: %d\n", error);
732 725
733 if (cpu_is_omap16xx()) { 726 if (cpu_is_omap16xx()) {
734 /* configure LOW_PWR pin */ 727 /* configure LOW_PWR pin */
diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
index 7e76fbf19b5d..64235dee5614 100644
--- a/arch/arm/mach-omap2/board-2430sdp.c
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -104,7 +104,7 @@ static struct resource sdp2430_smc91x_resources[] = {
104 [1] = { 104 [1] = {
105 .start = OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ), 105 .start = OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ),
106 .end = OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ), 106 .end = OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ),
107 .flags = IORESOURCE_IRQ, 107 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
108 }, 108 },
109}; 109};
110 110
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
index 3bb49c17c858..7846551f0575 100644
--- a/arch/arm/mach-omap2/board-apollon.c
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -26,7 +26,6 @@
26#include <linux/interrupt.h> 26#include <linux/interrupt.h>
27#include <linux/delay.h> 27#include <linux/delay.h>
28#include <linux/leds.h> 28#include <linux/leds.h>
29#include <linux/irq.h>
30 29
31#include <asm/hardware.h> 30#include <asm/hardware.h>
32#include <asm/mach-types.h> 31#include <asm/mach-types.h>
@@ -127,7 +126,7 @@ static struct resource apollon_smc91x_resources[] = {
127 [1] = { 126 [1] = {
128 .start = OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ), 127 .start = OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ),
129 .end = OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ), 128 .end = OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ),
130 .flags = IORESOURCE_IRQ, 129 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
131 }, 130 },
132}; 131};
133 132
diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c
index 8d322c20ccae..3234deedb946 100644
--- a/arch/arm/mach-omap2/timer-gp.c
+++ b/arch/arm/mach-omap2/timer-gp.c
@@ -40,13 +40,9 @@ static inline void omap2_gp_timer_start(unsigned long load_val)
40 40
41static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id) 41static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id)
42{ 42{
43 write_seqlock(&xtime_lock);
44
45 omap_dm_timer_write_status(gptimer, OMAP_TIMER_INT_OVERFLOW); 43 omap_dm_timer_write_status(gptimer, OMAP_TIMER_INT_OVERFLOW);
46 timer_tick(); 44 timer_tick();
47 45
48 write_sequnlock(&xtime_lock);
49
50 return IRQ_HANDLED; 46 return IRQ_HANDLED;
51} 47}
52 48
diff --git a/arch/arm/mach-orion/Kconfig b/arch/arm/mach-orion/Kconfig
new file mode 100644
index 000000000000..1dcbb6ac5a30
--- /dev/null
+++ b/arch/arm/mach-orion/Kconfig
@@ -0,0 +1,41 @@
1if ARCH_ORION
2
3menu "Orion Implementations"
4
5config MACH_DB88F5281
6 bool "Marvell Orion-2 Development Board"
7 select I2C_BOARDINFO
8 help
9 Say 'Y' here if you want your kernel to support the
10 Marvell Orion-2 (88F5281) Development Board
11
12config MACH_RD88F5182
13 bool "Marvell Orion-NAS Reference Design"
14 select I2C_BOARDINFO
15 help
16 Say 'Y' here if you want your kernel to support the
17 Marvell Orion-NAS (88F5182) RD2
18
19config MACH_KUROBOX_PRO
20 bool "KuroBox Pro"
21 select I2C_BOARDINFO
22 help
23 Say 'Y' here if you want your kernel to support the
24 KuroBox Pro platform.
25
26config MACH_DNS323
27 bool "D-Link DNS-323"
28 select I2C_BOARDINFO
29 help
30 Say 'Y' here if you want your kernel to support the
31 D-Link DNS-323 platform.
32
33config MACH_TS209
34 bool "QNAP TS-109/TS-209"
35 help
36 Say 'Y' here if you want your kernel to support the
37 QNAP TS-109/TS-209 platform.
38
39endmenu
40
41endif
diff --git a/arch/arm/mach-orion/Makefile b/arch/arm/mach-orion/Makefile
new file mode 100644
index 000000000000..f91d937a73e8
--- /dev/null
+++ b/arch/arm/mach-orion/Makefile
@@ -0,0 +1,6 @@
1obj-y += common.o addr-map.o pci.o gpio.o irq.o time.o
2obj-$(CONFIG_MACH_DB88F5281) += db88f5281-setup.o
3obj-$(CONFIG_MACH_RD88F5182) += rd88f5182-setup.o
4obj-$(CONFIG_MACH_KUROBOX_PRO) += kurobox_pro-setup.o
5obj-$(CONFIG_MACH_DNS323) += dns323-setup.o
6obj-$(CONFIG_MACH_TS209) += ts209-setup.o
diff --git a/arch/arm/mach-orion/Makefile.boot b/arch/arm/mach-orion/Makefile.boot
new file mode 100644
index 000000000000..67039c3e0c48
--- /dev/null
+++ b/arch/arm/mach-orion/Makefile.boot
@@ -0,0 +1,3 @@
1 zreladdr-y := 0x00008000
2params_phys-y := 0x00000100
3initrd_phys-y := 0x00800000
diff --git a/arch/arm/mach-orion/addr-map.c b/arch/arm/mach-orion/addr-map.c
new file mode 100644
index 000000000000..488da3811a68
--- /dev/null
+++ b/arch/arm/mach-orion/addr-map.c
@@ -0,0 +1,484 @@
1/*
2 * arch/arm/mach-orion/addr-map.c
3 *
4 * Address map functions for Marvell Orion System On Chip
5 *
6 * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
11 */
12
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <asm/hardware.h>
16#include "common.h"
17
18/*
19 * The Orion has fully programable address map. There's a separate address
20 * map for each of the device _master_ interfaces, e.g. CPU, PCI, PCIE, USB,
21 * Gigabit Ethernet, DMA/XOR engines, etc. Each interface has its own
22 * address decode windows that allow it to access any of the Orion resources.
23 *
24 * CPU address decoding --
25 * Linux assumes that it is the boot loader that already setup the access to
26 * DDR and internal registers.
27 * Setup access to PCI and PCI-E IO/MEM space is issued by core.c.
28 * Setup access to various devices located on the device bus interface (e.g.
29 * flashes, RTC, etc) should be issued by machine-setup.c according to
30 * specific board population (by using orion_setup_cpu_win()).
31 *
32 * Non-CPU Masters address decoding --
33 * Unlike the CPU, we setup the access from Orion's master interfaces to DDR
34 * banks only (the typical use case).
35 * Setup access for each master to DDR is issued by common.c.
36 *
37 * Note: although orion_setbits() and orion_clrbits() are not atomic
38 * no locking is necessary here since code in this file is only called
39 * at boot time when there is no concurrency issues.
40 */
41
42/*
43 * Generic Address Decode Windows bit settings
44 */
45#define TARGET_DDR 0
46#define TARGET_PCI 3
47#define TARGET_PCIE 4
48#define TARGET_DEV_BUS 1
49#define ATTR_DDR_CS(n) (((n) ==0) ? 0xe : \
50 ((n) == 1) ? 0xd : \
51 ((n) == 2) ? 0xb : \
52 ((n) == 3) ? 0x7 : 0xf)
53#define ATTR_PCIE_MEM 0x59
54#define ATTR_PCIE_IO 0x51
55#define ATTR_PCI_MEM 0x59
56#define ATTR_PCI_IO 0x51
57#define ATTR_DEV_CS0 0x1e
58#define ATTR_DEV_CS1 0x1d
59#define ATTR_DEV_CS2 0x1b
60#define ATTR_DEV_BOOT 0xf
61#define WIN_EN 1
62
63/*
64 * Helpers to get DDR banks info
65 */
66#define DDR_BASE_CS(n) ORION_DDR_REG(0x1500 + ((n) * 8))
67#define DDR_SIZE_CS(n) ORION_DDR_REG(0x1504 + ((n) * 8))
68#define DDR_MAX_CS 4
69#define DDR_REG_TO_SIZE(reg) (((reg) | 0xffffff) + 1)
70#define DDR_REG_TO_BASE(reg) ((reg) & 0xff000000)
71#define DDR_BANK_EN 1
72
73/*
74 * CPU Address Decode Windows registers
75 */
76#define CPU_WIN_CTRL(n) ORION_BRIDGE_REG(0x000 | ((n) << 4))
77#define CPU_WIN_BASE(n) ORION_BRIDGE_REG(0x004 | ((n) << 4))
78#define CPU_WIN_REMAP_LO(n) ORION_BRIDGE_REG(0x008 | ((n) << 4))
79#define CPU_WIN_REMAP_HI(n) ORION_BRIDGE_REG(0x00c | ((n) << 4))
80#define CPU_MAX_WIN 8
81
82/*
83 * Use this CPU address decode windows allocation
84 */
85#define CPU_WIN_PCIE_IO 0
86#define CPU_WIN_PCI_IO 1
87#define CPU_WIN_PCIE_MEM 2
88#define CPU_WIN_PCI_MEM 3
89#define CPU_WIN_DEV_BOOT 4
90#define CPU_WIN_DEV_CS0 5
91#define CPU_WIN_DEV_CS1 6
92#define CPU_WIN_DEV_CS2 7
93
94/*
95 * PCIE Address Decode Windows registers
96 */
97#define PCIE_BAR_CTRL(n) ORION_PCIE_REG(0x1804 + ((n - 1) * 4))
98#define PCIE_BAR_LO(n) ORION_PCIE_REG(0x0010 + ((n) * 8))
99#define PCIE_BAR_HI(n) ORION_PCIE_REG(0x0014 + ((n) * 8))
100#define PCIE_WIN_CTRL(n) ORION_PCIE_REG(0x1820 + ((n) << 4))
101#define PCIE_WIN_BASE(n) ORION_PCIE_REG(0x1824 + ((n) << 4))
102#define PCIE_WIN_REMAP(n) ORION_PCIE_REG(0x182c + ((n) << 4))
103#define PCIE_DEFWIN_CTRL ORION_PCIE_REG(0x18b0)
104#define PCIE_EXPROM_WIN_CTRL ORION_PCIE_REG(0x18c0)
105#define PCIE_EXPROM_WIN_REMP ORION_PCIE_REG(0x18c4)
106#define PCIE_MAX_BARS 3
107#define PCIE_MAX_WINS 5
108
109/*
110 * Use PCIE BAR '1' for all DDR banks
111 */
112#define PCIE_DRAM_BAR 1
113
114/*
115 * PCI Address Decode Windows registers
116 */
117#define PCI_BAR_SIZE_DDR_CS(n) (((n) == 0) ? ORION_PCI_REG(0xc08) : \
118 ((n) == 1) ? ORION_PCI_REG(0xd08) : \
119 ((n) == 2) ? ORION_PCI_REG(0xc0c) : \
120 ((n) == 3) ? ORION_PCI_REG(0xd0c) : 0)
121#define PCI_BAR_REMAP_DDR_CS(n) (((n) ==0) ? ORION_PCI_REG(0xc48) : \
122 ((n) == 1) ? ORION_PCI_REG(0xd48) : \
123 ((n) == 2) ? ORION_PCI_REG(0xc4c) : \
124 ((n) == 3) ? ORION_PCI_REG(0xd4c) : 0)
125#define PCI_BAR_ENABLE ORION_PCI_REG(0xc3c)
126#define PCI_CTRL_BASE_LO(n) ORION_PCI_REG(0x1e00 | ((n) << 4))
127#define PCI_CTRL_BASE_HI(n) ORION_PCI_REG(0x1e04 | ((n) << 4))
128#define PCI_CTRL_SIZE(n) ORION_PCI_REG(0x1e08 | ((n) << 4))
129#define PCI_ADDR_DECODE_CTRL ORION_PCI_REG(0xd3c)
130
131/*
132 * PCI configuration heleprs for BAR settings
133 */
134#define PCI_CONF_FUNC_BAR_CS(n) ((n) >> 1)
135#define PCI_CONF_REG_BAR_LO_CS(n) (((n) & 1) ? 0x18 : 0x10)
136#define PCI_CONF_REG_BAR_HI_CS(n) (((n) & 1) ? 0x1c : 0x14)
137
138/*
139 * Gigabit Ethernet Address Decode Windows registers
140 */
141#define ETH_WIN_BASE(win) ORION_ETH_REG(0x200 + ((win) * 8))
142#define ETH_WIN_SIZE(win) ORION_ETH_REG(0x204 + ((win) * 8))
143#define ETH_WIN_REMAP(win) ORION_ETH_REG(0x280 + ((win) * 4))
144#define ETH_WIN_EN ORION_ETH_REG(0x290)
145#define ETH_WIN_PROT ORION_ETH_REG(0x294)
146#define ETH_MAX_WIN 6
147#define ETH_MAX_REMAP_WIN 4
148
149/*
150 * USB Address Decode Windows registers
151 */
152#define USB_WIN_CTRL(i, w) ((i == 0) ? ORION_USB0_REG(0x320 + ((w) << 4)) \
153 : ORION_USB1_REG(0x320 + ((w) << 4)))
154#define USB_WIN_BASE(i, w) ((i == 0) ? ORION_USB0_REG(0x324 + ((w) << 4)) \
155 : ORION_USB1_REG(0x324 + ((w) << 4)))
156#define USB_MAX_WIN 4
157
158/*
159 * SATA Address Decode Windows registers
160 */
161#define SATA_WIN_CTRL(win) ORION_SATA_REG(0x30 + ((win) * 0x10))
162#define SATA_WIN_BASE(win) ORION_SATA_REG(0x34 + ((win) * 0x10))
163#define SATA_MAX_WIN 4
164
165static int __init orion_cpu_win_can_remap(u32 win)
166{
167 u32 dev, rev;
168
169 orion_pcie_id(&dev, &rev);
170 if ((dev == MV88F5281_DEV_ID && win < 4)
171 || (dev == MV88F5182_DEV_ID && win < 2)
172 || (dev == MV88F5181_DEV_ID && win < 2))
173 return 1;
174
175 return 0;
176}
177
178void __init orion_setup_cpu_win(enum orion_target target, u32 base, u32 size, int remap)
179{
180 u32 win, attr, ctrl;
181
182 switch (target) {
183 case ORION_PCIE_IO:
184 target = TARGET_PCIE;
185 attr = ATTR_PCIE_IO;
186 win = CPU_WIN_PCIE_IO;
187 break;
188 case ORION_PCI_IO:
189 target = TARGET_PCI;
190 attr = ATTR_PCI_IO;
191 win = CPU_WIN_PCI_IO;
192 break;
193 case ORION_PCIE_MEM:
194 target = TARGET_PCIE;
195 attr = ATTR_PCIE_MEM;
196 win = CPU_WIN_PCIE_MEM;
197 break;
198 case ORION_PCI_MEM:
199 target = TARGET_PCI;
200 attr = ATTR_PCI_MEM;
201 win = CPU_WIN_PCI_MEM;
202 break;
203 case ORION_DEV_BOOT:
204 target = TARGET_DEV_BUS;
205 attr = ATTR_DEV_BOOT;
206 win = CPU_WIN_DEV_BOOT;
207 break;
208 case ORION_DEV0:
209 target = TARGET_DEV_BUS;
210 attr = ATTR_DEV_CS0;
211 win = CPU_WIN_DEV_CS0;
212 break;
213 case ORION_DEV1:
214 target = TARGET_DEV_BUS;
215 attr = ATTR_DEV_CS1;
216 win = CPU_WIN_DEV_CS1;
217 break;
218 case ORION_DEV2:
219 target = TARGET_DEV_BUS;
220 attr = ATTR_DEV_CS2;
221 win = CPU_WIN_DEV_CS2;
222 break;
223 case ORION_DDR:
224 case ORION_REGS:
225 /*
226 * Must be mapped by bootloader.
227 */
228 default:
229 target = attr = win = -1;
230 BUG();
231 }
232
233 base &= 0xffff0000;
234 ctrl = (((size - 1) & 0xffff0000) | (attr << 8) |
235 (target << 4) | WIN_EN);
236
237 orion_write(CPU_WIN_BASE(win), base);
238 orion_write(CPU_WIN_CTRL(win), ctrl);
239
240 if (orion_cpu_win_can_remap(win)) {
241 if (remap >= 0) {
242 orion_write(CPU_WIN_REMAP_LO(win), remap & 0xffff0000);
243 orion_write(CPU_WIN_REMAP_HI(win), 0);
244 } else {
245 orion_write(CPU_WIN_REMAP_LO(win), base);
246 orion_write(CPU_WIN_REMAP_HI(win), 0);
247 }
248 }
249}
250
251void __init orion_setup_cpu_wins(void)
252{
253 int i;
254
255 /*
256 * First, disable and clear windows
257 */
258 for (i = 0; i < CPU_MAX_WIN; i++) {
259 orion_write(CPU_WIN_BASE(i), 0);
260 orion_write(CPU_WIN_CTRL(i), 0);
261 if (orion_cpu_win_can_remap(i)) {
262 orion_write(CPU_WIN_REMAP_LO(i), 0);
263 orion_write(CPU_WIN_REMAP_HI(i), 0);
264 }
265 }
266
267 /*
268 * Setup windows for PCI+PCIE IO+MAM space
269 */
270 orion_setup_cpu_win(ORION_PCIE_IO, ORION_PCIE_IO_BASE,
271 ORION_PCIE_IO_SIZE, ORION_PCIE_IO_REMAP);
272 orion_setup_cpu_win(ORION_PCI_IO, ORION_PCI_IO_BASE,
273 ORION_PCI_IO_SIZE, ORION_PCI_IO_REMAP);
274 orion_setup_cpu_win(ORION_PCIE_MEM, ORION_PCIE_MEM_BASE,
275 ORION_PCIE_MEM_SIZE, -1);
276 orion_setup_cpu_win(ORION_PCI_MEM, ORION_PCI_MEM_BASE,
277 ORION_PCI_MEM_SIZE, -1);
278}
279
280/*
281 * Setup PCIE BARs and Address Decode Wins:
282 * BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks
283 * WIN[0-3] -> DRAM bank[0-3]
284 */
285void __init orion_setup_pcie_wins(void)
286{
287 u32 base, size, i;
288
289 /*
290 * First, disable and clear BARs and windows
291 */
292 for (i = 1; i < PCIE_MAX_BARS; i++) {
293 orion_write(PCIE_BAR_CTRL(i), 0);
294 orion_write(PCIE_BAR_LO(i), 0);
295 orion_write(PCIE_BAR_HI(i), 0);
296 }
297
298 for (i = 0; i < PCIE_MAX_WINS; i++) {
299 orion_write(PCIE_WIN_CTRL(i), 0);
300 orion_write(PCIE_WIN_BASE(i), 0);
301 orion_write(PCIE_WIN_REMAP(i), 0);
302 }
303
304 /*
305 * Setup windows for DDR banks. Count total DDR size on the fly.
306 */
307 base = DDR_REG_TO_BASE(orion_read(DDR_BASE_CS(0)));
308 size = 0;
309 for (i = 0; i < DDR_MAX_CS; i++) {
310 u32 bank_base, bank_size;
311 bank_size = orion_read(DDR_SIZE_CS(i));
312 bank_base = orion_read(DDR_BASE_CS(i));
313 if (bank_size & DDR_BANK_EN) {
314 bank_size = DDR_REG_TO_SIZE(bank_size);
315 bank_base = DDR_REG_TO_BASE(bank_base);
316 orion_write(PCIE_WIN_BASE(i), bank_base & 0xffff0000);
317 orion_write(PCIE_WIN_REMAP(i), 0);
318 orion_write(PCIE_WIN_CTRL(i),
319 ((bank_size-1) & 0xffff0000) |
320 (ATTR_DDR_CS(i) << 8) |
321 (TARGET_DDR << 4) |
322 (PCIE_DRAM_BAR << 1) | WIN_EN);
323 size += bank_size;
324 }
325 }
326
327 /*
328 * Setup BAR[1] to all DRAM banks
329 */
330 orion_write(PCIE_BAR_LO(PCIE_DRAM_BAR), base & 0xffff0000);
331 orion_write(PCIE_BAR_HI(PCIE_DRAM_BAR), 0);
332 orion_write(PCIE_BAR_CTRL(PCIE_DRAM_BAR),
333 ((size - 1) & 0xffff0000) | WIN_EN);
334}
335
336void __init orion_setup_pci_wins(void)
337{
338 u32 base, size, i;
339
340 /*
341 * First, disable windows
342 */
343 orion_write(PCI_BAR_ENABLE, 0xffffffff);
344
345 /*
346 * Setup windows for DDR banks.
347 */
348 for (i = 0; i < DDR_MAX_CS; i++) {
349 base = orion_read(DDR_BASE_CS(i));
350 size = orion_read(DDR_SIZE_CS(i));
351 if (size & DDR_BANK_EN) {
352 u32 bus, dev, func, reg, val;
353 size = DDR_REG_TO_SIZE(size);
354 base = DDR_REG_TO_BASE(base);
355 bus = orion_pci_local_bus_nr();
356 dev = orion_pci_local_dev_nr();
357 func = PCI_CONF_FUNC_BAR_CS(i);
358 reg = PCI_CONF_REG_BAR_LO_CS(i);
359 orion_pci_hw_rd_conf(bus, dev, func, reg, 4, &val);
360 orion_pci_hw_wr_conf(bus, dev, func, reg, 4,
361 (base & 0xfffff000) | (val & 0xfff));
362 reg = PCI_CONF_REG_BAR_HI_CS(i);
363 orion_pci_hw_wr_conf(bus, dev, func, reg, 4, 0);
364 orion_write(PCI_BAR_SIZE_DDR_CS(i),
365 (size - 1) & 0xfffff000);
366 orion_write(PCI_BAR_REMAP_DDR_CS(i),
367 base & 0xfffff000);
368 orion_clrbits(PCI_BAR_ENABLE, (1 << i));
369 }
370 }
371
372 /*
373 * Disable automatic update of address remaping when writing to BARs
374 */
375 orion_setbits(PCI_ADDR_DECODE_CTRL, 1);
376}
377
378void __init orion_setup_usb_wins(void)
379{
380 int i;
381 u32 usb_if, dev, rev;
382 u32 max_usb_if = 1;
383
384 orion_pcie_id(&dev, &rev);
385 if (dev == MV88F5182_DEV_ID)
386 max_usb_if = 2;
387
388 for (usb_if = 0; usb_if < max_usb_if; usb_if++) {
389 /*
390 * First, disable and clear windows
391 */
392 for (i = 0; i < USB_MAX_WIN; i++) {
393 orion_write(USB_WIN_BASE(usb_if, i), 0);
394 orion_write(USB_WIN_CTRL(usb_if, i), 0);
395 }
396
397 /*
398 * Setup windows for DDR banks.
399 */
400 for (i = 0; i < DDR_MAX_CS; i++) {
401 u32 base, size;
402 size = orion_read(DDR_SIZE_CS(i));
403 base = orion_read(DDR_BASE_CS(i));
404 if (size & DDR_BANK_EN) {
405 base = DDR_REG_TO_BASE(base);
406 size = DDR_REG_TO_SIZE(size);
407 orion_write(USB_WIN_CTRL(usb_if, i),
408 ((size-1) & 0xffff0000) |
409 (ATTR_DDR_CS(i) << 8) |
410 (TARGET_DDR << 4) | WIN_EN);
411 orion_write(USB_WIN_BASE(usb_if, i),
412 base & 0xffff0000);
413 }
414 }
415 }
416}
417
418void __init orion_setup_eth_wins(void)
419{
420 int i;
421
422 /*
423 * First, disable and clear windows
424 */
425 for (i = 0; i < ETH_MAX_WIN; i++) {
426 orion_write(ETH_WIN_BASE(i), 0);
427 orion_write(ETH_WIN_SIZE(i), 0);
428 orion_setbits(ETH_WIN_EN, 1 << i);
429 orion_clrbits(ETH_WIN_PROT, 0x3 << (i * 2));
430 if (i < ETH_MAX_REMAP_WIN)
431 orion_write(ETH_WIN_REMAP(i), 0);
432 }
433
434 /*
435 * Setup windows for DDR banks.
436 */
437 for (i = 0; i < DDR_MAX_CS; i++) {
438 u32 base, size;
439 size = orion_read(DDR_SIZE_CS(i));
440 base = orion_read(DDR_BASE_CS(i));
441 if (size & DDR_BANK_EN) {
442 base = DDR_REG_TO_BASE(base);
443 size = DDR_REG_TO_SIZE(size);
444 orion_write(ETH_WIN_SIZE(i), (size-1) & 0xffff0000);
445 orion_write(ETH_WIN_BASE(i), (base & 0xffff0000) |
446 (ATTR_DDR_CS(i) << 8) |
447 TARGET_DDR);
448 orion_clrbits(ETH_WIN_EN, 1 << i);
449 orion_setbits(ETH_WIN_PROT, 0x3 << (i * 2));
450 }
451 }
452}
453
454void __init orion_setup_sata_wins(void)
455{
456 int i;
457
458 /*
459 * First, disable and clear windows
460 */
461 for (i = 0; i < SATA_MAX_WIN; i++) {
462 orion_write(SATA_WIN_BASE(i), 0);
463 orion_write(SATA_WIN_CTRL(i), 0);
464 }
465
466 /*
467 * Setup windows for DDR banks.
468 */
469 for (i = 0; i < DDR_MAX_CS; i++) {
470 u32 base, size;
471 size = orion_read(DDR_SIZE_CS(i));
472 base = orion_read(DDR_BASE_CS(i));
473 if (size & DDR_BANK_EN) {
474 base = DDR_REG_TO_BASE(base);
475 size = DDR_REG_TO_SIZE(size);
476 orion_write(SATA_WIN_CTRL(i),
477 ((size-1) & 0xffff0000) |
478 (ATTR_DDR_CS(i) << 8) |
479 (TARGET_DDR << 4) | WIN_EN);
480 orion_write(SATA_WIN_BASE(i),
481 base & 0xffff0000);
482 }
483 }
484}
diff --git a/arch/arm/mach-orion/common.c b/arch/arm/mach-orion/common.c
new file mode 100644
index 000000000000..5e20b6b32508
--- /dev/null
+++ b/arch/arm/mach-orion/common.c
@@ -0,0 +1,315 @@
1/*
2 * arch/arm/mach-orion/common.c
3 *
4 * Core functions for Marvell Orion System On Chip
5 *
6 * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
11 */
12
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/platform_device.h>
16#include <linux/serial_8250.h>
17#include <linux/mv643xx_eth.h>
18#include <linux/mv643xx_i2c.h>
19#include <asm/page.h>
20#include <asm/timex.h>
21#include <asm/mach/map.h>
22#include <asm/arch/orion.h>
23#include "common.h"
24
25/*****************************************************************************
26 * I/O Address Mapping
27 ****************************************************************************/
28static struct map_desc orion_io_desc[] __initdata = {
29 {
30 .virtual = ORION_REGS_BASE,
31 .pfn = __phys_to_pfn(ORION_REGS_BASE),
32 .length = ORION_REGS_SIZE,
33 .type = MT_DEVICE
34 },
35 {
36 .virtual = ORION_PCIE_IO_BASE,
37 .pfn = __phys_to_pfn(ORION_PCIE_IO_BASE),
38 .length = ORION_PCIE_IO_SIZE,
39 .type = MT_DEVICE
40 },
41 {
42 .virtual = ORION_PCI_IO_BASE,
43 .pfn = __phys_to_pfn(ORION_PCI_IO_BASE),
44 .length = ORION_PCI_IO_SIZE,
45 .type = MT_DEVICE
46 },
47 {
48 .virtual = ORION_PCIE_WA_BASE,
49 .pfn = __phys_to_pfn(ORION_PCIE_WA_BASE),
50 .length = ORION_PCIE_WA_SIZE,
51 .type = MT_DEVICE
52 },
53};
54
55void __init orion_map_io(void)
56{
57 iotable_init(orion_io_desc, ARRAY_SIZE(orion_io_desc));
58}
59
60/*****************************************************************************
61 * UART
62 ****************************************************************************/
63
64static struct resource orion_uart_resources[] = {
65 {
66 .start = UART0_BASE,
67 .end = UART0_BASE + 0xff,
68 .flags = IORESOURCE_MEM,
69 },
70 {
71 .start = IRQ_ORION_UART0,
72 .end = IRQ_ORION_UART0,
73 .flags = IORESOURCE_IRQ,
74 },
75 {
76 .start = UART1_BASE,
77 .end = UART1_BASE + 0xff,
78 .flags = IORESOURCE_MEM,
79 },
80 {
81 .start = IRQ_ORION_UART1,
82 .end = IRQ_ORION_UART1,
83 .flags = IORESOURCE_IRQ,
84 },
85};
86
87static struct plat_serial8250_port orion_uart_data[] = {
88 {
89 .mapbase = UART0_BASE,
90 .membase = (char *)UART0_BASE,
91 .irq = IRQ_ORION_UART0,
92 .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
93 .iotype = UPIO_MEM,
94 .regshift = 2,
95 .uartclk = ORION_TCLK,
96 },
97 {
98 .mapbase = UART1_BASE,
99 .membase = (char *)UART1_BASE,
100 .irq = IRQ_ORION_UART1,
101 .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
102 .iotype = UPIO_MEM,
103 .regshift = 2,
104 .uartclk = ORION_TCLK,
105 },
106 { },
107};
108
109static struct platform_device orion_uart = {
110 .name = "serial8250",
111 .id = PLAT8250_DEV_PLATFORM,
112 .dev = {
113 .platform_data = orion_uart_data,
114 },
115 .resource = orion_uart_resources,
116 .num_resources = ARRAY_SIZE(orion_uart_resources),
117};
118
119/*******************************************************************************
120 * USB Controller - 2 interfaces
121 ******************************************************************************/
122
123static struct resource orion_ehci0_resources[] = {
124 {
125 .start = ORION_USB0_REG_BASE,
126 .end = ORION_USB0_REG_BASE + SZ_4K,
127 .flags = IORESOURCE_MEM,
128 },
129 {
130 .start = IRQ_ORION_USB0_CTRL,
131 .end = IRQ_ORION_USB0_CTRL,
132 .flags = IORESOURCE_IRQ,
133 },
134};
135
136static struct resource orion_ehci1_resources[] = {
137 {
138 .start = ORION_USB1_REG_BASE,
139 .end = ORION_USB1_REG_BASE + SZ_4K,
140 .flags = IORESOURCE_MEM,
141 },
142 {
143 .start = IRQ_ORION_USB1_CTRL,
144 .end = IRQ_ORION_USB1_CTRL,
145 .flags = IORESOURCE_IRQ,
146 },
147};
148
149static u64 ehci_dmamask = 0xffffffffUL;
150
151static struct platform_device orion_ehci0 = {
152 .name = "orion-ehci",
153 .id = 0,
154 .dev = {
155 .dma_mask = &ehci_dmamask,
156 .coherent_dma_mask = 0xffffffff,
157 },
158 .resource = orion_ehci0_resources,
159 .num_resources = ARRAY_SIZE(orion_ehci0_resources),
160};
161
162static struct platform_device orion_ehci1 = {
163 .name = "orion-ehci",
164 .id = 1,
165 .dev = {
166 .dma_mask = &ehci_dmamask,
167 .coherent_dma_mask = 0xffffffff,
168 },
169 .resource = orion_ehci1_resources,
170 .num_resources = ARRAY_SIZE(orion_ehci1_resources),
171};
172
173/*****************************************************************************
174 * Gigabit Ethernet port
175 * (The Orion and Discovery (MV643xx) families use the same Ethernet driver)
176 ****************************************************************************/
177
178static struct resource orion_eth_shared_resources[] = {
179 {
180 .start = ORION_ETH_REG_BASE,
181 .end = ORION_ETH_REG_BASE + 0xffff,
182 .flags = IORESOURCE_MEM,
183 },
184};
185
186static struct platform_device orion_eth_shared = {
187 .name = MV643XX_ETH_SHARED_NAME,
188 .id = 0,
189 .num_resources = 1,
190 .resource = orion_eth_shared_resources,
191};
192
193static struct resource orion_eth_resources[] = {
194 {
195 .name = "eth irq",
196 .start = IRQ_ORION_ETH_SUM,
197 .end = IRQ_ORION_ETH_SUM,
198 .flags = IORESOURCE_IRQ,
199 }
200};
201
202static struct platform_device orion_eth = {
203 .name = MV643XX_ETH_NAME,
204 .id = 0,
205 .num_resources = 1,
206 .resource = orion_eth_resources,
207};
208
209void __init orion_eth_init(struct mv643xx_eth_platform_data *eth_data)
210{
211 orion_eth.dev.platform_data = eth_data;
212 platform_device_register(&orion_eth_shared);
213 platform_device_register(&orion_eth);
214}
215
216/*****************************************************************************
217 * I2C controller
218 * (The Orion and Discovery (MV643xx) families share the same I2C controller)
219 ****************************************************************************/
220
221static struct mv64xxx_i2c_pdata orion_i2c_pdata = {
222 .freq_m = 8, /* assumes 166 MHz TCLK */
223 .freq_n = 3,
224 .timeout = 1000, /* Default timeout of 1 second */
225};
226
227static struct resource orion_i2c_resources[] = {
228 {
229 .name = "i2c base",
230 .start = I2C_BASE,
231 .end = I2C_BASE + 0x20 -1,
232 .flags = IORESOURCE_MEM,
233 },
234 {
235 .name = "i2c irq",
236 .start = IRQ_ORION_I2C,
237 .end = IRQ_ORION_I2C,
238 .flags = IORESOURCE_IRQ,
239 },
240};
241
242static struct platform_device orion_i2c = {
243 .name = MV64XXX_I2C_CTLR_NAME,
244 .id = 0,
245 .num_resources = ARRAY_SIZE(orion_i2c_resources),
246 .resource = orion_i2c_resources,
247 .dev = {
248 .platform_data = &orion_i2c_pdata,
249 },
250};
251
252/*****************************************************************************
253 * General
254 ****************************************************************************/
255
256/*
257 * Identify device ID and rev from PCIE configuration header space '0'.
258 */
259static void orion_id(u32 *dev, u32 *rev, char **dev_name)
260{
261 orion_pcie_id(dev, rev);
262
263 if (*dev == MV88F5281_DEV_ID) {
264 if (*rev == MV88F5281_REV_D2) {
265 *dev_name = "MV88F5281-D2";
266 } else if (*rev == MV88F5281_REV_D1) {
267 *dev_name = "MV88F5281-D1";
268 } else {
269 *dev_name = "MV88F5281-Rev-Unsupported";
270 }
271 } else if (*dev == MV88F5182_DEV_ID) {
272 if (*rev == MV88F5182_REV_A2) {
273 *dev_name = "MV88F5182-A2";
274 } else {
275 *dev_name = "MV88F5182-Rev-Unsupported";
276 }
277 } else if (*dev == MV88F5181_DEV_ID) {
278 if (*rev == MV88F5181_REV_B1) {
279 *dev_name = "MV88F5181-Rev-B1";
280 } else {
281 *dev_name = "MV88F5181-Rev-Unsupported";
282 }
283 } else {
284 *dev_name = "Device-Unknown";
285 }
286}
287
288void __init orion_init(void)
289{
290 char *dev_name;
291 u32 dev, rev;
292
293 orion_id(&dev, &rev, &dev_name);
294 printk(KERN_INFO "Orion ID: %s. TCLK=%d.\n", dev_name, ORION_TCLK);
295
296 /*
297 * Setup Orion address map
298 */
299 orion_setup_cpu_wins();
300 orion_setup_usb_wins();
301 orion_setup_eth_wins();
302 orion_setup_pci_wins();
303 orion_setup_pcie_wins();
304 if (dev == MV88F5182_DEV_ID)
305 orion_setup_sata_wins();
306
307 /*
308 * REgister devices
309 */
310 platform_device_register(&orion_uart);
311 platform_device_register(&orion_ehci0);
312 if (dev == MV88F5182_DEV_ID)
313 platform_device_register(&orion_ehci1);
314 platform_device_register(&orion_i2c);
315}
diff --git a/arch/arm/mach-orion/common.h b/arch/arm/mach-orion/common.h
new file mode 100644
index 000000000000..06c10c06f03e
--- /dev/null
+++ b/arch/arm/mach-orion/common.h
@@ -0,0 +1,78 @@
1#ifndef __ARCH_ORION_COMMON_H__
2#define __ARCH_ORION_COMMON_H__
3
4/*
5 * Basic Orion init functions used early by machine-setup.
6 */
7
8void __init orion_map_io(void);
9void __init orion_init_irq(void);
10void __init orion_init(void);
11
12/*
13 * Enumerations and functions for Orion windows mapping. Used by Orion core
14 * functions to map its interfaces and by the machine-setup to map its on-
15 * board devices. Details in /mach-orion/addr-map.c
16 */
17
18enum orion_target {
19 ORION_DEV_BOOT = 0,
20 ORION_DEV0,
21 ORION_DEV1,
22 ORION_DEV2,
23 ORION_PCIE_MEM,
24 ORION_PCIE_IO,
25 ORION_PCI_MEM,
26 ORION_PCI_IO,
27 ORION_DDR,
28 ORION_REGS,
29 ORION_MAX_TARGETS
30};
31
32void orion_setup_cpu_win(enum orion_target target, u32 base, u32 size, int remap);
33void orion_setup_cpu_wins(void);
34void orion_setup_eth_wins(void);
35void orion_setup_usb_wins(void);
36void orion_setup_pci_wins(void);
37void orion_setup_pcie_wins(void);
38void orion_setup_sata_wins(void);
39
40/*
41 * Shared code used internally by other Orion core functions.
42 * (/mach-orion/pci.c)
43 */
44
45struct pci_sys_data;
46struct pci_bus;
47
48void orion_pcie_id(u32 *dev, u32 *rev);
49u32 orion_pcie_local_bus_nr(void);
50u32 orion_pci_local_bus_nr(void);
51u32 orion_pci_local_dev_nr(void);
52int orion_pci_sys_setup(int nr, struct pci_sys_data *sys);
53struct pci_bus *orion_pci_sys_scan_bus(int nr, struct pci_sys_data *sys);
54int orion_pci_hw_rd_conf(u32 bus, u32 dev, u32 func, u32 where, u32 size, u32 *val);
55int orion_pci_hw_wr_conf(u32 bus, u32 dev, u32 func, u32 where, u32 size, u32 val);
56
57/*
58 * Valid GPIO pins according to MPP setup, used by machine-setup.
59 * (/mach-orion/gpio.c).
60 */
61
62void __init orion_gpio_set_valid_pins(u32 pins);
63void gpio_display(void); /* debug */
64
65/*
66 * Orion system timer (clocksource + clockevnt, /mach-orion/time.c)
67 */
68extern struct sys_timer orion_timer;
69
70/*
71 * Pull in Orion Ethernet platform_data, used by machine-setup
72 */
73
74struct mv643xx_eth_platform_data;
75
76void __init orion_eth_init(struct mv643xx_eth_platform_data *eth_data);
77
78#endif /* __ARCH_ORION_COMMON_H__ */
diff --git a/arch/arm/mach-orion/db88f5281-setup.c b/arch/arm/mach-orion/db88f5281-setup.c
new file mode 100644
index 000000000000..cb2a95ce5b57
--- /dev/null
+++ b/arch/arm/mach-orion/db88f5281-setup.c
@@ -0,0 +1,364 @@
1/*
2 * arch/arm/mach-orion/db88f5281-setup.c
3 *
4 * Marvell Orion-2 Development Board Setup
5 *
6 * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
11 */
12
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/platform_device.h>
16#include <linux/pci.h>
17#include <linux/irq.h>
18#include <linux/mtd/physmap.h>
19#include <linux/mtd/nand.h>
20#include <linux/timer.h>
21#include <linux/mv643xx_eth.h>
22#include <linux/i2c.h>
23#include <asm/mach-types.h>
24#include <asm/gpio.h>
25#include <asm/mach/arch.h>
26#include <asm/mach/pci.h>
27#include <asm/arch/orion.h>
28#include <asm/arch/platform.h>
29#include "common.h"
30
31/*****************************************************************************
32 * DB-88F5281 on board devices
33 ****************************************************************************/
34
35/*
36 * 512K NOR flash Device bus boot chip select
37 */
38
39#define DB88F5281_NOR_BOOT_BASE 0xf4000000
40#define DB88F5281_NOR_BOOT_SIZE SZ_512K
41
42/*
43 * 7-Segment on Device bus chip select 0
44 */
45
46#define DB88F5281_7SEG_BASE 0xfa000000
47#define DB88F5281_7SEG_SIZE SZ_1K
48
49/*
50 * 32M NOR flash on Device bus chip select 1
51 */
52
53#define DB88F5281_NOR_BASE 0xfc000000
54#define DB88F5281_NOR_SIZE SZ_32M
55
56/*
57 * 32M NAND flash on Device bus chip select 2
58 */
59
60#define DB88F5281_NAND_BASE 0xfa800000
61#define DB88F5281_NAND_SIZE SZ_1K
62
63/*
64 * PCI
65 */
66
67#define DB88F5281_PCI_SLOT0_OFFS 7
68#define DB88F5281_PCI_SLOT0_IRQ_PIN 12
69#define DB88F5281_PCI_SLOT1_SLOT2_IRQ_PIN 13
70
71/*****************************************************************************
72 * 512M NOR Flash on Device bus Boot CS
73 ****************************************************************************/
74
75static struct physmap_flash_data db88f5281_boot_flash_data = {
76 .width = 1, /* 8 bit bus width */
77};
78
79static struct resource db88f5281_boot_flash_resource = {
80 .flags = IORESOURCE_MEM,
81 .start = DB88F5281_NOR_BOOT_BASE,
82 .end = DB88F5281_NOR_BOOT_BASE + DB88F5281_NOR_BOOT_SIZE - 1,
83};
84
85static struct platform_device db88f5281_boot_flash = {
86 .name = "physmap-flash",
87 .id = 0,
88 .dev = {
89 .platform_data = &db88f5281_boot_flash_data,
90 },
91 .num_resources = 1,
92 .resource = &db88f5281_boot_flash_resource,
93};
94
95/*****************************************************************************
96 * 32M NOR Flash on Device bus CS1
97 ****************************************************************************/
98
99static struct physmap_flash_data db88f5281_nor_flash_data = {
100 .width = 4, /* 32 bit bus width */
101};
102
103static struct resource db88f5281_nor_flash_resource = {
104 .flags = IORESOURCE_MEM,
105 .start = DB88F5281_NOR_BASE,
106 .end = DB88F5281_NOR_BASE + DB88F5281_NOR_SIZE - 1,
107};
108
109static struct platform_device db88f5281_nor_flash = {
110 .name = "physmap-flash",
111 .id = 1,
112 .dev = {
113 .platform_data = &db88f5281_nor_flash_data,
114 },
115 .num_resources = 1,
116 .resource = &db88f5281_nor_flash_resource,
117};
118
119/*****************************************************************************
120 * 32M NAND Flash on Device bus CS2
121 ****************************************************************************/
122
123static struct mtd_partition db88f5281_nand_parts[] = {
124 {
125 .name = "kernel",
126 .offset = 0,
127 .size = SZ_2M,
128 },
129 {
130 .name = "root",
131 .offset = SZ_2M,
132 .size = (SZ_16M - SZ_2M),
133 },
134 {
135 .name = "user",
136 .offset = SZ_16M,
137 .size = SZ_8M,
138 },
139 {
140 .name = "recovery",
141 .offset = (SZ_16M + SZ_8M),
142 .size = SZ_8M,
143 },
144};
145
146static struct resource db88f5281_nand_resource = {
147 .flags = IORESOURCE_MEM,
148 .start = DB88F5281_NAND_BASE,
149 .end = DB88F5281_NAND_BASE + DB88F5281_NAND_SIZE - 1,
150};
151
152static struct orion_nand_data db88f5281_nand_data = {
153 .parts = db88f5281_nand_parts,
154 .nr_parts = ARRAY_SIZE(db88f5281_nand_parts),
155 .cle = 0,
156 .ale = 1,
157 .width = 8,
158};
159
160static struct platform_device db88f5281_nand_flash = {
161 .name = "orion_nand",
162 .id = -1,
163 .dev = {
164 .platform_data = &db88f5281_nand_data,
165 },
166 .resource = &db88f5281_nand_resource,
167 .num_resources = 1,
168};
169
170/*****************************************************************************
171 * 7-Segment on Device bus CS0
172 * Dummy counter every 2 sec
173 ****************************************************************************/
174
175static void __iomem *db88f5281_7seg;
176static struct timer_list db88f5281_timer;
177
178static void db88f5281_7seg_event(unsigned long data)
179{
180 static int count = 0;
181 writel(0, db88f5281_7seg + (count << 4));
182 count = (count + 1) & 7;
183 mod_timer(&db88f5281_timer, jiffies + 2 * HZ);
184}
185
186static int __init db88f5281_7seg_init(void)
187{
188 if (machine_is_db88f5281()) {
189 db88f5281_7seg = ioremap(DB88F5281_7SEG_BASE,
190 DB88F5281_7SEG_SIZE);
191 if (!db88f5281_7seg) {
192 printk(KERN_ERR "Failed to ioremap db88f5281_7seg\n");
193 return -EIO;
194 }
195 setup_timer(&db88f5281_timer, db88f5281_7seg_event, 0);
196 mod_timer(&db88f5281_timer, jiffies + 2 * HZ);
197 }
198
199 return 0;
200}
201
202__initcall(db88f5281_7seg_init);
203
204/*****************************************************************************
205 * PCI
206 ****************************************************************************/
207
208void __init db88f5281_pci_preinit(void)
209{
210 int pin;
211
212 /*
213 * Configure PCI GPIO IRQ pins
214 */
215 pin = DB88F5281_PCI_SLOT0_IRQ_PIN;
216 if (gpio_request(pin, "PCI Int1") == 0) {
217 if (gpio_direction_input(pin) == 0) {
218 set_irq_type(gpio_to_irq(pin), IRQT_LOW);
219 } else {
220 printk(KERN_ERR "db88f5281_pci_preinit faield to "
221 "set_irq_type pin %d\n", pin);
222 gpio_free(pin);
223 }
224 } else {
225 printk(KERN_ERR "db88f5281_pci_preinit failed to gpio_request %d\n", pin);
226 }
227
228 pin = DB88F5281_PCI_SLOT1_SLOT2_IRQ_PIN;
229 if (gpio_request(pin, "PCI Int2") == 0) {
230 if (gpio_direction_input(pin) == 0) {
231 set_irq_type(gpio_to_irq(pin), IRQT_LOW);
232 } else {
233 printk(KERN_ERR "db88f5281_pci_preinit faield "
234 "to set_irq_type pin %d\n", pin);
235 gpio_free(pin);
236 }
237 } else {
238 printk(KERN_ERR "db88f5281_pci_preinit failed to gpio_request %d\n", pin);
239 }
240}
241
242static int __init db88f5281_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
243{
244 /*
245 * PCIE IRQ is connected internally (not GPIO)
246 */
247 if (dev->bus->number == orion_pcie_local_bus_nr())
248 return IRQ_ORION_PCIE0_INT;
249
250 /*
251 * PCI IRQs are connected via GPIOs
252 */
253 switch (slot - DB88F5281_PCI_SLOT0_OFFS) {
254 case 0:
255 return gpio_to_irq(DB88F5281_PCI_SLOT0_IRQ_PIN);
256 case 1:
257 case 2:
258 return gpio_to_irq(DB88F5281_PCI_SLOT1_SLOT2_IRQ_PIN);
259 default:
260 return -1;
261 }
262}
263
264static struct hw_pci db88f5281_pci __initdata = {
265 .nr_controllers = 2,
266 .preinit = db88f5281_pci_preinit,
267 .swizzle = pci_std_swizzle,
268 .setup = orion_pci_sys_setup,
269 .scan = orion_pci_sys_scan_bus,
270 .map_irq = db88f5281_pci_map_irq,
271};
272
273static int __init db88f5281_pci_init(void)
274{
275 if (machine_is_db88f5281())
276 pci_common_init(&db88f5281_pci);
277
278 return 0;
279}
280
281subsys_initcall(db88f5281_pci_init);
282
283/*****************************************************************************
284 * Ethernet
285 ****************************************************************************/
286static struct mv643xx_eth_platform_data db88f5281_eth_data = {
287 .phy_addr = 8,
288 .force_phy_addr = 1,
289};
290
291/*****************************************************************************
292 * RTC DS1339 on I2C bus
293 ****************************************************************************/
294static struct i2c_board_info __initdata db88f5281_i2c_rtc = {
295 .driver_name = "rtc-ds1307",
296 .type = "ds1339",
297 .addr = 0x68,
298};
299
300/*****************************************************************************
301 * General Setup
302 ****************************************************************************/
303
304static struct platform_device *db88f5281_devs[] __initdata = {
305 &db88f5281_boot_flash,
306 &db88f5281_nor_flash,
307 &db88f5281_nand_flash,
308};
309
310static void __init db88f5281_init(void)
311{
312 /*
313 * Basic Orion setup. Need to be called early.
314 */
315 orion_init();
316
317 /*
318 * Setup the CPU address decode windows for our on-board devices
319 */
320 orion_setup_cpu_win(ORION_DEV_BOOT, DB88F5281_NOR_BOOT_BASE,
321 DB88F5281_NOR_BOOT_SIZE, -1);
322 orion_setup_cpu_win(ORION_DEV0, DB88F5281_7SEG_BASE,
323 DB88F5281_7SEG_SIZE, -1);
324 orion_setup_cpu_win(ORION_DEV1, DB88F5281_NOR_BASE,
325 DB88F5281_NOR_SIZE, -1);
326 orion_setup_cpu_win(ORION_DEV2, DB88F5281_NAND_BASE,
327 DB88F5281_NAND_SIZE, -1);
328
329 /*
330 * Setup Multiplexing Pins:
331 * MPP0: GPIO (USB Over Current) MPP1: GPIO (USB Vbat input)
332 * MPP2: PCI_REQn[2] MPP3: PCI_GNTn[2]
333 * MPP4: PCI_REQn[3] MPP5: PCI_GNTn[3]
334 * MPP6: GPIO (JP0, CON17.2) MPP7: GPIO (JP1, CON17.1)
335 * MPP8: GPIO (JP2, CON11.2) MPP9: GPIO (JP3, CON11.3)
336 * MPP10: GPIO (RTC int) MPP11: GPIO (Baud Rate Generator)
337 * MPP12: GPIO (PCI int 1) MPP13: GPIO (PCI int 2)
338 * MPP14: NAND_REn[2] MPP15: NAND_WEn[2]
339 * MPP16: UART1_RX MPP17: UART1_TX
340 * MPP18: UART1_CTS MPP19: UART1_RTS
341 * MPP-DEV: DEV_D[16:31]
342 */
343 orion_write(MPP_0_7_CTRL, 0x00222203);
344 orion_write(MPP_8_15_CTRL, 0x44000000);
345 orion_write(MPP_16_19_CTRL, 0);
346 orion_write(MPP_DEV_CTRL, 0);
347
348 orion_gpio_set_valid_pins(0x00003fc3);
349
350 platform_add_devices(db88f5281_devs, ARRAY_SIZE(db88f5281_devs));
351 i2c_register_board_info(0, &db88f5281_i2c_rtc, 1);
352 orion_eth_init(&db88f5281_eth_data);
353}
354
355MACHINE_START(DB88F5281, "Marvell Orion-2 Development Board")
356 /* Maintainer: Tzachi Perelstein <tzachi@marvell.com> */
357 .phys_io = ORION_REGS_BASE,
358 .io_pg_offst = ((ORION_REGS_BASE) >> 18) & 0xfffc,
359 .boot_params = 0x00000100,
360 .init_machine = db88f5281_init,
361 .map_io = orion_map_io,
362 .init_irq = orion_init_irq,
363 .timer = &orion_timer,
364MACHINE_END
diff --git a/arch/arm/mach-orion/dns323-setup.c b/arch/arm/mach-orion/dns323-setup.c
new file mode 100644
index 000000000000..c8a806f249c6
--- /dev/null
+++ b/arch/arm/mach-orion/dns323-setup.c
@@ -0,0 +1,322 @@
1/*
2 * arch/arm/mach-orion/dns323-setup.c
3 *
4 * Copyright (C) 2007 Herbert Valerio Riedel <hvr@gnu.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
10 *
11 */
12
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/platform_device.h>
16#include <linux/pci.h>
17#include <linux/irq.h>
18#include <linux/mtd/physmap.h>
19#include <linux/mv643xx_eth.h>
20#include <linux/leds.h>
21#include <linux/gpio_keys.h>
22#include <linux/input.h>
23#include <linux/i2c.h>
24#include <asm/mach-types.h>
25#include <asm/gpio.h>
26#include <asm/mach/arch.h>
27#include <asm/mach/pci.h>
28#include <asm/arch/orion.h>
29#include <asm/arch/platform.h>
30#include "common.h"
31
32#define DNS323_GPIO_LED_RIGHT_AMBER 1
33#define DNS323_GPIO_LED_LEFT_AMBER 2
34#define DNS323_GPIO_LED_POWER 5
35#define DNS323_GPIO_OVERTEMP 6
36#define DNS323_GPIO_RTC 7
37#define DNS323_GPIO_POWER_OFF 8
38#define DNS323_GPIO_KEY_POWER 9
39#define DNS323_GPIO_KEY_RESET 10
40
41/****************************************************************************
42 * PCI setup
43 */
44
45static int __init dns323_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
46{
47 /* PCI-E */
48 if (dev->bus->number == orion_pcie_local_bus_nr())
49 return IRQ_ORION_PCIE0_INT;
50
51 pr_err("%s: requested mapping for unknown bus\n", __func__);
52
53 return -1;
54}
55
56static struct hw_pci dns323_pci __initdata = {
57 .nr_controllers = 1,
58 .swizzle = pci_std_swizzle,
59 .setup = orion_pci_sys_setup,
60 .scan = orion_pci_sys_scan_bus,
61 .map_irq = dns323_pci_map_irq,
62};
63
64static int __init dns323_pci_init(void)
65{
66 if (machine_is_dns323())
67 pci_common_init(&dns323_pci);
68
69 return 0;
70}
71
72subsys_initcall(dns323_pci_init);
73
74/****************************************************************************
75 * Ethernet
76 */
77
78static struct mv643xx_eth_platform_data dns323_eth_data = {
79 .phy_addr = 8,
80 .force_phy_addr = 1,
81};
82
83/****************************************************************************
84 * 8MiB NOR flash (Spansion S29GL064M90TFIR4)
85 *
86 * Layout as used by D-Link:
87 * 0x00000000-0x00010000 : "MTD1"
88 * 0x00010000-0x00020000 : "MTD2"
89 * 0x00020000-0x001a0000 : "Linux Kernel"
90 * 0x001a0000-0x007d0000 : "File System"
91 * 0x007d0000-0x00800000 : "u-boot"
92 */
93
94#define DNS323_NOR_BOOT_BASE 0xf4000000
95#define DNS323_NOR_BOOT_SIZE SZ_8M
96
97static struct mtd_partition dns323_partitions[] = {
98 {
99 .name = "MTD1",
100 .size = 0x00010000,
101 .offset = 0,
102 }, {
103 .name = "MTD2",
104 .size = 0x00010000,
105 .offset = 0x00010000,
106 }, {
107 .name = "Linux Kernel",
108 .size = 0x00180000,
109 .offset = 0x00020000,
110 }, {
111 .name = "File System",
112 .size = 0x00630000,
113 .offset = 0x001A0000,
114 }, {
115 .name = "u-boot",
116 .size = 0x00030000,
117 .offset = 0x007d0000,
118 }
119};
120
121static struct physmap_flash_data dns323_nor_flash_data = {
122 .width = 1,
123 .parts = dns323_partitions,
124 .nr_parts = ARRAY_SIZE(dns323_partitions)
125};
126
127static struct resource dns323_nor_flash_resource = {
128 .flags = IORESOURCE_MEM,
129 .start = DNS323_NOR_BOOT_BASE,
130 .end = DNS323_NOR_BOOT_BASE + DNS323_NOR_BOOT_SIZE - 1,
131};
132
133static struct platform_device dns323_nor_flash = {
134 .name = "physmap-flash",
135 .id = 0,
136 .dev = { .platform_data = &dns323_nor_flash_data, },
137 .resource = &dns323_nor_flash_resource,
138 .num_resources = 1,
139};
140
141/****************************************************************************
142 * GPIO LEDs (simple - doesn't use hardware blinking support)
143 */
144
145static struct gpio_led dns323_leds[] = {
146 {
147 .name = "power:blue",
148 .gpio = DNS323_GPIO_LED_POWER,
149 .active_low = 1,
150 }, {
151 .name = "right:amber",
152 .gpio = DNS323_GPIO_LED_RIGHT_AMBER,
153 .active_low = 1,
154 }, {
155 .name = "left:amber",
156 .gpio = DNS323_GPIO_LED_LEFT_AMBER,
157 .active_low = 1,
158 },
159};
160
161static struct gpio_led_platform_data dns323_led_data = {
162 .num_leds = ARRAY_SIZE(dns323_leds),
163 .leds = dns323_leds,
164};
165
166static struct platform_device dns323_gpio_leds = {
167 .name = "leds-gpio",
168 .id = -1,
169 .dev = { .platform_data = &dns323_led_data, },
170};
171
172/****************************************************************************
173 * GPIO Attached Keys
174 */
175
176static struct gpio_keys_button dns323_buttons[] = {
177 {
178 .code = KEY_RESTART,
179 .gpio = DNS323_GPIO_KEY_RESET,
180 .desc = "Reset Button",
181 .active_low = 1,
182 },
183 {
184 .code = KEY_POWER,
185 .gpio = DNS323_GPIO_KEY_POWER,
186 .desc = "Power Button",
187 .active_low = 1,
188 }
189};
190
191static struct gpio_keys_platform_data dns323_button_data = {
192 .buttons = dns323_buttons,
193 .nbuttons = ARRAY_SIZE(dns323_buttons),
194};
195
196static struct platform_device dns323_button_device = {
197 .name = "gpio-keys",
198 .id = -1,
199 .num_resources = 0,
200 .dev = { .platform_data = &dns323_button_data, },
201};
202
203/****************************************************************************
204 * General Setup
205 */
206
207static struct platform_device *dns323_plat_devices[] __initdata = {
208 &dns323_nor_flash,
209 &dns323_gpio_leds,
210 &dns323_button_device,
211};
212
213/*
214 * On the DNS-323 the following devices are attached via I2C:
215 *
216 * i2c addr | chip | description
217 * 0x3e | GMT G760Af | fan speed PWM controller
218 * 0x48 | GMT G751-2f | temp. sensor and therm. watchdog (LM75 compatible)
219 * 0x68 | ST M41T80 | RTC w/ alarm
220 */
221static struct i2c_board_info __initdata dns323_i2c_devices[] = {
222 {
223 I2C_BOARD_INFO("g760a", 0x3e),
224 .type = "g760a",
225 },
226#if 0
227 /* this entry requires the new-style driver model lm75 driver,
228 * for the meantime "insmod lm75.ko force_lm75=0,0x48" is needed */
229 {
230 I2C_BOARD_INFO("lm75", 0x48),
231 .type = "g751",
232 },
233#endif
234 {
235 I2C_BOARD_INFO("rtc-m41t80", 0x68),
236 .type = "m41t80",
237 }
238};
239
240/* DNS-323 specific power off method */
241static void dns323_power_off(void)
242{
243 pr_info("%s: triggering power-off...\n", __func__);
244 gpio_set_value(DNS323_GPIO_POWER_OFF, 1);
245}
246
247static void __init dns323_init(void)
248{
249 /* Setup basic Orion functions. Need to be called early. */
250 orion_init();
251
252 /* setup flash mapping
253 * CS3 holds a 8 MB Spansion S29GL064M90TFIR4
254 */
255 orion_setup_cpu_win(ORION_DEV_BOOT, DNS323_NOR_BOOT_BASE,
256 DNS323_NOR_BOOT_SIZE, -1);
257
258 /* DNS-323 has a Marvell 88X7042 SATA controller attached via PCIE
259 *
260 * Open a special address decode windows for the PCIE WA.
261 */
262 orion_write(ORION_REGS_BASE | 0x20074, ORION_PCIE_WA_BASE);
263 orion_write(ORION_REGS_BASE | 0x20070,
264 (0x7941 | (((ORION_PCIE_WA_SIZE >> 16) - 1)) << 16));
265
266 /* set MPP to 0 as D-Link's 2.6.12.6 kernel did */
267 orion_write(MPP_0_7_CTRL, 0);
268 orion_write(MPP_8_15_CTRL, 0);
269 orion_write(MPP_16_19_CTRL, 0);
270 orion_write(MPP_DEV_CTRL, 0);
271
272 /* Define used GPIO pins
273
274 GPIO Map:
275
276 | 0 | | PEX_RST_OUT (not controlled by GPIO)
277 | 1 | Out | right amber LED (= sata ch0 LED) (low-active)
278 | 2 | Out | left amber LED (= sata ch1 LED) (low-active)
279 | 3 | Out | //unknown//
280 | 4 | Out | power button LED (low-active, together with pin #5)
281 | 5 | Out | power button LED (low-active, together with pin #4)
282 | 6 | In | GMT G751-2f overtemp. shutdown signal (low-active)
283 | 7 | In | M41T80 nIRQ/OUT/SQW signal
284 | 8 | Out | triggers power off (high-active)
285 | 9 | In | power button switch (low-active)
286 | 10 | In | reset button switch (low-active)
287 | 11 | Out | //unknown//
288 | 12 | Out | //unknown//
289 | 13 | Out | //unknown//
290 | 14 | Out | //unknown//
291 | 15 | Out | //unknown//
292 */
293 orion_gpio_set_valid_pins(0x07f6);
294
295 /* register dns323 specific power-off method */
296 if ((gpio_request(DNS323_GPIO_POWER_OFF, "POWEROFF") != 0)
297 || (gpio_direction_output(DNS323_GPIO_POWER_OFF, 0) != 0))
298 pr_err("DNS323: failed to setup power-off GPIO\n");
299
300 pm_power_off = dns323_power_off;
301
302 /* register flash and other platform devices */
303 platform_add_devices(dns323_plat_devices,
304 ARRAY_SIZE(dns323_plat_devices));
305
306 i2c_register_board_info(0, dns323_i2c_devices,
307 ARRAY_SIZE(dns323_i2c_devices));
308
309 orion_eth_init(&dns323_eth_data);
310}
311
312/* Warning: D-Link uses a wrong mach-type (=526) in their bootloader */
313MACHINE_START(DNS323, "D-Link DNS-323")
314 /* Maintainer: Herbert Valerio Riedel <hvr@gnu.org> */
315 .phys_io = ORION_REGS_BASE,
316 .io_pg_offst = ((ORION_REGS_BASE) >> 18) & 0xFFFC,
317 .boot_params = 0x00000100,
318 .init_machine = dns323_init,
319 .map_io = orion_map_io,
320 .init_irq = orion_init_irq,
321 .timer = &orion_timer,
322MACHINE_END
diff --git a/arch/arm/mach-orion/gpio.c b/arch/arm/mach-orion/gpio.c
new file mode 100644
index 000000000000..d5f00c86d616
--- /dev/null
+++ b/arch/arm/mach-orion/gpio.c
@@ -0,0 +1,225 @@
1/*
2 * arch/arm/mach-orion/gpio.c
3 *
4 * GPIO functions for Marvell Orion System On Chip
5 *
6 * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
11 */
12
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/spinlock.h>
17#include <linux/bitops.h>
18#include <asm/gpio.h>
19#include <asm/arch/orion.h>
20#include "common.h"
21
22static DEFINE_SPINLOCK(gpio_lock);
23static unsigned long gpio_valid[BITS_TO_LONGS(GPIO_MAX)];
24static const char *gpio_label[GPIO_MAX]; /* non null for allocated GPIOs */
25
26void __init orion_gpio_set_valid_pins(u32 pins)
27{
28 gpio_valid[0] = pins;
29}
30
31/*
32 * GENERIC_GPIO primitives
33 */
34int gpio_direction_input(unsigned pin)
35{
36 unsigned long flags;
37
38 if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) {
39 pr_debug("%s: invalid GPIO %d\n", __FUNCTION__, pin);
40 return -EINVAL;
41 }
42
43 spin_lock_irqsave(&gpio_lock, flags);
44
45 /*
46 * Some callers might have not used the gpio_request(),
47 * so flag this pin as requested now.
48 */
49 if (!gpio_label[pin])
50 gpio_label[pin] = "?";
51
52 orion_setbits(GPIO_IO_CONF, 1 << pin);
53
54 spin_unlock_irqrestore(&gpio_lock, flags);
55 return 0;
56}
57EXPORT_SYMBOL(gpio_direction_input);
58
59int gpio_direction_output(unsigned pin, int value)
60{
61 unsigned long flags;
62 int mask;
63
64 if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) {
65 pr_debug("%s: invalid GPIO %d\n", __FUNCTION__, pin);
66 return -EINVAL;
67 }
68
69 spin_lock_irqsave(&gpio_lock, flags);
70
71 /*
72 * Some callers might have not used the gpio_request(),
73 * so flag this pin as requested now.
74 */
75 if (!gpio_label[pin])
76 gpio_label[pin] = "?";
77
78 mask = 1 << pin;
79 orion_clrbits(GPIO_BLINK_EN, mask);
80 if (value)
81 orion_setbits(GPIO_OUT, mask);
82 else
83 orion_clrbits(GPIO_OUT, mask);
84 orion_clrbits(GPIO_IO_CONF, mask);
85
86 spin_unlock_irqrestore(&gpio_lock, flags);
87 return 0;
88}
89EXPORT_SYMBOL(gpio_direction_output);
90
91int gpio_get_value(unsigned pin)
92{
93 int val, mask = 1 << pin;
94
95 if (orion_read(GPIO_IO_CONF) & mask)
96 val = orion_read(GPIO_DATA_IN) ^ orion_read(GPIO_IN_POL);
97 else
98 val = orion_read(GPIO_OUT);
99
100 return val & mask;
101}
102EXPORT_SYMBOL(gpio_get_value);
103
104void gpio_set_value(unsigned pin, int value)
105{
106 unsigned long flags;
107 int mask = 1 << pin;
108
109 spin_lock_irqsave(&gpio_lock, flags);
110
111 orion_clrbits(GPIO_BLINK_EN, mask);
112 if (value)
113 orion_setbits(GPIO_OUT, mask);
114 else
115 orion_clrbits(GPIO_OUT, mask);
116
117 spin_unlock_irqrestore(&gpio_lock, flags);
118}
119EXPORT_SYMBOL(gpio_set_value);
120
121void orion_gpio_set_blink(unsigned pin, int blink)
122{
123 unsigned long flags;
124 int mask = 1 << pin;
125
126 spin_lock_irqsave(&gpio_lock, flags);
127
128 orion_clrbits(GPIO_OUT, mask);
129 if (blink)
130 orion_setbits(GPIO_BLINK_EN, mask);
131 else
132 orion_clrbits(GPIO_BLINK_EN, mask);
133
134 spin_unlock_irqrestore(&gpio_lock, flags);
135}
136EXPORT_SYMBOL(orion_gpio_set_blink);
137
138int gpio_request(unsigned pin, const char *label)
139{
140 int ret = 0;
141 unsigned long flags;
142
143 if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) {
144 pr_debug("%s: invalid GPIO %d\n", __FUNCTION__, pin);
145 return -EINVAL;
146 }
147
148 spin_lock_irqsave(&gpio_lock, flags);
149
150 if (gpio_label[pin]) {
151 pr_debug("%s: GPIO %d already used as %s\n",
152 __FUNCTION__, pin, gpio_label[pin]);
153 ret = -EBUSY;
154 } else
155 gpio_label[pin] = label ? label : "?";
156
157 spin_unlock_irqrestore(&gpio_lock, flags);
158 return ret;
159}
160EXPORT_SYMBOL(gpio_request);
161
162void gpio_free(unsigned pin)
163{
164 if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) {
165 pr_debug("%s: invalid GPIO %d\n", __FUNCTION__, pin);
166 return;
167 }
168
169 if (!gpio_label[pin])
170 pr_warning("%s: GPIO %d already freed\n", __FUNCTION__, pin);
171 else
172 gpio_label[pin] = NULL;
173}
174EXPORT_SYMBOL(gpio_free);
175
176/* Debug helper */
177void gpio_display(void)
178{
179 int i;
180
181 for (i = 0; i < GPIO_MAX; i++) {
182 printk(KERN_DEBUG "Pin-%d: ", i);
183
184 if (!test_bit(i, gpio_valid)) {
185 printk("non-GPIO\n");
186 } else if (!gpio_label[i]) {
187 printk("GPIO, free\n");
188 } else {
189 printk("GPIO, used by %s, ", gpio_label[i]);
190 if (orion_read(GPIO_IO_CONF) & (1 << i)) {
191 printk("input, active %s, level %s, edge %s\n",
192 ((orion_read(GPIO_IN_POL) >> i) & 1) ? "low" : "high",
193 ((orion_read(GPIO_LEVEL_MASK) >> i) & 1) ? "enabled" : "masked",
194 ((orion_read(GPIO_EDGE_MASK) >> i) & 1) ? "enabled" : "masked");
195 } else {
196 printk("output, val=%d\n", (orion_read(GPIO_OUT) >> i) & 1);
197 }
198 }
199 }
200
201 printk(KERN_DEBUG "MPP_0_7_CTRL (0x%08x) = 0x%08x\n",
202 MPP_0_7_CTRL, orion_read(MPP_0_7_CTRL));
203 printk(KERN_DEBUG "MPP_8_15_CTRL (0x%08x) = 0x%08x\n",
204 MPP_8_15_CTRL, orion_read(MPP_8_15_CTRL));
205 printk(KERN_DEBUG "MPP_16_19_CTRL (0x%08x) = 0x%08x\n",
206 MPP_16_19_CTRL, orion_read(MPP_16_19_CTRL));
207 printk(KERN_DEBUG "MPP_DEV_CTRL (0x%08x) = 0x%08x\n",
208 MPP_DEV_CTRL, orion_read(MPP_DEV_CTRL));
209 printk(KERN_DEBUG "GPIO_OUT (0x%08x) = 0x%08x\n",
210 GPIO_OUT, orion_read(GPIO_OUT));
211 printk(KERN_DEBUG "GPIO_IO_CONF (0x%08x) = 0x%08x\n",
212 GPIO_IO_CONF, orion_read(GPIO_IO_CONF));
213 printk(KERN_DEBUG "GPIO_BLINK_EN (0x%08x) = 0x%08x\n",
214 GPIO_BLINK_EN, orion_read(GPIO_BLINK_EN));
215 printk(KERN_DEBUG "GPIO_IN_POL (0x%08x) = 0x%08x\n",
216 GPIO_IN_POL, orion_read(GPIO_IN_POL));
217 printk(KERN_DEBUG "GPIO_DATA_IN (0x%08x) = 0x%08x\n",
218 GPIO_DATA_IN, orion_read(GPIO_DATA_IN));
219 printk(KERN_DEBUG "GPIO_LEVEL_MASK (0x%08x) = 0x%08x\n",
220 GPIO_LEVEL_MASK, orion_read(GPIO_LEVEL_MASK));
221 printk(KERN_DEBUG "GPIO_EDGE_CAUSE (0x%08x) = 0x%08x\n",
222 GPIO_EDGE_CAUSE, orion_read(GPIO_EDGE_CAUSE));
223 printk(KERN_DEBUG "GPIO_EDGE_MASK (0x%08x) = 0x%08x\n",
224 GPIO_EDGE_MASK, orion_read(GPIO_EDGE_MASK));
225}
diff --git a/arch/arm/mach-orion/irq.c b/arch/arm/mach-orion/irq.c
new file mode 100644
index 000000000000..df7e12ad378b
--- /dev/null
+++ b/arch/arm/mach-orion/irq.c
@@ -0,0 +1,241 @@
1/*
2 * arch/arm/mach-orion/irq.c
3 *
4 * Core IRQ functions for Marvell Orion System On Chip
5 *
6 * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
11 */
12
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/irq.h>
16#include <asm/gpio.h>
17#include <asm/arch/orion.h>
18#include "common.h"
19
20/*****************************************************************************
21 * Orion GPIO IRQ
22 *
23 * GPIO_IN_POL register controlls whether GPIO_DATA_IN will hold the same
24 * value of the line or the opposite value.
25 *
26 * Level IRQ handlers: DATA_IN is used directly as cause register.
27 * Interrupt are masked by LEVEL_MASK registers.
28 * Edge IRQ handlers: Change in DATA_IN are latched in EDGE_CAUSE.
29 * Interrupt are masked by EDGE_MASK registers.
30 * Both-edge handlers: Similar to regular Edge handlers, but also swaps
31 * the polarity to catch the next line transaction.
32 * This is a race condition that might not perfectly
33 * work on some use cases.
34 *
35 * Every eight GPIO lines are grouped (OR'ed) before going up to main
36 * cause register.
37 *
38 * EDGE cause mask
39 * data-in /--------| |-----| |----\
40 * -----| |----- ---- to main cause reg
41 * X \----------------| |----/
42 * polarity LEVEL mask
43 *
44 ****************************************************************************/
45static void orion_gpio_irq_ack(u32 irq)
46{
47 int pin = irq_to_gpio(irq);
48 if (irq_desc[irq].status & IRQ_LEVEL)
49 /*
50 * Mask bit for level interrupt
51 */
52 orion_clrbits(GPIO_LEVEL_MASK, 1 << pin);
53 else
54 /*
55 * Clear casue bit for egde interrupt
56 */
57 orion_clrbits(GPIO_EDGE_CAUSE, 1 << pin);
58}
59
60static void orion_gpio_irq_mask(u32 irq)
61{
62 int pin = irq_to_gpio(irq);
63 if (irq_desc[irq].status & IRQ_LEVEL)
64 orion_clrbits(GPIO_LEVEL_MASK, 1 << pin);
65 else
66 orion_clrbits(GPIO_EDGE_MASK, 1 << pin);
67}
68
69static void orion_gpio_irq_unmask(u32 irq)
70{
71 int pin = irq_to_gpio(irq);
72 if (irq_desc[irq].status & IRQ_LEVEL)
73 orion_setbits(GPIO_LEVEL_MASK, 1 << pin);
74 else
75 orion_setbits(GPIO_EDGE_MASK, 1 << pin);
76}
77
78static int orion_gpio_set_irq_type(u32 irq, u32 type)
79{
80 int pin = irq_to_gpio(irq);
81 struct irq_desc *desc;
82
83 if ((orion_read(GPIO_IO_CONF) & (1 << pin)) == 0) {
84 printk(KERN_ERR "orion_gpio_set_irq_type failed "
85 "(irq %d, pin %d).\n", irq, pin);
86 return -EINVAL;
87 }
88
89 desc = irq_desc + irq;
90
91 switch (type) {
92 case IRQT_HIGH:
93 desc->handle_irq = handle_level_irq;
94 desc->status |= IRQ_LEVEL;
95 orion_clrbits(GPIO_IN_POL, (1 << pin));
96 break;
97 case IRQT_LOW:
98 desc->handle_irq = handle_level_irq;
99 desc->status |= IRQ_LEVEL;
100 orion_setbits(GPIO_IN_POL, (1 << pin));
101 break;
102 case IRQT_RISING:
103 desc->handle_irq = handle_edge_irq;
104 desc->status &= ~IRQ_LEVEL;
105 orion_clrbits(GPIO_IN_POL, (1 << pin));
106 break;
107 case IRQT_FALLING:
108 desc->handle_irq = handle_edge_irq;
109 desc->status &= ~IRQ_LEVEL;
110 orion_setbits(GPIO_IN_POL, (1 << pin));
111 break;
112 case IRQT_BOTHEDGE:
113 desc->handle_irq = handle_edge_irq;
114 desc->status &= ~IRQ_LEVEL;
115 /*
116 * set initial polarity based on current input level
117 */
118 if ((orion_read(GPIO_IN_POL) ^ orion_read(GPIO_DATA_IN))
119 & (1 << pin))
120 orion_setbits(GPIO_IN_POL, (1 << pin)); /* falling */
121 else
122 orion_clrbits(GPIO_IN_POL, (1 << pin)); /* rising */
123
124 break;
125 default:
126 printk(KERN_ERR "failed to set irq=%d (type=%d)\n", irq, type);
127 return -EINVAL;
128 }
129
130 desc->status &= ~IRQ_TYPE_SENSE_MASK;
131 desc->status |= type & IRQ_TYPE_SENSE_MASK;
132
133 return 0;
134}
135
136static struct irq_chip orion_gpio_irq_chip = {
137 .name = "Orion-IRQ-GPIO",
138 .ack = orion_gpio_irq_ack,
139 .mask = orion_gpio_irq_mask,
140 .unmask = orion_gpio_irq_unmask,
141 .set_type = orion_gpio_set_irq_type,
142};
143
144static void orion_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
145{
146 u32 cause, offs, pin;
147
148 BUG_ON(irq < IRQ_ORION_GPIO_0_7 || irq > IRQ_ORION_GPIO_24_31);
149 offs = (irq - IRQ_ORION_GPIO_0_7) * 8;
150 cause = (orion_read(GPIO_DATA_IN) & orion_read(GPIO_LEVEL_MASK)) |
151 (orion_read(GPIO_EDGE_CAUSE) & orion_read(GPIO_EDGE_MASK));
152
153 for (pin = offs; pin < offs + 8; pin++) {
154 if (cause & (1 << pin)) {
155 irq = gpio_to_irq(pin);
156 desc = irq_desc + irq;
157 if ((desc->status & IRQ_TYPE_SENSE_MASK) == IRQT_BOTHEDGE) {
158 /* Swap polarity (race with GPIO line) */
159 u32 polarity = orion_read(GPIO_IN_POL);
160 polarity ^= 1 << pin;
161 orion_write(GPIO_IN_POL, polarity);
162 }
163 desc_handle_irq(irq, desc);
164 }
165 }
166}
167
168static void __init orion_init_gpio_irq(void)
169{
170 int i;
171 struct irq_desc *desc;
172
173 /*
174 * Mask and clear GPIO IRQ interrupts
175 */
176 orion_write(GPIO_LEVEL_MASK, 0x0);
177 orion_write(GPIO_EDGE_MASK, 0x0);
178 orion_write(GPIO_EDGE_CAUSE, 0x0);
179
180 /*
181 * Register chained level handlers for GPIO IRQs by default.
182 * User can use set_type() if he wants to use edge types handlers.
183 */
184 for (i = IRQ_ORION_GPIO_START; i < NR_IRQS; i++) {
185 set_irq_chip(i, &orion_gpio_irq_chip);
186 set_irq_handler(i, handle_level_irq);
187 desc = irq_desc + i;
188 desc->status |= IRQ_LEVEL;
189 set_irq_flags(i, IRQF_VALID);
190 }
191 set_irq_chained_handler(IRQ_ORION_GPIO_0_7, orion_gpio_irq_handler);
192 set_irq_chained_handler(IRQ_ORION_GPIO_8_15, orion_gpio_irq_handler);
193 set_irq_chained_handler(IRQ_ORION_GPIO_16_23, orion_gpio_irq_handler);
194 set_irq_chained_handler(IRQ_ORION_GPIO_24_31, orion_gpio_irq_handler);
195}
196
197/*****************************************************************************
198 * Orion Main IRQ
199 ****************************************************************************/
200static void orion_main_irq_mask(u32 irq)
201{
202 orion_clrbits(MAIN_IRQ_MASK, 1 << irq);
203}
204
205static void orion_main_irq_unmask(u32 irq)
206{
207 orion_setbits(MAIN_IRQ_MASK, 1 << irq);
208}
209
210static struct irq_chip orion_main_irq_chip = {
211 .name = "Orion-IRQ-Main",
212 .ack = orion_main_irq_mask,
213 .mask = orion_main_irq_mask,
214 .unmask = orion_main_irq_unmask,
215};
216
217static void __init orion_init_main_irq(void)
218{
219 int i;
220
221 /*
222 * Mask and clear Main IRQ interrupts
223 */
224 orion_write(MAIN_IRQ_MASK, 0x0);
225 orion_write(MAIN_IRQ_CAUSE, 0x0);
226
227 /*
228 * Register level handler for Main IRQs
229 */
230 for (i = 0; i < IRQ_ORION_GPIO_START; i++) {
231 set_irq_chip(i, &orion_main_irq_chip);
232 set_irq_handler(i, handle_level_irq);
233 set_irq_flags(i, IRQF_VALID);
234 }
235}
236
237void __init orion_init_irq(void)
238{
239 orion_init_main_irq();
240 orion_init_gpio_irq();
241}
diff --git a/arch/arm/mach-orion/kurobox_pro-setup.c b/arch/arm/mach-orion/kurobox_pro-setup.c
new file mode 100644
index 000000000000..2d812ed6b5c7
--- /dev/null
+++ b/arch/arm/mach-orion/kurobox_pro-setup.c
@@ -0,0 +1,234 @@
1/*
2 * arch/arm/mach-orion/kurobox_pro-setup.c
3 *
4 * Maintainer: Ronen Shitrit <rshitrit@marvell.com>
5 *
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
9 */
10
11#include <linux/kernel.h>
12#include <linux/init.h>
13#include <linux/platform_device.h>
14#include <linux/pci.h>
15#include <linux/irq.h>
16#include <linux/mtd/physmap.h>
17#include <linux/mtd/nand.h>
18#include <linux/mv643xx_eth.h>
19#include <linux/i2c.h>
20#include <asm/mach-types.h>
21#include <asm/gpio.h>
22#include <asm/mach/arch.h>
23#include <asm/mach/pci.h>
24#include <asm/arch/orion.h>
25#include <asm/arch/platform.h>
26#include "common.h"
27
28/*****************************************************************************
29 * KUROBOX-PRO Info
30 ****************************************************************************/
31
32/*
33 * 256K NOR flash Device bus boot chip select
34 */
35
36#define KUROBOX_PRO_NOR_BOOT_BASE 0xf4000000
37#define KUROBOX_PRO_NOR_BOOT_SIZE SZ_256K
38
39/*
40 * 256M NAND flash on Device bus chip select 1
41 */
42
43#define KUROBOX_PRO_NAND_BASE 0xfc000000
44#define KUROBOX_PRO_NAND_SIZE SZ_2M
45
46/*****************************************************************************
47 * 256MB NAND Flash on Device bus CS0
48 ****************************************************************************/
49
50static struct mtd_partition kurobox_pro_nand_parts[] = {
51 {
52 .name = "uImage",
53 .offset = 0,
54 .size = SZ_4M,
55 },
56 {
57 .name = "rootfs",
58 .offset = SZ_4M,
59 .size = SZ_64M,
60 },
61 {
62 .name = "extra",
63 .offset = SZ_4M + SZ_64M,
64 .size = SZ_256M - (SZ_4M + SZ_64M),
65 },
66};
67
68static struct resource kurobox_pro_nand_resource = {
69 .flags = IORESOURCE_MEM,
70 .start = KUROBOX_PRO_NAND_BASE,
71 .end = KUROBOX_PRO_NAND_BASE + KUROBOX_PRO_NAND_SIZE - 1,
72};
73
74static struct orion_nand_data kurobox_pro_nand_data = {
75 .parts = kurobox_pro_nand_parts,
76 .nr_parts = ARRAY_SIZE(kurobox_pro_nand_parts),
77 .cle = 0,
78 .ale = 1,
79 .width = 8,
80};
81
82static struct platform_device kurobox_pro_nand_flash = {
83 .name = "orion_nand",
84 .id = -1,
85 .dev = {
86 .platform_data = &kurobox_pro_nand_data,
87 },
88 .resource = &kurobox_pro_nand_resource,
89 .num_resources = 1,
90};
91
92/*****************************************************************************
93 * 256KB NOR Flash on BOOT Device
94 ****************************************************************************/
95
96static struct physmap_flash_data kurobox_pro_nor_flash_data = {
97 .width = 1,
98};
99
100static struct resource kurobox_pro_nor_flash_resource = {
101 .flags = IORESOURCE_MEM,
102 .start = KUROBOX_PRO_NOR_BOOT_BASE,
103 .end = KUROBOX_PRO_NOR_BOOT_BASE + KUROBOX_PRO_NOR_BOOT_SIZE - 1,
104};
105
106static struct platform_device kurobox_pro_nor_flash = {
107 .name = "physmap-flash",
108 .id = 0,
109 .dev = {
110 .platform_data = &kurobox_pro_nor_flash_data,
111 },
112 .num_resources = 1,
113 .resource = &kurobox_pro_nor_flash_resource,
114};
115
116/*****************************************************************************
117 * PCI
118 ****************************************************************************/
119
120static int __init kurobox_pro_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
121{
122 /*
123 * PCI isn't used on the Kuro
124 */
125 if (dev->bus->number == orion_pcie_local_bus_nr())
126 return IRQ_ORION_PCIE0_INT;
127 else
128 printk(KERN_ERR "kurobox_pro_pci_map_irq failed, unknown bus\n");
129
130 return -1;
131}
132
133static struct hw_pci kurobox_pro_pci __initdata = {
134 .nr_controllers = 1,
135 .swizzle = pci_std_swizzle,
136 .setup = orion_pci_sys_setup,
137 .scan = orion_pci_sys_scan_bus,
138 .map_irq = kurobox_pro_pci_map_irq,
139};
140
141static int __init kurobox_pro_pci_init(void)
142{
143 if (machine_is_kurobox_pro())
144 pci_common_init(&kurobox_pro_pci);
145
146 return 0;
147}
148
149subsys_initcall(kurobox_pro_pci_init);
150
151/*****************************************************************************
152 * Ethernet
153 ****************************************************************************/
154
155static struct mv643xx_eth_platform_data kurobox_pro_eth_data = {
156 .phy_addr = 8,
157 .force_phy_addr = 1,
158};
159
160/*****************************************************************************
161 * RTC 5C372a on I2C bus
162 ****************************************************************************/
163static struct i2c_board_info __initdata kurobox_pro_i2c_rtc = {
164 .driver_name = "rtc-rs5c372",
165 .type = "rs5c372a",
166 .addr = 0x32,
167};
168
169/*****************************************************************************
170 * General Setup
171 ****************************************************************************/
172
173static struct platform_device *kurobox_pro_devices[] __initdata = {
174 &kurobox_pro_nor_flash,
175 &kurobox_pro_nand_flash,
176};
177
178static void __init kurobox_pro_init(void)
179{
180 /*
181 * Setup basic Orion functions. Need to be called early.
182 */
183 orion_init();
184
185 /*
186 * Setup the CPU address decode windows for our devices
187 */
188 orion_setup_cpu_win(ORION_DEV_BOOT, KUROBOX_PRO_NOR_BOOT_BASE,
189 KUROBOX_PRO_NOR_BOOT_SIZE, -1);
190 orion_setup_cpu_win(ORION_DEV0, KUROBOX_PRO_NAND_BASE,
191 KUROBOX_PRO_NAND_SIZE, -1);
192 /*
193 * Open a special address decode windows for the PCIE WA.
194 */
195 orion_write(ORION_REGS_BASE | 0x20074, ORION_PCIE_WA_BASE);
196 orion_write(ORION_REGS_BASE | 0x20070, (0x7941 |
197 (((ORION_PCIE_WA_SIZE >> 16) - 1)) << 16));
198
199 /*
200 * Setup Multiplexing Pins --
201 * MPP[0-1] Not used
202 * MPP[2] GPIO Micon
203 * MPP[3] GPIO RTC
204 * MPP[4-5] Not used
205 * MPP[6] Nand Flash REn
206 * MPP[7] Nand Flash WEn
207 * MPP[8-11] Not used
208 * MPP[12] SATA 0 presence Indication
209 * MPP[13] SATA 1 presence Indication
210 * MPP[14] SATA 0 active Indication
211 * MPP[15] SATA 1 active indication
212 * MPP[16-19] Not used
213 */
214 orion_write(MPP_0_7_CTRL, 0x44220003);
215 orion_write(MPP_8_15_CTRL, 0x55550000);
216 orion_write(MPP_16_19_CTRL, 0x0);
217
218 orion_gpio_set_valid_pins(0x0000000c);
219
220 platform_add_devices(kurobox_pro_devices, ARRAY_SIZE(kurobox_pro_devices));
221 i2c_register_board_info(0, &kurobox_pro_i2c_rtc, 1);
222 orion_eth_init(&kurobox_pro_eth_data);
223}
224
225MACHINE_START(KUROBOX_PRO, "Buffalo/Revogear Kurobox Pro")
226 /* Maintainer: Ronen Shitrit <rshitrit@marvell.com> */
227 .phys_io = ORION_REGS_BASE,
228 .io_pg_offst = ((ORION_REGS_BASE) >> 18) & 0xFFFC,
229 .boot_params = 0x00000100,
230 .init_machine = kurobox_pro_init,
231 .map_io = orion_map_io,
232 .init_irq = orion_init_irq,
233 .timer = &orion_timer,
234MACHINE_END
diff --git a/arch/arm/mach-orion/pci.c b/arch/arm/mach-orion/pci.c
new file mode 100644
index 000000000000..0498d7c69b30
--- /dev/null
+++ b/arch/arm/mach-orion/pci.c
@@ -0,0 +1,557 @@
1/*
2 * arch/arm/mach-orion/pci.c
3 *
4 * PCI and PCIE functions for Marvell Orion System On Chip
5 *
6 * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
11 */
12
13#include <linux/kernel.h>
14#include <linux/pci.h>
15#include <asm/mach/pci.h>
16#include "common.h"
17
18/*****************************************************************************
19 * Orion has one PCIE controller and one PCI controller.
20 *
21 * Note1: The local PCIE bus number is '0'. The local PCI bus number
22 * follows the scanned PCIE bridged busses, if any.
23 *
24 * Note2: It is possible for PCI/PCIE agents to access many subsystem's
25 * space, by configuring BARs and Address Decode Windows, e.g. flashes on
26 * device bus, Orion registers, etc. However this code only enable the
27 * access to DDR banks.
28 ****************************************************************************/
29
30
31/*****************************************************************************
32 * PCIE controller
33 ****************************************************************************/
34#define PCIE_CTRL ORION_PCIE_REG(0x1a00)
35#define PCIE_STAT ORION_PCIE_REG(0x1a04)
36#define PCIE_DEV_ID ORION_PCIE_REG(0x0000)
37#define PCIE_CMD_STAT ORION_PCIE_REG(0x0004)
38#define PCIE_DEV_REV ORION_PCIE_REG(0x0008)
39#define PCIE_MASK ORION_PCIE_REG(0x1910)
40#define PCIE_CONF_ADDR ORION_PCIE_REG(0x18f8)
41#define PCIE_CONF_DATA ORION_PCIE_REG(0x18fc)
42
43/*
44 * PCIE_STAT bits
45 */
46#define PCIE_STAT_LINK_DOWN 1
47#define PCIE_STAT_BUS_OFFS 8
48#define PCIE_STAT_BUS_MASK (0xff << PCIE_STAT_BUS_OFFS)
49#define PCIE_STAT_DEV_OFFS 20
50#define PCIE_STAT_DEV_MASK (0x1f << PCIE_STAT_DEV_OFFS)
51
52/*
53 * PCIE_CONF_ADDR bits
54 */
55#define PCIE_CONF_REG(r) ((((r) & 0xf00) << 24) | ((r) & 0xfc))
56#define PCIE_CONF_FUNC(f) (((f) & 0x3) << 8)
57#define PCIE_CONF_DEV(d) (((d) & 0x1f) << 11)
58#define PCIE_CONF_BUS(b) (((b) & 0xff) << 16)
59#define PCIE_CONF_ADDR_EN (1 << 31)
60
61/*
62 * PCIE config cycles are done by programming the PCIE_CONF_ADDR register
63 * and then reading the PCIE_CONF_DATA register. Need to make sure these
64 * transactions are atomic.
65 */
66static DEFINE_SPINLOCK(orion_pcie_lock);
67
68void orion_pcie_id(u32 *dev, u32 *rev)
69{
70 *dev = orion_read(PCIE_DEV_ID) >> 16;
71 *rev = orion_read(PCIE_DEV_REV) & 0xff;
72}
73
74u32 orion_pcie_local_bus_nr(void)
75{
76 u32 stat = orion_read(PCIE_STAT);
77 return((stat & PCIE_STAT_BUS_MASK) >> PCIE_STAT_BUS_OFFS);
78}
79
80static u32 orion_pcie_local_dev_nr(void)
81{
82 u32 stat = orion_read(PCIE_STAT);
83 return((stat & PCIE_STAT_DEV_MASK) >> PCIE_STAT_DEV_OFFS);
84}
85
86static u32 orion_pcie_no_link(void)
87{
88 u32 stat = orion_read(PCIE_STAT);
89 return(stat & PCIE_STAT_LINK_DOWN);
90}
91
92static void orion_pcie_set_bus_nr(int nr)
93{
94 orion_clrbits(PCIE_STAT, PCIE_STAT_BUS_MASK);
95 orion_setbits(PCIE_STAT, nr << PCIE_STAT_BUS_OFFS);
96}
97
98static void orion_pcie_master_slave_enable(void)
99{
100 orion_setbits(PCIE_CMD_STAT, PCI_COMMAND_MASTER |
101 PCI_COMMAND_IO |
102 PCI_COMMAND_MEMORY);
103}
104
105static void orion_pcie_enable_interrupts(void)
106{
107 /*
108 * Enable interrupts lines
109 * INTA[24] INTB[25] INTC[26] INTD[27]
110 */
111 orion_setbits(PCIE_MASK, 0xf<<24);
112}
113
114static int orion_pcie_valid_config(u32 bus, u32 dev)
115{
116 /*
117 * Don't go out when trying to access --
118 * 1. our own device
119 * 2. where there's no device connected (no link)
120 * 3. nonexisting devices on local bus
121 */
122
123 if ((orion_pcie_local_bus_nr() == bus) &&
124 (orion_pcie_local_dev_nr() == dev))
125 return 0;
126
127 if (orion_pcie_no_link())
128 return 0;
129
130 if (bus == orion_pcie_local_bus_nr())
131 if (((orion_pcie_local_dev_nr() == 0) && (dev != 1)) ||
132 ((orion_pcie_local_dev_nr() != 0) && (dev != 0)))
133 return 0;
134
135 return 1;
136}
137
138static int orion_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
139 int size, u32 *val)
140{
141 unsigned long flags;
142 unsigned int dev, rev, pcie_addr;
143
144 if (orion_pcie_valid_config(bus->number, PCI_SLOT(devfn)) == 0) {
145 *val = 0xffffffff;
146 return PCIBIOS_DEVICE_NOT_FOUND;
147 }
148
149 spin_lock_irqsave(&orion_pcie_lock, flags);
150
151 orion_write(PCIE_CONF_ADDR, PCIE_CONF_BUS(bus->number) |
152 PCIE_CONF_DEV(PCI_SLOT(devfn)) |
153 PCIE_CONF_FUNC(PCI_FUNC(devfn)) |
154 PCIE_CONF_REG(where) | PCIE_CONF_ADDR_EN);
155
156 orion_pcie_id(&dev, &rev);
157 if (dev == MV88F5181_DEV_ID || dev == MV88F5182_DEV_ID) {
158 /* extended register space */
159 pcie_addr = ORION_PCIE_WA_BASE;
160 pcie_addr |= PCIE_CONF_BUS(bus->number) |
161 PCIE_CONF_DEV(PCI_SLOT(devfn)) |
162 PCIE_CONF_FUNC(PCI_FUNC(devfn)) |
163 PCIE_CONF_REG(where);
164 *val = orion_read(pcie_addr);
165 } else
166 *val = orion_read(PCIE_CONF_DATA);
167
168 if (size == 1)
169 *val = (*val >> (8*(where & 0x3))) & 0xff;
170 else if (size == 2)
171 *val = (*val >> (8*(where & 0x3))) & 0xffff;
172
173 spin_unlock_irqrestore(&orion_pcie_lock, flags);
174
175 return PCIBIOS_SUCCESSFUL;
176}
177
178
179static int orion_pcie_wr_conf(struct pci_bus *bus, u32 devfn, int where,
180 int size, u32 val)
181{
182 unsigned long flags;
183 int ret;
184
185 if (orion_pcie_valid_config(bus->number, PCI_SLOT(devfn)) == 0)
186 return PCIBIOS_DEVICE_NOT_FOUND;
187
188 spin_lock_irqsave(&orion_pcie_lock, flags);
189
190 ret = PCIBIOS_SUCCESSFUL;
191
192 orion_write(PCIE_CONF_ADDR, PCIE_CONF_BUS(bus->number) |
193 PCIE_CONF_DEV(PCI_SLOT(devfn)) |
194 PCIE_CONF_FUNC(PCI_FUNC(devfn)) |
195 PCIE_CONF_REG(where) | PCIE_CONF_ADDR_EN);
196
197 if (size == 4) {
198 __raw_writel(val, PCIE_CONF_DATA);
199 } else if (size == 2) {
200 __raw_writew(val, PCIE_CONF_DATA + (where & 0x3));
201 } else if (size == 1) {
202 __raw_writeb(val, PCIE_CONF_DATA + (where & 0x3));
203 } else {
204 ret = PCIBIOS_BAD_REGISTER_NUMBER;
205 }
206
207 spin_unlock_irqrestore(&orion_pcie_lock, flags);
208
209 return ret;
210}
211
212struct pci_ops orion_pcie_ops = {
213 .read = orion_pcie_rd_conf,
214 .write = orion_pcie_wr_conf,
215};
216
217
218static int orion_pcie_setup(struct pci_sys_data *sys)
219{
220 struct resource *res;
221
222 /*
223 * Master + Slave enable
224 */
225 orion_pcie_master_slave_enable();
226
227 /*
228 * Enable interrupts lines A-D
229 */
230 orion_pcie_enable_interrupts();
231
232 /*
233 * Request resource
234 */
235 res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL);
236 if (!res)
237 panic("orion_pci_setup unable to alloc resources");
238
239 /*
240 * IORESOURCE_IO
241 */
242 res[0].name = "PCI-EX I/O Space";
243 res[0].flags = IORESOURCE_IO;
244 res[0].start = ORION_PCIE_IO_REMAP;
245 res[0].end = res[0].start + ORION_PCIE_IO_SIZE - 1;
246 if (request_resource(&ioport_resource, &res[0]))
247 panic("Request PCIE IO resource failed\n");
248 sys->resource[0] = &res[0];
249
250 /*
251 * IORESOURCE_MEM
252 */
253 res[1].name = "PCI-EX Memory Space";
254 res[1].flags = IORESOURCE_MEM;
255 res[1].start = ORION_PCIE_MEM_BASE;
256 res[1].end = res[1].start + ORION_PCIE_MEM_SIZE - 1;
257 if (request_resource(&iomem_resource, &res[1]))
258 panic("Request PCIE Memory resource failed\n");
259 sys->resource[1] = &res[1];
260
261 sys->resource[2] = NULL;
262 sys->io_offset = 0;
263
264 return 1;
265}
266
267/*****************************************************************************
268 * PCI controller
269 ****************************************************************************/
270#define PCI_MODE ORION_PCI_REG(0xd00)
271#define PCI_CMD ORION_PCI_REG(0xc00)
272#define PCI_P2P_CONF ORION_PCI_REG(0x1d14)
273#define PCI_CONF_ADDR ORION_PCI_REG(0xc78)
274#define PCI_CONF_DATA ORION_PCI_REG(0xc7c)
275
276/*
277 * PCI_MODE bits
278 */
279#define PCI_MODE_64BIT (1 << 2)
280#define PCI_MODE_PCIX ((1 << 4) | (1 << 5))
281
282/*
283 * PCI_CMD bits
284 */
285#define PCI_CMD_HOST_REORDER (1 << 29)
286
287/*
288 * PCI_P2P_CONF bits
289 */
290#define PCI_P2P_BUS_OFFS 16
291#define PCI_P2P_BUS_MASK (0xff << PCI_P2P_BUS_OFFS)
292#define PCI_P2P_DEV_OFFS 24
293#define PCI_P2P_DEV_MASK (0x1f << PCI_P2P_DEV_OFFS)
294
295/*
296 * PCI_CONF_ADDR bits
297 */
298#define PCI_CONF_REG(reg) ((reg) & 0xfc)
299#define PCI_CONF_FUNC(func) (((func) & 0x3) << 8)
300#define PCI_CONF_DEV(dev) (((dev) & 0x1f) << 11)
301#define PCI_CONF_BUS(bus) (((bus) & 0xff) << 16)
302#define PCI_CONF_ADDR_EN (1 << 31)
303
304/*
305 * Internal configuration space
306 */
307#define PCI_CONF_FUNC_STAT_CMD 0
308#define PCI_CONF_REG_STAT_CMD 4
309#define PCIX_STAT 0x64
310#define PCIX_STAT_BUS_OFFS 8
311#define PCIX_STAT_BUS_MASK (0xff << PCIX_STAT_BUS_OFFS)
312
313/*
314 * PCI config cycles are done by programming the PCI_CONF_ADDR register
315 * and then reading the PCI_CONF_DATA register. Need to make sure these
316 * transactions are atomic.
317 */
318static DEFINE_SPINLOCK(orion_pci_lock);
319
320u32 orion_pci_local_bus_nr(void)
321{
322 u32 conf = orion_read(PCI_P2P_CONF);
323 return((conf & PCI_P2P_BUS_MASK) >> PCI_P2P_BUS_OFFS);
324}
325
326u32 orion_pci_local_dev_nr(void)
327{
328 u32 conf = orion_read(PCI_P2P_CONF);
329 return((conf & PCI_P2P_DEV_MASK) >> PCI_P2P_DEV_OFFS);
330}
331
332int orion_pci_hw_rd_conf(u32 bus, u32 dev, u32 func,
333 u32 where, u32 size, u32 *val)
334{
335 unsigned long flags;
336 spin_lock_irqsave(&orion_pci_lock, flags);
337
338 orion_write(PCI_CONF_ADDR, PCI_CONF_BUS(bus) |
339 PCI_CONF_DEV(dev) | PCI_CONF_REG(where) |
340 PCI_CONF_FUNC(func) | PCI_CONF_ADDR_EN);
341
342 *val = orion_read(PCI_CONF_DATA);
343
344 if (size == 1)
345 *val = (*val >> (8*(where & 0x3))) & 0xff;
346 else if (size == 2)
347 *val = (*val >> (8*(where & 0x3))) & 0xffff;
348
349 spin_unlock_irqrestore(&orion_pci_lock, flags);
350
351 return PCIBIOS_SUCCESSFUL;
352}
353
354int orion_pci_hw_wr_conf(u32 bus, u32 dev, u32 func,
355 u32 where, u32 size, u32 val)
356{
357 unsigned long flags;
358 int ret = PCIBIOS_SUCCESSFUL;
359
360 spin_lock_irqsave(&orion_pci_lock, flags);
361
362 orion_write(PCI_CONF_ADDR, PCI_CONF_BUS(bus) |
363 PCI_CONF_DEV(dev) | PCI_CONF_REG(where) |
364 PCI_CONF_FUNC(func) | PCI_CONF_ADDR_EN);
365
366 if (size == 4) {
367 __raw_writel(val, PCI_CONF_DATA);
368 } else if (size == 2) {
369 __raw_writew(val, PCI_CONF_DATA + (where & 0x3));
370 } else if (size == 1) {
371 __raw_writeb(val, PCI_CONF_DATA + (where & 0x3));
372 } else {
373 ret = PCIBIOS_BAD_REGISTER_NUMBER;
374 }
375
376 spin_unlock_irqrestore(&orion_pci_lock, flags);
377
378 return ret;
379}
380
381static int orion_pci_rd_conf(struct pci_bus *bus, u32 devfn,
382 int where, int size, u32 *val)
383{
384 /*
385 * Don't go out for local device
386 */
387 if ((orion_pci_local_bus_nr() == bus->number) &&
388 (orion_pci_local_dev_nr() == PCI_SLOT(devfn))) {
389 *val = 0xffffffff;
390 return PCIBIOS_DEVICE_NOT_FOUND;
391 }
392
393 return orion_pci_hw_rd_conf(bus->number, PCI_SLOT(devfn),
394 PCI_FUNC(devfn), where, size, val);
395}
396
397static int orion_pci_wr_conf(struct pci_bus *bus, u32 devfn,
398 int where, int size, u32 val)
399{
400 /*
401 * Don't go out for local device
402 */
403 if ((orion_pci_local_bus_nr() == bus->number) &&
404 (orion_pci_local_dev_nr() == PCI_SLOT(devfn)))
405 return PCIBIOS_DEVICE_NOT_FOUND;
406
407 return orion_pci_hw_wr_conf(bus->number, PCI_SLOT(devfn),
408 PCI_FUNC(devfn), where, size, val);
409}
410
411struct pci_ops orion_pci_ops = {
412 .read = orion_pci_rd_conf,
413 .write = orion_pci_wr_conf,
414};
415
416static void orion_pci_set_bus_nr(int nr)
417{
418 u32 p2p = orion_read(PCI_P2P_CONF);
419
420 if (orion_read(PCI_MODE) & PCI_MODE_PCIX) {
421 /*
422 * PCI-X mode
423 */
424 u32 pcix_status, bus, dev;
425 bus = (p2p & PCI_P2P_BUS_MASK) >> PCI_P2P_BUS_OFFS;
426 dev = (p2p & PCI_P2P_DEV_MASK) >> PCI_P2P_DEV_OFFS;
427 orion_pci_hw_rd_conf(bus, dev, 0, PCIX_STAT, 4, &pcix_status);
428 pcix_status &= ~PCIX_STAT_BUS_MASK;
429 pcix_status |= (nr << PCIX_STAT_BUS_OFFS);
430 orion_pci_hw_wr_conf(bus, dev, 0, PCIX_STAT, 4, pcix_status);
431 } else {
432 /*
433 * PCI Conventional mode
434 */
435 p2p &= ~PCI_P2P_BUS_MASK;
436 p2p |= (nr << PCI_P2P_BUS_OFFS);
437 orion_write(PCI_P2P_CONF, p2p);
438 }
439}
440
441static void orion_pci_master_slave_enable(void)
442{
443 u32 bus_nr, dev_nr, func, reg, val;
444
445 bus_nr = orion_pci_local_bus_nr();
446 dev_nr = orion_pci_local_dev_nr();
447 func = PCI_CONF_FUNC_STAT_CMD;
448 reg = PCI_CONF_REG_STAT_CMD;
449 orion_pci_hw_rd_conf(bus_nr, dev_nr, func, reg, 4, &val);
450 val |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
451 orion_pci_hw_wr_conf(bus_nr, dev_nr, func, reg, 4, val | 0x7);
452}
453
454static int orion_pci_setup(struct pci_sys_data *sys)
455{
456 struct resource *res;
457
458 /*
459 * Master + Slave enable
460 */
461 orion_pci_master_slave_enable();
462
463 /*
464 * Force ordering
465 */
466 orion_setbits(PCI_CMD, PCI_CMD_HOST_REORDER);
467
468 /*
469 * Request resources
470 */
471 res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL);
472 if (!res)
473 panic("orion_pci_setup unable to alloc resources");
474
475 /*
476 * IORESOURCE_IO
477 */
478 res[0].name = "PCI I/O Space";
479 res[0].flags = IORESOURCE_IO;
480 res[0].start = ORION_PCI_IO_REMAP;
481 res[0].end = res[0].start + ORION_PCI_IO_SIZE - 1;
482 if (request_resource(&ioport_resource, &res[0]))
483 panic("Request PCI IO resource failed\n");
484 sys->resource[0] = &res[0];
485
486 /*
487 * IORESOURCE_MEM
488 */
489 res[1].name = "PCI Memory Space";
490 res[1].flags = IORESOURCE_MEM;
491 res[1].start = ORION_PCI_MEM_BASE;
492 res[1].end = res[1].start + ORION_PCI_MEM_SIZE - 1;
493 if (request_resource(&iomem_resource, &res[1]))
494 panic("Request PCI Memory resource failed\n");
495 sys->resource[1] = &res[1];
496
497 sys->resource[2] = NULL;
498 sys->io_offset = 0;
499
500 return 1;
501}
502
503
504/*****************************************************************************
505 * General PCIE + PCI
506 ****************************************************************************/
507int orion_pci_sys_setup(int nr, struct pci_sys_data *sys)
508{
509 int ret = 0;
510
511 if (nr == 0) {
512 /*
513 * PCIE setup
514 */
515 orion_pcie_set_bus_nr(0);
516 ret = orion_pcie_setup(sys);
517 } else if (nr == 1) {
518 /*
519 * PCI setup
520 */
521 ret = orion_pci_setup(sys);
522 }
523
524 return ret;
525}
526
527struct pci_bus *orion_pci_sys_scan_bus(int nr, struct pci_sys_data *sys)
528{
529 struct pci_ops *ops;
530 struct pci_bus *bus;
531
532
533 if (nr == 0) {
534 u32 pci_bus;
535 /*
536 * PCIE scan
537 */
538 ops = &orion_pcie_ops;
539 bus = pci_scan_bus(sys->busnr, ops, sys);
540 /*
541 * Set local PCI bus number to follow PCIE bridges (if any)
542 */
543 pci_bus = bus->number + bus->subordinate - bus->secondary + 1;
544 orion_pci_set_bus_nr(pci_bus);
545 } else if (nr == 1) {
546 /*
547 * PCI scan
548 */
549 ops = &orion_pci_ops;
550 bus = pci_scan_bus(sys->busnr, ops, sys);
551 } else {
552 BUG();
553 bus = NULL;
554 }
555
556 return bus;
557}
diff --git a/arch/arm/mach-orion/rd88f5182-setup.c b/arch/arm/mach-orion/rd88f5182-setup.c
new file mode 100644
index 000000000000..026d74325d01
--- /dev/null
+++ b/arch/arm/mach-orion/rd88f5182-setup.c
@@ -0,0 +1,306 @@
1/*
2 * arch/arm/mach-orion/rd88f5182-setup.c
3 *
4 * Marvell Orion-NAS Reference Design Setup
5 *
6 * Maintainer: Ronen Shitrit <rshitrit@marvell.com>
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
11 */
12
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/platform_device.h>
16#include <linux/pci.h>
17#include <linux/irq.h>
18#include <linux/mtd/physmap.h>
19#include <linux/mv643xx_eth.h>
20#include <linux/i2c.h>
21#include <asm/mach-types.h>
22#include <asm/gpio.h>
23#include <asm/leds.h>
24#include <asm/mach/arch.h>
25#include <asm/mach/pci.h>
26#include <asm/arch/orion.h>
27#include <asm/arch/platform.h>
28#include "common.h"
29
30/*****************************************************************************
31 * RD-88F5182 Info
32 ****************************************************************************/
33
34/*
35 * 512K NOR flash Device bus boot chip select
36 */
37
38#define RD88F5182_NOR_BOOT_BASE 0xf4000000
39#define RD88F5182_NOR_BOOT_SIZE SZ_512K
40
41/*
42 * 16M NOR flash on Device bus chip select 1
43 */
44
45#define RD88F5182_NOR_BASE 0xfc000000
46#define RD88F5182_NOR_SIZE SZ_16M
47
48/*
49 * PCI
50 */
51
52#define RD88F5182_PCI_SLOT0_OFFS 7
53#define RD88F5182_PCI_SLOT0_IRQ_A_PIN 7
54#define RD88F5182_PCI_SLOT0_IRQ_B_PIN 6
55
56/*
57 * GPIO Debug LED
58 */
59
60#define RD88F5182_GPIO_DBG_LED 0
61
62/*****************************************************************************
63 * 16M NOR Flash on Device bus CS1
64 ****************************************************************************/
65
66static struct physmap_flash_data rd88f5182_nor_flash_data = {
67 .width = 1,
68};
69
70static struct resource rd88f5182_nor_flash_resource = {
71 .flags = IORESOURCE_MEM,
72 .start = RD88F5182_NOR_BASE,
73 .end = RD88F5182_NOR_BASE + RD88F5182_NOR_SIZE - 1,
74};
75
76static struct platform_device rd88f5182_nor_flash = {
77 .name = "physmap-flash",
78 .id = 0,
79 .dev = {
80 .platform_data = &rd88f5182_nor_flash_data,
81 },
82 .num_resources = 1,
83 .resource = &rd88f5182_nor_flash_resource,
84};
85
86#ifdef CONFIG_LEDS
87
88/*****************************************************************************
89 * Use GPIO debug led as CPU active indication
90 ****************************************************************************/
91
92static void rd88f5182_dbgled_event(led_event_t evt)
93{
94 int val;
95
96 if (evt == led_idle_end)
97 val = 1;
98 else if (evt == led_idle_start)
99 val = 0;
100 else
101 return;
102
103 gpio_set_value(RD88F5182_GPIO_DBG_LED, val);
104}
105
106static int __init rd88f5182_dbgled_init(void)
107{
108 int pin;
109
110 if (machine_is_rd88f5182()) {
111 pin = RD88F5182_GPIO_DBG_LED;
112
113 if (gpio_request(pin, "DBGLED") == 0) {
114 if (gpio_direction_output(pin, 0) != 0) {
115 printk(KERN_ERR "rd88f5182_dbgled_init failed "
116 "to set output pin %d\n", pin);
117 gpio_free(pin);
118 return 0;
119 }
120 } else {
121 printk(KERN_ERR "rd88f5182_dbgled_init failed "
122 "to request gpio %d\n", pin);
123 return 0;
124 }
125
126 leds_event = rd88f5182_dbgled_event;
127 }
128 return 0;
129}
130
131__initcall(rd88f5182_dbgled_init);
132
133#endif
134
135/*****************************************************************************
136 * PCI
137 ****************************************************************************/
138
139void __init rd88f5182_pci_preinit(void)
140{
141 int pin;
142
143 /*
144 * Configure PCI GPIO IRQ pins
145 */
146 pin = RD88F5182_PCI_SLOT0_IRQ_A_PIN;
147 if (gpio_request(pin, "PCI IntA") == 0) {
148 if (gpio_direction_input(pin) == 0) {
149 set_irq_type(gpio_to_irq(pin), IRQT_LOW);
150 } else {
151 printk(KERN_ERR "rd88f5182_pci_preinit faield to "
152 "set_irq_type pin %d\n", pin);
153 gpio_free(pin);
154 }
155 } else {
156 printk(KERN_ERR "rd88f5182_pci_preinit failed to request gpio %d\n", pin);
157 }
158
159 pin = RD88F5182_PCI_SLOT0_IRQ_B_PIN;
160 if (gpio_request(pin, "PCI IntB") == 0) {
161 if (gpio_direction_input(pin) == 0) {
162 set_irq_type(gpio_to_irq(pin), IRQT_LOW);
163 } else {
164 printk(KERN_ERR "rd88f5182_pci_preinit faield to "
165 "set_irq_type pin %d\n", pin);
166 gpio_free(pin);
167 }
168 } else {
169 printk(KERN_ERR "rd88f5182_pci_preinit failed to gpio_request %d\n", pin);
170 }
171}
172
173static int __init rd88f5182_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
174{
175 /*
176 * PCI-E isn't used on the RD2
177 */
178 if (dev->bus->number == orion_pcie_local_bus_nr())
179 return IRQ_ORION_PCIE0_INT;
180
181 /*
182 * PCI IRQs are connected via GPIOs
183 */
184 switch (slot - RD88F5182_PCI_SLOT0_OFFS) {
185 case 0:
186 if (pin == 1)
187 return gpio_to_irq(RD88F5182_PCI_SLOT0_IRQ_A_PIN);
188 else
189 return gpio_to_irq(RD88F5182_PCI_SLOT0_IRQ_B_PIN);
190 default:
191 return -1;
192 }
193}
194
195static struct hw_pci rd88f5182_pci __initdata = {
196 .nr_controllers = 2,
197 .preinit = rd88f5182_pci_preinit,
198 .swizzle = pci_std_swizzle,
199 .setup = orion_pci_sys_setup,
200 .scan = orion_pci_sys_scan_bus,
201 .map_irq = rd88f5182_pci_map_irq,
202};
203
204static int __init rd88f5182_pci_init(void)
205{
206 if (machine_is_rd88f5182())
207 pci_common_init(&rd88f5182_pci);
208
209 return 0;
210}
211
212subsys_initcall(rd88f5182_pci_init);
213
214/*****************************************************************************
215 * Ethernet
216 ****************************************************************************/
217
218static struct mv643xx_eth_platform_data rd88f5182_eth_data = {
219 .phy_addr = 8,
220 .force_phy_addr = 1,
221};
222
223/*****************************************************************************
224 * RTC DS1338 on I2C bus
225 ****************************************************************************/
226static struct i2c_board_info __initdata rd88f5182_i2c_rtc = {
227 .driver_name = "rtc-ds1307",
228 .type = "ds1338",
229 .addr = 0x68,
230};
231
232/*****************************************************************************
233 * General Setup
234 ****************************************************************************/
235
236static struct platform_device *rd88f5182_devices[] __initdata = {
237 &rd88f5182_nor_flash,
238};
239
240static void __init rd88f5182_init(void)
241{
242 /*
243 * Setup basic Orion functions. Need to be called early.
244 */
245 orion_init();
246
247 /*
248 * Setup the CPU address decode windows for our devices
249 */
250 orion_setup_cpu_win(ORION_DEV_BOOT, RD88F5182_NOR_BOOT_BASE,
251 RD88F5182_NOR_BOOT_SIZE, -1);
252 orion_setup_cpu_win(ORION_DEV1, RD88F5182_NOR_BASE,
253 RD88F5182_NOR_SIZE, -1);
254
255 /*
256 * Open a special address decode windows for the PCIE WA.
257 */
258 orion_write(ORION_REGS_BASE | 0x20074, ORION_PCIE_WA_BASE);
259 orion_write(ORION_REGS_BASE | 0x20070, (0x7941 |
260 (((ORION_PCIE_WA_SIZE >> 16) - 1)) << 16));
261
262 /*
263 * Setup Multiplexing Pins --
264 * MPP[0] Debug Led (GPIO - Out)
265 * MPP[1] Debug Led (GPIO - Out)
266 * MPP[2] N/A
267 * MPP[3] RTC_Int (GPIO - In)
268 * MPP[4] GPIO
269 * MPP[5] GPIO
270 * MPP[6] PCI_intA (GPIO - In)
271 * MPP[7] PCI_intB (GPIO - In)
272 * MPP[8-11] N/A
273 * MPP[12] SATA 0 presence Indication
274 * MPP[13] SATA 1 presence Indication
275 * MPP[14] SATA 0 active Indication
276 * MPP[15] SATA 1 active indication
277 * MPP[16-19] Not used
278 * MPP[20] PCI Clock to MV88F5182
279 * MPP[21] PCI Clock to mini PCI CON11
280 * MPP[22] USB 0 over current indication
281 * MPP[23] USB 1 over current indication
282 * MPP[24] USB 1 over current enable
283 * MPP[25] USB 0 over current enable
284 */
285
286 orion_write(MPP_0_7_CTRL, 0x00000003);
287 orion_write(MPP_8_15_CTRL, 0x55550000);
288 orion_write(MPP_16_19_CTRL, 0x5555);
289
290 orion_gpio_set_valid_pins(0x000000fb);
291
292 platform_add_devices(rd88f5182_devices, ARRAY_SIZE(rd88f5182_devices));
293 i2c_register_board_info(0, &rd88f5182_i2c_rtc, 1);
294 orion_eth_init(&rd88f5182_eth_data);
295}
296
297MACHINE_START(RD88F5182, "Marvell Orion-NAS Reference Design")
298 /* Maintainer: Ronen Shitrit <rshitrit@marvell.com> */
299 .phys_io = ORION_REGS_BASE,
300 .io_pg_offst = ((ORION_REGS_BASE) >> 18) & 0xFFFC,
301 .boot_params = 0x00000100,
302 .init_machine = rd88f5182_init,
303 .map_io = orion_map_io,
304 .init_irq = orion_init_irq,
305 .timer = &orion_timer,
306MACHINE_END
diff --git a/arch/arm/mach-orion/time.c b/arch/arm/mach-orion/time.c
new file mode 100644
index 000000000000..bd4262da4f40
--- /dev/null
+++ b/arch/arm/mach-orion/time.c
@@ -0,0 +1,181 @@
1/*
2 * arch/arm/mach-orion/time.c
3 *
4 * Core time functions for Marvell Orion System On Chip
5 *
6 * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
11 */
12
13#include <linux/kernel.h>
14#include <linux/clockchips.h>
15#include <linux/interrupt.h>
16#include <linux/irq.h>
17#include <asm/mach/time.h>
18#include <asm/arch/orion.h>
19#include "common.h"
20
21/*
22 * Timer0: clock_event_device, Tick.
23 * Timer1: clocksource, Free running.
24 * WatchDog: Not used.
25 *
26 * Timers are counting down.
27 */
28#define CLOCKEVENT 0
29#define CLOCKSOURCE 1
30
31/*
32 * Timers bits
33 */
34#define BRIDGE_INT_TIMER(x) (1 << ((x) + 1))
35#define TIMER_EN(x) (1 << ((x) * 2))
36#define TIMER_RELOAD_EN(x) (1 << (((x) * 2) + 1))
37#define BRIDGE_INT_TIMER_WD (1 << 3)
38#define TIMER_WD_EN (1 << 4)
39#define TIMER_WD_RELOAD_EN (1 << 5)
40
41static cycle_t orion_clksrc_read(void)
42{
43 return (0xffffffff - orion_read(TIMER_VAL(CLOCKSOURCE)));
44}
45
46static struct clocksource orion_clksrc = {
47 .name = "orion_clocksource",
48 .shift = 20,
49 .rating = 300,
50 .read = orion_clksrc_read,
51 .mask = CLOCKSOURCE_MASK(32),
52 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
53};
54
55static int
56orion_clkevt_next_event(unsigned long delta, struct clock_event_device *dev)
57{
58 unsigned long flags;
59
60 if (delta == 0)
61 return -ETIME;
62
63 local_irq_save(flags);
64
65 /*
66 * Clear and enable timer interrupt bit
67 */
68 orion_write(BRIDGE_CAUSE, ~BRIDGE_INT_TIMER(CLOCKEVENT));
69 orion_setbits(BRIDGE_MASK, BRIDGE_INT_TIMER(CLOCKEVENT));
70
71 /*
72 * Setup new timer value
73 */
74 orion_write(TIMER_VAL(CLOCKEVENT), delta);
75
76 /*
77 * Disable auto reload and kickoff the timer
78 */
79 orion_clrbits(TIMER_CTRL, TIMER_RELOAD_EN(CLOCKEVENT));
80 orion_setbits(TIMER_CTRL, TIMER_EN(CLOCKEVENT));
81
82 local_irq_restore(flags);
83
84 return 0;
85}
86
87static void
88orion_clkevt_mode(enum clock_event_mode mode, struct clock_event_device *dev)
89{
90 unsigned long flags;
91
92 local_irq_save(flags);
93
94 if (mode == CLOCK_EVT_MODE_PERIODIC) {
95 /*
96 * Setup latch cycles in timer and enable reload interrupt.
97 */
98 orion_write(TIMER_VAL_RELOAD(CLOCKEVENT), LATCH);
99 orion_write(TIMER_VAL(CLOCKEVENT), LATCH);
100 orion_setbits(BRIDGE_MASK, BRIDGE_INT_TIMER(CLOCKEVENT));
101 orion_setbits(TIMER_CTRL, TIMER_RELOAD_EN(CLOCKEVENT) |
102 TIMER_EN(CLOCKEVENT));
103 } else {
104 /*
105 * Disable timer and interrupt
106 */
107 orion_clrbits(BRIDGE_MASK, BRIDGE_INT_TIMER(CLOCKEVENT));
108 orion_write(BRIDGE_CAUSE, ~BRIDGE_INT_TIMER(CLOCKEVENT));
109 orion_clrbits(TIMER_CTRL, TIMER_RELOAD_EN(CLOCKEVENT) |
110 TIMER_EN(CLOCKEVENT));
111 }
112
113 local_irq_restore(flags);
114}
115
116static struct clock_event_device orion_clkevt = {
117 .name = "orion_tick",
118 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
119 .shift = 32,
120 .rating = 300,
121 .cpumask = CPU_MASK_CPU0,
122 .set_next_event = orion_clkevt_next_event,
123 .set_mode = orion_clkevt_mode,
124};
125
126static irqreturn_t orion_timer_interrupt(int irq, void *dev_id)
127{
128 /*
129 * Clear cause bit and do event
130 */
131 orion_write(BRIDGE_CAUSE, ~BRIDGE_INT_TIMER(CLOCKEVENT));
132 orion_clkevt.event_handler(&orion_clkevt);
133 return IRQ_HANDLED;
134}
135
136static struct irqaction orion_timer_irq = {
137 .name = "orion_tick",
138 .flags = IRQF_DISABLED | IRQF_TIMER,
139 .handler = orion_timer_interrupt
140};
141
142static void orion_timer_init(void)
143{
144 /*
145 * Setup clocksource free running timer (no interrupt on reload)
146 */
147 orion_write(TIMER_VAL(CLOCKSOURCE), 0xffffffff);
148 orion_write(TIMER_VAL_RELOAD(CLOCKSOURCE), 0xffffffff);
149 orion_clrbits(BRIDGE_MASK, BRIDGE_INT_TIMER(CLOCKSOURCE));
150 orion_setbits(TIMER_CTRL, TIMER_RELOAD_EN(CLOCKSOURCE) |
151 TIMER_EN(CLOCKSOURCE));
152
153 /*
154 * Register clocksource
155 */
156 orion_clksrc.mult =
157 clocksource_hz2mult(CLOCK_TICK_RATE, orion_clksrc.shift);
158
159 clocksource_register(&orion_clksrc);
160
161 /*
162 * Connect and enable tick handler
163 */
164 setup_irq(IRQ_ORION_BRIDGE, &orion_timer_irq);
165
166 /*
167 * Register clockevent
168 */
169 orion_clkevt.mult =
170 div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, orion_clkevt.shift);
171 orion_clkevt.max_delta_ns =
172 clockevent_delta2ns(0xfffffffe, &orion_clkevt);
173 orion_clkevt.min_delta_ns =
174 clockevent_delta2ns(1, &orion_clkevt);
175
176 clockevents_register_device(&orion_clkevt);
177}
178
179struct sys_timer orion_timer = {
180 .init = orion_timer_init,
181};
diff --git a/arch/arm/mach-orion/ts209-setup.c b/arch/arm/mach-orion/ts209-setup.c
new file mode 100644
index 000000000000..e3e930efd155
--- /dev/null
+++ b/arch/arm/mach-orion/ts209-setup.c
@@ -0,0 +1,335 @@
1/*
2 * QNAP TS-109/TS-209 Board Setup
3 *
4 * Maintainer: Byron Bradley <byron.bbradley@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/platform_device.h>
15#include <linux/pci.h>
16#include <linux/irq.h>
17#include <linux/mtd/physmap.h>
18#include <linux/mtd/nand.h>
19#include <linux/mv643xx_eth.h>
20#include <linux/gpio_keys.h>
21#include <linux/input.h>
22#include <linux/i2c.h>
23#include <linux/serial_reg.h>
24#include <asm/mach-types.h>
25#include <asm/gpio.h>
26#include <asm/mach/arch.h>
27#include <asm/mach/pci.h>
28#include <asm/arch/orion.h>
29#include <asm/arch/platform.h>
30#include "common.h"
31
32#define QNAP_TS209_NOR_BOOT_BASE 0xf4000000
33#define QNAP_TS209_NOR_BOOT_SIZE SZ_8M
34
35/****************************************************************************
36 * 8MiB NOR flash. The struct mtd_partition is not in the same order as the
37 * partitions on the device because we want to keep compatability with
38 * existing QNAP firmware.
39 *
40 * Layout as used by QNAP:
41 * [2] 0x00000000-0x00200000 : "Kernel"
42 * [3] 0x00200000-0x00600000 : "RootFS1"
43 * [4] 0x00600000-0x00700000 : "RootFS2"
44 * [6] 0x00700000-0x00760000 : "NAS Config" (read-only)
45 * [5] 0x00760000-0x00780000 : "U-Boot Config"
46 * [1] 0x00780000-0x00800000 : "U-Boot" (read-only)
47 ***************************************************************************/
48static struct mtd_partition qnap_ts209_partitions[] = {
49 {
50 .name = "U-Boot",
51 .size = 0x00080000,
52 .offset = 0x00780000,
53 .mask_flags = MTD_WRITEABLE,
54 }, {
55 .name = "Kernel",
56 .size = 0x00200000,
57 .offset = 0,
58 }, {
59 .name = "RootFS1",
60 .size = 0x00400000,
61 .offset = 0x00200000,
62 }, {
63 .name = "RootFS2",
64 .size = 0x00100000,
65 .offset = 0x00600000,
66 }, {
67 .name = "U-Boot Config",
68 .size = 0x00020000,
69 .offset = 0x00760000,
70 }, {
71 .name = "NAS Config",
72 .size = 0x00060000,
73 .offset = 0x00700000,
74 .mask_flags = MTD_WRITEABLE,
75 }
76};
77
78static struct physmap_flash_data qnap_ts209_nor_flash_data = {
79 .width = 1,
80 .parts = qnap_ts209_partitions,
81 .nr_parts = ARRAY_SIZE(qnap_ts209_partitions)
82};
83
84static struct resource qnap_ts209_nor_flash_resource = {
85 .flags = IORESOURCE_MEM,
86 .start = QNAP_TS209_NOR_BOOT_BASE,
87 .end = QNAP_TS209_NOR_BOOT_BASE + QNAP_TS209_NOR_BOOT_SIZE - 1,
88};
89
90static struct platform_device qnap_ts209_nor_flash = {
91 .name = "physmap-flash",
92 .id = 0,
93 .dev = { .platform_data = &qnap_ts209_nor_flash_data, },
94 .resource = &qnap_ts209_nor_flash_resource,
95 .num_resources = 1,
96};
97
98/*****************************************************************************
99 * PCI
100 ****************************************************************************/
101
102#define QNAP_TS209_PCI_SLOT0_OFFS 7
103#define QNAP_TS209_PCI_SLOT0_IRQ_PIN 6
104#define QNAP_TS209_PCI_SLOT1_IRQ_PIN 7
105
106void __init qnap_ts209_pci_preinit(void)
107{
108 int pin;
109
110 /*
111 * Configure PCI GPIO IRQ pins
112 */
113 pin = QNAP_TS209_PCI_SLOT0_IRQ_PIN;
114 if (gpio_request(pin, "PCI Int1") == 0) {
115 if (gpio_direction_input(pin) == 0) {
116 set_irq_type(gpio_to_irq(pin), IRQT_LOW);
117 } else {
118 printk(KERN_ERR "qnap_ts209_pci_preinit failed to "
119 "set_irq_type pin %d\n", pin);
120 gpio_free(pin);
121 }
122 } else {
123 printk(KERN_ERR "qnap_ts209_pci_preinit failed to gpio_request "
124 "%d\n", pin);
125 }
126
127 pin = QNAP_TS209_PCI_SLOT1_IRQ_PIN;
128 if (gpio_request(pin, "PCI Int2") == 0) {
129 if (gpio_direction_input(pin) == 0) {
130 set_irq_type(gpio_to_irq(pin), IRQT_LOW);
131 } else {
132 printk(KERN_ERR "qnap_ts209_pci_preinit failed "
133 "to set_irq_type pin %d\n", pin);
134 gpio_free(pin);
135 }
136 } else {
137 printk(KERN_ERR "qnap_ts209_pci_preinit failed to gpio_request "
138 "%d\n", pin);
139 }
140}
141
142static int __init qnap_ts209_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
143{
144 /*
145 * PCIE IRQ is connected internally (not GPIO)
146 */
147 if (dev->bus->number == orion_pcie_local_bus_nr())
148 return IRQ_ORION_PCIE0_INT;
149
150 /*
151 * PCI IRQs are connected via GPIOs
152 */
153 switch (slot - QNAP_TS209_PCI_SLOT0_OFFS) {
154 case 0:
155 return gpio_to_irq(QNAP_TS209_PCI_SLOT0_IRQ_PIN);
156 case 1:
157 return gpio_to_irq(QNAP_TS209_PCI_SLOT1_IRQ_PIN);
158 default:
159 return -1;
160 }
161}
162
163static struct hw_pci qnap_ts209_pci __initdata = {
164 .nr_controllers = 2,
165 .preinit = qnap_ts209_pci_preinit,
166 .swizzle = pci_std_swizzle,
167 .setup = orion_pci_sys_setup,
168 .scan = orion_pci_sys_scan_bus,
169 .map_irq = qnap_ts209_pci_map_irq,
170};
171
172static int __init qnap_ts209_pci_init(void)
173{
174 if (machine_is_ts_x09())
175 pci_common_init(&qnap_ts209_pci);
176
177 return 0;
178}
179
180subsys_initcall(qnap_ts209_pci_init);
181
182/*****************************************************************************
183 * Ethernet
184 ****************************************************************************/
185
186static struct mv643xx_eth_platform_data qnap_ts209_eth_data = {
187 .phy_addr = 8,
188 .force_phy_addr = 1,
189};
190
191/*****************************************************************************
192 * RTC S35390A on I2C bus
193 ****************************************************************************/
194static struct i2c_board_info __initdata qnap_ts209_i2c_rtc = {
195 .driver_name = "rtc-s35390a",
196 .addr = 0x30,
197};
198
199/****************************************************************************
200 * GPIO Attached Keys
201 * Power button is attached to the PIC microcontroller
202 ****************************************************************************/
203
204#define QNAP_TS209_GPIO_KEY_MEDIA 1
205#define QNAP_TS209_GPIO_KEY_RESET 2
206
207static struct gpio_keys_button qnap_ts209_buttons[] = {
208 {
209 .code = KEY_RESTART,
210 .gpio = QNAP_TS209_GPIO_KEY_MEDIA,
211 .desc = "USB Copy Button",
212 .active_low = 1,
213 },
214 {
215 .code = KEY_POWER,
216 .gpio = QNAP_TS209_GPIO_KEY_RESET,
217 .desc = "Reset Button",
218 .active_low = 1,
219 }
220};
221
222static struct gpio_keys_platform_data qnap_ts209_button_data = {
223 .buttons = qnap_ts209_buttons,
224 .nbuttons = ARRAY_SIZE(qnap_ts209_buttons),
225};
226
227static struct platform_device qnap_ts209_button_device = {
228 .name = "gpio-keys",
229 .id = -1,
230 .num_resources = 0,
231 .dev = { .platform_data = &qnap_ts209_button_data, },
232};
233
234/*****************************************************************************
235 * General Setup
236 ****************************************************************************/
237
238static struct platform_device *qnap_ts209_devices[] __initdata = {
239 &qnap_ts209_nor_flash,
240 &qnap_ts209_button_device,
241};
242
243/*
244 * QNAP TS-[12]09 specific power off method via UART1-attached PIC
245 */
246
247#define UART1_REG(x) (UART1_BASE + ((UART_##x) << 2))
248
249static void qnap_ts209_power_off(void)
250{
251 /* 19200 baud divisor */
252 const unsigned divisor = ((ORION_TCLK + (8 * 19200)) / (16 * 19200));
253
254 pr_info("%s: triggering power-off...\n", __func__);
255
256 /* hijack uart1 and reset into sane state (19200,8n1) */
257 orion_write(UART1_REG(LCR), 0x83);
258 orion_write(UART1_REG(DLL), divisor & 0xff);
259 orion_write(UART1_REG(DLM), (divisor >> 8) & 0xff);
260 orion_write(UART1_REG(LCR), 0x03);
261 orion_write(UART1_REG(IER), 0x00);
262 orion_write(UART1_REG(FCR), 0x00);
263 orion_write(UART1_REG(MCR), 0x00);
264
265 /* send the power-off command 'A' to PIC */
266 orion_write(UART1_REG(TX), 'A');
267}
268
269static void __init qnap_ts209_init(void)
270{
271 /*
272 * Setup basic Orion functions. Need to be called early.
273 */
274 orion_init();
275
276 /*
277 * Setup flash mapping
278 */
279 orion_setup_cpu_win(ORION_DEV_BOOT, QNAP_TS209_NOR_BOOT_BASE,
280 QNAP_TS209_NOR_BOOT_SIZE, -1);
281
282 /*
283 * Open a special address decode windows for the PCIE WA.
284 */
285 orion_write(ORION_REGS_BASE | 0x20074, ORION_PCIE_WA_BASE);
286 orion_write(ORION_REGS_BASE | 0x20070, (0x7941 |
287 (((ORION_PCIE_WA_SIZE >> 16) - 1)) << 16));
288
289 /*
290 * Setup Multiplexing Pins --
291 * MPP[0] Reserved
292 * MPP[1] USB copy button (0 active)
293 * MPP[2] Load defaults button (0 active)
294 * MPP[3] GPIO RTC
295 * MPP[4-5] Reserved
296 * MPP[6] PCI Int A
297 * MPP[7] PCI Int B
298 * MPP[8-11] Reserved
299 * MPP[12] SATA 0 presence
300 * MPP[13] SATA 1 presence
301 * MPP[14] SATA 0 active
302 * MPP[15] SATA 1 active
303 * MPP[16] UART1 RXD
304 * MPP[17] UART1 TXD
305 * MPP[18] SW_RST (0 active)
306 * MPP[19] Reserved
307 * MPP[20] PCI clock 0
308 * MPP[21] PCI clock 1
309 * MPP[22] USB 0 over current
310 * MPP[23-25] Reserved
311 */
312 orion_write(MPP_0_7_CTRL, 0x3);
313 orion_write(MPP_8_15_CTRL, 0x55550000);
314 orion_write(MPP_16_19_CTRL, 0x5500);
315 orion_gpio_set_valid_pins(0x3cc0fff);
316
317 /* register ts209 specific power-off method */
318 pm_power_off = qnap_ts209_power_off;
319
320 platform_add_devices(qnap_ts209_devices,
321 ARRAY_SIZE(qnap_ts209_devices));
322 i2c_register_board_info(0, &qnap_ts209_i2c_rtc, 1);
323 orion_eth_init(&qnap_ts209_eth_data);
324}
325
326MACHINE_START(TS209, "QNAP TS-109/TS-209")
327 /* Maintainer: Byron Bradley <byron.bbradley@gmail.com> */
328 .phys_io = ORION_REGS_BASE,
329 .io_pg_offst = ((ORION_REGS_BASE) >> 18) & 0xFFFC,
330 .boot_params = 0x00000100,
331 .init_machine = qnap_ts209_init,
332 .map_io = orion_map_io,
333 .init_irq = orion_init_irq,
334 .timer = &orion_timer,
335MACHINE_END
diff --git a/arch/arm/mach-pnx4008/time.c b/arch/arm/mach-pnx4008/time.c
index 67e05f005a6b..6d4ca8fc0cb4 100644
--- a/arch/arm/mach-pnx4008/time.c
+++ b/arch/arm/mach-pnx4008/time.c
@@ -51,8 +51,6 @@ static irqreturn_t pnx4008_timer_interrupt(int irq, void *dev_id)
51{ 51{
52 if (__raw_readl(HSTIM_INT) & MATCH0_INT) { 52 if (__raw_readl(HSTIM_INT) & MATCH0_INT) {
53 53
54 write_seqlock(&xtime_lock);
55
56 do { 54 do {
57 timer_tick(); 55 timer_tick();
58 56
@@ -73,8 +71,6 @@ static irqreturn_t pnx4008_timer_interrupt(int irq, void *dev_id)
73 } while ((signed) 71 } while ((signed)
74 (__raw_readl(HSTIM_MATCH0) - 72 (__raw_readl(HSTIM_MATCH0) -
75 __raw_readl(HSTIM_COUNTER)) < 0); 73 __raw_readl(HSTIM_COUNTER)) < 0);
76
77 write_sequnlock(&xtime_lock);
78 } 74 }
79 75
80 return IRQ_HANDLED; 76 return IRQ_HANDLED;
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index 656d49661a29..0908bea0f609 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -51,6 +51,50 @@ config PXA_SHARPSL
51 SL-C3000 (Spitz), SL-C3100 (Borzoi) or SL-C6000x (Tosa) 51 SL-C3000 (Spitz), SL-C3100 (Borzoi) or SL-C6000x (Tosa)
52 handheld computer. 52 handheld computer.
53 53
54config ARCH_PXA_ESERIES
55 bool "PXA based Toshiba e-series PDAs"
56 select PXA25x
57
58config MACH_E330
59 bool "Toshiba e330"
60 default y
61 depends on ARCH_PXA_ESERIES
62 help
63 Say Y here if you intend to run this kernel on a Toshiba
64 e330 family PDA.
65
66config MACH_E740
67 bool "Toshiba e740"
68 default y
69 depends on ARCH_PXA_ESERIES
70 help
71 Say Y here if you intend to run this kernel on a Toshiba
72 e740 family PDA.
73
74config MACH_E750
75 bool "Toshiba e750"
76 default y
77 depends on ARCH_PXA_ESERIES
78 help
79 Say Y here if you intend to run this kernel on a Toshiba
80 e750 family PDA.
81
82config MACH_E400
83 bool "Toshiba e400"
84 default y
85 depends on ARCH_PXA_ESERIES
86 help
87 Say Y here if you intend to run this kernel on a Toshiba
88 e400 family PDA.
89
90config MACH_E800
91 bool "Toshiba e800"
92 default y
93 depends on ARCH_PXA_ESERIES
94 help
95 Say Y here if you intend to run this kernel on a Toshiba
96 e800 family PDA.
97
54config MACH_TRIZEPS4 98config MACH_TRIZEPS4
55 bool "Keith und Koep Trizeps4 DIMM-Module" 99 bool "Keith und Koep Trizeps4 DIMM-Module"
56 select PXA27x 100 select PXA27x
@@ -59,15 +103,44 @@ config MACH_EM_X270
59 bool "CompuLab EM-x270 platform" 103 bool "CompuLab EM-x270 platform"
60 select PXA27x 104 select PXA27x
61 105
106config MACH_COLIBRI
107 bool "Toradex Colibri PX27x"
108 select PXA27x
109
62config MACH_ZYLONITE 110config MACH_ZYLONITE
63 bool "PXA3xx Development Platform" 111 bool "PXA3xx Development Platform"
64 select PXA3xx 112 select PXA3xx
65 113
114config MACH_LITTLETON
115 bool "PXA3xx Form Factor Platform (aka Littleton)"
116 select PXA3xx
117 select PXA_SSP
118
66config MACH_ARMCORE 119config MACH_ARMCORE
67 bool "CompuLab CM-X270 modules" 120 bool "CompuLab CM-X270 modules"
68 select PXA27x 121 select PXA27x
69 select IWMMXT 122 select IWMMXT
70 123
124config MACH_MAGICIAN
125 bool "Enable HTC Magician Support"
126 depends on ARCH_PXA
127 select PXA27x
128 select IWMMXT
129
130config MACH_PCM027
131 bool "Phytec phyCORE-PXA270 CPU module (PCM-027)"
132 select PXA27x
133 select IWMMXT
134
135endchoice
136
137choice
138 prompt "Used baseboard"
139 depends on MACH_PCM027
140
141config MACH_PCM990_BASEBOARD
142 bool "PHYTEC PCM-990 development board"
143
71endchoice 144endchoice
72 145
73if PXA_SHARPSL 146if PXA_SHARPSL
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index 4263527e5123..b5c916c0747d 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -3,7 +3,7 @@
3# 3#
4 4
5# Common support (must be linked before board specific support) 5# Common support (must be linked before board specific support)
6obj-y += clock.o generic.o irq.o dma.o time.o 6obj-y += clock.o devices.o generic.o irq.o dma.o time.o
7obj-$(CONFIG_PXA25x) += pxa25x.o 7obj-$(CONFIG_PXA25x) += pxa25x.o
8obj-$(CONFIG_PXA27x) += pxa27x.o 8obj-$(CONFIG_PXA27x) += pxa27x.o
9obj-$(CONFIG_PXA3xx) += pxa3xx.o mfp.o 9obj-$(CONFIG_PXA3xx) += pxa3xx.o mfp.o
@@ -16,18 +16,24 @@ obj-$(CONFIG_MACH_LOGICPD_PXA270) += lpd270.o
16obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o 16obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o
17obj-$(CONFIG_ARCH_PXA_IDP) += idp.o 17obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
18obj-$(CONFIG_MACH_TRIZEPS4) += trizeps4.o 18obj-$(CONFIG_MACH_TRIZEPS4) += trizeps4.o
19obj-$(CONFIG_MACH_COLIBRI) += colibri.o
19obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o corgi_pm.o 20obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o corgi_pm.o
20obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o spitz_pm.o 21obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o spitz_pm.o
21obj-$(CONFIG_MACH_AKITA) += akita-ioexp.o 22obj-$(CONFIG_MACH_AKITA) += akita-ioexp.o
22obj-$(CONFIG_MACH_POODLE) += poodle.o corgi_ssp.o 23obj-$(CONFIG_MACH_POODLE) += poodle.o corgi_ssp.o
24obj-$(CONFIG_MACH_PCM027) += pcm027.o
25obj-$(CONFIG_MACH_PCM990_BASEBOARD) += pcm990-baseboard.o
23obj-$(CONFIG_MACH_TOSA) += tosa.o 26obj-$(CONFIG_MACH_TOSA) += tosa.o
24obj-$(CONFIG_MACH_EM_X270) += em-x270.o 27obj-$(CONFIG_MACH_EM_X270) += em-x270.o
28obj-$(CONFIG_MACH_MAGICIAN) += magician.o
29obj-$(CONFIG_ARCH_PXA_ESERIES) += eseries.o
25 30
26ifeq ($(CONFIG_MACH_ZYLONITE),y) 31ifeq ($(CONFIG_MACH_ZYLONITE),y)
27 obj-y += zylonite.o 32 obj-y += zylonite.o
28 obj-$(CONFIG_CPU_PXA300) += zylonite_pxa300.o 33 obj-$(CONFIG_CPU_PXA300) += zylonite_pxa300.o
29 obj-$(CONFIG_CPU_PXA320) += zylonite_pxa320.o 34 obj-$(CONFIG_CPU_PXA320) += zylonite_pxa320.o
30endif 35endif
36obj-$(CONFIG_MACH_LITTLETON) += littleton.o
31 37
32obj-$(CONFIG_MACH_ARMCORE) += cm-x270.o 38obj-$(CONFIG_MACH_ARMCORE) += cm-x270.o
33 39
@@ -41,13 +47,10 @@ led-$(CONFIG_MACH_TRIZEPS4) += leds-trizeps4.o
41obj-$(CONFIG_LEDS) += $(led-y) 47obj-$(CONFIG_LEDS) += $(led-y)
42 48
43# Misc features 49# Misc features
44obj-$(CONFIG_PM) += pm.o sleep.o 50obj-$(CONFIG_PM) += pm.o sleep.o standby.o
51obj-$(CONFIG_CPU_FREQ) += cpu-pxa.o
45obj-$(CONFIG_PXA_SSP) += ssp.o 52obj-$(CONFIG_PXA_SSP) += ssp.o
46 53
47ifeq ($(CONFIG_PXA27x),y)
48obj-$(CONFIG_PM) += standby.o
49endif
50
51ifeq ($(CONFIG_PCI),y) 54ifeq ($(CONFIG_PCI),y)
52obj-$(CONFIG_MACH_ARMCORE) += cm-x270-pci.o 55obj-$(CONFIG_MACH_ARMCORE) += cm-x270-pci.o
53endif 56endif
diff --git a/arch/arm/mach-pxa/akita-ioexp.c b/arch/arm/mach-pxa/akita-ioexp.c
index 12d2fe0ceff6..254892ac30cd 100644
--- a/arch/arm/mach-pxa/akita-ioexp.c
+++ b/arch/arm/mach-pxa/akita-ioexp.c
@@ -29,7 +29,7 @@
29#define MAX7310_TIMEOUT 0x04 29#define MAX7310_TIMEOUT 0x04
30 30
31/* Addresses to scan */ 31/* Addresses to scan */
32static unsigned short normal_i2c[] = { 0x18, I2C_CLIENT_END }; 32static const unsigned short normal_i2c[] = { 0x18, I2C_CLIENT_END };
33 33
34/* I2C Magic */ 34/* I2C Magic */
35I2C_CLIENT_INSMOD; 35I2C_CLIENT_INSMOD;
diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c
index 177664ccb2e2..28cfd71c032d 100644
--- a/arch/arm/mach-pxa/cm-x270.c
+++ b/arch/arm/mach-pxa/cm-x270.c
@@ -487,18 +487,15 @@ static int cmx270_mci_init(struct device *dev,
487 487
488 /* card detect IRQ on GPIO 83 */ 488 /* card detect IRQ on GPIO 83 */
489 pxa_gpio_mode(IRQ_TO_GPIO(CMX270_MMC_IRQ)); 489 pxa_gpio_mode(IRQ_TO_GPIO(CMX270_MMC_IRQ));
490 set_irq_type(CMX270_MMC_IRQ, IRQT_FALLING);
491 490
492 err = request_irq(CMX270_MMC_IRQ, cmx270_detect_int, 491 err = request_irq(CMX270_MMC_IRQ, cmx270_detect_int,
493 IRQF_DISABLED | IRQF_TRIGGER_FALLING, 492 IRQF_DISABLED | IRQF_TRIGGER_FALLING,
494 "MMC card detect", data); 493 "MMC card detect", data);
495 if (err) { 494 if (err)
496 printk(KERN_ERR "cmx270_mci_init: MMC/SD: can't" 495 printk(KERN_ERR "cmx270_mci_init: MMC/SD: can't"
497 " request MMC card detect IRQ\n"); 496 " request MMC card detect IRQ\n");
498 return -1;
499 }
500 497
501 return 0; 498 return err;
502} 499}
503 500
504static void cmx270_mci_setpower(struct device *dev, unsigned int vdd) 501static void cmx270_mci_setpower(struct device *dev, unsigned int vdd)
@@ -566,7 +563,7 @@ static int cmx270_resume(struct sys_device *dev)
566} 563}
567 564
568static struct sysdev_class cmx270_pm_sysclass = { 565static struct sysdev_class cmx270_pm_sysclass = {
569 set_kset_name("pm"), 566 .name = "pm",
570 .resume = cmx270_resume, 567 .resume = cmx270_resume,
571 .suspend = cmx270_suspend, 568 .suspend = cmx270_suspend,
572}; 569};
diff --git a/arch/arm/mach-pxa/colibri.c b/arch/arm/mach-pxa/colibri.c
new file mode 100644
index 000000000000..6db54e31c397
--- /dev/null
+++ b/arch/arm/mach-pxa/colibri.c
@@ -0,0 +1,134 @@
1/*
2 * linux/arch/arm/mach-pxa/colibri.c
3 *
4 * Support for Toradex PXA27x based Colibri module
5 * Daniel Mack <daniel@caiaq.de>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/platform_device.h>
15#include <linux/sysdev.h>
16#include <linux/interrupt.h>
17#include <linux/bitops.h>
18#include <linux/ioport.h>
19#include <linux/delay.h>
20#include <linux/mtd/mtd.h>
21#include <linux/mtd/partitions.h>
22#include <linux/mtd/physmap.h>
23#include <asm/mach-types.h>
24#include <asm/hardware.h>
25#include <asm/irq.h>
26#include <asm/sizes.h>
27#include <asm/mach/arch.h>
28#include <asm/mach/map.h>
29#include <asm/mach/irq.h>
30#include <asm/mach/flash.h>
31#include <asm/arch/pxa-regs.h>
32#include <asm/arch/colibri.h>
33
34#include "generic.h"
35#include "devices.h"
36
37/*
38 * Flash
39 */
40static struct mtd_partition colibri_partitions[] = {
41 {
42 .name = "Bootloader",
43 .offset = 0x00000000,
44 .size = 0x00040000,
45 .mask_flags = MTD_WRITEABLE /* force read-only */
46 }, {
47 .name = "Kernel",
48 .offset = 0x00040000,
49 .size = 0x00400000,
50 .mask_flags = 0
51 }, {
52 .name = "Rootfs",
53 .offset = 0x00440000,
54 .size = MTDPART_SIZ_FULL,
55 .mask_flags = 0
56 }
57};
58
59static struct physmap_flash_data colibri_flash_data[] = {
60 {
61 .width = 4, /* bankwidth in bytes */
62 .parts = colibri_partitions,
63 .nr_parts = ARRAY_SIZE(colibri_partitions)
64 }
65};
66
67static struct resource flash_resource = {
68 .start = PXA_CS0_PHYS,
69 .end = PXA_CS0_PHYS + SZ_32M - 1,
70 .flags = IORESOURCE_MEM,
71};
72
73static struct platform_device flash_device = {
74 .name = "physmap-flash",
75 .id = 0,
76 .dev = {
77 .platform_data = colibri_flash_data,
78 },
79 .resource = &flash_resource,
80 .num_resources = 1,
81};
82
83/*
84 * DM9000 Ethernet
85 */
86static struct resource dm9000_resources[] = {
87 [0] = {
88 .start = COLIBRI_ETH_PHYS,
89 .end = COLIBRI_ETH_PHYS + 3,
90 .flags = IORESOURCE_MEM,
91 },
92 [1] = {
93 .start = COLIBRI_ETH_PHYS + 4,
94 .end = COLIBRI_ETH_PHYS + 4 + 500,
95 .flags = IORESOURCE_MEM,
96 },
97 [2] = {
98 .start = COLIBRI_ETH_IRQ,
99 .end = COLIBRI_ETH_IRQ,
100 .flags = IORESOURCE_IRQ,
101 },
102};
103
104static struct platform_device dm9000_device = {
105 .name = "dm9000",
106 .id = -1,
107 .num_resources = ARRAY_SIZE(dm9000_resources),
108 .resource = dm9000_resources,
109};
110
111static struct platform_device *colibri_devices[] __initdata = {
112 &flash_device,
113 &dm9000_device,
114};
115
116static void __init colibri_init(void)
117{
118 /* DM9000 LAN */
119 pxa_gpio_mode(GPIO78_nCS_2_MD);
120 pxa_gpio_mode(GPIO_DM9000 | GPIO_IN);
121 set_irq_type(COLIBRI_ETH_IRQ, IRQT_FALLING);
122
123 platform_add_devices(colibri_devices, ARRAY_SIZE(colibri_devices));
124}
125
126MACHINE_START(COLIBRI, "Toradex Colibri PXA27x")
127 .phys_io = 0x40000000,
128 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
129 .boot_params = COLIBRI_SDRAM_BASE + 0x100,
130 .init_machine = colibri_init,
131 .map_io = pxa_map_io,
132 .init_irq = pxa27x_init_irq,
133 .timer = &pxa_timer,
134MACHINE_END
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 2363cc64fe07..9292576b83b3 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -21,6 +21,7 @@
21#include <linux/mmc/host.h> 21#include <linux/mmc/host.h>
22#include <linux/pm.h> 22#include <linux/pm.h>
23#include <linux/backlight.h> 23#include <linux/backlight.h>
24#include <video/w100fb.h>
24 25
25#include <asm/setup.h> 26#include <asm/setup.h>
26#include <asm/memory.h> 27#include <asm/memory.h>
@@ -141,6 +142,136 @@ struct corgissp_machinfo corgi_ssp_machinfo = {
141 142
142 143
143/* 144/*
145 * LCD/Framebuffer
146 */
147static void w100_lcdtg_suspend(struct w100fb_par *par)
148{
149 corgi_lcdtg_suspend();
150}
151
152static void w100_lcdtg_init(struct w100fb_par *par)
153{
154 corgi_lcdtg_hw_init(par->xres);
155}
156
157
158static struct w100_tg_info corgi_lcdtg_info = {
159 .change = w100_lcdtg_init,
160 .suspend = w100_lcdtg_suspend,
161 .resume = w100_lcdtg_init,
162};
163
164static struct w100_mem_info corgi_fb_mem = {
165 .ext_cntl = 0x00040003,
166 .sdram_mode_reg = 0x00650021,
167 .ext_timing_cntl = 0x10002a4a,
168 .io_cntl = 0x7ff87012,
169 .size = 0x1fffff,
170};
171
172static struct w100_gen_regs corgi_fb_regs = {
173 .lcd_format = 0x00000003,
174 .lcdd_cntl1 = 0x01CC0000,
175 .lcdd_cntl2 = 0x0003FFFF,
176 .genlcd_cntl1 = 0x00FFFF0D,
177 .genlcd_cntl2 = 0x003F3003,
178 .genlcd_cntl3 = 0x000102aa,
179};
180
181static struct w100_gpio_regs corgi_fb_gpio = {
182 .init_data1 = 0x000000bf,
183 .init_data2 = 0x00000000,
184 .gpio_dir1 = 0x00000000,
185 .gpio_oe1 = 0x03c0feff,
186 .gpio_dir2 = 0x00000000,
187 .gpio_oe2 = 0x00000000,
188};
189
190static struct w100_mode corgi_fb_modes[] = {
191{
192 .xres = 480,
193 .yres = 640,
194 .left_margin = 0x56,
195 .right_margin = 0x55,
196 .upper_margin = 0x03,
197 .lower_margin = 0x00,
198 .crtc_ss = 0x82360056,
199 .crtc_ls = 0xA0280000,
200 .crtc_gs = 0x80280028,
201 .crtc_vpos_gs = 0x02830002,
202 .crtc_rev = 0x00400008,
203 .crtc_dclk = 0xA0000000,
204 .crtc_gclk = 0x8015010F,
205 .crtc_goe = 0x80100110,
206 .crtc_ps1_active = 0x41060010,
207 .pll_freq = 75,
208 .fast_pll_freq = 100,
209 .sysclk_src = CLK_SRC_PLL,
210 .sysclk_divider = 0,
211 .pixclk_src = CLK_SRC_PLL,
212 .pixclk_divider = 2,
213 .pixclk_divider_rotated = 6,
214},{
215 .xres = 240,
216 .yres = 320,
217 .left_margin = 0x27,
218 .right_margin = 0x2e,
219 .upper_margin = 0x01,
220 .lower_margin = 0x00,
221 .crtc_ss = 0x81170027,
222 .crtc_ls = 0xA0140000,
223 .crtc_gs = 0xC0140014,
224 .crtc_vpos_gs = 0x00010141,
225 .crtc_rev = 0x00400008,
226 .crtc_dclk = 0xA0000000,
227 .crtc_gclk = 0x8015010F,
228 .crtc_goe = 0x80100110,
229 .crtc_ps1_active = 0x41060010,
230 .pll_freq = 0,
231 .fast_pll_freq = 0,
232 .sysclk_src = CLK_SRC_XTAL,
233 .sysclk_divider = 0,
234 .pixclk_src = CLK_SRC_XTAL,
235 .pixclk_divider = 1,
236 .pixclk_divider_rotated = 1,
237},
238
239};
240
241static struct w100fb_mach_info corgi_fb_info = {
242 .tg = &corgi_lcdtg_info,
243 .init_mode = INIT_MODE_ROTATED,
244 .mem = &corgi_fb_mem,
245 .regs = &corgi_fb_regs,
246 .modelist = &corgi_fb_modes[0],
247 .num_modes = 2,
248 .gpio = &corgi_fb_gpio,
249 .xtal_freq = 12500000,
250 .xtal_dbl = 0,
251};
252
253static struct resource corgi_fb_resources[] = {
254 [0] = {
255 .start = 0x08000000,
256 .end = 0x08ffffff,
257 .flags = IORESOURCE_MEM,
258 },
259};
260
261static struct platform_device corgifb_device = {
262 .name = "w100fb",
263 .id = -1,
264 .num_resources = ARRAY_SIZE(corgi_fb_resources),
265 .resource = corgi_fb_resources,
266 .dev = {
267 .platform_data = &corgi_fb_info,
268 .parent = &corgissp_device.dev,
269 },
270
271};
272
273
274/*
144 * Corgi Backlight Device 275 * Corgi Backlight Device
145 */ 276 */
146static void corgi_bl_kick_battery(void) 277static void corgi_bl_kick_battery(void)
@@ -154,6 +285,21 @@ static void corgi_bl_kick_battery(void)
154 } 285 }
155} 286}
156 287
288static void corgi_bl_set_intensity(int intensity)
289{
290 if (intensity > 0x10)
291 intensity += 0x10;
292
293 /* Bits 0-4 are accessed via the SSP interface */
294 corgi_ssp_blduty_set(intensity & 0x1f);
295
296 /* Bit 5 is via SCOOP */
297 if (intensity & 0x0020)
298 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT);
299 else
300 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT);
301}
302
157static struct generic_bl_info corgi_bl_machinfo = { 303static struct generic_bl_info corgi_bl_machinfo = {
158 .name = "corgi-bl", 304 .name = "corgi-bl",
159 .max_intensity = 0x2f, 305 .max_intensity = 0x2f,
@@ -190,9 +336,40 @@ static struct platform_device corgiled_device = {
190 .id = -1, 336 .id = -1,
191}; 337};
192 338
339
193/* 340/*
194 * Corgi Touch Screen Device 341 * Corgi Touch Screen Device
195 */ 342 */
343static unsigned long (*get_hsync_invperiod)(struct device *dev);
344
345static void inline sharpsl_wait_sync(int gpio)
346{
347 while((GPLR(gpio) & GPIO_bit(gpio)) == 0);
348 while((GPLR(gpio) & GPIO_bit(gpio)) != 0);
349}
350
351static unsigned long corgi_get_hsync_invperiod(void)
352{
353 if (!get_hsync_invperiod)
354 get_hsync_invperiod = symbol_get(w100fb_get_hsynclen);
355 if (!get_hsync_invperiod)
356 return 0;
357
358 return get_hsync_invperiod(&corgifb_device.dev);
359}
360
361static void corgi_put_hsync(void)
362{
363 if (get_hsync_invperiod)
364 symbol_put(w100fb_get_hsynclen);
365 get_hsync_invperiod = NULL;
366}
367
368static void corgi_wait_hsync(void)
369{
370 sharpsl_wait_sync(CORGI_GPIO_HSYNC);
371}
372
196static struct resource corgits_resources[] = { 373static struct resource corgits_resources[] = {
197 [0] = { 374 [0] = {
198 .start = CORGI_IRQ_GPIO_TP_INT, 375 .start = CORGI_IRQ_GPIO_TP_INT,
@@ -202,9 +379,9 @@ static struct resource corgits_resources[] = {
202}; 379};
203 380
204static struct corgits_machinfo corgi_ts_machinfo = { 381static struct corgits_machinfo corgi_ts_machinfo = {
205 .get_hsync_len = corgi_get_hsync_len, 382 .get_hsync_invperiod = corgi_get_hsync_invperiod,
206 .put_hsync = corgi_put_hsync, 383 .put_hsync = corgi_put_hsync,
207 .wait_hsync = corgi_wait_hsync, 384 .wait_hsync = corgi_wait_hsync,
208}; 385};
209 386
210static struct platform_device corgits_device = { 387static struct platform_device corgits_device = {
@@ -242,12 +419,10 @@ static int corgi_mci_init(struct device *dev, irq_handler_t corgi_detect_int, vo
242 err = request_irq(CORGI_IRQ_GPIO_nSD_DETECT, corgi_detect_int, 419 err = request_irq(CORGI_IRQ_GPIO_nSD_DETECT, corgi_detect_int,
243 IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 420 IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
244 "MMC card detect", data); 421 "MMC card detect", data);
245 if (err) { 422 if (err)
246 printk(KERN_ERR "corgi_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); 423 printk(KERN_ERR "corgi_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
247 return -1;
248 }
249 424
250 return 0; 425 return err;
251} 426}
252 427
253static void corgi_mci_setpower(struct device *dev, unsigned int vdd) 428static void corgi_mci_setpower(struct device *dev, unsigned int vdd)
diff --git a/arch/arm/mach-pxa/corgi_lcd.c b/arch/arm/mach-pxa/corgi_lcd.c
index 365b9435f748..9328df37afd1 100644
--- a/arch/arm/mach-pxa/corgi_lcd.c
+++ b/arch/arm/mach-pxa/corgi_lcd.c
@@ -173,7 +173,7 @@ static void lcdtg_set_phadadj(int mode)
173 173
174static int lcd_inited; 174static int lcd_inited;
175 175
176static void lcdtg_hw_init(int mode) 176void corgi_lcdtg_hw_init(int mode)
177{ 177{
178 if (!lcd_inited) { 178 if (!lcd_inited) {
179 int comadj; 179 int comadj;
@@ -254,7 +254,7 @@ static void lcdtg_hw_init(int mode)
254 } 254 }
255} 255}
256 256
257static void lcdtg_suspend(void) 257void corgi_lcdtg_suspend(void)
258{ 258{
259 /* 60Hz x 2 frame = 16.7msec x 2 = 33.4 msec */ 259 /* 60Hz x 2 frame = 16.7msec x 2 = 33.4 msec */
260 mdelay(34); 260 mdelay(34);
@@ -288,298 +288,3 @@ static void lcdtg_suspend(void)
288 lcd_inited = 0; 288 lcd_inited = 0;
289} 289}
290 290
291
292/*
293 * Corgi w100 Frame Buffer Device
294 */
295#ifdef CONFIG_PXA_SHARP_C7xx
296
297#include <video/w100fb.h>
298
299static void w100_lcdtg_suspend(struct w100fb_par *par)
300{
301 lcdtg_suspend();
302}
303
304static void w100_lcdtg_init(struct w100fb_par *par)
305{
306 lcdtg_hw_init(par->xres);
307}
308
309
310static struct w100_tg_info corgi_lcdtg_info = {
311 .change = w100_lcdtg_init,
312 .suspend = w100_lcdtg_suspend,
313 .resume = w100_lcdtg_init,
314};
315
316static struct w100_mem_info corgi_fb_mem = {
317 .ext_cntl = 0x00040003,
318 .sdram_mode_reg = 0x00650021,
319 .ext_timing_cntl = 0x10002a4a,
320 .io_cntl = 0x7ff87012,
321 .size = 0x1fffff,
322};
323
324static struct w100_gen_regs corgi_fb_regs = {
325 .lcd_format = 0x00000003,
326 .lcdd_cntl1 = 0x01CC0000,
327 .lcdd_cntl2 = 0x0003FFFF,
328 .genlcd_cntl1 = 0x00FFFF0D,
329 .genlcd_cntl2 = 0x003F3003,
330 .genlcd_cntl3 = 0x000102aa,
331};
332
333static struct w100_gpio_regs corgi_fb_gpio = {
334 .init_data1 = 0x000000bf,
335 .init_data2 = 0x00000000,
336 .gpio_dir1 = 0x00000000,
337 .gpio_oe1 = 0x03c0feff,
338 .gpio_dir2 = 0x00000000,
339 .gpio_oe2 = 0x00000000,
340};
341
342static struct w100_mode corgi_fb_modes[] = {
343{
344 .xres = 480,
345 .yres = 640,
346 .left_margin = 0x56,
347 .right_margin = 0x55,
348 .upper_margin = 0x03,
349 .lower_margin = 0x00,
350 .crtc_ss = 0x82360056,
351 .crtc_ls = 0xA0280000,
352 .crtc_gs = 0x80280028,
353 .crtc_vpos_gs = 0x02830002,
354 .crtc_rev = 0x00400008,
355 .crtc_dclk = 0xA0000000,
356 .crtc_gclk = 0x8015010F,
357 .crtc_goe = 0x80100110,
358 .crtc_ps1_active = 0x41060010,
359 .pll_freq = 75,
360 .fast_pll_freq = 100,
361 .sysclk_src = CLK_SRC_PLL,
362 .sysclk_divider = 0,
363 .pixclk_src = CLK_SRC_PLL,
364 .pixclk_divider = 2,
365 .pixclk_divider_rotated = 6,
366},{
367 .xres = 240,
368 .yres = 320,
369 .left_margin = 0x27,
370 .right_margin = 0x2e,
371 .upper_margin = 0x01,
372 .lower_margin = 0x00,
373 .crtc_ss = 0x81170027,
374 .crtc_ls = 0xA0140000,
375 .crtc_gs = 0xC0140014,
376 .crtc_vpos_gs = 0x00010141,
377 .crtc_rev = 0x00400008,
378 .crtc_dclk = 0xA0000000,
379 .crtc_gclk = 0x8015010F,
380 .crtc_goe = 0x80100110,
381 .crtc_ps1_active = 0x41060010,
382 .pll_freq = 0,
383 .fast_pll_freq = 0,
384 .sysclk_src = CLK_SRC_XTAL,
385 .sysclk_divider = 0,
386 .pixclk_src = CLK_SRC_XTAL,
387 .pixclk_divider = 1,
388 .pixclk_divider_rotated = 1,
389},
390
391};
392
393static struct w100fb_mach_info corgi_fb_info = {
394 .tg = &corgi_lcdtg_info,
395 .init_mode = INIT_MODE_ROTATED,
396 .mem = &corgi_fb_mem,
397 .regs = &corgi_fb_regs,
398 .modelist = &corgi_fb_modes[0],
399 .num_modes = 2,
400 .gpio = &corgi_fb_gpio,
401 .xtal_freq = 12500000,
402 .xtal_dbl = 0,
403};
404
405static struct resource corgi_fb_resources[] = {
406 [0] = {
407 .start = 0x08000000,
408 .end = 0x08ffffff,
409 .flags = IORESOURCE_MEM,
410 },
411};
412
413struct platform_device corgifb_device = {
414 .name = "w100fb",
415 .id = -1,
416 .num_resources = ARRAY_SIZE(corgi_fb_resources),
417 .resource = corgi_fb_resources,
418 .dev = {
419 .platform_data = &corgi_fb_info,
420 .parent = &corgissp_device.dev,
421 },
422
423};
424#endif
425
426
427/*
428 * Spitz PXA Frame Buffer Device
429 */
430#ifdef CONFIG_PXA_SHARP_Cxx00
431
432#include <asm/arch/pxafb.h>
433
434void spitz_lcd_power(int on, struct fb_var_screeninfo *var)
435{
436 if (on)
437 lcdtg_hw_init(var->xres);
438 else
439 lcdtg_suspend();
440}
441
442#endif
443
444
445/*
446 * Corgi/Spitz Touchscreen to LCD interface
447 */
448static unsigned long (*get_hsync_time)(struct device *dev);
449
450static void inline sharpsl_wait_sync(int gpio)
451{
452 while((GPLR(gpio) & GPIO_bit(gpio)) == 0);
453 while((GPLR(gpio) & GPIO_bit(gpio)) != 0);
454}
455
456#ifdef CONFIG_PXA_SHARP_C7xx
457unsigned long corgi_get_hsync_len(void)
458{
459 if (!get_hsync_time)
460 get_hsync_time = symbol_get(w100fb_get_hsynclen);
461 if (!get_hsync_time)
462 return 0;
463
464 return get_hsync_time(&corgifb_device.dev);
465}
466
467void corgi_put_hsync(void)
468{
469 if (get_hsync_time)
470 symbol_put(w100fb_get_hsynclen);
471 get_hsync_time = NULL;
472}
473
474void corgi_wait_hsync(void)
475{
476 sharpsl_wait_sync(CORGI_GPIO_HSYNC);
477}
478#endif
479
480#ifdef CONFIG_PXA_SHARP_Cxx00
481static struct device *spitz_pxafb_dev;
482
483static int is_pxafb_device(struct device * dev, void * data)
484{
485 struct platform_device *pdev = container_of(dev, struct platform_device, dev);
486
487 return (strncmp(pdev->name, "pxa2xx-fb", 9) == 0);
488}
489
490unsigned long spitz_get_hsync_len(void)
491{
492#ifdef CONFIG_FB_PXA
493 if (!spitz_pxafb_dev) {
494 spitz_pxafb_dev = bus_find_device(&platform_bus_type, NULL, NULL, is_pxafb_device);
495 if (!spitz_pxafb_dev)
496 return 0;
497 }
498 if (!get_hsync_time)
499 get_hsync_time = symbol_get(pxafb_get_hsync_time);
500 if (!get_hsync_time)
501#endif
502 return 0;
503
504 return pxafb_get_hsync_time(spitz_pxafb_dev);
505}
506
507void spitz_put_hsync(void)
508{
509 put_device(spitz_pxafb_dev);
510 if (get_hsync_time)
511 symbol_put(pxafb_get_hsync_time);
512 spitz_pxafb_dev = NULL;
513 get_hsync_time = NULL;
514}
515
516void spitz_wait_hsync(void)
517{
518 sharpsl_wait_sync(SPITZ_GPIO_HSYNC);
519}
520#endif
521
522/*
523 * Corgi/Spitz Backlight Power
524 */
525#ifdef CONFIG_PXA_SHARP_C7xx
526void corgi_bl_set_intensity(int intensity)
527{
528 if (intensity > 0x10)
529 intensity += 0x10;
530
531 /* Bits 0-4 are accessed via the SSP interface */
532 corgi_ssp_blduty_set(intensity & 0x1f);
533
534 /* Bit 5 is via SCOOP */
535 if (intensity & 0x0020)
536 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT);
537 else
538 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT);
539}
540#endif
541
542
543#if defined(CONFIG_MACH_SPITZ) || defined(CONFIG_MACH_BORZOI)
544void spitz_bl_set_intensity(int intensity)
545{
546 if (intensity > 0x10)
547 intensity += 0x10;
548
549 /* Bits 0-4 are accessed via the SSP interface */
550 corgi_ssp_blduty_set(intensity & 0x1f);
551
552 /* Bit 5 is via SCOOP */
553 if (intensity & 0x0020)
554 reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_CONT);
555 else
556 set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_CONT);
557
558 if (intensity)
559 set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_ON);
560 else
561 reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_ON);
562}
563#endif
564
565#ifdef CONFIG_MACH_AKITA
566void akita_bl_set_intensity(int intensity)
567{
568 if (intensity > 0x10)
569 intensity += 0x10;
570
571 /* Bits 0-4 are accessed via the SSP interface */
572 corgi_ssp_blduty_set(intensity & 0x1f);
573
574 /* Bit 5 is via IO-Expander */
575 if (intensity & 0x0020)
576 akita_reset_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_CONT);
577 else
578 akita_set_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_CONT);
579
580 if (intensity)
581 akita_set_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_ON);
582 else
583 akita_reset_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_ON);
584}
585#endif
diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c
index 40dea3d5142b..efba65edcd51 100644
--- a/arch/arm/mach-pxa/corgi_ssp.c
+++ b/arch/arm/mach-pxa/corgi_ssp.c
@@ -21,6 +21,7 @@
21 21
22#include <asm/arch/ssp.h> 22#include <asm/arch/ssp.h>
23#include <asm/arch/pxa-regs.h> 23#include <asm/arch/pxa-regs.h>
24#include <asm/arch/regs-ssp.h>
24#include "sharpsl.h" 25#include "sharpsl.h"
25 26
26static DEFINE_SPINLOCK(corgi_ssp_lock); 27static DEFINE_SPINLOCK(corgi_ssp_lock);
diff --git a/arch/arm/mach-pxa/cpu-pxa.c b/arch/arm/mach-pxa/cpu-pxa.c
new file mode 100644
index 000000000000..cbc583beedc8
--- /dev/null
+++ b/arch/arm/mach-pxa/cpu-pxa.c
@@ -0,0 +1,294 @@
1/*
2 * linux/arch/arm/mach-pxa/cpu-pxa.c
3 *
4 * Copyright (C) 2002,2003 Intrinsyc Software
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 * History:
21 * 31-Jul-2002 : Initial version [FB]
22 * 29-Jan-2003 : added PXA255 support [FB]
23 * 20-Apr-2003 : ported to v2.5 (Dustin McIntire, Sensoria Corp.)
24 *
25 * Note:
26 * This driver may change the memory bus clock rate, but will not do any
27 * platform specific access timing changes... for example if you have flash
28 * memory connected to CS0, you will need to register a platform specific
29 * notifier which will adjust the memory access strobes to maintain a
30 * minimum strobe width.
31 *
32 */
33
34#include <linux/kernel.h>
35#include <linux/module.h>
36#include <linux/sched.h>
37#include <linux/init.h>
38#include <linux/cpufreq.h>
39
40#include <asm/hardware.h>
41#include <asm/arch/pxa-regs.h>
42#include <asm/arch/pxa2xx-regs.h>
43
44#ifdef DEBUG
45static unsigned int freq_debug;
46MODULE_PARM(freq_debug, "i");
47MODULE_PARM_DESC(freq_debug, "Set the debug messages to on=1/off=0");
48#else
49#define freq_debug 0
50#endif
51
52typedef struct {
53 unsigned int khz;
54 unsigned int membus;
55 unsigned int cccr;
56 unsigned int div2;
57} pxa_freqs_t;
58
59/* Define the refresh period in mSec for the SDRAM and the number of rows */
60#define SDRAM_TREF 64 /* standard 64ms SDRAM */
61#define SDRAM_ROWS 4096 /* 64MB=8192 32MB=4096 */
62#define MDREFR_DRI(x) (((x) * SDRAM_TREF) / (SDRAM_ROWS * 32))
63
64#define CCLKCFG_TURBO 0x1
65#define CCLKCFG_FCS 0x2
66#define PXA25x_MIN_FREQ 99500
67#define PXA25x_MAX_FREQ 398100
68#define MDREFR_DB2_MASK (MDREFR_K2DB2 | MDREFR_K1DB2)
69#define MDREFR_DRI_MASK 0xFFF
70
71
72/* Use the run mode frequencies for the CPUFREQ_POLICY_PERFORMANCE policy */
73static pxa_freqs_t pxa255_run_freqs[] =
74{
75 /* CPU MEMBUS CCCR DIV2*/
76 { 99500, 99500, 0x121, 1}, /* run= 99, turbo= 99, PXbus=50, SDRAM=50 */
77 {132700, 132700, 0x123, 1}, /* run=133, turbo=133, PXbus=66, SDRAM=66 */
78 {199100, 99500, 0x141, 0}, /* run=199, turbo=199, PXbus=99, SDRAM=99 */
79 {265400, 132700, 0x143, 1}, /* run=265, turbo=265, PXbus=133, SDRAM=66 */
80 {331800, 165900, 0x145, 1}, /* run=331, turbo=331, PXbus=166, SDRAM=83 */
81 {398100, 99500, 0x161, 0}, /* run=398, turbo=398, PXbus=196, SDRAM=99 */
82 {0,}
83};
84#define NUM_RUN_FREQS ARRAY_SIZE(pxa255_run_freqs)
85
86static struct cpufreq_frequency_table pxa255_run_freq_table[NUM_RUN_FREQS+1];
87
88/* Use the turbo mode frequencies for the CPUFREQ_POLICY_POWERSAVE policy */
89static pxa_freqs_t pxa255_turbo_freqs[] =
90{
91 /* CPU MEMBUS CCCR DIV2*/
92 { 99500, 99500, 0x121, 1}, /* run=99, turbo= 99, PXbus=50, SDRAM=50 */
93 {199100, 99500, 0x221, 0}, /* run=99, turbo=199, PXbus=50, SDRAM=99 */
94 {298500, 99500, 0x321, 0}, /* run=99, turbo=287, PXbus=50, SDRAM=99 */
95 {298600, 99500, 0x1c1, 0}, /* run=199, turbo=287, PXbus=99, SDRAM=99 */
96 {398100, 99500, 0x241, 0}, /* run=199, turbo=398, PXbus=99, SDRAM=99 */
97 {0,}
98};
99#define NUM_TURBO_FREQS ARRAY_SIZE(pxa255_turbo_freqs)
100
101static struct cpufreq_frequency_table pxa255_turbo_freq_table[NUM_TURBO_FREQS+1];
102
103extern unsigned get_clk_frequency_khz(int info);
104
105/* find a valid frequency point */
106static int pxa_verify_policy(struct cpufreq_policy *policy)
107{
108 struct cpufreq_frequency_table *pxa_freqs_table;
109 int ret;
110
111 if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
112 pxa_freqs_table = pxa255_run_freq_table;
113 } else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) {
114 pxa_freqs_table = pxa255_turbo_freq_table;
115 } else {
116 printk("CPU PXA: Unknown policy found. "
117 "Using CPUFREQ_POLICY_PERFORMANCE\n");
118 pxa_freqs_table = pxa255_run_freq_table;
119 }
120
121 ret = cpufreq_frequency_table_verify(policy, pxa_freqs_table);
122
123 if (freq_debug)
124 pr_debug("Verified CPU policy: %dKhz min to %dKhz max\n",
125 policy->min, policy->max);
126
127 return ret;
128}
129
130static int pxa_set_target(struct cpufreq_policy *policy,
131 unsigned int target_freq,
132 unsigned int relation)
133{
134 struct cpufreq_frequency_table *pxa_freqs_table;
135 pxa_freqs_t *pxa_freq_settings;
136 struct cpufreq_freqs freqs;
137 int idx;
138 unsigned long flags;
139 unsigned int unused, preset_mdrefr, postset_mdrefr;
140 void *ramstart = phys_to_virt(0xa0000000);
141
142 /* Get the current policy */
143 if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
144 pxa_freq_settings = pxa255_run_freqs;
145 pxa_freqs_table = pxa255_run_freq_table;
146 } else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) {
147 pxa_freq_settings = pxa255_turbo_freqs;
148 pxa_freqs_table = pxa255_turbo_freq_table;
149 } else {
150 printk("CPU PXA: Unknown policy found. "
151 "Using CPUFREQ_POLICY_PERFORMANCE\n");
152 pxa_freq_settings = pxa255_run_freqs;
153 pxa_freqs_table = pxa255_run_freq_table;
154 }
155
156 /* Lookup the next frequency */
157 if (cpufreq_frequency_table_target(policy, pxa_freqs_table,
158 target_freq, relation, &idx)) {
159 return -EINVAL;
160 }
161
162 freqs.old = policy->cur;
163 freqs.new = pxa_freq_settings[idx].khz;
164 freqs.cpu = policy->cpu;
165
166 if (freq_debug)
167 pr_debug(KERN_INFO "Changing CPU frequency to %d Mhz, (SDRAM %d Mhz)\n",
168 freqs.new / 1000, (pxa_freq_settings[idx].div2) ?
169 (pxa_freq_settings[idx].membus / 2000) :
170 (pxa_freq_settings[idx].membus / 1000));
171
172 /*
173 * Tell everyone what we're about to do...
174 * you should add a notify client with any platform specific
175 * Vcc changing capability
176 */
177 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
178
179 /* Calculate the next MDREFR. If we're slowing down the SDRAM clock
180 * we need to preset the smaller DRI before the change. If we're speeding
181 * up we need to set the larger DRI value after the change.
182 */
183 preset_mdrefr = postset_mdrefr = MDREFR;
184 if ((MDREFR & MDREFR_DRI_MASK) > MDREFR_DRI(pxa_freq_settings[idx].membus)) {
185 preset_mdrefr = (preset_mdrefr & ~MDREFR_DRI_MASK) |
186 MDREFR_DRI(pxa_freq_settings[idx].membus);
187 }
188 postset_mdrefr = (postset_mdrefr & ~MDREFR_DRI_MASK) |
189 MDREFR_DRI(pxa_freq_settings[idx].membus);
190
191 /* If we're dividing the memory clock by two for the SDRAM clock, this
192 * must be set prior to the change. Clearing the divide must be done
193 * after the change.
194 */
195 if (pxa_freq_settings[idx].div2) {
196 preset_mdrefr |= MDREFR_DB2_MASK;
197 postset_mdrefr |= MDREFR_DB2_MASK;
198 } else {
199 postset_mdrefr &= ~MDREFR_DB2_MASK;
200 }
201
202 local_irq_save(flags);
203
204 /* Set new the CCCR */
205 CCCR = pxa_freq_settings[idx].cccr;
206
207 asm volatile(" \n\
208 ldr r4, [%1] /* load MDREFR */ \n\
209 b 2f \n\
210 .align 5 \n\
2111: \n\
212 str %4, [%1] /* preset the MDREFR */ \n\
213 mcr p14, 0, %2, c6, c0, 0 /* set CCLKCFG[FCS] */ \n\
214 str %5, [%1] /* postset the MDREFR */ \n\
215 \n\
216 b 3f \n\
2172: b 1b \n\
2183: nop \n\
219 "
220 : "=&r" (unused)
221 : "r" (&MDREFR), "r" (CCLKCFG_TURBO|CCLKCFG_FCS), "r" (ramstart),
222 "r" (preset_mdrefr), "r" (postset_mdrefr)
223 : "r4", "r5");
224 local_irq_restore(flags);
225
226 /*
227 * Tell everyone what we've just done...
228 * you should add a notify client with any platform specific
229 * SDRAM refresh timer adjustments
230 */
231 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
232
233 return 0;
234}
235
236static int pxa_cpufreq_init(struct cpufreq_policy *policy)
237{
238 int i;
239
240 /* set default policy and cpuinfo */
241 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
242 policy->policy = CPUFREQ_POLICY_PERFORMANCE;
243 policy->cpuinfo.max_freq = PXA25x_MAX_FREQ;
244 policy->cpuinfo.min_freq = PXA25x_MIN_FREQ;
245 policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */
246 policy->cur = get_clk_frequency_khz(0); /* current freq */
247 policy->min = policy->max = policy->cur;
248
249 /* Generate the run cpufreq_frequency_table struct */
250 for (i = 0; i < NUM_RUN_FREQS; i++) {
251 pxa255_run_freq_table[i].frequency = pxa255_run_freqs[i].khz;
252 pxa255_run_freq_table[i].index = i;
253 }
254
255 pxa255_run_freq_table[i].frequency = CPUFREQ_TABLE_END;
256 /* Generate the turbo cpufreq_frequency_table struct */
257 for (i = 0; i < NUM_TURBO_FREQS; i++) {
258 pxa255_turbo_freq_table[i].frequency = pxa255_turbo_freqs[i].khz;
259 pxa255_turbo_freq_table[i].index = i;
260 }
261 pxa255_turbo_freq_table[i].frequency = CPUFREQ_TABLE_END;
262
263 printk(KERN_INFO "PXA CPU frequency change support initialized\n");
264
265 return 0;
266}
267
268static struct cpufreq_driver pxa_cpufreq_driver = {
269 .verify = pxa_verify_policy,
270 .target = pxa_set_target,
271 .init = pxa_cpufreq_init,
272 .name = "PXA25x",
273};
274
275static int __init pxa_cpu_init(void)
276{
277 int ret = -ENODEV;
278 if (cpu_is_pxa25x())
279 ret = cpufreq_register_driver(&pxa_cpufreq_driver);
280 return ret;
281}
282
283static void __exit pxa_cpu_exit(void)
284{
285 if (cpu_is_pxa25x())
286 cpufreq_unregister_driver(&pxa_cpufreq_driver);
287}
288
289
290MODULE_AUTHOR ("Intrinsyc Software Inc.");
291MODULE_DESCRIPTION ("CPU frequency changing driver for the PXA architecture");
292MODULE_LICENSE("GPL");
293module_init(pxa_cpu_init);
294module_exit(pxa_cpu_exit);
diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c
new file mode 100644
index 000000000000..50ff453ad370
--- /dev/null
+++ b/arch/arm/mach-pxa/devices.c
@@ -0,0 +1,662 @@
1#include <linux/module.h>
2#include <linux/kernel.h>
3#include <linux/init.h>
4#include <linux/platform_device.h>
5#include <linux/dma-mapping.h>
6
7#include <asm/arch/gpio.h>
8#include <asm/arch/udc.h>
9#include <asm/arch/pxafb.h>
10#include <asm/arch/mmc.h>
11#include <asm/arch/irda.h>
12#include <asm/arch/i2c.h>
13
14#include "devices.h"
15
16void __init pxa_register_device(struct platform_device *dev, void *data)
17{
18 int ret;
19
20 dev->dev.platform_data = data;
21
22 ret = platform_device_register(dev);
23 if (ret)
24 dev_err(&dev->dev, "unable to register device: %d\n", ret);
25}
26
27static struct resource pxamci_resources[] = {
28 [0] = {
29 .start = 0x41100000,
30 .end = 0x41100fff,
31 .flags = IORESOURCE_MEM,
32 },
33 [1] = {
34 .start = IRQ_MMC,
35 .end = IRQ_MMC,
36 .flags = IORESOURCE_IRQ,
37 },
38 [2] = {
39 .start = 21,
40 .end = 21,
41 .flags = IORESOURCE_DMA,
42 },
43 [3] = {
44 .start = 22,
45 .end = 22,
46 .flags = IORESOURCE_DMA,
47 },
48};
49
50static u64 pxamci_dmamask = 0xffffffffUL;
51
52struct platform_device pxa_device_mci = {
53 .name = "pxa2xx-mci",
54 .id = 0,
55 .dev = {
56 .dma_mask = &pxamci_dmamask,
57 .coherent_dma_mask = 0xffffffff,
58 },
59 .num_resources = ARRAY_SIZE(pxamci_resources),
60 .resource = pxamci_resources,
61};
62
63void __init pxa_set_mci_info(struct pxamci_platform_data *info)
64{
65 pxa_register_device(&pxa_device_mci, info);
66}
67
68
69static struct pxa2xx_udc_mach_info pxa_udc_info;
70
71void __init pxa_set_udc_info(struct pxa2xx_udc_mach_info *info)
72{
73 memcpy(&pxa_udc_info, info, sizeof *info);
74}
75
76static struct resource pxa2xx_udc_resources[] = {
77 [0] = {
78 .start = 0x40600000,
79 .end = 0x4060ffff,
80 .flags = IORESOURCE_MEM,
81 },
82 [1] = {
83 .start = IRQ_USB,
84 .end = IRQ_USB,
85 .flags = IORESOURCE_IRQ,
86 },
87};
88
89static u64 udc_dma_mask = ~(u32)0;
90
91struct platform_device pxa_device_udc = {
92 .name = "pxa2xx-udc",
93 .id = -1,
94 .resource = pxa2xx_udc_resources,
95 .num_resources = ARRAY_SIZE(pxa2xx_udc_resources),
96 .dev = {
97 .platform_data = &pxa_udc_info,
98 .dma_mask = &udc_dma_mask,
99 }
100};
101
102static struct resource pxafb_resources[] = {
103 [0] = {
104 .start = 0x44000000,
105 .end = 0x4400ffff,
106 .flags = IORESOURCE_MEM,
107 },
108 [1] = {
109 .start = IRQ_LCD,
110 .end = IRQ_LCD,
111 .flags = IORESOURCE_IRQ,
112 },
113};
114
115static u64 fb_dma_mask = ~(u64)0;
116
117struct platform_device pxa_device_fb = {
118 .name = "pxa2xx-fb",
119 .id = -1,
120 .dev = {
121 .dma_mask = &fb_dma_mask,
122 .coherent_dma_mask = 0xffffffff,
123 },
124 .num_resources = ARRAY_SIZE(pxafb_resources),
125 .resource = pxafb_resources,
126};
127
128void __init set_pxa_fb_info(struct pxafb_mach_info *info)
129{
130 pxa_register_device(&pxa_device_fb, info);
131}
132
133void __init set_pxa_fb_parent(struct device *parent_dev)
134{
135 pxa_device_fb.dev.parent = parent_dev;
136}
137
138static struct resource pxa_resource_ffuart[] = {
139 {
140 .start = __PREG(FFUART),
141 .end = __PREG(FFUART) + 35,
142 .flags = IORESOURCE_MEM,
143 }, {
144 .start = IRQ_FFUART,
145 .end = IRQ_FFUART,
146 .flags = IORESOURCE_IRQ,
147 }
148};
149
150struct platform_device pxa_device_ffuart= {
151 .name = "pxa2xx-uart",
152 .id = 0,
153 .resource = pxa_resource_ffuart,
154 .num_resources = ARRAY_SIZE(pxa_resource_ffuart),
155};
156
157static struct resource pxa_resource_btuart[] = {
158 {
159 .start = __PREG(BTUART),
160 .end = __PREG(BTUART) + 35,
161 .flags = IORESOURCE_MEM,
162 }, {
163 .start = IRQ_BTUART,
164 .end = IRQ_BTUART,
165 .flags = IORESOURCE_IRQ,
166 }
167};
168
169struct platform_device pxa_device_btuart = {
170 .name = "pxa2xx-uart",
171 .id = 1,
172 .resource = pxa_resource_btuart,
173 .num_resources = ARRAY_SIZE(pxa_resource_btuart),
174};
175
176static struct resource pxa_resource_stuart[] = {
177 {
178 .start = __PREG(STUART),
179 .end = __PREG(STUART) + 35,
180 .flags = IORESOURCE_MEM,
181 }, {
182 .start = IRQ_STUART,
183 .end = IRQ_STUART,
184 .flags = IORESOURCE_IRQ,
185 }
186};
187
188struct platform_device pxa_device_stuart = {
189 .name = "pxa2xx-uart",
190 .id = 2,
191 .resource = pxa_resource_stuart,
192 .num_resources = ARRAY_SIZE(pxa_resource_stuart),
193};
194
195static struct resource pxa_resource_hwuart[] = {
196 {
197 .start = __PREG(HWUART),
198 .end = __PREG(HWUART) + 47,
199 .flags = IORESOURCE_MEM,
200 }, {
201 .start = IRQ_HWUART,
202 .end = IRQ_HWUART,
203 .flags = IORESOURCE_IRQ,
204 }
205};
206
207struct platform_device pxa_device_hwuart = {
208 .name = "pxa2xx-uart",
209 .id = 3,
210 .resource = pxa_resource_hwuart,
211 .num_resources = ARRAY_SIZE(pxa_resource_hwuart),
212};
213
214static struct resource pxai2c_resources[] = {
215 {
216 .start = 0x40301680,
217 .end = 0x403016a3,
218 .flags = IORESOURCE_MEM,
219 }, {
220 .start = IRQ_I2C,
221 .end = IRQ_I2C,
222 .flags = IORESOURCE_IRQ,
223 },
224};
225
226struct platform_device pxa_device_i2c = {
227 .name = "pxa2xx-i2c",
228 .id = 0,
229 .resource = pxai2c_resources,
230 .num_resources = ARRAY_SIZE(pxai2c_resources),
231};
232
233void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info)
234{
235 pxa_register_device(&pxa_device_i2c, info);
236}
237
238static struct resource pxai2s_resources[] = {
239 {
240 .start = 0x40400000,
241 .end = 0x40400083,
242 .flags = IORESOURCE_MEM,
243 }, {
244 .start = IRQ_I2S,
245 .end = IRQ_I2S,
246 .flags = IORESOURCE_IRQ,
247 },
248};
249
250struct platform_device pxa_device_i2s = {
251 .name = "pxa2xx-i2s",
252 .id = -1,
253 .resource = pxai2s_resources,
254 .num_resources = ARRAY_SIZE(pxai2s_resources),
255};
256
257static u64 pxaficp_dmamask = ~(u32)0;
258
259struct platform_device pxa_device_ficp = {
260 .name = "pxa2xx-ir",
261 .id = -1,
262 .dev = {
263 .dma_mask = &pxaficp_dmamask,
264 .coherent_dma_mask = 0xffffffff,
265 },
266};
267
268void __init pxa_set_ficp_info(struct pxaficp_platform_data *info)
269{
270 pxa_register_device(&pxa_device_ficp, info);
271}
272
273struct platform_device pxa_device_rtc = {
274 .name = "sa1100-rtc",
275 .id = -1,
276};
277
278#ifdef CONFIG_PXA25x
279
280static u64 pxa25x_ssp_dma_mask = DMA_BIT_MASK(32);
281
282static struct resource pxa25x_resource_ssp[] = {
283 [0] = {
284 .start = 0x41000000,
285 .end = 0x4100001f,
286 .flags = IORESOURCE_MEM,
287 },
288 [1] = {
289 .start = IRQ_SSP,
290 .end = IRQ_SSP,
291 .flags = IORESOURCE_IRQ,
292 },
293 [2] = {
294 /* DRCMR for RX */
295 .start = 13,
296 .end = 13,
297 .flags = IORESOURCE_DMA,
298 },
299 [3] = {
300 /* DRCMR for TX */
301 .start = 14,
302 .end = 14,
303 .flags = IORESOURCE_DMA,
304 },
305};
306
307struct platform_device pxa25x_device_ssp = {
308 .name = "pxa25x-ssp",
309 .id = 0,
310 .dev = {
311 .dma_mask = &pxa25x_ssp_dma_mask,
312 .coherent_dma_mask = DMA_BIT_MASK(32),
313 },
314 .resource = pxa25x_resource_ssp,
315 .num_resources = ARRAY_SIZE(pxa25x_resource_ssp),
316};
317
318static u64 pxa25x_nssp_dma_mask = DMA_BIT_MASK(32);
319
320static struct resource pxa25x_resource_nssp[] = {
321 [0] = {
322 .start = 0x41400000,
323 .end = 0x4140002f,
324 .flags = IORESOURCE_MEM,
325 },
326 [1] = {
327 .start = IRQ_NSSP,
328 .end = IRQ_NSSP,
329 .flags = IORESOURCE_IRQ,
330 },
331 [2] = {
332 /* DRCMR for RX */
333 .start = 15,
334 .end = 15,
335 .flags = IORESOURCE_DMA,
336 },
337 [3] = {
338 /* DRCMR for TX */
339 .start = 16,
340 .end = 16,
341 .flags = IORESOURCE_DMA,
342 },
343};
344
345struct platform_device pxa25x_device_nssp = {
346 .name = "pxa25x-nssp",
347 .id = 1,
348 .dev = {
349 .dma_mask = &pxa25x_nssp_dma_mask,
350 .coherent_dma_mask = DMA_BIT_MASK(32),
351 },
352 .resource = pxa25x_resource_nssp,
353 .num_resources = ARRAY_SIZE(pxa25x_resource_nssp),
354};
355
356static u64 pxa25x_assp_dma_mask = DMA_BIT_MASK(32);
357
358static struct resource pxa25x_resource_assp[] = {
359 [0] = {
360 .start = 0x41500000,
361 .end = 0x4150002f,
362 .flags = IORESOURCE_MEM,
363 },
364 [1] = {
365 .start = IRQ_ASSP,
366 .end = IRQ_ASSP,
367 .flags = IORESOURCE_IRQ,
368 },
369 [2] = {
370 /* DRCMR for RX */
371 .start = 23,
372 .end = 23,
373 .flags = IORESOURCE_DMA,
374 },
375 [3] = {
376 /* DRCMR for TX */
377 .start = 24,
378 .end = 24,
379 .flags = IORESOURCE_DMA,
380 },
381};
382
383struct platform_device pxa25x_device_assp = {
384 /* ASSP is basically equivalent to NSSP */
385 .name = "pxa25x-nssp",
386 .id = 2,
387 .dev = {
388 .dma_mask = &pxa25x_assp_dma_mask,
389 .coherent_dma_mask = DMA_BIT_MASK(32),
390 },
391 .resource = pxa25x_resource_assp,
392 .num_resources = ARRAY_SIZE(pxa25x_resource_assp),
393};
394#endif /* CONFIG_PXA25x */
395
396#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
397
398static u64 pxa27x_ohci_dma_mask = DMA_BIT_MASK(32);
399
400static struct resource pxa27x_resource_ohci[] = {
401 [0] = {
402 .start = 0x4C000000,
403 .end = 0x4C00ff6f,
404 .flags = IORESOURCE_MEM,
405 },
406 [1] = {
407 .start = IRQ_USBH1,
408 .end = IRQ_USBH1,
409 .flags = IORESOURCE_IRQ,
410 },
411};
412
413struct platform_device pxa27x_device_ohci = {
414 .name = "pxa27x-ohci",
415 .id = -1,
416 .dev = {
417 .dma_mask = &pxa27x_ohci_dma_mask,
418 .coherent_dma_mask = DMA_BIT_MASK(32),
419 },
420 .num_resources = ARRAY_SIZE(pxa27x_resource_ohci),
421 .resource = pxa27x_resource_ohci,
422};
423
424void __init pxa_set_ohci_info(struct pxaohci_platform_data *info)
425{
426 pxa_register_device(&pxa27x_device_ohci, info);
427}
428
429static u64 pxa27x_ssp1_dma_mask = DMA_BIT_MASK(32);
430
431static struct resource pxa27x_resource_ssp1[] = {
432 [0] = {
433 .start = 0x41000000,
434 .end = 0x4100003f,
435 .flags = IORESOURCE_MEM,
436 },
437 [1] = {
438 .start = IRQ_SSP,
439 .end = IRQ_SSP,
440 .flags = IORESOURCE_IRQ,
441 },
442 [2] = {
443 /* DRCMR for RX */
444 .start = 13,
445 .end = 13,
446 .flags = IORESOURCE_DMA,
447 },
448 [3] = {
449 /* DRCMR for TX */
450 .start = 14,
451 .end = 14,
452 .flags = IORESOURCE_DMA,
453 },
454};
455
456struct platform_device pxa27x_device_ssp1 = {
457 .name = "pxa27x-ssp",
458 .id = 0,
459 .dev = {
460 .dma_mask = &pxa27x_ssp1_dma_mask,
461 .coherent_dma_mask = DMA_BIT_MASK(32),
462 },
463 .resource = pxa27x_resource_ssp1,
464 .num_resources = ARRAY_SIZE(pxa27x_resource_ssp1),
465};
466
467static u64 pxa27x_ssp2_dma_mask = DMA_BIT_MASK(32);
468
469static struct resource pxa27x_resource_ssp2[] = {
470 [0] = {
471 .start = 0x41700000,
472 .end = 0x4170003f,
473 .flags = IORESOURCE_MEM,
474 },
475 [1] = {
476 .start = IRQ_SSP2,
477 .end = IRQ_SSP2,
478 .flags = IORESOURCE_IRQ,
479 },
480 [2] = {
481 /* DRCMR for RX */
482 .start = 15,
483 .end = 15,
484 .flags = IORESOURCE_DMA,
485 },
486 [3] = {
487 /* DRCMR for TX */
488 .start = 16,
489 .end = 16,
490 .flags = IORESOURCE_DMA,
491 },
492};
493
494struct platform_device pxa27x_device_ssp2 = {
495 .name = "pxa27x-ssp",
496 .id = 1,
497 .dev = {
498 .dma_mask = &pxa27x_ssp2_dma_mask,
499 .coherent_dma_mask = DMA_BIT_MASK(32),
500 },
501 .resource = pxa27x_resource_ssp2,
502 .num_resources = ARRAY_SIZE(pxa27x_resource_ssp2),
503};
504
505static u64 pxa27x_ssp3_dma_mask = DMA_BIT_MASK(32);
506
507static struct resource pxa27x_resource_ssp3[] = {
508 [0] = {
509 .start = 0x41900000,
510 .end = 0x4190003f,
511 .flags = IORESOURCE_MEM,
512 },
513 [1] = {
514 .start = IRQ_SSP3,
515 .end = IRQ_SSP3,
516 .flags = IORESOURCE_IRQ,
517 },
518 [2] = {
519 /* DRCMR for RX */
520 .start = 66,
521 .end = 66,
522 .flags = IORESOURCE_DMA,
523 },
524 [3] = {
525 /* DRCMR for TX */
526 .start = 67,
527 .end = 67,
528 .flags = IORESOURCE_DMA,
529 },
530};
531
532struct platform_device pxa27x_device_ssp3 = {
533 .name = "pxa27x-ssp",
534 .id = 2,
535 .dev = {
536 .dma_mask = &pxa27x_ssp3_dma_mask,
537 .coherent_dma_mask = DMA_BIT_MASK(32),
538 },
539 .resource = pxa27x_resource_ssp3,
540 .num_resources = ARRAY_SIZE(pxa27x_resource_ssp3),
541};
542#endif /* CONFIG_PXA27x || CONFIG_PXA3xx */
543
544#ifdef CONFIG_PXA3xx
545static u64 pxa3xx_ssp4_dma_mask = DMA_BIT_MASK(32);
546
547static struct resource pxa3xx_resource_ssp4[] = {
548 [0] = {
549 .start = 0x41a00000,
550 .end = 0x41a0003f,
551 .flags = IORESOURCE_MEM,
552 },
553 [1] = {
554 .start = IRQ_SSP4,
555 .end = IRQ_SSP4,
556 .flags = IORESOURCE_IRQ,
557 },
558 [2] = {
559 /* DRCMR for RX */
560 .start = 2,
561 .end = 2,
562 .flags = IORESOURCE_DMA,
563 },
564 [3] = {
565 /* DRCMR for TX */
566 .start = 3,
567 .end = 3,
568 .flags = IORESOURCE_DMA,
569 },
570};
571
572struct platform_device pxa3xx_device_ssp4 = {
573 /* PXA3xx SSP is basically equivalent to PXA27x */
574 .name = "pxa27x-ssp",
575 .id = 3,
576 .dev = {
577 .dma_mask = &pxa3xx_ssp4_dma_mask,
578 .coherent_dma_mask = DMA_BIT_MASK(32),
579 },
580 .resource = pxa3xx_resource_ssp4,
581 .num_resources = ARRAY_SIZE(pxa3xx_resource_ssp4),
582};
583
584static struct resource pxa3xx_resources_mci2[] = {
585 [0] = {
586 .start = 0x42000000,
587 .end = 0x42000fff,
588 .flags = IORESOURCE_MEM,
589 },
590 [1] = {
591 .start = IRQ_MMC2,
592 .end = IRQ_MMC2,
593 .flags = IORESOURCE_IRQ,
594 },
595 [2] = {
596 .start = 93,
597 .end = 93,
598 .flags = IORESOURCE_DMA,
599 },
600 [3] = {
601 .start = 94,
602 .end = 94,
603 .flags = IORESOURCE_DMA,
604 },
605};
606
607struct platform_device pxa3xx_device_mci2 = {
608 .name = "pxa2xx-mci",
609 .id = 1,
610 .dev = {
611 .dma_mask = &pxamci_dmamask,
612 .coherent_dma_mask = 0xffffffff,
613 },
614 .num_resources = ARRAY_SIZE(pxa3xx_resources_mci2),
615 .resource = pxa3xx_resources_mci2,
616};
617
618void __init pxa3xx_set_mci2_info(struct pxamci_platform_data *info)
619{
620 pxa_register_device(&pxa3xx_device_mci2, info);
621}
622
623static struct resource pxa3xx_resources_mci3[] = {
624 [0] = {
625 .start = 0x42500000,
626 .end = 0x42500fff,
627 .flags = IORESOURCE_MEM,
628 },
629 [1] = {
630 .start = IRQ_MMC3,
631 .end = IRQ_MMC3,
632 .flags = IORESOURCE_IRQ,
633 },
634 [2] = {
635 .start = 100,
636 .end = 100,
637 .flags = IORESOURCE_DMA,
638 },
639 [3] = {
640 .start = 101,
641 .end = 101,
642 .flags = IORESOURCE_DMA,
643 },
644};
645
646struct platform_device pxa3xx_device_mci3 = {
647 .name = "pxa2xx-mci",
648 .id = 2,
649 .dev = {
650 .dma_mask = &pxamci_dmamask,
651 .coherent_dma_mask = 0xffffffff,
652 },
653 .num_resources = ARRAY_SIZE(pxa3xx_resources_mci3),
654 .resource = pxa3xx_resources_mci3,
655};
656
657void __init pxa3xx_set_mci3_info(struct pxamci_platform_data *info)
658{
659 pxa_register_device(&pxa3xx_device_mci3, info);
660}
661
662#endif /* CONFIG_PXA3xx */
diff --git a/arch/arm/mach-pxa/devices.h b/arch/arm/mach-pxa/devices.h
index 94c8d5cdd60a..96c7c8909068 100644
--- a/arch/arm/mach-pxa/devices.h
+++ b/arch/arm/mach-pxa/devices.h
@@ -1,4 +1,6 @@
1extern struct platform_device pxa_device_mci; 1extern struct platform_device pxa_device_mci;
2extern struct platform_device pxa3xx_device_mci2;
3extern struct platform_device pxa3xx_device_mci3;
2extern struct platform_device pxa_device_udc; 4extern struct platform_device pxa_device_udc;
3extern struct platform_device pxa_device_fb; 5extern struct platform_device pxa_device_fb;
4extern struct platform_device pxa_device_ffuart; 6extern struct platform_device pxa_device_ffuart;
@@ -12,3 +14,13 @@ extern struct platform_device pxa_device_rtc;
12 14
13extern struct platform_device pxa27x_device_i2c_power; 15extern struct platform_device pxa27x_device_i2c_power;
14extern struct platform_device pxa27x_device_ohci; 16extern struct platform_device pxa27x_device_ohci;
17
18extern struct platform_device pxa25x_device_ssp;
19extern struct platform_device pxa25x_device_nssp;
20extern struct platform_device pxa25x_device_assp;
21extern struct platform_device pxa27x_device_ssp1;
22extern struct platform_device pxa27x_device_ssp2;
23extern struct platform_device pxa27x_device_ssp3;
24extern struct platform_device pxa3xx_device_ssp4;
25
26void __init pxa_register_device(struct platform_device *dev, void *data);
diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c
new file mode 100644
index 000000000000..ee0ae93c876a
--- /dev/null
+++ b/arch/arm/mach-pxa/eseries.c
@@ -0,0 +1,101 @@
1/*
2 * Hardware definitions for the Toshiba eseries PDAs
3 *
4 * Copyright (c) 2003 Ian Molton <spyro@f2s.com>
5 *
6 * This file is licensed under
7 * the terms of the GNU General Public License version 2. This program
8 * is licensed "as is" without any warranty of any kind, whether express
9 * or implied.
10 *
11 */
12
13#include <linux/init.h>
14
15#include <asm/setup.h>
16#include <asm/mach/arch.h>
17#include <asm/arch/hardware.h>
18#include <asm/mach-types.h>
19
20#include <generic.h>
21
22/* Only e800 has 128MB RAM */
23static void __init eseries_fixup(struct machine_desc *desc,
24 struct tag *tags, char **cmdline, struct meminfo *mi)
25{
26 mi->nr_banks=1;
27 mi->bank[0].start = 0xa0000000;
28 mi->bank[0].node = 0;
29 if (machine_is_e800())
30 mi->bank[0].size = (128*1024*1024);
31 else
32 mi->bank[0].size = (64*1024*1024);
33}
34
35/* e-series machine definitions */
36
37#ifdef CONFIG_MACH_E330
38MACHINE_START(E330, "Toshiba e330")
39 /* Maintainer: Ian Molton (spyro@f2s.com) */
40 .phys_io = 0x40000000,
41 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
42 .boot_params = 0xa0000100,
43 .map_io = pxa_map_io,
44 .init_irq = pxa25x_init_irq,
45 .fixup = eseries_fixup,
46 .timer = &pxa_timer,
47MACHINE_END
48#endif
49
50#ifdef CONFIG_MACH_E740
51MACHINE_START(E740, "Toshiba e740")
52 /* Maintainer: Ian Molton (spyro@f2s.com) */
53 .phys_io = 0x40000000,
54 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
55 .boot_params = 0xa0000100,
56 .map_io = pxa_map_io,
57 .init_irq = pxa25x_init_irq,
58 .fixup = eseries_fixup,
59 .timer = &pxa_timer,
60MACHINE_END
61#endif
62
63#ifdef CONFIG_MACH_E750
64MACHINE_START(E750, "Toshiba e750")
65 /* Maintainer: Ian Molton (spyro@f2s.com) */
66 .phys_io = 0x40000000,
67 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
68 .boot_params = 0xa0000100,
69 .map_io = pxa_map_io,
70 .init_irq = pxa25x_init_irq,
71 .fixup = eseries_fixup,
72 .timer = &pxa_timer,
73MACHINE_END
74#endif
75
76#ifdef CONFIG_MACH_E400
77MACHINE_START(E400, "Toshiba e400")
78 /* Maintainer: Ian Molton (spyro@f2s.com) */
79 .phys_io = 0x40000000,
80 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
81 .boot_params = 0xa0000100,
82 .map_io = pxa_map_io,
83 .init_irq = pxa25x_init_irq,
84 .fixup = eseries_fixup,
85 .timer = &pxa_timer,
86MACHINE_END
87#endif
88
89#ifdef CONFIG_MACH_E800
90MACHINE_START(E800, "Toshiba e800")
91 /* Maintainer: Ian Molton (spyro@f2s.com) */
92 .phys_io = 0x40000000,
93 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
94 .boot_params = 0xa0000100,
95 .map_io = pxa_map_io,
96 .init_irq = pxa25x_init_irq,
97 .fixup = eseries_fixup,
98 .timer = &pxa_timer,
99MACHINE_END
100#endif
101
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index 1c34946ee16e..698aeec52961 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -20,7 +20,6 @@
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/platform_device.h>
24#include <linux/ioport.h> 23#include <linux/ioport.h>
25#include <linux/pm.h> 24#include <linux/pm.h>
26#include <linux/string.h> 25#include <linux/string.h>
@@ -33,13 +32,7 @@
33 32
34#include <asm/arch/pxa-regs.h> 33#include <asm/arch/pxa-regs.h>
35#include <asm/arch/gpio.h> 34#include <asm/arch/gpio.h>
36#include <asm/arch/udc.h>
37#include <asm/arch/pxafb.h>
38#include <asm/arch/mmc.h>
39#include <asm/arch/irda.h>
40#include <asm/arch/i2c.h>
41 35
42#include "devices.h"
43#include "generic.h" 36#include "generic.h"
44 37
45/* 38/*
@@ -203,7 +196,7 @@ static struct map_desc standard_io_desc[] __initdata = {
203 }, { /* Mem Ctl */ 196 }, { /* Mem Ctl */
204 .virtual = 0xf6000000, 197 .virtual = 0xf6000000,
205 .pfn = __phys_to_pfn(0x48000000), 198 .pfn = __phys_to_pfn(0x48000000),
206 .length = 0x00100000, 199 .length = 0x00200000,
207 .type = MT_DEVICE 200 .type = MT_DEVICE
208 }, { /* USB host */ 201 }, { /* USB host */
209 .virtual = 0xf8000000, 202 .virtual = 0xf8000000,
@@ -233,245 +226,3 @@ void __init pxa_map_io(void)
233 iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc)); 226 iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
234 get_clk_frequency_khz(1); 227 get_clk_frequency_khz(1);
235} 228}
236
237
238static struct resource pxamci_resources[] = {
239 [0] = {
240 .start = 0x41100000,
241 .end = 0x41100fff,
242 .flags = IORESOURCE_MEM,
243 },
244 [1] = {
245 .start = IRQ_MMC,
246 .end = IRQ_MMC,
247 .flags = IORESOURCE_IRQ,
248 },
249};
250
251static u64 pxamci_dmamask = 0xffffffffUL;
252
253struct platform_device pxa_device_mci = {
254 .name = "pxa2xx-mci",
255 .id = -1,
256 .dev = {
257 .dma_mask = &pxamci_dmamask,
258 .coherent_dma_mask = 0xffffffff,
259 },
260 .num_resources = ARRAY_SIZE(pxamci_resources),
261 .resource = pxamci_resources,
262};
263
264void __init pxa_set_mci_info(struct pxamci_platform_data *info)
265{
266 pxa_device_mci.dev.platform_data = info;
267}
268
269
270static struct pxa2xx_udc_mach_info pxa_udc_info;
271
272void __init pxa_set_udc_info(struct pxa2xx_udc_mach_info *info)
273{
274 memcpy(&pxa_udc_info, info, sizeof *info);
275}
276
277static struct resource pxa2xx_udc_resources[] = {
278 [0] = {
279 .start = 0x40600000,
280 .end = 0x4060ffff,
281 .flags = IORESOURCE_MEM,
282 },
283 [1] = {
284 .start = IRQ_USB,
285 .end = IRQ_USB,
286 .flags = IORESOURCE_IRQ,
287 },
288};
289
290static u64 udc_dma_mask = ~(u32)0;
291
292struct platform_device pxa_device_udc = {
293 .name = "pxa2xx-udc",
294 .id = -1,
295 .resource = pxa2xx_udc_resources,
296 .num_resources = ARRAY_SIZE(pxa2xx_udc_resources),
297 .dev = {
298 .platform_data = &pxa_udc_info,
299 .dma_mask = &udc_dma_mask,
300 }
301};
302
303static struct resource pxafb_resources[] = {
304 [0] = {
305 .start = 0x44000000,
306 .end = 0x4400ffff,
307 .flags = IORESOURCE_MEM,
308 },
309 [1] = {
310 .start = IRQ_LCD,
311 .end = IRQ_LCD,
312 .flags = IORESOURCE_IRQ,
313 },
314};
315
316static u64 fb_dma_mask = ~(u64)0;
317
318struct platform_device pxa_device_fb = {
319 .name = "pxa2xx-fb",
320 .id = -1,
321 .dev = {
322 .dma_mask = &fb_dma_mask,
323 .coherent_dma_mask = 0xffffffff,
324 },
325 .num_resources = ARRAY_SIZE(pxafb_resources),
326 .resource = pxafb_resources,
327};
328
329void __init set_pxa_fb_info(struct pxafb_mach_info *info)
330{
331 pxa_device_fb.dev.platform_data = info;
332}
333
334void __init set_pxa_fb_parent(struct device *parent_dev)
335{
336 pxa_device_fb.dev.parent = parent_dev;
337}
338
339static struct resource pxa_resource_ffuart[] = {
340 {
341 .start = __PREG(FFUART),
342 .end = __PREG(FFUART) + 35,
343 .flags = IORESOURCE_MEM,
344 }, {
345 .start = IRQ_FFUART,
346 .end = IRQ_FFUART,
347 .flags = IORESOURCE_IRQ,
348 }
349};
350
351struct platform_device pxa_device_ffuart= {
352 .name = "pxa2xx-uart",
353 .id = 0,
354 .resource = pxa_resource_ffuart,
355 .num_resources = ARRAY_SIZE(pxa_resource_ffuart),
356};
357
358static struct resource pxa_resource_btuart[] = {
359 {
360 .start = __PREG(BTUART),
361 .end = __PREG(BTUART) + 35,
362 .flags = IORESOURCE_MEM,
363 }, {
364 .start = IRQ_BTUART,
365 .end = IRQ_BTUART,
366 .flags = IORESOURCE_IRQ,
367 }
368};
369
370struct platform_device pxa_device_btuart = {
371 .name = "pxa2xx-uart",
372 .id = 1,
373 .resource = pxa_resource_btuart,
374 .num_resources = ARRAY_SIZE(pxa_resource_btuart),
375};
376
377static struct resource pxa_resource_stuart[] = {
378 {
379 .start = __PREG(STUART),
380 .end = __PREG(STUART) + 35,
381 .flags = IORESOURCE_MEM,
382 }, {
383 .start = IRQ_STUART,
384 .end = IRQ_STUART,
385 .flags = IORESOURCE_IRQ,
386 }
387};
388
389struct platform_device pxa_device_stuart = {
390 .name = "pxa2xx-uart",
391 .id = 2,
392 .resource = pxa_resource_stuart,
393 .num_resources = ARRAY_SIZE(pxa_resource_stuart),
394};
395
396static struct resource pxa_resource_hwuart[] = {
397 {
398 .start = __PREG(HWUART),
399 .end = __PREG(HWUART) + 47,
400 .flags = IORESOURCE_MEM,
401 }, {
402 .start = IRQ_HWUART,
403 .end = IRQ_HWUART,
404 .flags = IORESOURCE_IRQ,
405 }
406};
407
408struct platform_device pxa_device_hwuart = {
409 .name = "pxa2xx-uart",
410 .id = 3,
411 .resource = pxa_resource_hwuart,
412 .num_resources = ARRAY_SIZE(pxa_resource_hwuart),
413};
414
415static struct resource pxai2c_resources[] = {
416 {
417 .start = 0x40301680,
418 .end = 0x403016a3,
419 .flags = IORESOURCE_MEM,
420 }, {
421 .start = IRQ_I2C,
422 .end = IRQ_I2C,
423 .flags = IORESOURCE_IRQ,
424 },
425};
426
427struct platform_device pxa_device_i2c = {
428 .name = "pxa2xx-i2c",
429 .id = 0,
430 .resource = pxai2c_resources,
431 .num_resources = ARRAY_SIZE(pxai2c_resources),
432};
433
434void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info)
435{
436 pxa_device_i2c.dev.platform_data = info;
437}
438
439static struct resource pxai2s_resources[] = {
440 {
441 .start = 0x40400000,
442 .end = 0x40400083,
443 .flags = IORESOURCE_MEM,
444 }, {
445 .start = IRQ_I2S,
446 .end = IRQ_I2S,
447 .flags = IORESOURCE_IRQ,
448 },
449};
450
451struct platform_device pxa_device_i2s = {
452 .name = "pxa2xx-i2s",
453 .id = -1,
454 .resource = pxai2s_resources,
455 .num_resources = ARRAY_SIZE(pxai2s_resources),
456};
457
458static u64 pxaficp_dmamask = ~(u32)0;
459
460struct platform_device pxa_device_ficp = {
461 .name = "pxa2xx-ir",
462 .id = -1,
463 .dev = {
464 .dma_mask = &pxaficp_dmamask,
465 .coherent_dma_mask = 0xffffffff,
466 },
467};
468
469void __init pxa_set_ficp_info(struct pxaficp_platform_data *info)
470{
471 pxa_device_ficp.dev.platform_data = info;
472}
473
474struct platform_device pxa_device_rtc = {
475 .name = "sa1100-rtc",
476 .id = -1,
477};
diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c
index 465108da2851..0a9434432c55 100644
--- a/arch/arm/mach-pxa/idp.c
+++ b/arch/arm/mach-pxa/idp.c
@@ -54,7 +54,7 @@ static struct resource smc91x_resources[] = {
54 [1] = { 54 [1] = {
55 .start = IRQ_GPIO(4), 55 .start = IRQ_GPIO(4),
56 .end = IRQ_GPIO(4), 56 .end = IRQ_GPIO(4),
57 .flags = IORESOURCE_IRQ, 57 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
58 } 58 }
59}; 59};
60 60
diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c
new file mode 100644
index 000000000000..0a4b54c21314
--- /dev/null
+++ b/arch/arm/mach-pxa/littleton.c
@@ -0,0 +1,325 @@
1/*
2 * linux/arch/arm/mach-pxa/littleton.c
3 *
4 * Support for the Marvell Littleton Development Platform.
5 *
6 * Author: Jason Chagas (largely modified code)
7 * Created: Nov 20, 2006
8 * Copyright: (C) Copyright 2006 Marvell International Ltd.
9 *
10 * 2007-11-22 modified to align with latest kernel
11 * eric miao <eric.miao@marvell.com>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * publishhed by the Free Software Foundation.
16 */
17
18#include <linux/init.h>
19#include <linux/interrupt.h>
20#include <linux/delay.h>
21#include <linux/platform_device.h>
22#include <linux/clk.h>
23
24#include <asm/types.h>
25#include <asm/setup.h>
26#include <asm/memory.h>
27#include <asm/mach-types.h>
28#include <asm/hardware.h>
29#include <asm/irq.h>
30
31#include <asm/mach/arch.h>
32#include <asm/mach/map.h>
33#include <asm/mach/irq.h>
34
35#include <asm/arch/pxa-regs.h>
36#include <asm/arch/mfp-pxa300.h>
37#include <asm/arch/gpio.h>
38#include <asm/arch/pxafb.h>
39#include <asm/arch/ssp.h>
40#include <asm/arch/littleton.h>
41
42#include "generic.h"
43
44#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
45
46/* Littleton MFP configurations */
47static mfp_cfg_t littleton_mfp_cfg[] __initdata = {
48 /* LCD */
49 GPIO54_LCD_LDD_0,
50 GPIO55_LCD_LDD_1,
51 GPIO56_LCD_LDD_2,
52 GPIO57_LCD_LDD_3,
53 GPIO58_LCD_LDD_4,
54 GPIO59_LCD_LDD_5,
55 GPIO60_LCD_LDD_6,
56 GPIO61_LCD_LDD_7,
57 GPIO62_LCD_LDD_8,
58 GPIO63_LCD_LDD_9,
59 GPIO64_LCD_LDD_10,
60 GPIO65_LCD_LDD_11,
61 GPIO66_LCD_LDD_12,
62 GPIO67_LCD_LDD_13,
63 GPIO68_LCD_LDD_14,
64 GPIO69_LCD_LDD_15,
65 GPIO70_LCD_LDD_16,
66 GPIO71_LCD_LDD_17,
67 GPIO72_LCD_FCLK,
68 GPIO73_LCD_LCLK,
69 GPIO74_LCD_PCLK,
70 GPIO75_LCD_BIAS,
71
72 /* SSP2 */
73 GPIO25_SSP2_SCLK,
74 GPIO17_SSP2_FRM,
75 GPIO27_SSP2_TXD,
76
77 /* Debug Ethernet */
78 GPIO90_GPIO,
79};
80
81static struct resource smc91x_resources[] = {
82 [0] = {
83 .start = (LITTLETON_ETH_PHYS + 0x300),
84 .end = (LITTLETON_ETH_PHYS + 0xfffff),
85 .flags = IORESOURCE_MEM,
86 },
87 [1] = {
88 .start = IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO90)),
89 .end = IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO90)),
90 .flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING,
91 }
92};
93
94static struct platform_device smc91x_device = {
95 .name = "smc91x",
96 .id = 0,
97 .num_resources = ARRAY_SIZE(smc91x_resources),
98 .resource = smc91x_resources,
99};
100
101#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULES)
102/* use bit 30, 31 as the indicator of command parameter number */
103#define CMD0(x) ((0x00000000) | ((x) << 9))
104#define CMD1(x, x1) ((0x40000000) | ((x) << 9) | 0x100 | (x1))
105#define CMD2(x, x1, x2) ((0x80000000) | ((x) << 18) | 0x20000 |\
106 ((x1) << 9) | 0x100 | (x2))
107
108static uint32_t lcd_panel_reset[] = {
109 CMD0(0x1), /* reset */
110 CMD0(0x0), /* nop */
111 CMD0(0x0), /* nop */
112 CMD0(0x0), /* nop */
113};
114
115static uint32_t lcd_panel_on[] = {
116 CMD0(0x29), /* Display ON */
117 CMD2(0xB8, 0xFF, 0xF9), /* Output Control */
118 CMD0(0x11), /* Sleep out */
119 CMD1(0xB0, 0x16), /* Wake */
120};
121
122static uint32_t lcd_panel_off[] = {
123 CMD0(0x28), /* Display OFF */
124 CMD2(0xB8, 0x80, 0x02), /* Output Control */
125 CMD0(0x10), /* Sleep in */
126 CMD1(0xB0, 0x00), /* Deep stand by in */
127};
128
129static uint32_t lcd_vga_pass_through[] = {
130 CMD1(0xB0, 0x16),
131 CMD1(0xBC, 0x80),
132 CMD1(0xE1, 0x00),
133 CMD1(0x36, 0x50),
134 CMD1(0x3B, 0x00),
135};
136
137static uint32_t lcd_qvga_pass_through[] = {
138 CMD1(0xB0, 0x16),
139 CMD1(0xBC, 0x81),
140 CMD1(0xE1, 0x00),
141 CMD1(0x36, 0x50),
142 CMD1(0x3B, 0x22),
143};
144
145static uint32_t lcd_vga_transfer[] = {
146 CMD1(0xcf, 0x02), /* Blanking period control (1) */
147 CMD2(0xd0, 0x08, 0x04), /* Blanking period control (2) */
148 CMD1(0xd1, 0x01), /* CKV timing control on/off */
149 CMD2(0xd2, 0x14, 0x00), /* CKV 1,2 timing control */
150 CMD2(0xd3, 0x1a, 0x0f), /* OEV timing control */
151 CMD2(0xd4, 0x1f, 0xaf), /* ASW timing control (1) */
152 CMD1(0xd5, 0x14), /* ASW timing control (2) */
153 CMD0(0x21), /* Invert for normally black display */
154 CMD0(0x29), /* Display on */
155};
156
157static uint32_t lcd_qvga_transfer[] = {
158 CMD1(0xd6, 0x02), /* Blanking period control (1) */
159 CMD2(0xd7, 0x08, 0x04), /* Blanking period control (2) */
160 CMD1(0xd8, 0x01), /* CKV timing control on/off */
161 CMD2(0xd9, 0x00, 0x08), /* CKV 1,2 timing control */
162 CMD2(0xde, 0x05, 0x0a), /* OEV timing control */
163 CMD2(0xdf, 0x0a, 0x19), /* ASW timing control (1) */
164 CMD1(0xe0, 0x0a), /* ASW timing control (2) */
165 CMD0(0x21), /* Invert for normally black display */
166 CMD0(0x29), /* Display on */
167};
168
169static uint32_t lcd_panel_config[] = {
170 CMD2(0xb8, 0xff, 0xf9), /* Output control */
171 CMD0(0x11), /* sleep out */
172 CMD1(0xba, 0x01), /* Display mode (1) */
173 CMD1(0xbb, 0x00), /* Display mode (2) */
174 CMD1(0x3a, 0x60), /* Display mode 18-bit RGB */
175 CMD1(0xbf, 0x10), /* Drive system change control */
176 CMD1(0xb1, 0x56), /* Booster operation setup */
177 CMD1(0xb2, 0x33), /* Booster mode setup */
178 CMD1(0xb3, 0x11), /* Booster frequency setup */
179 CMD1(0xb4, 0x02), /* Op amp/system clock */
180 CMD1(0xb5, 0x35), /* VCS voltage */
181 CMD1(0xb6, 0x40), /* VCOM voltage */
182 CMD1(0xb7, 0x03), /* External display signal */
183 CMD1(0xbd, 0x00), /* ASW slew rate */
184 CMD1(0xbe, 0x00), /* Dummy data for QuadData operation */
185 CMD1(0xc0, 0x11), /* Sleep out FR count (A) */
186 CMD1(0xc1, 0x11), /* Sleep out FR count (B) */
187 CMD1(0xc2, 0x11), /* Sleep out FR count (C) */
188 CMD2(0xc3, 0x20, 0x40), /* Sleep out FR count (D) */
189 CMD2(0xc4, 0x60, 0xc0), /* Sleep out FR count (E) */
190 CMD2(0xc5, 0x10, 0x20), /* Sleep out FR count (F) */
191 CMD1(0xc6, 0xc0), /* Sleep out FR count (G) */
192 CMD2(0xc7, 0x33, 0x43), /* Gamma 1 fine tuning (1) */
193 CMD1(0xc8, 0x44), /* Gamma 1 fine tuning (2) */
194 CMD1(0xc9, 0x33), /* Gamma 1 inclination adjustment */
195 CMD1(0xca, 0x00), /* Gamma 1 blue offset adjustment */
196 CMD2(0xec, 0x01, 0xf0), /* Horizontal clock cycles */
197};
198
199static void ssp_reconfig(struct ssp_dev *dev, int nparam)
200{
201 static int last_nparam = -1;
202
203 /* check if it is necessary to re-config SSP */
204 if (nparam == last_nparam)
205 return;
206
207 ssp_disable(dev);
208 ssp_config(dev, (nparam == 2) ? 0x0010058a : 0x00100581, 0x18, 0, 0);
209
210 last_nparam = nparam;
211}
212
213static void ssp_send_cmd(uint32_t *cmd, int num)
214{
215 static int ssp_initialized;
216 static struct ssp_dev ssp2;
217
218 int i;
219
220 if (!ssp_initialized) {
221 ssp_init(&ssp2, 2, SSP_NO_IRQ);
222 ssp_initialized = 1;
223 }
224
225 clk_enable(ssp2.ssp->clk);
226 for (i = 0; i < num; i++, cmd++) {
227 ssp_reconfig(&ssp2, (*cmd >> 30) & 0x3);
228 ssp_write_word(&ssp2, *cmd & 0x3fffffff);
229
230 /* FIXME: ssp_flush() is mandatory here to work */
231 ssp_flush(&ssp2);
232 }
233 clk_disable(ssp2.ssp->clk);
234}
235
236static void littleton_lcd_power(int on, struct fb_var_screeninfo *var)
237{
238 if (on) {
239 ssp_send_cmd(ARRAY_AND_SIZE(lcd_panel_on));
240 ssp_send_cmd(ARRAY_AND_SIZE(lcd_panel_reset));
241 if (var->xres > 240) {
242 /* VGA */
243 ssp_send_cmd(ARRAY_AND_SIZE(lcd_vga_pass_through));
244 ssp_send_cmd(ARRAY_AND_SIZE(lcd_panel_config));
245 ssp_send_cmd(ARRAY_AND_SIZE(lcd_vga_transfer));
246 } else {
247 /* QVGA */
248 ssp_send_cmd(ARRAY_AND_SIZE(lcd_qvga_pass_through));
249 ssp_send_cmd(ARRAY_AND_SIZE(lcd_panel_config));
250 ssp_send_cmd(ARRAY_AND_SIZE(lcd_qvga_transfer));
251 }
252 } else
253 ssp_send_cmd(ARRAY_AND_SIZE(lcd_panel_off));
254}
255
256static struct pxafb_mode_info tpo_tdo24mtea1_modes[] = {
257 [0] = {
258 /* VGA */
259 .pixclock = 38250,
260 .xres = 480,
261 .yres = 640,
262 .bpp = 16,
263 .hsync_len = 8,
264 .left_margin = 8,
265 .right_margin = 24,
266 .vsync_len = 2,
267 .upper_margin = 2,
268 .lower_margin = 4,
269 .sync = 0,
270 },
271 [1] = {
272 /* QVGA */
273 .pixclock = 153000,
274 .xres = 240,
275 .yres = 320,
276 .bpp = 16,
277 .hsync_len = 8,
278 .left_margin = 8,
279 .right_margin = 88,
280 .vsync_len = 2,
281 .upper_margin = 2,
282 .lower_margin = 2,
283 .sync = 0,
284 },
285};
286
287static struct pxafb_mach_info littleton_lcd_info = {
288 .modes = tpo_tdo24mtea1_modes,
289 .num_modes = 2,
290 .lccr0 = LCCR0_Act,
291 .lccr3 = LCCR3_HSP | LCCR3_VSP,
292 .pxafb_lcd_power = littleton_lcd_power,
293};
294
295static void littleton_init_lcd(void)
296{
297 set_pxa_fb_info(&littleton_lcd_info);
298}
299#else
300static inline void littleton_init_lcd(void) {};
301#endif /* CONFIG_FB_PXA || CONFIG_FB_PXA_MODULES */
302
303static void __init littleton_init(void)
304{
305 /* initialize MFP configurations */
306 pxa3xx_mfp_config(ARRAY_AND_SIZE(littleton_mfp_cfg));
307
308 /*
309 * Note: we depend bootloader set the correct
310 * value to MSC register for SMC91x.
311 */
312 platform_device_register(&smc91x_device);
313
314 littleton_init_lcd();
315}
316
317MACHINE_START(LITTLETON, "Marvell Form Factor Development Platform (aka Littleton)")
318 .phys_io = 0x40000000,
319 .boot_params = 0xa0000100,
320 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
321 .map_io = pxa_map_io,
322 .init_irq = pxa3xx_init_irq,
323 .timer = &pxa_timer,
324 .init_machine = littleton_init,
325MACHINE_END
diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c
index 26116440a7c9..afa62ffe3ad5 100644
--- a/arch/arm/mach-pxa/lpd270.c
+++ b/arch/arm/mach-pxa/lpd270.c
@@ -38,6 +38,7 @@
38#include <asm/mach/flash.h> 38#include <asm/mach/flash.h>
39 39
40#include <asm/arch/pxa-regs.h> 40#include <asm/arch/pxa-regs.h>
41#include <asm/arch/pxa2xx-regs.h>
41#include <asm/arch/lpd270.h> 42#include <asm/arch/lpd270.h>
42#include <asm/arch/audio.h> 43#include <asm/arch/audio.h>
43#include <asm/arch/pxafb.h> 44#include <asm/arch/pxafb.h>
@@ -122,7 +123,7 @@ static int lpd270_irq_resume(struct sys_device *dev)
122} 123}
123 124
124static struct sysdev_class lpd270_irq_sysclass = { 125static struct sysdev_class lpd270_irq_sysclass = {
125 set_kset_name("cpld_irq"), 126 .name = "cpld_irq",
126 .resume = lpd270_irq_resume, 127 .resume = lpd270_irq_resume,
127}; 128};
128 129
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 011a1a72b61c..e7ae4bb3e361 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -41,6 +41,7 @@
41#include <asm/hardware/sa1111.h> 41#include <asm/hardware/sa1111.h>
42 42
43#include <asm/arch/pxa-regs.h> 43#include <asm/arch/pxa-regs.h>
44#include <asm/arch/pxa2xx-regs.h>
44#include <asm/arch/lubbock.h> 45#include <asm/arch/lubbock.h>
45#include <asm/arch/udc.h> 46#include <asm/arch/udc.h>
46#include <asm/arch/irda.h> 47#include <asm/arch/irda.h>
@@ -126,7 +127,7 @@ static int lubbock_irq_resume(struct sys_device *dev)
126} 127}
127 128
128static struct sysdev_class lubbock_irq_sysclass = { 129static struct sysdev_class lubbock_irq_sysclass = {
129 set_kset_name("cpld_irq"), 130 .name = "cpld_irq",
130 .resume = lubbock_irq_resume, 131 .resume = lubbock_irq_resume,
131}; 132};
132 133
@@ -136,9 +137,13 @@ static struct sys_device lubbock_irq_device = {
136 137
137static int __init lubbock_irq_device_init(void) 138static int __init lubbock_irq_device_init(void)
138{ 139{
139 int ret = sysdev_class_register(&lubbock_irq_sysclass); 140 int ret = -ENODEV;
140 if (ret == 0) 141
141 ret = sysdev_register(&lubbock_irq_device); 142 if (machine_is_lubbock()) {
143 ret = sysdev_class_register(&lubbock_irq_sysclass);
144 if (ret == 0)
145 ret = sysdev_register(&lubbock_irq_device);
146 }
142 return ret; 147 return ret;
143} 148}
144 149
@@ -191,7 +196,7 @@ static struct resource smc91x_resources[] = {
191 [1] = { 196 [1] = {
192 .start = LUBBOCK_ETH_IRQ, 197 .start = LUBBOCK_ETH_IRQ,
193 .end = LUBBOCK_ETH_IRQ, 198 .end = LUBBOCK_ETH_IRQ,
194 .flags = IORESOURCE_IRQ, 199 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
195 }, 200 },
196 [2] = { 201 [2] = {
197 .name = "smc91x-attrib", 202 .name = "smc91x-attrib",
@@ -206,30 +211,13 @@ static struct resource smc91x_resources[] = {
206 * (to J5) and poking board registers (as done below). Else it's only useful 211 * (to J5) and poking board registers (as done below). Else it's only useful
207 * for the temperature sensors. 212 * for the temperature sensors.
208 */ 213 */
209static struct resource pxa_ssp_resources[] = {
210 [0] = {
211 .start = __PREG(SSCR0_P(1)),
212 .end = __PREG(SSCR0_P(1)) + 0x14,
213 .flags = IORESOURCE_MEM,
214 },
215 [1] = {
216 .start = IRQ_SSP,
217 .end = IRQ_SSP,
218 .flags = IORESOURCE_IRQ,
219 },
220};
221
222static struct pxa2xx_spi_master pxa_ssp_master_info = { 214static struct pxa2xx_spi_master pxa_ssp_master_info = {
223 .ssp_type = PXA25x_SSP,
224 .clock_enable = CKEN_SSP,
225 .num_chipselect = 0, 215 .num_chipselect = 0,
226}; 216};
227 217
228static struct platform_device pxa_ssp = { 218static struct platform_device pxa_ssp = {
229 .name = "pxa2xx-spi", 219 .name = "pxa2xx-spi",
230 .id = 1, 220 .id = 1,
231 .resource = pxa_ssp_resources,
232 .num_resources = ARRAY_SIZE(pxa_ssp_resources),
233 .dev = { 221 .dev = {
234 .platform_data = &pxa_ssp_master_info, 222 .platform_data = &pxa_ssp_master_info,
235 }, 223 },
diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
new file mode 100644
index 000000000000..d98ef7ada2f8
--- /dev/null
+++ b/arch/arm/mach-pxa/magician.c
@@ -0,0 +1,218 @@
1/*
2 * Support for HTC Magician PDA phones:
3 * i-mate JAM, O2 Xda mini, Orange SPV M500, Qtek s100, Qtek s110
4 * and T-Mobile MDA Compact.
5 *
6 * Copyright (c) 2006-2007 Philipp Zabel
7 *
8 * Based on hx4700.c, spitz.c and others.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 */
15
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/platform_device.h>
19#include <linux/gpio_keys.h>
20#include <linux/input.h>
21#include <linux/mtd/mtd.h>
22#include <linux/mtd/map.h>
23#include <linux/mtd/physmap.h>
24
25#include <asm/gpio.h>
26#include <asm/hardware.h>
27#include <asm/mach-types.h>
28#include <asm/mach/arch.h>
29#include <asm/arch/magician.h>
30#include <asm/arch/pxa-regs.h>
31#include <asm/arch/pxafb.h>
32#include <asm/arch/irda.h>
33#include <asm/arch/ohci.h>
34
35#include "generic.h"
36
37/*
38 * IRDA
39 */
40
41static void magician_irda_transceiver_mode(struct device *dev, int mode)
42{
43 gpio_set_value(GPIO83_MAGICIAN_nIR_EN, mode & IR_OFF);
44}
45
46static struct pxaficp_platform_data magician_ficp_info = {
47 .transceiver_cap = IR_SIRMODE | IR_OFF,
48 .transceiver_mode = magician_irda_transceiver_mode,
49};
50
51/*
52 * GPIO Keys
53 */
54
55static struct gpio_keys_button magician_button_table[] = {
56 {KEY_POWER, GPIO0_MAGICIAN_KEY_POWER, 0, "Power button"},
57 {KEY_ESC, GPIO37_MAGICIAN_KEY_HANGUP, 0, "Hangup button"},
58 {KEY_F10, GPIO38_MAGICIAN_KEY_CONTACTS, 0, "Contacts button"},
59 {KEY_CALENDAR, GPIO90_MAGICIAN_KEY_CALENDAR, 0, "Calendar button"},
60 {KEY_CAMERA, GPIO91_MAGICIAN_KEY_CAMERA, 0, "Camera button"},
61 {KEY_UP, GPIO93_MAGICIAN_KEY_UP, 0, "Up button"},
62 {KEY_DOWN, GPIO94_MAGICIAN_KEY_DOWN, 0, "Down button"},
63 {KEY_LEFT, GPIO95_MAGICIAN_KEY_LEFT, 0, "Left button"},
64 {KEY_RIGHT, GPIO96_MAGICIAN_KEY_RIGHT, 0, "Right button"},
65 {KEY_KPENTER, GPIO97_MAGICIAN_KEY_ENTER, 0, "Action button"},
66 {KEY_RECORD, GPIO98_MAGICIAN_KEY_RECORD, 0, "Record button"},
67 {KEY_VOLUMEUP, GPIO100_MAGICIAN_KEY_VOL_UP, 0, "Volume up"},
68 {KEY_VOLUMEDOWN, GPIO101_MAGICIAN_KEY_VOL_DOWN, 0, "Volume down"},
69 {KEY_PHONE, GPIO102_MAGICIAN_KEY_PHONE, 0, "Phone button"},
70 {KEY_PLAY, GPIO99_MAGICIAN_HEADPHONE_IN, 0, "Headset button"},
71};
72
73static struct gpio_keys_platform_data gpio_keys_data = {
74 .buttons = magician_button_table,
75 .nbuttons = ARRAY_SIZE(magician_button_table),
76};
77
78static struct platform_device gpio_keys = {
79 .name = "gpio-keys",
80 .dev = {
81 .platform_data = &gpio_keys_data,
82 },
83 .id = -1,
84};
85
86/*
87 * LCD - Toppoly TD028STEB1
88 */
89
90static struct pxafb_mode_info toppoly_modes[] = {
91 {
92 .pixclock = 96153,
93 .bpp = 16,
94 .xres = 240,
95 .yres = 320,
96 .hsync_len = 11,
97 .vsync_len = 3,
98 .left_margin = 19,
99 .upper_margin = 2,
100 .right_margin = 10,
101 .lower_margin = 2,
102 .sync = 0,
103 },
104};
105
106static struct pxafb_mach_info toppoly_info = {
107 .modes = toppoly_modes,
108 .num_modes = 1,
109 .fixed_modes = 1,
110 .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
111 .lccr3 = LCCR3_PixRsEdg,
112};
113
114/*
115 * Backlight
116 */
117
118static void magician_set_bl_intensity(int intensity)
119{
120 if (intensity) {
121 PWM_CTRL0 = 1;
122 PWM_PERVAL0 = 0xc8;
123 PWM_PWDUTY0 = intensity;
124 pxa_set_cken(CKEN_PWM0, 1);
125 } else {
126 pxa_set_cken(CKEN_PWM0, 0);
127 }
128}
129
130static struct generic_bl_info backlight_info = {
131 .default_intensity = 0x64,
132 .limit_mask = 0x0b,
133 .max_intensity = 0xc7,
134 .set_bl_intensity = magician_set_bl_intensity,
135};
136
137static struct platform_device backlight = {
138 .name = "corgi-bl",
139 .dev = {
140 .platform_data = &backlight_info,
141 },
142 .id = -1,
143};
144
145
146/*
147 * USB OHCI
148 */
149
150static int magician_ohci_init(struct device *dev)
151{
152 UHCHR = (UHCHR | UHCHR_SSEP2 | UHCHR_PCPL | UHCHR_CGR) &
153 ~(UHCHR_SSEP1 | UHCHR_SSEP3 | UHCHR_SSE);
154
155 return 0;
156}
157
158static struct pxaohci_platform_data magician_ohci_info = {
159 .port_mode = PMM_PERPORT_MODE,
160 .init = magician_ohci_init,
161 .power_budget = 0,
162};
163
164
165/*
166 * StrataFlash
167 */
168
169#define PXA_CS_SIZE 0x04000000
170
171static struct resource strataflash_resource = {
172 .start = PXA_CS0_PHYS,
173 .end = PXA_CS0_PHYS + PXA_CS_SIZE - 1,
174 .flags = IORESOURCE_MEM,
175};
176
177static struct physmap_flash_data strataflash_data = {
178 .width = 4,
179};
180
181static struct platform_device strataflash = {
182 .name = "physmap-flash",
183 .id = -1,
184 .num_resources = 1,
185 .resource = &strataflash_resource,
186 .dev = {
187 .platform_data = &strataflash_data,
188 },
189};
190
191/*
192 * Platform devices
193 */
194
195static struct platform_device *devices[] __initdata = {
196 &gpio_keys,
197 &backlight,
198 &strataflash,
199};
200
201static void __init magician_init(void)
202{
203 platform_add_devices(devices, ARRAY_SIZE(devices));
204 pxa_set_ohci_info(&magician_ohci_info);
205 pxa_set_ficp_info(&magician_ficp_info);
206 set_pxa_fb_info(&toppoly_info);
207}
208
209
210MACHINE_START(MAGICIAN, "HTC Magician")
211 .phys_io = 0x40000000,
212 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
213 .boot_params = 0xa0000100,
214 .map_io = pxa_map_io,
215 .init_irq = pxa27x_init_irq,
216 .init_machine = magician_init,
217 .timer = &pxa_timer,
218MACHINE_END
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index a4bc3483cbb3..345c3deeb02e 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -23,6 +23,7 @@
23#include <linux/ioport.h> 23#include <linux/ioport.h>
24#include <linux/mtd/mtd.h> 24#include <linux/mtd/mtd.h>
25#include <linux/mtd/partitions.h> 25#include <linux/mtd/partitions.h>
26#include <linux/backlight.h>
26 27
27#include <asm/types.h> 28#include <asm/types.h>
28#include <asm/setup.h> 29#include <asm/setup.h>
@@ -38,6 +39,7 @@
38#include <asm/mach/flash.h> 39#include <asm/mach/flash.h>
39 40
40#include <asm/arch/pxa-regs.h> 41#include <asm/arch/pxa-regs.h>
42#include <asm/arch/pxa2xx-regs.h>
41#include <asm/arch/mainstone.h> 43#include <asm/arch/mainstone.h>
42#include <asm/arch/audio.h> 44#include <asm/arch/audio.h>
43#include <asm/arch/pxafb.h> 45#include <asm/arch/pxafb.h>
@@ -120,7 +122,7 @@ static int mainstone_irq_resume(struct sys_device *dev)
120} 122}
121 123
122static struct sysdev_class mainstone_irq_sysclass = { 124static struct sysdev_class mainstone_irq_sysclass = {
123 set_kset_name("cpld_irq"), 125 .name = "cpld_irq",
124 .resume = mainstone_irq_resume, 126 .resume = mainstone_irq_resume,
125}; 127};
126 128
@@ -130,9 +132,13 @@ static struct sys_device mainstone_irq_device = {
130 132
131static int __init mainstone_irq_device_init(void) 133static int __init mainstone_irq_device_init(void)
132{ 134{
133 int ret = sysdev_class_register(&mainstone_irq_sysclass); 135 int ret = -ENODEV;
134 if (ret == 0) 136
135 ret = sysdev_register(&mainstone_irq_device); 137 if (machine_is_mainstone()) {
138 ret = sysdev_class_register(&mainstone_irq_sysclass);
139 if (ret == 0)
140 ret = sysdev_register(&mainstone_irq_device);
141 }
136 return ret; 142 return ret;
137} 143}
138 144
@@ -150,7 +156,7 @@ static struct resource smc91x_resources[] = {
150 [1] = { 156 [1] = {
151 .start = MAINSTONE_IRQ(3), 157 .start = MAINSTONE_IRQ(3),
152 .end = MAINSTONE_IRQ(3), 158 .end = MAINSTONE_IRQ(3),
153 .flags = IORESOURCE_IRQ, 159 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
154 } 160 }
155}; 161};
156 162
@@ -263,21 +269,60 @@ static struct platform_device mst_flash_device[2] = {
263 }, 269 },
264}; 270};
265 271
266static void mainstone_backlight_power(int on) 272#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
273static int mainstone_backlight_update_status(struct backlight_device *bl)
267{ 274{
268 if (on) { 275 int brightness = bl->props.brightness;
276
277 if (bl->props.power != FB_BLANK_UNBLANK ||
278 bl->props.fb_blank != FB_BLANK_UNBLANK)
279 brightness = 0;
280
281 if (brightness != 0) {
269 pxa_gpio_mode(GPIO16_PWM0_MD); 282 pxa_gpio_mode(GPIO16_PWM0_MD);
270 pxa_set_cken(CKEN_PWM0, 1); 283 pxa_set_cken(CKEN_PWM0, 1);
271 PWM_CTRL0 = 0; 284 }
272 PWM_PWDUTY0 = 0x3ff; 285 PWM_CTRL0 = 0;
273 PWM_PERVAL0 = 0x3ff; 286 PWM_PWDUTY0 = brightness;
274 } else { 287 PWM_PERVAL0 = bl->props.max_brightness;
275 PWM_CTRL0 = 0; 288 if (brightness == 0)
276 PWM_PWDUTY0 = 0x0;
277 PWM_PERVAL0 = 0x3FF;
278 pxa_set_cken(CKEN_PWM0, 0); 289 pxa_set_cken(CKEN_PWM0, 0);
290 return 0; /* pointless return value */
291}
292
293static int mainstone_backlight_get_brightness(struct backlight_device *bl)
294{
295 return PWM_PWDUTY0;
296}
297
298static /*const*/ struct backlight_ops mainstone_backlight_ops = {
299 .update_status = mainstone_backlight_update_status,
300 .get_brightness = mainstone_backlight_get_brightness,
301};
302
303static void __init mainstone_backlight_register(void)
304{
305 struct backlight_device *bl;
306
307 bl = backlight_device_register("mainstone-bl", &pxa_device_fb.dev,
308 NULL, &mainstone_backlight_ops);
309 if (IS_ERR(bl)) {
310 printk(KERN_ERR "mainstone: unable to register backlight: %ld\n",
311 PTR_ERR(bl));
312 return;
279 } 313 }
314
315 /*
316 * broken design - register-then-setup interfaces are
317 * utterly broken by definition.
318 */
319 bl->props.max_brightness = 1023;
320 bl->props.brightness = 1023;
321 backlight_update_status(bl);
280} 322}
323#else
324#define mainstone_backlight_register() do { } while (0)
325#endif
281 326
282static struct pxafb_mode_info toshiba_ltm04c380k_mode = { 327static struct pxafb_mode_info toshiba_ltm04c380k_mode = {
283 .pixclock = 50000, 328 .pixclock = 50000,
@@ -311,7 +356,6 @@ static struct pxafb_mach_info mainstone_pxafb_info = {
311 .num_modes = 1, 356 .num_modes = 1,
312 .lccr0 = LCCR0_Act, 357 .lccr0 = LCCR0_Act,
313 .lccr3 = LCCR3_PCP, 358 .lccr3 = LCCR3_PCP,
314 .pxafb_backlight_power = mainstone_backlight_power,
315}; 359};
316 360
317static int mainstone_mci_init(struct device *dev, irq_handler_t mstone_detect_int, void *data) 361static int mainstone_mci_init(struct device *dev, irq_handler_t mstone_detect_int, void *data)
@@ -335,12 +379,10 @@ static int mainstone_mci_init(struct device *dev, irq_handler_t mstone_detect_in
335 379
336 err = request_irq(MAINSTONE_MMC_IRQ, mstone_detect_int, IRQF_DISABLED, 380 err = request_irq(MAINSTONE_MMC_IRQ, mstone_detect_int, IRQF_DISABLED,
337 "MMC card detect", data); 381 "MMC card detect", data);
338 if (err) { 382 if (err)
339 printk(KERN_ERR "mainstone_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); 383 printk(KERN_ERR "mainstone_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
340 return -1;
341 }
342 384
343 return 0; 385 return err;
344} 386}
345 387
346static void mainstone_mci_setpower(struct device *dev, unsigned int vdd) 388static void mainstone_mci_setpower(struct device *dev, unsigned int vdd)
@@ -473,6 +515,7 @@ static void __init mainstone_init(void)
473 mainstone_pxafb_info.modes = &toshiba_ltm035a776c_mode; 515 mainstone_pxafb_info.modes = &toshiba_ltm035a776c_mode;
474 516
475 set_pxa_fb_info(&mainstone_pxafb_info); 517 set_pxa_fb_info(&mainstone_pxafb_info);
518 mainstone_backlight_register();
476 519
477 pxa_set_mci_info(&mainstone_mci_platform_data); 520 pxa_set_mci_info(&mainstone_mci_platform_data);
478 pxa_set_ficp_info(&mainstone_ficp_platform_data); 521 pxa_set_ficp_info(&mainstone_ficp_platform_data);
diff --git a/arch/arm/mach-pxa/mfp.c b/arch/arm/mach-pxa/mfp.c
index 436f96574964..ec1b2d8f61c4 100644
--- a/arch/arm/mach-pxa/mfp.c
+++ b/arch/arm/mach-pxa/mfp.c
@@ -17,9 +17,11 @@
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/io.h> 19#include <linux/io.h>
20#include <linux/sysdev.h>
20 21
21#include <asm/hardware.h> 22#include <asm/hardware.h>
22#include <asm/arch/mfp.h> 23#include <asm/arch/mfp.h>
24#include <asm/arch/mfp-pxa3xx.h>
23 25
24/* mfp_spin_lock is used to ensure that MFP register configuration 26/* mfp_spin_lock is used to ensure that MFP register configuration
25 * (most likely a read-modify-write operation) is atomic, and that 27 * (most likely a read-modify-write operation) is atomic, and that
@@ -28,43 +30,110 @@
28static DEFINE_SPINLOCK(mfp_spin_lock); 30static DEFINE_SPINLOCK(mfp_spin_lock);
29 31
30static void __iomem *mfpr_mmio_base = (void __iomem *)&__REG(MFPR_BASE); 32static void __iomem *mfpr_mmio_base = (void __iomem *)&__REG(MFPR_BASE);
33
34struct pxa3xx_mfp_pin {
35 unsigned long config; /* -1 for not configured */
36 unsigned long mfpr_off; /* MFPRxx Register offset */
37 unsigned long mfpr_run; /* Run-Mode Register Value */
38 unsigned long mfpr_lpm; /* Low Power Mode Register Value */
39};
40
31static struct pxa3xx_mfp_pin mfp_table[MFP_PIN_MAX]; 41static struct pxa3xx_mfp_pin mfp_table[MFP_PIN_MAX];
32 42
43/* mapping of MFP_LPM_* definitions to MFPR_LPM_* register bits */
44const static unsigned long mfpr_lpm[] = {
45 MFPR_LPM_INPUT,
46 MFPR_LPM_DRIVE_LOW,
47 MFPR_LPM_DRIVE_HIGH,
48 MFPR_LPM_PULL_LOW,
49 MFPR_LPM_PULL_HIGH,
50 MFPR_LPM_FLOAT,
51};
52
53/* mapping of MFP_PULL_* definitions to MFPR_PULL_* register bits */
54const static unsigned long mfpr_pull[] = {
55 MFPR_PULL_NONE,
56 MFPR_PULL_LOW,
57 MFPR_PULL_HIGH,
58 MFPR_PULL_BOTH,
59};
60
61/* mapping of MFP_LPM_EDGE_* definitions to MFPR_EDGE_* register bits */
62const static unsigned long mfpr_edge[] = {
63 MFPR_EDGE_NONE,
64 MFPR_EDGE_RISE,
65 MFPR_EDGE_FALL,
66 MFPR_EDGE_BOTH,
67};
68
33#define mfpr_readl(off) \ 69#define mfpr_readl(off) \
34 __raw_readl(mfpr_mmio_base + (off)) 70 __raw_readl(mfpr_mmio_base + (off))
35 71
36#define mfpr_writel(off, val) \ 72#define mfpr_writel(off, val) \
37 __raw_writel(val, mfpr_mmio_base + (off)) 73 __raw_writel(val, mfpr_mmio_base + (off))
38 74
75#define mfp_configured(p) ((p)->config != -1)
76
39/* 77/*
40 * perform a read-back of any MFPR register to make sure the 78 * perform a read-back of any MFPR register to make sure the
41 * previous writings are finished 79 * previous writings are finished
42 */ 80 */
43#define mfpr_sync() (void)__raw_readl(mfpr_mmio_base + 0) 81#define mfpr_sync() (void)__raw_readl(mfpr_mmio_base + 0)
44 82
45static inline void __mfp_config(int pin, unsigned long val) 83static inline void __mfp_config_run(struct pxa3xx_mfp_pin *p)
46{ 84{
47 unsigned long off = mfp_table[pin].mfpr_off; 85 if (mfp_configured(p))
86 mfpr_writel(p->mfpr_off, p->mfpr_run);
87}
48 88
49 mfp_table[pin].mfpr_val = val; 89static inline void __mfp_config_lpm(struct pxa3xx_mfp_pin *p)
50 mfpr_writel(off, val); 90{
91 if (mfp_configured(p)) {
92 unsigned long mfpr_clr = (p->mfpr_run & ~MFPR_EDGE_BOTH) | MFPR_EDGE_CLEAR;
93 if (mfpr_clr != p->mfpr_run)
94 mfpr_writel(p->mfpr_off, mfpr_clr);
95 if (p->mfpr_lpm != mfpr_clr)
96 mfpr_writel(p->mfpr_off, p->mfpr_lpm);
97 }
51} 98}
52 99
53void pxa3xx_mfp_config(mfp_cfg_t *mfp_cfgs, int num) 100void pxa3xx_mfp_config(unsigned long *mfp_cfgs, int num)
54{ 101{
55 int i, pin; 102 unsigned long flags;
56 unsigned long val, flags; 103 int i;
57 mfp_cfg_t *mfp_cfg = mfp_cfgs;
58 104
59 spin_lock_irqsave(&mfp_spin_lock, flags); 105 spin_lock_irqsave(&mfp_spin_lock, flags);
60 106
61 for (i = 0; i < num; i++, mfp_cfg++) { 107 for (i = 0; i < num; i++, mfp_cfgs++) {
62 pin = MFP_CFG_PIN(*mfp_cfg); 108 unsigned long tmp, c = *mfp_cfgs;
63 val = MFP_CFG_VAL(*mfp_cfg); 109 struct pxa3xx_mfp_pin *p;
110 int pin, af, drv, lpm, edge, pull;
64 111
112 pin = MFP_PIN(c);
65 BUG_ON(pin >= MFP_PIN_MAX); 113 BUG_ON(pin >= MFP_PIN_MAX);
66 114 p = &mfp_table[pin];
67 __mfp_config(pin, val); 115
116 af = MFP_AF(c);
117 drv = MFP_DS(c);
118 lpm = MFP_LPM_STATE(c);
119 edge = MFP_LPM_EDGE(c);
120 pull = MFP_PULL(c);
121
122 /* run-mode pull settings will conflict with MFPR bits of
123 * low power mode state, calculate mfpr_run and mfpr_lpm
124 * individually if pull != MFP_PULL_NONE
125 */
126 tmp = MFPR_AF_SEL(af) | MFPR_DRIVE(drv);
127
128 if (likely(pull == MFP_PULL_NONE)) {
129 p->mfpr_run = tmp | mfpr_lpm[lpm] | mfpr_edge[edge];
130 p->mfpr_lpm = p->mfpr_run;
131 } else {
132 p->mfpr_lpm = tmp | mfpr_lpm[lpm] | mfpr_edge[edge];
133 p->mfpr_run = tmp | mfpr_pull[pull];
134 }
135
136 p->config = c; __mfp_config_run(p);
68 } 137 }
69 138
70 mfpr_sync(); 139 mfpr_sync();
@@ -96,140 +165,82 @@ void pxa3xx_mfp_write(int mfp, unsigned long val)
96 spin_unlock_irqrestore(&mfp_spin_lock, flags); 165 spin_unlock_irqrestore(&mfp_spin_lock, flags);
97} 166}
98 167
99void pxa3xx_mfp_set_afds(int mfp, int af, int ds) 168void __init pxa3xx_mfp_init_addr(struct pxa3xx_mfp_addr_map *map)
100{
101 uint32_t mfpr_off, mfpr_val;
102 unsigned long flags;
103
104 BUG_ON(mfp >= MFP_PIN_MAX);
105
106 spin_lock_irqsave(&mfp_spin_lock, flags);
107 mfpr_off = mfp_table[mfp].mfpr_off;
108
109 mfpr_val = mfpr_readl(mfpr_off);
110 mfpr_val &= ~(MFPR_AF_MASK | MFPR_DRV_MASK);
111 mfpr_val |= (((af & 0x7) << MFPR_ALT_OFFSET) |
112 ((ds & 0x7) << MFPR_DRV_OFFSET));
113
114 mfpr_writel(mfpr_off, mfpr_val);
115 mfpr_sync();
116
117 spin_unlock_irqrestore(&mfp_spin_lock, flags);
118}
119
120void pxa3xx_mfp_set_rdh(int mfp, int rdh)
121{ 169{
122 uint32_t mfpr_off, mfpr_val; 170 struct pxa3xx_mfp_addr_map *p;
123 unsigned long flags; 171 unsigned long offset, flags;
124 172 int i;
125 BUG_ON(mfp >= MFP_PIN_MAX);
126 173
127 spin_lock_irqsave(&mfp_spin_lock, flags); 174 spin_lock_irqsave(&mfp_spin_lock, flags);
128 175
129 mfpr_off = mfp_table[mfp].mfpr_off; 176 for (p = map; p->start != MFP_PIN_INVALID; p++) {
130 177 offset = p->offset;
131 mfpr_val = mfpr_readl(mfpr_off); 178 i = p->start;
132 mfpr_val &= ~MFPR_RDH_MASK;
133
134 if (likely(rdh))
135 mfpr_val |= (1u << MFPR_SS_OFFSET);
136 179
137 mfpr_writel(mfpr_off, mfpr_val); 180 do {
138 mfpr_sync(); 181 mfp_table[i].mfpr_off = offset;
182 mfp_table[i].mfpr_run = 0;
183 mfp_table[i].mfpr_lpm = 0;
184 offset += 4; i++;
185 } while ((i <= p->end) && (p->end != -1));
186 }
139 187
140 spin_unlock_irqrestore(&mfp_spin_lock, flags); 188 spin_unlock_irqrestore(&mfp_spin_lock, flags);
141} 189}
142 190
143void pxa3xx_mfp_set_lpm(int mfp, int lpm) 191void __init pxa3xx_init_mfp(void)
144{ 192{
145 uint32_t mfpr_off, mfpr_val; 193 int i;
146 unsigned long flags;
147
148 BUG_ON(mfp >= MFP_PIN_MAX);
149
150 spin_lock_irqsave(&mfp_spin_lock, flags);
151
152 mfpr_off = mfp_table[mfp].mfpr_off;
153 mfpr_val = mfpr_readl(mfpr_off);
154 mfpr_val &= ~MFPR_LPM_MASK;
155
156 if (lpm & 0x1) mfpr_val |= 1u << MFPR_SON_OFFSET;
157 if (lpm & 0x2) mfpr_val |= 1u << MFPR_SD_OFFSET;
158 if (lpm & 0x4) mfpr_val |= 1u << MFPR_PU_OFFSET;
159 if (lpm & 0x8) mfpr_val |= 1u << MFPR_PD_OFFSET;
160 if (lpm &0x10) mfpr_val |= 1u << MFPR_PS_OFFSET;
161
162 mfpr_writel(mfpr_off, mfpr_val);
163 mfpr_sync();
164 194
165 spin_unlock_irqrestore(&mfp_spin_lock, flags); 195 for (i = 0; i < ARRAY_SIZE(mfp_table); i++)
196 mfp_table[i].config = -1;
166} 197}
167 198
168void pxa3xx_mfp_set_pull(int mfp, int pull) 199#ifdef CONFIG_PM
200/*
201 * Configure the MFPs appropriately for suspend/resume.
202 * FIXME: this should probably depend on which system state we're
203 * entering - for instance, we might not want to place MFP pins in
204 * a pull-down mode if they're an active low chip select, and we're
205 * just entering standby.
206 */
207static int pxa3xx_mfp_suspend(struct sys_device *d, pm_message_t state)
169{ 208{
170 uint32_t mfpr_off, mfpr_val; 209 int pin;
171 unsigned long flags;
172
173 BUG_ON(mfp >= MFP_PIN_MAX);
174
175 spin_lock_irqsave(&mfp_spin_lock, flags);
176 210
177 mfpr_off = mfp_table[mfp].mfpr_off; 211 for (pin = 0; pin < ARRAY_SIZE(mfp_table); pin++) {
178 mfpr_val = mfpr_readl(mfpr_off); 212 struct pxa3xx_mfp_pin *p = &mfp_table[pin];
179 mfpr_val &= ~MFPR_PULL_MASK; 213 __mfp_config_lpm(p);
180 mfpr_val |= ((pull & 0x7u) << MFPR_PD_OFFSET); 214 }
181 215 return 0;
182 mfpr_writel(mfpr_off, mfpr_val);
183 mfpr_sync();
184
185 spin_unlock_irqrestore(&mfp_spin_lock, flags);
186} 216}
187 217
188void pxa3xx_mfp_set_edge(int mfp, int edge) 218static int pxa3xx_mfp_resume(struct sys_device *d)
189{ 219{
190 uint32_t mfpr_off, mfpr_val; 220 int pin;
191 unsigned long flags;
192
193 BUG_ON(mfp >= MFP_PIN_MAX);
194
195 spin_lock_irqsave(&mfp_spin_lock, flags);
196
197 mfpr_off = mfp_table[mfp].mfpr_off;
198 mfpr_val = mfpr_readl(mfpr_off);
199
200 mfpr_val &= ~MFPR_EDGE_MASK;
201 mfpr_val |= (edge & 0x3u) << MFPR_ERE_OFFSET;
202 mfpr_val |= (!edge & 0x1) << MFPR_EC_OFFSET;
203 221
204 mfpr_writel(mfpr_off, mfpr_val); 222 for (pin = 0; pin < ARRAY_SIZE(mfp_table); pin++) {
205 mfpr_sync(); 223 struct pxa3xx_mfp_pin *p = &mfp_table[pin];
206 224 __mfp_config_run(p);
207 spin_unlock_irqrestore(&mfp_spin_lock, flags); 225 }
226 return 0;
208} 227}
209 228
210void __init pxa3xx_mfp_init_addr(struct pxa3xx_mfp_addr_map *map) 229static struct sysdev_class mfp_sysclass = {
211{ 230 set_kset_name("mfp"),
212 struct pxa3xx_mfp_addr_map *p; 231 .suspend = pxa3xx_mfp_suspend,
213 unsigned long offset, flags; 232 .resume = pxa3xx_mfp_resume,
214 int i; 233};
215
216 spin_lock_irqsave(&mfp_spin_lock, flags);
217
218 for (p = map; p->start != MFP_PIN_INVALID; p++) {
219 offset = p->offset;
220 i = p->start;
221
222 do {
223 mfp_table[i].mfpr_off = offset;
224 mfp_table[i].mfpr_val = 0;
225 offset += 4; i++;
226 } while ((i <= p->end) && (p->end != -1));
227 }
228 234
229 spin_unlock_irqrestore(&mfp_spin_lock, flags); 235static struct sys_device mfp_device = {
230} 236 .id = 0,
237 .cls = &mfp_sysclass,
238};
231 239
232void __init pxa3xx_init_mfp(void) 240static int __init mfp_init_devicefs(void)
233{ 241{
234 memset(mfp_table, 0, sizeof(mfp_table)); 242 sysdev_class_register(&mfp_sysclass);
243 return sysdev_register(&mfp_device);
235} 244}
245device_initcall(mfp_init_devicefs);
246#endif
diff --git a/arch/arm/mach-pxa/pcm027.c b/arch/arm/mach-pxa/pcm027.c
new file mode 100644
index 000000000000..540c3bba5f9a
--- /dev/null
+++ b/arch/arm/mach-pxa/pcm027.c
@@ -0,0 +1,216 @@
1/*
2 * linux/arch/arm/mach-pxa/pcm027.c
3 * Support for the Phytec phyCORE-PXA270 CPU card (aka PCM-027).
4 *
5 * Refer
6 * http://www.phytec.com/products/sbc/ARM-XScale/phyCORE-XScale-PXA270.html
7 * for additional hardware info
8 *
9 * Author: Juergen Kilb
10 * Created: April 05, 2005
11 * Copyright: Phytec Messtechnik GmbH
12 * e-Mail: armlinux@phytec.de
13 *
14 * based on Intel Mainstone Board
15 *
16 * Copyright 2007 Juergen Beisert @ Pengutronix (j.beisert@pengutronix.de)
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License version 2 as
20 * published by the Free Software Foundation.
21 */
22
23#include <linux/irq.h>
24#include <linux/platform_device.h>
25#include <linux/mtd/physmap.h>
26#include <linux/spi/spi.h>
27#include <linux/leds.h>
28#include <asm/mach-types.h>
29#include <asm/mach/arch.h>
30#include <asm/arch/hardware.h>
31#include <asm/arch/pxa-regs.h>
32#include <asm/arch/pxa2xx_spi.h>
33#include <asm/arch/pcm027.h>
34#include "generic.h"
35
36/*
37 * ABSTRACT:
38 *
39 * The PXA270 processor comes with a bunch of hardware on its silicon.
40 * Not all of this hardware can be used at the same time and not all
41 * is routed to module's connectors. Also it depends on the baseboard, what
42 * kind of hardware can be used in which way.
43 * -> So this file supports the main devices on the CPU card only!
44 * Refer pcm990-baseboard.c how to extend this features to get a full
45 * blown system with many common interfaces.
46 *
47 * The PCM-027 supports the following interfaces through its connectors and
48 * will be used in pcm990-baseboard.c:
49 *
50 * - LCD support
51 * - MMC support
52 * - IDE/CF card
53 * - FFUART
54 * - BTUART
55 * - IRUART
56 * - AC97
57 * - SSP
58 * - SSP3
59 *
60 * Claimed GPIOs:
61 * GPIO0 -> IRQ input from RTC
62 * GPIO2 -> SYS_ENA*)
63 * GPIO3 -> PWR_SCL
64 * GPIO4 -> PWR_SDA
65 * GPIO5 -> PowerCap0*)
66 * GPIO6 -> PowerCap1*)
67 * GPIO7 -> PowerCap2*)
68 * GPIO8 -> PowerCap3*)
69 * GPIO15 -> /CS1
70 * GPIO20 -> /CS2
71 * GPIO21 -> /CS3
72 * GPIO33 -> /CS5 network controller select
73 * GPIO52 -> IRQ from network controller
74 * GPIO78 -> /CS2
75 * GPIO80 -> /CS4
76 * GPIO90 -> LED0
77 * GPIO91 -> LED1
78 * GPIO114 -> IRQ from CAN controller
79 * GPIO117 -> SCL
80 * GPIO118 -> SDA
81 *
82 * *) CPU internal use only
83 */
84
85/*
86 * SMC91x network controller specific stuff
87 */
88static struct resource smc91x_resources[] = {
89 [0] = {
90 .start = PCM027_ETH_PHYS + 0x300,
91 .end = PCM027_ETH_PHYS + PCM027_ETH_SIZE,
92 .flags = IORESOURCE_MEM,
93 },
94 [1] = {
95 .start = PCM027_ETH_IRQ,
96 .end = PCM027_ETH_IRQ,
97 /* note: smc91x's driver doesn't use the trigger bits yet */
98 .flags = IORESOURCE_IRQ | PCM027_ETH_IRQ_EDGE,
99 }
100};
101
102static struct platform_device smc91x_device = {
103 .name = "smc91x",
104 .id = 0,
105 .num_resources = ARRAY_SIZE(smc91x_resources),
106 .resource = smc91x_resources,
107};
108
109static struct physmap_flash_data pcm027_flash_data = {
110 .width = 4,
111};
112
113static struct resource pcm027_flash_resource = {
114 .start = PCM027_FLASH_PHYS,
115 .end = PCM027_FLASH_PHYS + PCM027_FLASH_SIZE - 1 ,
116 .flags = IORESOURCE_MEM,
117};
118
119static struct platform_device pcm027_flash = {
120 .name = "physmap-flash",
121 .id = 0,
122 .dev = {
123 .platform_data = &pcm027_flash_data,
124 },
125 .resource = &pcm027_flash_resource,
126 .num_resources = 1,
127};
128
129#ifdef CONFIG_LEDS_GPIO
130
131static struct gpio_led pcm027_led[] = {
132 {
133 .name = "led0:red", /* FIXME */
134 .gpio = PCM027_LED_CPU
135 },
136 {
137 .name = "led1:green", /* FIXME */
138 .gpio = PCM027_LED_HEARD_BEAT
139 },
140};
141
142static struct gpio_led_platform_data pcm027_led_data = {
143 .num_leds = ARRAY_SIZE(pcm027_led),
144 .leds = pcm027_led
145};
146
147static struct platform_device pcm027_led_dev = {
148 .name = "leds-gpio",
149 .id = 0,
150 .dev = {
151 .platform_data = &pcm027_led_data,
152 },
153};
154
155#endif /* CONFIG_LEDS_GPIO */
156
157/*
158 * declare the available device resources on this board
159 */
160static struct platform_device *devices[] __initdata = {
161 &smc91x_device,
162 &pcm027_flash,
163#ifdef CONFIG_LEDS_GPIO
164 &pcm027_led_dev
165#endif
166};
167
168/*
169 * pcm027_init - breath some life into the board
170 */
171static void __init pcm027_init(void)
172{
173 /* system bus arbiter setting
174 * - Core_Park
175 * - LCD_wt:DMA_wt:CORE_Wt = 2:3:4
176 */
177 ARB_CNTRL = ARB_CORE_PARK | 0x234;
178
179 platform_add_devices(devices, ARRAY_SIZE(devices));
180
181 /* LEDs (on demand only) */
182#ifdef CONFIG_LEDS_GPIO
183 pxa_gpio_mode(PCM027_LED_CPU | GPIO_OUT);
184 pxa_gpio_mode(PCM027_LED_HEARD_BEAT | GPIO_OUT);
185#endif /* CONFIG_LEDS_GPIO */
186
187 /* at last call the baseboard to initialize itself */
188#ifdef CONFIG_MACH_PCM990_BASEBOARD
189 pcm990_baseboard_init();
190#endif
191}
192
193static void __init pcm027_map_io(void)
194{
195 pxa_map_io();
196
197 /* initialize sleep mode regs (wake-up sources, etc) */
198 PGSR0 = 0x01308000;
199 PGSR1 = 0x00CF0002;
200 PGSR2 = 0x0E294000;
201 PGSR3 = 0x0000C000;
202 PWER = 0x40000000 | PWER_GPIO0 | PWER_GPIO1;
203 PRER = 0x00000000;
204 PFER = 0x00000003;
205}
206
207MACHINE_START(PCM027, "Phytec Messtechnik GmbH phyCORE-PXA270")
208 /* Maintainer: Pengutronix */
209 .boot_params = 0xa0000100,
210 .phys_io = 0x40000000,
211 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
212 .map_io = pcm027_map_io,
213 .init_irq = pxa27x_init_irq,
214 .timer = &pxa_timer,
215 .init_machine = pcm027_init,
216MACHINE_END
diff --git a/arch/arm/mach-pxa/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c
new file mode 100644
index 000000000000..3dda16a20049
--- /dev/null
+++ b/arch/arm/mach-pxa/pcm990-baseboard.c
@@ -0,0 +1,330 @@
1/*
2 * arch/arm/mach-pxa/pcm990-baseboard.c
3 * Support for the Phytec phyCORE-PXA270 Development Platform (PCM-990).
4 *
5 * Refer
6 * http://www.phytec.com/products/rdk/ARM-XScale/phyCORE-XScale-PXA270.html
7 * for additional hardware info
8 *
9 * Author: Juergen Kilb
10 * Created: April 05, 2005
11 * Copyright: Phytec Messtechnik GmbH
12 * e-Mail: armlinux@phytec.de
13 *
14 * based on Intel Mainstone Board
15 *
16 * Copyright 2007 Juergen Beisert @ Pengutronix (j.beisert@pengutronix.de)
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License version 2 as
20 * published by the Free Software Foundation.
21 */
22
23#include <linux/irq.h>
24#include <linux/platform_device.h>
25#include <linux/ide.h>
26#include <asm/mach/map.h>
27#include <asm/arch/pxa-regs.h>
28#include <asm/arch/mmc.h>
29#include <asm/arch/ohci.h>
30#include <asm/arch/pcm990_baseboard.h>
31
32/*
33 * The PCM-990 development baseboard uses PCM-027's hardeware in the
34 * following way:
35 *
36 * - LCD support is in use
37 * - GPIO16 is output for back light on/off with PWM
38 * - GPIO58 ... GPIO73 are outputs for display data
39 * - GPIO74 is output output for LCDFCLK
40 * - GPIO75 is output for LCDLCLK
41 * - GPIO76 is output for LCDPCLK
42 * - GPIO77 is output for LCDBIAS
43 * - MMC support is in use
44 * - GPIO32 is output for MMCCLK
45 * - GPIO92 is MMDAT0
46 * - GPIO109 is MMDAT1
47 * - GPIO110 is MMCS0
48 * - GPIO111 is MMCS1
49 * - GPIO112 is MMCMD
50 * - IDE/CF card is in use
51 * - GPIO48 is output /POE
52 * - GPIO49 is output /PWE
53 * - GPIO50 is output /PIOR
54 * - GPIO51 is output /PIOW
55 * - GPIO54 is output /PCE2
56 * - GPIO55 is output /PREG
57 * - GPIO56 is input /PWAIT
58 * - GPIO57 is output /PIOS16
59 * - GPIO79 is output PSKTSEL
60 * - GPIO85 is output /PCE1
61 * - FFUART is in use
62 * - GPIO34 is input FFRXD
63 * - GPIO35 is input FFCTS
64 * - GPIO36 is input FFDCD
65 * - GPIO37 is input FFDSR
66 * - GPIO38 is input FFRI
67 * - GPIO39 is output FFTXD
68 * - GPIO40 is output FFDTR
69 * - GPIO41 is output FFRTS
70 * - BTUART is in use
71 * - GPIO42 is input BTRXD
72 * - GPIO43 is output BTTXD
73 * - GPIO44 is input BTCTS
74 * - GPIO45 is output BTRTS
75 * - IRUART is in use
76 * - GPIO46 is input STDRXD
77 * - GPIO47 is output STDTXD
78 * - AC97 is in use*)
79 * - GPIO28 is input AC97CLK
80 * - GPIO29 is input AC97DatIn
81 * - GPIO30 is output AC97DatO
82 * - GPIO31 is output AC97SYNC
83 * - GPIO113 is output AC97_RESET
84 * - SSP is in use
85 * - GPIO23 is output SSPSCLK
86 * - GPIO24 is output chip select to Max7301
87 * - GPIO25 is output SSPTXD
88 * - GPIO26 is input SSPRXD
89 * - GPIO27 is input for Max7301 IRQ
90 * - GPIO53 is input SSPSYSCLK
91 * - SSP3 is in use
92 * - GPIO81 is output SSPTXD3
93 * - GPIO82 is input SSPRXD3
94 * - GPIO83 is output SSPSFRM
95 * - GPIO84 is output SSPCLK3
96 *
97 * Otherwise claimed GPIOs:
98 * GPIO1 -> IRQ from user switch
99 * GPIO9 -> IRQ from power management
100 * GPIO10 -> IRQ from WML9712 AC97 controller
101 * GPIO11 -> IRQ from IDE controller
102 * GPIO12 -> IRQ from CF controller
103 * GPIO13 -> IRQ from CF controller
104 * GPIO14 -> GPIO free
105 * GPIO15 -> /CS1 selects baseboard's Control CPLD (U7, 16 bit wide data path)
106 * GPIO19 -> GPIO free
107 * GPIO20 -> /SDCS2
108 * GPIO21 -> /CS3 PC card socket select
109 * GPIO33 -> /CS5 network controller select
110 * GPIO78 -> /CS2 (16 bit wide data path)
111 * GPIO80 -> /CS4 (16 bit wide data path)
112 * GPIO86 -> GPIO free
113 * GPIO87 -> GPIO free
114 * GPIO90 -> LED0 on CPU module
115 * GPIO91 -> LED1 on CPI module
116 * GPIO117 -> SCL
117 * GPIO118 -> SDA
118 */
119
120static unsigned long pcm990_irq_enabled;
121
122static void pcm990_mask_ack_irq(unsigned int irq)
123{
124 int pcm990_irq = (irq - PCM027_IRQ(0));
125 PCM990_INTMSKENA = (pcm990_irq_enabled &= ~(1 << pcm990_irq));
126}
127
128static void pcm990_unmask_irq(unsigned int irq)
129{
130 int pcm990_irq = (irq - PCM027_IRQ(0));
131 /* the irq can be acknowledged only if deasserted, so it's done here */
132 PCM990_INTSETCLR |= 1 << pcm990_irq;
133 PCM990_INTMSKENA = (pcm990_irq_enabled |= (1 << pcm990_irq));
134}
135
136static struct irq_chip pcm990_irq_chip = {
137 .mask_ack = pcm990_mask_ack_irq,
138 .unmask = pcm990_unmask_irq,
139};
140
141static void pcm990_irq_handler(unsigned int irq, struct irq_desc *desc)
142{
143 unsigned long pending = (~PCM990_INTSETCLR) & pcm990_irq_enabled;
144
145 do {
146 GEDR(PCM990_CTRL_INT_IRQ_GPIO) =
147 GPIO_bit(PCM990_CTRL_INT_IRQ_GPIO);
148 if (likely(pending)) {
149 irq = PCM027_IRQ(0) + __ffs(pending);
150 desc = irq_desc + irq;
151 desc_handle_irq(irq, desc);
152 }
153 pending = (~PCM990_INTSETCLR) & pcm990_irq_enabled;
154 } while (pending);
155}
156
157static void __init pcm990_init_irq(void)
158{
159 int irq;
160
161 /* setup extra PCM990 irqs */
162 for (irq = PCM027_IRQ(0); irq <= PCM027_IRQ(3); irq++) {
163 set_irq_chip(irq, &pcm990_irq_chip);
164 set_irq_handler(irq, handle_level_irq);
165 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
166 }
167
168 PCM990_INTMSKENA = 0x00; /* disable all Interrupts */
169 PCM990_INTSETCLR = 0xFF;
170
171 set_irq_chained_handler(PCM990_CTRL_INT_IRQ, pcm990_irq_handler);
172 set_irq_type(PCM990_CTRL_INT_IRQ, PCM990_CTRL_INT_IRQ_EDGE);
173}
174
175static int pcm990_mci_init(struct device *dev, irq_handler_t mci_detect_int,
176 void *data)
177{
178 int err;
179
180 /*
181 * enable GPIO for PXA27x MMC controller
182 */
183 pxa_gpio_mode(GPIO32_MMCCLK_MD);
184 pxa_gpio_mode(GPIO112_MMCCMD_MD);
185 pxa_gpio_mode(GPIO92_MMCDAT0_MD);
186 pxa_gpio_mode(GPIO109_MMCDAT1_MD);
187 pxa_gpio_mode(GPIO110_MMCDAT2_MD);
188 pxa_gpio_mode(GPIO111_MMCDAT3_MD);
189
190 err = request_irq(PCM027_MMCDET_IRQ, mci_detect_int, IRQF_DISABLED,
191 "MMC card detect", data);
192 if (err)
193 printk(KERN_ERR "pcm990_mci_init: MMC/SD: can't request MMC "
194 "card detect IRQ\n");
195
196 return err;
197}
198
199static void pcm990_mci_setpower(struct device *dev, unsigned int vdd)
200{
201 struct pxamci_platform_data *p_d = dev->platform_data;
202
203 if ((1 << vdd) & p_d->ocr_mask)
204 __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG5) =
205 PCM990_CTRL_MMC2PWR;
206 else
207 __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG5) =
208 ~PCM990_CTRL_MMC2PWR;
209}
210
211static void pcm990_mci_exit(struct device *dev, void *data)
212{
213 free_irq(PCM027_MMCDET_IRQ, data);
214}
215
216#define MSECS_PER_JIFFY (1000/HZ)
217
218static struct pxamci_platform_data pcm990_mci_platform_data = {
219 .detect_delay = 250 / MSECS_PER_JIFFY,
220 .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
221 .init = pcm990_mci_init,
222 .setpower = pcm990_mci_setpower,
223 .exit = pcm990_mci_exit,
224};
225
226/*
227 * init OHCI hardware to work with
228 *
229 * Note: Only USB port 1 (host only) is connected
230 *
231 * GPIO88 (USBHPWR#1): overcurrent in, overcurrent when low
232 * GPIO89 (USBHPEN#1): power-on out, on when low
233 */
234static int pcm990_ohci_init(struct device *dev)
235{
236 pxa_gpio_mode(PCM990_USB_OVERCURRENT);
237 pxa_gpio_mode(PCM990_USB_PWR_EN);
238 /*
239 * disable USB port 2 and 3
240 * power sense is active low
241 */
242 UHCHR = ((UHCHR) | UHCHR_PCPL | UHCHR_PSPL | UHCHR_SSEP2 |
243 UHCHR_SSEP3) & ~(UHCHR_SSEP1 | UHCHR_SSE);
244 /*
245 * wait 10ms after Power on
246 * overcurrent per port
247 * power switch per port
248 */
249 UHCRHDA = (5<<24) | (1<<11) | (1<<8); /* FIXME: Required? */
250
251 return 0;
252}
253
254static struct pxaohci_platform_data pcm990_ohci_platform_data = {
255 .port_mode = PMM_PERPORT_MODE,
256 .init = pcm990_ohci_init,
257 .exit = NULL,
258};
259
260/*
261 * AC97 support
262 * Note: The connected AC97 mixer also reports interrupts at PCM990_AC97_IRQ
263 */
264static struct resource pxa27x_ac97_resources[] = {
265 [0] = {
266 .start = 0x40500000,
267 .end = 0x40500000 + 0xfff,
268 .flags = IORESOURCE_MEM,
269 },
270 [1] = {
271 .start = IRQ_AC97,
272 .end = IRQ_AC97,
273 .flags = IORESOURCE_IRQ,
274 },
275};
276
277static u64 pxa_ac97_dmamask = 0xffffffffUL;
278
279static struct platform_device pxa27x_device_ac97 = {
280 .name = "pxa2xx-ac97",
281 .id = -1,
282 .dev = {
283 .dma_mask = &pxa_ac97_dmamask,
284 .coherent_dma_mask = 0xffffffff,
285 },
286 .num_resources = ARRAY_SIZE(pxa27x_ac97_resources),
287 .resource = pxa27x_ac97_resources,
288};
289
290/*
291 * enable generic access to the base board control CPLDs U6 and U7
292 */
293static struct map_desc pcm990_io_desc[] __initdata = {
294 {
295 .virtual = PCM990_CTRL_BASE,
296 .pfn = __phys_to_pfn(PCM990_CTRL_PHYS),
297 .length = PCM990_CTRL_SIZE,
298 .type = MT_DEVICE /* CPLD */
299 }, {
300 .virtual = PCM990_CF_PLD_BASE,
301 .pfn = __phys_to_pfn(PCM990_CF_PLD_PHYS),
302 .length = PCM990_CF_PLD_SIZE,
303 .type = MT_DEVICE /* CPLD */
304 }
305};
306
307/*
308 * system init for baseboard usage. Will be called by pcm027 init.
309 *
310 * Add platform devices present on this baseboard and init
311 * them from CPU side as far as required to use them later on
312 */
313void __init pcm990_baseboard_init(void)
314{
315 /* register CPLD access */
316 iotable_init(pcm990_io_desc, ARRAY_SIZE(pcm990_io_desc));
317
318 /* register CPLD's IRQ controller */
319 pcm990_init_irq();
320
321 platform_device_register(&pxa27x_device_ac97);
322
323 /* MMC */
324 pxa_set_mci_info(&pcm990_mci_platform_data);
325
326 /* USB host */
327 pxa_set_ohci_info(&pcm990_ohci_platform_data);
328
329 printk(KERN_INFO"PCM-990 Evaluation baseboard initialized\n");
330}
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c
index a941c71c7d06..039194cbe477 100644
--- a/arch/arm/mach-pxa/pm.c
+++ b/arch/arm/mach-pxa/pm.c
@@ -38,34 +38,37 @@ int pxa_pm_enter(suspend_state_t state)
38 iwmmxt_task_disable(NULL); 38 iwmmxt_task_disable(NULL);
39#endif 39#endif
40 40
41 pxa_cpu_pm_fns->save(sleep_save); 41 /* skip registers saving for standby */
42 if (state != PM_SUSPEND_STANDBY) {
43 pxa_cpu_pm_fns->save(sleep_save);
44 /* before sleeping, calculate and save a checksum */
45 for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++)
46 sleep_save_checksum += sleep_save[i];
47 }
42 48
43 /* Clear sleep reset status */ 49 /* Clear sleep reset status */
44 RCSR = RCSR_SMR; 50 RCSR = RCSR_SMR;
45 51
46 /* before sleeping, calculate and save a checksum */
47 for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++)
48 sleep_save_checksum += sleep_save[i];
49
50 /* *** go zzz *** */ 52 /* *** go zzz *** */
51 pxa_cpu_pm_fns->enter(state); 53 pxa_cpu_pm_fns->enter(state);
52 cpu_init(); 54 cpu_init();
53 55
54 /* after sleeping, validate the checksum */ 56 if (state != PM_SUSPEND_STANDBY) {
55 for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++) 57 /* after sleeping, validate the checksum */
56 checksum += sleep_save[i]; 58 for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++)
59 checksum += sleep_save[i];
57 60
58 /* if invalid, display message and wait for a hardware reset */ 61 /* if invalid, display message and wait for a hardware reset */
59 if (checksum != sleep_save_checksum) { 62 if (checksum != sleep_save_checksum) {
60#ifdef CONFIG_ARCH_LUBBOCK 63#ifdef CONFIG_ARCH_LUBBOCK
61 LUB_HEXLED = 0xbadbadc5; 64 LUB_HEXLED = 0xbadbadc5;
62#endif 65#endif
63 while (1) 66 while (1)
64 pxa_cpu_pm_fns->enter(state); 67 pxa_cpu_pm_fns->enter(state);
68 }
69 pxa_cpu_pm_fns->restore(sleep_save);
65 } 70 }
66 71
67 pxa_cpu_pm_fns->restore(sleep_save);
68
69 pr_debug("*** made it back from resume\n"); 72 pr_debug("*** made it back from resume\n");
70 73
71 return 0; 74 return 0;
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index 655668d4d0e9..dd54496083cb 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -215,12 +215,10 @@ static int poodle_mci_init(struct device *dev, irq_handler_t poodle_detect_int,
215 err = request_irq(POODLE_IRQ_GPIO_nSD_DETECT, poodle_detect_int, 215 err = request_irq(POODLE_IRQ_GPIO_nSD_DETECT, poodle_detect_int,
216 IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 216 IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
217 "MMC card detect", data); 217 "MMC card detect", data);
218 if (err) { 218 if (err)
219 printk(KERN_ERR "poodle_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); 219 printk(KERN_ERR "poodle_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
220 return -1;
221 }
222 220
223 return 0; 221 return err;
224} 222}
225 223
226static void poodle_mci_setpower(struct device *dev, unsigned int vdd) 224static void poodle_mci_setpower(struct device *dev, unsigned int vdd)
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index 9732d5d9466b..ddd05bf78e02 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -111,21 +111,27 @@ static const struct clkops clk_pxa25x_lcd_ops = {
111 * 95.842MHz -> MMC 19.169MHz, I2C 31.949MHz, FICP 47.923MHz, USB 47.923MHz 111 * 95.842MHz -> MMC 19.169MHz, I2C 31.949MHz, FICP 47.923MHz, USB 47.923MHz
112 * 147.456MHz -> UART 14.7456MHz, AC97 12.288MHz, I2S 5.672MHz (allegedly) 112 * 147.456MHz -> UART 14.7456MHz, AC97 12.288MHz, I2S 5.672MHz (allegedly)
113 */ 113 */
114static struct clk pxa25x_hwuart_clk =
115 INIT_CKEN("UARTCLK", HWUART, 14745600, 1, &pxa_device_hwuart.dev)
116;
117
114static struct clk pxa25x_clks[] = { 118static struct clk pxa25x_clks[] = {
115 INIT_CK("LCDCLK", LCD, &clk_pxa25x_lcd_ops, &pxa_device_fb.dev), 119 INIT_CK("LCDCLK", LCD, &clk_pxa25x_lcd_ops, &pxa_device_fb.dev),
116 INIT_CKEN("UARTCLK", FFUART, 14745600, 1, &pxa_device_ffuart.dev), 120 INIT_CKEN("UARTCLK", FFUART, 14745600, 1, &pxa_device_ffuart.dev),
117 INIT_CKEN("UARTCLK", BTUART, 14745600, 1, &pxa_device_btuart.dev), 121 INIT_CKEN("UARTCLK", BTUART, 14745600, 1, &pxa_device_btuart.dev),
118 INIT_CKEN("UARTCLK", BTUART, 14745600, 1, &pxa_device_btuart.dev),
119 INIT_CKEN("UARTCLK", STUART, 14745600, 1, NULL), 122 INIT_CKEN("UARTCLK", STUART, 14745600, 1, NULL),
120 INIT_CKEN("UDCCLK", USB, 47923000, 5, &pxa_device_udc.dev), 123 INIT_CKEN("UDCCLK", USB, 47923000, 5, &pxa_device_udc.dev),
121 INIT_CKEN("MMCCLK", MMC, 19169000, 0, &pxa_device_mci.dev), 124 INIT_CKEN("MMCCLK", MMC, 19169000, 0, &pxa_device_mci.dev),
122 INIT_CKEN("I2CCLK", I2C, 31949000, 0, &pxa_device_i2c.dev), 125 INIT_CKEN("I2CCLK", I2C, 31949000, 0, &pxa_device_i2c.dev),
126
127 INIT_CKEN("SSPCLK", SSP, 3686400, 0, &pxa25x_device_ssp.dev),
128 INIT_CKEN("SSPCLK", NSSP, 3686400, 0, &pxa25x_device_nssp.dev),
129 INIT_CKEN("SSPCLK", ASSP, 3686400, 0, &pxa25x_device_assp.dev),
130
123 /* 131 /*
124 INIT_CKEN("PWMCLK", PWM0, 3686400, 0, NULL), 132 INIT_CKEN("PWMCLK", PWM0, 3686400, 0, NULL),
125 INIT_CKEN("PWMCLK", PWM0, 3686400, 0, NULL), 133 INIT_CKEN("PWMCLK", PWM0, 3686400, 0, NULL),
126 INIT_CKEN("SSPCLK", SSP, 3686400, 0, NULL),
127 INIT_CKEN("I2SCLK", I2S, 14745600, 0, NULL), 134 INIT_CKEN("I2SCLK", I2S, 14745600, 0, NULL),
128 INIT_CKEN("NSSPCLK", NSSP, 3686400, 0, NULL),
129 */ 135 */
130 INIT_CKEN("FICPCLK", FICP, 47923000, 0, NULL), 136 INIT_CKEN("FICPCLK", FICP, 47923000, 0, NULL),
131}; 137};
@@ -213,8 +219,6 @@ static void pxa25x_cpu_pm_restore(unsigned long *sleep_save)
213 219
214static void pxa25x_cpu_pm_enter(suspend_state_t state) 220static void pxa25x_cpu_pm_enter(suspend_state_t state)
215{ 221{
216 CKEN = 0;
217
218 switch (state) { 222 switch (state) {
219 case PM_SUSPEND_MEM: 223 case PM_SUSPEND_MEM:
220 /* set resume return address */ 224 /* set resume return address */
@@ -236,6 +240,8 @@ static void __init pxa25x_init_pm(void)
236{ 240{
237 pxa_cpu_pm_fns = &pxa25x_cpu_pm_fns; 241 pxa_cpu_pm_fns = &pxa25x_cpu_pm_fns;
238} 242}
243#else
244static inline void pxa25x_init_pm(void) {}
239#endif 245#endif
240 246
241/* PXA25x: supports wakeup from GPIO0..GPIO15 and RTC alarm 247/* PXA25x: supports wakeup from GPIO0..GPIO15 and RTC alarm
@@ -287,30 +293,33 @@ void __init pxa25x_init_irq(void)
287} 293}
288 294
289static struct platform_device *pxa25x_devices[] __initdata = { 295static struct platform_device *pxa25x_devices[] __initdata = {
290 &pxa_device_mci,
291 &pxa_device_udc, 296 &pxa_device_udc,
292 &pxa_device_fb,
293 &pxa_device_ffuart, 297 &pxa_device_ffuart,
294 &pxa_device_btuart, 298 &pxa_device_btuart,
295 &pxa_device_stuart, 299 &pxa_device_stuart,
296 &pxa_device_i2c,
297 &pxa_device_i2s, 300 &pxa_device_i2s,
298 &pxa_device_ficp,
299 &pxa_device_rtc, 301 &pxa_device_rtc,
302 &pxa25x_device_ssp,
303 &pxa25x_device_nssp,
304 &pxa25x_device_assp,
300}; 305};
301 306
302static int __init pxa25x_init(void) 307static int __init pxa25x_init(void)
303{ 308{
304 int ret = 0; 309 int ret = 0;
305 310
311 /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */
312 if (cpu_is_pxa25x())
313 clks_register(&pxa25x_hwuart_clk, 1);
314
306 if (cpu_is_pxa21x() || cpu_is_pxa25x()) { 315 if (cpu_is_pxa21x() || cpu_is_pxa25x()) {
307 clks_register(pxa25x_clks, ARRAY_SIZE(pxa25x_clks)); 316 clks_register(pxa25x_clks, ARRAY_SIZE(pxa25x_clks));
308 317
309 if ((ret = pxa_init_dma(16))) 318 if ((ret = pxa_init_dma(16)))
310 return ret; 319 return ret;
311#ifdef CONFIG_PM 320
312 pxa25x_init_pm(); 321 pxa25x_init_pm();
313#endif 322
314 ret = platform_add_devices(pxa25x_devices, 323 ret = platform_add_devices(pxa25x_devices,
315 ARRAY_SIZE(pxa25x_devices)); 324 ARRAY_SIZE(pxa25x_devices));
316 } 325 }
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 8e126e6b74c3..96cf274ec7cb 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -21,9 +21,11 @@
21#include <asm/irq.h> 21#include <asm/irq.h>
22#include <asm/arch/irqs.h> 22#include <asm/arch/irqs.h>
23#include <asm/arch/pxa-regs.h> 23#include <asm/arch/pxa-regs.h>
24#include <asm/arch/pxa2xx-regs.h>
24#include <asm/arch/ohci.h> 25#include <asm/arch/ohci.h>
25#include <asm/arch/pm.h> 26#include <asm/arch/pm.h>
26#include <asm/arch/dma.h> 27#include <asm/arch/dma.h>
28#include <asm/arch/i2c.h>
27 29
28#include "generic.h" 30#include "generic.h"
29#include "devices.h" 31#include "devices.h"
@@ -150,11 +152,12 @@ static struct clk pxa27x_clks[] = {
150 INIT_CKEN("I2CCLK", PWRI2C, 13000000, 0, &pxa27x_device_i2c_power.dev), 152 INIT_CKEN("I2CCLK", PWRI2C, 13000000, 0, &pxa27x_device_i2c_power.dev),
151 INIT_CKEN("KBDCLK", KEYPAD, 32768, 0, NULL), 153 INIT_CKEN("KBDCLK", KEYPAD, 32768, 0, NULL),
152 154
155 INIT_CKEN("SSPCLK", SSP1, 13000000, 0, &pxa27x_device_ssp1.dev),
156 INIT_CKEN("SSPCLK", SSP2, 13000000, 0, &pxa27x_device_ssp2.dev),
157 INIT_CKEN("SSPCLK", SSP3, 13000000, 0, &pxa27x_device_ssp3.dev),
158
153 /* 159 /*
154 INIT_CKEN("PWMCLK", PWM0, 13000000, 0, NULL), 160 INIT_CKEN("PWMCLK", PWM0, 13000000, 0, NULL),
155 INIT_CKEN("SSPCLK", SSP1, 13000000, 0, NULL),
156 INIT_CKEN("SSPCLK", SSP2, 13000000, 0, NULL),
157 INIT_CKEN("SSPCLK", SSP3, 13000000, 0, NULL),
158 INIT_CKEN("MSLCLK", MSL, 48000000, 0, NULL), 161 INIT_CKEN("MSLCLK", MSL, 48000000, 0, NULL),
159 INIT_CKEN("USIMCLK", USIM, 48000000, 0, NULL), 162 INIT_CKEN("USIMCLK", USIM, 48000000, 0, NULL),
160 INIT_CKEN("MSTKCLK", MEMSTK, 19500000, 0, NULL), 163 INIT_CKEN("MSTKCLK", MEMSTK, 19500000, 0, NULL),
@@ -263,12 +266,6 @@ void pxa27x_cpu_pm_enter(suspend_state_t state)
263{ 266{
264 extern void pxa_cpu_standby(void); 267 extern void pxa_cpu_standby(void);
265 268
266 if (state == PM_SUSPEND_STANDBY)
267 CKEN = (1 << CKEN_MEMC) | (1 << CKEN_OSTIMER) |
268 (1 << CKEN_LCD) | (1 << CKEN_PWM0);
269 else
270 CKEN = (1 << CKEN_MEMC) | (1 << CKEN_OSTIMER);
271
272 /* ensure voltage-change sequencer not initiated, which hangs */ 269 /* ensure voltage-change sequencer not initiated, which hangs */
273 PCFR &= ~PCFR_FVC; 270 PCFR &= ~PCFR_FVC;
274 271
@@ -304,6 +301,8 @@ static void __init pxa27x_init_pm(void)
304{ 301{
305 pxa_cpu_pm_fns = &pxa27x_cpu_pm_fns; 302 pxa_cpu_pm_fns = &pxa27x_cpu_pm_fns;
306} 303}
304#else
305static inline void pxa27x_init_pm(void) {}
307#endif 306#endif
308 307
309/* PXA27x: Various gpios can issue wakeup events. This logic only 308/* PXA27x: Various gpios can issue wakeup events. This logic only
@@ -373,37 +372,6 @@ void __init pxa27x_init_irq(void)
373 * device registration specific to PXA27x. 372 * device registration specific to PXA27x.
374 */ 373 */
375 374
376static u64 pxa27x_dmamask = 0xffffffffUL;
377
378static struct resource pxa27x_ohci_resources[] = {
379 [0] = {
380 .start = 0x4C000000,
381 .end = 0x4C00ff6f,
382 .flags = IORESOURCE_MEM,
383 },
384 [1] = {
385 .start = IRQ_USBH1,
386 .end = IRQ_USBH1,
387 .flags = IORESOURCE_IRQ,
388 },
389};
390
391struct platform_device pxa27x_device_ohci = {
392 .name = "pxa27x-ohci",
393 .id = -1,
394 .dev = {
395 .dma_mask = &pxa27x_dmamask,
396 .coherent_dma_mask = 0xffffffff,
397 },
398 .num_resources = ARRAY_SIZE(pxa27x_ohci_resources),
399 .resource = pxa27x_ohci_resources,
400};
401
402void __init pxa_set_ohci_info(struct pxaohci_platform_data *info)
403{
404 pxa27x_device_ohci.dev.platform_data = info;
405}
406
407static struct resource i2c_power_resources[] = { 375static struct resource i2c_power_resources[] = {
408 { 376 {
409 .start = 0x40f00180, 377 .start = 0x40f00180,
@@ -423,19 +391,22 @@ struct platform_device pxa27x_device_i2c_power = {
423 .num_resources = ARRAY_SIZE(i2c_power_resources), 391 .num_resources = ARRAY_SIZE(i2c_power_resources),
424}; 392};
425 393
394void __init pxa_set_i2c_power_info(struct i2c_pxa_platform_data *info)
395{
396 pxa27x_device_i2c_power.dev.platform_data = info;
397}
398
426static struct platform_device *devices[] __initdata = { 399static struct platform_device *devices[] __initdata = {
427 &pxa_device_mci,
428 &pxa_device_udc, 400 &pxa_device_udc,
429 &pxa_device_fb,
430 &pxa_device_ffuart, 401 &pxa_device_ffuart,
431 &pxa_device_btuart, 402 &pxa_device_btuart,
432 &pxa_device_stuart, 403 &pxa_device_stuart,
433 &pxa_device_i2c,
434 &pxa_device_i2s, 404 &pxa_device_i2s,
435 &pxa_device_ficp,
436 &pxa_device_rtc, 405 &pxa_device_rtc,
437 &pxa27x_device_i2c_power, 406 &pxa27x_device_i2c_power,
438 &pxa27x_device_ohci, 407 &pxa27x_device_ssp1,
408 &pxa27x_device_ssp2,
409 &pxa27x_device_ssp3,
439}; 410};
440 411
441static int __init pxa27x_init(void) 412static int __init pxa27x_init(void)
@@ -446,9 +417,9 @@ static int __init pxa27x_init(void)
446 417
447 if ((ret = pxa_init_dma(32))) 418 if ((ret = pxa_init_dma(32)))
448 return ret; 419 return ret;
449#ifdef CONFIG_PM 420
450 pxa27x_init_pm(); 421 pxa27x_init_pm();
451#endif 422
452 ret = platform_add_devices(devices, ARRAY_SIZE(devices)); 423 ret = platform_add_devices(devices, ARRAY_SIZE(devices));
453 } 424 }
454 return ret; 425 return ret;
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index 61d9c9d69e6b..5cbf057a1b32 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -19,6 +19,7 @@
19#include <linux/pm.h> 19#include <linux/pm.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/irq.h> 21#include <linux/irq.h>
22#include <linux/io.h>
22 23
23#include <asm/hardware.h> 24#include <asm/hardware.h>
24#include <asm/arch/pxa3xx-regs.h> 25#include <asm/arch/pxa3xx-regs.h>
@@ -86,7 +87,7 @@ unsigned int pxa3xx_get_clk_frequency_khz(int info)
86 HSS / 1000000, (HSS % 1000000) / 10000); 87 HSS / 1000000, (HSS % 1000000) / 10000);
87 } 88 }
88 89
89 return CLK; 90 return CLK / 1000;
90} 91}
91 92
92/* 93/*
@@ -189,8 +190,237 @@ static struct clk pxa3xx_clks[] = {
189 190
190 PXA3xx_CKEN("I2CCLK", I2C, 32842000, 0, &pxa_device_i2c.dev), 191 PXA3xx_CKEN("I2CCLK", I2C, 32842000, 0, &pxa_device_i2c.dev),
191 PXA3xx_CKEN("UDCCLK", UDC, 48000000, 5, &pxa_device_udc.dev), 192 PXA3xx_CKEN("UDCCLK", UDC, 48000000, 5, &pxa_device_udc.dev),
193 PXA3xx_CKEN("USBCLK", USBH, 48000000, 0, &pxa27x_device_ohci.dev),
194
195 PXA3xx_CKEN("SSPCLK", SSP1, 13000000, 0, &pxa27x_device_ssp1.dev),
196 PXA3xx_CKEN("SSPCLK", SSP2, 13000000, 0, &pxa27x_device_ssp2.dev),
197 PXA3xx_CKEN("SSPCLK", SSP3, 13000000, 0, &pxa27x_device_ssp3.dev),
198 PXA3xx_CKEN("SSPCLK", SSP4, 13000000, 0, &pxa3xx_device_ssp4.dev),
199
200 PXA3xx_CKEN("MMCCLK", MMC1, 19500000, 0, &pxa_device_mci.dev),
201 PXA3xx_CKEN("MMCCLK", MMC2, 19500000, 0, &pxa3xx_device_mci2.dev),
202 PXA3xx_CKEN("MMCCLK", MMC3, 19500000, 0, &pxa3xx_device_mci3.dev),
203};
204
205#ifdef CONFIG_PM
206#define SLEEP_SAVE_SIZE 4
207
208#define ISRAM_START 0x5c000000
209#define ISRAM_SIZE SZ_256K
210
211static void __iomem *sram;
212static unsigned long wakeup_src;
213
214static void pxa3xx_cpu_pm_save(unsigned long *sleep_save)
215{
216 pr_debug("PM: CKENA=%08x CKENB=%08x\n", CKENA, CKENB);
217
218 if (CKENA & (1 << CKEN_USBH)) {
219 printk(KERN_ERR "PM: USB host clock not stopped?\n");
220 CKENA &= ~(1 << CKEN_USBH);
221 }
222// CKENA |= 1 << (CKEN_ISC & 31);
223
224 /*
225 * Low power modes require the HSIO2 clock to be enabled.
226 */
227 CKENB |= 1 << (CKEN_HSIO2 & 31);
228}
229
230static void pxa3xx_cpu_pm_restore(unsigned long *sleep_save)
231{
232 CKENB &= ~(1 << (CKEN_HSIO2 & 31));
233}
234
235/*
236 * Enter a standby mode (S0D1C2 or S0D2C2). Upon wakeup, the dynamic
237 * memory controller has to be reinitialised, so we place some code
238 * in the SRAM to perform this function.
239 *
240 * We disable FIQs across the standby - otherwise, we might receive a
241 * FIQ while the SDRAM is unavailable.
242 */
243static void pxa3xx_cpu_standby(unsigned int pwrmode)
244{
245 extern const char pm_enter_standby_start[], pm_enter_standby_end[];
246 void (*fn)(unsigned int) = (void __force *)(sram + 0x8000);
247
248 memcpy_toio(sram + 0x8000, pm_enter_standby_start,
249 pm_enter_standby_end - pm_enter_standby_start);
250
251 AD2D0SR = ~0;
252 AD2D1SR = ~0;
253 AD2D0ER = wakeup_src;
254 AD2D1ER = 0;
255 ASCR = ASCR;
256 ARSR = ARSR;
257
258 local_fiq_disable();
259 fn(pwrmode);
260 local_fiq_enable();
261
262 AD2D0ER = 0;
263 AD2D1ER = 0;
264
265 printk("PM: AD2D0SR=%08x ASCR=%08x\n", AD2D0SR, ASCR);
266}
267
268static void pxa3xx_cpu_pm_enter(suspend_state_t state)
269{
270 /*
271 * Don't sleep if no wakeup sources are defined
272 */
273 if (wakeup_src == 0)
274 return;
275
276 switch (state) {
277 case PM_SUSPEND_STANDBY:
278 pxa3xx_cpu_standby(PXA3xx_PM_S0D2C2);
279 break;
280
281 case PM_SUSPEND_MEM:
282 break;
283 }
284}
285
286static int pxa3xx_cpu_pm_valid(suspend_state_t state)
287{
288 return state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY;
289}
290
291static struct pxa_cpu_pm_fns pxa3xx_cpu_pm_fns = {
292 .save_size = SLEEP_SAVE_SIZE,
293 .save = pxa3xx_cpu_pm_save,
294 .restore = pxa3xx_cpu_pm_restore,
295 .valid = pxa3xx_cpu_pm_valid,
296 .enter = pxa3xx_cpu_pm_enter,
192}; 297};
193 298
299static void __init pxa3xx_init_pm(void)
300{
301 sram = ioremap(ISRAM_START, ISRAM_SIZE);
302 if (!sram) {
303 printk(KERN_ERR "Unable to map ISRAM: disabling standby/suspend\n");
304 return;
305 }
306
307 /*
308 * Since we copy wakeup code into the SRAM, we need to ensure
309 * that it is preserved over the low power modes. Note: bit 8
310 * is undocumented in the developer manual, but must be set.
311 */
312 AD1R |= ADXR_L2 | ADXR_R0;
313 AD2R |= ADXR_L2 | ADXR_R0;
314 AD3R |= ADXR_L2 | ADXR_R0;
315
316 /*
317 * Clear the resume enable registers.
318 */
319 AD1D0ER = 0;
320 AD2D0ER = 0;
321 AD2D1ER = 0;
322 AD3ER = 0;
323
324 pxa_cpu_pm_fns = &pxa3xx_cpu_pm_fns;
325}
326
327static int pxa3xx_set_wake(unsigned int irq, unsigned int on)
328{
329 unsigned long flags, mask = 0;
330
331 switch (irq) {
332 case IRQ_SSP3:
333 mask = ADXER_MFP_WSSP3;
334 break;
335 case IRQ_MSL:
336 mask = ADXER_WMSL0;
337 break;
338 case IRQ_USBH2:
339 case IRQ_USBH1:
340 mask = ADXER_WUSBH;
341 break;
342 case IRQ_KEYPAD:
343 mask = ADXER_WKP;
344 break;
345 case IRQ_AC97:
346 mask = ADXER_MFP_WAC97;
347 break;
348 case IRQ_USIM:
349 mask = ADXER_WUSIM0;
350 break;
351 case IRQ_SSP2:
352 mask = ADXER_MFP_WSSP2;
353 break;
354 case IRQ_I2C:
355 mask = ADXER_MFP_WI2C;
356 break;
357 case IRQ_STUART:
358 mask = ADXER_MFP_WUART3;
359 break;
360 case IRQ_BTUART:
361 mask = ADXER_MFP_WUART2;
362 break;
363 case IRQ_FFUART:
364 mask = ADXER_MFP_WUART1;
365 break;
366 case IRQ_MMC:
367 mask = ADXER_MFP_WMMC1;
368 break;
369 case IRQ_SSP:
370 mask = ADXER_MFP_WSSP1;
371 break;
372 case IRQ_RTCAlrm:
373 mask = ADXER_WRTC;
374 break;
375 case IRQ_SSP4:
376 mask = ADXER_MFP_WSSP4;
377 break;
378 case IRQ_TSI:
379 mask = ADXER_WTSI;
380 break;
381 case IRQ_USIM2:
382 mask = ADXER_WUSIM1;
383 break;
384 case IRQ_MMC2:
385 mask = ADXER_MFP_WMMC2;
386 break;
387 case IRQ_NAND:
388 mask = ADXER_MFP_WFLASH;
389 break;
390 case IRQ_USB2:
391 mask = ADXER_WUSB2;
392 break;
393 case IRQ_WAKEUP0:
394 mask = ADXER_WEXTWAKE0;
395 break;
396 case IRQ_WAKEUP1:
397 mask = ADXER_WEXTWAKE1;
398 break;
399 case IRQ_MMC3:
400 mask = ADXER_MFP_GEN12;
401 break;
402 }
403
404 local_irq_save(flags);
405 if (on)
406 wakeup_src |= mask;
407 else
408 wakeup_src &= ~mask;
409 local_irq_restore(flags);
410
411 return 0;
412}
413
414static void pxa3xx_init_irq_pm(void)
415{
416 pxa_init_irq_set_wake(pxa3xx_set_wake);
417}
418
419#else
420static inline void pxa3xx_init_pm(void) {}
421static inline void pxa3xx_init_irq_pm(void) {}
422#endif
423
194void __init pxa3xx_init_irq(void) 424void __init pxa3xx_init_irq(void)
195{ 425{
196 /* enable CP6 access */ 426 /* enable CP6 access */
@@ -202,6 +432,7 @@ void __init pxa3xx_init_irq(void)
202 pxa_init_irq_low(); 432 pxa_init_irq_low();
203 pxa_init_irq_high(); 433 pxa_init_irq_high();
204 pxa_init_irq_gpio(128); 434 pxa_init_irq_gpio(128);
435 pxa3xx_init_irq_pm();
205} 436}
206 437
207/* 438/*
@@ -209,16 +440,16 @@ void __init pxa3xx_init_irq(void)
209 */ 440 */
210 441
211static struct platform_device *devices[] __initdata = { 442static struct platform_device *devices[] __initdata = {
212 &pxa_device_mci,
213 &pxa_device_udc, 443 &pxa_device_udc,
214 &pxa_device_fb,
215 &pxa_device_ffuart, 444 &pxa_device_ffuart,
216 &pxa_device_btuart, 445 &pxa_device_btuart,
217 &pxa_device_stuart, 446 &pxa_device_stuart,
218 &pxa_device_i2c,
219 &pxa_device_i2s, 447 &pxa_device_i2s,
220 &pxa_device_ficp,
221 &pxa_device_rtc, 448 &pxa_device_rtc,
449 &pxa27x_device_ssp1,
450 &pxa27x_device_ssp2,
451 &pxa27x_device_ssp3,
452 &pxa3xx_device_ssp4,
222}; 453};
223 454
224static int __init pxa3xx_init(void) 455static int __init pxa3xx_init(void)
@@ -231,6 +462,8 @@ static int __init pxa3xx_init(void)
231 if ((ret = pxa_init_dma(32))) 462 if ((ret = pxa_init_dma(32)))
232 return ret; 463 return ret;
233 464
465 pxa3xx_init_pm();
466
234 return platform_add_devices(devices, ARRAY_SIZE(devices)); 467 return platform_add_devices(devices, ARRAY_SIZE(devices));
235 } 468 }
236 return 0; 469 return 0;
diff --git a/arch/arm/mach-pxa/sharpsl.h b/arch/arm/mach-pxa/sharpsl.h
index da4769caaf72..047909a76651 100644
--- a/arch/arm/mach-pxa/sharpsl.h
+++ b/arch/arm/mach-pxa/sharpsl.h
@@ -26,28 +26,15 @@ void corgi_ssp_set_machinfo(struct corgissp_machinfo *machinfo);
26 26
27 27
28/* 28/*
29 * SharpSL Backlight 29 * SharpSL/Corgi LCD Driver
30 */ 30 */
31void corgi_bl_set_intensity(int intensity); 31void corgi_lcdtg_suspend(void);
32void spitz_bl_set_intensity(int intensity); 32void corgi_lcdtg_hw_init(int mode);
33void akita_bl_set_intensity(int intensity);
34
35
36/*
37 * SharpSL Touchscreen Driver
38 */
39unsigned long corgi_get_hsync_len(void);
40unsigned long spitz_get_hsync_len(void);
41void corgi_put_hsync(void);
42void spitz_put_hsync(void);
43void corgi_wait_hsync(void);
44void spitz_wait_hsync(void);
45 33
46 34
47/* 35/*
48 * SharpSL Battery/PM Driver 36 * SharpSL Battery/PM Driver
49 */ 37 */
50
51#define READ_GPIO_BIT(x) (GPLR(x) & GPIO_bit(x)) 38#define READ_GPIO_BIT(x) (GPLR(x) & GPIO_bit(x))
52 39
53/* MAX1111 Channel Definitions */ 40/* MAX1111 Channel Definitions */
diff --git a/arch/arm/mach-pxa/sleep.S b/arch/arm/mach-pxa/sleep.S
index d0447723b73a..14bb4a93ea52 100644
--- a/arch/arm/mach-pxa/sleep.S
+++ b/arch/arm/mach-pxa/sleep.S
@@ -16,6 +16,7 @@
16#include <asm/hardware.h> 16#include <asm/hardware.h>
17 17
18#include <asm/arch/pxa-regs.h> 18#include <asm/arch/pxa-regs.h>
19#include <asm/arch/pxa2xx-regs.h>
19 20
20#define MDREFR_KDIV 0x200a4000 // all banks 21#define MDREFR_KDIV 0x200a4000 // all banks
21#define CCCR_SLEEP 0x00000107 // L=7 2N=2 A=0 PPDIS=0 CPDIS=0 22#define CCCR_SLEEP 0x00000107 // L=7 2N=2 A=0 PPDIS=0 CPDIS=0
@@ -49,6 +50,7 @@ pxa_cpu_save_sp:
49 str r0, [r1] 50 str r0, [r1]
50 ldr pc, [sp], #4 51 ldr pc, [sp], #4
51 52
53#ifdef CONFIG_PXA27x
52/* 54/*
53 * pxa27x_cpu_suspend() 55 * pxa27x_cpu_suspend()
54 * 56 *
@@ -104,9 +106,11 @@ ENTRY(pxa27x_cpu_suspend)
104 106
105 @ align execution to a cache line 107 @ align execution to a cache line
106 b pxa_cpu_do_suspend 108 b pxa_cpu_do_suspend
109#endif
107 110
111#ifdef CONFIG_PXA25x
108/* 112/*
109 * pxa27x_cpu_suspend() 113 * pxa25x_cpu_suspend()
110 * 114 *
111 * Forces CPU into sleep state. 115 * Forces CPU into sleep state.
112 * 116 *
@@ -169,6 +173,7 @@ ENTRY(pxa25x_cpu_suspend)
169 mcr p14, 0, r0, c6, c0, 0 173 mcr p14, 0, r0, c6, c0, 0
170 orr r0, r0, #2 @ initiate change bit 174 orr r0, r0, #2 @ initiate change bit
171 b pxa_cpu_do_suspend 175 b pxa_cpu_do_suspend
176#endif
172 177
173 .ltorg 178 .ltorg
174 .align 5 179 .align 5
@@ -208,7 +213,7 @@ pxa_cpu_do_suspend:
20820: b 20b @ loop waiting for sleep 21320: b 20b @ loop waiting for sleep
209 214
210/* 215/*
211 * cpu_pxa_resume() 216 * pxa_cpu_resume()
212 * 217 *
213 * entry point from bootloader into kernel during resume 218 * entry point from bootloader into kernel during resume
214 * 219 *
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 2d78199d24af..5078edeadf96 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -271,6 +271,55 @@ static struct platform_device spitzled_device = {
271/* 271/*
272 * Spitz Touch Screen Device 272 * Spitz Touch Screen Device
273 */ 273 */
274
275static unsigned long (*get_hsync_invperiod)(struct device *dev);
276
277static void inline sharpsl_wait_sync(int gpio)
278{
279 while((GPLR(gpio) & GPIO_bit(gpio)) == 0);
280 while((GPLR(gpio) & GPIO_bit(gpio)) != 0);
281}
282
283static struct device *spitz_pxafb_dev;
284
285static int is_pxafb_device(struct device * dev, void * data)
286{
287 struct platform_device *pdev = container_of(dev, struct platform_device, dev);
288
289 return (strncmp(pdev->name, "pxa2xx-fb", 9) == 0);
290}
291
292static unsigned long spitz_get_hsync_invperiod(void)
293{
294#ifdef CONFIG_FB_PXA
295 if (!spitz_pxafb_dev) {
296 spitz_pxafb_dev = bus_find_device(&platform_bus_type, NULL, NULL, is_pxafb_device);
297 if (!spitz_pxafb_dev)
298 return 0;
299 }
300 if (!get_hsync_invperiod)
301 get_hsync_invperiod = symbol_get(pxafb_get_hsync_time);
302 if (!get_hsync_invperiod)
303#endif
304 return 0;
305
306 return get_hsync_invperiod(spitz_pxafb_dev);
307}
308
309static void spitz_put_hsync(void)
310{
311 put_device(spitz_pxafb_dev);
312 if (get_hsync_invperiod)
313 symbol_put(pxafb_get_hsync_time);
314 spitz_pxafb_dev = NULL;
315 get_hsync_invperiod = NULL;
316}
317
318static void spitz_wait_hsync(void)
319{
320 sharpsl_wait_sync(SPITZ_GPIO_HSYNC);
321}
322
274static struct resource spitzts_resources[] = { 323static struct resource spitzts_resources[] = {
275 [0] = { 324 [0] = {
276 .start = SPITZ_IRQ_GPIO_TP_INT, 325 .start = SPITZ_IRQ_GPIO_TP_INT,
@@ -280,9 +329,9 @@ static struct resource spitzts_resources[] = {
280}; 329};
281 330
282static struct corgits_machinfo spitz_ts_machinfo = { 331static struct corgits_machinfo spitz_ts_machinfo = {
283 .get_hsync_len = spitz_get_hsync_len, 332 .get_hsync_invperiod = spitz_get_hsync_invperiod,
284 .put_hsync = spitz_put_hsync, 333 .put_hsync = spitz_put_hsync,
285 .wait_hsync = spitz_wait_hsync, 334 .wait_hsync = spitz_wait_hsync,
286}; 335};
287 336
288static struct platform_device spitzts_device = { 337static struct platform_device spitzts_device = {
@@ -325,12 +374,10 @@ static int spitz_mci_init(struct device *dev, irq_handler_t spitz_detect_int, vo
325 err = request_irq(SPITZ_IRQ_GPIO_nSD_DETECT, spitz_detect_int, 374 err = request_irq(SPITZ_IRQ_GPIO_nSD_DETECT, spitz_detect_int,
326 IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 375 IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
327 "MMC card detect", data); 376 "MMC card detect", data);
328 if (err) { 377 if (err)
329 printk(KERN_ERR "spitz_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); 378 printk(KERN_ERR "spitz_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
330 return -1;
331 }
332 379
333 return 0; 380 return err;
334} 381}
335 382
336static void spitz_mci_setpower(struct device *dev, unsigned int vdd) 383static void spitz_mci_setpower(struct device *dev, unsigned int vdd)
@@ -423,6 +470,14 @@ static struct pxaficp_platform_data spitz_ficp_platform_data = {
423 * Spitz PXA Framebuffer 470 * Spitz PXA Framebuffer
424 */ 471 */
425 472
473static void spitz_lcd_power(int on, struct fb_var_screeninfo *var)
474{
475 if (on)
476 corgi_lcdtg_hw_init(var->xres);
477 else
478 corgi_lcdtg_suspend();
479}
480
426static struct pxafb_mode_info spitz_pxafb_modes[] = { 481static struct pxafb_mode_info spitz_pxafb_modes[] = {
427{ 482{
428 .pixclock = 19231, 483 .pixclock = 19231,
@@ -520,6 +575,27 @@ static void __init common_init(void)
520 set_pxa_fb_info(&spitz_pxafb_info); 575 set_pxa_fb_info(&spitz_pxafb_info);
521} 576}
522 577
578#if defined(CONFIG_MACH_SPITZ) || defined(CONFIG_MACH_BORZOI)
579static void spitz_bl_set_intensity(int intensity)
580{
581 if (intensity > 0x10)
582 intensity += 0x10;
583
584 /* Bits 0-4 are accessed via the SSP interface */
585 corgi_ssp_blduty_set(intensity & 0x1f);
586
587 /* Bit 5 is via SCOOP */
588 if (intensity & 0x0020)
589 reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_CONT);
590 else
591 set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_CONT);
592
593 if (intensity)
594 set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_ON);
595 else
596 reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_ON);
597}
598
523static void __init spitz_init(void) 599static void __init spitz_init(void)
524{ 600{
525 platform_scoop_config = &spitz_pcmcia_config; 601 platform_scoop_config = &spitz_pcmcia_config;
@@ -530,6 +606,7 @@ static void __init spitz_init(void)
530 606
531 platform_device_register(&spitzscoop2_device); 607 platform_device_register(&spitzscoop2_device);
532} 608}
609#endif
533 610
534#ifdef CONFIG_MACH_AKITA 611#ifdef CONFIG_MACH_AKITA
535/* 612/*
@@ -542,6 +619,26 @@ struct platform_device akitaioexp_device = {
542 619
543EXPORT_SYMBOL_GPL(akitaioexp_device); 620EXPORT_SYMBOL_GPL(akitaioexp_device);
544 621
622static void akita_bl_set_intensity(int intensity)
623{
624 if (intensity > 0x10)
625 intensity += 0x10;
626
627 /* Bits 0-4 are accessed via the SSP interface */
628 corgi_ssp_blduty_set(intensity & 0x1f);
629
630 /* Bit 5 is via IO-Expander */
631 if (intensity & 0x0020)
632 akita_reset_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_CONT);
633 else
634 akita_set_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_CONT);
635
636 if (intensity)
637 akita_set_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_ON);
638 else
639 akita_reset_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_ON);
640}
641
545static void __init akita_init(void) 642static void __init akita_init(void)
546{ 643{
547 spitz_ficp_platform_data.transceiver_mode = akita_irda_transceiver_mode; 644 spitz_ficp_platform_data.transceiver_mode = akita_irda_transceiver_mode;
@@ -558,7 +655,6 @@ static void __init akita_init(void)
558} 655}
559#endif 656#endif
560 657
561
562static void __init fixup_spitz(struct machine_desc *desc, 658static void __init fixup_spitz(struct machine_desc *desc,
563 struct tag *tags, char **cmdline, struct meminfo *mi) 659 struct tag *tags, char **cmdline, struct meminfo *mi)
564{ 660{
diff --git a/arch/arm/mach-pxa/ssp.c b/arch/arm/mach-pxa/ssp.c
index 422afee88169..00af7f2fed66 100644
--- a/arch/arm/mach-pxa/ssp.c
+++ b/arch/arm/mach-pxa/ssp.c
@@ -32,45 +32,27 @@
32#include <linux/ioport.h> 32#include <linux/ioport.h>
33#include <linux/init.h> 33#include <linux/init.h>
34#include <linux/mutex.h> 34#include <linux/mutex.h>
35#include <linux/clk.h>
36#include <linux/err.h>
37#include <linux/platform_device.h>
38
35#include <asm/io.h> 39#include <asm/io.h>
36#include <asm/irq.h> 40#include <asm/irq.h>
37#include <asm/hardware.h> 41#include <asm/hardware.h>
38#include <asm/arch/ssp.h> 42#include <asm/arch/ssp.h>
39#include <asm/arch/pxa-regs.h> 43#include <asm/arch/pxa-regs.h>
40 44#include <asm/arch/regs-ssp.h>
41#define PXA_SSP_PORTS 3
42 45
43#define TIMEOUT 100000 46#define TIMEOUT 100000
44 47
45struct ssp_info_ {
46 int irq;
47 u32 clock;
48};
49
50/*
51 * SSP port clock and IRQ settings
52 */
53static const struct ssp_info_ ssp_info[PXA_SSP_PORTS] = {
54#if defined (CONFIG_PXA27x)
55 {IRQ_SSP, CKEN_SSP1},
56 {IRQ_SSP2, CKEN_SSP2},
57 {IRQ_SSP3, CKEN_SSP3},
58#else
59 {IRQ_SSP, CKEN_SSP},
60 {IRQ_NSSP, CKEN_NSSP},
61 {IRQ_ASSP, CKEN_ASSP},
62#endif
63};
64
65static DEFINE_MUTEX(mutex);
66static int use_count[PXA_SSP_PORTS] = {0, 0, 0};
67
68static irqreturn_t ssp_interrupt(int irq, void *dev_id) 48static irqreturn_t ssp_interrupt(int irq, void *dev_id)
69{ 49{
70 struct ssp_dev *dev = (struct ssp_dev*) dev_id; 50 struct ssp_dev *dev = dev_id;
71 unsigned int status = SSSR_P(dev->port); 51 struct ssp_device *ssp = dev->ssp;
52 unsigned int status;
72 53
73 SSSR_P(dev->port) = status; /* clear status bits */ 54 status = __raw_readl(ssp->mmio_base + SSSR);
55 __raw_writel(status, ssp->mmio_base + SSSR);
74 56
75 if (status & SSSR_ROR) 57 if (status & SSSR_ROR)
76 printk(KERN_WARNING "SSP(%d): receiver overrun\n", dev->port); 58 printk(KERN_WARNING "SSP(%d): receiver overrun\n", dev->port);
@@ -99,15 +81,16 @@ static irqreturn_t ssp_interrupt(int irq, void *dev_id)
99 */ 81 */
100int ssp_write_word(struct ssp_dev *dev, u32 data) 82int ssp_write_word(struct ssp_dev *dev, u32 data)
101{ 83{
84 struct ssp_device *ssp = dev->ssp;
102 int timeout = TIMEOUT; 85 int timeout = TIMEOUT;
103 86
104 while (!(SSSR_P(dev->port) & SSSR_TNF)) { 87 while (!(__raw_readl(ssp->mmio_base + SSSR) & SSSR_TNF)) {
105 if (!--timeout) 88 if (!--timeout)
106 return -ETIMEDOUT; 89 return -ETIMEDOUT;
107 cpu_relax(); 90 cpu_relax();
108 } 91 }
109 92
110 SSDR_P(dev->port) = data; 93 __raw_writel(data, ssp->mmio_base + SSDR);
111 94
112 return 0; 95 return 0;
113} 96}
@@ -129,15 +112,16 @@ int ssp_write_word(struct ssp_dev *dev, u32 data)
129 */ 112 */
130int ssp_read_word(struct ssp_dev *dev, u32 *data) 113int ssp_read_word(struct ssp_dev *dev, u32 *data)
131{ 114{
115 struct ssp_device *ssp = dev->ssp;
132 int timeout = TIMEOUT; 116 int timeout = TIMEOUT;
133 117
134 while (!(SSSR_P(dev->port) & SSSR_RNE)) { 118 while (!(__raw_readl(ssp->mmio_base + SSSR) & SSSR_RNE)) {
135 if (!--timeout) 119 if (!--timeout)
136 return -ETIMEDOUT; 120 return -ETIMEDOUT;
137 cpu_relax(); 121 cpu_relax();
138 } 122 }
139 123
140 *data = SSDR_P(dev->port); 124 *data = __raw_readl(ssp->mmio_base + SSDR);
141 return 0; 125 return 0;
142} 126}
143 127
@@ -151,17 +135,28 @@ int ssp_read_word(struct ssp_dev *dev, u32 *data)
151 */ 135 */
152int ssp_flush(struct ssp_dev *dev) 136int ssp_flush(struct ssp_dev *dev)
153{ 137{
138 struct ssp_device *ssp = dev->ssp;
154 int timeout = TIMEOUT * 2; 139 int timeout = TIMEOUT * 2;
155 140
141 /* ensure TX FIFO is empty instead of not full */
142 if (cpu_is_pxa3xx()) {
143 while (__raw_readl(ssp->mmio_base + SSSR) & 0xf00) {
144 if (!--timeout)
145 return -ETIMEDOUT;
146 cpu_relax();
147 }
148 timeout = TIMEOUT * 2;
149 }
150
156 do { 151 do {
157 while (SSSR_P(dev->port) & SSSR_RNE) { 152 while (__raw_readl(ssp->mmio_base + SSSR) & SSSR_RNE) {
158 if (!--timeout) 153 if (!--timeout)
159 return -ETIMEDOUT; 154 return -ETIMEDOUT;
160 (void) SSDR_P(dev->port); 155 (void)__raw_readl(ssp->mmio_base + SSDR);
161 } 156 }
162 if (!--timeout) 157 if (!--timeout)
163 return -ETIMEDOUT; 158 return -ETIMEDOUT;
164 } while (SSSR_P(dev->port) & SSSR_BSY); 159 } while (__raw_readl(ssp->mmio_base + SSSR) & SSSR_BSY);
165 160
166 return 0; 161 return 0;
167} 162}
@@ -173,7 +168,12 @@ int ssp_flush(struct ssp_dev *dev)
173 */ 168 */
174void ssp_enable(struct ssp_dev *dev) 169void ssp_enable(struct ssp_dev *dev)
175{ 170{
176 SSCR0_P(dev->port) |= SSCR0_SSE; 171 struct ssp_device *ssp = dev->ssp;
172 uint32_t sscr0;
173
174 sscr0 = __raw_readl(ssp->mmio_base + SSCR0);
175 sscr0 |= SSCR0_SSE;
176 __raw_writel(sscr0, ssp->mmio_base + SSCR0);
177} 177}
178 178
179/** 179/**
@@ -183,7 +183,12 @@ void ssp_enable(struct ssp_dev *dev)
183 */ 183 */
184void ssp_disable(struct ssp_dev *dev) 184void ssp_disable(struct ssp_dev *dev)
185{ 185{
186 SSCR0_P(dev->port) &= ~SSCR0_SSE; 186 struct ssp_device *ssp = dev->ssp;
187 uint32_t sscr0;
188
189 sscr0 = __raw_readl(ssp->mmio_base + SSCR0);
190 sscr0 &= ~SSCR0_SSE;
191 __raw_writel(sscr0, ssp->mmio_base + SSCR0);
187} 192}
188 193
189/** 194/**
@@ -192,14 +197,16 @@ void ssp_disable(struct ssp_dev *dev)
192 * 197 *
193 * Save the configured SSP state for suspend. 198 * Save the configured SSP state for suspend.
194 */ 199 */
195void ssp_save_state(struct ssp_dev *dev, struct ssp_state *ssp) 200void ssp_save_state(struct ssp_dev *dev, struct ssp_state *state)
196{ 201{
197 ssp->cr0 = SSCR0_P(dev->port); 202 struct ssp_device *ssp = dev->ssp;
198 ssp->cr1 = SSCR1_P(dev->port); 203
199 ssp->to = SSTO_P(dev->port); 204 state->cr0 = __raw_readl(ssp->mmio_base + SSCR0);
200 ssp->psp = SSPSP_P(dev->port); 205 state->cr1 = __raw_readl(ssp->mmio_base + SSCR1);
206 state->to = __raw_readl(ssp->mmio_base + SSTO);
207 state->psp = __raw_readl(ssp->mmio_base + SSPSP);
201 208
202 SSCR0_P(dev->port) &= ~SSCR0_SSE; 209 ssp_disable(dev);
203} 210}
204 211
205/** 212/**
@@ -208,16 +215,18 @@ void ssp_save_state(struct ssp_dev *dev, struct ssp_state *ssp)
208 * 215 *
209 * Restore the SSP configuration saved previously by ssp_save_state. 216 * Restore the SSP configuration saved previously by ssp_save_state.
210 */ 217 */
211void ssp_restore_state(struct ssp_dev *dev, struct ssp_state *ssp) 218void ssp_restore_state(struct ssp_dev *dev, struct ssp_state *state)
212{ 219{
213 SSSR_P(dev->port) = SSSR_ROR | SSSR_TUR | SSSR_BCE; 220 struct ssp_device *ssp = dev->ssp;
221 uint32_t sssr = SSSR_ROR | SSSR_TUR | SSSR_BCE;
214 222
215 SSCR0_P(dev->port) = ssp->cr0 & ~SSCR0_SSE; 223 __raw_writel(sssr, ssp->mmio_base + SSSR);
216 SSCR1_P(dev->port) = ssp->cr1;
217 SSTO_P(dev->port) = ssp->to;
218 SSPSP_P(dev->port) = ssp->psp;
219 224
220 SSCR0_P(dev->port) = ssp->cr0; 225 __raw_writel(state->cr0 & ~SSCR0_SSE, ssp->mmio_base + SSCR0);
226 __raw_writel(state->cr1, ssp->mmio_base + SSCR1);
227 __raw_writel(state->to, ssp->mmio_base + SSTO);
228 __raw_writel(state->psp, ssp->mmio_base + SSPSP);
229 __raw_writel(state->cr0, ssp->mmio_base + SSCR0);
221} 230}
222 231
223/** 232/**
@@ -231,15 +240,17 @@ void ssp_restore_state(struct ssp_dev *dev, struct ssp_state *ssp)
231 */ 240 */
232int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 speed) 241int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 speed)
233{ 242{
243 struct ssp_device *ssp = dev->ssp;
244
234 dev->mode = mode; 245 dev->mode = mode;
235 dev->flags = flags; 246 dev->flags = flags;
236 dev->psp_flags = psp_flags; 247 dev->psp_flags = psp_flags;
237 dev->speed = speed; 248 dev->speed = speed;
238 249
239 /* set up port type, speed, port settings */ 250 /* set up port type, speed, port settings */
240 SSCR0_P(dev->port) = (dev->speed | dev->mode); 251 __raw_writel((dev->speed | dev->mode), ssp->mmio_base + SSCR0);
241 SSCR1_P(dev->port) = dev->flags; 252 __raw_writel(dev->flags, ssp->mmio_base + SSCR1);
242 SSPSP_P(dev->port) = dev->psp_flags; 253 __raw_writel(dev->psp_flags, ssp->mmio_base + SSPSP);
243 254
244 return 0; 255 return 0;
245} 256}
@@ -256,44 +267,32 @@ int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 spee
256 */ 267 */
257int ssp_init(struct ssp_dev *dev, u32 port, u32 init_flags) 268int ssp_init(struct ssp_dev *dev, u32 port, u32 init_flags)
258{ 269{
270 struct ssp_device *ssp;
259 int ret; 271 int ret;
260 272
261 if (port > PXA_SSP_PORTS || port == 0) 273 ssp = ssp_request(port, "SSP");
274 if (ssp == NULL)
262 return -ENODEV; 275 return -ENODEV;
263 276
264 mutex_lock(&mutex); 277 dev->ssp = ssp;
265 if (use_count[port - 1]) {
266 mutex_unlock(&mutex);
267 return -EBUSY;
268 }
269 use_count[port - 1]++;
270
271 if (!request_mem_region(__PREG(SSCR0_P(port)), 0x2c, "SSP")) {
272 use_count[port - 1]--;
273 mutex_unlock(&mutex);
274 return -EBUSY;
275 }
276 dev->port = port; 278 dev->port = port;
277 279
278 /* do we need to get irq */ 280 /* do we need to get irq */
279 if (!(init_flags & SSP_NO_IRQ)) { 281 if (!(init_flags & SSP_NO_IRQ)) {
280 ret = request_irq(ssp_info[port-1].irq, ssp_interrupt, 282 ret = request_irq(ssp->irq, ssp_interrupt,
281 0, "SSP", dev); 283 0, "SSP", dev);
282 if (ret) 284 if (ret)
283 goto out_region; 285 goto out_region;
284 dev->irq = ssp_info[port-1].irq; 286 dev->irq = ssp->irq;
285 } else 287 } else
286 dev->irq = 0; 288 dev->irq = 0;
287 289
288 /* turn on SSP port clock */ 290 /* turn on SSP port clock */
289 pxa_set_cken(ssp_info[port-1].clock, 1); 291 clk_enable(ssp->clk);
290 mutex_unlock(&mutex);
291 return 0; 292 return 0;
292 293
293out_region: 294out_region:
294 release_mem_region(__PREG(SSCR0_P(port)), 0x2c); 295 ssp_free(ssp);
295 use_count[port - 1]--;
296 mutex_unlock(&mutex);
297 return ret; 296 return ret;
298} 297}
299 298
@@ -304,23 +303,240 @@ out_region:
304 */ 303 */
305void ssp_exit(struct ssp_dev *dev) 304void ssp_exit(struct ssp_dev *dev)
306{ 305{
307 mutex_lock(&mutex); 306 struct ssp_device *ssp = dev->ssp;
308 SSCR0_P(dev->port) &= ~SSCR0_SSE; 307
308 ssp_disable(dev);
309 free_irq(dev->irq, dev);
310 clk_disable(ssp->clk);
311 ssp_free(ssp);
312}
313
314static DEFINE_MUTEX(ssp_lock);
315static LIST_HEAD(ssp_list);
316
317struct ssp_device *ssp_request(int port, const char *label)
318{
319 struct ssp_device *ssp = NULL;
320
321 mutex_lock(&ssp_lock);
322
323 list_for_each_entry(ssp, &ssp_list, node) {
324 if (ssp->port_id == port && ssp->use_count == 0) {
325 ssp->use_count++;
326 ssp->label = label;
327 break;
328 }
329 }
330
331 mutex_unlock(&ssp_lock);
332
333 if (ssp->port_id != port)
334 return NULL;
335
336 return ssp;
337}
338EXPORT_SYMBOL(ssp_request);
339
340void ssp_free(struct ssp_device *ssp)
341{
342 mutex_lock(&ssp_lock);
343 if (ssp->use_count) {
344 ssp->use_count--;
345 ssp->label = NULL;
346 } else
347 dev_err(&ssp->pdev->dev, "device already free\n");
348 mutex_unlock(&ssp_lock);
349}
350EXPORT_SYMBOL(ssp_free);
351
352static int __devinit ssp_probe(struct platform_device *pdev, int type)
353{
354 struct resource *res;
355 struct ssp_device *ssp;
356 int ret = 0;
357
358 ssp = kzalloc(sizeof(struct ssp_device), GFP_KERNEL);
359 if (ssp == NULL) {
360 dev_err(&pdev->dev, "failed to allocate memory");
361 return -ENOMEM;
362 }
363
364 ssp->clk = clk_get(&pdev->dev, "SSPCLK");
365 if (IS_ERR(ssp->clk)) {
366 ret = PTR_ERR(ssp->clk);
367 goto err_free;
368 }
369
370 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
371 if (res == NULL) {
372 dev_err(&pdev->dev, "no memory resource defined\n");
373 ret = -ENODEV;
374 goto err_free_clk;
375 }
376
377 res = request_mem_region(res->start, res->end - res->start + 1,
378 pdev->name);
379 if (res == NULL) {
380 dev_err(&pdev->dev, "failed to request memory resource\n");
381 ret = -EBUSY;
382 goto err_free_clk;
383 }
384
385 ssp->phys_base = res->start;
386
387 ssp->mmio_base = ioremap(res->start, res->end - res->start + 1);
388 if (ssp->mmio_base == NULL) {
389 dev_err(&pdev->dev, "failed to ioremap() registers\n");
390 ret = -ENODEV;
391 goto err_free_mem;
392 }
393
394 ssp->irq = platform_get_irq(pdev, 0);
395 if (ssp->irq < 0) {
396 dev_err(&pdev->dev, "no IRQ resource defined\n");
397 ret = -ENODEV;
398 goto err_free_io;
399 }
400
401 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
402 if (res == NULL) {
403 dev_err(&pdev->dev, "no SSP RX DRCMR defined\n");
404 ret = -ENODEV;
405 goto err_free_io;
406 }
407 ssp->drcmr_rx = res->start;
408
409 res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
410 if (res == NULL) {
411 dev_err(&pdev->dev, "no SSP TX DRCMR defined\n");
412 ret = -ENODEV;
413 goto err_free_io;
414 }
415 ssp->drcmr_tx = res->start;
416
417 /* PXA2xx/3xx SSP ports starts from 1 and the internal pdev->id
418 * starts from 0, do a translation here
419 */
420 ssp->port_id = pdev->id + 1;
421 ssp->use_count = 0;
422 ssp->type = type;
423
424 mutex_lock(&ssp_lock);
425 list_add(&ssp->node, &ssp_list);
426 mutex_unlock(&ssp_lock);
427
428 platform_set_drvdata(pdev, ssp);
429 return 0;
430
431err_free_io:
432 iounmap(ssp->mmio_base);
433err_free_mem:
434 release_mem_region(res->start, res->end - res->start + 1);
435err_free_clk:
436 clk_put(ssp->clk);
437err_free:
438 kfree(ssp);
439 return ret;
440}
441
442static int __devexit ssp_remove(struct platform_device *pdev)
443{
444 struct resource *res;
445 struct ssp_device *ssp;
446
447 ssp = platform_get_drvdata(pdev);
448 if (ssp == NULL)
449 return -ENODEV;
450
451 iounmap(ssp->mmio_base);
452
453 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
454 release_mem_region(res->start, res->end - res->start + 1);
455
456 clk_put(ssp->clk);
309 457
310 if (dev->port > PXA_SSP_PORTS || dev->port == 0) { 458 mutex_lock(&ssp_lock);
311 printk(KERN_WARNING "SSP: tried to close invalid port\n"); 459 list_del(&ssp->node);
312 mutex_unlock(&mutex); 460 mutex_unlock(&ssp_lock);
313 return; 461
462 kfree(ssp);
463 return 0;
464}
465
466static int __devinit pxa25x_ssp_probe(struct platform_device *pdev)
467{
468 return ssp_probe(pdev, PXA25x_SSP);
469}
470
471static int __devinit pxa25x_nssp_probe(struct platform_device *pdev)
472{
473 return ssp_probe(pdev, PXA25x_NSSP);
474}
475
476static int __devinit pxa27x_ssp_probe(struct platform_device *pdev)
477{
478 return ssp_probe(pdev, PXA27x_SSP);
479}
480
481static struct platform_driver pxa25x_ssp_driver = {
482 .driver = {
483 .name = "pxa25x-ssp",
484 },
485 .probe = pxa25x_ssp_probe,
486 .remove = __devexit_p(ssp_remove),
487};
488
489static struct platform_driver pxa25x_nssp_driver = {
490 .driver = {
491 .name = "pxa25x-nssp",
492 },
493 .probe = pxa25x_nssp_probe,
494 .remove = __devexit_p(ssp_remove),
495};
496
497static struct platform_driver pxa27x_ssp_driver = {
498 .driver = {
499 .name = "pxa27x-ssp",
500 },
501 .probe = pxa27x_ssp_probe,
502 .remove = __devexit_p(ssp_remove),
503};
504
505static int __init pxa_ssp_init(void)
506{
507 int ret = 0;
508
509 ret = platform_driver_register(&pxa25x_ssp_driver);
510 if (ret) {
511 printk(KERN_ERR "failed to register pxa25x_ssp_driver");
512 return ret;
513 }
514
515 ret = platform_driver_register(&pxa25x_nssp_driver);
516 if (ret) {
517 printk(KERN_ERR "failed to register pxa25x_nssp_driver");
518 return ret;
519 }
520
521 ret = platform_driver_register(&pxa27x_ssp_driver);
522 if (ret) {
523 printk(KERN_ERR "failed to register pxa27x_ssp_driver");
524 return ret;
314 } 525 }
315 526
316 pxa_set_cken(ssp_info[dev->port-1].clock, 0); 527 return ret;
317 if (dev->irq) 528}
318 free_irq(dev->irq, dev); 529
319 release_mem_region(__PREG(SSCR0_P(dev->port)), 0x2c); 530static void __exit pxa_ssp_exit(void)
320 use_count[dev->port - 1]--; 531{
321 mutex_unlock(&mutex); 532 platform_driver_unregister(&pxa25x_ssp_driver);
533 platform_driver_unregister(&pxa25x_nssp_driver);
534 platform_driver_unregister(&pxa27x_ssp_driver);
322} 535}
323 536
537arch_initcall(pxa_ssp_init);
538module_exit(pxa_ssp_exit);
539
324EXPORT_SYMBOL(ssp_write_word); 540EXPORT_SYMBOL(ssp_write_word);
325EXPORT_SYMBOL(ssp_read_word); 541EXPORT_SYMBOL(ssp_read_word);
326EXPORT_SYMBOL(ssp_flush); 542EXPORT_SYMBOL(ssp_flush);
diff --git a/arch/arm/mach-pxa/standby.S b/arch/arm/mach-pxa/standby.S
index d774430d02c0..167412e6bec8 100644
--- a/arch/arm/mach-pxa/standby.S
+++ b/arch/arm/mach-pxa/standby.S
@@ -17,6 +17,7 @@
17 17
18 .text 18 .text
19 19
20#ifdef CONFIG_PXA27x
20ENTRY(pxa_cpu_standby) 21ENTRY(pxa_cpu_standby)
21 ldr r0, =PSSR 22 ldr r0, =PSSR
22 mov r1, #(PSSR_PH | PSSR_STS) 23 mov r1, #(PSSR_PH | PSSR_STS)
@@ -29,3 +30,85 @@ ENTRY(pxa_cpu_standby)
291: mcr p14, 0, r2, c7, c0, 0 @ put the system into Standby 301: mcr p14, 0, r2, c7, c0, 0 @ put the system into Standby
30 str r1, [r0] @ make sure PSSR_PH/STS are clear 31 str r1, [r0] @ make sure PSSR_PH/STS are clear
31 mov pc, lr 32 mov pc, lr
33
34#endif
35
36#ifdef CONFIG_PXA3xx
37
38#define MDCNFG 0x0000
39#define MDCNFG_DMCEN (1 << 30)
40#define DDR_HCAL 0x0060
41#define DDR_HCAL_HCRNG 0x1f
42#define DDR_HCAL_HCPROG (1 << 28)
43#define DDR_HCAL_HCEN (1 << 31)
44#define DMCIER 0x0070
45#define DMCIER_EDLP (1 << 29)
46#define DMCISR 0x0078
47#define RCOMP 0x0100
48#define RCOMP_SWEVAL (1 << 31)
49
50ENTRY(pm_enter_standby_start)
51 mov r1, #0xf6000000 @ DMEMC_REG_BASE (MDCNFG)
52 add r1, r1, #0x00100000
53
54 /*
55 * Preload the TLB entry for accessing the dynamic memory
56 * controller registers. Note that page table lookups will
57 * fail until the dynamic memory controller has been
58 * reinitialised - and that includes MMU page table walks.
59 * This also means that only the dynamic memory controller
60 * can be reliably accessed in the code following standby.
61 */
62 ldr r2, [r1] @ Dummy read MDCNFG
63
64 mcr p14, 0, r0, c7, c0, 0
65 .rept 8
66 nop
67 .endr
68
69 ldr r0, [r1, #DDR_HCAL] @ Clear (and wait for) HCEN
70 bic r0, r0, #DDR_HCAL_HCEN
71 str r0, [r1, #DDR_HCAL]
721: ldr r0, [r1, #DDR_HCAL]
73 tst r0, #DDR_HCAL_HCEN
74 bne 1b
75
76 ldr r0, [r1, #RCOMP] @ Initiate RCOMP
77 orr r0, r0, #RCOMP_SWEVAL
78 str r0, [r1, #RCOMP]
79
80 mov r0, #~0 @ Clear interrupts
81 str r0, [r1, #DMCISR]
82
83 ldr r0, [r1, #DMCIER] @ set DMIER[EDLP]
84 orr r0, r0, #DMCIER_EDLP
85 str r0, [r1, #DMCIER]
86
87 ldr r0, [r1, #DDR_HCAL] @ clear HCRNG, set HCPROG, HCEN
88 bic r0, r0, #DDR_HCAL_HCRNG
89 orr r0, r0, #DDR_HCAL_HCEN | DDR_HCAL_HCPROG
90 str r0, [r1, #DDR_HCAL]
91
921: ldr r0, [r1, #DMCISR]
93 tst r0, #DMCIER_EDLP
94 beq 1b
95
96 ldr r0, [r1, #MDCNFG] @ set MDCNFG[DMCEN]
97 orr r0, r0, #MDCNFG_DMCEN
98 str r0, [r1, #MDCNFG]
991: ldr r0, [r1, #MDCNFG]
100 tst r0, #MDCNFG_DMCEN
101 beq 1b
102
103 ldr r0, [r1, #DDR_HCAL] @ set DDR_HCAL[HCRNG]
104 orr r0, r0, #2 @ HCRNG
105 str r0, [r1, #DDR_HCAL]
106
107 ldr r0, [r1, #DMCIER] @ Clear the interrupt
108 bic r0, r0, #0x20000000
109 str r0, [r1, #DMCIER]
110
111 mov pc, lr
112ENTRY(pm_enter_standby_end)
113
114#endif
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
index fbfa1920353d..7b7c0179795b 100644
--- a/arch/arm/mach-pxa/time.c
+++ b/arch/arm/mach-pxa/time.c
@@ -59,55 +59,17 @@ unsigned long long sched_clock(void)
59} 59}
60 60
61 61
62#define MIN_OSCR_DELTA 16
63
62static irqreturn_t 64static irqreturn_t
63pxa_ost0_interrupt(int irq, void *dev_id) 65pxa_ost0_interrupt(int irq, void *dev_id)
64{ 66{
65 int next_match;
66 struct clock_event_device *c = dev_id; 67 struct clock_event_device *c = dev_id;
67 68
68 if (c->mode == CLOCK_EVT_MODE_ONESHOT) { 69 /* Disarm the compare/match, signal the event. */
69 /* Disarm the compare/match, signal the event. */ 70 OIER &= ~OIER_E0;
70 OIER &= ~OIER_E0; 71 OSSR = OSSR_M0;
71 OSSR = OSSR_M0; 72 c->event_handler(c);
72 c->event_handler(c);
73 } else if (c->mode == CLOCK_EVT_MODE_PERIODIC) {
74 /* Call the event handler as many times as necessary
75 * to recover missed events, if any (if we update
76 * OSMR0 and OSCR0 is still ahead of us, we've missed
77 * the event). As we're dealing with that, re-arm the
78 * compare/match for the next event.
79 *
80 * HACK ALERT:
81 *
82 * There's a latency between the instruction that
83 * writes to OSMR0 and the actual commit to the
84 * physical hardware, because the CPU doesn't (have
85 * to) run at bus speed, there's a write buffer
86 * between the CPU and the bus, etc. etc. So if the
87 * target OSCR0 is "very close", to the OSMR0 load
88 * value, the update to OSMR0 might not get to the
89 * hardware in time and we'll miss that interrupt.
90 *
91 * To be safe, if the new OSMR0 is "very close" to the
92 * target OSCR0 value, we call the event_handler as
93 * though the event actually happened. According to
94 * Nico's comment in the previous version of this
95 * code, experience has shown that 6 OSCR ticks is
96 * "very close" but he went with 8. We will use 16,
97 * based on the results of testing on PXA270.
98 *
99 * To be doubly sure, we also tell clkevt via
100 * clockevents_register_device() not to ask for
101 * anything that might put us "very close".
102 */
103#define MIN_OSCR_DELTA 16
104 do {
105 OSSR = OSSR_M0;
106 next_match = (OSMR0 += LATCH);
107 c->event_handler(c);
108 } while (((signed long)(next_match - OSCR) <= MIN_OSCR_DELTA)
109 && (c->mode == CLOCK_EVT_MODE_PERIODIC));
110 }
111 73
112 return IRQ_HANDLED; 74 return IRQ_HANDLED;
113} 75}
@@ -133,14 +95,6 @@ pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
133 unsigned long irqflags; 95 unsigned long irqflags;
134 96
135 switch (mode) { 97 switch (mode) {
136 case CLOCK_EVT_MODE_PERIODIC:
137 raw_local_irq_save(irqflags);
138 OSSR = OSSR_M0;
139 OIER |= OIER_E0;
140 OSMR0 = OSCR + LATCH;
141 raw_local_irq_restore(irqflags);
142 break;
143
144 case CLOCK_EVT_MODE_ONESHOT: 98 case CLOCK_EVT_MODE_ONESHOT:
145 raw_local_irq_save(irqflags); 99 raw_local_irq_save(irqflags);
146 OIER &= ~OIER_E0; 100 OIER &= ~OIER_E0;
@@ -158,13 +112,14 @@ pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
158 break; 112 break;
159 113
160 case CLOCK_EVT_MODE_RESUME: 114 case CLOCK_EVT_MODE_RESUME:
115 case CLOCK_EVT_MODE_PERIODIC:
161 break; 116 break;
162 } 117 }
163} 118}
164 119
165static struct clock_event_device ckevt_pxa_osmr0 = { 120static struct clock_event_device ckevt_pxa_osmr0 = {
166 .name = "osmr0", 121 .name = "osmr0",
167 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, 122 .features = CLOCK_EVT_FEAT_ONESHOT,
168 .shift = 32, 123 .shift = 32,
169 .rating = 200, 124 .rating = 200,
170 .cpumask = CPU_MASK_CPU0, 125 .cpumask = CPU_MASK_CPU0,
@@ -214,7 +169,7 @@ static void __init pxa_timer_init(void)
214 ckevt_pxa_osmr0.max_delta_ns = 169 ckevt_pxa_osmr0.max_delta_ns =
215 clockevent_delta2ns(0x7fffffff, &ckevt_pxa_osmr0); 170 clockevent_delta2ns(0x7fffffff, &ckevt_pxa_osmr0);
216 ckevt_pxa_osmr0.min_delta_ns = 171 ckevt_pxa_osmr0.min_delta_ns =
217 clockevent_delta2ns(MIN_OSCR_DELTA, &ckevt_pxa_osmr0) + 1; 172 clockevent_delta2ns(MIN_OSCR_DELTA * 2, &ckevt_pxa_osmr0) + 1;
218 173
219 cksrc_pxa_oscr0.mult = 174 cksrc_pxa_oscr0.mult =
220 clocksource_hz2mult(clock_tick_rate, cksrc_pxa_oscr0.shift); 175 clocksource_hz2mult(clock_tick_rate, cksrc_pxa_oscr0.shift);
@@ -226,7 +181,7 @@ static void __init pxa_timer_init(void)
226} 181}
227 182
228#ifdef CONFIG_PM 183#ifdef CONFIG_PM
229static unsigned long osmr[4], oier; 184static unsigned long osmr[4], oier, oscr;
230 185
231static void pxa_timer_suspend(void) 186static void pxa_timer_suspend(void)
232{ 187{
@@ -235,23 +190,26 @@ static void pxa_timer_suspend(void)
235 osmr[2] = OSMR2; 190 osmr[2] = OSMR2;
236 osmr[3] = OSMR3; 191 osmr[3] = OSMR3;
237 oier = OIER; 192 oier = OIER;
193 oscr = OSCR;
238} 194}
239 195
240static void pxa_timer_resume(void) 196static void pxa_timer_resume(void)
241{ 197{
198 /*
199 * Ensure that we have at least MIN_OSCR_DELTA between match
200 * register 0 and the OSCR, to guarantee that we will receive
201 * the one-shot timer interrupt. We adjust OSMR0 in preference
202 * to OSCR to guarantee that OSCR is monotonically incrementing.
203 */
204 if (osmr[0] - oscr < MIN_OSCR_DELTA)
205 osmr[0] += MIN_OSCR_DELTA;
206
242 OSMR0 = osmr[0]; 207 OSMR0 = osmr[0];
243 OSMR1 = osmr[1]; 208 OSMR1 = osmr[1];
244 OSMR2 = osmr[2]; 209 OSMR2 = osmr[2];
245 OSMR3 = osmr[3]; 210 OSMR3 = osmr[3];
246 OIER = oier; 211 OIER = oier;
247 212 OSCR = oscr;
248 /*
249 * OSCR0 is the system timer, which has to increase
250 * monotonically until it rolls over in hardware. The value
251 * (OSMR0 - LATCH) is OSCR0 at the most recent system tick,
252 * which is a handy value to restore to OSCR0.
253 */
254 OSCR = OSMR0 - LATCH;
255} 213}
256#else 214#else
257#define pxa_timer_suspend NULL 215#define pxa_timer_suspend NULL
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index 240fd042083d..1919756900f4 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -184,16 +184,13 @@ static int tosa_mci_init(struct device *dev, irq_handler_t tosa_detect_int, void
184 184
185 tosa_mci_platform_data.detect_delay = msecs_to_jiffies(250); 185 tosa_mci_platform_data.detect_delay = msecs_to_jiffies(250);
186 186
187 err = request_irq(TOSA_IRQ_GPIO_nSD_DETECT, tosa_detect_int, IRQF_DISABLED, 187 err = request_irq(TOSA_IRQ_GPIO_nSD_DETECT, tosa_detect_int,
188 IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
188 "MMC/SD card detect", data); 189 "MMC/SD card detect", data);
189 if (err) { 190 if (err)
190 printk(KERN_ERR "tosa_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); 191 printk(KERN_ERR "tosa_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
191 return -1;
192 }
193
194 set_irq_type(TOSA_IRQ_GPIO_nSD_DETECT, IRQT_BOTHEDGE);
195 192
196 return 0; 193 return err;
197} 194}
198 195
199static void tosa_mci_setpower(struct device *dev, unsigned int vdd) 196static void tosa_mci_setpower(struct device *dev, unsigned int vdd)
diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c
index e4ba43bdf85d..853fc9433750 100644
--- a/arch/arm/mach-pxa/trizeps4.c
+++ b/arch/arm/mach-pxa/trizeps4.c
@@ -296,11 +296,10 @@ static int trizeps4_mci_init(struct device *dev, irq_handler_t mci_detect_int, v
296 err = request_irq(TRIZEPS4_MMC_IRQ, mci_detect_int, 296 err = request_irq(TRIZEPS4_MMC_IRQ, mci_detect_int,
297 IRQF_DISABLED | IRQF_TRIGGER_RISING, 297 IRQF_DISABLED | IRQF_TRIGGER_RISING,
298 "MMC card detect", data); 298 "MMC card detect", data);
299 if (err) { 299 if (err)
300 printk(KERN_ERR "trizeps4_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); 300 printk(KERN_ERR "trizeps4_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
301 return -1; 301
302 } 302 return err;
303 return 0;
304} 303}
305 304
306static void trizeps4_mci_exit(struct device *dev, void *data) 305static void trizeps4_mci_exit(struct device *dev, void *data)
diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c
index 743a87b2faa1..7731d50dd86c 100644
--- a/arch/arm/mach-pxa/zylonite.c
+++ b/arch/arm/mach-pxa/zylonite.c
@@ -25,9 +25,13 @@
25#include <asm/arch/gpio.h> 25#include <asm/arch/gpio.h>
26#include <asm/arch/pxafb.h> 26#include <asm/arch/pxafb.h>
27#include <asm/arch/zylonite.h> 27#include <asm/arch/zylonite.h>
28#include <asm/arch/mmc.h>
28 29
29#include "generic.h" 30#include "generic.h"
30 31
32#define MAX_SLOTS 3
33struct platform_mmc_slot zylonite_mmc_slot[MAX_SLOTS];
34
31int gpio_backlight; 35int gpio_backlight;
32int gpio_eth_irq; 36int gpio_eth_irq;
33 37
@@ -43,7 +47,7 @@ static struct resource smc91x_resources[] = {
43 [1] = { 47 [1] = {
44 .start = -1, /* for run-time assignment */ 48 .start = -1, /* for run-time assignment */
45 .end = -1, 49 .end = -1,
46 .flags = IORESOURCE_IRQ, 50 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
47 } 51 }
48}; 52};
49 53
@@ -156,6 +160,95 @@ static void __init zylonite_init_lcd(void)
156static inline void zylonite_init_lcd(void) {} 160static inline void zylonite_init_lcd(void) {}
157#endif 161#endif
158 162
163#if defined(CONFIG_MMC)
164static int zylonite_mci_ro(struct device *dev)
165{
166 struct platform_device *pdev = to_platform_device(dev);
167
168 return gpio_get_value(zylonite_mmc_slot[pdev->id].gpio_wp);
169}
170
171static int zylonite_mci_init(struct device *dev,
172 irq_handler_t zylonite_detect_int,
173 void *data)
174{
175 struct platform_device *pdev = to_platform_device(dev);
176 int err, cd_irq, gpio_cd, gpio_wp;
177
178 cd_irq = gpio_to_irq(zylonite_mmc_slot[pdev->id].gpio_cd);
179 gpio_cd = zylonite_mmc_slot[pdev->id].gpio_cd;
180 gpio_wp = zylonite_mmc_slot[pdev->id].gpio_wp;
181
182 /*
183 * setup GPIO for Zylonite MMC controller
184 */
185 err = gpio_request(gpio_cd, "mmc card detect");
186 if (err)
187 goto err_request_cd;
188 gpio_direction_input(gpio_cd);
189
190 err = gpio_request(gpio_wp, "mmc write protect");
191 if (err)
192 goto err_request_wp;
193 gpio_direction_input(gpio_wp);
194
195 err = request_irq(cd_irq, zylonite_detect_int,
196 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
197 "MMC card detect", data);
198 if (err) {
199 printk(KERN_ERR "%s: MMC/SD/SDIO: "
200 "can't request card detect IRQ\n", __func__);
201 goto err_request_irq;
202 }
203
204 return 0;
205
206err_request_irq:
207 gpio_free(gpio_wp);
208err_request_wp:
209 gpio_free(gpio_cd);
210err_request_cd:
211 return err;
212}
213
214static void zylonite_mci_exit(struct device *dev, void *data)
215{
216 struct platform_device *pdev = to_platform_device(dev);
217 int cd_irq, gpio_cd, gpio_wp;
218
219 cd_irq = gpio_to_irq(zylonite_mmc_slot[pdev->id].gpio_cd);
220 gpio_cd = zylonite_mmc_slot[pdev->id].gpio_cd;
221 gpio_wp = zylonite_mmc_slot[pdev->id].gpio_wp;
222
223 free_irq(cd_irq, data);
224 gpio_free(gpio_cd);
225 gpio_free(gpio_wp);
226}
227
228static struct pxamci_platform_data zylonite_mci_platform_data = {
229 .detect_delay = 20,
230 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
231 .init = zylonite_mci_init,
232 .exit = zylonite_mci_exit,
233 .get_ro = zylonite_mci_ro,
234};
235
236static struct pxamci_platform_data zylonite_mci2_platform_data = {
237 .detect_delay = 20,
238 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
239};
240
241static void __init zylonite_init_mmc(void)
242{
243 pxa_set_mci_info(&zylonite_mci_platform_data);
244 pxa3xx_set_mci2_info(&zylonite_mci2_platform_data);
245 if (cpu_is_pxa310())
246 pxa3xx_set_mci3_info(&zylonite_mci_platform_data);
247}
248#else
249static inline void zylonite_init_mmc(void) {}
250#endif
251
159static void __init zylonite_init(void) 252static void __init zylonite_init(void)
160{ 253{
161 /* board-processor specific initialization */ 254 /* board-processor specific initialization */
@@ -171,6 +264,7 @@ static void __init zylonite_init(void)
171 platform_device_register(&smc91x_device); 264 platform_device_register(&smc91x_device);
172 265
173 zylonite_init_lcd(); 266 zylonite_init_lcd();
267 zylonite_init_mmc();
174} 268}
175 269
176MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)") 270MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)")
diff --git a/arch/arm/mach-pxa/zylonite_pxa300.c b/arch/arm/mach-pxa/zylonite_pxa300.c
index 1832bc316501..6ac04c09b0e9 100644
--- a/arch/arm/mach-pxa/zylonite_pxa300.c
+++ b/arch/arm/mach-pxa/zylonite_pxa300.c
@@ -53,13 +53,13 @@ static mfp_cfg_t common_mfp_cfg[] __initdata = {
53 53
54 /* BTUART */ 54 /* BTUART */
55 GPIO111_UART2_RTS, 55 GPIO111_UART2_RTS,
56 GPIO112_UART2_RXD, 56 GPIO112_UART2_RXD | MFP_LPM_EDGE_FALL,
57 GPIO113_UART2_TXD, 57 GPIO113_UART2_TXD,
58 GPIO114_UART2_CTS, 58 GPIO114_UART2_CTS | MFP_LPM_EDGE_BOTH,
59 59
60 /* STUART */ 60 /* STUART */
61 GPIO109_UART3_TXD, 61 GPIO109_UART3_TXD,
62 GPIO110_UART3_RXD, 62 GPIO110_UART3_RXD | MFP_LPM_EDGE_FALL,
63 63
64 /* AC97 */ 64 /* AC97 */
65 GPIO23_AC97_nACRESET, 65 GPIO23_AC97_nACRESET,
@@ -70,16 +70,16 @@ static mfp_cfg_t common_mfp_cfg[] __initdata = {
70 GPIO28_AC97_SYNC, 70 GPIO28_AC97_SYNC,
71 71
72 /* Keypad */ 72 /* Keypad */
73 GPIO107_KP_DKIN_0, 73 GPIO107_KP_DKIN_0 | MFP_LPM_EDGE_BOTH,
74 GPIO108_KP_DKIN_1, 74 GPIO108_KP_DKIN_1 | MFP_LPM_EDGE_BOTH,
75 GPIO115_KP_MKIN_0, 75 GPIO115_KP_MKIN_0 | MFP_LPM_EDGE_BOTH,
76 GPIO116_KP_MKIN_1, 76 GPIO116_KP_MKIN_1 | MFP_LPM_EDGE_BOTH,
77 GPIO117_KP_MKIN_2, 77 GPIO117_KP_MKIN_2 | MFP_LPM_EDGE_BOTH,
78 GPIO118_KP_MKIN_3, 78 GPIO118_KP_MKIN_3 | MFP_LPM_EDGE_BOTH,
79 GPIO119_KP_MKIN_4, 79 GPIO119_KP_MKIN_4 | MFP_LPM_EDGE_BOTH,
80 GPIO120_KP_MKIN_5, 80 GPIO120_KP_MKIN_5 | MFP_LPM_EDGE_BOTH,
81 GPIO2_2_KP_MKIN_6, 81 GPIO2_2_KP_MKIN_6 | MFP_LPM_EDGE_BOTH,
82 GPIO3_2_KP_MKIN_7, 82 GPIO3_2_KP_MKIN_7 | MFP_LPM_EDGE_BOTH,
83 GPIO121_KP_MKOUT_0, 83 GPIO121_KP_MKOUT_0,
84 GPIO122_KP_MKOUT_1, 84 GPIO122_KP_MKOUT_1,
85 GPIO123_KP_MKOUT_2, 85 GPIO123_KP_MKOUT_2,
@@ -88,16 +88,33 @@ static mfp_cfg_t common_mfp_cfg[] __initdata = {
88 GPIO4_2_KP_MKOUT_5, 88 GPIO4_2_KP_MKOUT_5,
89 GPIO5_2_KP_MKOUT_6, 89 GPIO5_2_KP_MKOUT_6,
90 GPIO6_2_KP_MKOUT_7, 90 GPIO6_2_KP_MKOUT_7,
91
92 /* MMC1 */
93 GPIO3_MMC1_DAT0,
94 GPIO4_MMC1_DAT1 | MFP_LPM_EDGE_BOTH,
95 GPIO5_MMC1_DAT2,
96 GPIO6_MMC1_DAT3,
97 GPIO7_MMC1_CLK,
98 GPIO8_MMC1_CMD, /* CMD0 for slot 0 */
99 GPIO15_GPIO, /* CMD1 default as GPIO for slot 0 */
100
101 /* MMC2 */
102 GPIO9_MMC2_DAT0,
103 GPIO10_MMC2_DAT1 | MFP_LPM_EDGE_BOTH,
104 GPIO11_MMC2_DAT2,
105 GPIO12_MMC2_DAT3,
106 GPIO13_MMC2_CLK,
107 GPIO14_MMC2_CMD,
91}; 108};
92 109
93static mfp_cfg_t pxa300_mfp_cfg[] __initdata = { 110static mfp_cfg_t pxa300_mfp_cfg[] __initdata = {
94 /* FFUART */ 111 /* FFUART */
95 GPIO30_UART1_RXD, 112 GPIO30_UART1_RXD | MFP_LPM_EDGE_FALL,
96 GPIO31_UART1_TXD, 113 GPIO31_UART1_TXD,
97 GPIO32_UART1_CTS, 114 GPIO32_UART1_CTS,
98 GPIO37_UART1_RTS, 115 GPIO37_UART1_RTS,
99 GPIO33_UART1_DCD, 116 GPIO33_UART1_DCD,
100 GPIO34_UART1_DSR, 117 GPIO34_UART1_DSR | MFP_LPM_EDGE_FALL,
101 GPIO35_UART1_RI, 118 GPIO35_UART1_RI,
102 GPIO36_UART1_DTR, 119 GPIO36_UART1_DTR,
103 120
@@ -108,7 +125,7 @@ static mfp_cfg_t pxa300_mfp_cfg[] __initdata = {
108 125
109static mfp_cfg_t pxa310_mfp_cfg[] __initdata = { 126static mfp_cfg_t pxa310_mfp_cfg[] __initdata = {
110 /* FFUART */ 127 /* FFUART */
111 GPIO99_UART1_RXD, 128 GPIO99_UART1_RXD | MFP_LPM_EDGE_FALL,
112 GPIO100_UART1_TXD, 129 GPIO100_UART1_TXD,
113 GPIO101_UART1_CTS, 130 GPIO101_UART1_CTS,
114 GPIO106_UART1_RTS, 131 GPIO106_UART1_RTS,
@@ -116,6 +133,14 @@ static mfp_cfg_t pxa310_mfp_cfg[] __initdata = {
116 /* Ethernet */ 133 /* Ethernet */
117 GPIO2_nCS3, 134 GPIO2_nCS3,
118 GPIO102_GPIO, 135 GPIO102_GPIO,
136
137 /* MMC3 */
138 GPIO7_2_MMC3_DAT0,
139 GPIO8_2_MMC3_DAT1 | MFP_LPM_EDGE_BOTH,
140 GPIO9_2_MMC3_DAT2,
141 GPIO10_2_MMC3_DAT3,
142 GPIO103_MMC3_CLK,
143 GPIO105_MMC3_CMD,
119}; 144};
120 145
121#define NUM_LCD_DETECT_PINS 7 146#define NUM_LCD_DETECT_PINS 7
@@ -174,6 +199,10 @@ void __init zylonite_pxa300_init(void)
174 199
175 /* GPIO pin assignment */ 200 /* GPIO pin assignment */
176 gpio_backlight = mfp_to_gpio(MFP_PIN_GPIO20); 201 gpio_backlight = mfp_to_gpio(MFP_PIN_GPIO20);
202
203 /* MMC card detect & write protect for controller 0 */
204 zylonite_mmc_slot[0].gpio_cd = EXT_GPIO(0);
205 zylonite_mmc_slot[0].gpio_wp = EXT_GPIO(2);
177 } 206 }
178 207
179 if (cpu_is_pxa300()) { 208 if (cpu_is_pxa300()) {
@@ -184,5 +213,9 @@ void __init zylonite_pxa300_init(void)
184 if (cpu_is_pxa310()) { 213 if (cpu_is_pxa310()) {
185 pxa3xx_mfp_config(ARRAY_AND_SIZE(pxa310_mfp_cfg)); 214 pxa3xx_mfp_config(ARRAY_AND_SIZE(pxa310_mfp_cfg));
186 gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO102); 215 gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO102);
216
217 /* MMC card detect & write protect for controller 2 */
218 zylonite_mmc_slot[2].gpio_cd = EXT_GPIO(30);
219 zylonite_mmc_slot[2].gpio_wp = EXT_GPIO(31);
187 } 220 }
188} 221}
diff --git a/arch/arm/mach-pxa/zylonite_pxa320.c b/arch/arm/mach-pxa/zylonite_pxa320.c
index 94c715808b59..dfa79992b8ab 100644
--- a/arch/arm/mach-pxa/zylonite_pxa320.c
+++ b/arch/arm/mach-pxa/zylonite_pxa320.c
@@ -51,11 +51,11 @@ static mfp_cfg_t mfp_cfg[] __initdata = {
51 GPIO17_2_LCD_BIAS, 51 GPIO17_2_LCD_BIAS,
52 52
53 /* FFUART */ 53 /* FFUART */
54 GPIO41_UART1_RXD, 54 GPIO41_UART1_RXD | MFP_LPM_EDGE_FALL,
55 GPIO42_UART1_TXD, 55 GPIO42_UART1_TXD,
56 GPIO43_UART1_CTS, 56 GPIO43_UART1_CTS,
57 GPIO44_UART1_DCD, 57 GPIO44_UART1_DCD,
58 GPIO45_UART1_DSR, 58 GPIO45_UART1_DSR | MFP_LPM_EDGE_FALL,
59 GPIO46_UART1_RI, 59 GPIO46_UART1_RI,
60 GPIO47_UART1_DTR, 60 GPIO47_UART1_DTR,
61 GPIO48_UART1_RTS, 61 GPIO48_UART1_RTS,
@@ -73,16 +73,16 @@ static mfp_cfg_t mfp_cfg[] __initdata = {
73 GPIO33_I2C_SDA, 73 GPIO33_I2C_SDA,
74 74
75 /* Keypad */ 75 /* Keypad */
76 GPIO105_KP_DKIN_0, 76 GPIO105_KP_DKIN_0 | MFP_LPM_EDGE_BOTH,
77 GPIO106_KP_DKIN_1, 77 GPIO106_KP_DKIN_1 | MFP_LPM_EDGE_BOTH,
78 GPIO113_KP_MKIN_0, 78 GPIO113_KP_MKIN_0 | MFP_LPM_EDGE_BOTH,
79 GPIO114_KP_MKIN_1, 79 GPIO114_KP_MKIN_1 | MFP_LPM_EDGE_BOTH,
80 GPIO115_KP_MKIN_2, 80 GPIO115_KP_MKIN_2 | MFP_LPM_EDGE_BOTH,
81 GPIO116_KP_MKIN_3, 81 GPIO116_KP_MKIN_3 | MFP_LPM_EDGE_BOTH,
82 GPIO117_KP_MKIN_4, 82 GPIO117_KP_MKIN_4 | MFP_LPM_EDGE_BOTH,
83 GPIO118_KP_MKIN_5, 83 GPIO118_KP_MKIN_5 | MFP_LPM_EDGE_BOTH,
84 GPIO119_KP_MKIN_6, 84 GPIO119_KP_MKIN_6 | MFP_LPM_EDGE_BOTH,
85 GPIO120_KP_MKIN_7, 85 GPIO120_KP_MKIN_7 | MFP_LPM_EDGE_BOTH,
86 GPIO121_KP_MKOUT_0, 86 GPIO121_KP_MKOUT_0,
87 GPIO122_KP_MKOUT_1, 87 GPIO122_KP_MKOUT_1,
88 GPIO123_KP_MKOUT_2, 88 GPIO123_KP_MKOUT_2,
@@ -95,6 +95,23 @@ static mfp_cfg_t mfp_cfg[] __initdata = {
95 /* Ethernet */ 95 /* Ethernet */
96 GPIO4_nCS3, 96 GPIO4_nCS3,
97 GPIO90_GPIO, 97 GPIO90_GPIO,
98
99 /* MMC1 */
100 GPIO18_MMC1_DAT0,
101 GPIO19_MMC1_DAT1 | MFP_LPM_EDGE_BOTH,
102 GPIO20_MMC1_DAT2,
103 GPIO21_MMC1_DAT3,
104 GPIO22_MMC1_CLK,
105 GPIO23_MMC1_CMD,/* CMD0 for slot 0 */
106 GPIO31_GPIO, /* CMD1 default as GPIO for slot 0 */
107
108 /* MMC2 */
109 GPIO24_MMC2_DAT0,
110 GPIO25_MMC2_DAT1 | MFP_LPM_EDGE_BOTH,
111 GPIO26_MMC2_DAT2,
112 GPIO27_MMC2_DAT3,
113 GPIO28_MMC2_CLK,
114 GPIO29_MMC2_CMD,
98}; 115};
99 116
100#define NUM_LCD_DETECT_PINS 7 117#define NUM_LCD_DETECT_PINS 7
@@ -169,5 +186,9 @@ void __init zylonite_pxa320_init(void)
169 /* GPIO pin assignment */ 186 /* GPIO pin assignment */
170 gpio_backlight = mfp_to_gpio(MFP_PIN_GPIO14); 187 gpio_backlight = mfp_to_gpio(MFP_PIN_GPIO14);
171 gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO9); 188 gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO9);
189
190 /* MMC card detect & write protect for controller 0 */
191 zylonite_mmc_slot[0].gpio_cd = mfp_to_gpio(MFP_PIN_GPIO1);
192 zylonite_mmc_slot[0].gpio_wp = mfp_to_gpio(MFP_PIN_GPIO5);
172 } 193 }
173} 194}
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index c7f1b44da40d..61d70218f1e8 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -530,8 +530,6 @@ static unsigned long realview_gettimeoffset(void)
530 */ 530 */
531static irqreturn_t realview_timer_interrupt(int irq, void *dev_id) 531static irqreturn_t realview_timer_interrupt(int irq, void *dev_id)
532{ 532{
533 write_seqlock(&xtime_lock);
534
535 // ...clear the interrupt 533 // ...clear the interrupt
536 writel(1, TIMER0_VA_BASE + TIMER_INTCLR); 534 writel(1, TIMER0_VA_BASE + TIMER_INTCLR);
537 535
@@ -542,8 +540,6 @@ static irqreturn_t realview_timer_interrupt(int irq, void *dev_id)
542 update_process_times(user_mode(get_irq_regs())); 540 update_process_times(user_mode(get_irq_regs()));
543#endif 541#endif
544 542
545 write_sequnlock(&xtime_lock);
546
547 return IRQ_HANDLED; 543 return IRQ_HANDLED;
548} 544}
549 545
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index 587864fe25fb..66175471fff3 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -530,7 +530,7 @@ static struct s3c2410fb_mach_info __initdata bast_fb_info = {
530 530
531 .displays = bast_lcd_info, 531 .displays = bast_lcd_info,
532 .num_displays = ARRAY_SIZE(bast_lcd_info), 532 .num_displays = ARRAY_SIZE(bast_lcd_info),
533 .default_display = 4, 533 .default_display = 1,
534}; 534};
535 535
536/* Standard BAST devices */ 536/* Standard BAST devices */
@@ -540,7 +540,6 @@ static struct platform_device *bast_devices[] __initdata = {
540 &s3c_device_lcd, 540 &s3c_device_lcd,
541 &s3c_device_wdt, 541 &s3c_device_wdt,
542 &s3c_device_i2c, 542 &s3c_device_i2c,
543 &s3c_device_iis,
544 &s3c_device_rtc, 543 &s3c_device_rtc,
545 &s3c_device_nand, 544 &s3c_device_nand,
546 &bast_device_nor, 545 &bast_device_nor,
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
index 9f43f3f124f5..3aade7b78fe5 100644
--- a/arch/arm/mach-s3c2410/mach-vr1000.c
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -365,7 +365,6 @@ static struct platform_device *vr1000_devices[] __initdata = {
365 &s3c_device_lcd, 365 &s3c_device_lcd,
366 &s3c_device_wdt, 366 &s3c_device_wdt,
367 &s3c_device_i2c, 367 &s3c_device_i2c,
368 &s3c_device_iis,
369 &s3c_device_adc, 368 &s3c_device_adc,
370 &serial_device, 369 &serial_device,
371 &vr1000_nor, 370 &vr1000_nor,
diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c
index e580303cb0ab..0e7991940f81 100644
--- a/arch/arm/mach-s3c2410/s3c2410.c
+++ b/arch/arm/mach-s3c2410/s3c2410.c
@@ -100,7 +100,7 @@ void __init s3c2410_init_clocks(int xtal)
100} 100}
101 101
102struct sysdev_class s3c2410_sysclass = { 102struct sysdev_class s3c2410_sysclass = {
103 set_kset_name("s3c2410-core"), 103 .name = "s3c2410-core",
104}; 104};
105 105
106static struct sys_device s3c2410_sysdev = { 106static struct sys_device s3c2410_sysdev = {
diff --git a/arch/arm/mach-s3c2410/usb-simtec.c b/arch/arm/mach-s3c2410/usb-simtec.c
index bcd562ac1d3d..6aec86a5da56 100644
--- a/arch/arm/mach-s3c2410/usb-simtec.c
+++ b/arch/arm/mach-s3c2410/usb-simtec.c
@@ -60,7 +60,7 @@ usb_simtec_powercontrol(int port, int to)
60static irqreturn_t 60static irqreturn_t
61usb_simtec_ocirq(int irq, void *pw) 61usb_simtec_ocirq(int irq, void *pw)
62{ 62{
63 struct s3c2410_hcd_info *info = (struct s3c2410_hcd_info *)pw; 63 struct s3c2410_hcd_info *info = pw;
64 64
65 if (s3c2410_gpio_getpin(S3C2410_GPG10) == 0) { 65 if (s3c2410_gpio_getpin(S3C2410_GPG10) == 0) {
66 pr_debug("usb_simtec: over-current irq (oc detected)\n"); 66 pr_debug("usb_simtec: over-current irq (oc detected)\n");
diff --git a/arch/arm/mach-s3c2412/Kconfig b/arch/arm/mach-s3c2412/Kconfig
index 8e8fe48ea47f..0b43431d4b75 100644
--- a/arch/arm/mach-s3c2412/Kconfig
+++ b/arch/arm/mach-s3c2412/Kconfig
@@ -10,6 +10,7 @@ config CPU_S3C2412
10 select CPU_LLSERIAL_S3C2440 10 select CPU_LLSERIAL_S3C2440
11 select S3C2412_PM if PM 11 select S3C2412_PM if PM
12 select S3C2412_DMA if S3C2410_DMA 12 select S3C2412_DMA if S3C2410_DMA
13 select S3C2410_GPIO
13 help 14 help
14 Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line 15 Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line
15 16
diff --git a/arch/arm/mach-s3c2412/Makefile b/arch/arm/mach-s3c2412/Makefile
index f8e011691b31..267f3348301e 100644
--- a/arch/arm/mach-s3c2412/Makefile
+++ b/arch/arm/mach-s3c2412/Makefile
@@ -12,8 +12,9 @@ obj- :=
12obj-$(CONFIG_CPU_S3C2412) += s3c2412.o 12obj-$(CONFIG_CPU_S3C2412) += s3c2412.o
13obj-$(CONFIG_CPU_S3C2412) += irq.o 13obj-$(CONFIG_CPU_S3C2412) += irq.o
14obj-$(CONFIG_CPU_S3C2412) += clock.o 14obj-$(CONFIG_CPU_S3C2412) += clock.o
15obj-$(CONFIG_CPU_S3C2412) += gpio.o
15obj-$(CONFIG_S3C2412_DMA) += dma.o 16obj-$(CONFIG_S3C2412_DMA) += dma.o
16obj-$(CONFIG_S3C2412_PM) += pm.o 17obj-$(CONFIG_S3C2412_PM) += pm.o sleep.o
17 18
18# Machine support 19# Machine support
19 20
diff --git a/arch/arm/mach-s3c2412/clock.c b/arch/arm/mach-s3c2412/clock.c
index 458993601897..2697a65ba727 100644
--- a/arch/arm/mach-s3c2412/clock.c
+++ b/arch/arm/mach-s3c2412/clock.c
@@ -217,7 +217,7 @@ static int s3c2412_setparent_msysclk(struct clk *clk, struct clk *parent)
217 217
218 if (parent == &clk_mdivclk) 218 if (parent == &clk_mdivclk)
219 clksrc &= ~S3C2412_CLKSRC_MSYSCLK_MPLL; 219 clksrc &= ~S3C2412_CLKSRC_MSYSCLK_MPLL;
220 else if (parent == &clk_upll) 220 else if (parent == &clk_mpll)
221 clksrc |= S3C2412_CLKSRC_MSYSCLK_MPLL; 221 clksrc |= S3C2412_CLKSRC_MSYSCLK_MPLL;
222 else 222 else
223 return -EINVAL; 223 return -EINVAL;
@@ -234,6 +234,45 @@ static struct clk clk_msysclk = {
234 .set_parent = s3c2412_setparent_msysclk, 234 .set_parent = s3c2412_setparent_msysclk,
235}; 235};
236 236
237static int s3c2412_setparent_armclk(struct clk *clk, struct clk *parent)
238{
239 unsigned long flags;
240 unsigned long clkdiv;
241 unsigned long dvs;
242
243 /* Note, we current equate fclk andf msysclk for S3C2412 */
244
245 if (parent == &clk_msysclk || parent == &clk_f)
246 dvs = 0;
247 else if (parent == &clk_h)
248 dvs = S3C2412_CLKDIVN_DVSEN;
249 else
250 return -EINVAL;
251
252 clk->parent = parent;
253
254 /* update this under irq lockdown, clkdivn is not protected
255 * by the clock system. */
256
257 local_irq_save(flags);
258
259 clkdiv = __raw_readl(S3C2410_CLKDIVN);
260 clkdiv &= ~S3C2412_CLKDIVN_DVSEN;
261 clkdiv |= dvs;
262 __raw_writel(clkdiv, S3C2410_CLKDIVN);
263
264 local_irq_restore(flags);
265
266 return 0;
267}
268
269static struct clk clk_armclk = {
270 .name = "armclk",
271 .id = -1,
272 .parent = &clk_msysclk,
273 .set_parent = s3c2412_setparent_armclk,
274};
275
237/* these next clocks have an divider immediately after them, 276/* these next clocks have an divider immediately after them,
238 * so we can register them with their divider and leave out the 277 * so we can register them with their divider and leave out the
239 * intermediate clock stage 278 * intermediate clock stage
@@ -630,11 +669,13 @@ static struct clk *clks[] __initdata = {
630 &clk_erefclk, 669 &clk_erefclk,
631 &clk_urefclk, 670 &clk_urefclk,
632 &clk_mrefclk, 671 &clk_mrefclk,
672 &clk_armclk,
633}; 673};
634 674
635int __init s3c2412_baseclk_add(void) 675int __init s3c2412_baseclk_add(void)
636{ 676{
637 unsigned long clkcon = __raw_readl(S3C2410_CLKCON); 677 unsigned long clkcon = __raw_readl(S3C2410_CLKCON);
678 unsigned int dvs;
638 struct clk *clkp; 679 struct clk *clkp;
639 int ret; 680 int ret;
640 int ptr; 681 int ptr;
@@ -643,6 +684,8 @@ int __init s3c2412_baseclk_add(void)
643 clk_usb_bus.parent = &clk_usbsrc; 684 clk_usb_bus.parent = &clk_usbsrc;
644 clk_usb_bus.rate = 0x0; 685 clk_usb_bus.rate = 0x0;
645 686
687 clk_f.parent = &clk_msysclk;
688
646 s3c2412_clk_initparents(); 689 s3c2412_clk_initparents();
647 690
648 for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) { 691 for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) {
@@ -655,6 +698,15 @@ int __init s3c2412_baseclk_add(void)
655 } 698 }
656 } 699 }
657 700
701 /* set the dvs state according to what we got at boot time */
702
703 dvs = __raw_readl(S3C2410_CLKDIVN) & S3C2412_CLKDIVN_DVSEN;
704
705 if (dvs)
706 clk_armclk.parent = &clk_h;
707
708 printk(KERN_INFO "S3C2412: DVS is %s\n", dvs ? "on" : "off");
709
658 /* ensure usb bus clock is within correct rate of 48MHz */ 710 /* ensure usb bus clock is within correct rate of 48MHz */
659 711
660 if (clk_get_rate(&clk_usb_bus) != (48 * 1000 * 1000)) { 712 if (clk_get_rate(&clk_usb_bus) != (48 * 1000 * 1000)) {
diff --git a/arch/arm/mach-s3c2412/dma.c b/arch/arm/mach-s3c2412/dma.c
index 53c1d5bbce19..1dd864993566 100644
--- a/arch/arm/mach-s3c2412/dma.c
+++ b/arch/arm/mach-s3c2412/dma.c
@@ -30,6 +30,7 @@
30#include <asm/arch/regs-mem.h> 30#include <asm/arch/regs-mem.h>
31#include <asm/arch/regs-lcd.h> 31#include <asm/arch/regs-lcd.h>
32#include <asm/arch/regs-sdi.h> 32#include <asm/arch/regs-sdi.h>
33#include <asm/plat-s3c24xx/regs-s3c2412-iis.h>
33#include <asm/plat-s3c24xx/regs-iis.h> 34#include <asm/plat-s3c24xx/regs-iis.h>
34#include <asm/plat-s3c24xx/regs-spi.h> 35#include <asm/plat-s3c24xx/regs-spi.h>
35 36
@@ -39,106 +40,141 @@ static struct s3c24xx_dma_map __initdata s3c2412_dma_mappings[] = {
39 [DMACH_XD0] = { 40 [DMACH_XD0] = {
40 .name = "xdreq0", 41 .name = "xdreq0",
41 .channels = MAP(S3C2412_DMAREQSEL_XDREQ0), 42 .channels = MAP(S3C2412_DMAREQSEL_XDREQ0),
43 .channels_rx = MAP(S3C2412_DMAREQSEL_XDREQ0),
42 }, 44 },
43 [DMACH_XD1] = { 45 [DMACH_XD1] = {
44 .name = "xdreq1", 46 .name = "xdreq1",
45 .channels = MAP(S3C2412_DMAREQSEL_XDREQ1), 47 .channels = MAP(S3C2412_DMAREQSEL_XDREQ1),
48 .channels_rx = MAP(S3C2412_DMAREQSEL_XDREQ1),
46 }, 49 },
47 [DMACH_SDI] = { 50 [DMACH_SDI] = {
48 .name = "sdi", 51 .name = "sdi",
49 .channels = MAP(S3C2412_DMAREQSEL_SDI), 52 .channels = MAP(S3C2412_DMAREQSEL_SDI),
50 .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO, 53 .channels_rx = MAP(S3C2412_DMAREQSEL_SDI),
51 .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO, 54 .hw_addr.to = S3C2410_PA_SDI + S3C2410_SDIDATA,
55 .hw_addr.from = S3C2410_PA_SDI + S3C2410_SDIDATA,
52 }, 56 },
53 [DMACH_SPI0] = { 57 [DMACH_SPI0] = {
54 .name = "spi0", 58 .name = "spi0",
55 .channels = MAP(S3C2412_DMAREQSEL_SPI0TX), 59 .channels = MAP(S3C2412_DMAREQSEL_SPI0TX),
60 .channels_rx = MAP(S3C2412_DMAREQSEL_SPI0RX),
56 .hw_addr.to = S3C2410_PA_SPI + S3C2410_SPTDAT, 61 .hw_addr.to = S3C2410_PA_SPI + S3C2410_SPTDAT,
57 .hw_addr.from = S3C2410_PA_SPI + S3C2410_SPRDAT, 62 .hw_addr.from = S3C2410_PA_SPI + S3C2410_SPRDAT,
58 }, 63 },
59 [DMACH_SPI1] = { 64 [DMACH_SPI1] = {
60 .name = "spi1", 65 .name = "spi1",
61 .channels = MAP(S3C2412_DMAREQSEL_SPI1TX), 66 .channels = MAP(S3C2412_DMAREQSEL_SPI1TX),
67 .channels_rx = MAP(S3C2412_DMAREQSEL_SPI1RX),
62 .hw_addr.to = S3C2410_PA_SPI + S3C2412_SPI1 + S3C2410_SPTDAT, 68 .hw_addr.to = S3C2410_PA_SPI + S3C2412_SPI1 + S3C2410_SPTDAT,
63 .hw_addr.from = S3C2410_PA_SPI + S3C2412_SPI1 + S3C2410_SPRDAT, 69 .hw_addr.from = S3C2410_PA_SPI + S3C2412_SPI1 + S3C2410_SPRDAT,
64 }, 70 },
65 [DMACH_UART0] = { 71 [DMACH_UART0] = {
66 .name = "uart0", 72 .name = "uart0",
67 .channels = MAP(S3C2412_DMAREQSEL_UART0_0), 73 .channels = MAP(S3C2412_DMAREQSEL_UART0_0),
74 .channels_rx = MAP(S3C2412_DMAREQSEL_UART0_0),
68 .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH, 75 .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH,
69 .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH, 76 .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH,
70 }, 77 },
71 [DMACH_UART1] = { 78 [DMACH_UART1] = {
72 .name = "uart1", 79 .name = "uart1",
73 .channels = MAP(S3C2412_DMAREQSEL_UART1_0), 80 .channels = MAP(S3C2412_DMAREQSEL_UART1_0),
81 .channels_rx = MAP(S3C2412_DMAREQSEL_UART1_0),
74 .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH, 82 .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH,
75 .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH, 83 .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH,
76 }, 84 },
77 [DMACH_UART2] = { 85 [DMACH_UART2] = {
78 .name = "uart2", 86 .name = "uart2",
79 .channels = MAP(S3C2412_DMAREQSEL_UART2_0), 87 .channels = MAP(S3C2412_DMAREQSEL_UART2_0),
88 .channels_rx = MAP(S3C2412_DMAREQSEL_UART2_0),
80 .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH, 89 .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH,
81 .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH, 90 .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH,
82 }, 91 },
83 [DMACH_UART0_SRC2] = { 92 [DMACH_UART0_SRC2] = {
84 .name = "uart0", 93 .name = "uart0",
85 .channels = MAP(S3C2412_DMAREQSEL_UART0_1), 94 .channels = MAP(S3C2412_DMAREQSEL_UART0_1),
95 .channels_rx = MAP(S3C2412_DMAREQSEL_UART0_1),
86 .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH, 96 .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH,
87 .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH, 97 .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH,
88 }, 98 },
89 [DMACH_UART1_SRC2] = { 99 [DMACH_UART1_SRC2] = {
90 .name = "uart1", 100 .name = "uart1",
91 .channels = MAP(S3C2412_DMAREQSEL_UART1_1), 101 .channels = MAP(S3C2412_DMAREQSEL_UART1_1),
102 .channels_rx = MAP(S3C2412_DMAREQSEL_UART1_1),
92 .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH, 103 .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH,
93 .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH, 104 .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH,
94 }, 105 },
95 [DMACH_UART2_SRC2] = { 106 [DMACH_UART2_SRC2] = {
96 .name = "uart2", 107 .name = "uart2",
97 .channels = MAP(S3C2412_DMAREQSEL_UART2_1), 108 .channels = MAP(S3C2412_DMAREQSEL_UART2_1),
109 .channels_rx = MAP(S3C2412_DMAREQSEL_UART2_1),
98 .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH, 110 .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH,
99 .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH, 111 .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH,
100 }, 112 },
101 [DMACH_TIMER] = { 113 [DMACH_TIMER] = {
102 .name = "timer", 114 .name = "timer",
103 .channels = MAP(S3C2412_DMAREQSEL_TIMER), 115 .channels = MAP(S3C2412_DMAREQSEL_TIMER),
116 .channels_rx = MAP(S3C2412_DMAREQSEL_TIMER),
104 }, 117 },
105 [DMACH_I2S_IN] = { 118 [DMACH_I2S_IN] = {
106 .name = "i2s-sdi", 119 .name = "i2s-sdi",
107 .channels = MAP(S3C2412_DMAREQSEL_I2SRX), 120 .channels = MAP(S3C2412_DMAREQSEL_I2SRX),
108 .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO, 121 .channels_rx = MAP(S3C2412_DMAREQSEL_I2SRX),
122 .hw_addr.from = S3C2410_PA_IIS + S3C2412_IISRXD,
109 }, 123 },
110 [DMACH_I2S_OUT] = { 124 [DMACH_I2S_OUT] = {
111 .name = "i2s-sdo", 125 .name = "i2s-sdo",
112 .channels = MAP(S3C2412_DMAREQSEL_I2STX), 126 .channels = MAP(S3C2412_DMAREQSEL_I2STX),
113 .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO, 127 .channels_rx = MAP(S3C2412_DMAREQSEL_I2STX),
128 .hw_addr.to = S3C2410_PA_IIS + S3C2412_IISTXD,
114 }, 129 },
115 [DMACH_USB_EP1] = { 130 [DMACH_USB_EP1] = {
116 .name = "usb-ep1", 131 .name = "usb-ep1",
117 .channels = MAP(S3C2412_DMAREQSEL_USBEP1), 132 .channels = MAP(S3C2412_DMAREQSEL_USBEP1),
133 .channels_rx = MAP(S3C2412_DMAREQSEL_USBEP1),
118 }, 134 },
119 [DMACH_USB_EP2] = { 135 [DMACH_USB_EP2] = {
120 .name = "usb-ep2", 136 .name = "usb-ep2",
121 .channels = MAP(S3C2412_DMAREQSEL_USBEP2), 137 .channels = MAP(S3C2412_DMAREQSEL_USBEP2),
138 .channels_rx = MAP(S3C2412_DMAREQSEL_USBEP2),
122 }, 139 },
123 [DMACH_USB_EP3] = { 140 [DMACH_USB_EP3] = {
124 .name = "usb-ep3", 141 .name = "usb-ep3",
125 .channels = MAP(S3C2412_DMAREQSEL_USBEP3), 142 .channels = MAP(S3C2412_DMAREQSEL_USBEP3),
143 .channels_rx = MAP(S3C2412_DMAREQSEL_USBEP3),
126 }, 144 },
127 [DMACH_USB_EP4] = { 145 [DMACH_USB_EP4] = {
128 .name = "usb-ep4", 146 .name = "usb-ep4",
129 .channels = MAP(S3C2412_DMAREQSEL_USBEP4), 147 .channels = MAP(S3C2412_DMAREQSEL_USBEP4),
148 .channels_rx = MAP(S3C2412_DMAREQSEL_USBEP4),
130 }, 149 },
131}; 150};
132 151
152static void s3c2412_dma_direction(struct s3c2410_dma_chan *chan,
153 struct s3c24xx_dma_map *map,
154 enum s3c2410_dmasrc dir)
155{
156 unsigned long chsel;
157
158 if (dir == S3C2410_DMASRC_HW)
159 chsel = map->channels_rx[0];
160 else
161 chsel = map->channels[0];
162
163 chsel &= ~DMA_CH_VALID;
164 chsel |= S3C2412_DMAREQSEL_HW;
165
166 writel(chsel, chan->regs + S3C2412_DMA_DMAREQSEL);
167}
168
133static void s3c2412_dma_select(struct s3c2410_dma_chan *chan, 169static void s3c2412_dma_select(struct s3c2410_dma_chan *chan,
134 struct s3c24xx_dma_map *map) 170 struct s3c24xx_dma_map *map)
135{ 171{
136 writel(map->channels[0] | S3C2412_DMAREQSEL_HW, 172 s3c2412_dma_direction(chan, map, chan->source);
137 chan->regs + S3C2412_DMA_DMAREQSEL);
138} 173}
139 174
140static struct s3c24xx_dma_selection __initdata s3c2412_dma_sel = { 175static struct s3c24xx_dma_selection __initdata s3c2412_dma_sel = {
141 .select = s3c2412_dma_select, 176 .select = s3c2412_dma_select,
177 .direction = s3c2412_dma_direction,
142 .dcon_mask = 0, 178 .dcon_mask = 0,
143 .map = s3c2412_dma_mappings, 179 .map = s3c2412_dma_mappings,
144 .map_size = ARRAY_SIZE(s3c2412_dma_mappings), 180 .map_size = ARRAY_SIZE(s3c2412_dma_mappings),
diff --git a/arch/arm/mach-s3c2412/gpio.c b/arch/arm/mach-s3c2412/gpio.c
new file mode 100644
index 000000000000..8e55c3a2eab8
--- /dev/null
+++ b/arch/arm/mach-s3c2412/gpio.c
@@ -0,0 +1,60 @@
1/* linux/arch/arm/mach-s3c2412/gpio.c
2 *
3 * Copyright (c) 2007 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * http://armlinux.simtec.co.uk/.
7 *
8 * S3C2412/S3C2413 specific GPIO support
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <linux/kernel.h>
16#include <linux/types.h>
17#include <linux/module.h>
18#include <linux/interrupt.h>
19
20#include <asm/mach/arch.h>
21#include <asm/mach/map.h>
22
23#include <asm/arch/regs-gpio.h>
24
25#include <asm/hardware.h>
26
27int s3c2412_gpio_set_sleepcfg(unsigned int pin, unsigned int state)
28{
29 void __iomem *base = S3C24XX_GPIO_BASE(pin);
30 unsigned long offs = S3C2410_GPIO_OFFSET(pin);
31 unsigned long flags;
32 unsigned long slpcon;
33
34 offs *= 2;
35
36 if (pin < S3C2410_GPIO_BANKB)
37 return -EINVAL;
38
39 if (pin >= S3C2410_GPIO_BANKF &&
40 pin <= S3C2410_GPIO_BANKG)
41 return -EINVAL;
42
43 if (pin > (S3C2410_GPIO_BANKH + 32))
44 return -EINVAL;
45
46 local_irq_save(flags);
47
48 slpcon = __raw_readl(base + 0x0C);
49
50 slpcon &= ~(3 << offs);
51 slpcon |= state << offs;
52
53 __raw_writel(slpcon, base + 0x0C);
54
55 local_irq_restore(flags);
56
57 return 0;
58}
59
60EXPORT_SYMBOL(s3c2412_gpio_set_sleepcfg);
diff --git a/arch/arm/mach-s3c2412/irq.c b/arch/arm/mach-s3c2412/irq.c
index e9d0c769f5da..cc1917bf952a 100644
--- a/arch/arm/mach-s3c2412/irq.c
+++ b/arch/arm/mach-s3c2412/irq.c
@@ -33,6 +33,7 @@
33 33
34#include <asm/arch/regs-irq.h> 34#include <asm/arch/regs-irq.h>
35#include <asm/arch/regs-gpio.h> 35#include <asm/arch/regs-gpio.h>
36#include <asm/arch/regs-power.h>
36 37
37#include <asm/plat-s3c24xx/cpu.h> 38#include <asm/plat-s3c24xx/cpu.h>
38#include <asm/plat-s3c24xx/irq.h> 39#include <asm/plat-s3c24xx/irq.h>
@@ -153,6 +154,22 @@ static struct irq_chip s3c2412_irq_cfsdi = {
153 .unmask = s3c2412_irq_cfsdi_unmask, 154 .unmask = s3c2412_irq_cfsdi_unmask,
154}; 155};
155 156
157static int s3c2412_irq_rtc_wake(unsigned int irqno, unsigned int state)
158{
159 unsigned long pwrcfg;
160
161 pwrcfg = __raw_readl(S3C2412_PWRCFG);
162 if (state)
163 pwrcfg &= ~S3C2412_PWRCFG_RTC_MASKIRQ;
164 else
165 pwrcfg |= S3C2412_PWRCFG_RTC_MASKIRQ;
166 __raw_writel(pwrcfg, S3C2412_PWRCFG);
167
168 return s3c_irq_chip.set_wake(irqno, state);
169}
170
171static struct irq_chip s3c2412_irq_rtc_chip;
172
156static int s3c2412_irq_add(struct sys_device *sysdev) 173static int s3c2412_irq_add(struct sys_device *sysdev)
157{ 174{
158 unsigned int irqno; 175 unsigned int irqno;
@@ -173,6 +190,13 @@ static int s3c2412_irq_add(struct sys_device *sysdev)
173 set_irq_flags(irqno, IRQF_VALID); 190 set_irq_flags(irqno, IRQF_VALID);
174 } 191 }
175 192
193 /* change RTC IRQ's set wake method */
194
195 s3c2412_irq_rtc_chip = s3c_irq_chip;
196 s3c2412_irq_rtc_chip.set_wake = s3c2412_irq_rtc_wake;
197
198 set_irq_chip(IRQ_RTC, &s3c2412_irq_rtc_chip);
199
176 return 0; 200 return 0;
177} 201}
178 202
diff --git a/arch/arm/mach-s3c2412/pm.c b/arch/arm/mach-s3c2412/pm.c
index 8988dac388a9..d4ffb2d98076 100644
--- a/arch/arm/mach-s3c2412/pm.c
+++ b/arch/arm/mach-s3c2412/pm.c
@@ -33,6 +33,8 @@
33 33
34#include <asm/plat-s3c24xx/s3c2412.h> 34#include <asm/plat-s3c24xx/s3c2412.h>
35 35
36extern void s3c2412_sleep_enter(void);
37
36static void s3c2412_cpu_suspend(void) 38static void s3c2412_cpu_suspend(void)
37{ 39{
38 unsigned long tmp; 40 unsigned long tmp;
@@ -43,20 +45,7 @@ static void s3c2412_cpu_suspend(void)
43 tmp |= S3C2412_PWRCFG_STANDBYWFI_SLEEP; 45 tmp |= S3C2412_PWRCFG_STANDBYWFI_SLEEP;
44 __raw_writel(tmp, S3C2412_PWRCFG); 46 __raw_writel(tmp, S3C2412_PWRCFG);
45 47
46 /* issue the standby signal into the pm unit. Note, we 48 s3c2412_sleep_enter();
47 * issue a write-buffer drain just in case */
48
49 tmp = 0;
50
51 asm("b 1f\n\t"
52 ".align 5\n\t"
53 "1:\n\t"
54 "mcr p15, 0, %0, c7, c10, 4\n\t"
55 "mcr p15, 0, %0, c7, c0, 4" :: "r" (tmp));
56
57 /* we should never get past here */
58
59 panic("sleep resumed to originator?");
60} 49}
61 50
62static void s3c2412_pm_prepare(void) 51static void s3c2412_pm_prepare(void)
@@ -88,7 +77,6 @@ static struct sleep_save s3c2412_sleep[] = {
88 SAVE_ITEM(S3C2412_GPBSLPCON), 77 SAVE_ITEM(S3C2412_GPBSLPCON),
89 SAVE_ITEM(S3C2412_GPCSLPCON), 78 SAVE_ITEM(S3C2412_GPCSLPCON),
90 SAVE_ITEM(S3C2412_GPDSLPCON), 79 SAVE_ITEM(S3C2412_GPDSLPCON),
91 SAVE_ITEM(S3C2412_GPESLPCON),
92 SAVE_ITEM(S3C2412_GPFSLPCON), 80 SAVE_ITEM(S3C2412_GPFSLPCON),
93 SAVE_ITEM(S3C2412_GPGSLPCON), 81 SAVE_ITEM(S3C2412_GPGSLPCON),
94 SAVE_ITEM(S3C2412_GPHSLPCON), 82 SAVE_ITEM(S3C2412_GPHSLPCON),
diff --git a/arch/arm/mach-s3c2412/s3c2412.c b/arch/arm/mach-s3c2412/s3c2412.c
index 4f92a1562d77..abf1599c9f97 100644
--- a/arch/arm/mach-s3c2412/s3c2412.c
+++ b/arch/arm/mach-s3c2412/s3c2412.c
@@ -168,6 +168,8 @@ void __init s3c2412_init_clocks(int xtal)
168 168
169 fclk = s3c2410_get_pll(__raw_readl(S3C2410_MPLLCON), xtal*2); 169 fclk = s3c2410_get_pll(__raw_readl(S3C2410_MPLLCON), xtal*2);
170 170
171 clk_mpll.rate = fclk;
172
171 tmp = __raw_readl(S3C2410_CLKDIVN); 173 tmp = __raw_readl(S3C2410_CLKDIVN);
172 174
173 /* work out clock scalings */ 175 /* work out clock scalings */
@@ -196,7 +198,7 @@ void __init s3c2412_init_clocks(int xtal)
196*/ 198*/
197 199
198struct sysdev_class s3c2412_sysclass = { 200struct sysdev_class s3c2412_sysclass = {
199 set_kset_name("s3c2412-core"), 201 .name = "s3c2412-core",
200}; 202};
201 203
202static int __init s3c2412_core_init(void) 204static int __init s3c2412_core_init(void)
diff --git a/arch/arm/mach-s3c2412/sleep.S b/arch/arm/mach-s3c2412/sleep.S
new file mode 100644
index 000000000000..db32cac4199a
--- /dev/null
+++ b/arch/arm/mach-s3c2412/sleep.S
@@ -0,0 +1,68 @@
1/* linux/arch/arm/mach-s3c2412/sleep.S
2 *
3 * Copyright (c) 2007 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C2412 Power Manager low-level sleep support
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21*/
22
23#include <linux/linkage.h>
24#include <asm/assembler.h>
25#include <asm/hardware.h>
26#include <asm/arch/map.h>
27
28#include <asm/arch/regs-irq.h>
29
30 .text
31
32 .global s3c2412_sleep_enter
33
34s3c2412_sleep_enter:
35 mov r0, #0 /* argument for coprocessors */
36 ldr r1, =S3C2410_INTPND
37 ldr r2, =S3C2410_SRCPND
38 ldr r3, =S3C2410_EINTPEND
39
40 teq r0, r0
41 bl s3c2412_sleep_enter1
42 teq pc, r0
43 bl s3c2412_sleep_enter1
44
45 .align 5
46
47 /* this is called twice, first with the Z flag to ensure that the
48 * instructions have been loaded into the cache, and the second
49 * time to try and suspend the system.
50 */
51s3c2412_sleep_enter1:
52 mcr p15, 0, r0, c7, c10, 4
53 mcrne p15, 0, r0, c7, c0, 4
54
55 /* if we return from here, it is because an interrupt was
56 * active when we tried to shutdown. Try and ack the IRQ and
57 * retry, as simply returning causes the system to lock.
58 */
59
60 ldrne r9, [ r1 ]
61 strne r9, [ r1 ]
62 ldrne r9, [ r2 ]
63 strne r9, [ r2 ]
64 ldrne r9, [ r3 ]
65 strne r9, [ r3 ]
66 bne s3c2412_sleep_enter1
67
68 mov pc, r14
diff --git a/arch/arm/mach-s3c2440/clock.c b/arch/arm/mach-s3c2440/clock.c
index 79e2ea4adaf3..184d804934c9 100644
--- a/arch/arm/mach-s3c2440/clock.c
+++ b/arch/arm/mach-s3c2440/clock.c
@@ -111,14 +111,9 @@ static struct clk s3c2440_clk_ac97 = {
111 111
112static int s3c2440_clk_add(struct sys_device *sysdev) 112static int s3c2440_clk_add(struct sys_device *sysdev)
113{ 113{
114 unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN); 114 struct clk *clock_upll;
115 unsigned long clkdivn;
116 struct clk *clock_h; 115 struct clk *clock_h;
117 struct clk *clock_p; 116 struct clk *clock_p;
118 struct clk *clock_upll;
119
120 printk("S3C2440: Clock Support, DVS %s\n",
121 (camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off");
122 117
123 clock_p = clk_get(NULL, "pclk"); 118 clock_p = clk_get(NULL, "pclk");
124 clock_h = clk_get(NULL, "hclk"); 119 clock_h = clk_get(NULL, "hclk");
@@ -129,21 +124,6 @@ static int s3c2440_clk_add(struct sys_device *sysdev)
129 return -EINVAL; 124 return -EINVAL;
130 } 125 }
131 126
132 /* check rate of UPLL, and if it is near 96MHz, then change
133 * to using half the UPLL rate for the system */
134
135 if (clk_get_rate(clock_upll) > (94 * MHZ)) {
136 clk_usb_bus.rate = clk_get_rate(clock_upll) / 2;
137
138 mutex_lock(&clocks_mutex);
139
140 clkdivn = __raw_readl(S3C2410_CLKDIVN);
141 clkdivn |= S3C2440_CLKDIVN_UCLK;
142 __raw_writel(clkdivn, S3C2410_CLKDIVN);
143
144 mutex_unlock(&clocks_mutex);
145 }
146
147 s3c2440_clk_cam.parent = clock_h; 127 s3c2440_clk_cam.parent = clock_h;
148 s3c2440_clk_ac97.parent = clock_p; 128 s3c2440_clk_ac97.parent = clock_p;
149 s3c2440_clk_cam_upll.parent = clock_upll; 129 s3c2440_clk_cam_upll.parent = clock_upll;
diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c
index c326983f4a8f..78af7664988b 100644
--- a/arch/arm/mach-s3c2440/mach-osiris.c
+++ b/arch/arm/mach-s3c2440/mach-osiris.c
@@ -312,7 +312,7 @@ static int osiris_pm_resume(struct sys_device *sd)
312#endif 312#endif
313 313
314static struct sysdev_class osiris_pm_sysclass = { 314static struct sysdev_class osiris_pm_sysclass = {
315 set_kset_name("mach-osiris"), 315 .name = "mach-osiris",
316 .suspend = osiris_pm_suspend, 316 .suspend = osiris_pm_suspend,
317 .resume = osiris_pm_resume, 317 .resume = osiris_pm_resume,
318}; 318};
diff --git a/arch/arm/mach-s3c2442/clock.c b/arch/arm/mach-s3c2442/clock.c
index 5b9e830ac4d3..2d030d439fe9 100644
--- a/arch/arm/mach-s3c2442/clock.c
+++ b/arch/arm/mach-s3c2442/clock.c
@@ -115,14 +115,9 @@ static struct clk s3c2442_clk_cam_upll = {
115 115
116static int s3c2442_clk_add(struct sys_device *sysdev) 116static int s3c2442_clk_add(struct sys_device *sysdev)
117{ 117{
118 unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN); 118 struct clk *clock_upll;
119 unsigned long clkdivn;
120 struct clk *clock_h; 119 struct clk *clock_h;
121 struct clk *clock_p; 120 struct clk *clock_p;
122 struct clk *clock_upll;
123
124 printk("S3C2442: Clock Support, DVS %s\n",
125 (camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off");
126 121
127 clock_p = clk_get(NULL, "pclk"); 122 clock_p = clk_get(NULL, "pclk");
128 clock_h = clk_get(NULL, "hclk"); 123 clock_h = clk_get(NULL, "hclk");
@@ -133,21 +128,6 @@ static int s3c2442_clk_add(struct sys_device *sysdev)
133 return -EINVAL; 128 return -EINVAL;
134 } 129 }
135 130
136 /* check rate of UPLL, and if it is near 96MHz, then change
137 * to using half the UPLL rate for the system */
138
139 if (clk_get_rate(clock_upll) > (94 * MHZ)) {
140 clk_usb_bus.rate = clk_get_rate(clock_upll) / 2;
141
142 mutex_lock(&clocks_mutex);
143
144 clkdivn = __raw_readl(S3C2410_CLKDIVN);
145 clkdivn |= S3C2440_CLKDIVN_UCLK;
146 __raw_writel(clkdivn, S3C2410_CLKDIVN);
147
148 mutex_unlock(&clocks_mutex);
149 }
150
151 s3c2442_clk_cam.parent = clock_h; 131 s3c2442_clk_cam.parent = clock_h;
152 s3c2442_clk_cam_upll.parent = clock_upll; 132 s3c2442_clk_cam_upll.parent = clock_upll;
153 133
diff --git a/arch/arm/mach-s3c2443/s3c2443.c b/arch/arm/mach-s3c2443/s3c2443.c
index 8d8117158d23..9ce490560af9 100644
--- a/arch/arm/mach-s3c2443/s3c2443.c
+++ b/arch/arm/mach-s3c2443/s3c2443.c
@@ -43,7 +43,7 @@ static struct map_desc s3c2443_iodesc[] __initdata = {
43}; 43};
44 44
45struct sysdev_class s3c2443_sysclass = { 45struct sysdev_class s3c2443_sysclass = {
46 set_kset_name("s3c2443-core"), 46 .name = "s3c2443-core",
47}; 47};
48 48
49static struct sys_device s3c2443_sysdev = { 49static struct sys_device s3c2443_sysdev = {
diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c
index edf3347d9c5b..3dc17d7bf38e 100644
--- a/arch/arm/mach-sa1100/irq.c
+++ b/arch/arm/mach-sa1100/irq.c
@@ -283,7 +283,7 @@ static int sa1100irq_resume(struct sys_device *dev)
283} 283}
284 284
285static struct sysdev_class sa1100irq_sysclass = { 285static struct sysdev_class sa1100irq_sysclass = {
286 set_kset_name("sa11x0-irq"), 286 .name = "sa11x0-irq",
287 .suspend = sa1100irq_suspend, 287 .suspend = sa1100irq_suspend,
288 .resume = sa1100irq_resume, 288 .resume = sa1100irq_resume,
289}; 289};
diff --git a/arch/arm/mach-sa1100/ssp.c b/arch/arm/mach-sa1100/ssp.c
index 59703c6fb29b..06206ceb312e 100644
--- a/arch/arm/mach-sa1100/ssp.c
+++ b/arch/arm/mach-sa1100/ssp.c
@@ -29,9 +29,8 @@ static irqreturn_t ssp_interrupt(int irq, void *dev_id)
29{ 29{
30 unsigned int status = Ser4SSSR; 30 unsigned int status = Ser4SSSR;
31 31
32 if (status & SSSR_ROR) { 32 if (status & SSSR_ROR)
33 printk(KERN_WARNING "SSP: receiver overrun\n"); 33 printk(KERN_WARNING "SSP: receiver overrun\n");
34 }
35 34
36 Ser4SSSR = SSSR_ROR; 35 Ser4SSSR = SSSR_ROR;
37 36
diff --git a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c
index fdf7b016e7ad..c2677368d6af 100644
--- a/arch/arm/mach-sa1100/time.c
+++ b/arch/arm/mach-sa1100/time.c
@@ -14,6 +14,7 @@
14#include <linux/irq.h> 14#include <linux/irq.h>
15#include <linux/timex.h> 15#include <linux/timex.h>
16#include <linux/signal.h> 16#include <linux/signal.h>
17#include <linux/clocksource.h>
17 18
18#include <asm/mach/time.h> 19#include <asm/mach/time.h>
19#include <asm/hardware.h> 20#include <asm/hardware.h>
@@ -35,23 +36,6 @@ static int sa1100_set_rtc(void)
35 return 0; 36 return 0;
36} 37}
37 38
38/* IRQs are disabled before entering here from do_gettimeofday() */
39static unsigned long sa1100_gettimeoffset (void)
40{
41 unsigned long ticks_to_match, elapsed, usec;
42
43 /* Get ticks before next timer match */
44 ticks_to_match = OSMR0 - OSCR;
45
46 /* We need elapsed ticks since last match */
47 elapsed = LATCH - ticks_to_match;
48
49 /* Now convert them to usec */
50 usec = (unsigned long)(elapsed * (tick_nsec / 1000))/LATCH;
51
52 return usec;
53}
54
55#ifdef CONFIG_NO_IDLE_HZ 39#ifdef CONFIG_NO_IDLE_HZ
56static unsigned long initial_match; 40static unsigned long initial_match;
57static int match_posponed; 41static int match_posponed;
@@ -62,8 +46,6 @@ sa1100_timer_interrupt(int irq, void *dev_id)
62{ 46{
63 unsigned int next_match; 47 unsigned int next_match;
64 48
65 write_seqlock(&xtime_lock);
66
67#ifdef CONFIG_NO_IDLE_HZ 49#ifdef CONFIG_NO_IDLE_HZ
68 if (match_posponed) { 50 if (match_posponed) {
69 match_posponed = 0; 51 match_posponed = 0;
@@ -85,8 +67,6 @@ sa1100_timer_interrupt(int irq, void *dev_id)
85 next_match = (OSMR0 += LATCH); 67 next_match = (OSMR0 += LATCH);
86 } while ((signed long)(next_match - OSCR) <= 0); 68 } while ((signed long)(next_match - OSCR) <= 0);
87 69
88 write_sequnlock(&xtime_lock);
89
90 return IRQ_HANDLED; 70 return IRQ_HANDLED;
91} 71}
92 72
@@ -96,6 +76,20 @@ static struct irqaction sa1100_timer_irq = {
96 .handler = sa1100_timer_interrupt, 76 .handler = sa1100_timer_interrupt,
97}; 77};
98 78
79static cycle_t sa1100_read_oscr(void)
80{
81 return OSCR;
82}
83
84static struct clocksource cksrc_sa1100_oscr = {
85 .name = "oscr",
86 .rating = 200,
87 .read = sa1100_read_oscr,
88 .mask = CLOCKSOURCE_MASK(32),
89 .shift = 20,
90 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
91};
92
99static void __init sa1100_timer_init(void) 93static void __init sa1100_timer_init(void)
100{ 94{
101 unsigned long flags; 95 unsigned long flags;
@@ -109,6 +103,11 @@ static void __init sa1100_timer_init(void)
109 OIER = OIER_E0; /* enable match on timer 0 to cause interrupts */ 103 OIER = OIER_E0; /* enable match on timer 0 to cause interrupts */
110 OSMR0 = OSCR + LATCH; /* set initial match */ 104 OSMR0 = OSCR + LATCH; /* set initial match */
111 local_irq_restore(flags); 105 local_irq_restore(flags);
106
107 cksrc_sa1100_oscr.mult =
108 clocksource_hz2mult(CLOCK_TICK_RATE, cksrc_sa1100_oscr.shift);
109
110 clocksource_register(&cksrc_sa1100_oscr);
112} 111}
113 112
114#ifdef CONFIG_NO_IDLE_HZ 113#ifdef CONFIG_NO_IDLE_HZ
@@ -182,7 +181,6 @@ struct sys_timer sa1100_timer = {
182 .init = sa1100_timer_init, 181 .init = sa1100_timer_init,
183 .suspend = sa1100_timer_suspend, 182 .suspend = sa1100_timer_suspend,
184 .resume = sa1100_timer_resume, 183 .resume = sa1100_timer_resume,
185 .offset = sa1100_gettimeoffset,
186#ifdef CONFIG_NO_IDLE_HZ 184#ifdef CONFIG_NO_IDLE_HZ
187 .dyn_tick = &sa1100_dyn_tick, 185 .dyn_tick = &sa1100_dyn_tick,
188#endif 186#endif
diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c
index a0545db2a34f..09d9f33d4072 100644
--- a/arch/arm/mach-shark/core.c
+++ b/arch/arm/mach-shark/core.c
@@ -82,9 +82,7 @@ static void __init shark_map_io(void)
82static irqreturn_t 82static irqreturn_t
83shark_timer_interrupt(int irq, void *dev_id) 83shark_timer_interrupt(int irq, void *dev_id)
84{ 84{
85 write_seqlock(&xtime_lock);
86 timer_tick(); 85 timer_tick();
87 write_sequnlock(&xtime_lock);
88 return IRQ_HANDLED; 86 return IRQ_HANDLED;
89} 87}
90 88
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 7868f4dc1d00..76348f060f27 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -171,8 +171,8 @@ config CPU_ARM925T
171# ARM926T 171# ARM926T
172config CPU_ARM926T 172config CPU_ARM926T
173 bool "Support ARM926T processor" 173 bool "Support ARM926T processor"
174 depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_NS9XXX || ARCH_DAVINCI 174 depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 || ARCH_NS9XXX || ARCH_DAVINCI
175 default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_NS9XXX || ARCH_DAVINCI 175 default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 || ARCH_NS9XXX || ARCH_DAVINCI
176 select CPU_32v5 176 select CPU_32v5
177 select CPU_ABRT_EV5TJ 177 select CPU_ABRT_EV5TJ
178 select CPU_CACHE_VIVT 178 select CPU_CACHE_VIVT
@@ -342,11 +342,33 @@ config CPU_XSC3
342 select CPU_TLB_V4WBI if MMU 342 select CPU_TLB_V4WBI if MMU
343 select IO_36 343 select IO_36
344 344
345# Feroceon
346config CPU_FEROCEON
347 bool
348 depends on ARCH_ORION
349 default y
350 select CPU_32v5
351 select CPU_ABRT_EV5T
352 select CPU_CACHE_VIVT
353 select CPU_CP15_MMU
354 select CPU_COPY_V4WB if MMU
355 select CPU_TLB_V4WBI if MMU
356
357config CPU_FEROCEON_OLD_ID
358 bool "Accept early Feroceon cores with an ARM926 ID"
359 depends on CPU_FEROCEON && !CPU_ARM926T
360 default y
361 help
362 This enables the usage of some old Feroceon cores
363 for which the CPU ID is equal to the ARM926 ID.
364 Relevant for Feroceon-1850 and early Feroceon-2850.
365
345# ARMv6 366# ARMv6
346config CPU_V6 367config CPU_V6
347 bool "Support ARM V6 processor" 368 bool "Support ARM V6 processor"
348 depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP2 || ARCH_MX3 369 depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP2 || ARCH_MX3 || ARCH_MSM7X00A
349 default y if ARCH_MX3 370 default y if ARCH_MX3
371 default y if ARCH_MSM7X00A
350 select CPU_32v6 372 select CPU_32v6
351 select CPU_ABRT_EV6 373 select CPU_ABRT_EV6
352 select CPU_CACHE_V6 374 select CPU_CACHE_V6
@@ -538,7 +560,7 @@ comment "Processor Features"
538 560
539config ARM_THUMB 561config ARM_THUMB
540 bool "Support Thumb user binaries" 562 bool "Support Thumb user binaries"
541 depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_V6 || CPU_V7 563 depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_V6 || CPU_V7 || CPU_FEROCEON
542 default y 564 default y
543 help 565 help
544 Say Y if you want to include kernel support for running user space 566 Say Y if you want to include kernel support for running user space
@@ -600,7 +622,7 @@ config CPU_DCACHE_SIZE
600 622
601config CPU_DCACHE_WRITETHROUGH 623config CPU_DCACHE_WRITETHROUGH
602 bool "Force write through D-cache" 624 bool "Force write through D-cache"
603 depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020) && !CPU_DCACHE_DISABLE 625 depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_FEROCEON) && !CPU_DCACHE_DISABLE
604 default y if CPU_ARM925T 626 default y if CPU_ARM925T
605 help 627 help
606 Say Y here to use the data cache in writethrough mode. Unless you 628 Say Y here to use the data cache in writethrough mode. Unless you
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 762702765fc3..44536a0b995a 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -68,6 +68,7 @@ obj-$(CONFIG_CPU_SA110) += proc-sa110.o
68obj-$(CONFIG_CPU_SA1100) += proc-sa1100.o 68obj-$(CONFIG_CPU_SA1100) += proc-sa1100.o
69obj-$(CONFIG_CPU_XSCALE) += proc-xscale.o 69obj-$(CONFIG_CPU_XSCALE) += proc-xscale.o
70obj-$(CONFIG_CPU_XSC3) += proc-xsc3.o 70obj-$(CONFIG_CPU_XSC3) += proc-xsc3.o
71obj-$(CONFIG_CPU_FEROCEON) += proc-feroceon.o
71obj-$(CONFIG_CPU_V6) += proc-v6.o 72obj-$(CONFIG_CPU_V6) += proc-v6.o
72obj-$(CONFIG_CPU_V7) += proc-v7.o 73obj-$(CONFIG_CPU_V7) += proc-v7.o
73 74
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index a8a7dab757eb..28ad7ab1c0cd 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -12,6 +12,7 @@
12#include <linux/signal.h> 12#include <linux/signal.h>
13#include <linux/mm.h> 13#include <linux/mm.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/kprobes.h>
15 16
16#include <asm/system.h> 17#include <asm/system.h>
17#include <asm/pgtable.h> 18#include <asm/pgtable.h>
@@ -20,6 +21,29 @@
20 21
21#include "fault.h" 22#include "fault.h"
22 23
24
25#ifdef CONFIG_KPROBES
26static inline int notify_page_fault(struct pt_regs *regs, unsigned int fsr)
27{
28 int ret = 0;
29
30 if (!user_mode(regs)) {
31 /* kprobe_running() needs smp_processor_id() */
32 preempt_disable();
33 if (kprobe_running() && kprobe_fault_handler(regs, fsr))
34 ret = 1;
35 preempt_enable();
36 }
37
38 return ret;
39}
40#else
41static inline int notify_page_fault(struct pt_regs *regs, unsigned int fsr)
42{
43 return 0;
44}
45#endif
46
23/* 47/*
24 * This is useful to dump out the page tables associated with 48 * This is useful to dump out the page tables associated with
25 * 'addr' in mm 'mm'. 49 * 'addr' in mm 'mm'.
@@ -215,13 +239,16 @@ out:
215 return fault; 239 return fault;
216} 240}
217 241
218static int 242static int __kprobes
219do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) 243do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
220{ 244{
221 struct task_struct *tsk; 245 struct task_struct *tsk;
222 struct mm_struct *mm; 246 struct mm_struct *mm;
223 int fault, sig, code; 247 int fault, sig, code;
224 248
249 if (notify_page_fault(regs, fsr))
250 return 0;
251
225 tsk = current; 252 tsk = current;
226 mm = tsk->mm; 253 mm = tsk->mm;
227 254
@@ -311,7 +338,7 @@ no_context:
311 * interrupt or a critical region, and should only copy the information 338 * interrupt or a critical region, and should only copy the information
312 * from the master page table, nothing more. 339 * from the master page table, nothing more.
313 */ 340 */
314static int 341static int __kprobes
315do_translation_fault(unsigned long addr, unsigned int fsr, 342do_translation_fault(unsigned long addr, unsigned int fsr,
316 struct pt_regs *regs) 343 struct pt_regs *regs)
317{ 344{
diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S
new file mode 100644
index 000000000000..fa0dc7e6f0ea
--- /dev/null
+++ b/arch/arm/mm/proc-feroceon.S
@@ -0,0 +1,506 @@
1/*
2 * linux/arch/arm/mm/proc-feroceon.S: MMU functions for Feroceon
3 *
4 * Heavily based on proc-arm926.S
5 * Maintainer: Assaf Hoffman <hoffman@marvell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#include <linux/linkage.h>
23#include <linux/init.h>
24#include <asm/assembler.h>
25#include <asm/elf.h>
26#include <asm/pgtable-hwdef.h>
27#include <asm/pgtable.h>
28#include <asm/page.h>
29#include <asm/ptrace.h>
30#include "proc-macros.S"
31
32/*
33 * This is the maximum size of an area which will be invalidated
34 * using the single invalidate entry instructions. Anything larger
35 * than this, and we go for the whole cache.
36 *
37 * This value should be chosen such that we choose the cheapest
38 * alternative.
39 */
40#define CACHE_DLIMIT 16384
41
42/*
43 * the cache line size of the I and D cache
44 */
45#define CACHE_DLINESIZE 32
46
47 .text
48/*
49 * cpu_feroceon_proc_init()
50 */
51ENTRY(cpu_feroceon_proc_init)
52 mov pc, lr
53
54/*
55 * cpu_feroceon_proc_fin()
56 */
57ENTRY(cpu_feroceon_proc_fin)
58 stmfd sp!, {lr}
59 mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
60 msr cpsr_c, ip
61 bl feroceon_flush_kern_cache_all
62 mrc p15, 0, r0, c1, c0, 0 @ ctrl register
63 bic r0, r0, #0x1000 @ ...i............
64 bic r0, r0, #0x000e @ ............wca.
65 mcr p15, 0, r0, c1, c0, 0 @ disable caches
66 ldmfd sp!, {pc}
67
68/*
69 * cpu_feroceon_reset(loc)
70 *
71 * Perform a soft reset of the system. Put the CPU into the
72 * same state as it would be if it had been reset, and branch
73 * to what would be the reset vector.
74 *
75 * loc: location to jump to for soft reset
76 */
77 .align 5
78ENTRY(cpu_feroceon_reset)
79 mov ip, #0
80 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
81 mcr p15, 0, ip, c7, c10, 4 @ drain WB
82#ifdef CONFIG_MMU
83 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
84#endif
85 mrc p15, 0, ip, c1, c0, 0 @ ctrl register
86 bic ip, ip, #0x000f @ ............wcam
87 bic ip, ip, #0x1100 @ ...i...s........
88 mcr p15, 0, ip, c1, c0, 0 @ ctrl register
89 mov pc, r0
90
91/*
92 * cpu_feroceon_do_idle()
93 *
94 * Called with IRQs disabled
95 */
96 .align 10
97ENTRY(cpu_feroceon_do_idle)
98 mov r0, #0
99 mcr p15, 0, r0, c7, c10, 4 @ Drain write buffer
100 mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
101 mov pc, lr
102
103/*
104 * flush_user_cache_all()
105 *
106 * Clean and invalidate all cache entries in a particular
107 * address space.
108 */
109ENTRY(feroceon_flush_user_cache_all)
110 /* FALLTHROUGH */
111
112/*
113 * flush_kern_cache_all()
114 *
115 * Clean and invalidate the entire cache.
116 */
117ENTRY(feroceon_flush_kern_cache_all)
118 mov r2, #VM_EXEC
119 mov ip, #0
120__flush_whole_cache:
121#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
122 mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
123#else
1241: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate
125 bne 1b
126#endif
127 tst r2, #VM_EXEC
128 mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
129 mcrne p15, 0, ip, c7, c10, 4 @ drain WB
130 mov pc, lr
131
132/*
133 * flush_user_cache_range(start, end, flags)
134 *
135 * Clean and invalidate a range of cache entries in the
136 * specified address range.
137 *
138 * - start - start address (inclusive)
139 * - end - end address (exclusive)
140 * - flags - vm_flags describing address space
141 */
142ENTRY(feroceon_flush_user_cache_range)
143 mov ip, #0
144 sub r3, r1, r0 @ calculate total size
145 cmp r3, #CACHE_DLIMIT
146 bgt __flush_whole_cache
1471: tst r2, #VM_EXEC
148#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
149 mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
150 mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
151 add r0, r0, #CACHE_DLINESIZE
152 mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
153 mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
154 add r0, r0, #CACHE_DLINESIZE
155#else
156 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
157 mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
158 add r0, r0, #CACHE_DLINESIZE
159 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
160 mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
161 add r0, r0, #CACHE_DLINESIZE
162#endif
163 cmp r0, r1
164 blo 1b
165 tst r2, #VM_EXEC
166 mcrne p15, 0, ip, c7, c10, 4 @ drain WB
167 mov pc, lr
168
169/*
170 * coherent_kern_range(start, end)
171 *
172 * Ensure coherency between the Icache and the Dcache in the
173 * region described by start, end. If you have non-snooping
174 * Harvard caches, you need to implement this function.
175 *
176 * - start - virtual start address
177 * - end - virtual end address
178 */
179ENTRY(feroceon_coherent_kern_range)
180 /* FALLTHROUGH */
181
182/*
183 * coherent_user_range(start, end)
184 *
185 * Ensure coherency between the Icache and the Dcache in the
186 * region described by start, end. If you have non-snooping
187 * Harvard caches, you need to implement this function.
188 *
189 * - start - virtual start address
190 * - end - virtual end address
191 */
192ENTRY(feroceon_coherent_user_range)
193 bic r0, r0, #CACHE_DLINESIZE - 1
1941: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
195 mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
196 add r0, r0, #CACHE_DLINESIZE
197 cmp r0, r1
198 blo 1b
199 mcr p15, 0, r0, c7, c10, 4 @ drain WB
200 mov pc, lr
201
202/*
203 * flush_kern_dcache_page(void *page)
204 *
205 * Ensure no D cache aliasing occurs, either with itself or
206 * the I cache
207 *
208 * - addr - page aligned address
209 */
210ENTRY(feroceon_flush_kern_dcache_page)
211 add r1, r0, #PAGE_SZ
2121: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
213 add r0, r0, #CACHE_DLINESIZE
214 cmp r0, r1
215 blo 1b
216 mov r0, #0
217 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
218 mcr p15, 0, r0, c7, c10, 4 @ drain WB
219 mov pc, lr
220
221/*
222 * dma_inv_range(start, end)
223 *
224 * Invalidate (discard) the specified virtual address range.
225 * May not write back any entries. If 'start' or 'end'
226 * are not cache line aligned, those lines must be written
227 * back.
228 *
229 * - start - virtual start address
230 * - end - virtual end address
231 *
232 * (same as v4wb)
233 */
234ENTRY(feroceon_dma_inv_range)
235#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
236 tst r0, #CACHE_DLINESIZE - 1
237 mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
238 tst r1, #CACHE_DLINESIZE - 1
239 mcrne p15, 0, r1, c7, c10, 1 @ clean D entry
240#endif
241 bic r0, r0, #CACHE_DLINESIZE - 1
2421: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
243 add r0, r0, #CACHE_DLINESIZE
244 cmp r0, r1
245 blo 1b
246 mcr p15, 0, r0, c7, c10, 4 @ drain WB
247 mov pc, lr
248
249/*
250 * dma_clean_range(start, end)
251 *
252 * Clean the specified virtual address range.
253 *
254 * - start - virtual start address
255 * - end - virtual end address
256 *
257 * (same as v4wb)
258 */
259ENTRY(feroceon_dma_clean_range)
260#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
261 bic r0, r0, #CACHE_DLINESIZE - 1
2621: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
263 add r0, r0, #CACHE_DLINESIZE
264 cmp r0, r1
265 blo 1b
266#endif
267 mcr p15, 0, r0, c7, c10, 4 @ drain WB
268 mov pc, lr
269
270/*
271 * dma_flush_range(start, end)
272 *
273 * Clean and invalidate the specified virtual address range.
274 *
275 * - start - virtual start address
276 * - end - virtual end address
277 */
278ENTRY(feroceon_dma_flush_range)
279 bic r0, r0, #CACHE_DLINESIZE - 1
2801:
281#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
282 mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
283#else
284 mcr p15, 0, r0, c7, c10, 1 @ clean D entry
285#endif
286 add r0, r0, #CACHE_DLINESIZE
287 cmp r0, r1
288 blo 1b
289 mcr p15, 0, r0, c7, c10, 4 @ drain WB
290 mov pc, lr
291
292ENTRY(feroceon_cache_fns)
293 .long feroceon_flush_kern_cache_all
294 .long feroceon_flush_user_cache_all
295 .long feroceon_flush_user_cache_range
296 .long feroceon_coherent_kern_range
297 .long feroceon_coherent_user_range
298 .long feroceon_flush_kern_dcache_page
299 .long feroceon_dma_inv_range
300 .long feroceon_dma_clean_range
301 .long feroceon_dma_flush_range
302
303ENTRY(cpu_feroceon_dcache_clean_area)
304#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
3051: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
306 add r0, r0, #CACHE_DLINESIZE
307 subs r1, r1, #CACHE_DLINESIZE
308 bhi 1b
309#endif
310 mcr p15, 0, r0, c7, c10, 4 @ drain WB
311 mov pc, lr
312
313/* =============================== PageTable ============================== */
314
315/*
316 * cpu_feroceon_switch_mm(pgd)
317 *
318 * Set the translation base pointer to be as described by pgd.
319 *
320 * pgd: new page tables
321 */
322 .align 5
323ENTRY(cpu_feroceon_switch_mm)
324#ifdef CONFIG_MMU
325 mov ip, #0
326#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
327 mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
328#else
329@ && 'Clean & Invalidate whole DCache'
3301: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate
331 bne 1b
332#endif
333 mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
334 mcr p15, 0, ip, c7, c10, 4 @ drain WB
335 mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
336 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
337#endif
338 mov pc, lr
339
340/*
341 * cpu_feroceon_set_pte_ext(ptep, pte, ext)
342 *
343 * Set a PTE and flush it out
344 */
345 .align 5
346ENTRY(cpu_feroceon_set_pte_ext)
347#ifdef CONFIG_MMU
348 str r1, [r0], #-2048 @ linux version
349
350 eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
351
352 bic r2, r1, #PTE_SMALL_AP_MASK
353 bic r2, r2, #PTE_TYPE_MASK
354 orr r2, r2, #PTE_TYPE_SMALL
355
356 tst r1, #L_PTE_USER @ User?
357 orrne r2, r2, #PTE_SMALL_AP_URO_SRW
358
359 tst r1, #L_PTE_WRITE | L_PTE_DIRTY @ Write and Dirty?
360 orreq r2, r2, #PTE_SMALL_AP_UNO_SRW
361
362 tst r1, #L_PTE_PRESENT | L_PTE_YOUNG @ Present and Young?
363 movne r2, #0
364
365#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
366 eor r3, r2, #0x0a @ C & small page?
367 tst r3, #0x0b
368 biceq r2, r2, #4
369#endif
370 str r2, [r0] @ hardware version
371 mov r0, r0
372#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
373 mcr p15, 0, r0, c7, c10, 1 @ clean D entry
374#endif
375 mcr p15, 0, r0, c7, c10, 4 @ drain WB
376#endif
377 mov pc, lr
378
379 __INIT
380
381 .type __feroceon_setup, #function
382__feroceon_setup:
383 mov r0, #0
384 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4
385 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4
386#ifdef CONFIG_MMU
387 mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4
388#endif
389
390
391#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
392 mov r0, #4 @ disable write-back on caches explicitly
393 mcr p15, 7, r0, c15, c0, 0
394#endif
395
396 adr r5, feroceon_crval
397 ldmia r5, {r5, r6}
398 mrc p15, 0, r0, c1, c0 @ get control register v4
399 bic r0, r0, r5
400 orr r0, r0, r6
401#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
402 orr r0, r0, #0x4000 @ .1.. .... .... ....
403#endif
404 mov pc, lr
405 .size __feroceon_setup, . - __feroceon_setup
406
407 /*
408 * R
409 * .RVI ZFRS BLDP WCAM
410 * .011 0001 ..11 0101
411 *
412 */
413 .type feroceon_crval, #object
414feroceon_crval:
415 crval clear=0x00007f3f, mmuset=0x00003135, ucset=0x00001134
416
417 __INITDATA
418
419/*
420 * Purpose : Function pointers used to access above functions - all calls
421 * come through these
422 */
423 .type feroceon_processor_functions, #object
424feroceon_processor_functions:
425 .word v5t_early_abort
426 .word cpu_feroceon_proc_init
427 .word cpu_feroceon_proc_fin
428 .word cpu_feroceon_reset
429 .word cpu_feroceon_do_idle
430 .word cpu_feroceon_dcache_clean_area
431 .word cpu_feroceon_switch_mm
432 .word cpu_feroceon_set_pte_ext
433 .size feroceon_processor_functions, . - feroceon_processor_functions
434
435 .section ".rodata"
436
437 .type cpu_arch_name, #object
438cpu_arch_name:
439 .asciz "armv5te"
440 .size cpu_arch_name, . - cpu_arch_name
441
442 .type cpu_elf_name, #object
443cpu_elf_name:
444 .asciz "v5"
445 .size cpu_elf_name, . - cpu_elf_name
446
447 .type cpu_feroceon_name, #object
448cpu_feroceon_name:
449 .asciz "Feroceon"
450 .size cpu_feroceon_name, . - cpu_feroceon_name
451
452 .align
453
454 .section ".proc.info.init", #alloc, #execinstr
455
456#ifdef CONFIG_CPU_FEROCEON_OLD_ID
457 .type __feroceon_old_id_proc_info,#object
458__feroceon_old_id_proc_info:
459 .long 0x41069260
460 .long 0xfffffff0
461 .long PMD_TYPE_SECT | \
462 PMD_SECT_BUFFERABLE | \
463 PMD_SECT_CACHEABLE | \
464 PMD_BIT4 | \
465 PMD_SECT_AP_WRITE | \
466 PMD_SECT_AP_READ
467 .long PMD_TYPE_SECT | \
468 PMD_BIT4 | \
469 PMD_SECT_AP_WRITE | \
470 PMD_SECT_AP_READ
471 b __feroceon_setup
472 .long cpu_arch_name
473 .long cpu_elf_name
474 .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
475 .long cpu_feroceon_name
476 .long feroceon_processor_functions
477 .long v4wbi_tlb_fns
478 .long v4wb_user_fns
479 .long feroceon_cache_fns
480 .size __feroceon_old_id_proc_info, . - __feroceon_old_id_proc_info
481#endif
482
483 .type __feroceon_proc_info,#object
484__feroceon_proc_info:
485 .long 0x56055310
486 .long 0xfffffff0
487 .long PMD_TYPE_SECT | \
488 PMD_SECT_BUFFERABLE | \
489 PMD_SECT_CACHEABLE | \
490 PMD_BIT4 | \
491 PMD_SECT_AP_WRITE | \
492 PMD_SECT_AP_READ
493 .long PMD_TYPE_SECT | \
494 PMD_BIT4 | \
495 PMD_SECT_AP_WRITE | \
496 PMD_SECT_AP_READ
497 b __feroceon_setup
498 .long cpu_arch_name
499 .long cpu_elf_name
500 .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
501 .long cpu_feroceon_name
502 .long feroceon_processor_functions
503 .long v4wbi_tlb_fns
504 .long v4wb_user_fns
505 .long feroceon_cache_fns
506 .size __feroceon_proc_info, . - __feroceon_proc_info
diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c
index a9de727c9327..0a5cf3a6438b 100644
--- a/arch/arm/oprofile/common.c
+++ b/arch/arm/oprofile/common.c
@@ -96,7 +96,7 @@ static int op_arm_resume(struct sys_device *dev)
96} 96}
97 97
98static struct sysdev_class oprofile_sysclass = { 98static struct sysdev_class oprofile_sysclass = {
99 set_kset_name("oprofile"), 99 .name = "oprofile",
100 .resume = op_arm_resume, 100 .resume = op_arm_resume,
101 .suspend = op_arm_suspend, 101 .suspend = op_arm_suspend,
102}; 102};
diff --git a/arch/arm/plat-omap/debug-devices.c b/arch/arm/plat-omap/debug-devices.c
index 83a5f8b91857..f455233af082 100644
--- a/arch/arm/plat-omap/debug-devices.c
+++ b/arch/arm/plat-omap/debug-devices.c
@@ -29,7 +29,7 @@ static struct resource smc91x_resources[] = {
29 .flags = IORESOURCE_MEM, 29 .flags = IORESOURCE_MEM,
30 }, 30 },
31 [1] = { 31 [1] = {
32 .flags = IORESOURCE_IRQ, 32 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
33 }, 33 },
34}; 34};
35 35
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 6097753394ad..b2a87b8ef673 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -1455,7 +1455,7 @@ static int omap_gpio_resume(struct sys_device *dev)
1455} 1455}
1456 1456
1457static struct sysdev_class omap_gpio_sysclass = { 1457static struct sysdev_class omap_gpio_sysclass = {
1458 set_kset_name("gpio"), 1458 .name = "gpio",
1459 .suspend = omap_gpio_suspend, 1459 .suspend = omap_gpio_suspend,
1460 .resume = omap_gpio_resume, 1460 .resume = omap_gpio_resume,
1461}; 1461};
diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c
index 0360b1f14d11..1945ddfec18d 100644
--- a/arch/arm/plat-omap/mailbox.c
+++ b/arch/arm/plat-omap/mailbox.c
@@ -116,8 +116,8 @@ static void mbox_tx_work(struct work_struct *work)
116 } 116 }
117 117
118 spin_lock(q->queue_lock); 118 spin_lock(q->queue_lock);
119 blkdev_dequeue_request(rq); 119 if (__blk_end_request(rq, 0, 0))
120 end_that_request_last(rq, 0); 120 BUG();
121 spin_unlock(q->queue_lock); 121 spin_unlock(q->queue_lock);
122 } 122 }
123} 123}
@@ -149,10 +149,8 @@ static void mbox_rx_work(struct work_struct *work)
149 149
150 msg = (mbox_msg_t) rq->data; 150 msg = (mbox_msg_t) rq->data;
151 151
152 spin_lock_irqsave(q->queue_lock, flags); 152 if (blk_end_request(rq, 0, 0))
153 blkdev_dequeue_request(rq); 153 BUG();
154 end_that_request_last(rq, 0);
155 spin_unlock_irqrestore(q->queue_lock, flags);
156 154
157 mbox->rxq->callback((void *)msg); 155 mbox->rxq->callback((void *)msg);
158 } 156 }
@@ -212,7 +210,7 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox)
212 210
213static irqreturn_t mbox_interrupt(int irq, void *p) 211static irqreturn_t mbox_interrupt(int irq, void *p)
214{ 212{
215 struct omap_mbox *mbox = (struct omap_mbox *)p; 213 struct omap_mbox *mbox = p;
216 214
217 if (is_mbox_irq(mbox, IRQ_TX)) 215 if (is_mbox_irq(mbox, IRQ_TX))
218 __mbox_tx_interrupt(mbox); 216 __mbox_tx_interrupt(mbox);
@@ -263,10 +261,8 @@ omap_mbox_read(struct device *dev, struct device_attribute *attr, char *buf)
263 261
264 *p = (mbox_msg_t) rq->data; 262 *p = (mbox_msg_t) rq->data;
265 263
266 spin_lock_irqsave(q->queue_lock, flags); 264 if (blk_end_request(rq, 0, 0))
267 blkdev_dequeue_request(rq); 265 BUG();
268 end_that_request_last(rq, 0);
269 spin_unlock_irqrestore(q->queue_lock, flags);
270 266
271 if (unlikely(mbox_seq_test(mbox, *p))) { 267 if (unlikely(mbox_seq_test(mbox, *p))) {
272 pr_info("mbox: Illegal seq bit!(%08x) ignored\n", *p); 268 pr_info("mbox: Illegal seq bit!(%08x) ignored\n", *p);
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index f7b9ccdaacbc..2af5bd5a1344 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -98,9 +98,10 @@ static void omap_mcbsp_dump_reg(u8 id)
98 98
99static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id) 99static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id)
100{ 100{
101 struct omap_mcbsp * mcbsp_tx = (struct omap_mcbsp *)(dev_id); 101 struct omap_mcbsp *mcbsp_tx = dev_id;
102 102
103 DBG("TX IRQ callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2)); 103 DBG("TX IRQ callback : 0x%x\n",
104 OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2));
104 105
105 complete(&mcbsp_tx->tx_irq_completion); 106 complete(&mcbsp_tx->tx_irq_completion);
106 return IRQ_HANDLED; 107 return IRQ_HANDLED;
@@ -108,9 +109,10 @@ static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id)
108 109
109static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id) 110static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id)
110{ 111{
111 struct omap_mcbsp * mcbsp_rx = (struct omap_mcbsp *)(dev_id); 112 struct omap_mcbsp *mcbsp_rx = dev_id;
112 113
113 DBG("RX IRQ callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2)); 114 DBG("RX IRQ callback : 0x%x\n",
115 OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2));
114 116
115 complete(&mcbsp_rx->rx_irq_completion); 117 complete(&mcbsp_rx->rx_irq_completion);
116 return IRQ_HANDLED; 118 return IRQ_HANDLED;
@@ -118,9 +120,10 @@ static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id)
118 120
119static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data) 121static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data)
120{ 122{
121 struct omap_mcbsp * mcbsp_dma_tx = (struct omap_mcbsp *)(data); 123 struct omap_mcbsp *mcbsp_dma_tx = data;
122 124
123 DBG("TX DMA callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2)); 125 DBG("TX DMA callback : 0x%x\n",
126 OMAP_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2));
124 127
125 /* We can free the channels */ 128 /* We can free the channels */
126 omap_free_dma(mcbsp_dma_tx->dma_tx_lch); 129 omap_free_dma(mcbsp_dma_tx->dma_tx_lch);
@@ -131,9 +134,10 @@ static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data)
131 134
132static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data) 135static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data)
133{ 136{
134 struct omap_mcbsp * mcbsp_dma_rx = (struct omap_mcbsp *)(data); 137 struct omap_mcbsp *mcbsp_dma_rx = data;
135 138
136 DBG("RX DMA callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2)); 139 DBG("RX DMA callback : 0x%x\n",
140 OMAP_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2));
137 141
138 /* We can free the channels */ 142 /* We can free the channels */
139 omap_free_dma(mcbsp_dma_rx->dma_rx_lch); 143 omap_free_dma(mcbsp_dma_rx->dma_rx_lch);
diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile
index 8e5ccaa1f03c..131d20237dd7 100644
--- a/arch/arm/plat-s3c24xx/Makefile
+++ b/arch/arm/plat-s3c24xx/Makefile
@@ -23,6 +23,7 @@ obj-y += clock.o
23 23
24obj-$(CONFIG_CPU_S3C244X) += s3c244x.o 24obj-$(CONFIG_CPU_S3C244X) += s3c244x.o
25obj-$(CONFIG_CPU_S3C244X) += s3c244x-irq.o 25obj-$(CONFIG_CPU_S3C244X) += s3c244x-irq.o
26obj-$(CONFIG_CPU_S3C244X) += s3c244x-clock.o
26obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o 27obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o
27obj-$(CONFIG_PM) += pm.o 28obj-$(CONFIG_PM) += pm.o
28obj-$(CONFIG_PM) += sleep.o 29obj-$(CONFIG_PM) += sleep.o
diff --git a/arch/arm/plat-s3c24xx/clock.c b/arch/arm/plat-s3c24xx/clock.c
index 79cda0faec86..99a44746f8f2 100644
--- a/arch/arm/plat-s3c24xx/clock.c
+++ b/arch/arm/plat-s3c24xx/clock.c
@@ -172,6 +172,15 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
172 if (IS_ERR(clk)) 172 if (IS_ERR(clk))
173 return -EINVAL; 173 return -EINVAL;
174 174
175 /* We do not default just do a clk->rate = rate as
176 * the clock may have been made this way by choice.
177 */
178
179 WARN_ON(clk->set_rate == NULL);
180
181 if (clk->set_rate == NULL)
182 return -EINVAL;
183
175 mutex_lock(&clocks_mutex); 184 mutex_lock(&clocks_mutex);
176 ret = (clk->set_rate)(clk, rate); 185 ret = (clk->set_rate)(clk, rate);
177 mutex_unlock(&clocks_mutex); 186 mutex_unlock(&clocks_mutex);
@@ -213,6 +222,12 @@ EXPORT_SYMBOL(clk_set_parent);
213 222
214/* base clocks */ 223/* base clocks */
215 224
225static int clk_default_setrate(struct clk *clk, unsigned long rate)
226{
227 clk->rate = rate;
228 return 0;
229}
230
216struct clk clk_xtal = { 231struct clk clk_xtal = {
217 .name = "xtal", 232 .name = "xtal",
218 .id = -1, 233 .id = -1,
@@ -224,6 +239,7 @@ struct clk clk_xtal = {
224struct clk clk_mpll = { 239struct clk clk_mpll = {
225 .name = "mpll", 240 .name = "mpll",
226 .id = -1, 241 .id = -1,
242 .set_rate = clk_default_setrate,
227}; 243};
228 244
229struct clk clk_upll = { 245struct clk clk_upll = {
@@ -239,6 +255,7 @@ struct clk clk_f = {
239 .rate = 0, 255 .rate = 0,
240 .parent = &clk_mpll, 256 .parent = &clk_mpll,
241 .ctrlbit = 0, 257 .ctrlbit = 0,
258 .set_rate = clk_default_setrate,
242}; 259};
243 260
244struct clk clk_h = { 261struct clk clk_h = {
@@ -247,6 +264,7 @@ struct clk clk_h = {
247 .rate = 0, 264 .rate = 0,
248 .parent = NULL, 265 .parent = NULL,
249 .ctrlbit = 0, 266 .ctrlbit = 0,
267 .set_rate = clk_default_setrate,
250}; 268};
251 269
252struct clk clk_p = { 270struct clk clk_p = {
@@ -255,6 +273,7 @@ struct clk clk_p = {
255 .rate = 0, 273 .rate = 0,
256 .parent = NULL, 274 .parent = NULL,
257 .ctrlbit = 0, 275 .ctrlbit = 0,
276 .set_rate = clk_default_setrate,
258}; 277};
259 278
260struct clk clk_usb_bus = { 279struct clk clk_usb_bus = {
diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c
index 29696e46ed65..ac9ff1666fcc 100644
--- a/arch/arm/plat-s3c24xx/dma.c
+++ b/arch/arm/plat-s3c24xx/dma.c
@@ -525,7 +525,8 @@ int s3c2410_dma_enqueue(unsigned int channel, void *id,
525 } 525 }
526 } else if (chan->state == S3C2410_DMA_IDLE) { 526 } else if (chan->state == S3C2410_DMA_IDLE) {
527 if (chan->flags & S3C2410_DMAF_AUTOSTART) { 527 if (chan->flags & S3C2410_DMAF_AUTOSTART) {
528 s3c2410_dma_ctrl(chan->number, S3C2410_DMAOP_START); 528 s3c2410_dma_ctrl(chan->number | DMACH_LOW_LEVEL,
529 S3C2410_DMAOP_START);
529 } 530 }
530 } 531 }
531 532
@@ -787,7 +788,7 @@ int s3c2410_dma_request(unsigned int channel,
787 788
788 pr_debug("%s: channel initialised, %p\n", __FUNCTION__, chan); 789 pr_debug("%s: channel initialised, %p\n", __FUNCTION__, chan);
789 790
790 return 0; 791 return chan->number | DMACH_LOW_LEVEL;
791} 792}
792 793
793EXPORT_SYMBOL(s3c2410_dma_request); 794EXPORT_SYMBOL(s3c2410_dma_request);
@@ -1173,6 +1174,7 @@ int s3c2410_dma_devconfig(int channel,
1173 1174
1174 chan->source = source; 1175 chan->source = source;
1175 chan->dev_addr = devaddr; 1176 chan->dev_addr = devaddr;
1177 chan->hw_cfg = hwcfg;
1176 1178
1177 switch (source) { 1179 switch (source) {
1178 case S3C2410_DMASRC_HW: 1180 case S3C2410_DMASRC_HW:
@@ -1184,7 +1186,7 @@ int s3c2410_dma_devconfig(int channel,
1184 dma_wrreg(chan, S3C2410_DMA_DIDSTC, (0<<1) | (0<<0)); 1186 dma_wrreg(chan, S3C2410_DMA_DIDSTC, (0<<1) | (0<<0));
1185 1187
1186 chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DIDST); 1188 chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DIDST);
1187 return 0; 1189 break;
1188 1190
1189 case S3C2410_DMASRC_MEM: 1191 case S3C2410_DMASRC_MEM:
1190 /* source is memory */ 1192 /* source is memory */
@@ -1195,11 +1197,19 @@ int s3c2410_dma_devconfig(int channel,
1195 dma_wrreg(chan, S3C2410_DMA_DIDSTC, hwcfg & 3); 1197 dma_wrreg(chan, S3C2410_DMA_DIDSTC, hwcfg & 3);
1196 1198
1197 chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DISRC); 1199 chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DISRC);
1198 return 0; 1200 break;
1201
1202 default:
1203 printk(KERN_ERR "dma%d: invalid source type (%d)\n",
1204 channel, source);
1205
1206 return -EINVAL;
1199 } 1207 }
1200 1208
1201 printk(KERN_ERR "dma%d: invalid source type (%d)\n", channel, source); 1209 if (dma_sel.direction != NULL)
1202 return -EINVAL; 1210 (dma_sel.direction)(chan, chan->map, source);
1211
1212 return 0;
1203} 1213}
1204 1214
1205EXPORT_SYMBOL(s3c2410_dma_devconfig); 1215EXPORT_SYMBOL(s3c2410_dma_devconfig);
@@ -1227,6 +1237,10 @@ int s3c2410_dma_getposition(dmach_t channel, dma_addr_t *src, dma_addr_t *dst)
1227 1237
1228EXPORT_SYMBOL(s3c2410_dma_getposition); 1238EXPORT_SYMBOL(s3c2410_dma_getposition);
1229 1239
1240static struct s3c2410_dma_chan *to_dma_chan(struct sys_device *dev)
1241{
1242 return container_of(dev, struct s3c2410_dma_chan, dev);
1243}
1230 1244
1231/* system device class */ 1245/* system device class */
1232 1246
@@ -1234,7 +1248,7 @@ EXPORT_SYMBOL(s3c2410_dma_getposition);
1234 1248
1235static int s3c2410_dma_suspend(struct sys_device *dev, pm_message_t state) 1249static int s3c2410_dma_suspend(struct sys_device *dev, pm_message_t state)
1236{ 1250{
1237 struct s3c2410_dma_chan *cp = container_of(dev, struct s3c2410_dma_chan, dev); 1251 struct s3c2410_dma_chan *cp = to_dma_chan(dev);
1238 1252
1239 printk(KERN_DEBUG "suspending dma channel %d\n", cp->number); 1253 printk(KERN_DEBUG "suspending dma channel %d\n", cp->number);
1240 1254
@@ -1256,6 +1270,24 @@ static int s3c2410_dma_suspend(struct sys_device *dev, pm_message_t state)
1256 1270
1257static int s3c2410_dma_resume(struct sys_device *dev) 1271static int s3c2410_dma_resume(struct sys_device *dev)
1258{ 1272{
1273 struct s3c2410_dma_chan *cp = to_dma_chan(dev);
1274 unsigned int no = cp->number | DMACH_LOW_LEVEL;
1275
1276 /* restore channel's hardware configuration */
1277
1278 if (!cp->in_use)
1279 return 0;
1280
1281 printk(KERN_INFO "dma%d: restoring configuration\n", cp->number);
1282
1283 s3c2410_dma_config(no, cp->xfer_unit, cp->dcon);
1284 s3c2410_dma_devconfig(no, cp->source, cp->hw_cfg, cp->dev_addr);
1285
1286 /* re-select the dma source for this channel */
1287
1288 if (cp->map != NULL)
1289 dma_sel.select(cp, cp->map);
1290
1259 return 0; 1291 return 0;
1260} 1292}
1261 1293
@@ -1265,7 +1297,7 @@ static int s3c2410_dma_resume(struct sys_device *dev)
1265#endif /* CONFIG_PM */ 1297#endif /* CONFIG_PM */
1266 1298
1267struct sysdev_class dma_sysclass = { 1299struct sysdev_class dma_sysclass = {
1268 set_kset_name("s3c24xx-dma"), 1300 .name = "s3c24xx-dma",
1269 .suspend = s3c2410_dma_suspend, 1301 .suspend = s3c2410_dma_suspend,
1270 .resume = s3c2410_dma_resume, 1302 .resume = s3c2410_dma_resume,
1271}; 1303};
@@ -1445,6 +1477,7 @@ static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel)
1445 1477
1446 found: 1478 found:
1447 dmach = &s3c2410_chans[ch]; 1479 dmach = &s3c2410_chans[ch];
1480 dmach->map = ch_map;
1448 dma_chan_map[channel] = dmach; 1481 dma_chan_map[channel] = dmach;
1449 1482
1450 /* select the channel */ 1483 /* select the channel */
diff --git a/arch/arm/plat-s3c24xx/gpio.c b/arch/arm/plat-s3c24xx/gpio.c
index ec3a09c4d181..ee99dcc7f0bd 100644
--- a/arch/arm/plat-s3c24xx/gpio.c
+++ b/arch/arm/plat-s3c24xx/gpio.c
@@ -122,6 +122,19 @@ void s3c2410_gpio_pullup(unsigned int pin, unsigned int to)
122 122
123EXPORT_SYMBOL(s3c2410_gpio_pullup); 123EXPORT_SYMBOL(s3c2410_gpio_pullup);
124 124
125int s3c2410_gpio_getpull(unsigned int pin)
126{
127 void __iomem *base = S3C24XX_GPIO_BASE(pin);
128 unsigned long offs = S3C2410_GPIO_OFFSET(pin);
129
130 if (pin < S3C2410_GPIO_BANKB)
131 return -EINVAL;
132
133 return (__raw_readl(base + 0x08) & (1L << offs)) ? 1 : 0;
134}
135
136EXPORT_SYMBOL(s3c2410_gpio_getpull);
137
125void s3c2410_gpio_setpin(unsigned int pin, unsigned int to) 138void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
126{ 139{
127 void __iomem *base = S3C24XX_GPIO_BASE(pin); 140 void __iomem *base = S3C24XX_GPIO_BASE(pin);
@@ -186,3 +199,19 @@ int s3c2410_gpio_getirq(unsigned int pin)
186} 199}
187 200
188EXPORT_SYMBOL(s3c2410_gpio_getirq); 201EXPORT_SYMBOL(s3c2410_gpio_getirq);
202
203int s3c2410_gpio_irq2pin(unsigned int irq)
204{
205 if (irq >= IRQ_EINT0 && irq <= IRQ_EINT3)
206 return S3C2410_GPF0 + (irq - IRQ_EINT0);
207
208 if (irq >= IRQ_EINT4 && irq <= IRQ_EINT7)
209 return S3C2410_GPF4 + (irq - IRQ_EINT4);
210
211 if (irq >= IRQ_EINT8 && irq <= IRQ_EINT23)
212 return S3C2410_GPG0 + (irq - IRQ_EINT8);
213
214 return -EINVAL;
215}
216
217EXPORT_SYMBOL(s3c2410_gpio_irq2pin);
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index 8fbc88470261..d486f5112569 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -187,7 +187,7 @@ struct irq_chip s3c_irq_level_chip = {
187 .set_wake = s3c_irq_wake 187 .set_wake = s3c_irq_wake
188}; 188};
189 189
190static struct irq_chip s3c_irq_chip = { 190struct irq_chip s3c_irq_chip = {
191 .name = "s3c", 191 .name = "s3c",
192 .ack = s3c_irq_ack, 192 .ack = s3c_irq_ack,
193 .mask = s3c_irq_mask, 193 .mask = s3c_irq_mask,
diff --git a/arch/arm/plat-s3c24xx/pm.c b/arch/arm/plat-s3c24xx/pm.c
index 4fdb3117744f..bf5581a9aeea 100644
--- a/arch/arm/plat-s3c24xx/pm.c
+++ b/arch/arm/plat-s3c24xx/pm.c
@@ -83,38 +83,39 @@ static struct sleep_save core_save[] = {
83 SAVE_ITEM(S3C2410_REFRESH), 83 SAVE_ITEM(S3C2410_REFRESH),
84}; 84};
85 85
86static struct sleep_save gpio_save[] = { 86static struct gpio_sleep {
87 SAVE_ITEM(S3C2410_GPACON), 87 void __iomem *base;
88 SAVE_ITEM(S3C2410_GPADAT), 88 unsigned int gpcon;
89 89 unsigned int gpdat;
90 SAVE_ITEM(S3C2410_GPBCON), 90 unsigned int gpup;
91 SAVE_ITEM(S3C2410_GPBDAT), 91} gpio_save[] = {
92 SAVE_ITEM(S3C2410_GPBUP), 92 [0] = {
93 93 .base = S3C2410_GPACON,
94 SAVE_ITEM(S3C2410_GPCCON), 94 },
95 SAVE_ITEM(S3C2410_GPCDAT), 95 [1] = {
96 SAVE_ITEM(S3C2410_GPCUP), 96 .base = S3C2410_GPBCON,
97 97 },
98 SAVE_ITEM(S3C2410_GPDCON), 98 [2] = {
99 SAVE_ITEM(S3C2410_GPDDAT), 99 .base = S3C2410_GPCCON,
100 SAVE_ITEM(S3C2410_GPDUP), 100 },
101 101 [3] = {
102 SAVE_ITEM(S3C2410_GPECON), 102 .base = S3C2410_GPDCON,
103 SAVE_ITEM(S3C2410_GPEDAT), 103 },
104 SAVE_ITEM(S3C2410_GPEUP), 104 [4] = {
105 105 .base = S3C2410_GPECON,
106 SAVE_ITEM(S3C2410_GPFCON), 106 },
107 SAVE_ITEM(S3C2410_GPFDAT), 107 [5] = {
108 SAVE_ITEM(S3C2410_GPFUP), 108 .base = S3C2410_GPFCON,
109 109 },
110 SAVE_ITEM(S3C2410_GPGCON), 110 [6] = {
111 SAVE_ITEM(S3C2410_GPGDAT), 111 .base = S3C2410_GPGCON,
112 SAVE_ITEM(S3C2410_GPGUP), 112 },
113 113 [7] = {
114 SAVE_ITEM(S3C2410_GPHCON), 114 .base = S3C2410_GPHCON,
115 SAVE_ITEM(S3C2410_GPHDAT), 115 },
116 SAVE_ITEM(S3C2410_GPHUP), 116};
117 117
118static struct sleep_save misc_save[] = {
118 SAVE_ITEM(S3C2410_DCLKCON), 119 SAVE_ITEM(S3C2410_DCLKCON),
119}; 120};
120 121
@@ -486,6 +487,184 @@ static void s3c2410_pm_configure_extint(void)
486 } 487 }
487} 488}
488 489
490/* offsets for CON/DAT/UP registers */
491
492#define OFFS_CON (S3C2410_GPACON - S3C2410_GPACON)
493#define OFFS_DAT (S3C2410_GPADAT - S3C2410_GPACON)
494#define OFFS_UP (S3C2410_GPBUP - S3C2410_GPBCON)
495
496/* s3c2410_pm_save_gpios()
497 *
498 * Save the state of the GPIOs
499 */
500
501static void s3c2410_pm_save_gpios(void)
502{
503 struct gpio_sleep *gps = gpio_save;
504 unsigned int gpio;
505
506 for (gpio = 0; gpio < ARRAY_SIZE(gpio_save); gpio++, gps++) {
507 void __iomem *base = gps->base;
508
509 gps->gpcon = __raw_readl(base + OFFS_CON);
510 gps->gpdat = __raw_readl(base + OFFS_DAT);
511
512 if (gpio > 0)
513 gps->gpup = __raw_readl(base + OFFS_UP);
514
515 }
516}
517
518/* Test whether the given masked+shifted bits of an GPIO configuration
519 * are one of the SFN (special function) modes. */
520
521static inline int is_sfn(unsigned long con)
522{
523 return (con == 2 || con == 3);
524}
525
526/* Test if the given masked+shifted GPIO configuration is an input */
527
528static inline int is_in(unsigned long con)
529{
530 return con == 0;
531}
532
533/* Test if the given masked+shifted GPIO configuration is an output */
534
535static inline int is_out(unsigned long con)
536{
537 return con == 1;
538}
539
540/* s3c2410_pm_restore_gpio()
541 *
542 * Restore one of the GPIO banks that was saved during suspend. This is
543 * not as simple as once thought, due to the possibility of glitches
544 * from the order that the CON and DAT registers are set in.
545 *
546 * The three states the pin can be are {IN,OUT,SFN} which gives us 9
547 * combinations of changes to check. Three of these, if the pin stays
548 * in the same configuration can be discounted. This leaves us with
549 * the following:
550 *
551 * { IN => OUT } Change DAT first
552 * { IN => SFN } Change CON first
553 * { OUT => SFN } Change CON first, so new data will not glitch
554 * { OUT => IN } Change CON first, so new data will not glitch
555 * { SFN => IN } Change CON first
556 * { SFN => OUT } Change DAT first, so new data will not glitch [1]
557 *
558 * We do not currently deal with the UP registers as these control
559 * weak resistors, so a small delay in change should not need to bring
560 * these into the calculations.
561 *
562 * [1] this assumes that writing to a pin DAT whilst in SFN will set the
563 * state for when it is next output.
564 */
565
566static void s3c2410_pm_restore_gpio(int index, struct gpio_sleep *gps)
567{
568 void __iomem *base = gps->base;
569 unsigned long gps_gpcon = gps->gpcon;
570 unsigned long gps_gpdat = gps->gpdat;
571 unsigned long old_gpcon;
572 unsigned long old_gpdat;
573 unsigned long old_gpup = 0x0;
574 unsigned long gpcon;
575 int nr;
576
577 old_gpcon = __raw_readl(base + OFFS_CON);
578 old_gpdat = __raw_readl(base + OFFS_DAT);
579
580 if (base == S3C2410_GPACON) {
581 /* GPACON only has one bit per control / data and no PULLUPs.
582 * GPACON[x] = 0 => Output, 1 => SFN */
583
584 /* first set all SFN bits to SFN */
585
586 gpcon = old_gpcon | gps->gpcon;
587 __raw_writel(gpcon, base + OFFS_CON);
588
589 /* now set all the other bits */
590
591 __raw_writel(gps_gpdat, base + OFFS_DAT);
592 __raw_writel(gps_gpcon, base + OFFS_CON);
593 } else {
594 unsigned long old, new, mask;
595 unsigned long change_mask = 0x0;
596
597 old_gpup = __raw_readl(base + OFFS_UP);
598
599 /* Create a change_mask of all the items that need to have
600 * their CON value changed before their DAT value, so that
601 * we minimise the work between the two settings.
602 */
603
604 for (nr = 0, mask = 0x03; nr < 32; nr += 2, mask <<= 2) {
605 old = (old_gpcon & mask) >> nr;
606 new = (gps_gpcon & mask) >> nr;
607
608 /* If there is no change, then skip */
609
610 if (old == new)
611 continue;
612
613 /* If both are special function, then skip */
614
615 if (is_sfn(old) && is_sfn(new))
616 continue;
617
618 /* Change is IN => OUT, do not change now */
619
620 if (is_in(old) && is_out(new))
621 continue;
622
623 /* Change is SFN => OUT, do not change now */
624
625 if (is_sfn(old) && is_out(new))
626 continue;
627
628 /* We should now be at the case of IN=>SFN,
629 * OUT=>SFN, OUT=>IN, SFN=>IN. */
630
631 change_mask |= mask;
632 }
633
634 /* Write the new CON settings */
635
636 gpcon = old_gpcon & ~change_mask;
637 gpcon |= gps_gpcon & change_mask;
638
639 __raw_writel(gpcon, base + OFFS_CON);
640
641 /* Now change any items that require DAT,CON */
642
643 __raw_writel(gps_gpdat, base + OFFS_DAT);
644 __raw_writel(gps_gpcon, base + OFFS_CON);
645 __raw_writel(gps->gpup, base + OFFS_UP);
646 }
647
648 DBG("GPIO[%d] CON %08lx => %08lx, DAT %08lx => %08lx\n",
649 index, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat);
650}
651
652
653/** s3c2410_pm_restore_gpios()
654 *
655 * Restore the state of the GPIOs
656 */
657
658static void s3c2410_pm_restore_gpios(void)
659{
660 struct gpio_sleep *gps = gpio_save;
661 int gpio;
662
663 for (gpio = 0; gpio < ARRAY_SIZE(gpio_save); gpio++, gps++) {
664 s3c2410_pm_restore_gpio(gpio, gps);
665 }
666}
667
489void (*pm_cpu_prep)(void); 668void (*pm_cpu_prep)(void);
490void (*pm_cpu_sleep)(void); 669void (*pm_cpu_sleep)(void);
491 670
@@ -535,7 +714,8 @@ static int s3c2410_pm_enter(suspend_state_t state)
535 714
536 /* save all necessary core registers not covered by the drivers */ 715 /* save all necessary core registers not covered by the drivers */
537 716
538 s3c2410_pm_do_save(gpio_save, ARRAY_SIZE(gpio_save)); 717 s3c2410_pm_save_gpios();
718 s3c2410_pm_do_save(misc_save, ARRAY_SIZE(misc_save));
539 s3c2410_pm_do_save(core_save, ARRAY_SIZE(core_save)); 719 s3c2410_pm_do_save(core_save, ARRAY_SIZE(core_save));
540 s3c2410_pm_do_save(uart_save, ARRAY_SIZE(uart_save)); 720 s3c2410_pm_do_save(uart_save, ARRAY_SIZE(uart_save));
541 721
@@ -585,8 +765,9 @@ static int s3c2410_pm_enter(suspend_state_t state)
585 /* restore the system state */ 765 /* restore the system state */
586 766
587 s3c2410_pm_do_restore_core(core_save, ARRAY_SIZE(core_save)); 767 s3c2410_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
588 s3c2410_pm_do_restore(gpio_save, ARRAY_SIZE(gpio_save)); 768 s3c2410_pm_do_restore(misc_save, ARRAY_SIZE(misc_save));
589 s3c2410_pm_do_restore(uart_save, ARRAY_SIZE(uart_save)); 769 s3c2410_pm_do_restore(uart_save, ARRAY_SIZE(uart_save));
770 s3c2410_pm_restore_gpios();
590 771
591 s3c2410_pm_debug_init(); 772 s3c2410_pm_debug_init();
592 773
diff --git a/arch/arm/plat-s3c24xx/s3c244x-clock.c b/arch/arm/plat-s3c24xx/s3c244x-clock.c
new file mode 100644
index 000000000000..faf3e0f9f4e2
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/s3c244x-clock.c
@@ -0,0 +1,137 @@
1/* linux/arch/arm/plat-s3c24xx/s3c24xx-clock.c
2 *
3 * Copyright (c) 2004-2005,2008 Simtec Electronics
4 * http://armlinux.simtec.co.uk/
5 * Ben Dooks <ben@simtec.co.uk>
6 *
7 * S3C2440/S3C2442 Common clock support
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22*/
23
24#include <linux/init.h>
25#include <linux/module.h>
26#include <linux/kernel.h>
27#include <linux/list.h>
28#include <linux/errno.h>
29#include <linux/err.h>
30#include <linux/device.h>
31#include <linux/sysdev.h>
32#include <linux/interrupt.h>
33#include <linux/ioport.h>
34#include <linux/mutex.h>
35#include <linux/clk.h>
36
37#include <asm/hardware.h>
38#include <asm/atomic.h>
39#include <asm/irq.h>
40#include <asm/io.h>
41
42#include <asm/arch/regs-clock.h>
43
44#include <asm/plat-s3c24xx/clock.h>
45#include <asm/plat-s3c24xx/cpu.h>
46
47static int s3c2440_setparent_armclk(struct clk *clk, struct clk *parent)
48{
49 unsigned long camdivn;
50 unsigned long dvs;
51
52 if (parent == &clk_f)
53 dvs = 0;
54 else if (parent == &clk_h)
55 dvs = S3C2440_CAMDIVN_DVSEN;
56 else
57 return -EINVAL;
58
59 clk->parent = parent;
60
61 camdivn = __raw_readl(S3C2440_CAMDIVN);
62 camdivn &= ~S3C2440_CAMDIVN_DVSEN;
63 camdivn |= dvs;
64 __raw_writel(camdivn, S3C2440_CAMDIVN);
65
66 return 0;
67}
68
69static struct clk clk_arm = {
70 .name = "armclk",
71 .id = -1,
72 .set_parent = s3c2440_setparent_armclk,
73};
74
75static int s3c244x_clk_add(struct sys_device *sysdev)
76{
77 unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
78 unsigned long clkdivn;
79 struct clk *clock_upll;
80 int ret;
81
82 printk("S3C244X: Clock Support, DVS %s\n",
83 (camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off");
84
85 clk_arm.parent = (camdivn & S3C2440_CAMDIVN_DVSEN) ? &clk_h : &clk_f;
86
87 ret = s3c24xx_register_clock(&clk_arm);
88 if (ret < 0) {
89 printk(KERN_ERR "S3C24XX: Failed to add armclk (%d)\n", ret);
90 return ret;
91 }
92
93 clock_upll = clk_get(NULL, "upll");
94 if (IS_ERR(clock_upll)) {
95 printk(KERN_ERR "S3C244X: Failed to get upll clock\n");
96 return -ENOENT;
97 }
98
99 /* check rate of UPLL, and if it is near 96MHz, then change
100 * to using half the UPLL rate for the system */
101
102 if (clk_get_rate(clock_upll) > (94 * MHZ)) {
103 clk_usb_bus.rate = clk_get_rate(clock_upll) / 2;
104
105 mutex_lock(&clocks_mutex);
106
107 clkdivn = __raw_readl(S3C2410_CLKDIVN);
108 clkdivn |= S3C2440_CLKDIVN_UCLK;
109 __raw_writel(clkdivn, S3C2410_CLKDIVN);
110
111 mutex_unlock(&clocks_mutex);
112 }
113
114 return 0;
115}
116
117static struct sysdev_driver s3c2440_clk_driver = {
118 .add = s3c244x_clk_add,
119};
120
121static int s3c2440_clk_init(void)
122{
123 return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_clk_driver);
124}
125
126arch_initcall(s3c2440_clk_init);
127
128static struct sysdev_driver s3c2442_clk_driver = {
129 .add = s3c244x_clk_add,
130};
131
132static int s3c2442_clk_init(void)
133{
134 return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_clk_driver);
135}
136
137arch_initcall(s3c2442_clk_init);
diff --git a/arch/arm/plat-s3c24xx/s3c244x.c b/arch/arm/plat-s3c24xx/s3c244x.c
index 3444b13afac5..f197bb3a2366 100644
--- a/arch/arm/plat-s3c24xx/s3c244x.c
+++ b/arch/arm/plat-s3c24xx/s3c244x.c
@@ -151,13 +151,13 @@ static int s3c244x_resume(struct sys_device *dev)
151/* Since the S3C2442 and S3C2440 share items, put both sysclasses here */ 151/* Since the S3C2442 and S3C2440 share items, put both sysclasses here */
152 152
153struct sysdev_class s3c2440_sysclass = { 153struct sysdev_class s3c2440_sysclass = {
154 set_kset_name("s3c2440-core"), 154 .name = "s3c2440-core",
155 .suspend = s3c244x_suspend, 155 .suspend = s3c244x_suspend,
156 .resume = s3c244x_resume 156 .resume = s3c244x_resume
157}; 157};
158 158
159struct sysdev_class s3c2442_sysclass = { 159struct sysdev_class s3c2442_sysclass = {
160 set_kset_name("s3c2442-core"), 160 .name = "s3c2442-core",
161 .suspend = s3c244x_suspend, 161 .suspend = s3c244x_suspend,
162 .resume = s3c244x_resume 162 .resume = s3c244x_resume
163}; 163};
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index 0a9a5e7f62e5..7ed58c0c24c2 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -12,7 +12,7 @@
12# 12#
13# http://www.arm.linux.org.uk/developer/machines/?action=new 13# http://www.arm.linux.org.uk/developer/machines/?action=new
14# 14#
15# Last update: Fri May 11 19:53:41 2007 15# Last update: Sat Jan 26 14:45:34 2008
16# 16#
17# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number 17# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
18# 18#
@@ -266,7 +266,7 @@ stork_egg ARCH_STORK_EGG STORK_EGG 248
266wismo SA1100_WISMO WISMO 249 266wismo SA1100_WISMO WISMO 249
267ezlinx ARCH_EZLINX EZLINX 250 267ezlinx ARCH_EZLINX EZLINX 250
268at91rm9200 ARCH_AT91RM9200 AT91RM9200 251 268at91rm9200 ARCH_AT91RM9200 AT91RM9200 251
269orion ARCH_ORION ORION 252 269adtech_orion ARCH_ADTECH_ORION ADTECH_ORION 252
270neptune ARCH_NEPTUNE NEPTUNE 253 270neptune ARCH_NEPTUNE NEPTUNE 253
271hackkit SA1100_HACKKIT HACKKIT 254 271hackkit SA1100_HACKKIT HACKKIT 254
272pxa_wins30 ARCH_PXA_WINS30 PXA_WINS30 255 272pxa_wins30 ARCH_PXA_WINS30 PXA_WINS30 255
@@ -661,7 +661,6 @@ a9200ec MACH_A9200EC A9200EC 645
661pnx0105 MACH_PNX0105 PNX0105 646 661pnx0105 MACH_PNX0105 PNX0105 646
662adcpoecpu MACH_ADCPOECPU ADCPOECPU 647 662adcpoecpu MACH_ADCPOECPU ADCPOECPU 647
663csb637 MACH_CSB637 CSB637 648 663csb637 MACH_CSB637 CSB637 648
664ml69q6203 MACH_ML69Q6203 ML69Q6203 649
665mb9200 MACH_MB9200 MB9200 650 664mb9200 MACH_MB9200 MB9200 650
666kulun MACH_KULUN KULUN 651 665kulun MACH_KULUN KULUN 651
667snapper MACH_SNAPPER SNAPPER 652 666snapper MACH_SNAPPER SNAPPER 652
@@ -953,7 +952,6 @@ fred_jack MACH_FRED_JACK FRED_JACK 939
953ttg_color1 MACH_TTG_COLOR1 TTG_COLOR1 940 952ttg_color1 MACH_TTG_COLOR1 TTG_COLOR1 940
954nxeb500hmi MACH_NXEB500HMI NXEB500HMI 941 953nxeb500hmi MACH_NXEB500HMI NXEB500HMI 941
955netdcu8 MACH_NETDCU8 NETDCU8 942 954netdcu8 MACH_NETDCU8 NETDCU8 942
956ml675050_cpu_boa MACH_ML675050_CPU_BOA ML675050_CPU_BOA 943
957ng_fvx538 MACH_NG_FVX538 NG_FVX538 944 955ng_fvx538 MACH_NG_FVX538 NG_FVX538 944
958ng_fvs338 MACH_NG_FVS338 NG_FVS338 945 956ng_fvs338 MACH_NG_FVS338 NG_FVS338 945
959pnx4103 MACH_PNX4103 PNX4103 946 957pnx4103 MACH_PNX4103 PNX4103 946
@@ -1148,7 +1146,7 @@ aidx270 MACH_AIDX270 AIDX270 1134
1148rema MACH_REMA REMA 1135 1146rema MACH_REMA REMA 1135
1149bps1000 MACH_BPS1000 BPS1000 1136 1147bps1000 MACH_BPS1000 BPS1000 1136
1150hw90350 MACH_HW90350 HW90350 1137 1148hw90350 MACH_HW90350 HW90350 1137
1151omap_sdp3430 MACH_OMAP_SDP3430 OMAP_SDP3430 1138 1149omap_3430sdp MACH_OMAP_3430SDP OMAP_3430SDP 1138
1152bluetouch MACH_BLUETOUCH BLUETOUCH 1139 1150bluetouch MACH_BLUETOUCH BLUETOUCH 1139
1153vstms MACH_VSTMS VSTMS 1140 1151vstms MACH_VSTMS VSTMS 1140
1154xsbase270 MACH_XSBASE270 XSBASE270 1141 1152xsbase270 MACH_XSBASE270 XSBASE270 1141
@@ -1214,7 +1212,7 @@ osstbox MACH_OSSTBOX OSSTBOX 1203
1214kbat9261 MACH_KBAT9261 KBAT9261 1204 1212kbat9261 MACH_KBAT9261 KBAT9261 1204
1215ct1100 MACH_CT1100 CT1100 1205 1213ct1100 MACH_CT1100 CT1100 1205
1216akcppxa MACH_AKCPPXA AKCPPXA 1206 1214akcppxa MACH_AKCPPXA AKCPPXA 1206
1217zevio_1020 MACH_ZEVIO_1020 ZEVIO_1020 1207 1215ochaya1020 MACH_OCHAYA1020 OCHAYA1020 1207
1218hitrack MACH_HITRACK HITRACK 1208 1216hitrack MACH_HITRACK HITRACK 1208
1219syme1 MACH_SYME1 SYME1 1209 1217syme1 MACH_SYME1 SYME1 1209
1220syhl1 MACH_SYHL1 SYHL1 1210 1218syhl1 MACH_SYHL1 SYHL1 1210
@@ -1299,7 +1297,7 @@ xp179 MACH_XP179 XP179 1290
1299h4300 MACH_H4300 H4300 1291 1297h4300 MACH_H4300 H4300 1291
1300goramo_mlr MACH_GORAMO_MLR GORAMO_MLR 1292 1298goramo_mlr MACH_GORAMO_MLR GORAMO_MLR 1292
1301mxc30020evb MACH_MXC30020EVB MXC30020EVB 1293 1299mxc30020evb MACH_MXC30020EVB MXC30020EVB 1293
1302adsbitsymx MACH_ADSBITSIMX ADSBITSIMX 1294 1300adsbitsyg5 MACH_ADSBITSYG5 ADSBITSYG5 1294
1303adsportalplus MACH_ADSPORTALPLUS ADSPORTALPLUS 1295 1301adsportalplus MACH_ADSPORTALPLUS ADSPORTALPLUS 1295
1304mmsp2plus MACH_MMSP2PLUS MMSP2PLUS 1296 1302mmsp2plus MACH_MMSP2PLUS MMSP2PLUS 1296
1305em_x270 MACH_EM_X270 EM_X270 1297 1303em_x270 MACH_EM_X270 EM_X270 1297
@@ -1367,3 +1365,249 @@ db88f5281 MACH_DB88F5281 DB88F5281 1358
1367csb726 MACH_CSB726 CSB726 1359 1365csb726 MACH_CSB726 CSB726 1359
1368tik27 MACH_TIK27 TIK27 1360 1366tik27 MACH_TIK27 TIK27 1360
1369mx_uc7420 MACH_MX_UC7420 MX_UC7420 1361 1367mx_uc7420 MACH_MX_UC7420 MX_UC7420 1361
1368rirm3 MACH_RIRM3 RIRM3 1362
1369pelco_odyssey MACH_PELCO_ODYSSEY PELCO_ODYSSEY 1363
1370adx_abox MACH_ADX_ABOX ADX_ABOX 1365
1371adx_tpid MACH_ADX_TPID ADX_TPID 1366
1372minicheck MACH_MINICHECK MINICHECK 1367
1373idam MACH_IDAM IDAM 1368
1374mario_mx MACH_MARIO_MX MARIO_MX 1369
1375vi1888 MACH_VI1888 VI1888 1370
1376zr4230 MACH_ZR4230 ZR4230 1371
1377t1_ix_blue MACH_T1_IX_BLUE T1_IX_BLUE 1372
1378syhq2 MACH_SYHQ2 SYHQ2 1373
1379computime_r3 MACH_COMPUTIME_R3 COMPUTIME_R3 1374
1380oratis MACH_ORATIS ORATIS 1375
1381mikko MACH_MIKKO MIKKO 1376
1382holon MACH_HOLON HOLON 1377
1383olip8 MACH_OLIP8 OLIP8 1378
1384ghi270hg MACH_GHI270HG GHI270HG 1379
1385davinci_dm6467_evm MACH_DAVINCI_DM6467_EVM DAVINCI_DM6467_EVM 1380
1386davinci_dm355_evm MACH_DAVINCI_DM350_EVM DAVINCI_DM350_EVM 1381
1387blackriver MACH_BLACKRIVER BLACKRIVER 1383
1388sandgate_wp MACH_SANDGATEWP SANDGATEWP 1384
1389cdotbwsg MACH_CDOTBWSG CDOTBWSG 1385
1390quark963 MACH_QUARK963 QUARK963 1386
1391csb735 MACH_CSB735 CSB735 1387
1392littleton MACH_LITTLETON LITTLETON 1388
1393mio_p550 MACH_MIO_P550 MIO_P550 1389
1394motion2440 MACH_MOTION2440 MOTION2440 1390
1395imm500 MACH_IMM500 IMM500 1391
1396homematic MACH_HOMEMATIC HOMEMATIC 1392
1397ermine MACH_ERMINE ERMINE 1393
1398kb9202b MACH_KB9202B KB9202B 1394
1399hs1xx MACH_HS1XX HS1XX 1395
1400studentmate2440 MACH_STUDENTMATE2440 STUDENTMATE2440 1396
1401arvoo_l1_z1 MACH_ARVOO_L1_Z1 ARVOO_L1_Z1 1397
1402dep2410k MACH_DEP2410K DEP2410K 1398
1403xxsvideo MACH_XXSVIDEO XXSVIDEO 1399
1404im4004 MACH_IM4004 IM4004 1400
1405ochaya1050 MACH_OCHAYA1050 OCHAYA1050 1401
1406lep9261 MACH_LEP9261 LEP9261 1402
1407svenmeb MACH_SVENMEB SVENMEB 1403
1408fortunet2ne MACH_FORTUNET2NE FORTUNET2NE 1404
1409nxhx MACH_NXHX NXHX 1406
1410realview_pb11mp MACH_REALVIEW_PB11MP REALVIEW_PB11MP 1407
1411ids500 MACH_IDS500 IDS500 1408
1412ors_n725 MACH_ORS_N725 ORS_N725 1409
1413hsdarm MACH_HSDARM HSDARM 1410
1414sha_pon003 MACH_SHA_PON003 SHA_PON003 1411
1415sha_pon004 MACH_SHA_PON004 SHA_PON004 1412
1416sha_pon007 MACH_SHA_PON007 SHA_PON007 1413
1417sha_pon011 MACH_SHA_PON011 SHA_PON011 1414
1418h6042 MACH_H6042 H6042 1415
1419h6043 MACH_H6043 H6043 1416
1420looxc550 MACH_LOOXC550 LOOXC550 1417
1421cnty_titan MACH_CNTY_TITAN CNTY_TITAN 1418
1422app3xx MACH_APP3XX APP3XX 1419
1423sideoatsgrama MACH_SIDEOATSGRAMA SIDEOATSGRAMA 1420
1424xscale_palmt700p MACH_XSCALE_PALMT700P XSCALE_PALMT700P 1421
1425xscale_palmt700w MACH_XSCALE_PALMT700W XSCALE_PALMT700W 1422
1426xscale_palmt750 MACH_XSCALE_PALMT750 XSCALE_PALMT750 1423
1427xscale_palmt755p MACH_XSCALE_PALMT755P XSCALE_PALMT755P 1424
1428ezreganut9200 MACH_EZREGANUT9200 EZREGANUT9200 1425
1429sarge MACH_SARGE SARGE 1426
1430a696 MACH_A696 A696 1427
1431turtle1916 MACH_TURTLE TURTLE 1428
1432mx27_3ds MACH_MX27_3DS MX27_3DS 1430
1433bishop MACH_BISHOP BISHOP 1431
1434pxx MACH_PXX PXX 1432
1435redwood MACH_REDWOOD REDWOOD 1433
1436omap_2430dlp MACH_OMAP_2430DLP OMAP_2430DLP 1436
1437omap_2430osk MACH_OMAP_2430OSK OMAP_2430OSK 1437
1438sardine MACH_SARDINE SARDINE 1438
1439halibut MACH_HALIBUT HALIBUT 1439
1440trout MACH_TROUT TROUT 1440
1441goldfish MACH_GOLDFISH GOLDFISH 1441
1442gesbc2440 MACH_GESBC2440 GESBC2440 1442
1443nomad MACH_NOMAD NOMAD 1443
1444rosalind MACH_ROSALIND ROSALIND 1444
1445cc9p9215 MACH_CC9P9215 CC9P9215 1445
1446cc9p9210 MACH_CC9P9210 CC9P9210 1446
1447cc9p9215js MACH_CC9P9215JS CC9P9215JS 1447
1448cc9p9210js MACH_CC9P9210JS CC9P9210JS 1448
1449nasffe MACH_NASFFE NASFFE 1449
1450tn2x0bd MACH_TN2X0BD TN2X0BD 1450
1451gwmpxa MACH_GWMPXA GWMPXA 1451
1452exyplus MACH_EXYPLUS EXYPLUS 1452
1453jadoo21 MACH_JADOO21 JADOO21 1453
1454looxn560 MACH_LOOXN560 LOOXN560 1454
1455bonsai MACH_BONSAI BONSAI 1455
1456adsmilgato MACH_ADSMILGATO ADSMILGATO 1456
1457gba MACH_GBA GBA 1457
1458h6044 MACH_H6044 H6044 1458
1459app MACH_APP APP 1459
1460tct_hammer MACH_TCT_HAMMER TCT_HAMMER 1460
1461herald MACH_HERMES HERMES 1461
1462artemis MACH_ARTEMIS ARTEMIS 1462
1463htctitan MACH_HTCTITAN HTCTITAN 1463
1464qranium MACH_QRANIUM QRANIUM 1464
1465adx_wsc2 MACH_ADX_WSC2 ADX_WSC2 1465
1466adx_medinet MACH_ADX_MEDINET ADX_MEDINET 1466
1467bboard MACH_BBOARD BBOARD 1467
1468cambria MACH_CAMBRIA CAMBRIA 1468
1469mt7xxx MACH_MT7XXX MT7XXX 1469
1470matrix512 MACH_MATRIX512 MATRIX512 1470
1471matrix522 MACH_MATRIX522 MATRIX522 1471
1472ipac5010 MACH_IPAC5010 IPAC5010 1472
1473sakura MACH_SAKURA SAKURA 1473
1474grocx MACH_GROCX GROCX 1474
1475pm9263 MACH_PM9263 PM9263 1475
1476sim_one MACH_SIM_ONE SIM_ONE 1476
1477acq132 MACH_ACQ132 ACQ132 1477
1478datr MACH_DATR DATR 1478
1479actux1 MACH_ACTUX1 ACTUX1 1479
1480actux2 MACH_ACTUX2 ACTUX2 1480
1481actux3 MACH_ACTUX3 ACTUX3 1481
1482flexit MACH_FLEXIT FLEXIT 1482
1483bh2x0bd MACH_BH2X0BD BH2X0BD 1483
1484atb2002 MACH_ATB2002 ATB2002 1484
1485xenon MACH_XENON XENON 1485
1486fm607 MACH_FM607 FM607 1486
1487matrix514 MACH_MATRIX514 MATRIX514 1487
1488matrix524 MACH_MATRIX524 MATRIX524 1488
1489inpod MACH_INPOD INPOD 1489
1490jive MACH_JIVE JIVE 1490
1491tll_mx21 MACH_TLL_MX21 TLL_MX21 1491
1492sbc2800 MACH_SBC2800 SBC2800 1492
1493cc7ucamry MACH_CC7UCAMRY CC7UCAMRY 1493
1494ubisys_p9_sc15 MACH_UBISYS_P9_SC15 UBISYS_P9_SC15 1494
1495ubisys_p9_ssc2d10 MACH_UBISYS_P9_SSC2D10 UBISYS_P9_SSC2D10 1495
1496ubisys_p9_rcu3 MACH_UBISYS_P9_RCU3 UBISYS_P9_RCU3 1496
1497aml_m8000 MACH_AML_M8000 AML_M8000 1497
1498snapper_270 MACH_SNAPPER_270 SNAPPER_270 1498
1499omap_bbx MACH_OMAP_BBX OMAP_BBX 1499
1500ucn2410 MACH_UCN2410 UCN2410 1500
1501sam9_l9260 MACH_SAM9_L9260 SAM9_L9260 1501
1502eti_c2 MACH_ETI_C2 ETI_C2 1502
1503avalanche MACH_AVALANCHE AVALANCHE 1503
1504realview_pb1176 MACH_REALVIEW_PB1176 REALVIEW_PB1176 1504
1505dp1500 MACH_DP1500 DP1500 1505
1506apple_iphone MACH_APPLE_IPHONE APPLE_IPHONE 1506
1507yl9200 MACH_YL9200 YL9200 1507
1508rd88f5182 MACH_RD88F5182 RD88F5182 1508
1509kurobox_pro MACH_KUROBOX_PRO KUROBOX_PRO 1509
1510se_poet MACH_SE_POET SE_POET 1510
1511mx31_3ds MACH_MX31_3DS MX31_3DS 1511
1512r270 MACH_R270 R270 1512
1513armour21 MACH_ARMOUR21 ARMOUR21 1513
1514dt2 MACH_DT2 DT2 1514
1515vt4 MACH_VT4 VT4 1515
1516tyco320 MACH_TYCO320 TYCO320 1516
1517adma MACH_ADMA ADMA 1517
1518wp188 MACH_WP188 WP188 1518
1519corsica MACH_CORSICA CORSICA 1519
1520bigeye MACH_BIGEYE BIGEYE 1520
1521tll5000 MACH_TLL5000 TLL5000 1522
1522hni270 MACH_HNI_X270 HNI_X270 1523
1523qong MACH_QONG QONG 1524
1524tcompact MACH_TCOMPACT TCOMPACT 1525
1525puma5 MACH_PUMA5 PUMA5 1526
1526elara MACH_ELARA ELARA 1527
1527ellington MACH_ELLINGTON ELLINGTON 1528
1528xda_atom MACH_XDA_ATOM XDA_ATOM 1529
1529energizer2 MACH_ENERGIZER2 ENERGIZER2 1530
1530odin MACH_ODIN ODIN 1531
1531actux4 MACH_ACTUX4 ACTUX4 1532
1532esl_omap MACH_ESL_OMAP ESL_OMAP 1533
1533omap2evm MACH_OMAP2EVM OMAP2EVM 1534
1534omap3evm MACH_OMAP3EVM OMAP3EVM 1535
1535adx_pcu57 MACH_ADX_PCU57 ADX_PCU57 1536
1536monaco MACH_MONACO MONACO 1537
1537levante MACH_LEVANTE LEVANTE 1538
1538tmxipx425 MACH_TMXIPX425 TMXIPX425 1539
1539leep MACH_LEEP LEEP 1540
1540raad MACH_RAAD RAAD 1541
1541dns323 MACH_DNS323 DNS323 1542
1542ap1000 MACH_AP1000 AP1000 1543
1543a9sam6432 MACH_A9SAM6432 A9SAM6432 1544
1544shiny MACH_SHINY SHINY 1545
1545omap3_beagle MACH_OMAP3_BEAGLE OMAP3_BEAGLE 1546
1546csr_bdb2 MACH_CSR_BDB2 CSR_BDB2 1547
1547nokia_n810 MACH_NOKIA_N810 NOKIA_N810 1548
1548c270 MACH_C270 C270 1549
1549sentry MACH_SENTRY SENTRY 1550
1550pcm038 MACH_PCM038 PCM038 1551
1551anc300 MACH_ANC300 ANC300 1552
1552htckaiser MACH_HTCKAISER HTCKAISER 1553
1553sbat100 MACH_SBAT100 SBAT100 1554
1554modunorm MACH_MODUNORM MODUNORM 1555
1555pelos_twarm MACH_PELOS_TWARM PELOS_TWARM 1556
1556flank MACH_FLANK FLANK 1557
1557sirloin MACH_SIRLOIN SIRLOIN 1558
1558brisket MACH_BRISKET BRISKET 1559
1559chuck MACH_CHUCK CHUCK 1560
1560otter MACH_OTTER OTTER 1561
1561davinci_ldk MACH_DAVINCI_LDK DAVINCI_LDK 1562
1562phreedom MACH_PHREEDOM PHREEDOM 1563
1563sg310 MACH_SG310 SG310 1564
1564ts_x09 MACH_TS209 TS209 1565
1565at91cap9adk MACH_AT91CAP9ADK AT91CAP9ADK 1566
1566tion9315 MACH_TION9315 TION9315 1567
1567mast MACH_MAST MAST 1568
1568pfw MACH_PFW PFW 1569
1569yl_p2440 MACH_YL_P2440 YL_P2440 1570
1570zsbc32 MACH_ZSBC32 ZSBC32 1571
1571omap_pace2 MACH_OMAP_PACE2 OMAP_PACE2 1572
1572imx_pace2 MACH_IMX_PACE2 IMX_PACE2 1573
1573mx31moboard MACH_MX31MOBOARD MX31MOBOARD 1574
1574mx37_3ds MACH_MX37_3DS MX37_3DS 1575
1575rcc MACH_RCC RCC 1576
1576dmp MACH_ARM9 ARM9 1577
1577vision_ep9307 MACH_VISION_EP9307 VISION_EP9307 1578
1578scly1000 MACH_SCLY1000 SCLY1000 1579
1579fontel_ep MACH_FONTEL_EP FONTEL_EP 1580
1580voiceblue3g MACH_VOICEBLUE3G VOICEBLUE3G 1581
1581tt9200 MACH_TT9200 TT9200 1582
1582digi2410 MACH_DIGI2410 DIGI2410 1583
1583terastation_pro2 MACH_TERASTATION_PRO2 TERASTATION_PRO2 1584
1584linkstation_pro MACH_LINKSTATION_PRO LINKSTATION_PRO 1585
1585motorola_a780 MACH_MOTOROLA_A780 MOTOROLA_A780 1587
1586motorola_e6 MACH_MOTOROLA_E6 MOTOROLA_E6 1588
1587motorola_e2 MACH_MOTOROLA_E2 MOTOROLA_E2 1589
1588motorola_e680 MACH_MOTOROLA_E680 MOTOROLA_E680 1590
1589ur2410 MACH_UR2410 UR2410 1591
1590tas9261 MACH_TAS9261 TAS9261 1592
1591davinci_hermes_hd MACH_HERMES_HD HERMES_HD 1593
1592davinci_perseo_hd MACH_PERSEO_HD PERSEO_HD 1594
1593stargazer2 MACH_STARGAZER2 STARGAZER2 1595
1594e350 MACH_E350 E350 1596
1595wpcm450 MACH_WPCM450 WPCM450 1597
1596cartesio MACH_CARTESIO CARTESIO 1598
1597toybox MACH_TOYBOX TOYBOX 1599
1598tx27 MACH_TX27 TX27 1600
1599ts409 MACH_TS409 TS409 1601
1600p300 MACH_P300 P300 1602
1601xdacomet MACH_XDACOMET XDACOMET 1603
1602dexflex2 MACH_DEXFLEX2 DEXFLEX2 1604
1603ow MACH_OW OW 1605
1604armebs3 MACH_ARMEBS3 ARMEBS3 1606
1605u3 MACH_U3 U3 1607
1606smdk2450 MACH_SMDK2450 SMDK2450 1608
1607rsi_ews MACH_RSI_EWS RSI_EWS 1609
1608tnb MACH_TNB TNB 1610
1609toepath MACH_TOEPATH TOEPATH 1611
1610kb9263 MACH_KB9263 KB9263 1612
1611mt7108 MACH_MT7108 MT7108 1613
1612smtr2440 MACH_SMTR2440 SMTR2440 1614
1613manao MACH_MANAO MANAO 1615
diff --git a/arch/arm/vfp/vfp.h b/arch/arm/vfp/vfp.h
index 791d0238c68f..c85860bad585 100644
--- a/arch/arm/vfp/vfp.h
+++ b/arch/arm/vfp/vfp.h
@@ -265,7 +265,11 @@ struct vfp_double {
265 * which returns (double)0.0. This is useful for the compare with 265 * which returns (double)0.0. This is useful for the compare with
266 * zero instructions. 266 * zero instructions.
267 */ 267 */
268#ifdef CONFIG_VFPv3
269#define VFP_REG_ZERO 32
270#else
268#define VFP_REG_ZERO 16 271#define VFP_REG_ZERO 16
272#endif
269extern u64 vfp_get_double(unsigned int reg); 273extern u64 vfp_get_double(unsigned int reg);
270extern void vfp_put_double(u64 val, unsigned int reg); 274extern void vfp_put_double(u64 val, unsigned int reg);
271 275
diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S
index 0ac022f800a1..353f9e5c7919 100644
--- a/arch/arm/vfp/vfphw.S
+++ b/arch/arm/vfp/vfphw.S
@@ -99,12 +99,12 @@ vfp_support_entry:
99 DBGSTR1 "save old state %p", r4 99 DBGSTR1 "save old state %p", r4
100 cmp r4, #0 100 cmp r4, #0
101 beq no_old_VFP_process 101 beq no_old_VFP_process
102 VFPFSTMIA r4, r5 @ save the working registers
102 VFPFMRX r5, FPSCR @ current status 103 VFPFMRX r5, FPSCR @ current status
103 VFPFMRX r6, FPINST @ FPINST (always there, rev0 onwards) 104 tst r1, #FPEXC_EX @ is there additional state to save?
104 tst r1, #FPEXC_FPV2 @ is there an FPINST2 to read? 105 VFPFMRX r6, FPINST, NE @ FPINST (only if FPEXC.EX is set)
105 VFPFMRX r8, FPINST2, NE @ FPINST2 if needed - avoids reading 106 tstne r1, #FPEXC_FP2V @ is there an FPINST2 to read?
106 @ nonexistant reg on rev0 107 VFPFMRX r8, FPINST2, NE @ FPINST2 if needed (and present)
107 VFPFSTMIA r4 @ save the working registers
108 stmia r4, {r1, r5, r6, r8} @ save FPEXC, FPSCR, FPINST, FPINST2 108 stmia r4, {r1, r5, r6, r8} @ save FPEXC, FPSCR, FPINST, FPINST2
109 @ and point r4 at the word at the 109 @ and point r4 at the word at the
110 @ start of the register dump 110 @ start of the register dump
@@ -114,13 +114,13 @@ no_old_VFP_process:
114 DBGSTR1 "load state %p", r10 114 DBGSTR1 "load state %p", r10
115 str r10, [r3, r11, lsl #2] @ update the last_VFP_context pointer 115 str r10, [r3, r11, lsl #2] @ update the last_VFP_context pointer
116 @ Load the saved state back into the VFP 116 @ Load the saved state back into the VFP
117 VFPFLDMIA r10 @ reload the working registers while 117 VFPFLDMIA r10, r5 @ reload the working registers while
118 @ FPEXC is in a safe state 118 @ FPEXC is in a safe state
119 ldmia r10, {r1, r5, r6, r8} @ load FPEXC, FPSCR, FPINST, FPINST2 119 ldmia r10, {r1, r5, r6, r8} @ load FPEXC, FPSCR, FPINST, FPINST2
120 tst r1, #FPEXC_FPV2 @ is there an FPINST2 to write? 120 tst r1, #FPEXC_EX @ is there additional state to restore?
121 VFPFMXR FPINST2, r8, NE @ FPINST2 if needed - avoids writing 121 VFPFMXR FPINST, r6, NE @ restore FPINST (only if FPEXC.EX is set)
122 @ nonexistant reg on rev0 122 tstne r1, #FPEXC_FP2V @ is there an FPINST2 to write?
123 VFPFMXR FPINST, r6 123 VFPFMXR FPINST2, r8, NE @ FPINST2 if needed (and present)
124 VFPFMXR FPSCR, r5 @ restore status 124 VFPFMXR FPSCR, r5 @ restore status
125 125
126check_for_exception: 126check_for_exception:
@@ -136,10 +136,14 @@ check_for_exception:
136 136
137 137
138look_for_VFP_exceptions: 138look_for_VFP_exceptions:
139 tst r1, #FPEXC_EX 139 @ Check for synchronous or asynchronous exception
140 tst r1, #FPEXC_EX | FPEXC_DEX
140 bne process_exception 141 bne process_exception
142 @ On some implementations of the VFP subarch 1, setting FPSCR.IXE
143 @ causes all the CDP instructions to be bounced synchronously without
144 @ setting the FPEXC.EX bit
141 VFPFMRX r5, FPSCR 145 VFPFMRX r5, FPSCR
142 tst r5, #FPSCR_IXE @ IXE doesn't set FPEXC_EX ! 146 tst r5, #FPSCR_IXE
143 bne process_exception 147 bne process_exception
144 148
145 @ Fall into hand on to next handler - appropriate coproc instr 149 @ Fall into hand on to next handler - appropriate coproc instr
@@ -150,10 +154,6 @@ look_for_VFP_exceptions:
150 154
151process_exception: 155process_exception:
152 DBGSTR "bounce" 156 DBGSTR "bounce"
153 sub r2, r2, #4
154 str r2, [sp, #S_PC] @ retry the instruction on exit from
155 @ the imprecise exception handling in
156 @ the support code
157 mov r2, sp @ nothing stacked - regdump is at TOS 157 mov r2, sp @ nothing stacked - regdump is at TOS
158 mov lr, r9 @ setup for a return to the user code. 158 mov lr, r9 @ setup for a return to the user code.
159 159
@@ -161,7 +161,7 @@ process_exception:
161 @ r0 holds the trigger instruction 161 @ r0 holds the trigger instruction
162 @ r1 holds the FPEXC value 162 @ r1 holds the FPEXC value
163 @ r2 pointer to register dump 163 @ r2 pointer to register dump
164 b VFP9_bounce @ we have handled this - the support 164 b VFP_bounce @ we have handled this - the support
165 @ code will raise an exception if 165 @ code will raise an exception if
166 @ required. If not, the user code will 166 @ required. If not, the user code will
167 @ retry the faulted instruction 167 @ retry the faulted instruction
@@ -174,12 +174,12 @@ vfp_save_state:
174 @ r0 - save location 174 @ r0 - save location
175 @ r1 - FPEXC 175 @ r1 - FPEXC
176 DBGSTR1 "save VFP state %p", r0 176 DBGSTR1 "save VFP state %p", r0
177 VFPFSTMIA r0, r2 @ save the working registers
177 VFPFMRX r2, FPSCR @ current status 178 VFPFMRX r2, FPSCR @ current status
178 VFPFMRX r3, FPINST @ FPINST (always there, rev0 onwards) 179 tst r1, #FPEXC_EX @ is there additional state to save?
179 tst r1, #FPEXC_FPV2 @ is there an FPINST2 to read? 180 VFPFMRX r3, FPINST, NE @ FPINST (only if FPEXC.EX is set)
180 VFPFMRX r12, FPINST2, NE @ FPINST2 if needed - avoids reading 181 tstne r1, #FPEXC_FP2V @ is there an FPINST2 to read?
181 @ nonexistant reg on rev0 182 VFPFMRX r12, FPINST2, NE @ FPINST2 if needed (and present)
182 VFPFSTMIA r0 @ save the working registers
183 stmia r0, {r1, r2, r3, r12} @ save FPEXC, FPSCR, FPINST, FPINST2 183 stmia r0, {r1, r2, r3, r12} @ save FPEXC, FPSCR, FPINST, FPINST2
184 mov pc, lr 184 mov pc, lr
185#endif 185#endif
@@ -217,8 +217,15 @@ vfp_get_double:
217 fmrrd r0, r1, d\dr 217 fmrrd r0, r1, d\dr
218 mov pc, lr 218 mov pc, lr
219 .endr 219 .endr
220#ifdef CONFIG_VFPv3
221 @ d16 - d31 registers
222 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
223 mrrc p11, 3, r0, r1, c\dr @ fmrrd r0, r1, d\dr
224 mov pc, lr
225 .endr
226#endif
220 227
221 @ virtual register 16 for compare with zero 228 @ virtual register 16 (or 32 if VFPv3) for compare with zero
222 mov r0, #0 229 mov r0, #0
223 mov r1, #0 230 mov r1, #0
224 mov pc, lr 231 mov pc, lr
@@ -231,3 +238,10 @@ vfp_put_double:
231 fmdrr d\dr, r0, r1 238 fmdrr d\dr, r0, r1
232 mov pc, lr 239 mov pc, lr
233 .endr 240 .endr
241#ifdef CONFIG_VFPv3
242 @ d16 - d31 registers
243 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
244 mcrr p11, 3, r1, r2, c\dr @ fmdrr r1, r2, d\dr
245 mov pc, lr
246 .endr
247#endif
diff --git a/arch/arm/vfp/vfpinstr.h b/arch/arm/vfp/vfpinstr.h
index 7f343a4beca0..15b95b5ab97e 100644
--- a/arch/arm/vfp/vfpinstr.h
+++ b/arch/arm/vfp/vfpinstr.h
@@ -52,11 +52,11 @@
52#define FEXT_TO_IDX(inst) ((inst & 0x000f0000) >> 15 | (inst & (1 << 7)) >> 7) 52#define FEXT_TO_IDX(inst) ((inst & 0x000f0000) >> 15 | (inst & (1 << 7)) >> 7)
53 53
54#define vfp_get_sd(inst) ((inst & 0x0000f000) >> 11 | (inst & (1 << 22)) >> 22) 54#define vfp_get_sd(inst) ((inst & 0x0000f000) >> 11 | (inst & (1 << 22)) >> 22)
55#define vfp_get_dd(inst) ((inst & 0x0000f000) >> 12) 55#define vfp_get_dd(inst) ((inst & 0x0000f000) >> 12 | (inst & (1 << 22)) >> 18)
56#define vfp_get_sm(inst) ((inst & 0x0000000f) << 1 | (inst & (1 << 5)) >> 5) 56#define vfp_get_sm(inst) ((inst & 0x0000000f) << 1 | (inst & (1 << 5)) >> 5)
57#define vfp_get_dm(inst) ((inst & 0x0000000f)) 57#define vfp_get_dm(inst) ((inst & 0x0000000f) | (inst & (1 << 5)) >> 1)
58#define vfp_get_sn(inst) ((inst & 0x000f0000) >> 15 | (inst & (1 << 7)) >> 7) 58#define vfp_get_sn(inst) ((inst & 0x000f0000) >> 15 | (inst & (1 << 7)) >> 7)
59#define vfp_get_dn(inst) ((inst & 0x000f0000) >> 16) 59#define vfp_get_dn(inst) ((inst & 0x000f0000) >> 16 | (inst & (1 << 7)) >> 3)
60 60
61#define vfp_single(inst) (((inst) & 0x0000f00) == 0xa00) 61#define vfp_single(inst) (((inst) & 0x0000f00) == 0xa00)
62 62
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index b4e210df92f2..32455c633f1c 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -125,13 +125,13 @@ void vfp_raise_sigfpe(unsigned int sicode, struct pt_regs *regs)
125 send_sig_info(SIGFPE, &info, current); 125 send_sig_info(SIGFPE, &info, current);
126} 126}
127 127
128static void vfp_panic(char *reason) 128static void vfp_panic(char *reason, u32 inst)
129{ 129{
130 int i; 130 int i;
131 131
132 printk(KERN_ERR "VFP: Error: %s\n", reason); 132 printk(KERN_ERR "VFP: Error: %s\n", reason);
133 printk(KERN_ERR "VFP: EXC 0x%08x SCR 0x%08x INST 0x%08x\n", 133 printk(KERN_ERR "VFP: EXC 0x%08x SCR 0x%08x INST 0x%08x\n",
134 fmrx(FPEXC), fmrx(FPSCR), fmrx(FPINST)); 134 fmrx(FPEXC), fmrx(FPSCR), inst);
135 for (i = 0; i < 32; i += 2) 135 for (i = 0; i < 32; i += 2)
136 printk(KERN_ERR "VFP: s%2u: 0x%08x s%2u: 0x%08x\n", 136 printk(KERN_ERR "VFP: s%2u: 0x%08x s%2u: 0x%08x\n",
137 i, vfp_get_float(i), i+1, vfp_get_float(i+1)); 137 i, vfp_get_float(i), i+1, vfp_get_float(i+1));
@@ -147,19 +147,16 @@ static void vfp_raise_exceptions(u32 exceptions, u32 inst, u32 fpscr, struct pt_
147 pr_debug("VFP: raising exceptions %08x\n", exceptions); 147 pr_debug("VFP: raising exceptions %08x\n", exceptions);
148 148
149 if (exceptions == VFP_EXCEPTION_ERROR) { 149 if (exceptions == VFP_EXCEPTION_ERROR) {
150 vfp_panic("unhandled bounce"); 150 vfp_panic("unhandled bounce", inst);
151 vfp_raise_sigfpe(0, regs); 151 vfp_raise_sigfpe(0, regs);
152 return; 152 return;
153 } 153 }
154 154
155 /* 155 /*
156 * If any of the status flags are set, update the FPSCR. 156 * Update the FPSCR with the additional exception flags.
157 * Comparison instructions always return at least one of 157 * Comparison instructions always return at least one of
158 * these flags set. 158 * these flags set.
159 */ 159 */
160 if (exceptions & (FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V))
161 fpscr &= ~(FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V);
162
163 fpscr |= exceptions; 160 fpscr |= exceptions;
164 161
165 fmxr(FPSCR, fpscr); 162 fmxr(FPSCR, fpscr);
@@ -220,35 +217,64 @@ static u32 vfp_emulate_instruction(u32 inst, u32 fpscr, struct pt_regs *regs)
220/* 217/*
221 * Package up a bounce condition. 218 * Package up a bounce condition.
222 */ 219 */
223void VFP9_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) 220void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
224{ 221{
225 u32 fpscr, orig_fpscr, exceptions, inst; 222 u32 fpscr, orig_fpscr, fpsid, exceptions;
226 223
227 pr_debug("VFP: bounce: trigger %08x fpexc %08x\n", trigger, fpexc); 224 pr_debug("VFP: bounce: trigger %08x fpexc %08x\n", trigger, fpexc);
228 225
229 /* 226 /*
230 * Enable access to the VFP so we can handle the bounce. 227 * At this point, FPEXC can have the following configuration:
228 *
229 * EX DEX IXE
230 * 0 1 x - synchronous exception
231 * 1 x 0 - asynchronous exception
232 * 1 x 1 - sychronous on VFP subarch 1 and asynchronous on later
233 * 0 0 1 - synchronous on VFP9 (non-standard subarch 1
234 * implementation), undefined otherwise
235 *
236 * Clear various bits and enable access to the VFP so we can
237 * handle the bounce.
231 */ 238 */
232 fmxr(FPEXC, fpexc & ~(FPEXC_EX|FPEXC_FPV2|FPEXC_INV|FPEXC_UFC|FPEXC_OFC|FPEXC_IOC)); 239 fmxr(FPEXC, fpexc & ~(FPEXC_EX|FPEXC_DEX|FPEXC_FP2V|FPEXC_VV|FPEXC_TRAP_MASK));
233 240
241 fpsid = fmrx(FPSID);
234 orig_fpscr = fpscr = fmrx(FPSCR); 242 orig_fpscr = fpscr = fmrx(FPSCR);
235 243
236 /* 244 /*
237 * If we are running with inexact exceptions enabled, we need to 245 * Check for the special VFP subarch 1 and FPSCR.IXE bit case
238 * emulate the trigger instruction. Note that as we're emulating
239 * the trigger instruction, we need to increment PC.
240 */ 246 */
241 if (fpscr & FPSCR_IXE) { 247 if ((fpsid & FPSID_ARCH_MASK) == (1 << FPSID_ARCH_BIT)
242 regs->ARM_pc += 4; 248 && (fpscr & FPSCR_IXE)) {
249 /*
250 * Synchronous exception, emulate the trigger instruction
251 */
243 goto emulate; 252 goto emulate;
244 } 253 }
245 254
246 barrier(); 255 if (fpexc & FPEXC_EX) {
256 /*
257 * Asynchronous exception. The instruction is read from FPINST
258 * and the interrupted instruction has to be restarted.
259 */
260 trigger = fmrx(FPINST);
261 regs->ARM_pc -= 4;
262 } else if (!(fpexc & FPEXC_DEX)) {
263 /*
264 * Illegal combination of bits. It can be caused by an
265 * unallocated VFP instruction but with FPSCR.IXE set and not
266 * on VFP subarch 1.
267 */
268 vfp_raise_exceptions(VFP_EXCEPTION_ERROR, trigger, fpscr, regs);
269 return;
270 }
247 271
248 /* 272 /*
249 * Modify fpscr to indicate the number of iterations remaining 273 * Modify fpscr to indicate the number of iterations remaining.
274 * If FPEXC.EX is 0, FPEXC.DEX is 1 and the FPEXC.VV bit indicates
275 * whether FPEXC.VECITR or FPSCR.LEN is used.
250 */ 276 */
251 if (fpexc & FPEXC_EX) { 277 if (fpexc & (FPEXC_EX | FPEXC_VV)) {
252 u32 len; 278 u32 len;
253 279
254 len = fpexc + (1 << FPEXC_LENGTH_BIT); 280 len = fpexc + (1 << FPEXC_LENGTH_BIT);
@@ -262,15 +288,15 @@ void VFP9_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
262 * FPEXC bounce reason, but this appears to be unreliable. 288 * FPEXC bounce reason, but this appears to be unreliable.
263 * Emulate the bounced instruction instead. 289 * Emulate the bounced instruction instead.
264 */ 290 */
265 inst = fmrx(FPINST); 291 exceptions = vfp_emulate_instruction(trigger, fpscr, regs);
266 exceptions = vfp_emulate_instruction(inst, fpscr, regs);
267 if (exceptions) 292 if (exceptions)
268 vfp_raise_exceptions(exceptions, inst, orig_fpscr, regs); 293 vfp_raise_exceptions(exceptions, trigger, orig_fpscr, regs);
269 294
270 /* 295 /*
271 * If there isn't a second FP instruction, exit now. 296 * If there isn't a second FP instruction, exit now. Note that
297 * the FPEXC.FP2V bit is valid only if FPEXC.EX is 1.
272 */ 298 */
273 if (!(fpexc & FPEXC_FPV2)) 299 if (fpexc ^ (FPEXC_EX | FPEXC_FP2V))
274 return; 300 return;
275 301
276 /* 302 /*
@@ -279,10 +305,9 @@ void VFP9_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
279 */ 305 */
280 barrier(); 306 barrier();
281 trigger = fmrx(FPINST2); 307 trigger = fmrx(FPINST2);
282 orig_fpscr = fpscr = fmrx(FPSCR);
283 308
284 emulate: 309 emulate:
285 exceptions = vfp_emulate_instruction(trigger, fpscr, regs); 310 exceptions = vfp_emulate_instruction(trigger, orig_fpscr, regs);
286 if (exceptions) 311 if (exceptions)
287 vfp_raise_exceptions(exceptions, trigger, orig_fpscr, regs); 312 vfp_raise_exceptions(exceptions, trigger, orig_fpscr, regs);
288} 313}
@@ -306,16 +331,9 @@ static int __init vfp_init(void)
306{ 331{
307 unsigned int vfpsid; 332 unsigned int vfpsid;
308 unsigned int cpu_arch = cpu_architecture(); 333 unsigned int cpu_arch = cpu_architecture();
309 u32 access = 0;
310 334
311 if (cpu_arch >= CPU_ARCH_ARMv6) { 335 if (cpu_arch >= CPU_ARCH_ARMv6)
312 access = get_copro_access(); 336 vfp_enable(NULL);
313
314 /*
315 * Enable full access to VFP (cp10 and cp11)
316 */
317 set_copro_access(access | CPACC_FULL(10) | CPACC_FULL(11));
318 }
319 337
320 /* 338 /*
321 * First check that there is a VFP that we can use. 339 * First check that there is a VFP that we can use.
@@ -329,15 +347,9 @@ static int __init vfp_init(void)
329 vfp_vector = vfp_null_entry; 347 vfp_vector = vfp_null_entry;
330 348
331 printk(KERN_INFO "VFP support v0.3: "); 349 printk(KERN_INFO "VFP support v0.3: ");
332 if (VFP_arch) { 350 if (VFP_arch)
333 printk("not present\n"); 351 printk("not present\n");
334 352 else if (vfpsid & FPSID_NODOUBLE) {
335 /*
336 * Restore the copro access register.
337 */
338 if (cpu_arch >= CPU_ARCH_ARMv6)
339 set_copro_access(access);
340 } else if (vfpsid & FPSID_NODOUBLE) {
341 printk("no double precision support\n"); 353 printk("no double precision support\n");
342 } else { 354 } else {
343 smp_call_function(vfp_enable, NULL, 1, 1); 355 smp_call_function(vfp_enable, NULL, 1, 1);
diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig
index b77abce10c7a..e34e2c9c94cb 100644
--- a/arch/avr32/Kconfig
+++ b/arch/avr32/Kconfig
@@ -54,6 +54,9 @@ config ARCH_HAS_ILOG2_U32
54config ARCH_HAS_ILOG2_U64 54config ARCH_HAS_ILOG2_U64
55 def_bool n 55 def_bool n
56 56
57config ARCH_SUPPORTS_OPROFILE
58 def_bool y
59
57config GENERIC_HWEIGHT 60config GENERIC_HWEIGHT
58 def_bool y 61 def_bool y
59 62
@@ -81,19 +84,23 @@ config PLATFORM_AT32AP
81 select MMU 84 select MMU
82 select PERFORMANCE_COUNTERS 85 select PERFORMANCE_COUNTERS
83 86
84choice 87#
85 prompt "AVR32 CPU type" 88# CPU types
86 default CPU_AT32AP7000 89#
87 90
88config CPU_AT32AP7000 91# AP7000 derivatives
89 bool "AT32AP7000" 92config CPU_AT32AP700X
93 bool
90 select PLATFORM_AT32AP 94 select PLATFORM_AT32AP
91endchoice 95config CPU_AT32AP7000
92 96 bool
93# 97 select CPU_AT32AP700X
94# CPU Daughterboards for ATSTK1000 98config CPU_AT32AP7001
95config BOARD_ATSTK1002 99 bool
100 select CPU_AT32AP700X
101config CPU_AT32AP7002
96 bool 102 bool
103 select CPU_AT32AP700X
97 104
98choice 105choice
99 prompt "AVR32 board type" 106 prompt "AVR32 board type"
@@ -101,10 +108,10 @@ choice
101 108
102config BOARD_ATSTK1000 109config BOARD_ATSTK1000
103 bool "ATSTK1000 evaluation board" 110 bool "ATSTK1000 evaluation board"
104 select BOARD_ATSTK1002 if CPU_AT32AP7000
105 111
106config BOARD_ATNGW100 112config BOARD_ATNGW100
107 bool "ATNGW100 Network Gateway" 113 bool "ATNGW100 Network Gateway"
114 select CPU_AT32AP7000
108endchoice 115endchoice
109 116
110if BOARD_ATSTK1000 117if BOARD_ATSTK1000
@@ -123,15 +130,15 @@ source "arch/avr32/mach-at32ap/Kconfig"
123 130
124config LOAD_ADDRESS 131config LOAD_ADDRESS
125 hex 132 hex
126 default 0x10000000 if LOADER_U_BOOT=y && CPU_AT32AP7000=y 133 default 0x10000000 if LOADER_U_BOOT=y && CPU_AT32AP700X=y
127 134
128config ENTRY_ADDRESS 135config ENTRY_ADDRESS
129 hex 136 hex
130 default 0x90000000 if LOADER_U_BOOT=y && CPU_AT32AP7000=y 137 default 0x90000000 if LOADER_U_BOOT=y && CPU_AT32AP700X=y
131 138
132config PHYS_OFFSET 139config PHYS_OFFSET
133 hex 140 hex
134 default 0x10000000 if CPU_AT32AP7000=y 141 default 0x10000000 if CPU_AT32AP700X=y
135 142
136source "kernel/Kconfig.preempt" 143source "kernel/Kconfig.preempt"
137 144
@@ -163,6 +170,16 @@ config OWNERSHIP_TRACE
163 enabling Nexus-compliant debuggers to keep track of the PID of the 170 enabling Nexus-compliant debuggers to keep track of the PID of the
164 currently executing task. 171 currently executing task.
165 172
173config NMI_DEBUGGING
174 bool "NMI Debugging"
175 default n
176 help
177 Say Y here and pass the nmi_debug command-line parameter to
178 the kernel to turn on NMI debugging. Depending on the value
179 of the nmi_debug option, various pieces of information will
180 be dumped to the console when a Non-Maskable Interrupt
181 happens.
182
166# FPU emulation goes here 183# FPU emulation goes here
167 184
168source "kernel/Kconfig.hz" 185source "kernel/Kconfig.hz"
@@ -219,6 +236,8 @@ source "drivers/Kconfig"
219 236
220source "fs/Kconfig" 237source "fs/Kconfig"
221 238
239source "kernel/Kconfig.instrumentation"
240
222source "arch/avr32/Kconfig.debug" 241source "arch/avr32/Kconfig.debug"
223 242
224source "security/Kconfig" 243source "security/Kconfig"
diff --git a/arch/avr32/Kconfig.debug b/arch/avr32/Kconfig.debug
index 64ace00fe6cb..2283933a9a93 100644
--- a/arch/avr32/Kconfig.debug
+++ b/arch/avr32/Kconfig.debug
@@ -6,14 +6,4 @@ config TRACE_IRQFLAGS_SUPPORT
6 6
7source "lib/Kconfig.debug" 7source "lib/Kconfig.debug"
8 8
9config KPROBES
10 bool "Kprobes"
11 depends on DEBUG_KERNEL
12 help
13 Kprobes allows you to trap at almost any kernel address and
14 execute a callback function. register_kprobe() establishes
15 a probepoint and specifies the callback. Kprobes is useful
16 for kernel debugging, non-intrusive instrumentation and testing.
17 If in doubt, say "N".
18
19endmenu 9endmenu
diff --git a/arch/avr32/Makefile b/arch/avr32/Makefile
index 87918647be6d..17a3529341dd 100644
--- a/arch/avr32/Makefile
+++ b/arch/avr32/Makefile
@@ -16,7 +16,7 @@ KBUILD_AFLAGS += -mrelax -mno-pic
16CFLAGS_MODULE += -mno-relax 16CFLAGS_MODULE += -mno-relax
17LDFLAGS_vmlinux += --relax 17LDFLAGS_vmlinux += --relax
18 18
19cpuflags-$(CONFIG_CPU_AT32AP7000) += -mcpu=ap7000 19cpuflags-$(CONFIG_PLATFORM_AT32AP) += -march=ap
20 20
21KBUILD_CFLAGS += $(cpuflags-y) 21KBUILD_CFLAGS += $(cpuflags-y)
22KBUILD_AFLAGS += $(cpuflags-y) 22KBUILD_AFLAGS += $(cpuflags-y)
@@ -31,6 +31,7 @@ core-$(CONFIG_BOARD_ATNGW100) += arch/avr32/boards/atngw100/
31core-$(CONFIG_LOADER_U_BOOT) += arch/avr32/boot/u-boot/ 31core-$(CONFIG_LOADER_U_BOOT) += arch/avr32/boot/u-boot/
32core-y += arch/avr32/kernel/ 32core-y += arch/avr32/kernel/
33core-y += arch/avr32/mm/ 33core-y += arch/avr32/mm/
34drivers-$(CONFIG_OPROFILE) += arch/avr32/oprofile/
34libs-y += arch/avr32/lib/ 35libs-y += arch/avr32/lib/
35 36
36archincdir-$(CONFIG_PLATFORM_AT32AP) := arch-at32ap 37archincdir-$(CONFIG_PLATFORM_AT32AP) := arch-at32ap
diff --git a/arch/avr32/boards/atngw100/setup.c b/arch/avr32/boards/atngw100/setup.c
index 52987c81d668..a398be284966 100644
--- a/arch/avr32/boards/atngw100/setup.c
+++ b/arch/avr32/boards/atngw100/setup.c
@@ -20,7 +20,7 @@
20#include <asm/io.h> 20#include <asm/io.h>
21#include <asm/setup.h> 21#include <asm/setup.h>
22 22
23#include <asm/arch/at32ap7000.h> 23#include <asm/arch/at32ap700x.h>
24#include <asm/arch/board.h> 24#include <asm/arch/board.h>
25#include <asm/arch/init.h> 25#include <asm/arch/init.h>
26#include <asm/arch/portmux.h> 26#include <asm/arch/portmux.h>
diff --git a/arch/avr32/boards/atstk1000/Kconfig b/arch/avr32/boards/atstk1000/Kconfig
index 718578f64069..af90b00100fd 100644
--- a/arch/avr32/boards/atstk1000/Kconfig
+++ b/arch/avr32/boards/atstk1000/Kconfig
@@ -1,34 +1,53 @@
1# STK1000 customization 1# STK1000 customization
2 2
3if BOARD_ATSTK1002 3if BOARD_ATSTK1000
4 4
5config BOARD_ATSTK1002_CUSTOM 5choice
6 bool "Non-default STK-1002 jumper settings" 6 prompt "ATSTK1000 CPU daughterboard type"
7 default BOARD_ATSTK1002
8
9config BOARD_ATSTK1002
10 bool "ATSTK1002"
11 select CPU_AT32AP7000
12
13config BOARD_ATSTK1003
14 bool "ATSTK1003"
15 select CPU_AT32AP7001
16
17config BOARD_ATSTK1004
18 bool "ATSTK1004"
19 select CPU_AT32AP7002
20
21endchoice
22
23
24config BOARD_ATSTK100X_CUSTOM
25 bool "Non-default STK1002/STK1003/STK1004 jumper settings"
7 help 26 help
8 You will normally leave the jumpers on the CPU card at their 27 You will normally leave the jumpers on the CPU card at their
9 default settings. If you need to use certain peripherals, 28 default settings. If you need to use certain peripherals,
10 you will need to change some of those jumpers. 29 you will need to change some of those jumpers.
11 30
12if BOARD_ATSTK1002_CUSTOM 31if BOARD_ATSTK100X_CUSTOM
13 32
14config BOARD_ATSTK1002_SW1_CUSTOM 33config BOARD_ATSTK100X_SW1_CUSTOM
15 bool "SW1: use SSC1 (not SPI0)" 34 bool "SW1: use SSC1 (not SPI0)"
16 help 35 help
17 This also prevents using the external DAC as an audio interface, 36 This also prevents using the external DAC as an audio interface,
18 and means you can't initialize the on-board QVGA display. 37 and means you can't initialize the on-board QVGA display.
19 38
20config BOARD_ATSTK1002_SW2_CUSTOM 39config BOARD_ATSTK100X_SW2_CUSTOM
21 bool "SW2: use IRDA or TIMER0 (not UART-A, MMC/SD, and PS2-A)" 40 bool "SW2: use IRDA or TIMER0 (not UART-A, MMC/SD, and PS2-A)"
22 help 41 help
23 If you change this you'll want an updated boot loader putting 42 If you change this you'll want an updated boot loader putting
24 the console on UART-C not UART-A. 43 the console on UART-C not UART-A.
25 44
26config BOARD_ATSTK1002_SW3_CUSTOM 45config BOARD_ATSTK100X_SW3_CUSTOM
27 bool "SW3: use TIMER1 (not SSC0 and GCLK)" 46 bool "SW3: use TIMER1 (not SSC0 and GCLK)"
28 help 47 help
29 This also prevents using the external DAC as an audio interface. 48 This also prevents using the external DAC as an audio interface.
30 49
31config BOARD_ATSTK1002_SW4_CUSTOM 50config BOARD_ATSTK100X_SW4_CUSTOM
32 bool "SW4: use ISI/Camera (not GPIOs, SPI1, and PS2-B)" 51 bool "SW4: use ISI/Camera (not GPIOs, SPI1, and PS2-B)"
33 help 52 help
34 To use the camera interface you'll need a custom card (on the 53 To use the camera interface you'll need a custom card (on the
@@ -36,27 +55,29 @@ config BOARD_ATSTK1002_SW4_CUSTOM
36 55
37config BOARD_ATSTK1002_SW5_CUSTOM 56config BOARD_ATSTK1002_SW5_CUSTOM
38 bool "SW5: use MACB1 (not LCDC)" 57 bool "SW5: use MACB1 (not LCDC)"
58 depends on BOARD_ATSTK1002
39 59
40config BOARD_ATSTK1002_SW6_CUSTOM 60config BOARD_ATSTK1002_SW6_CUSTOM
41 bool "SW6: more GPIOs (not MACB0)" 61 bool "SW6: more GPIOs (not MACB0)"
62 depends on BOARD_ATSTK1002
42 63
43endif # custom 64endif # custom
44 65
45config BOARD_ATSTK1002_SPI1 66config BOARD_ATSTK100X_SPI1
46 bool "Configure SPI1 controller" 67 bool "Configure SPI1 controller"
47 depends on !BOARD_ATSTK1002_SW4_CUSTOM 68 depends on !BOARD_ATSTK100X_SW4_CUSTOM
48 help 69 help
49 All the signals for the second SPI controller are available on 70 All the signals for the second SPI controller are available on
50 GPIO lines and accessed through the J1 jumper block. Say "y" 71 GPIO lines and accessed through the J1 jumper block. Say "y"
51 here to configure that SPI controller. 72 here to configure that SPI controller.
52 73
53config BOARD_ATSTK1002_J2_LED 74config BOARD_ATSTK1000_J2_LED
54 bool 75 bool
55 default BOARD_ATSTK1002_J2_LED8 || BOARD_ATSTK1002_J2_RGB 76 default BOARD_ATSTK1000_J2_LED8 || BOARD_ATSTK1000_J2_RGB
56 77
57choice 78choice
58 prompt "LEDs connected to J2:" 79 prompt "LEDs connected to J2:"
59 depends on LEDS_GPIO && !BOARD_ATSTK1002_SW4_CUSTOM 80 depends on LEDS_GPIO && !BOARD_ATSTK100X_SW4_CUSTOM
60 optional 81 optional
61 help 82 help
62 Select this if you have jumpered the J2 jumper block to the 83 Select this if you have jumpered the J2 jumper block to the
@@ -64,16 +85,21 @@ choice
64 IDC cable. A default "heartbeat" trigger is provided, but 85 IDC cable. A default "heartbeat" trigger is provided, but
65 you can of course override this. 86 you can of course override this.
66 87
67config BOARD_ATSTK1002_J2_LED8 88config BOARD_ATSTK1000_J2_LED8
68 bool "LED0..LED7" 89 bool "LED0..LED7"
69 help 90 help
70 Select this if J2 is jumpered to LED0..LED7 amber leds. 91 Select this if J2 is jumpered to LED0..LED7 amber leds.
71 92
72config BOARD_ATSTK1002_J2_RGB 93config BOARD_ATSTK1000_J2_RGB
73 bool "RGB leds" 94 bool "RGB leds"
74 help 95 help
75 Select this if J2 is jumpered to the RGB leds. 96 Select this if J2 is jumpered to the RGB leds.
76 97
77endchoice 98endchoice
78 99
79endif # stk 1002 100config BOARD_ATSTK1000_EXTDAC
101 bool
102 depends on !BOARD_ATSTK100X_SW1_CUSTOM && !BOARD_ATSTK100X_SW3_CUSTOM
103 default y
104
105endif # stk 1000
diff --git a/arch/avr32/boards/atstk1000/Makefile b/arch/avr32/boards/atstk1000/Makefile
index 8e0992201bb9..beead86462e8 100644
--- a/arch/avr32/boards/atstk1000/Makefile
+++ b/arch/avr32/boards/atstk1000/Makefile
@@ -1,2 +1,4 @@
1obj-y += setup.o flash.o 1obj-y += setup.o flash.o
2obj-$(CONFIG_BOARD_ATSTK1002) += atstk1002.o 2obj-$(CONFIG_BOARD_ATSTK1002) += atstk1002.o
3obj-$(CONFIG_BOARD_ATSTK1003) += atstk1003.o
4obj-$(CONFIG_BOARD_ATSTK1004) += atstk1004.o
diff --git a/arch/avr32/boards/atstk1000/atstk1000.h b/arch/avr32/boards/atstk1000/atstk1000.h
index 9a49ed036b72..9392d3252865 100644
--- a/arch/avr32/boards/atstk1000/atstk1000.h
+++ b/arch/avr32/boards/atstk1000/atstk1000.h
@@ -12,4 +12,6 @@
12 12
13extern struct atmel_lcdfb_info atstk1000_lcdc_data; 13extern struct atmel_lcdfb_info atstk1000_lcdc_data;
14 14
15void atstk1000_setup_j2_leds(void);
16
15#endif /* __ARCH_AVR32_BOARDS_ATSTK1000_ATSTK1000_H */ 17#endif /* __ARCH_AVR32_BOARDS_ATSTK1000_ATSTK1000_H */
diff --git a/arch/avr32/boards/atstk1000/atstk1002.c b/arch/avr32/boards/atstk1000/atstk1002.c
index 5be0d13f4b03..000eb4220a12 100644
--- a/arch/avr32/boards/atstk1000/atstk1002.c
+++ b/arch/avr32/boards/atstk1000/atstk1002.c
@@ -11,7 +11,6 @@
11#include <linux/etherdevice.h> 11#include <linux/etherdevice.h>
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/leds.h>
15#include <linux/platform_device.h> 14#include <linux/platform_device.h>
16#include <linux/string.h> 15#include <linux/string.h>
17#include <linux/types.h> 16#include <linux/types.h>
@@ -22,7 +21,7 @@
22 21
23#include <asm/io.h> 22#include <asm/io.h>
24#include <asm/setup.h> 23#include <asm/setup.h>
25#include <asm/arch/at32ap7000.h> 24#include <asm/arch/at32ap700x.h>
26#include <asm/arch/board.h> 25#include <asm/arch/board.h>
27#include <asm/arch/init.h> 26#include <asm/arch/init.h>
28#include <asm/arch/portmux.h> 27#include <asm/arch/portmux.h>
@@ -49,18 +48,16 @@ static struct eth_platform_data __initdata eth_data[2] = {
49 }, 48 },
50}; 49};
51 50
52#ifndef CONFIG_BOARD_ATSTK1002_SW1_CUSTOM 51#ifdef CONFIG_BOARD_ATSTK1000_EXTDAC
53#ifndef CONFIG_BOARD_ATSTK1002_SW3_CUSTOM
54static struct at73c213_board_info at73c213_data = { 52static struct at73c213_board_info at73c213_data = {
55 .ssc_id = 0, 53 .ssc_id = 0,
56 .shortname = "AVR32 STK1000 external DAC", 54 .shortname = "AVR32 STK1000 external DAC",
57}; 55};
58#endif 56#endif
59#endif
60 57
61#ifndef CONFIG_BOARD_ATSTK1002_SW1_CUSTOM 58#ifndef CONFIG_BOARD_ATSTK100X_SW1_CUSTOM
62static struct spi_board_info spi0_board_info[] __initdata = { 59static struct spi_board_info spi0_board_info[] __initdata = {
63#ifndef CONFIG_BOARD_ATSTK1002_SW3_CUSTOM 60#ifdef CONFIG_BOARD_ATSTK1000_EXTDAC
64 { 61 {
65 /* AT73C213 */ 62 /* AT73C213 */
66 .modalias = "at73c213", 63 .modalias = "at73c213",
@@ -80,7 +77,7 @@ static struct spi_board_info spi0_board_info[] __initdata = {
80}; 77};
81#endif 78#endif
82 79
83#ifdef CONFIG_BOARD_ATSTK1002_SPI1 80#ifdef CONFIG_BOARD_ATSTK100X_SPI1
84static struct spi_board_info spi1_board_info[] __initdata = { { 81static struct spi_board_info spi1_board_info[] __initdata = { {
85 /* patch in custom entries here */ 82 /* patch in custom entries here */
86} }; 83} };
@@ -141,68 +138,8 @@ static void __init set_hw_addr(struct platform_device *pdev)
141 clk_put(pclk); 138 clk_put(pclk);
142} 139}
143 140
144#ifdef CONFIG_BOARD_ATSTK1002_J2_LED 141#ifdef CONFIG_BOARD_ATSTK1000_EXTDAC
145 142static void __init atstk1002_setup_extdac(void)
146static struct gpio_led stk_j2_led[] = {
147#ifdef CONFIG_BOARD_ATSTK1002_J2_LED8
148#define LEDSTRING "J2 jumpered to LED8"
149 { .name = "led0:amber", .gpio = GPIO_PIN_PB( 8), },
150 { .name = "led1:amber", .gpio = GPIO_PIN_PB( 9), },
151 { .name = "led2:amber", .gpio = GPIO_PIN_PB(10), },
152 { .name = "led3:amber", .gpio = GPIO_PIN_PB(13), },
153 { .name = "led4:amber", .gpio = GPIO_PIN_PB(14), },
154 { .name = "led5:amber", .gpio = GPIO_PIN_PB(15), },
155 { .name = "led6:amber", .gpio = GPIO_PIN_PB(16), },
156 { .name = "led7:amber", .gpio = GPIO_PIN_PB(30),
157 .default_trigger = "heartbeat", },
158#else /* RGB */
159#define LEDSTRING "J2 jumpered to RGB LEDs"
160 { .name = "r1:red", .gpio = GPIO_PIN_PB( 8), },
161 { .name = "g1:green", .gpio = GPIO_PIN_PB(10), },
162 { .name = "b1:blue", .gpio = GPIO_PIN_PB(14), },
163
164 { .name = "r2:red", .gpio = GPIO_PIN_PB( 9),
165 .default_trigger = "heartbeat", },
166 { .name = "g2:green", .gpio = GPIO_PIN_PB(13), },
167 { .name = "b2:blue", .gpio = GPIO_PIN_PB(15),
168 .default_trigger = "heartbeat", },
169 /* PB16, PB30 unused */
170#endif
171};
172
173static struct gpio_led_platform_data stk_j2_led_data = {
174 .num_leds = ARRAY_SIZE(stk_j2_led),
175 .leds = stk_j2_led,
176};
177
178static struct platform_device stk_j2_led_dev = {
179 .name = "leds-gpio",
180 .id = 2, /* gpio block J2 */
181 .dev = {
182 .platform_data = &stk_j2_led_data,
183 },
184};
185
186static void setup_j2_leds(void)
187{
188 unsigned i;
189
190 for (i = 0; i < ARRAY_SIZE(stk_j2_led); i++)
191 at32_select_gpio(stk_j2_led[i].gpio, AT32_GPIOF_OUTPUT);
192
193 printk("STK1002: " LEDSTRING "\n");
194 platform_device_register(&stk_j2_led_dev);
195}
196
197#else
198static void setup_j2_leds(void)
199{
200}
201#endif
202
203#ifndef CONFIG_BOARD_ATSTK1002_SW1_CUSTOM
204#ifndef CONFIG_BOARD_ATSTK1002_SW3_CUSTOM
205static void __init at73c213_set_clk(struct at73c213_board_info *info)
206{ 143{
207 struct clk *gclk; 144 struct clk *gclk;
208 struct clk *pll; 145 struct clk *pll;
@@ -220,7 +157,7 @@ static void __init at73c213_set_clk(struct at73c213_board_info *info)
220 } 157 }
221 158
222 at32_select_periph(GPIO_PIN_PA(30), GPIO_PERIPH_A, 0); 159 at32_select_periph(GPIO_PIN_PA(30), GPIO_PERIPH_A, 0);
223 info->dac_clk = gclk; 160 at73c213_data.dac_clk = gclk;
224 161
225err_set_clk: 162err_set_clk:
226 clk_put(pll); 163 clk_put(pll);
@@ -229,12 +166,16 @@ err_pll:
229err_gclk: 166err_gclk:
230 return; 167 return;
231} 168}
232#endif 169#else
233#endif 170static void __init atstk1002_setup_extdac(void)
171{
172
173}
174#endif /* CONFIG_BOARD_ATSTK1000_EXTDAC */
234 175
235void __init setup_board(void) 176void __init setup_board(void)
236{ 177{
237#ifdef CONFIG_BOARD_ATSTK1002_SW2_CUSTOM 178#ifdef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
238 at32_map_usart(0, 1); /* USART 0/B: /dev/ttyS1, IRDA */ 179 at32_map_usart(0, 1); /* USART 0/B: /dev/ttyS1, IRDA */
239#else 180#else
240 at32_map_usart(1, 0); /* USART 1/A: /dev/ttyS0, DB9 */ 181 at32_map_usart(1, 0); /* USART 1/A: /dev/ttyS0, DB9 */
@@ -271,7 +212,7 @@ static int __init atstk1002_init(void)
271 212
272 at32_add_system_devices(); 213 at32_add_system_devices();
273 214
274#ifdef CONFIG_BOARD_ATSTK1002_SW2_CUSTOM 215#ifdef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
275 at32_add_device_usart(1); 216 at32_add_device_usart(1);
276#else 217#else
277 at32_add_device_usart(0); 218 at32_add_device_usart(0);
@@ -281,10 +222,10 @@ static int __init atstk1002_init(void)
281#ifndef CONFIG_BOARD_ATSTK1002_SW6_CUSTOM 222#ifndef CONFIG_BOARD_ATSTK1002_SW6_CUSTOM
282 set_hw_addr(at32_add_device_eth(0, &eth_data[0])); 223 set_hw_addr(at32_add_device_eth(0, &eth_data[0]));
283#endif 224#endif
284#ifndef CONFIG_BOARD_ATSTK1002_SW1_CUSTOM 225#ifndef CONFIG_BOARD_ATSTK100X_SW1_CUSTOM
285 at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info)); 226 at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info));
286#endif 227#endif
287#ifdef CONFIG_BOARD_ATSTK1002_SPI1 228#ifdef CONFIG_BOARD_ATSTK100X_SPI1
288 at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); 229 at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));
289#endif 230#endif
290#ifdef CONFIG_BOARD_ATSTK1002_SW5_CUSTOM 231#ifdef CONFIG_BOARD_ATSTK1002_SW5_CUSTOM
@@ -294,17 +235,12 @@ static int __init atstk1002_init(void)
294 fbmem_start, fbmem_size); 235 fbmem_start, fbmem_size);
295#endif 236#endif
296 at32_add_device_usba(0, NULL); 237 at32_add_device_usba(0, NULL);
297#ifndef CONFIG_BOARD_ATSTK1002_SW3_CUSTOM 238#ifndef CONFIG_BOARD_ATSTK100X_SW3_CUSTOM
298 at32_add_device_ssc(0, ATMEL_SSC_TX); 239 at32_add_device_ssc(0, ATMEL_SSC_TX);
299#endif 240#endif
300 241
301 setup_j2_leds(); 242 atstk1000_setup_j2_leds();
302 243 atstk1002_setup_extdac();
303#ifndef CONFIG_BOARD_ATSTK1002_SW3_CUSTOM
304#ifndef CONFIG_BOARD_ATSTK1002_SW1_CUSTOM
305 at73c213_set_clk(&at73c213_data);
306#endif
307#endif
308 244
309 return 0; 245 return 0;
310} 246}
diff --git a/arch/avr32/boards/atstk1000/atstk1003.c b/arch/avr32/boards/atstk1000/atstk1003.c
new file mode 100644
index 000000000000..a0b223df35a2
--- /dev/null
+++ b/arch/avr32/boards/atstk1000/atstk1003.c
@@ -0,0 +1,162 @@
1/*
2 * ATSTK1003 daughterboard-specific init code
3 *
4 * Copyright (C) 2007 Atmel Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/clk.h>
11#include <linux/err.h>
12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/platform_device.h>
15#include <linux/string.h>
16#include <linux/types.h>
17
18#include <linux/spi/at73c213.h>
19#include <linux/spi/spi.h>
20
21#include <asm/setup.h>
22
23#include <asm/arch/at32ap700x.h>
24#include <asm/arch/board.h>
25#include <asm/arch/init.h>
26#include <asm/arch/portmux.h>
27
28#include "atstk1000.h"
29
30#ifdef CONFIG_BOARD_ATSTK1000_EXTDAC
31static struct at73c213_board_info at73c213_data = {
32 .ssc_id = 0,
33 .shortname = "AVR32 STK1000 external DAC",
34};
35#endif
36
37#ifndef CONFIG_BOARD_ATSTK100X_SW1_CUSTOM
38static struct spi_board_info spi0_board_info[] __initdata = {
39#ifdef CONFIG_BOARD_ATSTK1000_EXTDAC
40 {
41 /* AT73C213 */
42 .modalias = "at73c213",
43 .max_speed_hz = 200000,
44 .chip_select = 0,
45 .mode = SPI_MODE_1,
46 .platform_data = &at73c213_data,
47 },
48#endif
49 /*
50 * We can control the LTV350QV LCD panel, but it isn't much
51 * point since we don't have an LCD controller...
52 */
53};
54#endif
55
56#ifdef CONFIG_BOARD_ATSTK100X_SPI1
57static struct spi_board_info spi1_board_info[] __initdata = { {
58 /* patch in custom entries here */
59} };
60#endif
61
62#ifdef CONFIG_BOARD_ATSTK1000_EXTDAC
63static void __init atstk1003_setup_extdac(void)
64{
65 struct clk *gclk;
66 struct clk *pll;
67
68 gclk = clk_get(NULL, "gclk0");
69 if (IS_ERR(gclk))
70 goto err_gclk;
71 pll = clk_get(NULL, "pll0");
72 if (IS_ERR(pll))
73 goto err_pll;
74
75 if (clk_set_parent(gclk, pll)) {
76 pr_debug("STK1000: failed to set pll0 as parent for DAC clock\n");
77 goto err_set_clk;
78 }
79
80 at32_select_periph(GPIO_PIN_PA(30), GPIO_PERIPH_A, 0);
81 at73c213_data.dac_clk = gclk;
82
83err_set_clk:
84 clk_put(pll);
85err_pll:
86 clk_put(gclk);
87err_gclk:
88 return;
89}
90#else
91static void __init atstk1003_setup_extdac(void)
92{
93
94}
95#endif /* CONFIG_BOARD_ATSTK1000_EXTDAC */
96
97void __init setup_board(void)
98{
99#ifdef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
100 at32_map_usart(0, 1); /* USART 0/B: /dev/ttyS1, IRDA */
101#else
102 at32_map_usart(1, 0); /* USART 1/A: /dev/ttyS0, DB9 */
103#endif
104 /* USART 2/unused: expansion connector */
105 at32_map_usart(3, 2); /* USART 3/C: /dev/ttyS2, DB9 */
106
107 at32_setup_serial_console(0);
108}
109
110static int __init atstk1003_init(void)
111{
112 /*
113 * ATSTK1000 uses 32-bit SDRAM interface. Reserve the
114 * SDRAM-specific pins so that nobody messes with them.
115 */
116 at32_reserve_pin(GPIO_PIN_PE(0)); /* DATA[16] */
117 at32_reserve_pin(GPIO_PIN_PE(1)); /* DATA[17] */
118 at32_reserve_pin(GPIO_PIN_PE(2)); /* DATA[18] */
119 at32_reserve_pin(GPIO_PIN_PE(3)); /* DATA[19] */
120 at32_reserve_pin(GPIO_PIN_PE(4)); /* DATA[20] */
121 at32_reserve_pin(GPIO_PIN_PE(5)); /* DATA[21] */
122 at32_reserve_pin(GPIO_PIN_PE(6)); /* DATA[22] */
123 at32_reserve_pin(GPIO_PIN_PE(7)); /* DATA[23] */
124 at32_reserve_pin(GPIO_PIN_PE(8)); /* DATA[24] */
125 at32_reserve_pin(GPIO_PIN_PE(9)); /* DATA[25] */
126 at32_reserve_pin(GPIO_PIN_PE(10)); /* DATA[26] */
127 at32_reserve_pin(GPIO_PIN_PE(11)); /* DATA[27] */
128 at32_reserve_pin(GPIO_PIN_PE(12)); /* DATA[28] */
129 at32_reserve_pin(GPIO_PIN_PE(13)); /* DATA[29] */
130 at32_reserve_pin(GPIO_PIN_PE(14)); /* DATA[30] */
131 at32_reserve_pin(GPIO_PIN_PE(15)); /* DATA[31] */
132 at32_reserve_pin(GPIO_PIN_PE(26)); /* SDCS */
133
134 at32_add_system_devices();
135
136#ifdef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
137 at32_add_device_usart(1);
138#else
139 at32_add_device_usart(0);
140#endif
141 at32_add_device_usart(2);
142
143#ifndef CONFIG_BOARD_ATSTK100X_SW1_CUSTOM
144 at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info));
145#endif
146#ifdef CONFIG_BOARD_ATSTK100X_SPI1
147 at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));
148#endif
149#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
150 at32_add_device_mci(0);
151#endif
152 at32_add_device_usba(0, NULL);
153#ifndef CONFIG_BOARD_ATSTK100X_SW3_CUSTOM
154 at32_add_device_ssc(0, ATMEL_SSC_TX);
155#endif
156
157 atstk1000_setup_j2_leds();
158 atstk1003_setup_extdac();
159
160 return 0;
161}
162postcore_initcall(atstk1003_init);
diff --git a/arch/avr32/boards/atstk1000/atstk1004.c b/arch/avr32/boards/atstk1000/atstk1004.c
new file mode 100644
index 000000000000..5a77030e07a0
--- /dev/null
+++ b/arch/avr32/boards/atstk1000/atstk1004.c
@@ -0,0 +1,147 @@
1/*
2 * ATSTK1003 daughterboard-specific init code
3 *
4 * Copyright (C) 2007 Atmel Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/clk.h>
11#include <linux/err.h>
12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/platform_device.h>
15#include <linux/string.h>
16#include <linux/types.h>
17
18#include <linux/spi/at73c213.h>
19#include <linux/spi/spi.h>
20
21#include <video/atmel_lcdc.h>
22
23#include <asm/setup.h>
24
25#include <asm/arch/at32ap700x.h>
26#include <asm/arch/board.h>
27#include <asm/arch/init.h>
28#include <asm/arch/portmux.h>
29
30#include "atstk1000.h"
31
32#ifdef CONFIG_BOARD_ATSTK1000_EXTDAC
33static struct at73c213_board_info at73c213_data = {
34 .ssc_id = 0,
35 .shortname = "AVR32 STK1000 external DAC",
36};
37#endif
38
39#ifndef CONFIG_BOARD_ATSTK100X_SW1_CUSTOM
40static struct spi_board_info spi0_board_info[] __initdata = {
41#ifdef CONFIG_BOARD_ATSTK1000_EXTDAC
42 {
43 /* AT73C213 */
44 .modalias = "at73c213",
45 .max_speed_hz = 200000,
46 .chip_select = 0,
47 .mode = SPI_MODE_1,
48 .platform_data = &at73c213_data,
49 },
50#endif
51 {
52 /* QVGA display */
53 .modalias = "ltv350qv",
54 .max_speed_hz = 16000000,
55 .chip_select = 1,
56 .mode = SPI_MODE_3,
57 },
58};
59#endif
60
61#ifdef CONFIG_BOARD_ATSTK100X_SPI1
62static struct spi_board_info spi1_board_info[] __initdata = { {
63 /* patch in custom entries here */
64} };
65#endif
66
67#ifdef CONFIG_BOARD_ATSTK1000_EXTDAC
68static void __init atstk1004_setup_extdac(void)
69{
70 struct clk *gclk;
71 struct clk *pll;
72
73 gclk = clk_get(NULL, "gclk0");
74 if (IS_ERR(gclk))
75 goto err_gclk;
76 pll = clk_get(NULL, "pll0");
77 if (IS_ERR(pll))
78 goto err_pll;
79
80 if (clk_set_parent(gclk, pll)) {
81 pr_debug("STK1000: failed to set pll0 as parent for DAC clock\n");
82 goto err_set_clk;
83 }
84
85 at32_select_periph(GPIO_PIN_PA(30), GPIO_PERIPH_A, 0);
86 at73c213_data.dac_clk = gclk;
87
88err_set_clk:
89 clk_put(pll);
90err_pll:
91 clk_put(gclk);
92err_gclk:
93 return;
94}
95#else
96static void __init atstk1004_setup_extdac(void)
97{
98
99}
100#endif /* CONFIG_BOARD_ATSTK1000_EXTDAC */
101
102void __init setup_board(void)
103{
104#ifdef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
105 at32_map_usart(0, 1); /* USART 0/B: /dev/ttyS1, IRDA */
106#else
107 at32_map_usart(1, 0); /* USART 1/A: /dev/ttyS0, DB9 */
108#endif
109 /* USART 2/unused: expansion connector */
110 at32_map_usart(3, 2); /* USART 3/C: /dev/ttyS2, DB9 */
111
112 at32_setup_serial_console(0);
113}
114
115static int __init atstk1004_init(void)
116{
117 at32_add_system_devices();
118
119#ifdef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
120 at32_add_device_usart(1);
121#else
122 at32_add_device_usart(0);
123#endif
124 at32_add_device_usart(2);
125
126#ifndef CONFIG_BOARD_ATSTK100X_SW1_CUSTOM
127 at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info));
128#endif
129#ifdef CONFIG_BOARD_ATSTK100X_SPI1
130 at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));
131#endif
132#ifndef CONFIG_BOARD_ATSTK1002_SW2_CUSTOM
133 at32_add_device_mci(0);
134#endif
135 at32_add_device_lcdc(0, &atstk1000_lcdc_data,
136 fbmem_start, fbmem_size);
137 at32_add_device_usba(0, NULL);
138#ifndef CONFIG_BOARD_ATSTK100X_SW3_CUSTOM
139 at32_add_device_ssc(0, ATMEL_SSC_TX);
140#endif
141
142 atstk1000_setup_j2_leds();
143 atstk1004_setup_extdac();
144
145 return 0;
146}
147postcore_initcall(atstk1004_init);
diff --git a/arch/avr32/boards/atstk1000/setup.c b/arch/avr32/boards/atstk1000/setup.c
index c9af409ada9a..8bedf93876a3 100644
--- a/arch/avr32/boards/atstk1000/setup.c
+++ b/arch/avr32/boards/atstk1000/setup.c
@@ -10,13 +10,17 @@
10#include <linux/bootmem.h> 10#include <linux/bootmem.h>
11#include <linux/fb.h> 11#include <linux/fb.h>
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/platform_device.h>
13#include <linux/types.h> 14#include <linux/types.h>
14#include <linux/linkage.h> 15#include <linux/linkage.h>
15 16
16#include <video/atmel_lcdc.h> 17#include <video/atmel_lcdc.h>
17 18
18#include <asm/setup.h> 19#include <asm/setup.h>
20
21#include <asm/arch/at32ap700x.h>
19#include <asm/arch/board.h> 22#include <asm/arch/board.h>
23#include <asm/arch/portmux.h>
20 24
21#include "atstk1000.h" 25#include "atstk1000.h"
22 26
@@ -61,3 +65,63 @@ struct atmel_lcdfb_info __initdata atstk1000_lcdc_data = {
61 .default_monspecs = &atstk1000_default_monspecs, 65 .default_monspecs = &atstk1000_default_monspecs,
62 .guard_time = 2, 66 .guard_time = 2,
63}; 67};
68
69#ifdef CONFIG_BOARD_ATSTK1000_J2_LED
70#include <linux/leds.h>
71
72static struct gpio_led stk1000_j2_led[] = {
73#ifdef CONFIG_BOARD_ATSTK1000_J2_LED8
74#define LEDSTRING "J2 jumpered to LED8"
75 { .name = "led0:amber", .gpio = GPIO_PIN_PB( 8), },
76 { .name = "led1:amber", .gpio = GPIO_PIN_PB( 9), },
77 { .name = "led2:amber", .gpio = GPIO_PIN_PB(10), },
78 { .name = "led3:amber", .gpio = GPIO_PIN_PB(13), },
79 { .name = "led4:amber", .gpio = GPIO_PIN_PB(14), },
80 { .name = "led5:amber", .gpio = GPIO_PIN_PB(15), },
81 { .name = "led6:amber", .gpio = GPIO_PIN_PB(16), },
82 { .name = "led7:amber", .gpio = GPIO_PIN_PB(30),
83 .default_trigger = "heartbeat", },
84#else /* RGB */
85#define LEDSTRING "J2 jumpered to RGB LEDs"
86 { .name = "r1:red", .gpio = GPIO_PIN_PB( 8), },
87 { .name = "g1:green", .gpio = GPIO_PIN_PB(10), },
88 { .name = "b1:blue", .gpio = GPIO_PIN_PB(14), },
89
90 { .name = "r2:red", .gpio = GPIO_PIN_PB( 9),
91 .default_trigger = "heartbeat", },
92 { .name = "g2:green", .gpio = GPIO_PIN_PB(13), },
93 { .name = "b2:blue", .gpio = GPIO_PIN_PB(15),
94 .default_trigger = "heartbeat", },
95 /* PB16, PB30 unused */
96#endif
97};
98
99static struct gpio_led_platform_data stk1000_j2_led_data = {
100 .num_leds = ARRAY_SIZE(stk1000_j2_led),
101 .leds = stk1000_j2_led,
102};
103
104static struct platform_device stk1000_j2_led_dev = {
105 .name = "leds-gpio",
106 .id = 2, /* gpio block J2 */
107 .dev = {
108 .platform_data = &stk1000_j2_led_data,
109 },
110};
111
112void __init atstk1000_setup_j2_leds(void)
113{
114 unsigned i;
115
116 for (i = 0; i < ARRAY_SIZE(stk1000_j2_led); i++)
117 at32_select_gpio(stk1000_j2_led[i].gpio, AT32_GPIOF_OUTPUT);
118
119 printk("STK1000: " LEDSTRING "\n");
120 platform_device_register(&stk1000_j2_led_dev);
121}
122#else /* CONFIG_BOARD_ATSTK1000_J2_LED */
123void __init atstk1000_setup_j2_leds(void)
124{
125
126}
127#endif /* CONFIG_BOARD_ATSTK1000_J2_LED */
diff --git a/arch/avr32/configs/atngw100_defconfig b/arch/avr32/configs/atngw100_defconfig
index b799a68ffd97..06046074d68b 100644
--- a/arch/avr32/configs/atngw100_defconfig
+++ b/arch/avr32/configs/atngw100_defconfig
@@ -1,46 +1,51 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.22-rc5 3# Linux kernel version: 2.6.24-rc7
4# Sat Jun 23 15:40:05 2007 4# Wed Jan 9 23:20:41 2008
5# 5#
6CONFIG_AVR32=y 6CONFIG_AVR32=y
7CONFIG_GENERIC_GPIO=y 7CONFIG_GENERIC_GPIO=y
8CONFIG_GENERIC_HARDIRQS=y 8CONFIG_GENERIC_HARDIRQS=y
9CONFIG_STACKTRACE_SUPPORT=y
10CONFIG_LOCKDEP_SUPPORT=y
11CONFIG_TRACE_IRQFLAGS_SUPPORT=y
9CONFIG_HARDIRQS_SW_RESEND=y 12CONFIG_HARDIRQS_SW_RESEND=y
10CONFIG_GENERIC_IRQ_PROBE=y 13CONFIG_GENERIC_IRQ_PROBE=y
11CONFIG_RWSEM_GENERIC_SPINLOCK=y 14CONFIG_RWSEM_GENERIC_SPINLOCK=y
12CONFIG_GENERIC_TIME=y 15CONFIG_GENERIC_TIME=y
16# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
13# CONFIG_ARCH_HAS_ILOG2_U32 is not set 17# CONFIG_ARCH_HAS_ILOG2_U32 is not set
14# CONFIG_ARCH_HAS_ILOG2_U64 is not set 18# CONFIG_ARCH_HAS_ILOG2_U64 is not set
19CONFIG_ARCH_SUPPORTS_OPROFILE=y
15CONFIG_GENERIC_HWEIGHT=y 20CONFIG_GENERIC_HWEIGHT=y
16CONFIG_GENERIC_CALIBRATE_DELAY=y 21CONFIG_GENERIC_CALIBRATE_DELAY=y
17CONFIG_GENERIC_BUG=y 22CONFIG_GENERIC_BUG=y
18CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" 23CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
19 24
20# 25#
21# Code maturity level options 26# General setup
22# 27#
23CONFIG_EXPERIMENTAL=y 28CONFIG_EXPERIMENTAL=y
24CONFIG_BROKEN_ON_SMP=y 29CONFIG_BROKEN_ON_SMP=y
25CONFIG_INIT_ENV_ARG_LIMIT=32 30CONFIG_INIT_ENV_ARG_LIMIT=32
26
27#
28# General setup
29#
30CONFIG_LOCALVERSION="" 31CONFIG_LOCALVERSION=""
31# CONFIG_LOCALVERSION_AUTO is not set 32# CONFIG_LOCALVERSION_AUTO is not set
32CONFIG_SWAP=y 33CONFIG_SWAP=y
33CONFIG_SYSVIPC=y 34CONFIG_SYSVIPC=y
34# CONFIG_IPC_NS is not set
35CONFIG_SYSVIPC_SYSCTL=y 35CONFIG_SYSVIPC_SYSCTL=y
36CONFIG_POSIX_MQUEUE=y 36CONFIG_POSIX_MQUEUE=y
37CONFIG_BSD_PROCESS_ACCT=y 37CONFIG_BSD_PROCESS_ACCT=y
38CONFIG_BSD_PROCESS_ACCT_V3=y 38CONFIG_BSD_PROCESS_ACCT_V3=y
39# CONFIG_TASKSTATS is not set 39# CONFIG_TASKSTATS is not set
40# CONFIG_UTS_NS is not set 40# CONFIG_USER_NS is not set
41# CONFIG_PID_NS is not set
41# CONFIG_AUDIT is not set 42# CONFIG_AUDIT is not set
42# CONFIG_IKCONFIG is not set 43# CONFIG_IKCONFIG is not set
43CONFIG_LOG_BUF_SHIFT=14 44CONFIG_LOG_BUF_SHIFT=14
45# CONFIG_CGROUPS is not set
46CONFIG_FAIR_GROUP_SCHED=y
47CONFIG_FAIR_USER_SCHED=y
48# CONFIG_FAIR_CGROUP_SCHED is not set
44CONFIG_SYSFS_DEPRECATED=y 49CONFIG_SYSFS_DEPRECATED=y
45# CONFIG_RELAY is not set 50# CONFIG_RELAY is not set
46CONFIG_BLK_DEV_INITRD=y 51CONFIG_BLK_DEV_INITRD=y
@@ -61,35 +66,28 @@ CONFIG_FUTEX=y
61CONFIG_ANON_INODES=y 66CONFIG_ANON_INODES=y
62CONFIG_EPOLL=y 67CONFIG_EPOLL=y
63CONFIG_SIGNALFD=y 68CONFIG_SIGNALFD=y
64CONFIG_TIMERFD=y
65CONFIG_EVENTFD=y 69CONFIG_EVENTFD=y
66CONFIG_SHMEM=y 70CONFIG_SHMEM=y
67CONFIG_VM_EVENT_COUNTERS=y 71CONFIG_VM_EVENT_COUNTERS=y
68# CONFIG_SLUB_DEBUG is not set 72CONFIG_SLUB_DEBUG=y
69# CONFIG_SLAB is not set 73# CONFIG_SLAB is not set
70CONFIG_SLUB=y 74CONFIG_SLUB=y
71# CONFIG_SLOB is not set 75# CONFIG_SLOB is not set
76CONFIG_SLABINFO=y
72CONFIG_RT_MUTEXES=y 77CONFIG_RT_MUTEXES=y
73# CONFIG_TINY_SHMEM is not set 78# CONFIG_TINY_SHMEM is not set
74CONFIG_BASE_SMALL=1 79CONFIG_BASE_SMALL=1
75
76#
77# Loadable module support
78#
79CONFIG_MODULES=y 80CONFIG_MODULES=y
80CONFIG_MODULE_UNLOAD=y 81CONFIG_MODULE_UNLOAD=y
81CONFIG_MODULE_FORCE_UNLOAD=y 82CONFIG_MODULE_FORCE_UNLOAD=y
82# CONFIG_MODVERSIONS is not set 83# CONFIG_MODVERSIONS is not set
83# CONFIG_MODULE_SRCVERSION_ALL is not set 84# CONFIG_MODULE_SRCVERSION_ALL is not set
84CONFIG_KMOD=y 85CONFIG_KMOD=y
85
86#
87# Block layer
88#
89CONFIG_BLOCK=y 86CONFIG_BLOCK=y
90# CONFIG_LBD is not set 87# CONFIG_LBD is not set
91# CONFIG_BLK_DEV_IO_TRACE is not set 88# CONFIG_BLK_DEV_IO_TRACE is not set
92# CONFIG_LSF is not set 89# CONFIG_LSF is not set
90# CONFIG_BLK_DEV_BSG is not set
93 91
94# 92#
95# IO Schedulers 93# IO Schedulers
@@ -111,6 +109,7 @@ CONFIG_SUBARCH_AVR32B=y
111CONFIG_MMU=y 109CONFIG_MMU=y
112CONFIG_PERFORMANCE_COUNTERS=y 110CONFIG_PERFORMANCE_COUNTERS=y
113CONFIG_PLATFORM_AT32AP=y 111CONFIG_PLATFORM_AT32AP=y
112CONFIG_CPU_AT32AP700X=y
114CONFIG_CPU_AT32AP7000=y 113CONFIG_CPU_AT32AP7000=y
115# CONFIG_BOARD_ATSTK1000 is not set 114# CONFIG_BOARD_ATSTK1000 is not set
116CONFIG_BOARD_ATNGW100=y 115CONFIG_BOARD_ATNGW100=y
@@ -119,9 +118,9 @@ CONFIG_LOADER_U_BOOT=y
119# 118#
120# Atmel AVR32 AP options 119# Atmel AVR32 AP options
121# 120#
122# CONFIG_AP7000_32_BIT_SMC is not set 121# CONFIG_AP700X_32_BIT_SMC is not set
123CONFIG_AP7000_16_BIT_SMC=y 122CONFIG_AP700X_16_BIT_SMC=y
124# CONFIG_AP7000_8_BIT_SMC is not set 123# CONFIG_AP700X_8_BIT_SMC is not set
125CONFIG_LOAD_ADDRESS=0x10000000 124CONFIG_LOAD_ADDRESS=0x10000000
126CONFIG_ENTRY_ADDRESS=0x90000000 125CONFIG_ENTRY_ADDRESS=0x90000000
127CONFIG_PHYS_OFFSET=0x10000000 126CONFIG_PHYS_OFFSET=0x10000000
@@ -141,9 +140,11 @@ CONFIG_FLATMEM_MANUAL=y
141CONFIG_FLATMEM=y 140CONFIG_FLATMEM=y
142CONFIG_FLAT_NODE_MEM_MAP=y 141CONFIG_FLAT_NODE_MEM_MAP=y
143# CONFIG_SPARSEMEM_STATIC is not set 142# CONFIG_SPARSEMEM_STATIC is not set
143# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
144CONFIG_SPLIT_PTLOCK_CPUS=4 144CONFIG_SPLIT_PTLOCK_CPUS=4
145# CONFIG_RESOURCES_64BIT is not set 145# CONFIG_RESOURCES_64BIT is not set
146CONFIG_ZONE_DMA_FLAG=0 146CONFIG_ZONE_DMA_FLAG=0
147CONFIG_VIRT_TO_BUS=y
147# CONFIG_OWNERSHIP_TRACE is not set 148# CONFIG_OWNERSHIP_TRACE is not set
148# CONFIG_HZ_100 is not set 149# CONFIG_HZ_100 is not set
149CONFIG_HZ_250=y 150CONFIG_HZ_250=y
@@ -153,13 +154,31 @@ CONFIG_HZ=250
153CONFIG_CMDLINE="" 154CONFIG_CMDLINE=""
154 155
155# 156#
156# Bus options 157# Power management options
157# 158#
158# CONFIG_ARCH_SUPPORTS_MSI is not set
159 159
160# 160#
161# PCCARD (PCMCIA/CardBus) support 161# CPU Frequency scaling
162# 162#
163CONFIG_CPU_FREQ=y
164CONFIG_CPU_FREQ_TABLE=y
165# CONFIG_CPU_FREQ_DEBUG is not set
166# CONFIG_CPU_FREQ_STAT is not set
167CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
168# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
169# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
170# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
171CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
172# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
173CONFIG_CPU_FREQ_GOV_USERSPACE=y
174CONFIG_CPU_FREQ_GOV_ONDEMAND=y
175# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
176CONFIG_CPU_FREQ_AT32AP=y
177
178#
179# Bus options
180#
181# CONFIG_ARCH_SUPPORTS_MSI is not set
163# CONFIG_PCCARD is not set 182# CONFIG_PCCARD is not set
164 183
165# 184#
@@ -213,6 +232,7 @@ CONFIG_INET_TUNNEL=y
213CONFIG_INET_XFRM_MODE_TRANSPORT=y 232CONFIG_INET_XFRM_MODE_TRANSPORT=y
214CONFIG_INET_XFRM_MODE_TUNNEL=y 233CONFIG_INET_XFRM_MODE_TUNNEL=y
215CONFIG_INET_XFRM_MODE_BEET=y 234CONFIG_INET_XFRM_MODE_BEET=y
235# CONFIG_INET_LRO is not set
216CONFIG_INET_DIAG=y 236CONFIG_INET_DIAG=y
217CONFIG_INET_TCP_DIAG=y 237CONFIG_INET_TCP_DIAG=y
218# CONFIG_TCP_CONG_ADVANCED is not set 238# CONFIG_TCP_CONG_ADVANCED is not set
@@ -240,6 +260,7 @@ CONFIG_IPV6_SIT=y
240# CONFIG_NETWORK_SECMARK is not set 260# CONFIG_NETWORK_SECMARK is not set
241CONFIG_NETFILTER=y 261CONFIG_NETFILTER=y
242# CONFIG_NETFILTER_DEBUG is not set 262# CONFIG_NETFILTER_DEBUG is not set
263CONFIG_BRIDGE_NETFILTER=y
243 264
244# 265#
245# Core Netfilter Configuration 266# Core Netfilter Configuration
@@ -252,6 +273,7 @@ CONFIG_NF_CONNTRACK_MARK=y
252# CONFIG_NF_CONNTRACK_EVENTS is not set 273# CONFIG_NF_CONNTRACK_EVENTS is not set
253CONFIG_NF_CT_PROTO_GRE=m 274CONFIG_NF_CT_PROTO_GRE=m
254# CONFIG_NF_CT_PROTO_SCTP is not set 275# CONFIG_NF_CT_PROTO_SCTP is not set
276# CONFIG_NF_CT_PROTO_UDPLITE is not set
255CONFIG_NF_CONNTRACK_AMANDA=m 277CONFIG_NF_CONNTRACK_AMANDA=m
256CONFIG_NF_CONNTRACK_FTP=m 278CONFIG_NF_CONNTRACK_FTP=m
257CONFIG_NF_CONNTRACK_H323=m 279CONFIG_NF_CONNTRACK_H323=m
@@ -269,9 +291,11 @@ CONFIG_NETFILTER_XT_TARGET_MARK=m
269CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m 291CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
270CONFIG_NETFILTER_XT_TARGET_NFLOG=m 292CONFIG_NETFILTER_XT_TARGET_NFLOG=m
271# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set 293# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set
294# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
272CONFIG_NETFILTER_XT_TARGET_TCPMSS=m 295CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
273CONFIG_NETFILTER_XT_MATCH_COMMENT=m 296CONFIG_NETFILTER_XT_MATCH_COMMENT=m
274CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m 297CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
298# CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set
275CONFIG_NETFILTER_XT_MATCH_CONNMARK=m 299CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
276CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m 300CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
277# CONFIG_NETFILTER_XT_MATCH_DCCP is not set 301# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
@@ -284,6 +308,7 @@ CONFIG_NETFILTER_XT_MATCH_MAC=m
284CONFIG_NETFILTER_XT_MATCH_MARK=m 308CONFIG_NETFILTER_XT_MATCH_MARK=m
285CONFIG_NETFILTER_XT_MATCH_POLICY=m 309CONFIG_NETFILTER_XT_MATCH_POLICY=m
286CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m 310CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
311# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set
287CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m 312CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
288CONFIG_NETFILTER_XT_MATCH_QUOTA=m 313CONFIG_NETFILTER_XT_MATCH_QUOTA=m
289CONFIG_NETFILTER_XT_MATCH_REALM=m 314CONFIG_NETFILTER_XT_MATCH_REALM=m
@@ -292,6 +317,8 @@ CONFIG_NETFILTER_XT_MATCH_STATE=m
292CONFIG_NETFILTER_XT_MATCH_STATISTIC=m 317CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
293CONFIG_NETFILTER_XT_MATCH_STRING=m 318CONFIG_NETFILTER_XT_MATCH_STRING=m
294CONFIG_NETFILTER_XT_MATCH_TCPMSS=m 319CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
320# CONFIG_NETFILTER_XT_MATCH_TIME is not set
321# CONFIG_NETFILTER_XT_MATCH_U32 is not set
295CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m 322CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
296 323
297# 324#
@@ -359,13 +386,19 @@ CONFIG_IP6_NF_TARGET_REJECT=m
359CONFIG_IP6_NF_MANGLE=m 386CONFIG_IP6_NF_MANGLE=m
360CONFIG_IP6_NF_TARGET_HL=m 387CONFIG_IP6_NF_TARGET_HL=m
361CONFIG_IP6_NF_RAW=m 388CONFIG_IP6_NF_RAW=m
389
390#
391# Bridge: Netfilter Configuration
392#
393# CONFIG_BRIDGE_NF_EBTABLES is not set
362# CONFIG_IP_DCCP is not set 394# CONFIG_IP_DCCP is not set
363# CONFIG_IP_SCTP is not set 395# CONFIG_IP_SCTP is not set
364# CONFIG_TIPC is not set 396# CONFIG_TIPC is not set
365# CONFIG_ATM is not set 397# CONFIG_ATM is not set
366# CONFIG_BRIDGE is not set 398CONFIG_BRIDGE=m
367CONFIG_VLAN_8021Q=m 399CONFIG_VLAN_8021Q=m
368# CONFIG_DECNET is not set 400# CONFIG_DECNET is not set
401CONFIG_LLC=m
369# CONFIG_LLC2 is not set 402# CONFIG_LLC2 is not set
370# CONFIG_IPX is not set 403# CONFIG_IPX is not set
371# CONFIG_ATALK is not set 404# CONFIG_ATALK is not set
@@ -373,10 +406,6 @@ CONFIG_VLAN_8021Q=m
373# CONFIG_LAPB is not set 406# CONFIG_LAPB is not set
374# CONFIG_ECONET is not set 407# CONFIG_ECONET is not set
375# CONFIG_WAN_ROUTER is not set 408# CONFIG_WAN_ROUTER is not set
376
377#
378# QoS and/or fair queueing
379#
380# CONFIG_NET_SCHED is not set 409# CONFIG_NET_SCHED is not set
381CONFIG_NET_CLS_ROUTE=y 410CONFIG_NET_CLS_ROUTE=y
382 411
@@ -384,6 +413,7 @@ CONFIG_NET_CLS_ROUTE=y
384# Network testing 413# Network testing
385# 414#
386# CONFIG_NET_PKTGEN is not set 415# CONFIG_NET_PKTGEN is not set
416# CONFIG_NET_TCPPROBE is not set
387# CONFIG_HAMRADIO is not set 417# CONFIG_HAMRADIO is not set
388# CONFIG_IRDA is not set 418# CONFIG_IRDA is not set
389# CONFIG_BT is not set 419# CONFIG_BT is not set
@@ -397,6 +427,7 @@ CONFIG_NET_CLS_ROUTE=y
397# CONFIG_MAC80211 is not set 427# CONFIG_MAC80211 is not set
398# CONFIG_IEEE80211 is not set 428# CONFIG_IEEE80211 is not set
399# CONFIG_RFKILL is not set 429# CONFIG_RFKILL is not set
430# CONFIG_NET_9P is not set
400 431
401# 432#
402# Device Drivers 433# Device Drivers
@@ -405,16 +436,13 @@ CONFIG_NET_CLS_ROUTE=y
405# 436#
406# Generic Driver Options 437# Generic Driver Options
407# 438#
439CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
408CONFIG_STANDALONE=y 440CONFIG_STANDALONE=y
409# CONFIG_PREVENT_FIRMWARE_BUILD is not set 441# CONFIG_PREVENT_FIRMWARE_BUILD is not set
410# CONFIG_FW_LOADER is not set 442# CONFIG_FW_LOADER is not set
411# CONFIG_DEBUG_DRIVER is not set 443# CONFIG_DEBUG_DRIVER is not set
412# CONFIG_DEBUG_DEVRES is not set 444# CONFIG_DEBUG_DEVRES is not set
413# CONFIG_SYS_HYPERVISOR is not set 445# CONFIG_SYS_HYPERVISOR is not set
414
415#
416# Connector - unified userspace <-> kernelspace linker
417#
418# CONFIG_CONNECTOR is not set 446# CONFIG_CONNECTOR is not set
419CONFIG_MTD=y 447CONFIG_MTD=y
420# CONFIG_MTD_DEBUG is not set 448# CONFIG_MTD_DEBUG is not set
@@ -434,6 +462,7 @@ CONFIG_MTD_BLOCK=y
434# CONFIG_INFTL is not set 462# CONFIG_INFTL is not set
435# CONFIG_RFD_FTL is not set 463# CONFIG_RFD_FTL is not set
436# CONFIG_SSFDC is not set 464# CONFIG_SSFDC is not set
465# CONFIG_MTD_OOPS is not set
437 466
438# 467#
439# RAM/ROM/Flash chip drivers 468# RAM/ROM/Flash chip drivers
@@ -493,20 +522,8 @@ CONFIG_MTD_DATAFLASH=y
493# UBI - Unsorted block images 522# UBI - Unsorted block images
494# 523#
495# CONFIG_MTD_UBI is not set 524# CONFIG_MTD_UBI is not set
496
497#
498# Parallel port support
499#
500# CONFIG_PARPORT is not set 525# CONFIG_PARPORT is not set
501 526CONFIG_BLK_DEV=y
502#
503# Plug and Play support
504#
505# CONFIG_PNPACPI is not set
506
507#
508# Block devices
509#
510# CONFIG_BLK_DEV_COW_COMMON is not set 527# CONFIG_BLK_DEV_COW_COMMON is not set
511CONFIG_BLK_DEV_LOOP=m 528CONFIG_BLK_DEV_LOOP=m
512# CONFIG_BLK_DEV_CRYPTOLOOP is not set 529# CONFIG_BLK_DEV_CRYPTOLOOP is not set
@@ -517,11 +534,7 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
517CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 534CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
518# CONFIG_CDROM_PKTCDVD is not set 535# CONFIG_CDROM_PKTCDVD is not set
519# CONFIG_ATA_OVER_ETH is not set 536# CONFIG_ATA_OVER_ETH is not set
520 537# CONFIG_MISC_DEVICES is not set
521#
522# Misc devices
523#
524# CONFIG_BLINK is not set
525# CONFIG_IDE is not set 538# CONFIG_IDE is not set
526 539
527# 540#
@@ -529,30 +542,42 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
529# 542#
530# CONFIG_RAID_ATTRS is not set 543# CONFIG_RAID_ATTRS is not set
531# CONFIG_SCSI is not set 544# CONFIG_SCSI is not set
545# CONFIG_SCSI_DMA is not set
532# CONFIG_SCSI_NETLINK is not set 546# CONFIG_SCSI_NETLINK is not set
533# CONFIG_ATA is not set 547# CONFIG_ATA is not set
534
535#
536# Multi-device support (RAID and LVM)
537#
538# CONFIG_MD is not set 548# CONFIG_MD is not set
539
540#
541# Network device support
542#
543CONFIG_NETDEVICES=y 549CONFIG_NETDEVICES=y
550# CONFIG_NETDEVICES_MULTIQUEUE is not set
544# CONFIG_DUMMY is not set 551# CONFIG_DUMMY is not set
545# CONFIG_BONDING is not set 552# CONFIG_BONDING is not set
553# CONFIG_MACVLAN is not set
546# CONFIG_EQUALIZER is not set 554# CONFIG_EQUALIZER is not set
547CONFIG_TUN=m 555CONFIG_TUN=m
548# CONFIG_PHYLIB is not set 556# CONFIG_VETH is not set
549 557CONFIG_PHYLIB=y
550# 558
551# Ethernet (10 or 100Mbit) 559#
552# 560# MII PHY device drivers
561#
562# CONFIG_MARVELL_PHY is not set
563# CONFIG_DAVICOM_PHY is not set
564# CONFIG_QSEMI_PHY is not set
565# CONFIG_LXT_PHY is not set
566# CONFIG_CICADA_PHY is not set
567# CONFIG_VITESSE_PHY is not set
568# CONFIG_SMSC_PHY is not set
569# CONFIG_BROADCOM_PHY is not set
570# CONFIG_ICPLUS_PHY is not set
571# CONFIG_FIXED_PHY is not set
572# CONFIG_MDIO_BITBANG is not set
553CONFIG_NET_ETHERNET=y 573CONFIG_NET_ETHERNET=y
554CONFIG_MII=y 574# CONFIG_MII is not set
555CONFIG_MACB=y 575CONFIG_MACB=y
576# CONFIG_IBM_NEW_EMAC_ZMII is not set
577# CONFIG_IBM_NEW_EMAC_RGMII is not set
578# CONFIG_IBM_NEW_EMAC_TAH is not set
579# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
580# CONFIG_B44 is not set
556# CONFIG_NETDEV_1000 is not set 581# CONFIG_NETDEV_1000 is not set
557# CONFIG_NETDEV_10000 is not set 582# CONFIG_NETDEV_10000 is not set
558 583
@@ -571,21 +596,14 @@ CONFIG_PPP_DEFLATE=m
571CONFIG_PPP_BSDCOMP=m 596CONFIG_PPP_BSDCOMP=m
572CONFIG_PPP_MPPE=m 597CONFIG_PPP_MPPE=m
573CONFIG_PPPOE=m 598CONFIG_PPPOE=m
599# CONFIG_PPPOL2TP is not set
574# CONFIG_SLIP is not set 600# CONFIG_SLIP is not set
575CONFIG_SLHC=m 601CONFIG_SLHC=m
576# CONFIG_SHAPER is not set 602# CONFIG_SHAPER is not set
577# CONFIG_NETCONSOLE is not set 603# CONFIG_NETCONSOLE is not set
578# CONFIG_NETPOLL is not set 604# CONFIG_NETPOLL is not set
579# CONFIG_NET_POLL_CONTROLLER is not set 605# CONFIG_NET_POLL_CONTROLLER is not set
580
581#
582# ISDN subsystem
583#
584# CONFIG_ISDN is not set 606# CONFIG_ISDN is not set
585
586#
587# Telephony Support
588#
589# CONFIG_PHONE is not set 607# CONFIG_PHONE is not set
590 608
591# 609#
@@ -620,23 +638,50 @@ CONFIG_SERIAL_CORE=y
620CONFIG_SERIAL_CORE_CONSOLE=y 638CONFIG_SERIAL_CORE_CONSOLE=y
621CONFIG_UNIX98_PTYS=y 639CONFIG_UNIX98_PTYS=y
622# CONFIG_LEGACY_PTYS is not set 640# CONFIG_LEGACY_PTYS is not set
623
624#
625# IPMI
626#
627# CONFIG_IPMI_HANDLER is not set 641# CONFIG_IPMI_HANDLER is not set
628# CONFIG_WATCHDOG is not set
629# CONFIG_HW_RANDOM is not set 642# CONFIG_HW_RANDOM is not set
630# CONFIG_RTC is not set 643# CONFIG_RTC is not set
631# CONFIG_GEN_RTC is not set 644# CONFIG_GEN_RTC is not set
632# CONFIG_R3964 is not set 645# CONFIG_R3964 is not set
633# CONFIG_RAW_DRIVER is not set 646# CONFIG_RAW_DRIVER is not set
647# CONFIG_TCG_TPM is not set
648CONFIG_I2C=m
649CONFIG_I2C_BOARDINFO=y
650CONFIG_I2C_CHARDEV=m
634 651
635# 652#
636# TPM devices 653# I2C Algorithms
637# 654#
638# CONFIG_TCG_TPM is not set 655CONFIG_I2C_ALGOBIT=m
639# CONFIG_I2C is not set 656# CONFIG_I2C_ALGOPCF is not set
657# CONFIG_I2C_ALGOPCA is not set
658
659#
660# I2C Hardware Bus support
661#
662CONFIG_I2C_GPIO=m
663# CONFIG_I2C_OCORES is not set
664# CONFIG_I2C_PARPORT_LIGHT is not set
665# CONFIG_I2C_SIMTEC is not set
666# CONFIG_I2C_TAOS_EVM is not set
667# CONFIG_I2C_STUB is not set
668
669#
670# Miscellaneous I2C Chip support
671#
672# CONFIG_SENSORS_DS1337 is not set
673# CONFIG_SENSORS_DS1374 is not set
674# CONFIG_DS1682 is not set
675# CONFIG_SENSORS_EEPROM is not set
676# CONFIG_SENSORS_PCF8574 is not set
677# CONFIG_SENSORS_PCA9539 is not set
678# CONFIG_SENSORS_PCF8591 is not set
679# CONFIG_SENSORS_MAX6875 is not set
680# CONFIG_SENSORS_TSL2550 is not set
681# CONFIG_I2C_DEBUG_CORE is not set
682# CONFIG_I2C_DEBUG_ALGO is not set
683# CONFIG_I2C_DEBUG_BUS is not set
684# CONFIG_I2C_DEBUG_CHIP is not set
640 685
641# 686#
642# SPI support 687# SPI support
@@ -655,13 +700,25 @@ CONFIG_SPI_ATMEL=y
655# SPI Protocol Masters 700# SPI Protocol Masters
656# 701#
657# CONFIG_SPI_AT25 is not set 702# CONFIG_SPI_AT25 is not set
658# CONFIG_SPI_SPIDEV is not set 703CONFIG_SPI_SPIDEV=m
704# CONFIG_SPI_TLE62X0 is not set
705# CONFIG_W1 is not set
706# CONFIG_POWER_SUPPLY is not set
707# CONFIG_HWMON is not set
708CONFIG_WATCHDOG=y
709# CONFIG_WATCHDOG_NOWAYOUT is not set
659 710
660# 711#
661# Dallas's 1-wire bus 712# Watchdog Device Drivers
662# 713#
663# CONFIG_W1 is not set 714# CONFIG_SOFT_WATCHDOG is not set
664# CONFIG_HWMON is not set 715CONFIG_AT32AP700X_WDT=y
716
717#
718# Sonics Silicon Backplane
719#
720CONFIG_SSB_POSSIBLE=y
721# CONFIG_SSB is not set
665 722
666# 723#
667# Multifunction device drivers 724# Multifunction device drivers
@@ -678,23 +735,21 @@ CONFIG_SPI_ATMEL=y
678# 735#
679# Graphics support 736# Graphics support
680# 737#
738# CONFIG_VGASTATE is not set
739# CONFIG_VIDEO_OUTPUT_CONTROL is not set
740# CONFIG_FB is not set
681# CONFIG_BACKLIGHT_LCD_SUPPORT is not set 741# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
682 742
683# 743#
684# Display device support 744# Display device support
685# 745#
686# CONFIG_DISPLAY_SUPPORT is not set 746# CONFIG_DISPLAY_SUPPORT is not set
687# CONFIG_VGASTATE is not set
688# CONFIG_FB is not set
689 747
690# 748#
691# Sound 749# Sound
692# 750#
693# CONFIG_SOUND is not set 751# CONFIG_SOUND is not set
694 752CONFIG_USB_SUPPORT=y
695#
696# USB support
697#
698# CONFIG_USB_ARCH_HAS_HCD is not set 753# CONFIG_USB_ARCH_HAS_HCD is not set
699# CONFIG_USB_ARCH_HAS_OHCI is not set 754# CONFIG_USB_ARCH_HAS_OHCI is not set
700# CONFIG_USB_ARCH_HAS_EHCI is not set 755# CONFIG_USB_ARCH_HAS_EHCI is not set
@@ -706,12 +761,47 @@ CONFIG_SPI_ATMEL=y
706# 761#
707# USB Gadget Support 762# USB Gadget Support
708# 763#
709# CONFIG_USB_GADGET is not set 764CONFIG_USB_GADGET=y
710# CONFIG_MMC is not set 765# CONFIG_USB_GADGET_DEBUG is not set
711 766# CONFIG_USB_GADGET_DEBUG_FILES is not set
712# 767CONFIG_USB_GADGET_SELECTED=y
713# LED devices 768# CONFIG_USB_GADGET_AMD5536UDC is not set
714# 769CONFIG_USB_GADGET_ATMEL_USBA=y
770CONFIG_USB_ATMEL_USBA=y
771# CONFIG_USB_GADGET_FSL_USB2 is not set
772# CONFIG_USB_GADGET_NET2280 is not set
773# CONFIG_USB_GADGET_PXA2XX is not set
774# CONFIG_USB_GADGET_M66592 is not set
775# CONFIG_USB_GADGET_GOKU is not set
776# CONFIG_USB_GADGET_LH7A40X is not set
777# CONFIG_USB_GADGET_OMAP is not set
778# CONFIG_USB_GADGET_S3C2410 is not set
779# CONFIG_USB_GADGET_AT91 is not set
780# CONFIG_USB_GADGET_DUMMY_HCD is not set
781CONFIG_USB_GADGET_DUALSPEED=y
782CONFIG_USB_ZERO=m
783CONFIG_USB_ETH=m
784CONFIG_USB_ETH_RNDIS=y
785CONFIG_USB_GADGETFS=m
786CONFIG_USB_FILE_STORAGE=m
787# CONFIG_USB_FILE_STORAGE_TEST is not set
788CONFIG_USB_G_SERIAL=m
789# CONFIG_USB_MIDI_GADGET is not set
790CONFIG_MMC=m
791# CONFIG_MMC_DEBUG is not set
792# CONFIG_MMC_UNSAFE_RESUME is not set
793
794#
795# MMC/SD Card Drivers
796#
797CONFIG_MMC_BLOCK=m
798CONFIG_MMC_BLOCK_BOUNCE=y
799# CONFIG_SDIO_UART is not set
800
801#
802# MMC/SD Host Controller Drivers
803#
804CONFIG_MMC_SPI=m
715CONFIG_NEW_LEDS=y 805CONFIG_NEW_LEDS=y
716CONFIG_LEDS_CLASS=y 806CONFIG_LEDS_CLASS=y
717 807
@@ -726,53 +816,71 @@ CONFIG_LEDS_GPIO=y
726CONFIG_LEDS_TRIGGERS=y 816CONFIG_LEDS_TRIGGERS=y
727CONFIG_LEDS_TRIGGER_TIMER=y 817CONFIG_LEDS_TRIGGER_TIMER=y
728CONFIG_LEDS_TRIGGER_HEARTBEAT=y 818CONFIG_LEDS_TRIGGER_HEARTBEAT=y
729 819CONFIG_RTC_LIB=y
730 820CONFIG_RTC_CLASS=y
731# 821CONFIG_RTC_HCTOSYS=y
732# LED drivers 822CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
733# 823# CONFIG_RTC_DEBUG is not set
734 824
735# 825#
736# LED Triggers 826# RTC interfaces
737#
738
739#
740# InfiniBand support
741# 827#
828CONFIG_RTC_INTF_SYSFS=y
829CONFIG_RTC_INTF_PROC=y
830CONFIG_RTC_INTF_DEV=y
831# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
832# CONFIG_RTC_DRV_TEST is not set
742 833
743# 834#
744# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) 835# I2C RTC drivers
745# 836#
837# CONFIG_RTC_DRV_DS1307 is not set
838# CONFIG_RTC_DRV_DS1374 is not set
839# CONFIG_RTC_DRV_DS1672 is not set
840# CONFIG_RTC_DRV_MAX6900 is not set
841# CONFIG_RTC_DRV_RS5C372 is not set
842# CONFIG_RTC_DRV_ISL1208 is not set
843# CONFIG_RTC_DRV_X1205 is not set
844# CONFIG_RTC_DRV_PCF8563 is not set
845# CONFIG_RTC_DRV_PCF8583 is not set
846# CONFIG_RTC_DRV_M41T80 is not set
746 847
747# 848#
748# Real Time Clock 849# SPI RTC drivers
749# 850#
750# CONFIG_RTC_CLASS is not set 851# CONFIG_RTC_DRV_RS5C348 is not set
852# CONFIG_RTC_DRV_MAX6902 is not set
751 853
752# 854#
753# DMA Engine support 855# Platform RTC drivers
754# 856#
755# CONFIG_DMA_ENGINE is not set 857# CONFIG_RTC_DRV_DS1553 is not set
858# CONFIG_RTC_DRV_STK17TA8 is not set
859# CONFIG_RTC_DRV_DS1742 is not set
860# CONFIG_RTC_DRV_M48T86 is not set
861# CONFIG_RTC_DRV_M48T59 is not set
862# CONFIG_RTC_DRV_V3020 is not set
756 863
757# 864#
758# DMA Clients 865# on-CPU RTC drivers
759# 866#
867CONFIG_RTC_DRV_AT32AP700X=y
760 868
761# 869#
762# DMA Devices 870# Userspace I/O
763# 871#
872# CONFIG_UIO is not set
764 873
765# 874#
766# File systems 875# File systems
767# 876#
768CONFIG_EXT2_FS=y 877CONFIG_EXT2_FS=m
769# CONFIG_EXT2_FS_XATTR is not set 878# CONFIG_EXT2_FS_XATTR is not set
770# CONFIG_EXT2_FS_XIP is not set 879# CONFIG_EXT2_FS_XIP is not set
771CONFIG_EXT3_FS=y 880CONFIG_EXT3_FS=m
772# CONFIG_EXT3_FS_XATTR is not set 881# CONFIG_EXT3_FS_XATTR is not set
773# CONFIG_EXT4DEV_FS is not set 882# CONFIG_EXT4DEV_FS is not set
774CONFIG_JBD=y 883CONFIG_JBD=m
775# CONFIG_JBD_DEBUG is not set
776# CONFIG_REISERFS_FS is not set 884# CONFIG_REISERFS_FS is not set
777# CONFIG_JFS_FS is not set 885# CONFIG_JFS_FS is not set
778# CONFIG_FS_POSIX_ACL is not set 886# CONFIG_FS_POSIX_ACL is not set
@@ -781,7 +889,8 @@ CONFIG_JBD=y
781# CONFIG_OCFS2_FS is not set 889# CONFIG_OCFS2_FS is not set
782# CONFIG_MINIX_FS is not set 890# CONFIG_MINIX_FS is not set
783# CONFIG_ROMFS_FS is not set 891# CONFIG_ROMFS_FS is not set
784# CONFIG_INOTIFY is not set 892CONFIG_INOTIFY=y
893CONFIG_INOTIFY_USER=y
785# CONFIG_QUOTA is not set 894# CONFIG_QUOTA is not set
786# CONFIG_DNOTIFY is not set 895# CONFIG_DNOTIFY is not set
787# CONFIG_AUTOFS_FS is not set 896# CONFIG_AUTOFS_FS is not set
@@ -814,8 +923,7 @@ CONFIG_SYSFS=y
814CONFIG_TMPFS=y 923CONFIG_TMPFS=y
815# CONFIG_TMPFS_POSIX_ACL is not set 924# CONFIG_TMPFS_POSIX_ACL is not set
816# CONFIG_HUGETLB_PAGE is not set 925# CONFIG_HUGETLB_PAGE is not set
817CONFIG_RAMFS=y 926CONFIG_CONFIGFS_FS=m
818CONFIG_CONFIGFS_FS=y
819 927
820# 928#
821# Miscellaneous filesystems 929# Miscellaneous filesystems
@@ -830,10 +938,12 @@ CONFIG_CONFIGFS_FS=y
830CONFIG_JFFS2_FS=y 938CONFIG_JFFS2_FS=y
831CONFIG_JFFS2_FS_DEBUG=0 939CONFIG_JFFS2_FS_DEBUG=0
832CONFIG_JFFS2_FS_WRITEBUFFER=y 940CONFIG_JFFS2_FS_WRITEBUFFER=y
941# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
833# CONFIG_JFFS2_SUMMARY is not set 942# CONFIG_JFFS2_SUMMARY is not set
834# CONFIG_JFFS2_FS_XATTR is not set 943# CONFIG_JFFS2_FS_XATTR is not set
835# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set 944# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
836CONFIG_JFFS2_ZLIB=y 945CONFIG_JFFS2_ZLIB=y
946# CONFIG_JFFS2_LZO is not set
837CONFIG_JFFS2_RTIME=y 947CONFIG_JFFS2_RTIME=y
838# CONFIG_JFFS2_RUBIN is not set 948# CONFIG_JFFS2_RUBIN is not set
839# CONFIG_CRAMFS is not set 949# CONFIG_CRAMFS is not set
@@ -842,19 +952,21 @@ CONFIG_JFFS2_RTIME=y
842# CONFIG_QNX4FS_FS is not set 952# CONFIG_QNX4FS_FS is not set
843# CONFIG_SYSV_FS is not set 953# CONFIG_SYSV_FS is not set
844# CONFIG_UFS_FS is not set 954# CONFIG_UFS_FS is not set
845 955CONFIG_NETWORK_FILESYSTEMS=y
846#
847# Network File Systems
848#
849CONFIG_NFS_FS=y 956CONFIG_NFS_FS=y
850CONFIG_NFS_V3=y 957CONFIG_NFS_V3=y
851# CONFIG_NFS_V3_ACL is not set 958# CONFIG_NFS_V3_ACL is not set
852# CONFIG_NFS_V4 is not set 959# CONFIG_NFS_V4 is not set
853# CONFIG_NFS_DIRECTIO is not set 960# CONFIG_NFS_DIRECTIO is not set
854# CONFIG_NFSD is not set 961CONFIG_NFSD=m
962CONFIG_NFSD_V3=y
963# CONFIG_NFSD_V3_ACL is not set
964# CONFIG_NFSD_V4 is not set
965CONFIG_NFSD_TCP=y
855CONFIG_ROOT_NFS=y 966CONFIG_ROOT_NFS=y
856CONFIG_LOCKD=y 967CONFIG_LOCKD=y
857CONFIG_LOCKD_V4=y 968CONFIG_LOCKD_V4=y
969CONFIG_EXPORTFS=m
858CONFIG_NFS_COMMON=y 970CONFIG_NFS_COMMON=y
859CONFIG_SUNRPC=y 971CONFIG_SUNRPC=y
860# CONFIG_SUNRPC_BIND34 is not set 972# CONFIG_SUNRPC_BIND34 is not set
@@ -871,23 +983,18 @@ CONFIG_CIFS=m
871# CONFIG_NCP_FS is not set 983# CONFIG_NCP_FS is not set
872# CONFIG_CODA_FS is not set 984# CONFIG_CODA_FS is not set
873# CONFIG_AFS_FS is not set 985# CONFIG_AFS_FS is not set
874# CONFIG_9P_FS is not set
875 986
876# 987#
877# Partition Types 988# Partition Types
878# 989#
879# CONFIG_PARTITION_ADVANCED is not set 990# CONFIG_PARTITION_ADVANCED is not set
880CONFIG_MSDOS_PARTITION=y 991CONFIG_MSDOS_PARTITION=y
881 992CONFIG_NLS=m
882#
883# Native Language Support
884#
885CONFIG_NLS=y
886CONFIG_NLS_DEFAULT="iso8859-1" 993CONFIG_NLS_DEFAULT="iso8859-1"
887# CONFIG_NLS_CODEPAGE_437 is not set 994CONFIG_NLS_CODEPAGE_437=m
888# CONFIG_NLS_CODEPAGE_737 is not set 995# CONFIG_NLS_CODEPAGE_737 is not set
889# CONFIG_NLS_CODEPAGE_775 is not set 996# CONFIG_NLS_CODEPAGE_775 is not set
890CONFIG_NLS_CODEPAGE_850=y 997CONFIG_NLS_CODEPAGE_850=m
891# CONFIG_NLS_CODEPAGE_852 is not set 998# CONFIG_NLS_CODEPAGE_852 is not set
892# CONFIG_NLS_CODEPAGE_855 is not set 999# CONFIG_NLS_CODEPAGE_855 is not set
893# CONFIG_NLS_CODEPAGE_857 is not set 1000# CONFIG_NLS_CODEPAGE_857 is not set
@@ -908,7 +1015,7 @@ CONFIG_NLS_CODEPAGE_850=y
908# CONFIG_NLS_CODEPAGE_1250 is not set 1015# CONFIG_NLS_CODEPAGE_1250 is not set
909# CONFIG_NLS_CODEPAGE_1251 is not set 1016# CONFIG_NLS_CODEPAGE_1251 is not set
910# CONFIG_NLS_ASCII is not set 1017# CONFIG_NLS_ASCII is not set
911CONFIG_NLS_ISO8859_1=y 1018CONFIG_NLS_ISO8859_1=m
912# CONFIG_NLS_ISO8859_2 is not set 1019# CONFIG_NLS_ISO8859_2 is not set
913# CONFIG_NLS_ISO8859_3 is not set 1020# CONFIG_NLS_ISO8859_3 is not set
914# CONFIG_NLS_ISO8859_4 is not set 1021# CONFIG_NLS_ISO8859_4 is not set
@@ -921,18 +1028,19 @@ CONFIG_NLS_ISO8859_1=y
921# CONFIG_NLS_ISO8859_15 is not set 1028# CONFIG_NLS_ISO8859_15 is not set
922# CONFIG_NLS_KOI8_R is not set 1029# CONFIG_NLS_KOI8_R is not set
923# CONFIG_NLS_KOI8_U is not set 1030# CONFIG_NLS_KOI8_U is not set
924CONFIG_NLS_UTF8=y 1031CONFIG_NLS_UTF8=m
925
926#
927# Distributed Lock Manager
928#
929# CONFIG_DLM is not set 1032# CONFIG_DLM is not set
1033CONFIG_INSTRUMENTATION=y
1034CONFIG_PROFILING=y
1035CONFIG_OPROFILE=m
1036CONFIG_KPROBES=y
1037# CONFIG_MARKERS is not set
930 1038
931# 1039#
932# Kernel hacking 1040# Kernel hacking
933# 1041#
934CONFIG_TRACE_IRQFLAGS_SUPPORT=y
935# CONFIG_PRINTK_TIME is not set 1042# CONFIG_PRINTK_TIME is not set
1043CONFIG_ENABLE_WARN_DEPRECATED=y
936CONFIG_ENABLE_MUST_CHECK=y 1044CONFIG_ENABLE_MUST_CHECK=y
937CONFIG_MAGIC_SYSRQ=y 1045CONFIG_MAGIC_SYSRQ=y
938# CONFIG_UNUSED_SYMBOLS is not set 1046# CONFIG_UNUSED_SYMBOLS is not set
@@ -941,12 +1049,17 @@ CONFIG_MAGIC_SYSRQ=y
941CONFIG_DEBUG_KERNEL=y 1049CONFIG_DEBUG_KERNEL=y
942# CONFIG_DEBUG_SHIRQ is not set 1050# CONFIG_DEBUG_SHIRQ is not set
943CONFIG_DETECT_SOFTLOCKUP=y 1051CONFIG_DETECT_SOFTLOCKUP=y
1052CONFIG_SCHED_DEBUG=y
944# CONFIG_SCHEDSTATS is not set 1053# CONFIG_SCHEDSTATS is not set
945# CONFIG_TIMER_STATS is not set 1054# CONFIG_TIMER_STATS is not set
1055# CONFIG_SLUB_DEBUG_ON is not set
946# CONFIG_DEBUG_RT_MUTEXES is not set 1056# CONFIG_DEBUG_RT_MUTEXES is not set
947# CONFIG_RT_MUTEX_TESTER is not set 1057# CONFIG_RT_MUTEX_TESTER is not set
948# CONFIG_DEBUG_SPINLOCK is not set 1058# CONFIG_DEBUG_SPINLOCK is not set
949# CONFIG_DEBUG_MUTEXES is not set 1059# CONFIG_DEBUG_MUTEXES is not set
1060# CONFIG_DEBUG_LOCK_ALLOC is not set
1061# CONFIG_PROVE_LOCKING is not set
1062# CONFIG_LOCK_STAT is not set
950# CONFIG_DEBUG_SPINLOCK_SLEEP is not set 1063# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
951# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set 1064# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
952# CONFIG_DEBUG_KOBJECT is not set 1065# CONFIG_DEBUG_KOBJECT is not set
@@ -954,21 +1067,21 @@ CONFIG_DEBUG_BUGVERBOSE=y
954# CONFIG_DEBUG_INFO is not set 1067# CONFIG_DEBUG_INFO is not set
955# CONFIG_DEBUG_VM is not set 1068# CONFIG_DEBUG_VM is not set
956# CONFIG_DEBUG_LIST is not set 1069# CONFIG_DEBUG_LIST is not set
1070# CONFIG_DEBUG_SG is not set
957CONFIG_FRAME_POINTER=y 1071CONFIG_FRAME_POINTER=y
958# CONFIG_FORCED_INLINING is not set 1072# CONFIG_FORCED_INLINING is not set
1073# CONFIG_BOOT_PRINTK_DELAY is not set
959# CONFIG_RCU_TORTURE_TEST is not set 1074# CONFIG_RCU_TORTURE_TEST is not set
1075# CONFIG_LKDTM is not set
960# CONFIG_FAULT_INJECTION is not set 1076# CONFIG_FAULT_INJECTION is not set
961# CONFIG_KPROBES is not set 1077# CONFIG_SAMPLES is not set
962 1078
963# 1079#
964# Security options 1080# Security options
965# 1081#
966# CONFIG_KEYS is not set 1082# CONFIG_KEYS is not set
967# CONFIG_SECURITY is not set 1083# CONFIG_SECURITY is not set
968 1084# CONFIG_SECURITY_FILE_CAPABILITIES is not set
969#
970# Cryptographic options
971#
972CONFIG_CRYPTO=y 1085CONFIG_CRYPTO=y
973CONFIG_CRYPTO_ALGAPI=y 1086CONFIG_CRYPTO_ALGAPI=y
974CONFIG_CRYPTO_BLKCIPHER=y 1087CONFIG_CRYPTO_BLKCIPHER=y
@@ -989,6 +1102,7 @@ CONFIG_CRYPTO_ECB=m
989CONFIG_CRYPTO_CBC=y 1102CONFIG_CRYPTO_CBC=y
990CONFIG_CRYPTO_PCBC=m 1103CONFIG_CRYPTO_PCBC=m
991# CONFIG_CRYPTO_LRW is not set 1104# CONFIG_CRYPTO_LRW is not set
1105# CONFIG_CRYPTO_XTS is not set
992# CONFIG_CRYPTO_CRYPTD is not set 1106# CONFIG_CRYPTO_CRYPTD is not set
993CONFIG_CRYPTO_DES=y 1107CONFIG_CRYPTO_DES=y
994# CONFIG_CRYPTO_FCRYPT is not set 1108# CONFIG_CRYPTO_FCRYPT is not set
@@ -1002,15 +1116,14 @@ CONFIG_CRYPTO_DES=y
1002CONFIG_CRYPTO_ARC4=m 1116CONFIG_CRYPTO_ARC4=m
1003# CONFIG_CRYPTO_KHAZAD is not set 1117# CONFIG_CRYPTO_KHAZAD is not set
1004# CONFIG_CRYPTO_ANUBIS is not set 1118# CONFIG_CRYPTO_ANUBIS is not set
1119# CONFIG_CRYPTO_SEED is not set
1005CONFIG_CRYPTO_DEFLATE=y 1120CONFIG_CRYPTO_DEFLATE=y
1006# CONFIG_CRYPTO_MICHAEL_MIC is not set 1121# CONFIG_CRYPTO_MICHAEL_MIC is not set
1007# CONFIG_CRYPTO_CRC32C is not set 1122# CONFIG_CRYPTO_CRC32C is not set
1008# CONFIG_CRYPTO_CAMELLIA is not set 1123# CONFIG_CRYPTO_CAMELLIA is not set
1009# CONFIG_CRYPTO_TEST is not set 1124# CONFIG_CRYPTO_TEST is not set
1010 1125# CONFIG_CRYPTO_AUTHENC is not set
1011# 1126CONFIG_CRYPTO_HW=y
1012# Hardware crypto devices
1013#
1014 1127
1015# 1128#
1016# Library routines 1129# Library routines
@@ -1018,8 +1131,9 @@ CONFIG_CRYPTO_DEFLATE=y
1018CONFIG_BITREVERSE=y 1131CONFIG_BITREVERSE=y
1019CONFIG_CRC_CCITT=m 1132CONFIG_CRC_CCITT=m
1020# CONFIG_CRC16 is not set 1133# CONFIG_CRC16 is not set
1021# CONFIG_CRC_ITU_T is not set 1134CONFIG_CRC_ITU_T=m
1022CONFIG_CRC32=y 1135CONFIG_CRC32=y
1136CONFIG_CRC7=m
1023# CONFIG_LIBCRC32C is not set 1137# CONFIG_LIBCRC32C is not set
1024CONFIG_ZLIB_INFLATE=y 1138CONFIG_ZLIB_INFLATE=y
1025CONFIG_ZLIB_DEFLATE=y 1139CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/avr32/configs/atstk1002_defconfig b/arch/avr32/configs/atstk1002_defconfig
index 3b977fdbaa78..2fb2ede5f2b4 100644
--- a/arch/avr32/configs/atstk1002_defconfig
+++ b/arch/avr32/configs/atstk1002_defconfig
@@ -1,48 +1,48 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.22-rc5 3# Linux kernel version: 2.6.24-rc7
4# Sat Jun 23 15:32:08 2007 4# Wed Jan 9 23:07:43 2008
5# 5#
6CONFIG_AVR32=y 6CONFIG_AVR32=y
7CONFIG_GENERIC_GPIO=y 7CONFIG_GENERIC_GPIO=y
8CONFIG_GENERIC_HARDIRQS=y 8CONFIG_GENERIC_HARDIRQS=y
9CONFIG_STACKTRACE_SUPPORT=y
10CONFIG_LOCKDEP_SUPPORT=y
11CONFIG_TRACE_IRQFLAGS_SUPPORT=y
9CONFIG_HARDIRQS_SW_RESEND=y 12CONFIG_HARDIRQS_SW_RESEND=y
10CONFIG_GENERIC_IRQ_PROBE=y 13CONFIG_GENERIC_IRQ_PROBE=y
11CONFIG_RWSEM_GENERIC_SPINLOCK=y 14CONFIG_RWSEM_GENERIC_SPINLOCK=y
12CONFIG_GENERIC_TIME=y 15CONFIG_GENERIC_TIME=y
16# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
13# CONFIG_ARCH_HAS_ILOG2_U32 is not set 17# CONFIG_ARCH_HAS_ILOG2_U32 is not set
14# CONFIG_ARCH_HAS_ILOG2_U64 is not set 18# CONFIG_ARCH_HAS_ILOG2_U64 is not set
19CONFIG_ARCH_SUPPORTS_OPROFILE=y
15CONFIG_GENERIC_HWEIGHT=y 20CONFIG_GENERIC_HWEIGHT=y
16CONFIG_GENERIC_CALIBRATE_DELAY=y 21CONFIG_GENERIC_CALIBRATE_DELAY=y
17CONFIG_GENERIC_BUG=y 22CONFIG_GENERIC_BUG=y
18CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" 23CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
19 24
20# 25#
21# Code maturity level options 26# General setup
22# 27#
23CONFIG_EXPERIMENTAL=y 28CONFIG_EXPERIMENTAL=y
24CONFIG_BROKEN_ON_SMP=y 29CONFIG_BROKEN_ON_SMP=y
25CONFIG_INIT_ENV_ARG_LIMIT=32 30CONFIG_INIT_ENV_ARG_LIMIT=32
26
27#
28# General setup
29#
30CONFIG_LOCALVERSION="" 31CONFIG_LOCALVERSION=""
31# CONFIG_LOCALVERSION_AUTO is not set 32# CONFIG_LOCALVERSION_AUTO is not set
32CONFIG_SWAP=y 33CONFIG_SWAP=y
33CONFIG_SYSVIPC=y 34CONFIG_SYSVIPC=y
34# CONFIG_IPC_NS is not set
35CONFIG_SYSVIPC_SYSCTL=y 35CONFIG_SYSVIPC_SYSCTL=y
36CONFIG_POSIX_MQUEUE=y 36CONFIG_POSIX_MQUEUE=y
37CONFIG_BSD_PROCESS_ACCT=y 37# CONFIG_BSD_PROCESS_ACCT is not set
38CONFIG_BSD_PROCESS_ACCT_V3=y 38# CONFIG_TASKSTATS is not set
39CONFIG_TASKSTATS=y 39# CONFIG_USER_NS is not set
40CONFIG_TASK_DELAY_ACCT=y 40# CONFIG_PID_NS is not set
41# CONFIG_TASK_XACCT is not set 41# CONFIG_AUDIT is not set
42# CONFIG_UTS_NS is not set
43CONFIG_AUDIT=y
44# CONFIG_IKCONFIG is not set 42# CONFIG_IKCONFIG is not set
45CONFIG_LOG_BUF_SHIFT=14 43CONFIG_LOG_BUF_SHIFT=14
44# CONFIG_CGROUPS is not set
45# CONFIG_FAIR_GROUP_SCHED is not set
46CONFIG_SYSFS_DEPRECATED=y 46CONFIG_SYSFS_DEPRECATED=y
47CONFIG_RELAY=y 47CONFIG_RELAY=y
48CONFIG_BLK_DEV_INITRD=y 48CONFIG_BLK_DEV_INITRD=y
@@ -63,35 +63,28 @@ CONFIG_FUTEX=y
63CONFIG_ANON_INODES=y 63CONFIG_ANON_INODES=y
64CONFIG_EPOLL=y 64CONFIG_EPOLL=y
65CONFIG_SIGNALFD=y 65CONFIG_SIGNALFD=y
66CONFIG_TIMERFD=y
67CONFIG_EVENTFD=y 66CONFIG_EVENTFD=y
68CONFIG_SHMEM=y 67CONFIG_SHMEM=y
69CONFIG_VM_EVENT_COUNTERS=y 68CONFIG_VM_EVENT_COUNTERS=y
70# CONFIG_SLUB_DEBUG is not set 69CONFIG_SLUB_DEBUG=y
71# CONFIG_SLAB is not set 70# CONFIG_SLAB is not set
72CONFIG_SLUB=y 71CONFIG_SLUB=y
73# CONFIG_SLOB is not set 72# CONFIG_SLOB is not set
73CONFIG_SLABINFO=y
74CONFIG_RT_MUTEXES=y 74CONFIG_RT_MUTEXES=y
75# CONFIG_TINY_SHMEM is not set 75# CONFIG_TINY_SHMEM is not set
76CONFIG_BASE_SMALL=1 76CONFIG_BASE_SMALL=1
77
78#
79# Loadable module support
80#
81CONFIG_MODULES=y 77CONFIG_MODULES=y
82CONFIG_MODULE_UNLOAD=y 78CONFIG_MODULE_UNLOAD=y
83# CONFIG_MODULE_FORCE_UNLOAD is not set 79# CONFIG_MODULE_FORCE_UNLOAD is not set
84# CONFIG_MODVERSIONS is not set 80# CONFIG_MODVERSIONS is not set
85# CONFIG_MODULE_SRCVERSION_ALL is not set 81# CONFIG_MODULE_SRCVERSION_ALL is not set
86# CONFIG_KMOD is not set 82# CONFIG_KMOD is not set
87
88#
89# Block layer
90#
91CONFIG_BLOCK=y 83CONFIG_BLOCK=y
92# CONFIG_LBD is not set 84# CONFIG_LBD is not set
93# CONFIG_BLK_DEV_IO_TRACE is not set 85# CONFIG_BLK_DEV_IO_TRACE is not set
94# CONFIG_LSF is not set 86# CONFIG_LSF is not set
87# CONFIG_BLK_DEV_BSG is not set
95 88
96# 89#
97# IO Schedulers 90# IO Schedulers
@@ -99,12 +92,12 @@ CONFIG_BLOCK=y
99CONFIG_IOSCHED_NOOP=y 92CONFIG_IOSCHED_NOOP=y
100# CONFIG_IOSCHED_AS is not set 93# CONFIG_IOSCHED_AS is not set
101# CONFIG_IOSCHED_DEADLINE is not set 94# CONFIG_IOSCHED_DEADLINE is not set
102# CONFIG_IOSCHED_CFQ is not set 95CONFIG_IOSCHED_CFQ=y
103# CONFIG_DEFAULT_AS is not set 96# CONFIG_DEFAULT_AS is not set
104# CONFIG_DEFAULT_DEADLINE is not set 97# CONFIG_DEFAULT_DEADLINE is not set
105# CONFIG_DEFAULT_CFQ is not set 98CONFIG_DEFAULT_CFQ=y
106CONFIG_DEFAULT_NOOP=y 99# CONFIG_DEFAULT_NOOP is not set
107CONFIG_DEFAULT_IOSCHED="noop" 100CONFIG_DEFAULT_IOSCHED="cfq"
108 101
109# 102#
110# System Type and features 103# System Type and features
@@ -113,18 +106,27 @@ CONFIG_SUBARCH_AVR32B=y
113CONFIG_MMU=y 106CONFIG_MMU=y
114CONFIG_PERFORMANCE_COUNTERS=y 107CONFIG_PERFORMANCE_COUNTERS=y
115CONFIG_PLATFORM_AT32AP=y 108CONFIG_PLATFORM_AT32AP=y
109CONFIG_CPU_AT32AP700X=y
116CONFIG_CPU_AT32AP7000=y 110CONFIG_CPU_AT32AP7000=y
117CONFIG_BOARD_ATSTK1002=y
118CONFIG_BOARD_ATSTK1000=y 111CONFIG_BOARD_ATSTK1000=y
119# CONFIG_BOARD_ATNGW100 is not set 112# CONFIG_BOARD_ATNGW100 is not set
113CONFIG_BOARD_ATSTK1002=y
114# CONFIG_BOARD_ATSTK1003 is not set
115# CONFIG_BOARD_ATSTK1004 is not set
116# CONFIG_BOARD_ATSTK100X_CUSTOM is not set
117# CONFIG_BOARD_ATSTK100X_SPI1 is not set
118# CONFIG_BOARD_ATSTK1000_J2_LED is not set
119# CONFIG_BOARD_ATSTK1000_J2_LED8 is not set
120# CONFIG_BOARD_ATSTK1000_J2_RGB is not set
121CONFIG_BOARD_ATSTK1000_EXTDAC=y
120CONFIG_LOADER_U_BOOT=y 122CONFIG_LOADER_U_BOOT=y
121 123
122# 124#
123# Atmel AVR32 AP options 125# Atmel AVR32 AP options
124# 126#
125# CONFIG_AP7000_32_BIT_SMC is not set 127# CONFIG_AP700X_32_BIT_SMC is not set
126CONFIG_AP7000_16_BIT_SMC=y 128CONFIG_AP700X_16_BIT_SMC=y
127# CONFIG_AP7000_8_BIT_SMC is not set 129# CONFIG_AP700X_8_BIT_SMC is not set
128CONFIG_LOAD_ADDRESS=0x10000000 130CONFIG_LOAD_ADDRESS=0x10000000
129CONFIG_ENTRY_ADDRESS=0x90000000 131CONFIG_ENTRY_ADDRESS=0x90000000
130CONFIG_PHYS_OFFSET=0x10000000 132CONFIG_PHYS_OFFSET=0x10000000
@@ -144,9 +146,11 @@ CONFIG_FLATMEM_MANUAL=y
144CONFIG_FLATMEM=y 146CONFIG_FLATMEM=y
145CONFIG_FLAT_NODE_MEM_MAP=y 147CONFIG_FLAT_NODE_MEM_MAP=y
146# CONFIG_SPARSEMEM_STATIC is not set 148# CONFIG_SPARSEMEM_STATIC is not set
149# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
147CONFIG_SPLIT_PTLOCK_CPUS=4 150CONFIG_SPLIT_PTLOCK_CPUS=4
148# CONFIG_RESOURCES_64BIT is not set 151# CONFIG_RESOURCES_64BIT is not set
149CONFIG_ZONE_DMA_FLAG=0 152CONFIG_ZONE_DMA_FLAG=0
153CONFIG_VIRT_TO_BUS=y
150# CONFIG_OWNERSHIP_TRACE is not set 154# CONFIG_OWNERSHIP_TRACE is not set
151# CONFIG_HZ_100 is not set 155# CONFIG_HZ_100 is not set
152CONFIG_HZ_250=y 156CONFIG_HZ_250=y
@@ -156,13 +160,31 @@ CONFIG_HZ=250
156CONFIG_CMDLINE="" 160CONFIG_CMDLINE=""
157 161
158# 162#
159# Bus options 163# Power management options
160# 164#
161# CONFIG_ARCH_SUPPORTS_MSI is not set
162 165
163# 166#
164# PCCARD (PCMCIA/CardBus) support 167# CPU Frequency scaling
168#
169CONFIG_CPU_FREQ=y
170CONFIG_CPU_FREQ_TABLE=y
171# CONFIG_CPU_FREQ_DEBUG is not set
172# CONFIG_CPU_FREQ_STAT is not set
173CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
174# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
175# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
176# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
177CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
178# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
179CONFIG_CPU_FREQ_GOV_USERSPACE=y
180CONFIG_CPU_FREQ_GOV_ONDEMAND=y
181# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
182CONFIG_CPU_FREQ_AT32AP=y
183
165# 184#
185# Bus options
186#
187# CONFIG_ARCH_SUPPORTS_MSI is not set
166# CONFIG_PCCARD is not set 188# CONFIG_PCCARD is not set
167 189
168# 190#
@@ -182,7 +204,12 @@ CONFIG_NET=y
182CONFIG_PACKET=y 204CONFIG_PACKET=y
183CONFIG_PACKET_MMAP=y 205CONFIG_PACKET_MMAP=y
184CONFIG_UNIX=y 206CONFIG_UNIX=y
185# CONFIG_NET_KEY is not set 207CONFIG_XFRM=y
208CONFIG_XFRM_USER=m
209# CONFIG_XFRM_SUB_POLICY is not set
210# CONFIG_XFRM_MIGRATE is not set
211CONFIG_NET_KEY=m
212# CONFIG_NET_KEY_MIGRATE is not set
186CONFIG_INET=y 213CONFIG_INET=y
187# CONFIG_IP_MULTICAST is not set 214# CONFIG_IP_MULTICAST is not set
188# CONFIG_IP_ADVANCED_ROUTER is not set 215# CONFIG_IP_ADVANCED_ROUTER is not set
@@ -191,36 +218,52 @@ CONFIG_IP_PNP=y
191CONFIG_IP_PNP_DHCP=y 218CONFIG_IP_PNP_DHCP=y
192# CONFIG_IP_PNP_BOOTP is not set 219# CONFIG_IP_PNP_BOOTP is not set
193# CONFIG_IP_PNP_RARP is not set 220# CONFIG_IP_PNP_RARP is not set
194# CONFIG_NET_IPIP is not set 221CONFIG_NET_IPIP=m
195# CONFIG_NET_IPGRE is not set 222CONFIG_NET_IPGRE=m
196# CONFIG_ARPD is not set 223# CONFIG_ARPD is not set
197# CONFIG_SYN_COOKIES is not set 224# CONFIG_SYN_COOKIES is not set
198# CONFIG_INET_AH is not set 225CONFIG_INET_AH=m
199# CONFIG_INET_ESP is not set 226CONFIG_INET_ESP=m
200# CONFIG_INET_IPCOMP is not set 227# CONFIG_INET_IPCOMP is not set
201# CONFIG_INET_XFRM_TUNNEL is not set 228# CONFIG_INET_XFRM_TUNNEL is not set
202# CONFIG_INET_TUNNEL is not set 229CONFIG_INET_TUNNEL=m
203# CONFIG_INET_XFRM_MODE_TRANSPORT is not set 230CONFIG_INET_XFRM_MODE_TRANSPORT=m
204# CONFIG_INET_XFRM_MODE_TUNNEL is not set 231CONFIG_INET_XFRM_MODE_TUNNEL=m
205# CONFIG_INET_XFRM_MODE_BEET is not set 232CONFIG_INET_XFRM_MODE_BEET=m
233# CONFIG_INET_LRO is not set
206CONFIG_INET_DIAG=y 234CONFIG_INET_DIAG=y
207CONFIG_INET_TCP_DIAG=y 235CONFIG_INET_TCP_DIAG=y
208# CONFIG_TCP_CONG_ADVANCED is not set 236# CONFIG_TCP_CONG_ADVANCED is not set
209CONFIG_TCP_CONG_CUBIC=y 237CONFIG_TCP_CONG_CUBIC=y
210CONFIG_DEFAULT_TCP_CONG="cubic" 238CONFIG_DEFAULT_TCP_CONG="cubic"
211# CONFIG_TCP_MD5SIG is not set 239# CONFIG_TCP_MD5SIG is not set
212# CONFIG_IPV6 is not set 240CONFIG_IPV6=m
213# CONFIG_INET6_XFRM_TUNNEL is not set 241# CONFIG_IPV6_PRIVACY is not set
214# CONFIG_INET6_TUNNEL is not set 242# CONFIG_IPV6_ROUTER_PREF is not set
243# CONFIG_IPV6_OPTIMISTIC_DAD is not set
244CONFIG_INET6_AH=m
245CONFIG_INET6_ESP=m
246CONFIG_INET6_IPCOMP=m
247# CONFIG_IPV6_MIP6 is not set
248CONFIG_INET6_XFRM_TUNNEL=m
249CONFIG_INET6_TUNNEL=m
250CONFIG_INET6_XFRM_MODE_TRANSPORT=m
251CONFIG_INET6_XFRM_MODE_TUNNEL=m
252CONFIG_INET6_XFRM_MODE_BEET=m
253# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
254CONFIG_IPV6_SIT=m
255CONFIG_IPV6_TUNNEL=m
256# CONFIG_IPV6_MULTIPLE_TABLES is not set
215# CONFIG_NETWORK_SECMARK is not set 257# CONFIG_NETWORK_SECMARK is not set
216# CONFIG_NETFILTER is not set 258# CONFIG_NETFILTER is not set
217# CONFIG_IP_DCCP is not set 259# CONFIG_IP_DCCP is not set
218# CONFIG_IP_SCTP is not set 260# CONFIG_IP_SCTP is not set
219# CONFIG_TIPC is not set 261# CONFIG_TIPC is not set
220# CONFIG_ATM is not set 262# CONFIG_ATM is not set
221# CONFIG_BRIDGE is not set 263CONFIG_BRIDGE=m
222# CONFIG_VLAN_8021Q is not set 264# CONFIG_VLAN_8021Q is not set
223# CONFIG_DECNET is not set 265# CONFIG_DECNET is not set
266CONFIG_LLC=m
224# CONFIG_LLC2 is not set 267# CONFIG_LLC2 is not set
225# CONFIG_IPX is not set 268# CONFIG_IPX is not set
226# CONFIG_ATALK is not set 269# CONFIG_ATALK is not set
@@ -228,16 +271,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
228# CONFIG_LAPB is not set 271# CONFIG_LAPB is not set
229# CONFIG_ECONET is not set 272# CONFIG_ECONET is not set
230# CONFIG_WAN_ROUTER is not set 273# CONFIG_WAN_ROUTER is not set
231
232#
233# QoS and/or fair queueing
234#
235# CONFIG_NET_SCHED is not set 274# CONFIG_NET_SCHED is not set
236 275
237# 276#
238# Network testing 277# Network testing
239# 278#
240# CONFIG_NET_PKTGEN is not set 279# CONFIG_NET_PKTGEN is not set
280# CONFIG_NET_TCPPROBE is not set
241# CONFIG_HAMRADIO is not set 281# CONFIG_HAMRADIO is not set
242# CONFIG_IRDA is not set 282# CONFIG_IRDA is not set
243# CONFIG_BT is not set 283# CONFIG_BT is not set
@@ -251,6 +291,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
251# CONFIG_MAC80211 is not set 291# CONFIG_MAC80211 is not set
252# CONFIG_IEEE80211 is not set 292# CONFIG_IEEE80211 is not set
253# CONFIG_RFKILL is not set 293# CONFIG_RFKILL is not set
294# CONFIG_NET_9P is not set
254 295
255# 296#
256# Device Drivers 297# Device Drivers
@@ -259,16 +300,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
259# 300#
260# Generic Driver Options 301# Generic Driver Options
261# 302#
303CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
262CONFIG_STANDALONE=y 304CONFIG_STANDALONE=y
263# CONFIG_PREVENT_FIRMWARE_BUILD is not set 305# CONFIG_PREVENT_FIRMWARE_BUILD is not set
264# CONFIG_FW_LOADER is not set 306# CONFIG_FW_LOADER is not set
265# CONFIG_DEBUG_DRIVER is not set 307# CONFIG_DEBUG_DRIVER is not set
266# CONFIG_DEBUG_DEVRES is not set 308# CONFIG_DEBUG_DEVRES is not set
267# CONFIG_SYS_HYPERVISOR is not set 309# CONFIG_SYS_HYPERVISOR is not set
268
269#
270# Connector - unified userspace <-> kernelspace linker
271#
272# CONFIG_CONNECTOR is not set 310# CONFIG_CONNECTOR is not set
273CONFIG_MTD=y 311CONFIG_MTD=y
274# CONFIG_MTD_DEBUG is not set 312# CONFIG_MTD_DEBUG is not set
@@ -288,6 +326,7 @@ CONFIG_MTD_BLOCK=y
288# CONFIG_INFTL is not set 326# CONFIG_INFTL is not set
289# CONFIG_RFD_FTL is not set 327# CONFIG_RFD_FTL is not set
290# CONFIG_SSFDC is not set 328# CONFIG_SSFDC is not set
329# CONFIG_MTD_OOPS is not set
291 330
292# 331#
293# RAM/ROM/Flash chip drivers 332# RAM/ROM/Flash chip drivers
@@ -327,6 +366,8 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
327# 366#
328# Self-contained MTD device drivers 367# Self-contained MTD device drivers
329# 368#
369CONFIG_MTD_DATAFLASH=m
370CONFIG_MTD_M25P80=m
330# CONFIG_MTD_SLRAM is not set 371# CONFIG_MTD_SLRAM is not set
331# CONFIG_MTD_PHRAM is not set 372# CONFIG_MTD_PHRAM is not set
332# CONFIG_MTD_MTDRAM is not set 373# CONFIG_MTD_MTDRAM is not set
@@ -345,20 +386,8 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
345# UBI - Unsorted block images 386# UBI - Unsorted block images
346# 387#
347# CONFIG_MTD_UBI is not set 388# CONFIG_MTD_UBI is not set
348
349#
350# Parallel port support
351#
352# CONFIG_PARPORT is not set 389# CONFIG_PARPORT is not set
353 390CONFIG_BLK_DEV=y
354#
355# Plug and Play support
356#
357# CONFIG_PNPACPI is not set
358
359#
360# Block devices
361#
362# CONFIG_BLK_DEV_COW_COMMON is not set 391# CONFIG_BLK_DEV_COW_COMMON is not set
363CONFIG_BLK_DEV_LOOP=m 392CONFIG_BLK_DEV_LOOP=m
364# CONFIG_BLK_DEV_CRYPTOLOOP is not set 393# CONFIG_BLK_DEV_CRYPTOLOOP is not set
@@ -369,42 +398,87 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
369CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 398CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
370# CONFIG_CDROM_PKTCDVD is not set 399# CONFIG_CDROM_PKTCDVD is not set
371# CONFIG_ATA_OVER_ETH is not set 400# CONFIG_ATA_OVER_ETH is not set
372 401CONFIG_MISC_DEVICES=y
373# 402# CONFIG_EEPROM_93CX6 is not set
374# Misc devices 403CONFIG_ATMEL_SSC=m
375#
376# CONFIG_BLINK is not set
377# CONFIG_IDE is not set 404# CONFIG_IDE is not set
378 405
379# 406#
380# SCSI device support 407# SCSI device support
381# 408#
382# CONFIG_RAID_ATTRS is not set 409# CONFIG_RAID_ATTRS is not set
383# CONFIG_SCSI is not set 410CONFIG_SCSI=m
411CONFIG_SCSI_DMA=y
412# CONFIG_SCSI_TGT is not set
384# CONFIG_SCSI_NETLINK is not set 413# CONFIG_SCSI_NETLINK is not set
385# CONFIG_ATA is not set 414# CONFIG_SCSI_PROC_FS is not set
386 415
387# 416#
388# Multi-device support (RAID and LVM) 417# SCSI support type (disk, tape, CD-ROM)
389# 418#
390# CONFIG_MD is not set 419CONFIG_BLK_DEV_SD=m
420# CONFIG_CHR_DEV_ST is not set
421# CONFIG_CHR_DEV_OSST is not set
422CONFIG_BLK_DEV_SR=m
423# CONFIG_BLK_DEV_SR_VENDOR is not set
424# CONFIG_CHR_DEV_SG is not set
425# CONFIG_CHR_DEV_SCH is not set
391 426
392# 427#
393# Network device support 428# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
394# 429#
430# CONFIG_SCSI_MULTI_LUN is not set
431# CONFIG_SCSI_CONSTANTS is not set
432# CONFIG_SCSI_LOGGING is not set
433# CONFIG_SCSI_SCAN_ASYNC is not set
434CONFIG_SCSI_WAIT_SCAN=m
435
436#
437# SCSI Transports
438#
439# CONFIG_SCSI_SPI_ATTRS is not set
440# CONFIG_SCSI_FC_ATTRS is not set
441# CONFIG_SCSI_ISCSI_ATTRS is not set
442# CONFIG_SCSI_SAS_LIBSAS is not set
443# CONFIG_SCSI_SRP_ATTRS is not set
444# CONFIG_SCSI_LOWLEVEL is not set
445CONFIG_ATA=m
446# CONFIG_ATA_NONSTANDARD is not set
447CONFIG_PATA_AT32=m
448# CONFIG_PATA_PLATFORM is not set
449# CONFIG_MD is not set
395CONFIG_NETDEVICES=y 450CONFIG_NETDEVICES=y
396CONFIG_DUMMY=y 451# CONFIG_NETDEVICES_MULTIQUEUE is not set
452# CONFIG_DUMMY is not set
397# CONFIG_BONDING is not set 453# CONFIG_BONDING is not set
454# CONFIG_MACVLAN is not set
398# CONFIG_EQUALIZER is not set 455# CONFIG_EQUALIZER is not set
399CONFIG_TUN=m 456CONFIG_TUN=m
400# CONFIG_PHYLIB is not set 457# CONFIG_VETH is not set
401 458CONFIG_PHYLIB=y
402# 459
403# Ethernet (10 or 100Mbit) 460#
404# 461# MII PHY device drivers
462#
463# CONFIG_MARVELL_PHY is not set
464# CONFIG_DAVICOM_PHY is not set
465# CONFIG_QSEMI_PHY is not set
466# CONFIG_LXT_PHY is not set
467# CONFIG_CICADA_PHY is not set
468# CONFIG_VITESSE_PHY is not set
469# CONFIG_SMSC_PHY is not set
470# CONFIG_BROADCOM_PHY is not set
471# CONFIG_ICPLUS_PHY is not set
472# CONFIG_FIXED_PHY is not set
473# CONFIG_MDIO_BITBANG is not set
405CONFIG_NET_ETHERNET=y 474CONFIG_NET_ETHERNET=y
406CONFIG_MII=y 475# CONFIG_MII is not set
407CONFIG_MACB=y 476CONFIG_MACB=y
477# CONFIG_IBM_NEW_EMAC_ZMII is not set
478# CONFIG_IBM_NEW_EMAC_RGMII is not set
479# CONFIG_IBM_NEW_EMAC_TAH is not set
480# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
481# CONFIG_B44 is not set
408# CONFIG_NETDEV_1000 is not set 482# CONFIG_NETDEV_1000 is not set
409# CONFIG_NETDEV_10000 is not set 483# CONFIG_NETDEV_10000 is not set
410 484
@@ -423,27 +497,54 @@ CONFIG_PPP_DEFLATE=m
423CONFIG_PPP_BSDCOMP=m 497CONFIG_PPP_BSDCOMP=m
424# CONFIG_PPP_MPPE is not set 498# CONFIG_PPP_MPPE is not set
425# CONFIG_PPPOE is not set 499# CONFIG_PPPOE is not set
500# CONFIG_PPPOL2TP is not set
426# CONFIG_SLIP is not set 501# CONFIG_SLIP is not set
427CONFIG_SLHC=m 502CONFIG_SLHC=m
428# CONFIG_SHAPER is not set 503# CONFIG_SHAPER is not set
429# CONFIG_NETCONSOLE is not set 504# CONFIG_NETCONSOLE is not set
430# CONFIG_NETPOLL is not set 505# CONFIG_NETPOLL is not set
431# CONFIG_NET_POLL_CONTROLLER is not set 506# CONFIG_NET_POLL_CONTROLLER is not set
507# CONFIG_ISDN is not set
508# CONFIG_PHONE is not set
432 509
433# 510#
434# ISDN subsystem 511# Input device support
435# 512#
436# CONFIG_ISDN is not set 513CONFIG_INPUT=m
514# CONFIG_INPUT_FF_MEMLESS is not set
515CONFIG_INPUT_POLLDEV=m
437 516
438# 517#
439# Telephony Support 518# Userland interfaces
440# 519#
441# CONFIG_PHONE is not set 520CONFIG_INPUT_MOUSEDEV=m
521CONFIG_INPUT_MOUSEDEV_PSAUX=y
522CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
523CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
524# CONFIG_INPUT_JOYDEV is not set
525CONFIG_INPUT_EVDEV=m
526# CONFIG_INPUT_EVBUG is not set
442 527
443# 528#
444# Input device support 529# Input Device Drivers
445# 530#
446# CONFIG_INPUT is not set 531CONFIG_INPUT_KEYBOARD=y
532# CONFIG_KEYBOARD_ATKBD is not set
533# CONFIG_KEYBOARD_SUNKBD is not set
534# CONFIG_KEYBOARD_LKKBD is not set
535# CONFIG_KEYBOARD_XTKBD is not set
536# CONFIG_KEYBOARD_NEWTON is not set
537# CONFIG_KEYBOARD_STOWAWAY is not set
538CONFIG_KEYBOARD_GPIO=m
539CONFIG_INPUT_MOUSE=y
540# CONFIG_MOUSE_PS2 is not set
541# CONFIG_MOUSE_SERIAL is not set
542# CONFIG_MOUSE_VSXXXAA is not set
543CONFIG_MOUSE_GPIO=m
544# CONFIG_INPUT_JOYSTICK is not set
545# CONFIG_INPUT_TABLET is not set
546# CONFIG_INPUT_TOUCHSCREEN is not set
547# CONFIG_INPUT_MISC is not set
447 548
448# 549#
449# Hardware I/O ports 550# Hardware I/O ports
@@ -472,35 +573,87 @@ CONFIG_SERIAL_CORE=y
472CONFIG_SERIAL_CORE_CONSOLE=y 573CONFIG_SERIAL_CORE_CONSOLE=y
473CONFIG_UNIX98_PTYS=y 574CONFIG_UNIX98_PTYS=y
474# CONFIG_LEGACY_PTYS is not set 575# CONFIG_LEGACY_PTYS is not set
475
476#
477# IPMI
478#
479# CONFIG_IPMI_HANDLER is not set 576# CONFIG_IPMI_HANDLER is not set
480# CONFIG_WATCHDOG is not set
481# CONFIG_HW_RANDOM is not set 577# CONFIG_HW_RANDOM is not set
482# CONFIG_RTC is not set 578# CONFIG_RTC is not set
483# CONFIG_GEN_RTC is not set 579# CONFIG_GEN_RTC is not set
484# CONFIG_R3964 is not set 580# CONFIG_R3964 is not set
485# CONFIG_RAW_DRIVER is not set 581# CONFIG_RAW_DRIVER is not set
582# CONFIG_TCG_TPM is not set
583CONFIG_I2C=m
584CONFIG_I2C_BOARDINFO=y
585CONFIG_I2C_CHARDEV=m
486 586
487# 587#
488# TPM devices 588# I2C Algorithms
489# 589#
490# CONFIG_TCG_TPM is not set 590CONFIG_I2C_ALGOBIT=m
491# CONFIG_I2C is not set 591# CONFIG_I2C_ALGOPCF is not set
592# CONFIG_I2C_ALGOPCA is not set
593
594#
595# I2C Hardware Bus support
596#
597CONFIG_I2C_GPIO=m
598# CONFIG_I2C_OCORES is not set
599# CONFIG_I2C_PARPORT_LIGHT is not set
600# CONFIG_I2C_SIMTEC is not set
601# CONFIG_I2C_TAOS_EVM is not set
602# CONFIG_I2C_STUB is not set
603
604#
605# Miscellaneous I2C Chip support
606#
607# CONFIG_SENSORS_DS1337 is not set
608# CONFIG_SENSORS_DS1374 is not set
609# CONFIG_DS1682 is not set
610# CONFIG_SENSORS_EEPROM is not set
611# CONFIG_SENSORS_PCF8574 is not set
612# CONFIG_SENSORS_PCA9539 is not set
613# CONFIG_SENSORS_PCF8591 is not set
614# CONFIG_SENSORS_MAX6875 is not set
615# CONFIG_SENSORS_TSL2550 is not set
616# CONFIG_I2C_DEBUG_CORE is not set
617# CONFIG_I2C_DEBUG_ALGO is not set
618# CONFIG_I2C_DEBUG_BUS is not set
619# CONFIG_I2C_DEBUG_CHIP is not set
492 620
493# 621#
494# SPI support 622# SPI support
495# 623#
496# CONFIG_SPI is not set 624CONFIG_SPI=y
497# CONFIG_SPI_MASTER is not set 625# CONFIG_SPI_DEBUG is not set
626CONFIG_SPI_MASTER=y
627
628#
629# SPI Master Controller Drivers
630#
631CONFIG_SPI_ATMEL=y
632# CONFIG_SPI_BITBANG is not set
498 633
499# 634#
500# Dallas's 1-wire bus 635# SPI Protocol Masters
501# 636#
637# CONFIG_SPI_AT25 is not set
638CONFIG_SPI_SPIDEV=m
639# CONFIG_SPI_TLE62X0 is not set
502# CONFIG_W1 is not set 640# CONFIG_W1 is not set
641# CONFIG_POWER_SUPPLY is not set
503# CONFIG_HWMON is not set 642# CONFIG_HWMON is not set
643CONFIG_WATCHDOG=y
644# CONFIG_WATCHDOG_NOWAYOUT is not set
645
646#
647# Watchdog Device Drivers
648#
649# CONFIG_SOFT_WATCHDOG is not set
650CONFIG_AT32AP700X_WDT=y
651
652#
653# Sonics Silicon Backplane
654#
655CONFIG_SSB_POSSIBLE=y
656# CONFIG_SSB is not set
504 657
505# 658#
506# Multifunction device drivers 659# Multifunction device drivers
@@ -517,23 +670,94 @@ CONFIG_UNIX98_PTYS=y
517# 670#
518# Graphics support 671# Graphics support
519# 672#
520# CONFIG_BACKLIGHT_LCD_SUPPORT is not set 673# CONFIG_VGASTATE is not set
674# CONFIG_VIDEO_OUTPUT_CONTROL is not set
675CONFIG_FB=y
676# CONFIG_FIRMWARE_EDID is not set
677# CONFIG_FB_DDC is not set
678CONFIG_FB_CFB_FILLRECT=y
679CONFIG_FB_CFB_COPYAREA=y
680CONFIG_FB_CFB_IMAGEBLIT=y
681# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
682# CONFIG_FB_SYS_FILLRECT is not set
683# CONFIG_FB_SYS_COPYAREA is not set
684# CONFIG_FB_SYS_IMAGEBLIT is not set
685# CONFIG_FB_SYS_FOPS is not set
686CONFIG_FB_DEFERRED_IO=y
687# CONFIG_FB_SVGALIB is not set
688# CONFIG_FB_MACMODES is not set
689# CONFIG_FB_BACKLIGHT is not set
690# CONFIG_FB_MODE_HELPERS is not set
691# CONFIG_FB_TILEBLITTING is not set
692
693#
694# Frame buffer hardware drivers
695#
696# CONFIG_FB_S1D13XXX is not set
697CONFIG_FB_ATMEL=y
698# CONFIG_FB_VIRTUAL is not set
699CONFIG_BACKLIGHT_LCD_SUPPORT=y
700CONFIG_LCD_CLASS_DEVICE=y
701CONFIG_LCD_LTV350QV=y
702# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
521 703
522# 704#
523# Display device support 705# Display device support
524# 706#
525# CONFIG_DISPLAY_SUPPORT is not set 707# CONFIG_DISPLAY_SUPPORT is not set
526# CONFIG_VGASTATE is not set 708# CONFIG_LOGO is not set
527# CONFIG_FB is not set
528 709
529# 710#
530# Sound 711# Sound
531# 712#
532# CONFIG_SOUND is not set 713CONFIG_SOUND=m
714
715#
716# Advanced Linux Sound Architecture
717#
718CONFIG_SND=m
719CONFIG_SND_TIMER=m
720CONFIG_SND_PCM=m
721# CONFIG_SND_SEQUENCER is not set
722CONFIG_SND_OSSEMUL=y
723CONFIG_SND_MIXER_OSS=m
724CONFIG_SND_PCM_OSS=m
725CONFIG_SND_PCM_OSS_PLUGINS=y
726# CONFIG_SND_DYNAMIC_MINORS is not set
727# CONFIG_SND_SUPPORT_OLD_API is not set
728# CONFIG_SND_VERBOSE_PROCFS is not set
729# CONFIG_SND_VERBOSE_PRINTK is not set
730# CONFIG_SND_DEBUG is not set
533 731
534# 732#
535# USB support 733# Generic devices
734#
735# CONFIG_SND_DUMMY is not set
736# CONFIG_SND_MTPAV is not set
737# CONFIG_SND_SERIAL_U16550 is not set
738# CONFIG_SND_MPU401 is not set
739
536# 740#
741# SPI devices
742#
743CONFIG_SND_AT73C213=m
744CONFIG_SND_AT73C213_TARGET_BITRATE=48000
745
746#
747# System on Chip audio support
748#
749# CONFIG_SND_SOC is not set
750
751#
752# SoC Audio support for SuperH
753#
754
755#
756# Open Sound System
757#
758# CONFIG_SOUND_PRIME is not set
759# CONFIG_HID_SUPPORT is not set
760CONFIG_USB_SUPPORT=y
537# CONFIG_USB_ARCH_HAS_HCD is not set 761# CONFIG_USB_ARCH_HAS_HCD is not set
538# CONFIG_USB_ARCH_HAS_OHCI is not set 762# CONFIG_USB_ARCH_HAS_OHCI is not set
539# CONFIG_USB_ARCH_HAS_EHCI is not set 763# CONFIG_USB_ARCH_HAS_EHCI is not set
@@ -545,47 +769,116 @@ CONFIG_UNIX98_PTYS=y
545# 769#
546# USB Gadget Support 770# USB Gadget Support
547# 771#
548# CONFIG_USB_GADGET is not set 772CONFIG_USB_GADGET=y
549# CONFIG_MMC is not set 773# CONFIG_USB_GADGET_DEBUG is not set
550 774# CONFIG_USB_GADGET_DEBUG_FILES is not set
551# 775# CONFIG_USB_GADGET_DEBUG_FS is not set
552# LED devices 776CONFIG_USB_GADGET_SELECTED=y
553# 777# CONFIG_USB_GADGET_AMD5536UDC is not set
554# CONFIG_NEW_LEDS is not set 778CONFIG_USB_GADGET_ATMEL_USBA=y
779CONFIG_USB_ATMEL_USBA=y
780# CONFIG_USB_GADGET_FSL_USB2 is not set
781# CONFIG_USB_GADGET_NET2280 is not set
782# CONFIG_USB_GADGET_PXA2XX is not set
783# CONFIG_USB_GADGET_M66592 is not set
784# CONFIG_USB_GADGET_GOKU is not set
785# CONFIG_USB_GADGET_LH7A40X is not set
786# CONFIG_USB_GADGET_OMAP is not set
787# CONFIG_USB_GADGET_S3C2410 is not set
788# CONFIG_USB_GADGET_AT91 is not set
789# CONFIG_USB_GADGET_DUMMY_HCD is not set
790CONFIG_USB_GADGET_DUALSPEED=y
791CONFIG_USB_ZERO=m
792CONFIG_USB_ETH=m
793CONFIG_USB_ETH_RNDIS=y
794CONFIG_USB_GADGETFS=m
795CONFIG_USB_FILE_STORAGE=m
796# CONFIG_USB_FILE_STORAGE_TEST is not set
797CONFIG_USB_G_SERIAL=m
798# CONFIG_USB_MIDI_GADGET is not set
799CONFIG_MMC=m
800# CONFIG_MMC_DEBUG is not set
801# CONFIG_MMC_UNSAFE_RESUME is not set
802
803#
804# MMC/SD Card Drivers
805#
806CONFIG_MMC_BLOCK=m
807CONFIG_MMC_BLOCK_BOUNCE=y
808# CONFIG_SDIO_UART is not set
809
810#
811# MMC/SD Host Controller Drivers
812#
813CONFIG_MMC_SPI=m
814CONFIG_NEW_LEDS=y
815CONFIG_LEDS_CLASS=m
555 816
556# 817#
557# LED drivers 818# LED drivers
558# 819#
820CONFIG_LEDS_GPIO=m
559 821
560# 822#
561# LED Triggers 823# LED Triggers
562# 824#
825CONFIG_LEDS_TRIGGERS=y
826CONFIG_LEDS_TRIGGER_TIMER=m
827CONFIG_LEDS_TRIGGER_HEARTBEAT=m
828CONFIG_RTC_LIB=y
829CONFIG_RTC_CLASS=y
830CONFIG_RTC_HCTOSYS=y
831CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
832# CONFIG_RTC_DEBUG is not set
563 833
564# 834#
565# InfiniBand support 835# RTC interfaces
566# 836#
837CONFIG_RTC_INTF_SYSFS=y
838CONFIG_RTC_INTF_PROC=y
839CONFIG_RTC_INTF_DEV=y
840# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
841# CONFIG_RTC_DRV_TEST is not set
567 842
568# 843#
569# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) 844# I2C RTC drivers
570# 845#
846# CONFIG_RTC_DRV_DS1307 is not set
847# CONFIG_RTC_DRV_DS1374 is not set
848# CONFIG_RTC_DRV_DS1672 is not set
849# CONFIG_RTC_DRV_MAX6900 is not set
850# CONFIG_RTC_DRV_RS5C372 is not set
851# CONFIG_RTC_DRV_ISL1208 is not set
852# CONFIG_RTC_DRV_X1205 is not set
853# CONFIG_RTC_DRV_PCF8563 is not set
854# CONFIG_RTC_DRV_PCF8583 is not set
855# CONFIG_RTC_DRV_M41T80 is not set
571 856
572# 857#
573# Real Time Clock 858# SPI RTC drivers
574# 859#
575# CONFIG_RTC_CLASS is not set 860# CONFIG_RTC_DRV_RS5C348 is not set
861# CONFIG_RTC_DRV_MAX6902 is not set
576 862
577# 863#
578# DMA Engine support 864# Platform RTC drivers
579# 865#
580# CONFIG_DMA_ENGINE is not set 866# CONFIG_RTC_DRV_DS1553 is not set
867# CONFIG_RTC_DRV_STK17TA8 is not set
868# CONFIG_RTC_DRV_DS1742 is not set
869# CONFIG_RTC_DRV_M48T86 is not set
870# CONFIG_RTC_DRV_M48T59 is not set
871# CONFIG_RTC_DRV_V3020 is not set
581 872
582# 873#
583# DMA Clients 874# on-CPU RTC drivers
584# 875#
876CONFIG_RTC_DRV_AT32AP700X=y
585 877
586# 878#
587# DMA Devices 879# Userspace I/O
588# 880#
881# CONFIG_UIO is not set
589 882
590# 883#
591# File systems 884# File systems
@@ -593,8 +886,11 @@ CONFIG_UNIX98_PTYS=y
593CONFIG_EXT2_FS=m 886CONFIG_EXT2_FS=m
594# CONFIG_EXT2_FS_XATTR is not set 887# CONFIG_EXT2_FS_XATTR is not set
595# CONFIG_EXT2_FS_XIP is not set 888# CONFIG_EXT2_FS_XIP is not set
596# CONFIG_EXT3_FS is not set 889CONFIG_EXT3_FS=m
890# CONFIG_EXT3_FS_XATTR is not set
597# CONFIG_EXT4DEV_FS is not set 891# CONFIG_EXT4DEV_FS is not set
892CONFIG_JBD=m
893# CONFIG_JBD_DEBUG is not set
598# CONFIG_REISERFS_FS is not set 894# CONFIG_REISERFS_FS is not set
599# CONFIG_JFS_FS is not set 895# CONFIG_JFS_FS is not set
600# CONFIG_FS_POSIX_ACL is not set 896# CONFIG_FS_POSIX_ACL is not set
@@ -609,7 +905,7 @@ CONFIG_INOTIFY_USER=y
609# CONFIG_DNOTIFY is not set 905# CONFIG_DNOTIFY is not set
610# CONFIG_AUTOFS_FS is not set 906# CONFIG_AUTOFS_FS is not set
611# CONFIG_AUTOFS4_FS is not set 907# CONFIG_AUTOFS4_FS is not set
612# CONFIG_FUSE_FS is not set 908CONFIG_FUSE_FS=m
613 909
614# 910#
615# CD-ROM/DVD Filesystems 911# CD-ROM/DVD Filesystems
@@ -637,8 +933,7 @@ CONFIG_SYSFS=y
637CONFIG_TMPFS=y 933CONFIG_TMPFS=y
638# CONFIG_TMPFS_POSIX_ACL is not set 934# CONFIG_TMPFS_POSIX_ACL is not set
639# CONFIG_HUGETLB_PAGE is not set 935# CONFIG_HUGETLB_PAGE is not set
640CONFIG_RAMFS=y 936# CONFIG_CONFIGFS_FS is not set
641CONFIG_CONFIGFS_FS=m
642 937
643# 938#
644# Miscellaneous filesystems 939# Miscellaneous filesystems
@@ -652,11 +947,12 @@ CONFIG_CONFIGFS_FS=m
652# CONFIG_EFS_FS is not set 947# CONFIG_EFS_FS is not set
653CONFIG_JFFS2_FS=y 948CONFIG_JFFS2_FS=y
654CONFIG_JFFS2_FS_DEBUG=0 949CONFIG_JFFS2_FS_DEBUG=0
655CONFIG_JFFS2_FS_WRITEBUFFER=y 950# CONFIG_JFFS2_FS_WRITEBUFFER is not set
656# CONFIG_JFFS2_SUMMARY is not set 951# CONFIG_JFFS2_SUMMARY is not set
657# CONFIG_JFFS2_FS_XATTR is not set 952# CONFIG_JFFS2_FS_XATTR is not set
658# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set 953# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
659CONFIG_JFFS2_ZLIB=y 954CONFIG_JFFS2_ZLIB=y
955# CONFIG_JFFS2_LZO is not set
660CONFIG_JFFS2_RTIME=y 956CONFIG_JFFS2_RTIME=y
661# CONFIG_JFFS2_RUBIN is not set 957# CONFIG_JFFS2_RUBIN is not set
662# CONFIG_CRAMFS is not set 958# CONFIG_CRAMFS is not set
@@ -665,10 +961,7 @@ CONFIG_JFFS2_RTIME=y
665# CONFIG_QNX4FS_FS is not set 961# CONFIG_QNX4FS_FS is not set
666# CONFIG_SYSV_FS is not set 962# CONFIG_SYSV_FS is not set
667# CONFIG_UFS_FS is not set 963# CONFIG_UFS_FS is not set
668 964CONFIG_NETWORK_FILESYSTEMS=y
669#
670# Network File Systems
671#
672CONFIG_NFS_FS=y 965CONFIG_NFS_FS=y
673CONFIG_NFS_V3=y 966CONFIG_NFS_V3=y
674# CONFIG_NFS_V3_ACL is not set 967# CONFIG_NFS_V3_ACL is not set
@@ -688,17 +981,12 @@ CONFIG_SUNRPC=y
688# CONFIG_NCP_FS is not set 981# CONFIG_NCP_FS is not set
689# CONFIG_CODA_FS is not set 982# CONFIG_CODA_FS is not set
690# CONFIG_AFS_FS is not set 983# CONFIG_AFS_FS is not set
691# CONFIG_9P_FS is not set
692 984
693# 985#
694# Partition Types 986# Partition Types
695# 987#
696# CONFIG_PARTITION_ADVANCED is not set 988# CONFIG_PARTITION_ADVANCED is not set
697CONFIG_MSDOS_PARTITION=y 989CONFIG_MSDOS_PARTITION=y
698
699#
700# Native Language Support
701#
702CONFIG_NLS=m 990CONFIG_NLS=m
703CONFIG_NLS_DEFAULT="iso8859-1" 991CONFIG_NLS_DEFAULT="iso8859-1"
704CONFIG_NLS_CODEPAGE_437=m 992CONFIG_NLS_CODEPAGE_437=m
@@ -739,17 +1027,18 @@ CONFIG_NLS_ISO8859_1=m
739# CONFIG_NLS_KOI8_R is not set 1027# CONFIG_NLS_KOI8_R is not set
740# CONFIG_NLS_KOI8_U is not set 1028# CONFIG_NLS_KOI8_U is not set
741CONFIG_NLS_UTF8=m 1029CONFIG_NLS_UTF8=m
742
743#
744# Distributed Lock Manager
745#
746# CONFIG_DLM is not set 1030# CONFIG_DLM is not set
1031CONFIG_INSTRUMENTATION=y
1032CONFIG_PROFILING=y
1033CONFIG_OPROFILE=m
1034CONFIG_KPROBES=y
1035# CONFIG_MARKERS is not set
747 1036
748# 1037#
749# Kernel hacking 1038# Kernel hacking
750# 1039#
751CONFIG_TRACE_IRQFLAGS_SUPPORT=y
752# CONFIG_PRINTK_TIME is not set 1040# CONFIG_PRINTK_TIME is not set
1041CONFIG_ENABLE_WARN_DEPRECATED=y
753CONFIG_ENABLE_MUST_CHECK=y 1042CONFIG_ENABLE_MUST_CHECK=y
754CONFIG_MAGIC_SYSRQ=y 1043CONFIG_MAGIC_SYSRQ=y
755# CONFIG_UNUSED_SYMBOLS is not set 1044# CONFIG_UNUSED_SYMBOLS is not set
@@ -758,12 +1047,17 @@ CONFIG_DEBUG_FS=y
758CONFIG_DEBUG_KERNEL=y 1047CONFIG_DEBUG_KERNEL=y
759# CONFIG_DEBUG_SHIRQ is not set 1048# CONFIG_DEBUG_SHIRQ is not set
760CONFIG_DETECT_SOFTLOCKUP=y 1049CONFIG_DETECT_SOFTLOCKUP=y
1050CONFIG_SCHED_DEBUG=y
761# CONFIG_SCHEDSTATS is not set 1051# CONFIG_SCHEDSTATS is not set
762# CONFIG_TIMER_STATS is not set 1052# CONFIG_TIMER_STATS is not set
1053# CONFIG_SLUB_DEBUG_ON is not set
763# CONFIG_DEBUG_RT_MUTEXES is not set 1054# CONFIG_DEBUG_RT_MUTEXES is not set
764# CONFIG_RT_MUTEX_TESTER is not set 1055# CONFIG_RT_MUTEX_TESTER is not set
765# CONFIG_DEBUG_SPINLOCK is not set 1056# CONFIG_DEBUG_SPINLOCK is not set
766# CONFIG_DEBUG_MUTEXES is not set 1057# CONFIG_DEBUG_MUTEXES is not set
1058# CONFIG_DEBUG_LOCK_ALLOC is not set
1059# CONFIG_PROVE_LOCKING is not set
1060# CONFIG_LOCK_STAT is not set
767# CONFIG_DEBUG_SPINLOCK_SLEEP is not set 1061# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
768# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set 1062# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
769# CONFIG_DEBUG_KOBJECT is not set 1063# CONFIG_DEBUG_KOBJECT is not set
@@ -771,22 +1065,63 @@ CONFIG_DEBUG_BUGVERBOSE=y
771# CONFIG_DEBUG_INFO is not set 1065# CONFIG_DEBUG_INFO is not set
772# CONFIG_DEBUG_VM is not set 1066# CONFIG_DEBUG_VM is not set
773# CONFIG_DEBUG_LIST is not set 1067# CONFIG_DEBUG_LIST is not set
1068# CONFIG_DEBUG_SG is not set
774CONFIG_FRAME_POINTER=y 1069CONFIG_FRAME_POINTER=y
775CONFIG_FORCED_INLINING=y 1070CONFIG_FORCED_INLINING=y
1071# CONFIG_BOOT_PRINTK_DELAY is not set
776# CONFIG_RCU_TORTURE_TEST is not set 1072# CONFIG_RCU_TORTURE_TEST is not set
1073# CONFIG_LKDTM is not set
777# CONFIG_FAULT_INJECTION is not set 1074# CONFIG_FAULT_INJECTION is not set
778# CONFIG_KPROBES is not set 1075# CONFIG_SAMPLES is not set
779 1076
780# 1077#
781# Security options 1078# Security options
782# 1079#
783# CONFIG_KEYS is not set 1080# CONFIG_KEYS is not set
784# CONFIG_SECURITY is not set 1081# CONFIG_SECURITY is not set
785 1082# CONFIG_SECURITY_FILE_CAPABILITIES is not set
786# 1083CONFIG_CRYPTO=y
787# Cryptographic options 1084CONFIG_CRYPTO_ALGAPI=m
788# 1085CONFIG_CRYPTO_BLKCIPHER=m
789# CONFIG_CRYPTO is not set 1086CONFIG_CRYPTO_HASH=m
1087CONFIG_CRYPTO_MANAGER=m
1088CONFIG_CRYPTO_HMAC=m
1089# CONFIG_CRYPTO_XCBC is not set
1090# CONFIG_CRYPTO_NULL is not set
1091# CONFIG_CRYPTO_MD4 is not set
1092CONFIG_CRYPTO_MD5=m
1093CONFIG_CRYPTO_SHA1=m
1094# CONFIG_CRYPTO_SHA256 is not set
1095# CONFIG_CRYPTO_SHA512 is not set
1096# CONFIG_CRYPTO_WP512 is not set
1097# CONFIG_CRYPTO_TGR192 is not set
1098# CONFIG_CRYPTO_GF128MUL is not set
1099# CONFIG_CRYPTO_ECB is not set
1100CONFIG_CRYPTO_CBC=m
1101# CONFIG_CRYPTO_PCBC is not set
1102# CONFIG_CRYPTO_LRW is not set
1103# CONFIG_CRYPTO_XTS is not set
1104# CONFIG_CRYPTO_CRYPTD is not set
1105CONFIG_CRYPTO_DES=m
1106# CONFIG_CRYPTO_FCRYPT is not set
1107# CONFIG_CRYPTO_BLOWFISH is not set
1108# CONFIG_CRYPTO_TWOFISH is not set
1109# CONFIG_CRYPTO_SERPENT is not set
1110# CONFIG_CRYPTO_AES is not set
1111# CONFIG_CRYPTO_CAST5 is not set
1112# CONFIG_CRYPTO_CAST6 is not set
1113# CONFIG_CRYPTO_TEA is not set
1114# CONFIG_CRYPTO_ARC4 is not set
1115# CONFIG_CRYPTO_KHAZAD is not set
1116# CONFIG_CRYPTO_ANUBIS is not set
1117# CONFIG_CRYPTO_SEED is not set
1118CONFIG_CRYPTO_DEFLATE=m
1119# CONFIG_CRYPTO_MICHAEL_MIC is not set
1120# CONFIG_CRYPTO_CRC32C is not set
1121# CONFIG_CRYPTO_CAMELLIA is not set
1122# CONFIG_CRYPTO_TEST is not set
1123# CONFIG_CRYPTO_AUTHENC is not set
1124# CONFIG_CRYPTO_HW is not set
790 1125
791# 1126#
792# Library routines 1127# Library routines
@@ -794,10 +1129,10 @@ CONFIG_FORCED_INLINING=y
794CONFIG_BITREVERSE=y 1129CONFIG_BITREVERSE=y
795CONFIG_CRC_CCITT=m 1130CONFIG_CRC_CCITT=m
796# CONFIG_CRC16 is not set 1131# CONFIG_CRC16 is not set
797# CONFIG_CRC_ITU_T is not set 1132CONFIG_CRC_ITU_T=m
798CONFIG_CRC32=y 1133CONFIG_CRC32=y
1134CONFIG_CRC7=m
799# CONFIG_LIBCRC32C is not set 1135# CONFIG_LIBCRC32C is not set
800CONFIG_AUDIT_GENERIC=y
801CONFIG_ZLIB_INFLATE=y 1136CONFIG_ZLIB_INFLATE=y
802CONFIG_ZLIB_DEFLATE=y 1137CONFIG_ZLIB_DEFLATE=y
803CONFIG_PLIST=y 1138CONFIG_PLIST=y
diff --git a/arch/avr32/configs/atstk1003_defconfig b/arch/avr32/configs/atstk1003_defconfig
new file mode 100644
index 000000000000..45e23e03f074
--- /dev/null
+++ b/arch/avr32/configs/atstk1003_defconfig
@@ -0,0 +1,1015 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.24-rc7
4# Wed Jan 9 22:54:34 2008
5#
6CONFIG_AVR32=y
7CONFIG_GENERIC_GPIO=y
8CONFIG_GENERIC_HARDIRQS=y
9CONFIG_STACKTRACE_SUPPORT=y
10CONFIG_LOCKDEP_SUPPORT=y
11CONFIG_TRACE_IRQFLAGS_SUPPORT=y
12CONFIG_HARDIRQS_SW_RESEND=y
13CONFIG_GENERIC_IRQ_PROBE=y
14CONFIG_RWSEM_GENERIC_SPINLOCK=y
15CONFIG_GENERIC_TIME=y
16# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
17# CONFIG_ARCH_HAS_ILOG2_U32 is not set
18# CONFIG_ARCH_HAS_ILOG2_U64 is not set
19CONFIG_ARCH_SUPPORTS_OPROFILE=y
20CONFIG_GENERIC_HWEIGHT=y
21CONFIG_GENERIC_CALIBRATE_DELAY=y
22CONFIG_GENERIC_BUG=y
23CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
24
25#
26# General setup
27#
28CONFIG_EXPERIMENTAL=y
29CONFIG_BROKEN_ON_SMP=y
30CONFIG_INIT_ENV_ARG_LIMIT=32
31CONFIG_LOCALVERSION=""
32# CONFIG_LOCALVERSION_AUTO is not set
33CONFIG_SWAP=y
34CONFIG_SYSVIPC=y
35CONFIG_SYSVIPC_SYSCTL=y
36CONFIG_POSIX_MQUEUE=y
37CONFIG_BSD_PROCESS_ACCT=y
38CONFIG_BSD_PROCESS_ACCT_V3=y
39CONFIG_TASKSTATS=y
40CONFIG_TASK_DELAY_ACCT=y
41# CONFIG_TASK_XACCT is not set
42# CONFIG_USER_NS is not set
43# CONFIG_PID_NS is not set
44CONFIG_AUDIT=y
45# CONFIG_IKCONFIG is not set
46CONFIG_LOG_BUF_SHIFT=14
47# CONFIG_CGROUPS is not set
48CONFIG_FAIR_GROUP_SCHED=y
49CONFIG_FAIR_USER_SCHED=y
50# CONFIG_FAIR_CGROUP_SCHED is not set
51CONFIG_SYSFS_DEPRECATED=y
52CONFIG_RELAY=y
53CONFIG_BLK_DEV_INITRD=y
54CONFIG_INITRAMFS_SOURCE=""
55CONFIG_CC_OPTIMIZE_FOR_SIZE=y
56CONFIG_SYSCTL=y
57CONFIG_EMBEDDED=y
58# CONFIG_SYSCTL_SYSCALL is not set
59CONFIG_KALLSYMS=y
60# CONFIG_KALLSYMS_ALL is not set
61# CONFIG_KALLSYMS_EXTRA_PASS is not set
62CONFIG_HOTPLUG=y
63CONFIG_PRINTK=y
64CONFIG_BUG=y
65CONFIG_ELF_CORE=y
66# CONFIG_BASE_FULL is not set
67CONFIG_FUTEX=y
68CONFIG_ANON_INODES=y
69CONFIG_EPOLL=y
70CONFIG_SIGNALFD=y
71CONFIG_EVENTFD=y
72CONFIG_SHMEM=y
73CONFIG_VM_EVENT_COUNTERS=y
74# CONFIG_SLUB_DEBUG is not set
75# CONFIG_SLAB is not set
76CONFIG_SLUB=y
77# CONFIG_SLOB is not set
78CONFIG_SLABINFO=y
79CONFIG_RT_MUTEXES=y
80# CONFIG_TINY_SHMEM is not set
81CONFIG_BASE_SMALL=1
82CONFIG_MODULES=y
83CONFIG_MODULE_UNLOAD=y
84# CONFIG_MODULE_FORCE_UNLOAD is not set
85# CONFIG_MODVERSIONS is not set
86# CONFIG_MODULE_SRCVERSION_ALL is not set
87# CONFIG_KMOD is not set
88CONFIG_BLOCK=y
89# CONFIG_LBD is not set
90# CONFIG_BLK_DEV_IO_TRACE is not set
91# CONFIG_LSF is not set
92# CONFIG_BLK_DEV_BSG is not set
93
94#
95# IO Schedulers
96#
97CONFIG_IOSCHED_NOOP=y
98# CONFIG_IOSCHED_AS is not set
99# CONFIG_IOSCHED_DEADLINE is not set
100CONFIG_IOSCHED_CFQ=y
101# CONFIG_DEFAULT_AS is not set
102# CONFIG_DEFAULT_DEADLINE is not set
103CONFIG_DEFAULT_CFQ=y
104# CONFIG_DEFAULT_NOOP is not set
105CONFIG_DEFAULT_IOSCHED="cfq"
106
107#
108# System Type and features
109#
110CONFIG_SUBARCH_AVR32B=y
111CONFIG_MMU=y
112CONFIG_PERFORMANCE_COUNTERS=y
113CONFIG_PLATFORM_AT32AP=y
114CONFIG_CPU_AT32AP700X=y
115CONFIG_CPU_AT32AP7001=y
116CONFIG_BOARD_ATSTK1000=y
117# CONFIG_BOARD_ATNGW100 is not set
118# CONFIG_BOARD_ATSTK1002 is not set
119CONFIG_BOARD_ATSTK1003=y
120# CONFIG_BOARD_ATSTK1004 is not set
121# CONFIG_BOARD_ATSTK100X_CUSTOM is not set
122# CONFIG_BOARD_ATSTK100X_SPI1 is not set
123# CONFIG_BOARD_ATSTK1000_J2_LED is not set
124# CONFIG_BOARD_ATSTK1000_J2_LED8 is not set
125# CONFIG_BOARD_ATSTK1000_J2_RGB is not set
126CONFIG_BOARD_ATSTK1000_EXTDAC=y
127CONFIG_LOADER_U_BOOT=y
128
129#
130# Atmel AVR32 AP options
131#
132# CONFIG_AP700X_32_BIT_SMC is not set
133CONFIG_AP700X_16_BIT_SMC=y
134# CONFIG_AP700X_8_BIT_SMC is not set
135CONFIG_LOAD_ADDRESS=0x10000000
136CONFIG_ENTRY_ADDRESS=0x90000000
137CONFIG_PHYS_OFFSET=0x10000000
138CONFIG_PREEMPT_NONE=y
139# CONFIG_PREEMPT_VOLUNTARY is not set
140# CONFIG_PREEMPT is not set
141# CONFIG_HAVE_ARCH_BOOTMEM_NODE is not set
142# CONFIG_ARCH_HAVE_MEMORY_PRESENT is not set
143# CONFIG_NEED_NODE_MEMMAP_SIZE is not set
144CONFIG_ARCH_FLATMEM_ENABLE=y
145# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
146# CONFIG_ARCH_SPARSEMEM_ENABLE is not set
147CONFIG_SELECT_MEMORY_MODEL=y
148CONFIG_FLATMEM_MANUAL=y
149# CONFIG_DISCONTIGMEM_MANUAL is not set
150# CONFIG_SPARSEMEM_MANUAL is not set
151CONFIG_FLATMEM=y
152CONFIG_FLAT_NODE_MEM_MAP=y
153# CONFIG_SPARSEMEM_STATIC is not set
154# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
155CONFIG_SPLIT_PTLOCK_CPUS=4
156# CONFIG_RESOURCES_64BIT is not set
157CONFIG_ZONE_DMA_FLAG=0
158CONFIG_VIRT_TO_BUS=y
159# CONFIG_OWNERSHIP_TRACE is not set
160# CONFIG_HZ_100 is not set
161CONFIG_HZ_250=y
162# CONFIG_HZ_300 is not set
163# CONFIG_HZ_1000 is not set
164CONFIG_HZ=250
165CONFIG_CMDLINE=""
166
167#
168# Power management options
169#
170
171#
172# CPU Frequency scaling
173#
174CONFIG_CPU_FREQ=y
175CONFIG_CPU_FREQ_TABLE=y
176# CONFIG_CPU_FREQ_DEBUG is not set
177# CONFIG_CPU_FREQ_STAT is not set
178CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
179# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
180# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
181# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
182CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
183# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
184CONFIG_CPU_FREQ_GOV_USERSPACE=y
185CONFIG_CPU_FREQ_GOV_ONDEMAND=y
186# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
187CONFIG_CPU_FREQ_AT32AP=y
188
189#
190# Bus options
191#
192# CONFIG_ARCH_SUPPORTS_MSI is not set
193# CONFIG_PCCARD is not set
194
195#
196# Executable file formats
197#
198CONFIG_BINFMT_ELF=y
199# CONFIG_BINFMT_MISC is not set
200
201#
202# Networking
203#
204CONFIG_NET=y
205
206#
207# Networking options
208#
209CONFIG_PACKET=y
210CONFIG_PACKET_MMAP=y
211CONFIG_UNIX=y
212# CONFIG_NET_KEY is not set
213CONFIG_INET=y
214# CONFIG_IP_MULTICAST is not set
215# CONFIG_IP_ADVANCED_ROUTER is not set
216CONFIG_IP_FIB_HASH=y
217# CONFIG_IP_PNP is not set
218# CONFIG_NET_IPIP is not set
219# CONFIG_NET_IPGRE is not set
220# CONFIG_ARPD is not set
221# CONFIG_SYN_COOKIES is not set
222# CONFIG_INET_AH is not set
223# CONFIG_INET_ESP is not set
224# CONFIG_INET_IPCOMP is not set
225# CONFIG_INET_XFRM_TUNNEL is not set
226# CONFIG_INET_TUNNEL is not set
227# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
228# CONFIG_INET_XFRM_MODE_TUNNEL is not set
229# CONFIG_INET_XFRM_MODE_BEET is not set
230# CONFIG_INET_LRO is not set
231# CONFIG_INET_DIAG is not set
232# CONFIG_TCP_CONG_ADVANCED is not set
233CONFIG_TCP_CONG_CUBIC=y
234CONFIG_DEFAULT_TCP_CONG="cubic"
235# CONFIG_TCP_MD5SIG is not set
236# CONFIG_IPV6 is not set
237# CONFIG_INET6_XFRM_TUNNEL is not set
238# CONFIG_INET6_TUNNEL is not set
239# CONFIG_NETWORK_SECMARK is not set
240# CONFIG_NETFILTER is not set
241# CONFIG_IP_DCCP is not set
242# CONFIG_IP_SCTP is not set
243# CONFIG_TIPC is not set
244# CONFIG_ATM is not set
245# CONFIG_BRIDGE is not set
246# CONFIG_VLAN_8021Q is not set
247# CONFIG_DECNET is not set
248# CONFIG_LLC2 is not set
249# CONFIG_IPX is not set
250# CONFIG_ATALK is not set
251# CONFIG_X25 is not set
252# CONFIG_LAPB is not set
253# CONFIG_ECONET is not set
254# CONFIG_WAN_ROUTER is not set
255# CONFIG_NET_SCHED is not set
256
257#
258# Network testing
259#
260# CONFIG_NET_PKTGEN is not set
261# CONFIG_NET_TCPPROBE is not set
262# CONFIG_HAMRADIO is not set
263# CONFIG_IRDA is not set
264# CONFIG_BT is not set
265# CONFIG_AF_RXRPC is not set
266
267#
268# Wireless
269#
270# CONFIG_CFG80211 is not set
271# CONFIG_WIRELESS_EXT is not set
272# CONFIG_MAC80211 is not set
273# CONFIG_IEEE80211 is not set
274# CONFIG_RFKILL is not set
275# CONFIG_NET_9P is not set
276
277#
278# Device Drivers
279#
280
281#
282# Generic Driver Options
283#
284CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
285CONFIG_STANDALONE=y
286# CONFIG_PREVENT_FIRMWARE_BUILD is not set
287# CONFIG_FW_LOADER is not set
288# CONFIG_DEBUG_DRIVER is not set
289# CONFIG_DEBUG_DEVRES is not set
290# CONFIG_SYS_HYPERVISOR is not set
291# CONFIG_CONNECTOR is not set
292CONFIG_MTD=y
293# CONFIG_MTD_DEBUG is not set
294# CONFIG_MTD_CONCAT is not set
295CONFIG_MTD_PARTITIONS=y
296# CONFIG_MTD_REDBOOT_PARTS is not set
297CONFIG_MTD_CMDLINE_PARTS=y
298
299#
300# User Modules And Translation Layers
301#
302CONFIG_MTD_CHAR=y
303CONFIG_MTD_BLKDEVS=y
304CONFIG_MTD_BLOCK=y
305# CONFIG_FTL is not set
306# CONFIG_NFTL is not set
307# CONFIG_INFTL is not set
308# CONFIG_RFD_FTL is not set
309# CONFIG_SSFDC is not set
310# CONFIG_MTD_OOPS is not set
311
312#
313# RAM/ROM/Flash chip drivers
314#
315CONFIG_MTD_CFI=y
316# CONFIG_MTD_JEDECPROBE is not set
317CONFIG_MTD_GEN_PROBE=y
318# CONFIG_MTD_CFI_ADV_OPTIONS is not set
319CONFIG_MTD_MAP_BANK_WIDTH_1=y
320CONFIG_MTD_MAP_BANK_WIDTH_2=y
321CONFIG_MTD_MAP_BANK_WIDTH_4=y
322# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
323# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
324# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
325CONFIG_MTD_CFI_I1=y
326CONFIG_MTD_CFI_I2=y
327# CONFIG_MTD_CFI_I4 is not set
328# CONFIG_MTD_CFI_I8 is not set
329# CONFIG_MTD_CFI_INTELEXT is not set
330CONFIG_MTD_CFI_AMDSTD=y
331# CONFIG_MTD_CFI_STAA is not set
332CONFIG_MTD_CFI_UTIL=y
333# CONFIG_MTD_RAM is not set
334# CONFIG_MTD_ROM is not set
335# CONFIG_MTD_ABSENT is not set
336
337#
338# Mapping drivers for chip access
339#
340# CONFIG_MTD_COMPLEX_MAPPINGS is not set
341CONFIG_MTD_PHYSMAP=y
342CONFIG_MTD_PHYSMAP_START=0x8000000
343CONFIG_MTD_PHYSMAP_LEN=0x0
344CONFIG_MTD_PHYSMAP_BANKWIDTH=2
345# CONFIG_MTD_PLATRAM is not set
346
347#
348# Self-contained MTD device drivers
349#
350CONFIG_MTD_DATAFLASH=m
351CONFIG_MTD_M25P80=m
352# CONFIG_MTD_SLRAM is not set
353# CONFIG_MTD_PHRAM is not set
354# CONFIG_MTD_MTDRAM is not set
355# CONFIG_MTD_BLOCK2MTD is not set
356
357#
358# Disk-On-Chip Device Drivers
359#
360# CONFIG_MTD_DOC2000 is not set
361# CONFIG_MTD_DOC2001 is not set
362# CONFIG_MTD_DOC2001PLUS is not set
363# CONFIG_MTD_NAND is not set
364# CONFIG_MTD_ONENAND is not set
365
366#
367# UBI - Unsorted block images
368#
369# CONFIG_MTD_UBI is not set
370# CONFIG_PARPORT is not set
371CONFIG_BLK_DEV=y
372# CONFIG_BLK_DEV_COW_COMMON is not set
373CONFIG_BLK_DEV_LOOP=m
374# CONFIG_BLK_DEV_CRYPTOLOOP is not set
375CONFIG_BLK_DEV_NBD=m
376CONFIG_BLK_DEV_RAM=m
377CONFIG_BLK_DEV_RAM_COUNT=16
378CONFIG_BLK_DEV_RAM_SIZE=4096
379CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
380# CONFIG_CDROM_PKTCDVD is not set
381# CONFIG_ATA_OVER_ETH is not set
382CONFIG_MISC_DEVICES=y
383# CONFIG_EEPROM_93CX6 is not set
384CONFIG_ATMEL_SSC=m
385# CONFIG_IDE is not set
386
387#
388# SCSI device support
389#
390# CONFIG_RAID_ATTRS is not set
391CONFIG_SCSI=m
392CONFIG_SCSI_DMA=y
393# CONFIG_SCSI_TGT is not set
394# CONFIG_SCSI_NETLINK is not set
395# CONFIG_SCSI_PROC_FS is not set
396
397#
398# SCSI support type (disk, tape, CD-ROM)
399#
400CONFIG_BLK_DEV_SD=m
401# CONFIG_CHR_DEV_ST is not set
402# CONFIG_CHR_DEV_OSST is not set
403CONFIG_BLK_DEV_SR=m
404# CONFIG_BLK_DEV_SR_VENDOR is not set
405# CONFIG_CHR_DEV_SG is not set
406# CONFIG_CHR_DEV_SCH is not set
407
408#
409# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
410#
411# CONFIG_SCSI_MULTI_LUN is not set
412# CONFIG_SCSI_CONSTANTS is not set
413# CONFIG_SCSI_LOGGING is not set
414# CONFIG_SCSI_SCAN_ASYNC is not set
415CONFIG_SCSI_WAIT_SCAN=m
416
417#
418# SCSI Transports
419#
420# CONFIG_SCSI_SPI_ATTRS is not set
421# CONFIG_SCSI_FC_ATTRS is not set
422# CONFIG_SCSI_ISCSI_ATTRS is not set
423# CONFIG_SCSI_SAS_LIBSAS is not set
424# CONFIG_SCSI_SRP_ATTRS is not set
425CONFIG_SCSI_LOWLEVEL=y
426# CONFIG_ISCSI_TCP is not set
427# CONFIG_SCSI_DEBUG is not set
428CONFIG_ATA=m
429# CONFIG_ATA_NONSTANDARD is not set
430CONFIG_PATA_AT32=m
431# CONFIG_PATA_PLATFORM is not set
432# CONFIG_MD is not set
433CONFIG_NETDEVICES=y
434# CONFIG_NETDEVICES_MULTIQUEUE is not set
435# CONFIG_DUMMY is not set
436# CONFIG_BONDING is not set
437# CONFIG_MACVLAN is not set
438# CONFIG_EQUALIZER is not set
439# CONFIG_TUN is not set
440# CONFIG_VETH is not set
441# CONFIG_NET_ETHERNET is not set
442# CONFIG_NETDEV_1000 is not set
443# CONFIG_NETDEV_10000 is not set
444
445#
446# Wireless LAN
447#
448# CONFIG_WLAN_PRE80211 is not set
449# CONFIG_WLAN_80211 is not set
450# CONFIG_WAN is not set
451CONFIG_PPP=m
452# CONFIG_PPP_MULTILINK is not set
453# CONFIG_PPP_FILTER is not set
454CONFIG_PPP_ASYNC=m
455# CONFIG_PPP_SYNC_TTY is not set
456CONFIG_PPP_DEFLATE=m
457CONFIG_PPP_BSDCOMP=m
458# CONFIG_PPP_MPPE is not set
459# CONFIG_PPPOE is not set
460# CONFIG_PPPOL2TP is not set
461# CONFIG_SLIP is not set
462CONFIG_SLHC=m
463# CONFIG_SHAPER is not set
464# CONFIG_NETCONSOLE is not set
465# CONFIG_NETPOLL is not set
466# CONFIG_NET_POLL_CONTROLLER is not set
467# CONFIG_ISDN is not set
468# CONFIG_PHONE is not set
469
470#
471# Input device support
472#
473CONFIG_INPUT=m
474# CONFIG_INPUT_FF_MEMLESS is not set
475CONFIG_INPUT_POLLDEV=m
476
477#
478# Userland interfaces
479#
480CONFIG_INPUT_MOUSEDEV=m
481CONFIG_INPUT_MOUSEDEV_PSAUX=y
482CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
483CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
484# CONFIG_INPUT_JOYDEV is not set
485# CONFIG_INPUT_EVDEV is not set
486# CONFIG_INPUT_EVBUG is not set
487
488#
489# Input Device Drivers
490#
491CONFIG_INPUT_KEYBOARD=y
492# CONFIG_KEYBOARD_ATKBD is not set
493# CONFIG_KEYBOARD_SUNKBD is not set
494# CONFIG_KEYBOARD_LKKBD is not set
495# CONFIG_KEYBOARD_XTKBD is not set
496# CONFIG_KEYBOARD_NEWTON is not set
497# CONFIG_KEYBOARD_STOWAWAY is not set
498CONFIG_KEYBOARD_GPIO=m
499CONFIG_INPUT_MOUSE=y
500# CONFIG_MOUSE_PS2 is not set
501# CONFIG_MOUSE_SERIAL is not set
502# CONFIG_MOUSE_VSXXXAA is not set
503CONFIG_MOUSE_GPIO=m
504# CONFIG_INPUT_JOYSTICK is not set
505# CONFIG_INPUT_TABLET is not set
506# CONFIG_INPUT_TOUCHSCREEN is not set
507# CONFIG_INPUT_MISC is not set
508
509#
510# Hardware I/O ports
511#
512# CONFIG_SERIO is not set
513# CONFIG_GAMEPORT is not set
514
515#
516# Character devices
517#
518# CONFIG_VT is not set
519# CONFIG_SERIAL_NONSTANDARD is not set
520
521#
522# Serial drivers
523#
524# CONFIG_SERIAL_8250 is not set
525
526#
527# Non-8250 serial port support
528#
529CONFIG_SERIAL_ATMEL=y
530CONFIG_SERIAL_ATMEL_CONSOLE=y
531# CONFIG_SERIAL_ATMEL_TTYAT is not set
532CONFIG_SERIAL_CORE=y
533CONFIG_SERIAL_CORE_CONSOLE=y
534CONFIG_UNIX98_PTYS=y
535# CONFIG_LEGACY_PTYS is not set
536# CONFIG_IPMI_HANDLER is not set
537# CONFIG_HW_RANDOM is not set
538# CONFIG_RTC is not set
539# CONFIG_GEN_RTC is not set
540# CONFIG_R3964 is not set
541# CONFIG_RAW_DRIVER is not set
542# CONFIG_TCG_TPM is not set
543CONFIG_I2C=m
544CONFIG_I2C_BOARDINFO=y
545CONFIG_I2C_CHARDEV=m
546
547#
548# I2C Algorithms
549#
550CONFIG_I2C_ALGOBIT=m
551# CONFIG_I2C_ALGOPCF is not set
552# CONFIG_I2C_ALGOPCA is not set
553
554#
555# I2C Hardware Bus support
556#
557CONFIG_I2C_GPIO=m
558# CONFIG_I2C_OCORES is not set
559# CONFIG_I2C_PARPORT_LIGHT is not set
560# CONFIG_I2C_SIMTEC is not set
561# CONFIG_I2C_TAOS_EVM is not set
562# CONFIG_I2C_STUB is not set
563
564#
565# Miscellaneous I2C Chip support
566#
567# CONFIG_SENSORS_DS1337 is not set
568# CONFIG_SENSORS_DS1374 is not set
569# CONFIG_DS1682 is not set
570# CONFIG_SENSORS_EEPROM is not set
571# CONFIG_SENSORS_PCF8574 is not set
572# CONFIG_SENSORS_PCA9539 is not set
573# CONFIG_SENSORS_PCF8591 is not set
574# CONFIG_SENSORS_MAX6875 is not set
575# CONFIG_SENSORS_TSL2550 is not set
576# CONFIG_I2C_DEBUG_CORE is not set
577# CONFIG_I2C_DEBUG_ALGO is not set
578# CONFIG_I2C_DEBUG_BUS is not set
579# CONFIG_I2C_DEBUG_CHIP is not set
580
581#
582# SPI support
583#
584CONFIG_SPI=y
585# CONFIG_SPI_DEBUG is not set
586CONFIG_SPI_MASTER=y
587
588#
589# SPI Master Controller Drivers
590#
591CONFIG_SPI_ATMEL=y
592# CONFIG_SPI_BITBANG is not set
593
594#
595# SPI Protocol Masters
596#
597# CONFIG_SPI_AT25 is not set
598CONFIG_SPI_SPIDEV=m
599# CONFIG_SPI_TLE62X0 is not set
600# CONFIG_W1 is not set
601# CONFIG_POWER_SUPPLY is not set
602# CONFIG_HWMON is not set
603CONFIG_WATCHDOG=y
604# CONFIG_WATCHDOG_NOWAYOUT is not set
605
606#
607# Watchdog Device Drivers
608#
609# CONFIG_SOFT_WATCHDOG is not set
610CONFIG_AT32AP700X_WDT=y
611
612#
613# Sonics Silicon Backplane
614#
615CONFIG_SSB_POSSIBLE=y
616# CONFIG_SSB is not set
617
618#
619# Multifunction device drivers
620#
621# CONFIG_MFD_SM501 is not set
622
623#
624# Multimedia devices
625#
626# CONFIG_VIDEO_DEV is not set
627# CONFIG_DVB_CORE is not set
628# CONFIG_DAB is not set
629
630#
631# Graphics support
632#
633# CONFIG_VGASTATE is not set
634# CONFIG_VIDEO_OUTPUT_CONTROL is not set
635# CONFIG_FB is not set
636# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
637
638#
639# Display device support
640#
641# CONFIG_DISPLAY_SUPPORT is not set
642
643#
644# Sound
645#
646CONFIG_SOUND=m
647
648#
649# Advanced Linux Sound Architecture
650#
651CONFIG_SND=m
652CONFIG_SND_TIMER=m
653CONFIG_SND_PCM=m
654# CONFIG_SND_SEQUENCER is not set
655CONFIG_SND_OSSEMUL=y
656CONFIG_SND_MIXER_OSS=m
657CONFIG_SND_PCM_OSS=m
658CONFIG_SND_PCM_OSS_PLUGINS=y
659# CONFIG_SND_DYNAMIC_MINORS is not set
660CONFIG_SND_SUPPORT_OLD_API=y
661CONFIG_SND_VERBOSE_PROCFS=y
662# CONFIG_SND_VERBOSE_PRINTK is not set
663# CONFIG_SND_DEBUG is not set
664
665#
666# Generic devices
667#
668# CONFIG_SND_DUMMY is not set
669# CONFIG_SND_MTPAV is not set
670# CONFIG_SND_SERIAL_U16550 is not set
671# CONFIG_SND_MPU401 is not set
672
673#
674# SPI devices
675#
676CONFIG_SND_AT73C213=m
677CONFIG_SND_AT73C213_TARGET_BITRATE=48000
678
679#
680# System on Chip audio support
681#
682# CONFIG_SND_SOC is not set
683
684#
685# SoC Audio support for SuperH
686#
687
688#
689# Open Sound System
690#
691# CONFIG_SOUND_PRIME is not set
692# CONFIG_HID_SUPPORT is not set
693CONFIG_USB_SUPPORT=y
694# CONFIG_USB_ARCH_HAS_HCD is not set
695# CONFIG_USB_ARCH_HAS_OHCI is not set
696# CONFIG_USB_ARCH_HAS_EHCI is not set
697
698#
699# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
700#
701
702#
703# USB Gadget Support
704#
705CONFIG_USB_GADGET=y
706# CONFIG_USB_GADGET_DEBUG is not set
707# CONFIG_USB_GADGET_DEBUG_FILES is not set
708CONFIG_USB_GADGET_DEBUG_FS=y
709CONFIG_USB_GADGET_SELECTED=y
710# CONFIG_USB_GADGET_AMD5536UDC is not set
711CONFIG_USB_GADGET_ATMEL_USBA=y
712CONFIG_USB_ATMEL_USBA=y
713# CONFIG_USB_GADGET_FSL_USB2 is not set
714# CONFIG_USB_GADGET_NET2280 is not set
715# CONFIG_USB_GADGET_PXA2XX is not set
716# CONFIG_USB_GADGET_M66592 is not set
717# CONFIG_USB_GADGET_GOKU is not set
718# CONFIG_USB_GADGET_LH7A40X is not set
719# CONFIG_USB_GADGET_OMAP is not set
720# CONFIG_USB_GADGET_S3C2410 is not set
721# CONFIG_USB_GADGET_AT91 is not set
722# CONFIG_USB_GADGET_DUMMY_HCD is not set
723CONFIG_USB_GADGET_DUALSPEED=y
724CONFIG_USB_ZERO=m
725CONFIG_USB_ETH=m
726CONFIG_USB_ETH_RNDIS=y
727CONFIG_USB_GADGETFS=m
728CONFIG_USB_FILE_STORAGE=m
729# CONFIG_USB_FILE_STORAGE_TEST is not set
730CONFIG_USB_G_SERIAL=m
731# CONFIG_USB_MIDI_GADGET is not set
732CONFIG_MMC=m
733# CONFIG_MMC_DEBUG is not set
734# CONFIG_MMC_UNSAFE_RESUME is not set
735
736#
737# MMC/SD Card Drivers
738#
739CONFIG_MMC_BLOCK=m
740# CONFIG_MMC_BLOCK_BOUNCE is not set
741# CONFIG_SDIO_UART is not set
742
743#
744# MMC/SD Host Controller Drivers
745#
746CONFIG_MMC_SPI=m
747CONFIG_NEW_LEDS=y
748CONFIG_LEDS_CLASS=y
749
750#
751# LED drivers
752#
753CONFIG_LEDS_GPIO=y
754
755#
756# LED Triggers
757#
758CONFIG_LEDS_TRIGGERS=y
759CONFIG_LEDS_TRIGGER_TIMER=y
760CONFIG_LEDS_TRIGGER_HEARTBEAT=y
761CONFIG_RTC_LIB=y
762CONFIG_RTC_CLASS=y
763CONFIG_RTC_HCTOSYS=y
764CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
765# CONFIG_RTC_DEBUG is not set
766
767#
768# RTC interfaces
769#
770CONFIG_RTC_INTF_SYSFS=y
771CONFIG_RTC_INTF_PROC=y
772CONFIG_RTC_INTF_DEV=y
773# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
774# CONFIG_RTC_DRV_TEST is not set
775
776#
777# I2C RTC drivers
778#
779# CONFIG_RTC_DRV_DS1307 is not set
780# CONFIG_RTC_DRV_DS1374 is not set
781# CONFIG_RTC_DRV_DS1672 is not set
782# CONFIG_RTC_DRV_MAX6900 is not set
783# CONFIG_RTC_DRV_RS5C372 is not set
784# CONFIG_RTC_DRV_ISL1208 is not set
785# CONFIG_RTC_DRV_X1205 is not set
786# CONFIG_RTC_DRV_PCF8563 is not set
787# CONFIG_RTC_DRV_PCF8583 is not set
788# CONFIG_RTC_DRV_M41T80 is not set
789
790#
791# SPI RTC drivers
792#
793# CONFIG_RTC_DRV_RS5C348 is not set
794# CONFIG_RTC_DRV_MAX6902 is not set
795
796#
797# Platform RTC drivers
798#
799# CONFIG_RTC_DRV_DS1553 is not set
800# CONFIG_RTC_DRV_STK17TA8 is not set
801# CONFIG_RTC_DRV_DS1742 is not set
802# CONFIG_RTC_DRV_M48T86 is not set
803# CONFIG_RTC_DRV_M48T59 is not set
804# CONFIG_RTC_DRV_V3020 is not set
805
806#
807# on-CPU RTC drivers
808#
809CONFIG_RTC_DRV_AT32AP700X=y
810
811#
812# Userspace I/O
813#
814CONFIG_UIO=m
815
816#
817# File systems
818#
819CONFIG_EXT2_FS=m
820# CONFIG_EXT2_FS_XATTR is not set
821# CONFIG_EXT2_FS_XIP is not set
822CONFIG_EXT3_FS=m
823# CONFIG_EXT3_FS_XATTR is not set
824# CONFIG_EXT4DEV_FS is not set
825CONFIG_JBD=m
826# CONFIG_JBD_DEBUG is not set
827# CONFIG_REISERFS_FS is not set
828# CONFIG_JFS_FS is not set
829# CONFIG_FS_POSIX_ACL is not set
830# CONFIG_XFS_FS is not set
831# CONFIG_GFS2_FS is not set
832# CONFIG_OCFS2_FS is not set
833# CONFIG_MINIX_FS is not set
834# CONFIG_ROMFS_FS is not set
835CONFIG_INOTIFY=y
836CONFIG_INOTIFY_USER=y
837# CONFIG_QUOTA is not set
838# CONFIG_DNOTIFY is not set
839# CONFIG_AUTOFS_FS is not set
840# CONFIG_AUTOFS4_FS is not set
841CONFIG_FUSE_FS=m
842
843#
844# CD-ROM/DVD Filesystems
845#
846# CONFIG_ISO9660_FS is not set
847# CONFIG_UDF_FS is not set
848
849#
850# DOS/FAT/NT Filesystems
851#
852CONFIG_FAT_FS=m
853CONFIG_MSDOS_FS=m
854CONFIG_VFAT_FS=m
855CONFIG_FAT_DEFAULT_CODEPAGE=437
856CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
857# CONFIG_NTFS_FS is not set
858
859#
860# Pseudo filesystems
861#
862CONFIG_PROC_FS=y
863CONFIG_PROC_KCORE=y
864CONFIG_PROC_SYSCTL=y
865CONFIG_SYSFS=y
866CONFIG_TMPFS=y
867# CONFIG_TMPFS_POSIX_ACL is not set
868# CONFIG_HUGETLB_PAGE is not set
869CONFIG_CONFIGFS_FS=m
870
871#
872# Miscellaneous filesystems
873#
874# CONFIG_ADFS_FS is not set
875# CONFIG_AFFS_FS is not set
876# CONFIG_HFS_FS is not set
877# CONFIG_HFSPLUS_FS is not set
878# CONFIG_BEFS_FS is not set
879# CONFIG_BFS_FS is not set
880# CONFIG_EFS_FS is not set
881CONFIG_JFFS2_FS=y
882CONFIG_JFFS2_FS_DEBUG=0
883CONFIG_JFFS2_FS_WRITEBUFFER=y
884# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
885# CONFIG_JFFS2_SUMMARY is not set
886# CONFIG_JFFS2_FS_XATTR is not set
887# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
888CONFIG_JFFS2_ZLIB=y
889# CONFIG_JFFS2_LZO is not set
890CONFIG_JFFS2_RTIME=y
891# CONFIG_JFFS2_RUBIN is not set
892# CONFIG_CRAMFS is not set
893# CONFIG_VXFS_FS is not set
894# CONFIG_HPFS_FS is not set
895# CONFIG_QNX4FS_FS is not set
896# CONFIG_SYSV_FS is not set
897# CONFIG_UFS_FS is not set
898# CONFIG_NETWORK_FILESYSTEMS is not set
899
900#
901# Partition Types
902#
903# CONFIG_PARTITION_ADVANCED is not set
904CONFIG_MSDOS_PARTITION=y
905CONFIG_NLS=m
906CONFIG_NLS_DEFAULT="iso8859-1"
907CONFIG_NLS_CODEPAGE_437=m
908# CONFIG_NLS_CODEPAGE_737 is not set
909# CONFIG_NLS_CODEPAGE_775 is not set
910# CONFIG_NLS_CODEPAGE_850 is not set
911# CONFIG_NLS_CODEPAGE_852 is not set
912# CONFIG_NLS_CODEPAGE_855 is not set
913# CONFIG_NLS_CODEPAGE_857 is not set
914# CONFIG_NLS_CODEPAGE_860 is not set
915# CONFIG_NLS_CODEPAGE_861 is not set
916# CONFIG_NLS_CODEPAGE_862 is not set
917# CONFIG_NLS_CODEPAGE_863 is not set
918# CONFIG_NLS_CODEPAGE_864 is not set
919# CONFIG_NLS_CODEPAGE_865 is not set
920# CONFIG_NLS_CODEPAGE_866 is not set
921# CONFIG_NLS_CODEPAGE_869 is not set
922# CONFIG_NLS_CODEPAGE_936 is not set
923# CONFIG_NLS_CODEPAGE_950 is not set
924# CONFIG_NLS_CODEPAGE_932 is not set
925# CONFIG_NLS_CODEPAGE_949 is not set
926# CONFIG_NLS_CODEPAGE_874 is not set
927# CONFIG_NLS_ISO8859_8 is not set
928# CONFIG_NLS_CODEPAGE_1250 is not set
929# CONFIG_NLS_CODEPAGE_1251 is not set
930# CONFIG_NLS_ASCII is not set
931CONFIG_NLS_ISO8859_1=m
932# CONFIG_NLS_ISO8859_2 is not set
933# CONFIG_NLS_ISO8859_3 is not set
934# CONFIG_NLS_ISO8859_4 is not set
935# CONFIG_NLS_ISO8859_5 is not set
936# CONFIG_NLS_ISO8859_6 is not set
937# CONFIG_NLS_ISO8859_7 is not set
938# CONFIG_NLS_ISO8859_9 is not set
939# CONFIG_NLS_ISO8859_13 is not set
940# CONFIG_NLS_ISO8859_14 is not set
941# CONFIG_NLS_ISO8859_15 is not set
942# CONFIG_NLS_KOI8_R is not set
943# CONFIG_NLS_KOI8_U is not set
944CONFIG_NLS_UTF8=m
945# CONFIG_DLM is not set
946CONFIG_INSTRUMENTATION=y
947CONFIG_PROFILING=y
948CONFIG_OPROFILE=m
949CONFIG_KPROBES=y
950# CONFIG_MARKERS is not set
951
952#
953# Kernel hacking
954#
955# CONFIG_PRINTK_TIME is not set
956CONFIG_ENABLE_WARN_DEPRECATED=y
957CONFIG_ENABLE_MUST_CHECK=y
958CONFIG_MAGIC_SYSRQ=y
959# CONFIG_UNUSED_SYMBOLS is not set
960CONFIG_DEBUG_FS=y
961# CONFIG_HEADERS_CHECK is not set
962CONFIG_DEBUG_KERNEL=y
963# CONFIG_DEBUG_SHIRQ is not set
964CONFIG_DETECT_SOFTLOCKUP=y
965CONFIG_SCHED_DEBUG=y
966# CONFIG_SCHEDSTATS is not set
967# CONFIG_TIMER_STATS is not set
968# CONFIG_DEBUG_RT_MUTEXES is not set
969# CONFIG_RT_MUTEX_TESTER is not set
970# CONFIG_DEBUG_SPINLOCK is not set
971# CONFIG_DEBUG_MUTEXES is not set
972# CONFIG_DEBUG_LOCK_ALLOC is not set
973# CONFIG_PROVE_LOCKING is not set
974# CONFIG_LOCK_STAT is not set
975# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
976# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
977# CONFIG_DEBUG_KOBJECT is not set
978CONFIG_DEBUG_BUGVERBOSE=y
979# CONFIG_DEBUG_INFO is not set
980# CONFIG_DEBUG_VM is not set
981# CONFIG_DEBUG_LIST is not set
982# CONFIG_DEBUG_SG is not set
983CONFIG_FRAME_POINTER=y
984CONFIG_FORCED_INLINING=y
985# CONFIG_BOOT_PRINTK_DELAY is not set
986# CONFIG_RCU_TORTURE_TEST is not set
987# CONFIG_LKDTM is not set
988# CONFIG_FAULT_INJECTION is not set
989# CONFIG_SAMPLES is not set
990
991#
992# Security options
993#
994# CONFIG_KEYS is not set
995# CONFIG_SECURITY is not set
996# CONFIG_SECURITY_FILE_CAPABILITIES is not set
997# CONFIG_CRYPTO is not set
998
999#
1000# Library routines
1001#
1002CONFIG_BITREVERSE=y
1003CONFIG_CRC_CCITT=m
1004# CONFIG_CRC16 is not set
1005CONFIG_CRC_ITU_T=m
1006CONFIG_CRC32=y
1007CONFIG_CRC7=m
1008# CONFIG_LIBCRC32C is not set
1009CONFIG_AUDIT_GENERIC=y
1010CONFIG_ZLIB_INFLATE=y
1011CONFIG_ZLIB_DEFLATE=y
1012CONFIG_PLIST=y
1013CONFIG_HAS_IOMEM=y
1014CONFIG_HAS_IOPORT=y
1015CONFIG_HAS_DMA=y
diff --git a/arch/avr32/configs/atstk1004_defconfig b/arch/avr32/configs/atstk1004_defconfig
new file mode 100644
index 000000000000..634c52760349
--- /dev/null
+++ b/arch/avr32/configs/atstk1004_defconfig
@@ -0,0 +1,621 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.24-rc7
4# Wed Jan 9 23:04:20 2008
5#
6CONFIG_AVR32=y
7CONFIG_GENERIC_GPIO=y
8CONFIG_GENERIC_HARDIRQS=y
9CONFIG_STACKTRACE_SUPPORT=y
10CONFIG_LOCKDEP_SUPPORT=y
11CONFIG_TRACE_IRQFLAGS_SUPPORT=y
12CONFIG_HARDIRQS_SW_RESEND=y
13CONFIG_GENERIC_IRQ_PROBE=y
14CONFIG_RWSEM_GENERIC_SPINLOCK=y
15CONFIG_GENERIC_TIME=y
16# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
17# CONFIG_ARCH_HAS_ILOG2_U32 is not set
18# CONFIG_ARCH_HAS_ILOG2_U64 is not set
19CONFIG_ARCH_SUPPORTS_OPROFILE=y
20CONFIG_GENERIC_HWEIGHT=y
21CONFIG_GENERIC_CALIBRATE_DELAY=y
22CONFIG_GENERIC_BUG=y
23CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
24
25#
26# General setup
27#
28CONFIG_EXPERIMENTAL=y
29CONFIG_BROKEN_ON_SMP=y
30CONFIG_INIT_ENV_ARG_LIMIT=32
31CONFIG_LOCALVERSION=""
32# CONFIG_LOCALVERSION_AUTO is not set
33# CONFIG_SYSVIPC is not set
34# CONFIG_POSIX_MQUEUE is not set
35# CONFIG_BSD_PROCESS_ACCT is not set
36# CONFIG_TASKSTATS is not set
37# CONFIG_USER_NS is not set
38# CONFIG_PID_NS is not set
39# CONFIG_AUDIT is not set
40# CONFIG_IKCONFIG is not set
41CONFIG_LOG_BUF_SHIFT=14
42# CONFIG_CGROUPS is not set
43# CONFIG_FAIR_GROUP_SCHED is not set
44CONFIG_SYSFS_DEPRECATED=y
45# CONFIG_RELAY is not set
46# CONFIG_BLK_DEV_INITRD is not set
47CONFIG_CC_OPTIMIZE_FOR_SIZE=y
48CONFIG_SYSCTL=y
49CONFIG_EMBEDDED=y
50# CONFIG_SYSCTL_SYSCALL is not set
51CONFIG_KALLSYMS=y
52# CONFIG_KALLSYMS_EXTRA_PASS is not set
53CONFIG_HOTPLUG=y
54CONFIG_PRINTK=y
55CONFIG_BUG=y
56CONFIG_ELF_CORE=y
57# CONFIG_BASE_FULL is not set
58# CONFIG_FUTEX is not set
59# CONFIG_EPOLL is not set
60# CONFIG_SIGNALFD is not set
61# CONFIG_EVENTFD is not set
62CONFIG_SHMEM=y
63CONFIG_VM_EVENT_COUNTERS=y
64# CONFIG_SLAB is not set
65# CONFIG_SLUB is not set
66CONFIG_SLOB=y
67# CONFIG_TINY_SHMEM is not set
68CONFIG_BASE_SMALL=1
69# CONFIG_MODULES is not set
70# CONFIG_BLOCK is not set
71
72#
73# System Type and features
74#
75CONFIG_SUBARCH_AVR32B=y
76CONFIG_MMU=y
77CONFIG_PERFORMANCE_COUNTERS=y
78CONFIG_PLATFORM_AT32AP=y
79CONFIG_CPU_AT32AP700X=y
80CONFIG_CPU_AT32AP7002=y
81CONFIG_BOARD_ATSTK1000=y
82# CONFIG_BOARD_ATNGW100 is not set
83# CONFIG_BOARD_ATSTK1002 is not set
84# CONFIG_BOARD_ATSTK1003 is not set
85CONFIG_BOARD_ATSTK1004=y
86# CONFIG_BOARD_ATSTK100X_CUSTOM is not set
87# CONFIG_BOARD_ATSTK100X_SPI1 is not set
88# CONFIG_BOARD_ATSTK1000_J2_LED is not set
89CONFIG_BOARD_ATSTK1000_EXTDAC=y
90CONFIG_LOADER_U_BOOT=y
91
92#
93# Atmel AVR32 AP options
94#
95# CONFIG_AP700X_32_BIT_SMC is not set
96CONFIG_AP700X_16_BIT_SMC=y
97# CONFIG_AP700X_8_BIT_SMC is not set
98CONFIG_LOAD_ADDRESS=0x10000000
99CONFIG_ENTRY_ADDRESS=0x90000000
100CONFIG_PHYS_OFFSET=0x10000000
101CONFIG_PREEMPT_NONE=y
102# CONFIG_PREEMPT_VOLUNTARY is not set
103# CONFIG_PREEMPT is not set
104# CONFIG_HAVE_ARCH_BOOTMEM_NODE is not set
105# CONFIG_ARCH_HAVE_MEMORY_PRESENT is not set
106# CONFIG_NEED_NODE_MEMMAP_SIZE is not set
107CONFIG_ARCH_FLATMEM_ENABLE=y
108# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
109# CONFIG_ARCH_SPARSEMEM_ENABLE is not set
110CONFIG_SELECT_MEMORY_MODEL=y
111CONFIG_FLATMEM_MANUAL=y
112# CONFIG_DISCONTIGMEM_MANUAL is not set
113# CONFIG_SPARSEMEM_MANUAL is not set
114CONFIG_FLATMEM=y
115CONFIG_FLAT_NODE_MEM_MAP=y
116# CONFIG_SPARSEMEM_STATIC is not set
117# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
118CONFIG_SPLIT_PTLOCK_CPUS=4
119# CONFIG_RESOURCES_64BIT is not set
120CONFIG_ZONE_DMA_FLAG=0
121CONFIG_VIRT_TO_BUS=y
122# CONFIG_OWNERSHIP_TRACE is not set
123# CONFIG_HZ_100 is not set
124CONFIG_HZ_250=y
125# CONFIG_HZ_300 is not set
126# CONFIG_HZ_1000 is not set
127CONFIG_HZ=250
128CONFIG_CMDLINE=""
129
130#
131# Power management options
132#
133
134#
135# CPU Frequency scaling
136#
137CONFIG_CPU_FREQ=y
138CONFIG_CPU_FREQ_TABLE=y
139# CONFIG_CPU_FREQ_DEBUG is not set
140# CONFIG_CPU_FREQ_STAT is not set
141CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
142# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
143# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
144# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
145CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
146# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
147CONFIG_CPU_FREQ_GOV_USERSPACE=y
148CONFIG_CPU_FREQ_GOV_ONDEMAND=y
149# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
150CONFIG_CPU_FREQ_AT32AP=y
151
152#
153# Bus options
154#
155# CONFIG_ARCH_SUPPORTS_MSI is not set
156# CONFIG_PCCARD is not set
157
158#
159# Executable file formats
160#
161CONFIG_BINFMT_ELF=y
162# CONFIG_BINFMT_MISC is not set
163
164#
165# Networking
166#
167CONFIG_NET=y
168
169#
170# Networking options
171#
172CONFIG_PACKET=y
173CONFIG_PACKET_MMAP=y
174CONFIG_UNIX=y
175# CONFIG_NET_KEY is not set
176CONFIG_INET=y
177# CONFIG_IP_MULTICAST is not set
178# CONFIG_IP_ADVANCED_ROUTER is not set
179CONFIG_IP_FIB_HASH=y
180# CONFIG_IP_PNP is not set
181# CONFIG_NET_IPIP is not set
182# CONFIG_NET_IPGRE is not set
183# CONFIG_ARPD is not set
184# CONFIG_SYN_COOKIES is not set
185# CONFIG_INET_AH is not set
186# CONFIG_INET_ESP is not set
187# CONFIG_INET_IPCOMP is not set
188# CONFIG_INET_XFRM_TUNNEL is not set
189# CONFIG_INET_TUNNEL is not set
190# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
191# CONFIG_INET_XFRM_MODE_TUNNEL is not set
192# CONFIG_INET_XFRM_MODE_BEET is not set
193# CONFIG_INET_LRO is not set
194# CONFIG_INET_DIAG is not set
195# CONFIG_TCP_CONG_ADVANCED is not set
196CONFIG_TCP_CONG_CUBIC=y
197CONFIG_DEFAULT_TCP_CONG="cubic"
198# CONFIG_TCP_MD5SIG is not set
199# CONFIG_IPV6 is not set
200# CONFIG_INET6_XFRM_TUNNEL is not set
201# CONFIG_INET6_TUNNEL is not set
202# CONFIG_NETWORK_SECMARK is not set
203# CONFIG_NETFILTER is not set
204# CONFIG_IP_DCCP is not set
205# CONFIG_IP_SCTP is not set
206# CONFIG_TIPC is not set
207# CONFIG_ATM is not set
208# CONFIG_BRIDGE is not set
209# CONFIG_VLAN_8021Q is not set
210# CONFIG_DECNET is not set
211# CONFIG_LLC2 is not set
212# CONFIG_IPX is not set
213# CONFIG_ATALK is not set
214# CONFIG_X25 is not set
215# CONFIG_LAPB is not set
216# CONFIG_ECONET is not set
217# CONFIG_WAN_ROUTER is not set
218# CONFIG_NET_SCHED is not set
219
220#
221# Network testing
222#
223# CONFIG_NET_PKTGEN is not set
224# CONFIG_HAMRADIO is not set
225# CONFIG_IRDA is not set
226# CONFIG_BT is not set
227# CONFIG_AF_RXRPC is not set
228
229#
230# Wireless
231#
232# CONFIG_CFG80211 is not set
233# CONFIG_WIRELESS_EXT is not set
234# CONFIG_MAC80211 is not set
235# CONFIG_IEEE80211 is not set
236# CONFIG_RFKILL is not set
237# CONFIG_NET_9P is not set
238
239#
240# Device Drivers
241#
242
243#
244# Generic Driver Options
245#
246CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
247CONFIG_STANDALONE=y
248# CONFIG_PREVENT_FIRMWARE_BUILD is not set
249# CONFIG_FW_LOADER is not set
250# CONFIG_SYS_HYPERVISOR is not set
251# CONFIG_CONNECTOR is not set
252CONFIG_MTD=y
253# CONFIG_MTD_DEBUG is not set
254# CONFIG_MTD_CONCAT is not set
255CONFIG_MTD_PARTITIONS=y
256# CONFIG_MTD_REDBOOT_PARTS is not set
257CONFIG_MTD_CMDLINE_PARTS=y
258
259#
260# User Modules And Translation Layers
261#
262CONFIG_MTD_CHAR=y
263# CONFIG_MTD_OOPS is not set
264
265#
266# RAM/ROM/Flash chip drivers
267#
268CONFIG_MTD_CFI=y
269# CONFIG_MTD_JEDECPROBE is not set
270CONFIG_MTD_GEN_PROBE=y
271# CONFIG_MTD_CFI_ADV_OPTIONS is not set
272CONFIG_MTD_MAP_BANK_WIDTH_1=y
273CONFIG_MTD_MAP_BANK_WIDTH_2=y
274CONFIG_MTD_MAP_BANK_WIDTH_4=y
275# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
276# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
277# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
278CONFIG_MTD_CFI_I1=y
279CONFIG_MTD_CFI_I2=y
280# CONFIG_MTD_CFI_I4 is not set
281# CONFIG_MTD_CFI_I8 is not set
282# CONFIG_MTD_CFI_INTELEXT is not set
283CONFIG_MTD_CFI_AMDSTD=y
284# CONFIG_MTD_CFI_STAA is not set
285CONFIG_MTD_CFI_UTIL=y
286# CONFIG_MTD_RAM is not set
287# CONFIG_MTD_ROM is not set
288# CONFIG_MTD_ABSENT is not set
289
290#
291# Mapping drivers for chip access
292#
293# CONFIG_MTD_COMPLEX_MAPPINGS is not set
294CONFIG_MTD_PHYSMAP=y
295CONFIG_MTD_PHYSMAP_START=0x8000000
296CONFIG_MTD_PHYSMAP_LEN=0x0
297CONFIG_MTD_PHYSMAP_BANKWIDTH=2
298# CONFIG_MTD_PLATRAM is not set
299
300#
301# Self-contained MTD device drivers
302#
303# CONFIG_MTD_DATAFLASH is not set
304# CONFIG_MTD_M25P80 is not set
305# CONFIG_MTD_SLRAM is not set
306# CONFIG_MTD_PHRAM is not set
307# CONFIG_MTD_MTDRAM is not set
308
309#
310# Disk-On-Chip Device Drivers
311#
312# CONFIG_MTD_DOC2000 is not set
313# CONFIG_MTD_DOC2001 is not set
314# CONFIG_MTD_DOC2001PLUS is not set
315# CONFIG_MTD_NAND is not set
316# CONFIG_MTD_ONENAND is not set
317
318#
319# UBI - Unsorted block images
320#
321# CONFIG_MTD_UBI is not set
322# CONFIG_PARPORT is not set
323# CONFIG_MISC_DEVICES is not set
324
325#
326# SCSI device support
327#
328# CONFIG_SCSI_DMA is not set
329# CONFIG_SCSI_NETLINK is not set
330# CONFIG_NETDEVICES is not set
331# CONFIG_ISDN is not set
332# CONFIG_PHONE is not set
333
334#
335# Input device support
336#
337# CONFIG_INPUT is not set
338
339#
340# Hardware I/O ports
341#
342# CONFIG_SERIO is not set
343# CONFIG_GAMEPORT is not set
344
345#
346# Character devices
347#
348# CONFIG_VT is not set
349# CONFIG_SERIAL_NONSTANDARD is not set
350
351#
352# Serial drivers
353#
354# CONFIG_SERIAL_8250 is not set
355
356#
357# Non-8250 serial port support
358#
359CONFIG_SERIAL_ATMEL=y
360CONFIG_SERIAL_ATMEL_CONSOLE=y
361# CONFIG_SERIAL_ATMEL_TTYAT is not set
362CONFIG_SERIAL_CORE=y
363CONFIG_SERIAL_CORE_CONSOLE=y
364CONFIG_UNIX98_PTYS=y
365# CONFIG_LEGACY_PTYS is not set
366# CONFIG_IPMI_HANDLER is not set
367# CONFIG_HW_RANDOM is not set
368# CONFIG_RTC is not set
369# CONFIG_GEN_RTC is not set
370# CONFIG_R3964 is not set
371# CONFIG_TCG_TPM is not set
372# CONFIG_I2C is not set
373
374#
375# SPI support
376#
377CONFIG_SPI=y
378CONFIG_SPI_MASTER=y
379
380#
381# SPI Master Controller Drivers
382#
383CONFIG_SPI_ATMEL=y
384# CONFIG_SPI_BITBANG is not set
385
386#
387# SPI Protocol Masters
388#
389# CONFIG_SPI_AT25 is not set
390# CONFIG_SPI_SPIDEV is not set
391# CONFIG_SPI_TLE62X0 is not set
392# CONFIG_W1 is not set
393# CONFIG_POWER_SUPPLY is not set
394# CONFIG_HWMON is not set
395CONFIG_WATCHDOG=y
396# CONFIG_WATCHDOG_NOWAYOUT is not set
397
398#
399# Watchdog Device Drivers
400#
401# CONFIG_SOFT_WATCHDOG is not set
402CONFIG_AT32AP700X_WDT=y
403
404#
405# Sonics Silicon Backplane
406#
407CONFIG_SSB_POSSIBLE=y
408# CONFIG_SSB is not set
409
410#
411# Multifunction device drivers
412#
413# CONFIG_MFD_SM501 is not set
414
415#
416# Multimedia devices
417#
418# CONFIG_VIDEO_DEV is not set
419# CONFIG_DVB_CORE is not set
420# CONFIG_DAB is not set
421
422#
423# Graphics support
424#
425# CONFIG_VGASTATE is not set
426# CONFIG_VIDEO_OUTPUT_CONTROL is not set
427CONFIG_FB=y
428# CONFIG_FIRMWARE_EDID is not set
429# CONFIG_FB_DDC is not set
430CONFIG_FB_CFB_FILLRECT=y
431CONFIG_FB_CFB_COPYAREA=y
432CONFIG_FB_CFB_IMAGEBLIT=y
433# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
434# CONFIG_FB_SYS_FILLRECT is not set
435# CONFIG_FB_SYS_COPYAREA is not set
436# CONFIG_FB_SYS_IMAGEBLIT is not set
437# CONFIG_FB_SYS_FOPS is not set
438CONFIG_FB_DEFERRED_IO=y
439# CONFIG_FB_SVGALIB is not set
440# CONFIG_FB_MACMODES is not set
441# CONFIG_FB_BACKLIGHT is not set
442# CONFIG_FB_MODE_HELPERS is not set
443# CONFIG_FB_TILEBLITTING is not set
444
445#
446# Frame buffer hardware drivers
447#
448# CONFIG_FB_S1D13XXX is not set
449CONFIG_FB_ATMEL=y
450# CONFIG_FB_VIRTUAL is not set
451CONFIG_BACKLIGHT_LCD_SUPPORT=y
452CONFIG_LCD_CLASS_DEVICE=y
453CONFIG_LCD_LTV350QV=y
454# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
455
456#
457# Display device support
458#
459# CONFIG_DISPLAY_SUPPORT is not set
460# CONFIG_LOGO is not set
461
462#
463# Sound
464#
465# CONFIG_SOUND is not set
466CONFIG_USB_SUPPORT=y
467# CONFIG_USB_ARCH_HAS_HCD is not set
468# CONFIG_USB_ARCH_HAS_OHCI is not set
469# CONFIG_USB_ARCH_HAS_EHCI is not set
470
471#
472# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
473#
474
475#
476# USB Gadget Support
477#
478CONFIG_USB_GADGET=y
479# CONFIG_USB_GADGET_DEBUG_FILES is not set
480CONFIG_USB_GADGET_SELECTED=y
481# CONFIG_USB_GADGET_AMD5536UDC is not set
482CONFIG_USB_GADGET_ATMEL_USBA=y
483CONFIG_USB_ATMEL_USBA=y
484# CONFIG_USB_GADGET_FSL_USB2 is not set
485# CONFIG_USB_GADGET_NET2280 is not set
486# CONFIG_USB_GADGET_PXA2XX is not set
487# CONFIG_USB_GADGET_M66592 is not set
488# CONFIG_USB_GADGET_GOKU is not set
489# CONFIG_USB_GADGET_LH7A40X is not set
490# CONFIG_USB_GADGET_OMAP is not set
491# CONFIG_USB_GADGET_S3C2410 is not set
492# CONFIG_USB_GADGET_AT91 is not set
493# CONFIG_USB_GADGET_DUMMY_HCD is not set
494CONFIG_USB_GADGET_DUALSPEED=y
495# CONFIG_USB_ZERO is not set
496CONFIG_USB_ETH=y
497# CONFIG_USB_ETH_RNDIS is not set
498# CONFIG_USB_GADGETFS is not set
499# CONFIG_USB_FILE_STORAGE is not set
500# CONFIG_USB_G_SERIAL is not set
501# CONFIG_USB_MIDI_GADGET is not set
502# CONFIG_MMC is not set
503# CONFIG_NEW_LEDS is not set
504CONFIG_RTC_LIB=y
505CONFIG_RTC_CLASS=y
506CONFIG_RTC_HCTOSYS=y
507CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
508# CONFIG_RTC_DEBUG is not set
509
510#
511# RTC interfaces
512#
513CONFIG_RTC_INTF_SYSFS=y
514# CONFIG_RTC_INTF_PROC is not set
515CONFIG_RTC_INTF_DEV=y
516# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
517# CONFIG_RTC_DRV_TEST is not set
518
519#
520# SPI RTC drivers
521#
522# CONFIG_RTC_DRV_RS5C348 is not set
523# CONFIG_RTC_DRV_MAX6902 is not set
524
525#
526# Platform RTC drivers
527#
528# CONFIG_RTC_DRV_DS1553 is not set
529# CONFIG_RTC_DRV_STK17TA8 is not set
530# CONFIG_RTC_DRV_DS1742 is not set
531# CONFIG_RTC_DRV_M48T86 is not set
532# CONFIG_RTC_DRV_M48T59 is not set
533# CONFIG_RTC_DRV_V3020 is not set
534
535#
536# on-CPU RTC drivers
537#
538CONFIG_RTC_DRV_AT32AP700X=y
539
540#
541# Userspace I/O
542#
543# CONFIG_UIO is not set
544
545#
546# File systems
547#
548# CONFIG_INOTIFY is not set
549# CONFIG_QUOTA is not set
550# CONFIG_DNOTIFY is not set
551# CONFIG_AUTOFS_FS is not set
552# CONFIG_AUTOFS4_FS is not set
553# CONFIG_FUSE_FS is not set
554
555#
556# Pseudo filesystems
557#
558CONFIG_PROC_FS=y
559CONFIG_PROC_KCORE=y
560CONFIG_PROC_SYSCTL=y
561CONFIG_SYSFS=y
562CONFIG_TMPFS=y
563# CONFIG_TMPFS_POSIX_ACL is not set
564# CONFIG_HUGETLB_PAGE is not set
565# CONFIG_CONFIGFS_FS is not set
566
567#
568# Miscellaneous filesystems
569#
570CONFIG_JFFS2_FS=y
571CONFIG_JFFS2_FS_DEBUG=0
572# CONFIG_JFFS2_FS_WRITEBUFFER is not set
573# CONFIG_JFFS2_SUMMARY is not set
574# CONFIG_JFFS2_FS_XATTR is not set
575# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
576CONFIG_JFFS2_ZLIB=y
577# CONFIG_JFFS2_LZO is not set
578CONFIG_JFFS2_RTIME=y
579# CONFIG_JFFS2_RUBIN is not set
580# CONFIG_NETWORK_FILESYSTEMS is not set
581# CONFIG_NLS is not set
582# CONFIG_DLM is not set
583# CONFIG_INSTRUMENTATION is not set
584
585#
586# Kernel hacking
587#
588# CONFIG_PRINTK_TIME is not set
589CONFIG_ENABLE_WARN_DEPRECATED=y
590CONFIG_ENABLE_MUST_CHECK=y
591CONFIG_MAGIC_SYSRQ=y
592# CONFIG_UNUSED_SYMBOLS is not set
593# CONFIG_DEBUG_FS is not set
594# CONFIG_HEADERS_CHECK is not set
595# CONFIG_DEBUG_KERNEL is not set
596# CONFIG_DEBUG_BUGVERBOSE is not set
597# CONFIG_SAMPLES is not set
598
599#
600# Security options
601#
602# CONFIG_KEYS is not set
603# CONFIG_SECURITY is not set
604# CONFIG_SECURITY_FILE_CAPABILITIES is not set
605# CONFIG_CRYPTO is not set
606
607#
608# Library routines
609#
610CONFIG_BITREVERSE=y
611# CONFIG_CRC_CCITT is not set
612# CONFIG_CRC16 is not set
613# CONFIG_CRC_ITU_T is not set
614CONFIG_CRC32=y
615# CONFIG_CRC7 is not set
616# CONFIG_LIBCRC32C is not set
617CONFIG_ZLIB_INFLATE=y
618CONFIG_ZLIB_DEFLATE=y
619CONFIG_HAS_IOMEM=y
620CONFIG_HAS_IOPORT=y
621CONFIG_HAS_DMA=y
diff --git a/arch/avr32/kernel/Makefile b/arch/avr32/kernel/Makefile
index 2d6d48f35f69..e4b6d122b033 100644
--- a/arch/avr32/kernel/Makefile
+++ b/arch/avr32/kernel/Makefile
@@ -6,9 +6,10 @@ extra-y := head.o vmlinux.lds
6 6
7obj-$(CONFIG_SUBARCH_AVR32B) += entry-avr32b.o 7obj-$(CONFIG_SUBARCH_AVR32B) += entry-avr32b.o
8obj-y += syscall_table.o syscall-stubs.o irq.o 8obj-y += syscall_table.o syscall-stubs.o irq.o
9obj-y += setup.o traps.o semaphore.o ptrace.o 9obj-y += setup.o traps.o semaphore.o ocd.o ptrace.o
10obj-y += signal.o sys_avr32.o process.o time.o 10obj-y += signal.o sys_avr32.o process.o time.o
11obj-y += init_task.o switch_to.o cpu.o 11obj-y += init_task.o switch_to.o cpu.o
12obj-$(CONFIG_MODULES) += module.o avr32_ksyms.o 12obj-$(CONFIG_MODULES) += module.o avr32_ksyms.o
13obj-$(CONFIG_KPROBES) += kprobes.o 13obj-$(CONFIG_KPROBES) += kprobes.o
14obj-$(CONFIG_STACKTRACE) += stacktrace.o 14obj-$(CONFIG_STACKTRACE) += stacktrace.o
15obj-$(CONFIG_NMI_DEBUGGING) += nmi_debug.o
diff --git a/arch/avr32/kernel/cpu.c b/arch/avr32/kernel/cpu.c
index 2714cf6452b5..b8409caeb23d 100644
--- a/arch/avr32/kernel/cpu.c
+++ b/arch/avr32/kernel/cpu.c
@@ -13,6 +13,7 @@
13#include <linux/percpu.h> 13#include <linux/percpu.h>
14#include <linux/param.h> 14#include <linux/param.h>
15#include <linux/errno.h> 15#include <linux/errno.h>
16#include <linux/clk.h>
16 17
17#include <asm/setup.h> 18#include <asm/setup.h>
18#include <asm/sysreg.h> 19#include <asm/sysreg.h>
@@ -187,9 +188,20 @@ static int __init topology_init(void)
187 188
188subsys_initcall(topology_init); 189subsys_initcall(topology_init);
189 190
191struct chip_id_map {
192 u16 mid;
193 u16 pn;
194 const char *name;
195};
196
197static const struct chip_id_map chip_names[] = {
198 { .mid = 0x1f, .pn = 0x1e82, .name = "AT32AP700x" },
199};
200#define NR_CHIP_NAMES ARRAY_SIZE(chip_names)
201
190static const char *cpu_names[] = { 202static const char *cpu_names[] = {
191 "Morgan", 203 "Morgan",
192 "AP7000", 204 "AP7",
193}; 205};
194#define NR_CPU_NAMES ARRAY_SIZE(cpu_names) 206#define NR_CPU_NAMES ARRAY_SIZE(cpu_names)
195 207
@@ -206,12 +218,32 @@ static const char *mmu_types[] = {
206 "MPU" 218 "MPU"
207}; 219};
208 220
221static const char *cpu_feature_flags[] = {
222 "rmw", "dsp", "simd", "ocd", "perfctr", "java", "fpu",
223};
224
225static const char *get_chip_name(struct avr32_cpuinfo *cpu)
226{
227 unsigned int i;
228 unsigned int mid = avr32_get_manufacturer_id(cpu);
229 unsigned int pn = avr32_get_product_number(cpu);
230
231 for (i = 0; i < NR_CHIP_NAMES; i++) {
232 if (chip_names[i].mid == mid && chip_names[i].pn == pn)
233 return chip_names[i].name;
234 }
235
236 return "(unknown)";
237}
238
209void __init setup_processor(void) 239void __init setup_processor(void)
210{ 240{
211 unsigned long config0, config1; 241 unsigned long config0, config1;
212 unsigned long features; 242 unsigned long features;
213 unsigned cpu_id, cpu_rev, arch_id, arch_rev, mmu_type; 243 unsigned cpu_id, cpu_rev, arch_id, arch_rev, mmu_type;
244 unsigned device_id;
214 unsigned tmp; 245 unsigned tmp;
246 unsigned i;
215 247
216 config0 = sysreg_read(CONFIG0); 248 config0 = sysreg_read(CONFIG0);
217 config1 = sysreg_read(CONFIG1); 249 config1 = sysreg_read(CONFIG1);
@@ -221,11 +253,14 @@ void __init setup_processor(void)
221 arch_rev = SYSREG_BFEXT(AR, config0); 253 arch_rev = SYSREG_BFEXT(AR, config0);
222 mmu_type = SYSREG_BFEXT(MMUT, config0); 254 mmu_type = SYSREG_BFEXT(MMUT, config0);
223 255
256 device_id = ocd_read(DID);
257
224 boot_cpu_data.arch_type = arch_id; 258 boot_cpu_data.arch_type = arch_id;
225 boot_cpu_data.cpu_type = cpu_id; 259 boot_cpu_data.cpu_type = cpu_id;
226 boot_cpu_data.arch_revision = arch_rev; 260 boot_cpu_data.arch_revision = arch_rev;
227 boot_cpu_data.cpu_revision = cpu_rev; 261 boot_cpu_data.cpu_revision = cpu_rev;
228 boot_cpu_data.tlb_config = mmu_type; 262 boot_cpu_data.tlb_config = mmu_type;
263 boot_cpu_data.device_id = device_id;
229 264
230 tmp = SYSREG_BFEXT(ILSZ, config1); 265 tmp = SYSREG_BFEXT(ILSZ, config1);
231 if (tmp) { 266 if (tmp) {
@@ -247,41 +282,34 @@ void __init setup_processor(void)
247 return; 282 return;
248 } 283 }
249 284
250 printk ("CPU: %s [%02x] revision %d (%s revision %d)\n", 285 printk ("CPU: %s chip revision %c\n", get_chip_name(&boot_cpu_data),
286 avr32_get_chip_revision(&boot_cpu_data) + 'A');
287 printk ("CPU: %s [%02x] core revision %d (%s arch revision %d)\n",
251 cpu_names[cpu_id], cpu_id, cpu_rev, 288 cpu_names[cpu_id], cpu_id, cpu_rev,
252 arch_names[arch_id], arch_rev); 289 arch_names[arch_id], arch_rev);
253 printk ("CPU: MMU configuration: %s\n", mmu_types[mmu_type]); 290 printk ("CPU: MMU configuration: %s\n", mmu_types[mmu_type]);
254 291
255 printk ("CPU: features:"); 292 printk ("CPU: features:");
256 features = 0; 293 features = 0;
257 if (config0 & SYSREG_BIT(CONFIG0_R)) { 294 if (config0 & SYSREG_BIT(CONFIG0_R))
258 features |= AVR32_FEATURE_RMW; 295 features |= AVR32_FEATURE_RMW;
259 printk(" rmw"); 296 if (config0 & SYSREG_BIT(CONFIG0_D))
260 }
261 if (config0 & SYSREG_BIT(CONFIG0_D)) {
262 features |= AVR32_FEATURE_DSP; 297 features |= AVR32_FEATURE_DSP;
263 printk(" dsp"); 298 if (config0 & SYSREG_BIT(CONFIG0_S))
264 }
265 if (config0 & SYSREG_BIT(CONFIG0_S)) {
266 features |= AVR32_FEATURE_SIMD; 299 features |= AVR32_FEATURE_SIMD;
267 printk(" simd"); 300 if (config0 & SYSREG_BIT(CONFIG0_O))
268 }
269 if (config0 & SYSREG_BIT(CONFIG0_O)) {
270 features |= AVR32_FEATURE_OCD; 301 features |= AVR32_FEATURE_OCD;
271 printk(" ocd"); 302 if (config0 & SYSREG_BIT(CONFIG0_P))
272 }
273 if (config0 & SYSREG_BIT(CONFIG0_P)) {
274 features |= AVR32_FEATURE_PCTR; 303 features |= AVR32_FEATURE_PCTR;
275 printk(" perfctr"); 304 if (config0 & SYSREG_BIT(CONFIG0_J))
276 }
277 if (config0 & SYSREG_BIT(CONFIG0_J)) {
278 features |= AVR32_FEATURE_JAVA; 305 features |= AVR32_FEATURE_JAVA;
279 printk(" java"); 306 if (config0 & SYSREG_BIT(CONFIG0_F))
280 }
281 if (config0 & SYSREG_BIT(CONFIG0_F)) {
282 features |= AVR32_FEATURE_FPU; 307 features |= AVR32_FEATURE_FPU;
283 printk(" fpu"); 308
284 } 309 for (i = 0; i < ARRAY_SIZE(cpu_feature_flags); i++)
310 if (features & (1 << i))
311 printk(" %s", cpu_feature_flags[i]);
312
285 printk("\n"); 313 printk("\n");
286 boot_cpu_data.features = features; 314 boot_cpu_data.features = features;
287} 315}
@@ -291,6 +319,8 @@ static int c_show(struct seq_file *m, void *v)
291{ 319{
292 unsigned int icache_size, dcache_size; 320 unsigned int icache_size, dcache_size;
293 unsigned int cpu = smp_processor_id(); 321 unsigned int cpu = smp_processor_id();
322 unsigned int freq;
323 unsigned int i;
294 324
295 icache_size = boot_cpu_data.icache.ways * 325 icache_size = boot_cpu_data.icache.ways *
296 boot_cpu_data.icache.sets * 326 boot_cpu_data.icache.sets *
@@ -301,15 +331,21 @@ static int c_show(struct seq_file *m, void *v)
301 331
302 seq_printf(m, "processor\t: %d\n", cpu); 332 seq_printf(m, "processor\t: %d\n", cpu);
303 333
334 seq_printf(m, "chip type\t: %s revision %c\n",
335 get_chip_name(&boot_cpu_data),
336 avr32_get_chip_revision(&boot_cpu_data) + 'A');
304 if (boot_cpu_data.arch_type < NR_ARCH_NAMES) 337 if (boot_cpu_data.arch_type < NR_ARCH_NAMES)
305 seq_printf(m, "cpu family\t: %s revision %d\n", 338 seq_printf(m, "cpu arch\t: %s revision %d\n",
306 arch_names[boot_cpu_data.arch_type], 339 arch_names[boot_cpu_data.arch_type],
307 boot_cpu_data.arch_revision); 340 boot_cpu_data.arch_revision);
308 if (boot_cpu_data.cpu_type < NR_CPU_NAMES) 341 if (boot_cpu_data.cpu_type < NR_CPU_NAMES)
309 seq_printf(m, "cpu type\t: %s revision %d\n", 342 seq_printf(m, "cpu core\t: %s revision %d\n",
310 cpu_names[boot_cpu_data.cpu_type], 343 cpu_names[boot_cpu_data.cpu_type],
311 boot_cpu_data.cpu_revision); 344 boot_cpu_data.cpu_revision);
312 345
346 freq = (clk_get_rate(boot_cpu_data.clk) + 500) / 1000;
347 seq_printf(m, "cpu MHz\t\t: %u.%03u\n", freq / 1000, freq % 1000);
348
313 seq_printf(m, "i-cache\t\t: %dK (%u ways x %u sets x %u)\n", 349 seq_printf(m, "i-cache\t\t: %dK (%u ways x %u sets x %u)\n",
314 icache_size >> 10, 350 icache_size >> 10,
315 boot_cpu_data.icache.ways, 351 boot_cpu_data.icache.ways,
@@ -320,7 +356,13 @@ static int c_show(struct seq_file *m, void *v)
320 boot_cpu_data.dcache.ways, 356 boot_cpu_data.dcache.ways,
321 boot_cpu_data.dcache.sets, 357 boot_cpu_data.dcache.sets,
322 boot_cpu_data.dcache.linesz); 358 boot_cpu_data.dcache.linesz);
323 seq_printf(m, "bogomips\t: %lu.%02lu\n", 359
360 seq_printf(m, "features\t:");
361 for (i = 0; i < ARRAY_SIZE(cpu_feature_flags); i++)
362 if (boot_cpu_data.features & (1 << i))
363 seq_printf(m, " %s", cpu_feature_flags[i]);
364
365 seq_printf(m, "\nbogomips\t: %lu.%02lu\n",
324 boot_cpu_data.loops_per_jiffy / (500000/HZ), 366 boot_cpu_data.loops_per_jiffy / (500000/HZ),
325 (boot_cpu_data.loops_per_jiffy / (5000/HZ)) % 100); 367 (boot_cpu_data.loops_per_jiffy / (5000/HZ)) % 100);
326 368
@@ -343,7 +385,7 @@ static void c_stop(struct seq_file *m, void *v)
343 385
344} 386}
345 387
346struct seq_operations cpuinfo_op = { 388const struct seq_operations cpuinfo_op = {
347 .start = c_start, 389 .start = c_start,
348 .next = c_next, 390 .next = c_next,
349 .stop = c_stop, 391 .stop = c_stop,
diff --git a/arch/avr32/kernel/irq.c b/arch/avr32/kernel/irq.c
index 61f2de266f62..a8e767d836aa 100644
--- a/arch/avr32/kernel/irq.c
+++ b/arch/avr32/kernel/irq.c
@@ -25,6 +25,17 @@ void ack_bad_irq(unsigned int irq)
25 printk("unexpected IRQ %u\n", irq); 25 printk("unexpected IRQ %u\n", irq);
26} 26}
27 27
28/* May be overridden by platform code */
29int __weak nmi_enable(void)
30{
31 return -ENOSYS;
32}
33
34void __weak nmi_disable(void)
35{
36
37}
38
28#ifdef CONFIG_PROC_FS 39#ifdef CONFIG_PROC_FS
29int show_interrupts(struct seq_file *p, void *v) 40int show_interrupts(struct seq_file *p, void *v)
30{ 41{
diff --git a/arch/avr32/kernel/kprobes.c b/arch/avr32/kernel/kprobes.c
index 799ba89b07a8..f820e9f25520 100644
--- a/arch/avr32/kernel/kprobes.c
+++ b/arch/avr32/kernel/kprobes.c
@@ -48,6 +48,7 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
48void __kprobes arch_arm_kprobe(struct kprobe *p) 48void __kprobes arch_arm_kprobe(struct kprobe *p)
49{ 49{
50 pr_debug("arming kprobe at %p\n", p->addr); 50 pr_debug("arming kprobe at %p\n", p->addr);
51 ocd_enable(NULL);
51 *p->addr = BREAKPOINT_INSTRUCTION; 52 *p->addr = BREAKPOINT_INSTRUCTION;
52 flush_icache_range((unsigned long)p->addr, 53 flush_icache_range((unsigned long)p->addr,
53 (unsigned long)p->addr + sizeof(kprobe_opcode_t)); 54 (unsigned long)p->addr + sizeof(kprobe_opcode_t));
@@ -56,6 +57,7 @@ void __kprobes arch_arm_kprobe(struct kprobe *p)
56void __kprobes arch_disarm_kprobe(struct kprobe *p) 57void __kprobes arch_disarm_kprobe(struct kprobe *p)
57{ 58{
58 pr_debug("disarming kprobe at %p\n", p->addr); 59 pr_debug("disarming kprobe at %p\n", p->addr);
60 ocd_disable(NULL);
59 *p->addr = p->opcode; 61 *p->addr = p->opcode;
60 flush_icache_range((unsigned long)p->addr, 62 flush_icache_range((unsigned long)p->addr,
61 (unsigned long)p->addr + sizeof(kprobe_opcode_t)); 63 (unsigned long)p->addr + sizeof(kprobe_opcode_t));
@@ -260,9 +262,6 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
260 262
261int __init arch_init_kprobes(void) 263int __init arch_init_kprobes(void)
262{ 264{
263 printk("KPROBES: Enabling monitor mode (MM|DBE)...\n");
264 ocd_write(DC, (1 << OCD_DC_MM_BIT) | (1 << OCD_DC_DBE_BIT));
265
266 /* TODO: Register kretprobe trampoline */ 265 /* TODO: Register kretprobe trampoline */
267 return 0; 266 return 0;
268} 267}
diff --git a/arch/avr32/kernel/nmi_debug.c b/arch/avr32/kernel/nmi_debug.c
new file mode 100644
index 000000000000..3414b8566c29
--- /dev/null
+++ b/arch/avr32/kernel/nmi_debug.c
@@ -0,0 +1,82 @@
1/*
2 * Copyright (C) 2007 Atmel Corporation
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 version 2 as
6 * published by the Free Software Foundation.
7 */
8#include <linux/delay.h>
9#include <linux/kdebug.h>
10#include <linux/notifier.h>
11#include <linux/sched.h>
12
13#include <asm/irq.h>
14
15enum nmi_action {
16 NMI_SHOW_STATE = 1 << 0,
17 NMI_SHOW_REGS = 1 << 1,
18 NMI_DIE = 1 << 2,
19 NMI_DEBOUNCE = 1 << 3,
20};
21
22static unsigned long nmi_actions;
23
24static int nmi_debug_notify(struct notifier_block *self,
25 unsigned long val, void *data)
26{
27 struct die_args *args = data;
28
29 if (likely(val != DIE_NMI))
30 return NOTIFY_DONE;
31
32 if (nmi_actions & NMI_SHOW_STATE)
33 show_state();
34 if (nmi_actions & NMI_SHOW_REGS)
35 show_regs(args->regs);
36 if (nmi_actions & NMI_DEBOUNCE)
37 mdelay(10);
38 if (nmi_actions & NMI_DIE)
39 return NOTIFY_BAD;
40
41 return NOTIFY_OK;
42}
43
44static struct notifier_block nmi_debug_nb = {
45 .notifier_call = nmi_debug_notify,
46};
47
48static int __init nmi_debug_setup(char *str)
49{
50 char *p, *sep;
51
52 register_die_notifier(&nmi_debug_nb);
53 if (nmi_enable()) {
54 printk(KERN_WARNING "Unable to enable NMI.\n");
55 return 0;
56 }
57
58 if (*str != '=')
59 return 0;
60
61 for (p = str + 1; *p; p = sep + 1) {
62 sep = strchr(p, ',');
63 if (sep)
64 *sep = 0;
65 if (strcmp(p, "state") == 0)
66 nmi_actions |= NMI_SHOW_STATE;
67 else if (strcmp(p, "regs") == 0)
68 nmi_actions |= NMI_SHOW_REGS;
69 else if (strcmp(p, "debounce") == 0)
70 nmi_actions |= NMI_DEBOUNCE;
71 else if (strcmp(p, "die") == 0)
72 nmi_actions |= NMI_DIE;
73 else
74 printk(KERN_WARNING "NMI: Unrecognized action `%s'\n",
75 p);
76 if (!sep)
77 break;
78 }
79
80 return 0;
81}
82__setup("nmi_debug", nmi_debug_setup);
diff --git a/arch/avr32/kernel/ocd.c b/arch/avr32/kernel/ocd.c
new file mode 100644
index 000000000000..c4f023294d75
--- /dev/null
+++ b/arch/avr32/kernel/ocd.c
@@ -0,0 +1,163 @@
1/*
2 * Copyright (C) 2007 Atmel Corporation
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 version 2 as
6 * published by the Free Software Foundation.
7 */
8#include <linux/init.h>
9#include <linux/sched.h>
10#include <linux/spinlock.h>
11
12#include <asm/ocd.h>
13
14static long ocd_count;
15static spinlock_t ocd_lock;
16
17/**
18 * ocd_enable - enable on-chip debugging
19 * @child: task to be debugged
20 *
21 * If @child is non-NULL, ocd_enable() first checks if debugging has
22 * already been enabled for @child, and if it has, does nothing.
23 *
24 * If @child is NULL (e.g. when debugging the kernel), or debugging
25 * has not already been enabled for it, ocd_enable() increments the
26 * reference count and enables the debugging hardware.
27 */
28void ocd_enable(struct task_struct *child)
29{
30 u32 dc;
31
32 if (child)
33 pr_debug("ocd_enable: child=%s [%u]\n",
34 child->comm, child->pid);
35 else
36 pr_debug("ocd_enable (no child)\n");
37
38 if (!child || !test_and_set_tsk_thread_flag(child, TIF_DEBUG)) {
39 spin_lock(&ocd_lock);
40 ocd_count++;
41 dc = ocd_read(DC);
42 dc |= (1 << OCD_DC_MM_BIT) | (1 << OCD_DC_DBE_BIT);
43 ocd_write(DC, dc);
44 spin_unlock(&ocd_lock);
45 }
46}
47
48/**
49 * ocd_disable - disable on-chip debugging
50 * @child: task that was being debugged, but isn't anymore
51 *
52 * If @child is non-NULL, ocd_disable() checks if debugging is enabled
53 * for @child, and if it isn't, does nothing.
54 *
55 * If @child is NULL (e.g. when debugging the kernel), or debugging is
56 * enabled, ocd_disable() decrements the reference count, and if it
57 * reaches zero, disables the debugging hardware.
58 */
59void ocd_disable(struct task_struct *child)
60{
61 u32 dc;
62
63 if (!child)
64 pr_debug("ocd_disable (no child)\n");
65 else if (test_tsk_thread_flag(child, TIF_DEBUG))
66 pr_debug("ocd_disable: child=%s [%u]\n",
67 child->comm, child->pid);
68
69 if (!child || test_and_clear_tsk_thread_flag(child, TIF_DEBUG)) {
70 spin_lock(&ocd_lock);
71 ocd_count--;
72
73 WARN_ON(ocd_count < 0);
74
75 if (ocd_count <= 0) {
76 dc = ocd_read(DC);
77 dc &= ~((1 << OCD_DC_MM_BIT) | (1 << OCD_DC_DBE_BIT));
78 ocd_write(DC, dc);
79 }
80 spin_unlock(&ocd_lock);
81 }
82}
83
84#ifdef CONFIG_DEBUG_FS
85#include <linux/debugfs.h>
86#include <linux/module.h>
87
88static struct dentry *ocd_debugfs_root;
89static struct dentry *ocd_debugfs_DC;
90static struct dentry *ocd_debugfs_DS;
91static struct dentry *ocd_debugfs_count;
92
93static u64 ocd_DC_get(void *data)
94{
95 return ocd_read(DC);
96}
97static void ocd_DC_set(void *data, u64 val)
98{
99 ocd_write(DC, val);
100}
101DEFINE_SIMPLE_ATTRIBUTE(fops_DC, ocd_DC_get, ocd_DC_set, "0x%08llx\n");
102
103static u64 ocd_DS_get(void *data)
104{
105 return ocd_read(DS);
106}
107DEFINE_SIMPLE_ATTRIBUTE(fops_DS, ocd_DS_get, NULL, "0x%08llx\n");
108
109static u64 ocd_count_get(void *data)
110{
111 return ocd_count;
112}
113DEFINE_SIMPLE_ATTRIBUTE(fops_count, ocd_count_get, NULL, "%lld\n");
114
115static void ocd_debugfs_init(void)
116{
117 struct dentry *root;
118
119 root = debugfs_create_dir("ocd", NULL);
120 if (IS_ERR(root) || !root)
121 goto err_root;
122 ocd_debugfs_root = root;
123
124 ocd_debugfs_DC = debugfs_create_file("DC", S_IRUSR | S_IWUSR,
125 root, NULL, &fops_DC);
126 if (!ocd_debugfs_DC)
127 goto err_DC;
128
129 ocd_debugfs_DS = debugfs_create_file("DS", S_IRUSR, root,
130 NULL, &fops_DS);
131 if (!ocd_debugfs_DS)
132 goto err_DS;
133
134 ocd_debugfs_count = debugfs_create_file("count", S_IRUSR, root,
135 NULL, &fops_count);
136 if (!ocd_debugfs_count)
137 goto err_count;
138
139 return;
140
141err_count:
142 debugfs_remove(ocd_debugfs_DS);
143err_DS:
144 debugfs_remove(ocd_debugfs_DC);
145err_DC:
146 debugfs_remove(ocd_debugfs_root);
147err_root:
148 printk(KERN_WARNING "OCD: Failed to create debugfs entries\n");
149}
150#else
151static inline void ocd_debugfs_init(void)
152{
153
154}
155#endif
156
157static int __init ocd_init(void)
158{
159 spin_lock_init(&ocd_lock);
160 ocd_debugfs_init();
161 return 0;
162}
163arch_initcall(ocd_init);
diff --git a/arch/avr32/kernel/process.c b/arch/avr32/kernel/process.c
index 9d6dac8af7a2..eaaa69bbdc38 100644
--- a/arch/avr32/kernel/process.c
+++ b/arch/avr32/kernel/process.c
@@ -103,7 +103,7 @@ EXPORT_SYMBOL(kernel_thread);
103 */ 103 */
104void exit_thread(void) 104void exit_thread(void)
105{ 105{
106 /* nothing to do */ 106 ocd_disable(current);
107} 107}
108 108
109void flush_thread(void) 109void flush_thread(void)
@@ -345,6 +345,9 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
345 p->thread.cpu_context.ksp = (unsigned long)childregs; 345 p->thread.cpu_context.ksp = (unsigned long)childregs;
346 p->thread.cpu_context.pc = (unsigned long)ret_from_fork; 346 p->thread.cpu_context.pc = (unsigned long)ret_from_fork;
347 347
348 if ((clone_flags & CLONE_PTRACE) && test_thread_flag(TIF_DEBUG))
349 ocd_enable(p);
350
348 return 0; 351 return 0;
349} 352}
350 353
diff --git a/arch/avr32/kernel/ptrace.c b/arch/avr32/kernel/ptrace.c
index 002369e44093..1fed38fcf594 100644
--- a/arch/avr32/kernel/ptrace.c
+++ b/arch/avr32/kernel/ptrace.c
@@ -58,6 +58,7 @@ void ptrace_disable(struct task_struct *child)
58{ 58{
59 clear_tsk_thread_flag(child, TIF_SINGLE_STEP); 59 clear_tsk_thread_flag(child, TIF_SINGLE_STEP);
60 clear_tsk_thread_flag(child, TIF_BREAKPOINT); 60 clear_tsk_thread_flag(child, TIF_BREAKPOINT);
61 ocd_disable(child);
61} 62}
62 63
63/* 64/*
@@ -144,10 +145,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
144{ 145{
145 int ret; 146 int ret;
146 147
147 pr_debug("ptrace: Enabling monitor mode...\n");
148 ocd_write(DC, ocd_read(DC) | (1 << OCD_DC_MM_BIT)
149 | (1 << OCD_DC_DBE_BIT));
150
151 switch (request) { 148 switch (request) {
152 /* Read the word at location addr in the child process */ 149 /* Read the word at location addr in the child process */
153 case PTRACE_PEEKTEXT: 150 case PTRACE_PEEKTEXT:
diff --git a/arch/avr32/kernel/signal.c b/arch/avr32/kernel/signal.c
index 0ec14854a200..5616a00c10ba 100644
--- a/arch/avr32/kernel/signal.c
+++ b/arch/avr32/kernel/signal.c
@@ -270,19 +270,12 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset, int syscall)
270 if (!user_mode(regs)) 270 if (!user_mode(regs))
271 return 0; 271 return 0;
272 272
273 if (try_to_freeze()) {
274 signr = 0;
275 if (!signal_pending(current))
276 goto no_signal;
277 }
278
279 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 273 if (test_thread_flag(TIF_RESTORE_SIGMASK))
280 oldset = &current->saved_sigmask; 274 oldset = &current->saved_sigmask;
281 else if (!oldset) 275 else if (!oldset)
282 oldset = &current->blocked; 276 oldset = &current->blocked;
283 277
284 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 278 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
285no_signal:
286 if (syscall) { 279 if (syscall) {
287 switch (regs->r12) { 280 switch (regs->r12) {
288 case -ERESTART_RESTARTBLOCK: 281 case -ERESTART_RESTARTBLOCK:
diff --git a/arch/avr32/kernel/time.c b/arch/avr32/kernel/time.c
index 7014a3571ec0..36a46c3ae308 100644
--- a/arch/avr32/kernel/time.c
+++ b/arch/avr32/kernel/time.c
@@ -214,7 +214,7 @@ void __init time_init(void)
214} 214}
215 215
216static struct sysdev_class timer_class = { 216static struct sysdev_class timer_class = {
217 set_kset_name("timer"), 217 .name = "timer",
218}; 218};
219 219
220static struct sys_device timer_device = { 220static struct sys_device timer_device = {
diff --git a/arch/avr32/kernel/traps.c b/arch/avr32/kernel/traps.c
index 870c075e6314..cf6f686d9b0b 100644
--- a/arch/avr32/kernel/traps.c
+++ b/arch/avr32/kernel/traps.c
@@ -9,6 +9,7 @@
9#include <linux/bug.h> 9#include <linux/bug.h>
10#include <linux/init.h> 10#include <linux/init.h>
11#include <linux/kallsyms.h> 11#include <linux/kallsyms.h>
12#include <linux/kdebug.h>
12#include <linux/module.h> 13#include <linux/module.h>
13#include <linux/notifier.h> 14#include <linux/notifier.h>
14#include <linux/sched.h> 15#include <linux/sched.h>
@@ -107,9 +108,23 @@ void _exception(long signr, struct pt_regs *regs, int code,
107 108
108asmlinkage void do_nmi(unsigned long ecr, struct pt_regs *regs) 109asmlinkage void do_nmi(unsigned long ecr, struct pt_regs *regs)
109{ 110{
110 printk(KERN_ALERT "Got Non-Maskable Interrupt, dumping regs\n"); 111 int ret;
111 show_regs_log_lvl(regs, KERN_ALERT); 112
112 show_stack_log_lvl(current, regs->sp, regs, KERN_ALERT); 113 nmi_enter();
114
115 ret = notify_die(DIE_NMI, "NMI", regs, 0, ecr, SIGINT);
116 switch (ret) {
117 case NOTIFY_OK:
118 case NOTIFY_STOP:
119 return;
120 case NOTIFY_BAD:
121 die("Fatal Non-Maskable Interrupt", regs, SIGINT);
122 default:
123 break;
124 }
125
126 printk(KERN_ALERT "Got NMI, but nobody cared. Disabling...\n");
127 nmi_disable();
113} 128}
114 129
115asmlinkage void do_critical_exception(unsigned long ecr, struct pt_regs *regs) 130asmlinkage void do_critical_exception(unsigned long ecr, struct pt_regs *regs)
diff --git a/arch/avr32/kernel/vmlinux.lds.S b/arch/avr32/kernel/vmlinux.lds.S
index 11f08e35a2eb..481cfd40c053 100644
--- a/arch/avr32/kernel/vmlinux.lds.S
+++ b/arch/avr32/kernel/vmlinux.lds.S
@@ -27,19 +27,19 @@ SECTIONS
27 __init_begin = .; 27 __init_begin = .;
28 _sinittext = .; 28 _sinittext = .;
29 *(.text.reset) 29 *(.text.reset)
30 *(.init.text) 30 INIT_TEXT
31 /* 31 /*
32 * .exit.text is discarded at runtime, not 32 * .exit.text is discarded at runtime, not
33 * link time, to deal with references from 33 * link time, to deal with references from
34 * __bug_table 34 * __bug_table
35 */ 35 */
36 *(.exit.text) 36 EXIT_TEXT
37 _einittext = .; 37 _einittext = .;
38 . = ALIGN(4); 38 . = ALIGN(4);
39 __tagtable_begin = .; 39 __tagtable_begin = .;
40 *(.taglist.init) 40 *(.taglist.init)
41 __tagtable_end = .; 41 __tagtable_end = .;
42 *(.init.data) 42 INIT_DATA
43 . = ALIGN(16); 43 . = ALIGN(16);
44 __setup_start = .; 44 __setup_start = .;
45 *(.init.setup) 45 *(.init.setup)
@@ -135,7 +135,7 @@ SECTIONS
135 * thrown away, as cleanup code is never called unless it's a module. 135 * thrown away, as cleanup code is never called unless it's a module.
136 */ 136 */
137 /DISCARD/ : { 137 /DISCARD/ : {
138 *(.exit.data) 138 EXIT_DATA
139 *(.exitcall.exit) 139 *(.exitcall.exit)
140 } 140 }
141 141
diff --git a/arch/avr32/mach-at32ap/Kconfig b/arch/avr32/mach-at32ap/Kconfig
index eb307838457b..a7bbcc82058e 100644
--- a/arch/avr32/mach-at32ap/Kconfig
+++ b/arch/avr32/mach-at32ap/Kconfig
@@ -3,9 +3,9 @@ if PLATFORM_AT32AP
3menu "Atmel AVR32 AP options" 3menu "Atmel AVR32 AP options"
4 4
5choice 5choice
6 prompt "AT32AP7000 static memory bus width" 6 prompt "AT32AP700x static memory bus width"
7 depends on CPU_AT32AP7000 7 depends on CPU_AT32AP700X
8 default AP7000_16_BIT_SMC 8 default AP700X_16_BIT_SMC
9 help 9 help
10 Define the width of the AP7000 external static memory interface. 10 Define the width of the AP7000 external static memory interface.
11 This is used to determine how to mangle the address and/or data 11 This is used to determine how to mangle the address and/or data
@@ -15,13 +15,13 @@ choice
15 width for all chip selects, excluding the flash (which is using 15 width for all chip selects, excluding the flash (which is using
16 raw access and is thus not affected by any of this.) 16 raw access and is thus not affected by any of this.)
17 17
18config AP7000_32_BIT_SMC 18config AP700X_32_BIT_SMC
19 bool "32 bit" 19 bool "32 bit"
20 20
21config AP7000_16_BIT_SMC 21config AP700X_16_BIT_SMC
22 bool "16 bit" 22 bool "16 bit"
23 23
24config AP7000_8_BIT_SMC 24config AP700X_8_BIT_SMC
25 bool "8 bit" 25 bool "8 bit"
26 26
27endchoice 27endchoice
diff --git a/arch/avr32/mach-at32ap/Makefile b/arch/avr32/mach-at32ap/Makefile
index a8b445046e3e..5e9f8217befc 100644
--- a/arch/avr32/mach-at32ap/Makefile
+++ b/arch/avr32/mach-at32ap/Makefile
@@ -1,4 +1,4 @@
1obj-y += at32ap.o clock.o intc.o extint.o pio.o hsmc.o 1obj-y += at32ap.o clock.o intc.o extint.o pio.o hsmc.o
2obj-$(CONFIG_CPU_AT32AP7000) += at32ap7000.o 2obj-$(CONFIG_CPU_AT32AP700X) += at32ap700x.o
3obj-$(CONFIG_CPU_AT32AP7000) += time-tc.o 3obj-$(CONFIG_CPU_AT32AP700X) += time-tc.o
4obj-$(CONFIG_CPU_FREQ_AT32AP) += cpufreq.o 4obj-$(CONFIG_CPU_FREQ_AT32AP) += cpufreq.o
diff --git a/arch/avr32/mach-at32ap/at32ap7000.c b/arch/avr32/mach-at32ap/at32ap700x.c
index 7c4388f4f17f..14e61f05e1f6 100644
--- a/arch/avr32/mach-at32ap/at32ap7000.c
+++ b/arch/avr32/mach-at32ap/at32ap700x.c
@@ -13,8 +13,9 @@
13#include <linux/spi/spi.h> 13#include <linux/spi/spi.h>
14 14
15#include <asm/io.h> 15#include <asm/io.h>
16#include <asm/irq.h>
16 17
17#include <asm/arch/at32ap7000.h> 18#include <asm/arch/at32ap700x.h>
18#include <asm/arch/board.h> 19#include <asm/arch/board.h>
19#include <asm/arch/portmux.h> 20#include <asm/arch/portmux.h>
20 21
@@ -803,6 +804,7 @@ void __init at32_setup_serial_console(unsigned int usart_id)
803 * Ethernet 804 * Ethernet
804 * -------------------------------------------------------------------- */ 805 * -------------------------------------------------------------------- */
805 806
807#ifdef CONFIG_CPU_AT32AP7000
806static struct eth_platform_data macb0_data; 808static struct eth_platform_data macb0_data;
807static struct resource macb0_resource[] = { 809static struct resource macb0_resource[] = {
808 PBMEM(0xfff01800), 810 PBMEM(0xfff01800),
@@ -890,6 +892,7 @@ at32_add_device_eth(unsigned int id, struct eth_platform_data *data)
890 892
891 return pdev; 893 return pdev;
892} 894}
895#endif
893 896
894/* -------------------------------------------------------------------- 897/* --------------------------------------------------------------------
895 * SPI 898 * SPI
@@ -1064,6 +1067,7 @@ err_add_resources:
1064/* -------------------------------------------------------------------- 1067/* --------------------------------------------------------------------
1065 * LCDC 1068 * LCDC
1066 * -------------------------------------------------------------------- */ 1069 * -------------------------------------------------------------------- */
1070#if defined(CONFIG_CPU_AT32AP7000) || defined(CONFIG_CPU_AT32AP7002)
1067static struct atmel_lcdfb_info atmel_lcdfb0_data; 1071static struct atmel_lcdfb_info atmel_lcdfb0_data;
1068static struct resource atmel_lcdfb0_resource[] = { 1072static struct resource atmel_lcdfb0_resource[] = {
1069 { 1073 {
@@ -1179,6 +1183,7 @@ err_dup_modedb:
1179 kfree(monspecs); 1183 kfree(monspecs);
1180 return NULL; 1184 return NULL;
1181} 1185}
1186#endif
1182 1187
1183/* -------------------------------------------------------------------- 1188/* --------------------------------------------------------------------
1184 * SSC 1189 * SSC
@@ -1332,6 +1337,7 @@ out_free_pdev:
1332/* -------------------------------------------------------------------- 1337/* --------------------------------------------------------------------
1333 * IDE / CompactFlash 1338 * IDE / CompactFlash
1334 * -------------------------------------------------------------------- */ 1339 * -------------------------------------------------------------------- */
1340#if defined(CONFIG_CPU_AT32AP7000) || defined(CONFIG_CPU_AT32AP7001)
1335static struct resource at32_smc_cs4_resource[] __initdata = { 1341static struct resource at32_smc_cs4_resource[] __initdata = {
1336 { 1342 {
1337 .start = 0x04000000, 1343 .start = 0x04000000,
@@ -1464,6 +1470,7 @@ fail:
1464 platform_device_put(pdev); 1470 platform_device_put(pdev);
1465 return NULL; 1471 return NULL;
1466} 1472}
1473#endif
1467 1474
1468/* -------------------------------------------------------------------- 1475/* --------------------------------------------------------------------
1469 * AC97C 1476 * AC97C
@@ -1639,16 +1646,20 @@ struct clk *at32_clock_list[] = {
1639 &atmel_usart1_usart, 1646 &atmel_usart1_usart,
1640 &atmel_usart2_usart, 1647 &atmel_usart2_usart,
1641 &atmel_usart3_usart, 1648 &atmel_usart3_usart,
1649#if defined(CONFIG_CPU_AT32AP7000)
1642 &macb0_hclk, 1650 &macb0_hclk,
1643 &macb0_pclk, 1651 &macb0_pclk,
1644 &macb1_hclk, 1652 &macb1_hclk,
1645 &macb1_pclk, 1653 &macb1_pclk,
1654#endif
1646 &atmel_spi0_spi_clk, 1655 &atmel_spi0_spi_clk,
1647 &atmel_spi1_spi_clk, 1656 &atmel_spi1_spi_clk,
1648 &atmel_twi0_pclk, 1657 &atmel_twi0_pclk,
1649 &atmel_mci0_pclk, 1658 &atmel_mci0_pclk,
1659#if defined(CONFIG_CPU_AT32AP7000) || defined(CONFIG_CPU_AT32AP7002)
1650 &atmel_lcdfb0_hck1, 1660 &atmel_lcdfb0_hck1,
1651 &atmel_lcdfb0_pixclk, 1661 &atmel_lcdfb0_pixclk,
1662#endif
1652 &ssc0_pclk, 1663 &ssc0_pclk,
1653 &ssc1_pclk, 1664 &ssc1_pclk,
1654 &ssc2_pclk, 1665 &ssc2_pclk,
@@ -1697,7 +1708,9 @@ void __init at32_clock_init(void)
1697 genclk_init_parent(&gclk2); 1708 genclk_init_parent(&gclk2);
1698 genclk_init_parent(&gclk3); 1709 genclk_init_parent(&gclk3);
1699 genclk_init_parent(&gclk4); 1710 genclk_init_parent(&gclk4);
1711#if defined(CONFIG_CPU_AT32AP7000) || defined(CONFIG_CPU_AT32AP7002)
1700 genclk_init_parent(&atmel_lcdfb0_pixclk); 1712 genclk_init_parent(&atmel_lcdfb0_pixclk);
1713#endif
1701 genclk_init_parent(&abdac0_sample_clk); 1714 genclk_init_parent(&abdac0_sample_clk);
1702 1715
1703 /* 1716 /*
diff --git a/arch/avr32/mach-at32ap/extint.c b/arch/avr32/mach-at32ap/extint.c
index f5bfd4c81fe7..c36a6d59d6f0 100644
--- a/arch/avr32/mach-at32ap/extint.c
+++ b/arch/avr32/mach-at32ap/extint.c
@@ -26,16 +26,10 @@
26#define EIC_MODE 0x0014 26#define EIC_MODE 0x0014
27#define EIC_EDGE 0x0018 27#define EIC_EDGE 0x0018
28#define EIC_LEVEL 0x001c 28#define EIC_LEVEL 0x001c
29#define EIC_TEST 0x0020
30#define EIC_NMIC 0x0024 29#define EIC_NMIC 0x0024
31 30
32/* Bitfields in TEST */
33#define EIC_TESTEN_OFFSET 31
34#define EIC_TESTEN_SIZE 1
35
36/* Bitfields in NMIC */ 31/* Bitfields in NMIC */
37#define EIC_EN_OFFSET 0 32#define EIC_NMIC_ENABLE (1 << 0)
38#define EIC_EN_SIZE 1
39 33
40/* Bit manipulation macros */ 34/* Bit manipulation macros */
41#define EIC_BIT(name) \ 35#define EIC_BIT(name) \
@@ -63,6 +57,9 @@ struct eic {
63 unsigned int first_irq; 57 unsigned int first_irq;
64}; 58};
65 59
60static struct eic *nmi_eic;
61static bool nmi_enabled;
62
66static void eic_ack_irq(unsigned int irq) 63static void eic_ack_irq(unsigned int irq)
67{ 64{
68 struct eic *eic = get_irq_chip_data(irq); 65 struct eic *eic = get_irq_chip_data(irq);
@@ -133,8 +130,11 @@ static int eic_set_irq_type(unsigned int irq, unsigned int flow_type)
133 eic_writel(eic, EDGE, edge); 130 eic_writel(eic, EDGE, edge);
134 eic_writel(eic, LEVEL, level); 131 eic_writel(eic, LEVEL, level);
135 132
136 if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) 133 if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) {
137 flow_type |= IRQ_LEVEL; 134 flow_type |= IRQ_LEVEL;
135 __set_irq_handler_unlocked(irq, handle_level_irq);
136 } else
137 __set_irq_handler_unlocked(irq, handle_edge_irq);
138 desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); 138 desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
139 desc->status |= flow_type; 139 desc->status |= flow_type;
140 } 140 }
@@ -154,9 +154,8 @@ static struct irq_chip eic_chip = {
154static void demux_eic_irq(unsigned int irq, struct irq_desc *desc) 154static void demux_eic_irq(unsigned int irq, struct irq_desc *desc)
155{ 155{
156 struct eic *eic = desc->handler_data; 156 struct eic *eic = desc->handler_data;
157 struct irq_desc *ext_desc;
158 unsigned long status, pending; 157 unsigned long status, pending;
159 unsigned int i, ext_irq; 158 unsigned int i;
160 159
161 status = eic_readl(eic, ISR); 160 status = eic_readl(eic, ISR);
162 pending = status & eic_readl(eic, IMR); 161 pending = status & eic_readl(eic, IMR);
@@ -165,15 +164,28 @@ static void demux_eic_irq(unsigned int irq, struct irq_desc *desc)
165 i = fls(pending) - 1; 164 i = fls(pending) - 1;
166 pending &= ~(1 << i); 165 pending &= ~(1 << i);
167 166
168 ext_irq = i + eic->first_irq; 167 generic_handle_irq(i + eic->first_irq);
169 ext_desc = irq_desc + ext_irq;
170 if (ext_desc->status & IRQ_LEVEL)
171 handle_level_irq(ext_irq, ext_desc);
172 else
173 handle_edge_irq(ext_irq, ext_desc);
174 } 168 }
175} 169}
176 170
171int nmi_enable(void)
172{
173 nmi_enabled = true;
174
175 if (nmi_eic)
176 eic_writel(nmi_eic, NMIC, EIC_NMIC_ENABLE);
177
178 return 0;
179}
180
181void nmi_disable(void)
182{
183 if (nmi_eic)
184 eic_writel(nmi_eic, NMIC, 0);
185
186 nmi_enabled = false;
187}
188
177static int __init eic_probe(struct platform_device *pdev) 189static int __init eic_probe(struct platform_device *pdev)
178{ 190{
179 struct eic *eic; 191 struct eic *eic;
@@ -214,14 +226,13 @@ static int __init eic_probe(struct platform_device *pdev)
214 pattern = eic_readl(eic, MODE); 226 pattern = eic_readl(eic, MODE);
215 nr_irqs = fls(pattern); 227 nr_irqs = fls(pattern);
216 228
217 /* Trigger on falling edge unless overridden by driver */ 229 /* Trigger on low level unless overridden by driver */
218 eic_writel(eic, MODE, 0UL);
219 eic_writel(eic, EDGE, 0UL); 230 eic_writel(eic, EDGE, 0UL);
231 eic_writel(eic, LEVEL, 0UL);
220 232
221 eic->chip = &eic_chip; 233 eic->chip = &eic_chip;
222 234
223 for (i = 0; i < nr_irqs; i++) { 235 for (i = 0; i < nr_irqs; i++) {
224 /* NOTE the handler we set here is ignored by the demux */
225 set_irq_chip_and_handler(eic->first_irq + i, &eic_chip, 236 set_irq_chip_and_handler(eic->first_irq + i, &eic_chip,
226 handle_level_irq); 237 handle_level_irq);
227 set_irq_chip_data(eic->first_irq + i, eic); 238 set_irq_chip_data(eic->first_irq + i, eic);
@@ -230,6 +241,16 @@ static int __init eic_probe(struct platform_device *pdev)
230 set_irq_chained_handler(int_irq, demux_eic_irq); 241 set_irq_chained_handler(int_irq, demux_eic_irq);
231 set_irq_data(int_irq, eic); 242 set_irq_data(int_irq, eic);
232 243
244 if (pdev->id == 0) {
245 nmi_eic = eic;
246 if (nmi_enabled)
247 /*
248 * Someone tried to enable NMI before we were
249 * ready. Do it now.
250 */
251 nmi_enable();
252 }
253
233 dev_info(&pdev->dev, 254 dev_info(&pdev->dev,
234 "External Interrupt Controller at 0x%p, IRQ %u\n", 255 "External Interrupt Controller at 0x%p, IRQ %u\n",
235 eic->regs, int_irq); 256 eic->regs, int_irq);
diff --git a/arch/avr32/mm/dma-coherent.c b/arch/avr32/mm/dma-coherent.c
index 177fea8f7b71..6d8c794c3b81 100644
--- a/arch/avr32/mm/dma-coherent.c
+++ b/arch/avr32/mm/dma-coherent.c
@@ -41,6 +41,13 @@ static struct page *__dma_alloc(struct device *dev, size_t size,
41 struct page *page, *free, *end; 41 struct page *page, *free, *end;
42 int order; 42 int order;
43 43
44 /* Following is a work-around (a.k.a. hack) to prevent pages
45 * with __GFP_COMP being passed to split_page() which cannot
46 * handle them. The real problem is that this flag probably
47 * should be 0 on AVR32 as it is not supported on this
48 * platform--see CONFIG_HUGETLB_PAGE. */
49 gfp &= ~(__GFP_COMP);
50
44 size = PAGE_ALIGN(size); 51 size = PAGE_ALIGN(size);
45 order = get_order(size); 52 order = get_order(size);
46 53
diff --git a/arch/avr32/mm/tlb.c b/arch/avr32/mm/tlb.c
index 56672018e42f..b835257a8fa3 100644
--- a/arch/avr32/mm/tlb.c
+++ b/arch/avr32/mm/tlb.c
@@ -348,7 +348,7 @@ static int tlb_show(struct seq_file *tlb, void *v)
348 return 0; 348 return 0;
349} 349}
350 350
351static struct seq_operations tlb_ops = { 351static const struct seq_operations tlb_ops = {
352 .start = tlb_start, 352 .start = tlb_start,
353 .next = tlb_next, 353 .next = tlb_next,
354 .stop = tlb_stop, 354 .stop = tlb_stop,
diff --git a/arch/avr32/oprofile/Makefile b/arch/avr32/oprofile/Makefile
new file mode 100644
index 000000000000..1fe81c3c1e86
--- /dev/null
+++ b/arch/avr32/oprofile/Makefile
@@ -0,0 +1,8 @@
1obj-$(CONFIG_OPROFILE) += oprofile.o
2
3oprofile-y := $(addprefix ../../../drivers/oprofile/, \
4 oprof.o cpu_buffer.o buffer_sync.o \
5 event_buffer.o oprofile_files.o \
6 oprofilefs.o oprofile_stats.o \
7 timer_int.o)
8oprofile-y += op_model_avr32.o
diff --git a/arch/avr32/oprofile/op_model_avr32.c b/arch/avr32/oprofile/op_model_avr32.c
new file mode 100644
index 000000000000..e2f876bfc86b
--- /dev/null
+++ b/arch/avr32/oprofile/op_model_avr32.c
@@ -0,0 +1,235 @@
1/*
2 * AVR32 Performance Counter Driver
3 *
4 * Copyright (C) 2005-2007 Atmel Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Author: Ronny Pedersen
11 */
12#include <linux/errno.h>
13#include <linux/interrupt.h>
14#include <linux/irq.h>
15#include <linux/oprofile.h>
16#include <linux/sched.h>
17#include <linux/types.h>
18
19#include <asm/intc.h>
20#include <asm/sysreg.h>
21#include <asm/system.h>
22
23#define AVR32_PERFCTR_IRQ_GROUP 0
24#define AVR32_PERFCTR_IRQ_LINE 1
25
26enum { PCCNT, PCNT0, PCNT1, NR_counter };
27
28struct avr32_perf_counter {
29 unsigned long enabled;
30 unsigned long event;
31 unsigned long count;
32 unsigned long unit_mask;
33 unsigned long kernel;
34 unsigned long user;
35
36 u32 ie_mask;
37 u32 flag_mask;
38};
39
40static struct avr32_perf_counter counter[NR_counter] = {
41 {
42 .ie_mask = SYSREG_BIT(IEC),
43 .flag_mask = SYSREG_BIT(FC),
44 }, {
45 .ie_mask = SYSREG_BIT(IE0),
46 .flag_mask = SYSREG_BIT(F0),
47 }, {
48 .ie_mask = SYSREG_BIT(IE1),
49 .flag_mask = SYSREG_BIT(F1),
50 },
51};
52
53static void avr32_perf_counter_reset(void)
54{
55 /* Reset all counter and disable/clear all interrupts */
56 sysreg_write(PCCR, (SYSREG_BIT(PCCR_R)
57 | SYSREG_BIT(PCCR_C)
58 | SYSREG_BIT(FC)
59 | SYSREG_BIT(F0)
60 | SYSREG_BIT(F1)));
61}
62
63static irqreturn_t avr32_perf_counter_interrupt(int irq, void *dev_id)
64{
65 struct avr32_perf_counter *ctr = dev_id;
66 struct pt_regs *regs;
67 u32 pccr;
68
69 if (likely(!(intc_get_pending(AVR32_PERFCTR_IRQ_GROUP)
70 & (1 << AVR32_PERFCTR_IRQ_LINE))))
71 return IRQ_NONE;
72
73 regs = get_irq_regs();
74 pccr = sysreg_read(PCCR);
75
76 /* Clear the interrupt flags we're about to handle */
77 sysreg_write(PCCR, pccr);
78
79 /* PCCNT */
80 if (ctr->enabled && (pccr & ctr->flag_mask)) {
81 sysreg_write(PCCNT, -ctr->count);
82 oprofile_add_sample(regs, PCCNT);
83 }
84 ctr++;
85 /* PCNT0 */
86 if (ctr->enabled && (pccr & ctr->flag_mask)) {
87 sysreg_write(PCNT0, -ctr->count);
88 oprofile_add_sample(regs, PCNT0);
89 }
90 ctr++;
91 /* PCNT1 */
92 if (ctr->enabled && (pccr & ctr->flag_mask)) {
93 sysreg_write(PCNT1, -ctr->count);
94 oprofile_add_sample(regs, PCNT1);
95 }
96
97 return IRQ_HANDLED;
98}
99
100static int avr32_perf_counter_create_files(struct super_block *sb,
101 struct dentry *root)
102{
103 struct dentry *dir;
104 unsigned int i;
105 char filename[4];
106
107 for (i = 0; i < NR_counter; i++) {
108 snprintf(filename, sizeof(filename), "%u", i);
109 dir = oprofilefs_mkdir(sb, root, filename);
110
111 oprofilefs_create_ulong(sb, dir, "enabled",
112 &counter[i].enabled);
113 oprofilefs_create_ulong(sb, dir, "event",
114 &counter[i].event);
115 oprofilefs_create_ulong(sb, dir, "count",
116 &counter[i].count);
117
118 /* Dummy entries */
119 oprofilefs_create_ulong(sb, dir, "kernel",
120 &counter[i].kernel);
121 oprofilefs_create_ulong(sb, dir, "user",
122 &counter[i].user);
123 oprofilefs_create_ulong(sb, dir, "unit_mask",
124 &counter[i].unit_mask);
125 }
126
127 return 0;
128}
129
130static int avr32_perf_counter_setup(void)
131{
132 struct avr32_perf_counter *ctr;
133 u32 pccr;
134 int ret;
135 int i;
136
137 pr_debug("avr32_perf_counter_setup\n");
138
139 if (sysreg_read(PCCR) & SYSREG_BIT(PCCR_E)) {
140 printk(KERN_ERR
141 "oprofile: setup: perf counter already enabled\n");
142 return -EBUSY;
143 }
144
145 ret = request_irq(AVR32_PERFCTR_IRQ_GROUP,
146 avr32_perf_counter_interrupt, IRQF_SHARED,
147 "oprofile", counter);
148 if (ret)
149 return ret;
150
151 avr32_perf_counter_reset();
152
153 pccr = 0;
154 for (i = PCCNT; i < NR_counter; i++) {
155 ctr = &counter[i];
156 if (!ctr->enabled)
157 continue;
158
159 pr_debug("enabling counter %d...\n", i);
160
161 pccr |= ctr->ie_mask;
162
163 switch (i) {
164 case PCCNT:
165 /* PCCNT always counts cycles, so no events */
166 sysreg_write(PCCNT, -ctr->count);
167 break;
168 case PCNT0:
169 pccr |= SYSREG_BF(CONF0, ctr->event);
170 sysreg_write(PCNT0, -ctr->count);
171 break;
172 case PCNT1:
173 pccr |= SYSREG_BF(CONF1, ctr->event);
174 sysreg_write(PCNT1, -ctr->count);
175 break;
176 }
177 }
178
179 pr_debug("oprofile: writing 0x%x to PCCR...\n", pccr);
180
181 sysreg_write(PCCR, pccr);
182
183 return 0;
184}
185
186static void avr32_perf_counter_shutdown(void)
187{
188 pr_debug("avr32_perf_counter_shutdown\n");
189
190 avr32_perf_counter_reset();
191 free_irq(AVR32_PERFCTR_IRQ_GROUP, counter);
192}
193
194static int avr32_perf_counter_start(void)
195{
196 pr_debug("avr32_perf_counter_start\n");
197
198 sysreg_write(PCCR, sysreg_read(PCCR) | SYSREG_BIT(PCCR_E));
199
200 return 0;
201}
202
203static void avr32_perf_counter_stop(void)
204{
205 pr_debug("avr32_perf_counter_stop\n");
206
207 sysreg_write(PCCR, sysreg_read(PCCR) & ~SYSREG_BIT(PCCR_E));
208}
209
210static struct oprofile_operations avr32_perf_counter_ops __initdata = {
211 .create_files = avr32_perf_counter_create_files,
212 .setup = avr32_perf_counter_setup,
213 .shutdown = avr32_perf_counter_shutdown,
214 .start = avr32_perf_counter_start,
215 .stop = avr32_perf_counter_stop,
216 .cpu_type = "avr32",
217};
218
219int __init oprofile_arch_init(struct oprofile_operations *ops)
220{
221 if (!(current_cpu_data.features & AVR32_FEATURE_PCTR))
222 return -ENODEV;
223
224 memcpy(ops, &avr32_perf_counter_ops,
225 sizeof(struct oprofile_operations));
226
227 printk(KERN_INFO "oprofile: using AVR32 performance monitoring.\n");
228
229 return 0;
230}
231
232void oprofile_arch_exit(void)
233{
234
235}
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index 25232ba08119..fc7ca86ac8bf 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -85,11 +85,26 @@ config BF522
85 help 85 help
86 BF522 Processor Support. 86 BF522 Processor Support.
87 87
88config BF523
89 bool "BF523"
90 help
91 BF523 Processor Support.
92
93config BF524
94 bool "BF524"
95 help
96 BF524 Processor Support.
97
88config BF525 98config BF525
89 bool "BF525" 99 bool "BF525"
90 help 100 help
91 BF525 Processor Support. 101 BF525 Processor Support.
92 102
103config BF526
104 bool "BF526"
105 help
106 BF526 Processor Support.
107
93config BF527 108config BF527
94 bool "BF527" 109 bool "BF527"
95 help 110 help
@@ -198,7 +213,7 @@ endchoice
198 213
199config BF52x 214config BF52x
200 bool 215 bool
201 depends on (BF522 || BF525 || BF527) 216 depends on (BF522 || BF523 || BF524 || BF525 || BF526 || BF527)
202 default y 217 default y
203 218
204config BF53x 219config BF53x
@@ -253,11 +268,6 @@ config MEM_MT48LC32M16A2TG_75
253 depends on (BFIN527_EZKIT) 268 depends on (BFIN527_EZKIT)
254 default y 269 default y
255 270
256config BFIN_SHARED_FLASH_ENET
257 bool
258 depends on (BFIN533_STAMP)
259 default y
260
261source "arch/blackfin/mach-bf527/Kconfig" 271source "arch/blackfin/mach-bf527/Kconfig"
262source "arch/blackfin/mach-bf533/Kconfig" 272source "arch/blackfin/mach-bf533/Kconfig"
263source "arch/blackfin/mach-bf561/Kconfig" 273source "arch/blackfin/mach-bf561/Kconfig"
@@ -317,7 +327,7 @@ config VCO_MULT
317 range 1 64 327 range 1 64
318 default "22" if BFIN533_EZKIT 328 default "22" if BFIN533_EZKIT
319 default "45" if BFIN533_STAMP 329 default "45" if BFIN533_STAMP
320 default "20" if (BFIN537_STAMP || BFIN527_EZKIT) 330 default "20" if (BFIN537_STAMP || BFIN527_EZKIT || BFIN548_EZKIT)
321 default "22" if BFIN533_BLUETECHNIX_CM 331 default "22" if BFIN533_BLUETECHNIX_CM
322 default "20" if BFIN537_BLUETECHNIX_CM 332 default "20" if BFIN537_BLUETECHNIX_CM
323 default "20" if BFIN561_BLUETECHNIX_CM 333 default "20" if BFIN561_BLUETECHNIX_CM
@@ -354,7 +364,7 @@ config SCLK_DIV
354 range 1 15 364 range 1 15
355 default 5 if BFIN533_EZKIT 365 default 5 if BFIN533_EZKIT
356 default 5 if BFIN533_STAMP 366 default 5 if BFIN533_STAMP
357 default 4 if (BFIN537_STAMP || BFIN527_EZKIT) 367 default 4 if (BFIN537_STAMP || BFIN527_EZKIT || BFIN548_EZKIT)
358 default 5 if BFIN533_BLUETECHNIX_CM 368 default 5 if BFIN533_BLUETECHNIX_CM
359 default 4 if BFIN537_BLUETECHNIX_CM 369 default 4 if BFIN537_BLUETECHNIX_CM
360 default 4 if BFIN561_BLUETECHNIX_CM 370 default 4 if BFIN561_BLUETECHNIX_CM
@@ -371,7 +381,10 @@ config SCLK_DIV
371config MAX_VCO_HZ 381config MAX_VCO_HZ
372 int 382 int
373 default 600000000 if BF522 383 default 600000000 if BF522
384 default 400000000 if BF523
385 default 400000000 if BF524
374 default 600000000 if BF525 386 default 600000000 if BF525
387 default 400000000 if BF526
375 default 600000000 if BF527 388 default 600000000 if BF527
376 default 400000000 if BF531 389 default 400000000 if BF531
377 default 400000000 if BF532 390 default 400000000 if BF532
@@ -383,6 +396,8 @@ config MAX_VCO_HZ
383 default 533333333 if BF539 396 default 533333333 if BF539
384 default 600000000 if BF542 397 default 600000000 if BF542
385 default 533333333 if BF544 398 default 533333333 if BF544
399 default 600000000 if BF547
400 default 600000000 if BF548
386 default 533333333 if BF549 401 default 533333333 if BF549
387 default 600000000 if BF561 402 default 600000000 if BF561
388 403
@@ -409,6 +424,7 @@ config MEM_SIZE
409 default 32 if BFIN533_EZKIT 424 default 32 if BFIN533_EZKIT
410 default 64 if BFIN527_EZKIT 425 default 64 if BFIN527_EZKIT
411 default 64 if BFIN537_STAMP 426 default 64 if BFIN537_STAMP
427 default 64 if BFIN548_EZKIT
412 default 64 if BFIN561_EZKIT 428 default 64 if BFIN561_EZKIT
413 default 128 if BFIN533_STAMP 429 default 128 if BFIN533_STAMP
414 default 64 if PNAV10 430 default 64 if PNAV10
@@ -416,6 +432,7 @@ config MEM_SIZE
416 432
417config MEM_ADD_WIDTH 433config MEM_ADD_WIDTH
418 int "SDRAM Memory Address Width" 434 int "SDRAM Memory Address Width"
435 depends on (!BF54x)
419 default 9 if BFIN533_EZKIT 436 default 9 if BFIN533_EZKIT
420 default 9 if BFIN561_EZKIT 437 default 9 if BFIN561_EZKIT
421 default 9 if H8606_HVSISTEMAS 438 default 9 if H8606_HVSISTEMAS
@@ -424,6 +441,19 @@ config MEM_ADD_WIDTH
424 default 11 if BFIN533_STAMP 441 default 11 if BFIN533_STAMP
425 default 10 if PNAV10 442 default 10 if PNAV10
426 443
444
445choice
446 prompt "DDR SDRAM Chip Type"
447 depends on BFIN548_EZKIT
448 default MEM_MT46V32M16_5B
449
450config MEM_MT46V32M16_6T
451 bool "MT46V32M16_6T"
452
453config MEM_MT46V32M16_5B
454 bool "MT46V32M16_5B"
455endchoice
456
427config ENET_FLASH_PIN 457config ENET_FLASH_PIN
428 int "PF port/pin used for flash and ethernet sharing" 458 int "PF port/pin used for flash and ethernet sharing"
429 depends on (BFIN533_STAMP) 459 depends on (BFIN533_STAMP)
@@ -448,40 +478,6 @@ config BOOT_LOAD
448 memory region is used to capture NULL pointer references as well 478 memory region is used to capture NULL pointer references as well
449 as some core kernel functions. 479 as some core kernel functions.
450 480
451comment "LED Status Indicators"
452 depends on (BFIN533_STAMP || BFIN533_BLUETECHNIX_CM)
453
454config BFIN_ALIVE_LED
455 bool "Enable Board Alive"
456 depends on (BFIN533_STAMP || BFIN533_BLUETECHNIX_CM)
457 default n
458 help
459 Blink the LEDs you select when the kernel is running. Helps detect
460 a hung kernel.
461
462config BFIN_ALIVE_LED_NUM
463 int "LED"
464 depends on BFIN_ALIVE_LED
465 range 1 3 if BFIN533_STAMP
466 default "3" if BFIN533_STAMP
467 help
468 Select the LED (marked on the board) for you to blink.
469
470config BFIN_IDLE_LED
471 bool "Enable System Load/Idle LED"
472 depends on (BFIN533_STAMP || BFIN533_BLUETECHNIX_CM)
473 default n
474 help
475 Blinks the LED you select when to determine kernel load.
476
477config BFIN_IDLE_LED_NUM
478 int "LED"
479 depends on BFIN_IDLE_LED
480 range 1 3 if BFIN533_STAMP
481 default "2" if BFIN533_STAMP
482 help
483 Select the LED (marked on the board) for you to blink.
484
485choice 481choice
486 prompt "Blackfin Exception Scratch Register" 482 prompt "Blackfin Exception Scratch Register"
487 default BFIN_SCRATCH_REG_RETN 483 default BFIN_SCRATCH_REG_RETN
@@ -528,41 +524,6 @@ config BFIN_SCRATCH_REG_CYCLES
528 524
529endchoice 525endchoice
530 526
531#
532# Sorry - but you need to put the hex address here -
533#
534
535# Flag Data register
536config BFIN_ALIVE_LED_PORT
537 hex
538 default 0xFFC00700 if (BFIN533_STAMP)
539
540# Peripheral Flag Direction Register
541config BFIN_ALIVE_LED_DPORT
542 hex
543 default 0xFFC00730 if (BFIN533_STAMP)
544
545config BFIN_ALIVE_LED_PIN
546 hex
547 default 0x04 if (BFIN533_STAMP && BFIN_ALIVE_LED_NUM = 1)
548 default 0x08 if (BFIN533_STAMP && BFIN_ALIVE_LED_NUM = 2)
549 default 0x10 if (BFIN533_STAMP && BFIN_ALIVE_LED_NUM = 3)
550
551config BFIN_IDLE_LED_PORT
552 hex
553 default 0xFFC00700 if (BFIN533_STAMP)
554
555# Peripheral Flag Direction Register
556config BFIN_IDLE_LED_DPORT
557 hex
558 default 0xFFC00730 if (BFIN533_STAMP)
559
560config BFIN_IDLE_LED_PIN
561 hex
562 default 0x04 if (BFIN533_STAMP && BFIN_IDLE_LED_NUM = 1)
563 default 0x08 if (BFIN533_STAMP && BFIN_IDLE_LED_NUM = 2)
564 default 0x10 if (BFIN533_STAMP && BFIN_IDLE_LED_NUM = 3)
565
566endmenu 527endmenu
567 528
568 529
@@ -799,6 +760,15 @@ config L1_MAX_PIECE
799 Set the max memory pieces for the L1 SRAM allocation algorithm. 760 Set the max memory pieces for the L1 SRAM allocation algorithm.
800 Min value is 16. Max value is 1024. 761 Min value is 16. Max value is 1024.
801 762
763
764config MPU
765 bool "Enable the memory protection unit (EXPERIMENTAL)"
766 default n
767 help
768 Use the processor's MPU to protect applications from accessing
769 memory they do not own. This comes at a performance penalty
770 and is recommended only for debugging.
771
802comment "Asynchonous Memory Configuration" 772comment "Asynchonous Memory Configuration"
803 773
804menu "EBIU_AMGCTL Global Control" 774menu "EBIU_AMGCTL Global Control"
@@ -808,7 +778,6 @@ config C_AMCKEN
808 778
809config C_CDPRIO 779config C_CDPRIO
810 bool "DMA has priority over core for ext. accesses" 780 bool "DMA has priority over core for ext. accesses"
811 depends on !BF54x
812 default n 781 default n
813 782
814config C_B0PEN 783config C_B0PEN
@@ -949,8 +918,10 @@ endchoice
949config PM_WAKEUP_SIC_IWR 918config PM_WAKEUP_SIC_IWR
950 hex "Wakeup Events (SIC_IWR)" 919 hex "Wakeup Events (SIC_IWR)"
951 depends on PM_WAKEUP_GPIO_BY_SIC_IWR 920 depends on PM_WAKEUP_GPIO_BY_SIC_IWR
952 default 0x80000000 if (BF537 || BF536 || BF534) 921 default 0x8 if (BF537 || BF536 || BF534)
953 default 0x100000 if (BF533 || BF532 || BF531) 922 default 0x80 if (BF533 || BF532 || BF531)
923 default 0x80 if (BF54x)
924 default 0x80 if (BF52x)
954 925
955config PM_WAKEUP_GPIO_NUMBER 926config PM_WAKEUP_GPIO_NUMBER
956 int "Wakeup GPIO number" 927 int "Wakeup GPIO number"
diff --git a/arch/blackfin/Makefile b/arch/blackfin/Makefile
index c47e000f8324..0edc402fef54 100644
--- a/arch/blackfin/Makefile
+++ b/arch/blackfin/Makefile
@@ -21,7 +21,10 @@ KBUILD_DEFCONFIG := BF537-STAMP_defconfig
21 21
22# setup the machine name and the machine dependent settings 22# setup the machine name and the machine dependent settings
23machine-$(CONFIG_BF522) := bf527 23machine-$(CONFIG_BF522) := bf527
24machine-$(CONFIG_BF523) := bf527
25machine-$(CONFIG_BF524) := bf527
24machine-$(CONFIG_BF525) := bf527 26machine-$(CONFIG_BF525) := bf527
27machine-$(CONFIG_BF526) := bf527
25machine-$(CONFIG_BF527) := bf527 28machine-$(CONFIG_BF527) := bf527
26machine-$(CONFIG_BF531) := bf533 29machine-$(CONFIG_BF531) := bf533
27machine-$(CONFIG_BF532) := bf533 30machine-$(CONFIG_BF532) := bf533
@@ -39,7 +42,10 @@ MACHINE := $(machine-y)
39export MACHINE 42export MACHINE
40 43
41cpu-$(CONFIG_BF522) := bf522 44cpu-$(CONFIG_BF522) := bf522
45cpu-$(CONFIG_BF523) := bf523
46cpu-$(CONFIG_BF524) := bf524
42cpu-$(CONFIG_BF525) := bf525 47cpu-$(CONFIG_BF525) := bf525
48cpu-$(CONFIG_BF526) := bf526
43cpu-$(CONFIG_BF527) := bf527 49cpu-$(CONFIG_BF527) := bf527
44cpu-$(CONFIG_BF531) := bf531 50cpu-$(CONFIG_BF531) := bf531
45cpu-$(CONFIG_BF532) := bf532 51cpu-$(CONFIG_BF532) := bf532
@@ -76,6 +82,12 @@ core-y += arch/$(ARCH)/mach-$(MACHINE)/
76core-y += arch/$(ARCH)/mach-$(MACHINE)/boards/ 82core-y += arch/$(ARCH)/mach-$(MACHINE)/boards/
77endif 83endif
78 84
85ifeq ($(CONFIG_MPU),y)
86core-y += arch/$(ARCH)/kernel/cplb-mpu/
87else
88core-y += arch/$(ARCH)/kernel/cplb-nompu/
89endif
90
79libs-y += arch/$(ARCH)/lib/ 91libs-y += arch/$(ARCH)/lib/
80 92
81drivers-$(CONFIG_OPROFILE) += arch/$(ARCH)/oprofile/ 93drivers-$(CONFIG_OPROFILE) += arch/$(ARCH)/oprofile/
diff --git a/arch/blackfin/configs/BF527-EZKIT_defconfig b/arch/blackfin/configs/BF527-EZKIT_defconfig
index fa6eb4e00fae..d59ee1530bd4 100644
--- a/arch/blackfin/configs/BF527-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF527-EZKIT_defconfig
@@ -1,6 +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.22.12 3# Linux kernel version: 2.6.22.14
4# Thu Nov 29 17:32:47 2007
4# 5#
5# CONFIG_MMU is not set 6# CONFIG_MMU is not set
6# CONFIG_FPU is not set 7# CONFIG_FPU is not set
@@ -153,8 +154,8 @@ CONFIG_BFIN527_EZKIT=y
153CONFIG_BF527_SPORT0_PORTG=y 154CONFIG_BF527_SPORT0_PORTG=y
154CONFIG_BF527_SPORT0_TSCLK_PG10=y 155CONFIG_BF527_SPORT0_TSCLK_PG10=y
155# CONFIG_BF527_SPORT0_TSCLK_PG14 is not set 156# CONFIG_BF527_SPORT0_TSCLK_PG14 is not set
156# CONFIG_BF527_UART1_PORTF is not set 157CONFIG_BF527_UART1_PORTF=y
157CONFIG_BF527_UART1_PORTG=y 158# CONFIG_BF527_UART1_PORTG is not set
158# CONFIG_BF527_NAND_D_PORTF is not set 159# CONFIG_BF527_NAND_D_PORTF is not set
159CONFIG_BF527_NAND_D_PORTH=y 160CONFIG_BF527_NAND_D_PORTH=y
160 161
@@ -232,7 +233,7 @@ CONFIG_CLKIN_HZ=25000000
232# CONFIG_BFIN_KERNEL_CLOCK is not set 233# CONFIG_BFIN_KERNEL_CLOCK is not set
233CONFIG_MAX_VCO_HZ=600000000 234CONFIG_MAX_VCO_HZ=600000000
234CONFIG_MIN_VCO_HZ=50000000 235CONFIG_MIN_VCO_HZ=50000000
235CONFIG_MAX_SCLK_HZ=133000000 236CONFIG_MAX_SCLK_HZ=133333333
236CONFIG_MIN_SCLK_HZ=27000000 237CONFIG_MIN_SCLK_HZ=27000000
237 238
238# 239#
@@ -626,8 +627,8 @@ CONFIG_BFIN_MAC_RMII=y
626# CONFIG_SMSC911X is not set 627# CONFIG_SMSC911X is not set
627# CONFIG_DM9000 is not set 628# CONFIG_DM9000 is not set
628CONFIG_NETDEV_1000=y 629CONFIG_NETDEV_1000=y
629CONFIG_NETDEV_10000=y
630# CONFIG_AX88180 is not set 630# CONFIG_AX88180 is not set
631CONFIG_NETDEV_10000=y
631 632
632# 633#
633# Wireless LAN 634# Wireless LAN
@@ -1183,7 +1184,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
1183# 1184#
1184# CONFIG_PRINTK_TIME is not set 1185# CONFIG_PRINTK_TIME is not set
1185CONFIG_ENABLE_MUST_CHECK=y 1186CONFIG_ENABLE_MUST_CHECK=y
1186CONFIG_MAGIC_SYSRQ=y 1187# CONFIG_MAGIC_SYSRQ is not set
1187# CONFIG_UNUSED_SYMBOLS is not set 1188# CONFIG_UNUSED_SYMBOLS is not set
1188CONFIG_DEBUG_FS=y 1189CONFIG_DEBUG_FS=y
1189# CONFIG_HEADERS_CHECK is not set 1190# CONFIG_HEADERS_CHECK is not set
@@ -1208,7 +1209,7 @@ CONFIG_ACCESS_CHECK=y
1208# CONFIG_KEYS is not set 1209# CONFIG_KEYS is not set
1209CONFIG_SECURITY=y 1210CONFIG_SECURITY=y
1210# CONFIG_SECURITY_NETWORK is not set 1211# CONFIG_SECURITY_NETWORK is not set
1211CONFIG_SECURITY_CAPABILITIES=y 1212CONFIG_SECURITY_CAPABILITIES=m
1212 1213
1213# 1214#
1214# Cryptographic options 1215# Cryptographic options
@@ -1219,7 +1220,7 @@ CONFIG_SECURITY_CAPABILITIES=y
1219# Library routines 1220# Library routines
1220# 1221#
1221CONFIG_BITREVERSE=y 1222CONFIG_BITREVERSE=y
1222# CONFIG_CRC_CCITT is not set 1223CONFIG_CRC_CCITT=m
1223# CONFIG_CRC16 is not set 1224# CONFIG_CRC16 is not set
1224# CONFIG_CRC_ITU_T is not set 1225# CONFIG_CRC_ITU_T is not set
1225CONFIG_CRC32=y 1226CONFIG_CRC32=y
diff --git a/arch/blackfin/configs/BF533-EZKIT_defconfig b/arch/blackfin/configs/BF533-EZKIT_defconfig
index 4fdb49362ba3..811711f59a25 100644
--- a/arch/blackfin/configs/BF533-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF533-EZKIT_defconfig
@@ -1,6 +1,6 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.22.12 3# Linux kernel version: 2.6.22.16
4# 4#
5# CONFIG_MMU is not set 5# CONFIG_MMU is not set
6# CONFIG_FPU is not set 6# CONFIG_FPU is not set
@@ -115,7 +115,10 @@ CONFIG_PREEMPT_VOLUNTARY=y
115# Processor and Board Settings 115# Processor and Board Settings
116# 116#
117# CONFIG_BF522 is not set 117# CONFIG_BF522 is not set
118# CONFIG_BF523 is not set
119# CONFIG_BF524 is not set
118# CONFIG_BF525 is not set 120# CONFIG_BF525 is not set
121# CONFIG_BF526 is not set
119# CONFIG_BF527 is not set 122# CONFIG_BF527 is not set
120# CONFIG_BF531 is not set 123# CONFIG_BF531 is not set
121# CONFIG_BF532 is not set 124# CONFIG_BF532 is not set
@@ -194,7 +197,7 @@ CONFIG_CLKIN_HZ=27000000
194# CONFIG_BFIN_KERNEL_CLOCK is not set 197# CONFIG_BFIN_KERNEL_CLOCK is not set
195CONFIG_MAX_VCO_HZ=750000000 198CONFIG_MAX_VCO_HZ=750000000
196CONFIG_MIN_VCO_HZ=50000000 199CONFIG_MIN_VCO_HZ=50000000
197CONFIG_MAX_SCLK_HZ=133000000 200CONFIG_MAX_SCLK_HZ=133333333
198CONFIG_MIN_SCLK_HZ=27000000 201CONFIG_MIN_SCLK_HZ=27000000
199 202
200# 203#
@@ -267,6 +270,7 @@ CONFIG_BFIN_DCACHE=y
267# CONFIG_BFIN_WB is not set 270# CONFIG_BFIN_WB is not set
268CONFIG_BFIN_WT=y 271CONFIG_BFIN_WT=y
269CONFIG_L1_MAX_PIECE=16 272CONFIG_L1_MAX_PIECE=16
273# CONFIG_MPU is not set
270 274
271# 275#
272# Asynchonous Memory Configuration 276# Asynchonous Memory Configuration
@@ -321,7 +325,7 @@ CONFIG_PM=y
321CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y 325CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y
322# CONFIG_PM_WAKEUP_BY_GPIO is not set 326# CONFIG_PM_WAKEUP_BY_GPIO is not set
323# CONFIG_PM_WAKEUP_GPIO_API is not set 327# CONFIG_PM_WAKEUP_GPIO_API is not set
324CONFIG_PM_WAKEUP_SIC_IWR=0x100000 328CONFIG_PM_WAKEUP_SIC_IWR=0x80
325 329
326# 330#
327# CPU Frequency scaling 331# CPU Frequency scaling
@@ -510,7 +514,6 @@ CONFIG_MTD_CFI_I2=y
510# CONFIG_MTD_CFI_INTELEXT is not set 514# CONFIG_MTD_CFI_INTELEXT is not set
511# CONFIG_MTD_CFI_AMDSTD is not set 515# CONFIG_MTD_CFI_AMDSTD is not set
512# CONFIG_MTD_CFI_STAA is not set 516# CONFIG_MTD_CFI_STAA is not set
513CONFIG_MTD_MW320D=m
514CONFIG_MTD_RAM=y 517CONFIG_MTD_RAM=y
515CONFIG_MTD_ROM=m 518CONFIG_MTD_ROM=m
516# CONFIG_MTD_ABSENT is not set 519# CONFIG_MTD_ABSENT is not set
@@ -520,9 +523,6 @@ CONFIG_MTD_ROM=m
520# 523#
521CONFIG_MTD_COMPLEX_MAPPINGS=y 524CONFIG_MTD_COMPLEX_MAPPINGS=y
522# CONFIG_MTD_PHYSMAP is not set 525# CONFIG_MTD_PHYSMAP is not set
523CONFIG_MTD_BF5xx=m
524CONFIG_BFIN_FLASH_SIZE=0x400000
525CONFIG_EBIU_FLASH_BASE=0x20000000
526# CONFIG_MTD_UCLINUX is not set 526# CONFIG_MTD_UCLINUX is not set
527# CONFIG_MTD_PLATRAM is not set 527# CONFIG_MTD_PLATRAM is not set
528 528
@@ -610,8 +610,8 @@ CONFIG_SMC91X=y
610# CONFIG_SMSC911X is not set 610# CONFIG_SMSC911X is not set
611# CONFIG_DM9000 is not set 611# CONFIG_DM9000 is not set
612CONFIG_NETDEV_1000=y 612CONFIG_NETDEV_1000=y
613CONFIG_NETDEV_10000=y
614# CONFIG_AX88180 is not set 613# CONFIG_AX88180 is not set
614CONFIG_NETDEV_10000=y
615 615
616# 616#
617# Wireless LAN 617# Wireless LAN
@@ -680,7 +680,6 @@ CONFIG_INPUT_EVDEV=m
680CONFIG_BFIN_SPORT=y 680CONFIG_BFIN_SPORT=y
681# CONFIG_BFIN_TIMER_LATENCY is not set 681# CONFIG_BFIN_TIMER_LATENCY is not set
682# CONFIG_AD5304 is not set 682# CONFIG_AD5304 is not set
683# CONFIG_BF5xx_FBDMA is not set
684# CONFIG_VT is not set 683# CONFIG_VT is not set
685# CONFIG_SERIAL_NONSTANDARD is not set 684# CONFIG_SERIAL_NONSTANDARD is not set
686 685
diff --git a/arch/blackfin/configs/BF533-STAMP_defconfig b/arch/blackfin/configs/BF533-STAMP_defconfig
index b04e8e533e9a..9b7123cf27a3 100644
--- a/arch/blackfin/configs/BF533-STAMP_defconfig
+++ b/arch/blackfin/configs/BF533-STAMP_defconfig
@@ -1,6 +1,6 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.22.12 3# Linux kernel version: 2.6.22.16
4# 4#
5# CONFIG_MMU is not set 5# CONFIG_MMU is not set
6# CONFIG_FPU is not set 6# CONFIG_FPU is not set
@@ -115,7 +115,10 @@ CONFIG_PREEMPT_VOLUNTARY=y
115# Processor and Board Settings 115# Processor and Board Settings
116# 116#
117# CONFIG_BF522 is not set 117# CONFIG_BF522 is not set
118# CONFIG_BF523 is not set
119# CONFIG_BF524 is not set
118# CONFIG_BF525 is not set 120# CONFIG_BF525 is not set
121# CONFIG_BF526 is not set
119# CONFIG_BF527 is not set 122# CONFIG_BF527 is not set
120# CONFIG_BF531 is not set 123# CONFIG_BF531 is not set
121# CONFIG_BF532 is not set 124# CONFIG_BF532 is not set
@@ -140,7 +143,6 @@ CONFIG_BF_REV_0_3=y
140CONFIG_BF53x=y 143CONFIG_BF53x=y
141CONFIG_BFIN_SINGLE_CORE=y 144CONFIG_BFIN_SINGLE_CORE=y
142CONFIG_MEM_MT48LC64M4A2FB_7E=y 145CONFIG_MEM_MT48LC64M4A2FB_7E=y
143CONFIG_BFIN_SHARED_FLASH_ENET=y
144# CONFIG_BFIN533_EZKIT is not set 146# CONFIG_BFIN533_EZKIT is not set
145CONFIG_BFIN533_STAMP=y 147CONFIG_BFIN533_STAMP=y
146# CONFIG_BFIN533_BLUETECHNIX_CM is not set 148# CONFIG_BFIN533_BLUETECHNIX_CM is not set
@@ -195,7 +197,7 @@ CONFIG_CLKIN_HZ=11059200
195# CONFIG_BFIN_KERNEL_CLOCK is not set 197# CONFIG_BFIN_KERNEL_CLOCK is not set
196CONFIG_MAX_VCO_HZ=750000000 198CONFIG_MAX_VCO_HZ=750000000
197CONFIG_MIN_VCO_HZ=50000000 199CONFIG_MIN_VCO_HZ=50000000
198CONFIG_MAX_SCLK_HZ=133000000 200CONFIG_MAX_SCLK_HZ=133333333
199CONFIG_MIN_SCLK_HZ=27000000 201CONFIG_MIN_SCLK_HZ=27000000
200 202
201# 203#
@@ -215,18 +217,10 @@ CONFIG_MEM_ADD_WIDTH=11
215CONFIG_ENET_FLASH_PIN=0 217CONFIG_ENET_FLASH_PIN=0
216CONFIG_BOOT_LOAD=0x1000 218CONFIG_BOOT_LOAD=0x1000
217 219
218# 220
219# LED Status Indicators
220#
221# CONFIG_BFIN_ALIVE_LED is not set
222# CONFIG_BFIN_IDLE_LED is not set
223CONFIG_BFIN_SCRATCH_REG_RETN=y 221CONFIG_BFIN_SCRATCH_REG_RETN=y
224# CONFIG_BFIN_SCRATCH_REG_RETE is not set 222# CONFIG_BFIN_SCRATCH_REG_RETE is not set
225# CONFIG_BFIN_SCRATCH_REG_CYCLES is not set 223# CONFIG_BFIN_SCRATCH_REG_CYCLES is not set
226CONFIG_BFIN_ALIVE_LED_PORT=0xFFC00700
227CONFIG_BFIN_ALIVE_LED_DPORT=0xFFC00730
228CONFIG_BFIN_IDLE_LED_PORT=0xFFC00700
229CONFIG_BFIN_IDLE_LED_DPORT=0xFFC00730
230 224
231# 225#
232# Blackfin Kernel Optimizations 226# Blackfin Kernel Optimizations
@@ -279,6 +273,7 @@ CONFIG_BFIN_DCACHE=y
279# CONFIG_BFIN_WB is not set 273# CONFIG_BFIN_WB is not set
280CONFIG_BFIN_WT=y 274CONFIG_BFIN_WT=y
281CONFIG_L1_MAX_PIECE=16 275CONFIG_L1_MAX_PIECE=16
276# CONFIG_MPU is not set
282 277
283# 278#
284# Asynchonous Memory Configuration 279# Asynchonous Memory Configuration
@@ -333,7 +328,7 @@ CONFIG_PM=y
333CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y 328CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y
334# CONFIG_PM_WAKEUP_BY_GPIO is not set 329# CONFIG_PM_WAKEUP_BY_GPIO is not set
335# CONFIG_PM_WAKEUP_GPIO_API is not set 330# CONFIG_PM_WAKEUP_GPIO_API is not set
336CONFIG_PM_WAKEUP_SIC_IWR=0x100000 331CONFIG_PM_WAKEUP_SIC_IWR=0x80
337 332
338# 333#
339# CPU Frequency scaling 334# CPU Frequency scaling
@@ -522,7 +517,6 @@ CONFIG_MTD_CFI_I2=y
522# CONFIG_MTD_CFI_INTELEXT is not set 517# CONFIG_MTD_CFI_INTELEXT is not set
523# CONFIG_MTD_CFI_AMDSTD is not set 518# CONFIG_MTD_CFI_AMDSTD is not set
524# CONFIG_MTD_CFI_STAA is not set 519# CONFIG_MTD_CFI_STAA is not set
525CONFIG_MTD_MW320D=m
526CONFIG_MTD_RAM=y 520CONFIG_MTD_RAM=y
527CONFIG_MTD_ROM=m 521CONFIG_MTD_ROM=m
528# CONFIG_MTD_ABSENT is not set 522# CONFIG_MTD_ABSENT is not set
@@ -532,17 +526,6 @@ CONFIG_MTD_ROM=m
532# 526#
533CONFIG_MTD_COMPLEX_MAPPINGS=y 527CONFIG_MTD_COMPLEX_MAPPINGS=y
534# CONFIG_MTD_PHYSMAP is not set 528# CONFIG_MTD_PHYSMAP is not set
535CONFIG_MTD_BF5xx=m
536CONFIG_BFIN_FLASH_SIZE=0x400000
537CONFIG_EBIU_FLASH_BASE=0x20000000
538
539#
540# FLASH_EBIU_AMBCTL Control
541#
542CONFIG_BFIN_FLASH_BANK_0=0x7BB0
543CONFIG_BFIN_FLASH_BANK_1=0x7BB0
544CONFIG_BFIN_FLASH_BANK_2=0x7BB0
545CONFIG_BFIN_FLASH_BANK_3=0x7BB0
546# CONFIG_MTD_UCLINUX is not set 529# CONFIG_MTD_UCLINUX is not set
547# CONFIG_MTD_PLATRAM is not set 530# CONFIG_MTD_PLATRAM is not set
548 531
@@ -630,8 +613,8 @@ CONFIG_SMC91X=y
630# CONFIG_SMSC911X is not set 613# CONFIG_SMSC911X is not set
631# CONFIG_DM9000 is not set 614# CONFIG_DM9000 is not set
632CONFIG_NETDEV_1000=y 615CONFIG_NETDEV_1000=y
633CONFIG_NETDEV_10000=y
634# CONFIG_AX88180 is not set 616# CONFIG_AX88180 is not set
617CONFIG_NETDEV_10000=y
635 618
636# 619#
637# Wireless LAN 620# Wireless LAN
@@ -687,7 +670,6 @@ CONFIG_INPUT_MISC=y
687# CONFIG_INPUT_POWERMATE is not set 670# CONFIG_INPUT_POWERMATE is not set
688# CONFIG_INPUT_YEALINK is not set 671# CONFIG_INPUT_YEALINK is not set
689# CONFIG_INPUT_UINPUT is not set 672# CONFIG_INPUT_UINPUT is not set
690# CONFIG_BF53X_PFBUTTONS is not set
691CONFIG_TWI_KEYPAD=m 673CONFIG_TWI_KEYPAD=m
692CONFIG_BFIN_TWIKEYPAD_IRQ_PFX=39 674CONFIG_BFIN_TWIKEYPAD_IRQ_PFX=39
693 675
@@ -711,8 +693,6 @@ CONFIG_BFIN_SPORT=y
711CONFIG_TWI_LCD=m 693CONFIG_TWI_LCD=m
712CONFIG_TWI_LCD_SLAVE_ADDR=34 694CONFIG_TWI_LCD_SLAVE_ADDR=34
713# CONFIG_AD5304 is not set 695# CONFIG_AD5304 is not set
714# CONFIG_BF5xx_TEA5764 is not set
715# CONFIG_BF5xx_FBDMA is not set
716# CONFIG_VT is not set 696# CONFIG_VT is not set
717# CONFIG_SERIAL_NONSTANDARD is not set 697# CONFIG_SERIAL_NONSTANDARD is not set
718 698
@@ -778,7 +758,6 @@ CONFIG_I2C_ALGOBIT=m
778# 758#
779# I2C Hardware Bus support 759# I2C Hardware Bus support
780# 760#
781# CONFIG_I2C_BLACKFIN_GPIO is not set
782# CONFIG_I2C_GPIO is not set 761# CONFIG_I2C_GPIO is not set
783# CONFIG_I2C_OCORES is not set 762# CONFIG_I2C_OCORES is not set
784# CONFIG_I2C_PARPORT_LIGHT is not set 763# CONFIG_I2C_PARPORT_LIGHT is not set
diff --git a/arch/blackfin/configs/BF537-STAMP_defconfig b/arch/blackfin/configs/BF537-STAMP_defconfig
index f812b66318b9..b37ccc681e7a 100644
--- a/arch/blackfin/configs/BF537-STAMP_defconfig
+++ b/arch/blackfin/configs/BF537-STAMP_defconfig
@@ -1,6 +1,6 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.22.12 3# Linux kernel version: 2.6.22.16
4# 4#
5# CONFIG_MMU is not set 5# CONFIG_MMU is not set
6# CONFIG_FPU is not set 6# CONFIG_FPU is not set
@@ -115,7 +115,10 @@ CONFIG_PREEMPT_VOLUNTARY=y
115# Processor and Board Settings 115# Processor and Board Settings
116# 116#
117# CONFIG_BF522 is not set 117# CONFIG_BF522 is not set
118# CONFIG_BF523 is not set
119# CONFIG_BF524 is not set
118# CONFIG_BF525 is not set 120# CONFIG_BF525 is not set
121# CONFIG_BF526 is not set
119# CONFIG_BF527 is not set 122# CONFIG_BF527 is not set
120# CONFIG_BF531 is not set 123# CONFIG_BF531 is not set
121# CONFIG_BF532 is not set 124# CONFIG_BF532 is not set
@@ -170,6 +173,7 @@ CONFIG_IRQ_WATCH=13
170CONFIG_BFIN537_STAMP=y 173CONFIG_BFIN537_STAMP=y
171# CONFIG_BFIN537_BLUETECHNIX_CM is not set 174# CONFIG_BFIN537_BLUETECHNIX_CM is not set
172# CONFIG_PNAV10 is not set 175# CONFIG_PNAV10 is not set
176# CONFIG_CAMSIG_MINOTAUR is not set
173# CONFIG_GENERIC_BF537_BOARD is not set 177# CONFIG_GENERIC_BF537_BOARD is not set
174 178
175# 179#
@@ -201,7 +205,7 @@ CONFIG_CLKIN_HZ=25000000
201# CONFIG_BFIN_KERNEL_CLOCK is not set 205# CONFIG_BFIN_KERNEL_CLOCK is not set
202CONFIG_MAX_VCO_HZ=600000000 206CONFIG_MAX_VCO_HZ=600000000
203CONFIG_MIN_VCO_HZ=50000000 207CONFIG_MIN_VCO_HZ=50000000
204CONFIG_MAX_SCLK_HZ=133000000 208CONFIG_MAX_SCLK_HZ=133333333
205CONFIG_MIN_SCLK_HZ=27000000 209CONFIG_MIN_SCLK_HZ=27000000
206 210
207# 211#
@@ -274,6 +278,7 @@ CONFIG_BFIN_DCACHE=y
274# CONFIG_BFIN_WB is not set 278# CONFIG_BFIN_WB is not set
275CONFIG_BFIN_WT=y 279CONFIG_BFIN_WT=y
276CONFIG_L1_MAX_PIECE=16 280CONFIG_L1_MAX_PIECE=16
281# CONFIG_MPU is not set
277 282
278# 283#
279# Asynchonous Memory Configuration 284# Asynchonous Memory Configuration
@@ -328,7 +333,7 @@ CONFIG_PM=y
328CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y 333CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y
329# CONFIG_PM_WAKEUP_BY_GPIO is not set 334# CONFIG_PM_WAKEUP_BY_GPIO is not set
330# CONFIG_PM_WAKEUP_GPIO_API is not set 335# CONFIG_PM_WAKEUP_GPIO_API is not set
331CONFIG_PM_WAKEUP_SIC_IWR=0x80000000 336CONFIG_PM_WAKEUP_SIC_IWR=0x8
332 337
333# 338#
334# CPU Frequency scaling 339# CPU Frequency scaling
@@ -483,7 +488,7 @@ CONFIG_MTD=y
483# CONFIG_MTD_CONCAT is not set 488# CONFIG_MTD_CONCAT is not set
484CONFIG_MTD_PARTITIONS=y 489CONFIG_MTD_PARTITIONS=y
485# CONFIG_MTD_REDBOOT_PARTS is not set 490# CONFIG_MTD_REDBOOT_PARTS is not set
486# CONFIG_MTD_CMDLINE_PARTS is not set 491CONFIG_MTD_CMDLINE_PARTS=y
487 492
488# 493#
489# User Modules And Translation Layers 494# User Modules And Translation Layers
@@ -500,8 +505,8 @@ CONFIG_MTD_BLOCK=y
500# 505#
501# RAM/ROM/Flash chip drivers 506# RAM/ROM/Flash chip drivers
502# 507#
503# CONFIG_MTD_CFI is not set 508CONFIG_MTD_CFI=m
504CONFIG_MTD_JEDECPROBE=m 509# CONFIG_MTD_JEDECPROBE is not set
505CONFIG_MTD_GEN_PROBE=m 510CONFIG_MTD_GEN_PROBE=m
506# CONFIG_MTD_CFI_ADV_OPTIONS is not set 511# CONFIG_MTD_CFI_ADV_OPTIONS is not set
507CONFIG_MTD_MAP_BANK_WIDTH_1=y 512CONFIG_MTD_MAP_BANK_WIDTH_1=y
@@ -515,9 +520,9 @@ CONFIG_MTD_CFI_I2=y
515# CONFIG_MTD_CFI_I4 is not set 520# CONFIG_MTD_CFI_I4 is not set
516# CONFIG_MTD_CFI_I8 is not set 521# CONFIG_MTD_CFI_I8 is not set
517# CONFIG_MTD_CFI_INTELEXT is not set 522# CONFIG_MTD_CFI_INTELEXT is not set
518# CONFIG_MTD_CFI_AMDSTD is not set 523CONFIG_MTD_CFI_AMDSTD=m
519# CONFIG_MTD_CFI_STAA is not set 524# CONFIG_MTD_CFI_STAA is not set
520CONFIG_MTD_MW320D=m 525CONFIG_MTD_CFI_UTIL=m
521CONFIG_MTD_RAM=y 526CONFIG_MTD_RAM=y
522CONFIG_MTD_ROM=m 527CONFIG_MTD_ROM=m
523# CONFIG_MTD_ABSENT is not set 528# CONFIG_MTD_ABSENT is not set
@@ -525,11 +530,11 @@ CONFIG_MTD_ROM=m
525# 530#
526# Mapping drivers for chip access 531# Mapping drivers for chip access
527# 532#
528CONFIG_MTD_COMPLEX_MAPPINGS=y 533# CONFIG_MTD_COMPLEX_MAPPINGS is not set
529# CONFIG_MTD_PHYSMAP is not set 534CONFIG_MTD_PHYSMAP=m
530CONFIG_MTD_BF5xx=m 535CONFIG_MTD_PHYSMAP_START=0x20000000
531CONFIG_BFIN_FLASH_SIZE=0x400000 536CONFIG_MTD_PHYSMAP_LEN=0x0
532CONFIG_EBIU_FLASH_BASE=0x20000000 537CONFIG_MTD_PHYSMAP_BANKWIDTH=2
533# CONFIG_MTD_UCLINUX is not set 538# CONFIG_MTD_UCLINUX is not set
534# CONFIG_MTD_PLATRAM is not set 539# CONFIG_MTD_PLATRAM is not set
535 540
@@ -647,8 +652,8 @@ CONFIG_BFIN_RX_DESC_NUM=20
647# CONFIG_SMSC911X is not set 652# CONFIG_SMSC911X is not set
648# CONFIG_DM9000 is not set 653# CONFIG_DM9000 is not set
649CONFIG_NETDEV_1000=y 654CONFIG_NETDEV_1000=y
650CONFIG_NETDEV_10000=y
651# CONFIG_AX88180 is not set 655# CONFIG_AX88180 is not set
656CONFIG_NETDEV_10000=y
652 657
653# 658#
654# Wireless LAN 659# Wireless LAN
@@ -704,7 +709,6 @@ CONFIG_INPUT_MISC=y
704# CONFIG_INPUT_POWERMATE is not set 709# CONFIG_INPUT_POWERMATE is not set
705# CONFIG_INPUT_YEALINK is not set 710# CONFIG_INPUT_YEALINK is not set
706# CONFIG_INPUT_UINPUT is not set 711# CONFIG_INPUT_UINPUT is not set
707# CONFIG_BF53X_PFBUTTONS is not set
708CONFIG_TWI_KEYPAD=m 712CONFIG_TWI_KEYPAD=m
709CONFIG_BFIN_TWIKEYPAD_IRQ_PFX=72 713CONFIG_BFIN_TWIKEYPAD_IRQ_PFX=72
710 714
@@ -728,8 +732,6 @@ CONFIG_BFIN_SPORT=y
728CONFIG_TWI_LCD=m 732CONFIG_TWI_LCD=m
729CONFIG_TWI_LCD_SLAVE_ADDR=34 733CONFIG_TWI_LCD_SLAVE_ADDR=34
730# CONFIG_AD5304 is not set 734# CONFIG_AD5304 is not set
731# CONFIG_BF5xx_TEA5764 is not set
732# CONFIG_BF5xx_FBDMA is not set
733# CONFIG_VT is not set 735# CONFIG_VT is not set
734# CONFIG_SERIAL_NONSTANDARD is not set 736# CONFIG_SERIAL_NONSTANDARD is not set
735 737
@@ -802,7 +804,6 @@ CONFIG_I2C_CHARDEV=m
802# 804#
803# I2C Hardware Bus support 805# I2C Hardware Bus support
804# 806#
805# CONFIG_I2C_BLACKFIN_GPIO is not set
806CONFIG_I2C_BLACKFIN_TWI=m 807CONFIG_I2C_BLACKFIN_TWI=m
807CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=50 808CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=50
808# CONFIG_I2C_GPIO is not set 809# CONFIG_I2C_GPIO is not set
@@ -957,6 +958,7 @@ CONFIG_LQ035_SLAVE_ADDR=0x58
957# CONFIG_FB_BFIN_LANDSCAPE is not set 958# CONFIG_FB_BFIN_LANDSCAPE is not set
958# CONFIG_FB_BFIN_BGR is not set 959# CONFIG_FB_BFIN_BGR is not set
959# CONFIG_FB_BFIN_T350MCQB is not set 960# CONFIG_FB_BFIN_T350MCQB is not set
961# CONFIG_FB_HITACHI_TX09 is not set
960# CONFIG_FB_S1D13XXX is not set 962# CONFIG_FB_S1D13XXX is not set
961# CONFIG_FB_VIRTUAL is not set 963# CONFIG_FB_VIRTUAL is not set
962# CONFIG_LOGO is not set 964# CONFIG_LOGO is not set
@@ -1008,12 +1010,22 @@ CONFIG_SND_BFIN_AD73311_SE=4
1008# 1010#
1009# System on Chip audio support 1011# System on Chip audio support
1010# 1012#
1011# CONFIG_SND_SOC is not set 1013CONFIG_SND_SOC_AC97_BUS=y
1014CONFIG_SND_SOC=m
1015CONFIG_SND_BF5XX_SOC=m
1016CONFIG_SND_BF5XX_SOC_AC97=m
1017# CONFIG_SND_BF5XX_SOC_WM8750 is not set
1018# CONFIG_SND_BF5XX_SOC_WM8731 is not set
1019CONFIG_SND_BF5XX_SOC_BF5xx=m
1020CONFIG_SND_BF5XX_SPORT_NUM=0
1021# CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set
1022CONFIG_SND_SOC_AD1980=m
1012 1023
1013# 1024#
1014# Open Sound System 1025# Open Sound System
1015# 1026#
1016# CONFIG_SOUND_PRIME is not set 1027# CONFIG_SOUND_PRIME is not set
1028CONFIG_AC97_BUS=m
1017 1029
1018# 1030#
1019# HID Devices 1031# HID Devices
diff --git a/arch/blackfin/configs/BF548-EZKIT_defconfig b/arch/blackfin/configs/BF548-EZKIT_defconfig
index 48367cc9fe35..fd702161ef59 100644
--- a/arch/blackfin/configs/BF548-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF548-EZKIT_defconfig
@@ -1,6 +1,6 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.22.12 3# Linux kernel version: 2.6.22.16
4# 4#
5# CONFIG_MMU is not set 5# CONFIG_MMU is not set
6# CONFIG_FPU is not set 6# CONFIG_FPU is not set
@@ -115,7 +115,10 @@ CONFIG_PREEMPT_VOLUNTARY=y
115# Processor and Board Settings 115# Processor and Board Settings
116# 116#
117# CONFIG_BF522 is not set 117# CONFIG_BF522 is not set
118# CONFIG_BF523 is not set
119# CONFIG_BF524 is not set
118# CONFIG_BF525 is not set 120# CONFIG_BF525 is not set
121# CONFIG_BF526 is not set
119# CONFIG_BF527 is not set 122# CONFIG_BF527 is not set
120# CONFIG_BF531 is not set 123# CONFIG_BF531 is not set
121# CONFIG_BF532 is not set 124# CONFIG_BF532 is not set
@@ -126,8 +129,8 @@ CONFIG_PREEMPT_VOLUNTARY=y
126# CONFIG_BF542 is not set 129# CONFIG_BF542 is not set
127# CONFIG_BF544 is not set 130# CONFIG_BF544 is not set
128# CONFIG_BF547 is not set 131# CONFIG_BF547 is not set
129# CONFIG_BF548 is not set 132CONFIG_BF548=y
130CONFIG_BF549=y 133# CONFIG_BF549 is not set
131# CONFIG_BF561 is not set 134# CONFIG_BF561 is not set
132CONFIG_BF_REV_0_0=y 135CONFIG_BF_REV_0_0=y
133# CONFIG_BF_REV_0_1 is not set 136# CONFIG_BF_REV_0_1 is not set
@@ -265,9 +268,9 @@ CONFIG_PINT3_ASSIGN=0x02020303
265# 268#
266CONFIG_CLKIN_HZ=25000000 269CONFIG_CLKIN_HZ=25000000
267# CONFIG_BFIN_KERNEL_CLOCK is not set 270# CONFIG_BFIN_KERNEL_CLOCK is not set
268CONFIG_MAX_VCO_HZ=533000000 271CONFIG_MAX_VCO_HZ=600000000
269CONFIG_MIN_VCO_HZ=50000000 272CONFIG_MIN_VCO_HZ=50000000
270CONFIG_MAX_SCLK_HZ=133000000 273CONFIG_MAX_SCLK_HZ=133333333
271CONFIG_MIN_SCLK_HZ=27000000 274CONFIG_MIN_SCLK_HZ=27000000
272 275
273# 276#
@@ -283,7 +286,8 @@ CONFIG_HZ=250
283# Memory Setup 286# Memory Setup
284# 287#
285CONFIG_MEM_SIZE=64 288CONFIG_MEM_SIZE=64
286CONFIG_MEM_ADD_WIDTH=10 289# CONFIG_MEM_MT46V32M16_6T is not set
290CONFIG_MEM_MT46V32M16_5B=y
287CONFIG_BOOT_LOAD=0x1000 291CONFIG_BOOT_LOAD=0x1000
288CONFIG_BFIN_SCRATCH_REG_RETN=y 292CONFIG_BFIN_SCRATCH_REG_RETN=y
289# CONFIG_BFIN_SCRATCH_REG_RETE is not set 293# CONFIG_BFIN_SCRATCH_REG_RETE is not set
@@ -340,6 +344,7 @@ CONFIG_BFIN_DCACHE=y
340# CONFIG_BFIN_WB is not set 344# CONFIG_BFIN_WB is not set
341CONFIG_BFIN_WT=y 345CONFIG_BFIN_WT=y
342CONFIG_L1_MAX_PIECE=16 346CONFIG_L1_MAX_PIECE=16
347# CONFIG_MPU is not set
343 348
344# 349#
345# Asynchonous Memory Configuration 350# Asynchonous Memory Configuration
@@ -349,6 +354,7 @@ CONFIG_L1_MAX_PIECE=16
349# EBIU_AMGCTL Global Control 354# EBIU_AMGCTL Global Control
350# 355#
351CONFIG_C_AMCKEN=y 356CONFIG_C_AMCKEN=y
357# CONFIG_C_CDPRIO is not set
352# CONFIG_C_AMBEN is not set 358# CONFIG_C_AMBEN is not set
353# CONFIG_C_AMBEN_B0 is not set 359# CONFIG_C_AMBEN_B0 is not set
354# CONFIG_C_AMBEN_B0_B1 is not set 360# CONFIG_C_AMBEN_B0_B1 is not set
@@ -362,9 +368,9 @@ CONFIG_BANK_0=0x7BB0
362CONFIG_BANK_1=0x5554 368CONFIG_BANK_1=0x5554
363CONFIG_BANK_2=0x7BB0 369CONFIG_BANK_2=0x7BB0
364CONFIG_BANK_3=0x99B3 370CONFIG_BANK_3=0x99B3
365CONFIG_EBUI_MBSCTLVAL=0x0 371CONFIG_EBIU_MBSCTLVAL=0x0
366CONFIG_EBUI_MODEVAL=0x1 372CONFIG_EBIU_MODEVAL=0x1
367CONFIG_EBUI_FCTLVAL=0x6 373CONFIG_EBIU_FCTLVAL=0x6
368 374
369# 375#
370# Bus options (PCI, PCMCIA, EISA, MCA, ISA) 376# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
@@ -537,7 +543,6 @@ CONFIG_MTD_CFI_I2=y
537CONFIG_MTD_CFI_INTELEXT=y 543CONFIG_MTD_CFI_INTELEXT=y
538# CONFIG_MTD_CFI_AMDSTD is not set 544# CONFIG_MTD_CFI_AMDSTD is not set
539# CONFIG_MTD_CFI_STAA is not set 545# CONFIG_MTD_CFI_STAA is not set
540# CONFIG_MTD_MW320D is not set
541CONFIG_MTD_CFI_UTIL=y 546CONFIG_MTD_CFI_UTIL=y
542CONFIG_MTD_RAM=y 547CONFIG_MTD_RAM=y
543# CONFIG_MTD_ROM is not set 548# CONFIG_MTD_ROM is not set
@@ -549,9 +554,8 @@ CONFIG_MTD_RAM=y
549CONFIG_MTD_COMPLEX_MAPPINGS=y 554CONFIG_MTD_COMPLEX_MAPPINGS=y
550CONFIG_MTD_PHYSMAP=y 555CONFIG_MTD_PHYSMAP=y
551CONFIG_MTD_PHYSMAP_START=0x20000000 556CONFIG_MTD_PHYSMAP_START=0x20000000
552CONFIG_MTD_PHYSMAP_LEN=0x400000 557CONFIG_MTD_PHYSMAP_LEN=0
553CONFIG_MTD_PHYSMAP_BANKWIDTH=2 558CONFIG_MTD_PHYSMAP_BANKWIDTH=2
554# CONFIG_MTD_BF5xx is not set
555# CONFIG_MTD_UCLINUX is not set 559# CONFIG_MTD_UCLINUX is not set
556# CONFIG_MTD_PLATRAM is not set 560# CONFIG_MTD_PLATRAM is not set
557 561
@@ -690,8 +694,8 @@ CONFIG_MII=y
690CONFIG_SMSC911X=y 694CONFIG_SMSC911X=y
691# CONFIG_DM9000 is not set 695# CONFIG_DM9000 is not set
692CONFIG_NETDEV_1000=y 696CONFIG_NETDEV_1000=y
693CONFIG_NETDEV_10000=y
694# CONFIG_AX88180 is not set 697# CONFIG_AX88180 is not set
698CONFIG_NETDEV_10000=y
695 699
696# 700#
697# Wireless LAN 701# Wireless LAN
@@ -719,7 +723,7 @@ CONFIG_NETDEV_10000=y
719# 723#
720# Input device support 724# Input device support
721# 725#
722CONFIG_INPUT=m 726CONFIG_INPUT=y
723# CONFIG_INPUT_FF_MEMLESS is not set 727# CONFIG_INPUT_FF_MEMLESS is not set
724# CONFIG_INPUT_POLLDEV is not set 728# CONFIG_INPUT_POLLDEV is not set
725 729
@@ -745,7 +749,8 @@ CONFIG_INPUT_KEYBOARD=y
745# CONFIG_KEYBOARD_NEWTON is not set 749# CONFIG_KEYBOARD_NEWTON is not set
746# CONFIG_KEYBOARD_STOWAWAY is not set 750# CONFIG_KEYBOARD_STOWAWAY is not set
747# CONFIG_KEYBOARD_GPIO is not set 751# CONFIG_KEYBOARD_GPIO is not set
748CONFIG_KEYBOARD_BFIN=m 752CONFIG_KEYBOARD_BFIN=y
753# CONFIG_KEYBOARD_OPENCORES is not set
749# CONFIG_INPUT_MOUSE is not set 754# CONFIG_INPUT_MOUSE is not set
750# CONFIG_INPUT_JOYSTICK is not set 755# CONFIG_INPUT_JOYSTICK is not set
751# CONFIG_INPUT_TABLET is not set 756# CONFIG_INPUT_TABLET is not set
@@ -768,7 +773,6 @@ CONFIG_INPUT_MISC=y
768# CONFIG_INPUT_POWERMATE is not set 773# CONFIG_INPUT_POWERMATE is not set
769# CONFIG_INPUT_YEALINK is not set 774# CONFIG_INPUT_YEALINK is not set
770# CONFIG_INPUT_UINPUT is not set 775# CONFIG_INPUT_UINPUT is not set
771# CONFIG_BF53X_PFBUTTONS is not set
772# CONFIG_TWI_KEYPAD is not set 776# CONFIG_TWI_KEYPAD is not set
773 777
774# 778#
@@ -786,13 +790,16 @@ CONFIG_INPUT_MISC=y
786# CONFIG_BF5xx_PPIFCD is not set 790# CONFIG_BF5xx_PPIFCD is not set
787# CONFIG_BFIN_SIMPLE_TIMER is not set 791# CONFIG_BFIN_SIMPLE_TIMER is not set
788# CONFIG_BF5xx_PPI is not set 792# CONFIG_BF5xx_PPI is not set
793CONFIG_BFIN_OTP=y
794# CONFIG_BFIN_OTP_WRITE_ENABLE is not set
789# CONFIG_BFIN_SPORT is not set 795# CONFIG_BFIN_SPORT is not set
790# CONFIG_BFIN_TIMER_LATENCY is not set 796# CONFIG_BFIN_TIMER_LATENCY is not set
791# CONFIG_TWI_LCD is not set 797# CONFIG_TWI_LCD is not set
792# CONFIG_AD5304 is not set 798# CONFIG_AD5304 is not set
793# CONFIG_BF5xx_TEA5764 is not set 799CONFIG_VT=y
794# CONFIG_BF5xx_FBDMA is not set 800CONFIG_VT_CONSOLE=y
795# CONFIG_VT is not set 801CONFIG_HW_CONSOLE=y
802# CONFIG_VT_HW_CONSOLE_BINDING is not set
796# CONFIG_SERIAL_NONSTANDARD is not set 803# CONFIG_SERIAL_NONSTANDARD is not set
797 804
798# 805#
@@ -858,7 +865,6 @@ CONFIG_I2C_CHARDEV=y
858# 865#
859# I2C Hardware Bus support 866# I2C Hardware Bus support
860# 867#
861# CONFIG_I2C_BLACKFIN_GPIO is not set
862CONFIG_I2C_BLACKFIN_TWI=y 868CONFIG_I2C_BLACKFIN_TWI=y
863CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=50 869CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=50
864# CONFIG_I2C_GPIO is not set 870# CONFIG_I2C_GPIO is not set
@@ -976,12 +982,12 @@ CONFIG_DAB=y
976# 982#
977# CONFIG_DISPLAY_SUPPORT is not set 983# CONFIG_DISPLAY_SUPPORT is not set
978# CONFIG_VGASTATE is not set 984# CONFIG_VGASTATE is not set
979CONFIG_FB=m 985CONFIG_FB=y
980CONFIG_FIRMWARE_EDID=y 986CONFIG_FIRMWARE_EDID=y
981# CONFIG_FB_DDC is not set 987# CONFIG_FB_DDC is not set
982CONFIG_FB_CFB_FILLRECT=m 988CONFIG_FB_CFB_FILLRECT=y
983CONFIG_FB_CFB_COPYAREA=m 989CONFIG_FB_CFB_COPYAREA=y
984CONFIG_FB_CFB_IMAGEBLIT=m 990CONFIG_FB_CFB_IMAGEBLIT=y
985# CONFIG_FB_SYS_FILLRECT is not set 991# CONFIG_FB_SYS_FILLRECT is not set
986# CONFIG_FB_SYS_COPYAREA is not set 992# CONFIG_FB_SYS_COPYAREA is not set
987# CONFIG_FB_SYS_IMAGEBLIT is not set 993# CONFIG_FB_SYS_IMAGEBLIT is not set
@@ -998,11 +1004,34 @@ CONFIG_FB_DEFERRED_IO=y
998# 1004#
999# CONFIG_FB_BFIN_7171 is not set 1005# CONFIG_FB_BFIN_7171 is not set
1000# CONFIG_FB_BFIN_7393 is not set 1006# CONFIG_FB_BFIN_7393 is not set
1001CONFIG_FB_BF54X_LQ043=m 1007CONFIG_FB_BF54X_LQ043=y
1002# CONFIG_FB_BFIN_T350MCQB is not set 1008# CONFIG_FB_BFIN_T350MCQB is not set
1003# CONFIG_FB_S1D13XXX is not set 1009# CONFIG_FB_S1D13XXX is not set
1004# CONFIG_FB_VIRTUAL is not set 1010# CONFIG_FB_VIRTUAL is not set
1005# CONFIG_LOGO is not set 1011
1012#
1013# Console display driver support
1014#
1015CONFIG_DUMMY_CONSOLE=y
1016CONFIG_FRAMEBUFFER_CONSOLE=y
1017# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
1018CONFIG_FONTS=y
1019# CONFIG_FONT_8x8 is not set
1020# CONFIG_FONT_8x16 is not set
1021CONFIG_FONT_6x11=y
1022# CONFIG_FONT_7x14 is not set
1023# CONFIG_FONT_PEARL_8x8 is not set
1024# CONFIG_FONT_ACORN_8x8 is not set
1025# CONFIG_FONT_MINI_4x6 is not set
1026# CONFIG_FONT_SUN8x16 is not set
1027# CONFIG_FONT_SUN12x22 is not set
1028# CONFIG_FONT_10x18 is not set
1029CONFIG_LOGO=y
1030# CONFIG_LOGO_LINUX_MONO is not set
1031# CONFIG_LOGO_LINUX_VGA16 is not set
1032# CONFIG_LOGO_LINUX_CLUT224 is not set
1033# CONFIG_LOGO_BLACKFIN_VGA16 is not set
1034CONFIG_LOGO_BLACKFIN_CLUT224=y
1006 1035
1007# 1036#
1008# Sound 1037# Sound
@@ -1051,7 +1080,8 @@ CONFIG_SND_BF5XX_SOC_BF548_EZKIT=y
1051# CONFIG_SND_BF5XX_SOC_WM8750 is not set 1080# CONFIG_SND_BF5XX_SOC_WM8750 is not set
1052# CONFIG_SND_BF5XX_SOC_WM8731 is not set 1081# CONFIG_SND_BF5XX_SOC_WM8731 is not set
1053CONFIG_SND_BF5XX_SPORT_NUM=0 1082CONFIG_SND_BF5XX_SPORT_NUM=0
1054# CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set 1083CONFIG_SND_BF5XX_HAVE_COLD_RESET=y
1084CONFIG_SND_BF5XX_RESET_GPIO_NUM=19
1055CONFIG_SND_SOC_AD1980=y 1085CONFIG_SND_SOC_AD1980=y
1056 1086
1057# 1087#
@@ -1403,7 +1433,7 @@ CONFIG_NLS_UTF8=m
1403# 1433#
1404# CONFIG_PRINTK_TIME is not set 1434# CONFIG_PRINTK_TIME is not set
1405CONFIG_ENABLE_MUST_CHECK=y 1435CONFIG_ENABLE_MUST_CHECK=y
1406CONFIG_MAGIC_SYSRQ=y 1436# CONFIG_MAGIC_SYSRQ is not set
1407# CONFIG_UNUSED_SYMBOLS is not set 1437# CONFIG_UNUSED_SYMBOLS is not set
1408CONFIG_DEBUG_FS=y 1438CONFIG_DEBUG_FS=y
1409# CONFIG_HEADERS_CHECK is not set 1439# CONFIG_HEADERS_CHECK is not set
@@ -1428,7 +1458,7 @@ CONFIG_ACCESS_CHECK=y
1428# CONFIG_KEYS is not set 1458# CONFIG_KEYS is not set
1429CONFIG_SECURITY=y 1459CONFIG_SECURITY=y
1430# CONFIG_SECURITY_NETWORK is not set 1460# CONFIG_SECURITY_NETWORK is not set
1431CONFIG_SECURITY_CAPABILITIES=y 1461CONFIG_SECURITY_CAPABILITIES=m
1432 1462
1433# 1463#
1434# Cryptographic options 1464# Cryptographic options
@@ -1439,7 +1469,7 @@ CONFIG_SECURITY_CAPABILITIES=y
1439# Library routines 1469# Library routines
1440# 1470#
1441CONFIG_BITREVERSE=y 1471CONFIG_BITREVERSE=y
1442# CONFIG_CRC_CCITT is not set 1472CONFIG_CRC_CCITT=m
1443# CONFIG_CRC16 is not set 1473# CONFIG_CRC16 is not set
1444# CONFIG_CRC_ITU_T is not set 1474# CONFIG_CRC_ITU_T is not set
1445CONFIG_CRC32=y 1475CONFIG_CRC32=y
diff --git a/arch/blackfin/configs/BF561-EZKIT_defconfig b/arch/blackfin/configs/BF561-EZKIT_defconfig
index e9f100b45eb1..8546994939fb 100644
--- a/arch/blackfin/configs/BF561-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF561-EZKIT_defconfig
@@ -1,6 +1,6 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.22.12 3# Linux kernel version: 2.6.22.16
4# 4#
5# CONFIG_MMU is not set 5# CONFIG_MMU is not set
6# CONFIG_FPU is not set 6# CONFIG_FPU is not set
@@ -115,7 +115,10 @@ CONFIG_PREEMPT_VOLUNTARY=y
115# Processor and Board Settings 115# Processor and Board Settings
116# 116#
117# CONFIG_BF522 is not set 117# CONFIG_BF522 is not set
118# CONFIG_BF523 is not set
119# CONFIG_BF524 is not set
118# CONFIG_BF525 is not set 120# CONFIG_BF525 is not set
121# CONFIG_BF526 is not set
119# CONFIG_BF527 is not set 122# CONFIG_BF527 is not set
120# CONFIG_BF531 is not set 123# CONFIG_BF531 is not set
121# CONFIG_BF532 is not set 124# CONFIG_BF532 is not set
@@ -238,7 +241,7 @@ CONFIG_CLKIN_HZ=30000000
238# CONFIG_BFIN_KERNEL_CLOCK is not set 241# CONFIG_BFIN_KERNEL_CLOCK is not set
239CONFIG_MAX_VCO_HZ=600000000 242CONFIG_MAX_VCO_HZ=600000000
240CONFIG_MIN_VCO_HZ=50000000 243CONFIG_MIN_VCO_HZ=50000000
241CONFIG_MAX_SCLK_HZ=133000000 244CONFIG_MAX_SCLK_HZ=133333333
242CONFIG_MIN_SCLK_HZ=27000000 245CONFIG_MIN_SCLK_HZ=27000000
243 246
244# 247#
@@ -311,6 +314,7 @@ CONFIG_BFIN_DCACHE=y
311# CONFIG_BFIN_WB is not set 314# CONFIG_BFIN_WB is not set
312CONFIG_BFIN_WT=y 315CONFIG_BFIN_WT=y
313CONFIG_L1_MAX_PIECE=16 316CONFIG_L1_MAX_PIECE=16
317# CONFIG_MPU is not set
314 318
315# 319#
316# Asynchonous Memory Configuration 320# Asynchonous Memory Configuration
@@ -512,7 +516,7 @@ CONFIG_MTD=y
512# CONFIG_MTD_CONCAT is not set 516# CONFIG_MTD_CONCAT is not set
513CONFIG_MTD_PARTITIONS=y 517CONFIG_MTD_PARTITIONS=y
514# CONFIG_MTD_REDBOOT_PARTS is not set 518# CONFIG_MTD_REDBOOT_PARTS is not set
515# CONFIG_MTD_CMDLINE_PARTS is not set 519CONFIG_MTD_CMDLINE_PARTS=y
516 520
517# 521#
518# User Modules And Translation Layers 522# User Modules And Translation Layers
@@ -529,8 +533,8 @@ CONFIG_MTD_BLOCK=y
529# 533#
530# RAM/ROM/Flash chip drivers 534# RAM/ROM/Flash chip drivers
531# 535#
532# CONFIG_MTD_CFI is not set 536CONFIG_MTD_CFI=m
533CONFIG_MTD_JEDECPROBE=m 537# CONFIG_MTD_JEDECPROBE is not set
534CONFIG_MTD_GEN_PROBE=m 538CONFIG_MTD_GEN_PROBE=m
535# CONFIG_MTD_CFI_ADV_OPTIONS is not set 539# CONFIG_MTD_CFI_ADV_OPTIONS is not set
536CONFIG_MTD_MAP_BANK_WIDTH_1=y 540CONFIG_MTD_MAP_BANK_WIDTH_1=y
@@ -544,9 +548,9 @@ CONFIG_MTD_CFI_I2=y
544# CONFIG_MTD_CFI_I4 is not set 548# CONFIG_MTD_CFI_I4 is not set
545# CONFIG_MTD_CFI_I8 is not set 549# CONFIG_MTD_CFI_I8 is not set
546# CONFIG_MTD_CFI_INTELEXT is not set 550# CONFIG_MTD_CFI_INTELEXT is not set
547# CONFIG_MTD_CFI_AMDSTD is not set 551CONFIG_MTD_CFI_AMDSTD=m
548# CONFIG_MTD_CFI_STAA is not set 552# CONFIG_MTD_CFI_STAA is not set
549CONFIG_MTD_MW320D=m 553CONFIG_MTD_CFI_UTIL=m
550CONFIG_MTD_RAM=y 554CONFIG_MTD_RAM=y
551CONFIG_MTD_ROM=m 555CONFIG_MTD_ROM=m
552# CONFIG_MTD_ABSENT is not set 556# CONFIG_MTD_ABSENT is not set
@@ -554,12 +558,11 @@ CONFIG_MTD_ROM=m
554# 558#
555# Mapping drivers for chip access 559# Mapping drivers for chip access
556# 560#
557CONFIG_MTD_COMPLEX_MAPPINGS=y 561# CONFIG_MTD_COMPLEX_MAPPINGS is not set
558# CONFIG_MTD_PHYSMAP is not set 562CONFIG_MTD_PHYSMAP=m
559# CONFIG_MTD_EZKIT561 is not set 563CONFIG_MTD_PHYSMAP_START=0x20000000
560CONFIG_MTD_BF5xx=m 564CONFIG_MTD_PHYSMAP_LEN=0x0
561CONFIG_BFIN_FLASH_SIZE=0x0400000 565CONFIG_MTD_PHYSMAP_BANKWIDTH=2
562CONFIG_EBIU_FLASH_BASE=0x20000000
563# CONFIG_MTD_UCLINUX is not set 566# CONFIG_MTD_UCLINUX is not set
564# CONFIG_MTD_PLATRAM is not set 567# CONFIG_MTD_PLATRAM is not set
565 568
@@ -647,8 +650,8 @@ CONFIG_SMC91X=y
647# CONFIG_SMSC911X is not set 650# CONFIG_SMSC911X is not set
648# CONFIG_DM9000 is not set 651# CONFIG_DM9000 is not set
649CONFIG_NETDEV_1000=y 652CONFIG_NETDEV_1000=y
650CONFIG_NETDEV_10000=y
651# CONFIG_AX88180 is not set 653# CONFIG_AX88180 is not set
654CONFIG_NETDEV_10000=y
652 655
653# 656#
654# Wireless LAN 657# Wireless LAN
@@ -717,7 +720,6 @@ CONFIG_INPUT_EVDEV=m
717# CONFIG_BFIN_SPORT is not set 720# CONFIG_BFIN_SPORT is not set
718# CONFIG_BFIN_TIMER_LATENCY is not set 721# CONFIG_BFIN_TIMER_LATENCY is not set
719# CONFIG_AD5304 is not set 722# CONFIG_AD5304 is not set
720# CONFIG_BF5xx_FBDMA is not set
721# CONFIG_VT is not set 723# CONFIG_VT is not set
722# CONFIG_SERIAL_NONSTANDARD is not set 724# CONFIG_SERIAL_NONSTANDARD is not set
723 725
diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile
index 8a4cfb293b27..318b9b692a48 100644
--- a/arch/blackfin/kernel/Makefile
+++ b/arch/blackfin/kernel/Makefile
@@ -7,7 +7,7 @@ extra-y := init_task.o vmlinux.lds
7obj-y := \ 7obj-y := \
8 entry.o process.o bfin_ksyms.o ptrace.o setup.o signal.o \ 8 entry.o process.o bfin_ksyms.o ptrace.o setup.o signal.o \
9 sys_bfin.o time.o traps.o irqchip.o dma-mapping.o flat.o \ 9 sys_bfin.o time.o traps.o irqchip.o dma-mapping.o flat.o \
10 fixed_code.o cplbinit.o cacheinit.o reboot.o bfin_gpio.o 10 fixed_code.o reboot.o bfin_gpio.o
11 11
12obj-$(CONFIG_BFIN_GPTIMERS) += gptimers.o 12obj-$(CONFIG_BFIN_GPTIMERS) += gptimers.o
13obj-$(CONFIG_MODULES) += module.o 13obj-$(CONFIG_MODULES) += module.o
diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c
index b54446055a43..fa9debe8d5f4 100644
--- a/arch/blackfin/kernel/bfin_dma_5xx.c
+++ b/arch/blackfin/kernel/bfin_dma_5xx.c
@@ -339,13 +339,13 @@ EXPORT_SYMBOL(set_dma_config);
339 339
340unsigned short 340unsigned short
341set_bfin_dma_config(char direction, char flow_mode, 341set_bfin_dma_config(char direction, char flow_mode,
342 char intr_mode, char dma_mode, char width) 342 char intr_mode, char dma_mode, char width, char syncmode)
343{ 343{
344 unsigned short config; 344 unsigned short config;
345 345
346 config = 346 config =
347 ((direction << 1) | (width << 2) | (dma_mode << 4) | 347 ((direction << 1) | (width << 2) | (dma_mode << 4) |
348 (intr_mode << 6) | (flow_mode << 12) | RESTART); 348 (intr_mode << 6) | (flow_mode << 12) | (syncmode << 5));
349 return config; 349 return config;
350} 350}
351EXPORT_SYMBOL(set_bfin_dma_config); 351EXPORT_SYMBOL(set_bfin_dma_config);
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c
index ce85d4bf34ca..6bbe0a2fccb8 100644
--- a/arch/blackfin/kernel/bfin_gpio.c
+++ b/arch/blackfin/kernel/bfin_gpio.c
@@ -7,7 +7,7 @@
7 * Description: GPIO Abstraction Layer 7 * Description: GPIO Abstraction Layer
8 * 8 *
9 * Modified: 9 * Modified:
10 * Copyright 2007 Analog Devices Inc. 10 * Copyright 2008 Analog Devices Inc.
11 * 11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/ 12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 * 13 *
@@ -83,6 +83,7 @@
83#include <linux/delay.h> 83#include <linux/delay.h>
84#include <linux/module.h> 84#include <linux/module.h>
85#include <linux/err.h> 85#include <linux/err.h>
86#include <linux/proc_fs.h>
86#include <asm/blackfin.h> 87#include <asm/blackfin.h>
87#include <asm/gpio.h> 88#include <asm/gpio.h>
88#include <asm/portmux.h> 89#include <asm/portmux.h>
@@ -136,7 +137,6 @@ static unsigned short *port_fer[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
136 (unsigned short *) PORTG_FER, 137 (unsigned short *) PORTG_FER,
137 (unsigned short *) PORTH_FER, 138 (unsigned short *) PORTH_FER,
138}; 139};
139
140#endif 140#endif
141 141
142#ifdef BF527_FAMILY 142#ifdef BF527_FAMILY
@@ -178,15 +178,13 @@ static struct gpio_port_t *gpio_array[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
178#endif 178#endif
179 179
180static unsigned short reserved_gpio_map[gpio_bank(MAX_BLACKFIN_GPIOS)]; 180static unsigned short reserved_gpio_map[gpio_bank(MAX_BLACKFIN_GPIOS)];
181static unsigned short reserved_peri_map[gpio_bank(MAX_BLACKFIN_GPIOS + 16)]; 181static unsigned short reserved_peri_map[gpio_bank(MAX_RESOURCES)];
182 182
183#define MAX_RESOURCES 256
184#define RESOURCE_LABEL_SIZE 16 183#define RESOURCE_LABEL_SIZE 16
185 184
186struct str_ident { 185static struct str_ident {
187 char name[RESOURCE_LABEL_SIZE]; 186 char name[RESOURCE_LABEL_SIZE];
188} *str_ident; 187} str_ident[MAX_RESOURCES];
189
190 188
191#ifdef CONFIG_PM 189#ifdef CONFIG_PM
192static unsigned short wakeup_map[gpio_bank(MAX_BLACKFIN_GPIOS)]; 190static unsigned short wakeup_map[gpio_bank(MAX_BLACKFIN_GPIOS)];
@@ -212,7 +210,7 @@ static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG0_INT
212#endif /* CONFIG_PM */ 210#endif /* CONFIG_PM */
213 211
214#if defined(BF548_FAMILY) 212#if defined(BF548_FAMILY)
215inline int check_gpio(unsigned short gpio) 213inline int check_gpio(unsigned gpio)
216{ 214{
217 if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15 215 if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15
218 || gpio == GPIO_PH14 || gpio == GPIO_PH15 216 || gpio == GPIO_PH14 || gpio == GPIO_PH15
@@ -222,7 +220,7 @@ inline int check_gpio(unsigned short gpio)
222 return 0; 220 return 0;
223} 221}
224#else 222#else
225inline int check_gpio(unsigned short gpio) 223inline int check_gpio(unsigned gpio)
226{ 224{
227 if (gpio >= MAX_BLACKFIN_GPIOS) 225 if (gpio >= MAX_BLACKFIN_GPIOS)
228 return -EINVAL; 226 return -EINVAL;
@@ -230,9 +228,13 @@ inline int check_gpio(unsigned short gpio)
230} 228}
231#endif 229#endif
232 230
233static void set_label(unsigned short ident, const char *label) 231void gpio_error(unsigned gpio)
234{ 232{
233 printk(KERN_ERR "bfin-gpio: GPIO %d wasn't requested!\n", gpio);
234}
235 235
236static void set_label(unsigned short ident, const char *label)
237{
236 if (label && str_ident) { 238 if (label && str_ident) {
237 strncpy(str_ident[ident].name, label, 239 strncpy(str_ident[ident].name, label,
238 RESOURCE_LABEL_SIZE); 240 RESOURCE_LABEL_SIZE);
@@ -250,6 +252,11 @@ static char *get_label(unsigned short ident)
250 252
251static int cmp_label(unsigned short ident, const char *label) 253static int cmp_label(unsigned short ident, const char *label)
252{ 254{
255 if (label == NULL) {
256 dump_stack();
257 printk(KERN_ERR "Please provide none-null label\n");
258 }
259
253 if (label && str_ident) 260 if (label && str_ident)
254 return strncmp(str_ident[ident].name, 261 return strncmp(str_ident[ident].name,
255 label, strlen(label)); 262 label, strlen(label));
@@ -258,7 +265,7 @@ static int cmp_label(unsigned short ident, const char *label)
258} 265}
259 266
260#if defined(BF527_FAMILY) || defined(BF537_FAMILY) 267#if defined(BF527_FAMILY) || defined(BF537_FAMILY)
261static void port_setup(unsigned short gpio, unsigned short usage) 268static void port_setup(unsigned gpio, unsigned short usage)
262{ 269{
263 if (!check_gpio(gpio)) { 270 if (!check_gpio(gpio)) {
264 if (usage == GPIO_USAGE) 271 if (usage == GPIO_USAGE)
@@ -269,7 +276,7 @@ static void port_setup(unsigned short gpio, unsigned short usage)
269 } 276 }
270} 277}
271#elif defined(BF548_FAMILY) 278#elif defined(BF548_FAMILY)
272static void port_setup(unsigned short gpio, unsigned short usage) 279static void port_setup(unsigned gpio, unsigned short usage)
273{ 280{
274 if (usage == GPIO_USAGE) 281 if (usage == GPIO_USAGE)
275 gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio); 282 gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio);
@@ -390,7 +397,7 @@ inline void portmux_setup(unsigned short portno, unsigned short function)
390#endif 397#endif
391 398
392#ifndef BF548_FAMILY 399#ifndef BF548_FAMILY
393static void default_gpio(unsigned short gpio) 400static void default_gpio(unsigned gpio)
394{ 401{
395 unsigned short bank, bitmask; 402 unsigned short bank, bitmask;
396 unsigned long flags; 403 unsigned long flags;
@@ -410,7 +417,6 @@ static void default_gpio(unsigned short gpio)
410 gpio_bankb[bank]->edge &= ~bitmask; 417 gpio_bankb[bank]->edge &= ~bitmask;
411 AWA_DUMMY_READ(edge); 418 AWA_DUMMY_READ(edge);
412 local_irq_restore(flags); 419 local_irq_restore(flags);
413
414} 420}
415#else 421#else
416# define default_gpio(...) do { } while (0) 422# define default_gpio(...) do { } while (0)
@@ -418,12 +424,6 @@ static void default_gpio(unsigned short gpio)
418 424
419static int __init bfin_gpio_init(void) 425static int __init bfin_gpio_init(void)
420{ 426{
421 str_ident = kcalloc(MAX_RESOURCES,
422 sizeof(struct str_ident), GFP_KERNEL);
423 if (str_ident == NULL)
424 return -ENOMEM;
425
426 memset(str_ident, 0, MAX_RESOURCES * sizeof(struct str_ident));
427 427
428 printk(KERN_INFO "Blackfin GPIO Controller\n"); 428 printk(KERN_INFO "Blackfin GPIO Controller\n");
429 429
@@ -454,10 +454,9 @@ arch_initcall(bfin_gpio_init);
454/* Set a specific bit */ 454/* Set a specific bit */
455 455
456#define SET_GPIO(name) \ 456#define SET_GPIO(name) \
457void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \ 457void set_gpio_ ## name(unsigned gpio, unsigned short arg) \
458{ \ 458{ \
459 unsigned long flags; \ 459 unsigned long flags; \
460 BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); \
461 local_irq_save(flags); \ 460 local_irq_save(flags); \
462 if (arg) \ 461 if (arg) \
463 gpio_bankb[gpio_bank(gpio)]->name |= gpio_bit(gpio); \ 462 gpio_bankb[gpio_bank(gpio)]->name |= gpio_bit(gpio); \
@@ -477,10 +476,9 @@ SET_GPIO(both)
477 476
478#if ANOMALY_05000311 || ANOMALY_05000323 477#if ANOMALY_05000311 || ANOMALY_05000323
479#define SET_GPIO_SC(name) \ 478#define SET_GPIO_SC(name) \
480void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \ 479void set_gpio_ ## name(unsigned gpio, unsigned short arg) \
481{ \ 480{ \
482 unsigned long flags; \ 481 unsigned long flags; \
483 BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); \
484 local_irq_save(flags); \ 482 local_irq_save(flags); \
485 if (arg) \ 483 if (arg) \
486 gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \ 484 gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \
@@ -492,9 +490,8 @@ void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \
492EXPORT_SYMBOL(set_gpio_ ## name); 490EXPORT_SYMBOL(set_gpio_ ## name);
493#else 491#else
494#define SET_GPIO_SC(name) \ 492#define SET_GPIO_SC(name) \
495void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \ 493void set_gpio_ ## name(unsigned gpio, unsigned short arg) \
496{ \ 494{ \
497 BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); \
498 if (arg) \ 495 if (arg) \
499 gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \ 496 gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \
500 else \ 497 else \
@@ -508,19 +505,17 @@ SET_GPIO_SC(maskb)
508SET_GPIO_SC(data) 505SET_GPIO_SC(data)
509 506
510#if ANOMALY_05000311 || ANOMALY_05000323 507#if ANOMALY_05000311 || ANOMALY_05000323
511void set_gpio_toggle(unsigned short gpio) 508void set_gpio_toggle(unsigned gpio)
512{ 509{
513 unsigned long flags; 510 unsigned long flags;
514 BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
515 local_irq_save(flags); 511 local_irq_save(flags);
516 gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio); 512 gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio);
517 AWA_DUMMY_READ(toggle); 513 AWA_DUMMY_READ(toggle);
518 local_irq_restore(flags); 514 local_irq_restore(flags);
519} 515}
520#else 516#else
521void set_gpio_toggle(unsigned short gpio) 517void set_gpio_toggle(unsigned gpio)
522{ 518{
523 BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
524 gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio); 519 gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio);
525} 520}
526#endif 521#endif
@@ -531,7 +526,7 @@ EXPORT_SYMBOL(set_gpio_toggle);
531 526
532#if ANOMALY_05000311 || ANOMALY_05000323 527#if ANOMALY_05000311 || ANOMALY_05000323
533#define SET_GPIO_P(name) \ 528#define SET_GPIO_P(name) \
534void set_gpiop_ ## name(unsigned short gpio, unsigned short arg) \ 529void set_gpiop_ ## name(unsigned gpio, unsigned short arg) \
535{ \ 530{ \
536 unsigned long flags; \ 531 unsigned long flags; \
537 local_irq_save(flags); \ 532 local_irq_save(flags); \
@@ -542,7 +537,7 @@ void set_gpiop_ ## name(unsigned short gpio, unsigned short arg) \
542EXPORT_SYMBOL(set_gpiop_ ## name); 537EXPORT_SYMBOL(set_gpiop_ ## name);
543#else 538#else
544#define SET_GPIO_P(name) \ 539#define SET_GPIO_P(name) \
545void set_gpiop_ ## name(unsigned short gpio, unsigned short arg) \ 540void set_gpiop_ ## name(unsigned gpio, unsigned short arg) \
546{ \ 541{ \
547 gpio_bankb[gpio_bank(gpio)]->name = arg; \ 542 gpio_bankb[gpio_bank(gpio)]->name = arg; \
548} \ 543} \
@@ -558,11 +553,10 @@ SET_GPIO_P(both)
558SET_GPIO_P(maska) 553SET_GPIO_P(maska)
559SET_GPIO_P(maskb) 554SET_GPIO_P(maskb)
560 555
561
562/* Get a specific bit */ 556/* Get a specific bit */
563#if ANOMALY_05000311 || ANOMALY_05000323 557#if ANOMALY_05000311 || ANOMALY_05000323
564#define GET_GPIO(name) \ 558#define GET_GPIO(name) \
565unsigned short get_gpio_ ## name(unsigned short gpio) \ 559unsigned short get_gpio_ ## name(unsigned gpio) \
566{ \ 560{ \
567 unsigned long flags; \ 561 unsigned long flags; \
568 unsigned short ret; \ 562 unsigned short ret; \
@@ -575,7 +569,7 @@ unsigned short get_gpio_ ## name(unsigned short gpio) \
575EXPORT_SYMBOL(get_gpio_ ## name); 569EXPORT_SYMBOL(get_gpio_ ## name);
576#else 570#else
577#define GET_GPIO(name) \ 571#define GET_GPIO(name) \
578unsigned short get_gpio_ ## name(unsigned short gpio) \ 572unsigned short get_gpio_ ## name(unsigned gpio) \
579{ \ 573{ \
580 return (0x01 & (gpio_bankb[gpio_bank(gpio)]->name >> gpio_sub_n(gpio))); \ 574 return (0x01 & (gpio_bankb[gpio_bank(gpio)]->name >> gpio_sub_n(gpio))); \
581} \ 575} \
@@ -595,7 +589,7 @@ GET_GPIO(maskb)
595 589
596#if ANOMALY_05000311 || ANOMALY_05000323 590#if ANOMALY_05000311 || ANOMALY_05000323
597#define GET_GPIO_P(name) \ 591#define GET_GPIO_P(name) \
598unsigned short get_gpiop_ ## name(unsigned short gpio) \ 592unsigned short get_gpiop_ ## name(unsigned gpio) \
599{ \ 593{ \
600 unsigned long flags; \ 594 unsigned long flags; \
601 unsigned short ret; \ 595 unsigned short ret; \
@@ -608,7 +602,7 @@ unsigned short get_gpiop_ ## name(unsigned short gpio) \
608EXPORT_SYMBOL(get_gpiop_ ## name); 602EXPORT_SYMBOL(get_gpiop_ ## name);
609#else 603#else
610#define GET_GPIO_P(name) \ 604#define GET_GPIO_P(name) \
611unsigned short get_gpiop_ ## name(unsigned short gpio) \ 605unsigned short get_gpiop_ ## name(unsigned gpio) \
612{ \ 606{ \
613 return (gpio_bankb[gpio_bank(gpio)]->name);\ 607 return (gpio_bankb[gpio_bank(gpio)]->name);\
614} \ 608} \
@@ -645,7 +639,7 @@ GET_GPIO_P(maskb)
645************************************************************* 639*************************************************************
646* MODIFICATION HISTORY : 640* MODIFICATION HISTORY :
647**************************************************************/ 641**************************************************************/
648int gpio_pm_wakeup_request(unsigned short gpio, unsigned char type) 642int gpio_pm_wakeup_request(unsigned gpio, unsigned char type)
649{ 643{
650 unsigned long flags; 644 unsigned long flags;
651 645
@@ -653,7 +647,6 @@ int gpio_pm_wakeup_request(unsigned short gpio, unsigned char type)
653 return -EINVAL; 647 return -EINVAL;
654 648
655 local_irq_save(flags); 649 local_irq_save(flags);
656
657 wakeup_map[gpio_bank(gpio)] |= gpio_bit(gpio); 650 wakeup_map[gpio_bank(gpio)] |= gpio_bit(gpio);
658 wakeup_flags_map[gpio] = type; 651 wakeup_flags_map[gpio] = type;
659 local_irq_restore(flags); 652 local_irq_restore(flags);
@@ -662,7 +655,7 @@ int gpio_pm_wakeup_request(unsigned short gpio, unsigned char type)
662} 655}
663EXPORT_SYMBOL(gpio_pm_wakeup_request); 656EXPORT_SYMBOL(gpio_pm_wakeup_request);
664 657
665void gpio_pm_wakeup_free(unsigned short gpio) 658void gpio_pm_wakeup_free(unsigned gpio)
666{ 659{
667 unsigned long flags; 660 unsigned long flags;
668 661
@@ -677,7 +670,7 @@ void gpio_pm_wakeup_free(unsigned short gpio)
677} 670}
678EXPORT_SYMBOL(gpio_pm_wakeup_free); 671EXPORT_SYMBOL(gpio_pm_wakeup_free);
679 672
680static int bfin_gpio_wakeup_type(unsigned short gpio, unsigned char type) 673static int bfin_gpio_wakeup_type(unsigned gpio, unsigned char type)
681{ 674{
682 port_setup(gpio, GPIO_USAGE); 675 port_setup(gpio, GPIO_USAGE);
683 set_gpio_dir(gpio, 0); 676 set_gpio_dir(gpio, 0);
@@ -784,6 +777,14 @@ void gpio_pm_restore(void)
784} 777}
785 778
786#endif 779#endif
780#else /* BF548_FAMILY */
781
782unsigned short get_gpio_dir(unsigned gpio)
783{
784 return (0x01 & (gpio_array[gpio_bank(gpio)]->port_dir_clear >> gpio_sub_n(gpio)));
785}
786EXPORT_SYMBOL(get_gpio_dir);
787
787#endif /* BF548_FAMILY */ 788#endif /* BF548_FAMILY */
788 789
789/*********************************************************** 790/***********************************************************
@@ -1028,7 +1029,7 @@ EXPORT_SYMBOL(peripheral_free_list);
1028* MODIFICATION HISTORY : 1029* MODIFICATION HISTORY :
1029**************************************************************/ 1030**************************************************************/
1030 1031
1031int gpio_request(unsigned short gpio, const char *label) 1032int gpio_request(unsigned gpio, const char *label)
1032{ 1033{
1033 unsigned long flags; 1034 unsigned long flags;
1034 1035
@@ -1075,7 +1076,7 @@ int gpio_request(unsigned short gpio, const char *label)
1075} 1076}
1076EXPORT_SYMBOL(gpio_request); 1077EXPORT_SYMBOL(gpio_request);
1077 1078
1078void gpio_free(unsigned short gpio) 1079void gpio_free(unsigned gpio)
1079{ 1080{
1080 unsigned long flags; 1081 unsigned long flags;
1081 1082
@@ -1085,7 +1086,7 @@ void gpio_free(unsigned short gpio)
1085 local_irq_save(flags); 1086 local_irq_save(flags);
1086 1087
1087 if (unlikely(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))) { 1088 if (unlikely(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))) {
1088 printk(KERN_ERR "bfin-gpio: GPIO %d wasn't reserved!\n", gpio); 1089 gpio_error(gpio);
1089 dump_stack(); 1090 dump_stack();
1090 local_irq_restore(flags); 1091 local_irq_restore(flags);
1091 return; 1092 return;
@@ -1101,44 +1102,55 @@ void gpio_free(unsigned short gpio)
1101} 1102}
1102EXPORT_SYMBOL(gpio_free); 1103EXPORT_SYMBOL(gpio_free);
1103 1104
1105
1104#ifdef BF548_FAMILY 1106#ifdef BF548_FAMILY
1105void gpio_direction_input(unsigned short gpio) 1107int gpio_direction_input(unsigned gpio)
1106{ 1108{
1107 unsigned long flags; 1109 unsigned long flags;
1108 1110
1109 BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); 1111 if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
1112 gpio_error(gpio);
1113 return -EINVAL;
1114 }
1110 1115
1111 local_irq_save(flags); 1116 local_irq_save(flags);
1112 gpio_array[gpio_bank(gpio)]->port_dir_clear = gpio_bit(gpio); 1117 gpio_array[gpio_bank(gpio)]->port_dir_clear = gpio_bit(gpio);
1113 gpio_array[gpio_bank(gpio)]->port_inen |= gpio_bit(gpio); 1118 gpio_array[gpio_bank(gpio)]->port_inen |= gpio_bit(gpio);
1114 local_irq_restore(flags); 1119 local_irq_restore(flags);
1120
1121 return 0;
1115} 1122}
1116EXPORT_SYMBOL(gpio_direction_input); 1123EXPORT_SYMBOL(gpio_direction_input);
1117 1124
1118void gpio_direction_output(unsigned short gpio) 1125int gpio_direction_output(unsigned gpio, int value)
1119{ 1126{
1120 unsigned long flags; 1127 unsigned long flags;
1121 1128
1122 BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); 1129 if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
1130 gpio_error(gpio);
1131 return -EINVAL;
1132 }
1123 1133
1124 local_irq_save(flags); 1134 local_irq_save(flags);
1125 gpio_array[gpio_bank(gpio)]->port_inen &= ~gpio_bit(gpio); 1135 gpio_array[gpio_bank(gpio)]->port_inen &= ~gpio_bit(gpio);
1136 gpio_set_value(gpio, value);
1126 gpio_array[gpio_bank(gpio)]->port_dir_set = gpio_bit(gpio); 1137 gpio_array[gpio_bank(gpio)]->port_dir_set = gpio_bit(gpio);
1127 local_irq_restore(flags); 1138 local_irq_restore(flags);
1139
1140 return 0;
1128} 1141}
1129EXPORT_SYMBOL(gpio_direction_output); 1142EXPORT_SYMBOL(gpio_direction_output);
1130 1143
1131void gpio_set_value(unsigned short gpio, unsigned short arg) 1144void gpio_set_value(unsigned gpio, int arg)
1132{ 1145{
1133 if (arg) 1146 if (arg)
1134 gpio_array[gpio_bank(gpio)]->port_set = gpio_bit(gpio); 1147 gpio_array[gpio_bank(gpio)]->port_set = gpio_bit(gpio);
1135 else 1148 else
1136 gpio_array[gpio_bank(gpio)]->port_clear = gpio_bit(gpio); 1149 gpio_array[gpio_bank(gpio)]->port_clear = gpio_bit(gpio);
1137
1138} 1150}
1139EXPORT_SYMBOL(gpio_set_value); 1151EXPORT_SYMBOL(gpio_set_value);
1140 1152
1141unsigned short gpio_get_value(unsigned short gpio) 1153int gpio_get_value(unsigned gpio)
1142{ 1154{
1143 return (1 & (gpio_array[gpio_bank(gpio)]->port_data >> gpio_sub_n(gpio))); 1155 return (1 & (gpio_array[gpio_bank(gpio)]->port_data >> gpio_sub_n(gpio)));
1144} 1156}
@@ -1146,31 +1158,47 @@ EXPORT_SYMBOL(gpio_get_value);
1146 1158
1147#else 1159#else
1148 1160
1149void gpio_direction_input(unsigned short gpio) 1161int gpio_direction_input(unsigned gpio)
1150{ 1162{
1151 unsigned long flags; 1163 unsigned long flags;
1152 1164
1153 BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); 1165 if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
1166 gpio_error(gpio);
1167 return -EINVAL;
1168 }
1154 1169
1155 local_irq_save(flags); 1170 local_irq_save(flags);
1156 gpio_bankb[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio); 1171 gpio_bankb[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio);
1157 gpio_bankb[gpio_bank(gpio)]->inen |= gpio_bit(gpio); 1172 gpio_bankb[gpio_bank(gpio)]->inen |= gpio_bit(gpio);
1158 AWA_DUMMY_READ(inen); 1173 AWA_DUMMY_READ(inen);
1159 local_irq_restore(flags); 1174 local_irq_restore(flags);
1175
1176 return 0;
1160} 1177}
1161EXPORT_SYMBOL(gpio_direction_input); 1178EXPORT_SYMBOL(gpio_direction_input);
1162 1179
1163void gpio_direction_output(unsigned short gpio) 1180int gpio_direction_output(unsigned gpio, int value)
1164{ 1181{
1165 unsigned long flags; 1182 unsigned long flags;
1166 1183
1167 BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); 1184 if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
1185 gpio_error(gpio);
1186 return -EINVAL;
1187 }
1168 1188
1169 local_irq_save(flags); 1189 local_irq_save(flags);
1170 gpio_bankb[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio); 1190 gpio_bankb[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio);
1191
1192 if (value)
1193 gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio);
1194 else
1195 gpio_bankb[gpio_bank(gpio)]->data_clear = gpio_bit(gpio);
1196
1171 gpio_bankb[gpio_bank(gpio)]->dir |= gpio_bit(gpio); 1197 gpio_bankb[gpio_bank(gpio)]->dir |= gpio_bit(gpio);
1172 AWA_DUMMY_READ(dir); 1198 AWA_DUMMY_READ(dir);
1173 local_irq_restore(flags); 1199 local_irq_restore(flags);
1200
1201 return 0;
1174} 1202}
1175EXPORT_SYMBOL(gpio_direction_output); 1203EXPORT_SYMBOL(gpio_direction_output);
1176 1204
@@ -1190,7 +1218,40 @@ void bfin_gpio_reset_spi0_ssel1(void)
1190 1218
1191 port_setup(gpio, GPIO_USAGE); 1219 port_setup(gpio, GPIO_USAGE);
1192 gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio); 1220 gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio);
1221 AWA_DUMMY_READ(data_set);
1193 udelay(1); 1222 udelay(1);
1194} 1223}
1195 1224
1196#endif /*BF548_FAMILY */ 1225#endif /*BF548_FAMILY */
1226
1227#if defined(CONFIG_PROC_FS)
1228static int gpio_proc_read(char *buf, char **start, off_t offset,
1229 int len, int *unused_i, void *unused_v)
1230{
1231 int c, outlen = 0;
1232
1233 for (c = 0; c < MAX_RESOURCES; c++) {
1234 if (!check_gpio(c) && (reserved_gpio_map[gpio_bank(c)] & gpio_bit(c)))
1235 len = sprintf(buf, "GPIO_%d: %s \t\tGPIO %s\n", c,
1236 get_label(c), get_gpio_dir(c) ? "OUTPUT" : "INPUT");
1237 else if (reserved_peri_map[gpio_bank(c)] & gpio_bit(c))
1238 len = sprintf(buf, "GPIO_%d: %s \t\tPeripheral\n", c, get_label(c));
1239 else
1240 continue;
1241 buf += len;
1242 outlen += len;
1243 }
1244 return outlen;
1245}
1246
1247static __init int gpio_register_proc(void)
1248{
1249 struct proc_dir_entry *proc_gpio;
1250
1251 proc_gpio = create_proc_entry("gpio", S_IRUGO, NULL);
1252 if (proc_gpio)
1253 proc_gpio->read_proc = gpio_proc_read;
1254 return proc_gpio != NULL;
1255}
1256__initcall(gpio_register_proc);
1257#endif
diff --git a/arch/blackfin/kernel/cplb-mpu/Makefile b/arch/blackfin/kernel/cplb-mpu/Makefile
new file mode 100644
index 000000000000..286b69357f97
--- /dev/null
+++ b/arch/blackfin/kernel/cplb-mpu/Makefile
@@ -0,0 +1,8 @@
1#
2# arch/blackfin/kernel/cplb-nompu/Makefile
3#
4
5obj-y := cplbinit.o cacheinit.o cplbmgr.o
6
7obj-$(CONFIG_CPLB_INFO) += cplbinfo.o
8
diff --git a/arch/blackfin/kernel/cplb-mpu/cacheinit.c b/arch/blackfin/kernel/cplb-mpu/cacheinit.c
new file mode 100644
index 000000000000..9eecfa403187
--- /dev/null
+++ b/arch/blackfin/kernel/cplb-mpu/cacheinit.c
@@ -0,0 +1,62 @@
1/*
2 * Copyright 2004-2007 Analog Devices Inc.
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, see the file COPYING, or write
16 * to the Free Software Foundation, Inc.,
17 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <linux/cpu.h>
21
22#include <asm/cacheflush.h>
23#include <asm/blackfin.h>
24#include <asm/cplb.h>
25#include <asm/cplbinit.h>
26
27#if defined(CONFIG_BFIN_ICACHE)
28void bfin_icache_init(void)
29{
30 unsigned long ctrl;
31 int i;
32
33 SSYNC();
34 for (i = 0; i < MAX_CPLBS; i++) {
35 bfin_write32(ICPLB_ADDR0 + i * 4, icplb_tbl[i].addr);
36 bfin_write32(ICPLB_DATA0 + i * 4, icplb_tbl[i].data);
37 }
38 ctrl = bfin_read_IMEM_CONTROL();
39 ctrl |= IMC | ENICPLB;
40 bfin_write_IMEM_CONTROL(ctrl);
41 SSYNC();
42}
43#endif
44
45#if defined(CONFIG_BFIN_DCACHE)
46void bfin_dcache_init(void)
47{
48 unsigned long ctrl;
49 int i;
50
51 SSYNC();
52 for (i = 0; i < MAX_CPLBS; i++) {
53 bfin_write32(DCPLB_ADDR0 + i * 4, dcplb_tbl[i].addr);
54 bfin_write32(DCPLB_DATA0 + i * 4, dcplb_tbl[i].data);
55 }
56
57 ctrl = bfin_read_DMEM_CONTROL();
58 ctrl |= DMEM_CNTR;
59 bfin_write_DMEM_CONTROL(ctrl);
60 SSYNC();
61}
62#endif
diff --git a/arch/blackfin/kernel/cplb-mpu/cplbinfo.c b/arch/blackfin/kernel/cplb-mpu/cplbinfo.c
new file mode 100644
index 000000000000..bd072299f7f2
--- /dev/null
+++ b/arch/blackfin/kernel/cplb-mpu/cplbinfo.c
@@ -0,0 +1,144 @@
1/*
2 * File: arch/blackfin/mach-common/cplbinfo.c
3 * Based on:
4 * Author: Sonic Zhang <sonic.zhang@analog.com>
5 *
6 * Created: Jan. 2005
7 * Description: Display CPLB status
8 *
9 * Modified:
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */
29
30#include <linux/module.h>
31#include <linux/kernel.h>
32#include <linux/init.h>
33#include <linux/proc_fs.h>
34#include <linux/uaccess.h>
35
36#include <asm/current.h>
37#include <asm/system.h>
38#include <asm/cplb.h>
39#include <asm/cplbinit.h>
40#include <asm/blackfin.h>
41
42#define CPLB_I 1
43#define CPLB_D 2
44
45#define SYNC_SYS SSYNC()
46#define SYNC_CORE CSYNC()
47
48#define CPLB_BIT_PAGESIZE 0x30000
49
50static char page_size_string_table[][4] = { "1K", "4K", "1M", "4M" };
51
52static char *cplb_print_entry(char *buf, struct cplb_entry *tbl, int switched)
53{
54 int i;
55 buf += sprintf(buf, "Index\tAddress\t\tData\tSize\tU/RD\tU/WR\tS/WR\tSwitch\n");
56 for (i = 0; i < MAX_CPLBS; i++) {
57 unsigned long data = tbl[i].data;
58 unsigned long addr = tbl[i].addr;
59 if (!(data & CPLB_VALID))
60 continue;
61
62 buf +=
63 sprintf(buf,
64 "%d\t0x%08lx\t%06lx\t%s\t%c\t%c\t%c\t%c\n",
65 i, addr, data,
66 page_size_string_table[(data & 0x30000) >> 16],
67 (data & CPLB_USER_RD) ? 'Y' : 'N',
68 (data & CPLB_USER_WR) ? 'Y' : 'N',
69 (data & CPLB_SUPV_WR) ? 'Y' : 'N',
70 i < switched ? 'N' : 'Y');
71 }
72 buf += sprintf(buf, "\n");
73
74 return buf;
75}
76
77int cplbinfo_proc_output(char *buf)
78{
79 char *p;
80
81 p = buf;
82
83 p += sprintf(p, "------------------ CPLB Information ------------------\n\n");
84
85 if (bfin_read_IMEM_CONTROL() & ENICPLB) {
86 p += sprintf(p, "Instruction CPLB entry:\n");
87 p = cplb_print_entry(p, icplb_tbl, first_switched_icplb);
88 } else
89 p += sprintf(p, "Instruction CPLB is disabled.\n\n");
90
91 if (1 || bfin_read_DMEM_CONTROL() & ENDCPLB) {
92 p += sprintf(p, "Data CPLB entry:\n");
93 p = cplb_print_entry(p, dcplb_tbl, first_switched_dcplb);
94 } else
95 p += sprintf(p, "Data CPLB is disabled.\n");
96
97 p += sprintf(p, "ICPLB miss: %d\nICPLB supervisor miss: %d\n",
98 nr_icplb_miss, nr_icplb_supv_miss);
99 p += sprintf(p, "DCPLB miss: %d\nDCPLB protection fault:%d\n",
100 nr_dcplb_miss, nr_dcplb_prot);
101 p += sprintf(p, "CPLB flushes: %d\n",
102 nr_cplb_flush);
103
104 return p - buf;
105}
106
107static int cplbinfo_read_proc(char *page, char **start, off_t off,
108 int count, int *eof, void *data)
109{
110 int len;
111
112 len = cplbinfo_proc_output(page);
113 if (len <= off + count)
114 *eof = 1;
115 *start = page + off;
116 len -= off;
117 if (len > count)
118 len = count;
119 if (len < 0)
120 len = 0;
121 return len;
122}
123
124static int __init cplbinfo_init(void)
125{
126 struct proc_dir_entry *entry;
127
128 entry = create_proc_entry("cplbinfo", 0, NULL);
129 if (!entry)
130 return -ENOMEM;
131
132 entry->read_proc = cplbinfo_read_proc;
133 entry->data = NULL;
134
135 return 0;
136}
137
138static void __exit cplbinfo_exit(void)
139{
140 remove_proc_entry("cplbinfo", NULL);
141}
142
143module_init(cplbinfo_init);
144module_exit(cplbinfo_exit);
diff --git a/arch/blackfin/kernel/cplb-mpu/cplbinit.c b/arch/blackfin/kernel/cplb-mpu/cplbinit.c
new file mode 100644
index 000000000000..e2e2b5079f5b
--- /dev/null
+++ b/arch/blackfin/kernel/cplb-mpu/cplbinit.c
@@ -0,0 +1,91 @@
1/*
2 * Blackfin CPLB initialization
3 *
4 * Copyright 2004-2007 Analog Devices Inc.
5 *
6 * Bugs: Enter bugs at http://blackfin.uclinux.org/
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, see the file COPYING, or write
20 * to the Free Software Foundation, Inc.,
21 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23#include <linux/module.h>
24
25#include <asm/blackfin.h>
26#include <asm/cplb.h>
27#include <asm/cplbinit.h>
28
29struct cplb_entry icplb_tbl[MAX_CPLBS];
30struct cplb_entry dcplb_tbl[MAX_CPLBS];
31
32int first_switched_icplb, first_switched_dcplb;
33int first_mask_dcplb;
34
35void __init generate_cpl_tables(void)
36{
37 int i_d, i_i;
38 unsigned long addr;
39 unsigned long d_data, i_data;
40 unsigned long d_cache = 0, i_cache = 0;
41
42#ifdef CONFIG_BFIN_ICACHE
43 i_cache = CPLB_L1_CHBL | ANOMALY_05000158_WORKAROUND;
44#endif
45
46#ifdef CONFIG_BFIN_DCACHE
47 d_cache = CPLB_L1_CHBL;
48#ifdef CONFIG_BLKFIN_WT
49 d_cache |= CPLB_L1_AOW | CPLB_WT;
50#endif
51#endif
52 i_d = i_i = 0;
53
54 /* Set up the zero page. */
55 dcplb_tbl[i_d].addr = 0;
56 dcplb_tbl[i_d++].data = SDRAM_OOPS | PAGE_SIZE_1KB;
57
58#if 0
59 icplb_tbl[i_i].addr = 0;
60 icplb_tbl[i_i++].data = i_cache | CPLB_USER_RD | PAGE_SIZE_4KB;
61#endif
62
63 /* Cover kernel memory with 4M pages. */
64 addr = 0;
65 d_data = d_cache | CPLB_SUPV_WR | CPLB_VALID | PAGE_SIZE_4MB | CPLB_DIRTY;
66 i_data = i_cache | CPLB_VALID | CPLB_PORTPRIO | PAGE_SIZE_4MB;
67
68 for (; addr < memory_start; addr += 4 * 1024 * 1024) {
69 dcplb_tbl[i_d].addr = addr;
70 dcplb_tbl[i_d++].data = d_data;
71 icplb_tbl[i_i].addr = addr;
72 icplb_tbl[i_i++].data = i_data | (addr == 0 ? CPLB_USER_RD : 0);
73 }
74
75 /* Cover L1 memory. One 4M area for code and data each is enough. */
76#if L1_DATA_A_LENGTH > 0 || L1_DATA_B_LENGTH > 0
77 dcplb_tbl[i_d].addr = L1_DATA_A_START;
78 dcplb_tbl[i_d++].data = L1_DMEMORY | PAGE_SIZE_4MB;
79#endif
80 icplb_tbl[i_i].addr = L1_CODE_START;
81 icplb_tbl[i_i++].data = L1_IMEMORY | PAGE_SIZE_4MB;
82
83 first_mask_dcplb = i_d;
84 first_switched_dcplb = i_d + (1 << page_mask_order);
85 first_switched_icplb = i_i;
86
87 while (i_d < MAX_CPLBS)
88 dcplb_tbl[i_d++].data = 0;
89 while (i_i < MAX_CPLBS)
90 icplb_tbl[i_i++].data = 0;
91}
diff --git a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
new file mode 100644
index 000000000000..c426a22f9907
--- /dev/null
+++ b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
@@ -0,0 +1,338 @@
1/*
2 * Blackfin CPLB exception handling.
3 * Copyright 2004-2007 Analog Devices 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, see the file COPYING, or write
17 * to the Free Software Foundation, Inc.,
18 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20#include <linux/module.h>
21#include <linux/mm.h>
22
23#include <asm/blackfin.h>
24#include <asm/cplbinit.h>
25#include <asm/mmu_context.h>
26
27#ifdef CONFIG_BFIN_ICACHE
28
29#define FAULT_RW (1 << 16)
30#define FAULT_USERSUPV (1 << 17)
31
32int page_mask_nelts;
33int page_mask_order;
34unsigned long *current_rwx_mask;
35
36int nr_dcplb_miss, nr_icplb_miss, nr_icplb_supv_miss, nr_dcplb_prot;
37int nr_cplb_flush;
38
39static inline void disable_dcplb(void)
40{
41 unsigned long ctrl;
42 SSYNC();
43 ctrl = bfin_read_DMEM_CONTROL();
44 ctrl &= ~ENDCPLB;
45 bfin_write_DMEM_CONTROL(ctrl);
46 SSYNC();
47}
48
49static inline void enable_dcplb(void)
50{
51 unsigned long ctrl;
52 SSYNC();
53 ctrl = bfin_read_DMEM_CONTROL();
54 ctrl |= ENDCPLB;
55 bfin_write_DMEM_CONTROL(ctrl);
56 SSYNC();
57}
58
59static inline void disable_icplb(void)
60{
61 unsigned long ctrl;
62 SSYNC();
63 ctrl = bfin_read_IMEM_CONTROL();
64 ctrl &= ~ENICPLB;
65 bfin_write_IMEM_CONTROL(ctrl);
66 SSYNC();
67}
68
69static inline void enable_icplb(void)
70{
71 unsigned long ctrl;
72 SSYNC();
73 ctrl = bfin_read_IMEM_CONTROL();
74 ctrl |= ENICPLB;
75 bfin_write_IMEM_CONTROL(ctrl);
76 SSYNC();
77}
78
79/*
80 * Given the contents of the status register, return the index of the
81 * CPLB that caused the fault.
82 */
83static inline int faulting_cplb_index(int status)
84{
85 int signbits = __builtin_bfin_norm_fr1x32(status & 0xFFFF);
86 return 30 - signbits;
87}
88
89/*
90 * Given the contents of the status register and the DCPLB_DATA contents,
91 * return true if a write access should be permitted.
92 */
93static inline int write_permitted(int status, unsigned long data)
94{
95 if (status & FAULT_USERSUPV)
96 return !!(data & CPLB_SUPV_WR);
97 else
98 return !!(data & CPLB_USER_WR);
99}
100
101/* Counters to implement round-robin replacement. */
102static int icplb_rr_index, dcplb_rr_index;
103
104/*
105 * Find an ICPLB entry to be evicted and return its index.
106 */
107static int evict_one_icplb(void)
108{
109 int i;
110 for (i = first_switched_icplb; i < MAX_CPLBS; i++)
111 if ((icplb_tbl[i].data & CPLB_VALID) == 0)
112 return i;
113 i = first_switched_icplb + icplb_rr_index;
114 if (i >= MAX_CPLBS) {
115 i -= MAX_CPLBS - first_switched_icplb;
116 icplb_rr_index -= MAX_CPLBS - first_switched_icplb;
117 }
118 icplb_rr_index++;
119 return i;
120}
121
122static int evict_one_dcplb(void)
123{
124 int i;
125 for (i = first_switched_dcplb; i < MAX_CPLBS; i++)
126 if ((dcplb_tbl[i].data & CPLB_VALID) == 0)
127 return i;
128 i = first_switched_dcplb + dcplb_rr_index;
129 if (i >= MAX_CPLBS) {
130 i -= MAX_CPLBS - first_switched_dcplb;
131 dcplb_rr_index -= MAX_CPLBS - first_switched_dcplb;
132 }
133 dcplb_rr_index++;
134 return i;
135}
136
137static noinline int dcplb_miss(void)
138{
139 unsigned long addr = bfin_read_DCPLB_FAULT_ADDR();
140 int status = bfin_read_DCPLB_STATUS();
141 unsigned long *mask;
142 int idx;
143 unsigned long d_data;
144
145 nr_dcplb_miss++;
146 if (addr >= _ramend)
147 return CPLB_PROT_VIOL;
148
149 d_data = CPLB_SUPV_WR | CPLB_VALID | CPLB_DIRTY | PAGE_SIZE_4KB;
150#ifdef CONFIG_BFIN_DCACHE
151 d_data |= CPLB_L1_CHBL | ANOMALY_05000158_WORKAROUND;
152#ifdef CONFIG_BLKFIN_WT
153 d_data |= CPLB_L1_AOW | CPLB_WT;
154#endif
155#endif
156 mask = current_rwx_mask;
157 if (mask) {
158 int page = addr >> PAGE_SHIFT;
159 int offs = page >> 5;
160 int bit = 1 << (page & 31);
161
162 if (mask[offs] & bit)
163 d_data |= CPLB_USER_RD;
164
165 mask += page_mask_nelts;
166 if (mask[offs] & bit)
167 d_data |= CPLB_USER_WR;
168 }
169
170 idx = evict_one_dcplb();
171
172 addr &= PAGE_MASK;
173 dcplb_tbl[idx].addr = addr;
174 dcplb_tbl[idx].data = d_data;
175
176 disable_dcplb();
177 bfin_write32(DCPLB_DATA0 + idx * 4, d_data);
178 bfin_write32(DCPLB_ADDR0 + idx * 4, addr);
179 enable_dcplb();
180
181 return 0;
182}
183
184static noinline int icplb_miss(void)
185{
186 unsigned long addr = bfin_read_ICPLB_FAULT_ADDR();
187 int status = bfin_read_ICPLB_STATUS();
188 int idx;
189 unsigned long i_data;
190
191 nr_icplb_miss++;
192 if (status & FAULT_USERSUPV)
193 nr_icplb_supv_miss++;
194
195 if (addr >= _ramend)
196 return CPLB_PROT_VIOL;
197
198 /*
199 * First, try to find a CPLB that matches this address. If we
200 * find one, then the fact that we're in the miss handler means
201 * that the instruction crosses a page boundary.
202 */
203 for (idx = first_switched_icplb; idx < MAX_CPLBS; idx++) {
204 if (icplb_tbl[idx].data & CPLB_VALID) {
205 unsigned long this_addr = icplb_tbl[idx].addr;
206 if (this_addr <= addr && this_addr + PAGE_SIZE > addr) {
207 addr += PAGE_SIZE;
208 break;
209 }
210 }
211 }
212
213 i_data = CPLB_VALID | CPLB_PORTPRIO | PAGE_SIZE_4KB;
214#ifdef CONFIG_BFIN_ICACHE
215 i_data |= CPLB_L1_CHBL | ANOMALY_05000158_WORKAROUND;
216#endif
217
218 /*
219 * Two cases to distinguish - a supervisor access must necessarily
220 * be for a module page; we grant it unconditionally (could do better
221 * here in the future). Otherwise, check the x bitmap of the current
222 * process.
223 */
224 if (!(status & FAULT_USERSUPV)) {
225 unsigned long *mask = current_rwx_mask;
226
227 if (mask) {
228 int page = addr >> PAGE_SHIFT;
229 int offs = page >> 5;
230 int bit = 1 << (page & 31);
231
232 mask += 2 * page_mask_nelts;
233 if (mask[offs] & bit)
234 i_data |= CPLB_USER_RD;
235 }
236 }
237
238 idx = evict_one_icplb();
239 addr &= PAGE_MASK;
240 icplb_tbl[idx].addr = addr;
241 icplb_tbl[idx].data = i_data;
242
243 disable_icplb();
244 bfin_write32(ICPLB_DATA0 + idx * 4, i_data);
245 bfin_write32(ICPLB_ADDR0 + idx * 4, addr);
246 enable_icplb();
247
248 return 0;
249}
250
251static noinline int dcplb_protection_fault(void)
252{
253 unsigned long addr = bfin_read_DCPLB_FAULT_ADDR();
254 int status = bfin_read_DCPLB_STATUS();
255
256 nr_dcplb_prot++;
257
258 if (status & FAULT_RW) {
259 int idx = faulting_cplb_index(status);
260 unsigned long data = dcplb_tbl[idx].data;
261 if (!(data & CPLB_WT) && !(data & CPLB_DIRTY) &&
262 write_permitted(status, data)) {
263 data |= CPLB_DIRTY;
264 dcplb_tbl[idx].data = data;
265 bfin_write32(DCPLB_DATA0 + idx * 4, data);
266 return 0;
267 }
268 }
269 return CPLB_PROT_VIOL;
270}
271
272int cplb_hdr(int seqstat, struct pt_regs *regs)
273{
274 int cause = seqstat & 0x3f;
275 switch (cause) {
276 case 0x23:
277 return dcplb_protection_fault();
278 case 0x2C:
279 return icplb_miss();
280 case 0x26:
281 return dcplb_miss();
282 default:
283 return 1;
284 panic_cplb_error(seqstat, regs);
285 }
286}
287
288void flush_switched_cplbs(void)
289{
290 int i;
291
292 nr_cplb_flush++;
293
294 disable_icplb();
295 for (i = first_switched_icplb; i < MAX_CPLBS; i++) {
296 icplb_tbl[i].data = 0;
297 bfin_write32(ICPLB_DATA0 + i * 4, 0);
298 }
299 enable_icplb();
300
301 disable_dcplb();
302 for (i = first_mask_dcplb; i < MAX_CPLBS; i++) {
303 dcplb_tbl[i].data = 0;
304 bfin_write32(DCPLB_DATA0 + i * 4, 0);
305 }
306 enable_dcplb();
307}
308
309void set_mask_dcplbs(unsigned long *masks)
310{
311 int i;
312 unsigned long addr = (unsigned long)masks;
313 unsigned long d_data;
314 current_rwx_mask = masks;
315
316 if (!masks)
317 return;
318
319 d_data = CPLB_SUPV_WR | CPLB_VALID | CPLB_DIRTY | PAGE_SIZE_4KB;
320#ifdef CONFIG_BFIN_DCACHE
321 d_data |= CPLB_L1_CHBL;
322#ifdef CONFIG_BLKFIN_WT
323 d_data |= CPLB_L1_AOW | CPLB_WT;
324#endif
325#endif
326
327 disable_dcplb();
328 for (i = first_mask_dcplb; i < first_switched_dcplb; i++) {
329 dcplb_tbl[i].addr = addr;
330 dcplb_tbl[i].data = d_data;
331 bfin_write32(DCPLB_DATA0 + i * 4, d_data);
332 bfin_write32(DCPLB_ADDR0 + i * 4, addr);
333 addr += PAGE_SIZE;
334 }
335 enable_dcplb();
336}
337
338#endif
diff --git a/arch/blackfin/kernel/cplb-nompu/Makefile b/arch/blackfin/kernel/cplb-nompu/Makefile
new file mode 100644
index 000000000000..d36ea9b5382e
--- /dev/null
+++ b/arch/blackfin/kernel/cplb-nompu/Makefile
@@ -0,0 +1,8 @@
1#
2# arch/blackfin/kernel/cplb-nompu/Makefile
3#
4
5obj-y := cplbinit.o cacheinit.o cplbhdlr.o cplbmgr.o
6
7obj-$(CONFIG_CPLB_INFO) += cplbinfo.o
8
diff --git a/arch/blackfin/kernel/cacheinit.c b/arch/blackfin/kernel/cplb-nompu/cacheinit.c
index 62cbba7364b0..8a18399f6072 100644
--- a/arch/blackfin/kernel/cacheinit.c
+++ b/arch/blackfin/kernel/cplb-nompu/cacheinit.c
@@ -42,6 +42,7 @@ void bfin_icache_init(void)
42 ctrl = bfin_read_IMEM_CONTROL(); 42 ctrl = bfin_read_IMEM_CONTROL();
43 ctrl |= IMC | ENICPLB; 43 ctrl |= IMC | ENICPLB;
44 bfin_write_IMEM_CONTROL(ctrl); 44 bfin_write_IMEM_CONTROL(ctrl);
45 SSYNC();
45} 46}
46#endif 47#endif
47 48
@@ -63,5 +64,6 @@ void bfin_dcache_init(void)
63 ctrl = bfin_read_DMEM_CONTROL(); 64 ctrl = bfin_read_DMEM_CONTROL();
64 ctrl |= DMEM_CNTR; 65 ctrl |= DMEM_CNTR;
65 bfin_write_DMEM_CONTROL(ctrl); 66 bfin_write_DMEM_CONTROL(ctrl);
67 SSYNC();
66} 68}
67#endif 69#endif
diff --git a/arch/blackfin/mach-common/cplbhdlr.S b/arch/blackfin/kernel/cplb-nompu/cplbhdlr.S
index 2788532de72b..2788532de72b 100644
--- a/arch/blackfin/mach-common/cplbhdlr.S
+++ b/arch/blackfin/kernel/cplb-nompu/cplbhdlr.S
diff --git a/arch/blackfin/mach-common/cplbinfo.c b/arch/blackfin/kernel/cplb-nompu/cplbinfo.c
index a4f0b428a34d..a4f0b428a34d 100644
--- a/arch/blackfin/mach-common/cplbinfo.c
+++ b/arch/blackfin/kernel/cplb-nompu/cplbinfo.c
diff --git a/arch/blackfin/kernel/cplbinit.c b/arch/blackfin/kernel/cplb-nompu/cplbinit.c
index 6320bc45fbba..6320bc45fbba 100644
--- a/arch/blackfin/kernel/cplbinit.c
+++ b/arch/blackfin/kernel/cplb-nompu/cplbinit.c
diff --git a/arch/blackfin/mach-common/cplbmgr.S b/arch/blackfin/kernel/cplb-nompu/cplbmgr.S
index 6f909cbfac7b..f5cf3accef37 100644
--- a/arch/blackfin/mach-common/cplbmgr.S
+++ b/arch/blackfin/kernel/cplb-nompu/cplbmgr.S
@@ -75,6 +75,15 @@ ENTRY(_cplb_mgr)
75 * from the configuration table. 75 * from the configuration table.
76 */ 76 */
77 77
78 /* A multi-word instruction can cross a page boundary. This means the
79 * first part of the instruction can be in a valid page, but the
80 * second part is not, and hence generates the instruction miss.
81 * However, the fault address is for the start of the instruction,
82 * not the part that's in the bad page. Therefore, we have to check
83 * whether the fault address applies to a page that is already present
84 * in the table.
85 */
86
78 P4.L = LO(ICPLB_FAULT_ADDR); 87 P4.L = LO(ICPLB_FAULT_ADDR);
79 P4.H = HI(ICPLB_FAULT_ADDR); 88 P4.H = HI(ICPLB_FAULT_ADDR);
80 89
@@ -87,7 +96,7 @@ ENTRY(_cplb_mgr)
87 R4 = [P4]; /* Get faulting address*/ 96 R4 = [P4]; /* Get faulting address*/
88 R6 = 64; /* Advance past the fault address, which*/ 97 R6 = 64; /* Advance past the fault address, which*/
89 R6 = R6 + R4; /* we'll use if we find a match*/ 98 R6 = R6 + R4; /* we'll use if we find a match*/
90 R3 = ((16 << 8) | 2); /* Extract mask, bits 16 and 17.*/ 99 R3 = ((16 << 8) | 2); /* Extract mask, two bits at posn 16 */
91 100
92 R5 = 0; 101 R5 = 0;
93.Lisearch: 102.Lisearch:
@@ -125,7 +134,9 @@ ENTRY(_cplb_mgr)
125 P4.L = LO(IMEM_CONTROL); 134 P4.L = LO(IMEM_CONTROL);
126 P4.H = HI(IMEM_CONTROL); 135 P4.H = HI(IMEM_CONTROL);
127 136
128 /* disable cplbs */ 137 /* Turn off CPLBs while we work, necessary according to HRM before
138 * modifying CPLB descriptors
139 */
129 R5 = [P4]; /* Control Register*/ 140 R5 = [P4]; /* Control Register*/
130 BITCLR(R5,ENICPLB_P); 141 BITCLR(R5,ENICPLB_P);
131 CLI R1; 142 CLI R1;
@@ -179,7 +190,14 @@ ENTRY(_cplb_mgr)
179 [P0 - 4] = R0; 190 [P0 - 4] = R0;
180 R0 = [P0 - 0x100]; 191 R0 = [P0 - 0x100];
181 [P0-0x104] = R0; 192 [P0-0x104] = R0;
182.Lie_move:P0+=4; 193.Lie_move:
194 P0+=4;
195
196 /* Clear ICPLB_DATA15, in case we don't find a replacement
197 * otherwise, we would have a duplicate entry, and will crash
198 */
199 R0 = 0;
200 [P0 - 4] = R0;
183 201
184 /* We've made space in the ICPLB table, so that ICPLB15 202 /* We've made space in the ICPLB table, so that ICPLB15
185 * is now free to be overwritten. Next, we have to determine 203 * is now free to be overwritten. Next, we have to determine
@@ -504,14 +522,23 @@ ENTRY(_cplb_mgr)
504 R0 = [P0++]; /* move data */ 522 R0 = [P0++]; /* move data */
505 [P0 - 8] = R0; 523 [P0 - 8] = R0;
506 R0 = [P0-0x104] /* move address */ 524 R0 = [P0-0x104] /* move address */
507.Lde_move: [P0-0x108] = R0; 525.Lde_move:
526 [P0-0x108] = R0;
527
528.Lde_moved:
529 NOP;
530
531 /* Clear DCPLB_DATA15, in case we don't find a replacement
532 * otherwise, we would have a duplicate entry, and will crash
533 */
534 R0 = 0;
535 [P0 - 0x4] = R0;
508 536
509 /* We've now made space in DCPLB15 for the new CPLB to be 537 /* We've now made space in DCPLB15 for the new CPLB to be
510 * installed. The next stage is to locate a CPLB in the 538 * installed. The next stage is to locate a CPLB in the
511 * config table that covers the faulting address. 539 * config table that covers the faulting address.
512 */ 540 */
513 541
514.Lde_moved:NOP;
515 R0 = I0; /* Our faulting address */ 542 R0 = I0; /* Our faulting address */
516 543
517 P2.L = _dpdt_table; 544 P2.L = _dpdt_table;
diff --git a/arch/blackfin/kernel/early_printk.c b/arch/blackfin/kernel/early_printk.c
index 724f4a5a1d46..60f67f90fe35 100644
--- a/arch/blackfin/kernel/early_printk.c
+++ b/arch/blackfin/kernel/early_printk.c
@@ -187,7 +187,7 @@ asmlinkage void __init init_early_exception_vectors(void)
187 bfin_write_EVT15(early_trap); 187 bfin_write_EVT15(early_trap);
188 CSYNC(); 188 CSYNC();
189 189
190 /* Set all the return from interupt, exception, NMI to a known place 190 /* Set all the return from interrupt, exception, NMI to a known place
191 * so if we do a RETI, RETX or RETN by mistake - we go somewhere known 191 * so if we do a RETI, RETX or RETN by mistake - we go somewhere known
192 * Note - don't change RETS - we are in a subroutine, or 192 * Note - don't change RETS - we are in a subroutine, or
193 * RETE - since it might screw up if emulator is attached 193 * RETE - since it might screw up if emulator is attached
@@ -205,7 +205,7 @@ asmlinkage void __init early_trap_c(struct pt_regs *fp, void *retaddr)
205 if (likely(early_console == NULL)) 205 if (likely(early_console == NULL))
206 setup_early_printk(DEFAULT_EARLY_PORT); 206 setup_early_printk(DEFAULT_EARLY_PORT);
207 207
208 dump_bfin_mem((void *)fp->retx); 208 dump_bfin_mem(fp);
209 show_regs(fp); 209 show_regs(fp);
210 dump_bfin_trace_buffer(); 210 dump_bfin_trace_buffer();
211 211
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c
index 5bf15125f0d6..023dc80af187 100644
--- a/arch/blackfin/kernel/process.c
+++ b/arch/blackfin/kernel/process.c
@@ -39,9 +39,6 @@
39#include <asm/blackfin.h> 39#include <asm/blackfin.h>
40#include <asm/fixed_code.h> 40#include <asm/fixed_code.h>
41 41
42#define LED_ON 0
43#define LED_OFF 1
44
45asmlinkage void ret_from_fork(void); 42asmlinkage void ret_from_fork(void);
46 43
47/* Points to the SDRAM backup memory for the stack that is currently in 44/* Points to the SDRAM backup memory for the stack that is currently in
@@ -70,32 +67,6 @@ void (*pm_power_off)(void) = NULL;
70EXPORT_SYMBOL(pm_power_off); 67EXPORT_SYMBOL(pm_power_off);
71 68
72/* 69/*
73 * We are using a different LED from the one used to indicate timer interrupt.
74 */
75#if defined(CONFIG_BFIN_IDLE_LED)
76static inline void leds_switch(int flag)
77{
78 unsigned short tmp = 0;
79
80 tmp = bfin_read_CONFIG_BFIN_IDLE_LED_PORT();
81 SSYNC();
82
83 if (flag == LED_ON)
84 tmp &= ~CONFIG_BFIN_IDLE_LED_PIN; /* light on */
85 else
86 tmp |= CONFIG_BFIN_IDLE_LED_PIN; /* light off */
87
88 bfin_write_CONFIG_BFIN_IDLE_LED_PORT(tmp);
89 SSYNC();
90
91}
92#else
93static inline void leds_switch(int flag)
94{
95}
96#endif
97
98/*
99 * The idle loop on BFIN 70 * The idle loop on BFIN
100 */ 71 */
101#ifdef CONFIG_IDLE_L1 72#ifdef CONFIG_IDLE_L1
@@ -106,12 +77,10 @@ void cpu_idle(void)__attribute__((l1_text));
106void default_idle(void) 77void default_idle(void)
107{ 78{
108 while (!need_resched()) { 79 while (!need_resched()) {
109 leds_switch(LED_OFF);
110 local_irq_disable(); 80 local_irq_disable();
111 if (likely(!need_resched())) 81 if (likely(!need_resched()))
112 idle_with_irq_disabled(); 82 idle_with_irq_disabled();
113 local_irq_enable(); 83 local_irq_enable();
114 leds_switch(LED_ON);
115 } 84 }
116} 85}
117 86
@@ -327,6 +296,7 @@ void finish_atomic_sections (struct pt_regs *regs)
327} 296}
328 297
329#if defined(CONFIG_ACCESS_CHECK) 298#if defined(CONFIG_ACCESS_CHECK)
299/* Return 1 if access to memory range is OK, 0 otherwise */
330int _access_ok(unsigned long addr, unsigned long size) 300int _access_ok(unsigned long addr, unsigned long size)
331{ 301{
332 if (size == 0) 302 if (size == 0)
diff --git a/arch/blackfin/kernel/reboot.c b/arch/blackfin/kernel/reboot.c
index ae28aac6fec1..483f93dfc1b5 100644
--- a/arch/blackfin/kernel/reboot.c
+++ b/arch/blackfin/kernel/reboot.c
@@ -19,6 +19,11 @@
19#define SYSCR_VAL 0x10 19#define SYSCR_VAL 0x10
20#endif 20#endif
21 21
22/*
23 * Delay min 5 SCLK cycles using worst case CCLK/SCLK ratio (15)
24 */
25#define SWRST_DELAY (5 * 15)
26
22/* A system soft reset makes external memory unusable 27/* A system soft reset makes external memory unusable
23 * so force this function into L1. 28 * so force this function into L1.
24 */ 29 */
@@ -34,7 +39,13 @@ void bfin_reset(void)
34 while (1) { 39 while (1) {
35 /* initiate system soft reset with magic 0x7 */ 40 /* initiate system soft reset with magic 0x7 */
36 bfin_write_SWRST(0x7); 41 bfin_write_SWRST(0x7);
37 asm("ssync;"); 42
43 /* Wait for System reset to actually reset, needs to be 5 SCLKs, */
44 /* Assume CCLK / SCLK ratio is worst case (15), and use 5*15 */
45
46 asm("LSETUP(.Lfoo,.Lfoo) LC0 = %0\n .Lfoo: NOP;\n"
47 : : "a" (SWRST_DELAY) : "LC0", "LT0", "LB0");
48
38 /* clear system soft reset */ 49 /* clear system soft reset */
39 bfin_write_SWRST(0); 50 bfin_write_SWRST(0);
40 asm("ssync;"); 51 asm("ssync;");
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c
index d2822010b7ce..462cae893757 100644
--- a/arch/blackfin/kernel/setup.c
+++ b/arch/blackfin/kernel/setup.c
@@ -238,7 +238,13 @@ void __init setup_arch(char **cmdline_p)
238 memory_end = _ramend - DMA_UNCACHED_REGION; 238 memory_end = _ramend - DMA_UNCACHED_REGION;
239 239
240 _ramstart = (unsigned long)__bss_stop; 240 _ramstart = (unsigned long)__bss_stop;
241 _rambase = (unsigned long)_stext;
242#ifdef CONFIG_MPU
243 /* Round up to multiple of 4MB. */
244 memory_start = (_ramstart + 0x3fffff) & ~0x3fffff;
245#else
241 memory_start = PAGE_ALIGN(_ramstart); 246 memory_start = PAGE_ALIGN(_ramstart);
247#endif
242 248
243#if defined(CONFIG_MTD_UCLINUX) 249#if defined(CONFIG_MTD_UCLINUX)
244 /* generic memory mapped MTD driver */ 250 /* generic memory mapped MTD driver */
@@ -307,6 +313,11 @@ void __init setup_arch(char **cmdline_p)
307 printk(KERN_NOTICE "Warning: limiting memory to %liMB due to hardware anomaly 05000263\n", memory_end >> 20); 313 printk(KERN_NOTICE "Warning: limiting memory to %liMB due to hardware anomaly 05000263\n", memory_end >> 20);
308#endif /* ANOMALY_05000263 */ 314#endif /* ANOMALY_05000263 */
309 315
316#ifdef CONFIG_MPU
317 page_mask_nelts = ((_ramend >> PAGE_SHIFT) + 31) / 32;
318 page_mask_order = get_order(3 * page_mask_nelts * sizeof(long));
319#endif
320
310#if !defined(CONFIG_MTD_UCLINUX) 321#if !defined(CONFIG_MTD_UCLINUX)
311 memory_end -= SIZE_4K; /*In case there is no valid CPLB behind memory_end make sure we don't get to close*/ 322 memory_end -= SIZE_4K; /*In case there is no valid CPLB behind memory_end make sure we don't get to close*/
312#endif 323#endif
@@ -315,8 +326,6 @@ void __init setup_arch(char **cmdline_p)
315 init_mm.end_data = (unsigned long)_edata; 326 init_mm.end_data = (unsigned long)_edata;
316 init_mm.brk = (unsigned long)0; 327 init_mm.brk = (unsigned long)0;
317 328
318 init_leds();
319
320 _bfin_swrst = bfin_read_SWRST(); 329 _bfin_swrst = bfin_read_SWRST();
321 330
322 if (_bfin_swrst & RESET_DOUBLE) 331 if (_bfin_swrst & RESET_DOUBLE)
diff --git a/arch/blackfin/kernel/time.c b/arch/blackfin/kernel/time.c
index beef057bd1dc..5bd64e341df3 100644
--- a/arch/blackfin/kernel/time.c
+++ b/arch/blackfin/kernel/time.c
@@ -42,75 +42,6 @@
42static void time_sched_init(irqreturn_t(*timer_routine) 42static void time_sched_init(irqreturn_t(*timer_routine)
43 (int, void *)); 43 (int, void *));
44static unsigned long gettimeoffset(void); 44static unsigned long gettimeoffset(void);
45static inline void do_leds(void);
46
47#if (defined(CONFIG_BFIN_ALIVE_LED) || defined(CONFIG_BFIN_IDLE_LED))
48void __init init_leds(void)
49{
50 unsigned int tmp = 0;
51
52#if defined(CONFIG_BFIN_ALIVE_LED)
53 /* config pins as output. */
54 tmp = bfin_read_CONFIG_BFIN_ALIVE_LED_DPORT();
55 SSYNC();
56 bfin_write_CONFIG_BFIN_ALIVE_LED_DPORT(tmp | CONFIG_BFIN_ALIVE_LED_PIN);
57 SSYNC();
58
59 /* First set led be off */
60 tmp = bfin_read_CONFIG_BFIN_ALIVE_LED_PORT();
61 SSYNC();
62 bfin_write_CONFIG_BFIN_ALIVE_LED_PORT(tmp | CONFIG_BFIN_ALIVE_LED_PIN); /* light off */
63 SSYNC();
64#endif
65
66#if defined(CONFIG_BFIN_IDLE_LED)
67 /* config pins as output. */
68 tmp = bfin_read_CONFIG_BFIN_IDLE_LED_DPORT();
69 SSYNC();
70 bfin_write_CONFIG_BFIN_IDLE_LED_DPORT(tmp | CONFIG_BFIN_IDLE_LED_PIN);
71 SSYNC();
72
73 /* First set led be off */
74 tmp = bfin_read_CONFIG_BFIN_IDLE_LED_PORT();
75 SSYNC();
76 bfin_write_CONFIG_BFIN_IDLE_LED_PORT(tmp | CONFIG_BFIN_IDLE_LED_PIN); /* light off */
77 SSYNC();
78#endif
79}
80#else
81void __init init_leds(void)
82{
83}
84#endif
85
86#if defined(CONFIG_BFIN_ALIVE_LED)
87static inline void do_leds(void)
88{
89 static unsigned int count = 50;
90 static int flag;
91 unsigned short tmp = 0;
92
93 if (--count == 0) {
94 count = 50;
95 flag = ~flag;
96 }
97 tmp = bfin_read_CONFIG_BFIN_ALIVE_LED_PORT();
98 SSYNC();
99
100 if (flag)
101 tmp &= ~CONFIG_BFIN_ALIVE_LED_PIN; /* light on */
102 else
103 tmp |= CONFIG_BFIN_ALIVE_LED_PIN; /* light off */
104
105 bfin_write_CONFIG_BFIN_ALIVE_LED_PORT(tmp);
106 SSYNC();
107
108}
109#else
110static inline void do_leds(void)
111{
112}
113#endif
114 45
115static struct irqaction bfin_timer_irq = { 46static struct irqaction bfin_timer_irq = {
116 .name = "BFIN Timer Tick", 47 .name = "BFIN Timer Tick",
@@ -205,7 +136,6 @@ irqreturn_t timer_interrupt(int irq, void *dummy)
205 write_seqlock(&xtime_lock); 136 write_seqlock(&xtime_lock);
206 137
207 do_timer(1); 138 do_timer(1);
208 do_leds();
209 139
210#ifndef CONFIG_SMP 140#ifndef CONFIG_SMP
211 update_process_times(user_mode(get_irq_regs())); 141 update_process_times(user_mode(get_irq_regs()));
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c
index 21a55ef19cbd..66b5f3e3ae2a 100644
--- a/arch/blackfin/kernel/traps.c
+++ b/arch/blackfin/kernel/traps.c
@@ -36,8 +36,10 @@
36#include <asm/cacheflush.h> 36#include <asm/cacheflush.h>
37#include <asm/blackfin.h> 37#include <asm/blackfin.h>
38#include <asm/irq_handler.h> 38#include <asm/irq_handler.h>
39#include <linux/irq.h>
39#include <asm/trace.h> 40#include <asm/trace.h>
40#include <asm/fixed_code.h> 41#include <asm/fixed_code.h>
42#include <asm/dma.h>
41 43
42#ifdef CONFIG_KGDB 44#ifdef CONFIG_KGDB
43# include <linux/debugger.h> 45# include <linux/debugger.h>
@@ -170,7 +172,7 @@ asmlinkage void double_fault_c(struct pt_regs *fp)
170 oops_in_progress = 1; 172 oops_in_progress = 1;
171 printk(KERN_EMERG "\n" KERN_EMERG "Double Fault\n"); 173 printk(KERN_EMERG "\n" KERN_EMERG "Double Fault\n");
172 dump_bfin_process(fp); 174 dump_bfin_process(fp);
173 dump_bfin_mem((void *)fp->retx); 175 dump_bfin_mem(fp);
174 show_regs(fp); 176 show_regs(fp);
175 panic("Double Fault - unrecoverable event\n"); 177 panic("Double Fault - unrecoverable event\n");
176 178
@@ -195,9 +197,13 @@ asmlinkage void trap_c(struct pt_regs *fp)
195 * we will kernel panic, so the system reboots. 197 * we will kernel panic, so the system reboots.
196 * If KGDB is enabled, don't set this for kernel breakpoints 198 * If KGDB is enabled, don't set this for kernel breakpoints
197 */ 199 */
198 if ((bfin_read_IPEND() & 0xFFC0) 200
201 /* TODO: check to see if we are in some sort of deferred HWERR
202 * that we should be able to recover from, not kernel panic
203 */
204 if ((bfin_read_IPEND() & 0xFFC0) && (trapnr != VEC_STEP)
199#ifdef CONFIG_KGDB 205#ifdef CONFIG_KGDB
200 && trapnr != VEC_EXCPT02 206 && (trapnr != VEC_EXCPT02)
201#endif 207#endif
202 ){ 208 ){
203 console_verbose(); 209 console_verbose();
@@ -433,6 +439,36 @@ asmlinkage void trap_c(struct pt_regs *fp)
433 /* 0x3D - Reserved, Caught by default */ 439 /* 0x3D - Reserved, Caught by default */
434 /* 0x3E - Reserved, Caught by default */ 440 /* 0x3E - Reserved, Caught by default */
435 /* 0x3F - Reserved, Caught by default */ 441 /* 0x3F - Reserved, Caught by default */
442 case VEC_HWERR:
443 info.si_code = BUS_ADRALN;
444 sig = SIGBUS;
445 switch (fp->seqstat & SEQSTAT_HWERRCAUSE) {
446 /* System MMR Error */
447 case (SEQSTAT_HWERRCAUSE_SYSTEM_MMR):
448 info.si_code = BUS_ADRALN;
449 sig = SIGBUS;
450 printk(KERN_NOTICE HWC_x2(KERN_NOTICE));
451 break;
452 /* External Memory Addressing Error */
453 case (SEQSTAT_HWERRCAUSE_EXTERN_ADDR):
454 info.si_code = BUS_ADRERR;
455 sig = SIGBUS;
456 printk(KERN_NOTICE HWC_x3(KERN_NOTICE));
457 break;
458 /* Performance Monitor Overflow */
459 case (SEQSTAT_HWERRCAUSE_PERF_FLOW):
460 printk(KERN_NOTICE HWC_x12(KERN_NOTICE));
461 break;
462 /* RAISE 5 instruction */
463 case (SEQSTAT_HWERRCAUSE_RAISE_5):
464 printk(KERN_NOTICE HWC_x18(KERN_NOTICE));
465 break;
466 default: /* Reserved */
467 printk(KERN_NOTICE HWC_default(KERN_NOTICE));
468 break;
469 }
470 CHK_DEBUGGER_TRAP();
471 break;
436 default: 472 default:
437 info.si_code = TRAP_ILLTRAP; 473 info.si_code = TRAP_ILLTRAP;
438 sig = SIGTRAP; 474 sig = SIGTRAP;
@@ -447,7 +483,7 @@ asmlinkage void trap_c(struct pt_regs *fp)
447 if (sig != SIGTRAP) { 483 if (sig != SIGTRAP) {
448 unsigned long stack; 484 unsigned long stack;
449 dump_bfin_process(fp); 485 dump_bfin_process(fp);
450 dump_bfin_mem((void *)fp->retx); 486 dump_bfin_mem(fp);
451 show_regs(fp); 487 show_regs(fp);
452 488
453 /* Print out the trace buffer if it makes sense */ 489 /* Print out the trace buffer if it makes sense */
@@ -461,6 +497,7 @@ asmlinkage void trap_c(struct pt_regs *fp)
461 dump_bfin_trace_buffer(); 497 dump_bfin_trace_buffer();
462 show_stack(current, &stack); 498 show_stack(current, &stack);
463 if (oops_in_progress) { 499 if (oops_in_progress) {
500 print_modules();
464#ifndef CONFIG_ACCESS_CHECK 501#ifndef CONFIG_ACCESS_CHECK
465 printk(KERN_EMERG "Please turn on " 502 printk(KERN_EMERG "Please turn on "
466 "CONFIG_ACCESS_CHECK\n"); 503 "CONFIG_ACCESS_CHECK\n");
@@ -474,13 +511,6 @@ asmlinkage void trap_c(struct pt_regs *fp)
474 info.si_addr = (void *)fp->pc; 511 info.si_addr = (void *)fp->pc;
475 force_sig_info(sig, &info, current); 512 force_sig_info(sig, &info, current);
476 513
477 /* Ensure that bad return addresses don't end up in an infinite
478 * loop, due to speculative loads/reads. This needs to be done after
479 * the signal has been sent.
480 */
481 if (trapnr == VEC_CPLB_I_M && sig != SIGTRAP)
482 fp->pc = SAFE_USER_INSTRUCTION;
483
484 trace_buffer_restore(j); 514 trace_buffer_restore(j);
485 return; 515 return;
486} 516}
@@ -616,8 +646,10 @@ void dump_bfin_process(struct pt_regs *fp)
616 if (oops_in_progress) 646 if (oops_in_progress)
617 printk(KERN_EMERG "Kernel OOPS in progress\n"); 647 printk(KERN_EMERG "Kernel OOPS in progress\n");
618 648
619 if (context & 0x0020) 649 if (context & 0x0020 && (fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR)
620 printk(KERN_NOTICE "Deferred excecption or HW Error context\n"); 650 printk(KERN_NOTICE "HW Error context\n");
651 else if (context & 0x0020)
652 printk(KERN_NOTICE "Defered Exception context\n");
621 else if (context & 0x3FC0) 653 else if (context & 0x3FC0)
622 printk(KERN_NOTICE "Interrupt context\n"); 654 printk(KERN_NOTICE "Interrupt context\n");
623 else if (context & 0x4000) 655 else if (context & 0x4000)
@@ -645,59 +677,124 @@ void dump_bfin_process(struct pt_regs *fp)
645 "No Valid process in current context\n"); 677 "No Valid process in current context\n");
646} 678}
647 679
648void dump_bfin_mem(void *retaddr) 680void dump_bfin_mem(struct pt_regs *fp)
649{ 681{
682 unsigned short *addr, *erraddr, val = 0, err = 0;
683 char sti = 0, buf[6];
650 684
651 if (retaddr >= (void *)FIXED_CODE_START && retaddr < (void *)physical_mem_end 685 if (unlikely((fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR))
652#if L1_CODE_LENGTH != 0 686 erraddr = (void *)fp->pc;
653 /* FIXME: Copy the code out of L1 Instruction SRAM through dma 687 else
654 memcpy. */ 688 erraddr = (void *)fp->retx;
655 && !(retaddr >= (void *)L1_CODE_START 689
656 && retaddr < (void *)(L1_CODE_START + L1_CODE_LENGTH)) 690 printk(KERN_NOTICE "return address: [0x%p]; contents of:", erraddr);
657#endif 691
658 ) { 692 for (addr = (unsigned short *)((unsigned long)erraddr & ~0xF) - 0x10;
659 int i = ((unsigned int)retaddr & 0xFFFFFFF0) - 32; 693 addr < (unsigned short *)((unsigned long)erraddr & ~0xF) + 0x10;
660 unsigned short x = 0; 694 addr++) {
661 printk(KERN_NOTICE "return address: [0x%p]; contents of:", retaddr); 695 if (!((unsigned long)addr & 0xF))
662 for (; i < ((unsigned int)retaddr & 0xFFFFFFF0) + 32; i += 2) { 696 printk("\n" KERN_NOTICE "0x%p: ", addr);
663 if (!(i & 0xF)) 697
664 printk("\n" KERN_NOTICE "0x%08x: ", i); 698 if (get_user(val, addr)) {
665 699 if (addr >= (unsigned short *)L1_CODE_START &&
666 if (get_user(x, (unsigned short *)i)) 700 addr < (unsigned short *)(L1_CODE_START + L1_CODE_LENGTH)) {
667 break; 701 dma_memcpy(&val, addr, sizeof(val));
702 sprintf(buf, "%04x", val);
703 } else if (addr >= (unsigned short *)FIXED_CODE_START &&
704 addr <= (unsigned short *)memory_start) {
705 val = bfin_read16(addr);
706 sprintf(buf, "%04x", val);
707 } else {
708 val = 0;
709 sprintf(buf, "????");
710 }
711 } else
712 sprintf(buf, "%04x", val);
713
714 if (addr == erraddr) {
715 printk("[%s]", buf);
716 err = val;
717 } else
718 printk(" %s ", buf);
719
720 /* Do any previous instructions turn on interrupts? */
721 if (addr <= erraddr && /* in the past */
722 ((val >= 0x0040 && val <= 0x0047) || /* STI instruction */
723 val == 0x017b)) /* [SP++] = RETI */
724 sti = 1;
725 }
726
727 printk("\n");
728
729 /* Hardware error interrupts can be deferred */
730 if (unlikely(sti && (fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR &&
731 oops_in_progress)){
732 printk(KERN_NOTICE "Looks like this was a deferred error - sorry\n");
668#ifndef CONFIG_DEBUG_HWERR 733#ifndef CONFIG_DEBUG_HWERR
669 /* If one of the last few instructions was a STI 734 printk(KERN_NOTICE "The remaining message may be meaningless\n"
670 * it is likely that the error occured awhile ago 735 KERN_NOTICE "You should enable CONFIG_DEBUG_HWERR to get a"
671 * and we just noticed. This only happens in kernel 736 " better idea where it came from\n");
672 * context, which should mean an oops is happening 737#else
673 */ 738 /* If we are handling only one peripheral interrupt
674 if (oops_in_progress && x >= 0x0040 && x <= 0x0047 && i <= 0) 739 * and current mm and pid are valid, and the last error
675 panic("\n\nWARNING : You should reconfigure" 740 * was in that user space process's text area
676 " the kernel to turn on\n" 741 * print it out - because that is where the problem exists
677 " 'Hardware error interrupt" 742 */
678 " debugging'\n" 743 if ((!(((fp)->ipend & ~0x30) & (((fp)->ipend & ~0x30) - 1))) &&
679 " The rest of this error" 744 (current->pid && current->mm)) {
680 " is meanless\n"); 745 /* And the last RETI points to the current userspace context */
681#endif 746 if ((fp + 1)->pc >= current->mm->start_code &&
682 if (i == (unsigned int)retaddr) 747 (fp + 1)->pc <= current->mm->end_code) {
683 printk("[%04x]", x); 748 printk(KERN_NOTICE "It might be better to look around here : \n");
684 else 749 printk(KERN_NOTICE "-------------------------------------------\n");
685 printk(" %04x ", x); 750 show_regs(fp + 1);
751 printk(KERN_NOTICE "-------------------------------------------\n");
752 }
686 } 753 }
687 printk("\n"); 754#endif
688 } else 755 }
689 printk("\n" KERN_NOTICE
690 "Cannot look at the [PC] <%p> for it is"
691 " in unreadable memory - sorry\n", retaddr);
692} 756}
693 757
694void show_regs(struct pt_regs *fp) 758void show_regs(struct pt_regs *fp)
695{ 759{
696 char buf [150]; 760 char buf [150];
761 struct irqaction *action;
762 unsigned int i;
763 unsigned long flags;
697 764
698 printk(KERN_NOTICE "\n" KERN_NOTICE "SEQUENCER STATUS:\n"); 765 printk(KERN_NOTICE "\n" KERN_NOTICE "SEQUENCER STATUS:\t\t%s\n", print_tainted());
699 printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx SYSCFG: %04lx\n", 766 printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx SYSCFG: %04lx\n",
700 (long)fp->seqstat, fp->ipend, fp->syscfg); 767 (long)fp->seqstat, fp->ipend, fp->syscfg);
768 printk(KERN_NOTICE " HWERRCAUSE: 0x%lx\n",
769 (fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14);
770 printk(KERN_NOTICE " EXCAUSE : 0x%lx\n",
771 fp->seqstat & SEQSTAT_EXCAUSE);
772 for (i = 6; i <= 15 ; i++) {
773 if (fp->ipend & (1 << i)) {
774 decode_address(buf, bfin_read32(EVT0 + 4*i));
775 printk(KERN_NOTICE " physical IVG%i asserted : %s\n", i, buf);
776 }
777 }
778
779 /* if no interrupts are going off, don't print this out */
780 if (fp->ipend & ~0x3F) {
781 for (i = 0; i < (NR_IRQS - 1); i++) {
782 spin_lock_irqsave(&irq_desc[i].lock, flags);
783 action = irq_desc[i].action;
784 if (!action)
785 goto unlock;
786
787 decode_address(buf, (unsigned int)action->handler);
788 printk(KERN_NOTICE " logical irq %3d mapped : %s", i, buf);
789 for (action = action->next; action; action = action->next) {
790 decode_address(buf, (unsigned int)action->handler);
791 printk(", %s", buf);
792 }
793 printk("\n");
794unlock:
795 spin_unlock_irqrestore(&irq_desc[i].lock, flags);
796 }
797 }
701 798
702 decode_address(buf, fp->rete); 799 decode_address(buf, fp->rete);
703 printk(KERN_NOTICE " RETE: %s\n", buf); 800 printk(KERN_NOTICE " RETE: %s\n", buf);
@@ -708,9 +805,10 @@ void show_regs(struct pt_regs *fp)
708 decode_address(buf, fp->rets); 805 decode_address(buf, fp->rets);
709 printk(KERN_NOTICE " RETS: %s\n", buf); 806 printk(KERN_NOTICE " RETS: %s\n", buf);
710 decode_address(buf, fp->pc); 807 decode_address(buf, fp->pc);
711 printk(KERN_NOTICE " PC: %s\n", buf); 808 printk(KERN_NOTICE " PC : %s\n", buf);
712 809
713 if ((long)fp->seqstat & SEQSTAT_EXCAUSE) { 810 if (((long)fp->seqstat & SEQSTAT_EXCAUSE) &&
811 (((long)fp->seqstat & SEQSTAT_EXCAUSE) != VEC_HWERR)) {
714 decode_address(buf, bfin_read_DCPLB_FAULT_ADDR()); 812 decode_address(buf, bfin_read_DCPLB_FAULT_ADDR());
715 printk(KERN_NOTICE "DCPLB_FAULT_ADDR: %s\n", buf); 813 printk(KERN_NOTICE "DCPLB_FAULT_ADDR: %s\n", buf);
716 decode_address(buf, bfin_read_ICPLB_FAULT_ADDR()); 814 decode_address(buf, bfin_read_ICPLB_FAULT_ADDR());
@@ -824,7 +922,7 @@ void panic_cplb_error(int cplb_panic, struct pt_regs *fp)
824 printk(KERN_EMERG "DCPLB_FAULT_ADDR=%p\n", (void *)bfin_read_DCPLB_FAULT_ADDR()); 922 printk(KERN_EMERG "DCPLB_FAULT_ADDR=%p\n", (void *)bfin_read_DCPLB_FAULT_ADDR());
825 printk(KERN_EMERG "ICPLB_FAULT_ADDR=%p\n", (void *)bfin_read_ICPLB_FAULT_ADDR()); 923 printk(KERN_EMERG "ICPLB_FAULT_ADDR=%p\n", (void *)bfin_read_ICPLB_FAULT_ADDR());
826 dump_bfin_process(fp); 924 dump_bfin_process(fp);
827 dump_bfin_mem((void *)fp->retx); 925 dump_bfin_mem(fp);
828 show_regs(fp); 926 show_regs(fp);
829 dump_stack(); 927 dump_stack();
830 panic("Unrecoverable event\n"); 928 panic("Unrecoverable event\n");
diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S
index 9b75bc83c71f..858722421b40 100644
--- a/arch/blackfin/kernel/vmlinux.lds.S
+++ b/arch/blackfin/kernel/vmlinux.lds.S
@@ -91,13 +91,13 @@ SECTIONS
91 { 91 {
92 . = ALIGN(PAGE_SIZE); 92 . = ALIGN(PAGE_SIZE);
93 __sinittext = .; 93 __sinittext = .;
94 *(.init.text) 94 INIT_TEXT
95 __einittext = .; 95 __einittext = .;
96 } 96 }
97 .init.data : 97 .init.data :
98 { 98 {
99 . = ALIGN(16); 99 . = ALIGN(16);
100 *(.init.data) 100 INIT_DATA
101 } 101 }
102 .init.setup : 102 .init.setup :
103 { 103 {
@@ -198,8 +198,8 @@ SECTIONS
198 198
199 /DISCARD/ : 199 /DISCARD/ :
200 { 200 {
201 *(.exit.text) 201 EXIT_TEXT
202 *(.exit.data) 202 EXIT_DATA
203 *(.exitcall.exit) 203 *(.exitcall.exit)
204 } 204 }
205} 205}
diff --git a/arch/blackfin/lib/memcpy.S b/arch/blackfin/lib/memcpy.S
index 2e6336492b4b..e654a18a0754 100644
--- a/arch/blackfin/lib/memcpy.S
+++ b/arch/blackfin/lib/memcpy.S
@@ -70,8 +70,8 @@ ENTRY(_memcpy)
70 /* Check for aligned data.*/ 70 /* Check for aligned data.*/
71 71
72 R3 = R1 | R0; 72 R3 = R1 | R0;
73 R0 = 0x3; 73 R1 = 0x3;
74 R3 = R3 & R0; 74 R3 = R3 & R1;
75 CC = R3; /* low bits set on either address? */ 75 CC = R3; /* low bits set on either address? */
76 IF CC JUMP .Lnot_aligned; 76 IF CC JUMP .Lnot_aligned;
77 77
@@ -83,7 +83,6 @@ ENTRY(_memcpy)
83 /* less than eight bytes... */ 83 /* less than eight bytes... */
84 P2 = R2; 84 P2 = R2;
85 LSETUP(.Lthree_start, .Lthree_end) LC0=P2; 85 LSETUP(.Lthree_start, .Lthree_end) LC0=P2;
86 R0 = R1; /* setup src address for return */
87.Lthree_start: 86.Lthree_start:
88 R3 = B[P1++] (X); 87 R3 = B[P1++] (X);
89.Lthree_end: 88.Lthree_end:
@@ -95,7 +94,6 @@ ENTRY(_memcpy)
95 /* There's at least eight bytes to copy. */ 94 /* There's at least eight bytes to copy. */
96 P2 += -1; /* because we unroll one iteration */ 95 P2 += -1; /* because we unroll one iteration */
97 LSETUP(.Lword_loops, .Lword_loope) LC0=P2; 96 LSETUP(.Lword_loops, .Lword_loope) LC0=P2;
98 R0 = R1;
99 I1 = P1; 97 I1 = P1;
100 R3 = [I1++]; 98 R3 = [I1++];
101#if ANOMALY_05000202 99#if ANOMALY_05000202
@@ -120,7 +118,6 @@ ENTRY(_memcpy)
120.Lnot_aligned: 118.Lnot_aligned:
121 /* From here, we're copying byte-by-byte. */ 119 /* From here, we're copying byte-by-byte. */
122 LSETUP (.Lbyte_start, .Lbyte_end) LC0=P2; 120 LSETUP (.Lbyte_start, .Lbyte_end) LC0=P2;
123 R0 = R1; /* Save src address for return */
124.Lbyte_start: 121.Lbyte_start:
125 R1 = B[P1++] (X); 122 R1 = B[P1++] (X);
126.Lbyte_end: 123.Lbyte_end:
@@ -135,7 +132,6 @@ ENTRY(_memcpy)
135 * Don't bother to work out alignment for 132 * Don't bother to work out alignment for
136 * the reverse case. 133 * the reverse case.
137 */ 134 */
138 R0 = R1; /* save src for later. */
139 P0 = P0 + P2; 135 P0 = P0 + P2;
140 P0 += -1; 136 P0 += -1;
141 P1 = P1 + P2; 137 P1 = P1 + P2;
diff --git a/arch/blackfin/mach-bf527/Kconfig b/arch/blackfin/mach-bf527/Kconfig
index 5c736837d4bf..3cde4beeb214 100644
--- a/arch/blackfin/mach-bf527/Kconfig
+++ b/arch/blackfin/mach-bf527/Kconfig
@@ -43,7 +43,7 @@ endchoice
43 43
44choice 44choice
45 prompt "UART1" 45 prompt "UART1"
46 default BF527_UART1_PORTG 46 default BF527_UART1_PORTF
47 help 47 help
48 Select PORT used for UART1. See Hardware Reference Manual 48 Select PORT used for UART1. See Hardware Reference Manual
49 49
diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c
index 003e2ac654d8..f8c411a24af7 100644
--- a/arch/blackfin/mach-bf527/boards/ezkit.c
+++ b/arch/blackfin/mach-bf527/boards/ezkit.c
@@ -8,7 +8,7 @@
8 * 8 *
9 * Modified: 9 * Modified:
10 * Copyright 2005 National ICT Australia (NICTA) 10 * Copyright 2005 National ICT Australia (NICTA)
11 * Copyright 2004-2007 Analog Devices Inc. 11 * Copyright 2004-2008 Analog Devices Inc.
12 * 12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/ 13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 * 14 *
@@ -41,6 +41,7 @@
41#include <linux/irq.h> 41#include <linux/irq.h>
42#include <linux/interrupt.h> 42#include <linux/interrupt.h>
43#include <linux/usb/sl811.h> 43#include <linux/usb/sl811.h>
44#include <linux/usb/musb.h>
44#include <asm/cplb.h> 45#include <asm/cplb.h>
45#include <asm/dma.h> 46#include <asm/dma.h>
46#include <asm/bfin5xx_spi.h> 47#include <asm/bfin5xx_spi.h>
@@ -105,6 +106,69 @@ void __exit bfin_isp1761_exit(void)
105arch_initcall(bfin_isp1761_init); 106arch_initcall(bfin_isp1761_init);
106#endif 107#endif
107 108
109#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE)
110static struct resource musb_resources[] = {
111 [0] = {
112 .start = 0xffc03800,
113 .end = 0xffc03cff,
114 .flags = IORESOURCE_MEM,
115 },
116 [1] = { /* general IRQ */
117 .start = IRQ_USB_INT0,
118 .end = IRQ_USB_INT0,
119 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
120 },
121 [2] = { /* DMA IRQ */
122 .start = IRQ_USB_DMA,
123 .end = IRQ_USB_DMA,
124 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
125 },
126};
127
128static struct musb_hdrc_platform_data musb_plat = {
129#if defined(CONFIG_USB_MUSB_OTG)
130 .mode = MUSB_OTG,
131#elif defined(CONFIG_USB_MUSB_HDRC_HCD)
132 .mode = MUSB_HOST,
133#elif defined(CONFIG_USB_GADGET_MUSB_HDRC)
134 .mode = MUSB_PERIPHERAL,
135#endif
136 .multipoint = 0,
137};
138
139static u64 musb_dmamask = ~(u32)0;
140
141static struct platform_device musb_device = {
142 .name = "musb_hdrc",
143 .id = 0,
144 .dev = {
145 .dma_mask = &musb_dmamask,
146 .coherent_dma_mask = 0xffffffff,
147 .platform_data = &musb_plat,
148 },
149 .num_resources = ARRAY_SIZE(musb_resources),
150 .resource = musb_resources,
151};
152#endif
153
154#if defined(CONFIG_FB_BFIN_T350MCQB) || defined(CONFIG_FB_BFIN_T350MCQB_MODULE)
155
156static struct resource bf52x_t350mcqb_resources[] = {
157 {
158 .start = IRQ_PPI_ERROR,
159 .end = IRQ_PPI_ERROR,
160 .flags = IORESOURCE_IRQ,
161 },
162};
163
164static struct platform_device bf52x_t350mcqb_device = {
165 .name = "bfin-t350mcqb",
166 .id = -1,
167 .num_resources = ARRAY_SIZE(bf52x_t350mcqb_resources),
168 .resource = bf52x_t350mcqb_resources,
169};
170#endif
171
108#if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE) 172#if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE)
109static struct mtd_partition partition_info[] = { 173static struct mtd_partition partition_info[] = {
110 { 174 {
@@ -253,12 +317,7 @@ static struct resource sl811_hcd_resources[] = {
253void sl811_port_power(struct device *dev, int is_on) 317void sl811_port_power(struct device *dev, int is_on)
254{ 318{
255 gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS"); 319 gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS");
256 gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS); 320 gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS, is_on);
257
258 if (is_on)
259 gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 1);
260 else
261 gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 0);
262} 321}
263#endif 322#endif
264 323
@@ -718,6 +777,28 @@ static struct platform_device bfin_pata_device = {
718}; 777};
719#endif 778#endif
720 779
780#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
781#include <linux/input.h>
782#include <linux/gpio_keys.h>
783
784static struct gpio_keys_button bfin_gpio_keys_table[] = {
785 {BTN_0, GPIO_PG0, 1, "gpio-keys: BTN0"},
786 {BTN_1, GPIO_PG13, 1, "gpio-keys: BTN1"},
787};
788
789static struct gpio_keys_platform_data bfin_gpio_keys_data = {
790 .buttons = bfin_gpio_keys_table,
791 .nbuttons = ARRAY_SIZE(bfin_gpio_keys_table),
792};
793
794static struct platform_device bfin_device_gpiokeys = {
795 .name = "gpio-keys",
796 .dev = {
797 .platform_data = &bfin_gpio_keys_data,
798 },
799};
800#endif
801
721static struct platform_device *stamp_devices[] __initdata = { 802static struct platform_device *stamp_devices[] __initdata = {
722#if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE) 803#if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE)
723 &bf5xx_nand_device, 804 &bf5xx_nand_device,
@@ -739,6 +820,10 @@ static struct platform_device *stamp_devices[] __initdata = {
739 &isp1362_hcd_device, 820 &isp1362_hcd_device,
740#endif 821#endif
741 822
823#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE)
824 &musb_device,
825#endif
826
742#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) 827#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
743 &smc91x_device, 828 &smc91x_device,
744#endif 829#endif
@@ -763,6 +848,10 @@ static struct platform_device *stamp_devices[] __initdata = {
763 &bfin_fb_device, 848 &bfin_fb_device,
764#endif 849#endif
765 850
851#if defined(CONFIG_FB_BFIN_T350MCQB) || defined(CONFIG_FB_BFIN_T350MCQB_MODULE)
852 &bf52x_t350mcqb_device,
853#endif
854
766#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE) 855#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
767 &bfin_fb_adv7393_device, 856 &bfin_fb_adv7393_device,
768#endif 857#endif
@@ -783,6 +872,10 @@ static struct platform_device *stamp_devices[] __initdata = {
783#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) 872#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
784 &bfin_pata_device, 873 &bfin_pata_device,
785#endif 874#endif
875
876#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
877 &bfin_device_gpiokeys,
878#endif
786}; 879};
787 880
788static int __init stamp_init(void) 881static int __init stamp_init(void)
diff --git a/arch/blackfin/mach-bf533/boards/H8606.c b/arch/blackfin/mach-bf533/boards/H8606.c
index 6bcf4047f89c..a72c7a620fa1 100644
--- a/arch/blackfin/mach-bf533/boards/H8606.c
+++ b/arch/blackfin/mach-bf533/boards/H8606.c
@@ -40,6 +40,7 @@
40#endif 40#endif
41#include <linux/pata_platform.h> 41#include <linux/pata_platform.h>
42#include <linux/irq.h> 42#include <linux/irq.h>
43
43#include <asm/dma.h> 44#include <asm/dma.h>
44#include <asm/bfin5xx_spi.h> 45#include <asm/bfin5xx_spi.h>
45#include <asm/reboot.h> 46#include <asm/reboot.h>
@@ -303,7 +304,77 @@ static struct platform_device bfin_uart_device = {
303}; 304};
304#endif 305#endif
305 306
306static struct platform_device *stamp_devices[] __initdata = { 307#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
308
309#include <linux/serial_8250.h>
310#include <linux/serial.h>
311
312/*
313 * Configuration for two 16550 UARTS in FPGA at addresses 0x20200000 and 0x202000010.
314 * running at half system clock, both with interrupt output or-ed to PF8. Change to
315 * suit different FPGA configuration, or to suit real 16550 UARTS connected to the bus
316 */
317
318static struct plat_serial8250_port serial8250_platform_data [] = {
319 {
320 .membase = 0x20200000,
321 .mapbase = 0x20200000,
322 .irq = IRQ_PF8,
323 .flags = UPF_BOOT_AUTOCONF | UART_CONFIG_TYPE,
324 .iotype = UPIO_MEM,
325 .regshift = 1,
326 .uartclk = 66666667,
327 }, {
328 .membase = 0x20200010,
329 .mapbase = 0x20200010,
330 .irq = IRQ_PF8,
331 .flags = UPF_BOOT_AUTOCONF | UART_CONFIG_TYPE,
332 .iotype = UPIO_MEM,
333 .regshift = 1,
334 .uartclk = 66666667,
335 }, {
336 }
337};
338
339static struct platform_device serial8250_device = {
340 .id = PLAT8250_DEV_PLATFORM,
341 .name = "serial8250",
342 .dev = {
343 .platform_data = serial8250_platform_data,
344 },
345};
346
347#endif
348
349#if defined(CONFIG_KEYBOARD_OPENCORES) || defined(CONFIG_KEYBOARD_OPENCORES_MODULE)
350
351/*
352 * Configuration for one OpenCores keyboard controller in FPGA at address 0x20200030,
353 * interrupt output wired to PF9. Change to suit different FPGA configuration
354 */
355
356static struct resource opencores_kbd_resources[] = {
357 [0] = {
358 .start = 0x20200030,
359 .end = 0x20300030 + 2,
360 .flags = IORESOURCE_MEM,
361 },
362 [1] = {
363 .start = IRQ_PF9,
364 .end = IRQ_PF9,
365 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
366 },
367};
368
369static struct platform_device opencores_kbd_device = {
370 .id = -1,
371 .name = "opencores-kbd",
372 .resource = opencores_kbd_resources,
373 .num_resources = ARRAY_SIZE(opencores_kbd_resources),
374};
375#endif
376
377static struct platform_device *h8606_devices[] __initdata = {
307#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) 378#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
308 &rtc_device, 379 &rtc_device,
309#endif 380#endif
@@ -327,13 +398,21 @@ static struct platform_device *stamp_devices[] __initdata = {
327#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) 398#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
328 &bfin_uart_device, 399 &bfin_uart_device,
329#endif 400#endif
401
402#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
403 &serial8250_device,
404#endif
405
406#if defined(CONFIG_KEYBOARD_OPENCORES) || defined(CONFIG_KEYBOARD_OPENCORES_MODULE)
407 &opencores_kbd_device,
408#endif
330}; 409};
331 410
332static int __init H8606_init(void) 411static int __init H8606_init(void)
333{ 412{
334 printk(KERN_INFO "HV Sistemas H8606 board support by http://www.hvsistemas.com\n"); 413 printk(KERN_INFO "HV Sistemas H8606 board support by http://www.hvsistemas.com\n");
335 printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__); 414 printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
336 platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); 415 platform_add_devices(h8606_devices, ARRAY_SIZE(h8606_devices));
337#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 416#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
338 spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); 417 spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
339#endif 418#endif
diff --git a/arch/blackfin/mach-bf533/boards/ezkit.c b/arch/blackfin/mach-bf533/boards/ezkit.c
index be852034a68b..c37dd45c8803 100644
--- a/arch/blackfin/mach-bf533/boards/ezkit.c
+++ b/arch/blackfin/mach-bf533/boards/ezkit.c
@@ -256,6 +256,50 @@ static struct platform_device bfin_pata_device = {
256}; 256};
257#endif 257#endif
258 258
259#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
260#include <linux/input.h>
261#include <linux/gpio_keys.h>
262
263static struct gpio_keys_button bfin_gpio_keys_table[] = {
264 {BTN_0, GPIO_PF7, 1, "gpio-keys: BTN0"},
265 {BTN_1, GPIO_PF8, 1, "gpio-keys: BTN1"},
266 {BTN_2, GPIO_PF9, 1, "gpio-keys: BTN2"},
267 {BTN_3, GPIO_PF10, 1, "gpio-keys: BTN3"},
268};
269
270static struct gpio_keys_platform_data bfin_gpio_keys_data = {
271 .buttons = bfin_gpio_keys_table,
272 .nbuttons = ARRAY_SIZE(bfin_gpio_keys_table),
273};
274
275static struct platform_device bfin_device_gpiokeys = {
276 .name = "gpio-keys",
277 .dev = {
278 .platform_data = &bfin_gpio_keys_data,
279 },
280};
281#endif
282
283#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
284#include <linux/i2c-gpio.h>
285
286static struct i2c_gpio_platform_data i2c_gpio_data = {
287 .sda_pin = 1,
288 .scl_pin = 0,
289 .sda_is_open_drain = 0,
290 .scl_is_open_drain = 0,
291 .udelay = 40,
292};
293
294static struct platform_device i2c_gpio_device = {
295 .name = "i2c-gpio",
296 .id = 0,
297 .dev = {
298 .platform_data = &i2c_gpio_data,
299 },
300};
301#endif
302
259static struct platform_device *ezkit_devices[] __initdata = { 303static struct platform_device *ezkit_devices[] __initdata = {
260#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) 304#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
261 &smc91x_device, 305 &smc91x_device,
@@ -280,6 +324,14 @@ static struct platform_device *ezkit_devices[] __initdata = {
280#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) 324#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
281 &bfin_pata_device, 325 &bfin_pata_device,
282#endif 326#endif
327
328#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
329 &bfin_device_gpiokeys,
330#endif
331
332#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
333 &i2c_gpio_device,
334#endif
283}; 335};
284 336
285static int __init ezkit_init(void) 337static int __init ezkit_init(void)
diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c
index 8fde8d832850..ac52b040b336 100644
--- a/arch/blackfin/mach-bf533/boards/stamp.c
+++ b/arch/blackfin/mach-bf533/boards/stamp.c
@@ -32,6 +32,7 @@
32#include <linux/platform_device.h> 32#include <linux/platform_device.h>
33#include <linux/mtd/mtd.h> 33#include <linux/mtd/mtd.h>
34#include <linux/mtd/partitions.h> 34#include <linux/mtd/partitions.h>
35#include <linux/mtd/physmap.h>
35#include <linux/spi/spi.h> 36#include <linux/spi/spi.h>
36#include <linux/spi/flash.h> 37#include <linux/spi/flash.h>
37#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) 38#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
@@ -108,6 +109,50 @@ static struct platform_device net2272_bfin_device = {
108}; 109};
109#endif 110#endif
110 111
112static struct mtd_partition stamp_partitions[] = {
113 {
114 .name = "Bootloader",
115 .size = 0x20000,
116 .offset = 0,
117 }, {
118 .name = "Kernel",
119 .size = 0xE0000,
120 .offset = MTDPART_OFS_APPEND,
121 }, {
122 .name = "RootFS",
123 .size = MTDPART_SIZ_FULL,
124 .offset = MTDPART_OFS_APPEND,
125 }
126};
127
128static struct physmap_flash_data stamp_flash_data = {
129 .width = 2,
130 .parts = stamp_partitions,
131 .nr_parts = ARRAY_SIZE(stamp_partitions),
132};
133
134static struct resource stamp_flash_resource[] = {
135 {
136 .name = "cfi_probe",
137 .start = 0x20000000,
138 .end = 0x203fffff,
139 .flags = IORESOURCE_MEM,
140 }, {
141 .start = CONFIG_ENET_FLASH_PIN,
142 .flags = IORESOURCE_IRQ,
143 }
144};
145
146static struct platform_device stamp_flash_device = {
147 .name = "BF5xx-Flash",
148 .id = 0,
149 .dev = {
150 .platform_data = &stamp_flash_data,
151 },
152 .num_resources = ARRAY_SIZE(stamp_flash_resource),
153 .resource = stamp_flash_resource,
154};
155
111#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 156#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
112/* all SPI peripherals info goes here */ 157/* all SPI peripherals info goes here */
113 158
@@ -373,6 +418,49 @@ static struct platform_device bfin_pata_device = {
373}; 418};
374#endif 419#endif
375 420
421#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
422#include <linux/input.h>
423#include <linux/gpio_keys.h>
424
425static struct gpio_keys_button bfin_gpio_keys_table[] = {
426 {BTN_0, GPIO_PF5, 1, "gpio-keys: BTN0"},
427 {BTN_1, GPIO_PF6, 1, "gpio-keys: BTN1"},
428 {BTN_2, GPIO_PF8, 1, "gpio-keys: BTN2"},
429};
430
431static struct gpio_keys_platform_data bfin_gpio_keys_data = {
432 .buttons = bfin_gpio_keys_table,
433 .nbuttons = ARRAY_SIZE(bfin_gpio_keys_table),
434};
435
436static struct platform_device bfin_device_gpiokeys = {
437 .name = "gpio-keys",
438 .dev = {
439 .platform_data = &bfin_gpio_keys_data,
440 },
441};
442#endif
443
444#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
445#include <linux/i2c-gpio.h>
446
447static struct i2c_gpio_platform_data i2c_gpio_data = {
448 .sda_pin = 2,
449 .scl_pin = 3,
450 .sda_is_open_drain = 0,
451 .scl_is_open_drain = 0,
452 .udelay = 40,
453};
454
455static struct platform_device i2c_gpio_device = {
456 .name = "i2c-gpio",
457 .id = 0,
458 .dev = {
459 .platform_data = &i2c_gpio_data,
460 },
461};
462#endif
463
376static struct platform_device *stamp_devices[] __initdata = { 464static struct platform_device *stamp_devices[] __initdata = {
377#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) 465#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
378 &rtc_device, 466 &rtc_device,
@@ -406,6 +494,15 @@ static struct platform_device *stamp_devices[] __initdata = {
406#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) 494#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
407 &bfin_pata_device, 495 &bfin_pata_device,
408#endif 496#endif
497
498#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
499 &bfin_device_gpiokeys,
500#endif
501
502#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
503 &i2c_gpio_device,
504#endif
505 &stamp_flash_device,
409}; 506};
410 507
411static int __init stamp_init(void) 508static int __init stamp_init(void)
@@ -418,12 +515,10 @@ static int __init stamp_init(void)
418 return ret; 515 return ret;
419 516
420#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) 517#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
421# if defined(CONFIG_BFIN_SHARED_FLASH_ENET)
422 /* setup BF533_STAMP CPLD to route AMS3 to Ethernet MAC */ 518 /* setup BF533_STAMP CPLD to route AMS3 to Ethernet MAC */
423 bfin_write_FIO_DIR(bfin_read_FIO_DIR() | (1 << CONFIG_ENET_FLASH_PIN)); 519 bfin_write_FIO_DIR(bfin_read_FIO_DIR() | (1 << CONFIG_ENET_FLASH_PIN));
424 bfin_write_FIO_FLAG_S(1 << CONFIG_ENET_FLASH_PIN); 520 bfin_write_FIO_FLAG_S(1 << CONFIG_ENET_FLASH_PIN);
425 SSYNC(); 521 SSYNC();
426# endif
427#endif 522#endif
428 523
429#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 524#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
@@ -440,10 +535,8 @@ arch_initcall(stamp_init);
440 535
441void native_machine_restart(char *cmd) 536void native_machine_restart(char *cmd)
442{ 537{
443#if defined(CONFIG_BFIN_SHARED_FLASH_ENET) 538#define BIT_TO_SET (1 << CONFIG_ENET_FLASH_PIN)
444# define BIT_TO_SET (1 << CONFIG_ENET_FLASH_PIN)
445 bfin_write_FIO_INEN(~BIT_TO_SET); 539 bfin_write_FIO_INEN(~BIT_TO_SET);
446 bfin_write_FIO_DIR(BIT_TO_SET); 540 bfin_write_FIO_DIR(BIT_TO_SET);
447 bfin_write_FIO_FLAG_C(BIT_TO_SET); 541 bfin_write_FIO_FLAG_C(BIT_TO_SET);
448#endif
449} 542}
diff --git a/arch/blackfin/mach-bf537/boards/Kconfig b/arch/blackfin/mach-bf537/boards/Kconfig
index 96a15196e416..7e789dbef036 100644
--- a/arch/blackfin/mach-bf537/boards/Kconfig
+++ b/arch/blackfin/mach-bf537/boards/Kconfig
@@ -21,6 +21,12 @@ config PNAV10
21 help 21 help
22 PNAV board support. 22 PNAV board support.
23 23
24config CAMSIG_MINOTAUR
25 bool "Cambridge Signal Processing LTD Minotaur"
26 depends on (BF537)
27 help
28 Board supply package for CSP Minotaur
29
24config GENERIC_BF537_BOARD 30config GENERIC_BF537_BOARD
25 bool "Generic" 31 bool "Generic"
26 help 32 help
diff --git a/arch/blackfin/mach-bf537/boards/Makefile b/arch/blackfin/mach-bf537/boards/Makefile
index 94a85174283a..87e450f29e37 100644
--- a/arch/blackfin/mach-bf537/boards/Makefile
+++ b/arch/blackfin/mach-bf537/boards/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_GENERIC_BF537_BOARD) += generic_board.o
6obj-$(CONFIG_BFIN537_STAMP) += stamp.o led.o 6obj-$(CONFIG_BFIN537_STAMP) += stamp.o led.o
7obj-$(CONFIG_BFIN537_BLUETECHNIX_CM) += cm_bf537.o 7obj-$(CONFIG_BFIN537_BLUETECHNIX_CM) += cm_bf537.o
8obj-$(CONFIG_PNAV10) += pnav10.o 8obj-$(CONFIG_PNAV10) += pnav10.o
9obj-$(CONFIG_CAMSIG_MINOTAUR) += minotaur.o
diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537.c b/arch/blackfin/mach-bf537/boards/cm_bf537.c
index c0fb06dbc42e..8703b67d5ec6 100644
--- a/arch/blackfin/mach-bf537/boards/cm_bf537.c
+++ b/arch/blackfin/mach-bf537/boards/cm_bf537.c
@@ -29,6 +29,7 @@
29 */ 29 */
30 30
31#include <linux/device.h> 31#include <linux/device.h>
32#include <linux/etherdevice.h>
32#include <linux/platform_device.h> 33#include <linux/platform_device.h>
33#include <linux/mtd/mtd.h> 34#include <linux/mtd/mtd.h>
34#include <linux/mtd/partitions.h> 35#include <linux/mtd/partitions.h>
@@ -216,6 +217,12 @@ static struct platform_device rtc_device = {
216}; 217};
217#endif 218#endif
218 219
220#if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE)
221static struct platform_device hitachi_fb_device = {
222 .name = "hitachi-tx09",
223};
224#endif
225
219#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) 226#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
220static struct resource smc91x_resources[] = { 227static struct resource smc91x_resources[] = {
221 { 228 {
@@ -374,6 +381,10 @@ static struct platform_device bfin_pata_device = {
374#endif 381#endif
375 382
376static struct platform_device *cm_bf537_devices[] __initdata = { 383static struct platform_device *cm_bf537_devices[] __initdata = {
384#if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE)
385 &hitachi_fb_device,
386#endif
387
377#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) 388#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
378 &rtc_device, 389 &rtc_device,
379#endif 390#endif
diff --git a/arch/blackfin/mach-bf537/boards/generic_board.c b/arch/blackfin/mach-bf537/boards/generic_board.c
index 09f4bfbd2350..3e52f3f5bd58 100644
--- a/arch/blackfin/mach-bf537/boards/generic_board.c
+++ b/arch/blackfin/mach-bf537/boards/generic_board.c
@@ -8,7 +8,7 @@
8 * 8 *
9 * Modified: 9 * Modified:
10 * Copyright 2005 National ICT Australia (NICTA) 10 * Copyright 2005 National ICT Australia (NICTA)
11 * Copyright 2004-2007 Analog Devices Inc. 11 * Copyright 2004-2008 Analog Devices Inc.
12 * 12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/ 13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 * 14 *
@@ -29,6 +29,7 @@
29 */ 29 */
30 30
31#include <linux/device.h> 31#include <linux/device.h>
32#include <linux/etherdevice.h>
32#include <linux/platform_device.h> 33#include <linux/platform_device.h>
33#include <linux/mtd/mtd.h> 34#include <linux/mtd/mtd.h>
34#include <linux/mtd/partitions.h> 35#include <linux/mtd/partitions.h>
@@ -204,12 +205,8 @@ static struct resource sl811_hcd_resources[] = {
204void sl811_port_power(struct device *dev, int is_on) 205void sl811_port_power(struct device *dev, int is_on)
205{ 206{
206 gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS"); 207 gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS");
207 gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS); 208 gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS, is_on);
208 209
209 if (is_on)
210 gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 1);
211 else
212 gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 0);
213} 210}
214#endif 211#endif
215 212
@@ -733,9 +730,11 @@ void native_machine_restart(char *cmd)
733 bfin_gpio_reset_spi0_ssel1(); 730 bfin_gpio_reset_spi0_ssel1();
734} 731}
735 732
733#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
736void bfin_get_ether_addr(char *addr) 734void bfin_get_ether_addr(char *addr)
737{ 735{
738 random_ether_addr(addr); 736 random_ether_addr(addr);
739 printk(KERN_WARNING "%s:%s: Setting Ethernet MAC to a random one\n", __FILE__, __func__); 737 printk(KERN_WARNING "%s:%s: Setting Ethernet MAC to a random one\n", __FILE__, __func__);
740} 738}
741EXPORT_SYMBOL(bfin_get_ether_addr); 739EXPORT_SYMBOL(bfin_get_ether_addr);
740#endif
diff --git a/arch/blackfin/mach-bf537/boards/minotaur.c b/arch/blackfin/mach-bf537/boards/minotaur.c
new file mode 100644
index 000000000000..b8bbba85af53
--- /dev/null
+++ b/arch/blackfin/mach-bf537/boards/minotaur.c
@@ -0,0 +1,317 @@
1/*
2 */
3
4#include <linux/device.h>
5#include <linux/platform_device.h>
6#include <linux/mtd/mtd.h>
7#include <linux/mtd/partitions.h>
8#include <linux/spi/spi.h>
9#include <linux/spi/flash.h>
10#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
11#include <linux/usb_isp1362.h>
12#endif
13#include <linux/pata_platform.h>
14#include <linux/irq.h>
15#include <linux/interrupt.h>
16#include <linux/usb_sl811.h>
17#include <asm/dma.h>
18#include <asm/bfin5xx_spi.h>
19#include <asm/reboot.h>
20#include <linux/spi/ad7877.h>
21
22/*
23 * Name the Board for the /proc/cpuinfo
24 */
25char *bfin_board_name = "CamSig Minotaur BF537";
26
27#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
28static struct resource bfin_pcmcia_cf_resources[] = {
29 {
30 .start = 0x20310000, /* IO PORT */
31 .end = 0x20312000,
32 .flags = IORESOURCE_MEM,
33 }, {
34 .start = 0x20311000, /* Attribute Memory */
35 .end = 0x20311FFF,
36 .flags = IORESOURCE_MEM,
37 }, {
38 .start = IRQ_PF4,
39 .end = IRQ_PF4,
40 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
41 }, {
42 .start = IRQ_PF6, /* Card Detect PF6 */
43 .end = IRQ_PF6,
44 .flags = IORESOURCE_IRQ,
45 },
46};
47
48static struct platform_device bfin_pcmcia_cf_device = {
49 .name = "bfin_cf_pcmcia",
50 .id = -1,
51 .num_resources = ARRAY_SIZE(bfin_pcmcia_cf_resources),
52 .resource = bfin_pcmcia_cf_resources,
53};
54#endif
55
56#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
57static struct platform_device rtc_device = {
58 .name = "rtc-bfin",
59 .id = -1,
60};
61#endif
62
63#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
64static struct platform_device bfin_mac_device = {
65 .name = "bfin_mac",
66};
67#endif
68
69#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
70static struct resource net2272_bfin_resources[] = {
71 {
72 .start = 0x20300000,
73 .end = 0x20300000 + 0x100,
74 .flags = IORESOURCE_MEM,
75 }, {
76 .start = IRQ_PF7,
77 .end = IRQ_PF7,
78 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
79 },
80};
81
82static struct platform_device net2272_bfin_device = {
83 .name = "net2272",
84 .id = -1,
85 .num_resources = ARRAY_SIZE(net2272_bfin_resources),
86 .resource = net2272_bfin_resources,
87};
88#endif
89
90#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
91/* all SPI peripherals info goes here */
92
93#if defined(CONFIG_MTD_M25P80) \
94 || defined(CONFIG_MTD_M25P80_MODULE)
95
96/* Partition sizes */
97#define FLASH_SIZE 0x00400000
98#define PSIZE_UBOOT 0x00030000
99#define PSIZE_INITRAMFS 0x00240000
100
101static struct mtd_partition bfin_spi_flash_partitions[] = {
102 {
103 .name = "uboot",
104 .size = PSIZE_UBOOT,
105 .offset = 0x000000,
106 .mask_flags = MTD_CAP_ROM
107 }, {
108 .name = "initramfs",
109 .size = PSIZE_INITRAMFS,
110 .offset = PSIZE_UBOOT
111 }, {
112 .name = "opt",
113 .size = FLASH_SIZE - (PSIZE_UBOOT + PSIZE_INITRAMFS),
114 .offset = PSIZE_UBOOT + PSIZE_INITRAMFS,
115 }
116};
117
118static struct flash_platform_data bfin_spi_flash_data = {
119 .name = "m25p80",
120 .parts = bfin_spi_flash_partitions,
121 .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
122 .type = "m25p64",
123};
124
125/* SPI flash chip (m25p64) */
126static struct bfin5xx_spi_chip spi_flash_chip_info = {
127 .enable_dma = 0, /* use dma transfer with this chip*/
128 .bits_per_word = 8,
129};
130#endif
131
132#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE)
133static struct bfin5xx_spi_chip spi_mmc_chip_info = {
134 .enable_dma = 1,
135 .bits_per_word = 8,
136};
137#endif
138
139static struct spi_board_info bfin_spi_board_info[] __initdata = {
140#if defined(CONFIG_MTD_M25P80) \
141 || defined(CONFIG_MTD_M25P80_MODULE)
142 {
143 /* the modalias must be the same as spi device driver name */
144 .modalias = "m25p80", /* Name of spi_driver for this device */
145 .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
146 .bus_num = 0, /* Framework bus number */
147 .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/
148 .platform_data = &bfin_spi_flash_data,
149 .controller_data = &spi_flash_chip_info,
150 .mode = SPI_MODE_3,
151 },
152#endif
153
154#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE)
155 {
156 .modalias = "spi_mmc_dummy",
157 .max_speed_hz = 5000000, /* max spi clock (SCK) speed in HZ */
158 .bus_num = 0,
159 .chip_select = 0,
160 .platform_data = NULL,
161 .controller_data = &spi_mmc_chip_info,
162 .mode = SPI_MODE_3,
163 },
164 {
165 .modalias = "spi_mmc",
166 .max_speed_hz = 5000000, /* max spi clock (SCK) speed in HZ */
167 .bus_num = 0,
168 .chip_select = CONFIG_SPI_MMC_CS_CHAN,
169 .platform_data = NULL,
170 .controller_data = &spi_mmc_chip_info,
171 .mode = SPI_MODE_3,
172 },
173#endif
174};
175
176/* SPI controller data */
177static struct bfin5xx_spi_master bfin_spi0_info = {
178 .num_chipselect = 8,
179 .enable_dma = 1, /* master has the ability to do dma transfer */
180};
181
182/* SPI (0) */
183static struct resource bfin_spi0_resource[] = {
184 [0] = {
185 .start = SPI0_REGBASE,
186 .end = SPI0_REGBASE + 0xFF,
187 .flags = IORESOURCE_MEM,
188 },
189 [1] = {
190 .start = CH_SPI,
191 .end = CH_SPI,
192 .flags = IORESOURCE_IRQ,
193 },
194};
195
196static struct platform_device bfin_spi0_device = {
197 .name = "bfin-spi",
198 .id = 0, /* Bus number */
199 .num_resources = ARRAY_SIZE(bfin_spi0_resource),
200 .resource = bfin_spi0_resource,
201 .dev = {
202 .platform_data = &bfin_spi0_info, /* Passed to driver */
203 },
204};
205#endif /* spi master and devices */
206
207#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
208static struct resource bfin_uart_resources[] = {
209 {
210 .start = 0xFFC00400,
211 .end = 0xFFC004FF,
212 .flags = IORESOURCE_MEM,
213 }, {
214 .start = 0xFFC02000,
215 .end = 0xFFC020FF,
216 .flags = IORESOURCE_MEM,
217 },
218};
219
220static struct platform_device bfin_uart_device = {
221 .name = "bfin-uart",
222 .id = 1,
223 .num_resources = ARRAY_SIZE(bfin_uart_resources),
224 .resource = bfin_uart_resources,
225};
226#endif
227
228#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
229static struct resource bfin_twi0_resource[] = {
230 [0] = {
231 .start = TWI0_REGBASE,
232 .end = TWI0_REGBASE + 0xFF,
233 .flags = IORESOURCE_MEM,
234 },
235 [1] = {
236 .start = IRQ_TWI,
237 .end = IRQ_TWI,
238 .flags = IORESOURCE_IRQ,
239 },
240};
241
242static struct platform_device i2c_bfin_twi_device = {
243 .name = "i2c-bfin-twi",
244 .id = 0,
245 .num_resources = ARRAY_SIZE(bfin_twi0_resource),
246 .resource = bfin_twi0_resource,
247};
248#endif
249
250#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
251static struct platform_device bfin_sport0_uart_device = {
252 .name = "bfin-sport-uart",
253 .id = 0,
254};
255
256static struct platform_device bfin_sport1_uart_device = {
257 .name = "bfin-sport-uart",
258 .id = 1,
259};
260#endif
261
262static struct platform_device *minotaur_devices[] __initdata = {
263#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
264 &bfin_pcmcia_cf_device,
265#endif
266
267#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
268 &rtc_device,
269#endif
270
271#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
272 &bfin_mac_device,
273#endif
274
275#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
276 &net2272_bfin_device,
277#endif
278
279#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
280 &bfin_spi0_device,
281#endif
282
283#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
284 &bfin_uart_device,
285#endif
286
287#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
288 &i2c_bfin_twi_device,
289#endif
290
291#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
292 &bfin_sport0_uart_device,
293 &bfin_sport1_uart_device,
294#endif
295
296};
297
298static int __init minotaur_init(void)
299{
300 printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
301 platform_add_devices(minotaur_devices, ARRAY_SIZE(minotaur_devices));
302#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
303 spi_register_board_info(bfin_spi_board_info,
304 ARRAY_SIZE(bfin_spi_board_info));
305#endif
306
307 return 0;
308}
309
310arch_initcall(minotaur_init);
311
312void native_machine_restart(char *cmd)
313{
314 /* workaround reboot hang when booting from SPI */
315 if ((bfin_read_SYSCR() & 0x7) == 0x3)
316 bfin_gpio_reset_spi0_ssel1();
317}
diff --git a/arch/blackfin/mach-bf537/boards/pnav10.c b/arch/blackfin/mach-bf537/boards/pnav10.c
index fd5f4a6f08e4..509a8a236fd0 100644
--- a/arch/blackfin/mach-bf537/boards/pnav10.c
+++ b/arch/blackfin/mach-bf537/boards/pnav10.c
@@ -8,7 +8,7 @@
8 * 8 *
9 * Modified: 9 * Modified:
10 * Copyright 2005 National ICT Australia (NICTA) 10 * Copyright 2005 National ICT Australia (NICTA)
11 * Copyright 2004-2006 Analog Devices Inc. 11 * Copyright 2004-2008 Analog Devices Inc.
12 * 12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/ 13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 * 14 *
@@ -29,6 +29,7 @@
29 */ 29 */
30 30
31#include <linux/device.h> 31#include <linux/device.h>
32#include <linux/etherdevice.h>
32#include <linux/platform_device.h> 33#include <linux/platform_device.h>
33#include <linux/mtd/mtd.h> 34#include <linux/mtd/mtd.h>
34#include <linux/mtd/partitions.h> 35#include <linux/mtd/partitions.h>
@@ -133,12 +134,8 @@ static struct resource sl811_hcd_resources[] = {
133void sl811_port_power(struct device *dev, int is_on) 134void sl811_port_power(struct device *dev, int is_on)
134{ 135{
135 gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS"); 136 gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS");
136 gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS); 137 gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS, is_on);
137 138
138 if (is_on)
139 gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 1);
140 else
141 gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 0);
142} 139}
143#endif 140#endif
144 141
diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c
index 07b0dc273d2f..772541548b76 100644
--- a/arch/blackfin/mach-bf537/boards/stamp.c
+++ b/arch/blackfin/mach-bf537/boards/stamp.c
@@ -32,6 +32,7 @@
32#include <linux/platform_device.h> 32#include <linux/platform_device.h>
33#include <linux/mtd/mtd.h> 33#include <linux/mtd/mtd.h>
34#include <linux/mtd/partitions.h> 34#include <linux/mtd/partitions.h>
35#include <linux/mtd/physmap.h>
35#include <linux/spi/spi.h> 36#include <linux/spi/spi.h>
36#include <linux/spi/flash.h> 37#include <linux/spi/flash.h>
37#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) 38#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
@@ -103,6 +104,30 @@ void __exit bfin_isp1761_exit(void)
103arch_initcall(bfin_isp1761_init); 104arch_initcall(bfin_isp1761_init);
104#endif 105#endif
105 106
107#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
108#include <linux/input.h>
109#include <linux/gpio_keys.h>
110
111static struct gpio_keys_button bfin_gpio_keys_table[] = {
112 {BTN_0, GPIO_PF2, 1, "gpio-keys: BTN0"},
113 {BTN_1, GPIO_PF3, 1, "gpio-keys: BTN1"},
114 {BTN_2, GPIO_PF4, 1, "gpio-keys: BTN2"},
115 {BTN_3, GPIO_PF5, 1, "gpio-keys: BTN3"},
116};
117
118static struct gpio_keys_platform_data bfin_gpio_keys_data = {
119 .buttons = bfin_gpio_keys_table,
120 .nbuttons = ARRAY_SIZE(bfin_gpio_keys_table),
121};
122
123static struct platform_device bfin_device_gpiokeys = {
124 .name = "gpio-keys",
125 .dev = {
126 .platform_data = &bfin_gpio_keys_data,
127 },
128};
129#endif
130
106#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE) 131#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
107static struct resource bfin_pcmcia_cf_resources[] = { 132static struct resource bfin_pcmcia_cf_resources[] = {
108 { 133 {
@@ -226,12 +251,7 @@ static struct resource sl811_hcd_resources[] = {
226void sl811_port_power(struct device *dev, int is_on) 251void sl811_port_power(struct device *dev, int is_on)
227{ 252{
228 gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS"); 253 gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS");
229 gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS); 254 gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS, is_on);
230
231 if (is_on)
232 gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 1);
233 else
234 gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 0);
235} 255}
236#endif 256#endif
237 257
@@ -320,6 +340,49 @@ static struct platform_device net2272_bfin_device = {
320}; 340};
321#endif 341#endif
322 342
343static struct mtd_partition stamp_partitions[] = {
344 {
345 .name = "Bootloader",
346 .size = 0x20000,
347 .offset = 0,
348 }, {
349 .name = "Kernel",
350 .size = 0xE0000,
351 .offset = MTDPART_OFS_APPEND,
352 }, {
353 .name = "RootFS",
354 .size = 0x400000 - 0x20000 - 0xE0000 - 0x10000,
355 .offset = MTDPART_OFS_APPEND,
356 }, {
357 .name = "MAC Address",
358 .size = MTDPART_SIZ_FULL,
359 .offset = 0x3F0000,
360 .mask_flags = MTD_WRITEABLE,
361 }
362};
363
364static struct physmap_flash_data stamp_flash_data = {
365 .width = 2,
366 .parts = stamp_partitions,
367 .nr_parts = ARRAY_SIZE(stamp_partitions),
368};
369
370static struct resource stamp_flash_resource = {
371 .start = 0x20000000,
372 .end = 0x203fffff,
373 .flags = IORESOURCE_MEM,
374};
375
376static struct platform_device stamp_flash_device = {
377 .name = "physmap-flash",
378 .id = 0,
379 .dev = {
380 .platform_data = &stamp_flash_data,
381 },
382 .num_resources = 1,
383 .resource = &stamp_flash_resource,
384};
385
323#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 386#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
324/* all SPI peripherals info goes here */ 387/* all SPI peripherals info goes here */
325 388
@@ -738,6 +801,11 @@ static struct platform_device *stamp_devices[] __initdata = {
738#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) 801#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
739 &bfin_pata_device, 802 &bfin_pata_device,
740#endif 803#endif
804
805#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
806 &bfin_device_gpiokeys,
807#endif
808 &stamp_flash_device,
741}; 809};
742 810
743static int __init stamp_init(void) 811static int __init stamp_init(void)
diff --git a/arch/blackfin/mach-bf548/Kconfig b/arch/blackfin/mach-bf548/Kconfig
index d8bd3b49f150..1bfcd8f646ab 100644
--- a/arch/blackfin/mach-bf548/Kconfig
+++ b/arch/blackfin/mach-bf548/Kconfig
@@ -7,7 +7,7 @@ menu "BF548 Specific Configuration"
7config DEB_DMA_URGENT 7config DEB_DMA_URGENT
8 bool "DMA has priority over core for ext. accesses" 8 bool "DMA has priority over core for ext. accesses"
9 depends on BF54x 9 depends on BF54x
10 default n 10 default y
11 help 11 help
12 Treat any DEB1, DEB2 and DEB3 request as Urgent 12 Treat any DEB1, DEB2 and DEB3 request as Urgent
13 13
diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c
index d37d6653c4bc..14860f04d1bd 100644
--- a/arch/blackfin/mach-bf548/boards/ezkit.c
+++ b/arch/blackfin/mach-bf548/boards/ezkit.c
@@ -32,6 +32,7 @@
32#include <linux/platform_device.h> 32#include <linux/platform_device.h>
33#include <linux/mtd/mtd.h> 33#include <linux/mtd/mtd.h>
34#include <linux/mtd/partitions.h> 34#include <linux/mtd/partitions.h>
35#include <linux/mtd/physmap.h>
35#include <linux/spi/spi.h> 36#include <linux/spi/spi.h>
36#include <linux/spi/flash.h> 37#include <linux/spi/flash.h>
37#include <linux/irq.h> 38#include <linux/irq.h>
@@ -206,23 +207,6 @@ static struct platform_device smsc911x_device = {
206}; 207};
207#endif 208#endif
208 209
209#if defined(CONFIG_USB_BF54x_HCD) || defined(CONFIG_USB_BF54x_HCD_MODULE)
210static struct resource bf54x_hcd_resources[] = {
211 {
212 .start = 0xFFC03C00,
213 .end = 0xFFC040FF,
214 .flags = IORESOURCE_MEM,
215 },
216};
217
218static struct platform_device bf54x_hcd = {
219 .name = "bf54x-hcd",
220 .id = 0,
221 .num_resources = ARRAY_SIZE(bf54x_hcd_resources),
222 .resource = bf54x_hcd_resources,
223};
224#endif
225
226#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE) 210#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE)
227static struct resource musb_resources[] = { 211static struct resource musb_resources[] = {
228 [0] = { 212 [0] = {
@@ -243,14 +227,14 @@ static struct resource musb_resources[] = {
243}; 227};
244 228
245static struct musb_hdrc_platform_data musb_plat = { 229static struct musb_hdrc_platform_data musb_plat = {
246#ifdef CONFIG_USB_MUSB_OTG 230#if defined(CONFIG_USB_MUSB_OTG)
247 .mode = MUSB_OTG, 231 .mode = MUSB_OTG,
248#elif CONFIG_USB_MUSB_HDRC_HCD 232#elif defined(CONFIG_USB_MUSB_HDRC_HCD)
249 .mode = MUSB_HOST, 233 .mode = MUSB_HOST,
250#elif CONFIG_USB_GADGET_MUSB_HDRC 234#elif defined(CONFIG_USB_GADGET_MUSB_HDRC)
251 .mode = MUSB_PERIPHERAL, 235 .mode = MUSB_PERIPHERAL,
252#endif 236#endif
253 .multipoint = 1, 237 .multipoint = 0,
254}; 238};
255 239
256static u64 musb_dmamask = ~(u32)0; 240static u64 musb_dmamask = ~(u32)0;
@@ -344,6 +328,44 @@ static struct platform_device bf54x_sdh_device = {
344}; 328};
345#endif 329#endif
346 330
331static struct mtd_partition ezkit_partitions[] = {
332 {
333 .name = "Bootloader",
334 .size = 0x20000,
335 .offset = 0,
336 }, {
337 .name = "Kernel",
338 .size = 0xE0000,
339 .offset = MTDPART_OFS_APPEND,
340 }, {
341 .name = "RootFS",
342 .size = MTDPART_SIZ_FULL,
343 .offset = MTDPART_OFS_APPEND,
344 }
345};
346
347static struct physmap_flash_data ezkit_flash_data = {
348 .width = 2,
349 .parts = ezkit_partitions,
350 .nr_parts = ARRAY_SIZE(ezkit_partitions),
351};
352
353static struct resource ezkit_flash_resource = {
354 .start = 0x20000000,
355 .end = 0x20ffffff,
356 .flags = IORESOURCE_MEM,
357};
358
359static struct platform_device ezkit_flash_device = {
360 .name = "physmap-flash",
361 .id = 0,
362 .dev = {
363 .platform_data = &ezkit_flash_data,
364 },
365 .num_resources = 1,
366 .resource = &ezkit_flash_resource,
367};
368
347#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 369#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
348/* all SPI peripherals info goes here */ 370/* all SPI peripherals info goes here */
349#if defined(CONFIG_MTD_M25P80) \ 371#if defined(CONFIG_MTD_M25P80) \
@@ -531,6 +553,29 @@ static struct platform_device i2c_bfin_twi1_device = {
531#endif 553#endif
532#endif 554#endif
533 555
556#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
557#include <linux/gpio_keys.h>
558
559static struct gpio_keys_button bfin_gpio_keys_table[] = {
560 {BTN_0, GPIO_PB8, 1, "gpio-keys: BTN0"},
561 {BTN_1, GPIO_PB9, 1, "gpio-keys: BTN1"},
562 {BTN_2, GPIO_PB10, 1, "gpio-keys: BTN2"},
563 {BTN_3, GPIO_PB11, 1, "gpio-keys: BTN3"},
564};
565
566static struct gpio_keys_platform_data bfin_gpio_keys_data = {
567 .buttons = bfin_gpio_keys_table,
568 .nbuttons = ARRAY_SIZE(bfin_gpio_keys_table),
569};
570
571static struct platform_device bfin_device_gpiokeys = {
572 .name = "gpio-keys",
573 .dev = {
574 .platform_data = &bfin_gpio_keys_data,
575 },
576};
577#endif
578
534static struct platform_device *ezkit_devices[] __initdata = { 579static struct platform_device *ezkit_devices[] __initdata = {
535#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) 580#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
536 &rtc_device, 581 &rtc_device,
@@ -548,10 +593,6 @@ static struct platform_device *ezkit_devices[] __initdata = {
548 &smsc911x_device, 593 &smsc911x_device,
549#endif 594#endif
550 595
551#if defined(CONFIG_USB_BF54x_HCD) || defined(CONFIG_USB_BF54x_HCD_MODULE)
552 &bf54x_hcd,
553#endif
554
555#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE) 596#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE)
556 &musb_device, 597 &musb_device,
557#endif 598#endif
@@ -583,6 +624,11 @@ static struct platform_device *ezkit_devices[] __initdata = {
583 &i2c_bfin_twi1_device, 624 &i2c_bfin_twi1_device,
584#endif 625#endif
585#endif 626#endif
627
628#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
629 &bfin_device_gpiokeys,
630#endif
631 &ezkit_flash_device,
586}; 632};
587 633
588static int __init stamp_init(void) 634static int __init stamp_init(void)
diff --git a/arch/blackfin/mach-bf548/head.S b/arch/blackfin/mach-bf548/head.S
index 74b34c7f3629..74fe258421a5 100644
--- a/arch/blackfin/mach-bf548/head.S
+++ b/arch/blackfin/mach-bf548/head.S
@@ -298,8 +298,8 @@ ENTRY(_start_dma_code)
298 w[p0] = r0.l; 298 w[p0] = r0.l;
299 ssync; 299 ssync;
300 300
301 p0.h = hi(SIC_IWR); 301 p0.h = hi(SIC_IWR0);
302 p0.l = lo(SIC_IWR); 302 p0.l = lo(SIC_IWR0);
303 r0.l = 0x1; 303 r0.l = 0x1;
304 r0.h = 0x0; 304 r0.h = 0x0;
305 [p0] = r0; 305 [p0] = r0;
@@ -324,12 +324,25 @@ ENTRY(_start_dma_code)
324 w[p0] = r0.l; 324 w[p0] = r0.l;
325 ssync; 325 ssync;
326 326
327#if defined(CONFIG_BF54x)
328 P2.H = hi(EBIU_RSTCTL);
329 P2.L = lo(EBIU_RSTCTL);
330 R0 = [P2];
331 BITSET (R0, 3);
332#else
327 P2.H = hi(EBIU_SDGCTL); 333 P2.H = hi(EBIU_SDGCTL);
328 P2.L = lo(EBIU_SDGCTL); 334 P2.L = lo(EBIU_SDGCTL);
329 R0 = [P2]; 335 R0 = [P2];
330 BITSET (R0, 24); 336 BITSET (R0, 24);
337#endif
331 [P2] = R0; 338 [P2] = R0;
332 SSYNC; 339 SSYNC;
340#if defined(CONFIG_BF54x)
341.LSRR_MODE:
342 R0 = [P2];
343 CC = BITTST(R0, 4);
344 if !CC JUMP .LSRR_MODE;
345#endif
333 346
334 r0 = CONFIG_VCO_MULT & 63; /* Load the VCO multiplier */ 347 r0 = CONFIG_VCO_MULT & 63; /* Load the VCO multiplier */
335 r0 = r0 << 9; /* Shift it over, */ 348 r0 = r0 << 9; /* Shift it over, */
@@ -361,6 +374,39 @@ ENTRY(_start_dma_code)
361 w[p0] = r0.l; 374 w[p0] = r0.l;
362 ssync; 375 ssync;
363 376
377#if defined(CONFIG_BF54x)
378 P2.H = hi(EBIU_RSTCTL);
379 P2.L = lo(EBIU_RSTCTL);
380 R0 = [P2];
381 CC = BITTST(R0, 0);
382 if CC jump .Lskipddrrst;
383 BITSET (R0, 0);
384.Lskipddrrst:
385 BITCLR (R0, 3);
386 [P2] = R0;
387 SSYNC;
388
389 p0.l = lo(EBIU_DDRCTL0);
390 p0.h = hi(EBIU_DDRCTL0);
391 r0.l = lo(mem_DDRCTL0);
392 r0.h = hi(mem_DDRCTL0);
393 [p0] = r0;
394 ssync;
395
396 p0.l = lo(EBIU_DDRCTL1);
397 p0.h = hi(EBIU_DDRCTL1);
398 r0.l = lo(mem_DDRCTL1);
399 r0.h = hi(mem_DDRCTL1);
400 [p0] = r0;
401 ssync;
402
403 p0.l = lo(EBIU_DDRCTL2);
404 p0.h = hi(EBIU_DDRCTL2);
405 r0.l = lo(mem_DDRCTL2);
406 r0.h = hi(mem_DDRCTL2);
407 [p0] = r0;
408 ssync;
409#else
364 p0.l = lo(EBIU_SDRRC); 410 p0.l = lo(EBIU_SDRRC);
365 p0.h = hi(EBIU_SDRRC); 411 p0.h = hi(EBIU_SDRRC);
366 r0 = mem_SDRRC; 412 r0 = mem_SDRRC;
@@ -394,9 +440,10 @@ ENTRY(_start_dma_code)
394 R1 = R1 | R0; 440 R1 = R1 | R0;
395 [P2] = R1; 441 [P2] = R1;
396 SSYNC; 442 SSYNC;
443#endif
397 444
398 p0.h = hi(SIC_IWR); 445 p0.h = hi(SIC_IWR0);
399 p0.l = lo(SIC_IWR); 446 p0.l = lo(SIC_IWR0);
400 r0.l = lo(IWR_ENABLE_ALL); 447 r0.l = lo(IWR_ENABLE_ALL);
401 r0.h = hi(IWR_ENABLE_ALL); 448 r0.h = hi(IWR_ENABLE_ALL);
402 [p0] = r0; 449 [p0] = r0;
diff --git a/arch/blackfin/mach-bf548/ints-priority.c b/arch/blackfin/mach-bf548/ints-priority.c
index cb0ebac53c79..2665653cee37 100644
--- a/arch/blackfin/mach-bf548/ints-priority.c
+++ b/arch/blackfin/mach-bf548/ints-priority.c
@@ -4,7 +4,7 @@
4 * Author: Michael Hennerich 4 * Author: Michael Hennerich
5 * 5 *
6 * Created: 6 * Created:
7 * Description: Set up the interupt priorities 7 * Description: Set up the interrupt priorities
8 * 8 *
9 * Modified: 9 * Modified:
10 * Copyright 2004-2006 Analog Devices Inc. 10 * Copyright 2004-2006 Analog Devices Inc.
@@ -58,7 +58,7 @@ void program_IAR(void)
58 ((CONFIG_IRQ_PINT1 - 7) << IRQ_PINT1_POS) | 58 ((CONFIG_IRQ_PINT1 - 7) << IRQ_PINT1_POS) |
59 ((CONFIG_IRQ_MDMAS0 - 7) << IRQ_MDMAS0_POS) | 59 ((CONFIG_IRQ_MDMAS0 - 7) << IRQ_MDMAS0_POS) |
60 ((CONFIG_IRQ_MDMAS1 - 7) << IRQ_MDMAS1_POS) | 60 ((CONFIG_IRQ_MDMAS1 - 7) << IRQ_MDMAS1_POS) |
61 ((CONFIG_IRQ_WATCHDOG - 7) << IRQ_WATCHDOG_POS)); 61 ((CONFIG_IRQ_WATCHDOG - 7) << IRQ_WATCH_POS));
62 62
63 bfin_write_SIC_IAR3(((CONFIG_IRQ_DMAC1_ERR - 7) << IRQ_DMAC1_ERR_POS) | 63 bfin_write_SIC_IAR3(((CONFIG_IRQ_DMAC1_ERR - 7) << IRQ_DMAC1_ERR_POS) |
64 ((CONFIG_IRQ_SPORT2_ERR - 7) << IRQ_SPORT2_ERR_POS) | 64 ((CONFIG_IRQ_SPORT2_ERR - 7) << IRQ_SPORT2_ERR_POS) |
diff --git a/arch/blackfin/mach-bf561/boards/cm_bf561.c b/arch/blackfin/mach-bf561/boards/cm_bf561.c
index c19cd29b948a..3a79a9061bdc 100644
--- a/arch/blackfin/mach-bf561/boards/cm_bf561.c
+++ b/arch/blackfin/mach-bf561/boards/cm_bf561.c
@@ -198,6 +198,13 @@ static struct platform_device bfin_spi0_device = {
198#endif /* spi master and devices */ 198#endif /* spi master and devices */
199 199
200 200
201#if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE)
202static struct platform_device hitachi_fb_device = {
203 .name = "hitachi-tx09",
204};
205#endif
206
207
201#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) 208#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
202 209
203static struct resource smc91x_resources[] = { 210static struct resource smc91x_resources[] = {
@@ -315,6 +322,10 @@ static struct platform_device bfin_pata_device = {
315 322
316static struct platform_device *cm_bf561_devices[] __initdata = { 323static struct platform_device *cm_bf561_devices[] __initdata = {
317 324
325#if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE)
326 &hitachi_fb_device,
327#endif
328
318#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) 329#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
319 &bfin_uart_device, 330 &bfin_uart_device,
320#endif 331#endif
diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c
index 4ff8f6e7a11f..7601c3be1b5c 100644
--- a/arch/blackfin/mach-bf561/boards/ezkit.c
+++ b/arch/blackfin/mach-bf561/boards/ezkit.c
@@ -29,6 +29,9 @@
29 29
30#include <linux/device.h> 30#include <linux/device.h>
31#include <linux/platform_device.h> 31#include <linux/platform_device.h>
32#include <linux/mtd/mtd.h>
33#include <linux/mtd/partitions.h>
34#include <linux/mtd/physmap.h>
32#include <linux/spi/spi.h> 35#include <linux/spi/spi.h>
33#include <linux/irq.h> 36#include <linux/irq.h>
34#include <linux/interrupt.h> 37#include <linux/interrupt.h>
@@ -155,6 +158,44 @@ static struct platform_device bfin_uart_device = {
155}; 158};
156#endif 159#endif
157 160
161static struct mtd_partition ezkit_partitions[] = {
162 {
163 .name = "Bootloader",
164 .size = 0x20000,
165 .offset = 0,
166 }, {
167 .name = "Kernel",
168 .size = 0xE0000,
169 .offset = MTDPART_OFS_APPEND,
170 }, {
171 .name = "RootFS",
172 .size = MTDPART_SIZ_FULL,
173 .offset = MTDPART_OFS_APPEND,
174 }
175};
176
177static struct physmap_flash_data ezkit_flash_data = {
178 .width = 2,
179 .parts = ezkit_partitions,
180 .nr_parts = ARRAY_SIZE(ezkit_partitions),
181};
182
183static struct resource ezkit_flash_resource = {
184 .start = 0x20000000,
185 .end = 0x207fffff,
186 .flags = IORESOURCE_MEM,
187};
188
189static struct platform_device ezkit_flash_device = {
190 .name = "physmap-flash",
191 .id = 0,
192 .dev = {
193 .platform_data = &ezkit_flash_data,
194 },
195 .num_resources = 1,
196 .resource = &ezkit_flash_resource,
197};
198
158#ifdef CONFIG_SPI_BFIN 199#ifdef CONFIG_SPI_BFIN
159#if defined(CONFIG_SND_BLACKFIN_AD1836) \ 200#if defined(CONFIG_SND_BLACKFIN_AD1836) \
160 || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) 201 || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
@@ -246,6 +287,50 @@ static struct platform_device bfin_pata_device = {
246}; 287};
247#endif 288#endif
248 289
290#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
291#include <linux/input.h>
292#include <linux/gpio_keys.h>
293
294static struct gpio_keys_button bfin_gpio_keys_table[] = {
295 {BTN_0, GPIO_PF5, 1, "gpio-keys: BTN0"},
296 {BTN_1, GPIO_PF6, 1, "gpio-keys: BTN1"},
297 {BTN_2, GPIO_PF7, 1, "gpio-keys: BTN2"},
298 {BTN_3, GPIO_PF8, 1, "gpio-keys: BTN3"},
299};
300
301static struct gpio_keys_platform_data bfin_gpio_keys_data = {
302 .buttons = bfin_gpio_keys_table,
303 .nbuttons = ARRAY_SIZE(bfin_gpio_keys_table),
304};
305
306static struct platform_device bfin_device_gpiokeys = {
307 .name = "gpio-keys",
308 .dev = {
309 .platform_data = &bfin_gpio_keys_data,
310 },
311};
312#endif
313
314#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
315#include <linux/i2c-gpio.h>
316
317static struct i2c_gpio_platform_data i2c_gpio_data = {
318 .sda_pin = 1,
319 .scl_pin = 0,
320 .sda_is_open_drain = 0,
321 .scl_is_open_drain = 0,
322 .udelay = 40,
323};
324
325static struct platform_device i2c_gpio_device = {
326 .name = "i2c-gpio",
327 .id = 0,
328 .dev = {
329 .platform_data = &i2c_gpio_data,
330 },
331};
332#endif
333
249static struct platform_device *ezkit_devices[] __initdata = { 334static struct platform_device *ezkit_devices[] __initdata = {
250#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) 335#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
251 &smc91x_device, 336 &smc91x_device,
@@ -258,12 +343,23 @@ static struct platform_device *ezkit_devices[] __initdata = {
258#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 343#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
259 &bfin_spi0_device, 344 &bfin_spi0_device,
260#endif 345#endif
346
261#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) 347#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
262 &bfin_uart_device, 348 &bfin_uart_device,
263#endif 349#endif
350
264#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) 351#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
265 &bfin_pata_device, 352 &bfin_pata_device,
266#endif 353#endif
354
355#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
356 &bfin_device_gpiokeys,
357#endif
358
359#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
360 &i2c_gpio_device,
361#endif
362 &ezkit_flash_device,
267}; 363};
268 364
269static int __init ezkit_init(void) 365static int __init ezkit_init(void)
diff --git a/arch/blackfin/mach-bf561/coreb.c b/arch/blackfin/mach-bf561/coreb.c
index 5d1d21b4c2a7..1b44e9e6dc3b 100644
--- a/arch/blackfin/mach-bf561/coreb.c
+++ b/arch/blackfin/mach-bf561/coreb.c
@@ -33,7 +33,9 @@
33#include <linux/ioport.h> 33#include <linux/ioport.h>
34#include <linux/module.h> 34#include <linux/module.h>
35#include <linux/uaccess.h> 35#include <linux/uaccess.h>
36#include <linux/fs.h>
36#include <asm/dma.h> 37#include <asm/dma.h>
38#include <asm/cacheflush.h>
37 39
38#define MODULE_VER "v0.1" 40#define MODULE_VER "v0.1"
39 41
@@ -90,11 +92,12 @@ static ssize_t coreb_write(struct file *file, const char *buf, size_t count,
90 92
91 coreb_dma_done = 0; 93 coreb_dma_done = 0;
92 94
95 flush_dcache_range((unsigned long)buf, (unsigned long)(buf+len));
93 /* Source Channel */ 96 /* Source Channel */
94 set_dma_start_addr(CH_MEM_STREAM2_SRC, (unsigned long)buf); 97 set_dma_start_addr(CH_MEM_STREAM2_SRC, (unsigned long)buf);
95 set_dma_x_count(CH_MEM_STREAM2_SRC, len); 98 set_dma_x_count(CH_MEM_STREAM2_SRC, len);
96 set_dma_x_modify(CH_MEM_STREAM2_SRC, sizeof(char)); 99 set_dma_x_modify(CH_MEM_STREAM2_SRC, sizeof(char));
97 set_dma_config(CH_MEM_STREAM2_SRC, RESTART); 100 set_dma_config(CH_MEM_STREAM2_SRC, 0);
98 /* Destination Channel */ 101 /* Destination Channel */
99 set_dma_start_addr(CH_MEM_STREAM2_DEST, coreb_base + p); 102 set_dma_start_addr(CH_MEM_STREAM2_DEST, coreb_base + p);
100 set_dma_x_count(CH_MEM_STREAM2_DEST, len); 103 set_dma_x_count(CH_MEM_STREAM2_DEST, len);
@@ -135,11 +138,12 @@ static ssize_t coreb_read(struct file *file, char *buf, size_t count,
135 138
136 coreb_dma_done = 0; 139 coreb_dma_done = 0;
137 140
141 invalidate_dcache_range((unsigned long)buf, (unsigned long)(buf+len));
138 /* Source Channel */ 142 /* Source Channel */
139 set_dma_start_addr(CH_MEM_STREAM2_SRC, coreb_base + p); 143 set_dma_start_addr(CH_MEM_STREAM2_SRC, coreb_base + p);
140 set_dma_x_count(CH_MEM_STREAM2_SRC, len); 144 set_dma_x_count(CH_MEM_STREAM2_SRC, len);
141 set_dma_x_modify(CH_MEM_STREAM2_SRC, sizeof(char)); 145 set_dma_x_modify(CH_MEM_STREAM2_SRC, sizeof(char));
142 set_dma_config(CH_MEM_STREAM2_SRC, RESTART); 146 set_dma_config(CH_MEM_STREAM2_SRC, 0);
143 /* Destination Channel */ 147 /* Destination Channel */
144 set_dma_start_addr(CH_MEM_STREAM2_DEST, (unsigned long)buf); 148 set_dma_start_addr(CH_MEM_STREAM2_DEST, (unsigned long)buf);
145 set_dma_x_count(CH_MEM_STREAM2_DEST, len); 149 set_dma_x_count(CH_MEM_STREAM2_DEST, len);
@@ -266,7 +270,7 @@ static int coreb_ioctl(struct inode *inode, struct file *file,
266 coreb_status |= COREB_IS_RUNNING; 270 coreb_status |= COREB_IS_RUNNING;
267 bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() & ~0x0020); 271 bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() & ~0x0020);
268 SSYNC(); 272 SSYNC();
269 spin_lock_irq(&coreb_lock); 273 spin_unlock_irq(&coreb_lock);
270 break; 274 break;
271#if defined(CONFIG_BF561_COREB_RESET) 275#if defined(CONFIG_BF561_COREB_RESET)
272 case CMD_COREB_STOP: 276 case CMD_COREB_STOP:
@@ -275,7 +279,7 @@ static int coreb_ioctl(struct inode *inode, struct file *file,
275 bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() | 0x0020); 279 bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() | 0x0020);
276 bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | 0x0080); 280 bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | 0x0080);
277 coreb_status &= ~COREB_IS_RUNNING; 281 coreb_status &= ~COREB_IS_RUNNING;
278 spin_lock_irq(&coreb_lock); 282 spin_unlock_irq(&coreb_lock);
279 break; 283 break;
280 case CMD_COREB_RESET: 284 case CMD_COREB_RESET:
281 printk(KERN_INFO "Resetting Core B\n"); 285 printk(KERN_INFO "Resetting Core B\n");
diff --git a/arch/blackfin/mach-common/Makefile b/arch/blackfin/mach-common/Makefile
index 4d7733dfd5de..8636d4284bdb 100644
--- a/arch/blackfin/mach-common/Makefile
+++ b/arch/blackfin/mach-common/Makefile
@@ -3,10 +3,9 @@
3# 3#
4 4
5obj-y := \ 5obj-y := \
6 cache.o cacheinit.o cplbhdlr.o cplbmgr.o entry.o \ 6 cache.o cacheinit.o entry.o \
7 interrupt.o lock.o irqpanic.o arch_checks.o 7 interrupt.o lock.o irqpanic.o arch_checks.o
8 8
9obj-$(CONFIG_CPLB_INFO) += cplbinfo.o
10obj-$(CONFIG_BFIN_SINGLE_CORE) += ints-priority-sc.o 9obj-$(CONFIG_BFIN_SINGLE_CORE) += ints-priority-sc.o
11obj-$(CONFIG_BFIN_DUAL_CORE) += ints-priority-dc.o 10obj-$(CONFIG_BFIN_DUAL_CORE) += ints-priority-dc.o
12obj-$(CONFIG_PM) += pm.o dpmc.o 11obj-$(CONFIG_PM) += pm.o dpmc.o
diff --git a/arch/blackfin/mach-common/dpmc.S b/arch/blackfin/mach-common/dpmc.S
index 39fbc2861107..b82c096e1980 100644
--- a/arch/blackfin/mach-common/dpmc.S
+++ b/arch/blackfin/mach-common/dpmc.S
@@ -38,6 +38,9 @@ ENTRY(_unmask_wdog_wakeup_evt)
38#if defined(CONFIG_BF561) 38#if defined(CONFIG_BF561)
39 P0.H = hi(SICA_IWR1); 39 P0.H = hi(SICA_IWR1);
40 P0.L = lo(SICA_IWR1); 40 P0.L = lo(SICA_IWR1);
41#elif defined(CONFIG_BF54x) || defined(CONFIG_BF52x)
42 P0.h = HI(SIC_IWR0);
43 P0.l = LO(SIC_IWR0);
41#else 44#else
42 P0.h = HI(SIC_IWR); 45 P0.h = HI(SIC_IWR);
43 P0.l = LO(SIC_IWR); 46 P0.l = LO(SIC_IWR);
@@ -172,7 +175,7 @@ ENTRY(_sleep_mode)
172 call _set_sic_iwr; 175 call _set_sic_iwr;
173 176
174 R0 = 0xFFFF (Z); 177 R0 = 0xFFFF (Z);
175 call _set_rtc_istat 178 call _set_rtc_istat;
176 179
177 P0.H = hi(PLL_CTL); 180 P0.H = hi(PLL_CTL);
178 P0.L = lo(PLL_CTL); 181 P0.L = lo(PLL_CTL);
@@ -210,7 +213,7 @@ ENTRY(_hibernate_mode)
210 call _set_sic_iwr; 213 call _set_sic_iwr;
211 214
212 R0 = 0xFFFF (Z); 215 R0 = 0xFFFF (Z);
213 call _set_rtc_istat 216 call _set_rtc_istat;
214 217
215 P0.H = hi(VR_CTL); 218 P0.H = hi(VR_CTL);
216 P0.L = lo(VR_CTL); 219 P0.L = lo(VR_CTL);
@@ -236,7 +239,7 @@ ENTRY(_deep_sleep)
236 239
237 call _set_sic_iwr; 240 call _set_sic_iwr;
238 241
239 call _set_sdram_srfs; 242 call _set_dram_srfs;
240 243
241 /* Clear all the interrupts,bits sticky */ 244 /* Clear all the interrupts,bits sticky */
242 R0 = 0xFFFF (Z); 245 R0 = 0xFFFF (Z);
@@ -253,7 +256,7 @@ ENTRY(_deep_sleep)
253 SSYNC; 256 SSYNC;
254 IDLE; 257 IDLE;
255 258
256 call _unset_sdram_srfs; 259 call _unset_dram_srfs;
257 260
258 call _test_pll_locked; 261 call _test_pll_locked;
259 262
@@ -285,23 +288,22 @@ ENTRY(_sleep_deeper)
285 P3 = R0; 288 P3 = R0;
286 R0 = IWR_ENABLE(0); 289 R0 = IWR_ENABLE(0);
287 call _set_sic_iwr; 290 call _set_sic_iwr;
288 call _set_sdram_srfs; 291 call _set_dram_srfs; /* Set SDRAM Self Refresh */
289 292
290 /* Clear all the interrupts,bits sticky */ 293 /* Clear all the interrupts,bits sticky */
291 R0 = 0xFFFF (Z); 294 R0 = 0xFFFF (Z);
292 call _set_rtc_istat 295 call _set_rtc_istat;
293
294 P0.H = hi(PLL_DIV); 296 P0.H = hi(PLL_DIV);
295 P0.L = lo(PLL_DIV); 297 P0.L = lo(PLL_DIV);
296 R6 = W[P0](z); 298 R6 = W[P0](z);
297 R0.L = 0xF; 299 R0.L = 0xF;
298 W[P0] = R0.l; 300 W[P0] = R0.l; /* Set Max VCO to SCLK divider */
299 301
300 P0.H = hi(PLL_CTL); 302 P0.H = hi(PLL_CTL);
301 P0.L = lo(PLL_CTL); 303 P0.L = lo(PLL_CTL);
302 R5 = W[P0](z); 304 R5 = W[P0](z);
303 R0.L = (CONFIG_MIN_VCO_HZ/CONFIG_CLKIN_HZ) << 9; 305 R0.L = (CONFIG_MIN_VCO_HZ/CONFIG_CLKIN_HZ) << 9;
304 W[P0] = R0.l; 306 W[P0] = R0.l; /* Set Min CLKIN to VCO multiplier */
305 307
306 SSYNC; 308 SSYNC;
307 IDLE; 309 IDLE;
@@ -317,29 +319,28 @@ ENTRY(_sleep_deeper)
317 R1 = R1|R2; 319 R1 = R1|R2;
318 320
319 R2 = DEPOSIT(R7, R1); 321 R2 = DEPOSIT(R7, R1);
320 W[P0] = R2; 322 W[P0] = R2; /* Set Min Core Voltage */
321 323
322 SSYNC; 324 SSYNC;
323 IDLE; 325 IDLE;
324 326
325 call _test_pll_locked; 327 call _test_pll_locked;
326 328
329 R0 = P3;
330 call _set_sic_iwr; /* Set Awake from IDLE */
331
327 P0.H = hi(PLL_CTL); 332 P0.H = hi(PLL_CTL);
328 P0.L = lo(PLL_CTL); 333 P0.L = lo(PLL_CTL);
329 R0 = W[P0](z); 334 R0 = W[P0](z);
330 BITSET (R0, 3); 335 BITSET (R0, 3);
331 W[P0] = R0.L; 336 W[P0] = R0.L; /* Turn CCLK OFF */
332
333 R0 = P3;
334 call _set_sic_iwr;
335
336 SSYNC; 337 SSYNC;
337 IDLE; 338 IDLE;
338 339
339 call _test_pll_locked; 340 call _test_pll_locked;
340 341
341 R0 = IWR_ENABLE(0); 342 R0 = IWR_ENABLE(0);
342 call _set_sic_iwr; 343 call _set_sic_iwr; /* Set Awake from IDLE PLL */
343 344
344 P0.H = hi(VR_CTL); 345 P0.H = hi(VR_CTL);
345 P0.L = lo(VR_CTL); 346 P0.L = lo(VR_CTL);
@@ -352,15 +353,15 @@ ENTRY(_sleep_deeper)
352 353
353 P0.H = hi(PLL_DIV); 354 P0.H = hi(PLL_DIV);
354 P0.L = lo(PLL_DIV); 355 P0.L = lo(PLL_DIV);
355 W[P0]= R6; 356 W[P0]= R6; /* Restore CCLK and SCLK divider */
356 357
357 P0.H = hi(PLL_CTL); 358 P0.H = hi(PLL_CTL);
358 P0.L = lo(PLL_CTL); 359 P0.L = lo(PLL_CTL);
359 w[p0] = R5; 360 w[p0] = R5; /* Restore VCO multiplier */
360 IDLE; 361 IDLE;
361 call _test_pll_locked; 362 call _test_pll_locked;
362 363
363 call _unset_sdram_srfs; 364 call _unset_dram_srfs; /* SDRAM Self Refresh Off */
364 365
365 STI R4; 366 STI R4;
366 367
@@ -368,25 +369,47 @@ ENTRY(_sleep_deeper)
368 ( R7:0, P5:0 ) = [SP++]; 369 ( R7:0, P5:0 ) = [SP++];
369 RTS; 370 RTS;
370 371
371ENTRY(_set_sdram_srfs) 372ENTRY(_set_dram_srfs)
372 /* set the sdram to self refresh mode */ 373 /* set the dram to self refresh mode */
374#if defined(CONFIG_BF54x)
375 P0.H = hi(EBIU_RSTCTL);
376 P0.L = lo(EBIU_RSTCTL);
377 R2 = [P0];
378 R3.H = hi(SRREQ);
379 R3.L = lo(SRREQ);
380#else
373 P0.H = hi(EBIU_SDGCTL); 381 P0.H = hi(EBIU_SDGCTL);
374 P0.L = lo(EBIU_SDGCTL); 382 P0.L = lo(EBIU_SDGCTL);
375 R2 = [P0]; 383 R2 = [P0];
376 R3.H = hi(SRFS); 384 R3.H = hi(SRFS);
377 R3.L = lo(SRFS); 385 R3.L = lo(SRFS);
386#endif
378 R2 = R2|R3; 387 R2 = R2|R3;
379 [P0] = R2; 388 [P0] = R2;
380 ssync; 389 ssync;
390#if defined(CONFIG_BF54x)
391.LSRR_MODE:
392 R2 = [P0];
393 CC = BITTST(R2, 4);
394 if !CC JUMP .LSRR_MODE;
395#endif
381 RTS; 396 RTS;
382 397
383ENTRY(_unset_sdram_srfs) 398ENTRY(_unset_dram_srfs)
384 /* set the sdram out of self refresh mode */ 399 /* set the dram out of self refresh mode */
400#if defined(CONFIG_BF54x)
401 P0.H = hi(EBIU_RSTCTL);
402 P0.L = lo(EBIU_RSTCTL);
403 R2 = [P0];
404 R3.H = hi(SRREQ);
405 R3.L = lo(SRREQ);
406#else
385 P0.H = hi(EBIU_SDGCTL); 407 P0.H = hi(EBIU_SDGCTL);
386 P0.L = lo(EBIU_SDGCTL); 408 P0.L = lo(EBIU_SDGCTL);
387 R2 = [P0]; 409 R2 = [P0];
388 R3.H = hi(SRFS); 410 R3.H = hi(SRFS);
389 R3.L = lo(SRFS); 411 R3.L = lo(SRFS);
412#endif
390 R3 = ~R3; 413 R3 = ~R3;
391 R2 = R2&R3; 414 R2 = R2&R3;
392 [P0] = R2; 415 [P0] = R2;
@@ -394,8 +417,13 @@ ENTRY(_unset_sdram_srfs)
394 RTS; 417 RTS;
395 418
396ENTRY(_set_sic_iwr) 419ENTRY(_set_sic_iwr)
420#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x)
421 P0.H = hi(SIC_IWR0);
422 P0.L = lo(SIC_IWR0);
423#else
397 P0.H = hi(SIC_IWR); 424 P0.H = hi(SIC_IWR);
398 P0.L = lo(SIC_IWR); 425 P0.L = lo(SIC_IWR);
426#endif
399 [P0] = R0; 427 [P0] = R0;
400 SSYNC; 428 SSYNC;
401 RTS; 429 RTS;
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
index dc9d3ee2e691..56ff51bc8c21 100644
--- a/arch/blackfin/mach-common/entry.S
+++ b/arch/blackfin/mach-common/entry.S
@@ -95,6 +95,9 @@ ENTRY(_ex_workaround_261)
95 R6 = 0x26; /* Data CPLB Miss */ 95 R6 = 0x26; /* Data CPLB Miss */
96 cc = R6 == R7; 96 cc = R6 == R7;
97 if cc jump _ex_dcplb_miss (BP); 97 if cc jump _ex_dcplb_miss (BP);
98 R6 = 0x23; /* Data CPLB Miss */
99 cc = R6 == R7;
100 if cc jump _ex_dcplb_viol (BP);
98 /* Handle 0x23 Data CPLB Protection Violation 101 /* Handle 0x23 Data CPLB Protection Violation
99 * and Data CPLB Multiple Hits - Linux Trap Zero 102 * and Data CPLB Multiple Hits - Linux Trap Zero
100 */ 103 */
@@ -102,17 +105,33 @@ ENTRY(_ex_workaround_261)
102ENDPROC(_ex_workaround_261) 105ENDPROC(_ex_workaround_261)
103 106
104#else 107#else
108#ifdef CONFIG_MPU
109#define _ex_dviol _ex_dcplb_viol
110#else
105#define _ex_dviol _ex_trap_c 111#define _ex_dviol _ex_trap_c
112#endif
106#define _ex_dmiss _ex_dcplb_miss 113#define _ex_dmiss _ex_dcplb_miss
107#define _ex_dmult _ex_trap_c 114#define _ex_dmult _ex_trap_c
108#endif 115#endif
109 116
117
118ENTRY(_ex_dcplb_viol)
110ENTRY(_ex_dcplb_miss) 119ENTRY(_ex_dcplb_miss)
111ENTRY(_ex_icplb_miss) 120ENTRY(_ex_icplb_miss)
112 (R7:6,P5:4) = [sp++]; 121 (R7:6,P5:4) = [sp++];
113 ASTAT = [sp++]; 122 ASTAT = [sp++];
114 SAVE_ALL_SYS 123 SAVE_ALL_SYS
124#ifdef CONFIG_MPU
125 R0 = SEQSTAT;
126 R1 = SP;
127 sp += -12;
128 call _cplb_hdr;
129 sp += 12;
130 CC = R0 == 0;
131 IF !CC JUMP _handle_bad_cplb;
132#else
115 call __cplb_hdr; 133 call __cplb_hdr;
134#endif
116 DEBUG_START_HWTRACE(p5, r7) 135 DEBUG_START_HWTRACE(p5, r7)
117 RESTORE_ALL_SYS 136 RESTORE_ALL_SYS
118 SP = EX_SCRATCH_REG; 137 SP = EX_SCRATCH_REG;
@@ -329,7 +348,7 @@ ENTRY(_exception_to_level5)
329 R7 = R7 + R6; 348 R7 = R7 + R6;
330 P5 = R7; 349 P5 = R7;
331 R1 = [P5]; 350 R1 = [P5];
332 [SP + 8] = r1; 351 [SP + PT_SEQSTAT] = r1;
333 352
334 r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */ 353 r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */
335 SP += -12; 354 SP += -12;
@@ -633,9 +652,7 @@ ENTRY(_ret_from_exception)
633 [sp + PT_IPEND] = r0; 652 [sp + PT_IPEND] = r0;
634 653
6351: 6541:
636 r1 = 0x37(Z); 655 r2 = LO(~0x37) (Z);
637 r2 = ~r1;
638 r2.h = 0;
639 r0 = r2 & r0; 656 r0 = r2 & r0;
640 cc = r0 == 0; 657 cc = r0 == 0;
641 if !cc jump 4f; /* if not return to user mode, get out */ 658 if !cc jump 4f; /* if not return to user mode, get out */
@@ -1364,6 +1381,7 @@ ENTRY(_sys_call_table)
1364 .long _sys_set_robust_list 1381 .long _sys_set_robust_list
1365 .long _sys_get_robust_list /* 355 */ 1382 .long _sys_get_robust_list /* 355 */
1366 .long _sys_fallocate 1383 .long _sys_fallocate
1384 .long _sys_semtimedop
1367 .rept NR_syscalls-(.-_sys_call_table)/4 1385 .rept NR_syscalls-(.-_sys_call_table)/4
1368 .long _sys_ni_syscall 1386 .long _sys_ni_syscall
1369 .endr 1387 .endr
diff --git a/arch/blackfin/mach-common/interrupt.S b/arch/blackfin/mach-common/interrupt.S
index 4de376418a18..7f752c87fe46 100644
--- a/arch/blackfin/mach-common/interrupt.S
+++ b/arch/blackfin/mach-common/interrupt.S
@@ -34,9 +34,13 @@
34#include <asm/entry.h> 34#include <asm/entry.h>
35#include <asm/asm-offsets.h> 35#include <asm/asm-offsets.h>
36#include <asm/trace.h> 36#include <asm/trace.h>
37#include <asm/traps.h>
38#include <asm/thread_info.h>
37 39
38#include <asm/mach-common/context.S> 40#include <asm/mach-common/context.S>
39 41
42.extern _ret_from_exception
43
40#ifdef CONFIG_I_ENTRY_L1 44#ifdef CONFIG_I_ENTRY_L1
41.section .l1.text 45.section .l1.text
42#else 46#else
@@ -117,8 +121,8 @@ __common_int_entry:
117 121
118#if ANOMALY_05000283 || ANOMALY_05000315 122#if ANOMALY_05000283 || ANOMALY_05000315
119 cc = r7 == r7; 123 cc = r7 == r7;
120 p5.h = 0xffc0; 124 p5.h = HI(CHIPID);
121 p5.l = 0x0014; 125 p5.l = LO(CHIPID);
122 if cc jump 1f; 126 if cc jump 1f;
123 r7.l = W[p5]; 127 r7.l = W[p5];
1241: 1281:
@@ -134,26 +138,22 @@ __common_int_entry:
134 138
135/* interrupt routine for ivhw - 5 */ 139/* interrupt routine for ivhw - 5 */
136ENTRY(_evt_ivhw) 140ENTRY(_evt_ivhw)
137 SAVE_CONTEXT 141 SAVE_ALL_SYS
138#ifdef CONFIG_FRAME_POINTER 142#ifdef CONFIG_FRAME_POINTER
139 fp = 0; 143 fp = 0;
140#endif 144#endif
145
141#if ANOMALY_05000283 146#if ANOMALY_05000283
142 cc = r7 == r7; 147 cc = r7 == r7;
143 p5.h = 0xffc0; 148 p5.h = HI(CHIPID);
144 p5.l = 0x0014; 149 p5.l = LO(CHIPID);
145 if cc jump 1f; 150 if cc jump 1f;
146 r7.l = W[p5]; 151 r7.l = W[p5];
1471: 1521:
148#endif 153#endif
149 154
150 trace_buffer_stop(p0, r0);
151
152 r0 = IRQ_HWERR;
153 r1 = sp;
154
155#ifdef CONFIG_HARDWARE_PM 155#ifdef CONFIG_HARDWARE_PM
156 r7 = SEQSTAT; 156 r7 = [sp + PT_SEQSTAT];
157 r7 = r7 >>> 0xe; 157 r7 = r7 >>> 0xe;
158 r6 = 0x1F; 158 r6 = 0x1F;
159 r7 = r7 & r6; 159 r7 = r7 & r6;
@@ -161,11 +161,29 @@ ENTRY(_evt_ivhw)
161 cc = r7 == r5; 161 cc = r7 == r5;
162 if cc jump .Lcall_do_ovf; /* deal with performance counter overflow */ 162 if cc jump .Lcall_do_ovf; /* deal with performance counter overflow */
163#endif 163#endif
164 164 # We are going to dump something out, so make sure we print IPEND properly
165 p2.l = lo(IPEND);
166 p2.h = hi(IPEND);
167 r0 = [p2];
168 [sp + PT_IPEND] = r0;
169
170 /* set the EXCAUSE to HWERR for trap_c */
171 r0 = [sp + PT_SEQSTAT];
172 R1.L = LO(VEC_HWERR);
173 R1.H = HI(VEC_HWERR);
174 R0 = R0 | R1;
175 [sp + PT_SEQSTAT] = R0;
176
177 r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */
165 SP += -12; 178 SP += -12;
166 call _irq_panic; 179 call _trap_c;
167 SP += 12; 180 SP += 12;
181
182 call _ret_from_exception;
183.Lcommon_restore_all_sys:
184 RESTORE_ALL_SYS
168 rti; 185 rti;
186
169#ifdef CONFIG_HARDWARE_PM 187#ifdef CONFIG_HARDWARE_PM
170.Lcall_do_ovf: 188.Lcall_do_ovf:
171 189
@@ -173,9 +191,11 @@ ENTRY(_evt_ivhw)
173 call _pm_overflow; 191 call _pm_overflow;
174 SP += 12; 192 SP += 12;
175 193
176 jump .Lcommon_restore_context; 194 jump .Lcommon_restore_all_sys;
177#endif 195#endif
178 196
197ENDPROC(_evt_ivhw)
198
179/* Interrupt routine for evt2 (NMI). 199/* Interrupt routine for evt2 (NMI).
180 * We don't actually use this, so just return. 200 * We don't actually use this, so just return.
181 * For inner circle type details, please see: 201 * For inner circle type details, please see:
diff --git a/arch/blackfin/mach-common/ints-priority-dc.c b/arch/blackfin/mach-common/ints-priority-dc.c
index 4882f0e801a9..8d18d6b163bb 100644
--- a/arch/blackfin/mach-common/ints-priority-dc.c
+++ b/arch/blackfin/mach-common/ints-priority-dc.c
@@ -222,11 +222,12 @@ static void bf561_gpio_unmask_irq(unsigned int irq)
222static unsigned int bf561_gpio_irq_startup(unsigned int irq) 222static unsigned int bf561_gpio_irq_startup(unsigned int irq)
223{ 223{
224 unsigned int ret; 224 unsigned int ret;
225 char buf[8];
225 u16 gpionr = irq - IRQ_PF0; 226 u16 gpionr = irq - IRQ_PF0;
226 227
227 if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { 228 if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
228 229 snprintf(buf, sizeof buf, "IRQ %d", irq);
229 ret = gpio_request(gpionr, "IRQ"); 230 ret = gpio_request(gpionr, buf);
230 if (ret) 231 if (ret)
231 return ret; 232 return ret;
232 233
@@ -250,6 +251,7 @@ static int bf561_gpio_irq_type(unsigned int irq, unsigned int type)
250{ 251{
251 252
252 unsigned int ret; 253 unsigned int ret;
254 char buf[8];
253 u16 gpionr = irq - IRQ_PF0; 255 u16 gpionr = irq - IRQ_PF0;
254 256
255 257
@@ -265,8 +267,8 @@ static int bf561_gpio_irq_type(unsigned int irq, unsigned int type)
265 IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { 267 IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
266 268
267 if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { 269 if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
268 270 snprintf(buf, sizeof buf, "IRQ %d", irq);
269 ret = gpio_request(gpionr, "IRQ"); 271 ret = gpio_request(gpionr, buf);
270 if (ret) 272 if (ret)
271 return ret; 273 return ret;
272 274
diff --git a/arch/blackfin/mach-common/ints-priority-sc.c b/arch/blackfin/mach-common/ints-priority-sc.c
index 147f0731087a..dec42acb5de0 100644
--- a/arch/blackfin/mach-common/ints-priority-sc.c
+++ b/arch/blackfin/mach-common/ints-priority-sc.c
@@ -313,6 +313,7 @@ static void bfin_demux_error_irq(unsigned int int_err_irq,
313static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)]; 313static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)];
314static unsigned short gpio_edge_triggered[gpio_bank(MAX_BLACKFIN_GPIOS)]; 314static unsigned short gpio_edge_triggered[gpio_bank(MAX_BLACKFIN_GPIOS)];
315 315
316
316static void bfin_gpio_ack_irq(unsigned int irq) 317static void bfin_gpio_ack_irq(unsigned int irq)
317{ 318{
318 u16 gpionr = irq - IRQ_PF0; 319 u16 gpionr = irq - IRQ_PF0;
@@ -352,9 +353,11 @@ static unsigned int bfin_gpio_irq_startup(unsigned int irq)
352{ 353{
353 unsigned int ret; 354 unsigned int ret;
354 u16 gpionr = irq - IRQ_PF0; 355 u16 gpionr = irq - IRQ_PF0;
356 char buf[8];
355 357
356 if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { 358 if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
357 ret = gpio_request(gpionr, "IRQ"); 359 snprintf(buf, sizeof buf, "IRQ %d", irq);
360 ret = gpio_request(gpionr, buf);
358 if (ret) 361 if (ret)
359 return ret; 362 return ret;
360 } 363 }
@@ -376,6 +379,7 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
376{ 379{
377 380
378 unsigned int ret; 381 unsigned int ret;
382 char buf[8];
379 u16 gpionr = irq - IRQ_PF0; 383 u16 gpionr = irq - IRQ_PF0;
380 384
381 if (type == IRQ_TYPE_PROBE) { 385 if (type == IRQ_TYPE_PROBE) {
@@ -388,7 +392,8 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
388 if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | 392 if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING |
389 IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { 393 IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
390 if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { 394 if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
391 ret = gpio_request(gpionr, "IRQ"); 395 snprintf(buf, sizeof buf, "IRQ %d", irq);
396 ret = gpio_request(gpionr, buf);
392 if (ret) 397 if (ret)
393 return ret; 398 return ret;
394 } 399 }
@@ -478,6 +483,10 @@ static void bfin_demux_gpio_irq(unsigned int intb_irq,
478static unsigned char irq2pint_lut[NR_PINTS]; 483static unsigned char irq2pint_lut[NR_PINTS];
479static unsigned char pint2irq_lut[NR_PINT_SYS_IRQS * NR_PINT_BITS]; 484static unsigned char pint2irq_lut[NR_PINT_SYS_IRQS * NR_PINT_BITS];
480 485
486static unsigned int gpio_both_edge_triggered[NR_PINT_SYS_IRQS];
487static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)];
488
489
481struct pin_int_t { 490struct pin_int_t {
482 unsigned int mask_set; 491 unsigned int mask_set;
483 unsigned int mask_clear; 492 unsigned int mask_clear;
@@ -544,13 +553,20 @@ void init_pint_lut(void)
544 553
545} 554}
546 555
547static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)];
548
549static void bfin_gpio_ack_irq(unsigned int irq) 556static void bfin_gpio_ack_irq(unsigned int irq)
550{ 557{
551 u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; 558 u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
559 u32 pintbit = PINT_BIT(pint_val);
560 u8 bank = PINT_2_BANK(pint_val);
561
562 if (unlikely(gpio_both_edge_triggered[bank] & pintbit)) {
563 if (pint[bank]->invert_set & pintbit)
564 pint[bank]->invert_clear = pintbit;
565 else
566 pint[bank]->invert_set = pintbit;
567 }
568 pint[bank]->request = pintbit;
552 569
553 pint[PINT_2_BANK(pint_val)]->request = PINT_BIT(pint_val);
554 SSYNC(); 570 SSYNC();
555} 571}
556 572
@@ -560,6 +576,13 @@ static void bfin_gpio_mask_ack_irq(unsigned int irq)
560 u32 pintbit = PINT_BIT(pint_val); 576 u32 pintbit = PINT_BIT(pint_val);
561 u8 bank = PINT_2_BANK(pint_val); 577 u8 bank = PINT_2_BANK(pint_val);
562 578
579 if (unlikely(gpio_both_edge_triggered[bank] & pintbit)) {
580 if (pint[bank]->invert_set & pintbit)
581 pint[bank]->invert_clear = pintbit;
582 else
583 pint[bank]->invert_set = pintbit;
584 }
585
563 pint[bank]->request = pintbit; 586 pint[bank]->request = pintbit;
564 pint[bank]->mask_clear = pintbit; 587 pint[bank]->mask_clear = pintbit;
565 SSYNC(); 588 SSYNC();
@@ -587,7 +610,8 @@ static void bfin_gpio_unmask_irq(unsigned int irq)
587static unsigned int bfin_gpio_irq_startup(unsigned int irq) 610static unsigned int bfin_gpio_irq_startup(unsigned int irq)
588{ 611{
589 unsigned int ret; 612 unsigned int ret;
590 u16 gpionr = irq - IRQ_PA0; 613 char buf[8];
614 u16 gpionr = irq_to_gpio(irq);
591 u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; 615 u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
592 616
593 if (pint_val == IRQ_NOT_AVAIL) { 617 if (pint_val == IRQ_NOT_AVAIL) {
@@ -598,7 +622,8 @@ static unsigned int bfin_gpio_irq_startup(unsigned int irq)
598 } 622 }
599 623
600 if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { 624 if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
601 ret = gpio_request(gpionr, "IRQ"); 625 snprintf(buf, sizeof buf, "IRQ %d", irq);
626 ret = gpio_request(gpionr, buf);
602 if (ret) 627 if (ret)
603 return ret; 628 return ret;
604 } 629 }
@@ -611,16 +636,19 @@ static unsigned int bfin_gpio_irq_startup(unsigned int irq)
611 636
612static void bfin_gpio_irq_shutdown(unsigned int irq) 637static void bfin_gpio_irq_shutdown(unsigned int irq)
613{ 638{
639 u16 gpionr = irq_to_gpio(irq);
640
614 bfin_gpio_mask_irq(irq); 641 bfin_gpio_mask_irq(irq);
615 gpio_free(irq - IRQ_PA0); 642 gpio_free(gpionr);
616 gpio_enabled[gpio_bank(irq - IRQ_PA0)] &= ~gpio_bit(irq - IRQ_PA0); 643 gpio_enabled[gpio_bank(gpionr)] &= ~gpio_bit(gpionr);
617} 644}
618 645
619static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) 646static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
620{ 647{
621 648
622 unsigned int ret; 649 unsigned int ret;
623 u16 gpionr = irq - IRQ_PA0; 650 char buf[8];
651 u16 gpionr = irq_to_gpio(irq);
624 u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; 652 u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
625 u32 pintbit = PINT_BIT(pint_val); 653 u32 pintbit = PINT_BIT(pint_val);
626 u8 bank = PINT_2_BANK(pint_val); 654 u8 bank = PINT_2_BANK(pint_val);
@@ -638,7 +666,8 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
638 if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | 666 if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING |
639 IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { 667 IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
640 if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { 668 if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
641 ret = gpio_request(gpionr, "IRQ"); 669 snprintf(buf, sizeof buf, "IRQ %d", irq);
670 ret = gpio_request(gpionr, buf);
642 if (ret) 671 if (ret)
643 return ret; 672 return ret;
644 } 673 }
@@ -651,28 +680,33 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
651 680
652 gpio_direction_input(gpionr); 681 gpio_direction_input(gpionr);
653 682
654 if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
655 pint[bank]->edge_set = pintbit;
656 } else {
657 pint[bank]->edge_clear = pintbit;
658 }
659
660 if ((type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW))) 683 if ((type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW)))
661 pint[bank]->invert_set = pintbit; /* low or falling edge denoted by one */ 684 pint[bank]->invert_set = pintbit; /* low or falling edge denoted by one */
662 else 685 else
663 pint[bank]->invert_set = pintbit; /* high or rising edge denoted by zero */ 686 pint[bank]->invert_clear = pintbit; /* high or rising edge denoted by zero */
664 687
665 if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) 688 if ((type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
666 pint[bank]->invert_set = pintbit; 689 == (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
667 else
668 pint[bank]->invert_set = pintbit;
669 690
670 SSYNC(); 691 gpio_both_edge_triggered[bank] |= pintbit;
671 692
672 if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) 693 if (gpio_get_value(gpionr))
694 pint[bank]->invert_set = pintbit;
695 else
696 pint[bank]->invert_clear = pintbit;
697 } else {
698 gpio_both_edge_triggered[bank] &= ~pintbit;
699 }
700
701 if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
702 pint[bank]->edge_set = pintbit;
673 set_irq_handler(irq, handle_edge_irq); 703 set_irq_handler(irq, handle_edge_irq);
674 else 704 } else {
705 pint[bank]->edge_clear = pintbit;
675 set_irq_handler(irq, handle_level_irq); 706 set_irq_handler(irq, handle_level_irq);
707 }
708
709 SSYNC();
676 710
677 return 0; 711 return 0;
678} 712}
diff --git a/arch/blackfin/mach-common/irqpanic.c b/arch/blackfin/mach-common/irqpanic.c
index b22959b197e5..606ded9ff4e1 100644
--- a/arch/blackfin/mach-common/irqpanic.c
+++ b/arch/blackfin/mach-common/irqpanic.c
@@ -46,9 +46,6 @@ void irq_panic(int reason, struct pt_regs *regs) __attribute__ ((l1_text));
46 */ 46 */
47asmlinkage void irq_panic(int reason, struct pt_regs *regs) 47asmlinkage void irq_panic(int reason, struct pt_regs *regs)
48{ 48{
49 int sig = 0;
50 siginfo_t info;
51
52#ifdef CONFIG_DEBUG_ICACHE_CHECK 49#ifdef CONFIG_DEBUG_ICACHE_CHECK
53 unsigned int cmd, tag, ca, cache_hi, cache_lo, *pa; 50 unsigned int cmd, tag, ca, cache_hi, cache_lo, *pa;
54 unsigned short i, j, die; 51 unsigned short i, j, die;
@@ -136,53 +133,6 @@ asmlinkage void irq_panic(int reason, struct pt_regs *regs)
136 } 133 }
137#endif 134#endif
138 135
139 printk(KERN_EMERG "\n");
140 printk(KERN_EMERG "Exception: IRQ 0x%x entered\n", reason);
141 printk(KERN_EMERG " code=[0x%08lx], stack frame=0x%08lx, "
142 " bad PC=0x%08lx\n",
143 (unsigned long)regs->seqstat,
144 (unsigned long)regs,
145 (unsigned long)regs->pc);
146 if (reason == 0x5) {
147 printk(KERN_EMERG "----------- HARDWARE ERROR -----------\n");
148
149 /* There is only need to check for Hardware Errors, since other
150 * EXCEPTIONS are handled in TRAPS.c (MH)
151 */
152 switch (regs->seqstat & SEQSTAT_HWERRCAUSE) {
153 case (SEQSTAT_HWERRCAUSE_SYSTEM_MMR): /* System MMR Error */
154 info.si_code = BUS_ADRALN;
155 sig = SIGBUS;
156 printk(KERN_EMERG HWC_x2(KERN_EMERG));
157 break;
158 case (SEQSTAT_HWERRCAUSE_EXTERN_ADDR): /* External Memory Addressing Error */
159 info.si_code = BUS_ADRERR;
160 sig = SIGBUS;
161 printk(KERN_EMERG HWC_x3(KERN_EMERG));
162 break;
163 case (SEQSTAT_HWERRCAUSE_PERF_FLOW): /* Performance Monitor Overflow */
164 printk(KERN_EMERG HWC_x12(KERN_EMERG));
165 break;
166 case (SEQSTAT_HWERRCAUSE_RAISE_5): /* RAISE 5 instruction */
167 printk(KERN_EMERG HWC_x18(KERN_EMERG));
168 break;
169 default: /* Reserved */
170 printk(KERN_EMERG HWC_default(KERN_EMERG));
171 break;
172 }
173 }
174
175 regs->ipend = bfin_read_IPEND();
176 dump_bfin_process(regs);
177 dump_bfin_mem((void *)regs->pc);
178 show_regs(regs);
179 if (0 == (info.si_signo = sig) || 0 == user_mode(regs)) /* in kernelspace */
180 panic("Unhandled IRQ or exceptions!\n");
181 else { /* in userspace */
182 info.si_errno = 0;
183 info.si_addr = (void *)regs->pc;
184 force_sig_info(sig, &info, current);
185 }
186} 136}
187 137
188#ifdef CONFIG_HARDWARE_PM 138#ifdef CONFIG_HARDWARE_PM
diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c
index dac51fb06f22..81930f7d06f1 100644
--- a/arch/blackfin/mach-common/pm.c
+++ b/arch/blackfin/mach-common/pm.c
@@ -77,7 +77,15 @@ void bfin_pm_suspend_standby_enter(void)
77 77
78 gpio_pm_restore(); 78 gpio_pm_restore();
79 79
80#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x)
81 bfin_write_SIC_IWR0(IWR_ENABLE_ALL);
82 bfin_write_SIC_IWR1(IWR_ENABLE_ALL);
83# ifdef CONFIG_BF54x
84 bfin_write_SIC_IWR2(IWR_ENABLE_ALL);
85# endif
86#else
80 bfin_write_SIC_IWR(IWR_ENABLE_ALL); 87 bfin_write_SIC_IWR(IWR_ENABLE_ALL);
88#endif
81 89
82 local_irq_restore(flags); 90 local_irq_restore(flags);
83 } 91 }
@@ -85,7 +93,15 @@ void bfin_pm_suspend_standby_enter(void)
85 93
86#if defined(CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR) 94#if defined(CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR)
87 sleep_deeper(CONFIG_PM_WAKEUP_SIC_IWR); 95 sleep_deeper(CONFIG_PM_WAKEUP_SIC_IWR);
96# if defined(CONFIG_BF54x) || defined(CONFIG_BF52x)
97 bfin_write_SIC_IWR0(IWR_ENABLE_ALL);
98 bfin_write_SIC_IWR1(IWR_ENABLE_ALL);
99# ifdef CONFIG_BF54x
100 bfin_write_SIC_IWR2(IWR_ENABLE_ALL);
101# endif
102# else
88 bfin_write_SIC_IWR(IWR_ENABLE_ALL); 103 bfin_write_SIC_IWR(IWR_ENABLE_ALL);
104# endif
89#endif /* CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR */ 105#endif /* CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR */
90} 106}
91 107
diff --git a/arch/blackfin/mm/init.c b/arch/blackfin/mm/init.c
index e97ea8fc8dc4..eb1a12ac9e33 100644
--- a/arch/blackfin/mm/init.c
+++ b/arch/blackfin/mm/init.c
@@ -128,8 +128,8 @@ void __init paging_init(void)
128void __init mem_init(void) 128void __init mem_init(void)
129{ 129{
130 unsigned int codek = 0, datak = 0, initk = 0; 130 unsigned int codek = 0, datak = 0, initk = 0;
131 unsigned int reservedpages = 0, freepages = 0;
131 unsigned long tmp; 132 unsigned long tmp;
132 unsigned int len = _ramend - _rambase;
133 unsigned long start_mem = memory_start; 133 unsigned long start_mem = memory_start;
134 unsigned long end_mem = memory_end; 134 unsigned long end_mem = memory_end;
135 135
@@ -138,19 +138,36 @@ void __init mem_init(void)
138 138
139 start_mem = PAGE_ALIGN(start_mem); 139 start_mem = PAGE_ALIGN(start_mem);
140 max_mapnr = num_physpages = MAP_NR(high_memory); 140 max_mapnr = num_physpages = MAP_NR(high_memory);
141 printk(KERN_INFO "Physical pages: %lx\n", num_physpages); 141 printk(KERN_INFO "Kernel managed physical pages: %lu\n",
142 num_physpages);
142 143
143 /* This will put all memory onto the freelists. */ 144 /* This will put all memory onto the freelists. */
144 totalram_pages = free_all_bootmem(); 145 totalram_pages = free_all_bootmem();
145 146
147 reservedpages = 0;
148 for (tmp = 0; tmp < max_mapnr; tmp++)
149 if (PageReserved(pfn_to_page(tmp)))
150 reservedpages++;
151 freepages = max_mapnr - reservedpages;
152
153 /* do not count in kernel image between _rambase and _ramstart */
154 reservedpages -= (_ramstart - _rambase) >> PAGE_SHIFT;
155#if (defined(CONFIG_BFIN_ICACHE) && ANOMALY_05000263)
156 reservedpages += (_ramend - memory_end - DMA_UNCACHED_REGION) >>
157 PAGE_SHIFT;
158#endif
159
146 codek = (_etext - _stext) >> 10; 160 codek = (_etext - _stext) >> 10;
147 datak = (__bss_stop - __bss_start) >> 10;
148 initk = (__init_end - __init_begin) >> 10; 161 initk = (__init_end - __init_begin) >> 10;
162 datak = ((_ramstart - _rambase) >> 10) - codek - initk;
149 163
150 tmp = nr_free_pages() << PAGE_SHIFT;
151 printk(KERN_INFO 164 printk(KERN_INFO
152 "Memory available: %luk/%uk RAM, (%uk init code, %uk kernel code, %uk data, %uk dma)\n", 165 "Memory available: %luk/%luk RAM, "
153 tmp >> 10, len >> 10, initk, codek, datak, DMA_UNCACHED_REGION >> 10); 166 "(%uk init code, %uk kernel code, "
167 "%uk data, %uk dma, %uk reserved)\n",
168 (unsigned long) freepages << (PAGE_SHIFT-10), _ramend >> 10,
169 initk, codek, datak, DMA_UNCACHED_REGION >> 10,
170 (reservedpages << (PAGE_SHIFT-10)));
154 171
155 /* Initialize the blackfin L1 Memory. */ 172 /* Initialize the blackfin L1 Memory. */
156 l1sram_init(); 173 l1sram_init();
@@ -184,13 +201,15 @@ static __init void free_init_pages(const char *what, unsigned long begin, unsign
184#ifdef CONFIG_BLK_DEV_INITRD 201#ifdef CONFIG_BLK_DEV_INITRD
185void __init free_initrd_mem(unsigned long start, unsigned long end) 202void __init free_initrd_mem(unsigned long start, unsigned long end)
186{ 203{
204#ifndef CONFIG_MPU
187 free_init_pages("initrd memory", start, end); 205 free_init_pages("initrd memory", start, end);
206#endif
188} 207}
189#endif 208#endif
190 209
191void __init free_initmem(void) 210void __init free_initmem(void)
192{ 211{
193#ifdef CONFIG_RAMKERNEL 212#if defined CONFIG_RAMKERNEL && !defined CONFIG_MPU
194 free_init_pages("unused kernel memory", 213 free_init_pages("unused kernel memory",
195 (unsigned long)(&__init_begin), 214 (unsigned long)(&__init_begin),
196 (unsigned long)(&__init_end)); 215 (unsigned long)(&__init_end));
diff --git a/arch/cris/arch-v10/vmlinux.lds.S b/arch/cris/arch-v10/vmlinux.lds.S
index 97a7876ed681..93c9f0ea286b 100644
--- a/arch/cris/arch-v10/vmlinux.lds.S
+++ b/arch/cris/arch-v10/vmlinux.lds.S
@@ -57,10 +57,10 @@ SECTIONS
57 __init_begin = .; 57 __init_begin = .;
58 .init.text : { 58 .init.text : {
59 _sinittext = .; 59 _sinittext = .;
60 *(.init.text) 60 INIT_TEXT
61 _einittext = .; 61 _einittext = .;
62 } 62 }
63 .init.data : { *(.init.data) } 63 .init.data : { INIT_DATA }
64 . = ALIGN(16); 64 . = ALIGN(16);
65 __setup_start = .; 65 __setup_start = .;
66 .init.setup : { *(.init.setup) } 66 .init.setup : { *(.init.setup) }
@@ -109,8 +109,8 @@ SECTIONS
109 109
110 /* Sections to be discarded */ 110 /* Sections to be discarded */
111 /DISCARD/ : { 111 /DISCARD/ : {
112 *(.text.exit) 112 EXIT_TEXT
113 *(.data.exit) 113 EXIT_DATA
114 *(.exitcall.exit) 114 *(.exitcall.exit)
115 } 115 }
116 116
diff --git a/arch/cris/arch-v32/boot/compressed/Makefile b/arch/cris/arch-v32/boot/compressed/Makefile
index 9f77eda914ba..609692f9d5eb 100644
--- a/arch/cris/arch-v32/boot/compressed/Makefile
+++ b/arch/cris/arch-v32/boot/compressed/Makefile
@@ -7,7 +7,7 @@
7target = $(target_compressed_dir) 7target = $(target_compressed_dir)
8src = $(src_compressed_dir) 8src = $(src_compressed_dir)
9 9
10CC = gcc-cris -mlinux -march=v32 -I $(TOPDIR)/include 10CC = gcc-cris -mlinux -march=v32 $(LINUXINCLUDE)
11CFLAGS = -O2 11CFLAGS = -O2
12LD = gcc-cris -mlinux -march=v32 -nostdlib 12LD = gcc-cris -mlinux -march=v32 -nostdlib
13OBJCOPY = objcopy-cris 13OBJCOPY = objcopy-cris
diff --git a/arch/cris/arch-v32/drivers/iop_fw_load.c b/arch/cris/arch-v32/drivers/iop_fw_load.c
index 11f9895ded50..f4bdc1dfa320 100644
--- a/arch/cris/arch-v32/drivers/iop_fw_load.c
+++ b/arch/cris/arch-v32/drivers/iop_fw_load.c
@@ -20,6 +20,9 @@
20 20
21#define IOP_TIMEOUT 100 21#define IOP_TIMEOUT 100
22 22
23#error "This driver is broken with regard to its driver core usage."
24#error "Please contact <greg@kroah.com> for details on how to fix it properly."
25
23static struct device iop_spu_device[2] = { 26static struct device iop_spu_device[2] = {
24 { .bus_id = "iop-spu0", }, 27 { .bus_id = "iop-spu0", },
25 { .bus_id = "iop-spu1", }, 28 { .bus_id = "iop-spu1", },
@@ -192,6 +195,13 @@ int iop_start_mpu(unsigned int start_addr)
192 195
193static int __init iop_fw_load_init(void) 196static int __init iop_fw_load_init(void)
194{ 197{
198#if 0
199 /*
200 * static struct devices can not be added directly to sysfs by ignoring
201 * the driver model infrastructure. To fix this properly, please use
202 * the platform_bus to register these devices to be able to properly
203 * use the firmware infrastructure.
204 */
195 device_initialize(&iop_spu_device[0]); 205 device_initialize(&iop_spu_device[0]);
196 kobject_set_name(&iop_spu_device[0].kobj, "iop-spu0"); 206 kobject_set_name(&iop_spu_device[0].kobj, "iop-spu0");
197 kobject_add(&iop_spu_device[0].kobj); 207 kobject_add(&iop_spu_device[0].kobj);
@@ -201,6 +211,7 @@ static int __init iop_fw_load_init(void)
201 device_initialize(&iop_mpu_device); 211 device_initialize(&iop_mpu_device);
202 kobject_set_name(&iop_mpu_device.kobj, "iop-mpu"); 212 kobject_set_name(&iop_mpu_device.kobj, "iop-mpu");
203 kobject_add(&iop_mpu_device.kobj); 213 kobject_add(&iop_mpu_device.kobj);
214#endif
204 return 0; 215 return 0;
205} 216}
206 217
diff --git a/arch/cris/arch-v32/vmlinux.lds.S b/arch/cris/arch-v32/vmlinux.lds.S
index b076c134c0bb..fead8c59ea63 100644
--- a/arch/cris/arch-v32/vmlinux.lds.S
+++ b/arch/cris/arch-v32/vmlinux.lds.S
@@ -61,10 +61,10 @@ SECTIONS
61 __init_begin = .; 61 __init_begin = .;
62 .init.text : { 62 .init.text : {
63 _sinittext = .; 63 _sinittext = .;
64 *(.init.text) 64 INIT_TEXT
65 _einittext = .; 65 _einittext = .;
66 } 66 }
67 .init.data : { *(.init.data) } 67 .init.data : { INIT_DATA }
68 . = ALIGN(16); 68 . = ALIGN(16);
69 __setup_start = .; 69 __setup_start = .;
70 .init.setup : { *(.init.setup) } 70 .init.setup : { *(.init.setup) }
@@ -124,8 +124,8 @@ SECTIONS
124 124
125 /* Sections to be discarded */ 125 /* Sections to be discarded */
126 /DISCARD/ : { 126 /DISCARD/ : {
127 *(.text.exit) 127 EXIT_TEXT
128 *(.data.exit) 128 EXIT_DATA
129 *(.exitcall.exit) 129 *(.exitcall.exit)
130 } 130 }
131 131
diff --git a/arch/frv/boot/Makefile b/arch/frv/boot/Makefile
index dc6f03824423..6ae3254da019 100644
--- a/arch/frv/boot/Makefile
+++ b/arch/frv/boot/Makefile
@@ -10,7 +10,7 @@
10 10
11targets := Image zImage bootpImage 11targets := Image zImage bootpImage
12 12
13SYSTEM =$(TOPDIR)/$(LINUX) 13SYSTEM =$(LINUX)
14 14
15ZTEXTADDR = 0x02080000 15ZTEXTADDR = 0x02080000
16PARAMS_PHYS = 0x0207c000 16PARAMS_PHYS = 0x0207c000
@@ -45,7 +45,7 @@ zImage: $(CONFIGURE) compressed/$(LINUX)
45bootpImage: bootp/bootp 45bootpImage: bootp/bootp
46 $(OBJCOPY) -O binary -R .note -R .comment -S bootp/bootp $@ 46 $(OBJCOPY) -O binary -R .note -R .comment -S bootp/bootp $@
47 47
48compressed/$(LINUX): $(TOPDIR)/$(LINUX) dep 48compressed/$(LINUX): $(LINUX) dep
49 @$(MAKE) -C compressed $(LINUX) 49 @$(MAKE) -C compressed $(LINUX)
50 50
51bootp/bootp: zImage initrd 51bootp/bootp: zImage initrd
@@ -59,10 +59,10 @@ initrd:
59# installation 59# installation
60# 60#
61install: $(CONFIGURE) Image 61install: $(CONFIGURE) Image
62 sh ./install.sh $(KERNELRELEASE) Image $(TOPDIR)/System.map "$(INSTALL_PATH)" 62 sh ./install.sh $(KERNELRELEASE) Image System.map "$(INSTALL_PATH)"
63 63
64zinstall: $(CONFIGURE) zImage 64zinstall: $(CONFIGURE) zImage
65 sh ./install.sh $(KERNELRELEASE) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)" 65 sh ./install.sh $(KERNELRELEASE) zImage System.map "$(INSTALL_PATH)"
66 66
67# 67#
68# miscellany 68# miscellany
diff --git a/arch/frv/kernel/gdb-stub.c b/arch/frv/kernel/gdb-stub.c
index e89cad1192a9..48a0393e7cee 100644
--- a/arch/frv/kernel/gdb-stub.c
+++ b/arch/frv/kernel/gdb-stub.c
@@ -87,7 +87,7 @@
87 * Example: 87 * Example:
88 * $ cd ~/linux 88 * $ cd ~/linux
89 * $ make menuconfig <go to "Kernel Hacking" and turn on remote debugging> 89 * $ make menuconfig <go to "Kernel Hacking" and turn on remote debugging>
90 * $ make dep; make vmlinux 90 * $ make vmlinux
91 * 91 *
92 * Step 3: 92 * Step 3:
93 * Download the kernel to the remote target and start 93 * Download the kernel to the remote target and start
diff --git a/arch/frv/kernel/vmlinux.lds.S b/arch/frv/kernel/vmlinux.lds.S
index a17a81d58bf6..f42b328b1dd0 100644
--- a/arch/frv/kernel/vmlinux.lds.S
+++ b/arch/frv/kernel/vmlinux.lds.S
@@ -28,14 +28,14 @@ SECTIONS
28 .init.text : { 28 .init.text : {
29 *(.text.head) 29 *(.text.head)
30#ifndef CONFIG_DEBUG_INFO 30#ifndef CONFIG_DEBUG_INFO
31 *(.init.text) 31 INIT_TEXT
32 *(.exit.text) 32 EXIT_TEXT
33 *(.exit.data) 33 EXIT_DATA
34 *(.exitcall.exit) 34 *(.exitcall.exit)
35#endif 35#endif
36 } 36 }
37 _einittext = .; 37 _einittext = .;
38 .init.data : { *(.init.data) } 38 .init.data : { INIT_DATA }
39 39
40 . = ALIGN(8); 40 . = ALIGN(8);
41 __setup_start = .; 41 __setup_start = .;
@@ -106,8 +106,8 @@ SECTIONS
106 LOCK_TEXT 106 LOCK_TEXT
107#ifdef CONFIG_DEBUG_INFO 107#ifdef CONFIG_DEBUG_INFO
108 *( 108 *(
109 .init.text 109 INIT_TEXT
110 .exit.text 110 EXIT_TEXT
111 .exitcall.exit 111 .exitcall.exit
112 ) 112 )
113#endif 113#endif
@@ -138,7 +138,7 @@ SECTIONS
138 .data : { /* Data */ 138 .data : { /* Data */
139 DATA_DATA 139 DATA_DATA
140 *(.data.*) 140 *(.data.*)
141 *(.exit.data) 141 EXIT_DATA
142 CONSTRUCTORS 142 CONSTRUCTORS
143 } 143 }
144 144
diff --git a/arch/h8300/kernel/vmlinux.lds.S b/arch/h8300/kernel/vmlinux.lds.S
index a2e72d495551..43a87b9085b6 100644
--- a/arch/h8300/kernel/vmlinux.lds.S
+++ b/arch/h8300/kernel/vmlinux.lds.S
@@ -110,9 +110,9 @@ SECTIONS
110 . = ALIGN(0x4) ; 110 . = ALIGN(0x4) ;
111 ___init_begin = .; 111 ___init_begin = .;
112 __sinittext = .; 112 __sinittext = .;
113 *(.init.text) 113 INIT_TEXT
114 __einittext = .; 114 __einittext = .;
115 *(.init.data) 115 INIT_DATA
116 . = ALIGN(0x4) ; 116 . = ALIGN(0x4) ;
117 ___setup_start = .; 117 ___setup_start = .;
118 *(.init.setup) 118 *(.init.setup)
@@ -124,8 +124,8 @@ SECTIONS
124 ___con_initcall_start = .; 124 ___con_initcall_start = .;
125 *(.con_initcall.init) 125 *(.con_initcall.init)
126 ___con_initcall_end = .; 126 ___con_initcall_end = .;
127 *(.exit.text) 127 EXIT_TEXT
128 *(.exit.data) 128 EXIT_DATA
129#if defined(CONFIG_BLK_DEV_INITRD) 129#if defined(CONFIG_BLK_DEV_INITRD)
130 . = ALIGN(4); 130 . = ALIGN(4);
131 ___initramfs_start = .; 131 ___initramfs_start = .;
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index bef47725d4ad..5a41e75ae1fe 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -42,6 +42,11 @@ config MMU
42config SWIOTLB 42config SWIOTLB
43 bool 43 bool
44 44
45config GENERIC_LOCKBREAK
46 bool
47 default y
48 depends on SMP && PREEMPT
49
45config RWSEM_XCHGADD_ALGORITHM 50config RWSEM_XCHGADD_ALGORITHM
46 bool 51 bool
47 default y 52 default y
@@ -75,6 +80,9 @@ config GENERIC_TIME_VSYSCALL
75 bool 80 bool
76 default y 81 default y
77 82
83config ARCH_SETS_UP_PER_CPU_AREA
84 def_bool y
85
78config DMI 86config DMI
79 bool 87 bool
80 default y 88 default y
diff --git a/arch/ia64/hp/sim/simeth.c b/arch/ia64/hp/sim/simeth.c
index 08b117e2c54b..9898febf609a 100644
--- a/arch/ia64/hp/sim/simeth.c
+++ b/arch/ia64/hp/sim/simeth.c
@@ -497,11 +497,6 @@ simeth_interrupt(int irq, void *dev_id)
497{ 497{
498 struct net_device *dev = dev_id; 498 struct net_device *dev = dev_id;
499 499
500 if ( dev == NULL ) {
501 printk(KERN_WARNING "simeth: irq %d for unknown device\n", irq);
502 return IRQ_NONE;
503 }
504
505 /* 500 /*
506 * very simple loop because we get interrupts only when receiving 501 * very simple loop because we get interrupts only when receiving
507 */ 502 */
diff --git a/arch/ia64/hp/sim/simscsi.c b/arch/ia64/hp/sim/simscsi.c
index 6ef9b5219930..7661bb065fa5 100644
--- a/arch/ia64/hp/sim/simscsi.c
+++ b/arch/ia64/hp/sim/simscsi.c
@@ -360,7 +360,6 @@ static struct scsi_host_template driver_template = {
360 .max_sectors = 1024, 360 .max_sectors = 1024,
361 .cmd_per_lun = SIMSCSI_REQ_QUEUE_LEN, 361 .cmd_per_lun = SIMSCSI_REQ_QUEUE_LEN,
362 .use_clustering = DISABLE_CLUSTERING, 362 .use_clustering = DISABLE_CLUSTERING,
363 .use_sg_chaining = ENABLE_SG_CHAINING,
364}; 363};
365 364
366static int __init 365static int __init
diff --git a/arch/ia64/ia32/binfmt_elf32.c b/arch/ia64/ia32/binfmt_elf32.c
index 3e35987af458..4f0c30c38e99 100644
--- a/arch/ia64/ia32/binfmt_elf32.c
+++ b/arch/ia64/ia32/binfmt_elf32.c
@@ -222,7 +222,8 @@ elf32_set_personality (void)
222} 222}
223 223
224static unsigned long 224static unsigned long
225elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type) 225elf32_map(struct file *filep, unsigned long addr, struct elf_phdr *eppnt,
226 int prot, int type, unsigned long unused)
226{ 227{
227 unsigned long pgoff = (eppnt->p_vaddr) & ~IA32_PAGE_MASK; 228 unsigned long pgoff = (eppnt->p_vaddr) & ~IA32_PAGE_MASK;
228 229
diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c
index 196287928bae..e699eb6c44be 100644
--- a/arch/ia64/kernel/module.c
+++ b/arch/ia64/kernel/module.c
@@ -947,7 +947,7 @@ percpu_modcopy (void *pcpudst, const void *src, unsigned long size)
947{ 947{
948 unsigned int i; 948 unsigned int i;
949 for_each_possible_cpu(i) { 949 for_each_possible_cpu(i) {
950 memcpy(pcpudst + __per_cpu_offset[i], src, size); 950 memcpy(pcpudst + per_cpu_offset(i), src, size);
951 } 951 }
952} 952}
953#endif /* CONFIG_SMP */ 953#endif /* CONFIG_SMP */
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 4ac2b1f1bd3b..86028c69861e 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -71,8 +71,6 @@ unsigned long __per_cpu_offset[NR_CPUS];
71EXPORT_SYMBOL(__per_cpu_offset); 71EXPORT_SYMBOL(__per_cpu_offset);
72#endif 72#endif
73 73
74extern void ia64_setup_printk_clock(void);
75
76DEFINE_PER_CPU(struct cpuinfo_ia64, cpu_info); 74DEFINE_PER_CPU(struct cpuinfo_ia64, cpu_info);
77DEFINE_PER_CPU(unsigned long, local_per_cpu_offset); 75DEFINE_PER_CPU(unsigned long, local_per_cpu_offset);
78unsigned long ia64_cycles_per_usec; 76unsigned long ia64_cycles_per_usec;
@@ -507,8 +505,6 @@ setup_arch (char **cmdline_p)
507 /* process SAL system table: */ 505 /* process SAL system table: */
508 ia64_sal_init(__va(efi.sal_systab)); 506 ia64_sal_init(__va(efi.sal_systab));
509 507
510 ia64_setup_printk_clock();
511
512#ifdef CONFIG_SMP 508#ifdef CONFIG_SMP
513 cpu_physical_id(0) = hard_smp_processor_id(); 509 cpu_physical_id(0) = hard_smp_processor_id();
514#endif 510#endif
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index 2bb84214e5f1..3ab042720970 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -344,33 +344,6 @@ udelay (unsigned long usecs)
344} 344}
345EXPORT_SYMBOL(udelay); 345EXPORT_SYMBOL(udelay);
346 346
347static unsigned long long ia64_itc_printk_clock(void)
348{
349 if (ia64_get_kr(IA64_KR_PER_CPU_DATA))
350 return sched_clock();
351 return 0;
352}
353
354static unsigned long long ia64_default_printk_clock(void)
355{
356 return (unsigned long long)(jiffies_64 - INITIAL_JIFFIES) *
357 (1000000000/HZ);
358}
359
360unsigned long long (*ia64_printk_clock)(void) = &ia64_default_printk_clock;
361
362unsigned long long printk_clock(void)
363{
364 return ia64_printk_clock();
365}
366
367void __init
368ia64_setup_printk_clock(void)
369{
370 if (!(sal_platform_features & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT))
371 ia64_printk_clock = ia64_itc_printk_clock;
372}
373
374/* IA64 doesn't cache the timezone */ 347/* IA64 doesn't cache the timezone */
375void update_vsyscall_tz(void) 348void update_vsyscall_tz(void)
376{ 349{
diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c
index 14261fee5f4d..a2484fc1a06c 100644
--- a/arch/ia64/kernel/topology.c
+++ b/arch/ia64/kernel/topology.c
@@ -354,27 +354,27 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
354 if (unlikely(retval < 0)) 354 if (unlikely(retval < 0))
355 return retval; 355 return retval;
356 356
357 all_cpu_cache_info[cpu].kobj.parent = &sys_dev->kobj; 357 retval = kobject_init_and_add(&all_cpu_cache_info[cpu].kobj,
358 kobject_set_name(&all_cpu_cache_info[cpu].kobj, "%s", "cache"); 358 &cache_ktype_percpu_entry, &sys_dev->kobj,
359 all_cpu_cache_info[cpu].kobj.ktype = &cache_ktype_percpu_entry; 359 "%s", "cache");
360 retval = kobject_register(&all_cpu_cache_info[cpu].kobj);
361 360
362 for (i = 0; i < all_cpu_cache_info[cpu].num_cache_leaves; i++) { 361 for (i = 0; i < all_cpu_cache_info[cpu].num_cache_leaves; i++) {
363 this_object = LEAF_KOBJECT_PTR(cpu,i); 362 this_object = LEAF_KOBJECT_PTR(cpu,i);
364 this_object->kobj.parent = &all_cpu_cache_info[cpu].kobj; 363 retval = kobject_init_and_add(&(this_object->kobj),
365 kobject_set_name(&(this_object->kobj), "index%1lu", i); 364 &cache_ktype,
366 this_object->kobj.ktype = &cache_ktype; 365 &all_cpu_cache_info[cpu].kobj,
367 retval = kobject_register(&(this_object->kobj)); 366 "index%1lu", i);
368 if (unlikely(retval)) { 367 if (unlikely(retval)) {
369 for (j = 0; j < i; j++) { 368 for (j = 0; j < i; j++) {
370 kobject_unregister( 369 kobject_put(&(LEAF_KOBJECT_PTR(cpu,j)->kobj));
371 &(LEAF_KOBJECT_PTR(cpu,j)->kobj));
372 } 370 }
373 kobject_unregister(&all_cpu_cache_info[cpu].kobj); 371 kobject_put(&all_cpu_cache_info[cpu].kobj);
374 cpu_cache_sysfs_exit(cpu); 372 cpu_cache_sysfs_exit(cpu);
375 break; 373 break;
376 } 374 }
375 kobject_uevent(&(this_object->kobj), KOBJ_ADD);
377 } 376 }
377 kobject_uevent(&all_cpu_cache_info[cpu].kobj, KOBJ_ADD);
378 return retval; 378 return retval;
379} 379}
380 380
@@ -385,10 +385,10 @@ static int __cpuinit cache_remove_dev(struct sys_device * sys_dev)
385 unsigned long i; 385 unsigned long i;
386 386
387 for (i = 0; i < all_cpu_cache_info[cpu].num_cache_leaves; i++) 387 for (i = 0; i < all_cpu_cache_info[cpu].num_cache_leaves; i++)
388 kobject_unregister(&(LEAF_KOBJECT_PTR(cpu,i)->kobj)); 388 kobject_put(&(LEAF_KOBJECT_PTR(cpu,i)->kobj));
389 389
390 if (all_cpu_cache_info[cpu].kobj.parent) { 390 if (all_cpu_cache_info[cpu].kobj.parent) {
391 kobject_unregister(&all_cpu_cache_info[cpu].kobj); 391 kobject_put(&all_cpu_cache_info[cpu].kobj);
392 memset(&all_cpu_cache_info[cpu].kobj, 392 memset(&all_cpu_cache_info[cpu].kobj,
393 0, 393 0,
394 sizeof(struct kobject)); 394 sizeof(struct kobject));
diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S
index 757e419ebcf8..80622acc95de 100644
--- a/arch/ia64/kernel/vmlinux.lds.S
+++ b/arch/ia64/kernel/vmlinux.lds.S
@@ -27,8 +27,8 @@ SECTIONS
27{ 27{
28 /* Sections to be discarded */ 28 /* Sections to be discarded */
29 /DISCARD/ : { 29 /DISCARD/ : {
30 *(.exit.text) 30 EXIT_TEXT
31 *(.exit.data) 31 EXIT_DATA
32 *(.exitcall.exit) 32 *(.exitcall.exit)
33 *(.IA_64.unwind.exit.text) 33 *(.IA_64.unwind.exit.text)
34 *(.IA_64.unwind_info.exit.text) 34 *(.IA_64.unwind_info.exit.text)
@@ -119,12 +119,12 @@ SECTIONS
119 .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) 119 .init.text : AT(ADDR(.init.text) - LOAD_OFFSET)
120 { 120 {
121 _sinittext = .; 121 _sinittext = .;
122 *(.init.text) 122 INIT_TEXT
123 _einittext = .; 123 _einittext = .;
124 } 124 }
125 125
126 .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) 126 .init.data : AT(ADDR(.init.data) - LOAD_OFFSET)
127 { *(.init.data) } 127 { INIT_DATA }
128 128
129#ifdef CONFIG_BLK_DEV_INITRD 129#ifdef CONFIG_BLK_DEV_INITRD
130 .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) 130 .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET)
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
index 1f38a3a68390..bb1d24929640 100644
--- a/arch/ia64/sn/kernel/setup.c
+++ b/arch/ia64/sn/kernel/setup.c
@@ -64,7 +64,6 @@ extern void sn_timer_init(void);
64extern unsigned long last_time_offset; 64extern unsigned long last_time_offset;
65extern void (*ia64_mark_idle) (int); 65extern void (*ia64_mark_idle) (int);
66extern void snidle(int); 66extern void snidle(int);
67extern unsigned long long (*ia64_printk_clock)(void);
68 67
69unsigned long sn_rtc_cycles_per_second; 68unsigned long sn_rtc_cycles_per_second;
70EXPORT_SYMBOL(sn_rtc_cycles_per_second); 69EXPORT_SYMBOL(sn_rtc_cycles_per_second);
@@ -360,14 +359,6 @@ sn_scan_pcdp(void)
360 359
361static unsigned long sn2_rtc_initial; 360static unsigned long sn2_rtc_initial;
362 361
363static unsigned long long ia64_sn2_printk_clock(void)
364{
365 unsigned long rtc_now = rtc_time();
366
367 return (rtc_now - sn2_rtc_initial) *
368 (1000000000 / sn_rtc_cycles_per_second);
369}
370
371/** 362/**
372 * sn_setup - SN platform setup routine 363 * sn_setup - SN platform setup routine
373 * @cmdline_p: kernel command line 364 * @cmdline_p: kernel command line
@@ -468,8 +459,6 @@ void __init sn_setup(char **cmdline_p)
468 459
469 platform_intr_list[ACPI_INTERRUPT_CPEI] = IA64_CPE_VECTOR; 460 platform_intr_list[ACPI_INTERRUPT_CPEI] = IA64_CPE_VECTOR;
470 461
471 ia64_printk_clock = ia64_sn2_printk_clock;
472
473 printk("SGI SAL version %x.%02x\n", version >> 8, version & 0x00FF); 462 printk("SGI SAL version %x.%02x\n", version >> 8, version & 0x00FF);
474 463
475 /* 464 /*
diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig
index ab9a264cb194..f7237c5f531e 100644
--- a/arch/m32r/Kconfig
+++ b/arch/m32r/Kconfig
@@ -235,6 +235,11 @@ config IRAM_SIZE
235# Define implied options from the CPU selection here 235# Define implied options from the CPU selection here
236# 236#
237 237
238config GENERIC_LOCKBREAK
239 bool
240 default y
241 depends on SMP && PREEMPT
242
238config RWSEM_GENERIC_SPINLOCK 243config RWSEM_GENERIC_SPINLOCK
239 bool 244 bool
240 depends on M32R 245 depends on M32R
diff --git a/arch/m32r/kernel/vmlinux.lds.S b/arch/m32r/kernel/vmlinux.lds.S
index 942a8c7a4417..41b07854fcc6 100644
--- a/arch/m32r/kernel/vmlinux.lds.S
+++ b/arch/m32r/kernel/vmlinux.lds.S
@@ -76,10 +76,10 @@ SECTIONS
76 __init_begin = .; 76 __init_begin = .;
77 .init.text : { 77 .init.text : {
78 _sinittext = .; 78 _sinittext = .;
79 *(.init.text) 79 INIT_TEXT
80 _einittext = .; 80 _einittext = .;
81 } 81 }
82 .init.data : { *(.init.data) } 82 .init.data : { INIT_DATA }
83 . = ALIGN(16); 83 . = ALIGN(16);
84 __setup_start = .; 84 __setup_start = .;
85 .init.setup : { *(.init.setup) } 85 .init.setup : { *(.init.setup) }
@@ -100,8 +100,8 @@ SECTIONS
100 .altinstr_replacement : { *(.altinstr_replacement) } 100 .altinstr_replacement : { *(.altinstr_replacement) }
101 /* .exit.text is discard at runtime, not link time, to deal with references 101 /* .exit.text is discard at runtime, not link time, to deal with references
102 from .altinstructions and .eh_frame */ 102 from .altinstructions and .eh_frame */
103 .exit.text : { *(.exit.text) } 103 .exit.text : { EXIT_TEXT }
104 .exit.data : { *(.exit.data) } 104 .exit.data : { EXIT_DATA }
105 105
106#ifdef CONFIG_BLK_DEV_INITRD 106#ifdef CONFIG_BLK_DEV_INITRD
107 . = ALIGN(4096); 107 . = ALIGN(4096);
@@ -124,8 +124,8 @@ SECTIONS
124 124
125 /* Sections to be discarded */ 125 /* Sections to be discarded */
126 /DISCARD/ : { 126 /DISCARD/ : {
127 *(.exit.text) 127 EXIT_TEXT
128 *(.exit.data) 128 EXIT_DATA
129 *(.exitcall.exit) 129 *(.exitcall.exit)
130 } 130 }
131 131
diff --git a/arch/m68k/kernel/vmlinux-std.lds b/arch/m68k/kernel/vmlinux-std.lds
index 59fe285865ec..7537cc5e6159 100644
--- a/arch/m68k/kernel/vmlinux-std.lds
+++ b/arch/m68k/kernel/vmlinux-std.lds
@@ -45,10 +45,10 @@ SECTIONS
45 __init_begin = .; 45 __init_begin = .;
46 .init.text : { 46 .init.text : {
47 _sinittext = .; 47 _sinittext = .;
48 *(.init.text) 48 INIT_TEXT
49 _einittext = .; 49 _einittext = .;
50 } 50 }
51 .init.data : { *(.init.data) } 51 .init.data : { INIT_DATA }
52 . = ALIGN(16); 52 . = ALIGN(16);
53 __setup_start = .; 53 __setup_start = .;
54 .init.setup : { *(.init.setup) } 54 .init.setup : { *(.init.setup) }
@@ -82,8 +82,8 @@ SECTIONS
82 82
83 /* Sections to be discarded */ 83 /* Sections to be discarded */
84 /DISCARD/ : { 84 /DISCARD/ : {
85 *(.exit.text) 85 EXIT_TEXT
86 *(.exit.data) 86 EXIT_DATA
87 *(.exitcall.exit) 87 *(.exitcall.exit)
88 } 88 }
89 89
diff --git a/arch/m68k/kernel/vmlinux-sun3.lds b/arch/m68k/kernel/vmlinux-sun3.lds
index 4adffefb5c48..cdc313e7c299 100644
--- a/arch/m68k/kernel/vmlinux-sun3.lds
+++ b/arch/m68k/kernel/vmlinux-sun3.lds
@@ -38,10 +38,10 @@ SECTIONS
38__init_begin = .; 38__init_begin = .;
39 .init.text : { 39 .init.text : {
40 _sinittext = .; 40 _sinittext = .;
41 *(.init.text) 41 INIT_TEXT
42 _einittext = .; 42 _einittext = .;
43 } 43 }
44 .init.data : { *(.init.data) } 44 .init.data : { INIT_DATA }
45 . = ALIGN(16); 45 . = ALIGN(16);
46 __setup_start = .; 46 __setup_start = .;
47 .init.setup : { *(.init.setup) } 47 .init.setup : { *(.init.setup) }
@@ -77,8 +77,8 @@ __init_begin = .;
77 77
78 /* Sections to be discarded */ 78 /* Sections to be discarded */
79 /DISCARD/ : { 79 /DISCARD/ : {
80 *(.exit.text) 80 EXIT_TEXT
81 *(.exit.data) 81 EXIT_DATA
82 *(.exitcall.exit) 82 *(.exitcall.exit)
83 } 83 }
84 84
diff --git a/arch/m68knommu/kernel/vmlinux.lds.S b/arch/m68knommu/kernel/vmlinux.lds.S
index 07a0055602f4..b44edb08e212 100644
--- a/arch/m68knommu/kernel/vmlinux.lds.S
+++ b/arch/m68knommu/kernel/vmlinux.lds.S
@@ -143,9 +143,9 @@ SECTIONS {
143 . = ALIGN(4096); 143 . = ALIGN(4096);
144 __init_begin = .; 144 __init_begin = .;
145 _sinittext = .; 145 _sinittext = .;
146 *(.init.text) 146 INIT_TEXT
147 _einittext = .; 147 _einittext = .;
148 *(.init.data) 148 INIT_DATA
149 . = ALIGN(16); 149 . = ALIGN(16);
150 __setup_start = .; 150 __setup_start = .;
151 *(.init.setup) 151 *(.init.setup)
@@ -170,8 +170,8 @@ SECTIONS {
170 } > INIT 170 } > INIT
171 171
172 /DISCARD/ : { 172 /DISCARD/ : {
173 *(.exit.text) 173 EXIT_TEXT
174 *(.exit.data) 174 EXIT_DATA
175 *(.exitcall.exit) 175 *(.exitcall.exit)
176 } 176 }
177 177
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index b22c043b6ef8..4fad0a34b997 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -37,16 +37,6 @@ config BASLER_EXCITE
37 The eXcite is a smart camera platform manufactured by 37 The eXcite is a smart camera platform manufactured by
38 Basler Vision Technologies AG. 38 Basler Vision Technologies AG.
39 39
40config BASLER_EXCITE_PROTOTYPE
41 bool "Support for pre-release units"
42 depends on BASLER_EXCITE
43 default n
44 help
45 Pre-series (prototype) units are different from later ones in
46 some ways. Select this option if you have one of these. Please
47 note that a kernel built with this option selected will not be
48 able to run on normal units.
49
50config BCM47XX 40config BCM47XX
51 bool "BCM47XX based boards" 41 bool "BCM47XX based boards"
52 select CEVT_R4K 42 select CEVT_R4K
@@ -82,7 +72,7 @@ config MIPS_COBALT
82 select SYS_HAS_CPU_NEVADA 72 select SYS_HAS_CPU_NEVADA
83 select SYS_HAS_EARLY_PRINTK 73 select SYS_HAS_EARLY_PRINTK
84 select SYS_SUPPORTS_32BIT_KERNEL 74 select SYS_SUPPORTS_32BIT_KERNEL
85 select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL 75 select SYS_SUPPORTS_64BIT_KERNEL
86 select SYS_SUPPORTS_LITTLE_ENDIAN 76 select SYS_SUPPORTS_LITTLE_ENDIAN
87 select GENERIC_HARDIRQS_NO__DO_IRQ 77 select GENERIC_HARDIRQS_NO__DO_IRQ
88 78
@@ -91,6 +81,9 @@ config MACH_DECSTATION
91 select BOOT_ELF32 81 select BOOT_ELF32
92 select CEVT_R4K 82 select CEVT_R4K
93 select CSRC_R4K 83 select CSRC_R4K
84 select CPU_DADDI_WORKAROUNDS if 64BIT
85 select CPU_R4000_WORKAROUNDS if 64BIT
86 select CPU_R4400_WORKAROUNDS if 64BIT
94 select DMA_NONCOHERENT 87 select DMA_NONCOHERENT
95 select NO_IOPORT 88 select NO_IOPORT
96 select IRQ_CPU 89 select IRQ_CPU
@@ -124,12 +117,12 @@ config MACH_JAZZ
124 select ARCH_MAY_HAVE_PC_FDC 117 select ARCH_MAY_HAVE_PC_FDC
125 select CEVT_R4K 118 select CEVT_R4K
126 select CSRC_R4K 119 select CSRC_R4K
120 select DEFAULT_SGI_PARTITION if CPU_BIG_ENDIAN
127 select GENERIC_ISA_DMA 121 select GENERIC_ISA_DMA
128 select IRQ_CPU 122 select IRQ_CPU
129 select I8253 123 select I8253
130 select I8259 124 select I8259
131 select ISA 125 select ISA
132 select PCSPEAKER
133 select SYS_HAS_CPU_R4X00 126 select SYS_HAS_CPU_R4X00
134 select SYS_SUPPORTS_32BIT_KERNEL 127 select SYS_SUPPORTS_32BIT_KERNEL
135 select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL 128 select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
@@ -187,6 +180,7 @@ config LEMOTE_FULONG
187config MIPS_ATLAS 180config MIPS_ATLAS
188 bool "MIPS Atlas board" 181 bool "MIPS Atlas board"
189 select BOOT_ELF32 182 select BOOT_ELF32
183 select BOOT_RAW
190 select CEVT_R4K 184 select CEVT_R4K
191 select CSRC_R4K 185 select CSRC_R4K
192 select DMA_NONCOHERENT 186 select DMA_NONCOHERENT
@@ -219,6 +213,7 @@ config MIPS_MALTA
219 bool "MIPS Malta board" 213 bool "MIPS Malta board"
220 select ARCH_MAY_HAVE_PC_FDC 214 select ARCH_MAY_HAVE_PC_FDC
221 select BOOT_ELF32 215 select BOOT_ELF32
216 select BOOT_RAW
222 select CEVT_R4K 217 select CEVT_R4K
223 select CSRC_R4K 218 select CSRC_R4K
224 select DMA_NONCOHERENT 219 select DMA_NONCOHERENT
@@ -364,35 +359,6 @@ config PMC_YOSEMITE
364 Yosemite is an evaluation board for the RM9000x2 processor 359 Yosemite is an evaluation board for the RM9000x2 processor
365 manufactured by PMC-Sierra. 360 manufactured by PMC-Sierra.
366 361
367config QEMU
368 bool "Qemu"
369 select CEVT_R4K
370 select CSRC_R4K
371 select DMA_COHERENT
372 select GENERIC_ISA_DMA
373 select HAVE_STD_PC_SERIAL_PORT
374 select I8253
375 select I8259
376 select IRQ_CPU
377 select ISA
378 select PCSPEAKER
379 select SWAP_IO_SPACE
380 select SYS_HAS_CPU_MIPS32_R1
381 select SYS_HAS_EARLY_PRINTK
382 select SYS_SUPPORTS_32BIT_KERNEL
383 select SYS_SUPPORTS_BIG_ENDIAN
384 select SYS_SUPPORTS_LITTLE_ENDIAN
385 select GENERIC_HARDIRQS_NO__DO_IRQ
386 select NR_CPUS_DEFAULT_1
387 select SYS_SUPPORTS_SMP
388 help
389 Qemu is a software emulator which among other architectures also
390 can simulate a MIPS32 4Kc system. This patch adds support for the
391 system architecture that currently is being simulated by Qemu. It
392 will eventually be removed again when Qemu has the capability to
393 simulate actual MIPS hardware platforms. More information on Qemu
394 can be found at http://www.linux-mips.org/wiki/Qemu.
395
396config SGI_IP22 362config SGI_IP22
397 bool "SGI IP22 (Indy/Indigo2)" 363 bool "SGI IP22 (Indy/Indigo2)"
398 select ARC 364 select ARC
@@ -400,6 +366,7 @@ config SGI_IP22
400 select BOOT_ELF32 366 select BOOT_ELF32
401 select CEVT_R4K 367 select CEVT_R4K
402 select CSRC_R4K 368 select CSRC_R4K
369 select DEFAULT_SGI_PARTITION
403 select DMA_NONCOHERENT 370 select DMA_NONCOHERENT
404 select HW_HAS_EISA 371 select HW_HAS_EISA
405 select I8253 372 select I8253
@@ -407,6 +374,12 @@ config SGI_IP22
407 select IP22_CPU_SCACHE 374 select IP22_CPU_SCACHE
408 select IRQ_CPU 375 select IRQ_CPU
409 select GENERIC_ISA_DMA_SUPPORT_BROKEN 376 select GENERIC_ISA_DMA_SUPPORT_BROKEN
377 select SGI_HAS_DS1286
378 select SGI_HAS_I8042
379 select SGI_HAS_INDYDOG
380 select SGI_HAS_SEEQ
381 select SGI_HAS_WD93
382 select SGI_HAS_ZILOG
410 select SWAP_IO_SPACE 383 select SWAP_IO_SPACE
411 select SYS_HAS_CPU_R4X00 384 select SYS_HAS_CPU_R4X00
412 select SYS_HAS_CPU_R5000 385 select SYS_HAS_CPU_R5000
@@ -424,6 +397,7 @@ config SGI_IP27
424 select ARC 397 select ARC
425 select ARC64 398 select ARC64
426 select BOOT_ELF64 399 select BOOT_ELF64
400 select DEFAULT_SGI_PARTITION
427 select DMA_IP27 401 select DMA_IP27
428 select SYS_HAS_EARLY_PRINTK 402 select SYS_HAS_EARLY_PRINTK
429 select HW_HAS_PCI 403 select HW_HAS_PCI
@@ -440,6 +414,36 @@ config SGI_IP27
440 workstations. To compile a Linux kernel that runs on these, say Y 414 workstations. To compile a Linux kernel that runs on these, say Y
441 here. 415 here.
442 416
417config SGI_IP28
418 bool "SGI IP28 (Indigo2 R10k) (EXPERIMENTAL)"
419 depends on EXPERIMENTAL
420 select ARC
421 select ARC64
422 select BOOT_ELF64
423 select CEVT_R4K
424 select CSRC_R4K
425 select DEFAULT_SGI_PARTITION
426 select DMA_NONCOHERENT
427 select GENERIC_ISA_DMA_SUPPORT_BROKEN
428 select IRQ_CPU
429 select HW_HAS_EISA
430 select I8253
431 select I8259
432 select SGI_HAS_DS1286
433 select SGI_HAS_I8042
434 select SGI_HAS_INDYDOG
435 select SGI_HAS_SEEQ
436 select SGI_HAS_WD93
437 select SGI_HAS_ZILOG
438 select SWAP_IO_SPACE
439 select SYS_HAS_CPU_R10000
440 select SYS_HAS_EARLY_PRINTK
441 select SYS_SUPPORTS_64BIT_KERNEL
442 select SYS_SUPPORTS_BIG_ENDIAN
443 help
444 This is the SGI Indigo2 with R10000 processor. To compile a Linux
445 kernel that runs on these, say Y here.
446
443config SGI_IP32 447config SGI_IP32
444 bool "SGI IP32 (O2)" 448 bool "SGI IP32 (O2)"
445 select ARC 449 select ARC
@@ -545,19 +549,6 @@ config SIBYTE_SENTOSA
545 select SYS_SUPPORTS_BIG_ENDIAN 549 select SYS_SUPPORTS_BIG_ENDIAN
546 select SYS_SUPPORTS_LITTLE_ENDIAN 550 select SYS_SUPPORTS_LITTLE_ENDIAN
547 551
548config SIBYTE_PTSWARM
549 bool "Sibyte BCM91250PT-PTSWARM"
550 depends on EXPERIMENTAL
551 select BOOT_ELF32
552 select DMA_COHERENT
553 select NR_CPUS_DEFAULT_2
554 select SIBYTE_SB1250
555 select SWAP_IO_SPACE
556 select SYS_HAS_CPU_SB1
557 select SYS_SUPPORTS_BIG_ENDIAN
558 select SYS_SUPPORTS_HIGHMEM
559 select SYS_SUPPORTS_LITTLE_ENDIAN
560
561config SIBYTE_BIGSUR 552config SIBYTE_BIGSUR
562 bool "Sibyte BCM91480B-BigSur" 553 bool "Sibyte BCM91480B-BigSur"
563 select BOOT_ELF32 554 select BOOT_ELF32
@@ -575,10 +566,12 @@ config SNI_RM
575 bool "SNI RM200/300/400" 566 bool "SNI RM200/300/400"
576 select ARC if CPU_LITTLE_ENDIAN 567 select ARC if CPU_LITTLE_ENDIAN
577 select ARC32 if CPU_LITTLE_ENDIAN 568 select ARC32 if CPU_LITTLE_ENDIAN
569 select SNIPROM if CPU_BIG_ENDIAN
578 select ARCH_MAY_HAVE_PC_FDC 570 select ARCH_MAY_HAVE_PC_FDC
579 select BOOT_ELF32 571 select BOOT_ELF32
580 select CEVT_R4K 572 select CEVT_R4K
581 select CSRC_R4K 573 select CSRC_R4K
574 select DEFAULT_SGI_PARTITION if CPU_BIG_ENDIAN
582 select DMA_NONCOHERENT 575 select DMA_NONCOHERENT
583 select GENERIC_ISA_DMA 576 select GENERIC_ISA_DMA
584 select HW_HAS_EISA 577 select HW_HAS_EISA
@@ -587,7 +580,6 @@ config SNI_RM
587 select I8253 580 select I8253
588 select I8259 581 select I8259
589 select ISA 582 select ISA
590 select PCSPEAKER
591 select SWAP_IO_SPACE if CPU_BIG_ENDIAN 583 select SWAP_IO_SPACE if CPU_BIG_ENDIAN
592 select SYS_HAS_CPU_R4X00 584 select SYS_HAS_CPU_R4X00
593 select SYS_HAS_CPU_R5000 585 select SYS_HAS_CPU_R5000
@@ -690,6 +682,7 @@ config WR_PPMC
690endchoice 682endchoice
691 683
692source "arch/mips/au1000/Kconfig" 684source "arch/mips/au1000/Kconfig"
685source "arch/mips/basler/excite/Kconfig"
693source "arch/mips/jazz/Kconfig" 686source "arch/mips/jazz/Kconfig"
694source "arch/mips/lasat/Kconfig" 687source "arch/mips/lasat/Kconfig"
695source "arch/mips/pmc-sierra/Kconfig" 688source "arch/mips/pmc-sierra/Kconfig"
@@ -701,6 +694,11 @@ source "arch/mips/vr41xx/Kconfig"
701 694
702endmenu 695endmenu
703 696
697config GENERIC_LOCKBREAK
698 bool
699 default y
700 depends on SMP && PREEMPT
701
704config RWSEM_GENERIC_SPINLOCK 702config RWSEM_GENERIC_SPINLOCK
705 bool 703 bool
706 default y 704 default y
@@ -797,10 +795,6 @@ config DMA_COHERENT
797config DMA_IP27 795config DMA_IP27
798 bool 796 bool
799 797
800config DMA_IP32
801 bool
802 select DMA_NEED_PCI_MAP_STATE
803
804config DMA_NONCOHERENT 798config DMA_NONCOHERENT
805 bool 799 bool
806 select DMA_NEED_PCI_MAP_STATE 800 select DMA_NEED_PCI_MAP_STATE
@@ -956,16 +950,40 @@ config EMMA2RH
956config SERIAL_RM9000 950config SERIAL_RM9000
957 bool 951 bool
958 952
953config SGI_HAS_DS1286
954 bool
955
956config SGI_HAS_INDYDOG
957 bool
958
959config SGI_HAS_SEEQ
960 bool
961
962config SGI_HAS_WD93
963 bool
964
965config SGI_HAS_ZILOG
966 bool
967
968config SGI_HAS_I8042
969 bool
970
971config DEFAULT_SGI_PARTITION
972 bool
973
959config ARC32 974config ARC32
960 bool 975 bool
961 976
977config SNIPROM
978 bool
979
962config BOOT_ELF32 980config BOOT_ELF32
963 bool 981 bool
964 982
965config MIPS_L1_CACHE_SHIFT 983config MIPS_L1_CACHE_SHIFT
966 int 984 int
967 default "4" if MACH_DECSTATION 985 default "4" if MACH_DECSTATION
968 default "7" if SGI_IP27 || SNI_RM 986 default "7" if SGI_IP27 || SGI_IP28 || SNI_RM
969 default "4" if PMC_MSP4200_EVAL 987 default "4" if PMC_MSP4200_EVAL
970 default "5" 988 default "5"
971 989
@@ -974,7 +992,7 @@ config HAVE_STD_PC_SERIAL_PORT
974 992
975config ARC_CONSOLE 993config ARC_CONSOLE
976 bool "ARC console support" 994 bool "ARC console support"
977 depends on SGI_IP22 || (SNI_RM && CPU_LITTLE_ENDIAN) 995 depends on SGI_IP22 || SGI_IP28 || (SNI_RM && CPU_LITTLE_ENDIAN)
978 996
979config ARC_MEMORY 997config ARC_MEMORY
980 bool 998 bool
@@ -983,7 +1001,7 @@ config ARC_MEMORY
983 1001
984config ARC_PROMLIB 1002config ARC_PROMLIB
985 bool 1003 bool
986 depends on MACH_JAZZ || SNI_RM || SGI_IP22 || SGI_IP32 1004 depends on MACH_JAZZ || SNI_RM || SGI_IP22 || SGI_IP28 || SGI_IP32
987 default y 1005 default y
988 1006
989config ARC64 1007config ARC64
@@ -1443,7 +1461,9 @@ config MIPS_MT_SMP
1443 select MIPS_MT 1461 select MIPS_MT
1444 select NR_CPUS_DEFAULT_2 1462 select NR_CPUS_DEFAULT_2
1445 select SMP 1463 select SMP
1464 select SYS_SUPPORTS_SCHED_SMT if SMP
1446 select SYS_SUPPORTS_SMP 1465 select SYS_SUPPORTS_SMP
1466 select SMP_UP
1447 help 1467 help
1448 This is a kernel model which is also known a VSMP or lately 1468 This is a kernel model which is also known a VSMP or lately
1449 has been marketesed into SMVP. 1469 has been marketesed into SMVP.
@@ -1460,6 +1480,7 @@ config MIPS_MT_SMTC
1460 select NR_CPUS_DEFAULT_8 1480 select NR_CPUS_DEFAULT_8
1461 select SMP 1481 select SMP
1462 select SYS_SUPPORTS_SMP 1482 select SYS_SUPPORTS_SMP
1483 select SMP_UP
1463 help 1484 help
1464 This is a kernel model which is known a SMTC or lately has been 1485 This is a kernel model which is known a SMTC or lately has been
1465 marketesed into SMVP. 1486 marketesed into SMVP.
@@ -1469,6 +1490,19 @@ endchoice
1469config MIPS_MT 1490config MIPS_MT
1470 bool 1491 bool
1471 1492
1493config SCHED_SMT
1494 bool "SMT (multithreading) scheduler support"
1495 depends on SYS_SUPPORTS_SCHED_SMT
1496 default n
1497 help
1498 SMT scheduler support improves the CPU scheduler's decision making
1499 when dealing with MIPS MT enabled cores at a cost of slightly
1500 increased overhead in some places. If unsure say N here.
1501
1502config SYS_SUPPORTS_SCHED_SMT
1503 bool
1504
1505
1472config SYS_SUPPORTS_MULTITHREADING 1506config SYS_SUPPORTS_MULTITHREADING
1473 bool 1507 bool
1474 1508
@@ -1589,15 +1623,6 @@ config CPU_HAS_SMARTMIPS
1589config CPU_HAS_WB 1623config CPU_HAS_WB
1590 bool 1624 bool
1591 1625
1592config 64BIT_CONTEXT
1593 bool "Save 64bit integer registers"
1594 depends on 32BIT && CPU_LOONGSON2
1595 help
1596 Loongson2 CPU is 64bit , when used in 32BIT mode, its integer
1597 registers can still be accessed as 64bit, mainly for multimedia
1598 instructions. We must have all 64bit save/restored to make sure
1599 those instructions to get correct result.
1600
1601# 1626#
1602# Vectored interrupt mode is an R2 feature 1627# Vectored interrupt mode is an R2 feature
1603# 1628#
@@ -1619,6 +1644,19 @@ config GENERIC_CLOCKEVENTS_BROADCAST
1619 bool 1644 bool
1620 1645
1621# 1646#
1647# CPU non-features
1648#
1649config CPU_DADDI_WORKAROUNDS
1650 bool
1651
1652config CPU_R4000_WORKAROUNDS
1653 bool
1654 select CPU_R4400_WORKAROUNDS
1655
1656config CPU_R4400_WORKAROUNDS
1657 bool
1658
1659#
1622# Use the generic interrupt handling code in kernel/irq/: 1660# Use the generic interrupt handling code in kernel/irq/:
1623# 1661#
1624config GENERIC_HARDIRQS 1662config GENERIC_HARDIRQS
@@ -1721,6 +1759,9 @@ config SMP
1721 1759
1722 If you don't know what to do here, say N. 1760 If you don't know what to do here, say N.
1723 1761
1762config SMP_UP
1763 bool
1764
1724config SYS_SUPPORTS_SMP 1765config SYS_SUPPORTS_SMP
1725 bool 1766 bool
1726 1767
@@ -1978,9 +2019,6 @@ config MMU
1978config I8253 2019config I8253
1979 bool 2020 bool
1980 2021
1981config PCSPEAKER
1982 bool
1983
1984config ZONE_DMA32 2022config ZONE_DMA32
1985 bool 2023 bool
1986 2024
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index a1f8d8b96b03..3fb7f3065c92 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -141,6 +141,10 @@ cflags-$(CONFIG_CPU_R8000) += -march=r8000 -Wa,--trap
141cflags-$(CONFIG_CPU_R10000) += $(call cc-option,-march=r10000,-march=r8000) \ 141cflags-$(CONFIG_CPU_R10000) += $(call cc-option,-march=r10000,-march=r8000) \
142 -Wa,--trap 142 -Wa,--trap
143 143
144cflags-$(CONFIG_CPU_R4000_WORKAROUNDS) += $(call cc-option,-mfix-r4000,)
145cflags-$(CONFIG_CPU_R4400_WORKAROUNDS) += $(call cc-option,-mfix-r4400,)
146cflags-$(CONFIG_CPU_DADDI_WORKAROUNDS) += $(call cc-option,-mno-daddi,)
147
144ifdef CONFIG_CPU_SB1 148ifdef CONFIG_CPU_SB1
145ifdef CONFIG_SB1_PASS_1_WORKAROUNDS 149ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
146MODFLAGS += -msb1-pass1-workarounds 150MODFLAGS += -msb1-pass1-workarounds
@@ -152,6 +156,8 @@ endif
152# 156#
153libs-$(CONFIG_ARC) += arch/mips/fw/arc/ 157libs-$(CONFIG_ARC) += arch/mips/fw/arc/
154libs-$(CONFIG_CFE) += arch/mips/fw/cfe/ 158libs-$(CONFIG_CFE) += arch/mips/fw/cfe/
159libs-$(CONFIG_SNIPROM) += arch/mips/fw/sni/
160libs-y += arch/mips/fw/lib/
155libs-$(CONFIG_SIBYTE_CFE) += arch/mips/sibyte/cfe/ 161libs-$(CONFIG_SIBYTE_CFE) += arch/mips/sibyte/cfe/
156 162
157# 163#
@@ -308,7 +314,7 @@ core-$(CONFIG_MIPS_ATLAS) += arch/mips/mips-boards/atlas/
308cflags-$(CONFIG_MIPS_ATLAS) += -Iinclude/asm-mips/mach-atlas 314cflags-$(CONFIG_MIPS_ATLAS) += -Iinclude/asm-mips/mach-atlas
309cflags-$(CONFIG_MIPS_ATLAS) += -Iinclude/asm-mips/mach-mips 315cflags-$(CONFIG_MIPS_ATLAS) += -Iinclude/asm-mips/mach-mips
310load-$(CONFIG_MIPS_ATLAS) += 0xffffffff80100000 316load-$(CONFIG_MIPS_ATLAS) += 0xffffffff80100000
311all-$(CONFIG_MIPS_ATLAS) := vmlinux.srec 317all-$(CONFIG_MIPS_ATLAS) := vmlinux.bin
312 318
313# 319#
314# MIPS Malta board 320# MIPS Malta board
@@ -316,7 +322,7 @@ all-$(CONFIG_MIPS_ATLAS) := vmlinux.srec
316core-$(CONFIG_MIPS_MALTA) += arch/mips/mips-boards/malta/ 322core-$(CONFIG_MIPS_MALTA) += arch/mips/mips-boards/malta/
317cflags-$(CONFIG_MIPS_MALTA) += -Iinclude/asm-mips/mach-mips 323cflags-$(CONFIG_MIPS_MALTA) += -Iinclude/asm-mips/mach-mips
318load-$(CONFIG_MIPS_MALTA) += 0xffffffff80100000 324load-$(CONFIG_MIPS_MALTA) += 0xffffffff80100000
319all-$(CONFIG_MIPS_MALTA) := vmlinux.srec 325all-$(CONFIG_MIPS_MALTA) := vmlinux.bin
320 326
321# 327#
322# MIPS SEAD board 328# MIPS SEAD board
@@ -349,14 +355,6 @@ cflags-$(CONFIG_PMC_YOSEMITE) += -Iinclude/asm-mips/mach-yosemite
349load-$(CONFIG_PMC_YOSEMITE) += 0xffffffff80100000 355load-$(CONFIG_PMC_YOSEMITE) += 0xffffffff80100000
350 356
351# 357#
352# Qemu simulating MIPS32 4Kc
353#
354core-$(CONFIG_QEMU) += arch/mips/qemu/
355cflags-$(CONFIG_QEMU) += -Iinclude/asm-mips/mach-qemu
356load-$(CONFIG_QEMU) += 0xffffffff80010000
357all-$(CONFIG_QEMU) := vmlinux.bin
358
359#
360# Basler eXcite 358# Basler eXcite
361# 359#
362core-$(CONFIG_BASLER_EXCITE) += arch/mips/basler/excite/ 360core-$(CONFIG_BASLER_EXCITE) += arch/mips/basler/excite/
@@ -475,6 +473,20 @@ endif
475endif 473endif
476 474
477# 475#
476# SGI IP28 (Indigo2 R10k)
477#
478# Set the load address to >= 0xa800000020080000 if you want to leave space for
479# symmon, 0xa800000020004000 for production kernels ? Note that the value must
480# be 16kb aligned or the handling of the current variable will break.
481# Simplified: what IP22 does at 128MB+ in ksegN, IP28 does at 512MB+ in xkphys
482#
483#core-$(CONFIG_SGI_IP28) += arch/mips/sgi-ip22/ arch/mips/arc/arc_con.o
484core-$(CONFIG_SGI_IP28) += arch/mips/sgi-ip22/
485cflags-$(CONFIG_SGI_IP28) += -mr10k-cache-barrier=1 -Iinclude/asm-mips/mach-ip28
486#cflags-$(CONFIG_SGI_IP28) += -Iinclude/asm-mips/mach-ip28
487load-$(CONFIG_SGI_IP28) += 0xa800000020004000
488
489#
478# SGI-IP32 (O2) 490# SGI-IP32 (O2)
479# 491#
480# Set the load address to >= 80069000 if you want to leave space for symmon, 492# Set the load address to >= 80069000 if you want to leave space for symmon,
@@ -602,9 +614,11 @@ ifdef CONFIG_64BIT
602 endif 614 endif
603 endif 615 endif
604 616
605 ifeq ($(KBUILD_SYM32), y) 617 ifeq ($(KBUILD_SYM32)$(call cc-option-yn,-msym32), yy)
606 ifeq ($(call cc-option-yn,-msym32), y) 618 cflags-y += -msym32 -DKBUILD_64BIT_SYM32
607 cflags-y += -msym32 -DKBUILD_64BIT_SYM32 619 else
620 ifeq ($(CONFIG_CPU_DADDI_WORKAROUNDS), y)
621 $(error CONFIG_CPU_DADDI_WORKAROUNDS unsupported without -msym32)
608 endif 622 endif
609 endif 623 endif
610endif 624endif
diff --git a/arch/mips/au1000/common/au1xxx_irqmap.c b/arch/mips/au1000/common/au1xxx_irqmap.c
index 98a4e34b0248..37a10a01de9d 100644
--- a/arch/mips/au1000/common/au1xxx_irqmap.c
+++ b/arch/mips/au1000/common/au1xxx_irqmap.c
@@ -25,27 +25,10 @@
25 * with this program; if not, write to the Free Software Foundation, Inc., 25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 675 Mass Ave, Cambridge, MA 02139, USA. 26 * 675 Mass Ave, Cambridge, MA 02139, USA.
27 */ 27 */
28#include <linux/errno.h>
29#include <linux/init.h> 28#include <linux/init.h>
30#include <linux/irq.h> 29#include <linux/kernel.h>
31#include <linux/kernel_stat.h>
32#include <linux/module.h>
33#include <linux/signal.h>
34#include <linux/sched.h>
35#include <linux/types.h>
36#include <linux/interrupt.h>
37#include <linux/ioport.h>
38#include <linux/timex.h>
39#include <linux/slab.h>
40#include <linux/random.h>
41#include <linux/delay.h>
42#include <linux/bitops.h>
43 30
44#include <asm/bootinfo.h> 31#include <au1000.h>
45#include <asm/io.h>
46#include <asm/mipsregs.h>
47#include <asm/system.h>
48#include <asm/mach-au1x00/au1000.h>
49 32
50/* The IC0 interrupt table. This is processor, rather than 33/* The IC0 interrupt table. This is processor, rather than
51 * board dependent, so no reason to keep this info in the board 34 * board dependent, so no reason to keep this info in the board
diff --git a/arch/mips/au1000/common/dbdma.c b/arch/mips/au1000/common/dbdma.c
index edf91f41a786..428ed275a0f6 100644
--- a/arch/mips/au1000/common/dbdma.c
+++ b/arch/mips/au1000/common/dbdma.c
@@ -179,7 +179,7 @@ static dbdev_tab_t dbdev_tab[] = {
179 { 0, 0, 0, 0, 0, 0, 0 }, 179 { 0, 0, 0, 0, 0, 0, 0 },
180}; 180};
181 181
182#define DBDEV_TAB_SIZE (sizeof(dbdev_tab) / sizeof(dbdev_tab_t)) 182#define DBDEV_TAB_SIZE ARRAY_SIZE(dbdev_tab)
183 183
184static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS]; 184static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS];
185 185
diff --git a/arch/mips/au1000/common/platform.c b/arch/mips/au1000/common/platform.c
index d51e18fb789b..841904cdef4d 100644
--- a/arch/mips/au1000/common/platform.c
+++ b/arch/mips/au1000/common/platform.c
@@ -270,6 +270,24 @@ static struct platform_device smc91x_device = {
270 270
271#endif 271#endif
272 272
273/* All Alchemy demoboards with I2C have this #define in their headers */
274#ifdef SMBUS_PSC_BASE
275static struct resource pbdb_smbus_resources[] = {
276 {
277 .start = SMBUS_PSC_BASE,
278 .end = SMBUS_PSC_BASE + 0x24 - 1,
279 .flags = IORESOURCE_MEM,
280 },
281};
282
283static struct platform_device pbdb_smbus_device = {
284 .name = "au1xpsc_smbus",
285 .id = 0, /* bus number */
286 .num_resources = ARRAY_SIZE(pbdb_smbus_resources),
287 .resource = pbdb_smbus_resources,
288};
289#endif
290
273static struct platform_device *au1xxx_platform_devices[] __initdata = { 291static struct platform_device *au1xxx_platform_devices[] __initdata = {
274 &au1xxx_usb_ohci_device, 292 &au1xxx_usb_ohci_device,
275 &au1x00_pcmcia_device, 293 &au1x00_pcmcia_device,
@@ -287,6 +305,9 @@ static struct platform_device *au1xxx_platform_devices[] __initdata = {
287#ifdef CONFIG_MIPS_DB1200 305#ifdef CONFIG_MIPS_DB1200
288 &smc91x_device, 306 &smc91x_device,
289#endif 307#endif
308#ifdef SMBUS_PSC_BASE
309 &pbdb_smbus_device,
310#endif
290}; 311};
291 312
292int __init au1xxx_platform_init(void) 313int __init au1xxx_platform_init(void)
diff --git a/arch/mips/au1000/db1x00/init.c b/arch/mips/au1000/db1x00/init.c
index 43298fd9459c..e822c123eab8 100644
--- a/arch/mips/au1000/db1x00/init.c
+++ b/arch/mips/au1000/db1x00/init.c
@@ -57,17 +57,6 @@ void __init prom_init(void)
57 prom_argv = (char **) fw_arg1; 57 prom_argv = (char **) fw_arg1;
58 prom_envp = (char **) fw_arg2; 58 prom_envp = (char **) fw_arg2;
59 59
60 /* Set the platform # */
61#if defined(CONFIG_MIPS_DB1550)
62 mips_machtype = MACH_DB1550;
63#elif defined(CONFIG_MIPS_DB1500)
64 mips_machtype = MACH_DB1500;
65#elif defined(CONFIG_MIPS_DB1100)
66 mips_machtype = MACH_DB1100;
67#else
68 mips_machtype = MACH_DB1000;
69#endif
70
71 prom_init_cmdline(); 60 prom_init_cmdline();
72 61
73 memsize_str = prom_getenv("memsize"); 62 memsize_str = prom_getenv("memsize");
diff --git a/arch/mips/au1000/mtx-1/init.c b/arch/mips/au1000/mtx-1/init.c
index cdeae3212a2d..e700fd312a24 100644
--- a/arch/mips/au1000/mtx-1/init.c
+++ b/arch/mips/au1000/mtx-1/init.c
@@ -54,8 +54,6 @@ void __init prom_init(void)
54 prom_argv = (char **) fw_arg1; 54 prom_argv = (char **) fw_arg1;
55 prom_envp = (char **) fw_arg2; 55 prom_envp = (char **) fw_arg2;
56 56
57 mips_machtype = MACH_MTX1; /* set the platform # */
58
59 prom_init_cmdline(); 57 prom_init_cmdline();
60 58
61 memsize_str = prom_getenv("memsize"); 59 memsize_str = prom_getenv("memsize");
diff --git a/arch/mips/au1000/mtx-1/platform.c b/arch/mips/au1000/mtx-1/platform.c
index 49c0fb409fea..ce8637b3afa9 100644
--- a/arch/mips/au1000/mtx-1/platform.c
+++ b/arch/mips/au1000/mtx-1/platform.c
@@ -22,9 +22,32 @@
22#include <linux/types.h> 22#include <linux/types.h>
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24#include <linux/leds.h> 24#include <linux/leds.h>
25#include <linux/gpio_keys.h>
26#include <linux/input.h>
25 27
26#include <asm/gpio.h> 28#include <asm/gpio.h>
27 29
30static struct gpio_keys_button mtx1_gpio_button[] = {
31 {
32 .gpio = 207,
33 .code = BTN_0,
34 .desc = "System button",
35 }
36};
37
38static struct gpio_keys_platform_data mtx1_buttons_data = {
39 .buttons = mtx1_gpio_button,
40 .nbuttons = ARRAY_SIZE(mtx1_gpio_button),
41};
42
43static struct platform_device mtx1_button = {
44 .name = "gpio-keys",
45 .id = -1,
46 .dev = {
47 .platform_data = &mtx1_buttons_data,
48 }
49};
50
28static struct resource mtx1_wdt_res[] = { 51static struct resource mtx1_wdt_res[] = {
29 [0] = { 52 [0] = {
30 .start = 15, 53 .start = 15,
@@ -66,11 +89,13 @@ static struct platform_device mtx1_gpio_leds = {
66 89
67static struct __initdata platform_device * mtx1_devs[] = { 90static struct __initdata platform_device * mtx1_devs[] = {
68 &mtx1_gpio_leds, 91 &mtx1_gpio_leds,
69 &mtx1_wdt 92 &mtx1_wdt,
93 &mtx1_button
70}; 94};
71 95
72static int __init mtx1_register_devices(void) 96static int __init mtx1_register_devices(void)
73{ 97{
98 gpio_direction_input(207);
74 return platform_add_devices(mtx1_devs, ARRAY_SIZE(mtx1_devs)); 99 return platform_add_devices(mtx1_devs, ARRAY_SIZE(mtx1_devs));
75} 100}
76 101
diff --git a/arch/mips/au1000/pb1000/init.c b/arch/mips/au1000/pb1000/init.c
index ddccaf6997d0..2515b9fb24af 100644
--- a/arch/mips/au1000/pb1000/init.c
+++ b/arch/mips/au1000/pb1000/init.c
@@ -52,8 +52,6 @@ void __init prom_init(void)
52 prom_argv = (char **) fw_arg1; 52 prom_argv = (char **) fw_arg1;
53 prom_envp = (char **) fw_arg2; 53 prom_envp = (char **) fw_arg2;
54 54
55 mips_machtype = MACH_PB1000;
56
57 prom_init_cmdline(); 55 prom_init_cmdline();
58 memsize_str = prom_getenv("memsize"); 56 memsize_str = prom_getenv("memsize");
59 if (!memsize_str) { 57 if (!memsize_str) {
diff --git a/arch/mips/au1000/pb1100/init.c b/arch/mips/au1000/pb1100/init.c
index c93fd39b4aba..490c3801c275 100644
--- a/arch/mips/au1000/pb1100/init.c
+++ b/arch/mips/au1000/pb1100/init.c
@@ -53,8 +53,6 @@ void __init prom_init(void)
53 prom_argv = (char **) fw_arg1; 53 prom_argv = (char **) fw_arg1;
54 prom_envp = (char **) fw_arg3; 54 prom_envp = (char **) fw_arg3;
55 55
56 mips_machtype = MACH_PB1100;
57
58 prom_init_cmdline(); 56 prom_init_cmdline();
59 57
60 memsize_str = prom_getenv("memsize"); 58 memsize_str = prom_getenv("memsize");
diff --git a/arch/mips/au1000/pb1200/init.c b/arch/mips/au1000/pb1200/init.c
index c251570749ee..069ed45f04f2 100644
--- a/arch/mips/au1000/pb1200/init.c
+++ b/arch/mips/au1000/pb1200/init.c
@@ -53,8 +53,6 @@ void __init prom_init(void)
53 prom_argv = (char **) fw_arg1; 53 prom_argv = (char **) fw_arg1;
54 prom_envp = (char **) fw_arg2; 54 prom_envp = (char **) fw_arg2;
55 55
56 mips_machtype = MACH_PB1200;
57
58 prom_init_cmdline(); 56 prom_init_cmdline();
59 memsize_str = prom_getenv("memsize"); 57 memsize_str = prom_getenv("memsize");
60 if (!memsize_str) { 58 if (!memsize_str) {
diff --git a/arch/mips/au1000/pb1500/init.c b/arch/mips/au1000/pb1500/init.c
index 507d4b204161..db558c967048 100644
--- a/arch/mips/au1000/pb1500/init.c
+++ b/arch/mips/au1000/pb1500/init.c
@@ -53,8 +53,6 @@ void __init prom_init(void)
53 prom_argv = (char **) fw_arg1; 53 prom_argv = (char **) fw_arg1;
54 prom_envp = (char **) fw_arg2; 54 prom_envp = (char **) fw_arg2;
55 55
56 mips_machtype = MACH_PB1500;
57
58 prom_init_cmdline(); 56 prom_init_cmdline();
59 memsize_str = prom_getenv("memsize"); 57 memsize_str = prom_getenv("memsize");
60 if (!memsize_str) { 58 if (!memsize_str) {
diff --git a/arch/mips/au1000/pb1550/init.c b/arch/mips/au1000/pb1550/init.c
index b03eee601e36..b716363ea564 100644
--- a/arch/mips/au1000/pb1550/init.c
+++ b/arch/mips/au1000/pb1550/init.c
@@ -53,8 +53,6 @@ void __init prom_init(void)
53 prom_argv = (char **) fw_arg1; 53 prom_argv = (char **) fw_arg1;
54 prom_envp = (char **) fw_arg2; 54 prom_envp = (char **) fw_arg2;
55 55
56 mips_machtype = MACH_PB1550;
57
58 prom_init_cmdline(); 56 prom_init_cmdline();
59 memsize_str = prom_getenv("memsize"); 57 memsize_str = prom_getenv("memsize");
60 if (!memsize_str) { 58 if (!memsize_str) {
diff --git a/arch/mips/au1000/xxs1500/init.c b/arch/mips/au1000/xxs1500/init.c
index 6532939f377a..7e6878c1b0a5 100644
--- a/arch/mips/au1000/xxs1500/init.c
+++ b/arch/mips/au1000/xxs1500/init.c
@@ -52,8 +52,6 @@ void __init prom_init(void)
52 prom_argv = (char **) fw_arg1; 52 prom_argv = (char **) fw_arg1;
53 prom_envp = (char **) fw_arg2; 53 prom_envp = (char **) fw_arg2;
54 54
55 mips_machtype = MACH_XXS1500; /* set the platform # */
56
57 prom_init_cmdline(); 55 prom_init_cmdline();
58 56
59 memsize_str = prom_getenv("memsize"); 57 memsize_str = prom_getenv("memsize");
diff --git a/arch/mips/basler/excite/Kconfig b/arch/mips/basler/excite/Kconfig
new file mode 100644
index 000000000000..ba506075608b
--- /dev/null
+++ b/arch/mips/basler/excite/Kconfig
@@ -0,0 +1,9 @@
1config BASLER_EXCITE_PROTOTYPE
2 bool "Support for pre-release units"
3 depends on BASLER_EXCITE
4 default n
5 help
6 Pre-series (prototype) units are different from later ones in
7 some ways. Select this option if you have one of these. Please
8 note that a kernel built with this option selected will not be
9 able to run on normal units.
diff --git a/arch/mips/basler/excite/excite_iodev.c b/arch/mips/basler/excite/excite_iodev.c
index 6af0b21ebc32..476d20e08d0e 100644
--- a/arch/mips/basler/excite/excite_iodev.c
+++ b/arch/mips/basler/excite/excite_iodev.c
@@ -48,7 +48,7 @@ static DECLARE_WAIT_QUEUE_HEAD(wq);
48 48
49 49
50 50
51static struct file_operations fops = 51static const struct file_operations fops =
52{ 52{
53 .owner = THIS_MODULE, 53 .owner = THIS_MODULE,
54 .open = iodev_open, 54 .open = iodev_open,
diff --git a/arch/mips/basler/excite/excite_prom.c b/arch/mips/basler/excite/excite_prom.c
index 2d752c2f6e59..68d8bc597e34 100644
--- a/arch/mips/basler/excite/excite_prom.c
+++ b/arch/mips/basler/excite/excite_prom.c
@@ -135,8 +135,6 @@ void __init prom_init(void)
135#ifdef CONFIG_64BIT 135#ifdef CONFIG_64BIT
136# error 64 bit support not implemented 136# error 64 bit support not implemented
137#endif /* CONFIG_64BIT */ 137#endif /* CONFIG_64BIT */
138
139 mips_machtype = MACH_TITAN_EXCITE;
140} 138}
141 139
142/* This is called from free_initmem(), so we need to provide it */ 140/* This is called from free_initmem(), so we need to provide it */
diff --git a/arch/mips/cobalt/reset.c b/arch/mips/cobalt/reset.c
index 71eb4ccc4bc1..516b4428df4e 100644
--- a/arch/mips/cobalt/reset.c
+++ b/arch/mips/cobalt/reset.c
@@ -10,9 +10,10 @@
10 */ 10 */
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/io.h> 12#include <linux/io.h>
13#include <linux/jiffies.h>
14#include <linux/leds.h> 13#include <linux/leds.h>
15 14
15#include <asm/processor.h>
16
16#include <cobalt.h> 17#include <cobalt.h>
17 18
18#define RESET_PORT ((void __iomem *)CKSEG1ADDR(0x1c000000)) 19#define RESET_PORT ((void __iomem *)CKSEG1ADDR(0x1c000000))
@@ -29,28 +30,15 @@ device_initcall(ledtrig_power_off_init);
29 30
30void cobalt_machine_halt(void) 31void cobalt_machine_halt(void)
31{ 32{
32 int state, last, diff;
33 unsigned long mark;
34
35 /* 33 /*
36 * turn on power off LED on RaQ 34 * turn on power off LED on RaQ
37 *
38 * restart if ENTER and SELECT are pressed
39 */ 35 */
40
41 last = COBALT_KEY_PORT;
42
43 led_trigger_event(power_off_led_trigger, LED_FULL); 36 led_trigger_event(power_off_led_trigger, LED_FULL);
44 37
45 for (state = 0;;) { 38 local_irq_disable();
46 diff = COBALT_KEY_PORT ^ last; 39 while (1) {
47 last ^= diff; 40 if (cpu_wait)
48 41 cpu_wait();
49 if((diff & (COBALT_KEY_ENTER | COBALT_KEY_SELECT)) && !(~last & (COBALT_KEY_ENTER | COBALT_KEY_SELECT)))
50 writeb(RESET, RESET_PORT);
51
52 for (mark = jiffies; jiffies - mark < HZ;)
53 ;
54 } 42 }
55} 43}
56 44
diff --git a/arch/mips/configs/atlas_defconfig b/arch/mips/configs/atlas_defconfig
index 62bcc887f2ca..3443f6cd57bb 100644
--- a/arch/mips/configs/atlas_defconfig
+++ b/arch/mips/configs/atlas_defconfig
@@ -37,7 +37,6 @@ CONFIG_MIPS_ATLAS=y
37# CONFIG_PNX8550_STB810 is not set 37# CONFIG_PNX8550_STB810 is not set
38# CONFIG_MACH_VR41XX is not set 38# CONFIG_MACH_VR41XX is not set
39# CONFIG_PMC_YOSEMITE is not set 39# CONFIG_PMC_YOSEMITE is not set
40# CONFIG_QEMU is not set
41# CONFIG_MARKEINS is not set 40# CONFIG_MARKEINS is not set
42# CONFIG_SGI_IP22 is not set 41# CONFIG_SGI_IP22 is not set
43# CONFIG_SGI_IP27 is not set 42# CONFIG_SGI_IP27 is not set
@@ -47,7 +46,6 @@ CONFIG_MIPS_ATLAS=y
47# CONFIG_SIBYTE_SENTOSA is not set 46# CONFIG_SIBYTE_SENTOSA is not set
48# CONFIG_SIBYTE_RHONE is not set 47# CONFIG_SIBYTE_RHONE is not set
49# CONFIG_SIBYTE_CARMEL is not set 48# CONFIG_SIBYTE_CARMEL is not set
50# CONFIG_SIBYTE_PTSWARM is not set
51# CONFIG_SIBYTE_LITTLESUR is not set 49# CONFIG_SIBYTE_LITTLESUR is not set
52# CONFIG_SIBYTE_CRHINE is not set 50# CONFIG_SIBYTE_CRHINE is not set
53# CONFIG_SIBYTE_CRHONE is not set 51# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig
index 3c70c9d16d01..abf70d74e9d7 100644
--- a/arch/mips/configs/bigsur_defconfig
+++ b/arch/mips/configs/bigsur_defconfig
@@ -37,7 +37,6 @@ CONFIG_ZONE_DMA=y
37# CONFIG_PNX8550_STB810 is not set 37# CONFIG_PNX8550_STB810 is not set
38# CONFIG_MACH_VR41XX is not set 38# CONFIG_MACH_VR41XX is not set
39# CONFIG_PMC_YOSEMITE is not set 39# CONFIG_PMC_YOSEMITE is not set
40# CONFIG_QEMU is not set
41# CONFIG_MARKEINS is not set 40# CONFIG_MARKEINS is not set
42# CONFIG_SGI_IP22 is not set 41# CONFIG_SGI_IP22 is not set
43# CONFIG_SGI_IP27 is not set 42# CONFIG_SGI_IP27 is not set
@@ -47,7 +46,6 @@ CONFIG_SIBYTE_BIGSUR=y
47# CONFIG_SIBYTE_SENTOSA is not set 46# CONFIG_SIBYTE_SENTOSA is not set
48# CONFIG_SIBYTE_RHONE is not set 47# CONFIG_SIBYTE_RHONE is not set
49# CONFIG_SIBYTE_CARMEL is not set 48# CONFIG_SIBYTE_CARMEL is not set
50# CONFIG_SIBYTE_PTSWARM is not set
51# CONFIG_SIBYTE_LITTLESUR is not set 49# CONFIG_SIBYTE_LITTLESUR is not set
52# CONFIG_SIBYTE_CRHINE is not set 50# CONFIG_SIBYTE_CRHINE is not set
53# CONFIG_SIBYTE_CRHONE is not set 51# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/capcella_defconfig b/arch/mips/configs/capcella_defconfig
index 8ecbbb226c76..a94f14b5c8fa 100644
--- a/arch/mips/configs/capcella_defconfig
+++ b/arch/mips/configs/capcella_defconfig
@@ -24,7 +24,6 @@ CONFIG_MACH_VR41XX=y
24# CONFIG_PNX8550_STB810 is not set 24# CONFIG_PNX8550_STB810 is not set
25# CONFIG_PMC_MSP is not set 25# CONFIG_PMC_MSP is not set
26# CONFIG_PMC_YOSEMITE is not set 26# CONFIG_PMC_YOSEMITE is not set
27# CONFIG_QEMU is not set
28# CONFIG_SGI_IP22 is not set 27# CONFIG_SGI_IP22 is not set
29# CONFIG_SGI_IP27 is not set 28# CONFIG_SGI_IP27 is not set
30# CONFIG_SGI_IP32 is not set 29# CONFIG_SGI_IP32 is not set
@@ -35,7 +34,6 @@ CONFIG_MACH_VR41XX=y
35# CONFIG_SIBYTE_SWARM is not set 34# CONFIG_SIBYTE_SWARM is not set
36# CONFIG_SIBYTE_LITTLESUR is not set 35# CONFIG_SIBYTE_LITTLESUR is not set
37# CONFIG_SIBYTE_SENTOSA is not set 36# CONFIG_SIBYTE_SENTOSA is not set
38# CONFIG_SIBYTE_PTSWARM is not set
39# CONFIG_SIBYTE_BIGSUR is not set 37# CONFIG_SIBYTE_BIGSUR is not set
40# CONFIG_SNI_RM is not set 38# CONFIG_SNI_RM is not set
41# CONFIG_TOSHIBA_JMR3927 is not set 39# CONFIG_TOSHIBA_JMR3927 is not set
diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig
index 36c13039e237..b7295e988381 100644
--- a/arch/mips/configs/cobalt_defconfig
+++ b/arch/mips/configs/cobalt_defconfig
@@ -24,7 +24,6 @@ CONFIG_MIPS_COBALT=y
24# CONFIG_PNX8550_STB810 is not set 24# CONFIG_PNX8550_STB810 is not set
25# CONFIG_PMC_MSP is not set 25# CONFIG_PMC_MSP is not set
26# CONFIG_PMC_YOSEMITE is not set 26# CONFIG_PMC_YOSEMITE is not set
27# CONFIG_QEMU is not set
28# CONFIG_SGI_IP22 is not set 27# CONFIG_SGI_IP22 is not set
29# CONFIG_SGI_IP27 is not set 28# CONFIG_SGI_IP27 is not set
30# CONFIG_SGI_IP32 is not set 29# CONFIG_SGI_IP32 is not set
@@ -35,7 +34,6 @@ CONFIG_MIPS_COBALT=y
35# CONFIG_SIBYTE_SWARM is not set 34# CONFIG_SIBYTE_SWARM is not set
36# CONFIG_SIBYTE_LITTLESUR is not set 35# CONFIG_SIBYTE_LITTLESUR is not set
37# CONFIG_SIBYTE_SENTOSA is not set 36# CONFIG_SIBYTE_SENTOSA is not set
38# CONFIG_SIBYTE_PTSWARM is not set
39# CONFIG_SIBYTE_BIGSUR is not set 37# CONFIG_SIBYTE_BIGSUR is not set
40# CONFIG_SNI_RM is not set 38# CONFIG_SNI_RM is not set
41# CONFIG_TOSHIBA_JMR3927 is not set 39# CONFIG_TOSHIBA_JMR3927 is not set
diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig
index 5a8b7acb7dd7..36578968d386 100644
--- a/arch/mips/configs/db1000_defconfig
+++ b/arch/mips/configs/db1000_defconfig
@@ -38,7 +38,6 @@ CONFIG_MIPS_DB1000=y
38# CONFIG_PNX8550_STB810 is not set 38# CONFIG_PNX8550_STB810 is not set
39# CONFIG_MACH_VR41XX is not set 39# CONFIG_MACH_VR41XX is not set
40# CONFIG_PMC_YOSEMITE is not set 40# CONFIG_PMC_YOSEMITE is not set
41# CONFIG_QEMU is not set
42# CONFIG_MARKEINS is not set 41# CONFIG_MARKEINS is not set
43# CONFIG_SGI_IP22 is not set 42# CONFIG_SGI_IP22 is not set
44# CONFIG_SGI_IP27 is not set 43# CONFIG_SGI_IP27 is not set
@@ -48,7 +47,6 @@ CONFIG_MIPS_DB1000=y
48# CONFIG_SIBYTE_SENTOSA is not set 47# CONFIG_SIBYTE_SENTOSA is not set
49# CONFIG_SIBYTE_RHONE is not set 48# CONFIG_SIBYTE_RHONE is not set
50# CONFIG_SIBYTE_CARMEL is not set 49# CONFIG_SIBYTE_CARMEL is not set
51# CONFIG_SIBYTE_PTSWARM is not set
52# CONFIG_SIBYTE_LITTLESUR is not set 50# CONFIG_SIBYTE_LITTLESUR is not set
53# CONFIG_SIBYTE_CRHINE is not set 51# CONFIG_SIBYTE_CRHINE is not set
54# CONFIG_SIBYTE_CRHONE is not set 52# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig
index d4ed90bca269..5a90740c363a 100644
--- a/arch/mips/configs/db1100_defconfig
+++ b/arch/mips/configs/db1100_defconfig
@@ -38,7 +38,6 @@ CONFIG_MIPS_DB1100=y
38# CONFIG_PNX8550_STB810 is not set 38# CONFIG_PNX8550_STB810 is not set
39# CONFIG_MACH_VR41XX is not set 39# CONFIG_MACH_VR41XX is not set
40# CONFIG_PMC_YOSEMITE is not set 40# CONFIG_PMC_YOSEMITE is not set
41# CONFIG_QEMU is not set
42# CONFIG_MARKEINS is not set 41# CONFIG_MARKEINS is not set
43# CONFIG_SGI_IP22 is not set 42# CONFIG_SGI_IP22 is not set
44# CONFIG_SGI_IP27 is not set 43# CONFIG_SGI_IP27 is not set
@@ -48,7 +47,6 @@ CONFIG_MIPS_DB1100=y
48# CONFIG_SIBYTE_SENTOSA is not set 47# CONFIG_SIBYTE_SENTOSA is not set
49# CONFIG_SIBYTE_RHONE is not set 48# CONFIG_SIBYTE_RHONE is not set
50# CONFIG_SIBYTE_CARMEL is not set 49# CONFIG_SIBYTE_CARMEL is not set
51# CONFIG_SIBYTE_PTSWARM is not set
52# CONFIG_SIBYTE_LITTLESUR is not set 50# CONFIG_SIBYTE_LITTLESUR is not set
53# CONFIG_SIBYTE_CRHINE is not set 51# CONFIG_SIBYTE_CRHINE is not set
54# CONFIG_SIBYTE_CRHONE is not set 52# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/db1200_defconfig b/arch/mips/configs/db1200_defconfig
index a055657e6983..76f37a1159fe 100644
--- a/arch/mips/configs/db1200_defconfig
+++ b/arch/mips/configs/db1200_defconfig
@@ -38,7 +38,6 @@ CONFIG_MIPS_DB1200=y
38# CONFIG_PNX8550_STB810 is not set 38# CONFIG_PNX8550_STB810 is not set
39# CONFIG_MACH_VR41XX is not set 39# CONFIG_MACH_VR41XX is not set
40# CONFIG_PMC_YOSEMITE is not set 40# CONFIG_PMC_YOSEMITE is not set
41# CONFIG_QEMU is not set
42# CONFIG_MARKEINS is not set 41# CONFIG_MARKEINS is not set
43# CONFIG_SGI_IP22 is not set 42# CONFIG_SGI_IP22 is not set
44# CONFIG_SGI_IP27 is not set 43# CONFIG_SGI_IP27 is not set
@@ -48,7 +47,6 @@ CONFIG_MIPS_DB1200=y
48# CONFIG_SIBYTE_SENTOSA is not set 47# CONFIG_SIBYTE_SENTOSA is not set
49# CONFIG_SIBYTE_RHONE is not set 48# CONFIG_SIBYTE_RHONE is not set
50# CONFIG_SIBYTE_CARMEL is not set 49# CONFIG_SIBYTE_CARMEL is not set
51# CONFIG_SIBYTE_PTSWARM is not set
52# CONFIG_SIBYTE_LITTLESUR is not set 50# CONFIG_SIBYTE_LITTLESUR is not set
53# CONFIG_SIBYTE_CRHINE is not set 51# CONFIG_SIBYTE_CRHINE is not set
54# CONFIG_SIBYTE_CRHONE is not set 52# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig
index 0ad08cf446ec..508c91944f30 100644
--- a/arch/mips/configs/db1500_defconfig
+++ b/arch/mips/configs/db1500_defconfig
@@ -38,7 +38,6 @@ CONFIG_MIPS_DB1500=y
38# CONFIG_PNX8550_STB810 is not set 38# CONFIG_PNX8550_STB810 is not set
39# CONFIG_MACH_VR41XX is not set 39# CONFIG_MACH_VR41XX is not set
40# CONFIG_PMC_YOSEMITE is not set 40# CONFIG_PMC_YOSEMITE is not set
41# CONFIG_QEMU is not set
42# CONFIG_MARKEINS is not set 41# CONFIG_MARKEINS is not set
43# CONFIG_SGI_IP22 is not set 42# CONFIG_SGI_IP22 is not set
44# CONFIG_SGI_IP27 is not set 43# CONFIG_SGI_IP27 is not set
@@ -48,7 +47,6 @@ CONFIG_MIPS_DB1500=y
48# CONFIG_SIBYTE_SENTOSA is not set 47# CONFIG_SIBYTE_SENTOSA is not set
49# CONFIG_SIBYTE_RHONE is not set 48# CONFIG_SIBYTE_RHONE is not set
50# CONFIG_SIBYTE_CARMEL is not set 49# CONFIG_SIBYTE_CARMEL is not set
51# CONFIG_SIBYTE_PTSWARM is not set
52# CONFIG_SIBYTE_LITTLESUR is not set 50# CONFIG_SIBYTE_LITTLESUR is not set
53# CONFIG_SIBYTE_CRHINE is not set 51# CONFIG_SIBYTE_CRHINE is not set
54# CONFIG_SIBYTE_CRHONE is not set 52# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig
index 057c7d429c80..0c2c70d21db9 100644
--- a/arch/mips/configs/db1550_defconfig
+++ b/arch/mips/configs/db1550_defconfig
@@ -38,7 +38,6 @@ CONFIG_MIPS_DB1550=y
38# CONFIG_PNX8550_STB810 is not set 38# CONFIG_PNX8550_STB810 is not set
39# CONFIG_MACH_VR41XX is not set 39# CONFIG_MACH_VR41XX is not set
40# CONFIG_PMC_YOSEMITE is not set 40# CONFIG_PMC_YOSEMITE is not set
41# CONFIG_QEMU is not set
42# CONFIG_MARKEINS is not set 41# CONFIG_MARKEINS is not set
43# CONFIG_SGI_IP22 is not set 42# CONFIG_SGI_IP22 is not set
44# CONFIG_SGI_IP27 is not set 43# CONFIG_SGI_IP27 is not set
@@ -48,7 +47,6 @@ CONFIG_MIPS_DB1550=y
48# CONFIG_SIBYTE_SENTOSA is not set 47# CONFIG_SIBYTE_SENTOSA is not set
49# CONFIG_SIBYTE_RHONE is not set 48# CONFIG_SIBYTE_RHONE is not set
50# CONFIG_SIBYTE_CARMEL is not set 49# CONFIG_SIBYTE_CARMEL is not set
51# CONFIG_SIBYTE_PTSWARM is not set
52# CONFIG_SIBYTE_LITTLESUR is not set 50# CONFIG_SIBYTE_LITTLESUR is not set
53# CONFIG_SIBYTE_CRHINE is not set 51# CONFIG_SIBYTE_CRHINE is not set
54# CONFIG_SIBYTE_CRHONE is not set 52# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig
index 2fb350432669..58c2cd68c3a7 100644
--- a/arch/mips/configs/decstation_defconfig
+++ b/arch/mips/configs/decstation_defconfig
@@ -37,7 +37,6 @@ CONFIG_MACH_DECSTATION=y
37# CONFIG_PNX8550_STB810 is not set 37# CONFIG_PNX8550_STB810 is not set
38# CONFIG_MACH_VR41XX is not set 38# CONFIG_MACH_VR41XX is not set
39# CONFIG_PMC_YOSEMITE is not set 39# CONFIG_PMC_YOSEMITE is not set
40# CONFIG_QEMU is not set
41# CONFIG_MARKEINS is not set 40# CONFIG_MARKEINS is not set
42# CONFIG_SGI_IP22 is not set 41# CONFIG_SGI_IP22 is not set
43# CONFIG_SGI_IP27 is not set 42# CONFIG_SGI_IP27 is not set
@@ -47,7 +46,6 @@ CONFIG_MACH_DECSTATION=y
47# CONFIG_SIBYTE_SENTOSA is not set 46# CONFIG_SIBYTE_SENTOSA is not set
48# CONFIG_SIBYTE_RHONE is not set 47# CONFIG_SIBYTE_RHONE is not set
49# CONFIG_SIBYTE_CARMEL is not set 48# CONFIG_SIBYTE_CARMEL is not set
50# CONFIG_SIBYTE_PTSWARM is not set
51# CONFIG_SIBYTE_LITTLESUR is not set 49# CONFIG_SIBYTE_LITTLESUR is not set
52# CONFIG_SIBYTE_CRHINE is not set 50# CONFIG_SIBYTE_CRHINE is not set
53# CONFIG_SIBYTE_CRHONE is not set 51# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/e55_defconfig b/arch/mips/configs/e55_defconfig
index d0d07faeb844..90d81f5dcebc 100644
--- a/arch/mips/configs/e55_defconfig
+++ b/arch/mips/configs/e55_defconfig
@@ -24,7 +24,6 @@ CONFIG_MACH_VR41XX=y
24# CONFIG_PNX8550_STB810 is not set 24# CONFIG_PNX8550_STB810 is not set
25# CONFIG_PMC_MSP is not set 25# CONFIG_PMC_MSP is not set
26# CONFIG_PMC_YOSEMITE is not set 26# CONFIG_PMC_YOSEMITE is not set
27# CONFIG_QEMU is not set
28# CONFIG_SGI_IP22 is not set 27# CONFIG_SGI_IP22 is not set
29# CONFIG_SGI_IP27 is not set 28# CONFIG_SGI_IP27 is not set
30# CONFIG_SGI_IP32 is not set 29# CONFIG_SGI_IP32 is not set
@@ -35,7 +34,6 @@ CONFIG_MACH_VR41XX=y
35# CONFIG_SIBYTE_SWARM is not set 34# CONFIG_SIBYTE_SWARM is not set
36# CONFIG_SIBYTE_LITTLESUR is not set 35# CONFIG_SIBYTE_LITTLESUR is not set
37# CONFIG_SIBYTE_SENTOSA is not set 36# CONFIG_SIBYTE_SENTOSA is not set
38# CONFIG_SIBYTE_PTSWARM is not set
39# CONFIG_SIBYTE_BIGSUR is not set 37# CONFIG_SIBYTE_BIGSUR is not set
40# CONFIG_SNI_RM is not set 38# CONFIG_SNI_RM is not set
41# CONFIG_TOSHIBA_JMR3927 is not set 39# CONFIG_TOSHIBA_JMR3927 is not set
diff --git a/arch/mips/configs/emma2rh_defconfig b/arch/mips/configs/emma2rh_defconfig
index d73d965f7615..f9a003c2b3a1 100644
--- a/arch/mips/configs/emma2rh_defconfig
+++ b/arch/mips/configs/emma2rh_defconfig
@@ -37,7 +37,6 @@ CONFIG_ZONE_DMA=y
37# CONFIG_PNX8550_STB810 is not set 37# CONFIG_PNX8550_STB810 is not set
38# CONFIG_MACH_VR41XX is not set 38# CONFIG_MACH_VR41XX is not set
39# CONFIG_PMC_YOSEMITE is not set 39# CONFIG_PMC_YOSEMITE is not set
40# CONFIG_QEMU is not set
41CONFIG_MARKEINS=y 40CONFIG_MARKEINS=y
42# CONFIG_SGI_IP22 is not set 41# CONFIG_SGI_IP22 is not set
43# CONFIG_SGI_IP27 is not set 42# CONFIG_SGI_IP27 is not set
@@ -47,7 +46,6 @@ CONFIG_MARKEINS=y
47# CONFIG_SIBYTE_SENTOSA is not set 46# CONFIG_SIBYTE_SENTOSA is not set
48# CONFIG_SIBYTE_RHONE is not set 47# CONFIG_SIBYTE_RHONE is not set
49# CONFIG_SIBYTE_CARMEL is not set 48# CONFIG_SIBYTE_CARMEL is not set
50# CONFIG_SIBYTE_PTSWARM is not set
51# CONFIG_SIBYTE_LITTLESUR is not set 49# CONFIG_SIBYTE_LITTLESUR is not set
52# CONFIG_SIBYTE_CRHINE is not set 50# CONFIG_SIBYTE_CRHINE is not set
53# CONFIG_SIBYTE_CRHONE is not set 51# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/excite_defconfig b/arch/mips/configs/excite_defconfig
index 17a866057fd4..15efacc75d73 100644
--- a/arch/mips/configs/excite_defconfig
+++ b/arch/mips/configs/excite_defconfig
@@ -38,7 +38,6 @@ CONFIG_BASLER_EXCITE=y
38# CONFIG_PNX8550_STB810 is not set 38# CONFIG_PNX8550_STB810 is not set
39# CONFIG_MACH_VR41XX is not set 39# CONFIG_MACH_VR41XX is not set
40# CONFIG_PMC_YOSEMITE is not set 40# CONFIG_PMC_YOSEMITE is not set
41# CONFIG_QEMU is not set
42# CONFIG_MARKEINS is not set 41# CONFIG_MARKEINS is not set
43# CONFIG_SGI_IP22 is not set 42# CONFIG_SGI_IP22 is not set
44# CONFIG_SGI_IP27 is not set 43# CONFIG_SGI_IP27 is not set
@@ -48,7 +47,6 @@ CONFIG_BASLER_EXCITE=y
48# CONFIG_SIBYTE_SENTOSA is not set 47# CONFIG_SIBYTE_SENTOSA is not set
49# CONFIG_SIBYTE_RHONE is not set 48# CONFIG_SIBYTE_RHONE is not set
50# CONFIG_SIBYTE_CARMEL is not set 49# CONFIG_SIBYTE_CARMEL is not set
51# CONFIG_SIBYTE_PTSWARM is not set
52# CONFIG_SIBYTE_LITTLESUR is not set 50# CONFIG_SIBYTE_LITTLESUR is not set
53# CONFIG_SIBYTE_CRHINE is not set 51# CONFIG_SIBYTE_CRHINE is not set
54# CONFIG_SIBYTE_CRHONE is not set 52# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/fulong_defconfig b/arch/mips/configs/fulong_defconfig
index 4ef39a0527cc..5887a1735fba 100644
--- a/arch/mips/configs/fulong_defconfig
+++ b/arch/mips/configs/fulong_defconfig
@@ -23,7 +23,6 @@ CONFIG_LEMOTE_FULONG=y
23# CONFIG_PNX8550_STB810 is not set 23# CONFIG_PNX8550_STB810 is not set
24# CONFIG_MACH_VR41XX is not set 24# CONFIG_MACH_VR41XX is not set
25# CONFIG_PMC_YOSEMITE is not set 25# CONFIG_PMC_YOSEMITE is not set
26# CONFIG_QEMU is not set
27# CONFIG_MARKEINS is not set 26# CONFIG_MARKEINS is not set
28# CONFIG_SGI_IP22 is not set 27# CONFIG_SGI_IP22 is not set
29# CONFIG_SGI_IP27 is not set 28# CONFIG_SGI_IP27 is not set
@@ -33,7 +32,6 @@ CONFIG_LEMOTE_FULONG=y
33# CONFIG_SIBYTE_SENTOSA is not set 32# CONFIG_SIBYTE_SENTOSA is not set
34# CONFIG_SIBYTE_RHONE is not set 33# CONFIG_SIBYTE_RHONE is not set
35# CONFIG_SIBYTE_CARMEL is not set 34# CONFIG_SIBYTE_CARMEL is not set
36# CONFIG_SIBYTE_PTSWARM is not set
37# CONFIG_SIBYTE_LITTLESUR is not set 35# CONFIG_SIBYTE_LITTLESUR is not set
38# CONFIG_SIBYTE_CRHINE is not set 36# CONFIG_SIBYTE_CRHINE is not set
39# CONFIG_SIBYTE_CRHONE is not set 37# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig
index 670039bb1a7c..4f5e56c9335e 100644
--- a/arch/mips/configs/ip22_defconfig
+++ b/arch/mips/configs/ip22_defconfig
@@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y
25# CONFIG_PNX8550_STB810 is not set 25# CONFIG_PNX8550_STB810 is not set
26# CONFIG_PMC_MSP is not set 26# CONFIG_PMC_MSP is not set
27# CONFIG_PMC_YOSEMITE is not set 27# CONFIG_PMC_YOSEMITE is not set
28# CONFIG_QEMU is not set
29CONFIG_SGI_IP22=y 28CONFIG_SGI_IP22=y
30# CONFIG_SGI_IP27 is not set 29# CONFIG_SGI_IP27 is not set
31# CONFIG_SGI_IP32 is not set 30# CONFIG_SGI_IP32 is not set
@@ -36,7 +35,6 @@ CONFIG_SGI_IP22=y
36# CONFIG_SIBYTE_SWARM is not set 35# CONFIG_SIBYTE_SWARM is not set
37# CONFIG_SIBYTE_LITTLESUR is not set 36# CONFIG_SIBYTE_LITTLESUR is not set
38# CONFIG_SIBYTE_SENTOSA is not set 37# CONFIG_SIBYTE_SENTOSA is not set
39# CONFIG_SIBYTE_PTSWARM is not set
40# CONFIG_SIBYTE_BIGSUR is not set 38# CONFIG_SIBYTE_BIGSUR is not set
41# CONFIG_SNI_RM is not set 39# CONFIG_SNI_RM is not set
42# CONFIG_TOSHIBA_JMR3927 is not set 40# CONFIG_TOSHIBA_JMR3927 is not set
diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig
index 892d4c38fd0d..f40e437bd9e5 100644
--- a/arch/mips/configs/ip27_defconfig
+++ b/arch/mips/configs/ip27_defconfig
@@ -24,7 +24,6 @@ CONFIG_MIPS=y
24# CONFIG_PNX8550_STB810 is not set 24# CONFIG_PNX8550_STB810 is not set
25# CONFIG_PMC_MSP is not set 25# CONFIG_PMC_MSP is not set
26# CONFIG_PMC_YOSEMITE is not set 26# CONFIG_PMC_YOSEMITE is not set
27# CONFIG_QEMU is not set
28# CONFIG_SGI_IP22 is not set 27# CONFIG_SGI_IP22 is not set
29CONFIG_SGI_IP27=y 28CONFIG_SGI_IP27=y
30# CONFIG_SGI_IP32 is not set 29# CONFIG_SGI_IP32 is not set
@@ -35,7 +34,6 @@ CONFIG_SGI_IP27=y
35# CONFIG_SIBYTE_SWARM is not set 34# CONFIG_SIBYTE_SWARM is not set
36# CONFIG_SIBYTE_LITTLESUR is not set 35# CONFIG_SIBYTE_LITTLESUR is not set
37# CONFIG_SIBYTE_SENTOSA is not set 36# CONFIG_SIBYTE_SENTOSA is not set
38# CONFIG_SIBYTE_PTSWARM is not set
39# CONFIG_SIBYTE_BIGSUR is not set 37# CONFIG_SIBYTE_BIGSUR is not set
40# CONFIG_SNI_RM is not set 38# CONFIG_SNI_RM is not set
41# CONFIG_TOSHIBA_JMR3927 is not set 39# CONFIG_TOSHIBA_JMR3927 is not set
diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig
index 47f49b60c5d6..2c5c624c5d42 100644
--- a/arch/mips/configs/ip32_defconfig
+++ b/arch/mips/configs/ip32_defconfig
@@ -37,7 +37,6 @@ CONFIG_ZONE_DMA=y
37# CONFIG_PNX8550_STB810 is not set 37# CONFIG_PNX8550_STB810 is not set
38# CONFIG_MACH_VR41XX is not set 38# CONFIG_MACH_VR41XX is not set
39# CONFIG_PMC_YOSEMITE is not set 39# CONFIG_PMC_YOSEMITE is not set
40# CONFIG_QEMU is not set
41# CONFIG_MARKEINS is not set 40# CONFIG_MARKEINS is not set
42# CONFIG_SGI_IP22 is not set 41# CONFIG_SGI_IP22 is not set
43# CONFIG_SGI_IP27 is not set 42# CONFIG_SGI_IP27 is not set
@@ -47,7 +46,6 @@ CONFIG_SGI_IP32=y
47# CONFIG_SIBYTE_SENTOSA is not set 46# CONFIG_SIBYTE_SENTOSA is not set
48# CONFIG_SIBYTE_RHONE is not set 47# CONFIG_SIBYTE_RHONE is not set
49# CONFIG_SIBYTE_CARMEL is not set 48# CONFIG_SIBYTE_CARMEL is not set
50# CONFIG_SIBYTE_PTSWARM is not set
51# CONFIG_SIBYTE_LITTLESUR is not set 49# CONFIG_SIBYTE_LITTLESUR is not set
52# CONFIG_SIBYTE_CRHINE is not set 50# CONFIG_SIBYTE_CRHINE is not set
53# CONFIG_SIBYTE_CRHONE is not set 51# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/jazz_defconfig b/arch/mips/configs/jazz_defconfig
index fa655e247ecc..56148745e8f2 100644
--- a/arch/mips/configs/jazz_defconfig
+++ b/arch/mips/configs/jazz_defconfig
@@ -37,7 +37,6 @@ CONFIG_MACH_JAZZ=y
37# CONFIG_PNX8550_STB810 is not set 37# CONFIG_PNX8550_STB810 is not set
38# CONFIG_MACH_VR41XX is not set 38# CONFIG_MACH_VR41XX is not set
39# CONFIG_PMC_YOSEMITE is not set 39# CONFIG_PMC_YOSEMITE is not set
40# CONFIG_QEMU is not set
41# CONFIG_MARKEINS is not set 40# CONFIG_MARKEINS is not set
42# CONFIG_SGI_IP22 is not set 41# CONFIG_SGI_IP22 is not set
43# CONFIG_SGI_IP27 is not set 42# CONFIG_SGI_IP27 is not set
@@ -47,7 +46,6 @@ CONFIG_MACH_JAZZ=y
47# CONFIG_SIBYTE_SENTOSA is not set 46# CONFIG_SIBYTE_SENTOSA is not set
48# CONFIG_SIBYTE_RHONE is not set 47# CONFIG_SIBYTE_RHONE is not set
49# CONFIG_SIBYTE_CARMEL is not set 48# CONFIG_SIBYTE_CARMEL is not set
50# CONFIG_SIBYTE_PTSWARM is not set
51# CONFIG_SIBYTE_LITTLESUR is not set 49# CONFIG_SIBYTE_LITTLESUR is not set
52# CONFIG_SIBYTE_CRHINE is not set 50# CONFIG_SIBYTE_CRHINE is not set
53# CONFIG_SIBYTE_CRHONE is not set 51# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig
index eb96791c33ea..a7cd67753aac 100644
--- a/arch/mips/configs/jmr3927_defconfig
+++ b/arch/mips/configs/jmr3927_defconfig
@@ -24,7 +24,6 @@ CONFIG_MIPS=y
24# CONFIG_PNX8550_STB810 is not set 24# CONFIG_PNX8550_STB810 is not set
25# CONFIG_PMC_MSP is not set 25# CONFIG_PMC_MSP is not set
26# CONFIG_PMC_YOSEMITE is not set 26# CONFIG_PMC_YOSEMITE is not set
27# CONFIG_QEMU is not set
28# CONFIG_SGI_IP22 is not set 27# CONFIG_SGI_IP22 is not set
29# CONFIG_SGI_IP27 is not set 28# CONFIG_SGI_IP27 is not set
30# CONFIG_SGI_IP32 is not set 29# CONFIG_SGI_IP32 is not set
@@ -35,7 +34,6 @@ CONFIG_MIPS=y
35# CONFIG_SIBYTE_SWARM is not set 34# CONFIG_SIBYTE_SWARM is not set
36# CONFIG_SIBYTE_LITTLESUR is not set 35# CONFIG_SIBYTE_LITTLESUR is not set
37# CONFIG_SIBYTE_SENTOSA is not set 36# CONFIG_SIBYTE_SENTOSA is not set
38# CONFIG_SIBYTE_PTSWARM is not set
39# CONFIG_SIBYTE_BIGSUR is not set 37# CONFIG_SIBYTE_BIGSUR is not set
40# CONFIG_SNI_RM is not set 38# CONFIG_SNI_RM is not set
41CONFIG_TOSHIBA_JMR3927=y 39CONFIG_TOSHIBA_JMR3927=y
@@ -464,7 +462,6 @@ CONFIG_SERIAL_TXX9_STDSERIAL=y
464CONFIG_LEGACY_PTYS=y 462CONFIG_LEGACY_PTYS=y
465CONFIG_LEGACY_PTY_COUNT=256 463CONFIG_LEGACY_PTY_COUNT=256
466# CONFIG_IPMI_HANDLER is not set 464# CONFIG_IPMI_HANDLER is not set
467# CONFIG_WATCHDOG is not set
468# CONFIG_HW_RANDOM is not set 465# CONFIG_HW_RANDOM is not set
469# CONFIG_RTC is not set 466# CONFIG_RTC is not set
470# CONFIG_R3964 is not set 467# CONFIG_R3964 is not set
@@ -482,6 +479,20 @@ CONFIG_DEVPORT=y
482# CONFIG_W1 is not set 479# CONFIG_W1 is not set
483# CONFIG_POWER_SUPPLY is not set 480# CONFIG_POWER_SUPPLY is not set
484# CONFIG_HWMON is not set 481# CONFIG_HWMON is not set
482CONFIG_WATCHDOG=y
483# CONFIG_WATCHDOG_NOWAYOUT is not set
484
485#
486# Watchdog Device Drivers
487#
488# CONFIG_SOFT_WATCHDOG is not set
489CONFIG_TXX9_WDT=y
490
491#
492# PCI-based Watchdog Cards
493#
494# CONFIG_PCIPCWATCHDOG is not set
495# CONFIG_WDTPCI is not set
485 496
486# 497#
487# Multifunction device drivers 498# Multifunction device drivers
diff --git a/arch/mips/configs/lasat_defconfig b/arch/mips/configs/lasat_defconfig
index 2c665fcef089..e6aef999854c 100644
--- a/arch/mips/configs/lasat_defconfig
+++ b/arch/mips/configs/lasat_defconfig
@@ -25,7 +25,6 @@ CONFIG_LASAT=y
25# CONFIG_PNX8550_STB810 is not set 25# CONFIG_PNX8550_STB810 is not set
26# CONFIG_PMC_MSP is not set 26# CONFIG_PMC_MSP is not set
27# CONFIG_PMC_YOSEMITE is not set 27# CONFIG_PMC_YOSEMITE is not set
28# CONFIG_QEMU is not set
29# CONFIG_SGI_IP22 is not set 28# CONFIG_SGI_IP22 is not set
30# CONFIG_SGI_IP27 is not set 29# CONFIG_SGI_IP27 is not set
31# CONFIG_SGI_IP32 is not set 30# CONFIG_SGI_IP32 is not set
@@ -36,7 +35,6 @@ CONFIG_LASAT=y
36# CONFIG_SIBYTE_SWARM is not set 35# CONFIG_SIBYTE_SWARM is not set
37# CONFIG_SIBYTE_LITTLESUR is not set 36# CONFIG_SIBYTE_LITTLESUR is not set
38# CONFIG_SIBYTE_SENTOSA is not set 37# CONFIG_SIBYTE_SENTOSA is not set
39# CONFIG_SIBYTE_PTSWARM is not set
40# CONFIG_SIBYTE_BIGSUR is not set 38# CONFIG_SIBYTE_BIGSUR is not set
41# CONFIG_SNI_RM is not set 39# CONFIG_SNI_RM is not set
42# CONFIG_TOSHIBA_JMR3927 is not set 40# CONFIG_TOSHIBA_JMR3927 is not set
diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig
index 4b7e43c9f69a..3d0da952811c 100644
--- a/arch/mips/configs/malta_defconfig
+++ b/arch/mips/configs/malta_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS_MALTA=y
25# CONFIG_PNX8550_STB810 is not set 25# CONFIG_PNX8550_STB810 is not set
26# CONFIG_PMC_MSP is not set 26# CONFIG_PMC_MSP is not set
27# CONFIG_PMC_YOSEMITE is not set 27# CONFIG_PMC_YOSEMITE is not set
28# CONFIG_QEMU is not set
29# CONFIG_SGI_IP22 is not set 28# CONFIG_SGI_IP22 is not set
30# CONFIG_SGI_IP27 is not set 29# CONFIG_SGI_IP27 is not set
31# CONFIG_SGI_IP32 is not set 30# CONFIG_SGI_IP32 is not set
@@ -36,7 +35,6 @@ CONFIG_MIPS_MALTA=y
36# CONFIG_SIBYTE_SWARM is not set 35# CONFIG_SIBYTE_SWARM is not set
37# CONFIG_SIBYTE_LITTLESUR is not set 36# CONFIG_SIBYTE_LITTLESUR is not set
38# CONFIG_SIBYTE_SENTOSA is not set 37# CONFIG_SIBYTE_SENTOSA is not set
39# CONFIG_SIBYTE_PTSWARM is not set
40# CONFIG_SIBYTE_BIGSUR is not set 38# CONFIG_SIBYTE_BIGSUR is not set
41# CONFIG_SNI_RM is not set 39# CONFIG_SNI_RM is not set
42# CONFIG_TOSHIBA_JMR3927 is not set 40# CONFIG_TOSHIBA_JMR3927 is not set
diff --git a/arch/mips/configs/mipssim_defconfig b/arch/mips/configs/mipssim_defconfig
index 61b72f5a953e..6db0bdaefb27 100644
--- a/arch/mips/configs/mipssim_defconfig
+++ b/arch/mips/configs/mipssim_defconfig
@@ -26,7 +26,6 @@ CONFIG_MIPS_SIM=y
26# CONFIG_PNX8550_STB810 is not set 26# CONFIG_PNX8550_STB810 is not set
27# CONFIG_PMC_MSP is not set 27# CONFIG_PMC_MSP is not set
28# CONFIG_PMC_YOSEMITE is not set 28# CONFIG_PMC_YOSEMITE is not set
29# CONFIG_QEMU is not set
30# CONFIG_SGI_IP22 is not set 29# CONFIG_SGI_IP22 is not set
31# CONFIG_SGI_IP27 is not set 30# CONFIG_SGI_IP27 is not set
32# CONFIG_SGI_IP32 is not set 31# CONFIG_SGI_IP32 is not set
@@ -37,7 +36,6 @@ CONFIG_MIPS_SIM=y
37# CONFIG_SIBYTE_SWARM is not set 36# CONFIG_SIBYTE_SWARM is not set
38# CONFIG_SIBYTE_LITTLESUR is not set 37# CONFIG_SIBYTE_LITTLESUR is not set
39# CONFIG_SIBYTE_SENTOSA is not set 38# CONFIG_SIBYTE_SENTOSA is not set
40# CONFIG_SIBYTE_PTSWARM is not set
41# CONFIG_SIBYTE_BIGSUR is not set 39# CONFIG_SIBYTE_BIGSUR is not set
42# CONFIG_SNI_RM is not set 40# CONFIG_SNI_RM is not set
43# CONFIG_TOSHIBA_JMR3927 is not set 41# CONFIG_TOSHIBA_JMR3927 is not set
diff --git a/arch/mips/configs/mpc30x_defconfig b/arch/mips/configs/mpc30x_defconfig
index 8334350d7229..27e23fc9363a 100644
--- a/arch/mips/configs/mpc30x_defconfig
+++ b/arch/mips/configs/mpc30x_defconfig
@@ -24,7 +24,6 @@ CONFIG_MACH_VR41XX=y
24# CONFIG_PNX8550_STB810 is not set 24# CONFIG_PNX8550_STB810 is not set
25# CONFIG_PMC_MSP is not set 25# CONFIG_PMC_MSP is not set
26# CONFIG_PMC_YOSEMITE is not set 26# CONFIG_PMC_YOSEMITE is not set
27# CONFIG_QEMU is not set
28# CONFIG_SGI_IP22 is not set 27# CONFIG_SGI_IP22 is not set
29# CONFIG_SGI_IP27 is not set 28# CONFIG_SGI_IP27 is not set
30# CONFIG_SGI_IP32 is not set 29# CONFIG_SGI_IP32 is not set
@@ -35,7 +34,6 @@ CONFIG_MACH_VR41XX=y
35# CONFIG_SIBYTE_SWARM is not set 34# CONFIG_SIBYTE_SWARM is not set
36# CONFIG_SIBYTE_LITTLESUR is not set 35# CONFIG_SIBYTE_LITTLESUR is not set
37# CONFIG_SIBYTE_SENTOSA is not set 36# CONFIG_SIBYTE_SENTOSA is not set
38# CONFIG_SIBYTE_PTSWARM is not set
39# CONFIG_SIBYTE_BIGSUR is not set 37# CONFIG_SIBYTE_BIGSUR is not set
40# CONFIG_SNI_RM is not set 38# CONFIG_SNI_RM is not set
41# CONFIG_TOSHIBA_JMR3927 is not set 39# CONFIG_TOSHIBA_JMR3927 is not set
diff --git a/arch/mips/configs/msp71xx_defconfig b/arch/mips/configs/msp71xx_defconfig
index 69278999c9a2..b12b73f6d74f 100644
--- a/arch/mips/configs/msp71xx_defconfig
+++ b/arch/mips/configs/msp71xx_defconfig
@@ -38,7 +38,6 @@ CONFIG_ZONE_DMA=y
38# CONFIG_MACH_VR41XX is not set 38# CONFIG_MACH_VR41XX is not set
39CONFIG_PMC_MSP=y 39CONFIG_PMC_MSP=y
40# CONFIG_PMC_YOSEMITE is not set 40# CONFIG_PMC_YOSEMITE is not set
41# CONFIG_QEMU is not set
42# CONFIG_MARKEINS is not set 41# CONFIG_MARKEINS is not set
43# CONFIG_SGI_IP22 is not set 42# CONFIG_SGI_IP22 is not set
44# CONFIG_SGI_IP27 is not set 43# CONFIG_SGI_IP27 is not set
@@ -48,7 +47,6 @@ CONFIG_PMC_MSP=y
48# CONFIG_SIBYTE_SENTOSA is not set 47# CONFIG_SIBYTE_SENTOSA is not set
49# CONFIG_SIBYTE_RHONE is not set 48# CONFIG_SIBYTE_RHONE is not set
50# CONFIG_SIBYTE_CARMEL is not set 49# CONFIG_SIBYTE_CARMEL is not set
51# CONFIG_SIBYTE_PTSWARM is not set
52# CONFIG_SIBYTE_LITTLESUR is not set 50# CONFIG_SIBYTE_LITTLESUR is not set
53# CONFIG_SIBYTE_CRHINE is not set 51# CONFIG_SIBYTE_CRHINE is not set
54# CONFIG_SIBYTE_CRHONE is not set 52# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig
index b536d7c63790..fa3aa3919448 100644
--- a/arch/mips/configs/mtx1_defconfig
+++ b/arch/mips/configs/mtx1_defconfig
@@ -24,7 +24,6 @@ CONFIG_MACH_ALCHEMY=y
24# CONFIG_PNX8550_STB810 is not set 24# CONFIG_PNX8550_STB810 is not set
25# CONFIG_PMC_MSP is not set 25# CONFIG_PMC_MSP is not set
26# CONFIG_PMC_YOSEMITE is not set 26# CONFIG_PMC_YOSEMITE is not set
27# CONFIG_QEMU is not set
28# CONFIG_SGI_IP22 is not set 27# CONFIG_SGI_IP22 is not set
29# CONFIG_SGI_IP27 is not set 28# CONFIG_SGI_IP27 is not set
30# CONFIG_SGI_IP32 is not set 29# CONFIG_SGI_IP32 is not set
@@ -35,7 +34,6 @@ CONFIG_MACH_ALCHEMY=y
35# CONFIG_SIBYTE_SWARM is not set 34# CONFIG_SIBYTE_SWARM is not set
36# CONFIG_SIBYTE_LITTLESUR is not set 35# CONFIG_SIBYTE_LITTLESUR is not set
37# CONFIG_SIBYTE_SENTOSA is not set 36# CONFIG_SIBYTE_SENTOSA is not set
38# CONFIG_SIBYTE_PTSWARM is not set
39# CONFIG_SIBYTE_BIGSUR is not set 37# CONFIG_SIBYTE_BIGSUR is not set
40# CONFIG_SNI_RM is not set 38# CONFIG_SNI_RM is not set
41# CONFIG_TOSHIBA_JMR3927 is not set 39# CONFIG_TOSHIBA_JMR3927 is not set
@@ -1617,6 +1615,7 @@ CONFIG_INPUT_EVBUG=m
1617# 1615#
1618CONFIG_INPUT_KEYBOARD=y 1616CONFIG_INPUT_KEYBOARD=y
1619CONFIG_KEYBOARD_ATKBD=y 1617CONFIG_KEYBOARD_ATKBD=y
1618CONFIG_KEYBOARD_GPIO=y
1620CONFIG_KEYBOARD_SUNKBD=m 1619CONFIG_KEYBOARD_SUNKBD=m
1621CONFIG_KEYBOARD_LKKBD=m 1620CONFIG_KEYBOARD_LKKBD=m
1622CONFIG_KEYBOARD_XTKBD=m 1621CONFIG_KEYBOARD_XTKBD=m
diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig
index 703d28db05b9..1d0157d3a5bb 100644
--- a/arch/mips/configs/pb1100_defconfig
+++ b/arch/mips/configs/pb1100_defconfig
@@ -38,7 +38,6 @@ CONFIG_MIPS_PB1100=y
38# CONFIG_PNX8550_STB810 is not set 38# CONFIG_PNX8550_STB810 is not set
39# CONFIG_MACH_VR41XX is not set 39# CONFIG_MACH_VR41XX is not set
40# CONFIG_PMC_YOSEMITE is not set 40# CONFIG_PMC_YOSEMITE is not set
41# CONFIG_QEMU is not set
42# CONFIG_MARKEINS is not set 41# CONFIG_MARKEINS is not set
43# CONFIG_SGI_IP22 is not set 42# CONFIG_SGI_IP22 is not set
44# CONFIG_SGI_IP27 is not set 43# CONFIG_SGI_IP27 is not set
@@ -48,7 +47,6 @@ CONFIG_MIPS_PB1100=y
48# CONFIG_SIBYTE_SENTOSA is not set 47# CONFIG_SIBYTE_SENTOSA is not set
49# CONFIG_SIBYTE_RHONE is not set 48# CONFIG_SIBYTE_RHONE is not set
50# CONFIG_SIBYTE_CARMEL is not set 49# CONFIG_SIBYTE_CARMEL is not set
51# CONFIG_SIBYTE_PTSWARM is not set
52# CONFIG_SIBYTE_LITTLESUR is not set 50# CONFIG_SIBYTE_LITTLESUR is not set
53# CONFIG_SIBYTE_CRHINE is not set 51# CONFIG_SIBYTE_CRHINE is not set
54# CONFIG_SIBYTE_CRHONE is not set 52# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig
index 82f0c5cee0dc..d0491a05ee58 100644
--- a/arch/mips/configs/pb1500_defconfig
+++ b/arch/mips/configs/pb1500_defconfig
@@ -38,7 +38,6 @@ CONFIG_MIPS_PB1500=y
38# CONFIG_PNX8550_STB810 is not set 38# CONFIG_PNX8550_STB810 is not set
39# CONFIG_MACH_VR41XX is not set 39# CONFIG_MACH_VR41XX is not set
40# CONFIG_PMC_YOSEMITE is not set 40# CONFIG_PMC_YOSEMITE is not set
41# CONFIG_QEMU is not set
42# CONFIG_MARKEINS is not set 41# CONFIG_MARKEINS is not set
43# CONFIG_SGI_IP22 is not set 42# CONFIG_SGI_IP22 is not set
44# CONFIG_SGI_IP27 is not set 43# CONFIG_SGI_IP27 is not set
@@ -48,7 +47,6 @@ CONFIG_MIPS_PB1500=y
48# CONFIG_SIBYTE_SENTOSA is not set 47# CONFIG_SIBYTE_SENTOSA is not set
49# CONFIG_SIBYTE_RHONE is not set 48# CONFIG_SIBYTE_RHONE is not set
50# CONFIG_SIBYTE_CARMEL is not set 49# CONFIG_SIBYTE_CARMEL is not set
51# CONFIG_SIBYTE_PTSWARM is not set
52# CONFIG_SIBYTE_LITTLESUR is not set 50# CONFIG_SIBYTE_LITTLESUR is not set
53# CONFIG_SIBYTE_CRHINE is not set 51# CONFIG_SIBYTE_CRHINE is not set
54# CONFIG_SIBYTE_CRHONE is not set 52# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig
index 147a4fc7fdd8..16d78d3cd2aa 100644
--- a/arch/mips/configs/pb1550_defconfig
+++ b/arch/mips/configs/pb1550_defconfig
@@ -38,7 +38,6 @@ CONFIG_MIPS_PB1550=y
38# CONFIG_PNX8550_STB810 is not set 38# CONFIG_PNX8550_STB810 is not set
39# CONFIG_MACH_VR41XX is not set 39# CONFIG_MACH_VR41XX is not set
40# CONFIG_PMC_YOSEMITE is not set 40# CONFIG_PMC_YOSEMITE is not set
41# CONFIG_QEMU is not set
42# CONFIG_MARKEINS is not set 41# CONFIG_MARKEINS is not set
43# CONFIG_SGI_IP22 is not set 42# CONFIG_SGI_IP22 is not set
44# CONFIG_SGI_IP27 is not set 43# CONFIG_SGI_IP27 is not set
@@ -48,7 +47,6 @@ CONFIG_MIPS_PB1550=y
48# CONFIG_SIBYTE_SENTOSA is not set 47# CONFIG_SIBYTE_SENTOSA is not set
49# CONFIG_SIBYTE_RHONE is not set 48# CONFIG_SIBYTE_RHONE is not set
50# CONFIG_SIBYTE_CARMEL is not set 49# CONFIG_SIBYTE_CARMEL is not set
51# CONFIG_SIBYTE_PTSWARM is not set
52# CONFIG_SIBYTE_LITTLESUR is not set 50# CONFIG_SIBYTE_LITTLESUR is not set
53# CONFIG_SIBYTE_CRHINE is not set 51# CONFIG_SIBYTE_CRHINE is not set
54# CONFIG_SIBYTE_CRHONE is not set 52# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/pnx8550-jbs_defconfig b/arch/mips/configs/pnx8550-jbs_defconfig
index f6906b069e04..518a60892b78 100644
--- a/arch/mips/configs/pnx8550-jbs_defconfig
+++ b/arch/mips/configs/pnx8550-jbs_defconfig
@@ -37,7 +37,6 @@ CONFIG_PNX8550_JBS=y
37# CONFIG_PNX8550_STB810 is not set 37# CONFIG_PNX8550_STB810 is not set
38# CONFIG_MACH_VR41XX is not set 38# CONFIG_MACH_VR41XX is not set
39# CONFIG_PMC_YOSEMITE is not set 39# CONFIG_PMC_YOSEMITE is not set
40# CONFIG_QEMU is not set
41# CONFIG_MARKEINS is not set 40# CONFIG_MARKEINS is not set
42# CONFIG_SGI_IP22 is not set 41# CONFIG_SGI_IP22 is not set
43# CONFIG_SGI_IP27 is not set 42# CONFIG_SGI_IP27 is not set
@@ -47,7 +46,6 @@ CONFIG_PNX8550_JBS=y
47# CONFIG_SIBYTE_SENTOSA is not set 46# CONFIG_SIBYTE_SENTOSA is not set
48# CONFIG_SIBYTE_RHONE is not set 47# CONFIG_SIBYTE_RHONE is not set
49# CONFIG_SIBYTE_CARMEL is not set 48# CONFIG_SIBYTE_CARMEL is not set
50# CONFIG_SIBYTE_PTSWARM is not set
51# CONFIG_SIBYTE_LITTLESUR is not set 49# CONFIG_SIBYTE_LITTLESUR is not set
52# CONFIG_SIBYTE_CRHINE is not set 50# CONFIG_SIBYTE_CRHINE is not set
53# CONFIG_SIBYTE_CRHONE is not set 51# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/pnx8550-stb810_defconfig b/arch/mips/configs/pnx8550-stb810_defconfig
index b741f81696fb..68351eb81bc8 100644
--- a/arch/mips/configs/pnx8550-stb810_defconfig
+++ b/arch/mips/configs/pnx8550-stb810_defconfig
@@ -37,7 +37,6 @@ CONFIG_ZONE_DMA=y
37CONFIG_PNX8550_STB810=y 37CONFIG_PNX8550_STB810=y
38# CONFIG_MACH_VR41XX is not set 38# CONFIG_MACH_VR41XX is not set
39# CONFIG_PMC_YOSEMITE is not set 39# CONFIG_PMC_YOSEMITE is not set
40# CONFIG_QEMU is not set
41# CONFIG_MARKEINS is not set 40# CONFIG_MARKEINS is not set
42# CONFIG_SGI_IP22 is not set 41# CONFIG_SGI_IP22 is not set
43# CONFIG_SGI_IP27 is not set 42# CONFIG_SGI_IP27 is not set
@@ -47,7 +46,6 @@ CONFIG_PNX8550_STB810=y
47# CONFIG_SIBYTE_SENTOSA is not set 46# CONFIG_SIBYTE_SENTOSA is not set
48# CONFIG_SIBYTE_RHONE is not set 47# CONFIG_SIBYTE_RHONE is not set
49# CONFIG_SIBYTE_CARMEL is not set 48# CONFIG_SIBYTE_CARMEL is not set
50# CONFIG_SIBYTE_PTSWARM is not set
51# CONFIG_SIBYTE_LITTLESUR is not set 49# CONFIG_SIBYTE_LITTLESUR is not set
52# CONFIG_SIBYTE_CRHINE is not set 50# CONFIG_SIBYTE_CRHINE is not set
53# CONFIG_SIBYTE_CRHONE is not set 51# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/qemu_defconfig b/arch/mips/configs/qemu_defconfig
index b3caf5125c15..72ca147f9422 100644
--- a/arch/mips/configs/qemu_defconfig
+++ b/arch/mips/configs/qemu_defconfig
@@ -37,7 +37,6 @@ CONFIG_ZONE_DMA=y
37# CONFIG_PNX8550_STB810 is not set 37# CONFIG_PNX8550_STB810 is not set
38# CONFIG_MACH_VR41XX is not set 38# CONFIG_MACH_VR41XX is not set
39# CONFIG_PMC_YOSEMITE is not set 39# CONFIG_PMC_YOSEMITE is not set
40CONFIG_QEMU=y
41# CONFIG_MARKEINS is not set 40# CONFIG_MARKEINS is not set
42# CONFIG_SGI_IP22 is not set 41# CONFIG_SGI_IP22 is not set
43# CONFIG_SGI_IP27 is not set 42# CONFIG_SGI_IP27 is not set
@@ -47,7 +46,6 @@ CONFIG_QEMU=y
47# CONFIG_SIBYTE_SENTOSA is not set 46# CONFIG_SIBYTE_SENTOSA is not set
48# CONFIG_SIBYTE_RHONE is not set 47# CONFIG_SIBYTE_RHONE is not set
49# CONFIG_SIBYTE_CARMEL is not set 48# CONFIG_SIBYTE_CARMEL is not set
50# CONFIG_SIBYTE_PTSWARM is not set
51# CONFIG_SIBYTE_LITTLESUR is not set 49# CONFIG_SIBYTE_LITTLESUR is not set
52# CONFIG_SIBYTE_CRHINE is not set 50# CONFIG_SIBYTE_CRHINE is not set
53# CONFIG_SIBYTE_CRHONE is not set 51# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/rbhma4200_defconfig b/arch/mips/configs/rbhma4200_defconfig
index 9383a598094b..470f6f4d3ea2 100644
--- a/arch/mips/configs/rbhma4200_defconfig
+++ b/arch/mips/configs/rbhma4200_defconfig
@@ -24,7 +24,6 @@ CONFIG_MIPS=y
24# CONFIG_PNX8550_STB810 is not set 24# CONFIG_PNX8550_STB810 is not set
25# CONFIG_PMC_MSP is not set 25# CONFIG_PMC_MSP is not set
26# CONFIG_PMC_YOSEMITE is not set 26# CONFIG_PMC_YOSEMITE is not set
27# CONFIG_QEMU is not set
28# CONFIG_SGI_IP22 is not set 27# CONFIG_SGI_IP22 is not set
29# CONFIG_SGI_IP27 is not set 28# CONFIG_SGI_IP27 is not set
30# CONFIG_SGI_IP32 is not set 29# CONFIG_SGI_IP32 is not set
@@ -35,7 +34,6 @@ CONFIG_MIPS=y
35# CONFIG_SIBYTE_SWARM is not set 34# CONFIG_SIBYTE_SWARM is not set
36# CONFIG_SIBYTE_LITTLESUR is not set 35# CONFIG_SIBYTE_LITTLESUR is not set
37# CONFIG_SIBYTE_SENTOSA is not set 36# CONFIG_SIBYTE_SENTOSA is not set
38# CONFIG_SIBYTE_PTSWARM is not set
39# CONFIG_SIBYTE_BIGSUR is not set 37# CONFIG_SIBYTE_BIGSUR is not set
40# CONFIG_SNI_RM is not set 38# CONFIG_SNI_RM is not set
41# CONFIG_TOSHIBA_JMR3927 is not set 39# CONFIG_TOSHIBA_JMR3927 is not set
@@ -431,7 +429,6 @@ CONFIG_UNIX98_PTYS=y
431CONFIG_LEGACY_PTYS=y 429CONFIG_LEGACY_PTYS=y
432CONFIG_LEGACY_PTY_COUNT=256 430CONFIG_LEGACY_PTY_COUNT=256
433# CONFIG_IPMI_HANDLER is not set 431# CONFIG_IPMI_HANDLER is not set
434# CONFIG_WATCHDOG is not set
435# CONFIG_HW_RANDOM is not set 432# CONFIG_HW_RANDOM is not set
436# CONFIG_RTC is not set 433# CONFIG_RTC is not set
437# CONFIG_R3964 is not set 434# CONFIG_R3964 is not set
@@ -449,6 +446,20 @@ CONFIG_DEVPORT=y
449# CONFIG_W1 is not set 446# CONFIG_W1 is not set
450# CONFIG_POWER_SUPPLY is not set 447# CONFIG_POWER_SUPPLY is not set
451# CONFIG_HWMON is not set 448# CONFIG_HWMON is not set
449CONFIG_WATCHDOG=y
450# CONFIG_WATCHDOG_NOWAYOUT is not set
451
452#
453# Watchdog Device Drivers
454#
455# CONFIG_SOFT_WATCHDOG is not set
456CONFIG_TXX9_WDT=m
457
458#
459# PCI-based Watchdog Cards
460#
461# CONFIG_PCIPCWATCHDOG is not set
462# CONFIG_WDTPCI is not set
452 463
453# 464#
454# Multifunction device drivers 465# Multifunction device drivers
diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig
index d1b56cc0fd7c..5a39f56b175e 100644
--- a/arch/mips/configs/rbhma4500_defconfig
+++ b/arch/mips/configs/rbhma4500_defconfig
@@ -24,7 +24,6 @@ CONFIG_MIPS=y
24# CONFIG_PNX8550_STB810 is not set 24# CONFIG_PNX8550_STB810 is not set
25# CONFIG_PMC_MSP is not set 25# CONFIG_PMC_MSP is not set
26# CONFIG_PMC_YOSEMITE is not set 26# CONFIG_PMC_YOSEMITE is not set
27# CONFIG_QEMU is not set
28# CONFIG_SGI_IP22 is not set 27# CONFIG_SGI_IP22 is not set
29# CONFIG_SGI_IP27 is not set 28# CONFIG_SGI_IP27 is not set
30# CONFIG_SGI_IP32 is not set 29# CONFIG_SGI_IP32 is not set
@@ -35,7 +34,6 @@ CONFIG_MIPS=y
35# CONFIG_SIBYTE_SWARM is not set 34# CONFIG_SIBYTE_SWARM is not set
36# CONFIG_SIBYTE_LITTLESUR is not set 35# CONFIG_SIBYTE_LITTLESUR is not set
37# CONFIG_SIBYTE_SENTOSA is not set 36# CONFIG_SIBYTE_SENTOSA is not set
38# CONFIG_SIBYTE_PTSWARM is not set
39# CONFIG_SIBYTE_BIGSUR is not set 37# CONFIG_SIBYTE_BIGSUR is not set
40# CONFIG_SNI_RM is not set 38# CONFIG_SNI_RM is not set
41# CONFIG_TOSHIBA_JMR3927 is not set 39# CONFIG_TOSHIBA_JMR3927 is not set
@@ -450,7 +448,6 @@ CONFIG_UNIX98_PTYS=y
450CONFIG_LEGACY_PTYS=y 448CONFIG_LEGACY_PTYS=y
451CONFIG_LEGACY_PTY_COUNT=256 449CONFIG_LEGACY_PTY_COUNT=256
452# CONFIG_IPMI_HANDLER is not set 450# CONFIG_IPMI_HANDLER is not set
453# CONFIG_WATCHDOG is not set
454# CONFIG_HW_RANDOM is not set 451# CONFIG_HW_RANDOM is not set
455# CONFIG_RTC is not set 452# CONFIG_RTC is not set
456# CONFIG_R3964 is not set 453# CONFIG_R3964 is not set
@@ -479,6 +476,20 @@ CONFIG_SPI_AT25=y
479# CONFIG_W1 is not set 476# CONFIG_W1 is not set
480# CONFIG_POWER_SUPPLY is not set 477# CONFIG_POWER_SUPPLY is not set
481# CONFIG_HWMON is not set 478# CONFIG_HWMON is not set
479CONFIG_WATCHDOG=y
480# CONFIG_WATCHDOG_NOWAYOUT is not set
481
482#
483# Watchdog Device Drivers
484#
485# CONFIG_SOFT_WATCHDOG is not set
486CONFIG_TXX9_WDT=m
487
488#
489# PCI-based Watchdog Cards
490#
491# CONFIG_PCIPCWATCHDOG is not set
492# CONFIG_WDTPCI is not set
482 493
483# 494#
484# Multifunction device drivers 495# Multifunction device drivers
diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig
index fc388118b114..56371b860eb0 100644
--- a/arch/mips/configs/rm200_defconfig
+++ b/arch/mips/configs/rm200_defconfig
@@ -37,7 +37,6 @@ CONFIG_ZONE_DMA=y
37# CONFIG_PNX8550_STB810 is not set 37# CONFIG_PNX8550_STB810 is not set
38# CONFIG_MACH_VR41XX is not set 38# CONFIG_MACH_VR41XX is not set
39# CONFIG_PMC_YOSEMITE is not set 39# CONFIG_PMC_YOSEMITE is not set
40# CONFIG_QEMU is not set
41# CONFIG_MARKEINS is not set 40# CONFIG_MARKEINS is not set
42# CONFIG_SGI_IP22 is not set 41# CONFIG_SGI_IP22 is not set
43# CONFIG_SGI_IP27 is not set 42# CONFIG_SGI_IP27 is not set
@@ -47,7 +46,6 @@ CONFIG_ZONE_DMA=y
47# CONFIG_SIBYTE_SENTOSA is not set 46# CONFIG_SIBYTE_SENTOSA is not set
48# CONFIG_SIBYTE_RHONE is not set 47# CONFIG_SIBYTE_RHONE is not set
49# CONFIG_SIBYTE_CARMEL is not set 48# CONFIG_SIBYTE_CARMEL is not set
50# CONFIG_SIBYTE_PTSWARM is not set
51# CONFIG_SIBYTE_LITTLESUR is not set 49# CONFIG_SIBYTE_LITTLESUR is not set
52# CONFIG_SIBYTE_CRHINE is not set 50# CONFIG_SIBYTE_CRHINE is not set
53# CONFIG_SIBYTE_CRHONE is not set 51# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig
index c2798229cbfb..117470b60e34 100644
--- a/arch/mips/configs/sb1250-swarm_defconfig
+++ b/arch/mips/configs/sb1250-swarm_defconfig
@@ -37,7 +37,6 @@ CONFIG_ZONE_DMA=y
37# CONFIG_PNX8550_STB810 is not set 37# CONFIG_PNX8550_STB810 is not set
38# CONFIG_MACH_VR41XX is not set 38# CONFIG_MACH_VR41XX is not set
39# CONFIG_PMC_YOSEMITE is not set 39# CONFIG_PMC_YOSEMITE is not set
40# CONFIG_QEMU is not set
41# CONFIG_MARKEINS is not set 40# CONFIG_MARKEINS is not set
42# CONFIG_SGI_IP22 is not set 41# CONFIG_SGI_IP22 is not set
43# CONFIG_SGI_IP27 is not set 42# CONFIG_SGI_IP27 is not set
@@ -47,7 +46,6 @@ CONFIG_SIBYTE_SWARM=y
47# CONFIG_SIBYTE_SENTOSA is not set 46# CONFIG_SIBYTE_SENTOSA is not set
48# CONFIG_SIBYTE_RHONE is not set 47# CONFIG_SIBYTE_RHONE is not set
49# CONFIG_SIBYTE_CARMEL is not set 48# CONFIG_SIBYTE_CARMEL is not set
50# CONFIG_SIBYTE_PTSWARM is not set
51# CONFIG_SIBYTE_LITTLESUR is not set 49# CONFIG_SIBYTE_LITTLESUR is not set
52# CONFIG_SIBYTE_CRHINE is not set 50# CONFIG_SIBYTE_CRHINE is not set
53# CONFIG_SIBYTE_CRHONE is not set 51# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/sead_defconfig b/arch/mips/configs/sead_defconfig
index 2b6282d132a8..3ee75b15c0b0 100644
--- a/arch/mips/configs/sead_defconfig
+++ b/arch/mips/configs/sead_defconfig
@@ -37,7 +37,6 @@ CONFIG_MIPS_SEAD=y
37# CONFIG_PNX8550_STB810 is not set 37# CONFIG_PNX8550_STB810 is not set
38# CONFIG_MACH_VR41XX is not set 38# CONFIG_MACH_VR41XX is not set
39# CONFIG_PMC_YOSEMITE is not set 39# CONFIG_PMC_YOSEMITE is not set
40# CONFIG_QEMU is not set
41# CONFIG_MARKEINS is not set 40# CONFIG_MARKEINS is not set
42# CONFIG_SGI_IP22 is not set 41# CONFIG_SGI_IP22 is not set
43# CONFIG_SGI_IP27 is not set 42# CONFIG_SGI_IP27 is not set
@@ -47,7 +46,6 @@ CONFIG_MIPS_SEAD=y
47# CONFIG_SIBYTE_SENTOSA is not set 46# CONFIG_SIBYTE_SENTOSA is not set
48# CONFIG_SIBYTE_RHONE is not set 47# CONFIG_SIBYTE_RHONE is not set
49# CONFIG_SIBYTE_CARMEL is not set 48# CONFIG_SIBYTE_CARMEL is not set
50# CONFIG_SIBYTE_PTSWARM is not set
51# CONFIG_SIBYTE_LITTLESUR is not set 49# CONFIG_SIBYTE_LITTLESUR is not set
52# CONFIG_SIBYTE_CRHINE is not set 50# CONFIG_SIBYTE_CRHINE is not set
53# CONFIG_SIBYTE_CRHONE is not set 51# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/tb0219_defconfig b/arch/mips/configs/tb0219_defconfig
index 326aa7aa40ea..af82e1a1823c 100644
--- a/arch/mips/configs/tb0219_defconfig
+++ b/arch/mips/configs/tb0219_defconfig
@@ -24,7 +24,6 @@ CONFIG_MACH_VR41XX=y
24# CONFIG_PNX8550_STB810 is not set 24# CONFIG_PNX8550_STB810 is not set
25# CONFIG_PMC_MSP is not set 25# CONFIG_PMC_MSP is not set
26# CONFIG_PMC_YOSEMITE is not set 26# CONFIG_PMC_YOSEMITE is not set
27# CONFIG_QEMU is not set
28# CONFIG_SGI_IP22 is not set 27# CONFIG_SGI_IP22 is not set
29# CONFIG_SGI_IP27 is not set 28# CONFIG_SGI_IP27 is not set
30# CONFIG_SGI_IP32 is not set 29# CONFIG_SGI_IP32 is not set
@@ -35,7 +34,6 @@ CONFIG_MACH_VR41XX=y
35# CONFIG_SIBYTE_SWARM is not set 34# CONFIG_SIBYTE_SWARM is not set
36# CONFIG_SIBYTE_LITTLESUR is not set 35# CONFIG_SIBYTE_LITTLESUR is not set
37# CONFIG_SIBYTE_SENTOSA is not set 36# CONFIG_SIBYTE_SENTOSA is not set
38# CONFIG_SIBYTE_PTSWARM is not set
39# CONFIG_SIBYTE_BIGSUR is not set 37# CONFIG_SIBYTE_BIGSUR is not set
40# CONFIG_SNI_RM is not set 38# CONFIG_SNI_RM is not set
41# CONFIG_TOSHIBA_JMR3927 is not set 39# CONFIG_TOSHIBA_JMR3927 is not set
diff --git a/arch/mips/configs/tb0226_defconfig b/arch/mips/configs/tb0226_defconfig
index 9fd0faeacf53..a95385b24546 100644
--- a/arch/mips/configs/tb0226_defconfig
+++ b/arch/mips/configs/tb0226_defconfig
@@ -24,7 +24,6 @@ CONFIG_MACH_VR41XX=y
24# CONFIG_PNX8550_STB810 is not set 24# CONFIG_PNX8550_STB810 is not set
25# CONFIG_PMC_MSP is not set 25# CONFIG_PMC_MSP is not set
26# CONFIG_PMC_YOSEMITE is not set 26# CONFIG_PMC_YOSEMITE is not set
27# CONFIG_QEMU is not set
28# CONFIG_SGI_IP22 is not set 27# CONFIG_SGI_IP22 is not set
29# CONFIG_SGI_IP27 is not set 28# CONFIG_SGI_IP27 is not set
30# CONFIG_SGI_IP32 is not set 29# CONFIG_SGI_IP32 is not set
@@ -35,7 +34,6 @@ CONFIG_MACH_VR41XX=y
35# CONFIG_SIBYTE_SWARM is not set 34# CONFIG_SIBYTE_SWARM is not set
36# CONFIG_SIBYTE_LITTLESUR is not set 35# CONFIG_SIBYTE_LITTLESUR is not set
37# CONFIG_SIBYTE_SENTOSA is not set 36# CONFIG_SIBYTE_SENTOSA is not set
38# CONFIG_SIBYTE_PTSWARM is not set
39# CONFIG_SIBYTE_BIGSUR is not set 37# CONFIG_SIBYTE_BIGSUR is not set
40# CONFIG_SNI_RM is not set 38# CONFIG_SNI_RM is not set
41# CONFIG_TOSHIBA_JMR3927 is not set 39# CONFIG_TOSHIBA_JMR3927 is not set
diff --git a/arch/mips/configs/tb0287_defconfig b/arch/mips/configs/tb0287_defconfig
index 499b6bd7ee68..40d4a40a970e 100644
--- a/arch/mips/configs/tb0287_defconfig
+++ b/arch/mips/configs/tb0287_defconfig
@@ -24,7 +24,6 @@ CONFIG_MACH_VR41XX=y
24# CONFIG_PNX8550_STB810 is not set 24# CONFIG_PNX8550_STB810 is not set
25# CONFIG_PMC_MSP is not set 25# CONFIG_PMC_MSP is not set
26# CONFIG_PMC_YOSEMITE is not set 26# CONFIG_PMC_YOSEMITE is not set
27# CONFIG_QEMU is not set
28# CONFIG_SGI_IP22 is not set 27# CONFIG_SGI_IP22 is not set
29# CONFIG_SGI_IP27 is not set 28# CONFIG_SGI_IP27 is not set
30# CONFIG_SGI_IP32 is not set 29# CONFIG_SGI_IP32 is not set
@@ -35,7 +34,6 @@ CONFIG_MACH_VR41XX=y
35# CONFIG_SIBYTE_SWARM is not set 34# CONFIG_SIBYTE_SWARM is not set
36# CONFIG_SIBYTE_LITTLESUR is not set 35# CONFIG_SIBYTE_LITTLESUR is not set
37# CONFIG_SIBYTE_SENTOSA is not set 36# CONFIG_SIBYTE_SENTOSA is not set
38# CONFIG_SIBYTE_PTSWARM is not set
39# CONFIG_SIBYTE_BIGSUR is not set 37# CONFIG_SIBYTE_BIGSUR is not set
40# CONFIG_SNI_RM is not set 38# CONFIG_SNI_RM is not set
41# CONFIG_TOSHIBA_JMR3927 is not set 39# CONFIG_TOSHIBA_JMR3927 is not set
diff --git a/arch/mips/configs/workpad_defconfig b/arch/mips/configs/workpad_defconfig
index b52256ca0b53..edf90b321fe6 100644
--- a/arch/mips/configs/workpad_defconfig
+++ b/arch/mips/configs/workpad_defconfig
@@ -24,7 +24,6 @@ CONFIG_MACH_VR41XX=y
24# CONFIG_PNX8550_STB810 is not set 24# CONFIG_PNX8550_STB810 is not set
25# CONFIG_PMC_MSP is not set 25# CONFIG_PMC_MSP is not set
26# CONFIG_PMC_YOSEMITE is not set 26# CONFIG_PMC_YOSEMITE is not set
27# CONFIG_QEMU is not set
28# CONFIG_SGI_IP22 is not set 27# CONFIG_SGI_IP22 is not set
29# CONFIG_SGI_IP27 is not set 28# CONFIG_SGI_IP27 is not set
30# CONFIG_SGI_IP32 is not set 29# CONFIG_SGI_IP32 is not set
@@ -35,7 +34,6 @@ CONFIG_MACH_VR41XX=y
35# CONFIG_SIBYTE_SWARM is not set 34# CONFIG_SIBYTE_SWARM is not set
36# CONFIG_SIBYTE_LITTLESUR is not set 35# CONFIG_SIBYTE_LITTLESUR is not set
37# CONFIG_SIBYTE_SENTOSA is not set 36# CONFIG_SIBYTE_SENTOSA is not set
38# CONFIG_SIBYTE_PTSWARM is not set
39# CONFIG_SIBYTE_BIGSUR is not set 37# CONFIG_SIBYTE_BIGSUR is not set
40# CONFIG_SNI_RM is not set 38# CONFIG_SNI_RM is not set
41# CONFIG_TOSHIBA_JMR3927 is not set 39# CONFIG_TOSHIBA_JMR3927 is not set
diff --git a/arch/mips/configs/wrppmc_defconfig b/arch/mips/configs/wrppmc_defconfig
index 7e410e10fed7..2e3c683b2052 100644
--- a/arch/mips/configs/wrppmc_defconfig
+++ b/arch/mips/configs/wrppmc_defconfig
@@ -37,7 +37,6 @@ CONFIG_WR_PPMC=y
37# CONFIG_PNX8550_STB810 is not set 37# CONFIG_PNX8550_STB810 is not set
38# CONFIG_MACH_VR41XX is not set 38# CONFIG_MACH_VR41XX is not set
39# CONFIG_PMC_YOSEMITE is not set 39# CONFIG_PMC_YOSEMITE is not set
40# CONFIG_QEMU is not set
41# CONFIG_MARKEINS is not set 40# CONFIG_MARKEINS is not set
42# CONFIG_SGI_IP22 is not set 41# CONFIG_SGI_IP22 is not set
43# CONFIG_SGI_IP27 is not set 42# CONFIG_SGI_IP27 is not set
@@ -47,7 +46,6 @@ CONFIG_WR_PPMC=y
47# CONFIG_SIBYTE_SENTOSA is not set 46# CONFIG_SIBYTE_SENTOSA is not set
48# CONFIG_SIBYTE_RHONE is not set 47# CONFIG_SIBYTE_RHONE is not set
49# CONFIG_SIBYTE_CARMEL is not set 48# CONFIG_SIBYTE_CARMEL is not set
50# CONFIG_SIBYTE_PTSWARM is not set
51# CONFIG_SIBYTE_LITTLESUR is not set 49# CONFIG_SIBYTE_LITTLESUR is not set
52# CONFIG_SIBYTE_CRHINE is not set 50# CONFIG_SIBYTE_CRHINE is not set
53# CONFIG_SIBYTE_CRHONE is not set 51# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig
index acaf0e21bb00..b6178ffbc523 100644
--- a/arch/mips/configs/yosemite_defconfig
+++ b/arch/mips/configs/yosemite_defconfig
@@ -37,7 +37,6 @@ CONFIG_ZONE_DMA=y
37# CONFIG_PNX8550_STB810 is not set 37# CONFIG_PNX8550_STB810 is not set
38# CONFIG_MACH_VR41XX is not set 38# CONFIG_MACH_VR41XX is not set
39CONFIG_PMC_YOSEMITE=y 39CONFIG_PMC_YOSEMITE=y
40# CONFIG_QEMU is not set
41# CONFIG_MARKEINS is not set 40# CONFIG_MARKEINS is not set
42# CONFIG_SGI_IP22 is not set 41# CONFIG_SGI_IP22 is not set
43# CONFIG_SGI_IP27 is not set 42# CONFIG_SGI_IP27 is not set
@@ -47,7 +46,6 @@ CONFIG_PMC_YOSEMITE=y
47# CONFIG_SIBYTE_SENTOSA is not set 46# CONFIG_SIBYTE_SENTOSA is not set
48# CONFIG_SIBYTE_RHONE is not set 47# CONFIG_SIBYTE_RHONE is not set
49# CONFIG_SIBYTE_CARMEL is not set 48# CONFIG_SIBYTE_CARMEL is not set
50# CONFIG_SIBYTE_PTSWARM is not set
51# CONFIG_SIBYTE_LITTLESUR is not set 49# CONFIG_SIBYTE_LITTLESUR is not set
52# CONFIG_SIBYTE_CRHINE is not set 50# CONFIG_SIBYTE_CRHINE is not set
53# CONFIG_SIBYTE_CRHONE is not set 51# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/dec/time.c b/arch/mips/dec/time.c
index 820e5331205f..60349062595a 100644
--- a/arch/mips/dec/time.c
+++ b/arch/mips/dec/time.c
@@ -161,7 +161,6 @@ static cycle_t dec_ioasic_hpt_read(void)
161 161
162void __init plat_time_init(void) 162void __init plat_time_init(void)
163{ 163{
164 mips_timer_state = dec_timer_state;
165 mips_timer_ack = dec_timer_ack; 164 mips_timer_ack = dec_timer_ack;
166 165
167 if (!cpu_has_counter && IOASIC) 166 if (!cpu_has_counter && IOASIC)
diff --git a/arch/mips/defconfig b/arch/mips/defconfig
index 670039bb1a7c..4f5e56c9335e 100644
--- a/arch/mips/defconfig
+++ b/arch/mips/defconfig
@@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y
25# CONFIG_PNX8550_STB810 is not set 25# CONFIG_PNX8550_STB810 is not set
26# CONFIG_PMC_MSP is not set 26# CONFIG_PMC_MSP is not set
27# CONFIG_PMC_YOSEMITE is not set 27# CONFIG_PMC_YOSEMITE is not set
28# CONFIG_QEMU is not set
29CONFIG_SGI_IP22=y 28CONFIG_SGI_IP22=y
30# CONFIG_SGI_IP27 is not set 29# CONFIG_SGI_IP27 is not set
31# CONFIG_SGI_IP32 is not set 30# CONFIG_SGI_IP32 is not set
@@ -36,7 +35,6 @@ CONFIG_SGI_IP22=y
36# CONFIG_SIBYTE_SWARM is not set 35# CONFIG_SIBYTE_SWARM is not set
37# CONFIG_SIBYTE_LITTLESUR is not set 36# CONFIG_SIBYTE_LITTLESUR is not set
38# CONFIG_SIBYTE_SENTOSA is not set 37# CONFIG_SIBYTE_SENTOSA is not set
39# CONFIG_SIBYTE_PTSWARM is not set
40# CONFIG_SIBYTE_BIGSUR is not set 38# CONFIG_SIBYTE_BIGSUR is not set
41# CONFIG_SNI_RM is not set 39# CONFIG_SNI_RM is not set
42# CONFIG_TOSHIBA_JMR3927 is not set 40# CONFIG_TOSHIBA_JMR3927 is not set
diff --git a/arch/mips/fw/arc/cmdline.c b/arch/mips/fw/arc/cmdline.c
index fd604ef28823..4ca4eef934a5 100644
--- a/arch/mips/fw/arc/cmdline.c
+++ b/arch/mips/fw/arc/cmdline.c
@@ -52,7 +52,7 @@ static char * __init move_firmware_args(char* cp)
52 strcat(cp, used_arc[i][1]); 52 strcat(cp, used_arc[i][1]);
53 cp += strlen(used_arc[i][1]); 53 cp += strlen(used_arc[i][1]);
54 /* ... and now the argument */ 54 /* ... and now the argument */
55 s = strstr(prom_argv(actr), "="); 55 s = strchr(prom_argv(actr), '=');
56 if (s) { 56 if (s) {
57 s++; 57 s++;
58 strcpy(cp, s); 58 strcpy(cp, s);
diff --git a/arch/mips/fw/arc/init.c b/arch/mips/fw/arc/init.c
index e2f75b13312f..3ad8788b6eaa 100644
--- a/arch/mips/fw/arc/init.c
+++ b/arch/mips/fw/arc/init.c
@@ -12,6 +12,7 @@
12 12
13#include <asm/bootinfo.h> 13#include <asm/bootinfo.h>
14#include <asm/sgialib.h> 14#include <asm/sgialib.h>
15#include <asm/smp-ops.h>
15 16
16#undef DEBUG_PROM_INIT 17#undef DEBUG_PROM_INIT
17 18
@@ -48,4 +49,11 @@ void __init prom_init(void)
48 ArcRead(0, &c, 1, &cnt); 49 ArcRead(0, &c, 1, &cnt);
49 ArcEnterInteractiveMode(); 50 ArcEnterInteractiveMode();
50#endif 51#endif
52#ifdef CONFIG_SGI_IP27
53 {
54 extern struct plat_smp_ops ip27_smp_ops;
55
56 register_smp_ops(&ip27_smp_ops);
57 }
58#endif
51} 59}
diff --git a/arch/mips/fw/cfe/cfe_api.c b/arch/mips/fw/cfe/cfe_api.c
index a9f69e4e40ac..717db74f7c6e 100644
--- a/arch/mips/fw/cfe/cfe_api.c
+++ b/arch/mips/fw/cfe/cfe_api.c
@@ -16,19 +16,16 @@
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */ 17 */
18 18
19/* ********************************************************************* 19/*
20 * 20 *
21 * Broadcom Common Firmware Environment (CFE) 21 * Broadcom Common Firmware Environment (CFE)
22 * 22 *
23 * Device Function stubs File: cfe_api.c 23 * This module contains device function stubs (small routines to
24 * 24 * call the standard "iocb" interface entry point to CFE).
25 * This module contains device function stubs (small routines to 25 * There should be one routine here per iocb function call.
26 * call the standard "iocb" interface entry point to CFE). 26 *
27 * There should be one routine here per iocb function call. 27 * Authors: Mitch Lichtenberg, Chris Demetriou
28 * 28 */
29 * Authors: Mitch Lichtenberg, Chris Demetriou
30 *
31 ********************************************************************* */
32 29
33#include <asm/fw/cfe/cfe_api.h> 30#include <asm/fw/cfe/cfe_api.h>
34#include "cfe_api_int.h" 31#include "cfe_api_int.h"
@@ -37,12 +34,8 @@
37#define XPTR_FROM_NATIVE(n) ((cfe_xptr_t) (intptr_t) (n)) 34#define XPTR_FROM_NATIVE(n) ((cfe_xptr_t) (intptr_t) (n))
38#define NATIVE_FROM_XPTR(x) ((void *) (intptr_t) (x)) 35#define NATIVE_FROM_XPTR(x) ((void *) (intptr_t) (x))
39 36
40#ifdef CFE_API_IMPL_NAMESPACE 37int cfe_iocb_dispatch(struct cfe_xiocb *xiocb);
41#define cfe_iocb_dispatch(a) __cfe_iocb_dispatch(a)
42#endif
43int cfe_iocb_dispatch(cfe_xiocb_t * xiocb);
44 38
45#if defined(CFE_API_common) || defined(CFE_API_ALL)
46/* 39/*
47 * Declare the dispatch function with args of "intptr_t". 40 * Declare the dispatch function with args of "intptr_t".
48 * This makes sure whatever model we're compiling in 41 * This makes sure whatever model we're compiling in
@@ -53,27 +46,25 @@ int cfe_iocb_dispatch(cfe_xiocb_t * xiocb);
53 */ 46 */
54 47
55static int (*cfe_dispfunc) (intptr_t handle, intptr_t xiocb) = 0; 48static int (*cfe_dispfunc) (intptr_t handle, intptr_t xiocb) = 0;
56static cfe_xuint_t cfe_handle = 0; 49static u64 cfe_handle = 0;
57 50
58int cfe_init(cfe_xuint_t handle, cfe_xuint_t ept) 51int cfe_init(u64 handle, u64 ept)
59{ 52{
60 cfe_dispfunc = NATIVE_FROM_XPTR(ept); 53 cfe_dispfunc = NATIVE_FROM_XPTR(ept);
61 cfe_handle = handle; 54 cfe_handle = handle;
62 return 0; 55 return 0;
63} 56}
64 57
65int cfe_iocb_dispatch(cfe_xiocb_t * xiocb) 58int cfe_iocb_dispatch(struct cfe_xiocb * xiocb)
66{ 59{
67 if (!cfe_dispfunc) 60 if (!cfe_dispfunc)
68 return -1; 61 return -1;
69 return (*cfe_dispfunc) ((intptr_t) cfe_handle, (intptr_t) xiocb); 62 return (*cfe_dispfunc) ((intptr_t) cfe_handle, (intptr_t) xiocb);
70} 63}
71#endif /* CFE_API_common || CFE_API_ALL */
72 64
73#if defined(CFE_API_close) || defined(CFE_API_ALL)
74int cfe_close(int handle) 65int cfe_close(int handle)
75{ 66{
76 cfe_xiocb_t xiocb; 67 struct cfe_xiocb xiocb;
77 68
78 xiocb.xiocb_fcode = CFE_CMD_DEV_CLOSE; 69 xiocb.xiocb_fcode = CFE_CMD_DEV_CLOSE;
79 xiocb.xiocb_status = 0; 70 xiocb.xiocb_status = 0;
@@ -86,18 +77,16 @@ int cfe_close(int handle)
86 return xiocb.xiocb_status; 77 return xiocb.xiocb_status;
87 78
88} 79}
89#endif /* CFE_API_close || CFE_API_ALL */
90 80
91#if defined(CFE_API_cpu_start) || defined(CFE_API_ALL)
92int cfe_cpu_start(int cpu, void (*fn) (void), long sp, long gp, long a1) 81int cfe_cpu_start(int cpu, void (*fn) (void), long sp, long gp, long a1)
93{ 82{
94 cfe_xiocb_t xiocb; 83 struct cfe_xiocb xiocb;
95 84
96 xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL; 85 xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL;
97 xiocb.xiocb_status = 0; 86 xiocb.xiocb_status = 0;
98 xiocb.xiocb_handle = 0; 87 xiocb.xiocb_handle = 0;
99 xiocb.xiocb_flags = 0; 88 xiocb.xiocb_flags = 0;
100 xiocb.xiocb_psize = sizeof(xiocb_cpuctl_t); 89 xiocb.xiocb_psize = sizeof(struct xiocb_cpuctl);
101 xiocb.plist.xiocb_cpuctl.cpu_number = cpu; 90 xiocb.plist.xiocb_cpuctl.cpu_number = cpu;
102 xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_START; 91 xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_START;
103 xiocb.plist.xiocb_cpuctl.gp_val = gp; 92 xiocb.plist.xiocb_cpuctl.gp_val = gp;
@@ -109,18 +98,16 @@ int cfe_cpu_start(int cpu, void (*fn) (void), long sp, long gp, long a1)
109 98
110 return xiocb.xiocb_status; 99 return xiocb.xiocb_status;
111} 100}
112#endif /* CFE_API_cpu_start || CFE_API_ALL */
113 101
114#if defined(CFE_API_cpu_stop) || defined(CFE_API_ALL)
115int cfe_cpu_stop(int cpu) 102int cfe_cpu_stop(int cpu)
116{ 103{
117 cfe_xiocb_t xiocb; 104 struct cfe_xiocb xiocb;
118 105
119 xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL; 106 xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL;
120 xiocb.xiocb_status = 0; 107 xiocb.xiocb_status = 0;
121 xiocb.xiocb_handle = 0; 108 xiocb.xiocb_handle = 0;
122 xiocb.xiocb_flags = 0; 109 xiocb.xiocb_flags = 0;
123 xiocb.xiocb_psize = sizeof(xiocb_cpuctl_t); 110 xiocb.xiocb_psize = sizeof(struct xiocb_cpuctl);
124 xiocb.plist.xiocb_cpuctl.cpu_number = cpu; 111 xiocb.plist.xiocb_cpuctl.cpu_number = cpu;
125 xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_STOP; 112 xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_STOP;
126 113
@@ -128,18 +115,16 @@ int cfe_cpu_stop(int cpu)
128 115
129 return xiocb.xiocb_status; 116 return xiocb.xiocb_status;
130} 117}
131#endif /* CFE_API_cpu_stop || CFE_API_ALL */
132 118
133#if defined(CFE_API_enumenv) || defined(CFE_API_ALL)
134int cfe_enumenv(int idx, char *name, int namelen, char *val, int vallen) 119int cfe_enumenv(int idx, char *name, int namelen, char *val, int vallen)
135{ 120{
136 cfe_xiocb_t xiocb; 121 struct cfe_xiocb xiocb;
137 122
138 xiocb.xiocb_fcode = CFE_CMD_ENV_SET; 123 xiocb.xiocb_fcode = CFE_CMD_ENV_SET;
139 xiocb.xiocb_status = 0; 124 xiocb.xiocb_status = 0;
140 xiocb.xiocb_handle = 0; 125 xiocb.xiocb_handle = 0;
141 xiocb.xiocb_flags = 0; 126 xiocb.xiocb_flags = 0;
142 xiocb.xiocb_psize = sizeof(xiocb_envbuf_t); 127 xiocb.xiocb_psize = sizeof(struct xiocb_envbuf);
143 xiocb.plist.xiocb_envbuf.enum_idx = idx; 128 xiocb.plist.xiocb_envbuf.enum_idx = idx;
144 xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name); 129 xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name);
145 xiocb.plist.xiocb_envbuf.name_length = namelen; 130 xiocb.plist.xiocb_envbuf.name_length = namelen;
@@ -150,20 +135,17 @@ int cfe_enumenv(int idx, char *name, int namelen, char *val, int vallen)
150 135
151 return xiocb.xiocb_status; 136 return xiocb.xiocb_status;
152} 137}
153#endif /* CFE_API_enumenv || CFE_API_ALL */
154 138
155#if defined(CFE_API_enummem) || defined(CFE_API_ALL)
156int 139int
157cfe_enummem(int idx, int flags, cfe_xuint_t * start, cfe_xuint_t * length, 140cfe_enummem(int idx, int flags, u64 *start, u64 *length, u64 *type)
158 cfe_xuint_t * type)
159{ 141{
160 cfe_xiocb_t xiocb; 142 struct cfe_xiocb xiocb;
161 143
162 xiocb.xiocb_fcode = CFE_CMD_FW_MEMENUM; 144 xiocb.xiocb_fcode = CFE_CMD_FW_MEMENUM;
163 xiocb.xiocb_status = 0; 145 xiocb.xiocb_status = 0;
164 xiocb.xiocb_handle = 0; 146 xiocb.xiocb_handle = 0;
165 xiocb.xiocb_flags = flags; 147 xiocb.xiocb_flags = flags;
166 xiocb.xiocb_psize = sizeof(xiocb_meminfo_t); 148 xiocb.xiocb_psize = sizeof(struct xiocb_meminfo);
167 xiocb.plist.xiocb_meminfo.mi_idx = idx; 149 xiocb.plist.xiocb_meminfo.mi_idx = idx;
168 150
169 cfe_iocb_dispatch(&xiocb); 151 cfe_iocb_dispatch(&xiocb);
@@ -177,30 +159,26 @@ cfe_enummem(int idx, int flags, cfe_xuint_t * start, cfe_xuint_t * length,
177 159
178 return 0; 160 return 0;
179} 161}
180#endif /* CFE_API_enummem || CFE_API_ALL */
181 162
182#if defined(CFE_API_exit) || defined(CFE_API_ALL)
183int cfe_exit(int warm, int status) 163int cfe_exit(int warm, int status)
184{ 164{
185 cfe_xiocb_t xiocb; 165 struct cfe_xiocb xiocb;
186 166
187 xiocb.xiocb_fcode = CFE_CMD_FW_RESTART; 167 xiocb.xiocb_fcode = CFE_CMD_FW_RESTART;
188 xiocb.xiocb_status = 0; 168 xiocb.xiocb_status = 0;
189 xiocb.xiocb_handle = 0; 169 xiocb.xiocb_handle = 0;
190 xiocb.xiocb_flags = warm ? CFE_FLG_WARMSTART : 0; 170 xiocb.xiocb_flags = warm ? CFE_FLG_WARMSTART : 0;
191 xiocb.xiocb_psize = sizeof(xiocb_exitstat_t); 171 xiocb.xiocb_psize = sizeof(struct xiocb_exitstat);
192 xiocb.plist.xiocb_exitstat.status = status; 172 xiocb.plist.xiocb_exitstat.status = status;
193 173
194 cfe_iocb_dispatch(&xiocb); 174 cfe_iocb_dispatch(&xiocb);
195 175
196 return xiocb.xiocb_status; 176 return xiocb.xiocb_status;
197} 177}
198#endif /* CFE_API_exit || CFE_API_ALL */
199 178
200#if defined(CFE_API_flushcache) || defined(CFE_API_ALL)
201int cfe_flushcache(int flg) 179int cfe_flushcache(int flg)
202{ 180{
203 cfe_xiocb_t xiocb; 181 struct cfe_xiocb xiocb;
204 182
205 xiocb.xiocb_fcode = CFE_CMD_FW_FLUSHCACHE; 183 xiocb.xiocb_fcode = CFE_CMD_FW_FLUSHCACHE;
206 xiocb.xiocb_status = 0; 184 xiocb.xiocb_status = 0;
@@ -212,34 +190,30 @@ int cfe_flushcache(int flg)
212 190
213 return xiocb.xiocb_status; 191 return xiocb.xiocb_status;
214} 192}
215#endif /* CFE_API_flushcache || CFE_API_ALL */
216 193
217#if defined(CFE_API_getdevinfo) || defined(CFE_API_ALL)
218int cfe_getdevinfo(char *name) 194int cfe_getdevinfo(char *name)
219{ 195{
220 cfe_xiocb_t xiocb; 196 struct cfe_xiocb xiocb;
221 197
222 xiocb.xiocb_fcode = CFE_CMD_DEV_GETINFO; 198 xiocb.xiocb_fcode = CFE_CMD_DEV_GETINFO;
223 xiocb.xiocb_status = 0; 199 xiocb.xiocb_status = 0;
224 xiocb.xiocb_handle = 0; 200 xiocb.xiocb_handle = 0;
225 xiocb.xiocb_flags = 0; 201 xiocb.xiocb_flags = 0;
226 xiocb.xiocb_psize = sizeof(xiocb_buffer_t); 202 xiocb.xiocb_psize = sizeof(struct xiocb_buffer);
227 xiocb.plist.xiocb_buffer.buf_offset = 0; 203 xiocb.plist.xiocb_buffer.buf_offset = 0;
228 xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(name); 204 xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(name);
229 xiocb.plist.xiocb_buffer.buf_length = cfe_strlen(name); 205 xiocb.plist.xiocb_buffer.buf_length = strlen(name);
230 206
231 cfe_iocb_dispatch(&xiocb); 207 cfe_iocb_dispatch(&xiocb);
232 208
233 if (xiocb.xiocb_status < 0) 209 if (xiocb.xiocb_status < 0)
234 return xiocb.xiocb_status; 210 return xiocb.xiocb_status;
235 return xiocb.plist.xiocb_buffer.buf_devflags; 211 return xiocb.plist.xiocb_buffer.buf_ioctlcmd;
236} 212}
237#endif /* CFE_API_getdevinfo || CFE_API_ALL */
238 213
239#if defined(CFE_API_getenv) || defined(CFE_API_ALL)
240int cfe_getenv(char *name, char *dest, int destlen) 214int cfe_getenv(char *name, char *dest, int destlen)
241{ 215{
242 cfe_xiocb_t xiocb; 216 struct cfe_xiocb xiocb;
243 217
244 *dest = 0; 218 *dest = 0;
245 219
@@ -247,10 +221,10 @@ int cfe_getenv(char *name, char *dest, int destlen)
247 xiocb.xiocb_status = 0; 221 xiocb.xiocb_status = 0;
248 xiocb.xiocb_handle = 0; 222 xiocb.xiocb_handle = 0;
249 xiocb.xiocb_flags = 0; 223 xiocb.xiocb_flags = 0;
250 xiocb.xiocb_psize = sizeof(xiocb_envbuf_t); 224 xiocb.xiocb_psize = sizeof(struct xiocb_envbuf);
251 xiocb.plist.xiocb_envbuf.enum_idx = 0; 225 xiocb.plist.xiocb_envbuf.enum_idx = 0;
252 xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name); 226 xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name);
253 xiocb.plist.xiocb_envbuf.name_length = cfe_strlen(name); 227 xiocb.plist.xiocb_envbuf.name_length = strlen(name);
254 xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(dest); 228 xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(dest);
255 xiocb.plist.xiocb_envbuf.val_length = destlen; 229 xiocb.plist.xiocb_envbuf.val_length = destlen;
256 230
@@ -258,18 +232,16 @@ int cfe_getenv(char *name, char *dest, int destlen)
258 232
259 return xiocb.xiocb_status; 233 return xiocb.xiocb_status;
260} 234}
261#endif /* CFE_API_getenv || CFE_API_ALL */
262 235
263#if defined(CFE_API_getfwinfo) || defined(CFE_API_ALL)
264int cfe_getfwinfo(cfe_fwinfo_t * info) 236int cfe_getfwinfo(cfe_fwinfo_t * info)
265{ 237{
266 cfe_xiocb_t xiocb; 238 struct cfe_xiocb xiocb;
267 239
268 xiocb.xiocb_fcode = CFE_CMD_FW_GETINFO; 240 xiocb.xiocb_fcode = CFE_CMD_FW_GETINFO;
269 xiocb.xiocb_status = 0; 241 xiocb.xiocb_status = 0;
270 xiocb.xiocb_handle = 0; 242 xiocb.xiocb_handle = 0;
271 xiocb.xiocb_flags = 0; 243 xiocb.xiocb_flags = 0;
272 xiocb.xiocb_psize = sizeof(xiocb_fwinfo_t); 244 xiocb.xiocb_psize = sizeof(struct xiocb_fwinfo);
273 245
274 cfe_iocb_dispatch(&xiocb); 246 cfe_iocb_dispatch(&xiocb);
275 247
@@ -292,12 +264,10 @@ int cfe_getfwinfo(cfe_fwinfo_t * info)
292 264
293 return 0; 265 return 0;
294} 266}
295#endif /* CFE_API_getfwinfo || CFE_API_ALL */
296 267
297#if defined(CFE_API_getstdhandle) || defined(CFE_API_ALL)
298int cfe_getstdhandle(int flg) 268int cfe_getstdhandle(int flg)
299{ 269{
300 cfe_xiocb_t xiocb; 270 struct cfe_xiocb xiocb;
301 271
302 xiocb.xiocb_fcode = CFE_CMD_DEV_GETHANDLE; 272 xiocb.xiocb_fcode = CFE_CMD_DEV_GETHANDLE;
303 xiocb.xiocb_status = 0; 273 xiocb.xiocb_status = 0;
@@ -311,23 +281,17 @@ int cfe_getstdhandle(int flg)
311 return xiocb.xiocb_status; 281 return xiocb.xiocb_status;
312 return xiocb.xiocb_handle; 282 return xiocb.xiocb_handle;
313} 283}
314#endif /* CFE_API_getstdhandle || CFE_API_ALL */
315 284
316#if defined(CFE_API_getticks) || defined(CFE_API_ALL)
317int64_t 285int64_t
318#ifdef CFE_API_IMPL_NAMESPACE
319__cfe_getticks(void)
320#else
321cfe_getticks(void) 286cfe_getticks(void)
322#endif
323{ 287{
324 cfe_xiocb_t xiocb; 288 struct cfe_xiocb xiocb;
325 289
326 xiocb.xiocb_fcode = CFE_CMD_FW_GETTIME; 290 xiocb.xiocb_fcode = CFE_CMD_FW_GETTIME;
327 xiocb.xiocb_status = 0; 291 xiocb.xiocb_status = 0;
328 xiocb.xiocb_handle = 0; 292 xiocb.xiocb_handle = 0;
329 xiocb.xiocb_flags = 0; 293 xiocb.xiocb_flags = 0;
330 xiocb.xiocb_psize = sizeof(xiocb_time_t); 294 xiocb.xiocb_psize = sizeof(struct xiocb_time);
331 xiocb.plist.xiocb_time.ticks = 0; 295 xiocb.plist.xiocb_time.ticks = 0;
332 296
333 cfe_iocb_dispatch(&xiocb); 297 cfe_iocb_dispatch(&xiocb);
@@ -335,18 +299,16 @@ cfe_getticks(void)
335 return xiocb.plist.xiocb_time.ticks; 299 return xiocb.plist.xiocb_time.ticks;
336 300
337} 301}
338#endif /* CFE_API_getticks || CFE_API_ALL */
339 302
340#if defined(CFE_API_inpstat) || defined(CFE_API_ALL)
341int cfe_inpstat(int handle) 303int cfe_inpstat(int handle)
342{ 304{
343 cfe_xiocb_t xiocb; 305 struct cfe_xiocb xiocb;
344 306
345 xiocb.xiocb_fcode = CFE_CMD_DEV_INPSTAT; 307 xiocb.xiocb_fcode = CFE_CMD_DEV_INPSTAT;
346 xiocb.xiocb_status = 0; 308 xiocb.xiocb_status = 0;
347 xiocb.xiocb_handle = handle; 309 xiocb.xiocb_handle = handle;
348 xiocb.xiocb_flags = 0; 310 xiocb.xiocb_flags = 0;
349 xiocb.xiocb_psize = sizeof(xiocb_inpstat_t); 311 xiocb.xiocb_psize = sizeof(struct xiocb_inpstat);
350 xiocb.plist.xiocb_inpstat.inp_status = 0; 312 xiocb.plist.xiocb_inpstat.inp_status = 0;
351 313
352 cfe_iocb_dispatch(&xiocb); 314 cfe_iocb_dispatch(&xiocb);
@@ -355,20 +317,18 @@ int cfe_inpstat(int handle)
355 return xiocb.xiocb_status; 317 return xiocb.xiocb_status;
356 return xiocb.plist.xiocb_inpstat.inp_status; 318 return xiocb.plist.xiocb_inpstat.inp_status;
357} 319}
358#endif /* CFE_API_inpstat || CFE_API_ALL */
359 320
360#if defined(CFE_API_ioctl) || defined(CFE_API_ALL)
361int 321int
362cfe_ioctl(int handle, unsigned int ioctlnum, unsigned char *buffer, 322cfe_ioctl(int handle, unsigned int ioctlnum, unsigned char *buffer,
363 int length, int *retlen, cfe_xuint_t offset) 323 int length, int *retlen, u64 offset)
364{ 324{
365 cfe_xiocb_t xiocb; 325 struct cfe_xiocb xiocb;
366 326
367 xiocb.xiocb_fcode = CFE_CMD_DEV_IOCTL; 327 xiocb.xiocb_fcode = CFE_CMD_DEV_IOCTL;
368 xiocb.xiocb_status = 0; 328 xiocb.xiocb_status = 0;
369 xiocb.xiocb_handle = handle; 329 xiocb.xiocb_handle = handle;
370 xiocb.xiocb_flags = 0; 330 xiocb.xiocb_flags = 0;
371 xiocb.xiocb_psize = sizeof(xiocb_buffer_t); 331 xiocb.xiocb_psize = sizeof(struct xiocb_buffer);
372 xiocb.plist.xiocb_buffer.buf_offset = offset; 332 xiocb.plist.xiocb_buffer.buf_offset = offset;
373 xiocb.plist.xiocb_buffer.buf_ioctlcmd = ioctlnum; 333 xiocb.plist.xiocb_buffer.buf_ioctlcmd = ioctlnum;
374 xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer); 334 xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer);
@@ -380,21 +340,19 @@ cfe_ioctl(int handle, unsigned int ioctlnum, unsigned char *buffer,
380 *retlen = xiocb.plist.xiocb_buffer.buf_retlen; 340 *retlen = xiocb.plist.xiocb_buffer.buf_retlen;
381 return xiocb.xiocb_status; 341 return xiocb.xiocb_status;
382} 342}
383#endif /* CFE_API_ioctl || CFE_API_ALL */
384 343
385#if defined(CFE_API_open) || defined(CFE_API_ALL)
386int cfe_open(char *name) 344int cfe_open(char *name)
387{ 345{
388 cfe_xiocb_t xiocb; 346 struct cfe_xiocb xiocb;
389 347
390 xiocb.xiocb_fcode = CFE_CMD_DEV_OPEN; 348 xiocb.xiocb_fcode = CFE_CMD_DEV_OPEN;
391 xiocb.xiocb_status = 0; 349 xiocb.xiocb_status = 0;
392 xiocb.xiocb_handle = 0; 350 xiocb.xiocb_handle = 0;
393 xiocb.xiocb_flags = 0; 351 xiocb.xiocb_flags = 0;
394 xiocb.xiocb_psize = sizeof(xiocb_buffer_t); 352 xiocb.xiocb_psize = sizeof(struct xiocb_buffer);
395 xiocb.plist.xiocb_buffer.buf_offset = 0; 353 xiocb.plist.xiocb_buffer.buf_offset = 0;
396 xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(name); 354 xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(name);
397 xiocb.plist.xiocb_buffer.buf_length = cfe_strlen(name); 355 xiocb.plist.xiocb_buffer.buf_length = strlen(name);
398 356
399 cfe_iocb_dispatch(&xiocb); 357 cfe_iocb_dispatch(&xiocb);
400 358
@@ -402,27 +360,21 @@ int cfe_open(char *name)
402 return xiocb.xiocb_status; 360 return xiocb.xiocb_status;
403 return xiocb.xiocb_handle; 361 return xiocb.xiocb_handle;
404} 362}
405#endif /* CFE_API_open || CFE_API_ALL */
406 363
407#if defined(CFE_API_read) || defined(CFE_API_ALL)
408int cfe_read(int handle, unsigned char *buffer, int length) 364int cfe_read(int handle, unsigned char *buffer, int length)
409{ 365{
410 return cfe_readblk(handle, 0, buffer, length); 366 return cfe_readblk(handle, 0, buffer, length);
411} 367}
412#endif /* CFE_API_read || CFE_API_ALL */
413 368
414#if defined(CFE_API_readblk) || defined(CFE_API_ALL) 369int cfe_readblk(int handle, s64 offset, unsigned char *buffer, int length)
415int
416cfe_readblk(int handle, cfe_xint_t offset, unsigned char *buffer,
417 int length)
418{ 370{
419 cfe_xiocb_t xiocb; 371 struct cfe_xiocb xiocb;
420 372
421 xiocb.xiocb_fcode = CFE_CMD_DEV_READ; 373 xiocb.xiocb_fcode = CFE_CMD_DEV_READ;
422 xiocb.xiocb_status = 0; 374 xiocb.xiocb_status = 0;
423 xiocb.xiocb_handle = handle; 375 xiocb.xiocb_handle = handle;
424 xiocb.xiocb_flags = 0; 376 xiocb.xiocb_flags = 0;
425 xiocb.xiocb_psize = sizeof(xiocb_buffer_t); 377 xiocb.xiocb_psize = sizeof(struct xiocb_buffer);
426 xiocb.plist.xiocb_buffer.buf_offset = offset; 378 xiocb.plist.xiocb_buffer.buf_offset = offset;
427 xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer); 379 xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer);
428 xiocb.plist.xiocb_buffer.buf_length = length; 380 xiocb.plist.xiocb_buffer.buf_length = length;
@@ -433,62 +385,41 @@ cfe_readblk(int handle, cfe_xint_t offset, unsigned char *buffer,
433 return xiocb.xiocb_status; 385 return xiocb.xiocb_status;
434 return xiocb.plist.xiocb_buffer.buf_retlen; 386 return xiocb.plist.xiocb_buffer.buf_retlen;
435} 387}
436#endif /* CFE_API_readblk || CFE_API_ALL */
437 388
438#if defined(CFE_API_setenv) || defined(CFE_API_ALL)
439int cfe_setenv(char *name, char *val) 389int cfe_setenv(char *name, char *val)
440{ 390{
441 cfe_xiocb_t xiocb; 391 struct cfe_xiocb xiocb;
442 392
443 xiocb.xiocb_fcode = CFE_CMD_ENV_SET; 393 xiocb.xiocb_fcode = CFE_CMD_ENV_SET;
444 xiocb.xiocb_status = 0; 394 xiocb.xiocb_status = 0;
445 xiocb.xiocb_handle = 0; 395 xiocb.xiocb_handle = 0;
446 xiocb.xiocb_flags = 0; 396 xiocb.xiocb_flags = 0;
447 xiocb.xiocb_psize = sizeof(xiocb_envbuf_t); 397 xiocb.xiocb_psize = sizeof(struct xiocb_envbuf);
448 xiocb.plist.xiocb_envbuf.enum_idx = 0; 398 xiocb.plist.xiocb_envbuf.enum_idx = 0;
449 xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name); 399 xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name);
450 xiocb.plist.xiocb_envbuf.name_length = cfe_strlen(name); 400 xiocb.plist.xiocb_envbuf.name_length = strlen(name);
451 xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(val); 401 xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(val);
452 xiocb.plist.xiocb_envbuf.val_length = cfe_strlen(val); 402 xiocb.plist.xiocb_envbuf.val_length = strlen(val);
453 403
454 cfe_iocb_dispatch(&xiocb); 404 cfe_iocb_dispatch(&xiocb);
455 405
456 return xiocb.xiocb_status; 406 return xiocb.xiocb_status;
457} 407}
458#endif /* CFE_API_setenv || CFE_API_ALL */
459
460#if (defined(CFE_API_strlen) || defined(CFE_API_ALL)) \
461 && !defined(CFE_API_STRLEN_CUSTOM)
462int cfe_strlen(char *name)
463{
464 int count = 0;
465
466 while (*name++)
467 count++;
468 408
469 return count;
470}
471#endif /* CFE_API_strlen || CFE_API_ALL */
472
473#if defined(CFE_API_write) || defined(CFE_API_ALL)
474int cfe_write(int handle, unsigned char *buffer, int length) 409int cfe_write(int handle, unsigned char *buffer, int length)
475{ 410{
476 return cfe_writeblk(handle, 0, buffer, length); 411 return cfe_writeblk(handle, 0, buffer, length);
477} 412}
478#endif /* CFE_API_write || CFE_API_ALL */
479 413
480#if defined(CFE_API_writeblk) || defined(CFE_API_ALL) 414int cfe_writeblk(int handle, s64 offset, unsigned char *buffer, int length)
481int
482cfe_writeblk(int handle, cfe_xint_t offset, unsigned char *buffer,
483 int length)
484{ 415{
485 cfe_xiocb_t xiocb; 416 struct cfe_xiocb xiocb;
486 417
487 xiocb.xiocb_fcode = CFE_CMD_DEV_WRITE; 418 xiocb.xiocb_fcode = CFE_CMD_DEV_WRITE;
488 xiocb.xiocb_status = 0; 419 xiocb.xiocb_status = 0;
489 xiocb.xiocb_handle = handle; 420 xiocb.xiocb_handle = handle;
490 xiocb.xiocb_flags = 0; 421 xiocb.xiocb_flags = 0;
491 xiocb.xiocb_psize = sizeof(xiocb_buffer_t); 422 xiocb.xiocb_psize = sizeof(struct xiocb_buffer);
492 xiocb.plist.xiocb_buffer.buf_offset = offset; 423 xiocb.plist.xiocb_buffer.buf_offset = offset;
493 xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer); 424 xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer);
494 xiocb.plist.xiocb_buffer.buf_length = length; 425 xiocb.plist.xiocb_buffer.buf_length = length;
@@ -499,4 +430,3 @@ cfe_writeblk(int handle, cfe_xint_t offset, unsigned char *buffer,
499 return xiocb.xiocb_status; 430 return xiocb.xiocb_status;
500 return xiocb.plist.xiocb_buffer.buf_retlen; 431 return xiocb.plist.xiocb_buffer.buf_retlen;
501} 432}
502#endif /* CFE_API_writeblk || CFE_API_ALL */
diff --git a/arch/mips/fw/cfe/cfe_api_int.h b/arch/mips/fw/cfe/cfe_api_int.h
index f7e5a64b55f3..d9759e646956 100644
--- a/arch/mips/fw/cfe/cfe_api_int.h
+++ b/arch/mips/fw/cfe/cfe_api_int.h
@@ -15,28 +15,12 @@
15 * along with this program; if not, write to the Free Software 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. 16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */ 17 */
18
19/* *********************************************************************
20 *
21 * Broadcom Common Firmware Environment (CFE)
22 *
23 * Device function prototypes File: cfe_api_int.h
24 *
25 * This header defines all internal types and macros for the
26 * library. This is stuff that's not exported to an app
27 * using the library.
28 *
29 * Authors: Mitch Lichtenberg, Chris Demetriou
30 *
31 ********************************************************************* */
32
33#ifndef CFE_API_INT_H 18#ifndef CFE_API_INT_H
34#define CFE_API_INT_H 19#define CFE_API_INT_H
35 20
36/* ********************************************************************* 21/*
37 * Constants 22 * Constants.
38 ********************************************************************* */ 23 */
39
40#define CFE_CMD_FW_GETINFO 0 24#define CFE_CMD_FW_GETINFO 0
41#define CFE_CMD_FW_RESTART 1 25#define CFE_CMD_FW_RESTART 1
42#define CFE_CMD_FW_BOOT 2 26#define CFE_CMD_FW_BOOT 2
@@ -64,89 +48,101 @@
64 48
65#define CFE_CMD_VENDOR_USE 0x8000 /* codes above this are for customer use */ 49#define CFE_CMD_VENDOR_USE 0x8000 /* codes above this are for customer use */
66 50
67/* ********************************************************************* 51/*
68 * Structures 52 * Structures.
69 ********************************************************************* */ 53 */
70 54
71typedef uint64_t cfe_xuint_t; 55/* eeek, signed "pointers" */
72typedef int64_t cfe_xint_t; 56typedef s64 cfe_xptr_t;
73typedef int64_t cfe_xptr_t;
74 57
75typedef struct xiocb_buffer_s { 58struct xiocb_buffer {
76 cfe_xuint_t buf_offset; /* offset on device (bytes) */ 59 u64 buf_offset; /* offset on device (bytes) */
77 cfe_xptr_t buf_ptr; /* pointer to a buffer */ 60 cfe_xptr_t buf_ptr; /* pointer to a buffer */
78 cfe_xuint_t buf_length; /* length of this buffer */ 61 u64 buf_length; /* length of this buffer */
79 cfe_xuint_t buf_retlen; /* returned length (for read ops) */ 62 u64 buf_retlen; /* returned length (for read ops) */
80 cfe_xuint_t buf_ioctlcmd; /* IOCTL command (used only for IOCTLs) */ 63 u64 buf_ioctlcmd; /* IOCTL command (used only for IOCTLs) */
81} xiocb_buffer_t; 64};
82
83#define buf_devflags buf_ioctlcmd /* returned device info flags */
84 65
85typedef struct xiocb_inpstat_s { 66struct xiocb_inpstat {
86 cfe_xuint_t inp_status; /* 1 means input available */ 67 u64 inp_status; /* 1 means input available */
87} xiocb_inpstat_t; 68};
88 69
89typedef struct xiocb_envbuf_s { 70struct xiocb_envbuf {
90 cfe_xint_t enum_idx; /* 0-based enumeration index */ 71 s64 enum_idx; /* 0-based enumeration index */
91 cfe_xptr_t name_ptr; /* name string buffer */ 72 cfe_xptr_t name_ptr; /* name string buffer */
92 cfe_xint_t name_length; /* size of name buffer */ 73 s64 name_length; /* size of name buffer */
93 cfe_xptr_t val_ptr; /* value string buffer */ 74 cfe_xptr_t val_ptr; /* value string buffer */
94 cfe_xint_t val_length; /* size of value string buffer */ 75 s64 val_length; /* size of value string buffer */
95} xiocb_envbuf_t; 76};
96 77
97typedef struct xiocb_cpuctl_s { 78struct xiocb_cpuctl {
98 cfe_xuint_t cpu_number; /* cpu number to control */ 79 u64 cpu_number; /* cpu number to control */
99 cfe_xuint_t cpu_command; /* command to issue to CPU */ 80 u64 cpu_command; /* command to issue to CPU */
100 cfe_xuint_t start_addr; /* CPU start address */ 81 u64 start_addr; /* CPU start address */
101 cfe_xuint_t gp_val; /* starting GP value */ 82 u64 gp_val; /* starting GP value */
102 cfe_xuint_t sp_val; /* starting SP value */ 83 u64 sp_val; /* starting SP value */
103 cfe_xuint_t a1_val; /* starting A1 value */ 84 u64 a1_val; /* starting A1 value */
104} xiocb_cpuctl_t; 85};
105 86
106typedef struct xiocb_time_s { 87struct xiocb_time {
107 cfe_xint_t ticks; /* current time in ticks */ 88 s64 ticks; /* current time in ticks */
108} xiocb_time_t; 89};
109 90
110typedef struct xiocb_exitstat_s { 91struct xiocb_exitstat{
111 cfe_xint_t status; 92 s64 status;
112} xiocb_exitstat_t; 93};
113 94
114typedef struct xiocb_meminfo_s { 95struct xiocb_meminfo {
115 cfe_xint_t mi_idx; /* 0-based enumeration index */ 96 s64 mi_idx; /* 0-based enumeration index */
116 cfe_xint_t mi_type; /* type of memory block */ 97 s64 mi_type; /* type of memory block */
117 cfe_xuint_t mi_addr; /* physical start address */ 98 u64 mi_addr; /* physical start address */
118 cfe_xuint_t mi_size; /* block size */ 99 u64 mi_size; /* block size */
119} xiocb_meminfo_t; 100};
120 101
121typedef struct xiocb_fwinfo_s { 102struct xiocb_fwinfo {
122 cfe_xint_t fwi_version; /* major, minor, eco version */ 103 s64 fwi_version; /* major, minor, eco version */
123 cfe_xint_t fwi_totalmem; /* total installed mem */ 104 s64 fwi_totalmem; /* total installed mem */
124 cfe_xint_t fwi_flags; /* various flags */ 105 s64 fwi_flags; /* various flags */
125 cfe_xint_t fwi_boardid; /* board ID */ 106 s64 fwi_boardid; /* board ID */
126 cfe_xint_t fwi_bootarea_va; /* VA of boot area */ 107 s64 fwi_bootarea_va; /* VA of boot area */
127 cfe_xint_t fwi_bootarea_pa; /* PA of boot area */ 108 s64 fwi_bootarea_pa; /* PA of boot area */
128 cfe_xint_t fwi_bootarea_size; /* size of boot area */ 109 s64 fwi_bootarea_size; /* size of boot area */
129 cfe_xint_t fwi_reserved1; 110 s64 fwi_reserved1;
130 cfe_xint_t fwi_reserved2; 111 s64 fwi_reserved2;
131 cfe_xint_t fwi_reserved3; 112 s64 fwi_reserved3;
132} xiocb_fwinfo_t; 113};
133 114
134typedef struct cfe_xiocb_s { 115struct cfe_xiocb {
135 cfe_xuint_t xiocb_fcode; /* IOCB function code */ 116 u64 xiocb_fcode; /* IOCB function code */
136 cfe_xint_t xiocb_status; /* return status */ 117 s64 xiocb_status; /* return status */
137 cfe_xint_t xiocb_handle; /* file/device handle */ 118 s64 xiocb_handle; /* file/device handle */
138 cfe_xuint_t xiocb_flags; /* flags for this IOCB */ 119 u64 xiocb_flags; /* flags for this IOCB */
139 cfe_xuint_t xiocb_psize; /* size of parameter list */ 120 u64 xiocb_psize; /* size of parameter list */
140 union { 121 union {
141 xiocb_buffer_t xiocb_buffer; /* buffer parameters */ 122 /* buffer parameters */
142 xiocb_inpstat_t xiocb_inpstat; /* input status parameters */ 123 struct xiocb_buffer xiocb_buffer;
143 xiocb_envbuf_t xiocb_envbuf; /* environment function parameters */ 124
144 xiocb_cpuctl_t xiocb_cpuctl; /* CPU control parameters */ 125 /* input status parameters */
145 xiocb_time_t xiocb_time; /* timer parameters */ 126 struct xiocb_inpstat xiocb_inpstat;
146 xiocb_meminfo_t xiocb_meminfo; /* memory arena info parameters */ 127
147 xiocb_fwinfo_t xiocb_fwinfo; /* firmware information */ 128 /* environment function parameters */
148 xiocb_exitstat_t xiocb_exitstat; /* Exit Status */ 129 struct xiocb_envbuf xiocb_envbuf;
130
131 /* CPU control parameters */
132 struct xiocb_cpuctl xiocb_cpuctl;
133
134 /* timer parameters */
135 struct xiocb_time xiocb_time;
136
137 /* memory arena info parameters */
138 struct xiocb_meminfo xiocb_meminfo;
139
140 /* firmware information */
141 struct xiocb_fwinfo xiocb_fwinfo;
142
143 /* Exit Status */
144 struct xiocb_exitstat xiocb_exitstat;
149 } plist; 145 } plist;
150} cfe_xiocb_t; 146};
151 147
152#endif /* CFE_API_INT_H */ 148#endif /* CFE_API_INT_H */
diff --git a/arch/mips/fw/lib/Makefile b/arch/mips/fw/lib/Makefile
new file mode 100644
index 000000000000..84befc968fc4
--- /dev/null
+++ b/arch/mips/fw/lib/Makefile
@@ -0,0 +1,5 @@
1#
2# Makefile for generic prom monitor library routines under Linux.
3#
4
5lib-$(CONFIG_64BIT) += call_o32.o
diff --git a/arch/mips/fw/lib/call_o32.S b/arch/mips/fw/lib/call_o32.S
new file mode 100644
index 000000000000..bdf7d1d4081a
--- /dev/null
+++ b/arch/mips/fw/lib/call_o32.S
@@ -0,0 +1,97 @@
1/*
2 * arch/mips/dec/prom/call_o32.S
3 *
4 * O32 interface for the 64 (or N32) ABI.
5 *
6 * Copyright (C) 2002 Maciej W. Rozycki
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
12 */
13
14#include <asm/asm.h>
15#include <asm/regdef.h>
16
17/* Maximum number of arguments supported. Must be even! */
18#define O32_ARGC 32
19/* Number of static registers we save. */
20#define O32_STATC 11
21/* Frame size for static register */
22#define O32_FRAMESZ (SZREG * O32_STATC)
23/* Frame size on new stack */
24#define O32_FRAMESZ_NEW (SZREG + 4 * O32_ARGC)
25
26 .text
27
28/*
29 * O32 function call dispatcher, for interfacing 32-bit ROM routines.
30 *
31 * The standard 64 (N32) calling sequence is supported, with a0
32 * holding a function pointer, a1 a new stack pointer, a2-a7 -- its
33 * first six arguments and the stack -- remaining ones (up to O32_ARGC,
34 * including a2-a7). Static registers, gp and fp are preserved, v0 holds
35 * a result. This code relies on the called o32 function for sp and ra
36 * restoration and this dispatcher has to be placed in a KSEGx (or KUSEG)
37 * address space. Any pointers passed have to point to addresses within
38 * one of these spaces as well.
39 */
40NESTED(call_o32, O32_FRAMESZ, ra)
41 REG_SUBU sp,O32_FRAMESZ
42
43 REG_S ra,O32_FRAMESZ-1*SZREG(sp)
44 REG_S fp,O32_FRAMESZ-2*SZREG(sp)
45 REG_S gp,O32_FRAMESZ-3*SZREG(sp)
46 REG_S s7,O32_FRAMESZ-4*SZREG(sp)
47 REG_S s6,O32_FRAMESZ-5*SZREG(sp)
48 REG_S s5,O32_FRAMESZ-6*SZREG(sp)
49 REG_S s4,O32_FRAMESZ-7*SZREG(sp)
50 REG_S s3,O32_FRAMESZ-8*SZREG(sp)
51 REG_S s2,O32_FRAMESZ-9*SZREG(sp)
52 REG_S s1,O32_FRAMESZ-10*SZREG(sp)
53 REG_S s0,O32_FRAMESZ-11*SZREG(sp)
54
55 move jp,a0
56 REG_SUBU s0,a1,O32_FRAMESZ_NEW
57 REG_S sp,O32_FRAMESZ_NEW-1*SZREG(s0)
58
59 sll a0,a2,zero
60 sll a1,a3,zero
61 sll a2,a4,zero
62 sll a3,a5,zero
63 sw a6,0x10(s0)
64 sw a7,0x14(s0)
65
66 PTR_LA t0,O32_FRAMESZ(sp)
67 PTR_LA t1,0x18(s0)
68 li t2,O32_ARGC-6
691:
70 lw t3,(t0)
71 REG_ADDU t0,SZREG
72 sw t3,(t1)
73 REG_SUBU t2,1
74 REG_ADDU t1,4
75 bnez t2,1b
76
77 move sp,s0
78
79 jalr jp
80
81 REG_L sp,O32_FRAMESZ_NEW-1*SZREG(sp)
82
83 REG_L s0,O32_FRAMESZ-11*SZREG(sp)
84 REG_L s1,O32_FRAMESZ-10*SZREG(sp)
85 REG_L s2,O32_FRAMESZ-9*SZREG(sp)
86 REG_L s3,O32_FRAMESZ-8*SZREG(sp)
87 REG_L s4,O32_FRAMESZ-7*SZREG(sp)
88 REG_L s5,O32_FRAMESZ-6*SZREG(sp)
89 REG_L s6,O32_FRAMESZ-5*SZREG(sp)
90 REG_L s7,O32_FRAMESZ-4*SZREG(sp)
91 REG_L gp,O32_FRAMESZ-3*SZREG(sp)
92 REG_L fp,O32_FRAMESZ-2*SZREG(sp)
93 REG_L ra,O32_FRAMESZ-1*SZREG(sp)
94
95 REG_ADDU sp,O32_FRAMESZ
96 jr ra
97END(call_o32)
diff --git a/arch/mips/fw/sni/Makefile b/arch/mips/fw/sni/Makefile
new file mode 100644
index 000000000000..d9740a3788e2
--- /dev/null
+++ b/arch/mips/fw/sni/Makefile
@@ -0,0 +1,5 @@
1#
2# Makefile for the SNI prom monitor routines under Linux.
3#
4
5lib-$(CONFIG_SNIPROM) += sniprom.o
diff --git a/arch/mips/fw/sni/sniprom.c b/arch/mips/fw/sni/sniprom.c
new file mode 100644
index 000000000000..96ba99202758
--- /dev/null
+++ b/arch/mips/fw/sni/sniprom.c
@@ -0,0 +1,151 @@
1/*
2 * Big Endian PROM code for SNI RM machines
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2005-2006 Florian Lohoff (flo@rfc822.org)
9 * Copyright (C) 2005-2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
10 */
11
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/string.h>
15#include <linux/console.h>
16
17#include <asm/addrspace.h>
18#include <asm/sni.h>
19#include <asm/mipsprom.h>
20#include <asm/mipsregs.h>
21#include <asm/bootinfo.h>
22
23/* special SNI prom calls */
24/*
25 * This does not exist in all proms - SINIX compares
26 * the prom env variable "version" against "2.0008"
27 * or greater. If lesser it tries to probe interesting
28 * registers
29 */
30#define PROM_GET_MEMCONF 58
31#define PROM_GET_HWCONF 61
32
33#define PROM_VEC (u64 *)CKSEG1ADDR(0x1fc00000)
34#define PROM_ENTRY(x) (PROM_VEC + (x))
35
36#define ___prom_putchar ((int *(*)(int))PROM_ENTRY(PROM_PUTCHAR))
37#define ___prom_getenv ((char *(*)(char *))PROM_ENTRY(PROM_GETENV))
38#define ___prom_get_memconf ((void (*)(void *))PROM_ENTRY(PROM_GET_MEMCONF))
39#define ___prom_get_hwconf ((u32 (*)(void))PROM_ENTRY(PROM_GET_HWCONF))
40
41#ifdef CONFIG_64BIT
42
43static u8 o32_stk[16384];
44#define O32_STK &o32_stk[sizeof(o32_stk)]
45
46#define __PROM_O32(fun, arg) fun arg __asm__(#fun); \
47 __asm__(#fun " = call_o32")
48
49int __PROM_O32(__prom_putchar, (int *(*)(int), void *, int));
50char *__PROM_O32(__prom_getenv, (char *(*)(char *), void *, char *));
51void __PROM_O32(__prom_get_memconf, (void (*)(void *), void *, void *));
52u32 __PROM_O32(__prom_get_hwconf, (u32 (*)(void), void *));
53
54#define _prom_putchar(x) __prom_putchar(___prom_putchar, O32_STK, x)
55#define _prom_getenv(x) __prom_getenv(___prom_getenv, O32_STK, x)
56#define _prom_get_memconf(x) __prom_get_memconf(___prom_get_memconf, O32_STK, x)
57#define _prom_get_hwconf() __prom_get_hwconf(___prom_get_hwconf, O32_STK)
58
59#else
60#define _prom_putchar(x) ___prom_putchar(x)
61#define _prom_getenv(x) ___prom_getenv(x)
62#define _prom_get_memconf(x) ___prom_get_memconf(x)
63#define _prom_get_hwconf(x) ___prom_get_hwconf(x)
64#endif
65
66void prom_putchar(char c)
67{
68 _prom_putchar(c);
69}
70
71
72char *prom_getenv(char *s)
73{
74 return _prom_getenv(s);
75}
76
77void *prom_get_hwconf(void)
78{
79 u32 hwconf = _prom_get_hwconf();
80
81 if (hwconf == 0xffffffff)
82 return NULL;
83
84 return (void *)CKSEG1ADDR(hwconf);
85}
86
87void __init prom_free_prom_memory(void)
88{
89}
90
91/*
92 * /proc/cpuinfo system type
93 *
94 */
95char *system_type = "Unknown";
96const char *get_system_type(void)
97{
98 return system_type;
99}
100
101static void __init sni_mem_init(void)
102{
103 int i, memsize;
104 struct membank {
105 u32 size;
106 u32 base;
107 u32 size2;
108 u32 pad1;
109 u32 pad2;
110 } memconf[8];
111 int brd_type = *(unsigned char *)SNI_IDPROM_BRDTYPE;
112
113
114 /* MemSIZE from prom in 16MByte chunks */
115 memsize = *((unsigned char *) SNI_IDPROM_MEMSIZE) * 16;
116
117 pr_debug("IDProm memsize: %u MByte\n", memsize);
118
119 /* get memory bank layout from prom */
120 _prom_get_memconf(&memconf);
121
122 pr_debug("prom_get_mem_conf memory configuration:\n");
123 for (i = 0; i < 8 && memconf[i].size; i++) {
124 if (brd_type == SNI_BRD_PCI_TOWER ||
125 brd_type == SNI_BRD_PCI_TOWER_CPLUS) {
126 if (memconf[i].base >= 0x20000000 &&
127 memconf[i].base < 0x30000000)
128 memconf[i].base -= 0x20000000;
129 }
130 pr_debug("Bank%d: %08x @ %08x\n", i,
131 memconf[i].size, memconf[i].base);
132 add_memory_region(memconf[i].base, memconf[i].size,
133 BOOT_MEM_RAM);
134 }
135}
136
137void __init prom_init(void)
138{
139 int argc = fw_arg0;
140 u32 *argv = (u32 *)CKSEG0ADDR(fw_arg1);
141 int i;
142
143 sni_mem_init();
144
145 /* copy prom cmdline parameters to kernel cmdline */
146 for (i = 1; i < argc; i++) {
147 strcat(arcs_cmdline, (char *)CKSEG0ADDR(argv[i]));
148 if (i < (argc - 1))
149 strcat(arcs_cmdline, " ");
150 }
151}
diff --git a/arch/mips/gt64120/wrppmc/setup.c b/arch/mips/gt64120/wrppmc/setup.c
index 51f6b7862460..728ef6a80edd 100644
--- a/arch/mips/gt64120/wrppmc/setup.c
+++ b/arch/mips/gt64120/wrppmc/setup.c
@@ -121,8 +121,6 @@ const char *get_system_type(void)
121 */ 121 */
122void __init prom_init(void) 122void __init prom_init(void)
123{ 123{
124 mips_machtype = MACH_WRPPMC;
125
126 add_memory_region(WRPPMC_SDRAM_SCS0_BASE, WRPPMC_SDRAM_SCS0_SIZE, BOOT_MEM_RAM); 124 add_memory_region(WRPPMC_SDRAM_SCS0_BASE, WRPPMC_SDRAM_SCS0_SIZE, BOOT_MEM_RAM);
127 add_memory_region(WRPPMC_BOOTROM_BASE, WRPPMC_BOOTROM_SIZE, BOOT_MEM_ROM_DATA); 125 add_memory_region(WRPPMC_BOOTROM_BASE, WRPPMC_BOOTROM_SIZE, BOOT_MEM_ROM_DATA);
128 126
diff --git a/arch/mips/jazz/setup.c b/arch/mips/jazz/setup.c
index a7857973ca03..a7947199c99b 100644
--- a/arch/mips/jazz/setup.c
+++ b/arch/mips/jazz/setup.c
@@ -200,12 +200,19 @@ static struct platform_device jazz_cmos_pdev = {
200 .resource = jazz_cmos_rsrc 200 .resource = jazz_cmos_rsrc
201}; 201};
202 202
203static struct platform_device pcspeaker_pdev = {
204 .name = "pcspkr",
205 .id = -1,
206};
207
203static int __init jazz_setup_devinit(void) 208static int __init jazz_setup_devinit(void)
204{ 209{
205 platform_device_register(&jazz_serial8250_device); 210 platform_device_register(&jazz_serial8250_device);
206 platform_device_register(&jazz_esp_pdev); 211 platform_device_register(&jazz_esp_pdev);
207 platform_device_register(&jazz_sonic_pdev); 212 platform_device_register(&jazz_sonic_pdev);
208 platform_device_register(&jazz_cmos_pdev); 213 platform_device_register(&jazz_cmos_pdev);
214 platform_device_register(&pcspeaker_pdev);
215
209 return 0; 216 return 0;
210} 217}
211 218
diff --git a/arch/mips/jmr3927/rbhma3100/init.c b/arch/mips/jmr3927/rbhma3100/init.c
index b643f75ec9a5..700b9cf8eb9d 100644
--- a/arch/mips/jmr3927/rbhma3100/init.c
+++ b/arch/mips/jmr3927/rbhma3100/init.c
@@ -52,10 +52,6 @@ void __init prom_init(void)
52 puts("Warning: TX3927 TLB off\n"); 52 puts("Warning: TX3927 TLB off\n");
53#endif 53#endif
54 54
55#ifdef CONFIG_TOSHIBA_JMR3927
56 mips_machtype = MACH_TOSHIBA_JMR3927;
57#endif
58
59 prom_init_cmdline(); 55 prom_init_cmdline();
60 add_memory_region(0, JMR3927_SDRAM_SIZE, BOOT_MEM_RAM); 56 add_memory_region(0, JMR3927_SDRAM_SIZE, BOOT_MEM_RAM);
61} 57}
diff --git a/arch/mips/jmr3927/rbhma3100/setup.c b/arch/mips/jmr3927/rbhma3100/setup.c
index 06e01c8f4e3a..c886d804d303 100644
--- a/arch/mips/jmr3927/rbhma3100/setup.c
+++ b/arch/mips/jmr3927/rbhma3100/setup.c
@@ -29,21 +29,17 @@
29 29
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/kernel.h> 31#include <linux/kernel.h>
32#include <linux/kdev_t.h>
33#include <linux/types.h> 32#include <linux/types.h>
34#include <linux/pci.h> 33#include <linux/pci.h>
35#include <linux/ide.h>
36#include <linux/ioport.h> 34#include <linux/ioport.h>
37#include <linux/delay.h> 35#include <linux/delay.h>
38#include <linux/pm.h> 36#include <linux/pm.h>
39#include <linux/platform_device.h> 37#include <linux/platform_device.h>
38#include <linux/clk.h>
40#ifdef CONFIG_SERIAL_TXX9 39#ifdef CONFIG_SERIAL_TXX9
41#include <linux/tty.h>
42#include <linux/serial.h>
43#include <linux/serial_core.h> 40#include <linux/serial_core.h>
44#endif 41#endif
45 42
46#include <asm/addrspace.h>
47#include <asm/txx9tmr.h> 43#include <asm/txx9tmr.h>
48#include <asm/reboot.h> 44#include <asm/reboot.h>
49#include <asm/jmr3927/jmr3927.h> 45#include <asm/jmr3927/jmr3927.h>
@@ -238,6 +234,8 @@ static void __init tx3927_setup(void)
238 tx3927_ccfgptr->ccfg &= ~TX3927_CCFG_BEOW; 234 tx3927_ccfgptr->ccfg &= ~TX3927_CCFG_BEOW;
239 /* Disable PCI snoop */ 235 /* Disable PCI snoop */
240 tx3927_ccfgptr->ccfg &= ~TX3927_CCFG_PSNP; 236 tx3927_ccfgptr->ccfg &= ~TX3927_CCFG_PSNP;
237 /* do reset on watchdog */
238 tx3927_ccfgptr->ccfg |= TX3927_CCFG_WR;
241 239
242#ifdef DO_WRITE_THROUGH 240#ifdef DO_WRITE_THROUGH
243 /* Enable PCI SNOOP - with write through only */ 241 /* Enable PCI SNOOP - with write through only */
@@ -388,3 +386,55 @@ static int __init jmr3927_rtc_init(void)
388 return IS_ERR(dev) ? PTR_ERR(dev) : 0; 386 return IS_ERR(dev) ? PTR_ERR(dev) : 0;
389} 387}
390device_initcall(jmr3927_rtc_init); 388device_initcall(jmr3927_rtc_init);
389
390/* Watchdog support */
391
392static int __init txx9_wdt_init(unsigned long base)
393{
394 struct resource res = {
395 .start = base,
396 .end = base + 0x100 - 1,
397 .flags = IORESOURCE_MEM,
398 };
399 struct platform_device *dev =
400 platform_device_register_simple("txx9wdt", -1, &res, 1);
401 return IS_ERR(dev) ? PTR_ERR(dev) : 0;
402}
403
404static int __init jmr3927_wdt_init(void)
405{
406 return txx9_wdt_init(TX3927_TMR_REG(2));
407}
408device_initcall(jmr3927_wdt_init);
409
410/* Minimum CLK support */
411
412struct clk *clk_get(struct device *dev, const char *id)
413{
414 if (!strcmp(id, "imbus_clk"))
415 return (struct clk *)JMR3927_IMCLK;
416 return ERR_PTR(-ENOENT);
417}
418EXPORT_SYMBOL(clk_get);
419
420int clk_enable(struct clk *clk)
421{
422 return 0;
423}
424EXPORT_SYMBOL(clk_enable);
425
426void clk_disable(struct clk *clk)
427{
428}
429EXPORT_SYMBOL(clk_disable);
430
431unsigned long clk_get_rate(struct clk *clk)
432{
433 return (unsigned long)clk;
434}
435EXPORT_SYMBOL(clk_get_rate);
436
437void clk_put(struct clk *clk)
438{
439}
440EXPORT_SYMBOL(clk_put);
diff --git a/arch/mips/kernel/cpu-bugs64.c b/arch/mips/kernel/cpu-bugs64.c
index af78456d4138..417bb3e336ac 100644
--- a/arch/mips/kernel/cpu-bugs64.c
+++ b/arch/mips/kernel/cpu-bugs64.c
@@ -18,6 +18,15 @@
18#include <asm/mipsregs.h> 18#include <asm/mipsregs.h>
19#include <asm/system.h> 19#include <asm/system.h>
20 20
21static char bug64hit[] __initdata =
22 "reliable operation impossible!\n%s";
23static char nowar[] __initdata =
24 "Please report to <linux-mips@linux-mips.org>.";
25static char r4kwar[] __initdata =
26 "Enable CPU_R4000_WORKAROUNDS to rectify.";
27static char daddiwar[] __initdata =
28 "Enable CPU_DADDI_WORKAROUNDS to rectify.";
29
21static inline void align_mod(const int align, const int mod) 30static inline void align_mod(const int align, const int mod)
22{ 31{
23 asm volatile( 32 asm volatile(
@@ -155,13 +164,7 @@ static inline void check_mult_sh(void)
155 } 164 }
156 165
157 printk("no.\n"); 166 printk("no.\n");
158 panic("Reliable operation impossible!\n" 167 panic(bug64hit, !R4000_WAR ? r4kwar : nowar);
159#ifndef CONFIG_CPU_R4000
160 "Configure for R4000 to enable the workaround."
161#else
162 "Please report to <linux-mips@linux-mips.org>."
163#endif
164 );
165} 168}
166 169
167static volatile int daddi_ov __initdata = 0; 170static volatile int daddi_ov __initdata = 0;
@@ -233,15 +236,11 @@ static inline void check_daddi(void)
233 } 236 }
234 237
235 printk("no.\n"); 238 printk("no.\n");
236 panic("Reliable operation impossible!\n" 239 panic(bug64hit, !DADDI_WAR ? daddiwar : nowar);
237#if !defined(CONFIG_CPU_R4000) && !defined(CONFIG_CPU_R4400)
238 "Configure for R4000 or R4400 to enable the workaround."
239#else
240 "Please report to <linux-mips@linux-mips.org>."
241#endif
242 );
243} 240}
244 241
242int daddiu_bug __initdata = -1;
243
245static inline void check_daddiu(void) 244static inline void check_daddiu(void)
246{ 245{
247 long v, w, tmp; 246 long v, w, tmp;
@@ -281,7 +280,9 @@ static inline void check_daddiu(void)
281 : "=&r" (v), "=&r" (w), "=&r" (tmp) 280 : "=&r" (v), "=&r" (w), "=&r" (tmp)
282 : "I" (0xffffffffffffdb9aUL), "I" (0x1234)); 281 : "I" (0xffffffffffffdb9aUL), "I" (0x1234));
283 282
284 if (v == w) { 283 daddiu_bug = v != w;
284
285 if (!daddiu_bug) {
285 printk("no.\n"); 286 printk("no.\n");
286 return; 287 return;
287 } 288 }
@@ -303,18 +304,16 @@ static inline void check_daddiu(void)
303 } 304 }
304 305
305 printk("no.\n"); 306 printk("no.\n");
306 panic("Reliable operation impossible!\n" 307 panic(bug64hit, !DADDI_WAR ? daddiwar : nowar);
307#if !defined(CONFIG_CPU_R4000) && !defined(CONFIG_CPU_R4400)
308 "Configure for R4000 or R4400 to enable the workaround."
309#else
310 "Please report to <linux-mips@linux-mips.org>."
311#endif
312 );
313} 308}
314 309
315void __init check_bugs64(void) 310void __init check_bugs64_early(void)
316{ 311{
317 check_mult_sh(); 312 check_mult_sh();
318 check_daddi();
319 check_daddiu(); 313 check_daddiu();
320} 314}
315
316void __init check_bugs64(void)
317{
318 check_daddi();
319}
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index 5c2794391bf5..5861a432a52f 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -188,6 +188,8 @@ static inline void check_wait(void)
188 case CPU_AU1500: 188 case CPU_AU1500:
189 case CPU_AU1550: 189 case CPU_AU1550:
190 case CPU_AU1200: 190 case CPU_AU1200:
191 case CPU_AU1210:
192 case CPU_AU1250:
191 if (allow_au1k_wait) 193 if (allow_au1k_wait)
192 cpu_wait = au1k_wait; 194 cpu_wait = au1k_wait;
193 break; 195 break;
@@ -733,6 +735,11 @@ static inline void cpu_probe_alchemy(struct cpuinfo_mips *c)
733 break; 735 break;
734 case 4: 736 case 4:
735 c->cputype = CPU_AU1200; 737 c->cputype = CPU_AU1200;
738 if (2 == (c->processor_id & 0xff))
739 c->cputype = CPU_AU1250;
740 break;
741 case 5:
742 c->cputype = CPU_AU1210;
736 break; 743 break;
737 default: 744 default:
738 panic("Unknown Au Core!"); 745 panic("Unknown Au Core!");
@@ -858,6 +865,8 @@ static __init const char *cpu_to_name(struct cpuinfo_mips *c)
858 case CPU_AU1100: name = "Au1100"; break; 865 case CPU_AU1100: name = "Au1100"; break;
859 case CPU_AU1550: name = "Au1550"; break; 866 case CPU_AU1550: name = "Au1550"; break;
860 case CPU_AU1200: name = "Au1200"; break; 867 case CPU_AU1200: name = "Au1200"; break;
868 case CPU_AU1210: name = "Au1210"; break;
869 case CPU_AU1250: name = "Au1250"; break;
861 case CPU_4KEC: name = "MIPS 4KEc"; break; 870 case CPU_4KEC: name = "MIPS 4KEc"; break;
862 case CPU_4KSC: name = "MIPS 4KSc"; break; 871 case CPU_4KSC: name = "MIPS 4KSc"; break;
863 case CPU_VR41XX: name = "NEC Vr41xx"; break; 872 case CPU_VR41XX: name = "NEC Vr41xx"; break;
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
index e76a76bf0b3d..c6ada98ee042 100644
--- a/arch/mips/kernel/genex.S
+++ b/arch/mips/kernel/genex.S
@@ -6,7 +6,7 @@
6 * Copyright (C) 1994 - 2000, 2001, 2003 Ralf Baechle 6 * Copyright (C) 1994 - 2000, 2001, 2003 Ralf Baechle
7 * Copyright (C) 1999, 2000 Silicon Graphics, Inc. 7 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
8 * Copyright (C) 2001 MIPS Technologies, Inc. 8 * Copyright (C) 2001 MIPS Technologies, Inc.
9 * Copyright (C) 2002 Maciej W. Rozycki 9 * Copyright (C) 2002, 2007 Maciej W. Rozycki
10 */ 10 */
11#include <linux/init.h> 11#include <linux/init.h>
12 12
@@ -471,7 +471,13 @@ NESTED(nmi_handler, PT_SIZE, sp)
471 jr k0 471 jr k0
472 rfe 472 rfe
473#else 473#else
474#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
474 LONG_ADDIU k0, 4 /* stall on $k0 */ 475 LONG_ADDIU k0, 4 /* stall on $k0 */
476#else
477 .set at=v1
478 LONG_ADDIU k0, 4
479 .set noat
480#endif
475 MTC0 k0, CP0_EPC 481 MTC0 k0, CP0_EPC
476 /* I hope three instructions between MTC0 and ERET are enough... */ 482 /* I hope three instructions between MTC0 and ERET are enough... */
477 ori k1, _THREAD_MASK 483 ori k1, _THREAD_MASK
diff --git a/arch/mips/kernel/i8253.c b/arch/mips/kernel/i8253.c
index c2d497ceffdd..fc4aa07b6d35 100644
--- a/arch/mips/kernel/i8253.c
+++ b/arch/mips/kernel/i8253.c
@@ -24,9 +24,7 @@ DEFINE_SPINLOCK(i8253_lock);
24static void init_pit_timer(enum clock_event_mode mode, 24static void init_pit_timer(enum clock_event_mode mode,
25 struct clock_event_device *evt) 25 struct clock_event_device *evt)
26{ 26{
27 unsigned long flags; 27 spin_lock(&i8253_lock);
28
29 spin_lock_irqsave(&i8253_lock, flags);
30 28
31 switch(mode) { 29 switch(mode) {
32 case CLOCK_EVT_MODE_PERIODIC: 30 case CLOCK_EVT_MODE_PERIODIC:
@@ -55,7 +53,7 @@ static void init_pit_timer(enum clock_event_mode mode,
55 /* Nothing to do here */ 53 /* Nothing to do here */
56 break; 54 break;
57 } 55 }
58 spin_unlock_irqrestore(&i8253_lock, flags); 56 spin_unlock(&i8253_lock);
59} 57}
60 58
61/* 59/*
@@ -65,12 +63,10 @@ static void init_pit_timer(enum clock_event_mode mode,
65 */ 63 */
66static int pit_next_event(unsigned long delta, struct clock_event_device *evt) 64static int pit_next_event(unsigned long delta, struct clock_event_device *evt)
67{ 65{
68 unsigned long flags; 66 spin_lock(&i8253_lock);
69
70 spin_lock_irqsave(&i8253_lock, flags);
71 outb_p(delta & 0xff , PIT_CH0); /* LSB */ 67 outb_p(delta & 0xff , PIT_CH0); /* LSB */
72 outb(delta >> 8 , PIT_CH0); /* MSB */ 68 outb(delta >> 8 , PIT_CH0); /* MSB */
73 spin_unlock_irqrestore(&i8253_lock, flags); 69 spin_unlock(&i8253_lock);
74 70
75 return 0; 71 return 0;
76} 72}
diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c
index 471013577108..197d7977de35 100644
--- a/arch/mips/kernel/i8259.c
+++ b/arch/mips/kernel/i8259.c
@@ -238,7 +238,7 @@ static int i8259A_shutdown(struct sys_device *dev)
238} 238}
239 239
240static struct sysdev_class i8259_sysdev_class = { 240static struct sysdev_class i8259_sysdev_class = {
241 set_kset_name("i8259"), 241 .name = "i8259",
242 .resume = i8259A_resume, 242 .resume = i8259A_resume,
243 .shutdown = i8259A_shutdown, 243 .shutdown = i8259A_shutdown,
244}; 244};
diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c
index d2c2e00e5864..f6704ab16306 100644
--- a/arch/mips/kernel/kspd.c
+++ b/arch/mips/kernel/kspd.c
@@ -161,8 +161,7 @@ static unsigned int translate_open_flags(int flags)
161 int i; 161 int i;
162 unsigned int ret = 0; 162 unsigned int ret = 0;
163 163
164 for (i = 0; i < (sizeof(open_flags_table) / sizeof(struct apsp_table)); 164 for (i = 0; i < ARRAY_SIZE(open_flags_table); i++) {
165 i++) {
166 if( (flags & open_flags_table[i].sp) ) { 165 if( (flags & open_flags_table[i].sp) ) {
167 ret |= open_flags_table[i].ap; 166 ret |= open_flags_table[i].ap;
168 } 167 }
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index 2b8ec1102e86..65af3cc90abb 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -174,36 +174,16 @@ struct rlimit32 {
174 int rlim_max; 174 int rlim_max;
175}; 175};
176 176
177#ifdef __MIPSEB__ 177asmlinkage long sys32_truncate64(const char __user * path,
178asmlinkage long sys32_truncate64(const char __user * path, unsigned long __dummy, 178 unsigned long __dummy, int a2, int a3)
179 int length_hi, int length_lo)
180#endif
181#ifdef __MIPSEL__
182asmlinkage long sys32_truncate64(const char __user * path, unsigned long __dummy,
183 int length_lo, int length_hi)
184#endif
185{ 179{
186 loff_t length; 180 return sys_truncate(path, merge_64(a2, a3));
187
188 length = ((unsigned long) length_hi << 32) | (unsigned int) length_lo;
189
190 return sys_truncate(path, length);
191} 181}
192 182
193#ifdef __MIPSEB__
194asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy, 183asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy,
195 int length_hi, int length_lo) 184 int a2, int a3)
196#endif
197#ifdef __MIPSEL__
198asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy,
199 int length_lo, int length_hi)
200#endif
201{ 185{
202 loff_t length; 186 return sys_ftruncate(fd, merge_64(a2, a3));
203
204 length = ((unsigned long) length_hi << 32) | (unsigned int) length_lo;
205
206 return sys_ftruncate(fd, length);
207} 187}
208 188
209static inline long 189static inline long
diff --git a/arch/mips/kernel/mips-mt-fpaff.c b/arch/mips/kernel/mips-mt-fpaff.c
index 892665bb12b1..bb4f00c0cbe9 100644
--- a/arch/mips/kernel/mips-mt-fpaff.c
+++ b/arch/mips/kernel/mips-mt-fpaff.c
@@ -58,13 +58,13 @@ asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len,
58 if (copy_from_user(&new_mask, user_mask_ptr, sizeof(new_mask))) 58 if (copy_from_user(&new_mask, user_mask_ptr, sizeof(new_mask)))
59 return -EFAULT; 59 return -EFAULT;
60 60
61 lock_cpu_hotplug(); 61 get_online_cpus();
62 read_lock(&tasklist_lock); 62 read_lock(&tasklist_lock);
63 63
64 p = find_process_by_pid(pid); 64 p = find_process_by_pid(pid);
65 if (!p) { 65 if (!p) {
66 read_unlock(&tasklist_lock); 66 read_unlock(&tasklist_lock);
67 unlock_cpu_hotplug(); 67 put_online_cpus();
68 return -ESRCH; 68 return -ESRCH;
69 } 69 }
70 70
@@ -106,7 +106,7 @@ asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len,
106 106
107out_unlock: 107out_unlock:
108 put_task_struct(p); 108 put_task_struct(p);
109 unlock_cpu_hotplug(); 109 put_online_cpus();
110 return retval; 110 return retval;
111} 111}
112 112
@@ -125,7 +125,7 @@ asmlinkage long mipsmt_sys_sched_getaffinity(pid_t pid, unsigned int len,
125 if (len < real_len) 125 if (len < real_len)
126 return -EINVAL; 126 return -EINVAL;
127 127
128 lock_cpu_hotplug(); 128 get_online_cpus();
129 read_lock(&tasklist_lock); 129 read_lock(&tasklist_lock);
130 130
131 retval = -ESRCH; 131 retval = -ESRCH;
@@ -140,7 +140,7 @@ asmlinkage long mipsmt_sys_sched_getaffinity(pid_t pid, unsigned int len,
140 140
141out_unlock: 141out_unlock:
142 read_unlock(&tasklist_lock); 142 read_unlock(&tasklist_lock);
143 unlock_cpu_hotplug(); 143 put_online_cpus();
144 if (retval) 144 if (retval)
145 return retval; 145 return retval;
146 if (copy_to_user(user_mask_ptr, &mask, real_len)) 146 if (copy_to_user(user_mask_ptr, &mask, real_len))
diff --git a/arch/mips/kernel/mips-mt.c b/arch/mips/kernel/mips-mt.c
index 3d6b1ec1f328..640fb0cc6e39 100644
--- a/arch/mips/kernel/mips-mt.c
+++ b/arch/mips/kernel/mips-mt.c
@@ -17,7 +17,6 @@
17#include <asm/system.h> 17#include <asm/system.h>
18#include <asm/hardirq.h> 18#include <asm/hardirq.h>
19#include <asm/mmu_context.h> 19#include <asm/mmu_context.h>
20#include <asm/smp.h>
21#include <asm/mipsmtregs.h> 20#include <asm/mipsmtregs.h>
22#include <asm/r4kcache.h> 21#include <asm/r4kcache.h>
23#include <asm/cacheflush.h> 22#include <asm/cacheflush.h>
diff --git a/arch/mips/kernel/pcspeaker.c b/arch/mips/kernel/pcspeaker.c
deleted file mode 100644
index 475df6904219..000000000000
--- a/arch/mips/kernel/pcspeaker.c
+++ /dev/null
@@ -1,28 +0,0 @@
1/*
2 * Copyright (C) 2006 IBM Corporation
3 *
4 * Implements device information for i8253 timer chip
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation
9 */
10
11#include <linux/platform_device.h>
12
13static __init int add_pcspkr(void)
14{
15 struct platform_device *pd;
16 int ret;
17
18 pd = platform_device_alloc("pcspkr", -1);
19 if (!pd)
20 return -ENOMEM;
21
22 ret = platform_device_add(pd);
23 if (ret)
24 platform_device_put(pd);
25
26 return ret;
27}
28device_initcall(add_pcspkr);
diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c
index 6e6e947cce1e..36f065398243 100644
--- a/arch/mips/kernel/proc.c
+++ b/arch/mips/kernel/proc.c
@@ -62,6 +62,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
62 ); 62 );
63 seq_printf(m, "shadow register sets\t: %d\n", 63 seq_printf(m, "shadow register sets\t: %d\n",
64 cpu_data[n].srsets); 64 cpu_data[n].srsets);
65 seq_printf(m, "core\t\t\t: %d\n", cpu_data[n].core);
65 66
66 sprintf(fmt, "VCE%%c exceptions\t\t: %s\n", 67 sprintf(fmt, "VCE%%c exceptions\t\t: %s\n",
67 cpu_has_vce ? "%u" : "not available"); 68 cpu_has_vce ? "%u" : "not available");
@@ -89,7 +90,7 @@ static void c_stop(struct seq_file *m, void *v)
89{ 90{
90} 91}
91 92
92struct seq_operations cpuinfo_op = { 93const struct seq_operations cpuinfo_op = {
93 .start = c_start, 94 .start = c_start,
94 .next = c_next, 95 .next = c_next,
95 .stop = c_stop, 96 .stop = c_stop,
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c
index 1ba00c15505b..0233798f7155 100644
--- a/arch/mips/kernel/rtlx.c
+++ b/arch/mips/kernel/rtlx.c
@@ -40,7 +40,6 @@
40#include <asm/atomic.h> 40#include <asm/atomic.h>
41#include <asm/cpu.h> 41#include <asm/cpu.h>
42#include <asm/processor.h> 42#include <asm/processor.h>
43#include <asm/mips_mt.h>
44#include <asm/system.h> 43#include <asm/system.h>
45#include <asm/vpe.h> 44#include <asm/vpe.h>
46#include <asm/rtlx.h> 45#include <asm/rtlx.h>
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index f8a535afce39..269c252d956f 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -8,7 +8,7 @@
8 * Copyright (C) 1994, 95, 96, 97, 98, 99, 2000, 01, 02, 03 Ralf Baechle 8 * Copyright (C) 1994, 95, 96, 97, 98, 99, 2000, 01, 02, 03 Ralf Baechle
9 * Copyright (C) 1996 Stoned Elipot 9 * Copyright (C) 1996 Stoned Elipot
10 * Copyright (C) 1999 Silicon Graphics, Inc. 10 * Copyright (C) 1999 Silicon Graphics, Inc.
11 * Copyright (C) 2000 2001, 2002 Maciej W. Rozycki 11 * Copyright (C) 2000, 2001, 2002, 2007 Maciej W. Rozycki
12 */ 12 */
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/ioport.h> 14#include <linux/ioport.h>
@@ -24,10 +24,12 @@
24 24
25#include <asm/addrspace.h> 25#include <asm/addrspace.h>
26#include <asm/bootinfo.h> 26#include <asm/bootinfo.h>
27#include <asm/bugs.h>
27#include <asm/cache.h> 28#include <asm/cache.h>
28#include <asm/cpu.h> 29#include <asm/cpu.h>
29#include <asm/sections.h> 30#include <asm/sections.h>
30#include <asm/setup.h> 31#include <asm/setup.h>
32#include <asm/smp-ops.h>
31#include <asm/system.h> 33#include <asm/system.h>
32 34
33struct cpuinfo_mips cpu_data[NR_CPUS] __read_mostly; 35struct cpuinfo_mips cpu_data[NR_CPUS] __read_mostly;
@@ -561,6 +563,7 @@ void __init setup_arch(char **cmdline_p)
561 } 563 }
562#endif 564#endif
563 cpu_report(); 565 cpu_report();
566 check_bugs_early();
564 567
565#if defined(CONFIG_VT) 568#if defined(CONFIG_VT)
566#if defined(CONFIG_VGA_CONSOLE) 569#if defined(CONFIG_VGA_CONSOLE)
@@ -573,9 +576,7 @@ void __init setup_arch(char **cmdline_p)
573 arch_mem_init(cmdline_p); 576 arch_mem_init(cmdline_p);
574 577
575 resource_init(); 578 resource_init();
576#ifdef CONFIG_SMP
577 plat_smp_setup(); 579 plat_smp_setup();
578#endif
579} 580}
580 581
581static int __init fpu_disable(char *s) 582static int __init fpu_disable(char *s)
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c
index 94e210cc6cb6..89e6f6aa5166 100644
--- a/arch/mips/kernel/smp-mt.c
+++ b/arch/mips/kernel/smp-mt.c
@@ -22,6 +22,7 @@
22#include <linux/cpumask.h> 22#include <linux/cpumask.h>
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/compiler.h> 24#include <linux/compiler.h>
25#include <linux/smp.h>
25 26
26#include <asm/atomic.h> 27#include <asm/atomic.h>
27#include <asm/cacheflush.h> 28#include <asm/cacheflush.h>
@@ -30,7 +31,6 @@
30#include <asm/system.h> 31#include <asm/system.h>
31#include <asm/hardirq.h> 32#include <asm/hardirq.h>
32#include <asm/mmu_context.h> 33#include <asm/mmu_context.h>
33#include <asm/smp.h>
34#include <asm/time.h> 34#include <asm/time.h>
35#include <asm/mipsregs.h> 35#include <asm/mipsregs.h>
36#include <asm/mipsmtregs.h> 36#include <asm/mipsmtregs.h>
@@ -215,68 +215,67 @@ static void __init smp_tc_init(unsigned int tc, unsigned int mvpconf0)
215 write_tc_c0_tchalt(TCHALT_H); 215 write_tc_c0_tchalt(TCHALT_H);
216} 216}
217 217
218/* 218static void vsmp_send_ipi_single(int cpu, unsigned int action)
219 * Common setup before any secondaries are started
220 * Make sure all CPU's are in a sensible state before we boot any of the
221 * secondarys
222 */
223void __init plat_smp_setup(void)
224{ 219{
225 unsigned int mvpconf0, ntc, tc, ncpu = 0; 220 int i;
226 221 unsigned long flags;
227#ifdef CONFIG_MIPS_MT_FPAFF 222 int vpflags;
228 /* If we have an FPU, enroll ourselves in the FPU-full mask */
229 if (cpu_has_fpu)
230 cpu_set(0, mt_fpu_cpumask);
231#endif /* CONFIG_MIPS_MT_FPAFF */
232 if (!cpu_has_mipsmt)
233 return;
234
235 /* disable MT so we can configure */
236 dvpe();
237 dmt();
238 223
239 /* Put MVPE's into 'configuration state' */ 224 local_irq_save(flags);
240 set_c0_mvpcontrol(MVPCONTROL_VPC);
241 225
242 mvpconf0 = read_c0_mvpconf0(); 226 vpflags = dvpe(); /* cant access the other CPU's registers whilst MVPE enabled */
243 ntc = (mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT;
244 227
245 /* we'll always have more TC's than VPE's, so loop setting everything 228 switch (action) {
246 to a sensible state */ 229 case SMP_CALL_FUNCTION:
247 for (tc = 0; tc <= ntc; tc++) { 230 i = C_SW1;
248 settc(tc); 231 break;
249 232
250 smp_tc_init(tc, mvpconf0); 233 case SMP_RESCHEDULE_YOURSELF:
251 ncpu = smp_vpe_init(tc, mvpconf0, ncpu); 234 default:
235 i = C_SW0;
236 break;
252 } 237 }
253 238
254 /* Release config state */ 239 /* 1:1 mapping of vpe and tc... */
255 clear_c0_mvpcontrol(MVPCONTROL_VPC); 240 settc(cpu);
241 write_vpe_c0_cause(read_vpe_c0_cause() | i);
242 evpe(vpflags);
256 243
257 /* We'll wait until starting the secondaries before starting MVPE */ 244 local_irq_restore(flags);
245}
258 246
259 printk(KERN_INFO "Detected %i available secondary CPU(s)\n", ncpu); 247static void vsmp_send_ipi_mask(cpumask_t mask, unsigned int action)
248{
249 unsigned int i;
250
251 for_each_cpu_mask(i, mask)
252 vsmp_send_ipi_single(i, action);
260} 253}
261 254
262void __init plat_prepare_cpus(unsigned int max_cpus) 255static void __cpuinit vsmp_init_secondary(void)
263{ 256{
264 mips_mt_set_cpuoptions(); 257 /* Enable per-cpu interrupts */
265 258
266 /* set up ipi interrupts */ 259 /* This is Malta specific: IPI,performance and timer inetrrupts */
267 if (cpu_has_vint) { 260 write_c0_status((read_c0_status() & ~ST0_IM ) |
268 set_vi_handler(MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch); 261 (STATUSF_IP0 | STATUSF_IP1 | STATUSF_IP6 | STATUSF_IP7));
269 set_vi_handler(MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch); 262}
270 }
271 263
272 cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ; 264static void __cpuinit vsmp_smp_finish(void)
273 cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ; 265{
266 write_c0_compare(read_c0_count() + (8* mips_hpt_frequency/HZ));
274 267
275 setup_irq(cpu_ipi_resched_irq, &irq_resched); 268#ifdef CONFIG_MIPS_MT_FPAFF
276 setup_irq(cpu_ipi_call_irq, &irq_call); 269 /* If we have an FPU, enroll ourselves in the FPU-full mask */
270 if (cpu_has_fpu)
271 cpu_set(smp_processor_id(), mt_fpu_cpumask);
272#endif /* CONFIG_MIPS_MT_FPAFF */
277 273
278 set_irq_handler(cpu_ipi_resched_irq, handle_percpu_irq); 274 local_irq_enable();
279 set_irq_handler(cpu_ipi_call_irq, handle_percpu_irq); 275}
276
277static void vsmp_cpus_done(void)
278{
280} 279}
281 280
282/* 281/*
@@ -287,7 +286,7 @@ void __init plat_prepare_cpus(unsigned int max_cpus)
287 * (unsigned long)idle->thread_info the gp 286 * (unsigned long)idle->thread_info the gp
288 * assumes a 1:1 mapping of TC => VPE 287 * assumes a 1:1 mapping of TC => VPE
289 */ 288 */
290void __cpuinit prom_boot_secondary(int cpu, struct task_struct *idle) 289static void __cpuinit vsmp_boot_secondary(int cpu, struct task_struct *idle)
291{ 290{
292 struct thread_info *gp = task_thread_info(idle); 291 struct thread_info *gp = task_thread_info(idle);
293 dvpe(); 292 dvpe();
@@ -321,57 +320,81 @@ void __cpuinit prom_boot_secondary(int cpu, struct task_struct *idle)
321 evpe(EVPE_ENABLE); 320 evpe(EVPE_ENABLE);
322} 321}
323 322
324void __cpuinit prom_init_secondary(void) 323/*
325{ 324 * Common setup before any secondaries are started
326 /* Enable per-cpu interrupts */ 325 * Make sure all CPU's are in a sensible state before we boot any of the
327 326 * secondarys
328 /* This is Malta specific: IPI,performance and timer inetrrupts */ 327 */
329 write_c0_status((read_c0_status() & ~ST0_IM ) | 328static void __init vsmp_smp_setup(void)
330 (STATUSF_IP0 | STATUSF_IP1 | STATUSF_IP6 | STATUSF_IP7));
331}
332
333void __cpuinit prom_smp_finish(void)
334{ 329{
335 write_c0_compare(read_c0_count() + (8* mips_hpt_frequency/HZ)); 330 unsigned int mvpconf0, ntc, tc, ncpu = 0;
331 unsigned int nvpe;
336 332
337#ifdef CONFIG_MIPS_MT_FPAFF 333#ifdef CONFIG_MIPS_MT_FPAFF
338 /* If we have an FPU, enroll ourselves in the FPU-full mask */ 334 /* If we have an FPU, enroll ourselves in the FPU-full mask */
339 if (cpu_has_fpu) 335 if (cpu_has_fpu)
340 cpu_set(smp_processor_id(), mt_fpu_cpumask); 336 cpu_set(0, mt_fpu_cpumask);
341#endif /* CONFIG_MIPS_MT_FPAFF */ 337#endif /* CONFIG_MIPS_MT_FPAFF */
338 if (!cpu_has_mipsmt)
339 return;
342 340
343 local_irq_enable(); 341 /* disable MT so we can configure */
344} 342 dvpe();
343 dmt();
345 344
346void prom_cpus_done(void) 345 /* Put MVPE's into 'configuration state' */
347{ 346 set_c0_mvpcontrol(MVPCONTROL_VPC);
348}
349 347
350void core_send_ipi(int cpu, unsigned int action) 348 mvpconf0 = read_c0_mvpconf0();
351{ 349 ntc = (mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT;
352 int i;
353 unsigned long flags;
354 int vpflags;
355 350
356 local_irq_save(flags); 351 nvpe = ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1;
352 smp_num_siblings = nvpe;
357 353
358 vpflags = dvpe(); /* cant access the other CPU's registers whilst MVPE enabled */ 354 /* we'll always have more TC's than VPE's, so loop setting everything
355 to a sensible state */
356 for (tc = 0; tc <= ntc; tc++) {
357 settc(tc);
359 358
360 switch (action) { 359 smp_tc_init(tc, mvpconf0);
361 case SMP_CALL_FUNCTION: 360 ncpu = smp_vpe_init(tc, mvpconf0, ncpu);
362 i = C_SW1; 361 }
363 break;
364 362
365 case SMP_RESCHEDULE_YOURSELF: 363 /* Release config state */
366 default: 364 clear_c0_mvpcontrol(MVPCONTROL_VPC);
367 i = C_SW0; 365
368 break; 366 /* We'll wait until starting the secondaries before starting MVPE */
367
368 printk(KERN_INFO "Detected %i available secondary CPU(s)\n", ncpu);
369}
370
371static void __init vsmp_prepare_cpus(unsigned int max_cpus)
372{
373 mips_mt_set_cpuoptions();
374
375 /* set up ipi interrupts */
376 if (cpu_has_vint) {
377 set_vi_handler(MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch);
378 set_vi_handler(MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch);
369 } 379 }
370 380
371 /* 1:1 mapping of vpe and tc... */ 381 cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ;
372 settc(cpu); 382 cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ;
373 write_vpe_c0_cause(read_vpe_c0_cause() | i);
374 evpe(vpflags);
375 383
376 local_irq_restore(flags); 384 setup_irq(cpu_ipi_resched_irq, &irq_resched);
385 setup_irq(cpu_ipi_call_irq, &irq_call);
386
387 set_irq_handler(cpu_ipi_resched_irq, handle_percpu_irq);
388 set_irq_handler(cpu_ipi_call_irq, handle_percpu_irq);
377} 389}
390
391struct plat_smp_ops vsmp_smp_ops = {
392 .send_ipi_single = vsmp_send_ipi_single,
393 .send_ipi_mask = vsmp_send_ipi_mask,
394 .init_secondary = vsmp_init_secondary,
395 .smp_finish = vsmp_smp_finish,
396 .cpus_done = vsmp_cpus_done,
397 .boot_secondary = vsmp_boot_secondary,
398 .smp_setup = vsmp_smp_setup,
399 .prepare_cpus = vsmp_prepare_cpus,
400};
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 63989e9df4f9..1e5dfc28294a 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -37,7 +37,6 @@
37#include <asm/processor.h> 37#include <asm/processor.h>
38#include <asm/system.h> 38#include <asm/system.h>
39#include <asm/mmu_context.h> 39#include <asm/mmu_context.h>
40#include <asm/smp.h>
41#include <asm/time.h> 40#include <asm/time.h>
42 41
43#ifdef CONFIG_MIPS_MT_SMTC 42#ifdef CONFIG_MIPS_MT_SMTC
@@ -56,6 +55,44 @@ EXPORT_SYMBOL(cpu_online_map);
56extern void __init calibrate_delay(void); 55extern void __init calibrate_delay(void);
57extern void cpu_idle(void); 56extern void cpu_idle(void);
58 57
58/* Number of TCs (or siblings in Intel speak) per CPU core */
59int smp_num_siblings = 1;
60EXPORT_SYMBOL(smp_num_siblings);
61
62/* representing the TCs (or siblings in Intel speak) of each logical CPU */
63cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
64EXPORT_SYMBOL(cpu_sibling_map);
65
66/* representing cpus for which sibling maps can be computed */
67static cpumask_t cpu_sibling_setup_map;
68
69static inline void set_cpu_sibling_map(int cpu)
70{
71 int i;
72
73 cpu_set(cpu, cpu_sibling_setup_map);
74
75 if (smp_num_siblings > 1) {
76 for_each_cpu_mask(i, cpu_sibling_setup_map) {
77 if (cpu_data[cpu].core == cpu_data[i].core) {
78 cpu_set(i, cpu_sibling_map[cpu]);
79 cpu_set(cpu, cpu_sibling_map[i]);
80 }
81 }
82 } else
83 cpu_set(cpu, cpu_sibling_map[cpu]);
84}
85
86struct plat_smp_ops *mp_ops;
87
88__cpuinit void register_smp_ops(struct plat_smp_ops *ops)
89{
90 if (ops)
91 printk(KERN_WARNING "Overriding previous set SMP ops\n");
92
93 mp_ops = ops;
94}
95
59/* 96/*
60 * First C code run on the secondary CPUs after being started up by 97 * First C code run on the secondary CPUs after being started up by
61 * the master. 98 * the master.
@@ -72,7 +109,7 @@ asmlinkage __cpuinit void start_secondary(void)
72 cpu_report(); 109 cpu_report();
73 per_cpu_trap_init(); 110 per_cpu_trap_init();
74 mips_clockevent_init(); 111 mips_clockevent_init();
75 prom_init_secondary(); 112 mp_ops->init_secondary();
76 113
77 /* 114 /*
78 * XXX parity protection should be folded in here when it's converted 115 * XXX parity protection should be folded in here when it's converted
@@ -84,7 +121,8 @@ asmlinkage __cpuinit void start_secondary(void)
84 cpu = smp_processor_id(); 121 cpu = smp_processor_id();
85 cpu_data[cpu].udelay_val = loops_per_jiffy; 122 cpu_data[cpu].udelay_val = loops_per_jiffy;
86 123
87 prom_smp_finish(); 124 mp_ops->smp_finish();
125 set_cpu_sibling_map(cpu);
88 126
89 cpu_set(cpu, cpu_callin_map); 127 cpu_set(cpu, cpu_callin_map);
90 128
@@ -155,7 +193,7 @@ int smp_call_function_mask(cpumask_t mask, void (*func) (void *info),
155 smp_mb(); 193 smp_mb();
156 194
157 /* Send a message to all other CPUs and wait for them to respond */ 195 /* Send a message to all other CPUs and wait for them to respond */
158 core_send_ipi_mask(mask, SMP_CALL_FUNCTION); 196 mp_ops->send_ipi_mask(mask, SMP_CALL_FUNCTION);
159 197
160 /* Wait for response */ 198 /* Wait for response */
161 /* FIXME: lock-up detection, backtrace on lock-up */ 199 /* FIXME: lock-up detection, backtrace on lock-up */
@@ -249,7 +287,7 @@ void smp_send_stop(void)
249 287
250void __init smp_cpus_done(unsigned int max_cpus) 288void __init smp_cpus_done(unsigned int max_cpus)
251{ 289{
252 prom_cpus_done(); 290 mp_ops->cpus_done();
253} 291}
254 292
255/* called from main before smp_init() */ 293/* called from main before smp_init() */
@@ -257,7 +295,8 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
257{ 295{
258 init_new_context(current, &init_mm); 296 init_new_context(current, &init_mm);
259 current_thread_info()->cpu = 0; 297 current_thread_info()->cpu = 0;
260 plat_prepare_cpus(max_cpus); 298 mp_ops->prepare_cpus(max_cpus);
299 set_cpu_sibling_map(0);
261#ifndef CONFIG_HOTPLUG_CPU 300#ifndef CONFIG_HOTPLUG_CPU
262 cpu_present_map = cpu_possible_map; 301 cpu_present_map = cpu_possible_map;
263#endif 302#endif
@@ -295,7 +334,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
295 if (IS_ERR(idle)) 334 if (IS_ERR(idle))
296 panic(KERN_ERR "Fork failed for CPU %d", cpu); 335 panic(KERN_ERR "Fork failed for CPU %d", cpu);
297 336
298 prom_boot_secondary(cpu, idle); 337 mp_ops->boot_secondary(cpu, idle);
299 338
300 /* 339 /*
301 * Trust is futile. We should really have timeouts ... 340 * Trust is futile. We should really have timeouts ...
diff --git a/arch/mips/kernel/smtc-proc.c b/arch/mips/kernel/smtc-proc.c
index 6f3709996172..fe256559c997 100644
--- a/arch/mips/kernel/smtc-proc.c
+++ b/arch/mips/kernel/smtc-proc.c
@@ -14,7 +14,6 @@
14#include <asm/system.h> 14#include <asm/system.h>
15#include <asm/hardirq.h> 15#include <asm/hardirq.h>
16#include <asm/mmu_context.h> 16#include <asm/mmu_context.h>
17#include <asm/smp.h>
18#include <asm/mipsregs.h> 17#include <asm/mipsregs.h>
19#include <asm/cacheflush.h> 18#include <asm/cacheflush.h>
20#include <linux/proc_fs.h> 19#include <linux/proc_fs.h>
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c
index 9c92d42996cb..85f700e58131 100644
--- a/arch/mips/kernel/smtc.c
+++ b/arch/mips/kernel/smtc.c
@@ -16,7 +16,6 @@
16#include <asm/hazards.h> 16#include <asm/hazards.h>
17#include <asm/irq.h> 17#include <asm/irq.h>
18#include <asm/mmu_context.h> 18#include <asm/mmu_context.h>
19#include <asm/smp.h>
20#include <asm/mipsregs.h> 19#include <asm/mipsregs.h>
21#include <asm/cacheflush.h> 20#include <asm/cacheflush.h>
22#include <asm/time.h> 21#include <asm/time.h>
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
index 2995be1ab3ca..9f85d4cecc5b 100644
--- a/arch/mips/kernel/time.c
+++ b/arch/mips/kernel/time.c
@@ -50,8 +50,6 @@ int update_persistent_clock(struct timespec now)
50 return rtc_mips_set_mmss(now.tv_sec); 50 return rtc_mips_set_mmss(now.tv_sec);
51} 51}
52 52
53int (*mips_timer_state)(void);
54
55int null_perf_irq(void) 53int null_perf_irq(void)
56{ 54{
57 return 0; 55 return 0;
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index 5fc2398bdb76..b5470ceb418b 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -114,11 +114,11 @@ SECTIONS
114 __init_begin = .; 114 __init_begin = .;
115 .init.text : { 115 .init.text : {
116 _sinittext = .; 116 _sinittext = .;
117 *(.init.text) 117 INIT_TEXT
118 _einittext = .; 118 _einittext = .;
119 } 119 }
120 .init.data : { 120 .init.data : {
121 *(.init.data) 121 INIT_DATA
122 } 122 }
123 . = ALIGN(16); 123 . = ALIGN(16);
124 .init.setup : { 124 .init.setup : {
@@ -144,10 +144,10 @@ SECTIONS
144 * references from .rodata 144 * references from .rodata
145 */ 145 */
146 .exit.text : { 146 .exit.text : {
147 *(.exit.text) 147 EXIT_TEXT
148 } 148 }
149 .exit.data : { 149 .exit.data : {
150 *(.exit.data) 150 EXIT_DATA
151 } 151 }
152#if defined(CONFIG_BLK_DEV_INITRD) 152#if defined(CONFIG_BLK_DEV_INITRD)
153 . = ALIGN(_PAGE_SIZE); 153 . = ALIGN(_PAGE_SIZE);
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
index c06eb812a95e..eed2dc4273e0 100644
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -53,7 +53,6 @@
53#include <asm/system.h> 53#include <asm/system.h>
54#include <asm/vpe.h> 54#include <asm/vpe.h>
55#include <asm/kspd.h> 55#include <asm/kspd.h>
56#include <asm/mips_mt.h>
57 56
58typedef void *vpe_handle; 57typedef void *vpe_handle;
59 58
diff --git a/arch/mips/lasat/picvue.c b/arch/mips/lasat/picvue.c
index 6471d0663fd8..d3d04c392e25 100644
--- a/arch/mips/lasat/picvue.c
+++ b/arch/mips/lasat/picvue.c
@@ -22,8 +22,6 @@
22 22
23struct pvc_defs *picvue; 23struct pvc_defs *picvue;
24 24
25DECLARE_MUTEX(pvc_sem);
26
27static void pvc_reg_write(u32 val) 25static void pvc_reg_write(u32 val)
28{ 26{
29 *picvue->reg = val; 27 *picvue->reg = val;
diff --git a/arch/mips/lasat/picvue.h b/arch/mips/lasat/picvue.h
index 2a96bf971897..91df55371127 100644
--- a/arch/mips/lasat/picvue.h
+++ b/arch/mips/lasat/picvue.h
@@ -4,8 +4,6 @@
4 * Brian Murphy <brian.murphy@eicon.com> 4 * Brian Murphy <brian.murphy@eicon.com>
5 * 5 *
6 */ 6 */
7#include <asm/semaphore.h>
8
9struct pvc_defs { 7struct pvc_defs {
10 volatile u32 *reg; 8 volatile u32 *reg;
11 u32 data_shift; 9 u32 data_shift;
@@ -45,4 +43,3 @@ void pvc_move(u8 cmd);
45void pvc_clear(void); 43void pvc_clear(void);
46void pvc_home(void); 44void pvc_home(void);
47 45
48extern struct semaphore pvc_sem;
diff --git a/arch/mips/lasat/picvue_proc.c b/arch/mips/lasat/picvue_proc.c
index 9947c1525822..0bb6037afba3 100644
--- a/arch/mips/lasat/picvue_proc.c
+++ b/arch/mips/lasat/picvue_proc.c
@@ -13,9 +13,11 @@
13#include <linux/interrupt.h> 13#include <linux/interrupt.h>
14 14
15#include <linux/timer.h> 15#include <linux/timer.h>
16#include <linux/mutex.h>
16 17
17#include "picvue.h" 18#include "picvue.h"
18 19
20static DEFINE_MUTEX(pvc_mutex);
19static char pvc_lines[PVC_NLINES][PVC_LINELEN+1]; 21static char pvc_lines[PVC_NLINES][PVC_LINELEN+1];
20static int pvc_linedata[PVC_NLINES]; 22static int pvc_linedata[PVC_NLINES];
21static struct proc_dir_entry *pvc_display_dir; 23static struct proc_dir_entry *pvc_display_dir;
@@ -48,9 +50,9 @@ static int pvc_proc_read_line(char *page, char **start,
48 return 0; 50 return 0;
49 } 51 }
50 52
51 down(&pvc_sem); 53 mutex_lock(&pvc_mutex);
52 page += sprintf(page, "%s\n", pvc_lines[lineno]); 54 page += sprintf(page, "%s\n", pvc_lines[lineno]);
53 up(&pvc_sem); 55 mutex_unlock(&pvc_mutex);
54 56
55 return page - origpage; 57 return page - origpage;
56} 58}
@@ -73,10 +75,10 @@ static int pvc_proc_write_line(struct file *file, const char *buffer,
73 if (buffer[count-1] == '\n') 75 if (buffer[count-1] == '\n')
74 count--; 76 count--;
75 77
76 down(&pvc_sem); 78 mutex_lock(&pvc_mutex);
77 strncpy(pvc_lines[lineno], buffer, count); 79 strncpy(pvc_lines[lineno], buffer, count);
78 pvc_lines[lineno][count] = '\0'; 80 pvc_lines[lineno][count] = '\0';
79 up(&pvc_sem); 81 mutex_unlock(&pvc_mutex);
80 82
81 tasklet_schedule(&pvc_display_tasklet); 83 tasklet_schedule(&pvc_display_tasklet);
82 84
@@ -89,7 +91,7 @@ static int pvc_proc_write_scroll(struct file *file, const char *buffer,
89 int origcount = count; 91 int origcount = count;
90 int cmd = simple_strtol(buffer, NULL, 10); 92 int cmd = simple_strtol(buffer, NULL, 10);
91 93
92 down(&pvc_sem); 94 mutex_lock(&pvc_mutex);
93 if (scroll_interval != 0) 95 if (scroll_interval != 0)
94 del_timer(&timer); 96 del_timer(&timer);
95 97
@@ -106,7 +108,7 @@ static int pvc_proc_write_scroll(struct file *file, const char *buffer,
106 } 108 }
107 add_timer(&timer); 109 add_timer(&timer);
108 } 110 }
109 up(&pvc_sem); 111 mutex_unlock(&pvc_mutex);
110 112
111 return origcount; 113 return origcount;
112} 114}
@@ -117,9 +119,9 @@ static int pvc_proc_read_scroll(char *page, char **start,
117{ 119{
118 char *origpage = page; 120 char *origpage = page;
119 121
120 down(&pvc_sem); 122 mutex_lock(&pvc_mutex);
121 page += sprintf(page, "%d\n", scroll_dir * scroll_interval); 123 page += sprintf(page, "%d\n", scroll_dir * scroll_interval);
122 up(&pvc_sem); 124 mutex_unlock(&pvc_mutex);
123 125
124 return page - origpage; 126 return page - origpage;
125} 127}
diff --git a/arch/mips/lemote/lm2e/pci.c b/arch/mips/lemote/lm2e/pci.c
index 1ade1cef3899..c1e41f15cc7e 100644
--- a/arch/mips/lemote/lm2e/pci.c
+++ b/arch/mips/lemote/lm2e/pci.c
@@ -81,9 +81,6 @@ static void __init ict_pcimap(void)
81 81
82static int __init pcibios_init(void) 82static int __init pcibios_init(void)
83{ 83{
84 extern int pci_probe_only;
85 pci_probe_only = 0;
86
87 ict_pcimap(); 84 ict_pcimap();
88 register_pci_controller(&loongson2e_pci_controller); 85 register_pci_controller(&loongson2e_pci_controller);
89 86
diff --git a/arch/mips/lemote/lm2e/prom.c b/arch/mips/lemote/lm2e/prom.c
index 824336812198..7edc15dfed6c 100644
--- a/arch/mips/lemote/lm2e/prom.c
+++ b/arch/mips/lemote/lm2e/prom.c
@@ -57,8 +57,6 @@ void __init prom_init(void)
57 arg = (int *)fw_arg1; 57 arg = (int *)fw_arg1;
58 env = (int *)fw_arg2; 58 env = (int *)fw_arg2;
59 59
60 mips_machtype = MACH_LEMOTE_FULONG;
61
62 prom_init_cmdline(); 60 prom_init_cmdline();
63 61
64 if ((strstr(arcs_cmdline, "console=")) == NULL) 62 if ((strstr(arcs_cmdline, "console=")) == NULL)
diff --git a/arch/mips/lib/csum_partial.S b/arch/mips/lib/csum_partial.S
index c0a77fe038be..8d7784122c14 100644
--- a/arch/mips/lib/csum_partial.S
+++ b/arch/mips/lib/csum_partial.S
@@ -7,6 +7,7 @@
7 * 7 *
8 * Copyright (C) 1998, 1999 Ralf Baechle 8 * Copyright (C) 1998, 1999 Ralf Baechle
9 * Copyright (C) 1999 Silicon Graphics, Inc. 9 * Copyright (C) 1999 Silicon Graphics, Inc.
10 * Copyright (C) 2007 Maciej W. Rozycki
10 */ 11 */
11#include <linux/errno.h> 12#include <linux/errno.h>
12#include <asm/asm.h> 13#include <asm/asm.h>
@@ -52,9 +53,12 @@
52#define UNIT(unit) ((unit)*NBYTES) 53#define UNIT(unit) ((unit)*NBYTES)
53 54
54#define ADDC(sum,reg) \ 55#define ADDC(sum,reg) \
56 .set push; \
57 .set noat; \
55 ADD sum, reg; \ 58 ADD sum, reg; \
56 sltu v1, sum, reg; \ 59 sltu v1, sum, reg; \
57 ADD sum, v1 60 ADD sum, v1; \
61 .set pop
58 62
59#define CSUM_BIGCHUNK1(src, offset, sum, _t0, _t1, _t2, _t3) \ 63#define CSUM_BIGCHUNK1(src, offset, sum, _t0, _t1, _t2, _t3) \
60 LOAD _t0, (offset + UNIT(0))(src); \ 64 LOAD _t0, (offset + UNIT(0))(src); \
@@ -92,13 +96,13 @@ LEAF(csum_partial)
92 move t7, zero 96 move t7, zero
93 97
94 sltiu t8, a1, 0x8 98 sltiu t8, a1, 0x8
95 bnez t8, small_csumcpy /* < 8 bytes to copy */ 99 bnez t8, .Lsmall_csumcpy /* < 8 bytes to copy */
96 move t2, a1 100 move t2, a1
97 101
98 andi t7, src, 0x1 /* odd buffer? */ 102 andi t7, src, 0x1 /* odd buffer? */
99 103
100hword_align: 104.Lhword_align:
101 beqz t7, word_align 105 beqz t7, .Lword_align
102 andi t8, src, 0x2 106 andi t8, src, 0x2
103 107
104 lbu t0, (src) 108 lbu t0, (src)
@@ -110,8 +114,8 @@ hword_align:
110 PTR_ADDU src, src, 0x1 114 PTR_ADDU src, src, 0x1
111 andi t8, src, 0x2 115 andi t8, src, 0x2
112 116
113word_align: 117.Lword_align:
114 beqz t8, dword_align 118 beqz t8, .Ldword_align
115 sltiu t8, a1, 56 119 sltiu t8, a1, 56
116 120
117 lhu t0, (src) 121 lhu t0, (src)
@@ -120,12 +124,12 @@ word_align:
120 sltiu t8, a1, 56 124 sltiu t8, a1, 56
121 PTR_ADDU src, src, 0x2 125 PTR_ADDU src, src, 0x2
122 126
123dword_align: 127.Ldword_align:
124 bnez t8, do_end_words 128 bnez t8, .Ldo_end_words
125 move t8, a1 129 move t8, a1
126 130
127 andi t8, src, 0x4 131 andi t8, src, 0x4
128 beqz t8, qword_align 132 beqz t8, .Lqword_align
129 andi t8, src, 0x8 133 andi t8, src, 0x8
130 134
131 lw t0, 0x00(src) 135 lw t0, 0x00(src)
@@ -134,8 +138,8 @@ dword_align:
134 PTR_ADDU src, src, 0x4 138 PTR_ADDU src, src, 0x4
135 andi t8, src, 0x8 139 andi t8, src, 0x8
136 140
137qword_align: 141.Lqword_align:
138 beqz t8, oword_align 142 beqz t8, .Loword_align
139 andi t8, src, 0x10 143 andi t8, src, 0x10
140 144
141#ifdef USE_DOUBLE 145#ifdef USE_DOUBLE
@@ -152,8 +156,8 @@ qword_align:
152 PTR_ADDU src, src, 0x8 156 PTR_ADDU src, src, 0x8
153 andi t8, src, 0x10 157 andi t8, src, 0x10
154 158
155oword_align: 159.Loword_align:
156 beqz t8, begin_movement 160 beqz t8, .Lbegin_movement
157 LONG_SRL t8, a1, 0x7 161 LONG_SRL t8, a1, 0x7
158 162
159#ifdef USE_DOUBLE 163#ifdef USE_DOUBLE
@@ -168,51 +172,55 @@ oword_align:
168 PTR_ADDU src, src, 0x10 172 PTR_ADDU src, src, 0x10
169 LONG_SRL t8, a1, 0x7 173 LONG_SRL t8, a1, 0x7
170 174
171begin_movement: 175.Lbegin_movement:
172 beqz t8, 1f 176 beqz t8, 1f
173 andi t2, a1, 0x40 177 andi t2, a1, 0x40
174 178
175move_128bytes: 179.Lmove_128bytes:
176 CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4) 180 CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4)
177 CSUM_BIGCHUNK(src, 0x20, sum, t0, t1, t3, t4) 181 CSUM_BIGCHUNK(src, 0x20, sum, t0, t1, t3, t4)
178 CSUM_BIGCHUNK(src, 0x40, sum, t0, t1, t3, t4) 182 CSUM_BIGCHUNK(src, 0x40, sum, t0, t1, t3, t4)
179 CSUM_BIGCHUNK(src, 0x60, sum, t0, t1, t3, t4) 183 CSUM_BIGCHUNK(src, 0x60, sum, t0, t1, t3, t4)
180 LONG_SUBU t8, t8, 0x01 184 LONG_SUBU t8, t8, 0x01
181 bnez t8, move_128bytes 185 .set reorder /* DADDI_WAR */
182 PTR_ADDU src, src, 0x80 186 PTR_ADDU src, src, 0x80
187 bnez t8, .Lmove_128bytes
188 .set noreorder
183 189
1841: 1901:
185 beqz t2, 1f 191 beqz t2, 1f
186 andi t2, a1, 0x20 192 andi t2, a1, 0x20
187 193
188move_64bytes: 194.Lmove_64bytes:
189 CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4) 195 CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4)
190 CSUM_BIGCHUNK(src, 0x20, sum, t0, t1, t3, t4) 196 CSUM_BIGCHUNK(src, 0x20, sum, t0, t1, t3, t4)
191 PTR_ADDU src, src, 0x40 197 PTR_ADDU src, src, 0x40
192 198
1931: 1991:
194 beqz t2, do_end_words 200 beqz t2, .Ldo_end_words
195 andi t8, a1, 0x1c 201 andi t8, a1, 0x1c
196 202
197move_32bytes: 203.Lmove_32bytes:
198 CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4) 204 CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4)
199 andi t8, a1, 0x1c 205 andi t8, a1, 0x1c
200 PTR_ADDU src, src, 0x20 206 PTR_ADDU src, src, 0x20
201 207
202do_end_words: 208.Ldo_end_words:
203 beqz t8, small_csumcpy 209 beqz t8, .Lsmall_csumcpy
204 andi t2, a1, 0x3 210 andi t2, a1, 0x3
205 LONG_SRL t8, t8, 0x2 211 LONG_SRL t8, t8, 0x2
206 212
207end_words: 213.Lend_words:
208 lw t0, (src) 214 lw t0, (src)
209 LONG_SUBU t8, t8, 0x1 215 LONG_SUBU t8, t8, 0x1
210 ADDC(sum, t0) 216 ADDC(sum, t0)
211 bnez t8, end_words 217 .set reorder /* DADDI_WAR */
212 PTR_ADDU src, src, 0x4 218 PTR_ADDU src, src, 0x4
219 bnez t8, .Lend_words
220 .set noreorder
213 221
214/* unknown src alignment and < 8 bytes to go */ 222/* unknown src alignment and < 8 bytes to go */
215small_csumcpy: 223.Lsmall_csumcpy:
216 move a1, t2 224 move a1, t2
217 225
218 andi t0, a1, 4 226 andi t0, a1, 4
@@ -246,6 +254,8 @@ small_csumcpy:
2461: ADDC(sum, t1) 2541: ADDC(sum, t1)
247 255
248 /* fold checksum */ 256 /* fold checksum */
257 .set push
258 .set noat
249#ifdef USE_DOUBLE 259#ifdef USE_DOUBLE
250 dsll32 v1, sum, 0 260 dsll32 v1, sum, 0
251 daddu sum, v1 261 daddu sum, v1
@@ -266,6 +276,7 @@ small_csumcpy:
266 srl sum, sum, 8 276 srl sum, sum, 8
267 or sum, v1 277 or sum, v1
268 andi sum, 0xffff 278 andi sum, 0xffff
279 .set pop
2691: 2801:
270 .set reorder 281 .set reorder
271 /* Add the passed partial csum. */ 282 /* Add the passed partial csum. */
@@ -373,7 +384,11 @@ small_csumcpy:
373 384
374#define ADDRMASK (NBYTES-1) 385#define ADDRMASK (NBYTES-1)
375 386
387#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
376 .set noat 388 .set noat
389#else
390 .set at=v1
391#endif
377 392
378LEAF(__csum_partial_copy_user) 393LEAF(__csum_partial_copy_user)
379 PTR_ADDU AT, src, len /* See (1) above. */ 394 PTR_ADDU AT, src, len /* See (1) above. */
@@ -398,95 +413,101 @@ FEXPORT(csum_partial_copy_nocheck)
398 */ 413 */
399 sltu t2, len, NBYTES 414 sltu t2, len, NBYTES
400 and t1, dst, ADDRMASK 415 and t1, dst, ADDRMASK
401 bnez t2, copy_bytes_checklen 416 bnez t2, .Lcopy_bytes_checklen
402 and t0, src, ADDRMASK 417 and t0, src, ADDRMASK
403 andi odd, dst, 0x1 /* odd buffer? */ 418 andi odd, dst, 0x1 /* odd buffer? */
404 bnez t1, dst_unaligned 419 bnez t1, .Ldst_unaligned
405 nop 420 nop
406 bnez t0, src_unaligned_dst_aligned 421 bnez t0, .Lsrc_unaligned_dst_aligned
407 /* 422 /*
408 * use delay slot for fall-through 423 * use delay slot for fall-through
409 * src and dst are aligned; need to compute rem 424 * src and dst are aligned; need to compute rem
410 */ 425 */
411both_aligned: 426.Lboth_aligned:
412 SRL t0, len, LOG_NBYTES+3 # +3 for 8 units/iter 427 SRL t0, len, LOG_NBYTES+3 # +3 for 8 units/iter
413 beqz t0, cleanup_both_aligned # len < 8*NBYTES 428 beqz t0, .Lcleanup_both_aligned # len < 8*NBYTES
414 nop 429 nop
415 SUB len, 8*NBYTES # subtract here for bgez loop 430 SUB len, 8*NBYTES # subtract here for bgez loop
416 .align 4 431 .align 4
4171: 4321:
418EXC( LOAD t0, UNIT(0)(src), l_exc) 433EXC( LOAD t0, UNIT(0)(src), .Ll_exc)
419EXC( LOAD t1, UNIT(1)(src), l_exc_copy) 434EXC( LOAD t1, UNIT(1)(src), .Ll_exc_copy)
420EXC( LOAD t2, UNIT(2)(src), l_exc_copy) 435EXC( LOAD t2, UNIT(2)(src), .Ll_exc_copy)
421EXC( LOAD t3, UNIT(3)(src), l_exc_copy) 436EXC( LOAD t3, UNIT(3)(src), .Ll_exc_copy)
422EXC( LOAD t4, UNIT(4)(src), l_exc_copy) 437EXC( LOAD t4, UNIT(4)(src), .Ll_exc_copy)
423EXC( LOAD t5, UNIT(5)(src), l_exc_copy) 438EXC( LOAD t5, UNIT(5)(src), .Ll_exc_copy)
424EXC( LOAD t6, UNIT(6)(src), l_exc_copy) 439EXC( LOAD t6, UNIT(6)(src), .Ll_exc_copy)
425EXC( LOAD t7, UNIT(7)(src), l_exc_copy) 440EXC( LOAD t7, UNIT(7)(src), .Ll_exc_copy)
426 SUB len, len, 8*NBYTES 441 SUB len, len, 8*NBYTES
427 ADD src, src, 8*NBYTES 442 ADD src, src, 8*NBYTES
428EXC( STORE t0, UNIT(0)(dst), s_exc) 443EXC( STORE t0, UNIT(0)(dst), .Ls_exc)
429 ADDC(sum, t0) 444 ADDC(sum, t0)
430EXC( STORE t1, UNIT(1)(dst), s_exc) 445EXC( STORE t1, UNIT(1)(dst), .Ls_exc)
431 ADDC(sum, t1) 446 ADDC(sum, t1)
432EXC( STORE t2, UNIT(2)(dst), s_exc) 447EXC( STORE t2, UNIT(2)(dst), .Ls_exc)
433 ADDC(sum, t2) 448 ADDC(sum, t2)
434EXC( STORE t3, UNIT(3)(dst), s_exc) 449EXC( STORE t3, UNIT(3)(dst), .Ls_exc)
435 ADDC(sum, t3) 450 ADDC(sum, t3)
436EXC( STORE t4, UNIT(4)(dst), s_exc) 451EXC( STORE t4, UNIT(4)(dst), .Ls_exc)
437 ADDC(sum, t4) 452 ADDC(sum, t4)
438EXC( STORE t5, UNIT(5)(dst), s_exc) 453EXC( STORE t5, UNIT(5)(dst), .Ls_exc)
439 ADDC(sum, t5) 454 ADDC(sum, t5)
440EXC( STORE t6, UNIT(6)(dst), s_exc) 455EXC( STORE t6, UNIT(6)(dst), .Ls_exc)
441 ADDC(sum, t6) 456 ADDC(sum, t6)
442EXC( STORE t7, UNIT(7)(dst), s_exc) 457EXC( STORE t7, UNIT(7)(dst), .Ls_exc)
443 ADDC(sum, t7) 458 ADDC(sum, t7)
459 .set reorder /* DADDI_WAR */
460 ADD dst, dst, 8*NBYTES
444 bgez len, 1b 461 bgez len, 1b
445 ADD dst, dst, 8*NBYTES 462 .set noreorder
446 ADD len, 8*NBYTES # revert len (see above) 463 ADD len, 8*NBYTES # revert len (see above)
447 464
448 /* 465 /*
449 * len == the number of bytes left to copy < 8*NBYTES 466 * len == the number of bytes left to copy < 8*NBYTES
450 */ 467 */
451cleanup_both_aligned: 468.Lcleanup_both_aligned:
452#define rem t7 469#define rem t7
453 beqz len, done 470 beqz len, .Ldone
454 sltu t0, len, 4*NBYTES 471 sltu t0, len, 4*NBYTES
455 bnez t0, less_than_4units 472 bnez t0, .Lless_than_4units
456 and rem, len, (NBYTES-1) # rem = len % NBYTES 473 and rem, len, (NBYTES-1) # rem = len % NBYTES
457 /* 474 /*
458 * len >= 4*NBYTES 475 * len >= 4*NBYTES
459 */ 476 */
460EXC( LOAD t0, UNIT(0)(src), l_exc) 477EXC( LOAD t0, UNIT(0)(src), .Ll_exc)
461EXC( LOAD t1, UNIT(1)(src), l_exc_copy) 478EXC( LOAD t1, UNIT(1)(src), .Ll_exc_copy)
462EXC( LOAD t2, UNIT(2)(src), l_exc_copy) 479EXC( LOAD t2, UNIT(2)(src), .Ll_exc_copy)
463EXC( LOAD t3, UNIT(3)(src), l_exc_copy) 480EXC( LOAD t3, UNIT(3)(src), .Ll_exc_copy)
464 SUB len, len, 4*NBYTES 481 SUB len, len, 4*NBYTES
465 ADD src, src, 4*NBYTES 482 ADD src, src, 4*NBYTES
466EXC( STORE t0, UNIT(0)(dst), s_exc) 483EXC( STORE t0, UNIT(0)(dst), .Ls_exc)
467 ADDC(sum, t0) 484 ADDC(sum, t0)
468EXC( STORE t1, UNIT(1)(dst), s_exc) 485EXC( STORE t1, UNIT(1)(dst), .Ls_exc)
469 ADDC(sum, t1) 486 ADDC(sum, t1)
470EXC( STORE t2, UNIT(2)(dst), s_exc) 487EXC( STORE t2, UNIT(2)(dst), .Ls_exc)
471 ADDC(sum, t2) 488 ADDC(sum, t2)
472EXC( STORE t3, UNIT(3)(dst), s_exc) 489EXC( STORE t3, UNIT(3)(dst), .Ls_exc)
473 ADDC(sum, t3) 490 ADDC(sum, t3)
474 beqz len, done 491 .set reorder /* DADDI_WAR */
475 ADD dst, dst, 4*NBYTES 492 ADD dst, dst, 4*NBYTES
476less_than_4units: 493 beqz len, .Ldone
494 .set noreorder
495.Lless_than_4units:
477 /* 496 /*
478 * rem = len % NBYTES 497 * rem = len % NBYTES
479 */ 498 */
480 beq rem, len, copy_bytes 499 beq rem, len, .Lcopy_bytes
481 nop 500 nop
4821: 5011:
483EXC( LOAD t0, 0(src), l_exc) 502EXC( LOAD t0, 0(src), .Ll_exc)
484 ADD src, src, NBYTES 503 ADD src, src, NBYTES
485 SUB len, len, NBYTES 504 SUB len, len, NBYTES
486EXC( STORE t0, 0(dst), s_exc) 505EXC( STORE t0, 0(dst), .Ls_exc)
487 ADDC(sum, t0) 506 ADDC(sum, t0)
507 .set reorder /* DADDI_WAR */
508 ADD dst, dst, NBYTES
488 bne rem, len, 1b 509 bne rem, len, 1b
489 ADD dst, dst, NBYTES 510 .set noreorder
490 511
491 /* 512 /*
492 * src and dst are aligned, need to copy rem bytes (rem < NBYTES) 513 * src and dst are aligned, need to copy rem bytes (rem < NBYTES)
@@ -500,20 +521,20 @@ EXC( STORE t0, 0(dst), s_exc)
500 * more instruction-level parallelism. 521 * more instruction-level parallelism.
501 */ 522 */
502#define bits t2 523#define bits t2
503 beqz len, done 524 beqz len, .Ldone
504 ADD t1, dst, len # t1 is just past last byte of dst 525 ADD t1, dst, len # t1 is just past last byte of dst
505 li bits, 8*NBYTES 526 li bits, 8*NBYTES
506 SLL rem, len, 3 # rem = number of bits to keep 527 SLL rem, len, 3 # rem = number of bits to keep
507EXC( LOAD t0, 0(src), l_exc) 528EXC( LOAD t0, 0(src), .Ll_exc)
508 SUB bits, bits, rem # bits = number of bits to discard 529 SUB bits, bits, rem # bits = number of bits to discard
509 SHIFT_DISCARD t0, t0, bits 530 SHIFT_DISCARD t0, t0, bits
510EXC( STREST t0, -1(t1), s_exc) 531EXC( STREST t0, -1(t1), .Ls_exc)
511 SHIFT_DISCARD_REVERT t0, t0, bits 532 SHIFT_DISCARD_REVERT t0, t0, bits
512 .set reorder 533 .set reorder
513 ADDC(sum, t0) 534 ADDC(sum, t0)
514 b done 535 b .Ldone
515 .set noreorder 536 .set noreorder
516dst_unaligned: 537.Ldst_unaligned:
517 /* 538 /*
518 * dst is unaligned 539 * dst is unaligned
519 * t0 = src & ADDRMASK 540 * t0 = src & ADDRMASK
@@ -524,25 +545,25 @@ dst_unaligned:
524 * Set match = (src and dst have same alignment) 545 * Set match = (src and dst have same alignment)
525 */ 546 */
526#define match rem 547#define match rem
527EXC( LDFIRST t3, FIRST(0)(src), l_exc) 548EXC( LDFIRST t3, FIRST(0)(src), .Ll_exc)
528 ADD t2, zero, NBYTES 549 ADD t2, zero, NBYTES
529EXC( LDREST t3, REST(0)(src), l_exc_copy) 550EXC( LDREST t3, REST(0)(src), .Ll_exc_copy)
530 SUB t2, t2, t1 # t2 = number of bytes copied 551 SUB t2, t2, t1 # t2 = number of bytes copied
531 xor match, t0, t1 552 xor match, t0, t1
532EXC( STFIRST t3, FIRST(0)(dst), s_exc) 553EXC( STFIRST t3, FIRST(0)(dst), .Ls_exc)
533 SLL t4, t1, 3 # t4 = number of bits to discard 554 SLL t4, t1, 3 # t4 = number of bits to discard
534 SHIFT_DISCARD t3, t3, t4 555 SHIFT_DISCARD t3, t3, t4
535 /* no SHIFT_DISCARD_REVERT to handle odd buffer properly */ 556 /* no SHIFT_DISCARD_REVERT to handle odd buffer properly */
536 ADDC(sum, t3) 557 ADDC(sum, t3)
537 beq len, t2, done 558 beq len, t2, .Ldone
538 SUB len, len, t2 559 SUB len, len, t2
539 ADD dst, dst, t2 560 ADD dst, dst, t2
540 beqz match, both_aligned 561 beqz match, .Lboth_aligned
541 ADD src, src, t2 562 ADD src, src, t2
542 563
543src_unaligned_dst_aligned: 564.Lsrc_unaligned_dst_aligned:
544 SRL t0, len, LOG_NBYTES+2 # +2 for 4 units/iter 565 SRL t0, len, LOG_NBYTES+2 # +2 for 4 units/iter
545 beqz t0, cleanup_src_unaligned 566 beqz t0, .Lcleanup_src_unaligned
546 and rem, len, (4*NBYTES-1) # rem = len % 4*NBYTES 567 and rem, len, (4*NBYTES-1) # rem = len % 4*NBYTES
5471: 5681:
548/* 569/*
@@ -551,49 +572,53 @@ src_unaligned_dst_aligned:
551 * It's OK to load FIRST(N+1) before REST(N) because the two addresses 572 * It's OK to load FIRST(N+1) before REST(N) because the two addresses
552 * are to the same unit (unless src is aligned, but it's not). 573 * are to the same unit (unless src is aligned, but it's not).
553 */ 574 */
554EXC( LDFIRST t0, FIRST(0)(src), l_exc) 575EXC( LDFIRST t0, FIRST(0)(src), .Ll_exc)
555EXC( LDFIRST t1, FIRST(1)(src), l_exc_copy) 576EXC( LDFIRST t1, FIRST(1)(src), .Ll_exc_copy)
556 SUB len, len, 4*NBYTES 577 SUB len, len, 4*NBYTES
557EXC( LDREST t0, REST(0)(src), l_exc_copy) 578EXC( LDREST t0, REST(0)(src), .Ll_exc_copy)
558EXC( LDREST t1, REST(1)(src), l_exc_copy) 579EXC( LDREST t1, REST(1)(src), .Ll_exc_copy)
559EXC( LDFIRST t2, FIRST(2)(src), l_exc_copy) 580EXC( LDFIRST t2, FIRST(2)(src), .Ll_exc_copy)
560EXC( LDFIRST t3, FIRST(3)(src), l_exc_copy) 581EXC( LDFIRST t3, FIRST(3)(src), .Ll_exc_copy)
561EXC( LDREST t2, REST(2)(src), l_exc_copy) 582EXC( LDREST t2, REST(2)(src), .Ll_exc_copy)
562EXC( LDREST t3, REST(3)(src), l_exc_copy) 583EXC( LDREST t3, REST(3)(src), .Ll_exc_copy)
563 ADD src, src, 4*NBYTES 584 ADD src, src, 4*NBYTES
564#ifdef CONFIG_CPU_SB1 585#ifdef CONFIG_CPU_SB1
565 nop # improves slotting 586 nop # improves slotting
566#endif 587#endif
567EXC( STORE t0, UNIT(0)(dst), s_exc) 588EXC( STORE t0, UNIT(0)(dst), .Ls_exc)
568 ADDC(sum, t0) 589 ADDC(sum, t0)
569EXC( STORE t1, UNIT(1)(dst), s_exc) 590EXC( STORE t1, UNIT(1)(dst), .Ls_exc)
570 ADDC(sum, t1) 591 ADDC(sum, t1)
571EXC( STORE t2, UNIT(2)(dst), s_exc) 592EXC( STORE t2, UNIT(2)(dst), .Ls_exc)
572 ADDC(sum, t2) 593 ADDC(sum, t2)
573EXC( STORE t3, UNIT(3)(dst), s_exc) 594EXC( STORE t3, UNIT(3)(dst), .Ls_exc)
574 ADDC(sum, t3) 595 ADDC(sum, t3)
596 .set reorder /* DADDI_WAR */
597 ADD dst, dst, 4*NBYTES
575 bne len, rem, 1b 598 bne len, rem, 1b
576 ADD dst, dst, 4*NBYTES 599 .set noreorder
577 600
578cleanup_src_unaligned: 601.Lcleanup_src_unaligned:
579 beqz len, done 602 beqz len, .Ldone
580 and rem, len, NBYTES-1 # rem = len % NBYTES 603 and rem, len, NBYTES-1 # rem = len % NBYTES
581 beq rem, len, copy_bytes 604 beq rem, len, .Lcopy_bytes
582 nop 605 nop
5831: 6061:
584EXC( LDFIRST t0, FIRST(0)(src), l_exc) 607EXC( LDFIRST t0, FIRST(0)(src), .Ll_exc)
585EXC( LDREST t0, REST(0)(src), l_exc_copy) 608EXC( LDREST t0, REST(0)(src), .Ll_exc_copy)
586 ADD src, src, NBYTES 609 ADD src, src, NBYTES
587 SUB len, len, NBYTES 610 SUB len, len, NBYTES
588EXC( STORE t0, 0(dst), s_exc) 611EXC( STORE t0, 0(dst), .Ls_exc)
589 ADDC(sum, t0) 612 ADDC(sum, t0)
613 .set reorder /* DADDI_WAR */
614 ADD dst, dst, NBYTES
590 bne len, rem, 1b 615 bne len, rem, 1b
591 ADD dst, dst, NBYTES 616 .set noreorder
592 617
593copy_bytes_checklen: 618.Lcopy_bytes_checklen:
594 beqz len, done 619 beqz len, .Ldone
595 nop 620 nop
596copy_bytes: 621.Lcopy_bytes:
597 /* 0 < len < NBYTES */ 622 /* 0 < len < NBYTES */
598#ifdef CONFIG_CPU_LITTLE_ENDIAN 623#ifdef CONFIG_CPU_LITTLE_ENDIAN
599#define SHIFT_START 0 624#define SHIFT_START 0
@@ -604,14 +629,14 @@ copy_bytes:
604#endif 629#endif
605 move t2, zero # partial word 630 move t2, zero # partial word
606 li t3, SHIFT_START # shift 631 li t3, SHIFT_START # shift
607/* use l_exc_copy here to return correct sum on fault */ 632/* use .Ll_exc_copy here to return correct sum on fault */
608#define COPY_BYTE(N) \ 633#define COPY_BYTE(N) \
609EXC( lbu t0, N(src), l_exc_copy); \ 634EXC( lbu t0, N(src), .Ll_exc_copy); \
610 SUB len, len, 1; \ 635 SUB len, len, 1; \
611EXC( sb t0, N(dst), s_exc); \ 636EXC( sb t0, N(dst), .Ls_exc); \
612 SLLV t0, t0, t3; \ 637 SLLV t0, t0, t3; \
613 addu t3, SHIFT_INC; \ 638 addu t3, SHIFT_INC; \
614 beqz len, copy_bytes_done; \ 639 beqz len, .Lcopy_bytes_done; \
615 or t2, t0 640 or t2, t0
616 641
617 COPY_BYTE(0) 642 COPY_BYTE(0)
@@ -622,15 +647,17 @@ EXC( sb t0, N(dst), s_exc); \
622 COPY_BYTE(4) 647 COPY_BYTE(4)
623 COPY_BYTE(5) 648 COPY_BYTE(5)
624#endif 649#endif
625EXC( lbu t0, NBYTES-2(src), l_exc_copy) 650EXC( lbu t0, NBYTES-2(src), .Ll_exc_copy)
626 SUB len, len, 1 651 SUB len, len, 1
627EXC( sb t0, NBYTES-2(dst), s_exc) 652EXC( sb t0, NBYTES-2(dst), .Ls_exc)
628 SLLV t0, t0, t3 653 SLLV t0, t0, t3
629 or t2, t0 654 or t2, t0
630copy_bytes_done: 655.Lcopy_bytes_done:
631 ADDC(sum, t2) 656 ADDC(sum, t2)
632done: 657.Ldone:
633 /* fold checksum */ 658 /* fold checksum */
659 .set push
660 .set noat
634#ifdef USE_DOUBLE 661#ifdef USE_DOUBLE
635 dsll32 v1, sum, 0 662 dsll32 v1, sum, 0
636 daddu sum, v1 663 daddu sum, v1
@@ -651,13 +678,14 @@ done:
651 srl sum, sum, 8 678 srl sum, sum, 8
652 or sum, v1 679 or sum, v1
653 andi sum, 0xffff 680 andi sum, 0xffff
681 .set pop
6541: 6821:
655 .set reorder 683 .set reorder
656 ADDC(sum, psum) 684 ADDC(sum, psum)
657 jr ra 685 jr ra
658 .set noreorder 686 .set noreorder
659 687
660l_exc_copy: 688.Ll_exc_copy:
661 /* 689 /*
662 * Copy bytes from src until faulting load address (or until a 690 * Copy bytes from src until faulting load address (or until a
663 * lb faults) 691 * lb faults)
@@ -672,15 +700,17 @@ l_exc_copy:
672 li t2, SHIFT_START 700 li t2, SHIFT_START
673 LOAD t0, THREAD_BUADDR(t0) 701 LOAD t0, THREAD_BUADDR(t0)
6741: 7021:
675EXC( lbu t1, 0(src), l_exc) 703EXC( lbu t1, 0(src), .Ll_exc)
676 ADD src, src, 1 704 ADD src, src, 1
677 sb t1, 0(dst) # can't fault -- we're copy_from_user 705 sb t1, 0(dst) # can't fault -- we're copy_from_user
678 SLLV t1, t1, t2 706 SLLV t1, t1, t2
679 addu t2, SHIFT_INC 707 addu t2, SHIFT_INC
680 ADDC(sum, t1) 708 ADDC(sum, t1)
709 .set reorder /* DADDI_WAR */
710 ADD dst, dst, 1
681 bne src, t0, 1b 711 bne src, t0, 1b
682 ADD dst, dst, 1 712 .set noreorder
683l_exc: 713.Ll_exc:
684 LOAD t0, TI_TASK($28) 714 LOAD t0, TI_TASK($28)
685 nop 715 nop
686 LOAD t0, THREAD_BUADDR(t0) # t0 is just past last good address 716 LOAD t0, THREAD_BUADDR(t0) # t0 is just past last good address
@@ -697,19 +727,30 @@ l_exc:
697 * Clear len bytes starting at dst. Can't call __bzero because it 727 * Clear len bytes starting at dst. Can't call __bzero because it
698 * might modify len. An inefficient loop for these rare times... 728 * might modify len. An inefficient loop for these rare times...
699 */ 729 */
700 beqz len, done 730 .set reorder /* DADDI_WAR */
701 SUB src, len, 1 731 SUB src, len, 1
732 beqz len, .Ldone
733 .set noreorder
7021: sb zero, 0(dst) 7341: sb zero, 0(dst)
703 ADD dst, dst, 1 735 ADD dst, dst, 1
736 .set push
737 .set noat
738#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
704 bnez src, 1b 739 bnez src, 1b
705 SUB src, src, 1 740 SUB src, src, 1
741#else
742 li v1, 1
743 bnez src, 1b
744 SUB src, src, v1
745#endif
706 li v1, -EFAULT 746 li v1, -EFAULT
707 b done 747 b .Ldone
708 sw v1, (errptr) 748 sw v1, (errptr)
709 749
710s_exc: 750.Ls_exc:
711 li v0, -1 /* invalid checksum */ 751 li v0, -1 /* invalid checksum */
712 li v1, -EFAULT 752 li v1, -EFAULT
713 jr ra 753 jr ra
714 sw v1, (errptr) 754 sw v1, (errptr)
755 .set pop
715 END(__csum_partial_copy_user) 756 END(__csum_partial_copy_user)
diff --git a/arch/mips/lib/memcpy-inatomic.S b/arch/mips/lib/memcpy-inatomic.S
index 3a534b2baa0f..736d0fb56a94 100644
--- a/arch/mips/lib/memcpy-inatomic.S
+++ b/arch/mips/lib/memcpy-inatomic.S
@@ -9,6 +9,7 @@
9 * Copyright (C) 1999, 2000, 01, 2002 Silicon Graphics, Inc. 9 * Copyright (C) 1999, 2000, 01, 2002 Silicon Graphics, Inc.
10 * Copyright (C) 2002 Broadcom, Inc. 10 * Copyright (C) 2002 Broadcom, Inc.
11 * memcpy/copy_user author: Mark Vandevoorde 11 * memcpy/copy_user author: Mark Vandevoorde
12 * Copyright (C) 2007 Maciej W. Rozycki
12 * 13 *
13 * Mnemonic names for arguments to memcpy/__copy_user 14 * Mnemonic names for arguments to memcpy/__copy_user
14 */ 15 */
@@ -175,7 +176,11 @@
175 176
176 .text 177 .text
177 .set noreorder 178 .set noreorder
179#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
178 .set noat 180 .set noat
181#else
182 .set at=v1
183#endif
179 184
180/* 185/*
181 * A combined memcpy/__copy_user 186 * A combined memcpy/__copy_user
@@ -204,36 +209,36 @@ LEAF(__copy_user_inatomic)
204 and t1, dst, ADDRMASK 209 and t1, dst, ADDRMASK
205 PREF( 0, 1*32(src) ) 210 PREF( 0, 1*32(src) )
206 PREF( 1, 1*32(dst) ) 211 PREF( 1, 1*32(dst) )
207 bnez t2, copy_bytes_checklen 212 bnez t2, .Lcopy_bytes_checklen
208 and t0, src, ADDRMASK 213 and t0, src, ADDRMASK
209 PREF( 0, 2*32(src) ) 214 PREF( 0, 2*32(src) )
210 PREF( 1, 2*32(dst) ) 215 PREF( 1, 2*32(dst) )
211 bnez t1, dst_unaligned 216 bnez t1, .Ldst_unaligned
212 nop 217 nop
213 bnez t0, src_unaligned_dst_aligned 218 bnez t0, .Lsrc_unaligned_dst_aligned
214 /* 219 /*
215 * use delay slot for fall-through 220 * use delay slot for fall-through
216 * src and dst are aligned; need to compute rem 221 * src and dst are aligned; need to compute rem
217 */ 222 */
218both_aligned: 223.Lboth_aligned:
219 SRL t0, len, LOG_NBYTES+3 # +3 for 8 units/iter 224 SRL t0, len, LOG_NBYTES+3 # +3 for 8 units/iter
220 beqz t0, cleanup_both_aligned # len < 8*NBYTES 225 beqz t0, .Lcleanup_both_aligned # len < 8*NBYTES
221 and rem, len, (8*NBYTES-1) # rem = len % (8*NBYTES) 226 and rem, len, (8*NBYTES-1) # rem = len % (8*NBYTES)
222 PREF( 0, 3*32(src) ) 227 PREF( 0, 3*32(src) )
223 PREF( 1, 3*32(dst) ) 228 PREF( 1, 3*32(dst) )
224 .align 4 229 .align 4
2251: 2301:
226EXC( LOAD t0, UNIT(0)(src), l_exc) 231EXC( LOAD t0, UNIT(0)(src), .Ll_exc)
227EXC( LOAD t1, UNIT(1)(src), l_exc_copy) 232EXC( LOAD t1, UNIT(1)(src), .Ll_exc_copy)
228EXC( LOAD t2, UNIT(2)(src), l_exc_copy) 233EXC( LOAD t2, UNIT(2)(src), .Ll_exc_copy)
229EXC( LOAD t3, UNIT(3)(src), l_exc_copy) 234EXC( LOAD t3, UNIT(3)(src), .Ll_exc_copy)
230 SUB len, len, 8*NBYTES 235 SUB len, len, 8*NBYTES
231EXC( LOAD t4, UNIT(4)(src), l_exc_copy) 236EXC( LOAD t4, UNIT(4)(src), .Ll_exc_copy)
232EXC( LOAD t7, UNIT(5)(src), l_exc_copy) 237EXC( LOAD t7, UNIT(5)(src), .Ll_exc_copy)
233 STORE t0, UNIT(0)(dst) 238 STORE t0, UNIT(0)(dst)
234 STORE t1, UNIT(1)(dst) 239 STORE t1, UNIT(1)(dst)
235EXC( LOAD t0, UNIT(6)(src), l_exc_copy) 240EXC( LOAD t0, UNIT(6)(src), .Ll_exc_copy)
236EXC( LOAD t1, UNIT(7)(src), l_exc_copy) 241EXC( LOAD t1, UNIT(7)(src), .Ll_exc_copy)
237 ADD src, src, 8*NBYTES 242 ADD src, src, 8*NBYTES
238 ADD dst, dst, 8*NBYTES 243 ADD dst, dst, 8*NBYTES
239 STORE t2, UNIT(-6)(dst) 244 STORE t2, UNIT(-6)(dst)
@@ -250,39 +255,43 @@ EXC( LOAD t1, UNIT(7)(src), l_exc_copy)
250 /* 255 /*
251 * len == rem == the number of bytes left to copy < 8*NBYTES 256 * len == rem == the number of bytes left to copy < 8*NBYTES
252 */ 257 */
253cleanup_both_aligned: 258.Lcleanup_both_aligned:
254 beqz len, done 259 beqz len, .Ldone
255 sltu t0, len, 4*NBYTES 260 sltu t0, len, 4*NBYTES
256 bnez t0, less_than_4units 261 bnez t0, .Lless_than_4units
257 and rem, len, (NBYTES-1) # rem = len % NBYTES 262 and rem, len, (NBYTES-1) # rem = len % NBYTES
258 /* 263 /*
259 * len >= 4*NBYTES 264 * len >= 4*NBYTES
260 */ 265 */
261EXC( LOAD t0, UNIT(0)(src), l_exc) 266EXC( LOAD t0, UNIT(0)(src), .Ll_exc)
262EXC( LOAD t1, UNIT(1)(src), l_exc_copy) 267EXC( LOAD t1, UNIT(1)(src), .Ll_exc_copy)
263EXC( LOAD t2, UNIT(2)(src), l_exc_copy) 268EXC( LOAD t2, UNIT(2)(src), .Ll_exc_copy)
264EXC( LOAD t3, UNIT(3)(src), l_exc_copy) 269EXC( LOAD t3, UNIT(3)(src), .Ll_exc_copy)
265 SUB len, len, 4*NBYTES 270 SUB len, len, 4*NBYTES
266 ADD src, src, 4*NBYTES 271 ADD src, src, 4*NBYTES
267 STORE t0, UNIT(0)(dst) 272 STORE t0, UNIT(0)(dst)
268 STORE t1, UNIT(1)(dst) 273 STORE t1, UNIT(1)(dst)
269 STORE t2, UNIT(2)(dst) 274 STORE t2, UNIT(2)(dst)
270 STORE t3, UNIT(3)(dst) 275 STORE t3, UNIT(3)(dst)
271 beqz len, done 276 .set reorder /* DADDI_WAR */
272 ADD dst, dst, 4*NBYTES 277 ADD dst, dst, 4*NBYTES
273less_than_4units: 278 beqz len, .Ldone
279 .set noreorder
280.Lless_than_4units:
274 /* 281 /*
275 * rem = len % NBYTES 282 * rem = len % NBYTES
276 */ 283 */
277 beq rem, len, copy_bytes 284 beq rem, len, .Lcopy_bytes
278 nop 285 nop
2791: 2861:
280EXC( LOAD t0, 0(src), l_exc) 287EXC( LOAD t0, 0(src), .Ll_exc)
281 ADD src, src, NBYTES 288 ADD src, src, NBYTES
282 SUB len, len, NBYTES 289 SUB len, len, NBYTES
283 STORE t0, 0(dst) 290 STORE t0, 0(dst)
291 .set reorder /* DADDI_WAR */
292 ADD dst, dst, NBYTES
284 bne rem, len, 1b 293 bne rem, len, 1b
285 ADD dst, dst, NBYTES 294 .set noreorder
286 295
287 /* 296 /*
288 * src and dst are aligned, need to copy rem bytes (rem < NBYTES) 297 * src and dst are aligned, need to copy rem bytes (rem < NBYTES)
@@ -296,17 +305,17 @@ EXC( LOAD t0, 0(src), l_exc)
296 * more instruction-level parallelism. 305 * more instruction-level parallelism.
297 */ 306 */
298#define bits t2 307#define bits t2
299 beqz len, done 308 beqz len, .Ldone
300 ADD t1, dst, len # t1 is just past last byte of dst 309 ADD t1, dst, len # t1 is just past last byte of dst
301 li bits, 8*NBYTES 310 li bits, 8*NBYTES
302 SLL rem, len, 3 # rem = number of bits to keep 311 SLL rem, len, 3 # rem = number of bits to keep
303EXC( LOAD t0, 0(src), l_exc) 312EXC( LOAD t0, 0(src), .Ll_exc)
304 SUB bits, bits, rem # bits = number of bits to discard 313 SUB bits, bits, rem # bits = number of bits to discard
305 SHIFT_DISCARD t0, t0, bits 314 SHIFT_DISCARD t0, t0, bits
306 STREST t0, -1(t1) 315 STREST t0, -1(t1)
307 jr ra 316 jr ra
308 move len, zero 317 move len, zero
309dst_unaligned: 318.Ldst_unaligned:
310 /* 319 /*
311 * dst is unaligned 320 * dst is unaligned
312 * t0 = src & ADDRMASK 321 * t0 = src & ADDRMASK
@@ -317,22 +326,22 @@ dst_unaligned:
317 * Set match = (src and dst have same alignment) 326 * Set match = (src and dst have same alignment)
318 */ 327 */
319#define match rem 328#define match rem
320EXC( LDFIRST t3, FIRST(0)(src), l_exc) 329EXC( LDFIRST t3, FIRST(0)(src), .Ll_exc)
321 ADD t2, zero, NBYTES 330 ADD t2, zero, NBYTES
322EXC( LDREST t3, REST(0)(src), l_exc_copy) 331EXC( LDREST t3, REST(0)(src), .Ll_exc_copy)
323 SUB t2, t2, t1 # t2 = number of bytes copied 332 SUB t2, t2, t1 # t2 = number of bytes copied
324 xor match, t0, t1 333 xor match, t0, t1
325 STFIRST t3, FIRST(0)(dst) 334 STFIRST t3, FIRST(0)(dst)
326 beq len, t2, done 335 beq len, t2, .Ldone
327 SUB len, len, t2 336 SUB len, len, t2
328 ADD dst, dst, t2 337 ADD dst, dst, t2
329 beqz match, both_aligned 338 beqz match, .Lboth_aligned
330 ADD src, src, t2 339 ADD src, src, t2
331 340
332src_unaligned_dst_aligned: 341.Lsrc_unaligned_dst_aligned:
333 SRL t0, len, LOG_NBYTES+2 # +2 for 4 units/iter 342 SRL t0, len, LOG_NBYTES+2 # +2 for 4 units/iter
334 PREF( 0, 3*32(src) ) 343 PREF( 0, 3*32(src) )
335 beqz t0, cleanup_src_unaligned 344 beqz t0, .Lcleanup_src_unaligned
336 and rem, len, (4*NBYTES-1) # rem = len % 4*NBYTES 345 and rem, len, (4*NBYTES-1) # rem = len % 4*NBYTES
337 PREF( 1, 3*32(dst) ) 346 PREF( 1, 3*32(dst) )
3381: 3471:
@@ -342,15 +351,15 @@ src_unaligned_dst_aligned:
342 * It's OK to load FIRST(N+1) before REST(N) because the two addresses 351 * It's OK to load FIRST(N+1) before REST(N) because the two addresses
343 * are to the same unit (unless src is aligned, but it's not). 352 * are to the same unit (unless src is aligned, but it's not).
344 */ 353 */
345EXC( LDFIRST t0, FIRST(0)(src), l_exc) 354EXC( LDFIRST t0, FIRST(0)(src), .Ll_exc)
346EXC( LDFIRST t1, FIRST(1)(src), l_exc_copy) 355EXC( LDFIRST t1, FIRST(1)(src), .Ll_exc_copy)
347 SUB len, len, 4*NBYTES 356 SUB len, len, 4*NBYTES
348EXC( LDREST t0, REST(0)(src), l_exc_copy) 357EXC( LDREST t0, REST(0)(src), .Ll_exc_copy)
349EXC( LDREST t1, REST(1)(src), l_exc_copy) 358EXC( LDREST t1, REST(1)(src), .Ll_exc_copy)
350EXC( LDFIRST t2, FIRST(2)(src), l_exc_copy) 359EXC( LDFIRST t2, FIRST(2)(src), .Ll_exc_copy)
351EXC( LDFIRST t3, FIRST(3)(src), l_exc_copy) 360EXC( LDFIRST t3, FIRST(3)(src), .Ll_exc_copy)
352EXC( LDREST t2, REST(2)(src), l_exc_copy) 361EXC( LDREST t2, REST(2)(src), .Ll_exc_copy)
353EXC( LDREST t3, REST(3)(src), l_exc_copy) 362EXC( LDREST t3, REST(3)(src), .Ll_exc_copy)
354 PREF( 0, 9*32(src) ) # 0 is PREF_LOAD (not streamed) 363 PREF( 0, 9*32(src) ) # 0 is PREF_LOAD (not streamed)
355 ADD src, src, 4*NBYTES 364 ADD src, src, 4*NBYTES
356#ifdef CONFIG_CPU_SB1 365#ifdef CONFIG_CPU_SB1
@@ -361,32 +370,36 @@ EXC( LDREST t3, REST(3)(src), l_exc_copy)
361 STORE t2, UNIT(2)(dst) 370 STORE t2, UNIT(2)(dst)
362 STORE t3, UNIT(3)(dst) 371 STORE t3, UNIT(3)(dst)
363 PREF( 1, 9*32(dst) ) # 1 is PREF_STORE (not streamed) 372 PREF( 1, 9*32(dst) ) # 1 is PREF_STORE (not streamed)
373 .set reorder /* DADDI_WAR */
374 ADD dst, dst, 4*NBYTES
364 bne len, rem, 1b 375 bne len, rem, 1b
365 ADD dst, dst, 4*NBYTES 376 .set noreorder
366 377
367cleanup_src_unaligned: 378.Lcleanup_src_unaligned:
368 beqz len, done 379 beqz len, .Ldone
369 and rem, len, NBYTES-1 # rem = len % NBYTES 380 and rem, len, NBYTES-1 # rem = len % NBYTES
370 beq rem, len, copy_bytes 381 beq rem, len, .Lcopy_bytes
371 nop 382 nop
3721: 3831:
373EXC( LDFIRST t0, FIRST(0)(src), l_exc) 384EXC( LDFIRST t0, FIRST(0)(src), .Ll_exc)
374EXC( LDREST t0, REST(0)(src), l_exc_copy) 385EXC( LDREST t0, REST(0)(src), .Ll_exc_copy)
375 ADD src, src, NBYTES 386 ADD src, src, NBYTES
376 SUB len, len, NBYTES 387 SUB len, len, NBYTES
377 STORE t0, 0(dst) 388 STORE t0, 0(dst)
389 .set reorder /* DADDI_WAR */
390 ADD dst, dst, NBYTES
378 bne len, rem, 1b 391 bne len, rem, 1b
379 ADD dst, dst, NBYTES 392 .set noreorder
380 393
381copy_bytes_checklen: 394.Lcopy_bytes_checklen:
382 beqz len, done 395 beqz len, .Ldone
383 nop 396 nop
384copy_bytes: 397.Lcopy_bytes:
385 /* 0 < len < NBYTES */ 398 /* 0 < len < NBYTES */
386#define COPY_BYTE(N) \ 399#define COPY_BYTE(N) \
387EXC( lb t0, N(src), l_exc); \ 400EXC( lb t0, N(src), .Ll_exc); \
388 SUB len, len, 1; \ 401 SUB len, len, 1; \
389 beqz len, done; \ 402 beqz len, .Ldone; \
390 sb t0, N(dst) 403 sb t0, N(dst)
391 404
392 COPY_BYTE(0) 405 COPY_BYTE(0)
@@ -397,16 +410,16 @@ EXC( lb t0, N(src), l_exc); \
397 COPY_BYTE(4) 410 COPY_BYTE(4)
398 COPY_BYTE(5) 411 COPY_BYTE(5)
399#endif 412#endif
400EXC( lb t0, NBYTES-2(src), l_exc) 413EXC( lb t0, NBYTES-2(src), .Ll_exc)
401 SUB len, len, 1 414 SUB len, len, 1
402 jr ra 415 jr ra
403 sb t0, NBYTES-2(dst) 416 sb t0, NBYTES-2(dst)
404done: 417.Ldone:
405 jr ra 418 jr ra
406 nop 419 nop
407 END(__copy_user_inatomic) 420 END(__copy_user_inatomic)
408 421
409l_exc_copy: 422.Ll_exc_copy:
410 /* 423 /*
411 * Copy bytes from src until faulting load address (or until a 424 * Copy bytes from src until faulting load address (or until a
412 * lb faults) 425 * lb faults)
@@ -421,12 +434,14 @@ l_exc_copy:
421 nop 434 nop
422 LOAD t0, THREAD_BUADDR(t0) 435 LOAD t0, THREAD_BUADDR(t0)
4231: 4361:
424EXC( lb t1, 0(src), l_exc) 437EXC( lb t1, 0(src), .Ll_exc)
425 ADD src, src, 1 438 ADD src, src, 1
426 sb t1, 0(dst) # can't fault -- we're copy_from_user 439 sb t1, 0(dst) # can't fault -- we're copy_from_user
440 .set reorder /* DADDI_WAR */
441 ADD dst, dst, 1
427 bne src, t0, 1b 442 bne src, t0, 1b
428 ADD dst, dst, 1 443 .set noreorder
429l_exc: 444.Ll_exc:
430 LOAD t0, TI_TASK($28) 445 LOAD t0, TI_TASK($28)
431 nop 446 nop
432 LOAD t0, THREAD_BUADDR(t0) # t0 is just past last good address 447 LOAD t0, THREAD_BUADDR(t0) # t0 is just past last good address
diff --git a/arch/mips/lib/memcpy.S b/arch/mips/lib/memcpy.S
index a526c62cb76a..c06cccf60bec 100644
--- a/arch/mips/lib/memcpy.S
+++ b/arch/mips/lib/memcpy.S
@@ -9,6 +9,7 @@
9 * Copyright (C) 1999, 2000, 01, 2002 Silicon Graphics, Inc. 9 * Copyright (C) 1999, 2000, 01, 2002 Silicon Graphics, Inc.
10 * Copyright (C) 2002 Broadcom, Inc. 10 * Copyright (C) 2002 Broadcom, Inc.
11 * memcpy/copy_user author: Mark Vandevoorde 11 * memcpy/copy_user author: Mark Vandevoorde
12 * Copyright (C) 2007 Maciej W. Rozycki
12 * 13 *
13 * Mnemonic names for arguments to memcpy/__copy_user 14 * Mnemonic names for arguments to memcpy/__copy_user
14 */ 15 */
@@ -175,7 +176,11 @@
175 176
176 .text 177 .text
177 .set noreorder 178 .set noreorder
179#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
178 .set noat 180 .set noat
181#else
182 .set at=v1
183#endif
179 184
180/* 185/*
181 * A combined memcpy/__copy_user 186 * A combined memcpy/__copy_user
@@ -186,7 +191,7 @@
186 .align 5 191 .align 5
187LEAF(memcpy) /* a0=dst a1=src a2=len */ 192LEAF(memcpy) /* a0=dst a1=src a2=len */
188 move v0, dst /* return value */ 193 move v0, dst /* return value */
189__memcpy: 194.L__memcpy:
190FEXPORT(__copy_user) 195FEXPORT(__copy_user)
191 /* 196 /*
192 * Note: dst & src may be unaligned, len may be 0 197 * Note: dst & src may be unaligned, len may be 0
@@ -194,6 +199,7 @@ FEXPORT(__copy_user)
194 */ 199 */
195#define rem t8 200#define rem t8
196 201
202 R10KCBARRIER(0(ra))
197 /* 203 /*
198 * The "issue break"s below are very approximate. 204 * The "issue break"s below are very approximate.
199 * Issue delays for dcache fills will perturb the schedule, as will 205 * Issue delays for dcache fills will perturb the schedule, as will
@@ -207,44 +213,45 @@ FEXPORT(__copy_user)
207 and t1, dst, ADDRMASK 213 and t1, dst, ADDRMASK
208 PREF( 0, 1*32(src) ) 214 PREF( 0, 1*32(src) )
209 PREF( 1, 1*32(dst) ) 215 PREF( 1, 1*32(dst) )
210 bnez t2, copy_bytes_checklen 216 bnez t2, .Lcopy_bytes_checklen
211 and t0, src, ADDRMASK 217 and t0, src, ADDRMASK
212 PREF( 0, 2*32(src) ) 218 PREF( 0, 2*32(src) )
213 PREF( 1, 2*32(dst) ) 219 PREF( 1, 2*32(dst) )
214 bnez t1, dst_unaligned 220 bnez t1, .Ldst_unaligned
215 nop 221 nop
216 bnez t0, src_unaligned_dst_aligned 222 bnez t0, .Lsrc_unaligned_dst_aligned
217 /* 223 /*
218 * use delay slot for fall-through 224 * use delay slot for fall-through
219 * src and dst are aligned; need to compute rem 225 * src and dst are aligned; need to compute rem
220 */ 226 */
221both_aligned: 227.Lboth_aligned:
222 SRL t0, len, LOG_NBYTES+3 # +3 for 8 units/iter 228 SRL t0, len, LOG_NBYTES+3 # +3 for 8 units/iter
223 beqz t0, cleanup_both_aligned # len < 8*NBYTES 229 beqz t0, .Lcleanup_both_aligned # len < 8*NBYTES
224 and rem, len, (8*NBYTES-1) # rem = len % (8*NBYTES) 230 and rem, len, (8*NBYTES-1) # rem = len % (8*NBYTES)
225 PREF( 0, 3*32(src) ) 231 PREF( 0, 3*32(src) )
226 PREF( 1, 3*32(dst) ) 232 PREF( 1, 3*32(dst) )
227 .align 4 233 .align 4
2281: 2341:
229EXC( LOAD t0, UNIT(0)(src), l_exc) 235 R10KCBARRIER(0(ra))
230EXC( LOAD t1, UNIT(1)(src), l_exc_copy) 236EXC( LOAD t0, UNIT(0)(src), .Ll_exc)
231EXC( LOAD t2, UNIT(2)(src), l_exc_copy) 237EXC( LOAD t1, UNIT(1)(src), .Ll_exc_copy)
232EXC( LOAD t3, UNIT(3)(src), l_exc_copy) 238EXC( LOAD t2, UNIT(2)(src), .Ll_exc_copy)
239EXC( LOAD t3, UNIT(3)(src), .Ll_exc_copy)
233 SUB len, len, 8*NBYTES 240 SUB len, len, 8*NBYTES
234EXC( LOAD t4, UNIT(4)(src), l_exc_copy) 241EXC( LOAD t4, UNIT(4)(src), .Ll_exc_copy)
235EXC( LOAD t7, UNIT(5)(src), l_exc_copy) 242EXC( LOAD t7, UNIT(5)(src), .Ll_exc_copy)
236EXC( STORE t0, UNIT(0)(dst), s_exc_p8u) 243EXC( STORE t0, UNIT(0)(dst), .Ls_exc_p8u)
237EXC( STORE t1, UNIT(1)(dst), s_exc_p7u) 244EXC( STORE t1, UNIT(1)(dst), .Ls_exc_p7u)
238EXC( LOAD t0, UNIT(6)(src), l_exc_copy) 245EXC( LOAD t0, UNIT(6)(src), .Ll_exc_copy)
239EXC( LOAD t1, UNIT(7)(src), l_exc_copy) 246EXC( LOAD t1, UNIT(7)(src), .Ll_exc_copy)
240 ADD src, src, 8*NBYTES 247 ADD src, src, 8*NBYTES
241 ADD dst, dst, 8*NBYTES 248 ADD dst, dst, 8*NBYTES
242EXC( STORE t2, UNIT(-6)(dst), s_exc_p6u) 249EXC( STORE t2, UNIT(-6)(dst), .Ls_exc_p6u)
243EXC( STORE t3, UNIT(-5)(dst), s_exc_p5u) 250EXC( STORE t3, UNIT(-5)(dst), .Ls_exc_p5u)
244EXC( STORE t4, UNIT(-4)(dst), s_exc_p4u) 251EXC( STORE t4, UNIT(-4)(dst), .Ls_exc_p4u)
245EXC( STORE t7, UNIT(-3)(dst), s_exc_p3u) 252EXC( STORE t7, UNIT(-3)(dst), .Ls_exc_p3u)
246EXC( STORE t0, UNIT(-2)(dst), s_exc_p2u) 253EXC( STORE t0, UNIT(-2)(dst), .Ls_exc_p2u)
247EXC( STORE t1, UNIT(-1)(dst), s_exc_p1u) 254EXC( STORE t1, UNIT(-1)(dst), .Ls_exc_p1u)
248 PREF( 0, 8*32(src) ) 255 PREF( 0, 8*32(src) )
249 PREF( 1, 8*32(dst) ) 256 PREF( 1, 8*32(dst) )
250 bne len, rem, 1b 257 bne len, rem, 1b
@@ -253,39 +260,45 @@ EXC( STORE t1, UNIT(-1)(dst), s_exc_p1u)
253 /* 260 /*
254 * len == rem == the number of bytes left to copy < 8*NBYTES 261 * len == rem == the number of bytes left to copy < 8*NBYTES
255 */ 262 */
256cleanup_both_aligned: 263.Lcleanup_both_aligned:
257 beqz len, done 264 beqz len, .Ldone
258 sltu t0, len, 4*NBYTES 265 sltu t0, len, 4*NBYTES
259 bnez t0, less_than_4units 266 bnez t0, .Lless_than_4units
260 and rem, len, (NBYTES-1) # rem = len % NBYTES 267 and rem, len, (NBYTES-1) # rem = len % NBYTES
261 /* 268 /*
262 * len >= 4*NBYTES 269 * len >= 4*NBYTES
263 */ 270 */
264EXC( LOAD t0, UNIT(0)(src), l_exc) 271EXC( LOAD t0, UNIT(0)(src), .Ll_exc)
265EXC( LOAD t1, UNIT(1)(src), l_exc_copy) 272EXC( LOAD t1, UNIT(1)(src), .Ll_exc_copy)
266EXC( LOAD t2, UNIT(2)(src), l_exc_copy) 273EXC( LOAD t2, UNIT(2)(src), .Ll_exc_copy)
267EXC( LOAD t3, UNIT(3)(src), l_exc_copy) 274EXC( LOAD t3, UNIT(3)(src), .Ll_exc_copy)
268 SUB len, len, 4*NBYTES 275 SUB len, len, 4*NBYTES
269 ADD src, src, 4*NBYTES 276 ADD src, src, 4*NBYTES
270EXC( STORE t0, UNIT(0)(dst), s_exc_p4u) 277 R10KCBARRIER(0(ra))
271EXC( STORE t1, UNIT(1)(dst), s_exc_p3u) 278EXC( STORE t0, UNIT(0)(dst), .Ls_exc_p4u)
272EXC( STORE t2, UNIT(2)(dst), s_exc_p2u) 279EXC( STORE t1, UNIT(1)(dst), .Ls_exc_p3u)
273EXC( STORE t3, UNIT(3)(dst), s_exc_p1u) 280EXC( STORE t2, UNIT(2)(dst), .Ls_exc_p2u)
274 beqz len, done 281EXC( STORE t3, UNIT(3)(dst), .Ls_exc_p1u)
275 ADD dst, dst, 4*NBYTES 282 .set reorder /* DADDI_WAR */
276less_than_4units: 283 ADD dst, dst, 4*NBYTES
284 beqz len, .Ldone
285 .set noreorder
286.Lless_than_4units:
277 /* 287 /*
278 * rem = len % NBYTES 288 * rem = len % NBYTES
279 */ 289 */
280 beq rem, len, copy_bytes 290 beq rem, len, .Lcopy_bytes
281 nop 291 nop
2821: 2921:
283EXC( LOAD t0, 0(src), l_exc) 293 R10KCBARRIER(0(ra))
294EXC( LOAD t0, 0(src), .Ll_exc)
284 ADD src, src, NBYTES 295 ADD src, src, NBYTES
285 SUB len, len, NBYTES 296 SUB len, len, NBYTES
286EXC( STORE t0, 0(dst), s_exc_p1u) 297EXC( STORE t0, 0(dst), .Ls_exc_p1u)
298 .set reorder /* DADDI_WAR */
299 ADD dst, dst, NBYTES
287 bne rem, len, 1b 300 bne rem, len, 1b
288 ADD dst, dst, NBYTES 301 .set noreorder
289 302
290 /* 303 /*
291 * src and dst are aligned, need to copy rem bytes (rem < NBYTES) 304 * src and dst are aligned, need to copy rem bytes (rem < NBYTES)
@@ -299,17 +312,17 @@ EXC( STORE t0, 0(dst), s_exc_p1u)
299 * more instruction-level parallelism. 312 * more instruction-level parallelism.
300 */ 313 */
301#define bits t2 314#define bits t2
302 beqz len, done 315 beqz len, .Ldone
303 ADD t1, dst, len # t1 is just past last byte of dst 316 ADD t1, dst, len # t1 is just past last byte of dst
304 li bits, 8*NBYTES 317 li bits, 8*NBYTES
305 SLL rem, len, 3 # rem = number of bits to keep 318 SLL rem, len, 3 # rem = number of bits to keep
306EXC( LOAD t0, 0(src), l_exc) 319EXC( LOAD t0, 0(src), .Ll_exc)
307 SUB bits, bits, rem # bits = number of bits to discard 320 SUB bits, bits, rem # bits = number of bits to discard
308 SHIFT_DISCARD t0, t0, bits 321 SHIFT_DISCARD t0, t0, bits
309EXC( STREST t0, -1(t1), s_exc) 322EXC( STREST t0, -1(t1), .Ls_exc)
310 jr ra 323 jr ra
311 move len, zero 324 move len, zero
312dst_unaligned: 325.Ldst_unaligned:
313 /* 326 /*
314 * dst is unaligned 327 * dst is unaligned
315 * t0 = src & ADDRMASK 328 * t0 = src & ADDRMASK
@@ -320,22 +333,23 @@ dst_unaligned:
320 * Set match = (src and dst have same alignment) 333 * Set match = (src and dst have same alignment)
321 */ 334 */
322#define match rem 335#define match rem
323EXC( LDFIRST t3, FIRST(0)(src), l_exc) 336EXC( LDFIRST t3, FIRST(0)(src), .Ll_exc)
324 ADD t2, zero, NBYTES 337 ADD t2, zero, NBYTES
325EXC( LDREST t3, REST(0)(src), l_exc_copy) 338EXC( LDREST t3, REST(0)(src), .Ll_exc_copy)
326 SUB t2, t2, t1 # t2 = number of bytes copied 339 SUB t2, t2, t1 # t2 = number of bytes copied
327 xor match, t0, t1 340 xor match, t0, t1
328EXC( STFIRST t3, FIRST(0)(dst), s_exc) 341 R10KCBARRIER(0(ra))
329 beq len, t2, done 342EXC( STFIRST t3, FIRST(0)(dst), .Ls_exc)
343 beq len, t2, .Ldone
330 SUB len, len, t2 344 SUB len, len, t2
331 ADD dst, dst, t2 345 ADD dst, dst, t2
332 beqz match, both_aligned 346 beqz match, .Lboth_aligned
333 ADD src, src, t2 347 ADD src, src, t2
334 348
335src_unaligned_dst_aligned: 349.Lsrc_unaligned_dst_aligned:
336 SRL t0, len, LOG_NBYTES+2 # +2 for 4 units/iter 350 SRL t0, len, LOG_NBYTES+2 # +2 for 4 units/iter
337 PREF( 0, 3*32(src) ) 351 PREF( 0, 3*32(src) )
338 beqz t0, cleanup_src_unaligned 352 beqz t0, .Lcleanup_src_unaligned
339 and rem, len, (4*NBYTES-1) # rem = len % 4*NBYTES 353 and rem, len, (4*NBYTES-1) # rem = len % 4*NBYTES
340 PREF( 1, 3*32(dst) ) 354 PREF( 1, 3*32(dst) )
3411: 3551:
@@ -345,52 +359,59 @@ src_unaligned_dst_aligned:
345 * It's OK to load FIRST(N+1) before REST(N) because the two addresses 359 * It's OK to load FIRST(N+1) before REST(N) because the two addresses
346 * are to the same unit (unless src is aligned, but it's not). 360 * are to the same unit (unless src is aligned, but it's not).
347 */ 361 */
348EXC( LDFIRST t0, FIRST(0)(src), l_exc) 362 R10KCBARRIER(0(ra))
349EXC( LDFIRST t1, FIRST(1)(src), l_exc_copy) 363EXC( LDFIRST t0, FIRST(0)(src), .Ll_exc)
364EXC( LDFIRST t1, FIRST(1)(src), .Ll_exc_copy)
350 SUB len, len, 4*NBYTES 365 SUB len, len, 4*NBYTES
351EXC( LDREST t0, REST(0)(src), l_exc_copy) 366EXC( LDREST t0, REST(0)(src), .Ll_exc_copy)
352EXC( LDREST t1, REST(1)(src), l_exc_copy) 367EXC( LDREST t1, REST(1)(src), .Ll_exc_copy)
353EXC( LDFIRST t2, FIRST(2)(src), l_exc_copy) 368EXC( LDFIRST t2, FIRST(2)(src), .Ll_exc_copy)
354EXC( LDFIRST t3, FIRST(3)(src), l_exc_copy) 369EXC( LDFIRST t3, FIRST(3)(src), .Ll_exc_copy)
355EXC( LDREST t2, REST(2)(src), l_exc_copy) 370EXC( LDREST t2, REST(2)(src), .Ll_exc_copy)
356EXC( LDREST t3, REST(3)(src), l_exc_copy) 371EXC( LDREST t3, REST(3)(src), .Ll_exc_copy)
357 PREF( 0, 9*32(src) ) # 0 is PREF_LOAD (not streamed) 372 PREF( 0, 9*32(src) ) # 0 is PREF_LOAD (not streamed)
358 ADD src, src, 4*NBYTES 373 ADD src, src, 4*NBYTES
359#ifdef CONFIG_CPU_SB1 374#ifdef CONFIG_CPU_SB1
360 nop # improves slotting 375 nop # improves slotting
361#endif 376#endif
362EXC( STORE t0, UNIT(0)(dst), s_exc_p4u) 377EXC( STORE t0, UNIT(0)(dst), .Ls_exc_p4u)
363EXC( STORE t1, UNIT(1)(dst), s_exc_p3u) 378EXC( STORE t1, UNIT(1)(dst), .Ls_exc_p3u)
364EXC( STORE t2, UNIT(2)(dst), s_exc_p2u) 379EXC( STORE t2, UNIT(2)(dst), .Ls_exc_p2u)
365EXC( STORE t3, UNIT(3)(dst), s_exc_p1u) 380EXC( STORE t3, UNIT(3)(dst), .Ls_exc_p1u)
366 PREF( 1, 9*32(dst) ) # 1 is PREF_STORE (not streamed) 381 PREF( 1, 9*32(dst) ) # 1 is PREF_STORE (not streamed)
382 .set reorder /* DADDI_WAR */
383 ADD dst, dst, 4*NBYTES
367 bne len, rem, 1b 384 bne len, rem, 1b
368 ADD dst, dst, 4*NBYTES 385 .set noreorder
369 386
370cleanup_src_unaligned: 387.Lcleanup_src_unaligned:
371 beqz len, done 388 beqz len, .Ldone
372 and rem, len, NBYTES-1 # rem = len % NBYTES 389 and rem, len, NBYTES-1 # rem = len % NBYTES
373 beq rem, len, copy_bytes 390 beq rem, len, .Lcopy_bytes
374 nop 391 nop
3751: 3921:
376EXC( LDFIRST t0, FIRST(0)(src), l_exc) 393 R10KCBARRIER(0(ra))
377EXC( LDREST t0, REST(0)(src), l_exc_copy) 394EXC( LDFIRST t0, FIRST(0)(src), .Ll_exc)
395EXC( LDREST t0, REST(0)(src), .Ll_exc_copy)
378 ADD src, src, NBYTES 396 ADD src, src, NBYTES
379 SUB len, len, NBYTES 397 SUB len, len, NBYTES
380EXC( STORE t0, 0(dst), s_exc_p1u) 398EXC( STORE t0, 0(dst), .Ls_exc_p1u)
399 .set reorder /* DADDI_WAR */
400 ADD dst, dst, NBYTES
381 bne len, rem, 1b 401 bne len, rem, 1b
382 ADD dst, dst, NBYTES 402 .set noreorder
383 403
384copy_bytes_checklen: 404.Lcopy_bytes_checklen:
385 beqz len, done 405 beqz len, .Ldone
386 nop 406 nop
387copy_bytes: 407.Lcopy_bytes:
388 /* 0 < len < NBYTES */ 408 /* 0 < len < NBYTES */
409 R10KCBARRIER(0(ra))
389#define COPY_BYTE(N) \ 410#define COPY_BYTE(N) \
390EXC( lb t0, N(src), l_exc); \ 411EXC( lb t0, N(src), .Ll_exc); \
391 SUB len, len, 1; \ 412 SUB len, len, 1; \
392 beqz len, done; \ 413 beqz len, .Ldone; \
393EXC( sb t0, N(dst), s_exc_p1) 414EXC( sb t0, N(dst), .Ls_exc_p1)
394 415
395 COPY_BYTE(0) 416 COPY_BYTE(0)
396 COPY_BYTE(1) 417 COPY_BYTE(1)
@@ -400,16 +421,16 @@ EXC( sb t0, N(dst), s_exc_p1)
400 COPY_BYTE(4) 421 COPY_BYTE(4)
401 COPY_BYTE(5) 422 COPY_BYTE(5)
402#endif 423#endif
403EXC( lb t0, NBYTES-2(src), l_exc) 424EXC( lb t0, NBYTES-2(src), .Ll_exc)
404 SUB len, len, 1 425 SUB len, len, 1
405 jr ra 426 jr ra
406EXC( sb t0, NBYTES-2(dst), s_exc_p1) 427EXC( sb t0, NBYTES-2(dst), .Ls_exc_p1)
407done: 428.Ldone:
408 jr ra 429 jr ra
409 nop 430 nop
410 END(memcpy) 431 END(memcpy)
411 432
412l_exc_copy: 433.Ll_exc_copy:
413 /* 434 /*
414 * Copy bytes from src until faulting load address (or until a 435 * Copy bytes from src until faulting load address (or until a
415 * lb faults) 436 * lb faults)
@@ -424,12 +445,14 @@ l_exc_copy:
424 nop 445 nop
425 LOAD t0, THREAD_BUADDR(t0) 446 LOAD t0, THREAD_BUADDR(t0)
4261: 4471:
427EXC( lb t1, 0(src), l_exc) 448EXC( lb t1, 0(src), .Ll_exc)
428 ADD src, src, 1 449 ADD src, src, 1
429 sb t1, 0(dst) # can't fault -- we're copy_from_user 450 sb t1, 0(dst) # can't fault -- we're copy_from_user
451 .set reorder /* DADDI_WAR */
452 ADD dst, dst, 1
430 bne src, t0, 1b 453 bne src, t0, 1b
431 ADD dst, dst, 1 454 .set noreorder
432l_exc: 455.Ll_exc:
433 LOAD t0, TI_TASK($28) 456 LOAD t0, TI_TASK($28)
434 nop 457 nop
435 LOAD t0, THREAD_BUADDR(t0) # t0 is just past last good address 458 LOAD t0, THREAD_BUADDR(t0) # t0 is just past last good address
@@ -446,20 +469,33 @@ l_exc:
446 * Clear len bytes starting at dst. Can't call __bzero because it 469 * Clear len bytes starting at dst. Can't call __bzero because it
447 * might modify len. An inefficient loop for these rare times... 470 * might modify len. An inefficient loop for these rare times...
448 */ 471 */
449 beqz len, done 472 .set reorder /* DADDI_WAR */
450 SUB src, len, 1 473 SUB src, len, 1
474 beqz len, .Ldone
475 .set noreorder
4511: sb zero, 0(dst) 4761: sb zero, 0(dst)
452 ADD dst, dst, 1 477 ADD dst, dst, 1
478#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
453 bnez src, 1b 479 bnez src, 1b
454 SUB src, src, 1 480 SUB src, src, 1
481#else
482 .set push
483 .set noat
484 li v1, 1
485 bnez src, 1b
486 SUB src, src, v1
487 .set pop
488#endif
455 jr ra 489 jr ra
456 nop 490 nop
457 491
458 492
459#define SEXC(n) \ 493#define SEXC(n) \
460s_exc_p ## n ## u: \ 494 .set reorder; /* DADDI_WAR */ \
461 jr ra; \ 495.Ls_exc_p ## n ## u: \
462 ADD len, len, n*NBYTES 496 ADD len, len, n*NBYTES; \
497 jr ra; \
498 .set noreorder
463 499
464SEXC(8) 500SEXC(8)
465SEXC(7) 501SEXC(7)
@@ -470,10 +506,12 @@ SEXC(3)
470SEXC(2) 506SEXC(2)
471SEXC(1) 507SEXC(1)
472 508
473s_exc_p1: 509.Ls_exc_p1:
510 .set reorder /* DADDI_WAR */
511 ADD len, len, 1
474 jr ra 512 jr ra
475 ADD len, len, 1 513 .set noreorder
476s_exc: 514.Ls_exc:
477 jr ra 515 jr ra
478 nop 516 nop
479 517
@@ -484,38 +522,44 @@ LEAF(memmove)
484 sltu t0, a1, t0 # dst + len <= src -> memcpy 522 sltu t0, a1, t0 # dst + len <= src -> memcpy
485 sltu t1, a0, t1 # dst >= src + len -> memcpy 523 sltu t1, a0, t1 # dst >= src + len -> memcpy
486 and t0, t1 524 and t0, t1
487 beqz t0, __memcpy 525 beqz t0, .L__memcpy
488 move v0, a0 /* return value */ 526 move v0, a0 /* return value */
489 beqz a2, r_out 527 beqz a2, .Lr_out
490 END(memmove) 528 END(memmove)
491 529
492 /* fall through to __rmemcpy */ 530 /* fall through to __rmemcpy */
493LEAF(__rmemcpy) /* a0=dst a1=src a2=len */ 531LEAF(__rmemcpy) /* a0=dst a1=src a2=len */
494 sltu t0, a1, a0 532 sltu t0, a1, a0
495 beqz t0, r_end_bytes_up # src >= dst 533 beqz t0, .Lr_end_bytes_up # src >= dst
496 nop 534 nop
497 ADD a0, a2 # dst = dst + len 535 ADD a0, a2 # dst = dst + len
498 ADD a1, a2 # src = src + len 536 ADD a1, a2 # src = src + len
499 537
500r_end_bytes: 538.Lr_end_bytes:
539 R10KCBARRIER(0(ra))
501 lb t0, -1(a1) 540 lb t0, -1(a1)
502 SUB a2, a2, 0x1 541 SUB a2, a2, 0x1
503 sb t0, -1(a0) 542 sb t0, -1(a0)
504 SUB a1, a1, 0x1 543 SUB a1, a1, 0x1
505 bnez a2, r_end_bytes 544 .set reorder /* DADDI_WAR */
506 SUB a0, a0, 0x1 545 SUB a0, a0, 0x1
546 bnez a2, .Lr_end_bytes
547 .set noreorder
507 548
508r_out: 549.Lr_out:
509 jr ra 550 jr ra
510 move a2, zero 551 move a2, zero
511 552
512r_end_bytes_up: 553.Lr_end_bytes_up:
554 R10KCBARRIER(0(ra))
513 lb t0, (a1) 555 lb t0, (a1)
514 SUB a2, a2, 0x1 556 SUB a2, a2, 0x1
515 sb t0, (a0) 557 sb t0, (a0)
516 ADD a1, a1, 0x1 558 ADD a1, a1, 0x1
517 bnez a2, r_end_bytes_up 559 .set reorder /* DADDI_WAR */
518 ADD a0, a0, 0x1 560 ADD a0, a0, 0x1
561 bnez a2, .Lr_end_bytes_up
562 .set noreorder
519 563
520 jr ra 564 jr ra
521 move a2, zero 565 move a2, zero
diff --git a/arch/mips/lib/memset.S b/arch/mips/lib/memset.S
index 3f8b8b3d0b23..77dc3b20110a 100644
--- a/arch/mips/lib/memset.S
+++ b/arch/mips/lib/memset.S
@@ -5,6 +5,7 @@
5 * 5 *
6 * Copyright (C) 1998, 1999, 2000 by Ralf Baechle 6 * Copyright (C) 1998, 1999, 2000 by Ralf Baechle
7 * Copyright (C) 1999, 2000 Silicon Graphics, Inc. 7 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
8 * Copyright (C) 2007 Maciej W. Rozycki
8 */ 9 */
9#include <asm/asm.h> 10#include <asm/asm.h>
10#include <asm/asm-offsets.h> 11#include <asm/asm-offsets.h>
@@ -71,34 +72,45 @@ LEAF(memset)
71 72
72FEXPORT(__bzero) 73FEXPORT(__bzero)
73 sltiu t0, a2, LONGSIZE /* very small region? */ 74 sltiu t0, a2, LONGSIZE /* very small region? */
74 bnez t0, small_memset 75 bnez t0, .Lsmall_memset
75 andi t0, a0, LONGMASK /* aligned? */ 76 andi t0, a0, LONGMASK /* aligned? */
76 77
78#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
77 beqz t0, 1f 79 beqz t0, 1f
78 PTR_SUBU t0, LONGSIZE /* alignment in bytes */ 80 PTR_SUBU t0, LONGSIZE /* alignment in bytes */
81#else
82 .set noat
83 li AT, LONGSIZE
84 beqz t0, 1f
85 PTR_SUBU t0, AT /* alignment in bytes */
86 .set at
87#endif
79 88
89 R10KCBARRIER(0(ra))
80#ifdef __MIPSEB__ 90#ifdef __MIPSEB__
81 EX(LONG_S_L, a1, (a0), first_fixup) /* make word/dword aligned */ 91 EX(LONG_S_L, a1, (a0), .Lfirst_fixup) /* make word/dword aligned */
82#endif 92#endif
83#ifdef __MIPSEL__ 93#ifdef __MIPSEL__
84 EX(LONG_S_R, a1, (a0), first_fixup) /* make word/dword aligned */ 94 EX(LONG_S_R, a1, (a0), .Lfirst_fixup) /* make word/dword aligned */
85#endif 95#endif
86 PTR_SUBU a0, t0 /* long align ptr */ 96 PTR_SUBU a0, t0 /* long align ptr */
87 PTR_ADDU a2, t0 /* correct size */ 97 PTR_ADDU a2, t0 /* correct size */
88 98
891: ori t1, a2, 0x3f /* # of full blocks */ 991: ori t1, a2, 0x3f /* # of full blocks */
90 xori t1, 0x3f 100 xori t1, 0x3f
91 beqz t1, memset_partial /* no block to fill */ 101 beqz t1, .Lmemset_partial /* no block to fill */
92 andi t0, a2, 0x40-LONGSIZE 102 andi t0, a2, 0x40-LONGSIZE
93 103
94 PTR_ADDU t1, a0 /* end address */ 104 PTR_ADDU t1, a0 /* end address */
95 .set reorder 105 .set reorder
961: PTR_ADDIU a0, 64 1061: PTR_ADDIU a0, 64
97 f_fill64 a0, -64, a1, fwd_fixup 107 R10KCBARRIER(0(ra))
108 f_fill64 a0, -64, a1, .Lfwd_fixup
98 bne t1, a0, 1b 109 bne t1, a0, 1b
99 .set noreorder 110 .set noreorder
100 111
101memset_partial: 112.Lmemset_partial:
113 R10KCBARRIER(0(ra))
102 PTR_LA t1, 2f /* where to start */ 114 PTR_LA t1, 2f /* where to start */
103#if LONGSIZE == 4 115#if LONGSIZE == 4
104 PTR_SUBU t1, t0 116 PTR_SUBU t1, t0
@@ -106,7 +118,7 @@ memset_partial:
106 .set noat 118 .set noat
107 LONG_SRL AT, t0, 1 119 LONG_SRL AT, t0, 1
108 PTR_SUBU t1, AT 120 PTR_SUBU t1, AT
109 .set noat 121 .set at
110#endif 122#endif
111 jr t1 123 jr t1
112 PTR_ADDU a0, t0 /* dest ptr */ 124 PTR_ADDU a0, t0 /* dest ptr */
@@ -114,26 +126,28 @@ memset_partial:
114 .set push 126 .set push
115 .set noreorder 127 .set noreorder
116 .set nomacro 128 .set nomacro
117 f_fill64 a0, -64, a1, partial_fixup /* ... but first do longs ... */ 129 f_fill64 a0, -64, a1, .Lpartial_fixup /* ... but first do longs ... */
1182: .set pop 1302: .set pop
119 andi a2, LONGMASK /* At most one long to go */ 131 andi a2, LONGMASK /* At most one long to go */
120 132
121 beqz a2, 1f 133 beqz a2, 1f
122 PTR_ADDU a0, a2 /* What's left */ 134 PTR_ADDU a0, a2 /* What's left */
135 R10KCBARRIER(0(ra))
123#ifdef __MIPSEB__ 136#ifdef __MIPSEB__
124 EX(LONG_S_R, a1, -1(a0), last_fixup) 137 EX(LONG_S_R, a1, -1(a0), .Llast_fixup)
125#endif 138#endif
126#ifdef __MIPSEL__ 139#ifdef __MIPSEL__
127 EX(LONG_S_L, a1, -1(a0), last_fixup) 140 EX(LONG_S_L, a1, -1(a0), .Llast_fixup)
128#endif 141#endif
1291: jr ra 1421: jr ra
130 move a2, zero 143 move a2, zero
131 144
132small_memset: 145.Lsmall_memset:
133 beqz a2, 2f 146 beqz a2, 2f
134 PTR_ADDU t1, a0, a2 147 PTR_ADDU t1, a0, a2
135 148
1361: PTR_ADDIU a0, 1 /* fill bytewise */ 1491: PTR_ADDIU a0, 1 /* fill bytewise */
150 R10KCBARRIER(0(ra))
137 bne t1, a0, 1b 151 bne t1, a0, 1b
138 sb a1, -1(a0) 152 sb a1, -1(a0)
139 153
@@ -141,11 +155,11 @@ small_memset:
141 move a2, zero 155 move a2, zero
142 END(memset) 156 END(memset)
143 157
144first_fixup: 158.Lfirst_fixup:
145 jr ra 159 jr ra
146 nop 160 nop
147 161
148fwd_fixup: 162.Lfwd_fixup:
149 PTR_L t0, TI_TASK($28) 163 PTR_L t0, TI_TASK($28)
150 LONG_L t0, THREAD_BUADDR(t0) 164 LONG_L t0, THREAD_BUADDR(t0)
151 andi a2, 0x3f 165 andi a2, 0x3f
@@ -153,7 +167,7 @@ fwd_fixup:
153 jr ra 167 jr ra
154 LONG_SUBU a2, t0 168 LONG_SUBU a2, t0
155 169
156partial_fixup: 170.Lpartial_fixup:
157 PTR_L t0, TI_TASK($28) 171 PTR_L t0, TI_TASK($28)
158 LONG_L t0, THREAD_BUADDR(t0) 172 LONG_L t0, THREAD_BUADDR(t0)
159 andi a2, LONGMASK 173 andi a2, LONGMASK
@@ -161,6 +175,6 @@ partial_fixup:
161 jr ra 175 jr ra
162 LONG_SUBU a2, t0 176 LONG_SUBU a2, t0
163 177
164last_fixup: 178.Llast_fixup:
165 jr ra 179 jr ra
166 andi v1, a2, LONGMASK 180 andi v1, a2, LONGMASK
diff --git a/arch/mips/lib/strlen_user.S b/arch/mips/lib/strlen_user.S
index eca558d83a37..fdbb970f670d 100644
--- a/arch/mips/lib/strlen_user.S
+++ b/arch/mips/lib/strlen_user.S
@@ -24,16 +24,16 @@
24LEAF(__strlen_user_asm) 24LEAF(__strlen_user_asm)
25 LONG_L v0, TI_ADDR_LIMIT($28) # pointer ok? 25 LONG_L v0, TI_ADDR_LIMIT($28) # pointer ok?
26 and v0, a0 26 and v0, a0
27 bnez v0, fault 27 bnez v0, .Lfault
28 28
29FEXPORT(__strlen_user_nocheck_asm) 29FEXPORT(__strlen_user_nocheck_asm)
30 move v0, a0 30 move v0, a0
311: EX(lb, t0, (v0), fault) 311: EX(lb, t0, (v0), .Lfault)
32 PTR_ADDIU v0, 1 32 PTR_ADDIU v0, 1
33 bnez t0, 1b 33 bnez t0, 1b
34 PTR_SUBU v0, a0 34 PTR_SUBU v0, a0
35 jr ra 35 jr ra
36 END(__strlen_user_asm) 36 END(__strlen_user_asm)
37 37
38fault: move v0, zero 38.Lfault: move v0, zero
39 jr ra 39 jr ra
diff --git a/arch/mips/lib/strncpy_user.S b/arch/mips/lib/strncpy_user.S
index d16c76fbfac7..7201b2ff08c8 100644
--- a/arch/mips/lib/strncpy_user.S
+++ b/arch/mips/lib/strncpy_user.S
@@ -30,29 +30,30 @@
30LEAF(__strncpy_from_user_asm) 30LEAF(__strncpy_from_user_asm)
31 LONG_L v0, TI_ADDR_LIMIT($28) # pointer ok? 31 LONG_L v0, TI_ADDR_LIMIT($28) # pointer ok?
32 and v0, a1 32 and v0, a1
33 bnez v0, fault 33 bnez v0, .Lfault
34 34
35FEXPORT(__strncpy_from_user_nocheck_asm) 35FEXPORT(__strncpy_from_user_nocheck_asm)
36 move v0, zero 36 move v0, zero
37 move v1, a1 37 move v1, a1
38 .set noreorder 38 .set noreorder
391: EX(lbu, t0, (v1), fault) 391: EX(lbu, t0, (v1), .Lfault)
40 PTR_ADDIU v1, 1 40 PTR_ADDIU v1, 1
41 R10KCBARRIER(0(ra))
41 beqz t0, 2f 42 beqz t0, 2f
42 sb t0, (a0) 43 sb t0, (a0)
43 PTR_ADDIU v0, 1 44 PTR_ADDIU v0, 1
44 bne v0, a2, 1b
45 PTR_ADDIU a0, 1
46 .set reorder 45 .set reorder
46 PTR_ADDIU a0, 1
47 bne v0, a2, 1b
472: PTR_ADDU t0, a1, v0 482: PTR_ADDU t0, a1, v0
48 xor t0, a1 49 xor t0, a1
49 bltz t0, fault 50 bltz t0, .Lfault
50 jr ra # return n 51 jr ra # return n
51 END(__strncpy_from_user_asm) 52 END(__strncpy_from_user_asm)
52 53
53fault: li v0, -EFAULT 54.Lfault: li v0, -EFAULT
54 jr ra 55 jr ra
55 56
56 .section __ex_table,"a" 57 .section __ex_table,"a"
57 PTR 1b, fault 58 PTR 1b, .Lfault
58 .previous 59 .previous
diff --git a/arch/mips/lib/strnlen_user.S b/arch/mips/lib/strnlen_user.S
index c0ea15194a0e..c768e3000616 100644
--- a/arch/mips/lib/strnlen_user.S
+++ b/arch/mips/lib/strnlen_user.S
@@ -28,18 +28,19 @@
28LEAF(__strnlen_user_asm) 28LEAF(__strnlen_user_asm)
29 LONG_L v0, TI_ADDR_LIMIT($28) # pointer ok? 29 LONG_L v0, TI_ADDR_LIMIT($28) # pointer ok?
30 and v0, a0 30 and v0, a0
31 bnez v0, fault 31 bnez v0, .Lfault
32 32
33FEXPORT(__strnlen_user_nocheck_asm) 33FEXPORT(__strnlen_user_nocheck_asm)
34 move v0, a0 34 move v0, a0
35 PTR_ADDU a1, a0 # stop pointer 35 PTR_ADDU a1, a0 # stop pointer
361: beq v0, a1, 1f # limit reached? 361: beq v0, a1, 1f # limit reached?
37 EX(lb, t0, (v0), fault) 37 EX(lb, t0, (v0), .Lfault)
38 PTR_ADDU v0, 1 38 PTR_ADDU v0, 1
39 bnez t0, 1b 39 bnez t0, 1b
401: PTR_SUBU v0, a0 401: PTR_SUBU v0, a0
41 jr ra 41 jr ra
42 END(__strnlen_user_asm) 42 END(__strnlen_user_asm)
43 43
44fault: move v0, zero 44.Lfault:
45 move v0, zero
45 jr ra 46 jr ra
diff --git a/arch/mips/lib/uncached.c b/arch/mips/lib/uncached.c
index 58d14f4d9349..27b012d4341c 100644
--- a/arch/mips/lib/uncached.c
+++ b/arch/mips/lib/uncached.c
@@ -46,9 +46,9 @@ unsigned long __init run_uncached(void *func)
46 if (sp >= (long)CKSEG0 && sp < (long)CKSEG2) 46 if (sp >= (long)CKSEG0 && sp < (long)CKSEG2)
47 usp = CKSEG1ADDR(sp); 47 usp = CKSEG1ADDR(sp);
48#ifdef CONFIG_64BIT 48#ifdef CONFIG_64BIT
49 else if ((long long)sp >= (long long)PHYS_TO_XKPHYS(0LL, 0) && 49 else if ((long long)sp >= (long long)PHYS_TO_XKPHYS(0, 0) &&
50 (long long)sp < (long long)PHYS_TO_XKPHYS(8LL, 0)) 50 (long long)sp < (long long)PHYS_TO_XKPHYS(8, 0))
51 usp = PHYS_TO_XKPHYS((long long)K_CALG_UNCACHED, 51 usp = PHYS_TO_XKPHYS(K_CALG_UNCACHED,
52 XKPHYS_TO_PHYS((long long)sp)); 52 XKPHYS_TO_PHYS((long long)sp));
53#endif 53#endif
54 else { 54 else {
@@ -58,9 +58,9 @@ unsigned long __init run_uncached(void *func)
58 if (lfunc >= (long)CKSEG0 && lfunc < (long)CKSEG2) 58 if (lfunc >= (long)CKSEG0 && lfunc < (long)CKSEG2)
59 ufunc = CKSEG1ADDR(lfunc); 59 ufunc = CKSEG1ADDR(lfunc);
60#ifdef CONFIG_64BIT 60#ifdef CONFIG_64BIT
61 else if ((long long)lfunc >= (long long)PHYS_TO_XKPHYS(0LL, 0) && 61 else if ((long long)lfunc >= (long long)PHYS_TO_XKPHYS(0, 0) &&
62 (long long)lfunc < (long long)PHYS_TO_XKPHYS(8LL, 0)) 62 (long long)lfunc < (long long)PHYS_TO_XKPHYS(8, 0))
63 ufunc = PHYS_TO_XKPHYS((long long)K_CALG_UNCACHED, 63 ufunc = PHYS_TO_XKPHYS(K_CALG_UNCACHED,
64 XKPHYS_TO_PHYS((long long)lfunc)); 64 XKPHYS_TO_PHYS((long long)lfunc));
65#endif 65#endif
66 else { 66 else {
diff --git a/arch/mips/mips-boards/atlas/atlas_setup.c b/arch/mips/mips-boards/atlas/atlas_setup.c
index e405d112a067..5c500802271e 100644
--- a/arch/mips/mips-boards/atlas/atlas_setup.c
+++ b/arch/mips/mips-boards/atlas/atlas_setup.c
@@ -34,12 +34,6 @@
34#include <asm/time.h> 34#include <asm/time.h>
35#include <asm/traps.h> 35#include <asm/traps.h>
36 36
37extern void mips_reboot_setup(void);
38
39#ifdef CONFIG_KGDB
40extern void kgdb_config(void);
41#endif
42
43static void __init serial_init(void); 37static void __init serial_init(void);
44 38
45const char *get_system_type(void) 39const char *get_system_type(void)
diff --git a/arch/mips/mips-boards/generic/init.c b/arch/mips/mips-boards/generic/init.c
index 30f1f54cb68b..1695dca5506b 100644
--- a/arch/mips/mips-boards/generic/init.c
+++ b/arch/mips/mips-boards/generic/init.c
@@ -250,6 +250,8 @@ void __init mips_ejtag_setup(void)
250 flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); 250 flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
251} 251}
252 252
253extern struct plat_smp_ops msmtc_smp_ops;
254
253void __init prom_init(void) 255void __init prom_init(void)
254{ 256{
255 prom_argc = fw_arg0; 257 prom_argc = fw_arg0;
@@ -416,4 +418,10 @@ void __init prom_init(void)
416#ifdef CONFIG_SERIAL_8250_CONSOLE 418#ifdef CONFIG_SERIAL_8250_CONSOLE
417 console_config(); 419 console_config();
418#endif 420#endif
421#ifdef CONFIG_MIPS_MT_SMP
422 register_smp_ops(&vsmp_smp_ops);
423#endif
424#ifdef CONFIG_MIPS_MT_SMTC
425 register_smp_ops(&msmtc_smp_ops);
426#endif
419} 427}
diff --git a/arch/mips/mips-boards/malta/malta_int.c b/arch/mips/mips-boards/malta/malta_int.c
index f010261b75d8..dbe60eb55e29 100644
--- a/arch/mips/mips-boards/malta/malta_int.c
+++ b/arch/mips/mips-boards/malta/malta_int.c
@@ -26,13 +26,13 @@
26#include <linux/sched.h> 26#include <linux/sched.h>
27#include <linux/slab.h> 27#include <linux/slab.h>
28#include <linux/interrupt.h> 28#include <linux/interrupt.h>
29#include <linux/io.h>
29#include <linux/kernel_stat.h> 30#include <linux/kernel_stat.h>
30#include <linux/kernel.h> 31#include <linux/kernel.h>
31#include <linux/random.h> 32#include <linux/random.h>
32 33
33#include <asm/i8259.h> 34#include <asm/i8259.h>
34#include <asm/irq_cpu.h> 35#include <asm/irq_cpu.h>
35#include <asm/io.h>
36#include <asm/irq_regs.h> 36#include <asm/irq_regs.h>
37#include <asm/mips-boards/malta.h> 37#include <asm/mips-boards/malta.h>
38#include <asm/mips-boards/maltaint.h> 38#include <asm/mips-boards/maltaint.h>
@@ -47,7 +47,7 @@ static DEFINE_SPINLOCK(mips_irq_lock);
47static inline int mips_pcibios_iack(void) 47static inline int mips_pcibios_iack(void)
48{ 48{
49 int irq; 49 int irq;
50 u32 dummy; 50 u32 dummy;
51 51
52 /* 52 /*
53 * Determine highest priority pending interrupt by performing 53 * Determine highest priority pending interrupt by performing
@@ -58,7 +58,7 @@ static inline int mips_pcibios_iack(void)
58 case MIPS_REVISION_SCON_ROCIT: 58 case MIPS_REVISION_SCON_ROCIT:
59 case MIPS_REVISION_SCON_SOCITSC: 59 case MIPS_REVISION_SCON_SOCITSC:
60 case MIPS_REVISION_SCON_SOCITSCP: 60 case MIPS_REVISION_SCON_SOCITSCP:
61 MSC_READ(MSC01_PCI_IACK, irq); 61 MSC_READ(MSC01_PCI_IACK, irq);
62 irq &= 0xff; 62 irq &= 0xff;
63 break; 63 break;
64 case MIPS_REVISION_SCON_GT64120: 64 case MIPS_REVISION_SCON_GT64120:
@@ -83,7 +83,7 @@ static inline int mips_pcibios_iack(void)
83 BONITO_PCIMAP_CFG = 0; 83 BONITO_PCIMAP_CFG = 0;
84 break; 84 break;
85 default: 85 default:
86 printk("Unknown system controller.\n"); 86 printk(KERN_WARNING "Unknown system controller.\n");
87 return -1; 87 return -1;
88 } 88 }
89 return irq; 89 return irq;
@@ -114,7 +114,8 @@ static void malta_hw0_irqdispatch(void)
114 114
115 irq = get_int(); 115 irq = get_int();
116 if (irq < 0) { 116 if (irq < 0) {
117 return; /* interrupt has already been cleared */ 117 /* interrupt has already been cleared */
118 return;
118 } 119 }
119 120
120 do_IRQ(MALTA_INT_BASE + irq); 121 do_IRQ(MALTA_INT_BASE + irq);
@@ -123,15 +124,15 @@ static void malta_hw0_irqdispatch(void)
123static void corehi_irqdispatch(void) 124static void corehi_irqdispatch(void)
124{ 125{
125 unsigned int intedge, intsteer, pcicmd, pcibadaddr; 126 unsigned int intedge, intsteer, pcicmd, pcibadaddr;
126 unsigned int pcimstat, intisr, inten, intpol; 127 unsigned int pcimstat, intisr, inten, intpol;
127 unsigned int intrcause, datalo, datahi; 128 unsigned int intrcause, datalo, datahi;
128 struct pt_regs *regs = get_irq_regs(); 129 struct pt_regs *regs = get_irq_regs();
129 130
130 printk("CoreHI interrupt, shouldn't happen, so we die here!!!\n"); 131 printk(KERN_EMERG "CoreHI interrupt, shouldn't happen, we die here!\n");
131 printk("epc : %08lx\nStatus: %08lx\n" 132 printk(KERN_EMERG "epc : %08lx\nStatus: %08lx\n"
132 "Cause : %08lx\nbadVaddr : %08lx\n", 133 "Cause : %08lx\nbadVaddr : %08lx\n",
133 regs->cp0_epc, regs->cp0_status, 134 regs->cp0_epc, regs->cp0_status,
134 regs->cp0_cause, regs->cp0_badvaddr); 135 regs->cp0_cause, regs->cp0_badvaddr);
135 136
136 /* Read all the registers and then print them as there is a 137 /* Read all the registers and then print them as there is a
137 problem with interspersed printk's upsetting the Bonito controller. 138 problem with interspersed printk's upsetting the Bonito controller.
@@ -139,41 +140,41 @@ static void corehi_irqdispatch(void)
139 */ 140 */
140 141
141 switch (mips_revision_sconid) { 142 switch (mips_revision_sconid) {
142 case MIPS_REVISION_SCON_SOCIT: 143 case MIPS_REVISION_SCON_SOCIT:
143 case MIPS_REVISION_SCON_ROCIT: 144 case MIPS_REVISION_SCON_ROCIT:
144 case MIPS_REVISION_SCON_SOCITSC: 145 case MIPS_REVISION_SCON_SOCITSC:
145 case MIPS_REVISION_SCON_SOCITSCP: 146 case MIPS_REVISION_SCON_SOCITSCP:
146 ll_msc_irq(); 147 ll_msc_irq();
147 break; 148 break;
148 case MIPS_REVISION_SCON_GT64120: 149 case MIPS_REVISION_SCON_GT64120:
149 intrcause = GT_READ(GT_INTRCAUSE_OFS); 150 intrcause = GT_READ(GT_INTRCAUSE_OFS);
150 datalo = GT_READ(GT_CPUERR_ADDRLO_OFS); 151 datalo = GT_READ(GT_CPUERR_ADDRLO_OFS);
151 datahi = GT_READ(GT_CPUERR_ADDRHI_OFS); 152 datahi = GT_READ(GT_CPUERR_ADDRHI_OFS);
152 printk("GT_INTRCAUSE = %08x\n", intrcause); 153 printk(KERN_EMERG "GT_INTRCAUSE = %08x\n", intrcause);
153 printk("GT_CPUERR_ADDR = %02x%08x\n", datahi, datalo); 154 printk(KERN_EMERG "GT_CPUERR_ADDR = %02x%08x\n",
154 break; 155 datahi, datalo);
155 case MIPS_REVISION_SCON_BONITO: 156 break;
156 pcibadaddr = BONITO_PCIBADADDR; 157 case MIPS_REVISION_SCON_BONITO:
157 pcimstat = BONITO_PCIMSTAT; 158 pcibadaddr = BONITO_PCIBADADDR;
158 intisr = BONITO_INTISR; 159 pcimstat = BONITO_PCIMSTAT;
159 inten = BONITO_INTEN; 160 intisr = BONITO_INTISR;
160 intpol = BONITO_INTPOL; 161 inten = BONITO_INTEN;
161 intedge = BONITO_INTEDGE; 162 intpol = BONITO_INTPOL;
162 intsteer = BONITO_INTSTEER; 163 intedge = BONITO_INTEDGE;
163 pcicmd = BONITO_PCICMD; 164 intsteer = BONITO_INTSTEER;
164 printk("BONITO_INTISR = %08x\n", intisr); 165 pcicmd = BONITO_PCICMD;
165 printk("BONITO_INTEN = %08x\n", inten); 166 printk(KERN_EMERG "BONITO_INTISR = %08x\n", intisr);
166 printk("BONITO_INTPOL = %08x\n", intpol); 167 printk(KERN_EMERG "BONITO_INTEN = %08x\n", inten);
167 printk("BONITO_INTEDGE = %08x\n", intedge); 168 printk(KERN_EMERG "BONITO_INTPOL = %08x\n", intpol);
168 printk("BONITO_INTSTEER = %08x\n", intsteer); 169 printk(KERN_EMERG "BONITO_INTEDGE = %08x\n", intedge);
169 printk("BONITO_PCICMD = %08x\n", pcicmd); 170 printk(KERN_EMERG "BONITO_INTSTEER = %08x\n", intsteer);
170 printk("BONITO_PCIBADADDR = %08x\n", pcibadaddr); 171 printk(KERN_EMERG "BONITO_PCICMD = %08x\n", pcicmd);
171 printk("BONITO_PCIMSTAT = %08x\n", pcimstat); 172 printk(KERN_EMERG "BONITO_PCIBADADDR = %08x\n", pcibadaddr);
172 break; 173 printk(KERN_EMERG "BONITO_PCIMSTAT = %08x\n", pcimstat);
173 } 174 break;
174 175 }
175 /* We die here*/ 176
176 die("CoreHi interrupt", regs); 177 die("CoreHi interrupt", regs);
177} 178}
178 179
179static inline int clz(unsigned long x) 180static inline int clz(unsigned long x)
@@ -214,9 +215,9 @@ static inline unsigned int irq_ffs(unsigned int pending)
214 215
215 t0 = pending & 0x8000; 216 t0 = pending & 0x8000;
216 t0 = t0 < 1; 217 t0 = t0 < 1;
217 //t0 = t0 << 2; 218 /* t0 = t0 << 2; */
218 a0 = a0 - t0; 219 a0 = a0 - t0;
219 //pending = pending << t0; 220 /* pending = pending << t0; */
220 221
221 return a0; 222 return a0;
222#endif 223#endif
@@ -299,21 +300,29 @@ void __init arch_init_irq(void)
299 if (!cpu_has_veic) 300 if (!cpu_has_veic)
300 mips_cpu_irq_init(); 301 mips_cpu_irq_init();
301 302
302 switch(mips_revision_sconid) { 303 switch (mips_revision_sconid) {
303 case MIPS_REVISION_SCON_SOCIT: 304 case MIPS_REVISION_SCON_SOCIT:
304 case MIPS_REVISION_SCON_ROCIT: 305 case MIPS_REVISION_SCON_ROCIT:
305 if (cpu_has_veic) 306 if (cpu_has_veic)
306 init_msc_irqs(MIPS_MSC01_IC_REG_BASE, MSC01E_INT_BASE, msc_eicirqmap, msc_nr_eicirqs); 307 init_msc_irqs(MIPS_MSC01_IC_REG_BASE,
308 MSC01E_INT_BASE, msc_eicirqmap,
309 msc_nr_eicirqs);
307 else 310 else
308 init_msc_irqs(MIPS_MSC01_IC_REG_BASE, MSC01C_INT_BASE, msc_irqmap, msc_nr_irqs); 311 init_msc_irqs(MIPS_MSC01_IC_REG_BASE,
312 MSC01C_INT_BASE, msc_irqmap,
313 msc_nr_irqs);
309 break; 314 break;
310 315
311 case MIPS_REVISION_SCON_SOCITSC: 316 case MIPS_REVISION_SCON_SOCITSC:
312 case MIPS_REVISION_SCON_SOCITSCP: 317 case MIPS_REVISION_SCON_SOCITSCP:
313 if (cpu_has_veic) 318 if (cpu_has_veic)
314 init_msc_irqs(MIPS_SOCITSC_IC_REG_BASE, MSC01E_INT_BASE, msc_eicirqmap, msc_nr_eicirqs); 319 init_msc_irqs(MIPS_SOCITSC_IC_REG_BASE,
320 MSC01E_INT_BASE, msc_eicirqmap,
321 msc_nr_eicirqs);
315 else 322 else
316 init_msc_irqs(MIPS_SOCITSC_IC_REG_BASE, MSC01C_INT_BASE, msc_irqmap, msc_nr_irqs); 323 init_msc_irqs(MIPS_SOCITSC_IC_REG_BASE,
324 MSC01C_INT_BASE, msc_irqmap,
325 msc_nr_irqs);
317 } 326 }
318 327
319 if (cpu_has_veic) { 328 if (cpu_has_veic) {
@@ -321,8 +330,7 @@ void __init arch_init_irq(void)
321 set_vi_handler(MSC01E_INT_COREHI, corehi_irqdispatch); 330 set_vi_handler(MSC01E_INT_COREHI, corehi_irqdispatch);
322 setup_irq(MSC01E_INT_BASE+MSC01E_INT_I8259A, &i8259irq); 331 setup_irq(MSC01E_INT_BASE+MSC01E_INT_I8259A, &i8259irq);
323 setup_irq(MSC01E_INT_BASE+MSC01E_INT_COREHI, &corehi_irqaction); 332 setup_irq(MSC01E_INT_BASE+MSC01E_INT_COREHI, &corehi_irqaction);
324 } 333 } else if (cpu_has_vint) {
325 else if (cpu_has_vint) {
326 set_vi_handler(MIPSCPU_INT_I8259A, malta_hw0_irqdispatch); 334 set_vi_handler(MIPSCPU_INT_I8259A, malta_hw0_irqdispatch);
327 set_vi_handler(MIPSCPU_INT_COREHI, corehi_irqdispatch); 335 set_vi_handler(MIPSCPU_INT_COREHI, corehi_irqdispatch);
328#ifdef CONFIG_MIPS_MT_SMTC 336#ifdef CONFIG_MIPS_MT_SMTC
@@ -344,11 +352,12 @@ void __init arch_init_irq(void)
344 } 352 }
345#else /* Not SMTC */ 353#else /* Not SMTC */
346 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq); 354 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq);
347 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction); 355 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI,
356 &corehi_irqaction);
348#endif /* CONFIG_MIPS_MT_SMTC */ 357#endif /* CONFIG_MIPS_MT_SMTC */
349 } 358 } else {
350 else {
351 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq); 359 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq);
352 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction); 360 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI,
361 &corehi_irqaction);
353 } 362 }
354} 363}
diff --git a/arch/mips/mips-boards/malta/malta_setup.c b/arch/mips/mips-boards/malta/malta_setup.c
index bc43a5c2224d..2cd8f5734b36 100644
--- a/arch/mips/mips-boards/malta/malta_setup.c
+++ b/arch/mips/mips-boards/malta/malta_setup.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * Carsten Langgaard, carstenl@mips.com 2 * Carsten Langgaard, carstenl@mips.com
3 * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. 3 * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
4 * Copyright (C) Dmitri Vorobiev
4 * 5 *
5 * This program is free software; you can distribute it and/or modify it 6 * This program is free software; you can distribute it and/or modify it
6 * under the terms of the GNU General Public License (Version 2) as 7 * under the terms of the GNU General Public License (Version 2) as
@@ -15,39 +16,57 @@
15 * with this program; if not, write to the Free Software Foundation, Inc., 16 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. 17 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
17 */ 18 */
19#include <linux/cpu.h>
18#include <linux/init.h> 20#include <linux/init.h>
19#include <linux/sched.h> 21#include <linux/sched.h>
20#include <linux/ioport.h> 22#include <linux/ioport.h>
23#include <linux/irq.h>
21#include <linux/pci.h> 24#include <linux/pci.h>
22#include <linux/screen_info.h> 25#include <linux/screen_info.h>
26#include <linux/time.h>
23 27
24#include <asm/cpu.h>
25#include <asm/bootinfo.h> 28#include <asm/bootinfo.h>
26#include <asm/irq.h>
27#include <asm/mips-boards/generic.h> 29#include <asm/mips-boards/generic.h>
28#include <asm/mips-boards/prom.h> 30#include <asm/mips-boards/prom.h>
29#include <asm/mips-boards/malta.h> 31#include <asm/mips-boards/malta.h>
30#include <asm/mips-boards/maltaint.h> 32#include <asm/mips-boards/maltaint.h>
31#include <asm/dma.h> 33#include <asm/dma.h>
32#include <asm/time.h>
33#include <asm/traps.h> 34#include <asm/traps.h>
34#ifdef CONFIG_VT 35#ifdef CONFIG_VT
35#include <linux/console.h> 36#include <linux/console.h>
36#endif 37#endif
37 38
38extern void mips_reboot_setup(void);
39extern unsigned long mips_rtc_get_time(void);
40
41#ifdef CONFIG_KGDB
42extern void kgdb_config(void);
43#endif
44
45struct resource standard_io_resources[] = { 39struct resource standard_io_resources[] = {
46 { .name = "dma1", .start = 0x00, .end = 0x1f, .flags = IORESOURCE_BUSY }, 40 {
47 { .name = "timer", .start = 0x40, .end = 0x5f, .flags = IORESOURCE_BUSY }, 41 .name = "dma1",
48 { .name = "keyboard", .start = 0x60, .end = 0x6f, .flags = IORESOURCE_BUSY }, 42 .start = 0x00,
49 { .name = "dma page reg", .start = 0x80, .end = 0x8f, .flags = IORESOURCE_BUSY }, 43 .end = 0x1f,
50 { .name = "dma2", .start = 0xc0, .end = 0xdf, .flags = IORESOURCE_BUSY }, 44 .flags = IORESOURCE_BUSY
45 },
46 {
47 .name = "timer",
48 .start = 0x40,
49 .end = 0x5f,
50 .flags = IORESOURCE_BUSY
51 },
52 {
53 .name = "keyboard",
54 .start = 0x60,
55 .end = 0x6f,
56 .flags = IORESOURCE_BUSY
57 },
58 {
59 .name = "dma page reg",
60 .start = 0x80,
61 .end = 0x8f,
62 .flags = IORESOURCE_BUSY
63 },
64 {
65 .name = "dma2",
66 .start = 0xc0,
67 .end = 0xdf,
68 .flags = IORESOURCE_BUSY
69 },
51}; 70};
52 71
53const char *get_system_type(void) 72const char *get_system_type(void)
@@ -62,7 +81,7 @@ const char display_string[] = " LINUX ON MALTA ";
62#endif /* CONFIG_MIPS_MT_SMTC */ 81#endif /* CONFIG_MIPS_MT_SMTC */
63 82
64#ifdef CONFIG_BLK_DEV_FD 83#ifdef CONFIG_BLK_DEV_FD
65void __init fd_activate(void) 84static void __init fd_activate(void)
66{ 85{
67 /* 86 /*
68 * Activate Floppy Controller in the SMSC FDC37M817 Super I/O 87 * Activate Floppy Controller in the SMSC FDC37M817 Super I/O
@@ -83,6 +102,85 @@ void __init fd_activate(void)
83} 102}
84#endif 103#endif
85 104
105#ifdef CONFIG_BLK_DEV_IDE
106static void __init pci_clock_check(void)
107{
108 unsigned int __iomem *jmpr_p =
109 (unsigned int *) ioremap(MALTA_JMPRS_REG, sizeof(unsigned int));
110 int jmpr = (__raw_readl(jmpr_p) >> 2) & 0x07;
111 static const int pciclocks[] __initdata = {
112 33, 20, 25, 30, 12, 16, 37, 10
113 };
114 int pciclock = pciclocks[jmpr];
115 char *argptr = prom_getcmdline();
116
117 if (pciclock != 33 && !strstr(argptr, "idebus=")) {
118 printk(KERN_WARNING "WARNING: PCI clock is %dMHz, "
119 "setting idebus\n", pciclock);
120 argptr += strlen(argptr);
121 sprintf(argptr, " idebus=%d", pciclock);
122 if (pciclock < 20 || pciclock > 66)
123 printk(KERN_WARNING "WARNING: IDE timing "
124 "calculations will be incorrect\n");
125 }
126}
127#endif
128
129#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
130static void __init screen_info_setup(void)
131{
132 screen_info = (struct screen_info) {
133 .orig_x = 0,
134 .orig_y = 25,
135 .ext_mem_k = 0,
136 .orig_video_page = 0,
137 .orig_video_mode = 0,
138 .orig_video_cols = 80,
139 .unused2 = 0,
140 .orig_video_ega_bx = 0,
141 .unused3 = 0,
142 .orig_video_lines = 25,
143 .orig_video_isVGA = VIDEO_TYPE_VGAC,
144 .orig_video_points = 16
145 };
146}
147#endif
148
149static void __init bonito_quirks_setup(void)
150{
151 char *argptr;
152
153 argptr = prom_getcmdline();
154 if (strstr(argptr, "debug")) {
155 BONITO_BONGENCFG |= BONITO_BONGENCFG_DEBUGMODE;
156 printk(KERN_INFO "Enabled Bonito debug mode\n");
157 } else
158 BONITO_BONGENCFG &= ~BONITO_BONGENCFG_DEBUGMODE;
159
160#ifdef CONFIG_DMA_COHERENT
161 if (BONITO_PCICACHECTRL & BONITO_PCICACHECTRL_CPUCOH_PRES) {
162 BONITO_PCICACHECTRL |= BONITO_PCICACHECTRL_CPUCOH_EN;
163 printk(KERN_INFO "Enabled Bonito CPU coherency\n");
164
165 argptr = prom_getcmdline();
166 if (strstr(argptr, "iobcuncached")) {
167 BONITO_PCICACHECTRL &= ~BONITO_PCICACHECTRL_IOBCCOH_EN;
168 BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG &
169 ~(BONITO_PCIMEMBASECFG_MEMBASE0_CACHED |
170 BONITO_PCIMEMBASECFG_MEMBASE1_CACHED);
171 printk(KERN_INFO "Disabled Bonito IOBC coherency\n");
172 } else {
173 BONITO_PCICACHECTRL |= BONITO_PCICACHECTRL_IOBCCOH_EN;
174 BONITO_PCIMEMBASECFG |=
175 (BONITO_PCIMEMBASECFG_MEMBASE0_CACHED |
176 BONITO_PCIMEMBASECFG_MEMBASE1_CACHED);
177 printk(KERN_INFO "Enabled Bonito IOBC coherency\n");
178 }
179 } else
180 panic("Hardware DMA cache coherency not supported");
181#endif
182}
183
86void __init plat_mem_setup(void) 184void __init plat_mem_setup(void)
87{ 185{
88 unsigned int i; 186 unsigned int i;
@@ -102,86 +200,24 @@ void __init plat_mem_setup(void)
102 kgdb_config(); 200 kgdb_config();
103#endif 201#endif
104 202
105 if (mips_revision_sconid == MIPS_REVISION_SCON_BONITO) {
106 char *argptr;
107
108 argptr = prom_getcmdline();
109 if (strstr(argptr, "debug")) {
110 BONITO_BONGENCFG |= BONITO_BONGENCFG_DEBUGMODE;
111 printk("Enabled Bonito debug mode\n");
112 }
113 else
114 BONITO_BONGENCFG &= ~BONITO_BONGENCFG_DEBUGMODE;
115
116#ifdef CONFIG_DMA_COHERENT
117 if (BONITO_PCICACHECTRL & BONITO_PCICACHECTRL_CPUCOH_PRES) {
118 BONITO_PCICACHECTRL |= BONITO_PCICACHECTRL_CPUCOH_EN;
119 printk("Enabled Bonito CPU coherency\n");
120
121 argptr = prom_getcmdline();
122 if (strstr(argptr, "iobcuncached")) {
123 BONITO_PCICACHECTRL &= ~BONITO_PCICACHECTRL_IOBCCOH_EN;
124 BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG &
125 ~(BONITO_PCIMEMBASECFG_MEMBASE0_CACHED |
126 BONITO_PCIMEMBASECFG_MEMBASE1_CACHED);
127 printk("Disabled Bonito IOBC coherency\n");
128 }
129 else {
130 BONITO_PCICACHECTRL |= BONITO_PCICACHECTRL_IOBCCOH_EN;
131 BONITO_PCIMEMBASECFG |=
132 (BONITO_PCIMEMBASECFG_MEMBASE0_CACHED |
133 BONITO_PCIMEMBASECFG_MEMBASE1_CACHED);
134 printk("Enabled Bonito IOBC coherency\n");
135 }
136 }
137 else
138 panic("Hardware DMA cache coherency not supported");
139
140#endif
141 }
142#ifdef CONFIG_DMA_COHERENT 203#ifdef CONFIG_DMA_COHERENT
143 else { 204 if (mips_revision_sconid != MIPS_REVISION_SCON_BONITO)
144 panic("Hardware DMA cache coherency not supported"); 205 panic("Hardware DMA cache coherency not supported");
145 }
146#endif 206#endif
147 207
208 if (mips_revision_sconid == MIPS_REVISION_SCON_BONITO)
209 bonito_quirks_setup();
210
148#ifdef CONFIG_BLK_DEV_IDE 211#ifdef CONFIG_BLK_DEV_IDE
149 /* Check PCI clock */ 212 pci_clock_check();
150 {
151 unsigned int __iomem *jmpr_p = (unsigned int *) ioremap(MALTA_JMPRS_REG, sizeof(unsigned int));
152 int jmpr = (__raw_readl(jmpr_p) >> 2) & 0x07;
153 static const int pciclocks[] __initdata = {
154 33, 20, 25, 30, 12, 16, 37, 10
155 };
156 int pciclock = pciclocks[jmpr];
157 char *argptr = prom_getcmdline();
158
159 if (pciclock != 33 && !strstr (argptr, "idebus=")) {
160 printk("WARNING: PCI clock is %dMHz, setting idebus\n", pciclock);
161 argptr += strlen(argptr);
162 sprintf(argptr, " idebus=%d", pciclock);
163 if (pciclock < 20 || pciclock > 66)
164 printk("WARNING: IDE timing calculations will be incorrect\n");
165 }
166 }
167#endif 213#endif
214
168#ifdef CONFIG_BLK_DEV_FD 215#ifdef CONFIG_BLK_DEV_FD
169 fd_activate(); 216 fd_activate();
170#endif 217#endif
171#ifdef CONFIG_VT 218
172#if defined(CONFIG_VGA_CONSOLE) 219#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
173 screen_info = (struct screen_info) { 220 screen_info_setup();
174 0, 25, /* orig-x, orig-y */
175 0, /* unused */
176 0, /* orig-video-page */
177 0, /* orig-video-mode */
178 80, /* orig-video-cols */
179 0, 0, 0, /* ega_ax, ega_bx, ega_cx */
180 25, /* orig-video-lines */
181 VIDEO_TYPE_VGAC, /* orig-video-isVGA */
182 16 /* orig-video-points */
183 };
184#endif
185#endif 221#endif
186 mips_reboot_setup(); 222 mips_reboot_setup();
187} 223}
diff --git a/arch/mips/mips-boards/malta/malta_smtc.c b/arch/mips/mips-boards/malta/malta_smtc.c
index 5c980f4a48fe..5ea705e49454 100644
--- a/arch/mips/mips-boards/malta/malta_smtc.c
+++ b/arch/mips/mips-boards/malta/malta_smtc.c
@@ -15,28 +15,26 @@
15 * Cause the specified action to be performed on a targeted "CPU" 15 * Cause the specified action to be performed on a targeted "CPU"
16 */ 16 */
17 17
18void core_send_ipi(int cpu, unsigned int action) 18static void msmtc_send_ipi_single(int cpu, unsigned int action)
19{ 19{
20 /* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */ 20 /* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */
21 smtc_send_ipi(cpu, LINUX_SMP_IPI, action); 21 smtc_send_ipi(cpu, LINUX_SMP_IPI, action);
22} 22}
23 23
24/* 24static void msmtc_send_ipi_mask(cpumask_t mask, unsigned int action)
25 * Platform "CPU" startup hook
26 */
27
28void __cpuinit prom_boot_secondary(int cpu, struct task_struct *idle)
29{ 25{
30 smtc_boot_secondary(cpu, idle); 26 unsigned int i;
27
28 for_each_cpu_mask(i, mask)
29 msmtc_send_ipi_single(i, action);
31} 30}
32 31
33/* 32/*
34 * Post-config but pre-boot cleanup entry point 33 * Post-config but pre-boot cleanup entry point
35 */ 34 */
36 35static void __cpuinit msmtc_init_secondary(void)
37void __cpuinit prom_init_secondary(void)
38{ 36{
39 void smtc_init_secondary(void); 37 void smtc_init_secondary(void);
40 int myvpe; 38 int myvpe;
41 39
42 /* Don't enable Malta I/O interrupts (IP2) for secondary VPEs */ 40 /* Don't enable Malta I/O interrupts (IP2) for secondary VPEs */
@@ -50,45 +48,61 @@ void __cpuinit prom_init_secondary(void)
50 set_c0_status(0x100 << cp0_perfcount_irq); 48 set_c0_status(0x100 << cp0_perfcount_irq);
51 } 49 }
52 50
53 smtc_init_secondary(); 51 smtc_init_secondary();
54} 52}
55 53
56/* 54/*
57 * Platform SMP pre-initialization 55 * Platform "CPU" startup hook
58 *
59 * As noted above, we can assume a single CPU for now
60 * but it may be multithreaded.
61 */ 56 */
62 57static void __cpuinit msmtc_boot_secondary(int cpu, struct task_struct *idle)
63void __cpuinit plat_smp_setup(void)
64{ 58{
65 if (read_c0_config3() & (1<<2)) 59 smtc_boot_secondary(cpu, idle);
66 mipsmt_build_cpu_map(0);
67} 60}
68 61
69void __init plat_prepare_cpus(unsigned int max_cpus) 62/*
63 * SMP initialization finalization entry point
64 */
65static void __cpuinit msmtc_smp_finish(void)
70{ 66{
71 if (read_c0_config3() & (1<<2)) 67 smtc_smp_finish();
72 mipsmt_prepare_cpus();
73} 68}
74 69
75/* 70/*
76 * SMP initialization finalization entry point 71 * Hook for after all CPUs are online
77 */ 72 */
78 73
79void __cpuinit prom_smp_finish(void) 74static void msmtc_cpus_done(void)
80{ 75{
81 smtc_smp_finish();
82} 76}
83 77
84/* 78/*
85 * Hook for after all CPUs are online 79 * Platform SMP pre-initialization
80 *
81 * As noted above, we can assume a single CPU for now
82 * but it may be multithreaded.
86 */ 83 */
87 84
88void prom_cpus_done(void) 85static void __init msmtc_smp_setup(void)
89{ 86{
87 mipsmt_build_cpu_map(0);
90} 88}
91 89
90static void __init msmtc_prepare_cpus(unsigned int max_cpus)
91{
92 mipsmt_prepare_cpus();
93}
94
95struct plat_smp_ops msmtc_smp_ops = {
96 .send_ipi_single = msmtc_send_ipi_single,
97 .send_ipi_mask = msmtc_send_ipi_mask,
98 .init_secondary = msmtc_init_secondary,
99 .smp_finish = msmtc_smp_finish,
100 .cpus_done = msmtc_cpus_done,
101 .boot_secondary = msmtc_boot_secondary,
102 .smp_setup = msmtc_smp_setup,
103 .prepare_cpus = msmtc_prepare_cpus,
104};
105
92#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF 106#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
93/* 107/*
94 * IRQ affinity hook 108 * IRQ affinity hook
diff --git a/arch/mips/mips-boards/sead/sead_setup.c b/arch/mips/mips-boards/sead/sead_setup.c
index 1fb61b852304..8aa8e5b7b074 100644
--- a/arch/mips/mips-boards/sead/sead_setup.c
+++ b/arch/mips/mips-boards/sead/sead_setup.c
@@ -34,8 +34,6 @@
34#include <asm/mips-boards/seadint.h> 34#include <asm/mips-boards/seadint.h>
35#include <asm/time.h> 35#include <asm/time.h>
36 36
37extern void mips_reboot_setup(void);
38
39static void __init serial_init(void); 37static void __init serial_init(void);
40 38
41const char *get_system_type(void) 39const char *get_system_type(void)
diff --git a/arch/mips/mipssim/Makefile b/arch/mips/mipssim/Makefile
index 75568b584df4..57f43c1c7882 100644
--- a/arch/mips/mipssim/Makefile
+++ b/arch/mips/mipssim/Makefile
@@ -21,6 +21,6 @@ obj-y := sim_platform.o sim_setup.o sim_mem.o sim_time.o sim_int.o \
21 sim_cmdline.o 21 sim_cmdline.o
22 22
23obj-$(CONFIG_EARLY_PRINTK) += sim_console.o 23obj-$(CONFIG_EARLY_PRINTK) += sim_console.o
24obj-$(CONFIG_SMP) += sim_smp.o 24obj-$(CONFIG_MIPS_MT_SMTC) += sim_smtc.o
25 25
26EXTRA_CFLAGS += -Werror 26EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/mipssim/sim_setup.c b/arch/mips/mipssim/sim_setup.c
index 452c129d02c1..d49fe73426b7 100644
--- a/arch/mips/mipssim/sim_setup.c
+++ b/arch/mips/mipssim/sim_setup.c
@@ -60,6 +60,8 @@ void __init plat_mem_setup(void)
60#endif 60#endif
61} 61}
62 62
63extern struct plat_smp_ops ssmtc_smp_ops;
64
63void __init prom_init(void) 65void __init prom_init(void)
64{ 66{
65 set_io_port_base(0xbfd00000); 67 set_io_port_base(0xbfd00000);
@@ -67,8 +69,20 @@ void __init prom_init(void)
67 pr_info("\nLINUX started...\n"); 69 pr_info("\nLINUX started...\n");
68 prom_init_cmdline(); 70 prom_init_cmdline();
69 prom_meminit(); 71 prom_meminit();
70}
71 72
73#ifdef CONFIG_MIPS_MT_SMP
74 if (cpu_has_mipsmt)
75 register_smp_ops(&vsmp_smp_ops);
76 else
77 register_smp_ops(&up_smp_ops);
78#endif
79#ifdef CONFIG_MIPS_MT_SMTC
80 if (cpu_has_mipsmt)
81 register_smp_ops(&ssmtc_smp_ops);
82 else
83 register_smp_ops(&up_smp_ops);
84#endif
85}
72 86
73static void __init serial_init(void) 87static void __init serial_init(void)
74{ 88{
diff --git a/arch/mips/mipssim/sim_smp.c b/arch/mips/mipssim/sim_smtc.c
index ccbbccac23ef..d6e4f656ad14 100644
--- a/arch/mips/mipssim/sim_smp.c
+++ b/arch/mips/mipssim/sim_smtc.c
@@ -16,7 +16,7 @@
16 * 16 *
17 */ 17 */
18/* 18/*
19 * Simulator Platform-specific hooks for SMP operation 19 * Simulator Platform-specific hooks for SMTC operation
20 */ 20 */
21#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/sched.h> 22#include <linux/sched.h>
@@ -29,65 +29,72 @@
29#include <asm/processor.h> 29#include <asm/processor.h>
30#include <asm/system.h> 30#include <asm/system.h>
31#include <asm/mmu_context.h> 31#include <asm/mmu_context.h>
32#ifdef CONFIG_MIPS_MT_SMTC
33#include <asm/smtc_ipi.h> 32#include <asm/smtc_ipi.h>
34#endif /* CONFIG_MIPS_MT_SMTC */
35 33
36/* VPE/SMP Prototype implements platform interfaces directly */ 34/* VPE/SMP Prototype implements platform interfaces directly */
37#if !defined(CONFIG_MIPS_MT_SMP)
38 35
39/* 36/*
40 * Cause the specified action to be performed on a targeted "CPU" 37 * Cause the specified action to be performed on a targeted "CPU"
41 */ 38 */
42 39
43void core_send_ipi(int cpu, unsigned int action) 40static void ssmtc_send_ipi_single(int cpu, unsigned int action)
44{ 41{
45#ifdef CONFIG_MIPS_MT_SMTC
46 smtc_send_ipi(cpu, LINUX_SMP_IPI, action); 42 smtc_send_ipi(cpu, LINUX_SMP_IPI, action);
47#endif /* CONFIG_MIPS_MT_SMTC */ 43 /* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */
48/* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */ 44}
45
46static inline void ssmtc_send_ipi_mask(cpumask_t mask, unsigned int action)
47{
48 unsigned int i;
49 49
50 for_each_cpu_mask(i, mask)
51 ssmtc_send_ipi_single(i, action);
50} 52}
51 53
52/* 54/*
53 * Platform "CPU" startup hook 55 * Post-config but pre-boot cleanup entry point
54 */ 56 */
55 57static void __cpuinit ssmtc_init_secondary(void)
56void __cpuinit prom_boot_secondary(int cpu, struct task_struct *idle)
57{ 58{
58#ifdef CONFIG_MIPS_MT_SMTC 59 void smtc_init_secondary(void);
59 smtc_boot_secondary(cpu, idle); 60
60#endif /* CONFIG_MIPS_MT_SMTC */ 61 smtc_init_secondary();
61} 62}
62 63
63/* 64/*
64 * Post-config but pre-boot cleanup entry point 65 * SMP initialization finalization entry point
65 */ 66 */
67static void __cpuinit ssmtc_smp_finish(void)
68{
69 smtc_smp_finish();
70}
66 71
67void __cpuinit prom_init_secondary(void) 72/*
73 * Hook for after all CPUs are online
74 */
75static void ssmtc_cpus_done(void)
68{ 76{
69#ifdef CONFIG_MIPS_MT_SMTC 77}
70 void smtc_init_secondary(void);
71 78
72 smtc_init_secondary(); 79/*
73#endif /* CONFIG_MIPS_MT_SMTC */ 80 * Platform "CPU" startup hook
81 */
82static void __cpuinit ssmtc_boot_secondary(int cpu, struct task_struct *idle)
83{
84 smtc_boot_secondary(cpu, idle);
74} 85}
75 86
76void plat_smp_setup(void) 87static void __init ssmtc_smp_setup(void)
77{ 88{
78#ifdef CONFIG_MIPS_MT_SMTC
79 if (read_c0_config3() & (1 << 2)) 89 if (read_c0_config3() & (1 << 2))
80 mipsmt_build_cpu_map(0); 90 mipsmt_build_cpu_map(0);
81#endif /* CONFIG_MIPS_MT_SMTC */
82} 91}
83 92
84/* 93/*
85 * Platform SMP pre-initialization 94 * Platform SMP pre-initialization
86 */ 95 */
87 96static void ssmtc_prepare_cpus(unsigned int max_cpus)
88void plat_prepare_cpus(unsigned int max_cpus)
89{ 97{
90#ifdef CONFIG_MIPS_MT_SMTC
91 /* 98 /*
92 * As noted above, we can assume a single CPU for now 99 * As noted above, we can assume a single CPU for now
93 * but it may be multithreaded. 100 * but it may be multithreaded.
@@ -96,28 +103,15 @@ void plat_prepare_cpus(unsigned int max_cpus)
96 if (read_c0_config3() & (1 << 2)) { 103 if (read_c0_config3() & (1 << 2)) {
97 mipsmt_prepare_cpus(); 104 mipsmt_prepare_cpus();
98 } 105 }
99#endif /* CONFIG_MIPS_MT_SMTC */
100} 106}
101 107
102/* 108struct plat_smp_ops ssmtc_smp_ops = {
103 * SMP initialization finalization entry point 109 .send_ipi_single = ssmtc_send_ipi_single,
104 */ 110 .send_ipi_mask = ssmtc_send_ipi_mask,
105 111 .init_secondary = ssmtc_init_secondary,
106void __cpuinit prom_smp_finish(void) 112 .smp_finish = ssmtc_smp_finish,
107{ 113 .cpus_done = ssmtc_cpus_done,
108#ifdef CONFIG_MIPS_MT_SMTC 114 .boot_secondary = ssmtc_boot_secondary,
109 smtc_smp_finish(); 115 .smp_setup = ssmtc_smp_setup,
110#endif /* CONFIG_MIPS_MT_SMTC */ 116 .prepare_cpus = ssmtc_prepare_cpus,
111} 117};
112
113/*
114 * Hook for after all CPUs are online
115 */
116
117void prom_cpus_done(void)
118{
119#ifdef CONFIG_MIPS_MT_SMTC
120
121#endif /* CONFIG_MIPS_MT_SMTC */
122}
123#endif /* CONFIG_MIPS32R2_MT_SMP */
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 9355f1c9325f..02bd180f0e02 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -449,7 +449,7 @@ static inline void local_r4k_flush_cache_page(void *args)
449 * If the page isn't marked valid, the page cannot possibly be 449 * If the page isn't marked valid, the page cannot possibly be
450 * in the cache. 450 * in the cache.
451 */ 451 */
452 if (!(pte_val(*ptep) & _PAGE_PRESENT)) 452 if (!(pte_present(*ptep)))
453 return; 453 return;
454 454
455 if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) 455 if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID))
@@ -468,8 +468,6 @@ static inline void local_r4k_flush_cache_page(void *args)
468 468
469 if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) { 469 if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
470 r4k_blast_dcache_page(addr); 470 r4k_blast_dcache_page(addr);
471 if (exec && !cpu_icache_snoops_remote_store)
472 r4k_blast_scache_page(addr);
473 } 471 }
474 if (exec) { 472 if (exec) {
475 if (vaddr && cpu_has_vtag_icache && mm == current->active_mm) { 473 if (vaddr && cpu_has_vtag_icache && mm == current->active_mm) {
@@ -533,13 +531,6 @@ static inline void local_r4k_flush_icache_range(void *args)
533 R4600_HIT_CACHEOP_WAR_IMPL; 531 R4600_HIT_CACHEOP_WAR_IMPL;
534 protected_blast_dcache_range(start, end); 532 protected_blast_dcache_range(start, end);
535 } 533 }
536
537 if (!cpu_icache_snoops_remote_store && scache_size) {
538 if (end - start > scache_size)
539 r4k_blast_scache();
540 else
541 protected_blast_scache_range(start, end);
542 }
543 } 534 }
544 535
545 if (end - start > icache_size) 536 if (end - start > icache_size)
@@ -598,7 +589,7 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
598 if (size >= scache_size) 589 if (size >= scache_size)
599 r4k_blast_scache(); 590 r4k_blast_scache();
600 else 591 else
601 blast_scache_range(addr, addr + size); 592 blast_inv_scache_range(addr, addr + size);
602 return; 593 return;
603 } 594 }
604 595
@@ -606,7 +597,7 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
606 r4k_blast_dcache(); 597 r4k_blast_dcache();
607 } else { 598 } else {
608 R4600_HIT_CACHEOP_WAR_IMPL; 599 R4600_HIT_CACHEOP_WAR_IMPL;
609 blast_dcache_range(addr, addr + size); 600 blast_inv_dcache_range(addr, addr + size);
610 } 601 }
611 602
612 bc_inv(addr, size); 603 bc_inv(addr, size);
@@ -989,6 +980,8 @@ static void __init probe_pcache(void)
989 case CPU_AU1100: 980 case CPU_AU1100:
990 case CPU_AU1550: 981 case CPU_AU1550:
991 case CPU_AU1200: 982 case CPU_AU1200:
983 case CPU_AU1210:
984 case CPU_AU1250:
992 c->icache.flags |= MIPS_CACHE_IC_F_DC; 985 c->icache.flags |= MIPS_CACHE_IC_F_DC;
993 break; 986 break;
994 } 987 }
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index 810535dd091b..ae39dd88b9aa 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -383,7 +383,7 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
383 BUG_ON(direction == DMA_NONE); 383 BUG_ON(direction == DMA_NONE);
384 384
385 if (!plat_device_is_coherent(dev)) 385 if (!plat_device_is_coherent(dev))
386 dma_cache_wback_inv((unsigned long)vaddr, size); 386 __dma_sync((unsigned long)vaddr, size, direction);
387} 387}
388 388
389EXPORT_SYMBOL(dma_cache_sync); 389EXPORT_SYMBOL(dma_cache_sync);
diff --git a/arch/mips/mm/pg-r4k.c b/arch/mips/mm/pg-r4k.c
index 4f770ac885ce..9185fbf37c0d 100644
--- a/arch/mips/mm/pg-r4k.c
+++ b/arch/mips/mm/pg-r4k.c
@@ -4,6 +4,7 @@
4 * for more details. 4 * for more details.
5 * 5 *
6 * Copyright (C) 2003, 04, 05 Ralf Baechle (ralf@linux-mips.org) 6 * Copyright (C) 2003, 04, 05 Ralf Baechle (ralf@linux-mips.org)
7 * Copyright (C) 2007 Maciej W. Rozycki
7 */ 8 */
8#include <linux/init.h> 9#include <linux/init.h>
9#include <linux/kernel.h> 10#include <linux/kernel.h>
@@ -12,6 +13,7 @@
12#include <linux/module.h> 13#include <linux/module.h>
13#include <linux/proc_fs.h> 14#include <linux/proc_fs.h>
14 15
16#include <asm/bugs.h>
15#include <asm/cacheops.h> 17#include <asm/cacheops.h>
16#include <asm/inst.h> 18#include <asm/inst.h>
17#include <asm/io.h> 19#include <asm/io.h>
@@ -255,64 +257,58 @@ static inline void build_store_reg(int reg)
255 __build_store_reg(reg); 257 __build_store_reg(reg);
256} 258}
257 259
258static inline void build_addiu_a2_a0(unsigned long offset) 260static inline void build_addiu_rt_rs(unsigned int rt, unsigned int rs,
261 unsigned long offset)
259{ 262{
260 union mips_instruction mi; 263 union mips_instruction mi;
261 264
262 BUG_ON(offset > 0x7fff); 265 BUG_ON(offset > 0x7fff);
263 266
264 mi.i_format.opcode = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op; 267 if (cpu_has_64bit_gp_regs && DADDI_WAR && r4k_daddiu_bug()) {
265 mi.i_format.rs = 4; /* $a0 */ 268 mi.i_format.opcode = addiu_op;
266 mi.i_format.rt = 6; /* $a2 */ 269 mi.i_format.rs = 0; /* $zero */
267 mi.i_format.simmediate = offset; 270 mi.i_format.rt = 25; /* $t9 */
271 mi.i_format.simmediate = offset;
272 emit_instruction(mi);
268 273
274 mi.r_format.opcode = spec_op;
275 mi.r_format.rs = rs;
276 mi.r_format.rt = 25; /* $t9 */
277 mi.r_format.rd = rt;
278 mi.r_format.re = 0;
279 mi.r_format.func = daddu_op;
280 } else {
281 mi.i_format.opcode = cpu_has_64bit_gp_regs ?
282 daddiu_op : addiu_op;
283 mi.i_format.rs = rs;
284 mi.i_format.rt = rt;
285 mi.i_format.simmediate = offset;
286 }
269 emit_instruction(mi); 287 emit_instruction(mi);
270} 288}
271 289
272static inline void build_addiu_a2(unsigned long offset) 290static inline void build_addiu_a2_a0(unsigned long offset)
273{ 291{
274 union mips_instruction mi; 292 build_addiu_rt_rs(6, 4, offset); /* $a2, $a0, offset */
275 293}
276 BUG_ON(offset > 0x7fff);
277
278 mi.i_format.opcode = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op;
279 mi.i_format.rs = 6; /* $a2 */
280 mi.i_format.rt = 6; /* $a2 */
281 mi.i_format.simmediate = offset;
282 294
283 emit_instruction(mi); 295static inline void build_addiu_a2(unsigned long offset)
296{
297 build_addiu_rt_rs(6, 6, offset); /* $a2, $a2, offset */
284} 298}
285 299
286static inline void build_addiu_a1(unsigned long offset) 300static inline void build_addiu_a1(unsigned long offset)
287{ 301{
288 union mips_instruction mi; 302 build_addiu_rt_rs(5, 5, offset); /* $a1, $a1, offset */
289
290 BUG_ON(offset > 0x7fff);
291
292 mi.i_format.opcode = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op;
293 mi.i_format.rs = 5; /* $a1 */
294 mi.i_format.rt = 5; /* $a1 */
295 mi.i_format.simmediate = offset;
296 303
297 load_offset -= offset; 304 load_offset -= offset;
298
299 emit_instruction(mi);
300} 305}
301 306
302static inline void build_addiu_a0(unsigned long offset) 307static inline void build_addiu_a0(unsigned long offset)
303{ 308{
304 union mips_instruction mi; 309 build_addiu_rt_rs(4, 4, offset); /* $a0, $a0, offset */
305
306 BUG_ON(offset > 0x7fff);
307
308 mi.i_format.opcode = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op;
309 mi.i_format.rs = 4; /* $a0 */
310 mi.i_format.rt = 4; /* $a0 */
311 mi.i_format.simmediate = offset;
312 310
313 store_offset -= offset; 311 store_offset -= offset;
314
315 emit_instruction(mi);
316} 312}
317 313
318static inline void build_bne(unsigned int *dest) 314static inline void build_bne(unsigned int *dest)
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index a61246d3533d..d026302e0ecc 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -6,7 +6,7 @@
6 * Synthesize TLB refill handlers at runtime. 6 * Synthesize TLB refill handlers at runtime.
7 * 7 *
8 * Copyright (C) 2004,2005,2006 by Thiemo Seufer 8 * Copyright (C) 2004,2005,2006 by Thiemo Seufer
9 * Copyright (C) 2005 Maciej W. Rozycki 9 * Copyright (C) 2005, 2007 Maciej W. Rozycki
10 * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org) 10 * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org)
11 * 11 *
12 * ... and the days got worse and worse and now you see 12 * ... and the days got worse and worse and now you see
@@ -19,20 +19,15 @@
19 * (Condolences to Napoleon XIV) 19 * (Condolences to Napoleon XIV)
20 */ 20 */
21 21
22#include <stdarg.h>
23
24#include <linux/mm.h>
25#include <linux/kernel.h> 22#include <linux/kernel.h>
26#include <linux/types.h> 23#include <linux/types.h>
27#include <linux/string.h> 24#include <linux/string.h>
28#include <linux/init.h> 25#include <linux/init.h>
29 26
30#include <asm/pgtable.h> 27#include <asm/bugs.h>
31#include <asm/cacheflush.h>
32#include <asm/mmu_context.h> 28#include <asm/mmu_context.h>
33#include <asm/inst.h> 29#include <asm/inst.h>
34#include <asm/elf.h> 30#include <asm/elf.h>
35#include <asm/smp.h>
36#include <asm/war.h> 31#include <asm/war.h>
37 32
38static inline int r45k_bvahwbug(void) 33static inline int r45k_bvahwbug(void)
@@ -66,7 +61,7 @@ static inline int __maybe_unused r10000_llsc_war(void)
66 * why; it's not an issue caused by the core RTL. 61 * why; it's not an issue caused by the core RTL.
67 * 62 *
68 */ 63 */
69static __init int __attribute__((unused)) m4kc_tlbp_war(void) 64static int __init m4kc_tlbp_war(void)
70{ 65{
71 return (current_cpu_data.processor_id & 0xffff00) == 66 return (current_cpu_data.processor_id & 0xffff00) ==
72 (PRID_COMP_MIPS | PRID_IMP_4KC); 67 (PRID_COMP_MIPS | PRID_IMP_4KC);
@@ -140,7 +135,7 @@ struct insn {
140 | (e) << RE_SH \ 135 | (e) << RE_SH \
141 | (f) << FUNC_SH) 136 | (f) << FUNC_SH)
142 137
143static __initdata struct insn insn_table[] = { 138static struct insn insn_table[] __initdata = {
144 { insn_addiu, M(addiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, 139 { insn_addiu, M(addiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
145 { insn_addu, M(spec_op, 0, 0, 0, 0, addu_op), RS | RT | RD }, 140 { insn_addu, M(spec_op, 0, 0, 0, 0, addu_op), RS | RT | RD },
146 { insn_and, M(spec_op, 0, 0, 0, 0, and_op), RS | RT | RD }, 141 { insn_and, M(spec_op, 0, 0, 0, 0, and_op), RS | RT | RD },
@@ -193,7 +188,7 @@ static __initdata struct insn insn_table[] = {
193 188
194#undef M 189#undef M
195 190
196static __init u32 build_rs(u32 arg) 191static u32 __init build_rs(u32 arg)
197{ 192{
198 if (arg & ~RS_MASK) 193 if (arg & ~RS_MASK)
199 printk(KERN_WARNING "TLB synthesizer field overflow\n"); 194 printk(KERN_WARNING "TLB synthesizer field overflow\n");
@@ -201,7 +196,7 @@ static __init u32 build_rs(u32 arg)
201 return (arg & RS_MASK) << RS_SH; 196 return (arg & RS_MASK) << RS_SH;
202} 197}
203 198
204static __init u32 build_rt(u32 arg) 199static u32 __init build_rt(u32 arg)
205{ 200{
206 if (arg & ~RT_MASK) 201 if (arg & ~RT_MASK)
207 printk(KERN_WARNING "TLB synthesizer field overflow\n"); 202 printk(KERN_WARNING "TLB synthesizer field overflow\n");
@@ -209,7 +204,7 @@ static __init u32 build_rt(u32 arg)
209 return (arg & RT_MASK) << RT_SH; 204 return (arg & RT_MASK) << RT_SH;
210} 205}
211 206
212static __init u32 build_rd(u32 arg) 207static u32 __init build_rd(u32 arg)
213{ 208{
214 if (arg & ~RD_MASK) 209 if (arg & ~RD_MASK)
215 printk(KERN_WARNING "TLB synthesizer field overflow\n"); 210 printk(KERN_WARNING "TLB synthesizer field overflow\n");
@@ -217,7 +212,7 @@ static __init u32 build_rd(u32 arg)
217 return (arg & RD_MASK) << RD_SH; 212 return (arg & RD_MASK) << RD_SH;
218} 213}
219 214
220static __init u32 build_re(u32 arg) 215static u32 __init build_re(u32 arg)
221{ 216{
222 if (arg & ~RE_MASK) 217 if (arg & ~RE_MASK)
223 printk(KERN_WARNING "TLB synthesizer field overflow\n"); 218 printk(KERN_WARNING "TLB synthesizer field overflow\n");
@@ -225,7 +220,7 @@ static __init u32 build_re(u32 arg)
225 return (arg & RE_MASK) << RE_SH; 220 return (arg & RE_MASK) << RE_SH;
226} 221}
227 222
228static __init u32 build_simm(s32 arg) 223static u32 __init build_simm(s32 arg)
229{ 224{
230 if (arg > 0x7fff || arg < -0x8000) 225 if (arg > 0x7fff || arg < -0x8000)
231 printk(KERN_WARNING "TLB synthesizer field overflow\n"); 226 printk(KERN_WARNING "TLB synthesizer field overflow\n");
@@ -233,7 +228,7 @@ static __init u32 build_simm(s32 arg)
233 return arg & 0xffff; 228 return arg & 0xffff;
234} 229}
235 230
236static __init u32 build_uimm(u32 arg) 231static u32 __init build_uimm(u32 arg)
237{ 232{
238 if (arg & ~IMM_MASK) 233 if (arg & ~IMM_MASK)
239 printk(KERN_WARNING "TLB synthesizer field overflow\n"); 234 printk(KERN_WARNING "TLB synthesizer field overflow\n");
@@ -241,7 +236,7 @@ static __init u32 build_uimm(u32 arg)
241 return arg & IMM_MASK; 236 return arg & IMM_MASK;
242} 237}
243 238
244static __init u32 build_bimm(s32 arg) 239static u32 __init build_bimm(s32 arg)
245{ 240{
246 if (arg > 0x1ffff || arg < -0x20000) 241 if (arg > 0x1ffff || arg < -0x20000)
247 printk(KERN_WARNING "TLB synthesizer field overflow\n"); 242 printk(KERN_WARNING "TLB synthesizer field overflow\n");
@@ -252,7 +247,7 @@ static __init u32 build_bimm(s32 arg)
252 return ((arg < 0) ? (1 << 15) : 0) | ((arg >> 2) & 0x7fff); 247 return ((arg < 0) ? (1 << 15) : 0) | ((arg >> 2) & 0x7fff);
253} 248}
254 249
255static __init u32 build_jimm(u32 arg) 250static u32 __init build_jimm(u32 arg)
256{ 251{
257 if (arg & ~((JIMM_MASK) << 2)) 252 if (arg & ~((JIMM_MASK) << 2))
258 printk(KERN_WARNING "TLB synthesizer field overflow\n"); 253 printk(KERN_WARNING "TLB synthesizer field overflow\n");
@@ -260,7 +255,7 @@ static __init u32 build_jimm(u32 arg)
260 return (arg >> 2) & JIMM_MASK; 255 return (arg >> 2) & JIMM_MASK;
261} 256}
262 257
263static __init u32 build_func(u32 arg) 258static u32 __init build_func(u32 arg)
264{ 259{
265 if (arg & ~FUNC_MASK) 260 if (arg & ~FUNC_MASK)
266 printk(KERN_WARNING "TLB synthesizer field overflow\n"); 261 printk(KERN_WARNING "TLB synthesizer field overflow\n");
@@ -268,7 +263,7 @@ static __init u32 build_func(u32 arg)
268 return arg & FUNC_MASK; 263 return arg & FUNC_MASK;
269} 264}
270 265
271static __init u32 build_set(u32 arg) 266static u32 __init build_set(u32 arg)
272{ 267{
273 if (arg & ~SET_MASK) 268 if (arg & ~SET_MASK)
274 printk(KERN_WARNING "TLB synthesizer field overflow\n"); 269 printk(KERN_WARNING "TLB synthesizer field overflow\n");
@@ -293,7 +288,7 @@ static void __init build_insn(u32 **buf, enum opcode opc, ...)
293 break; 288 break;
294 } 289 }
295 290
296 if (!ip) 291 if (!ip || (opc == insn_daddiu && r4k_daddiu_bug()))
297 panic("Unsupported TLB synthesizer instruction %d", opc); 292 panic("Unsupported TLB synthesizer instruction %d", opc);
298 293
299 op = ip->match; 294 op = ip->match;
@@ -315,69 +310,69 @@ static void __init build_insn(u32 **buf, enum opcode opc, ...)
315} 310}
316 311
317#define I_u1u2u3(op) \ 312#define I_u1u2u3(op) \
318 static inline void __init i##op(u32 **buf, unsigned int a, \ 313 static void __init __maybe_unused i##op(u32 **buf, unsigned int a, \
319 unsigned int b, unsigned int c) \ 314 unsigned int b, unsigned int c) \
320 { \ 315 { \
321 build_insn(buf, insn##op, a, b, c); \ 316 build_insn(buf, insn##op, a, b, c); \
322 } 317 }
323 318
324#define I_u2u1u3(op) \ 319#define I_u2u1u3(op) \
325 static inline void __init i##op(u32 **buf, unsigned int a, \ 320 static void __init __maybe_unused i##op(u32 **buf, unsigned int a, \
326 unsigned int b, unsigned int c) \ 321 unsigned int b, unsigned int c) \
327 { \ 322 { \
328 build_insn(buf, insn##op, b, a, c); \ 323 build_insn(buf, insn##op, b, a, c); \
329 } 324 }
330 325
331#define I_u3u1u2(op) \ 326#define I_u3u1u2(op) \
332 static inline void __init i##op(u32 **buf, unsigned int a, \ 327 static void __init __maybe_unused i##op(u32 **buf, unsigned int a, \
333 unsigned int b, unsigned int c) \ 328 unsigned int b, unsigned int c) \
334 { \ 329 { \
335 build_insn(buf, insn##op, b, c, a); \ 330 build_insn(buf, insn##op, b, c, a); \
336 } 331 }
337 332
338#define I_u1u2s3(op) \ 333#define I_u1u2s3(op) \
339 static inline void __init i##op(u32 **buf, unsigned int a, \ 334 static void __init __maybe_unused i##op(u32 **buf, unsigned int a, \
340 unsigned int b, signed int c) \ 335 unsigned int b, signed int c) \
341 { \ 336 { \
342 build_insn(buf, insn##op, a, b, c); \ 337 build_insn(buf, insn##op, a, b, c); \
343 } 338 }
344 339
345#define I_u2s3u1(op) \ 340#define I_u2s3u1(op) \
346 static inline void __init i##op(u32 **buf, unsigned int a, \ 341 static void __init __maybe_unused i##op(u32 **buf, unsigned int a, \
347 signed int b, unsigned int c) \ 342 signed int b, unsigned int c) \
348 { \ 343 { \
349 build_insn(buf, insn##op, c, a, b); \ 344 build_insn(buf, insn##op, c, a, b); \
350 } 345 }
351 346
352#define I_u2u1s3(op) \ 347#define I_u2u1s3(op) \
353 static inline void __init i##op(u32 **buf, unsigned int a, \ 348 static void __init __maybe_unused i##op(u32 **buf, unsigned int a, \
354 unsigned int b, signed int c) \ 349 unsigned int b, signed int c) \
355 { \ 350 { \
356 build_insn(buf, insn##op, b, a, c); \ 351 build_insn(buf, insn##op, b, a, c); \
357 } 352 }
358 353
359#define I_u1u2(op) \ 354#define I_u1u2(op) \
360 static inline void __init i##op(u32 **buf, unsigned int a, \ 355 static void __init __maybe_unused i##op(u32 **buf, unsigned int a, \
361 unsigned int b) \ 356 unsigned int b) \
362 { \ 357 { \
363 build_insn(buf, insn##op, a, b); \ 358 build_insn(buf, insn##op, a, b); \
364 } 359 }
365 360
366#define I_u1s2(op) \ 361#define I_u1s2(op) \
367 static inline void __init i##op(u32 **buf, unsigned int a, \ 362 static void __init __maybe_unused i##op(u32 **buf, unsigned int a, \
368 signed int b) \ 363 signed int b) \
369 { \ 364 { \
370 build_insn(buf, insn##op, a, b); \ 365 build_insn(buf, insn##op, a, b); \
371 } 366 }
372 367
373#define I_u1(op) \ 368#define I_u1(op) \
374 static inline void __init i##op(u32 **buf, unsigned int a) \ 369 static void __init __maybe_unused i##op(u32 **buf, unsigned int a) \
375 { \ 370 { \
376 build_insn(buf, insn##op, a); \ 371 build_insn(buf, insn##op, a); \
377 } 372 }
378 373
379#define I_0(op) \ 374#define I_0(op) \
380 static inline void __init i##op(u32 **buf) \ 375 static void __init __maybe_unused i##op(u32 **buf) \
381 { \ 376 { \
382 build_insn(buf, insn##op); \ 377 build_insn(buf, insn##op); \
383 } 378 }
@@ -457,7 +452,7 @@ struct label {
457 enum label_id lab; 452 enum label_id lab;
458}; 453};
459 454
460static __init void build_label(struct label **lab, u32 *addr, 455static void __init build_label(struct label **lab, u32 *addr,
461 enum label_id l) 456 enum label_id l)
462{ 457{
463 (*lab)->addr = addr; 458 (*lab)->addr = addr;
@@ -466,7 +461,7 @@ static __init void build_label(struct label **lab, u32 *addr,
466} 461}
467 462
468#define L_LA(lb) \ 463#define L_LA(lb) \
469 static inline void l##lb(struct label **lab, u32 *addr) \ 464 static inline void __init l##lb(struct label **lab, u32 *addr) \
470 { \ 465 { \
471 build_label(lab, addr, label##lb); \ 466 build_label(lab, addr, label##lb); \
472 } 467 }
@@ -525,37 +520,46 @@ L_LA(_r3000_write_probe_fail)
525#define i_ssnop(buf) i_sll(buf, 0, 0, 1) 520#define i_ssnop(buf) i_sll(buf, 0, 0, 1)
526#define i_ehb(buf) i_sll(buf, 0, 0, 3) 521#define i_ehb(buf) i_sll(buf, 0, 0, 3)
527 522
528#ifdef CONFIG_64BIT 523static int __init __maybe_unused in_compat_space_p(long addr)
529static __init int __maybe_unused in_compat_space_p(long addr)
530{ 524{
531 /* Is this address in 32bit compat space? */ 525 /* Is this address in 32bit compat space? */
526#ifdef CONFIG_64BIT
532 return (((addr) & 0xffffffff00000000L) == 0xffffffff00000000L); 527 return (((addr) & 0xffffffff00000000L) == 0xffffffff00000000L);
528#else
529 return 1;
530#endif
533} 531}
534 532
535static __init int __maybe_unused rel_highest(long val) 533static int __init __maybe_unused rel_highest(long val)
536{ 534{
535#ifdef CONFIG_64BIT
537 return ((((val + 0x800080008000L) >> 48) & 0xffff) ^ 0x8000) - 0x8000; 536 return ((((val + 0x800080008000L) >> 48) & 0xffff) ^ 0x8000) - 0x8000;
537#else
538 return 0;
539#endif
538} 540}
539 541
540static __init int __maybe_unused rel_higher(long val) 542static int __init __maybe_unused rel_higher(long val)
541{ 543{
544#ifdef CONFIG_64BIT
542 return ((((val + 0x80008000L) >> 32) & 0xffff) ^ 0x8000) - 0x8000; 545 return ((((val + 0x80008000L) >> 32) & 0xffff) ^ 0x8000) - 0x8000;
543} 546#else
547 return 0;
544#endif 548#endif
549}
545 550
546static __init int rel_hi(long val) 551static int __init rel_hi(long val)
547{ 552{
548 return ((((val + 0x8000L) >> 16) & 0xffff) ^ 0x8000) - 0x8000; 553 return ((((val + 0x8000L) >> 16) & 0xffff) ^ 0x8000) - 0x8000;
549} 554}
550 555
551static __init int rel_lo(long val) 556static int __init rel_lo(long val)
552{ 557{
553 return ((val & 0xffff) ^ 0x8000) - 0x8000; 558 return ((val & 0xffff) ^ 0x8000) - 0x8000;
554} 559}
555 560
556static __init void i_LA_mostly(u32 **buf, unsigned int rs, long addr) 561static void __init i_LA_mostly(u32 **buf, unsigned int rs, long addr)
557{ 562{
558#ifdef CONFIG_64BIT
559 if (!in_compat_space_p(addr)) { 563 if (!in_compat_space_p(addr)) {
560 i_lui(buf, rs, rel_highest(addr)); 564 i_lui(buf, rs, rel_highest(addr));
561 if (rel_higher(addr)) 565 if (rel_higher(addr))
@@ -567,16 +571,18 @@ static __init void i_LA_mostly(u32 **buf, unsigned int rs, long addr)
567 } else 571 } else
568 i_dsll32(buf, rs, rs, 0); 572 i_dsll32(buf, rs, rs, 0);
569 } else 573 } else
570#endif
571 i_lui(buf, rs, rel_hi(addr)); 574 i_lui(buf, rs, rel_hi(addr));
572} 575}
573 576
574static __init void __maybe_unused i_LA(u32 **buf, unsigned int rs, 577static void __init __maybe_unused i_LA(u32 **buf, unsigned int rs, long addr)
575 long addr)
576{ 578{
577 i_LA_mostly(buf, rs, addr); 579 i_LA_mostly(buf, rs, addr);
578 if (rel_lo(addr)) 580 if (rel_lo(addr)) {
579 i_ADDIU(buf, rs, rs, rel_lo(addr)); 581 if (!in_compat_space_p(addr))
582 i_daddiu(buf, rs, rs, rel_lo(addr));
583 else
584 i_addiu(buf, rs, rs, rel_lo(addr));
585 }
580} 586}
581 587
582/* 588/*
@@ -589,7 +595,7 @@ struct reloc {
589 enum label_id lab; 595 enum label_id lab;
590}; 596};
591 597
592static __init void r_mips_pc16(struct reloc **rel, u32 *addr, 598static void __init r_mips_pc16(struct reloc **rel, u32 *addr,
593 enum label_id l) 599 enum label_id l)
594{ 600{
595 (*rel)->addr = addr; 601 (*rel)->addr = addr;
@@ -614,7 +620,7 @@ static inline void __resolve_relocs(struct reloc *rel, struct label *lab)
614 } 620 }
615} 621}
616 622
617static __init void resolve_relocs(struct reloc *rel, struct label *lab) 623static void __init resolve_relocs(struct reloc *rel, struct label *lab)
618{ 624{
619 struct label *l; 625 struct label *l;
620 626
@@ -624,7 +630,7 @@ static __init void resolve_relocs(struct reloc *rel, struct label *lab)
624 __resolve_relocs(rel, l); 630 __resolve_relocs(rel, l);
625} 631}
626 632
627static __init void move_relocs(struct reloc *rel, u32 *first, u32 *end, 633static void __init move_relocs(struct reloc *rel, u32 *first, u32 *end,
628 long off) 634 long off)
629{ 635{
630 for (; rel->lab != label_invalid; rel++) 636 for (; rel->lab != label_invalid; rel++)
@@ -632,7 +638,7 @@ static __init void move_relocs(struct reloc *rel, u32 *first, u32 *end,
632 rel->addr += off; 638 rel->addr += off;
633} 639}
634 640
635static __init void move_labels(struct label *lab, u32 *first, u32 *end, 641static void __init move_labels(struct label *lab, u32 *first, u32 *end,
636 long off) 642 long off)
637{ 643{
638 for (; lab->lab != label_invalid; lab++) 644 for (; lab->lab != label_invalid; lab++)
@@ -640,7 +646,7 @@ static __init void move_labels(struct label *lab, u32 *first, u32 *end,
640 lab->addr += off; 646 lab->addr += off;
641} 647}
642 648
643static __init void copy_handler(struct reloc *rel, struct label *lab, 649static void __init copy_handler(struct reloc *rel, struct label *lab,
644 u32 *first, u32 *end, u32 *target) 650 u32 *first, u32 *end, u32 *target)
645{ 651{
646 long off = (long)(target - first); 652 long off = (long)(target - first);
@@ -651,7 +657,7 @@ static __init void copy_handler(struct reloc *rel, struct label *lab,
651 move_labels(lab, first, end, off); 657 move_labels(lab, first, end, off);
652} 658}
653 659
654static __init int __maybe_unused insn_has_bdelay(struct reloc *rel, 660static int __init __maybe_unused insn_has_bdelay(struct reloc *rel,
655 u32 *addr) 661 u32 *addr)
656{ 662{
657 for (; rel->lab != label_invalid; rel++) { 663 for (; rel->lab != label_invalid; rel++) {
@@ -714,6 +720,22 @@ il_bgez(u32 **p, struct reloc **r, unsigned int reg, enum label_id l)
714 i_bgez(p, reg, 0); 720 i_bgez(p, reg, 0);
715} 721}
716 722
723/*
724 * For debug purposes.
725 */
726static inline void dump_handler(const u32 *handler, int count)
727{
728 int i;
729
730 pr_debug("\t.set push\n");
731 pr_debug("\t.set noreorder\n");
732
733 for (i = 0; i < count; i++)
734 pr_debug("\t%p\t.word 0x%08x\n", &handler[i], handler[i]);
735
736 pr_debug("\t.set pop\n");
737}
738
717/* The only general purpose registers allowed in TLB handlers. */ 739/* The only general purpose registers allowed in TLB handlers. */
718#define K0 26 740#define K0 26
719#define K1 27 741#define K1 27
@@ -743,11 +765,11 @@ il_bgez(u32 **p, struct reloc **r, unsigned int reg, enum label_id l)
743 * We deliberately chose a buffer size of 128, so we won't scribble 765 * We deliberately chose a buffer size of 128, so we won't scribble
744 * over anything important on overflow before we panic. 766 * over anything important on overflow before we panic.
745 */ 767 */
746static __initdata u32 tlb_handler[128]; 768static u32 tlb_handler[128] __initdata;
747 769
748/* simply assume worst case size for labels and relocs */ 770/* simply assume worst case size for labels and relocs */
749static __initdata struct label labels[128]; 771static struct label labels[128] __initdata;
750static __initdata struct reloc relocs[128]; 772static struct reloc relocs[128] __initdata;
751 773
752/* 774/*
753 * The R3000 TLB handler is simple. 775 * The R3000 TLB handler is simple.
@@ -756,7 +778,6 @@ static void __init build_r3000_tlb_refill_handler(void)
756{ 778{
757 long pgdc = (long)pgd_current; 779 long pgdc = (long)pgd_current;
758 u32 *p; 780 u32 *p;
759 int i;
760 781
761 memset(tlb_handler, 0, sizeof(tlb_handler)); 782 memset(tlb_handler, 0, sizeof(tlb_handler));
762 p = tlb_handler; 783 p = tlb_handler;
@@ -785,13 +806,9 @@ static void __init build_r3000_tlb_refill_handler(void)
785 pr_info("Synthesized TLB refill handler (%u instructions).\n", 806 pr_info("Synthesized TLB refill handler (%u instructions).\n",
786 (unsigned int)(p - tlb_handler)); 807 (unsigned int)(p - tlb_handler));
787 808
788 pr_debug("\t.set push\n");
789 pr_debug("\t.set noreorder\n");
790 for (i = 0; i < (p - tlb_handler); i++)
791 pr_debug("\t.word 0x%08x\n", tlb_handler[i]);
792 pr_debug("\t.set pop\n");
793
794 memcpy((void *)ebase, tlb_handler, 0x80); 809 memcpy((void *)ebase, tlb_handler, 0x80);
810
811 dump_handler((u32 *)ebase, 32);
795} 812}
796 813
797/* 814/*
@@ -801,7 +818,7 @@ static void __init build_r3000_tlb_refill_handler(void)
801 * other one.To keep things simple, we first assume linear space, 818 * other one.To keep things simple, we first assume linear space,
802 * then we relocate it to the final handler layout as needed. 819 * then we relocate it to the final handler layout as needed.
803 */ 820 */
804static __initdata u32 final_handler[64]; 821static u32 final_handler[64] __initdata;
805 822
806/* 823/*
807 * Hazards 824 * Hazards
@@ -825,7 +842,7 @@ static __initdata u32 final_handler[64];
825 * 842 *
826 * As if we MIPS hackers wouldn't know how to nop pipelines happy ... 843 * As if we MIPS hackers wouldn't know how to nop pipelines happy ...
827 */ 844 */
828static __init void __maybe_unused build_tlb_probe_entry(u32 **p) 845static void __init __maybe_unused build_tlb_probe_entry(u32 **p)
829{ 846{
830 switch (current_cpu_type()) { 847 switch (current_cpu_type()) {
831 /* Found by experiment: R4600 v2.0 needs this, too. */ 848 /* Found by experiment: R4600 v2.0 needs this, too. */
@@ -849,7 +866,7 @@ static __init void __maybe_unused build_tlb_probe_entry(u32 **p)
849 */ 866 */
850enum tlb_write_entry { tlb_random, tlb_indexed }; 867enum tlb_write_entry { tlb_random, tlb_indexed };
851 868
852static __init void build_tlb_write_entry(u32 **p, struct label **l, 869static void __init build_tlb_write_entry(u32 **p, struct label **l,
853 struct reloc **r, 870 struct reloc **r,
854 enum tlb_write_entry wmode) 871 enum tlb_write_entry wmode)
855{ 872{
@@ -860,6 +877,12 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l,
860 case tlb_indexed: tlbw = i_tlbwi; break; 877 case tlb_indexed: tlbw = i_tlbwi; break;
861 } 878 }
862 879
880 if (cpu_has_mips_r2) {
881 i_ehb(p);
882 tlbw(p);
883 return;
884 }
885
863 switch (current_cpu_type()) { 886 switch (current_cpu_type()) {
864 case CPU_R4000PC: 887 case CPU_R4000PC:
865 case CPU_R4000SC: 888 case CPU_R4000SC:
@@ -894,6 +917,8 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l,
894 case CPU_AU1500: 917 case CPU_AU1500:
895 case CPU_AU1550: 918 case CPU_AU1550:
896 case CPU_AU1200: 919 case CPU_AU1200:
920 case CPU_AU1210:
921 case CPU_AU1250:
897 case CPU_PR4450: 922 case CPU_PR4450:
898 i_nop(p); 923 i_nop(p);
899 tlbw(p); 924 tlbw(p);
@@ -935,14 +960,6 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l,
935 tlbw(p); 960 tlbw(p);
936 break; 961 break;
937 962
938 case CPU_4KEC:
939 case CPU_24K:
940 case CPU_34K:
941 case CPU_74K:
942 i_ehb(p);
943 tlbw(p);
944 break;
945
946 case CPU_RM9000: 963 case CPU_RM9000:
947 /* 964 /*
948 * When the JTLB is updated by tlbwi or tlbwr, a subsequent 965 * When the JTLB is updated by tlbwi or tlbwr, a subsequent
@@ -993,7 +1010,7 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l,
993 * TMP and PTR are scratch. 1010 * TMP and PTR are scratch.
994 * TMP will be clobbered, PTR will hold the pmd entry. 1011 * TMP will be clobbered, PTR will hold the pmd entry.
995 */ 1012 */
996static __init void 1013static void __init
997build_get_pmde64(u32 **p, struct label **l, struct reloc **r, 1014build_get_pmde64(u32 **p, struct label **l, struct reloc **r,
998 unsigned int tmp, unsigned int ptr) 1015 unsigned int tmp, unsigned int ptr)
999{ 1016{
@@ -1054,7 +1071,7 @@ build_get_pmde64(u32 **p, struct label **l, struct reloc **r,
1054 * BVADDR is the faulting address, PTR is scratch. 1071 * BVADDR is the faulting address, PTR is scratch.
1055 * PTR will hold the pgd for vmalloc. 1072 * PTR will hold the pgd for vmalloc.
1056 */ 1073 */
1057static __init void 1074static void __init
1058build_get_pgd_vmalloc64(u32 **p, struct label **l, struct reloc **r, 1075build_get_pgd_vmalloc64(u32 **p, struct label **l, struct reloc **r,
1059 unsigned int bvaddr, unsigned int ptr) 1076 unsigned int bvaddr, unsigned int ptr)
1060{ 1077{
@@ -1087,7 +1104,10 @@ build_get_pgd_vmalloc64(u32 **p, struct label **l, struct reloc **r,
1087 } else { 1104 } else {
1088 i_LA_mostly(p, ptr, modd); 1105 i_LA_mostly(p, ptr, modd);
1089 il_b(p, r, label_vmalloc_done); 1106 il_b(p, r, label_vmalloc_done);
1090 i_daddiu(p, ptr, ptr, rel_lo(modd)); 1107 if (in_compat_space_p(modd))
1108 i_addiu(p, ptr, ptr, rel_lo(modd));
1109 else
1110 i_daddiu(p, ptr, ptr, rel_lo(modd));
1091 } 1111 }
1092 1112
1093 l_vmalloc(l, *p); 1113 l_vmalloc(l, *p);
@@ -1108,7 +1128,10 @@ build_get_pgd_vmalloc64(u32 **p, struct label **l, struct reloc **r,
1108 } else { 1128 } else {
1109 i_LA_mostly(p, ptr, swpd); 1129 i_LA_mostly(p, ptr, swpd);
1110 il_b(p, r, label_vmalloc_done); 1130 il_b(p, r, label_vmalloc_done);
1111 i_daddiu(p, ptr, ptr, rel_lo(swpd)); 1131 if (in_compat_space_p(swpd))
1132 i_addiu(p, ptr, ptr, rel_lo(swpd));
1133 else
1134 i_daddiu(p, ptr, ptr, rel_lo(swpd));
1112 } 1135 }
1113} 1136}
1114 1137
@@ -1118,7 +1141,7 @@ build_get_pgd_vmalloc64(u32 **p, struct label **l, struct reloc **r,
1118 * TMP and PTR are scratch. 1141 * TMP and PTR are scratch.
1119 * TMP will be clobbered, PTR will hold the pgd entry. 1142 * TMP will be clobbered, PTR will hold the pgd entry.
1120 */ 1143 */
1121static __init void __maybe_unused 1144static void __init __maybe_unused
1122build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr) 1145build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr)
1123{ 1146{
1124 long pgdc = (long)pgd_current; 1147 long pgdc = (long)pgd_current;
@@ -1153,7 +1176,7 @@ build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr)
1153 1176
1154#endif /* !CONFIG_64BIT */ 1177#endif /* !CONFIG_64BIT */
1155 1178
1156static __init void build_adjust_context(u32 **p, unsigned int ctx) 1179static void __init build_adjust_context(u32 **p, unsigned int ctx)
1157{ 1180{
1158 unsigned int shift = 4 - (PTE_T_LOG2 + 1) + PAGE_SHIFT - 12; 1181 unsigned int shift = 4 - (PTE_T_LOG2 + 1) + PAGE_SHIFT - 12;
1159 unsigned int mask = (PTRS_PER_PTE / 2 - 1) << (PTE_T_LOG2 + 1); 1182 unsigned int mask = (PTRS_PER_PTE / 2 - 1) << (PTE_T_LOG2 + 1);
@@ -1179,7 +1202,7 @@ static __init void build_adjust_context(u32 **p, unsigned int ctx)
1179 i_andi(p, ctx, ctx, mask); 1202 i_andi(p, ctx, ctx, mask);
1180} 1203}
1181 1204
1182static __init void build_get_ptep(u32 **p, unsigned int tmp, unsigned int ptr) 1205static void __init build_get_ptep(u32 **p, unsigned int tmp, unsigned int ptr)
1183{ 1206{
1184 /* 1207 /*
1185 * Bug workaround for the Nevada. It seems as if under certain 1208 * Bug workaround for the Nevada. It seems as if under certain
@@ -1204,7 +1227,7 @@ static __init void build_get_ptep(u32 **p, unsigned int tmp, unsigned int ptr)
1204 i_ADDU(p, ptr, ptr, tmp); /* add in offset */ 1227 i_ADDU(p, ptr, ptr, tmp); /* add in offset */
1205} 1228}
1206 1229
1207static __init void build_update_entries(u32 **p, unsigned int tmp, 1230static void __init build_update_entries(u32 **p, unsigned int tmp,
1208 unsigned int ptep) 1231 unsigned int ptep)
1209{ 1232{
1210 /* 1233 /*
@@ -1254,7 +1277,6 @@ static void __init build_r4000_tlb_refill_handler(void)
1254 struct reloc *r = relocs; 1277 struct reloc *r = relocs;
1255 u32 *f; 1278 u32 *f;
1256 unsigned int final_len; 1279 unsigned int final_len;
1257 int i;
1258 1280
1259 memset(tlb_handler, 0, sizeof(tlb_handler)); 1281 memset(tlb_handler, 0, sizeof(tlb_handler));
1260 memset(labels, 0, sizeof(labels)); 1282 memset(labels, 0, sizeof(labels));
@@ -1356,20 +1378,9 @@ static void __init build_r4000_tlb_refill_handler(void)
1356 pr_info("Synthesized TLB refill handler (%u instructions).\n", 1378 pr_info("Synthesized TLB refill handler (%u instructions).\n",
1357 final_len); 1379 final_len);
1358 1380
1359 f = final_handler;
1360#if defined(CONFIG_64BIT) && !defined(CONFIG_CPU_LOONGSON2)
1361 if (final_len > 32)
1362 final_len = 64;
1363 else
1364 f = final_handler + 32;
1365#endif /* CONFIG_64BIT */
1366 pr_debug("\t.set push\n");
1367 pr_debug("\t.set noreorder\n");
1368 for (i = 0; i < final_len; i++)
1369 pr_debug("\t.word 0x%08x\n", f[i]);
1370 pr_debug("\t.set pop\n");
1371
1372 memcpy((void *)ebase, final_handler, 0x100); 1381 memcpy((void *)ebase, final_handler, 0x100);
1382
1383 dump_handler((u32 *)ebase, 64);
1373} 1384}
1374 1385
1375/* 1386/*
@@ -1381,18 +1392,15 @@ static void __init build_r4000_tlb_refill_handler(void)
1381extern void tlb_do_page_fault_0(void); 1392extern void tlb_do_page_fault_0(void);
1382extern void tlb_do_page_fault_1(void); 1393extern void tlb_do_page_fault_1(void);
1383 1394
1384#define __tlb_handler_align \
1385 __attribute__((__aligned__(1 << CONFIG_MIPS_L1_CACHE_SHIFT)))
1386
1387/* 1395/*
1388 * 128 instructions for the fastpath handler is generous and should 1396 * 128 instructions for the fastpath handler is generous and should
1389 * never be exceeded. 1397 * never be exceeded.
1390 */ 1398 */
1391#define FASTPATH_SIZE 128 1399#define FASTPATH_SIZE 128
1392 1400
1393u32 __tlb_handler_align handle_tlbl[FASTPATH_SIZE]; 1401u32 handle_tlbl[FASTPATH_SIZE] __cacheline_aligned;
1394u32 __tlb_handler_align handle_tlbs[FASTPATH_SIZE]; 1402u32 handle_tlbs[FASTPATH_SIZE] __cacheline_aligned;
1395u32 __tlb_handler_align handle_tlbm[FASTPATH_SIZE]; 1403u32 handle_tlbm[FASTPATH_SIZE] __cacheline_aligned;
1396 1404
1397static void __init 1405static void __init
1398iPTE_LW(u32 **p, struct label **l, unsigned int pte, unsigned int ptr) 1406iPTE_LW(u32 **p, struct label **l, unsigned int pte, unsigned int ptr)
@@ -1600,7 +1608,6 @@ static void __init build_r3000_tlb_load_handler(void)
1600 u32 *p = handle_tlbl; 1608 u32 *p = handle_tlbl;
1601 struct label *l = labels; 1609 struct label *l = labels;
1602 struct reloc *r = relocs; 1610 struct reloc *r = relocs;
1603 int i;
1604 1611
1605 memset(handle_tlbl, 0, sizeof(handle_tlbl)); 1612 memset(handle_tlbl, 0, sizeof(handle_tlbl));
1606 memset(labels, 0, sizeof(labels)); 1613 memset(labels, 0, sizeof(labels));
@@ -1623,11 +1630,7 @@ static void __init build_r3000_tlb_load_handler(void)
1623 pr_info("Synthesized TLB load handler fastpath (%u instructions).\n", 1630 pr_info("Synthesized TLB load handler fastpath (%u instructions).\n",
1624 (unsigned int)(p - handle_tlbl)); 1631 (unsigned int)(p - handle_tlbl));
1625 1632
1626 pr_debug("\t.set push\n"); 1633 dump_handler(handle_tlbl, ARRAY_SIZE(handle_tlbl));
1627 pr_debug("\t.set noreorder\n");
1628 for (i = 0; i < (p - handle_tlbl); i++)
1629 pr_debug("\t.word 0x%08x\n", handle_tlbl[i]);
1630 pr_debug("\t.set pop\n");
1631} 1634}
1632 1635
1633static void __init build_r3000_tlb_store_handler(void) 1636static void __init build_r3000_tlb_store_handler(void)
@@ -1635,7 +1638,6 @@ static void __init build_r3000_tlb_store_handler(void)
1635 u32 *p = handle_tlbs; 1638 u32 *p = handle_tlbs;
1636 struct label *l = labels; 1639 struct label *l = labels;
1637 struct reloc *r = relocs; 1640 struct reloc *r = relocs;
1638 int i;
1639 1641
1640 memset(handle_tlbs, 0, sizeof(handle_tlbs)); 1642 memset(handle_tlbs, 0, sizeof(handle_tlbs));
1641 memset(labels, 0, sizeof(labels)); 1643 memset(labels, 0, sizeof(labels));
@@ -1658,11 +1660,7 @@ static void __init build_r3000_tlb_store_handler(void)
1658 pr_info("Synthesized TLB store handler fastpath (%u instructions).\n", 1660 pr_info("Synthesized TLB store handler fastpath (%u instructions).\n",
1659 (unsigned int)(p - handle_tlbs)); 1661 (unsigned int)(p - handle_tlbs));
1660 1662
1661 pr_debug("\t.set push\n"); 1663 dump_handler(handle_tlbs, ARRAY_SIZE(handle_tlbs));
1662 pr_debug("\t.set noreorder\n");
1663 for (i = 0; i < (p - handle_tlbs); i++)
1664 pr_debug("\t.word 0x%08x\n", handle_tlbs[i]);
1665 pr_debug("\t.set pop\n");
1666} 1664}
1667 1665
1668static void __init build_r3000_tlb_modify_handler(void) 1666static void __init build_r3000_tlb_modify_handler(void)
@@ -1670,7 +1668,6 @@ static void __init build_r3000_tlb_modify_handler(void)
1670 u32 *p = handle_tlbm; 1668 u32 *p = handle_tlbm;
1671 struct label *l = labels; 1669 struct label *l = labels;
1672 struct reloc *r = relocs; 1670 struct reloc *r = relocs;
1673 int i;
1674 1671
1675 memset(handle_tlbm, 0, sizeof(handle_tlbm)); 1672 memset(handle_tlbm, 0, sizeof(handle_tlbm));
1676 memset(labels, 0, sizeof(labels)); 1673 memset(labels, 0, sizeof(labels));
@@ -1693,11 +1690,7 @@ static void __init build_r3000_tlb_modify_handler(void)
1693 pr_info("Synthesized TLB modify handler fastpath (%u instructions).\n", 1690 pr_info("Synthesized TLB modify handler fastpath (%u instructions).\n",
1694 (unsigned int)(p - handle_tlbm)); 1691 (unsigned int)(p - handle_tlbm));
1695 1692
1696 pr_debug("\t.set push\n"); 1693 dump_handler(handle_tlbm, ARRAY_SIZE(handle_tlbm));
1697 pr_debug("\t.set noreorder\n");
1698 for (i = 0; i < (p - handle_tlbm); i++)
1699 pr_debug("\t.word 0x%08x\n", handle_tlbm[i]);
1700 pr_debug("\t.set pop\n");
1701} 1694}
1702 1695
1703/* 1696/*
@@ -1750,7 +1743,6 @@ static void __init build_r4000_tlb_load_handler(void)
1750 u32 *p = handle_tlbl; 1743 u32 *p = handle_tlbl;
1751 struct label *l = labels; 1744 struct label *l = labels;
1752 struct reloc *r = relocs; 1745 struct reloc *r = relocs;
1753 int i;
1754 1746
1755 memset(handle_tlbl, 0, sizeof(handle_tlbl)); 1747 memset(handle_tlbl, 0, sizeof(handle_tlbl));
1756 memset(labels, 0, sizeof(labels)); 1748 memset(labels, 0, sizeof(labels));
@@ -1783,11 +1775,7 @@ static void __init build_r4000_tlb_load_handler(void)
1783 pr_info("Synthesized TLB load handler fastpath (%u instructions).\n", 1775 pr_info("Synthesized TLB load handler fastpath (%u instructions).\n",
1784 (unsigned int)(p - handle_tlbl)); 1776 (unsigned int)(p - handle_tlbl));
1785 1777
1786 pr_debug("\t.set push\n"); 1778 dump_handler(handle_tlbl, ARRAY_SIZE(handle_tlbl));
1787 pr_debug("\t.set noreorder\n");
1788 for (i = 0; i < (p - handle_tlbl); i++)
1789 pr_debug("\t.word 0x%08x\n", handle_tlbl[i]);
1790 pr_debug("\t.set pop\n");
1791} 1779}
1792 1780
1793static void __init build_r4000_tlb_store_handler(void) 1781static void __init build_r4000_tlb_store_handler(void)
@@ -1795,7 +1783,6 @@ static void __init build_r4000_tlb_store_handler(void)
1795 u32 *p = handle_tlbs; 1783 u32 *p = handle_tlbs;
1796 struct label *l = labels; 1784 struct label *l = labels;
1797 struct reloc *r = relocs; 1785 struct reloc *r = relocs;
1798 int i;
1799 1786
1800 memset(handle_tlbs, 0, sizeof(handle_tlbs)); 1787 memset(handle_tlbs, 0, sizeof(handle_tlbs));
1801 memset(labels, 0, sizeof(labels)); 1788 memset(labels, 0, sizeof(labels));
@@ -1819,11 +1806,7 @@ static void __init build_r4000_tlb_store_handler(void)
1819 pr_info("Synthesized TLB store handler fastpath (%u instructions).\n", 1806 pr_info("Synthesized TLB store handler fastpath (%u instructions).\n",
1820 (unsigned int)(p - handle_tlbs)); 1807 (unsigned int)(p - handle_tlbs));
1821 1808
1822 pr_debug("\t.set push\n"); 1809 dump_handler(handle_tlbs, ARRAY_SIZE(handle_tlbs));
1823 pr_debug("\t.set noreorder\n");
1824 for (i = 0; i < (p - handle_tlbs); i++)
1825 pr_debug("\t.word 0x%08x\n", handle_tlbs[i]);
1826 pr_debug("\t.set pop\n");
1827} 1810}
1828 1811
1829static void __init build_r4000_tlb_modify_handler(void) 1812static void __init build_r4000_tlb_modify_handler(void)
@@ -1831,7 +1814,6 @@ static void __init build_r4000_tlb_modify_handler(void)
1831 u32 *p = handle_tlbm; 1814 u32 *p = handle_tlbm;
1832 struct label *l = labels; 1815 struct label *l = labels;
1833 struct reloc *r = relocs; 1816 struct reloc *r = relocs;
1834 int i;
1835 1817
1836 memset(handle_tlbm, 0, sizeof(handle_tlbm)); 1818 memset(handle_tlbm, 0, sizeof(handle_tlbm));
1837 memset(labels, 0, sizeof(labels)); 1819 memset(labels, 0, sizeof(labels));
@@ -1856,11 +1838,7 @@ static void __init build_r4000_tlb_modify_handler(void)
1856 pr_info("Synthesized TLB modify handler fastpath (%u instructions).\n", 1838 pr_info("Synthesized TLB modify handler fastpath (%u instructions).\n",
1857 (unsigned int)(p - handle_tlbm)); 1839 (unsigned int)(p - handle_tlbm));
1858 1840
1859 pr_debug("\t.set push\n"); 1841 dump_handler(handle_tlbm, ARRAY_SIZE(handle_tlbm));
1860 pr_debug("\t.set noreorder\n");
1861 for (i = 0; i < (p - handle_tlbm); i++)
1862 pr_debug("\t.word 0x%08x\n", handle_tlbm[i]);
1863 pr_debug("\t.set pop\n");
1864} 1842}
1865 1843
1866void __init build_tlb_refill_handler(void) 1844void __init build_tlb_refill_handler(void)
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c
index bdfa07aecd97..ccbea229a0e6 100644
--- a/arch/mips/oprofile/op_model_mipsxx.c
+++ b/arch/mips/oprofile/op_model_mipsxx.c
@@ -19,7 +19,7 @@
19#define M_PERFCTL_SUPERVISOR (1UL << 2) 19#define M_PERFCTL_SUPERVISOR (1UL << 2)
20#define M_PERFCTL_USER (1UL << 3) 20#define M_PERFCTL_USER (1UL << 3)
21#define M_PERFCTL_INTERRUPT_ENABLE (1UL << 4) 21#define M_PERFCTL_INTERRUPT_ENABLE (1UL << 4)
22#define M_PERFCTL_EVENT(event) (((event) & 0x3f) << 5) 22#define M_PERFCTL_EVENT(event) (((event) & 0x3ff) << 5)
23#define M_PERFCTL_VPEID(vpe) ((vpe) << 16) 23#define M_PERFCTL_VPEID(vpe) ((vpe) << 16)
24#define M_PERFCTL_MT_EN(filter) ((filter) << 20) 24#define M_PERFCTL_MT_EN(filter) ((filter) << 20)
25#define M_TC_EN_ALL M_PERFCTL_MT_EN(0) 25#define M_TC_EN_ALL M_PERFCTL_MT_EN(0)
diff --git a/arch/mips/pci/pci-bcm1480.c b/arch/mips/pci/pci-bcm1480.c
index 47f316c86ab1..30ed36125bcd 100644
--- a/arch/mips/pci/pci-bcm1480.c
+++ b/arch/mips/pci/pci-bcm1480.c
@@ -178,8 +178,8 @@ struct pci_ops bcm1480_pci_ops = {
178 178
179static struct resource bcm1480_mem_resource = { 179static struct resource bcm1480_mem_resource = {
180 .name = "BCM1480 PCI MEM", 180 .name = "BCM1480 PCI MEM",
181 .start = 0x30000000UL, 181 .start = A_BCM1480_PHYS_PCI_MEM_MATCH_BYTES,
182 .end = 0x3fffffffUL, 182 .end = A_BCM1480_PHYS_PCI_MEM_MATCH_BYTES + 0xfffffffUL,
183 .flags = IORESOURCE_MEM, 183 .flags = IORESOURCE_MEM,
184}; 184};
185 185
diff --git a/arch/mips/pci/pci-bcm1480ht.c b/arch/mips/pci/pci-bcm1480ht.c
index a63e3bd6b0ac..005e7fecab08 100644
--- a/arch/mips/pci/pci-bcm1480ht.c
+++ b/arch/mips/pci/pci-bcm1480ht.c
@@ -173,8 +173,8 @@ struct pci_ops bcm1480ht_pci_ops = {
173 173
174static struct resource bcm1480ht_mem_resource = { 174static struct resource bcm1480ht_mem_resource = {
175 .name = "BCM1480 HT MEM", 175 .name = "BCM1480 HT MEM",
176 .start = 0x40000000UL, 176 .start = A_BCM1480_PHYS_HT_MEM_MATCH_BYTES,
177 .end = 0x5fffffffUL, 177 .end = A_BCM1480_PHYS_HT_MEM_MATCH_BYTES + 0x1fffffffUL,
178 .flags = IORESOURCE_MEM, 178 .flags = IORESOURCE_MEM,
179}; 179};
180 180
diff --git a/arch/mips/philips/pnx8550/common/setup.c b/arch/mips/philips/pnx8550/common/setup.c
index 2ce298f4d19a..92d764c97701 100644
--- a/arch/mips/philips/pnx8550/common/setup.c
+++ b/arch/mips/philips/pnx8550/common/setup.c
@@ -74,7 +74,7 @@ struct resource standard_io_resources[] = {
74 }, 74 },
75}; 75};
76 76
77#define STANDARD_IO_RESOURCES (sizeof(standard_io_resources)/sizeof(struct resource)) 77#define STANDARD_IO_RESOURCES ARRAY_SIZE(standard_io_resources)
78 78
79extern struct resource pci_io_resource; 79extern struct resource pci_io_resource;
80extern struct resource pci_mem_resource; 80extern struct resource pci_mem_resource;
diff --git a/arch/mips/philips/pnx8550/common/time.c b/arch/mips/philips/pnx8550/common/time.c
index 6d494e0de3d9..62f495b57f93 100644
--- a/arch/mips/philips/pnx8550/common/time.c
+++ b/arch/mips/philips/pnx8550/common/time.c
@@ -47,11 +47,6 @@ static struct clocksource pnx_clocksource = {
47 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 47 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
48}; 48};
49 49
50static void timer_ack(void)
51{
52 write_c0_compare(cpj);
53}
54
55static irqreturn_t pnx8xxx_timer_interrupt(int irq, void *dev_id) 50static irqreturn_t pnx8xxx_timer_interrupt(int irq, void *dev_id)
56{ 51{
57 struct clock_event_device *c = dev_id; 52 struct clock_event_device *c = dev_id;
@@ -94,30 +89,22 @@ static struct clock_event_device pnx8xxx_clockevent = {
94 .set_next_event = pnx8xxx_set_next_event, 89 .set_next_event = pnx8xxx_set_next_event,
95}; 90};
96 91
97/* 92static inline void timer_ack(void)
98 * plat_time_init() - it does the following things: 93{
99 * 94 write_c0_compare(cpj);
100 * 1) plat_time_init() - 95}
101 * a) (optional) set up RTC routines,
102 * b) (optional) calibrate and set the mips_hpt_frequency
103 * (only needed if you intended to use cpu counter as timer interrupt
104 * source)
105 */
106 96
107__init void plat_time_init(void) 97__init void plat_time_init(void)
108{ 98{
109 unsigned int configPR; 99 unsigned int configPR;
110 unsigned int n; 100 unsigned int n;
111 unsigned int m; 101 unsigned int m;
112 unsigned int p; 102 unsigned int p;
113 unsigned int pow2p; 103 unsigned int pow2p;
114 104
115 clockevents_register_device(&pnx8xxx_clockevent); 105 clockevents_register_device(&pnx8xxx_clockevent);
116 clocksource_register(&pnx_clocksource); 106 clocksource_register(&pnx_clocksource);
117 107
118 setup_irq(PNX8550_INT_TIMER1, &pnx8xxx_timer_irq);
119 setup_irq(PNX8550_INT_TIMER2, &monotonic_irqaction);
120
121 /* Timer 1 start */ 108 /* Timer 1 start */
122 configPR = read_c0_config7(); 109 configPR = read_c0_config7();
123 configPR &= ~0x00000008; 110 configPR &= ~0x00000008;
@@ -158,6 +145,6 @@ __init void plat_time_init(void)
158 write_c0_count2(0); 145 write_c0_count2(0);
159 write_c0_compare2(0xffffffff); 146 write_c0_compare2(0xffffffff);
160 147
148 setup_irq(PNX8550_INT_TIMER1, &pnx8xxx_timer_irq);
149 setup_irq(PNX8550_INT_TIMER2, &monotonic_irqaction);
161} 150}
162
163
diff --git a/arch/mips/philips/pnx8550/jbs/init.c b/arch/mips/philips/pnx8550/jbs/init.c
index cfd90fa3d799..90b4d35f3ece 100644
--- a/arch/mips/philips/pnx8550/jbs/init.c
+++ b/arch/mips/philips/pnx8550/jbs/init.c
@@ -45,11 +45,8 @@ const char *get_system_type(void)
45 45
46void __init prom_init(void) 46void __init prom_init(void)
47{ 47{
48
49 unsigned long memsize; 48 unsigned long memsize;
50 49
51 mips_machtype = MACH_PHILIPS_JBS;
52
53 //memsize = 0x02800000; /* Trimedia uses memory above */ 50 //memsize = 0x02800000; /* Trimedia uses memory above */
54 memsize = 0x08000000; /* Trimedia uses memory above */ 51 memsize = 0x08000000; /* Trimedia uses memory above */
55 add_memory_region(0, memsize, BOOT_MEM_RAM); 52 add_memory_region(0, memsize, BOOT_MEM_RAM);
diff --git a/arch/mips/philips/pnx8550/stb810/prom_init.c b/arch/mips/philips/pnx8550/stb810/prom_init.c
index fdb33ed089b9..832dd60b0a7a 100644
--- a/arch/mips/philips/pnx8550/stb810/prom_init.c
+++ b/arch/mips/philips/pnx8550/stb810/prom_init.c
@@ -41,8 +41,6 @@ void __init prom_init(void)
41 41
42 prom_init_cmdline(); 42 prom_init_cmdline();
43 43
44 mips_machtype = MACH_PHILIPS_STB810;
45
46 memsize = 0x08000000; /* Trimedia uses memory above */ 44 memsize = 0x08000000; /* Trimedia uses memory above */
47 add_memory_region(0, memsize, BOOT_MEM_RAM); 45 add_memory_region(0, memsize, BOOT_MEM_RAM);
48} 46}
diff --git a/arch/mips/pmc-sierra/yosemite/i2c-yosemite.h b/arch/mips/pmc-sierra/yosemite/i2c-yosemite.h
deleted file mode 100644
index 31c5523276fa..000000000000
--- a/arch/mips/pmc-sierra/yosemite/i2c-yosemite.h
+++ /dev/null
@@ -1,96 +0,0 @@
1/*
2 * arch/mips/pmc-sierra/yosemite/i2c-yosemite.h
3 *
4 * Copyright (C) 2003 PMC-Sierra Inc.
5 * Author: Manish Lachwani (lachwani@pmc-sierra.com)
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
13 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
15 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
16 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
17 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
18 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
19 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
21 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22 *
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27
28#ifndef __I2C_YOSEMITE_H
29#define __I2C_YOSEMITE_H
30
31/* Read and Write operations to the chip */
32
33#define TITAN_I2C_BASE 0xbb000000 /* XXX Needs to change */
34
35#define TITAN_I2C_WRITE(offset, data) \
36 *(volatile unsigned long *)(TITAN_I2C_BASE + offset) = data
37
38#define TITAN_I2C_READ(offset) *(volatile unsigned long *)(TITAN_I2C_BASE + offset)
39
40
41/* Local constansts*/
42#define TITAN_I2C_MAX_FILTER 15
43#define TITAN_I2C_MAX_CLK 1023
44#define TITAN_I2C_MAX_ARBF 15
45#define TITAN_I2C_MAX_NAK 15
46#define TITAN_I2C_MAX_MASTERCODE 7
47#define TITAN_I2C_MAX_WORDS_PER_RW 4
48#define TITAN_I2C_MAX_POLL 100
49
50/* Registers used for I2C work */
51#define TITAN_I2C_SCMB_CONTROL 0x0180 /* SCMB Control */
52#define TITAN_I2C_SCMB_CLOCK_A 0x0184 /* SCMB Clock A */
53#define TITAN_I2C_SCMB_CLOCK_B 0x0188 /* SCMB Clock B */
54#define TITAN_I2C_CONFIG 0x01A0 /* I2C Config */
55#define TITAN_I2C_COMMAND 0x01A4 /* I2C Command */
56#define TITAN_I2C_SLAVE_ADDRESS 0x01A8 /* I2C Slave Address */
57#define TITAN_I2C_DATA 0x01AC /* I2C Data [15:0] */
58#define TITAN_I2C_INTERRUPTS 0x01BC /* I2C Interrupts */
59
60/* Error */
61#define TITAN_I2C_ERR_ARB_LOST (-9220)
62#define TITAN_I2C_ERR_NO_RESP (-9221)
63#define TITAN_I2C_ERR_DATA_COLLISION (-9222)
64#define TITAN_I2C_ERR_TIMEOUT (-9223)
65#define TITAN_I2C_ERR_OK 0
66
67/* I2C Command Type */
68typedef enum {
69 TITAN_I2C_CMD_WRITE = 0,
70 TITAN_I2C_CMD_READ = 1,
71 TITAN_I2C_CMD_READ_WRITE = 2
72} titan_i2c_cmd_type;
73
74/* I2C structures */
75typedef struct {
76 int filtera; /* Register 0x0184, bits 15 - 12 */
77 int clka; /* Register 0x0184, bits 9 - 0 */
78 int filterb; /* Register 0x0188, bits 15 - 12 */
79 int clkb; /* Register 0x0188, bits 9 - 0 */
80} titan_i2c_config;
81
82/* I2C command type */
83typedef struct {
84 titan_i2c_cmd_type type; /* Type of command */
85 int num_arb; /* Register 0x01a0, bits 15 - 12 */
86 int num_nak; /* Register 0x01a0, bits 11 - 8 */
87 int addr_size; /* Register 0x01a0, bit 7 */
88 int mst_code; /* Register 0x01a0, bits 6 - 4 */
89 int arb_en; /* Register 0x01a0, bit 1 */
90 int speed; /* Register 0x01a0, bit 0 */
91 int slave_addr; /* Register 0x01a8 */
92 int write_size; /* Register 0x01a4, bits 10 - 8 */
93 unsigned int *data; /* Register 0x01ac */
94} titan_i2c_command;
95
96#endif /* __I2C_YOSEMITE_H */
diff --git a/arch/mips/pmc-sierra/yosemite/prom.c b/arch/mips/pmc-sierra/yosemite/prom.c
index 9b9936de6589..35dc435846a6 100644
--- a/arch/mips/pmc-sierra/yosemite/prom.c
+++ b/arch/mips/pmc-sierra/yosemite/prom.c
@@ -19,6 +19,7 @@
19#include <asm/pgtable.h> 19#include <asm/pgtable.h>
20#include <asm/processor.h> 20#include <asm/processor.h>
21#include <asm/reboot.h> 21#include <asm/reboot.h>
22#include <asm/smp-ops.h>
22#include <asm/system.h> 23#include <asm/system.h>
23#include <asm/bootinfo.h> 24#include <asm/bootinfo.h>
24#include <asm/pmon.h> 25#include <asm/pmon.h>
@@ -78,6 +79,8 @@ static void prom_halt(void)
78 __asm__(".set\tmips3\n\t" "wait\n\t" ".set\tmips0"); 79 __asm__(".set\tmips3\n\t" "wait\n\t" ".set\tmips0");
79} 80}
80 81
82extern struct plat_smp_ops yos_smp_ops;
83
81/* 84/*
82 * Init routine which accepts the variables from PMON 85 * Init routine which accepts the variables from PMON
83 */ 86 */
@@ -126,9 +129,9 @@ void __init prom_init(void)
126 env++; 129 env++;
127 } 130 }
128 131
129 mips_machtype = MACH_TITAN_YOSEMITE;
130
131 prom_grab_secondary(); 132 prom_grab_secondary();
133
134 register_smp_ops(&yos_smp_ops);
132} 135}
133 136
134void __init prom_free_prom_memory(void) 137void __init prom_free_prom_memory(void)
diff --git a/arch/mips/pmc-sierra/yosemite/smp.c b/arch/mips/pmc-sierra/yosemite/smp.c
index b0f12cd2968a..653f3ec61cab 100644
--- a/arch/mips/pmc-sierra/yosemite/smp.c
+++ b/arch/mips/pmc-sierra/yosemite/smp.c
@@ -42,70 +42,6 @@ void __init prom_grab_secondary(void)
42 launchstack + LAUNCHSTACK_SIZE, 0); 42 launchstack + LAUNCHSTACK_SIZE, 0);
43} 43}
44 44
45/*
46 * Detect available CPUs, populate phys_cpu_present_map before smp_init
47 *
48 * We don't want to start the secondary CPU yet nor do we have a nice probing
49 * feature in PMON so we just assume presence of the secondary core.
50 */
51void __init plat_smp_setup(void)
52{
53 int i;
54
55 cpus_clear(phys_cpu_present_map);
56
57 for (i = 0; i < 2; i++) {
58 cpu_set(i, phys_cpu_present_map);
59 __cpu_number_map[i] = i;
60 __cpu_logical_map[i] = i;
61 }
62}
63
64void __init plat_prepare_cpus(unsigned int max_cpus)
65{
66 /*
67 * Be paranoid. Enable the IPI only if we're really about to go SMP.
68 */
69 if (cpus_weight(cpu_possible_map))
70 set_c0_status(STATUSF_IP5);
71}
72
73/*
74 * Firmware CPU startup hook
75 * Complicated by PMON's weird interface which tries to minimic the UNIX fork.
76 * It launches the next * available CPU and copies some information on the
77 * stack so the first thing we do is throw away that stuff and load useful
78 * values into the registers ...
79 */
80void __cpuinit prom_boot_secondary(int cpu, struct task_struct *idle)
81{
82 unsigned long gp = (unsigned long) task_thread_info(idle);
83 unsigned long sp = __KSTK_TOS(idle);
84
85 secondary_sp = sp;
86 secondary_gp = gp;
87
88 spin_unlock(&launch_lock);
89}
90
91/* Hook for after all CPUs are online */
92void prom_cpus_done(void)
93{
94}
95
96/*
97 * After we've done initial boot, this function is called to allow the
98 * board code to clean up state, if needed
99 */
100void __cpuinit prom_init_secondary(void)
101{
102 set_c0_status(ST0_CO | ST0_IE | ST0_IM);
103}
104
105void __cpuinit prom_smp_finish(void)
106{
107}
108
109void titan_mailbox_irq(void) 45void titan_mailbox_irq(void)
110{ 46{
111 int cpu = smp_processor_id(); 47 int cpu = smp_processor_id();
@@ -133,7 +69,7 @@ void titan_mailbox_irq(void)
133/* 69/*
134 * Send inter-processor interrupt 70 * Send inter-processor interrupt
135 */ 71 */
136void core_send_ipi(int cpu, unsigned int action) 72static void yos_send_ipi_single(int cpu, unsigned int action)
137{ 73{
138 /* 74 /*
139 * Generate an INTMSG so that it can be sent over to the 75 * Generate an INTMSG so that it can be sent over to the
@@ -159,3 +95,86 @@ void core_send_ipi(int cpu, unsigned int action)
159 break; 95 break;
160 } 96 }
161} 97}
98
99static void yos_send_ipi_mask(cpumask_t mask, unsigned int action)
100{
101 unsigned int i;
102
103 for_each_cpu_mask(i, mask)
104 yos_send_ipi_single(i, action);
105}
106
107/*
108 * After we've done initial boot, this function is called to allow the
109 * board code to clean up state, if needed
110 */
111static void __cpuinit yos_init_secondary(void)
112{
113 set_c0_status(ST0_CO | ST0_IE | ST0_IM);
114}
115
116static void __cpuinit yos_smp_finish(void)
117{
118}
119
120/* Hook for after all CPUs are online */
121static void yos_cpus_done(void)
122{
123}
124
125/*
126 * Firmware CPU startup hook
127 * Complicated by PMON's weird interface which tries to minimic the UNIX fork.
128 * It launches the next * available CPU and copies some information on the
129 * stack so the first thing we do is throw away that stuff and load useful
130 * values into the registers ...
131 */
132static void __cpuinit yos_boot_secondary(int cpu, struct task_struct *idle)
133{
134 unsigned long gp = (unsigned long) task_thread_info(idle);
135 unsigned long sp = __KSTK_TOS(idle);
136
137 secondary_sp = sp;
138 secondary_gp = gp;
139
140 spin_unlock(&launch_lock);
141}
142
143/*
144 * Detect available CPUs, populate phys_cpu_present_map before smp_init
145 *
146 * We don't want to start the secondary CPU yet nor do we have a nice probing
147 * feature in PMON so we just assume presence of the secondary core.
148 */
149static void __init yos_smp_setup(void)
150{
151 int i;
152
153 cpus_clear(phys_cpu_present_map);
154
155 for (i = 0; i < 2; i++) {
156 cpu_set(i, phys_cpu_present_map);
157 __cpu_number_map[i] = i;
158 __cpu_logical_map[i] = i;
159 }
160}
161
162static void __init yos_prepare_cpus(unsigned int max_cpus)
163{
164 /*
165 * Be paranoid. Enable the IPI only if we're really about to go SMP.
166 */
167 if (cpus_weight(cpu_possible_map))
168 set_c0_status(STATUSF_IP5);
169}
170
171struct plat_smp_ops yos_smp_ops = {
172 .send_ipi_single = yos_send_ipi_single,
173 .send_ipi_mask = yos_send_ipi_mask,
174 .init_secondary = yos_init_secondary,
175 .smp_finish = yos_smp_finish,
176 .cpus_done = yos_cpus_done,
177 .boot_secondary = yos_boot_secondary,
178 .smp_setup = yos_smp_setup,
179 .prepare_cpus = yos_prepare_cpus,
180};
diff --git a/arch/mips/qemu/Makefile b/arch/mips/qemu/Makefile
deleted file mode 100644
index 2ba4ef34b4a7..000000000000
--- a/arch/mips/qemu/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
1#
2# Makefile for Qemu specific kernel interface routines under Linux.
3#
4
5obj-y = q-firmware.o q-irq.o q-mem.o q-setup.o q-reset.o
6
7obj-$(CONFIG_EARLY_PRINTK) += q-console.o
8obj-$(CONFIG_SMP) += q-smp.o
9
10EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/qemu/q-console.c b/arch/mips/qemu/q-console.c
deleted file mode 100644
index 81101ae5017a..000000000000
--- a/arch/mips/qemu/q-console.c
+++ /dev/null
@@ -1,26 +0,0 @@
1#include <linux/console.h>
2#include <linux/init.h>
3#include <linux/serial_reg.h>
4#include <asm/io.h>
5
6#define PORT(offset) (0x3f8 + (offset))
7
8static inline unsigned int serial_in(int offset)
9{
10 return inb(PORT(offset));
11}
12
13static inline void serial_out(int offset, int value)
14{
15 outb(value, PORT(offset));
16}
17
18int prom_putchar(char c)
19{
20 while ((serial_in(UART_LSR) & UART_LSR_THRE) == 0)
21 ;
22
23 serial_out(UART_TX, c);
24
25 return 1;
26}
diff --git a/arch/mips/qemu/q-firmware.c b/arch/mips/qemu/q-firmware.c
deleted file mode 100644
index 3ed43f416cd1..000000000000
--- a/arch/mips/qemu/q-firmware.c
+++ /dev/null
@@ -1,24 +0,0 @@
1#include <linux/init.h>
2#include <linux/string.h>
3#include <asm/addrspace.h>
4#include <asm/bootinfo.h>
5#include <asm/io.h>
6
7#define QEMU_PORT_BASE 0xb4000000
8
9void __init prom_init(void)
10{
11 int *cmdline;
12
13 cmdline = (int *) (CKSEG0 + (0x10 << 20) - 260);
14 if (*cmdline == 0x12345678) {
15 if (*(char *)(cmdline + 1))
16 strcpy(arcs_cmdline, (char *)(cmdline + 1));
17 add_memory_region(0x0<<20, cmdline[-1], BOOT_MEM_RAM);
18 } else {
19 add_memory_region(0x0<<20, 0x10<<20, BOOT_MEM_RAM);
20 }
21
22
23 set_io_port_base(QEMU_PORT_BASE);
24}
diff --git a/arch/mips/qemu/q-irq.c b/arch/mips/qemu/q-irq.c
deleted file mode 100644
index 7df36dbe65c7..000000000000
--- a/arch/mips/qemu/q-irq.c
+++ /dev/null
@@ -1,37 +0,0 @@
1#include <linux/init.h>
2#include <linux/interrupt.h>
3#include <linux/linkage.h>
4
5#include <asm/i8259.h>
6#include <asm/irq_cpu.h>
7#include <asm/mipsregs.h>
8#include <asm/qemu.h>
9#include <asm/system.h>
10#include <asm/time.h>
11
12asmlinkage void plat_irq_dispatch(void)
13{
14 unsigned int pending = read_c0_status() & read_c0_cause();
15
16 if (pending & 0x8000) {
17 do_IRQ(Q_COUNT_COMPARE_IRQ);
18 return;
19 }
20 if (pending & 0x0400) {
21 int irq = i8259_irq();
22
23 if (likely(irq >= 0))
24 do_IRQ(irq);
25
26 return;
27 }
28}
29
30void __init arch_init_irq(void)
31{
32 mips_hpt_frequency = QEMU_C0_COUNTER_CLOCK; /* 100MHz */
33
34 mips_cpu_irq_init();
35 init_i8259_irqs();
36 set_c0_status(0x400);
37}
diff --git a/arch/mips/qemu/q-mem.c b/arch/mips/qemu/q-mem.c
deleted file mode 100644
index dae39b59de15..000000000000
--- a/arch/mips/qemu/q-mem.c
+++ /dev/null
@@ -1,5 +0,0 @@
1#include <linux/init.h>
2
3void __init prom_free_prom_memory(void)
4{
5}
diff --git a/arch/mips/qemu/q-reset.c b/arch/mips/qemu/q-reset.c
deleted file mode 100644
index dbbe44ad7e89..000000000000
--- a/arch/mips/qemu/q-reset.c
+++ /dev/null
@@ -1,33 +0,0 @@
1
2#include <asm/io.h>
3#include <asm/reboot.h>
4#include <asm/cacheflush.h>
5#include <asm/qemu.h>
6
7static void qemu_machine_restart(char *command)
8{
9 volatile unsigned int *reg = (unsigned int *)QEMU_RESTART_REG;
10
11 set_c0_status(ST0_BEV | ST0_ERL);
12 change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
13 flush_cache_all();
14 write_c0_wired(0);
15 *reg = 42;
16 while (1)
17 cpu_wait();
18}
19
20static void qemu_machine_halt(void)
21{
22 volatile unsigned int *reg = (unsigned int *)QEMU_HALT_REG;
23
24 *reg = 42;
25 while (1)
26 cpu_wait();
27}
28
29void qemu_reboot_setup(void)
30{
31 _machine_restart = qemu_machine_restart;
32 _machine_halt = qemu_machine_halt;
33}
diff --git a/arch/mips/qemu/q-setup.c b/arch/mips/qemu/q-setup.c
deleted file mode 100644
index 969cedc8d8b9..000000000000
--- a/arch/mips/qemu/q-setup.c
+++ /dev/null
@@ -1,22 +0,0 @@
1#include <linux/init.h>
2
3#include <asm/i8253.h>
4#include <asm/io.h>
5#include <asm/time.h>
6
7extern void qemu_reboot_setup(void);
8
9const char *get_system_type(void)
10{
11 return "Qemu";
12}
13
14void __init plat_time_init(void)
15{
16 setup_pit_timer();
17}
18
19void __init plat_mem_setup(void)
20{
21 qemu_reboot_setup();
22}
diff --git a/arch/mips/qemu/q-smp.c b/arch/mips/qemu/q-smp.c
deleted file mode 100644
index 4b0178d0df0b..000000000000
--- a/arch/mips/qemu/q-smp.c
+++ /dev/null
@@ -1,55 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2006 by Ralf Baechle (ralf@linux-mips.org)
7 *
8 * Symmetric Uniprocessor (TM) Support
9 */
10#include <linux/kernel.h>
11#include <linux/sched.h>
12
13/*
14 * Send inter-processor interrupt
15 */
16void core_send_ipi(int cpu, unsigned int action)
17{
18 panic(KERN_ERR "%s called", __FUNCTION__);
19}
20
21/*
22 * After we've done initial boot, this function is called to allow the
23 * board code to clean up state, if needed
24 */
25void __cpuinit prom_init_secondary(void)
26{
27}
28
29void __cpuinit prom_smp_finish(void)
30{
31}
32
33/* Hook for after all CPUs are online */
34void prom_cpus_done(void)
35{
36}
37
38void __init prom_prepare_cpus(unsigned int max_cpus)
39{
40 cpus_clear(phys_cpu_present_map);
41}
42
43/*
44 * Firmware CPU startup hook
45 */
46void __cpuinit prom_boot_secondary(int cpu, struct task_struct *idle)
47{
48}
49
50void __init plat_smp_setup(void)
51{
52}
53void __init plat_prepare_cpus(unsigned int max_cpus)
54{
55}
diff --git a/arch/mips/sgi-ip22/Makefile b/arch/mips/sgi-ip22/Makefile
index e3acb51b70b5..ef1564e40c8d 100644
--- a/arch/mips/sgi-ip22/Makefile
+++ b/arch/mips/sgi-ip22/Makefile
@@ -3,9 +3,11 @@
3# under Linux. 3# under Linux.
4# 4#
5 5
6obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-berr.o \ 6obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-time.o ip22-nvram.o \
7 ip22-time.o ip22-nvram.o ip22-platform.o ip22-reset.o ip22-setup.o 7 ip22-platform.o ip22-reset.o ip22-setup.o
8 8
9obj-$(CONFIG_SGI_IP22) += ip22-berr.o
10obj-$(CONFIG_SGI_IP28) += ip28-berr.o
9obj-$(CONFIG_EISA) += ip22-eisa.o 11obj-$(CONFIG_EISA) += ip22-eisa.o
10 12
11EXTRA_CFLAGS += -Werror 13# EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/sgi-ip22/ip22-mc.c b/arch/mips/sgi-ip22/ip22-mc.c
index 01a805dcc67c..3f35d6367bec 100644
--- a/arch/mips/sgi-ip22/ip22-mc.c
+++ b/arch/mips/sgi-ip22/ip22-mc.c
@@ -4,6 +4,7 @@
4 * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) 4 * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
5 * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - Indigo2 changes 5 * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - Indigo2 changes
6 * Copyright (C) 2003 Ladislav Michl (ladis@linux-mips.org) 6 * Copyright (C) 2003 Ladislav Michl (ladis@linux-mips.org)
7 * Copyright (C) 2004 Peter Fuerst (pf@net.alphadv.de) - IP28
7 */ 8 */
8 9
9#include <linux/init.h> 10#include <linux/init.h>
@@ -137,9 +138,12 @@ void __init sgimc_init(void)
137 /* Step 2: Enable all parity checking in cpu control register 138 /* Step 2: Enable all parity checking in cpu control register
138 * zero. 139 * zero.
139 */ 140 */
141 /* don't touch parity settings for IP28 */
142#ifndef CONFIG_SGI_IP28
140 tmp = sgimc->cpuctrl0; 143 tmp = sgimc->cpuctrl0;
141 tmp |= (SGIMC_CCTRL0_EPERRGIO | SGIMC_CCTRL0_EPERRMEM | 144 tmp |= (SGIMC_CCTRL0_EPERRGIO | SGIMC_CCTRL0_EPERRMEM |
142 SGIMC_CCTRL0_R4KNOCHKPARR); 145 SGIMC_CCTRL0_R4KNOCHKPARR);
146#endif
143 sgimc->cpuctrl0 = tmp; 147 sgimc->cpuctrl0 = tmp;
144 148
145 /* Step 3: Setup the MC write buffer depth, this is controlled 149 /* Step 3: Setup the MC write buffer depth, this is controlled
diff --git a/arch/mips/sgi-ip22/ip28-berr.c b/arch/mips/sgi-ip22/ip28-berr.c
new file mode 100644
index 000000000000..30e12e2ec4b5
--- /dev/null
+++ b/arch/mips/sgi-ip22/ip28-berr.c
@@ -0,0 +1,502 @@
1/*
2 * ip28-berr.c: Bus error handling.
3 *
4 * Copyright (C) 2002, 2003 Ladislav Michl (ladis@linux-mips.org)
5 * Copyright (C) 2005 Peter Fuerst (pf@net.alphadv.de) - IP28
6 */
7
8#include <linux/init.h>
9#include <linux/kernel.h>
10#include <linux/sched.h>
11#include <linux/seq_file.h>
12
13#include <asm/addrspace.h>
14#include <asm/system.h>
15#include <asm/traps.h>
16#include <asm/branch.h>
17#include <asm/irq_regs.h>
18#include <asm/sgi/mc.h>
19#include <asm/sgi/hpc3.h>
20#include <asm/sgi/ioc.h>
21#include <asm/sgi/ip22.h>
22#include <asm/r4kcache.h>
23#include <asm/uaccess.h>
24#include <asm/bootinfo.h>
25
26static unsigned int count_be_is_fixup;
27static unsigned int count_be_handler;
28static unsigned int count_be_interrupt;
29static int debug_be_interrupt;
30
31static unsigned int cpu_err_stat; /* Status reg for CPU */
32static unsigned int gio_err_stat; /* Status reg for GIO */
33static unsigned int cpu_err_addr; /* Error address reg for CPU */
34static unsigned int gio_err_addr; /* Error address reg for GIO */
35static unsigned int extio_stat;
36static unsigned int hpc3_berr_stat; /* Bus error interrupt status */
37
38struct hpc3_stat {
39 unsigned long addr;
40 unsigned int ctrl;
41 unsigned int cbp;
42 unsigned int ndptr;
43};
44
45static struct {
46 struct hpc3_stat pbdma[8];
47 struct hpc3_stat scsi[2];
48 struct hpc3_stat ethrx, ethtx;
49} hpc3;
50
51static struct {
52 unsigned long err_addr;
53 struct {
54 u32 lo;
55 u32 hi;
56 } tags[1][2], tagd[4][2], tagi[4][2]; /* Way 0/1 */
57} cache_tags;
58
59static inline void save_cache_tags(unsigned busaddr)
60{
61 unsigned long addr = CAC_BASE | busaddr;
62 int i;
63 cache_tags.err_addr = addr;
64
65 /*
66 * Starting with a bus-address, save secondary cache (indexed by
67 * PA[23..18:7..6]) tags first.
68 */
69 addr &= ~1L;
70#define tag cache_tags.tags[0]
71 cache_op(Index_Load_Tag_S, addr);
72 tag[0].lo = read_c0_taglo(); /* PA[35:18], VA[13:12] */
73 tag[0].hi = read_c0_taghi(); /* PA[39:36] */
74 cache_op(Index_Load_Tag_S, addr | 1L);
75 tag[1].lo = read_c0_taglo(); /* PA[35:18], VA[13:12] */
76 tag[1].hi = read_c0_taghi(); /* PA[39:36] */
77#undef tag
78
79 /*
80 * Save all primary data cache (indexed by VA[13:5]) tags which
81 * might fit to this bus-address, knowing that VA[11:0] == PA[11:0].
82 * Saving all tags and evaluating them later is easier and safer
83 * than relying on VA[13:12] from the secondary cache tags to pick
84 * matching primary tags here already.
85 */
86 addr &= (0xffL << 56) | ((1 << 12) - 1);
87#define tag cache_tags.tagd[i]
88 for (i = 0; i < 4; ++i, addr += (1 << 12)) {
89 cache_op(Index_Load_Tag_D, addr);
90 tag[0].lo = read_c0_taglo(); /* PA[35:12] */
91 tag[0].hi = read_c0_taghi(); /* PA[39:36] */
92 cache_op(Index_Load_Tag_D, addr | 1L);
93 tag[1].lo = read_c0_taglo(); /* PA[35:12] */
94 tag[1].hi = read_c0_taghi(); /* PA[39:36] */
95 }
96#undef tag
97
98 /*
99 * Save primary instruction cache (indexed by VA[13:6]) tags
100 * the same way.
101 */
102 addr &= (0xffL << 56) | ((1 << 12) - 1);
103#define tag cache_tags.tagi[i]
104 for (i = 0; i < 4; ++i, addr += (1 << 12)) {
105 cache_op(Index_Load_Tag_I, addr);
106 tag[0].lo = read_c0_taglo(); /* PA[35:12] */
107 tag[0].hi = read_c0_taghi(); /* PA[39:36] */
108 cache_op(Index_Load_Tag_I, addr | 1L);
109 tag[1].lo = read_c0_taglo(); /* PA[35:12] */
110 tag[1].hi = read_c0_taghi(); /* PA[39:36] */
111 }
112#undef tag
113}
114
115#define GIO_ERRMASK 0xff00
116#define CPU_ERRMASK 0x3f00
117
118static void save_and_clear_buserr(void)
119{
120 int i;
121
122 /* save status registers */
123 cpu_err_addr = sgimc->cerr;
124 cpu_err_stat = sgimc->cstat;
125 gio_err_addr = sgimc->gerr;
126 gio_err_stat = sgimc->gstat;
127 extio_stat = sgioc->extio;
128 hpc3_berr_stat = hpc3c0->bestat;
129
130 hpc3.scsi[0].addr = (unsigned long)&hpc3c0->scsi_chan0;
131 hpc3.scsi[0].ctrl = hpc3c0->scsi_chan0.ctrl; /* HPC3_SCTRL_ACTIVE ? */
132 hpc3.scsi[0].cbp = hpc3c0->scsi_chan0.cbptr;
133 hpc3.scsi[0].ndptr = hpc3c0->scsi_chan0.ndptr;
134
135 hpc3.scsi[1].addr = (unsigned long)&hpc3c0->scsi_chan1;
136 hpc3.scsi[1].ctrl = hpc3c0->scsi_chan1.ctrl; /* HPC3_SCTRL_ACTIVE ? */
137 hpc3.scsi[1].cbp = hpc3c0->scsi_chan1.cbptr;
138 hpc3.scsi[1].ndptr = hpc3c0->scsi_chan1.ndptr;
139
140 hpc3.ethrx.addr = (unsigned long)&hpc3c0->ethregs.rx_cbptr;
141 hpc3.ethrx.ctrl = hpc3c0->ethregs.rx_ctrl; /* HPC3_ERXCTRL_ACTIVE ? */
142 hpc3.ethrx.cbp = hpc3c0->ethregs.rx_cbptr;
143 hpc3.ethrx.ndptr = hpc3c0->ethregs.rx_ndptr;
144
145 hpc3.ethtx.addr = (unsigned long)&hpc3c0->ethregs.tx_cbptr;
146 hpc3.ethtx.ctrl = hpc3c0->ethregs.tx_ctrl; /* HPC3_ETXCTRL_ACTIVE ? */
147 hpc3.ethtx.cbp = hpc3c0->ethregs.tx_cbptr;
148 hpc3.ethtx.ndptr = hpc3c0->ethregs.tx_ndptr;
149
150 for (i = 0; i < 8; ++i) {
151 /* HPC3_PDMACTRL_ISACT ? */
152 hpc3.pbdma[i].addr = (unsigned long)&hpc3c0->pbdma[i];
153 hpc3.pbdma[i].ctrl = hpc3c0->pbdma[i].pbdma_ctrl;
154 hpc3.pbdma[i].cbp = hpc3c0->pbdma[i].pbdma_bptr;
155 hpc3.pbdma[i].ndptr = hpc3c0->pbdma[i].pbdma_dptr;
156 }
157 i = 0;
158 if (gio_err_stat & CPU_ERRMASK)
159 i = gio_err_addr;
160 if (cpu_err_stat & CPU_ERRMASK)
161 i = cpu_err_addr;
162 save_cache_tags(i);
163
164 sgimc->cstat = sgimc->gstat = 0;
165}
166
167static void print_cache_tags(void)
168{
169 u32 scb, scw;
170 int i;
171
172 printk(KERN_ERR "Cache tags @ %08x:\n", (unsigned)cache_tags.err_addr);
173
174 /* PA[31:12] shifted to PTag0 (PA[35:12]) format */
175 scw = (cache_tags.err_addr >> 4) & 0x0fffff00;
176
177 scb = cache_tags.err_addr & ((1 << 12) - 1) & ~((1 << 5) - 1);
178 for (i = 0; i < 4; ++i) { /* for each possible VA[13:12] value */
179 if ((cache_tags.tagd[i][0].lo & 0x0fffff00) != scw &&
180 (cache_tags.tagd[i][1].lo & 0x0fffff00) != scw)
181 continue;
182 printk(KERN_ERR
183 "D: 0: %08x %08x, 1: %08x %08x (VA[13:5] %04x)\n",
184 cache_tags.tagd[i][0].hi, cache_tags.tagd[i][0].lo,
185 cache_tags.tagd[i][1].hi, cache_tags.tagd[i][1].lo,
186 scb | (1 << 12)*i);
187 }
188 scb = cache_tags.err_addr & ((1 << 12) - 1) & ~((1 << 6) - 1);
189 for (i = 0; i < 4; ++i) { /* for each possible VA[13:12] value */
190 if ((cache_tags.tagi[i][0].lo & 0x0fffff00) != scw &&
191 (cache_tags.tagi[i][1].lo & 0x0fffff00) != scw)
192 continue;
193 printk(KERN_ERR
194 "I: 0: %08x %08x, 1: %08x %08x (VA[13:6] %04x)\n",
195 cache_tags.tagi[i][0].hi, cache_tags.tagi[i][0].lo,
196 cache_tags.tagi[i][1].hi, cache_tags.tagi[i][1].lo,
197 scb | (1 << 12)*i);
198 }
199 i = read_c0_config();
200 scb = i & (1 << 13) ? 7:6; /* scblksize = 2^[7..6] */
201 scw = ((i >> 16) & 7) + 19 - 1; /* scwaysize = 2^[24..19] / 2 */
202
203 i = ((1 << scw) - 1) & ~((1 << scb) - 1);
204 printk(KERN_ERR "S: 0: %08x %08x, 1: %08x %08x (PA[%u:%u] %05x)\n",
205 cache_tags.tags[0][0].hi, cache_tags.tags[0][0].lo,
206 cache_tags.tags[0][1].hi, cache_tags.tags[0][1].lo,
207 scw-1, scb, i & (unsigned)cache_tags.err_addr);
208}
209
210static inline const char *cause_excode_text(int cause)
211{
212 static const char *txt[32] =
213 { "Interrupt",
214 "TLB modification",
215 "TLB (load or instruction fetch)",
216 "TLB (store)",
217 "Address error (load or instruction fetch)",
218 "Address error (store)",
219 "Bus error (instruction fetch)",
220 "Bus error (data: load or store)",
221 "Syscall",
222 "Breakpoint",
223 "Reserved instruction",
224 "Coprocessor unusable",
225 "Arithmetic Overflow",
226 "Trap",
227 "14",
228 "Floating-Point",
229 "16", "17", "18", "19", "20", "21", "22",
230 "Watch Hi/Lo",
231 "24", "25", "26", "27", "28", "29", "30", "31",
232 };
233 return txt[(cause & 0x7c) >> 2];
234}
235
236static void print_buserr(const struct pt_regs *regs)
237{
238 const int field = 2 * sizeof(unsigned long);
239 int error = 0;
240
241 if (extio_stat & EXTIO_MC_BUSERR) {
242 printk(KERN_ERR "MC Bus Error\n");
243 error |= 1;
244 }
245 if (extio_stat & EXTIO_HPC3_BUSERR) {
246 printk(KERN_ERR "HPC3 Bus Error 0x%x:<id=0x%x,%s,lane=0x%x>\n",
247 hpc3_berr_stat,
248 (hpc3_berr_stat & HPC3_BESTAT_PIDMASK) >>
249 HPC3_BESTAT_PIDSHIFT,
250 (hpc3_berr_stat & HPC3_BESTAT_CTYPE) ? "PIO" : "DMA",
251 hpc3_berr_stat & HPC3_BESTAT_BLMASK);
252 error |= 2;
253 }
254 if (extio_stat & EXTIO_EISA_BUSERR) {
255 printk(KERN_ERR "EISA Bus Error\n");
256 error |= 4;
257 }
258 if (cpu_err_stat & CPU_ERRMASK) {
259 printk(KERN_ERR "CPU error 0x%x<%s%s%s%s%s%s> @ 0x%08x\n",
260 cpu_err_stat,
261 cpu_err_stat & SGIMC_CSTAT_RD ? "RD " : "",
262 cpu_err_stat & SGIMC_CSTAT_PAR ? "PAR " : "",
263 cpu_err_stat & SGIMC_CSTAT_ADDR ? "ADDR " : "",
264 cpu_err_stat & SGIMC_CSTAT_SYSAD_PAR ? "SYSAD " : "",
265 cpu_err_stat & SGIMC_CSTAT_SYSCMD_PAR ? "SYSCMD " : "",
266 cpu_err_stat & SGIMC_CSTAT_BAD_DATA ? "BAD_DATA " : "",
267 cpu_err_addr);
268 error |= 8;
269 }
270 if (gio_err_stat & GIO_ERRMASK) {
271 printk(KERN_ERR "GIO error 0x%x:<%s%s%s%s%s%s%s%s> @ 0x%08x\n",
272 gio_err_stat,
273 gio_err_stat & SGIMC_GSTAT_RD ? "RD " : "",
274 gio_err_stat & SGIMC_GSTAT_WR ? "WR " : "",
275 gio_err_stat & SGIMC_GSTAT_TIME ? "TIME " : "",
276 gio_err_stat & SGIMC_GSTAT_PROM ? "PROM " : "",
277 gio_err_stat & SGIMC_GSTAT_ADDR ? "ADDR " : "",
278 gio_err_stat & SGIMC_GSTAT_BC ? "BC " : "",
279 gio_err_stat & SGIMC_GSTAT_PIO_RD ? "PIO_RD " : "",
280 gio_err_stat & SGIMC_GSTAT_PIO_WR ? "PIO_WR " : "",
281 gio_err_addr);
282 error |= 16;
283 }
284 if (!error)
285 printk(KERN_ERR "MC: Hmm, didn't find any error condition.\n");
286 else {
287 printk(KERN_ERR "CP0: config %08x, "
288 "MC: cpuctrl0/1: %08x/%05x, giopar: %04x\n"
289 "MC: cpu/gio_memacc: %08x/%05x, memcfg0/1: %08x/%08x\n",
290 read_c0_config(),
291 sgimc->cpuctrl0, sgimc->cpuctrl0, sgimc->giopar,
292 sgimc->cmacc, sgimc->gmacc,
293 sgimc->mconfig0, sgimc->mconfig1);
294 print_cache_tags();
295 }
296 printk(KERN_ALERT "%s, epc == %0*lx, ra == %0*lx\n",
297 cause_excode_text(regs->cp0_cause),
298 field, regs->cp0_epc, field, regs->regs[31]);
299}
300
301/*
302 * Check, whether MC's (virtual) DMA address caused the bus error.
303 * See "Virtual DMA Specification", Draft 1.5, Feb 13 1992, SGI
304 */
305
306static int addr_is_ram(unsigned long addr, unsigned sz)
307{
308 int i;
309
310 for (i = 0; i < boot_mem_map.nr_map; i++) {
311 unsigned long a = boot_mem_map.map[i].addr;
312 if (a <= addr && addr+sz <= a+boot_mem_map.map[i].size)
313 return 1;
314 }
315 return 0;
316}
317
318static int check_microtlb(u32 hi, u32 lo, unsigned long vaddr)
319{
320 /* This is likely rather similar to correct code ;-) */
321
322 vaddr &= 0x7fffffff; /* Doc. states that top bit is ignored */
323
324 /* If tlb-entry is valid and VPN-high (bits [30:21] ?) matches... */
325 if ((lo & 2) && (vaddr >> 21) == ((hi<<1) >> 22)) {
326 u32 ctl = sgimc->dma_ctrl;
327 if (ctl & 1) {
328 unsigned int pgsz = (ctl & 2) ? 14:12; /* 16k:4k */
329 /* PTEIndex is VPN-low (bits [22:14]/[20:12] ?) */
330 unsigned long pte = (lo >> 6) << 12; /* PTEBase */
331 pte += 8*((vaddr >> pgsz) & 0x1ff);
332 if (addr_is_ram(pte, 8)) {
333 /*
334 * Note: Since DMA hardware does look up
335 * translation on its own, this PTE *must*
336 * match the TLB/EntryLo-register format !
337 */
338 unsigned long a = *(unsigned long *)
339 PHYS_TO_XKSEG_UNCACHED(pte);
340 a = (a & 0x3f) << 6; /* PFN */
341 a += vaddr & ((1 << pgsz) - 1);
342 return (cpu_err_addr == a);
343 }
344 }
345 }
346 return 0;
347}
348
349static int check_vdma_memaddr(void)
350{
351 if (cpu_err_stat & CPU_ERRMASK) {
352 u32 a = sgimc->maddronly;
353
354 if (!(sgimc->dma_ctrl & 0x100)) /* Xlate-bit clear ? */
355 return (cpu_err_addr == a);
356
357 if (check_microtlb(sgimc->dtlb_hi0, sgimc->dtlb_lo0, a) ||
358 check_microtlb(sgimc->dtlb_hi1, sgimc->dtlb_lo1, a) ||
359 check_microtlb(sgimc->dtlb_hi2, sgimc->dtlb_lo2, a) ||
360 check_microtlb(sgimc->dtlb_hi3, sgimc->dtlb_lo3, a))
361 return 1;
362 }
363 return 0;
364}
365
366static int check_vdma_gioaddr(void)
367{
368 if (gio_err_stat & GIO_ERRMASK) {
369 u32 a = sgimc->gio_dma_trans;
370 a = (sgimc->gmaddronly & ~a) | (sgimc->gio_dma_sbits & a);
371 return (gio_err_addr == a);
372 }
373 return 0;
374}
375
376/*
377 * MC sends an interrupt whenever bus or parity errors occur. In addition,
378 * if the error happened during a CPU read, it also asserts the bus error
379 * pin on the R4K. Code in bus error handler save the MC bus error registers
380 * and then clear the interrupt when this happens.
381 */
382
383static int ip28_be_interrupt(const struct pt_regs *regs)
384{
385 int i;
386
387 save_and_clear_buserr();
388 /*
389 * Try to find out, whether we got here by a mispredicted speculative
390 * load/store operation. If so, it's not fatal, we can go on.
391 */
392 /* Any cause other than "Interrupt" (ExcCode 0) is fatal. */
393 if (regs->cp0_cause & CAUSEF_EXCCODE)
394 goto mips_be_fatal;
395
396 /* Any cause other than "Bus error interrupt" (IP6) is weird. */
397 if ((regs->cp0_cause & CAUSEF_IP6) != CAUSEF_IP6)
398 goto mips_be_fatal;
399
400 if (extio_stat & (EXTIO_HPC3_BUSERR | EXTIO_EISA_BUSERR))
401 goto mips_be_fatal;
402
403 /* Any state other than "Memory bus error" is fatal. */
404 if (cpu_err_stat & CPU_ERRMASK & ~SGIMC_CSTAT_ADDR)
405 goto mips_be_fatal;
406
407 /* GIO errors other than timeouts are fatal */
408 if (gio_err_stat & GIO_ERRMASK & ~SGIMC_GSTAT_TIME)
409 goto mips_be_fatal;
410
411 /*
412 * Now we have an asynchronous bus error, speculatively or DMA caused.
413 * Need to search all DMA descriptors for the error address.
414 */
415 for (i = 0; i < sizeof(hpc3)/sizeof(struct hpc3_stat); ++i) {
416 struct hpc3_stat *hp = (struct hpc3_stat *)&hpc3 + i;
417 if ((cpu_err_stat & CPU_ERRMASK) &&
418 (cpu_err_addr == hp->ndptr || cpu_err_addr == hp->cbp))
419 break;
420 if ((gio_err_stat & GIO_ERRMASK) &&
421 (gio_err_addr == hp->ndptr || gio_err_addr == hp->cbp))
422 break;
423 }
424 if (i < sizeof(hpc3)/sizeof(struct hpc3_stat)) {
425 struct hpc3_stat *hp = (struct hpc3_stat *)&hpc3 + i;
426 printk(KERN_ERR "at DMA addresses: HPC3 @ %08lx:"
427 " ctl %08x, ndp %08x, cbp %08x\n",
428 CPHYSADDR(hp->addr), hp->ctrl, hp->ndptr, hp->cbp);
429 goto mips_be_fatal;
430 }
431 /* Check MC's virtual DMA stuff. */
432 if (check_vdma_memaddr()) {
433 printk(KERN_ERR "at GIO DMA: mem address 0x%08x.\n",
434 sgimc->maddronly);
435 goto mips_be_fatal;
436 }
437 if (check_vdma_gioaddr()) {
438 printk(KERN_ERR "at GIO DMA: gio address 0x%08x.\n",
439 sgimc->gmaddronly);
440 goto mips_be_fatal;
441 }
442 /* A speculative bus error... */
443 if (debug_be_interrupt) {
444 print_buserr(regs);
445 printk(KERN_ERR "discarded!\n");
446 }
447 return MIPS_BE_DISCARD;
448
449mips_be_fatal:
450 print_buserr(regs);
451 return MIPS_BE_FATAL;
452}
453
454void ip22_be_interrupt(int irq)
455{
456 const struct pt_regs *regs = get_irq_regs();
457
458 count_be_interrupt++;
459
460 if (ip28_be_interrupt(regs) != MIPS_BE_DISCARD) {
461 /* Assume it would be too dangerous to continue ... */
462 die_if_kernel("Oops", regs);
463 force_sig(SIGBUS, current);
464 } else if (debug_be_interrupt)
465 show_regs((struct pt_regs *)regs);
466}
467
468static int ip28_be_handler(struct pt_regs *regs, int is_fixup)
469{
470 /*
471 * We arrive here only in the unusual case of do_be() invocation,
472 * i.e. by a bus error exception without a bus error interrupt.
473 */
474 if (is_fixup) {
475 count_be_is_fixup++;
476 save_and_clear_buserr();
477 return MIPS_BE_FIXUP;
478 }
479 count_be_handler++;
480 return ip28_be_interrupt(regs);
481}
482
483void __init ip22_be_init(void)
484{
485 board_be_handler = ip28_be_handler;
486}
487
488int ip28_show_be_info(struct seq_file *m)
489{
490 seq_printf(m, "IP28 be fixups\t\t: %u\n", count_be_is_fixup);
491 seq_printf(m, "IP28 be interrupts\t: %u\n", count_be_interrupt);
492 seq_printf(m, "IP28 be handler\t\t: %u\n", count_be_handler);
493
494 return 0;
495}
496
497static int __init debug_be_setup(char *str)
498{
499 debug_be_interrupt++;
500 return 1;
501}
502__setup("ip28_debug_be", debug_be_setup);
diff --git a/arch/mips/sgi-ip27/ip27-init.c b/arch/mips/sgi-ip27/ip27-init.c
index 3305fa9ae66d..a49e7c85f724 100644
--- a/arch/mips/sgi-ip27/ip27-init.c
+++ b/arch/mips/sgi-ip27/ip27-init.c
@@ -27,7 +27,6 @@
27#include <asm/sn/hub.h> 27#include <asm/sn/hub.h>
28#include <asm/sn/intr.h> 28#include <asm/sn/intr.h>
29#include <asm/current.h> 29#include <asm/current.h>
30#include <asm/smp.h>
31#include <asm/processor.h> 30#include <asm/processor.h>
32#include <asm/mmu_context.h> 31#include <asm/mmu_context.h>
33#include <asm/thread_info.h> 32#include <asm/thread_info.h>
diff --git a/arch/mips/sgi-ip27/ip27-klnuma.c b/arch/mips/sgi-ip27/ip27-klnuma.c
index f10d9839006d..48932ce1d730 100644
--- a/arch/mips/sgi-ip27/ip27-klnuma.c
+++ b/arch/mips/sgi-ip27/ip27-klnuma.c
@@ -11,7 +11,6 @@
11 11
12#include <asm/page.h> 12#include <asm/page.h>
13#include <asm/sections.h> 13#include <asm/sections.h>
14#include <asm/smp.h>
15#include <asm/sn/types.h> 14#include <asm/sn/types.h>
16#include <asm/sn/arch.h> 15#include <asm/sn/arch.h>
17#include <asm/sn/gda.h> 16#include <asm/sn/gda.h>
diff --git a/arch/mips/sgi-ip27/ip27-smp.c b/arch/mips/sgi-ip27/ip27-smp.c
index a70656d42191..f15fc93d6b35 100644
--- a/arch/mips/sgi-ip27/ip27-smp.c
+++ b/arch/mips/sgi-ip27/ip27-smp.c
@@ -140,30 +140,51 @@ static __init void intr_clear_all(nasid_t nasid)
140 REMOTE_HUB_CLR_INTR(nasid, i); 140 REMOTE_HUB_CLR_INTR(nasid, i);
141} 141}
142 142
143void __init plat_smp_setup(void) 143static void ip27_send_ipi_single(int destid, unsigned int action)
144{ 144{
145 cnodeid_t cnode; 145 int irq;
146 146
147 for_each_online_node(cnode) { 147 switch (action) {
148 if (cnode == 0) 148 case SMP_RESCHEDULE_YOURSELF:
149 continue; 149 irq = CPU_RESCHED_A_IRQ;
150 intr_clear_all(COMPACT_TO_NASID_NODEID(cnode)); 150 break;
151 case SMP_CALL_FUNCTION:
152 irq = CPU_CALL_A_IRQ;
153 break;
154 default:
155 panic("sendintr");
151 } 156 }
152 157
153 replicate_kernel_text(); 158 irq += cputoslice(destid);
154 159
155 /* 160 /*
156 * Assumption to be fixed: we're always booted on logical / physical 161 * Convert the compact hub number to the NASID to get the correct
157 * processor 0. While we're always running on logical processor 0 162 * part of the address space. Then set the interrupt bit associated
158 * this still means this is physical processor zero; it might for 163 * with the CPU we want to send the interrupt to.
159 * example be disabled in the firwware.
160 */ 164 */
161 alloc_cpupda(0, 0); 165 REMOTE_HUB_SEND_INTR(COMPACT_TO_NASID_NODEID(cpu_to_node(destid)), irq);
162} 166}
163 167
164void __init plat_prepare_cpus(unsigned int max_cpus) 168static void ip27_send_ipi_mask(cpumask_t mask, unsigned int action)
169{
170 unsigned int i;
171
172 for_each_cpu_mask(i, mask)
173 ip27_send_ipi_single(i, action);
174}
175
176static void __cpuinit ip27_init_secondary(void)
177{
178 per_cpu_init();
179 local_irq_enable();
180}
181
182static void __cpuinit ip27_smp_finish(void)
183{
184}
185
186static void __init ip27_cpus_done(void)
165{ 187{
166 /* We already did everything necessary earlier */
167} 188}
168 189
169/* 190/*
@@ -171,7 +192,7 @@ void __init plat_prepare_cpus(unsigned int max_cpus)
171 * set sp to the kernel stack of the newly created idle process, gp to the proc 192 * set sp to the kernel stack of the newly created idle process, gp to the proc
172 * struct so that current_thread_info() will work. 193 * struct so that current_thread_info() will work.
173 */ 194 */
174void __cpuinit prom_boot_secondary(int cpu, struct task_struct *idle) 195static void __cpuinit ip27_boot_secondary(int cpu, struct task_struct *idle)
175{ 196{
176 unsigned long gp = (unsigned long)task_thread_info(idle); 197 unsigned long gp = (unsigned long)task_thread_info(idle);
177 unsigned long sp = __KSTK_TOS(idle); 198 unsigned long sp = __KSTK_TOS(idle);
@@ -181,41 +202,39 @@ void __cpuinit prom_boot_secondary(int cpu, struct task_struct *idle)
181 0, (void *) sp, (void *) gp); 202 0, (void *) sp, (void *) gp);
182} 203}
183 204
184void __cpuinit prom_init_secondary(void) 205static void __init ip27_smp_setup(void)
185{ 206{
186 per_cpu_init(); 207 cnodeid_t cnode;
187 local_irq_enable();
188}
189
190void __init prom_cpus_done(void)
191{
192}
193
194void __cpuinit prom_smp_finish(void)
195{
196}
197
198void core_send_ipi(int destid, unsigned int action)
199{
200 int irq;
201 208
202 switch (action) { 209 for_each_online_node(cnode) {
203 case SMP_RESCHEDULE_YOURSELF: 210 if (cnode == 0)
204 irq = CPU_RESCHED_A_IRQ; 211 continue;
205 break; 212 intr_clear_all(COMPACT_TO_NASID_NODEID(cnode));
206 case SMP_CALL_FUNCTION:
207 irq = CPU_CALL_A_IRQ;
208 break;
209 default:
210 panic("sendintr");
211 } 213 }
212 214
213 irq += cputoslice(destid); 215 replicate_kernel_text();
214 216
215 /* 217 /*
216 * Convert the compact hub number to the NASID to get the correct 218 * Assumption to be fixed: we're always booted on logical / physical
217 * part of the address space. Then set the interrupt bit associated 219 * processor 0. While we're always running on logical processor 0
218 * with the CPU we want to send the interrupt to. 220 * this still means this is physical processor zero; it might for
221 * example be disabled in the firwware.
219 */ 222 */
220 REMOTE_HUB_SEND_INTR(COMPACT_TO_NASID_NODEID(cpu_to_node(destid)), irq); 223 alloc_cpupda(0, 0);
221} 224}
225
226static void __init ip27_prepare_cpus(unsigned int max_cpus)
227{
228 /* We already did everything necessary earlier */
229}
230
231struct plat_smp_ops ip27_smp_ops = {
232 .send_ipi_single = ip27_send_ipi_single,
233 .send_ipi_mask = ip27_send_ipi_mask,
234 .init_secondary = ip27_init_secondary,
235 .smp_finish = ip27_smp_finish,
236 .cpus_done = ip27_cpus_done,
237 .boot_secondary = ip27_boot_secondary,
238 .smp_setup = ip27_smp_setup,
239 .prepare_cpus = ip27_prepare_cpus,
240};
diff --git a/arch/mips/sibyte/bcm1480/smp.c b/arch/mips/sibyte/bcm1480/smp.c
index 436ba78359ab..183c460b9ca1 100644
--- a/arch/mips/sibyte/bcm1480/smp.c
+++ b/arch/mips/sibyte/bcm1480/smp.c
@@ -23,6 +23,7 @@
23 23
24#include <asm/mmu_context.h> 24#include <asm/mmu_context.h>
25#include <asm/io.h> 25#include <asm/io.h>
26#include <asm/fw/cfe/cfe_api.h>
26#include <asm/sibyte/sb1250.h> 27#include <asm/sibyte/sb1250.h>
27#include <asm/sibyte/bcm1480_regs.h> 28#include <asm/sibyte/bcm1480_regs.h>
28#include <asm/sibyte/bcm1480_int.h> 29#include <asm/sibyte/bcm1480_int.h>
@@ -67,28 +68,114 @@ void __cpuinit bcm1480_smp_init(void)
67 change_c0_status(ST0_IM, imask); 68 change_c0_status(ST0_IM, imask);
68} 69}
69 70
70void __cpuinit bcm1480_smp_finish(void) 71/*
72 * These are routines for dealing with the sb1250 smp capabilities
73 * independent of board/firmware
74 */
75
76/*
77 * Simple enough; everything is set up, so just poke the appropriate mailbox
78 * register, and we should be set
79 */
80static void bcm1480_send_ipi_single(int cpu, unsigned int action)
81{
82 __raw_writeq((((u64)action)<< 48), mailbox_0_set_regs[cpu]);
83}
84
85static void bcm1480_send_ipi_mask(cpumask_t mask, unsigned int action)
86{
87 unsigned int i;
88
89 for_each_cpu_mask(i, mask)
90 bcm1480_send_ipi_single(i, action);
91}
92
93/*
94 * Code to run on secondary just after probing the CPU
95 */
96static void __cpuinit bcm1480_init_secondary(void)
97{
98 extern void bcm1480_smp_init(void);
99
100 bcm1480_smp_init();
101}
102
103/*
104 * Do any tidying up before marking online and running the idle
105 * loop
106 */
107static void __cpuinit bcm1480_smp_finish(void)
71{ 108{
72 extern void sb1480_clockevent_init(void); 109 extern void sb1480_clockevent_init(void);
73 110
74 sb1480_clockevent_init(); 111 sb1480_clockevent_init();
75 local_irq_enable(); 112 local_irq_enable();
113 bcm1480_smp_finish();
76} 114}
77 115
78/* 116/*
79 * These are routines for dealing with the sb1250 smp capabilities 117 * Final cleanup after all secondaries booted
80 * independent of board/firmware
81 */ 118 */
119static void bcm1480_cpus_done(void)
120{
121}
82 122
83/* 123/*
84 * Simple enough; everything is set up, so just poke the appropriate mailbox 124 * Setup the PC, SP, and GP of a secondary processor and start it
85 * register, and we should be set 125 * running!
86 */ 126 */
87void core_send_ipi(int cpu, unsigned int action) 127static void __cpuinit bcm1480_boot_secondary(int cpu, struct task_struct *idle)
88{ 128{
89 __raw_writeq((((u64)action)<< 48), mailbox_0_set_regs[cpu]); 129 int retval;
130
131 retval = cfe_cpu_start(cpu_logical_map(cpu), &smp_bootstrap,
132 __KSTK_TOS(idle),
133 (unsigned long)task_thread_info(idle), 0);
134 if (retval != 0)
135 printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval);
90} 136}
91 137
138/*
139 * Use CFE to find out how many CPUs are available, setting up
140 * phys_cpu_present_map and the logical/physical mappings.
141 * XXXKW will the boot CPU ever not be physical 0?
142 *
143 * Common setup before any secondaries are started
144 */
145static void __init bcm1480_smp_setup(void)
146{
147 int i, num;
148
149 cpus_clear(phys_cpu_present_map);
150 cpu_set(0, phys_cpu_present_map);
151 __cpu_number_map[0] = 0;
152 __cpu_logical_map[0] = 0;
153
154 for (i = 1, num = 0; i < NR_CPUS; i++) {
155 if (cfe_cpu_stop(i) == 0) {
156 cpu_set(i, phys_cpu_present_map);
157 __cpu_number_map[i] = ++num;
158 __cpu_logical_map[num] = i;
159 }
160 }
161 printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num);
162}
163
164static void __init bcm1480_prepare_cpus(unsigned int max_cpus)
165{
166}
167
168struct plat_smp_ops bcm1480_smp_ops = {
169 .send_ipi_single = bcm1480_send_ipi_single,
170 .send_ipi_mask = bcm1480_send_ipi_mask,
171 .init_secondary = bcm1480_init_secondary,
172 .smp_finish = bcm1480_smp_finish,
173 .cpus_done = bcm1480_cpus_done,
174 .boot_secondary = bcm1480_boot_secondary,
175 .smp_setup = bcm1480_smp_setup,
176 .prepare_cpus = bcm1480_prepare_cpus,
177};
178
92void bcm1480_mailbox_interrupt(void) 179void bcm1480_mailbox_interrupt(void)
93{ 180{
94 int cpu = smp_processor_id(); 181 int cpu = smp_processor_id();
diff --git a/arch/mips/sibyte/cfe/Makefile b/arch/mips/sibyte/cfe/Makefile
index a1214937b705..02b32e142adf 100644
--- a/arch/mips/sibyte/cfe/Makefile
+++ b/arch/mips/sibyte/cfe/Makefile
@@ -1,3 +1,2 @@
1lib-y = setup.o 1lib-y = setup.o
2lib-$(CONFIG_SMP) += smp.o
3lib-$(CONFIG_SIBYTE_CFE_CONSOLE) += console.o 2lib-$(CONFIG_SIBYTE_CFE_CONSOLE) += console.o
diff --git a/arch/mips/sibyte/cfe/setup.c b/arch/mips/sibyte/cfe/setup.c
index dbd6e6fdd3f9..33fce826f8bf 100644
--- a/arch/mips/sibyte/cfe/setup.c
+++ b/arch/mips/sibyte/cfe/setup.c
@@ -28,6 +28,7 @@
28#include <asm/bootinfo.h> 28#include <asm/bootinfo.h>
29#include <asm/reboot.h> 29#include <asm/reboot.h>
30#include <asm/sibyte/board.h> 30#include <asm/sibyte/board.h>
31#include <asm/smp-ops.h>
31 32
32#include <asm/fw/cfe/cfe_api.h> 33#include <asm/fw/cfe/cfe_api.h>
33#include <asm/fw/cfe/cfe_error.h> 34#include <asm/fw/cfe/cfe_error.h>
@@ -232,6 +233,9 @@ static int __init initrd_setup(char *str)
232 233
233#endif 234#endif
234 235
236extern struct plat_smp_ops sb_smp_ops;
237extern struct plat_smp_ops bcm1480_smp_ops;
238
235/* 239/*
236 * prom_init is called just after the cpu type is determined, from setup_arch() 240 * prom_init is called just after the cpu type is determined, from setup_arch()
237 */ 241 */
@@ -297,9 +301,6 @@ void __init prom_init(void)
297 * command line 301 * command line
298 */ 302 */
299 strcpy(arcs_cmdline, "root=/dev/ram0 "); 303 strcpy(arcs_cmdline, "root=/dev/ram0 ");
300#ifdef CONFIG_SIBYTE_PTSWARM
301 strcat(arcs_cmdline, "console=ttyS0,115200 ");
302#endif
303 } else { 304 } else {
304 /* The loader should have set the command line */ 305 /* The loader should have set the command line */
305 /* too early for panic to do any good */ 306 /* too early for panic to do any good */
@@ -340,6 +341,13 @@ void __init prom_init(void)
340 arcs_cmdline[CL_SIZE-1] = 0; 341 arcs_cmdline[CL_SIZE-1] = 0;
341 342
342 prom_meminit(); 343 prom_meminit();
344
345#if defined(CONFIG_SIBYTE_BCM112X) || defined(CONFIG_SIBYTE_SB1250)
346 register_smp_ops(&sb_smp_ops);
347#endif
348#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
349 register_smp_ops(&bcm1480_smp_ops);
350#endif
343} 351}
344 352
345void __init prom_free_prom_memory(void) 353void __init prom_free_prom_memory(void)
diff --git a/arch/mips/sibyte/cfe/smp.c b/arch/mips/sibyte/cfe/smp.c
deleted file mode 100644
index 534a62912f21..000000000000
--- a/arch/mips/sibyte/cfe/smp.c
+++ /dev/null
@@ -1,110 +0,0 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003 Broadcom 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 2
7 * of the License, or (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
19#include <linux/init.h>
20#include <linux/sched.h>
21#include <linux/smp.h>
22#include <asm/processor.h>
23
24#include <asm/fw/cfe/cfe_api.h>
25#include <asm/fw/cfe/cfe_error.h>
26
27/*
28 * Use CFE to find out how many CPUs are available, setting up
29 * phys_cpu_present_map and the logical/physical mappings.
30 * XXXKW will the boot CPU ever not be physical 0?
31 *
32 * Common setup before any secondaries are started
33 */
34void __init plat_smp_setup(void)
35{
36 int i, num;
37
38 cpus_clear(phys_cpu_present_map);
39 cpu_set(0, phys_cpu_present_map);
40 __cpu_number_map[0] = 0;
41 __cpu_logical_map[0] = 0;
42
43 for (i = 1, num = 0; i < NR_CPUS; i++) {
44 if (cfe_cpu_stop(i) == 0) {
45 cpu_set(i, phys_cpu_present_map);
46 __cpu_number_map[i] = ++num;
47 __cpu_logical_map[num] = i;
48 }
49 }
50 printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num);
51}
52
53void __init plat_prepare_cpus(unsigned int max_cpus)
54{
55}
56
57/*
58 * Setup the PC, SP, and GP of a secondary processor and start it
59 * running!
60 */
61void __cpuinit prom_boot_secondary(int cpu, struct task_struct *idle)
62{
63 int retval;
64
65 retval = cfe_cpu_start(cpu_logical_map(cpu), &smp_bootstrap,
66 __KSTK_TOS(idle),
67 (unsigned long)task_thread_info(idle), 0);
68 if (retval != 0)
69 printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval);
70}
71
72/*
73 * Code to run on secondary just after probing the CPU
74 */
75void __cpuinit prom_init_secondary(void)
76{
77#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
78 extern void bcm1480_smp_init(void);
79 bcm1480_smp_init();
80#elif defined(CONFIG_SIBYTE_SB1250)
81 extern void sb1250_smp_init(void);
82 sb1250_smp_init();
83#else
84#error invalid SMP configuration
85#endif
86}
87
88/*
89 * Do any tidying up before marking online and running the idle
90 * loop
91 */
92void __cpuinit prom_smp_finish(void)
93{
94#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
95 extern void bcm1480_smp_finish(void);
96 bcm1480_smp_finish();
97#elif defined(CONFIG_SIBYTE_SB1250)
98 extern void sb1250_smp_finish(void);
99 sb1250_smp_finish();
100#else
101#error invalid SMP configuration
102#endif
103}
104
105/*
106 * Final cleanup after all secondaries booted
107 */
108void prom_cpus_done(void)
109{
110}
diff --git a/arch/mips/sibyte/sb1250/smp.c b/arch/mips/sibyte/sb1250/smp.c
index 3f52c95a4eb8..0734b933e969 100644
--- a/arch/mips/sibyte/sb1250/smp.c
+++ b/arch/mips/sibyte/sb1250/smp.c
@@ -24,6 +24,7 @@
24 24
25#include <asm/mmu_context.h> 25#include <asm/mmu_context.h>
26#include <asm/io.h> 26#include <asm/io.h>
27#include <asm/fw/cfe/cfe_api.h>
27#include <asm/sibyte/sb1250.h> 28#include <asm/sibyte/sb1250.h>
28#include <asm/sibyte/sb1250_regs.h> 29#include <asm/sibyte/sb1250_regs.h>
29#include <asm/sibyte/sb1250_int.h> 30#include <asm/sibyte/sb1250_int.h>
@@ -55,7 +56,43 @@ void __cpuinit sb1250_smp_init(void)
55 change_c0_status(ST0_IM, imask); 56 change_c0_status(ST0_IM, imask);
56} 57}
57 58
58void __cpuinit sb1250_smp_finish(void) 59/*
60 * These are routines for dealing with the sb1250 smp capabilities
61 * independent of board/firmware
62 */
63
64/*
65 * Simple enough; everything is set up, so just poke the appropriate mailbox
66 * register, and we should be set
67 */
68static void sb1250_send_ipi_single(int cpu, unsigned int action)
69{
70 __raw_writeq((((u64)action) << 48), mailbox_set_regs[cpu]);
71}
72
73static inline void sb1250_send_ipi_mask(cpumask_t mask, unsigned int action)
74{
75 unsigned int i;
76
77 for_each_cpu_mask(i, mask)
78 sb1250_send_ipi_single(i, action);
79}
80
81/*
82 * Code to run on secondary just after probing the CPU
83 */
84static void __cpuinit sb1250_init_secondary(void)
85{
86 extern void sb1250_smp_init(void);
87
88 sb1250_smp_init();
89}
90
91/*
92 * Do any tidying up before marking online and running the idle
93 * loop
94 */
95static void __cpuinit sb1250_smp_finish(void)
59{ 96{
60 extern void sb1250_clockevent_init(void); 97 extern void sb1250_clockevent_init(void);
61 98
@@ -64,19 +101,68 @@ void __cpuinit sb1250_smp_finish(void)
64} 101}
65 102
66/* 103/*
67 * These are routines for dealing with the sb1250 smp capabilities 104 * Final cleanup after all secondaries booted
68 * independent of board/firmware
69 */ 105 */
106static void sb1250_cpus_done(void)
107{
108}
70 109
71/* 110/*
72 * Simple enough; everything is set up, so just poke the appropriate mailbox 111 * Setup the PC, SP, and GP of a secondary processor and start it
73 * register, and we should be set 112 * running!
74 */ 113 */
75void core_send_ipi(int cpu, unsigned int action) 114static void __cpuinit sb1250_boot_secondary(int cpu, struct task_struct *idle)
76{ 115{
77 __raw_writeq((((u64)action) << 48), mailbox_set_regs[cpu]); 116 int retval;
117
118 retval = cfe_cpu_start(cpu_logical_map(cpu), &smp_bootstrap,
119 __KSTK_TOS(idle),
120 (unsigned long)task_thread_info(idle), 0);
121 if (retval != 0)
122 printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval);
78} 123}
79 124
125/*
126 * Use CFE to find out how many CPUs are available, setting up
127 * phys_cpu_present_map and the logical/physical mappings.
128 * XXXKW will the boot CPU ever not be physical 0?
129 *
130 * Common setup before any secondaries are started
131 */
132static void __init sb1250_smp_setup(void)
133{
134 int i, num;
135
136 cpus_clear(phys_cpu_present_map);
137 cpu_set(0, phys_cpu_present_map);
138 __cpu_number_map[0] = 0;
139 __cpu_logical_map[0] = 0;
140
141 for (i = 1, num = 0; i < NR_CPUS; i++) {
142 if (cfe_cpu_stop(i) == 0) {
143 cpu_set(i, phys_cpu_present_map);
144 __cpu_number_map[i] = ++num;
145 __cpu_logical_map[num] = i;
146 }
147 }
148 printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num);
149}
150
151static void __init sb1250_prepare_cpus(unsigned int max_cpus)
152{
153}
154
155struct plat_smp_ops sb_smp_ops = {
156 .send_ipi_single = sb1250_send_ipi_single,
157 .send_ipi_mask = sb1250_send_ipi_mask,
158 .init_secondary = sb1250_init_secondary,
159 .smp_finish = sb1250_smp_finish,
160 .cpus_done = sb1250_cpus_done,
161 .boot_secondary = sb1250_boot_secondary,
162 .smp_setup = sb1250_smp_setup,
163 .prepare_cpus = sb1250_prepare_cpus,
164};
165
80void sb1250_mailbox_interrupt(void) 166void sb1250_mailbox_interrupt(void)
81{ 167{
82 int cpu = smp_processor_id(); 168 int cpu = smp_processor_id();
diff --git a/arch/mips/sni/Makefile b/arch/mips/sni/Makefile
index 3a99cd62c0bd..a7dbeebe7fe6 100644
--- a/arch/mips/sni/Makefile
+++ b/arch/mips/sni/Makefile
@@ -3,6 +3,6 @@
3# 3#
4 4
5obj-y += irq.o reset.o setup.o a20r.o rm200.o pcimt.o pcit.o time.o 5obj-y += irq.o reset.o setup.o a20r.o rm200.o pcimt.o pcit.o time.o
6obj-$(CONFIG_CPU_BIG_ENDIAN) += sniprom.o 6obj-$(CONFIG_EISA) += eisa.o
7 7
8EXTRA_CFLAGS += -Werror 8EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/sni/a20r.c b/arch/mips/sni/a20r.c
index b74607599971..3f8cf5eb2f06 100644
--- a/arch/mips/sni/a20r.c
+++ b/arch/mips/sni/a20r.c
@@ -117,10 +117,19 @@ static struct resource sc26xx_rsrc[] = {
117 } 117 }
118}; 118};
119 119
120static unsigned int sc26xx_data[2] = {
121 /* DTR | RTS | DSR | CTS | DCD | RI */
122 (8 << 0) | (4 << 4) | (6 << 8) | (0 << 12) | (6 << 16) | (0 << 20),
123 (3 << 0) | (2 << 4) | (1 << 8) | (2 << 12) | (3 << 16) | (4 << 20)
124};
125
120static struct platform_device sc26xx_pdev = { 126static struct platform_device sc26xx_pdev = {
121 .name = "SC26xx", 127 .name = "SC26xx",
122 .num_resources = ARRAY_SIZE(sc26xx_rsrc), 128 .num_resources = ARRAY_SIZE(sc26xx_rsrc),
123 .resource = sc26xx_rsrc 129 .resource = sc26xx_rsrc,
130 .dev = {
131 .platform_data = sc26xx_data,
132 }
124}; 133};
125 134
126static u32 a20r_ack_hwint(void) 135static u32 a20r_ack_hwint(void)
@@ -231,9 +240,9 @@ static int __init snirm_a20r_setup_devinit(void)
231 platform_device_register(&sc26xx_pdev); 240 platform_device_register(&sc26xx_pdev);
232 platform_device_register(&a20r_serial8250_device); 241 platform_device_register(&a20r_serial8250_device);
233 platform_device_register(&a20r_ds1216_device); 242 platform_device_register(&a20r_ds1216_device);
243 sni_eisa_root_init();
234 break; 244 break;
235 } 245 }
236
237 return 0; 246 return 0;
238} 247}
239 248
diff --git a/arch/mips/sni/eisa.c b/arch/mips/sni/eisa.c
new file mode 100644
index 000000000000..7396cd719900
--- /dev/null
+++ b/arch/mips/sni/eisa.c
@@ -0,0 +1,50 @@
1/*
2 * Virtual EISA root driver.
3 * Acts as a placeholder if we don't have a proper EISA bridge.
4 *
5 * (C) 2003 Marc Zyngier <maz@wild-wind.fr.eu.org>
6 * modified for SNI usage by Thomas Bogendoerfer
7 *
8 * This code is released under the GPL version 2.
9 */
10
11#include <linux/kernel.h>
12#include <linux/platform_device.h>
13#include <linux/eisa.h>
14#include <linux/init.h>
15
16/* The default EISA device parent (virtual root device).
17 * Now use a platform device, since that's the obvious choice. */
18
19static struct platform_device eisa_root_dev = {
20 .name = "eisa",
21 .id = 0,
22};
23
24static struct eisa_root_device eisa_bus_root = {
25 .dev = &eisa_root_dev.dev,
26 .bus_base_addr = 0,
27 .res = &ioport_resource,
28 .slots = EISA_MAX_SLOTS,
29 .dma_mask = 0xffffffff,
30 .force_probe = 1,
31};
32
33int __init sni_eisa_root_init(void)
34{
35 int r;
36
37 r = platform_device_register(&eisa_root_dev);
38 if (!r)
39 return r;
40
41 eisa_root_dev.dev.driver_data = &eisa_bus_root;
42
43 if (eisa_root_register(&eisa_bus_root)) {
44 /* A real bridge may have been registered before
45 * us. So quietly unregister. */
46 platform_device_unregister(&eisa_root_dev);
47 return -1;
48 }
49 return 0;
50}
diff --git a/arch/mips/sni/irq.c b/arch/mips/sni/irq.c
index 9ccffdfb8289..e8e72bb3a9af 100644
--- a/arch/mips/sni/irq.c
+++ b/arch/mips/sni/irq.c
@@ -35,14 +35,14 @@ static irqreturn_t sni_isa_irq_handler(int dummy, void *p)
35 if (unlikely(irq < 0)) 35 if (unlikely(irq < 0))
36 return IRQ_NONE; 36 return IRQ_NONE;
37 37
38 do_IRQ(irq); 38 generic_handle_irq(irq);
39 return IRQ_HANDLED; 39 return IRQ_HANDLED;
40} 40}
41 41
42struct irqaction sni_isa_irq = { 42struct irqaction sni_isa_irq = {
43 .handler = sni_isa_irq_handler, 43 .handler = sni_isa_irq_handler,
44 .name = "ISA", 44 .name = "ISA",
45 .flags = IRQF_SHARED 45 .flags = IRQF_SHARED | IRQF_DISABLED
46}; 46};
47 47
48/* 48/*
diff --git a/arch/mips/sni/pcit.c b/arch/mips/sni/pcit.c
index 416f397c768b..e5f12cf96e8e 100644
--- a/arch/mips/sni/pcit.c
+++ b/arch/mips/sni/pcit.c
@@ -76,6 +76,11 @@ static struct platform_device pcit_cmos_device = {
76 .resource = pcit_cmos_rsrc 76 .resource = pcit_cmos_rsrc
77}; 77};
78 78
79static struct platform_device pcit_pcspeaker_pdev = {
80 .name = "pcspkr",
81 .id = -1,
82};
83
79static struct resource sni_io_resource = { 84static struct resource sni_io_resource = {
80 .start = 0x00000000UL, 85 .start = 0x00000000UL,
81 .end = 0x03bfffffUL, 86 .end = 0x03bfffffUL,
@@ -277,11 +282,13 @@ static int __init snirm_pcit_setup_devinit(void)
277 case SNI_BRD_PCI_TOWER: 282 case SNI_BRD_PCI_TOWER:
278 platform_device_register(&pcit_serial8250_device); 283 platform_device_register(&pcit_serial8250_device);
279 platform_device_register(&pcit_cmos_device); 284 platform_device_register(&pcit_cmos_device);
285 platform_device_register(&pcit_pcspeaker_pdev);
280 break; 286 break;
281 287
282 case SNI_BRD_PCI_TOWER_CPLUS: 288 case SNI_BRD_PCI_TOWER_CPLUS:
283 platform_device_register(&pcit_cplus_serial8250_device); 289 platform_device_register(&pcit_cplus_serial8250_device);
284 platform_device_register(&pcit_cmos_device); 290 platform_device_register(&pcit_cmos_device);
291 platform_device_register(&pcit_pcspeaker_pdev);
285 break; 292 break;
286 } 293 }
287 return 0; 294 return 0;
diff --git a/arch/mips/sni/rm200.c b/arch/mips/sni/rm200.c
index 67b061eef6cd..5310aa75afa4 100644
--- a/arch/mips/sni/rm200.c
+++ b/arch/mips/sni/rm200.c
@@ -5,30 +5,36 @@
5 * License. See the file "COPYING" in the main directory of this archive 5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details. 6 * for more details.
7 * 7 *
8 * Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de) 8 * Copyright (C) 2006,2007 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
9 *
10 * i8259 parts ripped out of arch/mips/kernel/i8259.c
9 */ 11 */
10 12
13#include <linux/delay.h>
11#include <linux/init.h> 14#include <linux/init.h>
12#include <linux/interrupt.h> 15#include <linux/interrupt.h>
13#include <linux/platform_device.h> 16#include <linux/platform_device.h>
14#include <linux/serial_8250.h> 17#include <linux/serial_8250.h>
18#include <linux/io.h>
15 19
16#include <asm/sni.h> 20#include <asm/sni.h>
17#include <asm/time.h> 21#include <asm/time.h>
18#include <asm/irq_cpu.h> 22#include <asm/irq_cpu.h>
19 23
20#define PORT(_base,_irq) \ 24#define RM200_I8259A_IRQ_BASE 32
25
26#define MEMPORT(_base,_irq) \
21 { \ 27 { \
22 .iobase = _base, \ 28 .mapbase = _base, \
23 .irq = _irq, \ 29 .irq = _irq, \
24 .uartclk = 1843200, \ 30 .uartclk = 1843200, \
25 .iotype = UPIO_PORT, \ 31 .iotype = UPIO_MEM, \
26 .flags = UPF_BOOT_AUTOCONF, \ 32 .flags = UPF_BOOT_AUTOCONF|UPF_IOREMAP, \
27 } 33 }
28 34
29static struct plat_serial8250_port rm200_data[] = { 35static struct plat_serial8250_port rm200_data[] = {
30 PORT(0x3f8, 4), 36 MEMPORT(0x160003f8, RM200_I8259A_IRQ_BASE + 4),
31 PORT(0x2f8, 3), 37 MEMPORT(0x160002f8, RM200_I8259A_IRQ_BASE + 3),
32 { }, 38 { },
33}; 39};
34 40
@@ -112,15 +118,311 @@ static int __init snirm_setup_devinit(void)
112 platform_device_register(&rm200_ds1216_device); 118 platform_device_register(&rm200_ds1216_device);
113 platform_device_register(&snirm_82596_rm200_pdev); 119 platform_device_register(&snirm_82596_rm200_pdev);
114 platform_device_register(&snirm_53c710_rm200_pdev); 120 platform_device_register(&snirm_53c710_rm200_pdev);
121 sni_eisa_root_init();
115 } 122 }
116 return 0; 123 return 0;
117} 124}
118 125
119device_initcall(snirm_setup_devinit); 126device_initcall(snirm_setup_devinit);
120 127
128/*
129 * RM200 has an ISA and an EISA bus. The iSA bus is only used
130 * for onboard devices and also has twi i8259 PICs. Since these
131 * PICs are no accessible via inb/outb the following code uses
132 * readb/writeb to access them
133 */
134
135DEFINE_SPINLOCK(sni_rm200_i8259A_lock);
136#define PIC_CMD 0x00
137#define PIC_IMR 0x01
138#define PIC_ISR PIC_CMD
139#define PIC_POLL PIC_ISR
140#define PIC_OCW3 PIC_ISR
141
142/* i8259A PIC related value */
143#define PIC_CASCADE_IR 2
144#define MASTER_ICW4_DEFAULT 0x01
145#define SLAVE_ICW4_DEFAULT 0x01
146
147/*
148 * This contains the irq mask for both 8259A irq controllers,
149 */
150static unsigned int rm200_cached_irq_mask = 0xffff;
151static __iomem u8 *rm200_pic_master;
152static __iomem u8 *rm200_pic_slave;
153
154#define cached_master_mask (rm200_cached_irq_mask)
155#define cached_slave_mask (rm200_cached_irq_mask >> 8)
156
157static void sni_rm200_disable_8259A_irq(unsigned int irq)
158{
159 unsigned int mask;
160 unsigned long flags;
161
162 irq -= RM200_I8259A_IRQ_BASE;
163 mask = 1 << irq;
164 spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
165 rm200_cached_irq_mask |= mask;
166 if (irq & 8)
167 writeb(cached_slave_mask, rm200_pic_slave + PIC_IMR);
168 else
169 writeb(cached_master_mask, rm200_pic_master + PIC_IMR);
170 spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
171}
172
173static void sni_rm200_enable_8259A_irq(unsigned int irq)
174{
175 unsigned int mask;
176 unsigned long flags;
177
178 irq -= RM200_I8259A_IRQ_BASE;
179 mask = ~(1 << irq);
180 spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
181 rm200_cached_irq_mask &= mask;
182 if (irq & 8)
183 writeb(cached_slave_mask, rm200_pic_slave + PIC_IMR);
184 else
185 writeb(cached_master_mask, rm200_pic_master + PIC_IMR);
186 spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
187}
188
189static inline int sni_rm200_i8259A_irq_real(unsigned int irq)
190{
191 int value;
192 int irqmask = 1 << irq;
193
194 if (irq < 8) {
195 writeb(0x0B, rm200_pic_master + PIC_CMD);
196 value = readb(rm200_pic_master + PIC_CMD) & irqmask;
197 writeb(0x0A, rm200_pic_master + PIC_CMD);
198 return value;
199 }
200 writeb(0x0B, rm200_pic_slave + PIC_CMD); /* ISR register */
201 value = readb(rm200_pic_slave + PIC_CMD) & (irqmask >> 8);
202 writeb(0x0A, rm200_pic_slave + PIC_CMD);
203 return value;
204}
205
206/*
207 * Careful! The 8259A is a fragile beast, it pretty
208 * much _has_ to be done exactly like this (mask it
209 * first, _then_ send the EOI, and the order of EOI
210 * to the two 8259s is important!
211 */
212void sni_rm200_mask_and_ack_8259A(unsigned int irq)
213{
214 unsigned int irqmask;
215 unsigned long flags;
216
217 irq -= RM200_I8259A_IRQ_BASE;
218 irqmask = 1 << irq;
219 spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
220 /*
221 * Lightweight spurious IRQ detection. We do not want
222 * to overdo spurious IRQ handling - it's usually a sign
223 * of hardware problems, so we only do the checks we can
224 * do without slowing down good hardware unnecessarily.
225 *
226 * Note that IRQ7 and IRQ15 (the two spurious IRQs
227 * usually resulting from the 8259A-1|2 PICs) occur
228 * even if the IRQ is masked in the 8259A. Thus we
229 * can check spurious 8259A IRQs without doing the
230 * quite slow i8259A_irq_real() call for every IRQ.
231 * This does not cover 100% of spurious interrupts,
232 * but should be enough to warn the user that there
233 * is something bad going on ...
234 */
235 if (rm200_cached_irq_mask & irqmask)
236 goto spurious_8259A_irq;
237 rm200_cached_irq_mask |= irqmask;
238
239handle_real_irq:
240 if (irq & 8) {
241 readb(rm200_pic_slave + PIC_IMR);
242 writeb(cached_slave_mask, rm200_pic_slave + PIC_IMR);
243 writeb(0x60+(irq & 7), rm200_pic_slave + PIC_CMD);
244 writeb(0x60+PIC_CASCADE_IR, rm200_pic_master + PIC_CMD);
245 } else {
246 readb(rm200_pic_master + PIC_IMR);
247 writeb(cached_master_mask, rm200_pic_master + PIC_IMR);
248 writeb(0x60+irq, rm200_pic_master + PIC_CMD);
249 }
250 spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
251 return;
252
253spurious_8259A_irq:
254 /*
255 * this is the slow path - should happen rarely.
256 */
257 if (sni_rm200_i8259A_irq_real(irq))
258 /*
259 * oops, the IRQ _is_ in service according to the
260 * 8259A - not spurious, go handle it.
261 */
262 goto handle_real_irq;
263
264 {
265 static int spurious_irq_mask;
266 /*
267 * At this point we can be sure the IRQ is spurious,
268 * lets ACK and report it. [once per IRQ]
269 */
270 if (!(spurious_irq_mask & irqmask)) {
271 printk(KERN_DEBUG
272 "spurious RM200 8259A interrupt: IRQ%d.\n", irq);
273 spurious_irq_mask |= irqmask;
274 }
275 atomic_inc(&irq_err_count);
276 /*
277 * Theoretically we do not have to handle this IRQ,
278 * but in Linux this does not cause problems and is
279 * simpler for us.
280 */
281 goto handle_real_irq;
282 }
283}
284
285static struct irq_chip sni_rm200_i8259A_chip = {
286 .name = "RM200-XT-PIC",
287 .mask = sni_rm200_disable_8259A_irq,
288 .unmask = sni_rm200_enable_8259A_irq,
289 .mask_ack = sni_rm200_mask_and_ack_8259A,
290};
291
292/*
293 * Do the traditional i8259 interrupt polling thing. This is for the few
294 * cases where no better interrupt acknowledge method is available and we
295 * absolutely must touch the i8259.
296 */
297static inline int sni_rm200_i8259_irq(void)
298{
299 int irq;
300
301 spin_lock(&sni_rm200_i8259A_lock);
302
303 /* Perform an interrupt acknowledge cycle on controller 1. */
304 writeb(0x0C, rm200_pic_master + PIC_CMD); /* prepare for poll */
305 irq = readb(rm200_pic_master + PIC_CMD) & 7;
306 if (irq == PIC_CASCADE_IR) {
307 /*
308 * Interrupt is cascaded so perform interrupt
309 * acknowledge on controller 2.
310 */
311 writeb(0x0C, rm200_pic_slave + PIC_CMD); /* prepare for poll */
312 irq = (readb(rm200_pic_slave + PIC_CMD) & 7) + 8;
313 }
314
315 if (unlikely(irq == 7)) {
316 /*
317 * This may be a spurious interrupt.
318 *
319 * Read the interrupt status register (ISR). If the most
320 * significant bit is not set then there is no valid
321 * interrupt.
322 */
323 writeb(0x0B, rm200_pic_master + PIC_ISR); /* ISR register */
324 if (~readb(rm200_pic_master + PIC_ISR) & 0x80)
325 irq = -1;
326 }
327
328 spin_unlock(&sni_rm200_i8259A_lock);
329
330 return likely(irq >= 0) ? irq + RM200_I8259A_IRQ_BASE : irq;
331}
332
333void sni_rm200_init_8259A(void)
334{
335 unsigned long flags;
336
337 spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
338
339 writeb(0xff, rm200_pic_master + PIC_IMR);
340 writeb(0xff, rm200_pic_slave + PIC_IMR);
341
342 writeb(0x11, rm200_pic_master + PIC_CMD);
343 writeb(0, rm200_pic_master + PIC_IMR);
344 writeb(1U << PIC_CASCADE_IR, rm200_pic_master + PIC_IMR);
345 writeb(MASTER_ICW4_DEFAULT, rm200_pic_master + PIC_IMR);
346 writeb(0x11, rm200_pic_slave + PIC_CMD);
347 writeb(8, rm200_pic_slave + PIC_IMR);
348 writeb(PIC_CASCADE_IR, rm200_pic_slave + PIC_IMR);
349 writeb(SLAVE_ICW4_DEFAULT, rm200_pic_slave + PIC_IMR);
350 udelay(100); /* wait for 8259A to initialize */
351
352 writeb(cached_master_mask, rm200_pic_master + PIC_IMR);
353 writeb(cached_slave_mask, rm200_pic_slave + PIC_IMR);
354
355 spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
356}
357
358/*
359 * IRQ2 is cascade interrupt to second interrupt controller
360 */
361static struct irqaction sni_rm200_irq2 = {
362 no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL
363};
364
365static struct resource sni_rm200_pic1_resource = {
366 .name = "onboard ISA pic1",
367 .start = 0x16000020,
368 .end = 0x16000023,
369 .flags = IORESOURCE_BUSY
370};
371
372static struct resource sni_rm200_pic2_resource = {
373 .name = "onboard ISA pic2",
374 .start = 0x160000a0,
375 .end = 0x160000a3,
376 .flags = IORESOURCE_BUSY
377};
378
379/* ISA irq handler */
380static irqreturn_t sni_rm200_i8259A_irq_handler(int dummy, void *p)
381{
382 int irq;
383
384 irq = sni_rm200_i8259_irq();
385 if (unlikely(irq < 0))
386 return IRQ_NONE;
387
388 do_IRQ(irq);
389 return IRQ_HANDLED;
390}
391
392struct irqaction sni_rm200_i8259A_irq = {
393 .handler = sni_rm200_i8259A_irq_handler,
394 .name = "onboard ISA",
395 .flags = IRQF_SHARED
396};
397
398void __init sni_rm200_i8259_irqs(void)
399{
400 int i;
401
402 rm200_pic_master = ioremap_nocache(0x16000020, 4);
403 if (!rm200_pic_master)
404 return;
405 rm200_pic_slave = ioremap_nocache(0x160000a0, 4);
406 if (!rm200_pic_master) {
407 iounmap(rm200_pic_master);
408 return;
409 }
410
411 insert_resource(&iomem_resource, &sni_rm200_pic1_resource);
412 insert_resource(&iomem_resource, &sni_rm200_pic2_resource);
413
414 sni_rm200_init_8259A();
415
416 for (i = RM200_I8259A_IRQ_BASE; i < RM200_I8259A_IRQ_BASE + 16; i++)
417 set_irq_chip_and_handler(i, &sni_rm200_i8259A_chip,
418 handle_level_irq);
419
420 setup_irq(RM200_I8259A_IRQ_BASE + PIC_CASCADE_IR, &sni_rm200_irq2);
421}
422
121 423
122#define SNI_RM200_INT_STAT_REG 0xbc000000 424#define SNI_RM200_INT_STAT_REG CKSEG1ADDR(0xbc000000)
123#define SNI_RM200_INT_ENA_REG 0xbc080000 425#define SNI_RM200_INT_ENA_REG CKSEG1ADDR(0xbc080000)
124 426
125#define SNI_RM200_INT_START 24 427#define SNI_RM200_INT_START 24
126#define SNI_RM200_INT_END 28 428#define SNI_RM200_INT_END 28
@@ -181,17 +483,17 @@ void __init sni_rm200_irq_init(void)
181 483
182 * (volatile u8 *)SNI_RM200_INT_ENA_REG = 0x1f; 484 * (volatile u8 *)SNI_RM200_INT_ENA_REG = 0x1f;
183 485
486 sni_rm200_i8259_irqs();
184 mips_cpu_irq_init(); 487 mips_cpu_irq_init();
185 /* Actually we've got more interrupts to handle ... */ 488 /* Actually we've got more interrupts to handle ... */
186 for (i = SNI_RM200_INT_START; i <= SNI_RM200_INT_END; i++) 489 for (i = SNI_RM200_INT_START; i <= SNI_RM200_INT_END; i++)
187 set_irq_chip(i, &rm200_irq_type); 490 set_irq_chip(i, &rm200_irq_type);
188 sni_hwint = sni_rm200_hwint; 491 sni_hwint = sni_rm200_hwint;
189 change_c0_status(ST0_IM, IE_IRQ0); 492 change_c0_status(ST0_IM, IE_IRQ0);
190 setup_irq(SNI_RM200_INT_START + 0, &sni_isa_irq); 493 setup_irq(SNI_RM200_INT_START + 0, &sni_rm200_i8259A_irq);
494 setup_irq(SNI_RM200_INT_START + 1, &sni_isa_irq);
191} 495}
192 496
193void __init sni_rm200_init(void) 497void __init sni_rm200_init(void)
194{ 498{
195 set_io_port_base(SNI_PORT_BASE + 0x02000000);
196 ioport_resource.end += 0x02000000;
197} 499}
diff --git a/arch/mips/sni/setup.c b/arch/mips/sni/setup.c
index e8b26bdee24c..5484e1c62054 100644
--- a/arch/mips/sni/setup.c
+++ b/arch/mips/sni/setup.c
@@ -19,11 +19,17 @@
19#include <asm/sgialib.h> 19#include <asm/sgialib.h>
20#endif 20#endif
21 21
22#ifdef CONFIG_SNIPROM
23#include <asm/mipsprom.h>
24#endif
25
26#include <asm/bootinfo.h>
22#include <asm/io.h> 27#include <asm/io.h>
23#include <asm/reboot.h> 28#include <asm/reboot.h>
24#include <asm/sni.h> 29#include <asm/sni.h>
25 30
26unsigned int sni_brd_type; 31unsigned int sni_brd_type;
32EXPORT_SYMBOL(sni_brd_type);
27 33
28extern void sni_machine_restart(char *command); 34extern void sni_machine_restart(char *command);
29extern void sni_machine_power_off(void); 35extern void sni_machine_power_off(void);
@@ -47,20 +53,152 @@ static void __init sni_display_setup(void)
47#endif 53#endif
48} 54}
49 55
56static void __init sni_console_setup(void)
57{
58#ifndef CONFIG_ARC
59 char *ctype;
60 char *cdev;
61 char *baud;
62 int port;
63 static char options[8];
64
65 cdev = prom_getenv("console_dev");
66 if (strncmp(cdev, "tty", 3) == 0) {
67 ctype = prom_getenv("console");
68 switch (*ctype) {
69 default:
70 case 'l':
71 port = 0;
72 baud = prom_getenv("lbaud");
73 break;
74 case 'r':
75 port = 1;
76 baud = prom_getenv("rbaud");
77 break;
78 }
79 if (baud)
80 strcpy(options, baud);
81 if (strncmp(cdev, "tty552", 6) == 0)
82 add_preferred_console("ttyS", port,
83 baud ? options : NULL);
84 else
85 add_preferred_console("ttySC", port,
86 baud ? options : NULL);
87 }
88#endif
89}
90
91#ifdef DEBUG
92static void __init sni_idprom_dump(void)
93{
94 int i;
95
96 pr_debug("SNI IDProm dump:\n");
97 for (i = 0; i < 256; i++) {
98 if (i%16 == 0)
99 pr_debug("%04x ", i);
100
101 printk("%02x ", *(unsigned char *) (SNI_IDPROM_BASE + i));
102
103 if (i % 16 == 15)
104 printk("\n");
105 }
106}
107#endif
50 108
51void __init plat_mem_setup(void) 109void __init plat_mem_setup(void)
52{ 110{
111 int cputype;
112
53 set_io_port_base(SNI_PORT_BASE); 113 set_io_port_base(SNI_PORT_BASE);
54// ioport_resource.end = sni_io_resource.end; 114// ioport_resource.end = sni_io_resource.end;
55 115
56 /* 116 /*
57 * Setup (E)ISA I/O memory access stuff 117 * Setup (E)ISA I/O memory access stuff
58 */ 118 */
59 isa_slot_offset = 0xb0000000; 119 isa_slot_offset = CKSEG1ADDR(0xb0000000);
60#ifdef CONFIG_EISA 120#ifdef CONFIG_EISA
61 EISA_bus = 1; 121 EISA_bus = 1;
62#endif 122#endif
63 123
124 sni_brd_type = *(unsigned char *)SNI_IDPROM_BRDTYPE;
125 cputype = *(unsigned char *)SNI_IDPROM_CPUTYPE;
126 switch (sni_brd_type) {
127 case SNI_BRD_TOWER_OASIC:
128 switch (cputype) {
129 case SNI_CPU_M8030:
130 system_type = "RM400-330";
131 break;
132 case SNI_CPU_M8031:
133 system_type = "RM400-430";
134 break;
135 case SNI_CPU_M8037:
136 system_type = "RM400-530";
137 break;
138 case SNI_CPU_M8034:
139 system_type = "RM400-730";
140 break;
141 default:
142 system_type = "RM400-xxx";
143 break;
144 }
145 break;
146 case SNI_BRD_MINITOWER:
147 switch (cputype) {
148 case SNI_CPU_M8021:
149 case SNI_CPU_M8043:
150 system_type = "RM400-120";
151 break;
152 case SNI_CPU_M8040:
153 system_type = "RM400-220";
154 break;
155 case SNI_CPU_M8053:
156 system_type = "RM400-225";
157 break;
158 case SNI_CPU_M8050:
159 system_type = "RM400-420";
160 break;
161 default:
162 system_type = "RM400-xxx";
163 break;
164 }
165 break;
166 case SNI_BRD_PCI_TOWER:
167 system_type = "RM400-Cxx";
168 break;
169 case SNI_BRD_RM200:
170 system_type = "RM200-xxx";
171 break;
172 case SNI_BRD_PCI_MTOWER:
173 system_type = "RM300-Cxx";
174 break;
175 case SNI_BRD_PCI_DESKTOP:
176 switch (read_c0_prid() & 0xff00) {
177 case PRID_IMP_R4600:
178 case PRID_IMP_R4700:
179 system_type = "RM200-C20";
180 break;
181 case PRID_IMP_R5000:
182 system_type = "RM200-C40";
183 break;
184 default:
185 system_type = "RM200-Cxx";
186 break;
187 }
188 break;
189 case SNI_BRD_PCI_TOWER_CPLUS:
190 system_type = "RM400-Exx";
191 break;
192 case SNI_BRD_PCI_MTOWER_CPLUS:
193 system_type = "RM300-Exx";
194 break;
195 }
196 pr_debug("Found SNI brdtype %02x name %s\n", sni_brd_type, system_type);
197
198#ifdef DEBUG
199 sni_idprom_dump();
200#endif
201
64 switch (sni_brd_type) { 202 switch (sni_brd_type) {
65 case SNI_BRD_10: 203 case SNI_BRD_10:
66 case SNI_BRD_10NEW: 204 case SNI_BRD_10NEW:
@@ -89,9 +227,10 @@ void __init plat_mem_setup(void)
89 pm_power_off = sni_machine_power_off; 227 pm_power_off = sni_machine_power_off;
90 228
91 sni_display_setup(); 229 sni_display_setup();
230 sni_console_setup();
92} 231}
93 232
94#if CONFIG_PCI 233#ifdef CONFIG_PCI
95 234
96#include <linux/pci.h> 235#include <linux/pci.h>
97#include <video/vga.h> 236#include <video/vga.h>
diff --git a/arch/mips/sni/sniprom.c b/arch/mips/sni/sniprom.c
deleted file mode 100644
index eff4b89d7b75..000000000000
--- a/arch/mips/sni/sniprom.c
+++ /dev/null
@@ -1,251 +0,0 @@
1/*
2 * Big Endian PROM code for SNI RM machines
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2005-2006 Florian Lohoff (flo@rfc822.org)
9 * Copyright (C) 2005-2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
10 */
11
12#define DEBUG
13
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/string.h>
17#include <linux/console.h>
18
19#include <asm/addrspace.h>
20#include <asm/sni.h>
21#include <asm/mipsprom.h>
22#include <asm/mipsregs.h>
23#include <asm/bootinfo.h>
24
25/* special SNI prom calls */
26/*
27 * This does not exist in all proms - SINIX compares
28 * the prom env variable "version" against "2.0008"
29 * or greater. If lesser it tries to probe interesting
30 * registers
31 */
32#define PROM_GET_MEMCONF 58
33
34#define PROM_VEC (u64 *)CKSEG1ADDR(0x1fc00000)
35#define PROM_ENTRY(x) (PROM_VEC + (x))
36
37
38static int *(*__prom_putchar)(int) = (int *(*)(int))PROM_ENTRY(PROM_PUTCHAR);
39
40void prom_putchar(char c)
41{
42 __prom_putchar(c);
43}
44
45static char *(*__prom_getenv)(char *) = (char *(*)(char *))PROM_ENTRY(PROM_GETENV);
46static void (*__prom_get_memconf)(void *) = (void (*)(void *))PROM_ENTRY(PROM_GET_MEMCONF);
47
48char *prom_getenv(char *s)
49{
50 return __prom_getenv(s);
51}
52
53void __init prom_free_prom_memory(void)
54{
55}
56
57/*
58 * /proc/cpuinfo system type
59 *
60 */
61static const char *systype = "Unknown";
62const char *get_system_type(void)
63{
64 return systype;
65}
66
67#define SNI_IDPROM_BASE 0xbff00000
68#define SNI_IDPROM_MEMSIZE (SNI_IDPROM_BASE+0x28) /* Memsize in 16MB quantities */
69#define SNI_IDPROM_BRDTYPE (SNI_IDPROM_BASE+0x29) /* Board Type */
70#define SNI_IDPROM_CPUTYPE (SNI_IDPROM_BASE+0x30) /* CPU Type */
71
72#define SNI_IDPROM_SIZE 0x1000
73
74#ifdef DEBUG
75static void __init sni_idprom_dump(void)
76{
77 int i;
78
79 pr_debug("SNI IDProm dump:\n");
80 for (i = 0; i < 256; i++) {
81 if (i%16 == 0)
82 pr_debug("%04x ", i);
83
84 printk("%02x ", *(unsigned char *) (SNI_IDPROM_BASE + i));
85
86 if (i % 16 == 15)
87 printk("\n");
88 }
89}
90#endif
91
92static void __init sni_mem_init(void )
93{
94 int i, memsize;
95 struct membank {
96 u32 size;
97 u32 base;
98 u32 size2;
99 u32 pad1;
100 u32 pad2;
101 } memconf[8];
102
103 /* MemSIZE from prom in 16MByte chunks */
104 memsize = *((unsigned char *) SNI_IDPROM_MEMSIZE) * 16;
105
106 pr_debug("IDProm memsize: %lu MByte\n", memsize);
107
108 /* get memory bank layout from prom */
109 __prom_get_memconf(&memconf);
110
111 pr_debug("prom_get_mem_conf memory configuration:\n");
112 for (i = 0;i < 8 && memconf[i].size; i++) {
113 if (sni_brd_type == SNI_BRD_PCI_TOWER ||
114 sni_brd_type == SNI_BRD_PCI_TOWER_CPLUS) {
115 if (memconf[i].base >= 0x20000000 &&
116 memconf[i].base < 0x30000000) {
117 memconf[i].base -= 0x20000000;
118 }
119 }
120 pr_debug("Bank%d: %08x @ %08x\n", i,
121 memconf[i].size, memconf[i].base);
122 add_memory_region(memconf[i].base, memconf[i].size, BOOT_MEM_RAM);
123 }
124}
125
126static void __init sni_console_setup(void)
127{
128 char *ctype;
129 char *cdev;
130 char *baud;
131 int port;
132 static char options[8];
133
134 cdev = prom_getenv("console_dev");
135 if (strncmp (cdev, "tty", 3) == 0) {
136 ctype = prom_getenv("console");
137 switch (*ctype) {
138 default:
139 case 'l':
140 port = 0;
141 baud = prom_getenv("lbaud");
142 break;
143 case 'r':
144 port = 1;
145 baud = prom_getenv("rbaud");
146 break;
147 }
148 if (baud)
149 strcpy(options, baud);
150 if (strncmp (cdev, "tty552", 6) == 0)
151 add_preferred_console("ttyS", port, baud ? options : NULL);
152 else
153 add_preferred_console("ttySC", port, baud ? options : NULL);
154 }
155}
156
157void __init prom_init(void)
158{
159 int argc = fw_arg0;
160 char **argv = (void *)fw_arg1;
161 int i;
162 int cputype;
163
164 sni_brd_type = *(unsigned char *)SNI_IDPROM_BRDTYPE;
165 cputype = *(unsigned char *)SNI_IDPROM_CPUTYPE;
166 switch (sni_brd_type) {
167 case SNI_BRD_TOWER_OASIC:
168 switch (cputype) {
169 case SNI_CPU_M8030:
170 systype = "RM400-330";
171 break;
172 case SNI_CPU_M8031:
173 systype = "RM400-430";
174 break;
175 case SNI_CPU_M8037:
176 systype = "RM400-530";
177 break;
178 case SNI_CPU_M8034:
179 systype = "RM400-730";
180 break;
181 default:
182 systype = "RM400-xxx";
183 break;
184 }
185 break;
186 case SNI_BRD_MINITOWER:
187 switch (cputype) {
188 case SNI_CPU_M8021:
189 case SNI_CPU_M8043:
190 systype = "RM400-120";
191 break;
192 case SNI_CPU_M8040:
193 systype = "RM400-220";
194 break;
195 case SNI_CPU_M8053:
196 systype = "RM400-225";
197 break;
198 case SNI_CPU_M8050:
199 systype = "RM400-420";
200 break;
201 default:
202 systype = "RM400-xxx";
203 break;
204 }
205 break;
206 case SNI_BRD_PCI_TOWER:
207 systype = "RM400-Cxx";
208 break;
209 case SNI_BRD_RM200:
210 systype = "RM200-xxx";
211 break;
212 case SNI_BRD_PCI_MTOWER:
213 systype = "RM300-Cxx";
214 break;
215 case SNI_BRD_PCI_DESKTOP:
216 switch (read_c0_prid() & 0xff00) {
217 case PRID_IMP_R4600:
218 case PRID_IMP_R4700:
219 systype = "RM200-C20";
220 break;
221 case PRID_IMP_R5000:
222 systype = "RM200-C40";
223 break;
224 default:
225 systype = "RM200-Cxx";
226 break;
227 }
228 break;
229 case SNI_BRD_PCI_TOWER_CPLUS:
230 systype = "RM400-Exx";
231 break;
232 case SNI_BRD_PCI_MTOWER_CPLUS:
233 systype = "RM300-Exx";
234 break;
235 }
236 pr_debug("Found SNI brdtype %02x name %s\n", sni_brd_type, systype);
237
238#ifdef DEBUG
239 sni_idprom_dump();
240#endif
241 sni_mem_init();
242 sni_console_setup();
243
244 /* copy prom cmdline parameters to kernel cmdline */
245 for (i = 1; i < argc; i++) {
246 strcat(arcs_cmdline, argv[i]);
247 if (i < (argc - 1))
248 strcat(arcs_cmdline, " ");
249 }
250}
251
diff --git a/arch/mips/sni/time.c b/arch/mips/sni/time.c
index 6f339af08d22..796e3ce28720 100644
--- a/arch/mips/sni/time.c
+++ b/arch/mips/sni/time.c
@@ -178,6 +178,7 @@ void __init plat_time_init(void)
178 sni_a20r_timer_setup(); 178 sni_a20r_timer_setup();
179 break; 179 break;
180 } 180 }
181 setup_pit_timer();
181} 182}
182 183
183unsigned long read_persistent_clock(void) 184unsigned long read_persistent_clock(void)
diff --git a/arch/mips/tx4927/common/Makefile b/arch/mips/tx4927/common/Makefile
index 18375787e094..a7fe76a64964 100644
--- a/arch/mips/tx4927/common/Makefile
+++ b/arch/mips/tx4927/common/Makefile
@@ -1,12 +1,8 @@
1# 1#
2# Makefile for common code for Toshiba TX4927 based systems 2# Makefile for common code for Toshiba TX4927 based systems
3# 3#
4# Note! Dependencies are done automagically by 'make dep', which also
5# removes any old dependencies. DON'T put your own dependencies here
6# unless it's something special (ie not a .c file).
7#
8 4
9obj-y += tx4927_prom.o tx4927_setup.o tx4927_irq.o 5obj-y += tx4927_prom.o tx4927_irq.o
10 6
11obj-$(CONFIG_TOSHIBA_FPCIB0) += smsc_fdc37m81x.o 7obj-$(CONFIG_TOSHIBA_FPCIB0) += smsc_fdc37m81x.o
12obj-$(CONFIG_KGDB) += tx4927_dbgio.o 8obj-$(CONFIG_KGDB) += tx4927_dbgio.o
diff --git a/arch/mips/tx4927/common/tx4927_setup.c b/arch/mips/tx4927/common/tx4927_setup.c
deleted file mode 100644
index 36c5f200eb3d..000000000000
--- a/arch/mips/tx4927/common/tx4927_setup.c
+++ /dev/null
@@ -1,186 +0,0 @@
1/*
2 * Author: MontaVista Software, Inc.
3 * source@mvista.com
4 *
5 * Copyright 2001-2002 MontaVista Software Inc.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
13 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
15 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
16 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
17 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
18 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
20 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
21 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22 *
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27#include <linux/errno.h>
28#include <linux/init.h>
29#include <linux/kernel_stat.h>
30#include <linux/module.h>
31#include <linux/signal.h>
32#include <linux/sched.h>
33#include <linux/types.h>
34#include <linux/interrupt.h>
35#include <linux/ioport.h>
36#include <linux/timex.h>
37#include <linux/slab.h>
38#include <linux/random.h>
39#include <linux/irq.h>
40#include <linux/bitops.h>
41#include <asm/bootinfo.h>
42#include <asm/io.h>
43#include <asm/irq.h>
44#include <asm/mipsregs.h>
45#include <asm/system.h>
46#include <asm/time.h>
47#include <asm/tx4927/tx4927.h>
48
49
50#undef DEBUG
51
52void dump_cp0(char *key);
53
54
55void __init plat_mem_setup(void)
56{
57#ifdef CONFIG_TOSHIBA_RBTX4927
58 {
59 extern void toshiba_rbtx4927_setup(void);
60 toshiba_rbtx4927_setup();
61 }
62#endif
63}
64
65void __init plat_time_init(void)
66{
67#ifdef CONFIG_TOSHIBA_RBTX4927
68 {
69 extern void toshiba_rbtx4927_time_init(void);
70 toshiba_rbtx4927_time_init();
71 }
72#endif
73}
74
75#ifdef DEBUG
76void print_cp0(char *key, int num, char *name, u32 val)
77{
78 printk("%s cp0:%02d:%s=0x%08x\n", key, num, name, val);
79 return;
80}
81
82void
83dump_cp0(char *key)
84{
85 if (key == NULL)
86 key = "";
87
88 print_cp0(key, 0, "INDEX ", read_c0_index());
89 print_cp0(key, 2, "ENTRYLO1", read_c0_entrylo0());
90 print_cp0(key, 3, "ENTRYLO2", read_c0_entrylo1());
91 print_cp0(key, 4, "CONTEXT ", read_c0_context());
92 print_cp0(key, 5, "PAGEMASK", read_c0_pagemask());
93 print_cp0(key, 6, "WIRED ", read_c0_wired());
94 //print_cp0(key, 8, "BADVADDR", read_c0_badvaddr());
95 print_cp0(key, 9, "COUNT ", read_c0_count());
96 print_cp0(key, 10, "ENTRYHI ", read_c0_entryhi());
97 print_cp0(key, 11, "COMPARE ", read_c0_compare());
98 print_cp0(key, 12, "STATUS ", read_c0_status());
99 print_cp0(key, 13, "CAUSE ", read_c0_cause() & 0xffff87ff);
100 print_cp0(key, 16, "CONFIG ", read_c0_config());
101 return;
102}
103
104void print_pic(char *key, unsigned long reg, char *name)
105{
106 printk(KERN_INFO "%s pic:0x%08lx:%s=0x%08x\n", key, reg, name,
107 __raw_readl((void __iomem *)reg));
108 return;
109}
110
111
112void dump_pic(char *key)
113{
114 if (key == NULL)
115 key = "";
116
117 print_pic(key, 0xff1ff600, "IRDEN ");
118 print_pic(key, 0xff1ff604, "IRDM0 ");
119 print_pic(key, 0xff1ff608, "IRDM1 ");
120
121 print_pic(key, 0xff1ff610, "IRLVL0 ");
122 print_pic(key, 0xff1ff614, "IRLVL1 ");
123 print_pic(key, 0xff1ff618, "IRLVL2 ");
124 print_pic(key, 0xff1ff61c, "IRLVL3 ");
125 print_pic(key, 0xff1ff620, "IRLVL4 ");
126 print_pic(key, 0xff1ff624, "IRLVL5 ");
127 print_pic(key, 0xff1ff628, "IRLVL6 ");
128 print_pic(key, 0xff1ff62c, "IRLVL7 ");
129
130 print_pic(key, 0xff1ff640, "IRMSK ");
131 print_pic(key, 0xff1ff660, "IREDC ");
132 print_pic(key, 0xff1ff680, "IRPND ");
133 print_pic(key, 0xff1ff6a0, "IRCS ");
134
135 print_pic(key, 0xff1ff514, "IRFLAG1 "); /* don't read IRLAG0 -- it hangs system */
136
137 print_pic(key, 0xff1ff518, "IRPOL ");
138 print_pic(key, 0xff1ff51c, "IRRCNT ");
139 print_pic(key, 0xff1ff520, "IRMASKINT");
140 print_pic(key, 0xff1ff524, "IRMASKEXT");
141
142 return;
143}
144
145
146void print_addr(char *hdr, char *key, unsigned long addr)
147{
148 printk(KERN_INFO "%s %s:0x%08lx=0x%08x\n", hdr, key, addr,
149 __raw_readl((void __iomem *)addr));
150 return;
151}
152
153
154void dump_180(char *key)
155{
156 u32 i;
157
158 for (i = 0x80000180; i < 0x80000180 + 0x80; i += 4) {
159 print_addr("180", key, i);
160 }
161 return;
162}
163
164
165void dump_eh0(char *key)
166{
167 int i;
168 extern unsigned long exception_handlers[];
169
170 for (i = (int) exception_handlers;
171 i < (int) (exception_handlers + 20); i += 4) {
172 print_addr("eh0", key, i);
173 }
174
175 return;
176}
177
178void pk0(void)
179{
180 volatile u32 val;
181
182 __asm__ __volatile__("ori %0, $26, 0":"=r"(val)
183 );
184 printk("k0=[0x%08x]\n", val);
185}
186#endif
diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
index 0299595ce1c4..e466e5e711d8 100644
--- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
+++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
@@ -45,27 +45,19 @@
45#include <linux/init.h> 45#include <linux/init.h>
46#include <linux/kernel.h> 46#include <linux/kernel.h>
47#include <linux/types.h> 47#include <linux/types.h>
48#include <linux/mm.h>
49#include <linux/swap.h>
50#include <linux/ioport.h> 48#include <linux/ioport.h>
51#include <linux/sched.h>
52#include <linux/interrupt.h> 49#include <linux/interrupt.h>
53#include <linux/pci.h> 50#include <linux/pci.h>
54#include <linux/timex.h>
55#include <linux/pm.h> 51#include <linux/pm.h>
56#include <linux/platform_device.h> 52#include <linux/platform_device.h>
53#include <linux/clk.h>
57 54
58#include <asm/bootinfo.h> 55#include <asm/bootinfo.h>
59#include <asm/page.h>
60#include <asm/io.h> 56#include <asm/io.h>
61#include <asm/irq.h>
62#include <asm/irq_regs.h>
63#include <asm/processor.h> 57#include <asm/processor.h>
64#include <asm/reboot.h> 58#include <asm/reboot.h>
65#include <asm/time.h> 59#include <asm/time.h>
66#include <asm/txx9tmr.h> 60#include <asm/txx9tmr.h>
67#include <linux/bootmem.h>
68#include <linux/blkdev.h>
69#ifdef CONFIG_TOSHIBA_FPCIB0 61#ifdef CONFIG_TOSHIBA_FPCIB0
70#include <asm/tx4927/smsc_fdc37m81x.h> 62#include <asm/tx4927/smsc_fdc37m81x.h>
71#endif 63#endif
@@ -73,42 +65,26 @@
73#ifdef CONFIG_PCI 65#ifdef CONFIG_PCI
74#include <asm/tx4927/tx4927_pci.h> 66#include <asm/tx4927/tx4927_pci.h>
75#endif 67#endif
76#ifdef CONFIG_BLK_DEV_IDEPCI
77#include <linux/hdreg.h>
78#include <linux/ide.h>
79#endif
80#ifdef CONFIG_SERIAL_TXX9 68#ifdef CONFIG_SERIAL_TXX9
81#include <linux/tty.h>
82#include <linux/serial.h>
83#include <linux/serial_core.h> 69#include <linux/serial_core.h>
84#endif 70#endif
85 71
86#undef TOSHIBA_RBTX4927_SETUP_DEBUG 72#undef TOSHIBA_RBTX4927_SETUP_DEBUG
87 73
88#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG 74#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG
89#define TOSHIBA_RBTX4927_SETUP_NONE 0x00000000
90
91#define TOSHIBA_RBTX4927_SETUP_INFO ( 1 << 0 )
92#define TOSHIBA_RBTX4927_SETUP_WARN ( 1 << 1 )
93#define TOSHIBA_RBTX4927_SETUP_EROR ( 1 << 2 )
94
95#define TOSHIBA_RBTX4927_SETUP_EFWFU ( 1 << 3 )
96#define TOSHIBA_RBTX4927_SETUP_SETUP ( 1 << 4 ) 75#define TOSHIBA_RBTX4927_SETUP_SETUP ( 1 << 4 )
97#define TOSHIBA_RBTX4927_SETUP_PCIBIOS ( 1 << 7 ) 76#define TOSHIBA_RBTX4927_SETUP_PCIBIOS ( 1 << 7 )
98#define TOSHIBA_RBTX4927_SETUP_PCI1 ( 1 << 8 ) 77#define TOSHIBA_RBTX4927_SETUP_PCI1 ( 1 << 8 )
99#define TOSHIBA_RBTX4927_SETUP_PCI2 ( 1 << 9 ) 78#define TOSHIBA_RBTX4927_SETUP_PCI2 ( 1 << 9 )
100#define TOSHIBA_RBTX4927_SETUP_PCI66 ( 1 << 10 )
101 79
102#define TOSHIBA_RBTX4927_SETUP_ALL 0xffffffff 80#define TOSHIBA_RBTX4927_SETUP_ALL 0xffffffff
103#endif 81#endif
104 82
105#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG 83#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG
106static const u32 toshiba_rbtx4927_setup_debug_flag = 84static const u32 toshiba_rbtx4927_setup_debug_flag =
107 (TOSHIBA_RBTX4927_SETUP_NONE | TOSHIBA_RBTX4927_SETUP_INFO | 85 (TOSHIBA_RBTX4927_SETUP_SETUP |
108 TOSHIBA_RBTX4927_SETUP_WARN | TOSHIBA_RBTX4927_SETUP_EROR |
109 TOSHIBA_RBTX4927_SETUP_EFWFU | TOSHIBA_RBTX4927_SETUP_SETUP |
110 | TOSHIBA_RBTX4927_SETUP_PCIBIOS | TOSHIBA_RBTX4927_SETUP_PCI1 | 86 | TOSHIBA_RBTX4927_SETUP_PCIBIOS | TOSHIBA_RBTX4927_SETUP_PCI1 |
111 TOSHIBA_RBTX4927_SETUP_PCI2 | TOSHIBA_RBTX4927_SETUP_PCI66); 87 TOSHIBA_RBTX4927_SETUP_PCI2);
112#endif 88#endif
113 89
114#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG 90#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG
@@ -718,7 +694,7 @@ void toshiba_rbtx4927_power_off(void)
718 /* no return */ 694 /* no return */
719} 695}
720 696
721void __init toshiba_rbtx4927_setup(void) 697void __init plat_mem_setup(void)
722{ 698{
723 int i; 699 int i;
724 u32 cp0_config; 700 u32 cp0_config;
@@ -741,13 +717,6 @@ void __init toshiba_rbtx4927_setup(void)
741 cp0_config = cp0_config & ~(TX49_CONF_IC | TX49_CONF_DC); 717 cp0_config = cp0_config & ~(TX49_CONF_IC | TX49_CONF_DC);
742 write_c0_config(cp0_config); 718 write_c0_config(cp0_config);
743 719
744#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG
745 {
746 extern void dump_cp0(char *);
747 dump_cp0("toshiba_rbtx4927_early_fw_fixup");
748 }
749#endif
750
751 set_io_port_base(KSEG1 + TBTX4927_ISA_IO_OFFSET); 720 set_io_port_base(KSEG1 + TBTX4927_ISA_IO_OFFSET);
752 TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, 721 TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP,
753 ":mips_io_port_base=0x%08lx\n", 722 ":mips_io_port_base=0x%08lx\n",
@@ -835,6 +804,8 @@ void __init toshiba_rbtx4927_setup(void)
835 } 804 }
836 805
837 /* CCFG */ 806 /* CCFG */
807 /* do reset on watchdog */
808 tx4927_ccfgptr->ccfg |= TX4927_CCFG_WR;
838 /* enable Timeout BusError */ 809 /* enable Timeout BusError */
839 if (tx4927_ccfg_toeon) 810 if (tx4927_ccfg_toeon)
840 tx4927_ccfgptr->ccfg |= TX4927_CCFG_TOE; 811 tx4927_ccfgptr->ccfg |= TX4927_CCFG_TOE;
@@ -936,8 +907,7 @@ void __init toshiba_rbtx4927_setup(void)
936 "+\n"); 907 "+\n");
937} 908}
938 909
939void __init 910void __init plat_time_init(void)
940toshiba_rbtx4927_time_init(void)
941{ 911{
942 mips_hpt_frequency = tx4927_cpu_clock / 2; 912 mips_hpt_frequency = tx4927_cpu_clock / 2;
943 if (tx4927_ccfgptr->ccfg & TX4927_CCFG_TINTDIS) 913 if (tx4927_ccfgptr->ccfg & TX4927_CCFG_TINTDIS)
@@ -977,3 +947,55 @@ static int __init rbtx4927_ne_init(void)
977 return IS_ERR(dev) ? PTR_ERR(dev) : 0; 947 return IS_ERR(dev) ? PTR_ERR(dev) : 0;
978} 948}
979device_initcall(rbtx4927_ne_init); 949device_initcall(rbtx4927_ne_init);
950
951/* Watchdog support */
952
953static int __init txx9_wdt_init(unsigned long base)
954{
955 struct resource res = {
956 .start = base,
957 .end = base + 0x100 - 1,
958 .flags = IORESOURCE_MEM,
959 };
960 struct platform_device *dev =
961 platform_device_register_simple("txx9wdt", -1, &res, 1);
962 return IS_ERR(dev) ? PTR_ERR(dev) : 0;
963}
964
965static int __init rbtx4927_wdt_init(void)
966{
967 return txx9_wdt_init(TX4927_TMR_REG(2) & 0xfffffffffULL);
968}
969device_initcall(rbtx4927_wdt_init);
970
971/* Minimum CLK support */
972
973struct clk *clk_get(struct device *dev, const char *id)
974{
975 if (!strcmp(id, "imbus_clk"))
976 return (struct clk *)50000000;
977 return ERR_PTR(-ENOENT);
978}
979EXPORT_SYMBOL(clk_get);
980
981int clk_enable(struct clk *clk)
982{
983 return 0;
984}
985EXPORT_SYMBOL(clk_enable);
986
987void clk_disable(struct clk *clk)
988{
989}
990EXPORT_SYMBOL(clk_disable);
991
992unsigned long clk_get_rate(struct clk *clk)
993{
994 return (unsigned long)clk;
995}
996EXPORT_SYMBOL(clk_get_rate);
997
998void clk_put(struct clk *clk)
999{
1000}
1001EXPORT_SYMBOL(clk_put);
diff --git a/arch/mips/tx4938/common/Makefile b/arch/mips/tx4938/common/Makefile
index 8352eca67906..56aa1ed1ee0c 100644
--- a/arch/mips/tx4938/common/Makefile
+++ b/arch/mips/tx4938/common/Makefile
@@ -1,12 +1,8 @@
1# 1#
2# Makefile for common code for Toshiba TX4927 based systems 2# Makefile for common code for Toshiba TX4927 based systems
3# 3#
4# Note! Dependencies are done automagically by 'make dep', which also
5# removes any old dependencies. DON'T put your own dependencies here
6# unless it's something special (ie not a .c file).
7#
8 4
9obj-y += prom.o setup.o irq.o 5obj-y += prom.o irq.o
10obj-$(CONFIG_KGDB) += dbgio.o 6obj-$(CONFIG_KGDB) += dbgio.o
11 7
12EXTRA_CFLAGS += -Werror 8EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/tx4938/common/setup.c b/arch/mips/tx4938/common/setup.c
deleted file mode 100644
index 3ba4101d141e..000000000000
--- a/arch/mips/tx4938/common/setup.c
+++ /dev/null
@@ -1,45 +0,0 @@
1/*
2 * linux/arch/mips/tx4938/common/setup.c
3 *
4 * common tx4938 setup routines
5 *
6 * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
7 * terms of the GNU General Public License version 2. This program is
8 * licensed "as is" without any warranty of any kind, whether express
9 * or implied.
10 *
11 * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
12 */
13
14#include <linux/errno.h>
15#include <linux/init.h>
16#include <linux/kernel_stat.h>
17#include <linux/module.h>
18#include <linux/signal.h>
19#include <linux/sched.h>
20#include <linux/types.h>
21#include <linux/interrupt.h>
22#include <linux/ioport.h>
23#include <linux/timex.h>
24#include <linux/slab.h>
25#include <linux/random.h>
26#include <linux/irq.h>
27#include <linux/bitops.h>
28#include <asm/bootinfo.h>
29#include <asm/io.h>
30#include <asm/irq.h>
31#include <asm/mipsregs.h>
32#include <asm/system.h>
33#include <asm/time.h>
34#include <asm/tx4938/rbtx4938.h>
35
36extern void toshiba_rbtx4938_setup(void);
37
38void __init tx4938_setup(void);
39void dump_cp0(char *key);
40
41void __init
42plat_mem_setup(void)
43{
44 toshiba_rbtx4938_setup();
45}
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/Makefile b/arch/mips/tx4938/toshiba_rbtx4938/Makefile
index 675bb1c3e40c..2316dd7dd1bd 100644
--- a/arch/mips/tx4938/toshiba_rbtx4938/Makefile
+++ b/arch/mips/tx4938/toshiba_rbtx4938/Makefile
@@ -1,10 +1,6 @@
1# 1#
2# Makefile for common code for Toshiba TX4927 based systems 2# Makefile for common code for Toshiba TX4927 based systems
3# 3#
4# Note! Dependencies are done automagically by 'make dep', which also
5# removes any old dependencies. DON'T put your own dependencies here
6# unless it's something special (ie not a .c file).
7#
8 4
9obj-y += prom.o setup.o irq.o spi_eeprom.o 5obj-y += prom.o setup.o irq.o spi_eeprom.o
10 6
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/prom.c b/arch/mips/tx4938/toshiba_rbtx4938/prom.c
index 69f21c1b7942..1644bffa501a 100644
--- a/arch/mips/tx4938/toshiba_rbtx4938/prom.c
+++ b/arch/mips/tx4938/toshiba_rbtx4938/prom.c
@@ -47,7 +47,6 @@ void __init prom_init(void)
47#ifndef CONFIG_TX4938_NAND_BOOT 47#ifndef CONFIG_TX4938_NAND_BOOT
48 prom_init_cmdline(); 48 prom_init_cmdline();
49#endif 49#endif
50 mips_machtype = MACH_TOSHIBA_RBTX4938;
51 50
52 msize = tx4938_get_mem_size(); 51 msize = tx4938_get_mem_size();
53 add_memory_region(0, msize << 20, BOOT_MEM_RAM); 52 add_memory_region(0, msize << 20, BOOT_MEM_RAM);
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
index 632e5d201353..61249f049cd6 100644
--- a/arch/mips/tx4938/toshiba_rbtx4938/setup.c
+++ b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
@@ -24,16 +24,12 @@
24 24
25#include <asm/wbflush.h> 25#include <asm/wbflush.h>
26#include <asm/reboot.h> 26#include <asm/reboot.h>
27#include <asm/irq.h>
28#include <asm/time.h> 27#include <asm/time.h>
29#include <asm/txx9tmr.h> 28#include <asm/txx9tmr.h>
30#include <asm/uaccess.h>
31#include <asm/io.h> 29#include <asm/io.h>
32#include <asm/bootinfo.h> 30#include <asm/bootinfo.h>
33#include <asm/tx4938/rbtx4938.h> 31#include <asm/tx4938/rbtx4938.h>
34#ifdef CONFIG_SERIAL_TXX9 32#ifdef CONFIG_SERIAL_TXX9
35#include <linux/tty.h>
36#include <linux/serial.h>
37#include <linux/serial_core.h> 33#include <linux/serial_core.h>
38#endif 34#endif
39#include <linux/spi/spi.h> 35#include <linux/spi/spi.h>
@@ -728,6 +724,8 @@ void __init tx4938_board_setup(void)
728 /* CCFG */ 724 /* CCFG */
729 /* clear WatchDogReset,BusErrorOnWrite flag (W1C) */ 725 /* clear WatchDogReset,BusErrorOnWrite flag (W1C) */
730 tx4938_ccfgptr->ccfg |= TX4938_CCFG_WDRST | TX4938_CCFG_BEOW; 726 tx4938_ccfgptr->ccfg |= TX4938_CCFG_WDRST | TX4938_CCFG_BEOW;
727 /* do reset on watchdog */
728 tx4938_ccfgptr->ccfg |= TX4938_CCFG_WR;
731 /* clear PCIC1 reset */ 729 /* clear PCIC1 reset */
732 if (tx4938_ccfgptr->clkctr & TX4938_CLKCTR_PCIC1RST) 730 if (tx4938_ccfgptr->clkctr & TX4938_CLKCTR_PCIC1RST)
733 tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIC1RST; 731 tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIC1RST;
@@ -855,7 +853,7 @@ void __init plat_time_init(void)
855 txx9_gbus_clock / 2); 853 txx9_gbus_clock / 2);
856} 854}
857 855
858void __init toshiba_rbtx4938_setup(void) 856void __init plat_mem_setup(void)
859{ 857{
860 unsigned long long pcfg; 858 unsigned long long pcfg;
861 char *argptr; 859 char *argptr;
@@ -1125,12 +1123,35 @@ static int __init rbtx4938_spi_init(void)
1125} 1123}
1126arch_initcall(rbtx4938_spi_init); 1124arch_initcall(rbtx4938_spi_init);
1127 1125
1126/* Watchdog support */
1127
1128static int __init txx9_wdt_init(unsigned long base)
1129{
1130 struct resource res = {
1131 .start = base,
1132 .end = base + 0x100 - 1,
1133 .flags = IORESOURCE_MEM,
1134 .parent = &tx4938_reg_resource,
1135 };
1136 struct platform_device *dev =
1137 platform_device_register_simple("txx9wdt", -1, &res, 1);
1138 return IS_ERR(dev) ? PTR_ERR(dev) : 0;
1139}
1140
1141static int __init rbtx4938_wdt_init(void)
1142{
1143 return txx9_wdt_init(TX4938_TMR_REG(2) & 0xfffffffffULL);
1144}
1145device_initcall(rbtx4938_wdt_init);
1146
1128/* Minimum CLK support */ 1147/* Minimum CLK support */
1129 1148
1130struct clk *clk_get(struct device *dev, const char *id) 1149struct clk *clk_get(struct device *dev, const char *id)
1131{ 1150{
1132 if (!strcmp(id, "spi-baseclk")) 1151 if (!strcmp(id, "spi-baseclk"))
1133 return (struct clk *)(txx9_gbus_clock / 2 / 4); 1152 return (struct clk *)(txx9_gbus_clock / 2 / 4);
1153 if (!strcmp(id, "imbus_clk"))
1154 return (struct clk *)(txx9_gbus_clock / 2);
1134 return ERR_PTR(-ENOENT); 1155 return ERR_PTR(-ENOENT);
1135} 1156}
1136EXPORT_SYMBOL(clk_get); 1157EXPORT_SYMBOL(clk_get);
diff --git a/arch/mips/vr41xx/common/init.c b/arch/mips/vr41xx/common/init.c
index 8d760df686c4..76d4b5ed3fc0 100644
--- a/arch/mips/vr41xx/common/init.c
+++ b/arch/mips/vr41xx/common/init.c
@@ -40,6 +40,8 @@ void __init plat_time_init(void)
40{ 40{
41 unsigned long tclock; 41 unsigned long tclock;
42 42
43 vr41xx_calculate_clock_frequency();
44
43 tclock = vr41xx_get_tclock_frequency(); 45 tclock = vr41xx_get_tclock_frequency();
44 if (current_cpu_data.processor_id == PRID_VR4131_REV2_0 || 46 if (current_cpu_data.processor_id == PRID_VR4131_REV2_0 ||
45 current_cpu_data.processor_id == PRID_VR4131_REV2_1) 47 current_cpu_data.processor_id == PRID_VR4131_REV2_1)
@@ -50,8 +52,6 @@ void __init plat_time_init(void)
50 52
51void __init plat_mem_setup(void) 53void __init plat_mem_setup(void)
52{ 54{
53 vr41xx_calculate_clock_frequency();
54
55 iomem_resource_init(); 55 iomem_resource_init();
56} 56}
57 57
diff --git a/arch/mips/vr41xx/nec-cmbvr4133/setup.c b/arch/mips/vr41xx/nec-cmbvr4133/setup.c
index 58e47686b499..7723d2011b08 100644
--- a/arch/mips/vr41xx/nec-cmbvr4133/setup.c
+++ b/arch/mips/vr41xx/nec-cmbvr4133/setup.c
@@ -50,7 +50,7 @@ static struct mtd_partition cmbvr4133_mtd_parts[] = {
50 } 50 }
51}; 51};
52 52
53#define number_partitions (sizeof(cmbvr4133_mtd_parts)/sizeof(struct mtd_partition)) 53#define number_partitions ARRAY_SIZE(cmbvr4133_mtd_parts)
54#endif 54#endif
55 55
56extern void i8259_init(void); 56extern void i8259_init(void);
@@ -64,8 +64,6 @@ static void __init nec_cmbvr4133_setup(void)
64#endif 64#endif
65 set_io_port_base(KSEG1ADDR(0x16000000)); 65 set_io_port_base(KSEG1ADDR(0x16000000));
66 66
67 mips_machtype = MACH_NEC_CMBVR4133;
68
69#ifdef CONFIG_PCI 67#ifdef CONFIG_PCI
70#ifdef CONFIG_ROCKHOPPER 68#ifdef CONFIG_ROCKHOPPER
71 ali_m5229_preinit(); 69 ali_m5229_preinit();
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index b8ef1787a191..2b649c46631c 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -19,6 +19,11 @@ config MMU
19config STACK_GROWSUP 19config STACK_GROWSUP
20 def_bool y 20 def_bool y
21 21
22config GENERIC_LOCKBREAK
23 bool
24 default y
25 depends on SMP && PREEMPT
26
22config RWSEM_GENERIC_SPINLOCK 27config RWSEM_GENERIC_SPINLOCK
23 def_bool y 28 def_bool y
24 29
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S
index 40d0ff9b81ab..50b4a3a25d0a 100644
--- a/arch/parisc/kernel/vmlinux.lds.S
+++ b/arch/parisc/kernel/vmlinux.lds.S
@@ -172,11 +172,11 @@ SECTIONS
172 __init_begin = .; 172 __init_begin = .;
173 .init.text : { 173 .init.text : {
174 _sinittext = .; 174 _sinittext = .;
175 *(.init.text) 175 INIT_TEXT
176 _einittext = .; 176 _einittext = .;
177 } 177 }
178 .init.data : { 178 .init.data : {
179 *(.init.data) 179 INIT_DATA
180 } 180 }
181 . = ALIGN(16); 181 . = ALIGN(16);
182 .init.setup : { 182 .init.setup : {
@@ -215,10 +215,10 @@ SECTIONS
215 * from .altinstructions and .eh_frame 215 * from .altinstructions and .eh_frame
216 */ 216 */
217 .exit.text : { 217 .exit.text : {
218 *(.exit.text) 218 EXIT_TEXT
219 } 219 }
220 .exit.data : { 220 .exit.data : {
221 *(.exit.data) 221 EXIT_DATA
222 } 222 }
223#ifdef CONFIG_BLK_DEV_INITRD 223#ifdef CONFIG_BLK_DEV_INITRD
224 . = ALIGN(PAGE_SIZE); 224 . = ALIGN(PAGE_SIZE);
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 5e1083829d82..2bf2f3f53029 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -42,6 +42,9 @@ config GENERIC_HARDIRQS
42 bool 42 bool
43 default y 43 default y
44 44
45config ARCH_SETS_UP_PER_CPU_AREA
46 def_bool PPC64
47
45config IRQ_PER_CPU 48config IRQ_PER_CPU
46 bool 49 bool
47 default y 50 default y
@@ -53,6 +56,11 @@ config RWSEM_XCHGADD_ALGORITHM
53 bool 56 bool
54 default y 57 default y
55 58
59config GENERIC_LOCKBREAK
60 bool
61 default y
62 depends on SMP && PREEMPT
63
56config ARCH_HAS_ILOG2_U32 64config ARCH_HAS_ILOG2_U32
57 bool 65 bool
58 default y 66 default y
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 7f6b07c30d69..122a27078998 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -72,7 +72,7 @@ obj-wlib := $(addsuffix .o, $(basename $(addprefix $(obj)/, $(src-wlib))))
72obj-plat := $(addsuffix .o, $(basename $(addprefix $(obj)/, $(src-plat)))) 72obj-plat := $(addsuffix .o, $(basename $(addprefix $(obj)/, $(src-plat))))
73 73
74quiet_cmd_copy_zlib = COPY $@ 74quiet_cmd_copy_zlib = COPY $@
75 cmd_copy_zlib = sed "s@__attribute_used__@@;s@<linux/\([^>]*\).*@\"\1\"@" $< > $@ 75 cmd_copy_zlib = sed "s@__used@@;s@<linux/\([^>]*\).*@\"\1\"@" $< > $@
76 76
77quiet_cmd_copy_zlibheader = COPY $@ 77quiet_cmd_copy_zlibheader = COPY $@
78 cmd_copy_zlibheader = sed "s@<linux/\([^>]*\).*@\"\1\"@" $< > $@ 78 cmd_copy_zlibheader = sed "s@<linux/\([^>]*\).*@\"\1\"@" $< > $@
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 3e17d154d0d4..8b056d2295cc 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -256,7 +256,7 @@ static int set_evrregs(struct task_struct *task, unsigned long *data)
256#endif /* CONFIG_SPE */ 256#endif /* CONFIG_SPE */
257 257
258 258
259static void set_single_step(struct task_struct *task) 259void user_enable_single_step(struct task_struct *task)
260{ 260{
261 struct pt_regs *regs = task->thread.regs; 261 struct pt_regs *regs = task->thread.regs;
262 262
@@ -271,7 +271,7 @@ static void set_single_step(struct task_struct *task)
271 set_tsk_thread_flag(task, TIF_SINGLESTEP); 271 set_tsk_thread_flag(task, TIF_SINGLESTEP);
272} 272}
273 273
274static void clear_single_step(struct task_struct *task) 274void user_disable_single_step(struct task_struct *task)
275{ 275{
276 struct pt_regs *regs = task->thread.regs; 276 struct pt_regs *regs = task->thread.regs;
277 277
@@ -313,7 +313,7 @@ static int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
313void ptrace_disable(struct task_struct *child) 313void ptrace_disable(struct task_struct *child)
314{ 314{
315 /* make sure the single step bit is not set. */ 315 /* make sure the single step bit is not set. */
316 clear_single_step(child); 316 user_disable_single_step(child);
317} 317}
318 318
319/* 319/*
@@ -445,52 +445,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
445 break; 445 break;
446 } 446 }
447 447
448 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
449 case PTRACE_CONT: { /* restart after signal. */
450 ret = -EIO;
451 if (!valid_signal(data))
452 break;
453 if (request == PTRACE_SYSCALL)
454 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
455 else
456 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
457 child->exit_code = data;
458 /* make sure the single step bit is not set. */
459 clear_single_step(child);
460 wake_up_process(child);
461 ret = 0;
462 break;
463 }
464
465/*
466 * make the child exit. Best I can do is send it a sigkill.
467 * perhaps it should be put in the status that it wants to
468 * exit.
469 */
470 case PTRACE_KILL: {
471 ret = 0;
472 if (child->exit_state == EXIT_ZOMBIE) /* already dead */
473 break;
474 child->exit_code = SIGKILL;
475 /* make sure the single step bit is not set. */
476 clear_single_step(child);
477 wake_up_process(child);
478 break;
479 }
480
481 case PTRACE_SINGLESTEP: { /* set the trap flag. */
482 ret = -EIO;
483 if (!valid_signal(data))
484 break;
485 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
486 set_single_step(child);
487 child->exit_code = data;
488 /* give it a chance to run. */
489 wake_up_process(child);
490 ret = 0;
491 break;
492 }
493
494 case PTRACE_GET_DEBUGREG: { 448 case PTRACE_GET_DEBUGREG: {
495 ret = -EINVAL; 449 ret = -EINVAL;
496 /* We only support one DABR and no IABRS at the moment */ 450 /* We only support one DABR and no IABRS at the moment */
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index 25d9a96484dd..c8127f832df0 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -158,7 +158,7 @@ static ssize_t show_##NAME(struct sys_device *dev, char *buf) \
158 unsigned long val = run_on_cpu(cpu->sysdev.id, read_##NAME, 0); \ 158 unsigned long val = run_on_cpu(cpu->sysdev.id, read_##NAME, 0); \
159 return sprintf(buf, "%lx\n", val); \ 159 return sprintf(buf, "%lx\n", val); \
160} \ 160} \
161static ssize_t __attribute_used__ \ 161static ssize_t __used \
162 store_##NAME(struct sys_device *dev, const char *buf, size_t count) \ 162 store_##NAME(struct sys_device *dev, const char *buf, size_t count) \
163{ \ 163{ \
164 struct cpu *cpu = container_of(dev, struct cpu, sysdev); \ 164 struct cpu *cpu = container_of(dev, struct cpu, sysdev); \
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index 19a5656001c0..f0bad7070fb5 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -37,8 +37,6 @@
37#include <asm/iseries/hv_call_xm.h> 37#include <asm/iseries/hv_call_xm.h>
38#include <asm/iseries/iommu.h> 38#include <asm/iseries/iommu.h>
39 39
40extern struct kset devices_subsys; /* needed for vio_find_name() */
41
42static struct bus_type vio_bus_type; 40static struct bus_type vio_bus_type;
43 41
44static struct vio_dev vio_bus_device = { /* fake "parent" device */ 42static struct vio_dev vio_bus_device = { /* fake "parent" device */
@@ -361,19 +359,16 @@ EXPORT_SYMBOL(vio_get_attribute);
361#ifdef CONFIG_PPC_PSERIES 359#ifdef CONFIG_PPC_PSERIES
362/* vio_find_name() - internal because only vio.c knows how we formatted the 360/* vio_find_name() - internal because only vio.c knows how we formatted the
363 * kobject name 361 * kobject name
364 * XXX once vio_bus_type.devices is actually used as a kset in
365 * drivers/base/bus.c, this function should be removed in favor of
366 * "device_find(kobj_name, &vio_bus_type)"
367 */ 362 */
368static struct vio_dev *vio_find_name(const char *kobj_name) 363static struct vio_dev *vio_find_name(const char *name)
369{ 364{
370 struct kobject *found; 365 struct device *found;
371 366
372 found = kset_find_obj(&devices_subsys, kobj_name); 367 found = bus_find_device_by_name(&vio_bus_type, NULL, name);
373 if (!found) 368 if (!found)
374 return NULL; 369 return NULL;
375 370
376 return to_vio_dev(container_of(found, struct device, kobj)); 371 return to_vio_dev(found);
377} 372}
378 373
379/** 374/**
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index f66fa5d966b0..0afb9e31d2a0 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -23,7 +23,7 @@ SECTIONS
23 /* Sections to be discarded. */ 23 /* Sections to be discarded. */
24 /DISCARD/ : { 24 /DISCARD/ : {
25 *(.exitcall.exit) 25 *(.exitcall.exit)
26 *(.exit.data) 26 EXIT_DATA
27 } 27 }
28 28
29 . = KERNELBASE; 29 . = KERNELBASE;
@@ -76,17 +76,19 @@ SECTIONS
76 76
77 .init.text : { 77 .init.text : {
78 _sinittext = .; 78 _sinittext = .;
79 *(.init.text) 79 INIT_TEXT
80 _einittext = .; 80 _einittext = .;
81 } 81 }
82 82
83 /* .exit.text is discarded at runtime, not link time, 83 /* .exit.text is discarded at runtime, not link time,
84 * to deal with references from __bug_table 84 * to deal with references from __bug_table
85 */ 85 */
86 .exit.text : { *(.exit.text) } 86 .exit.text : {
87 EXIT_TEXT
88 }
87 89
88 .init.data : { 90 .init.data : {
89 *(.init.data); 91 INIT_DATA
90 __vtop_table_begin = .; 92 __vtop_table_begin = .;
91 *(.vtop_fixup); 93 *(.vtop_fixup);
92 __vtop_table_end = .; 94 __vtop_table_end = .;
diff --git a/arch/powerpc/oprofile/op_model_power4.c b/arch/powerpc/oprofile/op_model_power4.c
index cddc250a6a5c..446a8bbb847b 100644
--- a/arch/powerpc/oprofile/op_model_power4.c
+++ b/arch/powerpc/oprofile/op_model_power4.c
@@ -172,15 +172,15 @@ static void power4_stop(void)
172} 172}
173 173
174/* Fake functions used by canonicalize_pc */ 174/* Fake functions used by canonicalize_pc */
175static void __attribute_used__ hypervisor_bucket(void) 175static void __used hypervisor_bucket(void)
176{ 176{
177} 177}
178 178
179static void __attribute_used__ rtas_bucket(void) 179static void __used rtas_bucket(void)
180{ 180{
181} 181}
182 182
183static void __attribute_used__ kernel_unknown_bucket(void) 183static void __used kernel_unknown_bucket(void)
184{ 184{
185} 185}
186 186
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index fb266ae32095..e45cfa84911f 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -511,7 +511,7 @@ static int spu_shutdown(struct sys_device *sysdev)
511} 511}
512 512
513static struct sysdev_class spu_sysdev_class = { 513static struct sysdev_class spu_sysdev_class = {
514 set_kset_name("spu"), 514 .name = "spu",
515 .shutdown = spu_shutdown, 515 .shutdown = spu_shutdown,
516}; 516};
517 517
diff --git a/arch/powerpc/platforms/pasemi/Makefile b/arch/powerpc/platforms/pasemi/Makefile
index 2cd2a4f26a48..8f52d7515793 100644
--- a/arch/powerpc/platforms/pasemi/Makefile
+++ b/arch/powerpc/platforms/pasemi/Makefile
@@ -1,3 +1,3 @@
1obj-y += setup.o pci.o time.o idle.o powersave.o iommu.o 1obj-y += setup.o pci.o time.o idle.o powersave.o iommu.o dma_lib.o
2obj-$(CONFIG_PPC_PASEMI_MDIO) += gpio_mdio.o 2obj-$(CONFIG_PPC_PASEMI_MDIO) += gpio_mdio.o
3obj-$(CONFIG_PPC_PASEMI_CPUFREQ) += cpufreq.o 3obj-$(CONFIG_PPC_PASEMI_CPUFREQ) += cpufreq.o
diff --git a/arch/powerpc/platforms/pasemi/dma_lib.c b/arch/powerpc/platforms/pasemi/dma_lib.c
new file mode 100644
index 000000000000..c529d8dff395
--- /dev/null
+++ b/arch/powerpc/platforms/pasemi/dma_lib.c
@@ -0,0 +1,488 @@
1/*
2 * Copyright (C) 2006-2007 PA Semi, Inc
3 *
4 * Common functions for DMA access on PA Semi PWRficient
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include <linux/init.h>
21#include <linux/module.h>
22#include <linux/pci.h>
23#include <linux/of.h>
24
25#include <asm/pasemi_dma.h>
26
27#define MAX_TXCH 64
28#define MAX_RXCH 64
29
30static struct pasdma_status *dma_status;
31
32static void __iomem *iob_regs;
33static void __iomem *mac_regs[6];
34static void __iomem *dma_regs;
35
36static int base_hw_irq;
37
38static int num_txch, num_rxch;
39
40static struct pci_dev *dma_pdev;
41
42/* Bitmaps to handle allocation of channels */
43
44static DECLARE_BITMAP(txch_free, MAX_TXCH);
45static DECLARE_BITMAP(rxch_free, MAX_RXCH);
46
47/* pasemi_read_iob_reg - read IOB register
48 * @reg: Register to read (offset into PCI CFG space)
49 */
50unsigned int pasemi_read_iob_reg(unsigned int reg)
51{
52 return in_le32(iob_regs+reg);
53}
54EXPORT_SYMBOL(pasemi_read_iob_reg);
55
56/* pasemi_write_iob_reg - write IOB register
57 * @reg: Register to write to (offset into PCI CFG space)
58 * @val: Value to write
59 */
60void pasemi_write_iob_reg(unsigned int reg, unsigned int val)
61{
62 out_le32(iob_regs+reg, val);
63}
64EXPORT_SYMBOL(pasemi_write_iob_reg);
65
66/* pasemi_read_mac_reg - read MAC register
67 * @intf: MAC interface
68 * @reg: Register to read (offset into PCI CFG space)
69 */
70unsigned int pasemi_read_mac_reg(int intf, unsigned int reg)
71{
72 return in_le32(mac_regs[intf]+reg);
73}
74EXPORT_SYMBOL(pasemi_read_mac_reg);
75
76/* pasemi_write_mac_reg - write MAC register
77 * @intf: MAC interface
78 * @reg: Register to write to (offset into PCI CFG space)
79 * @val: Value to write
80 */
81void pasemi_write_mac_reg(int intf, unsigned int reg, unsigned int val)
82{
83 out_le32(mac_regs[intf]+reg, val);
84}
85EXPORT_SYMBOL(pasemi_write_mac_reg);
86
87/* pasemi_read_dma_reg - read DMA register
88 * @reg: Register to read (offset into PCI CFG space)
89 */
90unsigned int pasemi_read_dma_reg(unsigned int reg)
91{
92 return in_le32(dma_regs+reg);
93}
94EXPORT_SYMBOL(pasemi_read_dma_reg);
95
96/* pasemi_write_dma_reg - write DMA register
97 * @reg: Register to write to (offset into PCI CFG space)
98 * @val: Value to write
99 */
100void pasemi_write_dma_reg(unsigned int reg, unsigned int val)
101{
102 out_le32(dma_regs+reg, val);
103}
104EXPORT_SYMBOL(pasemi_write_dma_reg);
105
106static int pasemi_alloc_tx_chan(enum pasemi_dmachan_type type)
107{
108 int bit;
109 int start, limit;
110
111 switch (type & (TXCHAN_EVT0|TXCHAN_EVT1)) {
112 case TXCHAN_EVT0:
113 start = 0;
114 limit = 10;
115 break;
116 case TXCHAN_EVT1:
117 start = 10;
118 limit = MAX_TXCH;
119 break;
120 default:
121 start = 0;
122 limit = MAX_TXCH;
123 break;
124 }
125retry:
126 bit = find_next_bit(txch_free, MAX_TXCH, start);
127 if (bit >= limit)
128 return -ENOSPC;
129 if (!test_and_clear_bit(bit, txch_free))
130 goto retry;
131
132 return bit;
133}
134
135static void pasemi_free_tx_chan(int chan)
136{
137 BUG_ON(test_bit(chan, txch_free));
138 set_bit(chan, txch_free);
139}
140
141static int pasemi_alloc_rx_chan(void)
142{
143 int bit;
144retry:
145 bit = find_first_bit(rxch_free, MAX_RXCH);
146 if (bit >= MAX_TXCH)
147 return -ENOSPC;
148 if (!test_and_clear_bit(bit, rxch_free))
149 goto retry;
150
151 return bit;
152}
153
154static void pasemi_free_rx_chan(int chan)
155{
156 BUG_ON(test_bit(chan, rxch_free));
157 set_bit(chan, rxch_free);
158}
159
160/* pasemi_dma_alloc_chan - Allocate a DMA channel
161 * @type: Type of channel to allocate
162 * @total_size: Total size of structure to allocate (to allow for more
163 * room behind the structure to be used by the client)
164 * @offset: Offset in bytes from start of the total structure to the beginning
165 * of struct pasemi_dmachan. Needed when struct pasemi_dmachan is
166 * not the first member of the client structure.
167 *
168 * pasemi_dma_alloc_chan allocates a DMA channel for use by a client. The
169 * type argument specifies whether it's a RX or TX channel, and in the case
170 * of TX channels which group it needs to belong to (if any).
171 *
172 * Returns a pointer to the total structure allocated on success, NULL
173 * on failure.
174 */
175void *pasemi_dma_alloc_chan(enum pasemi_dmachan_type type,
176 int total_size, int offset)
177{
178 void *buf;
179 struct pasemi_dmachan *chan;
180 int chno;
181
182 BUG_ON(total_size < sizeof(struct pasemi_dmachan));
183
184 buf = kzalloc(total_size, GFP_KERNEL);
185
186 if (!buf)
187 return NULL;
188 chan = buf + offset;
189
190 chan->priv = buf;
191
192 switch (type & (TXCHAN|RXCHAN)) {
193 case RXCHAN:
194 chno = pasemi_alloc_rx_chan();
195 chan->chno = chno;
196 chan->irq = irq_create_mapping(NULL,
197 base_hw_irq + num_txch + chno);
198 chan->status = &dma_status->rx_sta[chno];
199 break;
200 case TXCHAN:
201 chno = pasemi_alloc_tx_chan(type);
202 chan->chno = chno;
203 chan->irq = irq_create_mapping(NULL, base_hw_irq + chno);
204 chan->status = &dma_status->tx_sta[chno];
205 break;
206 }
207
208 chan->chan_type = type;
209
210 return chan;
211}
212EXPORT_SYMBOL(pasemi_dma_alloc_chan);
213
214/* pasemi_dma_free_chan - Free a previously allocated channel
215 * @chan: Channel to free
216 *
217 * Frees a previously allocated channel. It will also deallocate any
218 * descriptor ring associated with the channel, if allocated.
219 */
220void pasemi_dma_free_chan(struct pasemi_dmachan *chan)
221{
222 if (chan->ring_virt)
223 pasemi_dma_free_ring(chan);
224
225 switch (chan->chan_type & (RXCHAN|TXCHAN)) {
226 case RXCHAN:
227 pasemi_free_rx_chan(chan->chno);
228 break;
229 case TXCHAN:
230 pasemi_free_tx_chan(chan->chno);
231 break;
232 }
233
234 kfree(chan->priv);
235}
236EXPORT_SYMBOL(pasemi_dma_free_chan);
237
238/* pasemi_dma_alloc_ring - Allocate descriptor ring for a channel
239 * @chan: Channel for which to allocate
240 * @ring_size: Ring size in 64-bit (8-byte) words
241 *
242 * Allocate a descriptor ring for a channel. Returns 0 on success, errno
243 * on failure. The passed in struct pasemi_dmachan is updated with the
244 * virtual and DMA addresses of the ring.
245 */
246int pasemi_dma_alloc_ring(struct pasemi_dmachan *chan, int ring_size)
247{
248 BUG_ON(chan->ring_virt);
249
250 chan->ring_size = ring_size;
251
252 chan->ring_virt = dma_alloc_coherent(&dma_pdev->dev,
253 ring_size * sizeof(u64),
254 &chan->ring_dma, GFP_KERNEL);
255
256 if (!chan->ring_virt)
257 return -ENOMEM;
258
259 memset(chan->ring_virt, 0, ring_size * sizeof(u64));
260
261 return 0;
262}
263EXPORT_SYMBOL(pasemi_dma_alloc_ring);
264
265/* pasemi_dma_free_ring - Free an allocated descriptor ring for a channel
266 * @chan: Channel for which to free the descriptor ring
267 *
268 * Frees a previously allocated descriptor ring for a channel.
269 */
270void pasemi_dma_free_ring(struct pasemi_dmachan *chan)
271{
272 BUG_ON(!chan->ring_virt);
273
274 dma_free_coherent(&dma_pdev->dev, chan->ring_size * sizeof(u64),
275 chan->ring_virt, chan->ring_dma);
276 chan->ring_virt = NULL;
277 chan->ring_size = 0;
278 chan->ring_dma = 0;
279}
280EXPORT_SYMBOL(pasemi_dma_free_ring);
281
282/* pasemi_dma_start_chan - Start a DMA channel
283 * @chan: Channel to start
284 * @cmdsta: Additional CCMDSTA/TCMDSTA bits to write
285 *
286 * Enables (starts) a DMA channel with optional additional arguments.
287 */
288void pasemi_dma_start_chan(const struct pasemi_dmachan *chan, const u32 cmdsta)
289{
290 if (chan->chan_type == RXCHAN)
291 pasemi_write_dma_reg(PAS_DMA_RXCHAN_CCMDSTA(chan->chno),
292 cmdsta | PAS_DMA_RXCHAN_CCMDSTA_EN);
293 else
294 pasemi_write_dma_reg(PAS_DMA_TXCHAN_TCMDSTA(chan->chno),
295 cmdsta | PAS_DMA_TXCHAN_TCMDSTA_EN);
296}
297EXPORT_SYMBOL(pasemi_dma_start_chan);
298
299/* pasemi_dma_stop_chan - Stop a DMA channel
300 * @chan: Channel to stop
301 *
302 * Stops (disables) a DMA channel. This is done by setting the ST bit in the
303 * CMDSTA register and waiting on the ACT (active) bit to clear, then
304 * finally disabling the whole channel.
305 *
306 * This function will only try for a short while for the channel to stop, if
307 * it doesn't it will return failure.
308 *
309 * Returns 1 on success, 0 on failure.
310 */
311#define MAX_RETRIES 5000
312int pasemi_dma_stop_chan(const struct pasemi_dmachan *chan)
313{
314 int reg, retries;
315 u32 sta;
316
317 if (chan->chan_type == RXCHAN) {
318 reg = PAS_DMA_RXCHAN_CCMDSTA(chan->chno);
319 pasemi_write_dma_reg(reg, PAS_DMA_RXCHAN_CCMDSTA_ST);
320 for (retries = 0; retries < MAX_RETRIES; retries++) {
321 sta = pasemi_read_dma_reg(reg);
322 if (!(sta & PAS_DMA_RXCHAN_CCMDSTA_ACT)) {
323 pasemi_write_dma_reg(reg, 0);
324 return 1;
325 }
326 cond_resched();
327 }
328 } else {
329 reg = PAS_DMA_TXCHAN_TCMDSTA(chan->chno);
330 pasemi_write_dma_reg(reg, PAS_DMA_TXCHAN_TCMDSTA_ST);
331 for (retries = 0; retries < MAX_RETRIES; retries++) {
332 sta = pasemi_read_dma_reg(reg);
333 if (!(sta & PAS_DMA_TXCHAN_TCMDSTA_ACT)) {
334 pasemi_write_dma_reg(reg, 0);
335 return 1;
336 }
337 cond_resched();
338 }
339 }
340
341 return 0;
342}
343EXPORT_SYMBOL(pasemi_dma_stop_chan);
344
345/* pasemi_dma_alloc_buf - Allocate a buffer to use for DMA
346 * @chan: Channel to allocate for
347 * @size: Size of buffer in bytes
348 * @handle: DMA handle
349 *
350 * Allocate a buffer to be used by the DMA engine for read/write,
351 * similar to dma_alloc_coherent().
352 *
353 * Returns the virtual address of the buffer, or NULL in case of failure.
354 */
355void *pasemi_dma_alloc_buf(struct pasemi_dmachan *chan, int size,
356 dma_addr_t *handle)
357{
358 return dma_alloc_coherent(&dma_pdev->dev, size, handle, GFP_KERNEL);
359}
360EXPORT_SYMBOL(pasemi_dma_alloc_buf);
361
362/* pasemi_dma_free_buf - Free a buffer used for DMA
363 * @chan: Channel the buffer was allocated for
364 * @size: Size of buffer in bytes
365 * @handle: DMA handle
366 *
367 * Frees a previously allocated buffer.
368 */
369void pasemi_dma_free_buf(struct pasemi_dmachan *chan, int size,
370 dma_addr_t *handle)
371{
372 dma_free_coherent(&dma_pdev->dev, size, handle, GFP_KERNEL);
373}
374EXPORT_SYMBOL(pasemi_dma_free_buf);
375
376static void *map_onedev(struct pci_dev *p, int index)
377{
378 struct device_node *dn;
379 void __iomem *ret;
380
381 dn = pci_device_to_OF_node(p);
382 if (!dn)
383 goto fallback;
384
385 ret = of_iomap(dn, index);
386 if (!ret)
387 goto fallback;
388
389 return ret;
390fallback:
391 /* This is hardcoded and ugly, but we have some firmware versions
392 * that don't provide the register space in the device tree. Luckily
393 * they are at well-known locations so we can just do the math here.
394 */
395 return ioremap(0xe0000000 + (p->devfn << 12), 0x2000);
396}
397
398/* pasemi_dma_init - Initialize the PA Semi DMA library
399 *
400 * This function initializes the DMA library. It must be called before
401 * any other function in the library.
402 *
403 * Returns 0 on success, errno on failure.
404 */
405int pasemi_dma_init(void)
406{
407 static spinlock_t init_lock = SPIN_LOCK_UNLOCKED;
408 struct pci_dev *iob_pdev;
409 struct pci_dev *pdev;
410 struct resource res;
411 struct device_node *dn;
412 int i, intf, err = 0;
413 u32 tmp;
414
415 if (!machine_is(pasemi))
416 return -ENODEV;
417
418 spin_lock(&init_lock);
419
420 /* Make sure we haven't already initialized */
421 if (dma_pdev)
422 goto out;
423
424 iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL);
425 if (!iob_pdev) {
426 BUG();
427 printk(KERN_WARNING "Can't find I/O Bridge\n");
428 err = -ENODEV;
429 goto out;
430 }
431 iob_regs = map_onedev(iob_pdev, 0);
432
433 dma_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa007, NULL);
434 if (!dma_pdev) {
435 BUG();
436 printk(KERN_WARNING "Can't find DMA controller\n");
437 err = -ENODEV;
438 goto out;
439 }
440 dma_regs = map_onedev(dma_pdev, 0);
441 base_hw_irq = virq_to_hw(dma_pdev->irq);
442
443 pci_read_config_dword(dma_pdev, PAS_DMA_CAP_TXCH, &tmp);
444 num_txch = (tmp & PAS_DMA_CAP_TXCH_TCHN_M) >> PAS_DMA_CAP_TXCH_TCHN_S;
445
446 pci_read_config_dword(dma_pdev, PAS_DMA_CAP_RXCH, &tmp);
447 num_rxch = (tmp & PAS_DMA_CAP_RXCH_RCHN_M) >> PAS_DMA_CAP_RXCH_RCHN_S;
448
449 intf = 0;
450 for (pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa006, NULL);
451 pdev;
452 pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa006, pdev))
453 mac_regs[intf++] = map_onedev(pdev, 0);
454
455 pci_dev_put(pdev);
456
457 for (pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa005, NULL);
458 pdev;
459 pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa005, pdev))
460 mac_regs[intf++] = map_onedev(pdev, 0);
461
462 pci_dev_put(pdev);
463
464 dn = pci_device_to_OF_node(iob_pdev);
465 if (dn)
466 err = of_address_to_resource(dn, 1, &res);
467 if (!dn || err) {
468 /* Fallback for old firmware */
469 res.start = 0xfd800000;
470 res.end = res.start + 0x1000;
471 }
472 dma_status = __ioremap(res.start, res.end-res.start, 0);
473 pci_dev_put(iob_pdev);
474
475 for (i = 0; i < MAX_TXCH; i++)
476 __set_bit(i, txch_free);
477
478 for (i = 0; i < MAX_RXCH; i++)
479 __set_bit(i, rxch_free);
480
481 printk(KERN_INFO "PA Semi PWRficient DMA library initialized "
482 "(%d tx, %d rx channels)\n", num_txch, num_rxch);
483
484out:
485 spin_unlock(&init_lock);
486 return err;
487}
488EXPORT_SYMBOL(pasemi_dma_init);
diff --git a/arch/powerpc/platforms/pasemi/pasemi.h b/arch/powerpc/platforms/pasemi/pasemi.h
index c96127b029b6..b1e524f7489d 100644
--- a/arch/powerpc/platforms/pasemi/pasemi.h
+++ b/arch/powerpc/platforms/pasemi/pasemi.h
@@ -9,6 +9,7 @@ extern void __devinit pas_pci_dma_dev_setup(struct pci_dev *dev);
9extern void __iomem *pasemi_pci_getcfgaddr(struct pci_dev *dev, int offset); 9extern void __iomem *pasemi_pci_getcfgaddr(struct pci_dev *dev, int offset);
10 10
11extern void __init alloc_iobmap_l2(void); 11extern void __init alloc_iobmap_l2(void);
12extern void __init pasemi_map_registers(void);
12 13
13/* Power savings modes, implemented in asm */ 14/* Power savings modes, implemented in asm */
14extern void idle_spin(void); 15extern void idle_spin(void);
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index cd7216437416..40736400ef80 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -663,7 +663,7 @@ static int pmacpic_resume(struct sys_device *sysdev)
663#endif /* CONFIG_PM && CONFIG_PPC32 */ 663#endif /* CONFIG_PM && CONFIG_PPC32 */
664 664
665static struct sysdev_class pmacpic_sysclass = { 665static struct sysdev_class pmacpic_sysclass = {
666 set_kset_name("pmac_pic"), 666 .name = "pmac_pic",
667}; 667};
668 668
669static struct sys_device device_pmacpic = { 669static struct sys_device device_pmacpic = {
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index 412e6b42986f..c4ad54e0f288 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -153,7 +153,7 @@ static int pseries_add_processor(struct device_node *np)
153 for (i = 0; i < nthreads; i++) 153 for (i = 0; i < nthreads; i++)
154 cpu_set(i, tmp); 154 cpu_set(i, tmp);
155 155
156 lock_cpu_hotplug(); 156 cpu_maps_update_begin();
157 157
158 BUG_ON(!cpus_subset(cpu_present_map, cpu_possible_map)); 158 BUG_ON(!cpus_subset(cpu_present_map, cpu_possible_map));
159 159
@@ -190,7 +190,7 @@ static int pseries_add_processor(struct device_node *np)
190 } 190 }
191 err = 0; 191 err = 0;
192out_unlock: 192out_unlock:
193 unlock_cpu_hotplug(); 193 cpu_maps_update_done();
194 return err; 194 return err;
195} 195}
196 196
@@ -211,7 +211,7 @@ static void pseries_remove_processor(struct device_node *np)
211 211
212 nthreads = len / sizeof(u32); 212 nthreads = len / sizeof(u32);
213 213
214 lock_cpu_hotplug(); 214 cpu_maps_update_begin();
215 for (i = 0; i < nthreads; i++) { 215 for (i = 0; i < nthreads; i++) {
216 for_each_present_cpu(cpu) { 216 for_each_present_cpu(cpu) {
217 if (get_hard_smp_processor_id(cpu) != intserv[i]) 217 if (get_hard_smp_processor_id(cpu) != intserv[i])
@@ -225,7 +225,7 @@ static void pseries_remove_processor(struct device_node *np)
225 printk(KERN_WARNING "Could not find cpu to remove " 225 printk(KERN_WARNING "Could not find cpu to remove "
226 "with physical id 0x%x\n", intserv[i]); 226 "with physical id 0x%x\n", intserv[i]);
227 } 227 }
228 unlock_cpu_hotplug(); 228 cpu_maps_update_done();
229} 229}
230 230
231static int pseries_smp_notifier(struct notifier_block *nb, 231static int pseries_smp_notifier(struct notifier_block *nb,
diff --git a/arch/powerpc/platforms/pseries/power.c b/arch/powerpc/platforms/pseries/power.c
index 73e69023d90a..e95fc1594c84 100644
--- a/arch/powerpc/platforms/pseries/power.c
+++ b/arch/powerpc/platforms/pseries/power.c
@@ -28,13 +28,15 @@
28 28
29unsigned long rtas_poweron_auto; /* default and normal state is 0 */ 29unsigned long rtas_poweron_auto; /* default and normal state is 0 */
30 30
31static ssize_t auto_poweron_show(struct kset *kset, char *buf) 31static ssize_t auto_poweron_show(struct kobject *kobj,
32 struct kobj_attribute *attr, char *buf)
32{ 33{
33 return sprintf(buf, "%lu\n", rtas_poweron_auto); 34 return sprintf(buf, "%lu\n", rtas_poweron_auto);
34} 35}
35 36
36static ssize_t 37static ssize_t auto_poweron_store(struct kobject *kobj,
37auto_poweron_store(struct kset *kset, const char *buf, size_t n) 38 struct kobj_attribute *attr,
39 const char *buf, size_t n)
38{ 40{
39 int ret; 41 int ret;
40 unsigned long ups_restart; 42 unsigned long ups_restart;
@@ -47,17 +49,11 @@ auto_poweron_store(struct kset *kset, const char *buf, size_t n)
47 return -EINVAL; 49 return -EINVAL;
48} 50}
49 51
50static struct subsys_attribute auto_poweron_attr = { 52static struct kobj_attribute auto_poweron_attr =
51 .attr = { 53 __ATTR(auto_poweron, 0644, auto_poweron_show, auto_poweron_store);
52 .name = __stringify(auto_poweron),
53 .mode = 0644,
54 },
55 .show = auto_poweron_show,
56 .store = auto_poweron_store,
57};
58 54
59#ifndef CONFIG_PM 55#ifndef CONFIG_PM
60decl_subsys(power,NULL,NULL); 56struct kobject *power_kobj;
61 57
62static struct attribute *g[] = { 58static struct attribute *g[] = {
63 &auto_poweron_attr.attr, 59 &auto_poweron_attr.attr,
@@ -70,18 +66,16 @@ static struct attribute_group attr_group = {
70 66
71static int __init pm_init(void) 67static int __init pm_init(void)
72{ 68{
73 int error = subsystem_register(&power_subsys); 69 power_kobj = kobject_create_and_add("power", NULL);
74 if (!error) 70 if (!power_kobj)
75 error = sysfs_create_group(&power_subsys.kobj, &attr_group); 71 return -ENOMEM;
76 return error; 72 return sysfs_create_group(power_kobj, &attr_group);
77} 73}
78core_initcall(pm_init); 74core_initcall(pm_init);
79#else 75#else
80extern struct kset power_subsys;
81
82static int __init apo_pm_init(void) 76static int __init apo_pm_init(void)
83{ 77{
84 return (subsys_create_file(&power_subsys, &auto_poweron_attr)); 78 return (sysfs_create_file(power_kobj, &auto_poweron_attr));
85} 79}
86__initcall(apo_pm_init); 80__initcall(apo_pm_init);
87#endif 81#endif
diff --git a/arch/powerpc/platforms/pseries/rtasd.c b/arch/powerpc/platforms/pseries/rtasd.c
index 73401c820110..e3078ce41518 100644
--- a/arch/powerpc/platforms/pseries/rtasd.c
+++ b/arch/powerpc/platforms/pseries/rtasd.c
@@ -382,7 +382,7 @@ static void do_event_scan_all_cpus(long delay)
382{ 382{
383 int cpu; 383 int cpu;
384 384
385 lock_cpu_hotplug(); 385 get_online_cpus();
386 cpu = first_cpu(cpu_online_map); 386 cpu = first_cpu(cpu_online_map);
387 for (;;) { 387 for (;;) {
388 set_cpus_allowed(current, cpumask_of_cpu(cpu)); 388 set_cpus_allowed(current, cpumask_of_cpu(cpu));
@@ -390,15 +390,15 @@ static void do_event_scan_all_cpus(long delay)
390 set_cpus_allowed(current, CPU_MASK_ALL); 390 set_cpus_allowed(current, CPU_MASK_ALL);
391 391
392 /* Drop hotplug lock, and sleep for the specified delay */ 392 /* Drop hotplug lock, and sleep for the specified delay */
393 unlock_cpu_hotplug(); 393 put_online_cpus();
394 msleep_interruptible(delay); 394 msleep_interruptible(delay);
395 lock_cpu_hotplug(); 395 get_online_cpus();
396 396
397 cpu = next_cpu(cpu, cpu_online_map); 397 cpu = next_cpu(cpu, cpu_online_map);
398 if (cpu == NR_CPUS) 398 if (cpu == NR_CPUS)
399 break; 399 break;
400 } 400 }
401 unlock_cpu_hotplug(); 401 put_online_cpus();
402} 402}
403 403
404static int rtasd(void *unused) 404static int rtasd(void *unused)
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index d7f6a70e78df..ae0dbf4c1d66 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -894,7 +894,7 @@ unsigned int ipic_get_irq(void)
894} 894}
895 895
896static struct sysdev_class ipic_sysclass = { 896static struct sysdev_class ipic_sysclass = {
897 set_kset_name("ipic"), 897 .name = "ipic",
898}; 898};
899 899
900static struct sys_device device_ipic = { 900static struct sys_device device_ipic = {
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 0da7069c7c62..6ffdda244bb1 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -1628,7 +1628,7 @@ static struct sysdev_class mpic_sysclass = {
1628 .resume = mpic_resume, 1628 .resume = mpic_resume,
1629 .suspend = mpic_suspend, 1629 .suspend = mpic_suspend,
1630#endif 1630#endif
1631 set_kset_name("mpic"), 1631 .name = "mpic",
1632}; 1632};
1633 1633
1634static int mpic_init_sys(void) 1634static int mpic_init_sys(void)
diff --git a/arch/powerpc/sysdev/mv64x60_dev.c b/arch/powerpc/sysdev/mv64x60_dev.c
index 304056cafb1e..efda0028909d 100644
--- a/arch/powerpc/sysdev/mv64x60_dev.c
+++ b/arch/powerpc/sysdev/mv64x60_dev.c
@@ -361,12 +361,6 @@ static int __init mv64x60_i2c_device_setup(struct device_node *np, int id)
361 else 361 else
362 pdata.timeout = 1000; /* 1 second */ 362 pdata.timeout = 1000; /* 1 second */
363 363
364 prop = of_get_property(np, "retries", NULL);
365 if (prop)
366 pdata.retries = *prop;
367 else
368 pdata.retries = 1;
369
370 pdev = platform_device_alloc(MV64XXX_I2C_CTLR_NAME, id); 364 pdev = platform_device_alloc(MV64XXX_I2C_CTLR_NAME, id);
371 if (!pdev) 365 if (!pdev)
372 return -ENOMEM; 366 return -ENOMEM;
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c
index e1c0fd6dbc1a..f59444d3be75 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_ic.c
+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c
@@ -483,7 +483,7 @@ int qe_ic_set_high_priority(unsigned int virq, unsigned int priority, int high)
483} 483}
484 484
485static struct sysdev_class qe_ic_sysclass = { 485static struct sysdev_class qe_ic_sysclass = {
486 set_kset_name("qe_ic"), 486 .name = "qe_ic",
487}; 487};
488 488
489static struct sys_device device_qe_ic = { 489static struct sys_device device_qe_ic = {
diff --git a/arch/ppc/8260_io/enet.c b/arch/ppc/8260_io/enet.c
index 3ea4db2cc9e9..25ef55bacd99 100644
--- a/arch/ppc/8260_io/enet.c
+++ b/arch/ppc/8260_io/enet.c
@@ -272,7 +272,7 @@ scc_enet_timeout(struct net_device *dev)
272 * This is called from the CPM handler, not the MPC core interrupt. 272 * This is called from the CPM handler, not the MPC core interrupt.
273 */ 273 */
274static irqreturn_t 274static irqreturn_t
275scc_enet_interrupt(int irq, void * dev_id) 275scc_enet_interrupt(int irq, void *dev_id)
276{ 276{
277 struct net_device *dev = dev_id; 277 struct net_device *dev = dev_id;
278 volatile struct scc_enet_private *cep; 278 volatile struct scc_enet_private *cep;
@@ -280,7 +280,7 @@ scc_enet_interrupt(int irq, void * dev_id)
280 ushort int_events; 280 ushort int_events;
281 int must_restart; 281 int must_restart;
282 282
283 cep = (struct scc_enet_private *)dev->priv; 283 cep = dev->priv;
284 284
285 /* Get the interrupt events that caused us to be here. 285 /* Get the interrupt events that caused us to be here.
286 */ 286 */
diff --git a/arch/ppc/8260_io/fcc_enet.c b/arch/ppc/8260_io/fcc_enet.c
index 6f3ed6a72e0b..a3a27dafff1f 100644
--- a/arch/ppc/8260_io/fcc_enet.c
+++ b/arch/ppc/8260_io/fcc_enet.c
@@ -524,7 +524,7 @@ fcc_enet_timeout(struct net_device *dev)
524 524
525/* The interrupt handler. */ 525/* The interrupt handler. */
526static irqreturn_t 526static irqreturn_t
527fcc_enet_interrupt(int irq, void * dev_id) 527fcc_enet_interrupt(int irq, void *dev_id)
528{ 528{
529 struct net_device *dev = dev_id; 529 struct net_device *dev = dev_id;
530 volatile struct fcc_enet_private *cep; 530 volatile struct fcc_enet_private *cep;
@@ -532,7 +532,7 @@ fcc_enet_interrupt(int irq, void * dev_id)
532 ushort int_events; 532 ushort int_events;
533 int must_restart; 533 int must_restart;
534 534
535 cep = (struct fcc_enet_private *)dev->priv; 535 cep = dev->priv;
536 536
537 /* Get the interrupt events that caused us to be here. 537 /* Get the interrupt events that caused us to be here.
538 */ 538 */
diff --git a/arch/ppc/kernel/ppc_htab.c b/arch/ppc/kernel/ppc_htab.c
index aa07b63c0a6c..9ed36dd9cbff 100644
--- a/arch/ppc/kernel/ppc_htab.c
+++ b/arch/ppc/kernel/ppc_htab.c
@@ -436,7 +436,6 @@ int proc_dol2crvec(ctl_table *table, int write, struct file *filp,
436 */ 436 */
437static ctl_table htab_ctl_table[]={ 437static ctl_table htab_ctl_table[]={
438 { 438 {
439 .ctl_name = KERN_PPC_L2CR,
440 .procname = "l2cr", 439 .procname = "l2cr",
441 .mode = 0644, 440 .mode = 0644,
442 .proc_handler = &proc_dol2crvec, 441 .proc_handler = &proc_dol2crvec,
diff --git a/arch/ppc/kernel/vmlinux.lds.S b/arch/ppc/kernel/vmlinux.lds.S
index 98c1212674f6..52b64fcbdfc5 100644
--- a/arch/ppc/kernel/vmlinux.lds.S
+++ b/arch/ppc/kernel/vmlinux.lds.S
@@ -97,14 +97,14 @@ SECTIONS
97 __init_begin = .; 97 __init_begin = .;
98 .init.text : { 98 .init.text : {
99 _sinittext = .; 99 _sinittext = .;
100 *(.init.text) 100 INIT_TEXT
101 _einittext = .; 101 _einittext = .;
102 } 102 }
103 /* .exit.text is discarded at runtime, not link time, 103 /* .exit.text is discarded at runtime, not link time,
104 to deal with references from __bug_table */ 104 to deal with references from __bug_table */
105 .exit.text : { *(.exit.text) } 105 .exit.text : { EXIT_TEXT }
106 .init.data : { 106 .init.data : {
107 *(.init.data); 107 INIT_DATA
108 __vtop_table_begin = .; 108 __vtop_table_begin = .;
109 *(.vtop_fixup); 109 *(.vtop_fixup);
110 __vtop_table_end = .; 110 __vtop_table_end = .;
@@ -164,6 +164,6 @@ SECTIONS
164 /* Sections to be discarded. */ 164 /* Sections to be discarded. */
165 /DISCARD/ : { 165 /DISCARD/ : {
166 *(.exitcall.exit) 166 *(.exitcall.exit)
167 *(.exit.data) 167 EXIT_DATA
168 } 168 }
169} 169}
diff --git a/arch/ppc/platforms/katana.c b/arch/ppc/platforms/katana.c
index 52f63e6f0856..fe6e88cdb1cd 100644
--- a/arch/ppc/platforms/katana.c
+++ b/arch/ppc/platforms/katana.c
@@ -838,27 +838,6 @@ katana_find_end_of_memory(void)
838 return bdp->bi_memsize; 838 return bdp->bi_memsize;
839} 839}
840 840
841#if defined(CONFIG_I2C_MV64XXX) && defined(CONFIG_SENSORS_M41T00)
842extern ulong m41t00_get_rtc_time(void);
843extern int m41t00_set_rtc_time(ulong);
844
845static int __init
846katana_rtc_hookup(void)
847{
848 struct timespec tv;
849
850 ppc_md.get_rtc_time = m41t00_get_rtc_time;
851 ppc_md.set_rtc_time = m41t00_set_rtc_time;
852
853 tv.tv_nsec = 0;
854 tv.tv_sec = (ppc_md.get_rtc_time)();
855 do_settimeofday(&tv);
856
857 return 0;
858}
859late_initcall(katana_rtc_hookup);
860#endif
861
862#if defined(CONFIG_SERIAL_TEXT_DEBUG) && defined(CONFIG_SERIAL_MPSC_CONSOLE) 841#if defined(CONFIG_SERIAL_TEXT_DEBUG) && defined(CONFIG_SERIAL_MPSC_CONSOLE)
863static void __init 842static void __init
864katana_map_io(void) 843katana_map_io(void)
diff --git a/arch/ppc/syslib/mv64x60.c b/arch/ppc/syslib/mv64x60.c
index 2744b8a6f66a..90fe904d3614 100644
--- a/arch/ppc/syslib/mv64x60.c
+++ b/arch/ppc/syslib/mv64x60.c
@@ -411,7 +411,6 @@ static struct mv64xxx_i2c_pdata mv64xxx_i2c_pdata = {
411 .freq_m = 8, 411 .freq_m = 8,
412 .freq_n = 3, 412 .freq_n = 3,
413 .timeout = 1000, /* Default timeout of 1 second */ 413 .timeout = 1000, /* Default timeout of 1 second */
414 .retries = 1,
415}; 414};
416 415
417static struct resource mv64xxx_i2c_resources[] = { 416static struct resource mv64xxx_i2c_resources[] = {
diff --git a/arch/ppc/syslib/open_pic.c b/arch/ppc/syslib/open_pic.c
index 780a3b9b4fe9..67dffe27b5c3 100644
--- a/arch/ppc/syslib/open_pic.c
+++ b/arch/ppc/syslib/open_pic.c
@@ -1043,7 +1043,7 @@ int openpic_resume(struct sys_device *sysdev)
1043#endif /* CONFIG_PM */ 1043#endif /* CONFIG_PM */
1044 1044
1045static struct sysdev_class openpic_sysclass = { 1045static struct sysdev_class openpic_sysclass = {
1046 set_kset_name("openpic"), 1046 .name = "openpic",
1047}; 1047};
1048 1048
1049static struct sys_device device_openpic = { 1049static struct sys_device device_openpic = {
diff --git a/arch/ppc/syslib/open_pic2.c b/arch/ppc/syslib/open_pic2.c
index d585207f9f77..449075a04798 100644
--- a/arch/ppc/syslib/open_pic2.c
+++ b/arch/ppc/syslib/open_pic2.c
@@ -666,7 +666,7 @@ int openpic2_resume(struct sys_device *sysdev)
666 666
667/* HACK ALERT */ 667/* HACK ALERT */
668static struct sysdev_class openpic2_sysclass = { 668static struct sysdev_class openpic2_sysclass = {
669 set_kset_name("openpic2"), 669 .name = "openpic2",
670}; 670};
671 671
672static struct sys_device device_openpic2 = { 672static struct sys_device device_openpic2 = {
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 1330061020ab..6ef54d27fc00 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -276,9 +276,6 @@ source "kernel/Kconfig.preempt"
276 276
277source "mm/Kconfig" 277source "mm/Kconfig"
278 278
279config HOLES_IN_ZONE
280 def_bool y
281
282comment "I/O subsystem configuration" 279comment "I/O subsystem configuration"
283 280
284config MACHCHK_WARNING 281config MACHCHK_WARNING
diff --git a/arch/s390/crypto/Kconfig b/arch/s390/crypto/Kconfig
deleted file mode 100644
index d1defbbfcd81..000000000000
--- a/arch/s390/crypto/Kconfig
+++ /dev/null
@@ -1,60 +0,0 @@
1config CRYPTO_SHA1_S390
2 tristate "SHA1 digest algorithm"
3 depends on S390
4 select CRYPTO_ALGAPI
5 help
6 This is the s390 hardware accelerated implementation of the
7 SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
8
9config CRYPTO_SHA256_S390
10 tristate "SHA256 digest algorithm"
11 depends on S390
12 select CRYPTO_ALGAPI
13 help
14 This is the s390 hardware accelerated implementation of the
15 SHA256 secure hash standard (DFIPS 180-2).
16
17 This version of SHA implements a 256 bit hash with 128 bits of
18 security against collision attacks.
19
20config CRYPTO_DES_S390
21 tristate "DES and Triple DES cipher algorithms"
22 depends on S390
23 select CRYPTO_ALGAPI
24 select CRYPTO_BLKCIPHER
25 help
26 This us the s390 hardware accelerated implementation of the
27 DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3).
28
29config CRYPTO_AES_S390
30 tristate "AES cipher algorithms"
31 depends on S390
32 select CRYPTO_ALGAPI
33 select CRYPTO_BLKCIPHER
34 help
35 This is the s390 hardware accelerated implementation of the
36 AES cipher algorithms (FIPS-197). AES uses the Rijndael
37 algorithm.
38
39 Rijndael appears to be consistently a very good performer in
40 both hardware and software across a wide range of computing
41 environments regardless of its use in feedback or non-feedback
42 modes. Its key setup time is excellent, and its key agility is
43 good. Rijndael's very low memory requirements make it very well
44 suited for restricted-space environments, in which it also
45 demonstrates excellent performance. Rijndael's operations are
46 among the easiest to defend against power and timing attacks.
47
48 On s390 the System z9-109 currently only supports the key size
49 of 128 bit.
50
51config S390_PRNG
52 tristate "Pseudo random number generator device driver"
53 depends on S390
54 default "m"
55 help
56 Select this option if you want to use the s390 pseudo random number
57 generator. The PRNG is part of the cryptographic processor functions
58 and uses triple-DES to generate secure random numbers like the
59 ANSI X9.17 standard. The PRNG is usable via the char device
60 /dev/prandom.
diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c
index 512669691ad0..a3f67f8b5427 100644
--- a/arch/s390/crypto/aes_s390.c
+++ b/arch/s390/crypto/aes_s390.c
@@ -6,6 +6,7 @@
6 * s390 Version: 6 * s390 Version:
7 * Copyright IBM Corp. 2005,2007 7 * Copyright IBM Corp. 2005,2007
8 * Author(s): Jan Glauber (jang@de.ibm.com) 8 * Author(s): Jan Glauber (jang@de.ibm.com)
9 * Sebastian Siewior (sebastian@breakpoint.cc> SW-Fallback
9 * 10 *
10 * Derived from "crypto/aes_generic.c" 11 * Derived from "crypto/aes_generic.c"
11 * 12 *
@@ -16,17 +17,13 @@
16 * 17 *
17 */ 18 */
18 19
20#include <crypto/aes.h>
19#include <crypto/algapi.h> 21#include <crypto/algapi.h>
22#include <linux/err.h>
20#include <linux/module.h> 23#include <linux/module.h>
21#include <linux/init.h> 24#include <linux/init.h>
22#include "crypt_s390.h" 25#include "crypt_s390.h"
23 26
24#define AES_MIN_KEY_SIZE 16
25#define AES_MAX_KEY_SIZE 32
26
27/* data block size for all key lengths */
28#define AES_BLOCK_SIZE 16
29
30#define AES_KEYLEN_128 1 27#define AES_KEYLEN_128 1
31#define AES_KEYLEN_192 2 28#define AES_KEYLEN_192 2
32#define AES_KEYLEN_256 4 29#define AES_KEYLEN_256 4
@@ -39,45 +36,89 @@ struct s390_aes_ctx {
39 long enc; 36 long enc;
40 long dec; 37 long dec;
41 int key_len; 38 int key_len;
39 union {
40 struct crypto_blkcipher *blk;
41 struct crypto_cipher *cip;
42 } fallback;
42}; 43};
43 44
44static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, 45/*
45 unsigned int key_len) 46 * Check if the key_len is supported by the HW.
47 * Returns 0 if it is, a positive number if it is not and software fallback is
48 * required or a negative number in case the key size is not valid
49 */
50static int need_fallback(unsigned int key_len)
46{ 51{
47 struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
48 u32 *flags = &tfm->crt_flags;
49
50 switch (key_len) { 52 switch (key_len) {
51 case 16: 53 case 16:
52 if (!(keylen_flag & AES_KEYLEN_128)) 54 if (!(keylen_flag & AES_KEYLEN_128))
53 goto fail; 55 return 1;
54 break; 56 break;
55 case 24: 57 case 24:
56 if (!(keylen_flag & AES_KEYLEN_192)) 58 if (!(keylen_flag & AES_KEYLEN_192))
57 goto fail; 59 return 1;
58
59 break; 60 break;
60 case 32: 61 case 32:
61 if (!(keylen_flag & AES_KEYLEN_256)) 62 if (!(keylen_flag & AES_KEYLEN_256))
62 goto fail; 63 return 1;
63 break; 64 break;
64 default: 65 default:
65 goto fail; 66 return -1;
66 break; 67 break;
67 } 68 }
69 return 0;
70}
71
72static int setkey_fallback_cip(struct crypto_tfm *tfm, const u8 *in_key,
73 unsigned int key_len)
74{
75 struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
76 int ret;
77
78 sctx->fallback.blk->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK;
79 sctx->fallback.blk->base.crt_flags |= (tfm->crt_flags &
80 CRYPTO_TFM_REQ_MASK);
81
82 ret = crypto_cipher_setkey(sctx->fallback.cip, in_key, key_len);
83 if (ret) {
84 tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK;
85 tfm->crt_flags |= (sctx->fallback.blk->base.crt_flags &
86 CRYPTO_TFM_RES_MASK);
87 }
88 return ret;
89}
90
91static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
92 unsigned int key_len)
93{
94 struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
95 u32 *flags = &tfm->crt_flags;
96 int ret;
97
98 ret = need_fallback(key_len);
99 if (ret < 0) {
100 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
101 return -EINVAL;
102 }
68 103
69 sctx->key_len = key_len; 104 sctx->key_len = key_len;
70 memcpy(sctx->key, in_key, key_len); 105 if (!ret) {
71 return 0; 106 memcpy(sctx->key, in_key, key_len);
72fail: 107 return 0;
73 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; 108 }
74 return -EINVAL; 109
110 return setkey_fallback_cip(tfm, in_key, key_len);
75} 111}
76 112
77static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) 113static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
78{ 114{
79 const struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm); 115 const struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
80 116
117 if (unlikely(need_fallback(sctx->key_len))) {
118 crypto_cipher_encrypt_one(sctx->fallback.cip, out, in);
119 return;
120 }
121
81 switch (sctx->key_len) { 122 switch (sctx->key_len) {
82 case 16: 123 case 16:
83 crypt_s390_km(KM_AES_128_ENCRYPT, &sctx->key, out, in, 124 crypt_s390_km(KM_AES_128_ENCRYPT, &sctx->key, out, in,
@@ -98,6 +139,11 @@ static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
98{ 139{
99 const struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm); 140 const struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
100 141
142 if (unlikely(need_fallback(sctx->key_len))) {
143 crypto_cipher_decrypt_one(sctx->fallback.cip, out, in);
144 return;
145 }
146
101 switch (sctx->key_len) { 147 switch (sctx->key_len) {
102 case 16: 148 case 16:
103 crypt_s390_km(KM_AES_128_DECRYPT, &sctx->key, out, in, 149 crypt_s390_km(KM_AES_128_DECRYPT, &sctx->key, out, in,
@@ -114,6 +160,29 @@ static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
114 } 160 }
115} 161}
116 162
163static int fallback_init_cip(struct crypto_tfm *tfm)
164{
165 const char *name = tfm->__crt_alg->cra_name;
166 struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
167
168 sctx->fallback.cip = crypto_alloc_cipher(name, 0,
169 CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK);
170
171 if (IS_ERR(sctx->fallback.cip)) {
172 printk(KERN_ERR "Error allocating fallback algo %s\n", name);
173 return PTR_ERR(sctx->fallback.blk);
174 }
175
176 return 0;
177}
178
179static void fallback_exit_cip(struct crypto_tfm *tfm)
180{
181 struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
182
183 crypto_free_cipher(sctx->fallback.cip);
184 sctx->fallback.cip = NULL;
185}
117 186
118static struct crypto_alg aes_alg = { 187static struct crypto_alg aes_alg = {
119 .cra_name = "aes", 188 .cra_name = "aes",
@@ -125,6 +194,8 @@ static struct crypto_alg aes_alg = {
125 .cra_ctxsize = sizeof(struct s390_aes_ctx), 194 .cra_ctxsize = sizeof(struct s390_aes_ctx),
126 .cra_module = THIS_MODULE, 195 .cra_module = THIS_MODULE,
127 .cra_list = LIST_HEAD_INIT(aes_alg.cra_list), 196 .cra_list = LIST_HEAD_INIT(aes_alg.cra_list),
197 .cra_init = fallback_init_cip,
198 .cra_exit = fallback_exit_cip,
128 .cra_u = { 199 .cra_u = {
129 .cipher = { 200 .cipher = {
130 .cia_min_keysize = AES_MIN_KEY_SIZE, 201 .cia_min_keysize = AES_MIN_KEY_SIZE,
@@ -136,10 +207,70 @@ static struct crypto_alg aes_alg = {
136 } 207 }
137}; 208};
138 209
210static int setkey_fallback_blk(struct crypto_tfm *tfm, const u8 *key,
211 unsigned int len)
212{
213 struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
214 unsigned int ret;
215
216 sctx->fallback.blk->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK;
217 sctx->fallback.blk->base.crt_flags |= (tfm->crt_flags &
218 CRYPTO_TFM_REQ_MASK);
219
220 ret = crypto_blkcipher_setkey(sctx->fallback.blk, key, len);
221 if (ret) {
222 tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK;
223 tfm->crt_flags |= (sctx->fallback.blk->base.crt_flags &
224 CRYPTO_TFM_RES_MASK);
225 }
226 return ret;
227}
228
229static int fallback_blk_dec(struct blkcipher_desc *desc,
230 struct scatterlist *dst, struct scatterlist *src,
231 unsigned int nbytes)
232{
233 unsigned int ret;
234 struct crypto_blkcipher *tfm;
235 struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
236
237 tfm = desc->tfm;
238 desc->tfm = sctx->fallback.blk;
239
240 ret = crypto_blkcipher_decrypt_iv(desc, dst, src, nbytes);
241
242 desc->tfm = tfm;
243 return ret;
244}
245
246static int fallback_blk_enc(struct blkcipher_desc *desc,
247 struct scatterlist *dst, struct scatterlist *src,
248 unsigned int nbytes)
249{
250 unsigned int ret;
251 struct crypto_blkcipher *tfm;
252 struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
253
254 tfm = desc->tfm;
255 desc->tfm = sctx->fallback.blk;
256
257 ret = crypto_blkcipher_encrypt_iv(desc, dst, src, nbytes);
258
259 desc->tfm = tfm;
260 return ret;
261}
262
139static int ecb_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, 263static int ecb_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
140 unsigned int key_len) 264 unsigned int key_len)
141{ 265{
142 struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm); 266 struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
267 int ret;
268
269 ret = need_fallback(key_len);
270 if (ret > 0) {
271 sctx->key_len = key_len;
272 return setkey_fallback_blk(tfm, in_key, key_len);
273 }
143 274
144 switch (key_len) { 275 switch (key_len) {
145 case 16: 276 case 16:
@@ -188,6 +319,9 @@ static int ecb_aes_encrypt(struct blkcipher_desc *desc,
188 struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm); 319 struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
189 struct blkcipher_walk walk; 320 struct blkcipher_walk walk;
190 321
322 if (unlikely(need_fallback(sctx->key_len)))
323 return fallback_blk_enc(desc, dst, src, nbytes);
324
191 blkcipher_walk_init(&walk, dst, src, nbytes); 325 blkcipher_walk_init(&walk, dst, src, nbytes);
192 return ecb_aes_crypt(desc, sctx->enc, sctx->key, &walk); 326 return ecb_aes_crypt(desc, sctx->enc, sctx->key, &walk);
193} 327}
@@ -199,10 +333,37 @@ static int ecb_aes_decrypt(struct blkcipher_desc *desc,
199 struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm); 333 struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
200 struct blkcipher_walk walk; 334 struct blkcipher_walk walk;
201 335
336 if (unlikely(need_fallback(sctx->key_len)))
337 return fallback_blk_dec(desc, dst, src, nbytes);
338
202 blkcipher_walk_init(&walk, dst, src, nbytes); 339 blkcipher_walk_init(&walk, dst, src, nbytes);
203 return ecb_aes_crypt(desc, sctx->dec, sctx->key, &walk); 340 return ecb_aes_crypt(desc, sctx->dec, sctx->key, &walk);
204} 341}
205 342
343static int fallback_init_blk(struct crypto_tfm *tfm)
344{
345 const char *name = tfm->__crt_alg->cra_name;
346 struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
347
348 sctx->fallback.blk = crypto_alloc_blkcipher(name, 0,
349 CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK);
350
351 if (IS_ERR(sctx->fallback.blk)) {
352 printk(KERN_ERR "Error allocating fallback algo %s\n", name);
353 return PTR_ERR(sctx->fallback.blk);
354 }
355
356 return 0;
357}
358
359static void fallback_exit_blk(struct crypto_tfm *tfm)
360{
361 struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
362
363 crypto_free_blkcipher(sctx->fallback.blk);
364 sctx->fallback.blk = NULL;
365}
366
206static struct crypto_alg ecb_aes_alg = { 367static struct crypto_alg ecb_aes_alg = {
207 .cra_name = "ecb(aes)", 368 .cra_name = "ecb(aes)",
208 .cra_driver_name = "ecb-aes-s390", 369 .cra_driver_name = "ecb-aes-s390",
@@ -214,6 +375,8 @@ static struct crypto_alg ecb_aes_alg = {
214 .cra_type = &crypto_blkcipher_type, 375 .cra_type = &crypto_blkcipher_type,
215 .cra_module = THIS_MODULE, 376 .cra_module = THIS_MODULE,
216 .cra_list = LIST_HEAD_INIT(ecb_aes_alg.cra_list), 377 .cra_list = LIST_HEAD_INIT(ecb_aes_alg.cra_list),
378 .cra_init = fallback_init_blk,
379 .cra_exit = fallback_exit_blk,
217 .cra_u = { 380 .cra_u = {
218 .blkcipher = { 381 .blkcipher = {
219 .min_keysize = AES_MIN_KEY_SIZE, 382 .min_keysize = AES_MIN_KEY_SIZE,
@@ -229,6 +392,13 @@ static int cbc_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
229 unsigned int key_len) 392 unsigned int key_len)
230{ 393{
231 struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm); 394 struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
395 int ret;
396
397 ret = need_fallback(key_len);
398 if (ret > 0) {
399 sctx->key_len = key_len;
400 return setkey_fallback_blk(tfm, in_key, key_len);
401 }
232 402
233 switch (key_len) { 403 switch (key_len) {
234 case 16: 404 case 16:
@@ -283,6 +453,9 @@ static int cbc_aes_encrypt(struct blkcipher_desc *desc,
283 struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm); 453 struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
284 struct blkcipher_walk walk; 454 struct blkcipher_walk walk;
285 455
456 if (unlikely(need_fallback(sctx->key_len)))
457 return fallback_blk_enc(desc, dst, src, nbytes);
458
286 blkcipher_walk_init(&walk, dst, src, nbytes); 459 blkcipher_walk_init(&walk, dst, src, nbytes);
287 return cbc_aes_crypt(desc, sctx->enc, sctx->iv, &walk); 460 return cbc_aes_crypt(desc, sctx->enc, sctx->iv, &walk);
288} 461}
@@ -294,6 +467,9 @@ static int cbc_aes_decrypt(struct blkcipher_desc *desc,
294 struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm); 467 struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
295 struct blkcipher_walk walk; 468 struct blkcipher_walk walk;
296 469
470 if (unlikely(need_fallback(sctx->key_len)))
471 return fallback_blk_dec(desc, dst, src, nbytes);
472
297 blkcipher_walk_init(&walk, dst, src, nbytes); 473 blkcipher_walk_init(&walk, dst, src, nbytes);
298 return cbc_aes_crypt(desc, sctx->dec, sctx->iv, &walk); 474 return cbc_aes_crypt(desc, sctx->dec, sctx->iv, &walk);
299} 475}
@@ -309,6 +485,8 @@ static struct crypto_alg cbc_aes_alg = {
309 .cra_type = &crypto_blkcipher_type, 485 .cra_type = &crypto_blkcipher_type,
310 .cra_module = THIS_MODULE, 486 .cra_module = THIS_MODULE,
311 .cra_list = LIST_HEAD_INIT(cbc_aes_alg.cra_list), 487 .cra_list = LIST_HEAD_INIT(cbc_aes_alg.cra_list),
488 .cra_init = fallback_init_blk,
489 .cra_exit = fallback_exit_blk,
312 .cra_u = { 490 .cra_u = {
313 .blkcipher = { 491 .blkcipher = {
314 .min_keysize = AES_MIN_KEY_SIZE, 492 .min_keysize = AES_MIN_KEY_SIZE,
@@ -336,14 +514,10 @@ static int __init aes_init(void)
336 return -EOPNOTSUPP; 514 return -EOPNOTSUPP;
337 515
338 /* z9 109 and z9 BC/EC only support 128 bit key length */ 516 /* z9 109 and z9 BC/EC only support 128 bit key length */
339 if (keylen_flag == AES_KEYLEN_128) { 517 if (keylen_flag == AES_KEYLEN_128)
340 aes_alg.cra_u.cipher.cia_max_keysize = AES_MIN_KEY_SIZE;
341 ecb_aes_alg.cra_u.blkcipher.max_keysize = AES_MIN_KEY_SIZE;
342 cbc_aes_alg.cra_u.blkcipher.max_keysize = AES_MIN_KEY_SIZE;
343 printk(KERN_INFO 518 printk(KERN_INFO
344 "aes_s390: hardware acceleration only available for" 519 "aes_s390: hardware acceleration only available for "
345 "128 bit keys\n"); 520 "128 bit keys\n");
346 }
347 521
348 ret = crypto_register_alg(&aes_alg); 522 ret = crypto_register_alg(&aes_alg);
349 if (ret) 523 if (ret)
@@ -382,4 +556,3 @@ MODULE_ALIAS("aes");
382 556
383MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm"); 557MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm");
384MODULE_LICENSE("GPL"); 558MODULE_LICENSE("GPL");
385
diff --git a/arch/s390/crypto/prng.c b/arch/s390/crypto/prng.c
index 8eb3a1aedc22..0cfefddd8375 100644
--- a/arch/s390/crypto/prng.c
+++ b/arch/s390/crypto/prng.c
@@ -90,7 +90,7 @@ static ssize_t prng_read(struct file *file, char __user *ubuf, size_t nbytes,
90 int ret = 0; 90 int ret = 0;
91 int tmp; 91 int tmp;
92 92
93 /* nbytes can be arbitrary long, we spilt it into chunks */ 93 /* nbytes can be arbitrary length, we split it into chunks */
94 while (nbytes) { 94 while (nbytes) {
95 /* same as in extract_entropy_user in random.c */ 95 /* same as in extract_entropy_user in random.c */
96 if (need_resched()) { 96 if (need_resched()) {
@@ -146,7 +146,7 @@ static ssize_t prng_read(struct file *file, char __user *ubuf, size_t nbytes,
146 return ret; 146 return ret;
147} 147}
148 148
149static struct file_operations prng_fops = { 149static const struct file_operations prng_fops = {
150 .owner = THIS_MODULE, 150 .owner = THIS_MODULE,
151 .open = &prng_open, 151 .open = &prng_open,
152 .release = NULL, 152 .release = NULL,
diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c
index 5245717295b8..4b010ff814c9 100644
--- a/arch/s390/hypfs/inode.c
+++ b/arch/s390/hypfs/inode.c
@@ -490,7 +490,7 @@ static struct super_operations hypfs_s_ops = {
490 .show_options = hypfs_show_options, 490 .show_options = hypfs_show_options,
491}; 491};
492 492
493static decl_subsys(s390, NULL, NULL); 493static struct kobject *s390_kobj;
494 494
495static int __init hypfs_init(void) 495static int __init hypfs_init(void)
496{ 496{
@@ -506,17 +506,18 @@ static int __init hypfs_init(void)
506 goto fail_diag; 506 goto fail_diag;
507 } 507 }
508 } 508 }
509 kobj_set_kset_s(&s390_subsys, hypervisor_subsys); 509 s390_kobj = kobject_create_and_add("s390", hypervisor_kobj);
510 rc = subsystem_register(&s390_subsys); 510 if (!s390_kobj) {
511 if (rc) 511 rc = -ENOMEM;;
512 goto fail_sysfs; 512 goto fail_sysfs;
513 }
513 rc = register_filesystem(&hypfs_type); 514 rc = register_filesystem(&hypfs_type);
514 if (rc) 515 if (rc)
515 goto fail_filesystem; 516 goto fail_filesystem;
516 return 0; 517 return 0;
517 518
518fail_filesystem: 519fail_filesystem:
519 subsystem_unregister(&s390_subsys); 520 kobject_put(s390_kobj);
520fail_sysfs: 521fail_sysfs:
521 if (!MACHINE_IS_VM) 522 if (!MACHINE_IS_VM)
522 hypfs_diag_exit(); 523 hypfs_diag_exit();
@@ -530,7 +531,7 @@ static void __exit hypfs_exit(void)
530 if (!MACHINE_IS_VM) 531 if (!MACHINE_IS_VM)
531 hypfs_diag_exit(); 532 hypfs_diag_exit();
532 unregister_filesystem(&hypfs_type); 533 unregister_filesystem(&hypfs_type);
533 subsystem_unregister(&s390_subsys); 534 kobject_put(s390_kobj);
534} 535}
535 536
536module_init(hypfs_init) 537module_init(hypfs_init)
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index 56cb71007cd9..b3b650a93c7c 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -31,7 +31,3 @@ S390_KEXEC_OBJS := machine_kexec.o crash.o
31S390_KEXEC_OBJS += $(if $(CONFIG_64BIT),relocate_kernel64.o,relocate_kernel.o) 31S390_KEXEC_OBJS += $(if $(CONFIG_64BIT),relocate_kernel64.o,relocate_kernel.o)
32obj-$(CONFIG_KEXEC) += $(S390_KEXEC_OBJS) 32obj-$(CONFIG_KEXEC) += $(S390_KEXEC_OBJS)
33 33
34#
35# This is just to get the dependencies...
36#
37binfmt_elf32.o: $(TOPDIR)/fs/binfmt_elf.c
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index 1b3af7dab816..9f7b73b180f0 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -276,7 +276,7 @@ void __init startup_init(void)
276 create_kernel_nss(); 276 create_kernel_nss();
277 sort_main_extable(); 277 sort_main_extable();
278 setup_lowcore_early(); 278 setup_lowcore_early();
279 sclp_readinfo_early(); 279 sclp_read_info_early();
280 sclp_facilities_detect(); 280 sclp_facilities_detect();
281 memsize = sclp_memory_detect(); 281 memsize = sclp_memory_detect();
282#ifndef CONFIG_64BIT 282#ifndef CONFIG_64BIT
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S
index a87b1976d409..79dccd206a6e 100644
--- a/arch/s390/kernel/head64.S
+++ b/arch/s390/kernel/head64.S
@@ -157,7 +157,7 @@ startup_continue:
157 .long 0xb2b10000 # store facility list 157 .long 0xb2b10000 # store facility list
158 tm 0xc8,0x08 # check bit for clearing-by-ASCE 158 tm 0xc8,0x08 # check bit for clearing-by-ASCE
159 bno 0f-.LPG1(%r13) 159 bno 0f-.LPG1(%r13)
160 lhi %r1,2094 160 lhi %r1,2048
161 lhi %r2,0 161 lhi %r2,0
162 .long 0xb98e2001 162 .long 0xb98e2001
163 oi 7(%r12),0x80 # set IDTE flag 163 oi 7(%r12),0x80 # set IDTE flag
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index ce0856d32500..db28cca81fef 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -2,7 +2,7 @@
2 * arch/s390/kernel/ipl.c 2 * arch/s390/kernel/ipl.c
3 * ipl/reipl/dump support for Linux on s390. 3 * ipl/reipl/dump support for Linux on s390.
4 * 4 *
5 * Copyright (C) IBM Corp. 2005,2006 5 * Copyright IBM Corp. 2005,2007
6 * Author(s): Michael Holzheu <holzheu@de.ibm.com> 6 * Author(s): Michael Holzheu <holzheu@de.ibm.com>
7 * Heiko Carstens <heiko.carstens@de.ibm.com> 7 * Heiko Carstens <heiko.carstens@de.ibm.com>
8 * Volker Sameske <sameske@de.ibm.com> 8 * Volker Sameske <sameske@de.ibm.com>
@@ -31,6 +31,43 @@
31#define IPL_FCP_DUMP_STR "fcp_dump" 31#define IPL_FCP_DUMP_STR "fcp_dump"
32#define IPL_NSS_STR "nss" 32#define IPL_NSS_STR "nss"
33 33
34#define DUMP_CCW_STR "ccw"
35#define DUMP_FCP_STR "fcp"
36#define DUMP_NONE_STR "none"
37
38/*
39 * Four shutdown trigger types are supported:
40 * - panic
41 * - halt
42 * - power off
43 * - reipl
44 */
45#define ON_PANIC_STR "on_panic"
46#define ON_HALT_STR "on_halt"
47#define ON_POFF_STR "on_poff"
48#define ON_REIPL_STR "on_reboot"
49
50struct shutdown_action;
51struct shutdown_trigger {
52 char *name;
53 struct shutdown_action *action;
54};
55
56/*
57 * Five shutdown action types are supported:
58 */
59#define SHUTDOWN_ACTION_IPL_STR "ipl"
60#define SHUTDOWN_ACTION_REIPL_STR "reipl"
61#define SHUTDOWN_ACTION_DUMP_STR "dump"
62#define SHUTDOWN_ACTION_VMCMD_STR "vmcmd"
63#define SHUTDOWN_ACTION_STOP_STR "stop"
64
65struct shutdown_action {
66 char *name;
67 void (*fn) (struct shutdown_trigger *trigger);
68 int (*init) (void);
69};
70
34static char *ipl_type_str(enum ipl_type type) 71static char *ipl_type_str(enum ipl_type type)
35{ 72{
36 switch (type) { 73 switch (type) {
@@ -54,10 +91,6 @@ enum dump_type {
54 DUMP_TYPE_FCP = 4, 91 DUMP_TYPE_FCP = 4,
55}; 92};
56 93
57#define DUMP_NONE_STR "none"
58#define DUMP_CCW_STR "ccw"
59#define DUMP_FCP_STR "fcp"
60
61static char *dump_type_str(enum dump_type type) 94static char *dump_type_str(enum dump_type type)
62{ 95{
63 switch (type) { 96 switch (type) {
@@ -99,30 +132,6 @@ enum dump_method {
99 DUMP_METHOD_FCP_DIAG, 132 DUMP_METHOD_FCP_DIAG,
100}; 133};
101 134
102enum shutdown_action {
103 SHUTDOWN_REIPL,
104 SHUTDOWN_DUMP,
105 SHUTDOWN_STOP,
106};
107
108#define SHUTDOWN_REIPL_STR "reipl"
109#define SHUTDOWN_DUMP_STR "dump"
110#define SHUTDOWN_STOP_STR "stop"
111
112static char *shutdown_action_str(enum shutdown_action action)
113{
114 switch (action) {
115 case SHUTDOWN_REIPL:
116 return SHUTDOWN_REIPL_STR;
117 case SHUTDOWN_DUMP:
118 return SHUTDOWN_DUMP_STR;
119 case SHUTDOWN_STOP:
120 return SHUTDOWN_STOP_STR;
121 default:
122 return NULL;
123 }
124}
125
126static int diag308_set_works = 0; 135static int diag308_set_works = 0;
127 136
128static int reipl_capabilities = IPL_TYPE_UNKNOWN; 137static int reipl_capabilities = IPL_TYPE_UNKNOWN;
@@ -140,8 +149,6 @@ static enum dump_method dump_method = DUMP_METHOD_NONE;
140static struct ipl_parameter_block *dump_block_fcp; 149static struct ipl_parameter_block *dump_block_fcp;
141static struct ipl_parameter_block *dump_block_ccw; 150static struct ipl_parameter_block *dump_block_ccw;
142 151
143static enum shutdown_action on_panic_action = SHUTDOWN_STOP;
144
145static struct sclp_ipl_info sclp_ipl_info; 152static struct sclp_ipl_info sclp_ipl_info;
146 153
147int diag308(unsigned long subcode, void *addr) 154int diag308(unsigned long subcode, void *addr)
@@ -162,22 +169,25 @@ EXPORT_SYMBOL_GPL(diag308);
162/* SYSFS */ 169/* SYSFS */
163 170
164#define DEFINE_IPL_ATTR_RO(_prefix, _name, _format, _value) \ 171#define DEFINE_IPL_ATTR_RO(_prefix, _name, _format, _value) \
165static ssize_t sys_##_prefix##_##_name##_show(struct kset *kset, \ 172static ssize_t sys_##_prefix##_##_name##_show(struct kobject *kobj, \
173 struct kobj_attribute *attr, \
166 char *page) \ 174 char *page) \
167{ \ 175{ \
168 return sprintf(page, _format, _value); \ 176 return sprintf(page, _format, _value); \
169} \ 177} \
170static struct subsys_attribute sys_##_prefix##_##_name##_attr = \ 178static struct kobj_attribute sys_##_prefix##_##_name##_attr = \
171 __ATTR(_name, S_IRUGO, sys_##_prefix##_##_name##_show, NULL); 179 __ATTR(_name, S_IRUGO, sys_##_prefix##_##_name##_show, NULL);
172 180
173#define DEFINE_IPL_ATTR_RW(_prefix, _name, _fmt_out, _fmt_in, _value) \ 181#define DEFINE_IPL_ATTR_RW(_prefix, _name, _fmt_out, _fmt_in, _value) \
174static ssize_t sys_##_prefix##_##_name##_show(struct kset *kset, \ 182static ssize_t sys_##_prefix##_##_name##_show(struct kobject *kobj, \
183 struct kobj_attribute *attr, \
175 char *page) \ 184 char *page) \
176{ \ 185{ \
177 return sprintf(page, _fmt_out, \ 186 return sprintf(page, _fmt_out, \
178 (unsigned long long) _value); \ 187 (unsigned long long) _value); \
179} \ 188} \
180static ssize_t sys_##_prefix##_##_name##_store(struct kset *kset, \ 189static ssize_t sys_##_prefix##_##_name##_store(struct kobject *kobj, \
190 struct kobj_attribute *attr, \
181 const char *buf, size_t len) \ 191 const char *buf, size_t len) \
182{ \ 192{ \
183 unsigned long long value; \ 193 unsigned long long value; \
@@ -186,25 +196,27 @@ static ssize_t sys_##_prefix##_##_name##_store(struct kset *kset, \
186 _value = value; \ 196 _value = value; \
187 return len; \ 197 return len; \
188} \ 198} \
189static struct subsys_attribute sys_##_prefix##_##_name##_attr = \ 199static struct kobj_attribute sys_##_prefix##_##_name##_attr = \
190 __ATTR(_name,(S_IRUGO | S_IWUSR), \ 200 __ATTR(_name,(S_IRUGO | S_IWUSR), \
191 sys_##_prefix##_##_name##_show, \ 201 sys_##_prefix##_##_name##_show, \
192 sys_##_prefix##_##_name##_store); 202 sys_##_prefix##_##_name##_store);
193 203
194#define DEFINE_IPL_ATTR_STR_RW(_prefix, _name, _fmt_out, _fmt_in, _value)\ 204#define DEFINE_IPL_ATTR_STR_RW(_prefix, _name, _fmt_out, _fmt_in, _value)\
195static ssize_t sys_##_prefix##_##_name##_show(struct kset *kset, \ 205static ssize_t sys_##_prefix##_##_name##_show(struct kobject *kobj, \
206 struct kobj_attribute *attr, \
196 char *page) \ 207 char *page) \
197{ \ 208{ \
198 return sprintf(page, _fmt_out, _value); \ 209 return sprintf(page, _fmt_out, _value); \
199} \ 210} \
200static ssize_t sys_##_prefix##_##_name##_store(struct kset *kset, \ 211static ssize_t sys_##_prefix##_##_name##_store(struct kobject *kobj, \
212 struct kobj_attribute *attr, \
201 const char *buf, size_t len) \ 213 const char *buf, size_t len) \
202{ \ 214{ \
203 if (sscanf(buf, _fmt_in, _value) != 1) \ 215 strncpy(_value, buf, sizeof(_value) - 1); \
204 return -EINVAL; \ 216 strstrip(_value); \
205 return len; \ 217 return len; \
206} \ 218} \
207static struct subsys_attribute sys_##_prefix##_##_name##_attr = \ 219static struct kobj_attribute sys_##_prefix##_##_name##_attr = \
208 __ATTR(_name,(S_IRUGO | S_IWUSR), \ 220 __ATTR(_name,(S_IRUGO | S_IWUSR), \
209 sys_##_prefix##_##_name##_show, \ 221 sys_##_prefix##_##_name##_show, \
210 sys_##_prefix##_##_name##_store); 222 sys_##_prefix##_##_name##_store);
@@ -240,44 +252,19 @@ static __init enum ipl_type get_ipl_type(void)
240 return IPL_TYPE_FCP; 252 return IPL_TYPE_FCP;
241} 253}
242 254
243void __init setup_ipl_info(void)
244{
245 ipl_info.type = get_ipl_type();
246 switch (ipl_info.type) {
247 case IPL_TYPE_CCW:
248 ipl_info.data.ccw.dev_id.devno = ipl_devno;
249 ipl_info.data.ccw.dev_id.ssid = 0;
250 break;
251 case IPL_TYPE_FCP:
252 case IPL_TYPE_FCP_DUMP:
253 ipl_info.data.fcp.dev_id.devno =
254 IPL_PARMBLOCK_START->ipl_info.fcp.devno;
255 ipl_info.data.fcp.dev_id.ssid = 0;
256 ipl_info.data.fcp.wwpn = IPL_PARMBLOCK_START->ipl_info.fcp.wwpn;
257 ipl_info.data.fcp.lun = IPL_PARMBLOCK_START->ipl_info.fcp.lun;
258 break;
259 case IPL_TYPE_NSS:
260 strncpy(ipl_info.data.nss.name, kernel_nss_name,
261 sizeof(ipl_info.data.nss.name));
262 break;
263 case IPL_TYPE_UNKNOWN:
264 default:
265 /* We have no info to copy */
266 break;
267 }
268}
269
270struct ipl_info ipl_info; 255struct ipl_info ipl_info;
271EXPORT_SYMBOL_GPL(ipl_info); 256EXPORT_SYMBOL_GPL(ipl_info);
272 257
273static ssize_t ipl_type_show(struct kset *kset, char *page) 258static ssize_t ipl_type_show(struct kobject *kobj, struct kobj_attribute *attr,
259 char *page)
274{ 260{
275 return sprintf(page, "%s\n", ipl_type_str(ipl_info.type)); 261 return sprintf(page, "%s\n", ipl_type_str(ipl_info.type));
276} 262}
277 263
278static struct subsys_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type); 264static struct kobj_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type);
279 265
280static ssize_t sys_ipl_device_show(struct kset *kset, char *page) 266static ssize_t sys_ipl_device_show(struct kobject *kobj,
267 struct kobj_attribute *attr, char *page)
281{ 268{
282 struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START; 269 struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
283 270
@@ -292,7 +279,7 @@ static ssize_t sys_ipl_device_show(struct kset *kset, char *page)
292 } 279 }
293} 280}
294 281
295static struct subsys_attribute sys_ipl_device_attr = 282static struct kobj_attribute sys_ipl_device_attr =
296 __ATTR(device, S_IRUGO, sys_ipl_device_show, NULL); 283 __ATTR(device, S_IRUGO, sys_ipl_device_show, NULL);
297 284
298static ssize_t ipl_parameter_read(struct kobject *kobj, struct bin_attribute *attr, 285static ssize_t ipl_parameter_read(struct kobject *kobj, struct bin_attribute *attr,
@@ -367,7 +354,8 @@ static struct attribute_group ipl_fcp_attr_group = {
367 354
368/* CCW ipl device attributes */ 355/* CCW ipl device attributes */
369 356
370static ssize_t ipl_ccw_loadparm_show(struct kset *kset, char *page) 357static ssize_t ipl_ccw_loadparm_show(struct kobject *kobj,
358 struct kobj_attribute *attr, char *page)
371{ 359{
372 char loadparm[LOADPARM_LEN + 1] = {}; 360 char loadparm[LOADPARM_LEN + 1] = {};
373 361
@@ -379,7 +367,7 @@ static ssize_t ipl_ccw_loadparm_show(struct kset *kset, char *page)
379 return sprintf(page, "%s\n", loadparm); 367 return sprintf(page, "%s\n", loadparm);
380} 368}
381 369
382static struct subsys_attribute sys_ipl_ccw_loadparm_attr = 370static struct kobj_attribute sys_ipl_ccw_loadparm_attr =
383 __ATTR(loadparm, 0444, ipl_ccw_loadparm_show, NULL); 371 __ATTR(loadparm, 0444, ipl_ccw_loadparm_show, NULL);
384 372
385static struct attribute *ipl_ccw_attrs[] = { 373static struct attribute *ipl_ccw_attrs[] = {
@@ -418,10 +406,76 @@ static struct attribute_group ipl_unknown_attr_group = {
418 .attrs = ipl_unknown_attrs, 406 .attrs = ipl_unknown_attrs,
419}; 407};
420 408
421static decl_subsys(ipl, NULL, NULL); 409static struct kset *ipl_kset;
410
411static int __init ipl_register_fcp_files(void)
412{
413 int rc;
414
415 rc = sysfs_create_group(&ipl_kset->kobj, &ipl_fcp_attr_group);
416 if (rc)
417 goto out;
418 rc = sysfs_create_bin_file(&ipl_kset->kobj, &ipl_parameter_attr);
419 if (rc)
420 goto out_ipl_parm;
421 rc = sysfs_create_bin_file(&ipl_kset->kobj, &ipl_scp_data_attr);
422 if (!rc)
423 goto out;
424
425 sysfs_remove_bin_file(&ipl_kset->kobj, &ipl_parameter_attr);
426
427out_ipl_parm:
428 sysfs_remove_group(&ipl_kset->kobj, &ipl_fcp_attr_group);
429out:
430 return rc;
431}
432
433static void ipl_run(struct shutdown_trigger *trigger)
434{
435 diag308(DIAG308_IPL, NULL);
436 if (MACHINE_IS_VM)
437 __cpcmd("IPL", NULL, 0, NULL);
438 else if (ipl_info.type == IPL_TYPE_CCW)
439 reipl_ccw_dev(&ipl_info.data.ccw.dev_id);
440}
441
442static int ipl_init(void)
443{
444 int rc;
445
446 ipl_kset = kset_create_and_add("ipl", NULL, firmware_kobj);
447 if (!ipl_kset) {
448 rc = -ENOMEM;
449 goto out;
450 }
451 switch (ipl_info.type) {
452 case IPL_TYPE_CCW:
453 rc = sysfs_create_group(&ipl_kset->kobj, &ipl_ccw_attr_group);
454 break;
455 case IPL_TYPE_FCP:
456 case IPL_TYPE_FCP_DUMP:
457 rc = ipl_register_fcp_files();
458 break;
459 case IPL_TYPE_NSS:
460 rc = sysfs_create_group(&ipl_kset->kobj, &ipl_nss_attr_group);
461 break;
462 default:
463 rc = sysfs_create_group(&ipl_kset->kobj,
464 &ipl_unknown_attr_group);
465 break;
466 }
467out:
468 if (rc)
469 panic("ipl_init failed: rc = %i\n", rc);
470
471 return 0;
472}
473
474static struct shutdown_action ipl_action = {SHUTDOWN_ACTION_IPL_STR, ipl_run,
475 ipl_init};
422 476
423/* 477/*
424 * reipl section 478 * reipl shutdown action: Reboot Linux on shutdown.
425 */ 479 */
426 480
427/* FCP reipl device attributes */ 481/* FCP reipl device attributes */
@@ -465,7 +519,8 @@ static void reipl_get_ascii_loadparm(char *loadparm)
465 strstrip(loadparm); 519 strstrip(loadparm);
466} 520}
467 521
468static ssize_t reipl_ccw_loadparm_show(struct kset *kset, char *page) 522static ssize_t reipl_ccw_loadparm_show(struct kobject *kobj,
523 struct kobj_attribute *attr, char *page)
469{ 524{
470 char buf[LOADPARM_LEN + 1]; 525 char buf[LOADPARM_LEN + 1];
471 526
@@ -473,7 +528,8 @@ static ssize_t reipl_ccw_loadparm_show(struct kset *kset, char *page)
473 return sprintf(page, "%s\n", buf); 528 return sprintf(page, "%s\n", buf);
474} 529}
475 530
476static ssize_t reipl_ccw_loadparm_store(struct kset *kset, 531static ssize_t reipl_ccw_loadparm_store(struct kobject *kobj,
532 struct kobj_attribute *attr,
477 const char *buf, size_t len) 533 const char *buf, size_t len)
478{ 534{
479 int i, lp_len; 535 int i, lp_len;
@@ -500,7 +556,7 @@ static ssize_t reipl_ccw_loadparm_store(struct kset *kset,
500 return len; 556 return len;
501} 557}
502 558
503static struct subsys_attribute sys_reipl_ccw_loadparm_attr = 559static struct kobj_attribute sys_reipl_ccw_loadparm_attr =
504 __ATTR(loadparm, 0644, reipl_ccw_loadparm_show, 560 __ATTR(loadparm, 0644, reipl_ccw_loadparm_show,
505 reipl_ccw_loadparm_store); 561 reipl_ccw_loadparm_store);
506 562
@@ -539,7 +595,9 @@ static int reipl_set_type(enum ipl_type type)
539 595
540 switch(type) { 596 switch(type) {
541 case IPL_TYPE_CCW: 597 case IPL_TYPE_CCW:
542 if (MACHINE_IS_VM) 598 if (diag308_set_works)
599 reipl_method = REIPL_METHOD_CCW_DIAG;
600 else if (MACHINE_IS_VM)
543 reipl_method = REIPL_METHOD_CCW_VM; 601 reipl_method = REIPL_METHOD_CCW_VM;
544 else 602 else
545 reipl_method = REIPL_METHOD_CCW_CIO; 603 reipl_method = REIPL_METHOD_CCW_CIO;
@@ -568,13 +626,15 @@ static int reipl_set_type(enum ipl_type type)
568 return 0; 626 return 0;
569} 627}
570 628
571static ssize_t reipl_type_show(struct kset *kset, char *page) 629static ssize_t reipl_type_show(struct kobject *kobj,
630 struct kobj_attribute *attr, char *page)
572{ 631{
573 return sprintf(page, "%s\n", ipl_type_str(reipl_type)); 632 return sprintf(page, "%s\n", ipl_type_str(reipl_type));
574} 633}
575 634
576static ssize_t reipl_type_store(struct kset *kset, const char *buf, 635static ssize_t reipl_type_store(struct kobject *kobj,
577 size_t len) 636 struct kobj_attribute *attr,
637 const char *buf, size_t len)
578{ 638{
579 int rc = -EINVAL; 639 int rc = -EINVAL;
580 640
@@ -587,140 +647,12 @@ static ssize_t reipl_type_store(struct kset *kset, const char *buf,
587 return (rc != 0) ? rc : len; 647 return (rc != 0) ? rc : len;
588} 648}
589 649
590static struct subsys_attribute reipl_type_attr = 650static struct kobj_attribute reipl_type_attr =
591 __ATTR(reipl_type, 0644, reipl_type_show, reipl_type_store); 651 __ATTR(reipl_type, 0644, reipl_type_show, reipl_type_store);
592
593static decl_subsys(reipl, NULL, NULL);
594
595/*
596 * dump section
597 */
598
599/* FCP dump device attributes */
600
601DEFINE_IPL_ATTR_RW(dump_fcp, wwpn, "0x%016llx\n", "%016llx\n",
602 dump_block_fcp->ipl_info.fcp.wwpn);
603DEFINE_IPL_ATTR_RW(dump_fcp, lun, "0x%016llx\n", "%016llx\n",
604 dump_block_fcp->ipl_info.fcp.lun);
605DEFINE_IPL_ATTR_RW(dump_fcp, bootprog, "%lld\n", "%lld\n",
606 dump_block_fcp->ipl_info.fcp.bootprog);
607DEFINE_IPL_ATTR_RW(dump_fcp, br_lba, "%lld\n", "%lld\n",
608 dump_block_fcp->ipl_info.fcp.br_lba);
609DEFINE_IPL_ATTR_RW(dump_fcp, device, "0.0.%04llx\n", "0.0.%llx\n",
610 dump_block_fcp->ipl_info.fcp.devno);
611
612static struct attribute *dump_fcp_attrs[] = {
613 &sys_dump_fcp_device_attr.attr,
614 &sys_dump_fcp_wwpn_attr.attr,
615 &sys_dump_fcp_lun_attr.attr,
616 &sys_dump_fcp_bootprog_attr.attr,
617 &sys_dump_fcp_br_lba_attr.attr,
618 NULL,
619};
620
621static struct attribute_group dump_fcp_attr_group = {
622 .name = IPL_FCP_STR,
623 .attrs = dump_fcp_attrs,
624};
625
626/* CCW dump device attributes */
627
628DEFINE_IPL_ATTR_RW(dump_ccw, device, "0.0.%04llx\n", "0.0.%llx\n",
629 dump_block_ccw->ipl_info.ccw.devno);
630
631static struct attribute *dump_ccw_attrs[] = {
632 &sys_dump_ccw_device_attr.attr,
633 NULL,
634};
635
636static struct attribute_group dump_ccw_attr_group = {
637 .name = IPL_CCW_STR,
638 .attrs = dump_ccw_attrs,
639};
640
641/* dump type */
642
643static int dump_set_type(enum dump_type type)
644{
645 if (!(dump_capabilities & type))
646 return -EINVAL;
647 switch(type) {
648 case DUMP_TYPE_CCW:
649 if (MACHINE_IS_VM)
650 dump_method = DUMP_METHOD_CCW_VM;
651 else if (diag308_set_works)
652 dump_method = DUMP_METHOD_CCW_DIAG;
653 else
654 dump_method = DUMP_METHOD_CCW_CIO;
655 break;
656 case DUMP_TYPE_FCP:
657 dump_method = DUMP_METHOD_FCP_DIAG;
658 break;
659 default:
660 dump_method = DUMP_METHOD_NONE;
661 }
662 dump_type = type;
663 return 0;
664}
665
666static ssize_t dump_type_show(struct kset *kset, char *page)
667{
668 return sprintf(page, "%s\n", dump_type_str(dump_type));
669}
670
671static ssize_t dump_type_store(struct kset *kset, const char *buf,
672 size_t len)
673{
674 int rc = -EINVAL;
675
676 if (strncmp(buf, DUMP_NONE_STR, strlen(DUMP_NONE_STR)) == 0)
677 rc = dump_set_type(DUMP_TYPE_NONE);
678 else if (strncmp(buf, DUMP_CCW_STR, strlen(DUMP_CCW_STR)) == 0)
679 rc = dump_set_type(DUMP_TYPE_CCW);
680 else if (strncmp(buf, DUMP_FCP_STR, strlen(DUMP_FCP_STR)) == 0)
681 rc = dump_set_type(DUMP_TYPE_FCP);
682 return (rc != 0) ? rc : len;
683}
684
685static struct subsys_attribute dump_type_attr =
686 __ATTR(dump_type, 0644, dump_type_show, dump_type_store);
687
688static decl_subsys(dump, NULL, NULL);
689
690/*
691 * Shutdown actions section
692 */
693
694static decl_subsys(shutdown_actions, NULL, NULL);
695
696/* on panic */
697
698static ssize_t on_panic_show(struct kset *kset, char *page)
699{
700 return sprintf(page, "%s\n", shutdown_action_str(on_panic_action));
701}
702
703static ssize_t on_panic_store(struct kset *kset, const char *buf,
704 size_t len)
705{
706 if (strncmp(buf, SHUTDOWN_REIPL_STR, strlen(SHUTDOWN_REIPL_STR)) == 0)
707 on_panic_action = SHUTDOWN_REIPL;
708 else if (strncmp(buf, SHUTDOWN_DUMP_STR,
709 strlen(SHUTDOWN_DUMP_STR)) == 0)
710 on_panic_action = SHUTDOWN_DUMP;
711 else if (strncmp(buf, SHUTDOWN_STOP_STR,
712 strlen(SHUTDOWN_STOP_STR)) == 0)
713 on_panic_action = SHUTDOWN_STOP;
714 else
715 return -EINVAL;
716
717 return len;
718}
719 652
720static struct subsys_attribute on_panic_attr = 653static struct kset *reipl_kset;
721 __ATTR(on_panic, 0644, on_panic_show, on_panic_store);
722 654
723void do_reipl(void) 655void reipl_run(struct shutdown_trigger *trigger)
724{ 656{
725 struct ccw_dev_id devid; 657 struct ccw_dev_id devid;
726 static char buf[100]; 658 static char buf[100];
@@ -729,8 +661,6 @@ void do_reipl(void)
729 switch (reipl_method) { 661 switch (reipl_method) {
730 case REIPL_METHOD_CCW_CIO: 662 case REIPL_METHOD_CCW_CIO:
731 devid.devno = reipl_block_ccw->ipl_info.ccw.devno; 663 devid.devno = reipl_block_ccw->ipl_info.ccw.devno;
732 if (ipl_info.type == IPL_TYPE_CCW && devid.devno == ipl_devno)
733 diag308(DIAG308_IPL, NULL);
734 devid.ssid = 0; 664 devid.ssid = 0;
735 reipl_ccw_dev(&devid); 665 reipl_ccw_dev(&devid);
736 break; 666 break;
@@ -771,98 +701,6 @@ void do_reipl(void)
771 default: 701 default:
772 break; 702 break;
773 } 703 }
774 signal_processor(smp_processor_id(), sigp_stop_and_store_status);
775}
776
777static void do_dump(void)
778{
779 struct ccw_dev_id devid;
780 static char buf[100];
781
782 switch (dump_method) {
783 case DUMP_METHOD_CCW_CIO:
784 smp_send_stop();
785 devid.devno = dump_block_ccw->ipl_info.ccw.devno;
786 devid.ssid = 0;
787 reipl_ccw_dev(&devid);
788 break;
789 case DUMP_METHOD_CCW_VM:
790 smp_send_stop();
791 sprintf(buf, "STORE STATUS");
792 __cpcmd(buf, NULL, 0, NULL);
793 sprintf(buf, "IPL %X", dump_block_ccw->ipl_info.ccw.devno);
794 __cpcmd(buf, NULL, 0, NULL);
795 break;
796 case DUMP_METHOD_CCW_DIAG:
797 diag308(DIAG308_SET, dump_block_ccw);
798 diag308(DIAG308_DUMP, NULL);
799 break;
800 case DUMP_METHOD_FCP_DIAG:
801 diag308(DIAG308_SET, dump_block_fcp);
802 diag308(DIAG308_DUMP, NULL);
803 break;
804 case DUMP_METHOD_NONE:
805 default:
806 return;
807 }
808 printk(KERN_EMERG "Dump failed!\n");
809}
810
811/* init functions */
812
813static int __init ipl_register_fcp_files(void)
814{
815 int rc;
816
817 rc = sysfs_create_group(&ipl_subsys.kobj,
818 &ipl_fcp_attr_group);
819 if (rc)
820 goto out;
821 rc = sysfs_create_bin_file(&ipl_subsys.kobj,
822 &ipl_parameter_attr);
823 if (rc)
824 goto out_ipl_parm;
825 rc = sysfs_create_bin_file(&ipl_subsys.kobj,
826 &ipl_scp_data_attr);
827 if (!rc)
828 goto out;
829
830 sysfs_remove_bin_file(&ipl_subsys.kobj, &ipl_parameter_attr);
831
832out_ipl_parm:
833 sysfs_remove_group(&ipl_subsys.kobj, &ipl_fcp_attr_group);
834out:
835 return rc;
836}
837
838static int __init ipl_init(void)
839{
840 int rc;
841
842 rc = firmware_register(&ipl_subsys);
843 if (rc)
844 return rc;
845 switch (ipl_info.type) {
846 case IPL_TYPE_CCW:
847 rc = sysfs_create_group(&ipl_subsys.kobj,
848 &ipl_ccw_attr_group);
849 break;
850 case IPL_TYPE_FCP:
851 case IPL_TYPE_FCP_DUMP:
852 rc = ipl_register_fcp_files();
853 break;
854 case IPL_TYPE_NSS:
855 rc = sysfs_create_group(&ipl_subsys.kobj,
856 &ipl_nss_attr_group);
857 break;
858 default:
859 rc = sysfs_create_group(&ipl_subsys.kobj,
860 &ipl_unknown_attr_group);
861 break;
862 }
863 if (rc)
864 firmware_unregister(&ipl_subsys);
865 return rc;
866} 704}
867 705
868static void __init reipl_probe(void) 706static void __init reipl_probe(void)
@@ -883,7 +721,7 @@ static int __init reipl_nss_init(void)
883 721
884 if (!MACHINE_IS_VM) 722 if (!MACHINE_IS_VM)
885 return 0; 723 return 0;
886 rc = sysfs_create_group(&reipl_subsys.kobj, &reipl_nss_attr_group); 724 rc = sysfs_create_group(&reipl_kset->kobj, &reipl_nss_attr_group);
887 if (rc) 725 if (rc)
888 return rc; 726 return rc;
889 strncpy(reipl_nss_name, kernel_nss_name, NSS_NAME_SIZE + 1); 727 strncpy(reipl_nss_name, kernel_nss_name, NSS_NAME_SIZE + 1);
@@ -898,7 +736,7 @@ static int __init reipl_ccw_init(void)
898 reipl_block_ccw = (void *) get_zeroed_page(GFP_KERNEL); 736 reipl_block_ccw = (void *) get_zeroed_page(GFP_KERNEL);
899 if (!reipl_block_ccw) 737 if (!reipl_block_ccw)
900 return -ENOMEM; 738 return -ENOMEM;
901 rc = sysfs_create_group(&reipl_subsys.kobj, &reipl_ccw_attr_group); 739 rc = sysfs_create_group(&reipl_kset->kobj, &reipl_ccw_attr_group);
902 if (rc) { 740 if (rc) {
903 free_page((unsigned long)reipl_block_ccw); 741 free_page((unsigned long)reipl_block_ccw);
904 return rc; 742 return rc;
@@ -907,6 +745,7 @@ static int __init reipl_ccw_init(void)
907 reipl_block_ccw->hdr.version = IPL_PARM_BLOCK_VERSION; 745 reipl_block_ccw->hdr.version = IPL_PARM_BLOCK_VERSION;
908 reipl_block_ccw->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN; 746 reipl_block_ccw->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN;
909 reipl_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW; 747 reipl_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW;
748 reipl_block_ccw->hdr.flags = DIAG308_FLAGS_LP_VALID;
910 /* check if read scp info worked and set loadparm */ 749 /* check if read scp info worked and set loadparm */
911 if (sclp_ipl_info.is_valid) 750 if (sclp_ipl_info.is_valid)
912 memcpy(reipl_block_ccw->ipl_info.ccw.load_param, 751 memcpy(reipl_block_ccw->ipl_info.ccw.load_param,
@@ -915,8 +754,7 @@ static int __init reipl_ccw_init(void)
915 /* read scp info failed: set empty loadparm (EBCDIC blanks) */ 754 /* read scp info failed: set empty loadparm (EBCDIC blanks) */
916 memset(reipl_block_ccw->ipl_info.ccw.load_param, 0x40, 755 memset(reipl_block_ccw->ipl_info.ccw.load_param, 0x40,
917 LOADPARM_LEN); 756 LOADPARM_LEN);
918 /* FIXME: check for diag308_set_works when enabling diag ccw reipl */ 757 if (!MACHINE_IS_VM && !diag308_set_works)
919 if (!MACHINE_IS_VM)
920 sys_reipl_ccw_loadparm_attr.attr.mode = S_IRUGO; 758 sys_reipl_ccw_loadparm_attr.attr.mode = S_IRUGO;
921 if (ipl_info.type == IPL_TYPE_CCW) 759 if (ipl_info.type == IPL_TYPE_CCW)
922 reipl_block_ccw->ipl_info.ccw.devno = ipl_devno; 760 reipl_block_ccw->ipl_info.ccw.devno = ipl_devno;
@@ -936,7 +774,7 @@ static int __init reipl_fcp_init(void)
936 reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL); 774 reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
937 if (!reipl_block_fcp) 775 if (!reipl_block_fcp)
938 return -ENOMEM; 776 return -ENOMEM;
939 rc = sysfs_create_group(&reipl_subsys.kobj, &reipl_fcp_attr_group); 777 rc = sysfs_create_group(&reipl_kset->kobj, &reipl_fcp_attr_group);
940 if (rc) { 778 if (rc) {
941 free_page((unsigned long)reipl_block_fcp); 779 free_page((unsigned long)reipl_block_fcp);
942 return rc; 780 return rc;
@@ -954,16 +792,16 @@ static int __init reipl_fcp_init(void)
954 return 0; 792 return 0;
955} 793}
956 794
957static int __init reipl_init(void) 795static int reipl_init(void)
958{ 796{
959 int rc; 797 int rc;
960 798
961 rc = firmware_register(&reipl_subsys); 799 reipl_kset = kset_create_and_add("reipl", NULL, firmware_kobj);
962 if (rc) 800 if (!reipl_kset)
963 return rc; 801 return -ENOMEM;
964 rc = subsys_create_file(&reipl_subsys, &reipl_type_attr); 802 rc = sysfs_create_file(&reipl_kset->kobj, &reipl_type_attr.attr);
965 if (rc) { 803 if (rc) {
966 firmware_unregister(&reipl_subsys); 804 kset_unregister(reipl_kset);
967 return rc; 805 return rc;
968 } 806 }
969 rc = reipl_ccw_init(); 807 rc = reipl_ccw_init();
@@ -981,6 +819,140 @@ static int __init reipl_init(void)
981 return 0; 819 return 0;
982} 820}
983 821
822static struct shutdown_action reipl_action = {SHUTDOWN_ACTION_REIPL_STR,
823 reipl_run, reipl_init};
824
825/*
826 * dump shutdown action: Dump Linux on shutdown.
827 */
828
829/* FCP dump device attributes */
830
831DEFINE_IPL_ATTR_RW(dump_fcp, wwpn, "0x%016llx\n", "%016llx\n",
832 dump_block_fcp->ipl_info.fcp.wwpn);
833DEFINE_IPL_ATTR_RW(dump_fcp, lun, "0x%016llx\n", "%016llx\n",
834 dump_block_fcp->ipl_info.fcp.lun);
835DEFINE_IPL_ATTR_RW(dump_fcp, bootprog, "%lld\n", "%lld\n",
836 dump_block_fcp->ipl_info.fcp.bootprog);
837DEFINE_IPL_ATTR_RW(dump_fcp, br_lba, "%lld\n", "%lld\n",
838 dump_block_fcp->ipl_info.fcp.br_lba);
839DEFINE_IPL_ATTR_RW(dump_fcp, device, "0.0.%04llx\n", "0.0.%llx\n",
840 dump_block_fcp->ipl_info.fcp.devno);
841
842static struct attribute *dump_fcp_attrs[] = {
843 &sys_dump_fcp_device_attr.attr,
844 &sys_dump_fcp_wwpn_attr.attr,
845 &sys_dump_fcp_lun_attr.attr,
846 &sys_dump_fcp_bootprog_attr.attr,
847 &sys_dump_fcp_br_lba_attr.attr,
848 NULL,
849};
850
851static struct attribute_group dump_fcp_attr_group = {
852 .name = IPL_FCP_STR,
853 .attrs = dump_fcp_attrs,
854};
855
856/* CCW dump device attributes */
857
858DEFINE_IPL_ATTR_RW(dump_ccw, device, "0.0.%04llx\n", "0.0.%llx\n",
859 dump_block_ccw->ipl_info.ccw.devno);
860
861static struct attribute *dump_ccw_attrs[] = {
862 &sys_dump_ccw_device_attr.attr,
863 NULL,
864};
865
866static struct attribute_group dump_ccw_attr_group = {
867 .name = IPL_CCW_STR,
868 .attrs = dump_ccw_attrs,
869};
870
871/* dump type */
872
873static int dump_set_type(enum dump_type type)
874{
875 if (!(dump_capabilities & type))
876 return -EINVAL;
877 switch (type) {
878 case DUMP_TYPE_CCW:
879 if (diag308_set_works)
880 dump_method = DUMP_METHOD_CCW_DIAG;
881 else if (MACHINE_IS_VM)
882 dump_method = DUMP_METHOD_CCW_VM;
883 else
884 dump_method = DUMP_METHOD_CCW_CIO;
885 break;
886 case DUMP_TYPE_FCP:
887 dump_method = DUMP_METHOD_FCP_DIAG;
888 break;
889 default:
890 dump_method = DUMP_METHOD_NONE;
891 }
892 dump_type = type;
893 return 0;
894}
895
896static ssize_t dump_type_show(struct kobject *kobj,
897 struct kobj_attribute *attr, char *page)
898{
899 return sprintf(page, "%s\n", dump_type_str(dump_type));
900}
901
902static ssize_t dump_type_store(struct kobject *kobj,
903 struct kobj_attribute *attr,
904 const char *buf, size_t len)
905{
906 int rc = -EINVAL;
907
908 if (strncmp(buf, DUMP_NONE_STR, strlen(DUMP_NONE_STR)) == 0)
909 rc = dump_set_type(DUMP_TYPE_NONE);
910 else if (strncmp(buf, DUMP_CCW_STR, strlen(DUMP_CCW_STR)) == 0)
911 rc = dump_set_type(DUMP_TYPE_CCW);
912 else if (strncmp(buf, DUMP_FCP_STR, strlen(DUMP_FCP_STR)) == 0)
913 rc = dump_set_type(DUMP_TYPE_FCP);
914 return (rc != 0) ? rc : len;
915}
916
917static struct kobj_attribute dump_type_attr =
918 __ATTR(dump_type, 0644, dump_type_show, dump_type_store);
919
920static struct kset *dump_kset;
921
922static void dump_run(struct shutdown_trigger *trigger)
923{
924 struct ccw_dev_id devid;
925 static char buf[100];
926
927 switch (dump_method) {
928 case DUMP_METHOD_CCW_CIO:
929 smp_send_stop();
930 devid.devno = dump_block_ccw->ipl_info.ccw.devno;
931 devid.ssid = 0;
932 reipl_ccw_dev(&devid);
933 break;
934 case DUMP_METHOD_CCW_VM:
935 smp_send_stop();
936 sprintf(buf, "STORE STATUS");
937 __cpcmd(buf, NULL, 0, NULL);
938 sprintf(buf, "IPL %X", dump_block_ccw->ipl_info.ccw.devno);
939 __cpcmd(buf, NULL, 0, NULL);
940 break;
941 case DUMP_METHOD_CCW_DIAG:
942 diag308(DIAG308_SET, dump_block_ccw);
943 diag308(DIAG308_DUMP, NULL);
944 break;
945 case DUMP_METHOD_FCP_DIAG:
946 diag308(DIAG308_SET, dump_block_fcp);
947 diag308(DIAG308_DUMP, NULL);
948 break;
949 case DUMP_METHOD_NONE:
950 default:
951 return;
952 }
953 printk(KERN_EMERG "Dump failed!\n");
954}
955
984static int __init dump_ccw_init(void) 956static int __init dump_ccw_init(void)
985{ 957{
986 int rc; 958 int rc;
@@ -988,7 +960,7 @@ static int __init dump_ccw_init(void)
988 dump_block_ccw = (void *) get_zeroed_page(GFP_KERNEL); 960 dump_block_ccw = (void *) get_zeroed_page(GFP_KERNEL);
989 if (!dump_block_ccw) 961 if (!dump_block_ccw)
990 return -ENOMEM; 962 return -ENOMEM;
991 rc = sysfs_create_group(&dump_subsys.kobj, &dump_ccw_attr_group); 963 rc = sysfs_create_group(&dump_kset->kobj, &dump_ccw_attr_group);
992 if (rc) { 964 if (rc) {
993 free_page((unsigned long)dump_block_ccw); 965 free_page((unsigned long)dump_block_ccw);
994 return rc; 966 return rc;
@@ -1012,7 +984,7 @@ static int __init dump_fcp_init(void)
1012 dump_block_fcp = (void *) get_zeroed_page(GFP_KERNEL); 984 dump_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
1013 if (!dump_block_fcp) 985 if (!dump_block_fcp)
1014 return -ENOMEM; 986 return -ENOMEM;
1015 rc = sysfs_create_group(&dump_subsys.kobj, &dump_fcp_attr_group); 987 rc = sysfs_create_group(&dump_kset->kobj, &dump_fcp_attr_group);
1016 if (rc) { 988 if (rc) {
1017 free_page((unsigned long)dump_block_fcp); 989 free_page((unsigned long)dump_block_fcp);
1018 return rc; 990 return rc;
@@ -1026,33 +998,16 @@ static int __init dump_fcp_init(void)
1026 return 0; 998 return 0;
1027} 999}
1028 1000
1029#define SHUTDOWN_ON_PANIC_PRIO 0 1001static int dump_init(void)
1030
1031static int shutdown_on_panic_notify(struct notifier_block *self,
1032 unsigned long event, void *data)
1033{
1034 if (on_panic_action == SHUTDOWN_DUMP)
1035 do_dump();
1036 else if (on_panic_action == SHUTDOWN_REIPL)
1037 do_reipl();
1038 return NOTIFY_OK;
1039}
1040
1041static struct notifier_block shutdown_on_panic_nb = {
1042 .notifier_call = shutdown_on_panic_notify,
1043 .priority = SHUTDOWN_ON_PANIC_PRIO
1044};
1045
1046static int __init dump_init(void)
1047{ 1002{
1048 int rc; 1003 int rc;
1049 1004
1050 rc = firmware_register(&dump_subsys); 1005 dump_kset = kset_create_and_add("dump", NULL, firmware_kobj);
1051 if (rc) 1006 if (!dump_kset)
1052 return rc; 1007 return -ENOMEM;
1053 rc = subsys_create_file(&dump_subsys, &dump_type_attr); 1008 rc = sysfs_create_file(&dump_kset->kobj, &dump_type_attr.attr);
1054 if (rc) { 1009 if (rc) {
1055 firmware_unregister(&dump_subsys); 1010 kset_unregister(dump_kset);
1056 return rc; 1011 return rc;
1057 } 1012 }
1058 rc = dump_ccw_init(); 1013 rc = dump_ccw_init();
@@ -1065,46 +1020,381 @@ static int __init dump_init(void)
1065 return 0; 1020 return 0;
1066} 1021}
1067 1022
1068static int __init shutdown_actions_init(void) 1023static struct shutdown_action dump_action = {SHUTDOWN_ACTION_DUMP_STR,
1024 dump_run, dump_init};
1025
1026/*
1027 * vmcmd shutdown action: Trigger vm command on shutdown.
1028 */
1029
1030static char vmcmd_on_reboot[128];
1031static char vmcmd_on_panic[128];
1032static char vmcmd_on_halt[128];
1033static char vmcmd_on_poff[128];
1034
1035DEFINE_IPL_ATTR_STR_RW(vmcmd, on_reboot, "%s\n", "%s\n", vmcmd_on_reboot);
1036DEFINE_IPL_ATTR_STR_RW(vmcmd, on_panic, "%s\n", "%s\n", vmcmd_on_panic);
1037DEFINE_IPL_ATTR_STR_RW(vmcmd, on_halt, "%s\n", "%s\n", vmcmd_on_halt);
1038DEFINE_IPL_ATTR_STR_RW(vmcmd, on_poff, "%s\n", "%s\n", vmcmd_on_poff);
1039
1040static struct attribute *vmcmd_attrs[] = {
1041 &sys_vmcmd_on_reboot_attr.attr,
1042 &sys_vmcmd_on_panic_attr.attr,
1043 &sys_vmcmd_on_halt_attr.attr,
1044 &sys_vmcmd_on_poff_attr.attr,
1045 NULL,
1046};
1047
1048static struct attribute_group vmcmd_attr_group = {
1049 .attrs = vmcmd_attrs,
1050};
1051
1052static struct kset *vmcmd_kset;
1053
1054static void vmcmd_run(struct shutdown_trigger *trigger)
1055{
1056 char *cmd, *next_cmd;
1057
1058 if (strcmp(trigger->name, ON_REIPL_STR) == 0)
1059 cmd = vmcmd_on_reboot;
1060 else if (strcmp(trigger->name, ON_PANIC_STR) == 0)
1061 cmd = vmcmd_on_panic;
1062 else if (strcmp(trigger->name, ON_HALT_STR) == 0)
1063 cmd = vmcmd_on_halt;
1064 else if (strcmp(trigger->name, ON_POFF_STR) == 0)
1065 cmd = vmcmd_on_poff;
1066 else
1067 return;
1068
1069 if (strlen(cmd) == 0)
1070 return;
1071 do {
1072 next_cmd = strchr(cmd, '\n');
1073 if (next_cmd) {
1074 next_cmd[0] = 0;
1075 next_cmd += 1;
1076 }
1077 __cpcmd(cmd, NULL, 0, NULL);
1078 cmd = next_cmd;
1079 } while (cmd != NULL);
1080}
1081
1082static int vmcmd_init(void)
1069{ 1083{
1070 int rc; 1084 if (!MACHINE_IS_VM)
1085 return -ENOTSUPP;
1086 vmcmd_kset = kset_create_and_add("vmcmd", NULL, firmware_kobj);
1087 if (!vmcmd_kset)
1088 return -ENOMEM;
1089 return sysfs_create_group(&vmcmd_kset->kobj, &vmcmd_attr_group);
1090}
1071 1091
1072 rc = firmware_register(&shutdown_actions_subsys); 1092static struct shutdown_action vmcmd_action = {SHUTDOWN_ACTION_VMCMD_STR,
1073 if (rc) 1093 vmcmd_run, vmcmd_init};
1074 return rc; 1094
1075 rc = subsys_create_file(&shutdown_actions_subsys, &on_panic_attr); 1095/*
1076 if (rc) { 1096 * stop shutdown action: Stop Linux on shutdown.
1077 firmware_unregister(&shutdown_actions_subsys); 1097 */
1078 return rc; 1098
1099static void stop_run(struct shutdown_trigger *trigger)
1100{
1101 if (strcmp(trigger->name, ON_PANIC_STR) == 0)
1102 disabled_wait((unsigned long) __builtin_return_address(0));
1103 else {
1104 signal_processor(smp_processor_id(), sigp_stop);
1105 for (;;);
1079 } 1106 }
1080 atomic_notifier_chain_register(&panic_notifier_list,
1081 &shutdown_on_panic_nb);
1082 return 0;
1083} 1107}
1084 1108
1085static int __init s390_ipl_init(void) 1109static struct shutdown_action stop_action = {SHUTDOWN_ACTION_STOP_STR,
1110 stop_run, NULL};
1111
1112/* action list */
1113
1114static struct shutdown_action *shutdown_actions_list[] = {
1115 &ipl_action, &reipl_action, &dump_action, &vmcmd_action, &stop_action};
1116#define SHUTDOWN_ACTIONS_COUNT (sizeof(shutdown_actions_list) / sizeof(void *))
1117
1118/*
1119 * Trigger section
1120 */
1121
1122static struct kset *shutdown_actions_kset;
1123
1124static int set_trigger(const char *buf, struct shutdown_trigger *trigger,
1125 size_t len)
1086{ 1126{
1087 int rc; 1127 int i;
1128 for (i = 0; i < SHUTDOWN_ACTIONS_COUNT; i++) {
1129 if (!shutdown_actions_list[i])
1130 continue;
1131 if (strncmp(buf, shutdown_actions_list[i]->name,
1132 strlen(shutdown_actions_list[i]->name)) == 0) {
1133 trigger->action = shutdown_actions_list[i];
1134 return len;
1135 }
1136 }
1137 return -EINVAL;
1138}
1088 1139
1089 sclp_get_ipl_info(&sclp_ipl_info); 1140/* on reipl */
1141
1142static struct shutdown_trigger on_reboot_trigger = {ON_REIPL_STR,
1143 &reipl_action};
1144
1145static ssize_t on_reboot_show(struct kobject *kobj,
1146 struct kobj_attribute *attr, char *page)
1147{
1148 return sprintf(page, "%s\n", on_reboot_trigger.action->name);
1149}
1150
1151static ssize_t on_reboot_store(struct kobject *kobj,
1152 struct kobj_attribute *attr,
1153 const char *buf, size_t len)
1154{
1155 return set_trigger(buf, &on_reboot_trigger, len);
1156}
1157
1158static struct kobj_attribute on_reboot_attr =
1159 __ATTR(on_reboot, 0644, on_reboot_show, on_reboot_store);
1160
1161static void do_machine_restart(char *__unused)
1162{
1163 smp_send_stop();
1164 on_reboot_trigger.action->fn(&on_reboot_trigger);
1165 reipl_run(NULL);
1166}
1167void (*_machine_restart)(char *command) = do_machine_restart;
1168
1169/* on panic */
1170
1171static struct shutdown_trigger on_panic_trigger = {ON_PANIC_STR, &stop_action};
1172
1173static ssize_t on_panic_show(struct kobject *kobj,
1174 struct kobj_attribute *attr, char *page)
1175{
1176 return sprintf(page, "%s\n", on_panic_trigger.action->name);
1177}
1178
1179static ssize_t on_panic_store(struct kobject *kobj,
1180 struct kobj_attribute *attr,
1181 const char *buf, size_t len)
1182{
1183 return set_trigger(buf, &on_panic_trigger, len);
1184}
1185
1186static struct kobj_attribute on_panic_attr =
1187 __ATTR(on_panic, 0644, on_panic_show, on_panic_store);
1188
1189static void do_panic(void)
1190{
1191 on_panic_trigger.action->fn(&on_panic_trigger);
1192 stop_run(&on_panic_trigger);
1193}
1194
1195/* on halt */
1196
1197static struct shutdown_trigger on_halt_trigger = {ON_HALT_STR, &stop_action};
1198
1199static ssize_t on_halt_show(struct kobject *kobj,
1200 struct kobj_attribute *attr, char *page)
1201{
1202 return sprintf(page, "%s\n", on_halt_trigger.action->name);
1203}
1204
1205static ssize_t on_halt_store(struct kobject *kobj,
1206 struct kobj_attribute *attr,
1207 const char *buf, size_t len)
1208{
1209 return set_trigger(buf, &on_halt_trigger, len);
1210}
1211
1212static struct kobj_attribute on_halt_attr =
1213 __ATTR(on_halt, 0644, on_halt_show, on_halt_store);
1214
1215
1216static void do_machine_halt(void)
1217{
1218 smp_send_stop();
1219 on_halt_trigger.action->fn(&on_halt_trigger);
1220 stop_run(&on_halt_trigger);
1221}
1222void (*_machine_halt)(void) = do_machine_halt;
1223
1224/* on power off */
1225
1226static struct shutdown_trigger on_poff_trigger = {ON_POFF_STR, &stop_action};
1227
1228static ssize_t on_poff_show(struct kobject *kobj,
1229 struct kobj_attribute *attr, char *page)
1230{
1231 return sprintf(page, "%s\n", on_poff_trigger.action->name);
1232}
1233
1234static ssize_t on_poff_store(struct kobject *kobj,
1235 struct kobj_attribute *attr,
1236 const char *buf, size_t len)
1237{
1238 return set_trigger(buf, &on_poff_trigger, len);
1239}
1240
1241static struct kobj_attribute on_poff_attr =
1242 __ATTR(on_poff, 0644, on_poff_show, on_poff_store);
1243
1244
1245static void do_machine_power_off(void)
1246{
1247 smp_send_stop();
1248 on_poff_trigger.action->fn(&on_poff_trigger);
1249 stop_run(&on_poff_trigger);
1250}
1251void (*_machine_power_off)(void) = do_machine_power_off;
1252
1253static void __init shutdown_triggers_init(void)
1254{
1255 shutdown_actions_kset = kset_create_and_add("shutdown_actions", NULL,
1256 firmware_kobj);
1257 if (!shutdown_actions_kset)
1258 goto fail;
1259 if (sysfs_create_file(&shutdown_actions_kset->kobj,
1260 &on_reboot_attr.attr))
1261 goto fail;
1262 if (sysfs_create_file(&shutdown_actions_kset->kobj,
1263 &on_panic_attr.attr))
1264 goto fail;
1265 if (sysfs_create_file(&shutdown_actions_kset->kobj,
1266 &on_halt_attr.attr))
1267 goto fail;
1268 if (sysfs_create_file(&shutdown_actions_kset->kobj,
1269 &on_poff_attr.attr))
1270 goto fail;
1271
1272 return;
1273fail:
1274 panic("shutdown_triggers_init failed\n");
1275}
1276
1277static void __init shutdown_actions_init(void)
1278{
1279 int i;
1280
1281 for (i = 0; i < SHUTDOWN_ACTIONS_COUNT; i++) {
1282 if (!shutdown_actions_list[i]->init)
1283 continue;
1284 if (shutdown_actions_list[i]->init())
1285 shutdown_actions_list[i] = NULL;
1286 }
1287}
1288
1289static int __init s390_ipl_init(void)
1290{
1090 reipl_probe(); 1291 reipl_probe();
1091 rc = ipl_init(); 1292 sclp_get_ipl_info(&sclp_ipl_info);
1092 if (rc) 1293 shutdown_actions_init();
1093 return rc; 1294 shutdown_triggers_init();
1094 rc = reipl_init();
1095 if (rc)
1096 return rc;
1097 rc = dump_init();
1098 if (rc)
1099 return rc;
1100 rc = shutdown_actions_init();
1101 if (rc)
1102 return rc;
1103 return 0; 1295 return 0;
1104} 1296}
1105 1297
1106__initcall(s390_ipl_init); 1298__initcall(s390_ipl_init);
1107 1299
1300static void __init strncpy_skip_quote(char *dst, char *src, int n)
1301{
1302 int sx, dx;
1303
1304 dx = 0;
1305 for (sx = 0; src[sx] != 0; sx++) {
1306 if (src[sx] == '"')
1307 continue;
1308 dst[dx++] = src[sx];
1309 if (dx >= n)
1310 break;
1311 }
1312}
1313
1314static int __init vmcmd_on_reboot_setup(char *str)
1315{
1316 if (!MACHINE_IS_VM)
1317 return 1;
1318 strncpy_skip_quote(vmcmd_on_reboot, str, 127);
1319 vmcmd_on_reboot[127] = 0;
1320 on_reboot_trigger.action = &vmcmd_action;
1321 return 1;
1322}
1323__setup("vmreboot=", vmcmd_on_reboot_setup);
1324
1325static int __init vmcmd_on_panic_setup(char *str)
1326{
1327 if (!MACHINE_IS_VM)
1328 return 1;
1329 strncpy_skip_quote(vmcmd_on_panic, str, 127);
1330 vmcmd_on_panic[127] = 0;
1331 on_panic_trigger.action = &vmcmd_action;
1332 return 1;
1333}
1334__setup("vmpanic=", vmcmd_on_panic_setup);
1335
1336static int __init vmcmd_on_halt_setup(char *str)
1337{
1338 if (!MACHINE_IS_VM)
1339 return 1;
1340 strncpy_skip_quote(vmcmd_on_halt, str, 127);
1341 vmcmd_on_halt[127] = 0;
1342 on_halt_trigger.action = &vmcmd_action;
1343 return 1;
1344}
1345__setup("vmhalt=", vmcmd_on_halt_setup);
1346
1347static int __init vmcmd_on_poff_setup(char *str)
1348{
1349 if (!MACHINE_IS_VM)
1350 return 1;
1351 strncpy_skip_quote(vmcmd_on_poff, str, 127);
1352 vmcmd_on_poff[127] = 0;
1353 on_poff_trigger.action = &vmcmd_action;
1354 return 1;
1355}
1356__setup("vmpoff=", vmcmd_on_poff_setup);
1357
1358static int on_panic_notify(struct notifier_block *self,
1359 unsigned long event, void *data)
1360{
1361 do_panic();
1362 return NOTIFY_OK;
1363}
1364
1365static struct notifier_block on_panic_nb = {
1366 .notifier_call = on_panic_notify,
1367 .priority = 0,
1368};
1369
1370void __init setup_ipl(void)
1371{
1372 ipl_info.type = get_ipl_type();
1373 switch (ipl_info.type) {
1374 case IPL_TYPE_CCW:
1375 ipl_info.data.ccw.dev_id.devno = ipl_devno;
1376 ipl_info.data.ccw.dev_id.ssid = 0;
1377 break;
1378 case IPL_TYPE_FCP:
1379 case IPL_TYPE_FCP_DUMP:
1380 ipl_info.data.fcp.dev_id.devno =
1381 IPL_PARMBLOCK_START->ipl_info.fcp.devno;
1382 ipl_info.data.fcp.dev_id.ssid = 0;
1383 ipl_info.data.fcp.wwpn = IPL_PARMBLOCK_START->ipl_info.fcp.wwpn;
1384 ipl_info.data.fcp.lun = IPL_PARMBLOCK_START->ipl_info.fcp.lun;
1385 break;
1386 case IPL_TYPE_NSS:
1387 strncpy(ipl_info.data.nss.name, kernel_nss_name,
1388 sizeof(ipl_info.data.nss.name));
1389 break;
1390 case IPL_TYPE_UNKNOWN:
1391 default:
1392 /* We have no info to copy */
1393 break;
1394 }
1395 atomic_notifier_chain_register(&panic_notifier_list, &on_panic_nb);
1396}
1397
1108void __init ipl_save_parameters(void) 1398void __init ipl_save_parameters(void)
1109{ 1399{
1110 struct cio_iplinfo iplinfo; 1400 struct cio_iplinfo iplinfo;
@@ -1185,3 +1475,4 @@ void s390_reset_system(void)
1185 1475
1186 do_reset_calls(); 1476 do_reset_calls();
1187} 1477}
1478
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 29f7884b4ffa..0e7aca039307 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -36,7 +36,7 @@
36#include <linux/init.h> 36#include <linux/init.h>
37#include <linux/module.h> 37#include <linux/module.h>
38#include <linux/notifier.h> 38#include <linux/notifier.h>
39 39#include <linux/utsname.h>
40#include <asm/uaccess.h> 40#include <asm/uaccess.h>
41#include <asm/pgtable.h> 41#include <asm/pgtable.h>
42#include <asm/system.h> 42#include <asm/system.h>
@@ -182,13 +182,15 @@ void cpu_idle(void)
182 182
183void show_regs(struct pt_regs *regs) 183void show_regs(struct pt_regs *regs)
184{ 184{
185 struct task_struct *tsk = current; 185 print_modules();
186 186 printk("CPU: %d %s %s %.*s\n",
187 printk("CPU: %d %s\n", task_thread_info(tsk)->cpu, print_tainted()); 187 task_thread_info(current)->cpu, print_tainted(),
188 printk("Process %s (pid: %d, task: %p, ksp: %p)\n", 188 init_utsname()->release,
189 current->comm, task_pid_nr(current), (void *) tsk, 189 (int)strcspn(init_utsname()->version, " "),
190 (void *) tsk->thread.ksp); 190 init_utsname()->version);
191 191 printk("Process %s (pid: %d, task: %p, ksp: %p)\n",
192 current->comm, current->pid, current,
193 (void *) current->thread.ksp);
192 show_registers(regs); 194 show_registers(regs);
193 /* Show stack backtrace if pt_regs is from kernel mode */ 195 /* Show stack backtrace if pt_regs is from kernel mode */
194 if (!(regs->psw.mask & PSW_MASK_PSTATE)) 196 if (!(regs->psw.mask & PSW_MASK_PSTATE))
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index 1d81bf9488ae..6e036bae9875 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -86,13 +86,13 @@ FixPerRegisters(struct task_struct *task)
86 per_info->control_regs.bits.storage_alt_space_ctl = 0; 86 per_info->control_regs.bits.storage_alt_space_ctl = 0;
87} 87}
88 88
89static void set_single_step(struct task_struct *task) 89void user_enable_single_step(struct task_struct *task)
90{ 90{
91 task->thread.per_info.single_step = 1; 91 task->thread.per_info.single_step = 1;
92 FixPerRegisters(task); 92 FixPerRegisters(task);
93} 93}
94 94
95static void clear_single_step(struct task_struct *task) 95void user_disable_single_step(struct task_struct *task)
96{ 96{
97 task->thread.per_info.single_step = 0; 97 task->thread.per_info.single_step = 0;
98 FixPerRegisters(task); 98 FixPerRegisters(task);
@@ -107,7 +107,7 @@ void
107ptrace_disable(struct task_struct *child) 107ptrace_disable(struct task_struct *child)
108{ 108{
109 /* make sure the single step bit is not set. */ 109 /* make sure the single step bit is not set. */
110 clear_single_step(child); 110 user_disable_single_step(child);
111} 111}
112 112
113#ifndef CONFIG_64BIT 113#ifndef CONFIG_64BIT
@@ -651,7 +651,7 @@ do_ptrace(struct task_struct *child, long request, long addr, long data)
651 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 651 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
652 child->exit_code = data; 652 child->exit_code = data;
653 /* make sure the single step bit is not set. */ 653 /* make sure the single step bit is not set. */
654 clear_single_step(child); 654 user_disable_single_step(child);
655 wake_up_process(child); 655 wake_up_process(child);
656 return 0; 656 return 0;
657 657
@@ -665,7 +665,7 @@ do_ptrace(struct task_struct *child, long request, long addr, long data)
665 return 0; 665 return 0;
666 child->exit_code = SIGKILL; 666 child->exit_code = SIGKILL;
667 /* make sure the single step bit is not set. */ 667 /* make sure the single step bit is not set. */
668 clear_single_step(child); 668 user_disable_single_step(child);
669 wake_up_process(child); 669 wake_up_process(child);
670 return 0; 670 return 0;
671 671
@@ -675,10 +675,7 @@ do_ptrace(struct task_struct *child, long request, long addr, long data)
675 return -EIO; 675 return -EIO;
676 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 676 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
677 child->exit_code = data; 677 child->exit_code = data;
678 if (data) 678 user_enable_single_step(child);
679 set_tsk_thread_flag(child, TIF_SINGLE_STEP);
680 else
681 set_single_step(child);
682 /* give it a chance to run. */ 679 /* give it a chance to run. */
683 wake_up_process(child); 680 wake_up_process(child);
684 return 0; 681 return 0;
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 577aa7dd660e..766c783bd7a7 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -126,75 +126,6 @@ void __cpuinit cpu_init(void)
126} 126}
127 127
128/* 128/*
129 * VM halt and poweroff setup routines
130 */
131char vmhalt_cmd[128] = "";
132char vmpoff_cmd[128] = "";
133static char vmpanic_cmd[128] = "";
134
135static void strncpy_skip_quote(char *dst, char *src, int n)
136{
137 int sx, dx;
138
139 dx = 0;
140 for (sx = 0; src[sx] != 0; sx++) {
141 if (src[sx] == '"') continue;
142 dst[dx++] = src[sx];
143 if (dx >= n) break;
144 }
145}
146
147static int __init vmhalt_setup(char *str)
148{
149 strncpy_skip_quote(vmhalt_cmd, str, 127);
150 vmhalt_cmd[127] = 0;
151 return 1;
152}
153
154__setup("vmhalt=", vmhalt_setup);
155
156static int __init vmpoff_setup(char *str)
157{
158 strncpy_skip_quote(vmpoff_cmd, str, 127);
159 vmpoff_cmd[127] = 0;
160 return 1;
161}
162
163__setup("vmpoff=", vmpoff_setup);
164
165static int vmpanic_notify(struct notifier_block *self, unsigned long event,
166 void *data)
167{
168 if (MACHINE_IS_VM && strlen(vmpanic_cmd) > 0)
169 cpcmd(vmpanic_cmd, NULL, 0, NULL);
170
171 return NOTIFY_OK;
172}
173
174#define PANIC_PRI_VMPANIC 0
175
176static struct notifier_block vmpanic_nb = {
177 .notifier_call = vmpanic_notify,
178 .priority = PANIC_PRI_VMPANIC
179};
180
181static int __init vmpanic_setup(char *str)
182{
183 static int register_done __initdata = 0;
184
185 strncpy_skip_quote(vmpanic_cmd, str, 127);
186 vmpanic_cmd[127] = 0;
187 if (!register_done) {
188 register_done = 1;
189 atomic_notifier_chain_register(&panic_notifier_list,
190 &vmpanic_nb);
191 }
192 return 1;
193}
194
195__setup("vmpanic=", vmpanic_setup);
196
197/*
198 * condev= and conmode= setup parameter. 129 * condev= and conmode= setup parameter.
199 */ 130 */
200 131
@@ -308,38 +239,6 @@ static void __init setup_zfcpdump(unsigned int console_devno)
308static inline void setup_zfcpdump(unsigned int console_devno) {} 239static inline void setup_zfcpdump(unsigned int console_devno) {}
309#endif /* CONFIG_ZFCPDUMP */ 240#endif /* CONFIG_ZFCPDUMP */
310 241
311#ifdef CONFIG_SMP
312void (*_machine_restart)(char *command) = machine_restart_smp;
313void (*_machine_halt)(void) = machine_halt_smp;
314void (*_machine_power_off)(void) = machine_power_off_smp;
315#else
316/*
317 * Reboot, halt and power_off routines for non SMP.
318 */
319static void do_machine_restart_nonsmp(char * __unused)
320{
321 do_reipl();
322}
323
324static void do_machine_halt_nonsmp(void)
325{
326 if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0)
327 __cpcmd(vmhalt_cmd, NULL, 0, NULL);
328 signal_processor(smp_processor_id(), sigp_stop_and_store_status);
329}
330
331static void do_machine_power_off_nonsmp(void)
332{
333 if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0)
334 __cpcmd(vmpoff_cmd, NULL, 0, NULL);
335 signal_processor(smp_processor_id(), sigp_stop_and_store_status);
336}
337
338void (*_machine_restart)(char *command) = do_machine_restart_nonsmp;
339void (*_machine_halt)(void) = do_machine_halt_nonsmp;
340void (*_machine_power_off)(void) = do_machine_power_off_nonsmp;
341#endif
342
343 /* 242 /*
344 * Reboot, halt and power_off stubs. They just call _machine_restart, 243 * Reboot, halt and power_off stubs. They just call _machine_restart,
345 * _machine_halt or _machine_power_off. 244 * _machine_halt or _machine_power_off.
@@ -559,7 +458,9 @@ setup_resources(void)
559 data_resource.start = (unsigned long) &_etext; 458 data_resource.start = (unsigned long) &_etext;
560 data_resource.end = (unsigned long) &_edata - 1; 459 data_resource.end = (unsigned long) &_edata - 1;
561 460
562 for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) { 461 for (i = 0; i < MEMORY_CHUNKS; i++) {
462 if (!memory_chunk[i].size)
463 continue;
563 res = alloc_bootmem_low(sizeof(struct resource)); 464 res = alloc_bootmem_low(sizeof(struct resource));
564 res->flags = IORESOURCE_BUSY | IORESOURCE_MEM; 465 res->flags = IORESOURCE_BUSY | IORESOURCE_MEM;
565 switch (memory_chunk[i].type) { 466 switch (memory_chunk[i].type) {
@@ -617,7 +518,7 @@ EXPORT_SYMBOL_GPL(real_memory_size);
617static void __init setup_memory_end(void) 518static void __init setup_memory_end(void)
618{ 519{
619 unsigned long memory_size; 520 unsigned long memory_size;
620 unsigned long max_mem, max_phys; 521 unsigned long max_mem;
621 int i; 522 int i;
622 523
623#if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE) 524#if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE)
@@ -625,10 +526,31 @@ static void __init setup_memory_end(void)
625 memory_end = ZFCPDUMP_HSA_SIZE; 526 memory_end = ZFCPDUMP_HSA_SIZE;
626#endif 527#endif
627 memory_size = 0; 528 memory_size = 0;
628 max_phys = VMALLOC_END_INIT - VMALLOC_MIN_SIZE;
629 memory_end &= PAGE_MASK; 529 memory_end &= PAGE_MASK;
630 530
631 max_mem = memory_end ? min(max_phys, memory_end) : max_phys; 531 max_mem = memory_end ? min(VMALLOC_START, memory_end) : VMALLOC_START;
532 memory_end = min(max_mem, memory_end);
533
534 /*
535 * Make sure all chunks are MAX_ORDER aligned so we don't need the
536 * extra checks that HOLES_IN_ZONE would require.
537 */
538 for (i = 0; i < MEMORY_CHUNKS; i++) {
539 unsigned long start, end;
540 struct mem_chunk *chunk;
541 unsigned long align;
542
543 chunk = &memory_chunk[i];
544 align = 1UL << (MAX_ORDER + PAGE_SHIFT - 1);
545 start = (chunk->addr + align - 1) & ~(align - 1);
546 end = (chunk->addr + chunk->size) & ~(align - 1);
547 if (start >= end)
548 memset(chunk, 0, sizeof(*chunk));
549 else {
550 chunk->addr = start;
551 chunk->size = end - start;
552 }
553 }
632 554
633 for (i = 0; i < MEMORY_CHUNKS; i++) { 555 for (i = 0; i < MEMORY_CHUNKS; i++) {
634 struct mem_chunk *chunk = &memory_chunk[i]; 556 struct mem_chunk *chunk = &memory_chunk[i];
@@ -890,7 +812,7 @@ setup_arch(char **cmdline_p)
890 812
891 parse_early_param(); 813 parse_early_param();
892 814
893 setup_ipl_info(); 815 setup_ipl();
894 setup_memory_end(); 816 setup_memory_end();
895 setup_addressing_mode(); 817 setup_addressing_mode();
896 setup_memory(); 818 setup_memory();
@@ -899,7 +821,6 @@ setup_arch(char **cmdline_p)
899 821
900 cpu_init(); 822 cpu_init();
901 __cpu_logical_map[0] = S390_lowcore.cpu_data.cpu_addr; 823 __cpu_logical_map[0] = S390_lowcore.cpu_data.cpu_addr;
902 smp_setup_cpu_possible_map();
903 824
904 /* 825 /*
905 * Setup capabilities (ELF_HWCAP & ELF_PLATFORM). 826 * Setup capabilities (ELF_HWCAP & ELF_PLATFORM).
@@ -920,7 +841,7 @@ setup_arch(char **cmdline_p)
920 841
921void __cpuinit print_cpu_info(struct cpuinfo_S390 *cpuinfo) 842void __cpuinit print_cpu_info(struct cpuinfo_S390 *cpuinfo)
922{ 843{
923 printk("cpu %d " 844 printk(KERN_INFO "cpu %d "
924#ifdef CONFIG_SMP 845#ifdef CONFIG_SMP
925 "phys_idx=%d " 846 "phys_idx=%d "
926#endif 847#endif
@@ -996,7 +917,7 @@ static void *c_next(struct seq_file *m, void *v, loff_t *pos)
996static void c_stop(struct seq_file *m, void *v) 917static void c_stop(struct seq_file *m, void *v)
997{ 918{
998} 919}
999struct seq_operations cpuinfo_op = { 920const struct seq_operations cpuinfo_op = {
1000 .start = c_start, 921 .start = c_start,
1001 .next = c_next, 922 .next = c_next,
1002 .stop = c_stop, 923 .stop = c_stop,
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index d264671c1b71..4449bf32cbf1 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -471,6 +471,7 @@ void do_signal(struct pt_regs *regs)
471 471
472 if (signr > 0) { 472 if (signr > 0) {
473 /* Whee! Actually deliver the signal. */ 473 /* Whee! Actually deliver the signal. */
474 int ret;
474#ifdef CONFIG_COMPAT 475#ifdef CONFIG_COMPAT
475 if (test_thread_flag(TIF_31BIT)) { 476 if (test_thread_flag(TIF_31BIT)) {
476 extern int handle_signal32(unsigned long sig, 477 extern int handle_signal32(unsigned long sig,
@@ -478,15 +479,12 @@ void do_signal(struct pt_regs *regs)
478 siginfo_t *info, 479 siginfo_t *info,
479 sigset_t *oldset, 480 sigset_t *oldset,
480 struct pt_regs *regs); 481 struct pt_regs *regs);
481 if (handle_signal32( 482 ret = handle_signal32(signr, &ka, &info, oldset, regs);
482 signr, &ka, &info, oldset, regs) == 0) {
483 if (test_thread_flag(TIF_RESTORE_SIGMASK))
484 clear_thread_flag(TIF_RESTORE_SIGMASK);
485 }
486 return;
487 } 483 }
484 else
488#endif 485#endif
489 if (handle_signal(signr, &ka, &info, oldset, regs) == 0) { 486 ret = handle_signal(signr, &ka, &info, oldset, regs);
487 if (!ret) {
490 /* 488 /*
491 * A signal was successfully delivered; the saved 489 * A signal was successfully delivered; the saved
492 * sigmask will have been stored in the signal frame, 490 * sigmask will have been stored in the signal frame,
@@ -495,6 +493,14 @@ void do_signal(struct pt_regs *regs)
495 */ 493 */
496 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 494 if (test_thread_flag(TIF_RESTORE_SIGMASK))
497 clear_thread_flag(TIF_RESTORE_SIGMASK); 495 clear_thread_flag(TIF_RESTORE_SIGMASK);
496
497 /*
498 * If we would have taken a single-step trap
499 * for a normal instruction, act like we took
500 * one for the handler setup.
501 */
502 if (current->thread.per_info.single_step)
503 set_thread_flag(TIF_SINGLE_STEP);
498 } 504 }
499 return; 505 return;
500 } 506 }
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 264ea906db4c..aa37fa154512 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -42,6 +42,7 @@
42#include <asm/tlbflush.h> 42#include <asm/tlbflush.h>
43#include <asm/timer.h> 43#include <asm/timer.h>
44#include <asm/lowcore.h> 44#include <asm/lowcore.h>
45#include <asm/sclp.h>
45#include <asm/cpu.h> 46#include <asm/cpu.h>
46 47
47/* 48/*
@@ -53,11 +54,27 @@ EXPORT_SYMBOL(lowcore_ptr);
53cpumask_t cpu_online_map = CPU_MASK_NONE; 54cpumask_t cpu_online_map = CPU_MASK_NONE;
54EXPORT_SYMBOL(cpu_online_map); 55EXPORT_SYMBOL(cpu_online_map);
55 56
56cpumask_t cpu_possible_map = CPU_MASK_NONE; 57cpumask_t cpu_possible_map = CPU_MASK_ALL;
57EXPORT_SYMBOL(cpu_possible_map); 58EXPORT_SYMBOL(cpu_possible_map);
58 59
59static struct task_struct *current_set[NR_CPUS]; 60static struct task_struct *current_set[NR_CPUS];
60 61
62static u8 smp_cpu_type;
63static int smp_use_sigp_detection;
64
65enum s390_cpu_state {
66 CPU_STATE_STANDBY,
67 CPU_STATE_CONFIGURED,
68};
69
70#ifdef CONFIG_HOTPLUG_CPU
71static DEFINE_MUTEX(smp_cpu_state_mutex);
72#endif
73static int smp_cpu_state[NR_CPUS];
74
75static DEFINE_PER_CPU(struct cpu, cpu_devices);
76DEFINE_PER_CPU(struct s390_idle_data, s390_idle);
77
61static void smp_ext_bitcall(int, ec_bit_sig); 78static void smp_ext_bitcall(int, ec_bit_sig);
62 79
63/* 80/*
@@ -193,6 +210,33 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
193} 210}
194EXPORT_SYMBOL(smp_call_function_single); 211EXPORT_SYMBOL(smp_call_function_single);
195 212
213/**
214 * smp_call_function_mask(): Run a function on a set of other CPUs.
215 * @mask: The set of cpus to run on. Must not include the current cpu.
216 * @func: The function to run. This must be fast and non-blocking.
217 * @info: An arbitrary pointer to pass to the function.
218 * @wait: If true, wait (atomically) until function has completed on other CPUs.
219 *
220 * Returns 0 on success, else a negative status code.
221 *
222 * If @wait is true, then returns once @func has returned; otherwise
223 * it returns just before the target cpu calls @func.
224 *
225 * You must not call this function with disabled interrupts or from a
226 * hardware interrupt handler or from a bottom half handler.
227 */
228int
229smp_call_function_mask(cpumask_t mask,
230 void (*func)(void *), void *info,
231 int wait)
232{
233 preempt_disable();
234 __smp_call_function_map(func, info, 0, wait, mask);
235 preempt_enable();
236 return 0;
237}
238EXPORT_SYMBOL(smp_call_function_mask);
239
196void smp_send_stop(void) 240void smp_send_stop(void)
197{ 241{
198 int cpu, rc; 242 int cpu, rc;
@@ -217,33 +261,6 @@ void smp_send_stop(void)
217} 261}
218 262
219/* 263/*
220 * Reboot, halt and power_off routines for SMP.
221 */
222void machine_restart_smp(char *__unused)
223{
224 smp_send_stop();
225 do_reipl();
226}
227
228void machine_halt_smp(void)
229{
230 smp_send_stop();
231 if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0)
232 __cpcmd(vmhalt_cmd, NULL, 0, NULL);
233 signal_processor(smp_processor_id(), sigp_stop_and_store_status);
234 for (;;);
235}
236
237void machine_power_off_smp(void)
238{
239 smp_send_stop();
240 if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0)
241 __cpcmd(vmpoff_cmd, NULL, 0, NULL);
242 signal_processor(smp_processor_id(), sigp_stop_and_store_status);
243 for (;;);
244}
245
246/*
247 * This is the main routine where commands issued by other 264 * This is the main routine where commands issued by other
248 * cpus are handled. 265 * cpus are handled.
249 */ 266 */
@@ -355,6 +372,13 @@ void smp_ctl_clear_bit(int cr, int bit)
355} 372}
356EXPORT_SYMBOL(smp_ctl_clear_bit); 373EXPORT_SYMBOL(smp_ctl_clear_bit);
357 374
375/*
376 * In early ipl state a temp. logically cpu number is needed, so the sigp
377 * functions can be used to sense other cpus. Since NR_CPUS is >= 2 on
378 * CONFIG_SMP and the ipl cpu is logical cpu 0, it must be 1.
379 */
380#define CPU_INIT_NO 1
381
358#if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE) 382#if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE)
359 383
360/* 384/*
@@ -375,9 +399,10 @@ static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu)
375 "kernel was compiled with NR_CPUS=%i\n", cpu, NR_CPUS); 399 "kernel was compiled with NR_CPUS=%i\n", cpu, NR_CPUS);
376 return; 400 return;
377 } 401 }
378 zfcpdump_save_areas[cpu] = alloc_bootmem(sizeof(union save_area)); 402 zfcpdump_save_areas[cpu] = kmalloc(sizeof(union save_area), GFP_KERNEL);
379 __cpu_logical_map[1] = (__u16) phy_cpu; 403 __cpu_logical_map[CPU_INIT_NO] = (__u16) phy_cpu;
380 while (signal_processor(1, sigp_stop_and_store_status) == sigp_busy) 404 while (signal_processor(CPU_INIT_NO, sigp_stop_and_store_status) ==
405 sigp_busy)
381 cpu_relax(); 406 cpu_relax();
382 memcpy(zfcpdump_save_areas[cpu], 407 memcpy(zfcpdump_save_areas[cpu],
383 (void *)(unsigned long) store_prefix() + SAVE_AREA_BASE, 408 (void *)(unsigned long) store_prefix() + SAVE_AREA_BASE,
@@ -397,32 +422,155 @@ static inline void smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) { }
397 422
398#endif /* CONFIG_ZFCPDUMP || CONFIG_ZFCPDUMP_MODULE */ 423#endif /* CONFIG_ZFCPDUMP || CONFIG_ZFCPDUMP_MODULE */
399 424
400/* 425static int cpu_stopped(int cpu)
401 * Lets check how many CPUs we have.
402 */
403static unsigned int __init smp_count_cpus(void)
404{ 426{
405 unsigned int cpu, num_cpus; 427 __u32 status;
406 __u16 boot_cpu_addr;
407 428
408 /* 429 /* Check for stopped state */
409 * cpu 0 is the boot cpu. See smp_prepare_boot_cpu. 430 if (signal_processor_ps(&status, 0, cpu, sigp_sense) ==
410 */ 431 sigp_status_stored) {
432 if (status & 0x40)
433 return 1;
434 }
435 return 0;
436}
437
438static int cpu_known(int cpu_id)
439{
440 int cpu;
441
442 for_each_present_cpu(cpu) {
443 if (__cpu_logical_map[cpu] == cpu_id)
444 return 1;
445 }
446 return 0;
447}
448
449static int smp_rescan_cpus_sigp(cpumask_t avail)
450{
451 int cpu_id, logical_cpu;
452
453 logical_cpu = first_cpu(avail);
454 if (logical_cpu == NR_CPUS)
455 return 0;
456 for (cpu_id = 0; cpu_id <= 65535; cpu_id++) {
457 if (cpu_known(cpu_id))
458 continue;
459 __cpu_logical_map[logical_cpu] = cpu_id;
460 if (!cpu_stopped(logical_cpu))
461 continue;
462 cpu_set(logical_cpu, cpu_present_map);
463 smp_cpu_state[logical_cpu] = CPU_STATE_CONFIGURED;
464 logical_cpu = next_cpu(logical_cpu, avail);
465 if (logical_cpu == NR_CPUS)
466 break;
467 }
468 return 0;
469}
470
471static int smp_rescan_cpus_sclp(cpumask_t avail)
472{
473 struct sclp_cpu_info *info;
474 int cpu_id, logical_cpu, cpu;
475 int rc;
476
477 logical_cpu = first_cpu(avail);
478 if (logical_cpu == NR_CPUS)
479 return 0;
480 info = kmalloc(sizeof(*info), GFP_KERNEL);
481 if (!info)
482 return -ENOMEM;
483 rc = sclp_get_cpu_info(info);
484 if (rc)
485 goto out;
486 for (cpu = 0; cpu < info->combined; cpu++) {
487 if (info->has_cpu_type && info->cpu[cpu].type != smp_cpu_type)
488 continue;
489 cpu_id = info->cpu[cpu].address;
490 if (cpu_known(cpu_id))
491 continue;
492 __cpu_logical_map[logical_cpu] = cpu_id;
493 cpu_set(logical_cpu, cpu_present_map);
494 if (cpu >= info->configured)
495 smp_cpu_state[logical_cpu] = CPU_STATE_STANDBY;
496 else
497 smp_cpu_state[logical_cpu] = CPU_STATE_CONFIGURED;
498 logical_cpu = next_cpu(logical_cpu, avail);
499 if (logical_cpu == NR_CPUS)
500 break;
501 }
502out:
503 kfree(info);
504 return rc;
505}
506
507static int smp_rescan_cpus(void)
508{
509 cpumask_t avail;
510
511 cpus_xor(avail, cpu_possible_map, cpu_present_map);
512 if (smp_use_sigp_detection)
513 return smp_rescan_cpus_sigp(avail);
514 else
515 return smp_rescan_cpus_sclp(avail);
516}
517
518static void __init smp_detect_cpus(void)
519{
520 unsigned int cpu, c_cpus, s_cpus;
521 struct sclp_cpu_info *info;
522 u16 boot_cpu_addr, cpu_addr;
523
524 c_cpus = 1;
525 s_cpus = 0;
411 boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr; 526 boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
412 current_thread_info()->cpu = 0; 527 info = kmalloc(sizeof(*info), GFP_KERNEL);
413 num_cpus = 1; 528 if (!info)
414 for (cpu = 0; cpu <= 65535; cpu++) { 529 panic("smp_detect_cpus failed to allocate memory\n");
415 if ((__u16) cpu == boot_cpu_addr) 530 /* Use sigp detection algorithm if sclp doesn't work. */
531 if (sclp_get_cpu_info(info)) {
532 smp_use_sigp_detection = 1;
533 for (cpu = 0; cpu <= 65535; cpu++) {
534 if (cpu == boot_cpu_addr)
535 continue;
536 __cpu_logical_map[CPU_INIT_NO] = cpu;
537 if (!cpu_stopped(CPU_INIT_NO))
538 continue;
539 smp_get_save_area(c_cpus, cpu);
540 c_cpus++;
541 }
542 goto out;
543 }
544
545 if (info->has_cpu_type) {
546 for (cpu = 0; cpu < info->combined; cpu++) {
547 if (info->cpu[cpu].address == boot_cpu_addr) {
548 smp_cpu_type = info->cpu[cpu].type;
549 break;
550 }
551 }
552 }
553
554 for (cpu = 0; cpu < info->combined; cpu++) {
555 if (info->has_cpu_type && info->cpu[cpu].type != smp_cpu_type)
556 continue;
557 cpu_addr = info->cpu[cpu].address;
558 if (cpu_addr == boot_cpu_addr)
416 continue; 559 continue;
417 __cpu_logical_map[1] = (__u16) cpu; 560 __cpu_logical_map[CPU_INIT_NO] = cpu_addr;
418 if (signal_processor(1, sigp_sense) == sigp_not_operational) 561 if (!cpu_stopped(CPU_INIT_NO)) {
562 s_cpus++;
419 continue; 563 continue;
420 smp_get_save_area(num_cpus, cpu); 564 }
421 num_cpus++; 565 smp_get_save_area(c_cpus, cpu_addr);
566 c_cpus++;
422 } 567 }
423 printk("Detected %d CPU's\n", (int) num_cpus); 568out:
424 printk("Boot cpu address %2X\n", boot_cpu_addr); 569 kfree(info);
425 return num_cpus; 570 printk(KERN_INFO "CPUs: %d configured, %d standby\n", c_cpus, s_cpus);
571 get_online_cpus();
572 smp_rescan_cpus();
573 put_online_cpus();
426} 574}
427 575
428/* 576/*
@@ -453,8 +601,6 @@ int __cpuinit start_secondary(void *cpuvoid)
453 return 0; 601 return 0;
454} 602}
455 603
456DEFINE_PER_CPU(struct s390_idle_data, s390_idle);
457
458static void __init smp_create_idle(unsigned int cpu) 604static void __init smp_create_idle(unsigned int cpu)
459{ 605{
460 struct task_struct *p; 606 struct task_struct *p;
@@ -470,37 +616,82 @@ static void __init smp_create_idle(unsigned int cpu)
470 spin_lock_init(&(&per_cpu(s390_idle, cpu))->lock); 616 spin_lock_init(&(&per_cpu(s390_idle, cpu))->lock);
471} 617}
472 618
473static int cpu_stopped(int cpu) 619static int __cpuinit smp_alloc_lowcore(int cpu)
474{ 620{
475 __u32 status; 621 unsigned long async_stack, panic_stack;
622 struct _lowcore *lowcore;
623 int lc_order;
624
625 lc_order = sizeof(long) == 8 ? 1 : 0;
626 lowcore = (void *) __get_free_pages(GFP_KERNEL | GFP_DMA, lc_order);
627 if (!lowcore)
628 return -ENOMEM;
629 async_stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER);
630 if (!async_stack)
631 goto out_async_stack;
632 panic_stack = __get_free_page(GFP_KERNEL);
633 if (!panic_stack)
634 goto out_panic_stack;
635
636 *lowcore = S390_lowcore;
637 lowcore->async_stack = async_stack + ASYNC_SIZE;
638 lowcore->panic_stack = panic_stack + PAGE_SIZE;
476 639
477 /* Check for stopped state */ 640#ifndef CONFIG_64BIT
478 if (signal_processor_ps(&status, 0, cpu, sigp_sense) == 641 if (MACHINE_HAS_IEEE) {
479 sigp_status_stored) { 642 unsigned long save_area;
480 if (status & 0x40) 643
481 return 1; 644 save_area = get_zeroed_page(GFP_KERNEL);
645 if (!save_area)
646 goto out_save_area;
647 lowcore->extended_save_area_addr = (u32) save_area;
482 } 648 }
649#endif
650 lowcore_ptr[cpu] = lowcore;
483 return 0; 651 return 0;
652
653#ifndef CONFIG_64BIT
654out_save_area:
655 free_page(panic_stack);
656#endif
657out_panic_stack:
658 free_pages(async_stack, ASYNC_ORDER);
659out_async_stack:
660 free_pages((unsigned long) lowcore, lc_order);
661 return -ENOMEM;
484} 662}
485 663
486/* Upping and downing of CPUs */ 664#ifdef CONFIG_HOTPLUG_CPU
665static void smp_free_lowcore(int cpu)
666{
667 struct _lowcore *lowcore;
668 int lc_order;
669
670 lc_order = sizeof(long) == 8 ? 1 : 0;
671 lowcore = lowcore_ptr[cpu];
672#ifndef CONFIG_64BIT
673 if (MACHINE_HAS_IEEE)
674 free_page((unsigned long) lowcore->extended_save_area_addr);
675#endif
676 free_page(lowcore->panic_stack - PAGE_SIZE);
677 free_pages(lowcore->async_stack - ASYNC_SIZE, ASYNC_ORDER);
678 free_pages((unsigned long) lowcore, lc_order);
679 lowcore_ptr[cpu] = NULL;
680}
681#endif /* CONFIG_HOTPLUG_CPU */
487 682
488int __cpu_up(unsigned int cpu) 683/* Upping and downing of CPUs */
684int __cpuinit __cpu_up(unsigned int cpu)
489{ 685{
490 struct task_struct *idle; 686 struct task_struct *idle;
491 struct _lowcore *cpu_lowcore; 687 struct _lowcore *cpu_lowcore;
492 struct stack_frame *sf; 688 struct stack_frame *sf;
493 sigp_ccode ccode; 689 sigp_ccode ccode;
494 int curr_cpu;
495 690
496 for (curr_cpu = 0; curr_cpu <= 65535; curr_cpu++) { 691 if (smp_cpu_state[cpu] != CPU_STATE_CONFIGURED)
497 __cpu_logical_map[cpu] = (__u16) curr_cpu; 692 return -EIO;
498 if (cpu_stopped(cpu)) 693 if (smp_alloc_lowcore(cpu))
499 break; 694 return -ENOMEM;
500 }
501
502 if (!cpu_stopped(cpu))
503 return -ENODEV;
504 695
505 ccode = signal_processor_p((__u32)(unsigned long)(lowcore_ptr[cpu]), 696 ccode = signal_processor_p((__u32)(unsigned long)(lowcore_ptr[cpu]),
506 cpu, sigp_set_prefix); 697 cpu, sigp_set_prefix);
@@ -515,6 +706,7 @@ int __cpu_up(unsigned int cpu)
515 cpu_lowcore = lowcore_ptr[cpu]; 706 cpu_lowcore = lowcore_ptr[cpu];
516 cpu_lowcore->kernel_stack = (unsigned long) 707 cpu_lowcore->kernel_stack = (unsigned long)
517 task_stack_page(idle) + THREAD_SIZE; 708 task_stack_page(idle) + THREAD_SIZE;
709 cpu_lowcore->thread_info = (unsigned long) task_thread_info(idle);
518 sf = (struct stack_frame *) (cpu_lowcore->kernel_stack 710 sf = (struct stack_frame *) (cpu_lowcore->kernel_stack
519 - sizeof(struct pt_regs) 711 - sizeof(struct pt_regs)
520 - sizeof(struct stack_frame)); 712 - sizeof(struct stack_frame));
@@ -528,6 +720,8 @@ int __cpu_up(unsigned int cpu)
528 cpu_lowcore->percpu_offset = __per_cpu_offset[cpu]; 720 cpu_lowcore->percpu_offset = __per_cpu_offset[cpu];
529 cpu_lowcore->current_task = (unsigned long) idle; 721 cpu_lowcore->current_task = (unsigned long) idle;
530 cpu_lowcore->cpu_data.cpu_nr = cpu; 722 cpu_lowcore->cpu_data.cpu_nr = cpu;
723 cpu_lowcore->softirq_pending = 0;
724 cpu_lowcore->ext_call_fast = 0;
531 eieio(); 725 eieio();
532 726
533 while (signal_processor(cpu, sigp_restart) == sigp_busy) 727 while (signal_processor(cpu, sigp_restart) == sigp_busy)
@@ -538,44 +732,20 @@ int __cpu_up(unsigned int cpu)
538 return 0; 732 return 0;
539} 733}
540 734
541static unsigned int __initdata additional_cpus; 735static int __init setup_possible_cpus(char *s)
542static unsigned int __initdata possible_cpus;
543
544void __init smp_setup_cpu_possible_map(void)
545{ 736{
546 unsigned int phy_cpus, pos_cpus, cpu; 737 int pcpus, cpu;
547
548 phy_cpus = smp_count_cpus();
549 pos_cpus = min(phy_cpus + additional_cpus, (unsigned int) NR_CPUS);
550
551 if (possible_cpus)
552 pos_cpus = min(possible_cpus, (unsigned int) NR_CPUS);
553 738
554 for (cpu = 0; cpu < pos_cpus; cpu++) 739 pcpus = simple_strtoul(s, NULL, 0);
740 cpu_possible_map = cpumask_of_cpu(0);
741 for (cpu = 1; cpu < pcpus && cpu < NR_CPUS; cpu++)
555 cpu_set(cpu, cpu_possible_map); 742 cpu_set(cpu, cpu_possible_map);
556
557 phy_cpus = min(phy_cpus, pos_cpus);
558
559 for (cpu = 0; cpu < phy_cpus; cpu++)
560 cpu_set(cpu, cpu_present_map);
561}
562
563#ifdef CONFIG_HOTPLUG_CPU
564
565static int __init setup_additional_cpus(char *s)
566{
567 additional_cpus = simple_strtoul(s, NULL, 0);
568 return 0;
569}
570early_param("additional_cpus", setup_additional_cpus);
571
572static int __init setup_possible_cpus(char *s)
573{
574 possible_cpus = simple_strtoul(s, NULL, 0);
575 return 0; 743 return 0;
576} 744}
577early_param("possible_cpus", setup_possible_cpus); 745early_param("possible_cpus", setup_possible_cpus);
578 746
747#ifdef CONFIG_HOTPLUG_CPU
748
579int __cpu_disable(void) 749int __cpu_disable(void)
580{ 750{
581 struct ec_creg_mask_parms cr_parms; 751 struct ec_creg_mask_parms cr_parms;
@@ -612,7 +782,8 @@ void __cpu_die(unsigned int cpu)
612 /* Wait until target cpu is down */ 782 /* Wait until target cpu is down */
613 while (!smp_cpu_not_running(cpu)) 783 while (!smp_cpu_not_running(cpu))
614 cpu_relax(); 784 cpu_relax();
615 printk("Processor %d spun down\n", cpu); 785 smp_free_lowcore(cpu);
786 printk(KERN_INFO "Processor %d spun down\n", cpu);
616} 787}
617 788
618void cpu_die(void) 789void cpu_die(void)
@@ -625,49 +796,19 @@ void cpu_die(void)
625 796
626#endif /* CONFIG_HOTPLUG_CPU */ 797#endif /* CONFIG_HOTPLUG_CPU */
627 798
628/*
629 * Cycle through the processors and setup structures.
630 */
631
632void __init smp_prepare_cpus(unsigned int max_cpus) 799void __init smp_prepare_cpus(unsigned int max_cpus)
633{ 800{
634 unsigned long stack;
635 unsigned int cpu; 801 unsigned int cpu;
636 int i; 802
803 smp_detect_cpus();
637 804
638 /* request the 0x1201 emergency signal external interrupt */ 805 /* request the 0x1201 emergency signal external interrupt */
639 if (register_external_interrupt(0x1201, do_ext_call_interrupt) != 0) 806 if (register_external_interrupt(0x1201, do_ext_call_interrupt) != 0)
640 panic("Couldn't request external interrupt 0x1201"); 807 panic("Couldn't request external interrupt 0x1201");
641 memset(lowcore_ptr, 0, sizeof(lowcore_ptr)); 808 memset(lowcore_ptr, 0, sizeof(lowcore_ptr));
642 /*
643 * Initialize prefix pages and stacks for all possible cpus
644 */
645 print_cpu_info(&S390_lowcore.cpu_data); 809 print_cpu_info(&S390_lowcore.cpu_data);
810 smp_alloc_lowcore(smp_processor_id());
646 811
647 for_each_possible_cpu(i) {
648 lowcore_ptr[i] = (struct _lowcore *)
649 __get_free_pages(GFP_KERNEL | GFP_DMA,
650 sizeof(void*) == 8 ? 1 : 0);
651 stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER);
652 if (!lowcore_ptr[i] || !stack)
653 panic("smp_boot_cpus failed to allocate memory\n");
654
655 *(lowcore_ptr[i]) = S390_lowcore;
656 lowcore_ptr[i]->async_stack = stack + ASYNC_SIZE;
657 stack = __get_free_pages(GFP_KERNEL, 0);
658 if (!stack)
659 panic("smp_boot_cpus failed to allocate memory\n");
660 lowcore_ptr[i]->panic_stack = stack + PAGE_SIZE;
661#ifndef CONFIG_64BIT
662 if (MACHINE_HAS_IEEE) {
663 lowcore_ptr[i]->extended_save_area_addr =
664 (__u32) __get_free_pages(GFP_KERNEL, 0);
665 if (!lowcore_ptr[i]->extended_save_area_addr)
666 panic("smp_boot_cpus failed to "
667 "allocate memory\n");
668 }
669#endif
670 }
671#ifndef CONFIG_64BIT 812#ifndef CONFIG_64BIT
672 if (MACHINE_HAS_IEEE) 813 if (MACHINE_HAS_IEEE)
673 ctl_set_bit(14, 29); /* enable extended save area */ 814 ctl_set_bit(14, 29); /* enable extended save area */
@@ -683,15 +824,17 @@ void __init smp_prepare_boot_cpu(void)
683{ 824{
684 BUG_ON(smp_processor_id() != 0); 825 BUG_ON(smp_processor_id() != 0);
685 826
827 current_thread_info()->cpu = 0;
828 cpu_set(0, cpu_present_map);
686 cpu_set(0, cpu_online_map); 829 cpu_set(0, cpu_online_map);
687 S390_lowcore.percpu_offset = __per_cpu_offset[0]; 830 S390_lowcore.percpu_offset = __per_cpu_offset[0];
688 current_set[0] = current; 831 current_set[0] = current;
832 smp_cpu_state[0] = CPU_STATE_CONFIGURED;
689 spin_lock_init(&(&__get_cpu_var(s390_idle))->lock); 833 spin_lock_init(&(&__get_cpu_var(s390_idle))->lock);
690} 834}
691 835
692void __init smp_cpus_done(unsigned int max_cpus) 836void __init smp_cpus_done(unsigned int max_cpus)
693{ 837{
694 cpu_present_map = cpu_possible_map;
695} 838}
696 839
697/* 840/*
@@ -705,7 +848,79 @@ int setup_profiling_timer(unsigned int multiplier)
705 return 0; 848 return 0;
706} 849}
707 850
708static DEFINE_PER_CPU(struct cpu, cpu_devices); 851#ifdef CONFIG_HOTPLUG_CPU
852static ssize_t cpu_configure_show(struct sys_device *dev, char *buf)
853{
854 ssize_t count;
855
856 mutex_lock(&smp_cpu_state_mutex);
857 count = sprintf(buf, "%d\n", smp_cpu_state[dev->id]);
858 mutex_unlock(&smp_cpu_state_mutex);
859 return count;
860}
861
862static ssize_t cpu_configure_store(struct sys_device *dev, const char *buf,
863 size_t count)
864{
865 int cpu = dev->id;
866 int val, rc;
867 char delim;
868
869 if (sscanf(buf, "%d %c", &val, &delim) != 1)
870 return -EINVAL;
871 if (val != 0 && val != 1)
872 return -EINVAL;
873
874 mutex_lock(&smp_cpu_state_mutex);
875 get_online_cpus();
876 rc = -EBUSY;
877 if (cpu_online(cpu))
878 goto out;
879 rc = 0;
880 switch (val) {
881 case 0:
882 if (smp_cpu_state[cpu] == CPU_STATE_CONFIGURED) {
883 rc = sclp_cpu_deconfigure(__cpu_logical_map[cpu]);
884 if (!rc)
885 smp_cpu_state[cpu] = CPU_STATE_STANDBY;
886 }
887 break;
888 case 1:
889 if (smp_cpu_state[cpu] == CPU_STATE_STANDBY) {
890 rc = sclp_cpu_configure(__cpu_logical_map[cpu]);
891 if (!rc)
892 smp_cpu_state[cpu] = CPU_STATE_CONFIGURED;
893 }
894 break;
895 default:
896 break;
897 }
898out:
899 put_online_cpus();
900 mutex_unlock(&smp_cpu_state_mutex);
901 return rc ? rc : count;
902}
903static SYSDEV_ATTR(configure, 0644, cpu_configure_show, cpu_configure_store);
904#endif /* CONFIG_HOTPLUG_CPU */
905
906static ssize_t show_cpu_address(struct sys_device *dev, char *buf)
907{
908 return sprintf(buf, "%d\n", __cpu_logical_map[dev->id]);
909}
910static SYSDEV_ATTR(address, 0444, show_cpu_address, NULL);
911
912
913static struct attribute *cpu_common_attrs[] = {
914#ifdef CONFIG_HOTPLUG_CPU
915 &attr_configure.attr,
916#endif
917 &attr_address.attr,
918 NULL,
919};
920
921static struct attribute_group cpu_common_attr_group = {
922 .attrs = cpu_common_attrs,
923};
709 924
710static ssize_t show_capability(struct sys_device *dev, char *buf) 925static ssize_t show_capability(struct sys_device *dev, char *buf)
711{ 926{
@@ -750,15 +965,15 @@ static ssize_t show_idle_time(struct sys_device *dev, char *buf)
750} 965}
751static SYSDEV_ATTR(idle_time_us, 0444, show_idle_time, NULL); 966static SYSDEV_ATTR(idle_time_us, 0444, show_idle_time, NULL);
752 967
753static struct attribute *cpu_attrs[] = { 968static struct attribute *cpu_online_attrs[] = {
754 &attr_capability.attr, 969 &attr_capability.attr,
755 &attr_idle_count.attr, 970 &attr_idle_count.attr,
756 &attr_idle_time_us.attr, 971 &attr_idle_time_us.attr,
757 NULL, 972 NULL,
758}; 973};
759 974
760static struct attribute_group cpu_attr_group = { 975static struct attribute_group cpu_online_attr_group = {
761 .attrs = cpu_attrs, 976 .attrs = cpu_online_attrs,
762}; 977};
763 978
764static int __cpuinit smp_cpu_notify(struct notifier_block *self, 979static int __cpuinit smp_cpu_notify(struct notifier_block *self,
@@ -778,12 +993,12 @@ static int __cpuinit smp_cpu_notify(struct notifier_block *self,
778 idle->idle_time = 0; 993 idle->idle_time = 0;
779 idle->idle_count = 0; 994 idle->idle_count = 0;
780 spin_unlock_irq(&idle->lock); 995 spin_unlock_irq(&idle->lock);
781 if (sysfs_create_group(&s->kobj, &cpu_attr_group)) 996 if (sysfs_create_group(&s->kobj, &cpu_online_attr_group))
782 return NOTIFY_BAD; 997 return NOTIFY_BAD;
783 break; 998 break;
784 case CPU_DEAD: 999 case CPU_DEAD:
785 case CPU_DEAD_FROZEN: 1000 case CPU_DEAD_FROZEN:
786 sysfs_remove_group(&s->kobj, &cpu_attr_group); 1001 sysfs_remove_group(&s->kobj, &cpu_online_attr_group);
787 break; 1002 break;
788 } 1003 }
789 return NOTIFY_OK; 1004 return NOTIFY_OK;
@@ -793,6 +1008,62 @@ static struct notifier_block __cpuinitdata smp_cpu_nb = {
793 .notifier_call = smp_cpu_notify, 1008 .notifier_call = smp_cpu_notify,
794}; 1009};
795 1010
1011static int smp_add_present_cpu(int cpu)
1012{
1013 struct cpu *c = &per_cpu(cpu_devices, cpu);
1014 struct sys_device *s = &c->sysdev;
1015 int rc;
1016
1017 c->hotpluggable = 1;
1018 rc = register_cpu(c, cpu);
1019 if (rc)
1020 goto out;
1021 rc = sysfs_create_group(&s->kobj, &cpu_common_attr_group);
1022 if (rc)
1023 goto out_cpu;
1024 if (!cpu_online(cpu))
1025 goto out;
1026 rc = sysfs_create_group(&s->kobj, &cpu_online_attr_group);
1027 if (!rc)
1028 return 0;
1029 sysfs_remove_group(&s->kobj, &cpu_common_attr_group);
1030out_cpu:
1031#ifdef CONFIG_HOTPLUG_CPU
1032 unregister_cpu(c);
1033#endif
1034out:
1035 return rc;
1036}
1037
1038#ifdef CONFIG_HOTPLUG_CPU
1039static ssize_t rescan_store(struct sys_device *dev, const char *buf,
1040 size_t count)
1041{
1042 cpumask_t newcpus;
1043 int cpu;
1044 int rc;
1045
1046 mutex_lock(&smp_cpu_state_mutex);
1047 get_online_cpus();
1048 newcpus = cpu_present_map;
1049 rc = smp_rescan_cpus();
1050 if (rc)
1051 goto out;
1052 cpus_andnot(newcpus, cpu_present_map, newcpus);
1053 for_each_cpu_mask(cpu, newcpus) {
1054 rc = smp_add_present_cpu(cpu);
1055 if (rc)
1056 cpu_clear(cpu, cpu_present_map);
1057 }
1058 rc = 0;
1059out:
1060 put_online_cpus();
1061 mutex_unlock(&smp_cpu_state_mutex);
1062 return rc ? rc : count;
1063}
1064static SYSDEV_ATTR(rescan, 0200, NULL, rescan_store);
1065#endif /* CONFIG_HOTPLUG_CPU */
1066
796static int __init topology_init(void) 1067static int __init topology_init(void)
797{ 1068{
798 int cpu; 1069 int cpu;
@@ -800,16 +1071,14 @@ static int __init topology_init(void)
800 1071
801 register_cpu_notifier(&smp_cpu_nb); 1072 register_cpu_notifier(&smp_cpu_nb);
802 1073
803 for_each_possible_cpu(cpu) { 1074#ifdef CONFIG_HOTPLUG_CPU
804 struct cpu *c = &per_cpu(cpu_devices, cpu); 1075 rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj,
805 struct sys_device *s = &c->sysdev; 1076 &attr_rescan.attr);
806 1077 if (rc)
807 c->hotpluggable = 1; 1078 return rc;
808 register_cpu(c, cpu); 1079#endif
809 if (!cpu_online(cpu)) 1080 for_each_present_cpu(cpu) {
810 continue; 1081 rc = smp_add_present_cpu(cpu);
811 s = &c->sysdev;
812 rc = sysfs_create_group(&s->kobj, &cpu_attr_group);
813 if (rc) 1082 if (rc)
814 return rc; 1083 return rc;
815 } 1084 }
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 22b800ce2126..3bbac1293be4 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -1145,7 +1145,7 @@ static void etr_work_fn(struct work_struct *work)
1145 * Sysfs interface functions 1145 * Sysfs interface functions
1146 */ 1146 */
1147static struct sysdev_class etr_sysclass = { 1147static struct sysdev_class etr_sysclass = {
1148 set_kset_name("etr") 1148 .name = "etr",
1149}; 1149};
1150 1150
1151static struct sys_device etr_port0_dev = { 1151static struct sys_device etr_port0_dev = {
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 8ed16a83fba7..52b8342c6bf2 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -31,6 +31,7 @@
31#include <linux/reboot.h> 31#include <linux/reboot.h>
32#include <linux/kprobes.h> 32#include <linux/kprobes.h>
33#include <linux/bug.h> 33#include <linux/bug.h>
34#include <linux/utsname.h>
34#include <asm/system.h> 35#include <asm/system.h>
35#include <asm/uaccess.h> 36#include <asm/uaccess.h>
36#include <asm/io.h> 37#include <asm/io.h>
@@ -168,9 +169,16 @@ void show_stack(struct task_struct *task, unsigned long *sp)
168 */ 169 */
169void dump_stack(void) 170void dump_stack(void)
170{ 171{
172 printk("CPU: %d %s %s %.*s\n",
173 task_thread_info(current)->cpu, print_tainted(),
174 init_utsname()->release,
175 (int)strcspn(init_utsname()->version, " "),
176 init_utsname()->version);
177 printk("Process %s (pid: %d, task: %p, ksp: %p)\n",
178 current->comm, current->pid, current,
179 (void *) current->thread.ksp);
171 show_stack(NULL, NULL); 180 show_stack(NULL, NULL);
172} 181}
173
174EXPORT_SYMBOL(dump_stack); 182EXPORT_SYMBOL(dump_stack);
175 183
176static inline int mask_bits(struct pt_regs *regs, unsigned long bits) 184static inline int mask_bits(struct pt_regs *regs, unsigned long bits)
@@ -258,8 +266,14 @@ void die(const char * str, struct pt_regs * regs, long err)
258 console_verbose(); 266 console_verbose();
259 spin_lock_irq(&die_lock); 267 spin_lock_irq(&die_lock);
260 bust_spinlocks(1); 268 bust_spinlocks(1);
261 printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); 269 printk("%s: %04lx [#%d] ", str, err & 0xffff, ++die_counter);
262 print_modules(); 270#ifdef CONFIG_PREEMPT
271 printk("PREEMPT ");
272#endif
273#ifdef CONFIG_SMP
274 printk("SMP");
275#endif
276 printk("\n");
263 notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, SIGSEGV); 277 notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, SIGSEGV);
264 show_regs(regs); 278 show_regs(regs);
265 bust_spinlocks(0); 279 bust_spinlocks(0);
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index 849120e3e28a..7d43c3cd3ef3 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -17,6 +17,12 @@ ENTRY(_start)
17jiffies = jiffies_64; 17jiffies = jiffies_64;
18#endif 18#endif
19 19
20PHDRS {
21 text PT_LOAD FLAGS(5); /* R_E */
22 data PT_LOAD FLAGS(7); /* RWE */
23 note PT_NOTE FLAGS(0); /* ___ */
24}
25
20SECTIONS 26SECTIONS
21{ 27{
22 . = 0x00000000; 28 . = 0x00000000;
@@ -33,6 +39,9 @@ SECTIONS
33 39
34 _etext = .; /* End of text section */ 40 _etext = .; /* End of text section */
35 41
42 NOTES :text :note
43 BUG_TABLE :text
44
36 RODATA 45 RODATA
37 46
38#ifdef CONFIG_SHARED_KERNEL 47#ifdef CONFIG_SHARED_KERNEL
@@ -49,9 +58,6 @@ SECTIONS
49 __stop___ex_table = .; 58 __stop___ex_table = .;
50 } 59 }
51 60
52 NOTES
53 BUG_TABLE
54
55 .data : { /* Data */ 61 .data : { /* Data */
56 DATA_DATA 62 DATA_DATA
57 CONSTRUCTORS 63 CONSTRUCTORS
@@ -91,7 +97,7 @@ SECTIONS
91 __init_begin = .; 97 __init_begin = .;
92 .init.text : { 98 .init.text : {
93 _sinittext = .; 99 _sinittext = .;
94 *(.init.text) 100 INIT_TEXT
95 _einittext = .; 101 _einittext = .;
96 } 102 }
97 /* 103 /*
@@ -99,11 +105,11 @@ SECTIONS
99 * to deal with references from __bug_table 105 * to deal with references from __bug_table
100 */ 106 */
101 .exit.text : { 107 .exit.text : {
102 *(.exit.text) 108 EXIT_TEXT
103 } 109 }
104 110
105 .init.data : { 111 .init.data : {
106 *(.init.data) 112 INIT_DATA
107 } 113 }
108 . = ALIGN(0x100); 114 . = ALIGN(0x100);
109 .init.setup : { 115 .init.setup : {
@@ -150,7 +156,7 @@ SECTIONS
150 156
151 /* Sections to be discarded */ 157 /* Sections to be discarded */
152 /DISCARD/ : { 158 /DISCARD/ : {
153 *(.exit.data) 159 EXIT_DATA
154 *(.exitcall.exit) 160 *(.exitcall.exit)
155 } 161 }
156 162
diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c
index 8d76403fcf89..e41f4008afc5 100644
--- a/arch/s390/lib/spinlock.c
+++ b/arch/s390/lib/spinlock.c
@@ -39,7 +39,7 @@ static inline void _raw_yield_cpu(int cpu)
39 _raw_yield(); 39 _raw_yield();
40} 40}
41 41
42void _raw_spin_lock_wait(raw_spinlock_t *lp, unsigned int pc) 42void _raw_spin_lock_wait(raw_spinlock_t *lp)
43{ 43{
44 int count = spin_retry; 44 int count = spin_retry;
45 unsigned int cpu = ~smp_processor_id(); 45 unsigned int cpu = ~smp_processor_id();
@@ -53,15 +53,36 @@ void _raw_spin_lock_wait(raw_spinlock_t *lp, unsigned int pc)
53 } 53 }
54 if (__raw_spin_is_locked(lp)) 54 if (__raw_spin_is_locked(lp))
55 continue; 55 continue;
56 if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0) { 56 if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0)
57 lp->owner_pc = pc;
58 return; 57 return;
59 }
60 } 58 }
61} 59}
62EXPORT_SYMBOL(_raw_spin_lock_wait); 60EXPORT_SYMBOL(_raw_spin_lock_wait);
63 61
64int _raw_spin_trylock_retry(raw_spinlock_t *lp, unsigned int pc) 62void _raw_spin_lock_wait_flags(raw_spinlock_t *lp, unsigned long flags)
63{
64 int count = spin_retry;
65 unsigned int cpu = ~smp_processor_id();
66
67 local_irq_restore(flags);
68 while (1) {
69 if (count-- <= 0) {
70 unsigned int owner = lp->owner_cpu;
71 if (owner != 0)
72 _raw_yield_cpu(~owner);
73 count = spin_retry;
74 }
75 if (__raw_spin_is_locked(lp))
76 continue;
77 local_irq_disable();
78 if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0)
79 return;
80 local_irq_restore(flags);
81 }
82}
83EXPORT_SYMBOL(_raw_spin_lock_wait_flags);
84
85int _raw_spin_trylock_retry(raw_spinlock_t *lp)
65{ 86{
66 unsigned int cpu = ~smp_processor_id(); 87 unsigned int cpu = ~smp_processor_id();
67 int count; 88 int count;
@@ -69,10 +90,8 @@ int _raw_spin_trylock_retry(raw_spinlock_t *lp, unsigned int pc)
69 for (count = spin_retry; count > 0; count--) { 90 for (count = spin_retry; count > 0; count--) {
70 if (__raw_spin_is_locked(lp)) 91 if (__raw_spin_is_locked(lp))
71 continue; 92 continue;
72 if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0) { 93 if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0)
73 lp->owner_pc = pc;
74 return 1; 94 return 1;
75 }
76 } 95 }
77 return 0; 96 return 0;
78} 97}
diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c
index 394980b05e6f..880b0ebf894b 100644
--- a/arch/s390/mm/extmem.c
+++ b/arch/s390/mm/extmem.c
@@ -83,7 +83,7 @@ struct dcss_segment {
83}; 83};
84 84
85static DEFINE_MUTEX(dcss_lock); 85static DEFINE_MUTEX(dcss_lock);
86static struct list_head dcss_list = LIST_HEAD_INIT(dcss_list); 86static LIST_HEAD(dcss_list);
87static char *segtype_string[] = { "SW", "EW", "SR", "ER", "SN", "EN", "SC", 87static char *segtype_string[] = { "SW", "EW", "SR", "ER", "SN", "EN", "SC",
88 "EW/EN-MIXED" }; 88 "EW/EN-MIXED" };
89 89
diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c
index fb9c5a85aa56..79d13a166a3d 100644
--- a/arch/s390/mm/vmem.c
+++ b/arch/s390/mm/vmem.c
@@ -15,10 +15,6 @@
15#include <asm/setup.h> 15#include <asm/setup.h>
16#include <asm/tlbflush.h> 16#include <asm/tlbflush.h>
17 17
18unsigned long vmalloc_end;
19EXPORT_SYMBOL(vmalloc_end);
20
21static struct page *vmem_map;
22static DEFINE_MUTEX(vmem_mutex); 18static DEFINE_MUTEX(vmem_mutex);
23 19
24struct memory_segment { 20struct memory_segment {
@@ -188,8 +184,8 @@ static int vmem_add_mem_map(unsigned long start, unsigned long size)
188 pte_t pte; 184 pte_t pte;
189 int ret = -ENOMEM; 185 int ret = -ENOMEM;
190 186
191 map_start = vmem_map + PFN_DOWN(start); 187 map_start = VMEM_MAP + PFN_DOWN(start);
192 map_end = vmem_map + PFN_DOWN(start + size); 188 map_end = VMEM_MAP + PFN_DOWN(start + size);
193 189
194 start_addr = (unsigned long) map_start & PAGE_MASK; 190 start_addr = (unsigned long) map_start & PAGE_MASK;
195 end_addr = PFN_ALIGN((unsigned long) map_end); 191 end_addr = PFN_ALIGN((unsigned long) map_end);
@@ -240,10 +236,10 @@ static int vmem_add_mem(unsigned long start, unsigned long size)
240{ 236{
241 int ret; 237 int ret;
242 238
243 ret = vmem_add_range(start, size); 239 ret = vmem_add_mem_map(start, size);
244 if (ret) 240 if (ret)
245 return ret; 241 return ret;
246 return vmem_add_mem_map(start, size); 242 return vmem_add_range(start, size);
247} 243}
248 244
249/* 245/*
@@ -254,7 +250,7 @@ static int insert_memory_segment(struct memory_segment *seg)
254{ 250{
255 struct memory_segment *tmp; 251 struct memory_segment *tmp;
256 252
257 if (PFN_DOWN(seg->start + seg->size) > max_pfn || 253 if (seg->start + seg->size >= VMALLOC_START ||
258 seg->start + seg->size < seg->start) 254 seg->start + seg->size < seg->start)
259 return -ERANGE; 255 return -ERANGE;
260 256
@@ -357,17 +353,15 @@ out:
357 353
358/* 354/*
359 * map whole physical memory to virtual memory (identity mapping) 355 * map whole physical memory to virtual memory (identity mapping)
356 * we reserve enough space in the vmalloc area for vmemmap to hotplug
357 * additional memory segments.
360 */ 358 */
361void __init vmem_map_init(void) 359void __init vmem_map_init(void)
362{ 360{
363 unsigned long map_size;
364 int i; 361 int i;
365 362
366 map_size = ALIGN(max_low_pfn, MAX_ORDER_NR_PAGES) * sizeof(struct page); 363 BUILD_BUG_ON((unsigned long)VMEM_MAP + VMEM_MAP_SIZE > VMEM_MAP_MAX);
367 vmalloc_end = PFN_ALIGN(VMALLOC_END_INIT) - PFN_ALIGN(map_size); 364 NODE_DATA(0)->node_mem_map = VMEM_MAP;
368 vmem_map = (struct page *) vmalloc_end;
369 NODE_DATA(0)->node_mem_map = vmem_map;
370
371 for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) 365 for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++)
372 vmem_add_mem(memory_chunk[i].addr, memory_chunk[i].size); 366 vmem_add_mem(memory_chunk[i].addr, memory_chunk[i].size);
373} 367}
@@ -382,7 +376,7 @@ static int __init vmem_convert_memory_chunk(void)
382 int i; 376 int i;
383 377
384 mutex_lock(&vmem_mutex); 378 mutex_lock(&vmem_mutex);
385 for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) { 379 for (i = 0; i < MEMORY_CHUNKS; i++) {
386 if (!memory_chunk[i].size) 380 if (!memory_chunk[i].size)
387 continue; 381 continue;
388 seg = kzalloc(sizeof(*seg), GFP_KERNEL); 382 seg = kzalloc(sizeof(*seg), GFP_KERNEL);
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 496d635f89b2..1cd9c8fd927d 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -6,8 +6,7 @@
6mainmenu "Linux/SuperH Kernel Configuration" 6mainmenu "Linux/SuperH Kernel Configuration"
7 7
8config SUPERH 8config SUPERH
9 bool 9 def_bool y
10 default y
11 select EMBEDDED 10 select EMBEDDED
12 help 11 help
13 The SuperH is a RISC processor targeted for use in embedded systems 12 The SuperH is a RISC processor targeted for use in embedded systems
@@ -15,36 +14,36 @@ config SUPERH
15 gaming console. The SuperH port has a home page at 14 gaming console. The SuperH port has a home page at
16 <http://www.linux-sh.org/>. 15 <http://www.linux-sh.org/>.
17 16
17config SUPERH32
18 def_bool !SUPERH64
19
20config SUPERH64
21 def_bool y if CPU_SH5
22
18config RWSEM_GENERIC_SPINLOCK 23config RWSEM_GENERIC_SPINLOCK
19 bool 24 def_bool y
20 default y
21 25
22config RWSEM_XCHGADD_ALGORITHM 26config RWSEM_XCHGADD_ALGORITHM
23 bool 27 bool
24 28
25config GENERIC_BUG 29config GENERIC_BUG
26 def_bool y 30 def_bool y
27 depends on BUG 31 depends on BUG && SUPERH32
28 32
29config GENERIC_FIND_NEXT_BIT 33config GENERIC_FIND_NEXT_BIT
30 bool 34 def_bool y
31 default y
32 35
33config GENERIC_HWEIGHT 36config GENERIC_HWEIGHT
34 bool 37 def_bool y
35 default y
36 38
37config GENERIC_HARDIRQS 39config GENERIC_HARDIRQS
38 bool 40 def_bool y
39 default y
40 41
41config GENERIC_IRQ_PROBE 42config GENERIC_IRQ_PROBE
42 bool 43 def_bool y
43 default y
44 44
45config GENERIC_CALIBRATE_DELAY 45config GENERIC_CALIBRATE_DELAY
46 bool 46 def_bool y
47 default y
48 47
49config GENERIC_IOMAP 48config GENERIC_IOMAP
50 bool 49 bool
@@ -75,20 +74,16 @@ config ARCH_MAY_HAVE_PC_FDC
75 bool 74 bool
76 75
77config STACKTRACE_SUPPORT 76config STACKTRACE_SUPPORT
78 bool 77 def_bool y
79 default y
80 78
81config LOCKDEP_SUPPORT 79config LOCKDEP_SUPPORT
82 bool 80 def_bool y
83 default y
84 81
85config ARCH_HAS_ILOG2_U32 82config ARCH_HAS_ILOG2_U32
86 bool 83 def_bool n
87 default n
88 84
89config ARCH_HAS_ILOG2_U64 85config ARCH_HAS_ILOG2_U64
90 bool 86 def_bool n
91 default n
92 87
93config ARCH_NO_VIRT_TO_BUS 88config ARCH_NO_VIRT_TO_BUS
94 def_bool y 89 def_bool y
@@ -97,110 +92,234 @@ source "init/Kconfig"
97 92
98menu "System type" 93menu "System type"
99 94
100source "arch/sh/mm/Kconfig" 95#
96# Processor families
97#
98config CPU_SH2
99 bool
101 100
102menu "Processor features" 101config CPU_SH2A
102 bool
103 select CPU_SH2
104
105config CPU_SH3
106 bool
107 select CPU_HAS_INTEVT
108 select CPU_HAS_SR_RB
109
110config CPU_SH4
111 bool
112 select CPU_HAS_INTEVT
113 select CPU_HAS_SR_RB
114 select CPU_HAS_PTEA if !CPU_SH4A || CPU_SHX2
115 select CPU_HAS_FPU if !CPU_SH4AL_DSP
116
117config CPU_SH4A
118 bool
119 select CPU_SH4
120
121config CPU_SH4AL_DSP
122 bool
123 select CPU_SH4A
124 select CPU_HAS_DSP
125
126config CPU_SH5
127 bool
128 select CPU_HAS_FPU
129
130config CPU_SHX2
131 bool
132
133config CPU_SHX3
134 bool
103 135
104choice 136choice
105 prompt "Endianess selection" 137 prompt "Processor sub-type selection"
106 default CPU_LITTLE_ENDIAN
107 help
108 Some SuperH machines can be configured for either little or big
109 endian byte order. These modes require different kernels.
110 138
111config CPU_LITTLE_ENDIAN 139#
112 bool "Little Endian" 140# Processor subtypes
141#
113 142
114config CPU_BIG_ENDIAN 143# SH-2 Processor Support
115 bool "Big Endian"
116 144
117endchoice 145config CPU_SUBTYPE_SH7619
146 bool "Support SH7619 processor"
147 select CPU_SH2
148
149# SH-2A Processor Support
150
151config CPU_SUBTYPE_SH7203
152 bool "Support SH7203 processor"
153 select CPU_SH2A
154 select CPU_HAS_FPU
155
156config CPU_SUBTYPE_SH7206
157 bool "Support SH7206 processor"
158 select CPU_SH2A
118 159
119config SH_FPU 160config CPU_SUBTYPE_SH7263
120 bool "FPU support" 161 bool "Support SH7263 processor"
121 depends on CPU_HAS_FPU 162 select CPU_SH2A
122 default y 163 select CPU_HAS_FPU
164
165# SH-3 Processor Support
166
167config CPU_SUBTYPE_SH7705
168 bool "Support SH7705 processor"
169 select CPU_SH3
170
171config CPU_SUBTYPE_SH7706
172 bool "Support SH7706 processor"
173 select CPU_SH3
123 help 174 help
124 Selecting this option will enable support for SH processors that 175 Select SH7706 if you have a 133 Mhz SH-3 HD6417706 CPU.
125 have FPU units (ie, SH77xx).
126 176
127 This option must be set in order to enable the FPU. 177config CPU_SUBTYPE_SH7707
178 bool "Support SH7707 processor"
179 select CPU_SH3
180 help
181 Select SH7707 if you have a 60 Mhz SH-3 HD6417707 CPU.
128 182
129config SH_FPU_EMU 183config CPU_SUBTYPE_SH7708
130 bool "FPU emulation support" 184 bool "Support SH7708 processor"
131 depends on !SH_FPU && EXPERIMENTAL 185 select CPU_SH3
132 default n
133 help 186 help
134 Selecting this option will enable support for software FPU emulation. 187 Select SH7708 if you have a 60 Mhz SH-3 HD6417708S or
135 Most SH-3 users will want to say Y here, whereas most SH-4 users will 188 if you have a 100 Mhz SH-3 HD6417708R CPU.
136 want to say N.
137 189
138config SH_DSP 190config CPU_SUBTYPE_SH7709
139 bool "DSP support" 191 bool "Support SH7709 processor"
140 depends on CPU_HAS_DSP 192 select CPU_SH3
141 default y
142 help 193 help
143 Selecting this option will enable support for SH processors that 194 Select SH7709 if you have a 80 Mhz SH-3 HD6417709 CPU.
144 have DSP units (ie, SH2-DSP, SH3-DSP, and SH4AL-DSP).
145 195
146 This option must be set in order to enable the DSP. 196config CPU_SUBTYPE_SH7710
197 bool "Support SH7710 processor"
198 select CPU_SH3
199 select CPU_HAS_DSP
200 help
201 Select SH7710 if you have a SH3-DSP SH7710 CPU.
147 202
148config SH_ADC 203config CPU_SUBTYPE_SH7712
149 bool "ADC support" 204 bool "Support SH7712 processor"
150 depends on CPU_SH3 205 select CPU_SH3
151 default y 206 select CPU_HAS_DSP
152 help 207 help
153 Selecting this option will allow the Linux kernel to use SH3 on-chip 208 Select SH7712 if you have a SH3-DSP SH7712 CPU.
154 ADC module.
155 209
156 If unsure, say N. 210config CPU_SUBTYPE_SH7720
211 bool "Support SH7720 processor"
212 select CPU_SH3
213 select CPU_HAS_DSP
214 help
215 Select SH7720 if you have a SH3-DSP SH7720 CPU.
157 216
158config SH_STORE_QUEUES 217config CPU_SUBTYPE_SH7721
159 bool "Support for Store Queues" 218 bool "Support SH7721 processor"
160 depends on CPU_SH4 219 select CPU_SH3
220 select CPU_HAS_DSP
161 help 221 help
162 Selecting this option will enable an in-kernel API for manipulating 222 Select SH7721 if you have a SH3-DSP SH7721 CPU.
163 the store queues integrated in the SH-4 processors.
164 223
165config SPECULATIVE_EXECUTION 224# SH-4 Processor Support
166 bool "Speculative subroutine return" 225
167 depends on CPU_SUBTYPE_SH7780 && EXPERIMENTAL 226config CPU_SUBTYPE_SH7750
227 bool "Support SH7750 processor"
228 select CPU_SH4
168 help 229 help
169 This enables support for a speculative instruction fetch for 230 Select SH7750 if you have a 200 Mhz SH-4 HD6417750 CPU.
170 subroutine return. There are various pitfalls associated with
171 this, as outlined in the SH7780 hardware manual.
172 231
173 If unsure, say N. 232config CPU_SUBTYPE_SH7091
233 bool "Support SH7091 processor"
234 select CPU_SH4
235 help
236 Select SH7091 if you have an SH-4 based Sega device (such as
237 the Dreamcast, Naomi, and Naomi 2).
174 238
175config CPU_HAS_INTEVT 239config CPU_SUBTYPE_SH7750R
176 bool 240 bool "Support SH7750R processor"
241 select CPU_SH4
177 242
178config CPU_HAS_MASKREG_IRQ 243config CPU_SUBTYPE_SH7750S
179 bool 244 bool "Support SH7750S processor"
245 select CPU_SH4
180 246
181config CPU_HAS_IPR_IRQ 247config CPU_SUBTYPE_SH7751
182 bool 248 bool "Support SH7751 processor"
249 select CPU_SH4
250 help
251 Select SH7751 if you have a 166 Mhz SH-4 HD6417751 CPU,
252 or if you have a HD6417751R CPU.
183 253
184config CPU_HAS_SR_RB 254config CPU_SUBTYPE_SH7751R
185 bool 255 bool "Support SH7751R processor"
256 select CPU_SH4
257
258config CPU_SUBTYPE_SH7760
259 bool "Support SH7760 processor"
260 select CPU_SH4
261
262config CPU_SUBTYPE_SH4_202
263 bool "Support SH4-202 processor"
264 select CPU_SH4
265
266# SH-4A Processor Support
267
268config CPU_SUBTYPE_SH7763
269 bool "Support SH7763 processor"
270 select CPU_SH4A
186 help 271 help
187 This will enable the use of SR.RB register bank usage. Processors 272 Select SH7763 if you have a SH4A SH7763(R5S77631) CPU.
188 that are lacking this bit must have another method in place for
189 accomplishing what is taken care of by the banked registers.
190 273
191 See <file:Documentation/sh/register-banks.txt> for further 274config CPU_SUBTYPE_SH7770
192 information on SR.RB and register banking in the kernel in general. 275 bool "Support SH7770 processor"
276 select CPU_SH4A
193 277
194config CPU_HAS_PTEA 278config CPU_SUBTYPE_SH7780
195 bool 279 bool "Support SH7780 processor"
280 select CPU_SH4A
196 281
197config CPU_HAS_DSP 282config CPU_SUBTYPE_SH7785
198 bool 283 bool "Support SH7785 processor"
284 select CPU_SH4A
285 select CPU_SHX2
286 select ARCH_SPARSEMEM_ENABLE
287 select SYS_SUPPORTS_NUMA
199 288
200config CPU_HAS_FPU 289config CPU_SUBTYPE_SHX3
201 bool 290 bool "Support SH-X3 processor"
291 select CPU_SH4A
292 select CPU_SHX3
293 select ARCH_SPARSEMEM_ENABLE
294 select SYS_SUPPORTS_NUMA
295 select SYS_SUPPORTS_SMP
202 296
203endmenu 297# SH4AL-DSP Processor Support
298
299config CPU_SUBTYPE_SH7343
300 bool "Support SH7343 processor"
301 select CPU_SH4AL_DSP
302
303config CPU_SUBTYPE_SH7722
304 bool "Support SH7722 processor"
305 select CPU_SH4AL_DSP
306 select CPU_SHX2
307 select ARCH_SPARSEMEM_ENABLE
308 select SYS_SUPPORTS_NUMA
309
310# SH-5 Processor Support
311
312config CPU_SUBTYPE_SH5_101
313 bool "Support SH5-101 processor"
314 select CPU_SH5
315
316config CPU_SUBTYPE_SH5_103
317 bool "Support SH5-103 processor"
318
319endchoice
320
321source "arch/sh/mm/Kconfig"
322source "arch/sh/Kconfig.cpu"
204 323
205menu "Board support" 324menu "Board support"
206 325
@@ -321,13 +440,6 @@ config SH_SECUREEDGE5410
321 This includes both the OEM SecureEdge products as well as the 440 This includes both the OEM SecureEdge products as well as the
322 SME product line. 441 SME product line.
323 442
324config SH_HS7751RVOIP
325 bool "HS7751RVOIP"
326 depends on CPU_SUBTYPE_SH7751R
327 help
328 Select HS7751RVOIP if configuring for a Renesas Technology
329 Sales VoIP board.
330
331config SH_7710VOIPGW 443config SH_7710VOIPGW
332 bool "SH7710-VOIP-GW" 444 bool "SH7710-VOIP-GW"
333 depends on CPU_SUBTYPE_SH7710 445 depends on CPU_SUBTYPE_SH7710
@@ -343,6 +455,14 @@ config SH_RTS7751R2D
343 Select RTS7751R2D if configuring for a Renesas Technology 455 Select RTS7751R2D if configuring for a Renesas Technology
344 Sales SH-Graphics board. 456 Sales SH-Graphics board.
345 457
458config SH_SDK7780
459 bool "SDK7780R3"
460 depends on CPU_SUBTYPE_SH7780
461 select SYS_SUPPORTS_PCI
462 help
463 Select SDK7780 if configuring for a Renesas SH7780 SDK7780R3
464 evaluation board.
465
346config SH_HIGHLANDER 466config SH_HIGHLANDER
347 bool "Highlander" 467 bool "Highlander"
348 depends on CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785 468 depends on CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785
@@ -399,41 +519,47 @@ config SH_MAGIC_PANEL_R2
399 help 519 help
400 Select Magic Panel R2 if configuring for Magic Panel R2. 520 Select Magic Panel R2 if configuring for Magic Panel R2.
401 521
522config SH_CAYMAN
523 bool "Hitachi Cayman"
524 depends on CPU_SUBTYPE_SH5_101 || CPU_SUBTYPE_SH5_103
525 select SYS_SUPPORTS_PCI
526
402endmenu 527endmenu
403 528
404source "arch/sh/boards/renesas/hs7751rvoip/Kconfig"
405source "arch/sh/boards/renesas/rts7751r2d/Kconfig" 529source "arch/sh/boards/renesas/rts7751r2d/Kconfig"
406source "arch/sh/boards/renesas/r7780rp/Kconfig" 530source "arch/sh/boards/renesas/r7780rp/Kconfig"
531source "arch/sh/boards/renesas/sdk7780/Kconfig"
407source "arch/sh/boards/magicpanelr2/Kconfig" 532source "arch/sh/boards/magicpanelr2/Kconfig"
408 533
409menu "Timer and clock configuration" 534menu "Timer and clock configuration"
410 535
411config SH_TMU 536config SH_TMU
412 bool "TMU timer support" 537 def_bool y
538 prompt "TMU timer support"
413 depends on CPU_SH3 || CPU_SH4 539 depends on CPU_SH3 || CPU_SH4
414 select GENERIC_TIME 540 select GENERIC_TIME
415 select GENERIC_CLOCKEVENTS 541 select GENERIC_CLOCKEVENTS
416 default y
417 help 542 help
418 This enables the use of the TMU as the system timer. 543 This enables the use of the TMU as the system timer.
419 544
420config SH_CMT 545config SH_CMT
421 bool "CMT timer support" 546 def_bool y
547 prompt "CMT timer support"
422 depends on CPU_SH2 548 depends on CPU_SH2
423 default y
424 help 549 help
425 This enables the use of the CMT as the system timer. 550 This enables the use of the CMT as the system timer.
426 551
427config SH_MTU2 552config SH_MTU2
428 bool "MTU2 timer support" 553 def_bool n
554 prompt "MTU2 timer support"
429 depends on CPU_SH2A 555 depends on CPU_SH2A
430 default n
431 help 556 help
432 This enables the use of the MTU2 as the system timer. 557 This enables the use of the MTU2 as the system timer.
433 558
434config SH_TIMER_IRQ 559config SH_TIMER_IRQ
435 int 560 int
436 default "28" if CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785 561 default "28" if CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785 || \
562 CPU_SUBTYPE_SH7763
437 default "86" if CPU_SUBTYPE_SH7619 563 default "86" if CPU_SUBTYPE_SH7619
438 default "140" if CPU_SUBTYPE_SH7206 564 default "140" if CPU_SUBTYPE_SH7206
439 default "16" 565 default "16"
@@ -445,7 +571,8 @@ config SH_PCLK_FREQ
445 default "32000000" if CPU_SUBTYPE_SH7722 571 default "32000000" if CPU_SUBTYPE_SH7722
446 default "33333333" if CPU_SUBTYPE_SH7770 || \ 572 default "33333333" if CPU_SUBTYPE_SH7770 || \
447 CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7705 || \ 573 CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7705 || \
448 CPU_SUBTYPE_SH7206 574 CPU_SUBTYPE_SH7203 || CPU_SUBTYPE_SH7206 || \
575 CPU_SUBTYPE_SH7263
449 default "60000000" if CPU_SUBTYPE_SH7751 || CPU_SUBTYPE_SH7751R 576 default "60000000" if CPU_SUBTYPE_SH7751 || CPU_SUBTYPE_SH7751R
450 default "66000000" if CPU_SUBTYPE_SH4_202 577 default "66000000" if CPU_SUBTYPE_SH4_202
451 default "50000000" 578 default "50000000"
@@ -456,7 +583,7 @@ config SH_PCLK_FREQ
456 583
457config SH_CLK_MD 584config SH_CLK_MD
458 int "CPU Mode Pin Setting" 585 int "CPU Mode Pin Setting"
459 depends on CPU_SUBTYPE_SH7619 || CPU_SUBTYPE_SH7206 586 depends on CPU_SH2
460 default 6 if CPU_SUBTYPE_SH7206 587 default 6 if CPU_SUBTYPE_SH7206
461 default 5 if CPU_SUBTYPE_SH7619 588 default 5 if CPU_SUBTYPE_SH7619
462 default 0 589 default 0
@@ -490,9 +617,8 @@ source "arch/sh/drivers/Kconfig"
490endmenu 617endmenu
491 618
492config ISA_DMA_API 619config ISA_DMA_API
493 bool 620 def_bool y
494 depends on SH_MPC1211 621 depends on SH_MPC1211
495 default y
496 622
497menu "Kernel features" 623menu "Kernel features"
498 624
@@ -570,7 +696,7 @@ source "kernel/Kconfig.preempt"
570 696
571config GUSA 697config GUSA
572 def_bool y 698 def_bool y
573 depends on !SMP 699 depends on !SMP && SUPERH32
574 help 700 help
575 This enables support for gUSA (general UserSpace Atomicity). 701 This enables support for gUSA (general UserSpace Atomicity).
576 This is the default implementation for both UP and non-ll/sc 702 This is the default implementation for both UP and non-ll/sc
@@ -582,6 +708,16 @@ config GUSA
582 This should only be disabled for special cases where alternate 708 This should only be disabled for special cases where alternate
583 atomicity implementations exist. 709 atomicity implementations exist.
584 710
711config GUSA_RB
712 bool "Implement atomic operations by roll-back (gRB) (EXPERIMENTAL)"
713 depends on GUSA && CPU_SH3 || (CPU_SH4 && !CPU_SH4A)
714 help
715 Enabling this option will allow the kernel to implement some
716 atomic operations using a software implemention of load-locked/
717 store-conditional (LLSC). On machines which do not have hardware
718 LLSC, this should be more efficient than the other alternative of
719 disabling insterrupts around the atomic sequence.
720
585endmenu 721endmenu
586 722
587menu "Boot options" 723menu "Boot options"
diff --git a/arch/sh/Kconfig.cpu b/arch/sh/Kconfig.cpu
new file mode 100644
index 000000000000..d850184d0694
--- /dev/null
+++ b/arch/sh/Kconfig.cpu
@@ -0,0 +1,115 @@
1menu "Processor features"
2
3choice
4 prompt "Endianess selection"
5 default CPU_LITTLE_ENDIAN
6 help
7 Some SuperH machines can be configured for either little or big
8 endian byte order. These modes require different kernels.
9
10config CPU_LITTLE_ENDIAN
11 bool "Little Endian"
12
13config CPU_BIG_ENDIAN
14 bool "Big Endian"
15
16endchoice
17
18config SH_FPU
19 def_bool y
20 prompt "FPU support"
21 depends on CPU_HAS_FPU
22 help
23 Selecting this option will enable support for SH processors that
24 have FPU units (ie, SH77xx).
25
26 This option must be set in order to enable the FPU.
27
28config SH64_FPU_DENORM_FLUSH
29 bool "Flush floating point denorms to zero"
30 depends on SH_FPU && SUPERH64
31
32config SH_FPU_EMU
33 def_bool n
34 prompt "FPU emulation support"
35 depends on !SH_FPU && EXPERIMENTAL
36 help
37 Selecting this option will enable support for software FPU emulation.
38 Most SH-3 users will want to say Y here, whereas most SH-4 users will
39 want to say N.
40
41config SH_DSP
42 def_bool y
43 prompt "DSP support"
44 depends on CPU_HAS_DSP
45 help
46 Selecting this option will enable support for SH processors that
47 have DSP units (ie, SH2-DSP, SH3-DSP, and SH4AL-DSP).
48
49 This option must be set in order to enable the DSP.
50
51config SH_ADC
52 def_bool y
53 prompt "ADC support"
54 depends on CPU_SH3
55 help
56 Selecting this option will allow the Linux kernel to use SH3 on-chip
57 ADC module.
58
59 If unsure, say N.
60
61config SH_STORE_QUEUES
62 bool "Support for Store Queues"
63 depends on CPU_SH4
64 help
65 Selecting this option will enable an in-kernel API for manipulating
66 the store queues integrated in the SH-4 processors.
67
68config SPECULATIVE_EXECUTION
69 bool "Speculative subroutine return"
70 depends on CPU_SUBTYPE_SH7780 && EXPERIMENTAL
71 help
72 This enables support for a speculative instruction fetch for
73 subroutine return. There are various pitfalls associated with
74 this, as outlined in the SH7780 hardware manual.
75
76 If unsure, say N.
77
78config SH64_USER_MISALIGNED_FIXUP
79 def_bool y
80 prompt "Fixup misaligned loads/stores occurring in user mode"
81 depends on SUPERH64
82
83config SH64_ID2815_WORKAROUND
84 bool "Include workaround for SH5-101 cut2 silicon defect ID2815"
85 depends on CPU_SUBTYPE_SH5_101
86
87config CPU_HAS_INTEVT
88 bool
89
90config CPU_HAS_MASKREG_IRQ
91 bool
92
93config CPU_HAS_IPR_IRQ
94 bool
95
96config CPU_HAS_SR_RB
97 bool
98 help
99 This will enable the use of SR.RB register bank usage. Processors
100 that are lacking this bit must have another method in place for
101 accomplishing what is taken care of by the banked registers.
102
103 See <file:Documentation/sh/register-banks.txt> for further
104 information on SR.RB and register banking in the kernel in general.
105
106config CPU_HAS_PTEA
107 bool
108
109config CPU_HAS_DSP
110 bool
111
112config CPU_HAS_FPU
113 bool
114
115endmenu
diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug
index 722da6851f56..f7c716166ce8 100644
--- a/arch/sh/Kconfig.debug
+++ b/arch/sh/Kconfig.debug
@@ -1,8 +1,7 @@
1menu "Kernel hacking" 1menu "Kernel hacking"
2 2
3config TRACE_IRQFLAGS_SUPPORT 3config TRACE_IRQFLAGS_SUPPORT
4 bool 4 def_bool y
5 default y
6 5
7source "lib/Kconfig.debug" 6source "lib/Kconfig.debug"
8 7
@@ -30,12 +29,13 @@ config EARLY_SCIF_CONSOLE
30config EARLY_SCIF_CONSOLE_PORT 29config EARLY_SCIF_CONSOLE_PORT
31 hex 30 hex
32 depends on EARLY_SCIF_CONSOLE 31 depends on EARLY_SCIF_CONSOLE
33 default "0xffe00000" if CPU_SUBTYPE_SH7780 32 default "0xffe00000" if CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7763
34 default "0xffea0000" if CPU_SUBTYPE_SH7785 33 default "0xffea0000" if CPU_SUBTYPE_SH7785
35 default "0xfffe9800" if CPU_SUBTYPE_SH7206 34 default "0xfffe8000" if CPU_SUBTYPE_SH7203
35 default "0xfffe9800" if CPU_SUBTYPE_SH7206 || CPU_SUBTYPE_SH7263
36 default "0xf8420000" if CPU_SUBTYPE_SH7619 36 default "0xf8420000" if CPU_SUBTYPE_SH7619
37 default "0xa4400000" if CPU_SUBTYPE_SH7712 || CPU_SUBTYPE_SH7705 37 default "0xa4400000" if CPU_SUBTYPE_SH7712 || CPU_SUBTYPE_SH7705
38 default "0xa4430000" if CPU_SUBTYPE_SH7720 38 default "0xa4430000" if CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721
39 default "0xffc30000" if CPU_SUBTYPE_SHX3 39 default "0xffc30000" if CPU_SUBTYPE_SHX3
40 default "0xffe80000" if CPU_SH4 40 default "0xffe80000" if CPU_SH4
41 default "0x00000000" 41 default "0x00000000"
@@ -62,7 +62,7 @@ config DEBUG_BOOTMEM
62 62
63config DEBUG_STACKOVERFLOW 63config DEBUG_STACKOVERFLOW
64 bool "Check for stack overflows" 64 bool "Check for stack overflows"
65 depends on DEBUG_KERNEL 65 depends on DEBUG_KERNEL && SUPERH32
66 help 66 help
67 This option will cause messages to be printed if free stack space 67 This option will cause messages to be printed if free stack space
68 drops below a certain limit. 68 drops below a certain limit.
@@ -88,7 +88,7 @@ config 4KSTACKS
88 88
89config IRQSTACKS 89config IRQSTACKS
90 bool "Use separate kernel stacks when processing interrupts" 90 bool "Use separate kernel stacks when processing interrupts"
91 depends on DEBUG_KERNEL 91 depends on DEBUG_KERNEL && SUPERH32
92 help 92 help
93 If you say Y here the kernel will use separate kernel stacks 93 If you say Y here the kernel will use separate kernel stacks
94 for handling hard and soft interrupts. This can help avoid 94 for handling hard and soft interrupts. This can help avoid
@@ -119,19 +119,19 @@ config COMPILE_OPTIONS
119 depends on MORE_COMPILE_OPTIONS 119 depends on MORE_COMPILE_OPTIONS
120 120
121config KGDB_NMI 121config KGDB_NMI
122 bool "Enter KGDB on NMI" 122 def_bool n
123 default n 123 prompt "Enter KGDB on NMI"
124 124
125config SH_KGDB_CONSOLE 125config SH_KGDB_CONSOLE
126 bool "Console messages through GDB" 126 def_bool n
127 prompt "Console messages through GDB"
127 depends on !SERIAL_SH_SCI_CONSOLE && SERIAL_SH_SCI=y 128 depends on !SERIAL_SH_SCI_CONSOLE && SERIAL_SH_SCI=y
128 select SERIAL_CORE_CONSOLE 129 select SERIAL_CORE_CONSOLE
129 default n
130 130
131config KGDB_SYSRQ 131config KGDB_SYSRQ
132 bool "Allow SysRq 'G' to enter KGDB" 132 def_bool y
133 prompt "Allow SysRq 'G' to enter KGDB"
133 depends on MAGIC_SYSRQ 134 depends on MAGIC_SYSRQ
134 default y
135 135
136comment "Serial port setup" 136comment "Serial port setup"
137 137
@@ -174,4 +174,29 @@ endchoice
174 174
175endmenu 175endmenu
176 176
177if SUPERH64
178
179config SH64_PROC_ASIDS
180 bool "Debug: report ASIDs through /proc/asids"
181 depends on PROC_FS
182
183config SH64_SR_WATCH
184 bool "Debug: set SR.WATCH to enable hardware watchpoints and trace"
185
186config POOR_MANS_STRACE
187 bool "Debug: enable rudimentary strace facility"
188 help
189 This option allows system calls to be traced to the console. It also
190 aids in detecting kernel stack underflow. It is useful for debugging
191 early-userland problems (e.g. init incurring fatal exceptions.)
192
193config SH_ALPHANUMERIC
194 bool "Enable debug outputs to on-board alphanumeric display"
195 depends on SH_CAYMAN
196
197config SH_NO_BSS_INIT
198 bool "Avoid zeroing BSS (to speed-up startup on suitable platforms)"
199
200endif
201
177endmenu 202endmenu
diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index e189fae8b60c..17fc36186bf4 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -1,17 +1,13 @@
1# $Id: Makefile,v 1.35 2004/04/15 03:39:20 sugioka Exp $
2# 1#
3# This file is subject to the terms and conditions of the GNU General Public 2# arch/sh/Makefile
4# License. See the file "COPYING" in the main directory of this archive
5# for more details.
6# 3#
7# Copyright (C) 1999 Kaz Kojima 4# Copyright (C) 1999 Kaz Kojima
8# Copyright (C) 2002, 2003, 2004 Paul Mundt 5# Copyright (C) 2002, 2003, 2004 Paul Mundt
9# Copyright (C) 2002 M. R. Brown 6# Copyright (C) 2002 M. R. Brown
10# 7#
11# This file is included by the global makefile so that you can add your own 8# This file is subject to the terms and conditions of the GNU General Public
12# architecture-specific flags and dependencies. Remember to do have actions 9# License. See the file "COPYING" in the main directory of this archive
13# for "archclean" and "archdep" for cleaning up and making dependencies for 10# for more details.
14# this architecture
15# 11#
16isa-y := any 12isa-y := any
17isa-$(CONFIG_SH_DSP) := sh 13isa-$(CONFIG_SH_DSP) := sh
@@ -21,13 +17,9 @@ isa-$(CONFIG_CPU_SH3) := sh3
21isa-$(CONFIG_CPU_SH4) := sh4 17isa-$(CONFIG_CPU_SH4) := sh4
22isa-$(CONFIG_CPU_SH4A) := sh4a 18isa-$(CONFIG_CPU_SH4A) := sh4a
23isa-$(CONFIG_CPU_SH4AL_DSP) := sh4al 19isa-$(CONFIG_CPU_SH4AL_DSP) := sh4al
24 20isa-$(CONFIG_CPU_SH5) := shmedia
25isa-$(CONFIG_SH_DSP) := $(isa-y)-dsp 21isa-$(CONFIG_SH_DSP) := $(isa-y)-dsp
26 22
27ifndef CONFIG_MMU
28isa-y := $(isa-y)-nommu
29endif
30
31ifndef CONFIG_SH_DSP 23ifndef CONFIG_SH_DSP
32ifndef CONFIG_SH_FPU 24ifndef CONFIG_SH_FPU
33isa-y := $(isa-y)-nofpu 25isa-y := $(isa-y)-nofpu
@@ -44,6 +36,7 @@ cflags-$(CONFIG_CPU_SH4) := $(call cc-option,-m4,) \
44 $(call cc-option,-mno-implicit-fp,-m4-nofpu) 36 $(call cc-option,-mno-implicit-fp,-m4-nofpu)
45cflags-$(CONFIG_CPU_SH4A) += $(call cc-option,-m4a,) \ 37cflags-$(CONFIG_CPU_SH4A) += $(call cc-option,-m4a,) \
46 $(call cc-option,-m4a-nofpu,) 38 $(call cc-option,-m4a-nofpu,)
39cflags-$(CONFIG_CPU_SH5) := $(call cc-option,-m5-32media-nofpu,)
47 40
48cflags-$(CONFIG_CPU_BIG_ENDIAN) += -mb 41cflags-$(CONFIG_CPU_BIG_ENDIAN) += -mb
49cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -ml 42cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -ml
@@ -66,22 +59,27 @@ cflags-y += $(isaflags-y) -ffreestanding
66cflags-$(CONFIG_MORE_COMPILE_OPTIONS) += \ 59cflags-$(CONFIG_MORE_COMPILE_OPTIONS) += \
67 $(shell echo $(CONFIG_COMPILE_OPTIONS) | sed -e 's/"//g') 60 $(shell echo $(CONFIG_COMPILE_OPTIONS) | sed -e 's/"//g')
68 61
69OBJCOPYFLAGS := -O binary -R .note -R .note.gnu.build-id -R .comment -R .stab -R .stabstr -S 62OBJCOPYFLAGS := -O binary -R .note -R .note.gnu.build-id -R .comment \
63 -R .stab -R .stabstr -S
70 64
71# 65# Give the various platforms the opportunity to set default image types
72# arch/sh/defconfig doesn't reflect any real hardware, and as such should 66defaultimage-$(CONFIG_SUPERH32) := zImage
73# never be used by anyone. Use a board-specific defconfig that has a
74# reasonable chance of being current instead.
75#
76KBUILD_DEFCONFIG := r7780rp_defconfig
77 67
78KBUILD_IMAGE := arch/sh/boot/zImage 68# Set some sensible Kbuild defaults
69KBUILD_DEFCONFIG := r7780mp_defconfig
70KBUILD_IMAGE := $(defaultimage-y)
79 71
80# 72#
81# Choosing incompatible machines durings configuration will result in 73# Choosing incompatible machines durings configuration will result in
82# error messages during linking. 74# error messages during linking.
83# 75#
84LDFLAGS_vmlinux += -e _stext 76ifdef CONFIG_SUPERH32
77LDFLAGS_vmlinux += -e _stext
78else
79LDFLAGS_vmlinux += --defsym phys_stext=_stext-$(CONFIG_PAGE_OFFSET) \
80 --defsym phys_stext_shmedia=phys_stext+1 \
81 -e phys_stext_shmedia
82endif
85 83
86ifdef CONFIG_CPU_LITTLE_ENDIAN 84ifdef CONFIG_CPU_LITTLE_ENDIAN
87LDFLAGS_vmlinux += --defsym 'jiffies=jiffies_64' 85LDFLAGS_vmlinux += --defsym 'jiffies=jiffies_64'
@@ -94,7 +92,9 @@ endif
94KBUILD_CFLAGS += -pipe $(cflags-y) 92KBUILD_CFLAGS += -pipe $(cflags-y)
95KBUILD_AFLAGS += $(cflags-y) 93KBUILD_AFLAGS += $(cflags-y)
96 94
97head-y := arch/sh/kernel/head.o arch/sh/kernel/init_task.o 95head-y := arch/sh/kernel/init_task.o
96head-$(CONFIG_SUPERH32) += arch/sh/kernel/head_32.o
97head-$(CONFIG_SUPERH64) += arch/sh/kernel/head_64.o
98 98
99LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) 99LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
100 100
@@ -112,11 +112,11 @@ machdir-$(CONFIG_SH_DREAMCAST) += dreamcast
112machdir-$(CONFIG_SH_MPC1211) += mpc1211 112machdir-$(CONFIG_SH_MPC1211) += mpc1211
113machdir-$(CONFIG_SH_SH03) += sh03 113machdir-$(CONFIG_SH_SH03) += sh03
114machdir-$(CONFIG_SH_SECUREEDGE5410) += snapgear 114machdir-$(CONFIG_SH_SECUREEDGE5410) += snapgear
115machdir-$(CONFIG_SH_HS7751RVOIP) += renesas/hs7751rvoip
116machdir-$(CONFIG_SH_RTS7751R2D) += renesas/rts7751r2d 115machdir-$(CONFIG_SH_RTS7751R2D) += renesas/rts7751r2d
117machdir-$(CONFIG_SH_7751_SYSTEMH) += renesas/systemh 116machdir-$(CONFIG_SH_7751_SYSTEMH) += renesas/systemh
118machdir-$(CONFIG_SH_EDOSK7705) += renesas/edosk7705 117machdir-$(CONFIG_SH_EDOSK7705) += renesas/edosk7705
119machdir-$(CONFIG_SH_HIGHLANDER) += renesas/r7780rp 118machdir-$(CONFIG_SH_HIGHLANDER) += renesas/r7780rp
119machdir-$(CONFIG_SH_SDK7780) += renesas/sdk7780
120machdir-$(CONFIG_SH_7710VOIPGW) += renesas/sh7710voipgw 120machdir-$(CONFIG_SH_7710VOIPGW) += renesas/sh7710voipgw
121machdir-$(CONFIG_SH_X3PROTO) += renesas/x3proto 121machdir-$(CONFIG_SH_X3PROTO) += renesas/x3proto
122machdir-$(CONFIG_SH_SH4202_MICRODEV) += superh/microdev 122machdir-$(CONFIG_SH_SH4202_MICRODEV) += superh/microdev
@@ -127,6 +127,7 @@ machdir-$(CONFIG_SH_7206_SOLUTION_ENGINE) += se/7206
127machdir-$(CONFIG_SH_7619_SOLUTION_ENGINE) += se/7619 127machdir-$(CONFIG_SH_7619_SOLUTION_ENGINE) += se/7619
128machdir-$(CONFIG_SH_LBOX_RE2) += lboxre2 128machdir-$(CONFIG_SH_LBOX_RE2) += lboxre2
129machdir-$(CONFIG_SH_MAGIC_PANEL_R2) += magicpanelr2 129machdir-$(CONFIG_SH_MAGIC_PANEL_R2) += magicpanelr2
130machdir-$(CONFIG_SH_CAYMAN) += cayman
130 131
131incdir-y := $(notdir $(machdir-y)) 132incdir-y := $(notdir $(machdir-y))
132 133
@@ -137,22 +138,22 @@ endif
137 138
138# Companion chips 139# Companion chips
139core-$(CONFIG_HD6446X_SERIES) += arch/sh/cchips/hd6446x/ 140core-$(CONFIG_HD6446X_SERIES) += arch/sh/cchips/hd6446x/
140core-$(CONFIG_MFD_SM501) += arch/sh/cchips/voyagergx/
141 141
142cpuincdir-$(CONFIG_CPU_SH2) := cpu-sh2 142cpuincdir-$(CONFIG_CPU_SH2) := cpu-sh2
143cpuincdir-$(CONFIG_CPU_SH2A) := cpu-sh2a 143cpuincdir-$(CONFIG_CPU_SH2A) := cpu-sh2a
144cpuincdir-$(CONFIG_CPU_SH3) := cpu-sh3 144cpuincdir-$(CONFIG_CPU_SH3) := cpu-sh3
145cpuincdir-$(CONFIG_CPU_SH4) := cpu-sh4 145cpuincdir-$(CONFIG_CPU_SH4) := cpu-sh4
146cpuincdir-$(CONFIG_CPU_SH5) := cpu-sh5
146 147
147libs-y := arch/sh/lib/ $(libs-y) $(LIBGCC) 148libs-$(CONFIG_SUPERH32) := arch/sh/lib/ $(libs-y)
149libs-$(CONFIG_SUPERH64) := arch/sh/lib64/ $(libs-y)
150libs-y += $(LIBGCC)
148 151
149drivers-y += arch/sh/drivers/ 152drivers-y += arch/sh/drivers/
150drivers-$(CONFIG_OPROFILE) += arch/sh/oprofile/ 153drivers-$(CONFIG_OPROFILE) += arch/sh/oprofile/
151 154
152boot := arch/sh/boot 155boot := arch/sh/boot
153 156
154CPPFLAGS_vmlinux.lds := -traditional
155
156incdir-prefix := $(srctree)/include/asm-sh/ 157incdir-prefix := $(srctree)/include/asm-sh/
157 158
158# Update machine arch and proc symlinks if something which affects 159# Update machine arch and proc symlinks if something which affects
@@ -196,29 +197,61 @@ include/asm-sh/.mach: $(wildcard include/config/sh/*.h) \
196 done 197 done
197 @touch $@ 198 @touch $@
198 199
199archprepare: include/asm-sh/.cpu include/asm-sh/.mach maketools
200
201PHONY += maketools FORCE 200PHONY += maketools FORCE
201
202maketools: include/linux/version.h FORCE 202maketools: include/linux/version.h FORCE
203 $(Q)$(MAKE) $(build)=arch/sh/tools include/asm-sh/machtypes.h 203 $(Q)$(MAKE) $(build)=arch/sh/tools include/asm-sh/machtypes.h
204 204
205all: zImage 205all: $(KBUILD_IMAGE)
206 206
207zImage uImage uImage.srec vmlinux.srec: vmlinux 207zImage uImage uImage.srec vmlinux.srec: vmlinux
208 $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ 208 $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
209 209
210compressed: zImage 210compressed: zImage
211 211
212archprepare: include/asm-sh/.cpu include/asm-sh/.mach maketools \
213 arch/sh/lib64/syscalltab.h
214
212archclean: 215archclean:
213 $(Q)$(MAKE) $(clean)=$(boot) 216 $(Q)$(MAKE) $(clean)=$(boot)
214 217
215CLEAN_FILES += include/asm-sh/machtypes.h \
216 include/asm-sh/cpu include/asm-sh/.cpu \
217 include/asm-sh/mach include/asm-sh/.mach
218
219define archhelp 218define archhelp
220 @echo '* zImage - Compressed kernel image' 219 @echo '* zImage - Compressed kernel image'
221 @echo ' vmlinux.srec - Create an ELF S-record' 220 @echo ' vmlinux.srec - Create an ELF S-record'
222 @echo ' uImage - Create a bootable image for U-Boot' 221 @echo ' uImage - Create a bootable image for U-Boot'
223 @echo ' uImage.srec - Create an S-record for U-Boot' 222 @echo ' uImage.srec - Create an S-record for U-Boot'
224endef 223endef
224
225define filechk_gen-syscalltab
226 (set -e; \
227 echo "/*"; \
228 echo " * DO NOT MODIFY."; \
229 echo " *"; \
230 echo " * This file was generated by arch/sh/Makefile"; \
231 echo " * Any changes will be reverted at build time."; \
232 echo " */"; \
233 echo ""; \
234 echo "#ifndef __SYSCALLTAB_H"; \
235 echo "#define __SYSCALLTAB_H"; \
236 echo ""; \
237 echo "#include <linux/kernel.h>"; \
238 echo ""; \
239 echo "struct syscall_info {"; \
240 echo " const char *name;"; \
241 echo "} syscall_info_table[] = {"; \
242 sed -e '/^.*\.long /!d;s// { "/;s/\(\([^/]*\)\/\)\{1\}.*/\2/; \
243 s/[ \t]*$$//g;s/$$/" },/;s/\("\)sys_/\1/g'; \
244 echo "};"; \
245 echo ""; \
246 echo "#define NUM_SYSCALL_INFO_ENTRIES ARRAY_SIZE(syscall_info_table)";\
247 echo ""; \
248 echo "#endif /* __SYSCALLTAB_H */" )
249endef
250
251arch/sh/lib64/syscalltab.h: arch/sh/kernel/syscalls_64.S
252 $(call filechk,gen-syscalltab)
253
254CLEAN_FILES += arch/sh/lib64/syscalltab.h \
255 include/asm-sh/machtypes.h \
256 include/asm-sh/cpu include/asm-sh/.cpu \
257 include/asm-sh/mach include/asm-sh/.mach
diff --git a/arch/sh/boards/cayman/Makefile b/arch/sh/boards/cayman/Makefile
new file mode 100644
index 000000000000..489a8f867368
--- /dev/null
+++ b/arch/sh/boards/cayman/Makefile
@@ -0,0 +1,5 @@
1#
2# Makefile for the Hitachi Cayman specific parts of the kernel
3#
4obj-y := setup.o irq.o
5obj-$(CONFIG_HEARTBEAT) += led.o
diff --git a/arch/sh64/mach-cayman/irq.c b/arch/sh/boards/cayman/irq.c
index aaad36d37d1f..30ec7bebfaf1 100644
--- a/arch/sh64/mach-cayman/irq.c
+++ b/arch/sh/boards/cayman/irq.c
@@ -1,24 +1,26 @@
1/* 1/*
2 * This file is subject to the terms and conditions of the GNU General Public 2 * arch/sh/mach-cayman/irq.c - SH-5 Cayman Interrupt Support
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * arch/sh64/kernel/irq_cayman.c
7 *
8 * SH-5 Cayman Interrupt Support
9 * 3 *
10 * This file handles the board specific parts of the Cayman interrupt system 4 * This file handles the board specific parts of the Cayman interrupt system
11 * 5 *
12 * Copyright (C) 2002 Stuart Menefy 6 * Copyright (C) 2002 Stuart Menefy
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
13 */ 11 */
14 12#include <linux/io.h>
15#include <asm/irq.h>
16#include <asm/page.h>
17#include <asm/io.h>
18#include <linux/irq.h> 13#include <linux/irq.h>
19#include <linux/interrupt.h> 14#include <linux/interrupt.h>
20#include <linux/signal.h> 15#include <linux/signal.h>
21#include <asm/cayman.h> 16#include <asm/cpu/irq.h>
17#include <asm/page.h>
18
19/* Setup for the SMSC FDC37C935 / LAN91C100FD */
20#define SMSC_IRQ IRQ_IRL1
21
22/* Setup for PCI Bus 2, which transmits interrupts via the EPLD */
23#define PCI2_IRQ IRQ_IRL3
22 24
23unsigned long epld_virt; 25unsigned long epld_virt;
24 26
diff --git a/arch/sh64/mach-cayman/led.c b/arch/sh/boards/cayman/led.c
index b4e122fd9502..a808eac4ecd6 100644
--- a/arch/sh64/mach-cayman/led.c
+++ b/arch/sh/boards/cayman/led.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/sh64/mach-cayman/led.c 2 * arch/sh/boards/cayman/led.c
3 * 3 *
4 * Copyright (C) 2002 Stuart Menefy <stuart.menefy@st.com> 4 * Copyright (C) 2002 Stuart Menefy <stuart.menefy@st.com>
5 * 5 *
diff --git a/arch/sh64/mach-cayman/setup.c b/arch/sh/boards/cayman/setup.c
index 726c520d7eb9..8c9fa472d8f5 100644
--- a/arch/sh64/mach-cayman/setup.c
+++ b/arch/sh/boards/cayman/setup.c
@@ -1,28 +1,19 @@
1/* 1/*
2 * This file is subject to the terms and conditions of the GNU General Public 2 * arch/sh/mach-cayman/setup.c
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * arch/sh64/mach-cayman/setup.c
7 * 3 *
8 * SH5 Cayman support 4 * SH5 Cayman support
9 * 5 *
10 * This file handles the architecture-dependent parts of initialization 6 * Copyright (C) 2002 David J. Mckay & Benedict Gaster
7 * Copyright (C) 2003 - 2007 Paul Mundt
11 * 8 *
12 * Copyright David J. Mckay. 9 * This file is subject to the terms and conditions of the GNU General Public
13 * Needs major work! 10 * License. See the file "COPYING" in the main directory of this archive
14 * 11 * for more details.
15 * benedict.gaster@superh.com: 3rd May 2002
16 * Added support for ramdisk, removing statically linked romfs at the same time.
17 *
18 * lethal@linux-sh.org: 15th May 2003
19 * Use the generic procfs cpuinfo interface, just return a valid board name.
20 */ 12 */
21#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/io.h>
22#include <linux/kernel.h> 15#include <linux/kernel.h>
23#include <asm/platform.h> 16#include <asm/cpu/irq.h>
24#include <asm/irq.h>
25#include <asm/io.h>
26 17
27/* 18/*
28 * Platform Dependent Interrupt Priorities. 19 * Platform Dependent Interrupt Priorities.
@@ -96,42 +87,6 @@
96 87
97unsigned long smsc_superio_virt; 88unsigned long smsc_superio_virt;
98 89
99/*
100 * Platform dependent structures: maps and parms block.
101 */
102struct resource io_resources[] = {
103 /* To be updated with external devices */
104};
105
106struct resource kram_resources[] = {
107 /* These must be last in the array */
108 { .name = "Kernel code", .start = 0, .end = 0 },
109 /* These must be last in the array */
110 { .name = "Kernel data", .start = 0, .end = 0 }
111};
112
113struct resource xram_resources[] = {
114 /* To be updated with external devices */
115};
116
117struct resource rom_resources[] = {
118 /* To be updated with external devices */
119};
120
121struct sh64_platform platform_parms = {
122 .readonly_rootfs = 1,
123 .initial_root_dev = 0x0100,
124 .loader_type = 1,
125 .io_res_p = io_resources,
126 .io_res_count = ARRAY_SIZE(io_resources),
127 .kram_res_p = kram_resources,
128 .kram_res_count = ARRAY_SIZE(kram_resources),
129 .xram_res_p = xram_resources,
130 .xram_res_count = ARRAY_SIZE(xram_resources),
131 .rom_res_p = rom_resources,
132 .rom_res_count = ARRAY_SIZE(rom_resources),
133};
134
135int platform_int_priority[NR_INTC_IRQS] = { 90int platform_int_priority[NR_INTC_IRQS] = {
136 IR0, IR1, IR2, IR3, PCA, PCB, PCC, PCD, /* IRQ 0- 7 */ 91 IR0, IR1, IR2, IR3, PCA, PCB, PCC, PCD, /* IRQ 0- 7 */
137 RES, RES, RES, RES, SER, ERR, PW3, PW2, /* IRQ 8-15 */ 92 RES, RES, RES, RES, SER, ERR, PW3, PW2, /* IRQ 8-15 */
@@ -210,30 +165,23 @@ static int __init smsc_superio_setup(void)
210 165
211 return 0; 166 return 0;
212} 167}
213
214/* This is grotty, but, because kernel is always referenced on the link line
215 * before any devices, this is safe.
216 */
217__initcall(smsc_superio_setup); 168__initcall(smsc_superio_setup);
218 169
219void __init platform_setup(void) 170static void __iomem *cayman_ioport_map(unsigned long port, unsigned int len)
220{
221 /* Cayman platform leaves the decision to head.S, for now */
222 platform_parms.fpu_flags = fpu_in_use;
223}
224
225void __init platform_monitor(void)
226{ 171{
227 /* Nothing yet .. */ 172 if (port < 0x400) {
228} 173 extern unsigned long smsc_superio_virt;
174 return (void __iomem *)((port << 2) | smsc_superio_virt);
175 }
229 176
230void __init platform_reserve(void) 177 return (void __iomem *)port;
231{
232 /* Nothing yet .. */
233} 178}
234 179
235const char *get_system_type(void) 180extern void init_cayman_irq(void);
236{
237 return "Hitachi Cayman";
238}
239 181
182static struct sh_machine_vector mv_cayman __initmv = {
183 .mv_name = "Hitachi Cayman",
184 .mv_nr_irqs = 64,
185 .mv_ioport_map = cayman_ioport_map,
186 .mv_init_irq = init_cayman_irq,
187};
diff --git a/arch/sh/boards/dreamcast/irq.c b/arch/sh/boards/dreamcast/irq.c
index 5bf01f86c20c..9d0673a9092a 100644
--- a/arch/sh/boards/dreamcast/irq.c
+++ b/arch/sh/boards/dreamcast/irq.c
@@ -136,7 +136,7 @@ int systemasic_irq_demux(int irq)
136 emr = EMR_BASE + (level << 4) + (level << 2); 136 emr = EMR_BASE + (level << 4) + (level << 2);
137 esr = ESR_BASE + (level << 2); 137 esr = ESR_BASE + (level << 2);
138 138
139 /* Mask the ESR to filter any spurious, unwanted interrtupts */ 139 /* Mask the ESR to filter any spurious, unwanted interrupts */
140 status = inl(esr); 140 status = inl(esr);
141 status &= inl(emr); 141 status &= inl(emr);
142 142
diff --git a/arch/sh/boards/dreamcast/setup.c b/arch/sh/boards/dreamcast/setup.c
index 8799df6e866a..2581c8cd5df7 100644
--- a/arch/sh/boards/dreamcast/setup.c
+++ b/arch/sh/boards/dreamcast/setup.c
@@ -33,9 +33,6 @@ extern void aica_time_init(void);
33extern int gapspci_init(void); 33extern int gapspci_init(void);
34extern int systemasic_irq_demux(int); 34extern int systemasic_irq_demux(int);
35 35
36void *dreamcast_consistent_alloc(struct device *, size_t, dma_addr_t *, gfp_t);
37int dreamcast_consistent_free(struct device *, size_t, void *, dma_addr_t);
38
39static void __init dreamcast_setup(char **cmdline_p) 36static void __init dreamcast_setup(char **cmdline_p)
40{ 37{
41 int i; 38 int i;
@@ -64,9 +61,4 @@ static struct sh_machine_vector mv_dreamcast __initmv = {
64 .mv_name = "Sega Dreamcast", 61 .mv_name = "Sega Dreamcast",
65 .mv_setup = dreamcast_setup, 62 .mv_setup = dreamcast_setup,
66 .mv_irq_demux = systemasic_irq_demux, 63 .mv_irq_demux = systemasic_irq_demux,
67
68#ifdef CONFIG_PCI
69 .mv_consistent_alloc = dreamcast_consistent_alloc,
70 .mv_consistent_free = dreamcast_consistent_free,
71#endif
72}; 64};
diff --git a/arch/sh/boards/landisk/gio.c b/arch/sh/boards/landisk/gio.c
index a37643d002b2..17025080db35 100644
--- a/arch/sh/boards/landisk/gio.c
+++ b/arch/sh/boards/landisk/gio.c
@@ -121,7 +121,7 @@ static int gio_ioctl(struct inode *inode, struct file *filp,
121 return 0; 121 return 0;
122} 122}
123 123
124static struct file_operations gio_fops = { 124static const struct file_operations gio_fops = {
125 .owner = THIS_MODULE, 125 .owner = THIS_MODULE,
126 .open = gio_open, /* open */ 126 .open = gio_open, /* open */
127 .release = gio_close, /* release */ 127 .release = gio_close, /* release */
diff --git a/arch/sh/boards/renesas/hs7751rvoip/Kconfig b/arch/sh/boards/renesas/hs7751rvoip/Kconfig
deleted file mode 100644
index 1743be477be5..000000000000
--- a/arch/sh/boards/renesas/hs7751rvoip/Kconfig
+++ /dev/null
@@ -1,12 +0,0 @@
1if SH_HS7751RVOIP
2
3menu "HS7751RVoIP options"
4
5config HS7751RVOIP_CODEC
6 bool "Support VoIP Codec section"
7 help
8 Selecting this option will support CODEC section.
9
10endmenu
11
12endif
diff --git a/arch/sh/boards/renesas/hs7751rvoip/Makefile b/arch/sh/boards/renesas/hs7751rvoip/Makefile
deleted file mode 100644
index e626377c55ee..000000000000
--- a/arch/sh/boards/renesas/hs7751rvoip/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
1#
2# Makefile for the HS7751RVoIP specific parts of the kernel
3#
4
5obj-y := setup.o io.o irq.o
6
7obj-$(CONFIG_PCI) += pci.o
8
diff --git a/arch/sh/boards/renesas/hs7751rvoip/io.c b/arch/sh/boards/renesas/hs7751rvoip/io.c
deleted file mode 100644
index bb9aa0d62852..000000000000
--- a/arch/sh/boards/renesas/hs7751rvoip/io.c
+++ /dev/null
@@ -1,283 +0,0 @@
1/*
2 * linux/arch/sh/boards/renesas/hs7751rvoip/io.c
3 *
4 * Copyright (C) 2001 Ian da Silva, Jeremy Siegel
5 * Based largely on io_se.c.
6 *
7 * I/O routine for Renesas Technology sales HS7751RVoIP
8 *
9 * Initial version only to support LAN access; some
10 * placeholder code from io_hs7751rvoip.c left in with the
11 * expectation of later SuperIO and PCMCIA access.
12 */
13#include <linux/kernel.h>
14#include <linux/types.h>
15#include <linux/module.h>
16#include <linux/pci.h>
17#include <asm/io.h>
18#include <asm/hs7751rvoip.h>
19#include <asm/addrspace.h>
20
21extern void *area6_io8_base; /* Area 6 8bit I/O Base address */
22extern void *area5_io16_base; /* Area 5 16bit I/O Base address */
23
24/*
25 * The 7751R HS7751RVoIP uses the built-in PCI controller (PCIC)
26 * of the 7751R processor, and has a SuperIO accessible via the PCI.
27 * The board also includes a PCMCIA controller on its memory bus,
28 * like the other Solution Engine boards.
29 */
30
31#define CODEC_IO_BASE 0x1000
32#define CODEC_IOMAP(a) ((unsigned long)area6_io8_base + ((a) - CODEC_IO_BASE))
33
34static inline unsigned long port2adr(unsigned int port)
35{
36 if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
37 if (port == 0x3f6)
38 return ((unsigned long)area5_io16_base + 0x0c);
39 else
40 return ((unsigned long)area5_io16_base + 0x800 +
41 ((port-0x1f0) << 1));
42 else
43 maybebadio((unsigned long)port);
44 return port;
45}
46
47/* The 7751R HS7751RVoIP seems to have everything hooked */
48/* up pretty normally (nothing on high-bytes only...) so this */
49/* shouldn't be needed */
50static inline int shifted_port(unsigned long port)
51{
52 /* For IDE registers, value is not shifted */
53 if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
54 return 0;
55 else
56 return 1;
57}
58
59#if defined(CONFIG_HS7751RVOIP_CODEC)
60#define codec_port(port) \
61 ((CODEC_IO_BASE <= (port)) && ((port) < (CODEC_IO_BASE + 0x20)))
62#else
63#define codec_port(port) (0)
64#endif
65
66/*
67 * General outline: remap really low stuff [eventually] to SuperIO,
68 * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
69 * is mapped through the PCI IO window. Stuff with high bits (PXSEG)
70 * should be way beyond the window, and is used w/o translation for
71 * compatibility.
72 */
73unsigned char hs7751rvoip_inb(unsigned long port)
74{
75 if (PXSEG(port))
76 return ctrl_inb(port);
77 else if (codec_port(port))
78 return ctrl_inb(CODEC_IOMAP(port));
79 else if (is_pci_ioaddr(port) || shifted_port(port))
80 return ctrl_inb(pci_ioaddr(port));
81 else
82 return ctrl_inw(port2adr(port)) & 0xff;
83}
84
85unsigned char hs7751rvoip_inb_p(unsigned long port)
86{
87 unsigned char v;
88
89 if (PXSEG(port))
90 v = ctrl_inb(port);
91 else if (codec_port(port))
92 v = ctrl_inb(CODEC_IOMAP(port));
93 else if (is_pci_ioaddr(port) || shifted_port(port))
94 v = ctrl_inb(pci_ioaddr(port));
95 else
96 v = ctrl_inw(port2adr(port)) & 0xff;
97 ctrl_delay();
98 return v;
99}
100
101unsigned short hs7751rvoip_inw(unsigned long port)
102{
103 if (PXSEG(port))
104 return ctrl_inw(port);
105 else if (is_pci_ioaddr(port) || shifted_port(port))
106 return ctrl_inw(pci_ioaddr(port));
107 else
108 maybebadio(port);
109 return 0;
110}
111
112unsigned int hs7751rvoip_inl(unsigned long port)
113{
114 if (PXSEG(port))
115 return ctrl_inl(port);
116 else if (is_pci_ioaddr(port) || shifted_port(port))
117 return ctrl_inl(pci_ioaddr(port));
118 else
119 maybebadio(port);
120 return 0;
121}
122
123void hs7751rvoip_outb(unsigned char value, unsigned long port)
124{
125
126 if (PXSEG(port))
127 ctrl_outb(value, port);
128 else if (codec_port(port))
129 ctrl_outb(value, CODEC_IOMAP(port));
130 else if (is_pci_ioaddr(port) || shifted_port(port))
131 ctrl_outb(value, pci_ioaddr(port));
132 else
133 ctrl_outb(value, port2adr(port));
134}
135
136void hs7751rvoip_outb_p(unsigned char value, unsigned long port)
137{
138 if (PXSEG(port))
139 ctrl_outb(value, port);
140 else if (codec_port(port))
141 ctrl_outb(value, CODEC_IOMAP(port));
142 else if (is_pci_ioaddr(port) || shifted_port(port))
143 ctrl_outb(value, pci_ioaddr(port));
144 else
145 ctrl_outw(value, port2adr(port));
146
147 ctrl_delay();
148}
149
150void hs7751rvoip_outw(unsigned short value, unsigned long port)
151{
152 if (PXSEG(port))
153 ctrl_outw(value, port);
154 else if (is_pci_ioaddr(port) || shifted_port(port))
155 ctrl_outw(value, pci_ioaddr(port));
156 else
157 maybebadio(port);
158}
159
160void hs7751rvoip_outl(unsigned int value, unsigned long port)
161{
162 if (PXSEG(port))
163 ctrl_outl(value, port);
164 else if (is_pci_ioaddr(port) || shifted_port(port))
165 ctrl_outl(value, pci_ioaddr(port));
166 else
167 maybebadio(port);
168}
169
170void hs7751rvoip_insb(unsigned long port, void *addr, unsigned long count)
171{
172 u8 *buf = addr;
173
174 if (PXSEG(port))
175 while (count--)
176 *buf++ = ctrl_inb(port);
177 else if (codec_port(port))
178 while (count--)
179 *buf++ = ctrl_inb(CODEC_IOMAP(port));
180 else if (is_pci_ioaddr(port) || shifted_port(port)) {
181 volatile u8 *bp = (volatile u8 *)pci_ioaddr(port);
182
183 while (count--)
184 *buf++ = *bp;
185 } else {
186 volatile u16 *p = (volatile u16 *)port2adr(port);
187
188 while (count--)
189 *buf++ = *p & 0xff;
190 }
191}
192
193void hs7751rvoip_insw(unsigned long port, void *addr, unsigned long count)
194{
195 volatile u16 *p;
196 u16 *buf = addr;
197
198 if (PXSEG(port))
199 p = (volatile u16 *)port;
200 else if (is_pci_ioaddr(port) || shifted_port(port))
201 p = (volatile u16 *)pci_ioaddr(port);
202 else
203 p = (volatile u16 *)port2adr(port);
204 while (count--)
205 *buf++ = *p;
206}
207
208void hs7751rvoip_insl(unsigned long port, void *addr, unsigned long count)
209{
210
211 if (is_pci_ioaddr(port) || shifted_port(port)) {
212 volatile u32 *p = (volatile u32 *)pci_ioaddr(port);
213 u32 *buf = addr;
214
215 while (count--)
216 *buf++ = *p;
217 } else
218 maybebadio(port);
219}
220
221void hs7751rvoip_outsb(unsigned long port, const void *addr, unsigned long count)
222{
223 const u8 *buf = addr;
224
225 if (PXSEG(port))
226 while (count--)
227 ctrl_outb(*buf++, port);
228 else if (codec_port(port))
229 while (count--)
230 ctrl_outb(*buf++, CODEC_IOMAP(port));
231 else if (is_pci_ioaddr(port) || shifted_port(port)) {
232 volatile u8 *bp = (volatile u8 *)pci_ioaddr(port);
233
234 while (count--)
235 *bp = *buf++;
236 } else {
237 volatile u16 *p = (volatile u16 *)port2adr(port);
238
239 while (count--)
240 *p = *buf++;
241 }
242}
243
244void hs7751rvoip_outsw(unsigned long port, const void *addr, unsigned long count)
245{
246 volatile u16 *p;
247 const u16 *buf = addr;
248
249 if (PXSEG(port))
250 p = (volatile u16 *)port;
251 else if (is_pci_ioaddr(port) || shifted_port(port))
252 p = (volatile u16 *)pci_ioaddr(port);
253 else
254 p = (volatile u16 *)port2adr(port);
255
256 while (count--)
257 *p = *buf++;
258}
259
260void hs7751rvoip_outsl(unsigned long port, const void *addr, unsigned long count)
261{
262 const u32 *buf = addr;
263
264 if (is_pci_ioaddr(port) || shifted_port(port)) {
265 volatile u32 *p = (volatile u32 *)pci_ioaddr(port);
266
267 while (count--)
268 *p = *buf++;
269 } else
270 maybebadio(port);
271}
272
273void __iomem *hs7751rvoip_ioport_map(unsigned long port, unsigned int size)
274{
275 if (PXSEG(port))
276 return (void __iomem *)port;
277 else if (unlikely(codec_port(port) && (size == 1)))
278 return (void __iomem *)CODEC_IOMAP(port);
279 else if (is_pci_ioaddr(port))
280 return (void __iomem *)pci_ioaddr(port);
281
282 return (void __iomem *)port2adr(port);
283}
diff --git a/arch/sh/boards/renesas/hs7751rvoip/irq.c b/arch/sh/boards/renesas/hs7751rvoip/irq.c
deleted file mode 100644
index e55c6686b21f..000000000000
--- a/arch/sh/boards/renesas/hs7751rvoip/irq.c
+++ /dev/null
@@ -1,116 +0,0 @@
1/*
2 * linux/arch/sh/boards/renesas/hs7751rvoip/irq.c
3 *
4 * Copyright (C) 2000 Kazumoto Kojima
5 *
6 * Renesas Technology Sales HS7751RVoIP Support.
7 *
8 * Modified for HS7751RVoIP by
9 * Atom Create Engineering Co., Ltd. 2002.
10 * Lineo uSolutions, Inc. 2003.
11 */
12
13#include <linux/init.h>
14#include <linux/irq.h>
15#include <linux/interrupt.h>
16#include <asm/io.h>
17#include <asm/irq.h>
18#include <asm/hs7751rvoip.h>
19
20static int mask_pos[] = {8, 9, 10, 11, 12, 13, 0, 1, 2, 3, 4, 5, 6, 7};
21
22static void enable_hs7751rvoip_irq(unsigned int irq);
23static void disable_hs7751rvoip_irq(unsigned int irq);
24
25/* shutdown is same as "disable" */
26#define shutdown_hs7751rvoip_irq disable_hs7751rvoip_irq
27
28static void ack_hs7751rvoip_irq(unsigned int irq);
29static void end_hs7751rvoip_irq(unsigned int irq);
30
31static unsigned int startup_hs7751rvoip_irq(unsigned int irq)
32{
33 enable_hs7751rvoip_irq(irq);
34 return 0; /* never anything pending */
35}
36
37static void disable_hs7751rvoip_irq(unsigned int irq)
38{
39 unsigned short val;
40 unsigned short mask = 0xffff ^ (0x0001 << mask_pos[irq]);
41
42 /* Set the priority in IPR to 0 */
43 val = ctrl_inw(IRLCNTR3);
44 val &= mask;
45 ctrl_outw(val, IRLCNTR3);
46}
47
48static void enable_hs7751rvoip_irq(unsigned int irq)
49{
50 unsigned short val;
51 unsigned short value = (0x0001 << mask_pos[irq]);
52
53 /* Set priority in IPR back to original value */
54 val = ctrl_inw(IRLCNTR3);
55 val |= value;
56 ctrl_outw(val, IRLCNTR3);
57}
58
59static void ack_hs7751rvoip_irq(unsigned int irq)
60{
61 disable_hs7751rvoip_irq(irq);
62}
63
64static void end_hs7751rvoip_irq(unsigned int irq)
65{
66 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
67 enable_hs7751rvoip_irq(irq);
68}
69
70static struct hw_interrupt_type hs7751rvoip_irq_type = {
71 .typename = "HS7751RVoIP IRQ",
72 .startup = startup_hs7751rvoip_irq,
73 .shutdown = shutdown_hs7751rvoip_irq,
74 .enable = enable_hs7751rvoip_irq,
75 .disable = disable_hs7751rvoip_irq,
76 .ack = ack_hs7751rvoip_irq,
77 .end = end_hs7751rvoip_irq,
78};
79
80static void make_hs7751rvoip_irq(unsigned int irq)
81{
82 disable_irq_nosync(irq);
83 irq_desc[irq].chip = &hs7751rvoip_irq_type;
84 disable_hs7751rvoip_irq(irq);
85}
86
87/*
88 * Initialize IRQ setting
89 */
90void __init init_hs7751rvoip_IRQ(void)
91{
92 int i;
93
94 /* IRL0=ON HOOK1
95 * IRL1=OFF HOOK1
96 * IRL2=ON HOOK2
97 * IRL3=OFF HOOK2
98 * IRL4=Ringing Detection
99 * IRL5=CODEC
100 * IRL6=Ethernet
101 * IRL7=Ethernet Hub
102 * IRL8=USB Communication
103 * IRL9=USB Connection
104 * IRL10=USB DMA
105 * IRL11=CF Card
106 * IRL12=PCMCIA
107 * IRL13=PCI Slot
108 */
109 ctrl_outw(0x9876, IRLCNTR1);
110 ctrl_outw(0xdcba, IRLCNTR2);
111 ctrl_outw(0x0050, IRLCNTR4);
112 ctrl_outw(0x4321, IRLCNTR5);
113
114 for (i=0; i<14; i++)
115 make_hs7751rvoip_irq(i);
116}
diff --git a/arch/sh/boards/renesas/hs7751rvoip/pci.c b/arch/sh/boards/renesas/hs7751rvoip/pci.c
deleted file mode 100644
index 1c0ddee30d21..000000000000
--- a/arch/sh/boards/renesas/hs7751rvoip/pci.c
+++ /dev/null
@@ -1,149 +0,0 @@
1/*
2 * linux/arch/sh/boards/renesas/hs7751rvoip/pci.c
3 *
4 * Author: Ian DaSilva (idasilva@mvista.com)
5 *
6 * Highly leveraged from pci-bigsur.c, written by Dustin McIntire.
7 *
8 * May be copied or modified under the terms of the GNU General Public
9 * License. See linux/COPYING for more information.
10 *
11 * PCI initialization for the Renesas SH7751R HS7751RVoIP board
12 */
13
14#include <linux/kernel.h>
15#include <linux/types.h>
16#include <linux/init.h>
17#include <linux/delay.h>
18#include <linux/pci.h>
19#include <linux/module.h>
20
21#include <asm/io.h>
22#include "../../../drivers/pci/pci-sh7751.h"
23#include <asm/hs7751rvoip/hs7751rvoip.h>
24
25#define PCIMCR_MRSET_OFF 0xBFFFFFFF
26#define PCIMCR_RFSH_OFF 0xFFFFFFFB
27
28/*
29 * Only long word accesses of the PCIC's internal local registers and the
30 * configuration registers from the CPU is supported.
31 */
32#define PCIC_WRITE(x,v) writel((v), PCI_REG(x))
33#define PCIC_READ(x) readl(PCI_REG(x))
34
35/*
36 * Description: This function sets up and initializes the pcic, sets
37 * up the BARS, maps the DRAM into the address space etc, etc.
38 */
39int __init pcibios_init_platform(void)
40{
41 unsigned long bcr1, wcr1, wcr2, wcr3, mcr;
42 unsigned short bcr2, bcr3;
43
44 /*
45 * Initialize the slave bus controller on the pcic. The values used
46 * here should not be hardcoded, but they should be taken from the bsc
47 * on the processor, to make this function as generic as possible.
48 * (i.e. Another sbc may usr different SDRAM timing settings -- in order
49 * for the pcic to work, its settings need to be exactly the same.)
50 */
51 bcr1 = (*(volatile unsigned long *)(SH7751_BCR1));
52 bcr2 = (*(volatile unsigned short *)(SH7751_BCR2));
53 bcr3 = (*(volatile unsigned short *)(SH7751_BCR3));
54 wcr1 = (*(volatile unsigned long *)(SH7751_WCR1));
55 wcr2 = (*(volatile unsigned long *)(SH7751_WCR2));
56 wcr3 = (*(volatile unsigned long *)(SH7751_WCR3));
57 mcr = (*(volatile unsigned long *)(SH7751_MCR));
58
59 bcr1 = bcr1 | 0x00080000; /* Enable Bit 19, BREQEN */
60 (*(volatile unsigned long *)(SH7751_BCR1)) = bcr1;
61
62 bcr1 = bcr1 | 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */
63 PCIC_WRITE(SH7751_PCIBCR1, bcr1); /* PCIC BCR1 */
64 PCIC_WRITE(SH7751_PCIBCR2, bcr2); /* PCIC BCR2 */
65 PCIC_WRITE(SH7751_PCIBCR3, bcr3); /* PCIC BCR3 */
66 PCIC_WRITE(SH7751_PCIWCR1, wcr1); /* PCIC WCR1 */
67 PCIC_WRITE(SH7751_PCIWCR2, wcr2); /* PCIC WCR2 */
68 PCIC_WRITE(SH7751_PCIWCR3, wcr3); /* PCIC WCR3 */
69 mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF;
70 PCIC_WRITE(SH7751_PCIMCR, mcr); /* PCIC MCR */
71
72 /* Enable all interrupts, so we know what to fix */
73 PCIC_WRITE(SH7751_PCIINTM, 0x0000c3ff);
74 PCIC_WRITE(SH7751_PCIAINTM, 0x0000380f);
75
76 /* Set up standard PCI config registers */
77 PCIC_WRITE(SH7751_PCICONF1, 0xFB900047); /* Bus Master, Mem & I/O access */
78 PCIC_WRITE(SH7751_PCICONF2, 0x00000000); /* PCI Class code & Revision ID */
79 PCIC_WRITE(SH7751_PCICONF4, 0xab000001); /* PCI I/O address (local regs) */
80 PCIC_WRITE(SH7751_PCICONF5, 0x0c000000); /* PCI MEM address (local RAM) */
81 PCIC_WRITE(SH7751_PCICONF6, 0xd0000000); /* PCI MEM address (unused) */
82 PCIC_WRITE(SH7751_PCICONF11, 0x35051054); /* PCI Subsystem ID & Vendor ID */
83 PCIC_WRITE(SH7751_PCILSR0, 0x03f00000); /* MEM (full 64M exposed) */
84 PCIC_WRITE(SH7751_PCILSR1, 0x00000000); /* MEM (unused) */
85 PCIC_WRITE(SH7751_PCILAR0, 0x0c000000); /* MEM (direct map from PCI) */
86 PCIC_WRITE(SH7751_PCILAR1, 0x00000000); /* MEM (unused) */
87
88 /* Now turn it on... */
89 PCIC_WRITE(SH7751_PCICR, 0xa5000001);
90
91 /*
92 * Set PCIMBR and PCIIOBR here, assuming a single window
93 * (16M MEM, 256K IO) is enough. If a larger space is
94 * needed, the readx/writex and inx/outx functions will
95 * have to do more (e.g. setting registers for each call).
96 */
97
98 /*
99 * Set the MBR so PCI address is one-to-one with window,
100 * meaning all calls go straight through... use ifdef to
101 * catch erroneous assumption.
102 */
103 BUG_ON(PCIBIOS_MIN_MEM != SH7751_PCI_MEMORY_BASE);
104
105 PCIC_WRITE(SH7751_PCIMBR, PCIBIOS_MIN_MEM);
106
107 /* Set IOBR for window containing area specified in pci.h */
108 PCIC_WRITE(SH7751_PCIIOBR, (PCIBIOS_MIN_IO & SH7751_PCIIOBR_MASK));
109
110 /* All done, may as well say so... */
111 printk("SH7751R PCI: Finished initialization of the PCI controller\n");
112
113 return 1;
114}
115
116int __init pcibios_map_platform_irq(u8 slot, u8 pin)
117{
118 switch (slot) {
119 case 0: return IRQ_PCISLOT; /* PCI Extend slot */
120 case 1: return IRQ_PCMCIA; /* PCI Cardbus Bridge */
121 case 2: return IRQ_PCIETH; /* Realtek Ethernet controller */
122 case 3: return IRQ_PCIHUB; /* Realtek Ethernet Hub controller */
123 default:
124 printk("PCI: Bad IRQ mapping request for slot %d\n", slot);
125 return -1;
126 }
127}
128
129static struct resource sh7751_io_resource = {
130 .name = "SH7751_IO",
131 .start = 0x4000,
132 .end = 0x4000 + SH7751_PCI_IO_SIZE - 1,
133 .flags = IORESOURCE_IO
134};
135
136static struct resource sh7751_mem_resource = {
137 .name = "SH7751_mem",
138 .start = SH7751_PCI_MEMORY_BASE,
139 .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1,
140 .flags = IORESOURCE_MEM
141};
142
143extern struct pci_ops sh7751_pci_ops;
144
145struct pci_channel board_pci_channels[] = {
146 { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
147 { NULL, NULL, NULL, 0, 0 },
148};
149EXPORT_SYMBOL(board_pci_channels);
diff --git a/arch/sh/boards/renesas/hs7751rvoip/setup.c b/arch/sh/boards/renesas/hs7751rvoip/setup.c
deleted file mode 100644
index c05625975f2c..000000000000
--- a/arch/sh/boards/renesas/hs7751rvoip/setup.c
+++ /dev/null
@@ -1,105 +0,0 @@
1/*
2 * Renesas Technology Sales HS7751RVoIP Support.
3 *
4 * Copyright (C) 2000 Kazumoto Kojima
5 *
6 * Modified for HS7751RVoIP by
7 * Atom Create Engineering Co., Ltd. 2002.
8 * Lineo uSolutions, Inc. 2003.
9 */
10#include <linux/init.h>
11#include <linux/irq.h>
12#include <linux/mm.h>
13#include <linux/pm.h>
14#include <asm/hs7751rvoip.h>
15#include <asm/io.h>
16#include <asm/machvec.h>
17
18static void hs7751rvoip_power_off(void)
19{
20 ctrl_outw(ctrl_inw(PA_OUTPORTR) & 0xffdf, PA_OUTPORTR);
21}
22
23void *area5_io8_base;
24void *area6_io8_base;
25void *area5_io16_base;
26void *area6_io16_base;
27
28static int __init hs7751rvoip_cf_init(void)
29{
30 pgprot_t prot;
31 unsigned long paddrbase;
32
33 /* open I/O area window */
34 paddrbase = virt_to_phys((void *)(PA_AREA5_IO+0x00000800));
35 prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_COM16);
36 area5_io16_base = p3_ioremap(paddrbase, PAGE_SIZE, prot.pgprot);
37 if (!area5_io16_base) {
38 printk("allocate_cf_area : can't open CF I/O window!\n");
39 return -ENOMEM;
40 }
41
42 /* XXX : do we need attribute and common-memory area also? */
43
44 paddrbase = virt_to_phys((void *)PA_AREA6_IO);
45#if defined(CONFIG_HS7751RVOIP_CODEC)
46 prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_COM8);
47#else
48 prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_IO8);
49#endif
50 area6_io8_base = p3_ioremap(paddrbase, PAGE_SIZE, prot.pgprot);
51 if (!area6_io8_base) {
52 printk("allocate_cf_area : can't open CODEC I/O 8bit window!\n");
53 return -ENOMEM;
54 }
55 prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_IO16);
56 area6_io16_base = p3_ioremap(paddrbase, PAGE_SIZE, prot.pgprot);
57 if (!area6_io16_base) {
58 printk("allocate_cf_area : can't open CODEC I/O 16bit window!\n");
59 return -ENOMEM;
60 }
61
62 return 0;
63}
64device_initcall(hs7751rvoip_cf_init);
65
66/*
67 * Initialize the board
68 */
69static void __init hs7751rvoip_setup(char **cmdline_p)
70{
71 ctrl_outb(0xf0, PA_OUTPORTR);
72 pm_power_off = hs7751rvoip_power_off;
73
74 printk(KERN_INFO "Renesas Technology Sales HS7751RVoIP-2 support.\n");
75}
76
77static struct sh_machine_vector mv_hs7751rvoip __initmv = {
78 .mv_name = "HS7751RVoIP",
79 .mv_setup = hs7751rvoip_setup,
80 .mv_nr_irqs = 72,
81
82 .mv_inb = hs7751rvoip_inb,
83 .mv_inw = hs7751rvoip_inw,
84 .mv_inl = hs7751rvoip_inl,
85 .mv_outb = hs7751rvoip_outb,
86 .mv_outw = hs7751rvoip_outw,
87 .mv_outl = hs7751rvoip_outl,
88
89 .mv_inb_p = hs7751rvoip_inb_p,
90 .mv_inw_p = hs7751rvoip_inw,
91 .mv_inl_p = hs7751rvoip_inl,
92 .mv_outb_p = hs7751rvoip_outb_p,
93 .mv_outw_p = hs7751rvoip_outw,
94 .mv_outl_p = hs7751rvoip_outl,
95
96 .mv_insb = hs7751rvoip_insb,
97 .mv_insw = hs7751rvoip_insw,
98 .mv_insl = hs7751rvoip_insl,
99 .mv_outsb = hs7751rvoip_outsb,
100 .mv_outsw = hs7751rvoip_outsw,
101 .mv_outsl = hs7751rvoip_outsl,
102
103 .mv_init_irq = init_hs7751rvoip_IRQ,
104 .mv_ioport_map = hs7751rvoip_ioport_map,
105};
diff --git a/arch/sh/boards/renesas/r7780rp/Makefile b/arch/sh/boards/renesas/r7780rp/Makefile
index dd26182fbf58..20a10080b11f 100644
--- a/arch/sh/boards/renesas/r7780rp/Makefile
+++ b/arch/sh/boards/renesas/r7780rp/Makefile
@@ -3,7 +3,7 @@
3# 3#
4irqinit-$(CONFIG_SH_R7780MP) := irq-r7780mp.o 4irqinit-$(CONFIG_SH_R7780MP) := irq-r7780mp.o
5irqinit-$(CONFIG_SH_R7785RP) := irq-r7785rp.o 5irqinit-$(CONFIG_SH_R7785RP) := irq-r7785rp.o
6irqinit-$(CONFIG_SH_R7780RP) := irq-r7780rp.o irq.o 6irqinit-$(CONFIG_SH_R7780RP) := irq-r7780rp.o
7obj-y := setup.o $(irqinit-y) 7obj-y := setup.o $(irqinit-y)
8 8
9ifneq ($(CONFIG_SH_R7785RP),y) 9ifneq ($(CONFIG_SH_R7785RP),y)
diff --git a/arch/sh/boards/renesas/r7780rp/irq-r7780mp.c b/arch/sh/boards/renesas/r7780rp/irq-r7780mp.c
index 59b47fe061f9..1f8f073f27be 100644
--- a/arch/sh/boards/renesas/r7780rp/irq-r7780mp.c
+++ b/arch/sh/boards/renesas/r7780rp/irq-r7780mp.c
@@ -47,7 +47,7 @@ static unsigned char irl2irq[HL_NR_IRL] __initdata = {
47}; 47};
48 48
49static DECLARE_INTC_DESC(intc_desc, "r7780mp", vectors, 49static DECLARE_INTC_DESC(intc_desc, "r7780mp", vectors,
50 NULL, NULL, mask_registers, NULL, NULL); 50 NULL, mask_registers, NULL, NULL);
51 51
52unsigned char * __init highlander_init_irq_r7780mp(void) 52unsigned char * __init highlander_init_irq_r7780mp(void)
53{ 53{
diff --git a/arch/sh/boards/renesas/r7780rp/irq-r7780rp.c b/arch/sh/boards/renesas/r7780rp/irq-r7780rp.c
index fa4a534cade9..bd34048ed0e1 100644
--- a/arch/sh/boards/renesas/r7780rp/irq-r7780rp.c
+++ b/arch/sh/boards/renesas/r7780rp/irq-r7780rp.c
@@ -3,21 +3,65 @@
3 * 3 *
4 * Copyright (C) 2002 Atom Create Engineering Co., Ltd. 4 * Copyright (C) 2002 Atom Create Engineering Co., Ltd.
5 * Copyright (C) 2006 Paul Mundt 5 * Copyright (C) 2006 Paul Mundt
6 * Copyright (C) 2008 Magnus Damm
6 * 7 *
7 * This file is subject to the terms and conditions of the GNU General Public 8 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive 9 * License. See the file "COPYING" in the main directory of this archive
9 * for more details. 10 * for more details.
10 */ 11 */
11#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/irq.h>
12#include <linux/io.h> 14#include <linux/io.h>
13#include <asm/r7780rp.h> 15#include <asm/r7780rp.h>
14 16
17enum {
18 UNUSED = 0,
19
20 /* board specific interrupt sources */
21
22 AX88796, /* Ethernet controller */
23 PSW, /* Push Switch */
24 CF, /* Compact Flash */
25
26 PCI_A,
27 PCI_B,
28 PCI_C,
29 PCI_D,
30};
31
32static struct intc_vect vectors[] __initdata = {
33 INTC_IRQ(PCI_A, 65), /* dirty: overwrite cpu vectors for pci */
34 INTC_IRQ(PCI_B, 66),
35 INTC_IRQ(PCI_C, 67),
36 INTC_IRQ(PCI_D, 68),
37 INTC_IRQ(CF, IRQ_CF),
38 INTC_IRQ(PSW, IRQ_PSW),
39 INTC_IRQ(AX88796, IRQ_AX88796),
40};
41
42static struct intc_mask_reg mask_registers[] __initdata = {
43 { 0xa5000000, 0, 16, /* IRLMSK */
44 { PCI_A, PCI_B, PCI_C, PCI_D, CF, 0, 0, 0,
45 0, 0, 0, 0, 0, 0, PSW, AX88796 } },
46};
47
48static unsigned char irl2irq[HL_NR_IRL] __initdata = {
49 65, 66, 67, 68,
50 IRQ_CF, 0, 0, 0,
51 0, 0, 0, 0,
52 IRQ_AX88796, IRQ_PSW
53};
54
55static DECLARE_INTC_DESC(intc_desc, "r7780rp", vectors,
56 NULL, mask_registers, NULL, NULL);
57
15unsigned char * __init highlander_init_irq_r7780rp(void) 58unsigned char * __init highlander_init_irq_r7780rp(void)
16{ 59{
17 int i; 60 if (ctrl_inw(0xa5000600)) {
18 61 printk(KERN_INFO "Using r7780rp interrupt controller.\n");
19 for (i = 0; i < 15; i++) 62 register_intc_controller(&intc_desc);
20 make_r7780rp_irq(i); 63 return irl2irq;
64 }
21 65
22 return NULL; 66 return NULL;
23} 67}
diff --git a/arch/sh/boards/renesas/r7780rp/irq-r7785rp.c b/arch/sh/boards/renesas/r7780rp/irq-r7785rp.c
index b2c6a84673bd..bf7ec107fbc6 100644
--- a/arch/sh/boards/renesas/r7780rp/irq-r7785rp.c
+++ b/arch/sh/boards/renesas/r7780rp/irq-r7785rp.c
@@ -2,7 +2,7 @@
2 * Renesas Solutions Highlander R7785RP Support. 2 * Renesas Solutions Highlander R7785RP Support.
3 * 3 *
4 * Copyright (C) 2002 Atom Create Engineering Co., Ltd. 4 * Copyright (C) 2002 Atom Create Engineering Co., Ltd.
5 * Copyright (C) 2006 Paul Mundt 5 * Copyright (C) 2006 - 2008 Paul Mundt
6 * Copyright (C) 2007 Magnus Damm 6 * Copyright (C) 2007 Magnus Damm
7 * 7 *
8 * This file is subject to the terms and conditions of the GNU General Public 8 * This file is subject to the terms and conditions of the GNU General Public
@@ -17,31 +17,52 @@
17enum { 17enum {
18 UNUSED = 0, 18 UNUSED = 0,
19 19
20 /* board specific interrupt sources */ 20 /* FPGA specific interrupt sources */
21 AX88796, /* Ethernet controller */ 21 CF, /* Compact Flash */
22 CF, /* Compact Flash */ 22 SMBUS, /* SMBUS */
23 TP, /* Touch panel */
24 RTC, /* RTC Alarm */
25 TH_ALERT, /* Temperature sensor */
26 AX88796, /* Ethernet controller */
27
28 /* external bus connector */
29 EXT0, EXT1, EXT2, EXT3, EXT4, EXT5, EXT6, EXT7,
23}; 30};
24 31
25static struct intc_vect vectors[] __initdata = { 32static struct intc_vect vectors[] __initdata = {
26 INTC_IRQ(CF, IRQ_CF), 33 INTC_IRQ(CF, IRQ_CF),
34 INTC_IRQ(SMBUS, IRQ_SMBUS),
35 INTC_IRQ(TP, IRQ_TP),
36 INTC_IRQ(RTC, IRQ_RTC),
37 INTC_IRQ(TH_ALERT, IRQ_TH_ALERT),
38
39 INTC_IRQ(EXT0, IRQ_EXT0), INTC_IRQ(EXT1, IRQ_EXT1),
40 INTC_IRQ(EXT2, IRQ_EXT2), INTC_IRQ(EXT3, IRQ_EXT3),
41
42 INTC_IRQ(EXT4, IRQ_EXT4), INTC_IRQ(EXT5, IRQ_EXT5),
43 INTC_IRQ(EXT6, IRQ_EXT6), INTC_IRQ(EXT7, IRQ_EXT7),
44
27 INTC_IRQ(AX88796, IRQ_AX88796), 45 INTC_IRQ(AX88796, IRQ_AX88796),
28}; 46};
29 47
30static struct intc_mask_reg mask_registers[] __initdata = { 48static struct intc_mask_reg mask_registers[] __initdata = {
31 { 0xa4000010, 0, 16, /* IRLMCR1 */ 49 { 0xa4000010, 0, 16, /* IRLMCR1 */
32 { 0, 0, 0, 0, CF, AX88796, 0, 0, 50 { 0, 0, 0, 0, CF, AX88796, SMBUS, TP,
33 0, 0, 0, 0, 0, 0, 0, 0 } }, 51 RTC, 0, TH_ALERT, 0, 0, 0, 0, 0 } },
52 { 0xa4000012, 0, 16, /* IRLMCR2 */
53 { 0, 0, 0, 0, 0, 0, 0, 0,
54 EXT7, EXT6, EXT5, EXT4, EXT3, EXT2, EXT1, EXT0 } },
34}; 55};
35 56
36static unsigned char irl2irq[HL_NR_IRL] __initdata = { 57static unsigned char irl2irq[HL_NR_IRL] __initdata = {
37 0, IRQ_CF, 0, 0, 58 0, IRQ_CF, IRQ_EXT4, IRQ_EXT5,
38 0, 0, 0, 0, 59 IRQ_EXT6, IRQ_EXT7, IRQ_SMBUS, IRQ_TP,
39 0, 0, IRQ_AX88796, 0, 60 IRQ_RTC, IRQ_TH_ALERT, IRQ_AX88796, IRQ_EXT0,
40 0, 0, 0, 61 IRQ_EXT1, IRQ_EXT2, IRQ_EXT3,
41}; 62};
42 63
43static DECLARE_INTC_DESC(intc_desc, "r7785rp", vectors, 64static DECLARE_INTC_DESC(intc_desc, "r7785rp", vectors,
44 NULL, NULL, mask_registers, NULL, NULL); 65 NULL, mask_registers, NULL, NULL);
45 66
46unsigned char * __init highlander_init_irq_r7785rp(void) 67unsigned char * __init highlander_init_irq_r7785rp(void)
47{ 68{
@@ -58,7 +79,7 @@ unsigned char * __init highlander_init_irq_r7785rp(void)
58 ctrl_outw(0x7060, PA_IRLPRC); /* FPGA IRLC */ 79 ctrl_outw(0x7060, PA_IRLPRC); /* FPGA IRLC */
59 ctrl_outw(0x0000, PA_IRLPRD); /* FPGA IRLD */ 80 ctrl_outw(0x0000, PA_IRLPRD); /* FPGA IRLD */
60 ctrl_outw(0x4321, PA_IRLPRE); /* FPGA IRLE */ 81 ctrl_outw(0x4321, PA_IRLPRE); /* FPGA IRLE */
61 ctrl_outw(0x0000, PA_IRLPRF); /* FPGA IRLF */ 82 ctrl_outw(0xdcba, PA_IRLPRF); /* FPGA IRLF */
62 83
63 register_intc_controller(&intc_desc); 84 register_intc_controller(&intc_desc);
64 return irl2irq; 85 return irl2irq;
diff --git a/arch/sh/boards/renesas/r7780rp/irq.c b/arch/sh/boards/renesas/r7780rp/irq.c
deleted file mode 100644
index e0b8eb52f376..000000000000
--- a/arch/sh/boards/renesas/r7780rp/irq.c
+++ /dev/null
@@ -1,51 +0,0 @@
1/*
2 * Renesas Solutions Highlander R7780RP-1 Support.
3 *
4 * Copyright (C) 2002 Atom Create Engineering Co., Ltd.
5 * Copyright (C) 2006 Paul Mundt
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 */
11#include <linux/init.h>
12#include <linux/irq.h>
13#include <linux/interrupt.h>
14#include <linux/io.h>
15#include <asm/r7780rp.h>
16
17#ifdef CONFIG_SH_R7780RP
18static int mask_pos[] = {15, 14, 13, 12, 11, 10, 9, 8, 7, 5, 6, 4, 0, 1, 2, 0};
19#elif defined(CONFIG_SH_R7780MP)
20static int mask_pos[] = {12, 11, 9, 14, 15, 8, 13, 6, 5, 4, 3, 2, 0, 0, 1, 0};
21#elif defined(CONFIG_SH_R7785RP)
22static int mask_pos[] = {2, 11, 2, 2, 2, 2, 9, 8, 7, 5, 10, 2, 2, 2, 2, 2};
23#endif
24
25static void enable_r7780rp_irq(unsigned int irq)
26{
27 /* Set priority in IPR back to original value */
28 ctrl_outw(ctrl_inw(IRLCNTR1) | (1 << mask_pos[irq]), IRLCNTR1);
29}
30
31static void disable_r7780rp_irq(unsigned int irq)
32{
33 /* Set the priority in IPR to 0 */
34 ctrl_outw(ctrl_inw(IRLCNTR1) & (0xffff ^ (1 << mask_pos[irq])),
35 IRLCNTR1);
36}
37
38static struct irq_chip r7780rp_irq_chip __read_mostly = {
39 .name = "R7780RP",
40 .mask = disable_r7780rp_irq,
41 .unmask = enable_r7780rp_irq,
42 .mask_ack = disable_r7780rp_irq,
43};
44
45void make_r7780rp_irq(unsigned int irq)
46{
47 disable_irq_nosync(irq);
48 set_irq_chip_and_handler_name(irq, &r7780rp_irq_chip,
49 handle_level_irq, "level");
50 enable_r7780rp_irq(irq);
51}
diff --git a/arch/sh/boards/renesas/r7780rp/setup.c b/arch/sh/boards/renesas/r7780rp/setup.c
index 0fdc0bc19145..a43b47726f54 100644
--- a/arch/sh/boards/renesas/r7780rp/setup.c
+++ b/arch/sh/boards/renesas/r7780rp/setup.c
@@ -179,9 +179,11 @@ static struct platform_device ax88796_device = {
179static struct platform_device *r7780rp_devices[] __initdata = { 179static struct platform_device *r7780rp_devices[] __initdata = {
180 &r8a66597_usb_host_device, 180 &r8a66597_usb_host_device,
181 &m66592_usb_peripheral_device, 181 &m66592_usb_peripheral_device,
182 &cf_ide_device,
183 &heartbeat_device, 182 &heartbeat_device,
183#ifndef CONFIG_SH_R7780RP
184 &cf_ide_device,
184 &ax88796_device, 185 &ax88796_device,
186#endif
185}; 187};
186 188
187static int __init r7780rp_devices_setup(void) 189static int __init r7780rp_devices_setup(void)
@@ -316,9 +318,9 @@ void __init highlander_init_irq(void)
316 break; 318 break;
317#endif 319#endif
318#ifdef CONFIG_SH_R7780RP 320#ifdef CONFIG_SH_R7780RP
319 highlander_init_irq_r7780rp(); 321 ucp = highlander_init_irq_r7780rp();
320 ucp = irl2irq; 322 if (ucp)
321 break; 323 break;
322#endif 324#endif
323 } while (0); 325 } while (0);
324 326
diff --git a/arch/sh/boards/renesas/rts7751r2d/irq.c b/arch/sh/boards/renesas/rts7751r2d/irq.c
index 7cc2813adfe4..8e49f6e51247 100644
--- a/arch/sh/boards/renesas/rts7751r2d/irq.c
+++ b/arch/sh/boards/renesas/rts7751r2d/irq.c
@@ -13,7 +13,6 @@
13#include <linux/irq.h> 13#include <linux/irq.h>
14#include <linux/interrupt.h> 14#include <linux/interrupt.h>
15#include <linux/io.h> 15#include <linux/io.h>
16#include <asm/voyagergx.h>
17#include <asm/rts7751r2d.h> 16#include <asm/rts7751r2d.h>
18 17
19#define R2D_NR_IRL 13 18#define R2D_NR_IRL 13
@@ -71,7 +70,7 @@ static unsigned char irl2irq_r2d_1[R2D_NR_IRL] __initdata = {
71}; 70};
72 71
73static DECLARE_INTC_DESC(intc_desc_r2d_1, "r2d-1", vectors_r2d_1, 72static DECLARE_INTC_DESC(intc_desc_r2d_1, "r2d-1", vectors_r2d_1,
74 NULL, NULL, mask_registers_r2d_1, NULL, NULL); 73 NULL, mask_registers_r2d_1, NULL, NULL);
75 74
76#endif /* CONFIG_RTS7751R2D_1 */ 75#endif /* CONFIG_RTS7751R2D_1 */
77 76
@@ -109,7 +108,7 @@ static unsigned char irl2irq_r2d_plus[R2D_NR_IRL] __initdata = {
109}; 108};
110 109
111static DECLARE_INTC_DESC(intc_desc_r2d_plus, "r2d-plus", vectors_r2d_plus, 110static DECLARE_INTC_DESC(intc_desc_r2d_plus, "r2d-plus", vectors_r2d_plus,
112 NULL, NULL, mask_registers_r2d_plus, NULL, NULL); 111 NULL, mask_registers_r2d_plus, NULL, NULL);
113 112
114#endif /* CONFIG_RTS7751R2D_PLUS */ 113#endif /* CONFIG_RTS7751R2D_PLUS */
115 114
@@ -153,7 +152,4 @@ void __init init_rts7751r2d_IRQ(void)
153 } 152 }
154 153
155 register_intc_controller(d); 154 register_intc_controller(d);
156#ifdef CONFIG_MFD_SM501
157 setup_voyagergx_irq();
158#endif
159} 155}
diff --git a/arch/sh/boards/renesas/rts7751r2d/setup.c b/arch/sh/boards/renesas/rts7751r2d/setup.c
index 8125d20fdbd8..3452b072adde 100644
--- a/arch/sh/boards/renesas/rts7751r2d/setup.c
+++ b/arch/sh/boards/renesas/rts7751r2d/setup.c
@@ -13,34 +13,15 @@
13#include <linux/pata_platform.h> 13#include <linux/pata_platform.h>
14#include <linux/serial_8250.h> 14#include <linux/serial_8250.h>
15#include <linux/sm501.h> 15#include <linux/sm501.h>
16#include <linux/sm501-regs.h>
16#include <linux/pm.h> 17#include <linux/pm.h>
18#include <linux/fb.h>
19#include <linux/spi/spi.h>
20#include <linux/spi/spi_bitbang.h>
17#include <asm/machvec.h> 21#include <asm/machvec.h>
18#include <asm/rts7751r2d.h> 22#include <asm/rts7751r2d.h>
19#include <asm/voyagergx.h>
20#include <asm/io.h> 23#include <asm/io.h>
21 24#include <asm/spi.h>
22static void __init voyagergx_serial_init(void)
23{
24 unsigned long val;
25
26 /*
27 * GPIO Control
28 */
29 val = readl((void __iomem *)GPIO_MUX_HIGH);
30 val |= 0x00001fe0;
31 writel(val, (void __iomem *)GPIO_MUX_HIGH);
32
33 /*
34 * Power Mode Gate
35 */
36 val = readl((void __iomem *)POWER_MODE0_GATE);
37 val |= (POWER_MODE0_GATE_U0 | POWER_MODE0_GATE_U1);
38 writel(val, (void __iomem *)POWER_MODE0_GATE);
39
40 val = readl((void __iomem *)POWER_MODE1_GATE);
41 val |= (POWER_MODE1_GATE_U0 | POWER_MODE1_GATE_U1);
42 writel(val, (void __iomem *)POWER_MODE1_GATE);
43}
44 25
45static struct resource cf_ide_resources[] = { 26static struct resource cf_ide_resources[] = {
46 [0] = { 27 [0] = {
@@ -75,6 +56,43 @@ static struct platform_device cf_ide_device = {
75 }, 56 },
76}; 57};
77 58
59static struct spi_board_info spi_bus[] = {
60 {
61 .modalias = "rtc-r9701",
62 .max_speed_hz = 1000000,
63 .mode = SPI_MODE_3,
64 },
65};
66
67static void r2d_chip_select(struct sh_spi_info *spi, int cs, int state)
68{
69 BUG_ON(cs != 0); /* Single Epson RTC-9701JE attached on CS0 */
70 ctrl_outw(state == BITBANG_CS_ACTIVE, PA_RTCCE);
71}
72
73static struct sh_spi_info spi_info = {
74 .num_chipselect = 1,
75 .chip_select = r2d_chip_select,
76};
77
78static struct resource spi_sh_sci_resources[] = {
79 {
80 .start = 0xffe00000,
81 .end = 0xffe0001f,
82 .flags = IORESOURCE_MEM,
83 },
84};
85
86static struct platform_device spi_sh_sci_device = {
87 .name = "spi_sh_sci",
88 .id = -1,
89 .num_resources = ARRAY_SIZE(spi_sh_sci_resources),
90 .resource = spi_sh_sci_resources,
91 .dev = {
92 .platform_data = &spi_info,
93 },
94};
95
78static struct resource heartbeat_resources[] = { 96static struct resource heartbeat_resources[] = {
79 [0] = { 97 [0] = {
80 .start = PA_OUTPORT, 98 .start = PA_OUTPORT,
@@ -93,11 +111,11 @@ static struct platform_device heartbeat_device = {
93#ifdef CONFIG_MFD_SM501 111#ifdef CONFIG_MFD_SM501
94static struct plat_serial8250_port uart_platform_data[] = { 112static struct plat_serial8250_port uart_platform_data[] = {
95 { 113 {
96 .membase = (void __iomem *)VOYAGER_UART_BASE, 114 .membase = (void __iomem *)0xb3e30000,
97 .mapbase = VOYAGER_UART_BASE, 115 .mapbase = 0xb3e30000,
98 .iotype = UPIO_MEM, 116 .iotype = UPIO_MEM,
99 .irq = IRQ_SM501_U0, 117 .irq = IRQ_VOYAGER,
100 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, 118 .flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ,
101 .regshift = 2, 119 .regshift = 2,
102 .uartclk = (9600 * 16), 120 .uartclk = (9600 * 16),
103 }, 121 },
@@ -124,14 +142,67 @@ static struct resource sm501_resources[] = {
124 .flags = IORESOURCE_MEM, 142 .flags = IORESOURCE_MEM,
125 }, 143 },
126 [2] = { 144 [2] = {
127 .start = IRQ_SM501_CV, 145 .start = IRQ_VOYAGER,
128 .flags = IORESOURCE_IRQ, 146 .flags = IORESOURCE_IRQ,
129 }, 147 },
130}; 148};
131 149
150static struct fb_videomode sm501_default_mode = {
151 .pixclock = 35714,
152 .xres = 640,
153 .yres = 480,
154 .left_margin = 105,
155 .right_margin = 50,
156 .upper_margin = 35,
157 .lower_margin = 0,
158 .hsync_len = 96,
159 .vsync_len = 2,
160 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
161};
162
163static struct sm501_platdata_fbsub sm501_pdata_fbsub_pnl = {
164 .def_bpp = 16,
165 .def_mode = &sm501_default_mode,
166 .flags = SM501FB_FLAG_USE_INIT_MODE |
167 SM501FB_FLAG_USE_HWCURSOR |
168 SM501FB_FLAG_USE_HWACCEL |
169 SM501FB_FLAG_DISABLE_AT_EXIT,
170};
171
172static struct sm501_platdata_fbsub sm501_pdata_fbsub_crt = {
173 .flags = (SM501FB_FLAG_USE_INIT_MODE |
174 SM501FB_FLAG_USE_HWCURSOR |
175 SM501FB_FLAG_USE_HWACCEL |
176 SM501FB_FLAG_DISABLE_AT_EXIT),
177
178};
179
180static struct sm501_platdata_fb sm501_fb_pdata = {
181 .fb_route = SM501_FB_OWN,
182 .fb_crt = &sm501_pdata_fbsub_crt,
183 .fb_pnl = &sm501_pdata_fbsub_pnl,
184 .flags = SM501_FBPD_SWAP_FB_ENDIAN,
185};
186
187static struct sm501_initdata sm501_initdata = {
188 .gpio_high = {
189 .set = 0x00001fe0,
190 .mask = 0x0,
191 },
192 .devices = SM501_USE_USB_HOST,
193};
194
195static struct sm501_platdata sm501_platform_data = {
196 .init = &sm501_initdata,
197 .fb = &sm501_fb_pdata,
198};
199
132static struct platform_device sm501_device = { 200static struct platform_device sm501_device = {
133 .name = "sm501", 201 .name = "sm501",
134 .id = -1, 202 .id = -1,
203 .dev = {
204 .platform_data = &sm501_platform_data,
205 },
135 .num_resources = ARRAY_SIZE(sm501_resources), 206 .num_resources = ARRAY_SIZE(sm501_resources),
136 .resource = sm501_resources, 207 .resource = sm501_resources,
137}; 208};
@@ -145,10 +216,12 @@ static struct platform_device *rts7751r2d_devices[] __initdata = {
145#endif 216#endif
146 &cf_ide_device, 217 &cf_ide_device,
147 &heartbeat_device, 218 &heartbeat_device,
219 &spi_sh_sci_device,
148}; 220};
149 221
150static int __init rts7751r2d_devices_setup(void) 222static int __init rts7751r2d_devices_setup(void)
151{ 223{
224 spi_register_board_info(spi_bus, ARRAY_SIZE(spi_bus));
152 return platform_add_devices(rts7751r2d_devices, 225 return platform_add_devices(rts7751r2d_devices,
153 ARRAY_SIZE(rts7751r2d_devices)); 226 ARRAY_SIZE(rts7751r2d_devices));
154} 227}
@@ -192,6 +265,7 @@ u8 rts7751r2d_readb(void __iomem *addr)
192 */ 265 */
193static void __init rts7751r2d_setup(char **cmdline_p) 266static void __init rts7751r2d_setup(char **cmdline_p)
194{ 267{
268 void __iomem *sm501_reg;
195 u16 ver = ctrl_inw(PA_VERREG); 269 u16 ver = ctrl_inw(PA_VERREG);
196 270
197 printk(KERN_INFO "Renesas Technology Sales RTS7751R2D support.\n"); 271 printk(KERN_INFO "Renesas Technology Sales RTS7751R2D support.\n");
@@ -202,7 +276,30 @@ static void __init rts7751r2d_setup(char **cmdline_p)
202 ctrl_outw(0x0000, PA_OUTPORT); 276 ctrl_outw(0x0000, PA_OUTPORT);
203 pm_power_off = rts7751r2d_power_off; 277 pm_power_off = rts7751r2d_power_off;
204 278
205 voyagergx_serial_init(); 279 /* sm501 dram configuration:
280 * ColSizeX = 11 - External Memory Column Size: 256 words.
281 * APX = 1 - External Memory Active to Pre-Charge Delay: 7 clocks.
282 * RstX = 1 - External Memory Reset: Normal.
283 * Rfsh = 1 - Local Memory Refresh to Command Delay: 12 clocks.
284 * BwC = 1 - Local Memory Block Write Cycle Time: 2 clocks.
285 * BwP = 1 - Local Memory Block Write to Pre-Charge Delay: 1 clock.
286 * AP = 1 - Internal Memory Active to Pre-Charge Delay: 7 clocks.
287 * Rst = 1 - Internal Memory Reset: Normal.
288 * RA = 1 - Internal Memory Remain in Active State: Do not remain.
289 */
290
291 sm501_reg = (void __iomem *)0xb3e00000 + SM501_DRAM_CONTROL;
292 writel(readl(sm501_reg) | 0x00f107c0, sm501_reg);
293
294 /*
295 * Power Mode Gate - Enable UART0
296 */
297
298 sm501_reg = (void __iomem *)0xb3e00000 + SM501_POWER_MODE_0_GATE;
299 writel(readl(sm501_reg) | (1 << SM501_GATE_UART0), sm501_reg);
300
301 sm501_reg = (void __iomem *)0xb3e00000 + SM501_POWER_MODE_1_GATE;
302 writel(readl(sm501_reg) | (1 << SM501_GATE_UART0), sm501_reg);
206} 303}
207 304
208/* 305/*
@@ -215,8 +312,4 @@ static struct sh_machine_vector mv_rts7751r2d __initmv = {
215 .mv_irq_demux = rts7751r2d_irq_demux, 312 .mv_irq_demux = rts7751r2d_irq_demux,
216 .mv_writeb = rts7751r2d_writeb, 313 .mv_writeb = rts7751r2d_writeb,
217 .mv_readb = rts7751r2d_readb, 314 .mv_readb = rts7751r2d_readb,
218#if defined(CONFIG_MFD_SM501) && defined(CONFIG_USB_OHCI_HCD)
219 .mv_consistent_alloc = voyagergx_consistent_alloc,
220 .mv_consistent_free = voyagergx_consistent_free,
221#endif
222}; 315};
diff --git a/arch/sh/boards/renesas/sdk7780/Kconfig b/arch/sh/boards/renesas/sdk7780/Kconfig
new file mode 100644
index 000000000000..e4f5b6985be1
--- /dev/null
+++ b/arch/sh/boards/renesas/sdk7780/Kconfig
@@ -0,0 +1,23 @@
1if SH_SDK7780
2
3choice
4 prompt "SDK7780 options"
5 default SH_SDK7780_BASE
6
7config SH_SDK7780_STANDALONE
8 bool "SDK7780 board support"
9 depends on CPU_SUBTYPE_SH7780
10 help
11 Selecting this option will enable support for the
12 standalone version of the SDK7780. If in doubt, say Y.
13
14config SH_SDK7780_BASE
15 bool "SDK7780 with base-board support"
16 depends on CPU_SUBTYPE_SH7780
17 help
18 Selecting this option will enable support for the expansion
19 baseboard devices. If in doubt, say Y.
20
21endchoice
22
23endif
diff --git a/arch/sh/boards/renesas/sdk7780/Makefile b/arch/sh/boards/renesas/sdk7780/Makefile
new file mode 100644
index 000000000000..3d8f0befc35d
--- /dev/null
+++ b/arch/sh/boards/renesas/sdk7780/Makefile
@@ -0,0 +1,5 @@
1#
2# Makefile for the SDK7780 specific parts of the kernel
3#
4obj-y := setup.o irq.o
5
diff --git a/arch/sh/boards/renesas/sdk7780/irq.c b/arch/sh/boards/renesas/sdk7780/irq.c
new file mode 100644
index 000000000000..87cdc578f6ff
--- /dev/null
+++ b/arch/sh/boards/renesas/sdk7780/irq.c
@@ -0,0 +1,46 @@
1/*
2 * linux/arch/sh/boards/renesas/sdk7780/irq.c
3 *
4 * Renesas Technology Europe SDK7780 Support.
5 *
6 * Copyright (C) 2008 Nicholas Beck <nbeck@mpc-data.co.uk>
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/init.h>
13#include <linux/irq.h>
14#include <linux/io.h>
15#include <asm/sdk7780.h>
16
17enum {
18 UNUSED = 0,
19 /* board specific interrupt sources */
20 SMC91C111, /* Ethernet controller */
21};
22
23static struct intc_vect fpga_vectors[] __initdata = {
24 INTC_IRQ(SMC91C111, IRQ_ETHERNET),
25};
26
27static struct intc_mask_reg fpga_mask_registers[] __initdata = {
28 { 0, FPGA_IRQ0MR, 16,
29 { 0, 0, 0, 0, 0, 0, 0, 0,
30 0, 0, 0, SMC91C111, 0, 0, 0, 0 } },
31};
32
33static DECLARE_INTC_DESC(fpga_intc_desc, "sdk7780-irq", fpga_vectors,
34 NULL, fpga_mask_registers, NULL, NULL);
35
36void __init init_sdk7780_IRQ(void)
37{
38 printk(KERN_INFO "Using SDK7780 interrupt controller.\n");
39
40 ctrl_outw(0xFFFF, FPGA_IRQ0MR);
41 /* Setup IRL 0-3 */
42 ctrl_outw(0x0003, FPGA_IMSR);
43 plat_irq_setup_pins(IRQ_MODE_IRL3210);
44
45 register_intc_controller(&fpga_intc_desc);
46}
diff --git a/arch/sh/boards/renesas/sdk7780/setup.c b/arch/sh/boards/renesas/sdk7780/setup.c
new file mode 100644
index 000000000000..5df32f201870
--- /dev/null
+++ b/arch/sh/boards/renesas/sdk7780/setup.c
@@ -0,0 +1,109 @@
1/*
2 * arch/sh/boards/renesas/sdk7780/setup.c
3 *
4 * Renesas Solutions SH7780 SDK Support
5 * Copyright (C) 2008 Nicholas Beck <nbeck@mpc-data.co.uk>
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 */
11#include <linux/init.h>
12#include <linux/types.h>
13#include <linux/platform_device.h>
14#include <linux/pata_platform.h>
15#include <asm/machvec.h>
16#include <asm/sdk7780.h>
17#include <asm/heartbeat.h>
18#include <asm/io.h>
19#include <asm/addrspace.h>
20
21#define GPIO_PECR 0xFFEA0008
22
23//* Heartbeat */
24static struct heartbeat_data heartbeat_data = {
25 .regsize = 16,
26};
27
28static struct resource heartbeat_resources[] = {
29 [0] = {
30 .start = PA_LED,
31 .end = PA_LED,
32 .flags = IORESOURCE_MEM,
33 },
34};
35
36static struct platform_device heartbeat_device = {
37 .name = "heartbeat",
38 .id = -1,
39 .dev = {
40 .platform_data = &heartbeat_data,
41 },
42 .num_resources = ARRAY_SIZE(heartbeat_resources),
43 .resource = heartbeat_resources,
44};
45
46/* SMC91x */
47static struct resource smc91x_eth_resources[] = {
48 [0] = {
49 .name = "smc91x-regs" ,
50 .start = PA_LAN + 0x300,
51 .end = PA_LAN + 0x300 + 0x10 ,
52 .flags = IORESOURCE_MEM,
53 },
54 [1] = {
55 .start = IRQ_ETHERNET,
56 .end = IRQ_ETHERNET,
57 .flags = IORESOURCE_IRQ,
58 },
59};
60
61static struct platform_device smc91x_eth_device = {
62 .name = "smc91x",
63 .id = 0,
64 .dev = {
65 .dma_mask = NULL, /* don't use dma */
66 .coherent_dma_mask = 0xffffffff,
67 },
68 .num_resources = ARRAY_SIZE(smc91x_eth_resources),
69 .resource = smc91x_eth_resources,
70};
71
72static struct platform_device *sdk7780_devices[] __initdata = {
73 &heartbeat_device,
74 &smc91x_eth_device,
75};
76
77static int __init sdk7780_devices_setup(void)
78{
79 return platform_add_devices(sdk7780_devices,
80 ARRAY_SIZE(sdk7780_devices));
81}
82device_initcall(sdk7780_devices_setup);
83
84static void __init sdk7780_setup(char **cmdline_p)
85{
86 u16 ver = ctrl_inw(FPGA_FPVERR);
87 u16 dateStamp = ctrl_inw(FPGA_FPDATER);
88
89 printk(KERN_INFO "Renesas Technology Europe SDK7780 support.\n");
90 printk(KERN_INFO "Board version: %d (revision %d), "
91 "FPGA version: %d (revision %d), datestamp : %d\n",
92 (ver >> 12) & 0xf, (ver >> 8) & 0xf,
93 (ver >> 4) & 0xf, ver & 0xf,
94 dateStamp);
95
96 /* Setup pin mux'ing for PCIC */
97 ctrl_outw(0x0000, GPIO_PECR);
98}
99
100/*
101 * The Machine Vector
102 */
103static struct sh_machine_vector mv_se7780 __initmv = {
104 .mv_name = "Renesas SDK7780-R3" ,
105 .mv_setup = sdk7780_setup,
106 .mv_nr_irqs = 111,
107 .mv_init_irq = init_sdk7780_IRQ,
108};
109
diff --git a/arch/sh/boot/Makefile b/arch/sh/boot/Makefile
index 1b0f5be01d10..59f552c13349 100644
--- a/arch/sh/boot/Makefile
+++ b/arch/sh/boot/Makefile
@@ -35,17 +35,28 @@ $(obj)/compressed/vmlinux: FORCE
35KERNEL_LOAD := $(shell /bin/bash -c 'printf "0x%8x" \ 35KERNEL_LOAD := $(shell /bin/bash -c 'printf "0x%8x" \
36 $$[$(CONFIG_PAGE_OFFSET) + \ 36 $$[$(CONFIG_PAGE_OFFSET) + \
37 $(CONFIG_MEMORY_START) + \ 37 $(CONFIG_MEMORY_START) + \
38 $(CONFIG_ZERO_PAGE_OFFSET)]')
39
40KERNEL_ENTRY := $(shell /bin/bash -c 'printf "0x%8x" \
41 $$[$(CONFIG_PAGE_OFFSET) + \
42 $(CONFIG_MEMORY_START) + \
38 $(CONFIG_ZERO_PAGE_OFFSET)+0x1000]') 43 $(CONFIG_ZERO_PAGE_OFFSET)+0x1000]')
39 44
40quiet_cmd_uimage = UIMAGE $@ 45quiet_cmd_uimage = UIMAGE $@
41 cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A sh -O linux -T kernel \ 46 cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A sh -O linux -T kernel \
42 -C none -a $(KERNEL_LOAD) -e $(KERNEL_LOAD) \ 47 -C none -a $(KERNEL_LOAD) -e $(KERNEL_ENTRY) \
43 -n 'Linux-$(KERNELRELEASE)' -d $< $@ 48 -n 'Linux-$(KERNELRELEASE)' -d $< $@
44 49
45$(obj)/uImage: $(obj)/zImage FORCE 50$(obj)/uImage: $(obj)/vmlinux.bin.gz FORCE
46 $(call if_changed,uimage) 51 $(call if_changed,uimage)
47 @echo ' Image $@ is ready' 52 @echo ' Image $@ is ready'
48 53
54$(obj)/vmlinux.bin: vmlinux FORCE
55 $(call if_changed,objcopy)
56
57$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
58 $(call if_changed,gzip)
59
49OBJCOPYFLAGS_vmlinux.srec := -I binary -O srec 60OBJCOPYFLAGS_vmlinux.srec := -I binary -O srec
50$(obj)/vmlinux.srec: $(obj)/compressed/vmlinux 61$(obj)/vmlinux.srec: $(obj)/compressed/vmlinux
51 $(call if_changed,objcopy) 62 $(call if_changed,objcopy)
@@ -54,4 +65,5 @@ OBJCOPYFLAGS_uImage.srec := -I binary -O srec
54$(obj)/uImage.srec: $(obj)/uImage 65$(obj)/uImage.srec: $(obj)/uImage
55 $(call if_changed,objcopy) 66 $(call if_changed,objcopy)
56 67
57clean-files += uImage uImage.srec vmlinux.srec 68clean-files += uImage uImage.srec vmlinux.srec \
69 vmlinux.bin vmlinux.bin.gz
diff --git a/arch/sh/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile
index 906a13f82fe0..efb01dc3c8c3 100644
--- a/arch/sh/boot/compressed/Makefile
+++ b/arch/sh/boot/compressed/Makefile
@@ -1,43 +1,5 @@
1# 1ifeq ($(CONFIG_SUPERH32),y)
2# linux/arch/sh/boot/compressed/Makefile 2include ${srctree}/arch/sh/boot/compressed/Makefile_32
3# 3else
4# create a compressed vmlinux image from the original vmlinux 4include ${srctree}/arch/sh/boot/compressed/Makefile_64
5#
6
7targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o
8EXTRA_AFLAGS := -traditional
9
10OBJECTS = $(obj)/head.o $(obj)/misc.o
11
12ifdef CONFIG_SH_STANDARD_BIOS
13OBJECTS += $(obj)/../../kernel/sh_bios.o
14endif 5endif
15
16#
17# IMAGE_OFFSET is the load offset of the compression loader
18#
19IMAGE_OFFSET := $(shell /bin/bash -c 'printf "0x%08x" \
20 $$[$(CONFIG_PAGE_OFFSET) + \
21 $(CONFIG_MEMORY_START) + \
22 $(CONFIG_BOOT_LINK_OFFSET)]')
23
24LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
25
26LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -e startup -T $(obj)/../../kernel/vmlinux.lds
27
28
29$(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o $(LIBGCC) FORCE
30 $(call if_changed,ld)
31 @:
32
33$(obj)/vmlinux.bin: vmlinux FORCE
34 $(call if_changed,objcopy)
35
36$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
37 $(call if_changed,gzip)
38
39LDFLAGS_piggy.o := -r --format binary --oformat elf32-sh-linux -T
40OBJCOPYFLAGS += -R .empty_zero_page
41
42$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE
43 $(call if_changed,ld)
diff --git a/arch/sh/boot/compressed/Makefile_32 b/arch/sh/boot/compressed/Makefile_32
new file mode 100644
index 000000000000..6ac8d4a4ed1d
--- /dev/null
+++ b/arch/sh/boot/compressed/Makefile_32
@@ -0,0 +1,43 @@
1#
2# linux/arch/sh/boot/compressed/Makefile
3#
4# create a compressed vmlinux image from the original vmlinux
5#
6
7targets := vmlinux vmlinux.bin vmlinux.bin.gz \
8 head_32.o misc_32.o piggy.o
9EXTRA_AFLAGS := -traditional
10
11OBJECTS = $(obj)/head_32.o $(obj)/misc_32.o
12
13ifdef CONFIG_SH_STANDARD_BIOS
14OBJECTS += $(obj)/../../kernel/sh_bios.o
15endif
16
17#
18# IMAGE_OFFSET is the load offset of the compression loader
19#
20IMAGE_OFFSET := $(shell /bin/bash -c 'printf "0x%08x" \
21 $$[$(CONFIG_PAGE_OFFSET) + \
22 $(CONFIG_MEMORY_START) + \
23 $(CONFIG_BOOT_LINK_OFFSET)]')
24
25LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
26
27LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -e startup -T $(obj)/../../kernel/vmlinux.lds
28
29$(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o $(LIBGCC) FORCE
30 $(call if_changed,ld)
31 @:
32
33$(obj)/vmlinux.bin: vmlinux FORCE
34 $(call if_changed,objcopy)
35
36$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
37 $(call if_changed,gzip)
38
39LDFLAGS_piggy.o := -r --format binary --oformat elf32-sh-linux -T
40OBJCOPYFLAGS += -R .empty_zero_page
41
42$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE
43 $(call if_changed,ld)
diff --git a/arch/sh64/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile_64
index 9cd216718856..4334f2b86d8f 100644
--- a/arch/sh64/boot/compressed/Makefile
+++ b/arch/sh/boot/compressed/Makefile_64
@@ -1,32 +1,32 @@
1# 1#
2# linux/arch/sh64/boot/compressed/Makefile 2# arch/sh/boot/compressed/Makefile_64
3# 3#
4# This file is subject to the terms and conditions of the GNU General Public 4# create a compressed vmlinux image from the original vmlinux
5# License. See the file "COPYING" in the main directory of this archive
6# for more details.
7# 5#
8# Copyright (C) 2002 Stuart Menefy 6# Copyright (C) 2002 Stuart Menefy
9# Copyright (C) 2004 Paul Mundt 7# Copyright (C) 2004 Paul Mundt
10# 8#
11# create a compressed vmlinux image from the original vmlinux 9# This file is subject to the terms and conditions of the GNU General Public
10# License. See the file "COPYING" in the main directory of this archive
11# for more details.
12# 12#
13 13
14targets := vmlinux vmlinux.bin vmlinux.bin.gz \ 14targets := vmlinux vmlinux.bin vmlinux.bin.gz \
15 head.o misc.o cache.o piggy.o vmlinux.lds 15 head_64.o misc_64.o cache.o piggy.o
16
17EXTRA_AFLAGS := -traditional 16EXTRA_AFLAGS := -traditional
18 17
19OBJECTS := $(obj)/head.o $(obj)/misc.o $(obj)/cache.o 18OBJECTS := $(obj)/vmlinux_64.lds $(obj)/head_64.o $(obj)/misc_64.o \
19 $(obj)/cache.o
20 20
21# 21#
22# ZIMAGE_OFFSET is the load offset of the compression loader 22# ZIMAGE_OFFSET is the load offset of the compression loader
23# (4M for the kernel plus 64K for this loader) 23# (4M for the kernel plus 64K for this loader)
24# 24#
25ZIMAGE_OFFSET = $(shell printf "0x%8x" $$[$(CONFIG_MEMORY_START)+0x400000+0x10000]) 25ZIMAGE_OFFSET := $(shell /bin/bash -c 'printf "0x%08x" \
26 $$[$(CONFIG_PAGE_OFFSET)+0x400000+0x10000]')
26 27
27LDFLAGS_vmlinux := -Ttext $(ZIMAGE_OFFSET) -e startup \ 28LDFLAGS_vmlinux := -Ttext $(ZIMAGE_OFFSET) -e startup \
28 -T $(obj)/../../kernel/vmlinux.lds \ 29 -T $(obj)/../../kernel/vmlinux.lds
29 --no-warn-mismatch
30 30
31$(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o FORCE 31$(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o FORCE
32 $(call if_changed,ld) 32 $(call if_changed,ld)
@@ -41,6 +41,5 @@ $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
41LDFLAGS_piggy.o := -r --format binary --oformat elf32-sh64-linux -T 41LDFLAGS_piggy.o := -r --format binary --oformat elf32-sh64-linux -T
42OBJCOPYFLAGS += -R .empty_zero_page 42OBJCOPYFLAGS += -R .empty_zero_page
43 43
44$(obj)/piggy.o: $(obj)/vmlinux.lds $(obj)/vmlinux.bin.gz FORCE 44$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE
45 $(call if_changed,ld) 45 $(call if_changed,ld)
46
diff --git a/arch/sh/boot/compressed/cache.c b/arch/sh/boot/compressed/cache.c
new file mode 100644
index 000000000000..e27fc74f228c
--- /dev/null
+++ b/arch/sh/boot/compressed/cache.c
@@ -0,0 +1,12 @@
1int cache_control(unsigned int command)
2{
3 volatile unsigned int *p = (volatile unsigned int *) 0x80000000;
4 int i;
5
6 for (i = 0; i < (32 * 1024); i += 32) {
7 (void)*p;
8 p += (32 / sizeof (int));
9 }
10
11 return 0;
12}
diff --git a/arch/sh/boot/compressed/head.S b/arch/sh/boot/compressed/head_32.S
index a8399b013729..a8399b013729 100644
--- a/arch/sh/boot/compressed/head.S
+++ b/arch/sh/boot/compressed/head_32.S
diff --git a/arch/sh64/boot/compressed/head.S b/arch/sh/boot/compressed/head_64.S
index 82040b1a29cf..1d4ecbfc767c 100644
--- a/arch/sh64/boot/compressed/head.S
+++ b/arch/sh/boot/compressed/head_64.S
@@ -13,11 +13,10 @@
13 * Modification for compressed loader: 13 * Modification for compressed loader:
14 * Copyright (C) 2002 Stuart Menefy (stuart.menefy@st.com) 14 * Copyright (C) 2002 Stuart Menefy (stuart.menefy@st.com)
15 */ 15 */
16
17#include <linux/linkage.h> 16#include <linux/linkage.h>
18#include <asm/registers.h>
19#include <asm/cache.h> 17#include <asm/cache.h>
20#include <asm/mmu_context.h> 18#include <asm/cpu/mmu_context.h>
19#include <asm/cpu/registers.h>
21 20
22/* 21/*
23 * Fixed TLB entries to identity map the beginning of RAM 22 * Fixed TLB entries to identity map the beginning of RAM
@@ -51,14 +50,14 @@ startup:
51 * uninitialized target registers. 50 * uninitialized target registers.
52 * This must be executed before the first branch. 51 * This must be executed before the first branch.
53 */ 52 */
54 ptabs/u ZERO, tr0 53 ptabs/u r63, tr0
55 ptabs/u ZERO, tr1 54 ptabs/u r63, tr1
56 ptabs/u ZERO, tr2 55 ptabs/u r63, tr2
57 ptabs/u ZERO, tr3 56 ptabs/u r63, tr3
58 ptabs/u ZERO, tr4 57 ptabs/u r63, tr4
59 ptabs/u ZERO, tr5 58 ptabs/u r63, tr5
60 ptabs/u ZERO, tr6 59 ptabs/u r63, tr6
61 ptabs/u ZERO, tr7 60 ptabs/u r63, tr7
62 synci 61 synci
63 62
64 /* 63 /*
@@ -69,7 +68,7 @@ startup:
69 pta 1f, tr1 68 pta 1f, tr1
70 movi ITLB_FIXED, r21 69 movi ITLB_FIXED, r21
71 movi ITLB_LAST_VAR_UNRESTRICTED+TLB_STEP, r22 70 movi ITLB_LAST_VAR_UNRESTRICTED+TLB_STEP, r22
721: putcfg r21, 0, ZERO /* Clear MMUIR[n].PTEH.V */ 711: putcfg r21, 0, r63 /* Clear MMUIR[n].PTEH.V */
73 addi r21, TLB_STEP, r21 72 addi r21, TLB_STEP, r21
74 bne r21, r22, tr1 73 bne r21, r22, tr1
75 74
@@ -77,7 +76,7 @@ startup:
77 pta 1f, tr1 76 pta 1f, tr1
78 movi DTLB_FIXED, r21 77 movi DTLB_FIXED, r21
79 movi DTLB_LAST_VAR_UNRESTRICTED+TLB_STEP, r22 78 movi DTLB_LAST_VAR_UNRESTRICTED+TLB_STEP, r22
801: putcfg r21, 0, ZERO /* Clear MMUDR[n].PTEH.V */ 791: putcfg r21, 0, r63 /* Clear MMUDR[n].PTEH.V */
81 addi r21, TLB_STEP, r21 80 addi r21, TLB_STEP, r21
82 bne r21, r22, tr1 81 bne r21, r22, tr1
83 82
@@ -133,7 +132,7 @@ startup:
133 pt 1f, tr1 132 pt 1f, tr1
134 movi datalabel __bss_start, r22 133 movi datalabel __bss_start, r22
135 movi datalabel _end, r23 134 movi datalabel _end, r23
1361: st.l r22, 0, ZERO 1351: st.l r22, 0, r63
137 addi r22, 4, r22 136 addi r22, 4, r22
138 bne r22, r23, tr1 137 bne r22, r23, tr1
139 138
@@ -161,4 +160,4 @@ startup:
161 160
162 /* Shouldn't return here, but just in case, loop forever */ 161 /* Shouldn't return here, but just in case, loop forever */
163 pt 1f, tr0 162 pt 1f, tr0
1641: blink tr0, ZERO 1631: blink tr0, r63
diff --git a/arch/sh/boot/compressed/misc.c b/arch/sh/boot/compressed/misc_32.c
index df65e305acf7..adcea31e663e 100644
--- a/arch/sh/boot/compressed/misc.c
+++ b/arch/sh/boot/compressed/misc_32.c
@@ -230,7 +230,10 @@ long* stack_start = &user_stack[STACK_SIZE];
230void decompress_kernel(void) 230void decompress_kernel(void)
231{ 231{
232 output_data = 0; 232 output_data = 0;
233 output_ptr = P2SEGADDR((unsigned long)&_text+PAGE_SIZE); 233 output_ptr = PHYSADDR((unsigned long)&_text+PAGE_SIZE);
234#ifdef CONFIG_29BIT
235 output_ptr |= P2SEG;
236#endif
234 free_mem_ptr = (unsigned long)&_end; 237 free_mem_ptr = (unsigned long)&_end;
235 free_mem_end_ptr = free_mem_ptr + HEAP_SIZE; 238 free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
236 239
diff --git a/arch/sh64/boot/compressed/misc.c b/arch/sh/boot/compressed/misc_64.c
index aea00c53ce29..a006ef89b9dd 100644
--- a/arch/sh64/boot/compressed/misc.c
+++ b/arch/sh/boot/compressed/misc_64.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/sh64/boot/compressed/misc.c 2 * arch/sh/boot/compressed/misc_64.c
3 * 3 *
4 * This is a collection of several routines from gzip-1.0.3 4 * This is a collection of several routines from gzip-1.0.3
5 * adapted for Linux. 5 * adapted for Linux.
diff --git a/arch/sh64/boot/compressed/vmlinux.lds.S b/arch/sh/boot/compressed/vmlinux_64.lds
index 59c2ef4aeda5..59c2ef4aeda5 100644
--- a/arch/sh64/boot/compressed/vmlinux.lds.S
+++ b/arch/sh/boot/compressed/vmlinux_64.lds
diff --git a/arch/sh/cchips/voyagergx/Makefile b/arch/sh/cchips/voyagergx/Makefile
deleted file mode 100644
index f73963cb3744..000000000000
--- a/arch/sh/cchips/voyagergx/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
1#
2# Makefile for VoyagerGX
3#
4
5obj-y := irq.o setup.o
6
7obj-$(CONFIG_USB_OHCI_HCD) += consistent.o
8
9EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/cchips/voyagergx/consistent.c b/arch/sh/cchips/voyagergx/consistent.c
deleted file mode 100644
index 07e8b9c5a531..000000000000
--- a/arch/sh/cchips/voyagergx/consistent.c
+++ /dev/null
@@ -1,121 +0,0 @@
1/*
2 * arch/sh/cchips/voyagergx/consistent.c
3 *
4 * Copyright (C) 2004 Paul Mundt
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/mm.h>
11#include <linux/dma-mapping.h>
12#include <linux/slab.h>
13#include <linux/list.h>
14#include <linux/types.h>
15#include <linux/module.h>
16#include <linux/device.h>
17#include <asm/io.h>
18
19
20struct voya_alloc_entry {
21 struct list_head list;
22 unsigned long ofs;
23 unsigned long len;
24};
25
26static DEFINE_SPINLOCK(voya_list_lock);
27static LIST_HEAD(voya_alloc_list);
28
29#define OHCI_SRAM_START 0xb0000000
30#define OHCI_HCCA_SIZE 0x100
31#define OHCI_SRAM_SIZE 0x10000
32
33#define VOYAGER_OHCI_NAME "voyager-ohci"
34
35void *voyagergx_consistent_alloc(struct device *dev, size_t size,
36 dma_addr_t *handle, gfp_t flag)
37{
38 struct list_head *list = &voya_alloc_list;
39 struct voya_alloc_entry *entry;
40 unsigned long start, end;
41 unsigned long flags;
42
43 /*
44 * The SM501 contains an integrated 8051 with its own SRAM.
45 * Devices within the cchip can all hook into the 8051 SRAM.
46 * We presently use this for the OHCI.
47 *
48 * Everything else goes through consistent_alloc().
49 */
50 if (!dev || strcmp(dev->driver->name, VOYAGER_OHCI_NAME))
51 return NULL;
52
53 start = OHCI_SRAM_START + OHCI_HCCA_SIZE;
54
55 entry = kmalloc(sizeof(struct voya_alloc_entry), GFP_ATOMIC);
56 if (!entry)
57 return ERR_PTR(-ENOMEM);
58
59 entry->len = (size + 15) & ~15;
60
61 /*
62 * The basis for this allocator is dwmw2's malloc.. the
63 * Matrox allocator :-)
64 */
65 spin_lock_irqsave(&voya_list_lock, flags);
66 list_for_each(list, &voya_alloc_list) {
67 struct voya_alloc_entry *p;
68
69 p = list_entry(list, struct voya_alloc_entry, list);
70
71 if (p->ofs - start >= size)
72 goto out;
73
74 start = p->ofs + p->len;
75 }
76
77 end = start + (OHCI_SRAM_SIZE - OHCI_HCCA_SIZE);
78 list = &voya_alloc_list;
79
80 if (end - start >= size) {
81out:
82 entry->ofs = start;
83 list_add_tail(&entry->list, list);
84 spin_unlock_irqrestore(&voya_list_lock, flags);
85
86 *handle = start;
87 return (void *)start;
88 }
89
90 kfree(entry);
91 spin_unlock_irqrestore(&voya_list_lock, flags);
92
93 return ERR_PTR(-EINVAL);
94}
95
96int voyagergx_consistent_free(struct device *dev, size_t size,
97 void *vaddr, dma_addr_t handle)
98{
99 struct voya_alloc_entry *entry;
100 unsigned long flags;
101
102 if (!dev || strcmp(dev->driver->name, VOYAGER_OHCI_NAME))
103 return -EINVAL;
104
105 spin_lock_irqsave(&voya_list_lock, flags);
106 list_for_each_entry(entry, &voya_alloc_list, list) {
107 if (entry->ofs != handle)
108 continue;
109
110 list_del(&entry->list);
111 kfree(entry);
112
113 break;
114 }
115 spin_unlock_irqrestore(&voya_list_lock, flags);
116
117 return 0;
118}
119
120EXPORT_SYMBOL(voyagergx_consistent_alloc);
121EXPORT_SYMBOL(voyagergx_consistent_free);
diff --git a/arch/sh/cchips/voyagergx/irq.c b/arch/sh/cchips/voyagergx/irq.c
deleted file mode 100644
index ade303876841..000000000000
--- a/arch/sh/cchips/voyagergx/irq.c
+++ /dev/null
@@ -1,101 +0,0 @@
1/* -------------------------------------------------------------------- */
2/* setup_voyagergx.c: */
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., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 Copyright 2003 (c) Lineo uSolutions,Inc.
19*/
20#include <linux/interrupt.h>
21#include <linux/init.h>
22#include <linux/io.h>
23#include <asm/voyagergx.h>
24#include <asm/rts7751r2d.h>
25
26enum {
27 UNUSED = 0,
28
29 /* voyager specific interrupt sources */
30 UP, G54, G53, G52, G51, G50, G49, G48,
31 I2C, PW, DMA, PCI, I2S, AC, US,
32 U1, U0, CV, MC, S1, S0,
33 UH, TWOD, ZD, PV, CI,
34};
35
36static struct intc_vect vectors[] __initdata = {
37 INTC_IRQ(UP, IRQ_SM501_UP), INTC_IRQ(G54, IRQ_SM501_G54),
38 INTC_IRQ(G53, IRQ_SM501_G53), INTC_IRQ(G52, IRQ_SM501_G52),
39 INTC_IRQ(G51, IRQ_SM501_G51), INTC_IRQ(G50, IRQ_SM501_G50),
40 INTC_IRQ(G49, IRQ_SM501_G49), INTC_IRQ(G48, IRQ_SM501_G48),
41 INTC_IRQ(I2C, IRQ_SM501_I2C), INTC_IRQ(PW, IRQ_SM501_PW),
42 INTC_IRQ(DMA, IRQ_SM501_DMA), INTC_IRQ(PCI, IRQ_SM501_PCI),
43 INTC_IRQ(I2S, IRQ_SM501_I2S), INTC_IRQ(AC, IRQ_SM501_AC),
44 INTC_IRQ(US, IRQ_SM501_US), INTC_IRQ(U1, IRQ_SM501_U1),
45 INTC_IRQ(U0, IRQ_SM501_U0), INTC_IRQ(CV, IRQ_SM501_CV),
46 INTC_IRQ(MC, IRQ_SM501_MC), INTC_IRQ(S1, IRQ_SM501_S1),
47 INTC_IRQ(S0, IRQ_SM501_S0), INTC_IRQ(UH, IRQ_SM501_UH),
48 INTC_IRQ(TWOD, IRQ_SM501_2D), INTC_IRQ(ZD, IRQ_SM501_ZD),
49 INTC_IRQ(PV, IRQ_SM501_PV), INTC_IRQ(CI, IRQ_SM501_CI),
50};
51
52static struct intc_mask_reg mask_registers[] __initdata = {
53 { VOYAGER_INT_MASK, 0, 32, /* "Interrupt Mask", MMIO_base + 0x30 */
54 { UP, G54, G53, G52, G51, G50, G49, G48,
55 I2C, PW, 0, DMA, PCI, I2S, AC, US,
56 0, 0, U1, U0, CV, MC, S1, S0,
57 0, UH, 0, 0, TWOD, ZD, PV, CI } },
58};
59
60static DECLARE_INTC_DESC(intc_desc, "voyagergx", vectors,
61 NULL, NULL, mask_registers, NULL, NULL);
62
63static unsigned int voyagergx_stat2irq[32] = {
64 IRQ_SM501_CI, IRQ_SM501_PV, IRQ_SM501_ZD, IRQ_SM501_2D,
65 0, 0, IRQ_SM501_UH, 0,
66 IRQ_SM501_S0, IRQ_SM501_S1, IRQ_SM501_MC, IRQ_SM501_CV,
67 IRQ_SM501_U0, IRQ_SM501_U1, 0, 0,
68 IRQ_SM501_US, IRQ_SM501_AC, IRQ_SM501_I2S, IRQ_SM501_PCI,
69 IRQ_SM501_DMA, 0, IRQ_SM501_PW, IRQ_SM501_I2C,
70 IRQ_SM501_G48, IRQ_SM501_G49, IRQ_SM501_G50, IRQ_SM501_G51,
71 IRQ_SM501_G52, IRQ_SM501_G53, IRQ_SM501_G54, IRQ_SM501_UP
72};
73
74static void voyagergx_irq_demux(unsigned int irq, struct irq_desc *desc)
75{
76 unsigned long intv = ctrl_inl(INT_STATUS);
77 struct irq_desc *ext_desc;
78 unsigned int ext_irq;
79 unsigned int k = 0;
80
81 while (intv) {
82 ext_irq = voyagergx_stat2irq[k];
83 if (ext_irq && (intv & 1)) {
84 ext_desc = irq_desc + ext_irq;
85 handle_level_irq(ext_irq, ext_desc);
86 }
87 intv >>= 1;
88 k++;
89 }
90}
91
92void __init setup_voyagergx_irq(void)
93{
94 printk(KERN_INFO "VoyagerGX on irq %d (mapped into %d to %d)\n",
95 IRQ_VOYAGER,
96 VOYAGER_IRQ_BASE,
97 VOYAGER_IRQ_BASE + VOYAGER_IRQ_NUM - 1);
98
99 register_intc_controller(&intc_desc);
100 set_irq_chained_handler(IRQ_VOYAGER, voyagergx_irq_demux);
101}
diff --git a/arch/sh/cchips/voyagergx/setup.c b/arch/sh/cchips/voyagergx/setup.c
deleted file mode 100644
index 33f03027c193..000000000000
--- a/arch/sh/cchips/voyagergx/setup.c
+++ /dev/null
@@ -1,37 +0,0 @@
1/*
2 * arch/sh/cchips/voyagergx/setup.c
3 *
4 * Setup routines for VoyagerGX cchip.
5 *
6 * Copyright (C) 2003 Lineo uSolutions, 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/init.h>
14#include <linux/module.h>
15#include <asm/io.h>
16#include <asm/voyagergx.h>
17
18static int __init setup_voyagergx(void)
19{
20 unsigned long val;
21
22 val = readl((void __iomem *)DRAM_CTRL);
23 val |= (DRAM_CTRL_CPU_COLUMN_SIZE_256 |
24 DRAM_CTRL_CPU_ACTIVE_PRECHARGE |
25 DRAM_CTRL_CPU_RESET |
26 DRAM_CTRL_REFRESH_COMMAND |
27 DRAM_CTRL_BLOCK_WRITE_TIME |
28 DRAM_CTRL_BLOCK_WRITE_PRECHARGE |
29 DRAM_CTRL_ACTIVE_PRECHARGE |
30 DRAM_CTRL_RESET |
31 DRAM_CTRL_REMAIN_ACTIVE);
32 writel(val, (void __iomem *)DRAM_CTRL);
33
34 return 0;
35}
36
37module_init(setup_voyagergx);
diff --git a/arch/sh64/configs/cayman_defconfig b/arch/sh/configs/cayman_defconfig
index 75552bb01405..a05b278d72f5 100644
--- a/arch/sh64/configs/cayman_defconfig
+++ b/arch/sh/configs/cayman_defconfig
@@ -1,18 +1,22 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.24-rc1 3# Linux kernel version: 2.6.24-rc3
4# Fri Nov 2 14:35:27 2007 4# Fri Nov 23 14:15:55 2007
5# 5#
6CONFIG_SUPERH=y 6CONFIG_SUPERH=y
7# CONFIG_SUPERH32 is not set
7CONFIG_SUPERH64=y 8CONFIG_SUPERH64=y
8CONFIG_MMU=y
9CONFIG_QUICKLIST=y
10CONFIG_RWSEM_GENERIC_SPINLOCK=y 9CONFIG_RWSEM_GENERIC_SPINLOCK=y
11CONFIG_GENERIC_FIND_NEXT_BIT=y 10CONFIG_GENERIC_FIND_NEXT_BIT=y
12CONFIG_GENERIC_HWEIGHT=y 11CONFIG_GENERIC_HWEIGHT=y
13CONFIG_GENERIC_CALIBRATE_DELAY=y
14CONFIG_GENERIC_HARDIRQS=y 12CONFIG_GENERIC_HARDIRQS=y
15CONFIG_GENERIC_IRQ_PROBE=y 13CONFIG_GENERIC_IRQ_PROBE=y
14CONFIG_GENERIC_CALIBRATE_DELAY=y
15# CONFIG_GENERIC_TIME is not set
16# CONFIG_GENERIC_CLOCKEVENTS is not set
17CONFIG_SYS_SUPPORTS_PCI=y
18CONFIG_STACKTRACE_SUPPORT=y
19CONFIG_LOCKDEP_SUPPORT=y
16# CONFIG_ARCH_HAS_ILOG2_U32 is not set 20# CONFIG_ARCH_HAS_ILOG2_U32 is not set
17# CONFIG_ARCH_HAS_ILOG2_U64 is not set 21# CONFIG_ARCH_HAS_ILOG2_U64 is not set
18CONFIG_ARCH_NO_VIRT_TO_BUS=y 22CONFIG_ARCH_NO_VIRT_TO_BUS=y
@@ -33,6 +37,7 @@ CONFIG_POSIX_MQUEUE=y
33# CONFIG_BSD_PROCESS_ACCT is not set 37# CONFIG_BSD_PROCESS_ACCT is not set
34# CONFIG_TASKSTATS is not set 38# CONFIG_TASKSTATS is not set
35# CONFIG_USER_NS is not set 39# CONFIG_USER_NS is not set
40# CONFIG_PID_NS is not set
36# CONFIG_AUDIT is not set 41# CONFIG_AUDIT is not set
37# CONFIG_IKCONFIG is not set 42# CONFIG_IKCONFIG is not set
38CONFIG_LOG_BUF_SHIFT=14 43CONFIG_LOG_BUF_SHIFT=14
@@ -45,7 +50,7 @@ CONFIG_SYSFS_DEPRECATED=y
45# CONFIG_BLK_DEV_INITRD is not set 50# CONFIG_BLK_DEV_INITRD is not set
46# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set 51# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
47CONFIG_SYSCTL=y 52CONFIG_SYSCTL=y
48# CONFIG_EMBEDDED is not set 53CONFIG_EMBEDDED=y
49CONFIG_UID16=y 54CONFIG_UID16=y
50CONFIG_SYSCTL_SYSCALL=y 55CONFIG_SYSCTL_SYSCALL=y
51CONFIG_KALLSYMS=y 56CONFIG_KALLSYMS=y
@@ -97,73 +102,153 @@ CONFIG_DEFAULT_IOSCHED="cfq"
97# 102#
98# System type 103# System type
99# 104#
100# CONFIG_SH_SIMULATOR is not set
101CONFIG_SH_CAYMAN=y
102# CONFIG_SH_HARP is not set
103CONFIG_CPU_SH5=y 105CONFIG_CPU_SH5=y
106# CONFIG_CPU_SUBTYPE_SH7619 is not set
107# CONFIG_CPU_SUBTYPE_SH7206 is not set
108# CONFIG_CPU_SUBTYPE_SH7705 is not set
109# CONFIG_CPU_SUBTYPE_SH7706 is not set
110# CONFIG_CPU_SUBTYPE_SH7707 is not set
111# CONFIG_CPU_SUBTYPE_SH7708 is not set
112# CONFIG_CPU_SUBTYPE_SH7709 is not set
113# CONFIG_CPU_SUBTYPE_SH7710 is not set
114# CONFIG_CPU_SUBTYPE_SH7712 is not set
115# CONFIG_CPU_SUBTYPE_SH7720 is not set
116# CONFIG_CPU_SUBTYPE_SH7750 is not set
117# CONFIG_CPU_SUBTYPE_SH7091 is not set
118# CONFIG_CPU_SUBTYPE_SH7750R is not set
119# CONFIG_CPU_SUBTYPE_SH7750S is not set
120# CONFIG_CPU_SUBTYPE_SH7751 is not set
121# CONFIG_CPU_SUBTYPE_SH7751R is not set
122# CONFIG_CPU_SUBTYPE_SH7760 is not set
123# CONFIG_CPU_SUBTYPE_SH4_202 is not set
124# CONFIG_CPU_SUBTYPE_SH7770 is not set
125# CONFIG_CPU_SUBTYPE_SH7780 is not set
126# CONFIG_CPU_SUBTYPE_SH7785 is not set
127# CONFIG_CPU_SUBTYPE_SHX3 is not set
128# CONFIG_CPU_SUBTYPE_SH7343 is not set
129# CONFIG_CPU_SUBTYPE_SH7722 is not set
104CONFIG_CPU_SUBTYPE_SH5_101=y 130CONFIG_CPU_SUBTYPE_SH5_101=y
105# CONFIG_CPU_SUBTYPE_SH5_103 is not set 131# CONFIG_CPU_SUBTYPE_SH5_103 is not set
106CONFIG_LITTLE_ENDIAN=y 132
107# CONFIG_BIG_ENDIAN is not set 133#
108CONFIG_SH_FPU=y 134# Memory management options
109# CONFIG_SH64_FPU_DENORM_FLUSH is not set 135#
110CONFIG_SH64_PGTABLE_2_LEVEL=y 136CONFIG_QUICKLIST=y
111# CONFIG_SH64_PGTABLE_3_LEVEL is not set 137CONFIG_MMU=y
138CONFIG_PAGE_OFFSET=0x20000000
139CONFIG_MEMORY_START=0x80000000
140CONFIG_MEMORY_SIZE=0x00400000
141CONFIG_32BIT=y
142CONFIG_ARCH_FLATMEM_ENABLE=y
143CONFIG_ARCH_SPARSEMEM_ENABLE=y
144CONFIG_ARCH_SPARSEMEM_DEFAULT=y
145CONFIG_MAX_ACTIVE_REGIONS=1
146CONFIG_ARCH_POPULATES_NODE_MAP=y
147CONFIG_ARCH_SELECT_MEMORY_MODEL=y
148CONFIG_PAGE_SIZE_4KB=y
149# CONFIG_PAGE_SIZE_8KB is not set
150# CONFIG_PAGE_SIZE_64KB is not set
112CONFIG_HUGETLB_PAGE_SIZE_64K=y 151CONFIG_HUGETLB_PAGE_SIZE_64K=y
152# CONFIG_HUGETLB_PAGE_SIZE_256K is not set
113# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set 153# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
154# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set
155# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set
114# CONFIG_HUGETLB_PAGE_SIZE_512MB is not set 156# CONFIG_HUGETLB_PAGE_SIZE_512MB is not set
157CONFIG_SELECT_MEMORY_MODEL=y
158CONFIG_FLATMEM_MANUAL=y
159# CONFIG_DISCONTIGMEM_MANUAL is not set
160# CONFIG_SPARSEMEM_MANUAL is not set
161CONFIG_FLATMEM=y
162CONFIG_FLAT_NODE_MEM_MAP=y
163CONFIG_SPARSEMEM_STATIC=y
164# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
165CONFIG_SPLIT_PTLOCK_CPUS=4
166CONFIG_RESOURCES_64BIT=y
167CONFIG_ZONE_DMA_FLAG=0
168CONFIG_NR_QUICK=2
169
170#
171# Cache configuration
172#
173# CONFIG_SH_DIRECT_MAPPED is not set
174# CONFIG_CACHE_WRITEBACK is not set
175# CONFIG_CACHE_WRITETHROUGH is not set
176CONFIG_CACHE_OFF=y
177
178#
179# Processor features
180#
181CONFIG_CPU_LITTLE_ENDIAN=y
182# CONFIG_CPU_BIG_ENDIAN is not set
183CONFIG_SH_FPU=y
184# CONFIG_SH64_FPU_DENORM_FLUSH is not set
115CONFIG_SH64_USER_MISALIGNED_FIXUP=y 185CONFIG_SH64_USER_MISALIGNED_FIXUP=y
186CONFIG_SH64_ID2815_WORKAROUND=y
187CONFIG_CPU_HAS_FPU=y
116 188
117# 189#
118# Memory options 190# Board support
119# 191#
120CONFIG_CACHED_MEMORY_OFFSET=0x20000000 192CONFIG_SH_CAYMAN=y
121CONFIG_MEMORY_START=0x80000000
122CONFIG_MEMORY_SIZE_IN_MB=128
123 193
124# 194#
125# Cache options 195# Timer and clock configuration
126# 196#
127CONFIG_DCACHE_WRITE_BACK=y 197CONFIG_SH_TIMER_IRQ=16
128# CONFIG_DCACHE_WRITE_THROUGH is not set 198CONFIG_SH_PCLK_FREQ=50000000
129# CONFIG_DCACHE_DISABLED is not set 199# CONFIG_TICK_ONESHOT is not set
130# CONFIG_ICACHE_DISABLED is not set
131CONFIG_PCIDEVICE_MEMORY_START=C0000000
132CONFIG_DEVICE_MEMORY_START=E0000000
133CONFIG_FLASH_MEMORY_START=0x00000000
134CONFIG_PCI_BLOCK_START=0x40000000
135 200
136# 201#
137# CPU Subtype specific options 202# CPU Frequency scaling
203#
204# CONFIG_CPU_FREQ is not set
205
206#
207# DMA support
138# 208#
139CONFIG_SH64_ID2815_WORKAROUND=y
140 209
141# 210#
142# Misc options 211# Companion Chips
212#
213
214#
215# Additional SuperH Device Drivers
143# 216#
144CONFIG_HEARTBEAT=y 217CONFIG_HEARTBEAT=y
145CONFIG_HDSP253_LED=y 218# CONFIG_PUSH_SWITCH is not set
146# CONFIG_SH_DMA is not set 219
220#
221# Kernel features
222#
223# CONFIG_HZ_100 is not set
224CONFIG_HZ_250=y
225# CONFIG_HZ_300 is not set
226# CONFIG_HZ_1000 is not set
227CONFIG_HZ=250
228# CONFIG_KEXEC is not set
229# CONFIG_CRASH_DUMP is not set
230# CONFIG_PREEMPT_NONE is not set
231# CONFIG_PREEMPT_VOLUNTARY is not set
147CONFIG_PREEMPT=y 232CONFIG_PREEMPT=y
148CONFIG_SELECT_MEMORY_MODEL=y 233CONFIG_PREEMPT_BKL=y
149CONFIG_FLATMEM_MANUAL=y 234CONFIG_GUSA=y
150# CONFIG_DISCONTIGMEM_MANUAL is not set 235
151# CONFIG_SPARSEMEM_MANUAL is not set 236#
152CONFIG_FLATMEM=y 237# Boot options
153CONFIG_FLAT_NODE_MEM_MAP=y 238#
154# CONFIG_SPARSEMEM_STATIC is not set 239CONFIG_ZERO_PAGE_OFFSET=0x00001000
155# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set 240CONFIG_BOOT_LINK_OFFSET=0x00800000
156CONFIG_SPLIT_PTLOCK_CPUS=4 241# CONFIG_CMDLINE_BOOL is not set
157# CONFIG_RESOURCES_64BIT is not set
158CONFIG_ZONE_DMA_FLAG=0
159CONFIG_NR_QUICK=1
160 242
161# 243#
162# Bus options (PCI, PCMCIA, EISA, MCA, ISA) 244# Bus options
163# 245#
164CONFIG_PCI=y 246CONFIG_PCI=y
165CONFIG_SH_PCIDMA_NONCOHERENT=y 247CONFIG_SH_PCIDMA_NONCOHERENT=y
248CONFIG_PCI_AUTO=y
249CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
166# CONFIG_ARCH_SUPPORTS_MSI is not set 250# CONFIG_ARCH_SUPPORTS_MSI is not set
251CONFIG_PCI_LEGACY=y
167# CONFIG_PCI_DEBUG is not set 252# CONFIG_PCI_DEBUG is not set
168# CONFIG_PCCARD is not set 253# CONFIG_PCCARD is not set
169# CONFIG_HOTPLUG_PCI is not set 254# CONFIG_HOTPLUG_PCI is not set
@@ -354,11 +439,7 @@ CONFIG_SCSI_LOWLEVEL=y
354# CONFIG_SCSI_INITIO is not set 439# CONFIG_SCSI_INITIO is not set
355# CONFIG_SCSI_INIA100 is not set 440# CONFIG_SCSI_INIA100 is not set
356# CONFIG_SCSI_STEX is not set 441# CONFIG_SCSI_STEX is not set
357CONFIG_SCSI_SYM53C8XX_2=y 442# CONFIG_SCSI_SYM53C8XX_2 is not set
358CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
359CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
360CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
361CONFIG_SCSI_SYM53C8XX_MMIO=y
362# CONFIG_SCSI_QLOGIC_1280 is not set 443# CONFIG_SCSI_QLOGIC_1280 is not set
363# CONFIG_SCSI_QLA_FC is not set 444# CONFIG_SCSI_QLA_FC is not set
364# CONFIG_SCSI_QLA_ISCSI is not set 445# CONFIG_SCSI_QLA_ISCSI is not set
@@ -391,6 +472,7 @@ CONFIG_NETDEVICES=y
391# CONFIG_PHYLIB is not set 472# CONFIG_PHYLIB is not set
392CONFIG_NET_ETHERNET=y 473CONFIG_NET_ETHERNET=y
393# CONFIG_MII is not set 474# CONFIG_MII is not set
475# CONFIG_AX88796 is not set
394# CONFIG_STNIC is not set 476# CONFIG_STNIC is not set
395# CONFIG_HAPPYMEAL is not set 477# CONFIG_HAPPYMEAL is not set
396# CONFIG_SUNGEM is not set 478# CONFIG_SUNGEM is not set
@@ -398,40 +480,14 @@ CONFIG_NET_ETHERNET=y
398# CONFIG_NET_VENDOR_3COM is not set 480# CONFIG_NET_VENDOR_3COM is not set
399# CONFIG_SMC91X is not set 481# CONFIG_SMC91X is not set
400# CONFIG_SMC911X is not set 482# CONFIG_SMC911X is not set
401CONFIG_NET_TULIP=y 483# CONFIG_NET_TULIP is not set
402# CONFIG_DE2104X is not set
403CONFIG_TULIP=y
404# CONFIG_TULIP_MWI is not set
405# CONFIG_TULIP_MMIO is not set
406# CONFIG_TULIP_NAPI is not set
407# CONFIG_DE4X5 is not set
408# CONFIG_WINBOND_840 is not set
409# CONFIG_DM9102 is not set
410# CONFIG_ULI526X is not set
411# CONFIG_HP100 is not set 484# CONFIG_HP100 is not set
412# CONFIG_IBM_NEW_EMAC_ZMII is not set 485# CONFIG_IBM_NEW_EMAC_ZMII is not set
413# CONFIG_IBM_NEW_EMAC_RGMII is not set 486# CONFIG_IBM_NEW_EMAC_RGMII is not set
414# CONFIG_IBM_NEW_EMAC_TAH is not set 487# CONFIG_IBM_NEW_EMAC_TAH is not set
415# CONFIG_IBM_NEW_EMAC_EMAC4 is not set 488# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
416CONFIG_NET_PCI=y 489# CONFIG_NET_PCI is not set
417# CONFIG_PCNET32 is not set
418# CONFIG_AMD8111_ETH is not set
419# CONFIG_ADAPTEC_STARFIRE is not set
420# CONFIG_B44 is not set 490# CONFIG_B44 is not set
421# CONFIG_FORCEDETH is not set
422# CONFIG_EEPRO100 is not set
423# CONFIG_E100 is not set
424# CONFIG_FEALNX is not set
425# CONFIG_NATSEMI is not set
426# CONFIG_NE2K_PCI is not set
427# CONFIG_8139CP is not set
428# CONFIG_8139TOO is not set
429# CONFIG_SIS900 is not set
430# CONFIG_EPIC100 is not set
431# CONFIG_SUNDANCE is not set
432# CONFIG_TLAN is not set
433# CONFIG_VIA_RHINE is not set
434# CONFIG_SC92031 is not set
435CONFIG_NETDEV_1000=y 491CONFIG_NETDEV_1000=y
436# CONFIG_ACENIC is not set 492# CONFIG_ACENIC is not set
437# CONFIG_DL2K is not set 493# CONFIG_DL2K is not set
@@ -492,7 +548,7 @@ CONFIG_INPUT=y
492# Userland interfaces 548# Userland interfaces
493# 549#
494CONFIG_INPUT_MOUSEDEV=y 550CONFIG_INPUT_MOUSEDEV=y
495CONFIG_INPUT_MOUSEDEV_PSAUX=y 551# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
496CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 552CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
497CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 553CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
498# CONFIG_INPUT_JOYDEV is not set 554# CONFIG_INPUT_JOYDEV is not set
@@ -502,24 +558,8 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
502# 558#
503# Input Device Drivers 559# Input Device Drivers
504# 560#
505CONFIG_INPUT_KEYBOARD=y 561# CONFIG_INPUT_KEYBOARD is not set
506CONFIG_KEYBOARD_ATKBD=y 562# CONFIG_INPUT_MOUSE is not set
507# CONFIG_KEYBOARD_SUNKBD is not set
508# CONFIG_KEYBOARD_LKKBD is not set
509# CONFIG_KEYBOARD_XTKBD is not set
510# CONFIG_KEYBOARD_NEWTON is not set
511# CONFIG_KEYBOARD_STOWAWAY is not set
512CONFIG_INPUT_MOUSE=y
513CONFIG_MOUSE_PS2=y
514CONFIG_MOUSE_PS2_ALPS=y
515CONFIG_MOUSE_PS2_LOGIPS2PP=y
516CONFIG_MOUSE_PS2_SYNAPTICS=y
517CONFIG_MOUSE_PS2_LIFEBOOK=y
518CONFIG_MOUSE_PS2_TRACKPOINT=y
519# CONFIG_MOUSE_PS2_TOUCHKIT is not set
520# CONFIG_MOUSE_SERIAL is not set
521# CONFIG_MOUSE_APPLETOUCH is not set
522# CONFIG_MOUSE_VSXXXAA is not set
523# CONFIG_INPUT_JOYSTICK is not set 563# CONFIG_INPUT_JOYSTICK is not set
524# CONFIG_INPUT_TABLET is not set 564# CONFIG_INPUT_TABLET is not set
525# CONFIG_INPUT_TOUCHSCREEN is not set 565# CONFIG_INPUT_TOUCHSCREEN is not set
@@ -528,12 +568,7 @@ CONFIG_MOUSE_PS2_TRACKPOINT=y
528# 568#
529# Hardware I/O ports 569# Hardware I/O ports
530# 570#
531CONFIG_SERIO=y 571# CONFIG_SERIO is not set
532CONFIG_SERIO_I8042=y
533CONFIG_SERIO_SERPORT=y
534# CONFIG_SERIO_PCIPS2 is not set
535CONFIG_SERIO_LIBPS2=y
536# CONFIG_SERIO_RAW is not set
537# CONFIG_GAMEPORT is not set 572# CONFIG_GAMEPORT is not set
538 573
539# 574#
@@ -553,11 +588,7 @@ CONFIG_HW_CONSOLE=y
553# 588#
554# Non-8250 serial port support 589# Non-8250 serial port support
555# 590#
556CONFIG_SERIAL_SH_SCI=y 591# CONFIG_SERIAL_SH_SCI is not set
557CONFIG_SERIAL_SH_SCI_NR_UARTS=2
558CONFIG_SERIAL_SH_SCI_CONSOLE=y
559CONFIG_SERIAL_CORE=y
560CONFIG_SERIAL_CORE_CONSOLE=y
561# CONFIG_SERIAL_JSM is not set 592# CONFIG_SERIAL_JSM is not set
562CONFIG_UNIX98_PTYS=y 593CONFIG_UNIX98_PTYS=y
563CONFIG_LEGACY_PTYS=y 594CONFIG_LEGACY_PTYS=y
@@ -642,6 +673,7 @@ CONFIG_HWMON=y
642# CONFIG_SENSORS_ADT7470 is not set 673# CONFIG_SENSORS_ADT7470 is not set
643# CONFIG_SENSORS_ATXP1 is not set 674# CONFIG_SENSORS_ATXP1 is not set
644# CONFIG_SENSORS_DS1621 is not set 675# CONFIG_SENSORS_DS1621 is not set
676# CONFIG_SENSORS_I5K_AMB is not set
645# CONFIG_SENSORS_F71805F is not set 677# CONFIG_SENSORS_F71805F is not set
646# CONFIG_SENSORS_F71882FG is not set 678# CONFIG_SENSORS_F71882FG is not set
647# CONFIG_SENSORS_F75375S is not set 679# CONFIG_SENSORS_F75375S is not set
@@ -832,9 +864,9 @@ CONFIG_VIDEO_OUTPUT_CONTROL=y
832CONFIG_FB=y 864CONFIG_FB=y
833CONFIG_FIRMWARE_EDID=y 865CONFIG_FIRMWARE_EDID=y
834# CONFIG_FB_DDC is not set 866# CONFIG_FB_DDC is not set
835CONFIG_FB_CFB_FILLRECT=y 867# CONFIG_FB_CFB_FILLRECT is not set
836CONFIG_FB_CFB_COPYAREA=y 868# CONFIG_FB_CFB_COPYAREA is not set
837CONFIG_FB_CFB_IMAGEBLIT=y 869# CONFIG_FB_CFB_IMAGEBLIT is not set
838# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set 870# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
839# CONFIG_FB_SYS_FILLRECT is not set 871# CONFIG_FB_SYS_FILLRECT is not set
840# CONFIG_FB_SYS_COPYAREA is not set 872# CONFIG_FB_SYS_COPYAREA is not set
@@ -866,7 +898,7 @@ CONFIG_FB_MODE_HELPERS=y
866# CONFIG_FB_SAVAGE is not set 898# CONFIG_FB_SAVAGE is not set
867# CONFIG_FB_SIS is not set 899# CONFIG_FB_SIS is not set
868# CONFIG_FB_NEOMAGIC is not set 900# CONFIG_FB_NEOMAGIC is not set
869CONFIG_FB_KYRO=y 901# CONFIG_FB_KYRO is not set
870# CONFIG_FB_3DFX is not set 902# CONFIG_FB_3DFX is not set
871# CONFIG_FB_VOODOO1 is not set 903# CONFIG_FB_VOODOO1 is not set
872# CONFIG_FB_VT8623 is not set 904# CONFIG_FB_VT8623 is not set
@@ -1062,6 +1094,7 @@ CONFIG_INSTRUMENTATION=y
1062# 1094#
1063# Kernel hacking 1095# Kernel hacking
1064# 1096#
1097CONFIG_TRACE_IRQFLAGS_SUPPORT=y
1065# CONFIG_PRINTK_TIME is not set 1098# CONFIG_PRINTK_TIME is not set
1066CONFIG_ENABLE_WARN_DEPRECATED=y 1099CONFIG_ENABLE_WARN_DEPRECATED=y
1067CONFIG_ENABLE_MUST_CHECK=y 1100CONFIG_ENABLE_MUST_CHECK=y
@@ -1076,10 +1109,14 @@ CONFIG_SCHED_DEBUG=y
1076CONFIG_SCHEDSTATS=y 1109CONFIG_SCHEDSTATS=y
1077# CONFIG_TIMER_STATS is not set 1110# CONFIG_TIMER_STATS is not set
1078# CONFIG_DEBUG_SLAB is not set 1111# CONFIG_DEBUG_SLAB is not set
1112CONFIG_DEBUG_PREEMPT=y
1079# CONFIG_DEBUG_RT_MUTEXES is not set 1113# CONFIG_DEBUG_RT_MUTEXES is not set
1080# CONFIG_RT_MUTEX_TESTER is not set 1114# CONFIG_RT_MUTEX_TESTER is not set
1081# CONFIG_DEBUG_SPINLOCK is not set 1115# CONFIG_DEBUG_SPINLOCK is not set
1082# CONFIG_DEBUG_MUTEXES is not set 1116# CONFIG_DEBUG_MUTEXES is not set
1117# CONFIG_DEBUG_LOCK_ALLOC is not set
1118# CONFIG_PROVE_LOCKING is not set
1119# CONFIG_LOCK_STAT is not set
1083# CONFIG_DEBUG_SPINLOCK_SLEEP is not set 1120# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1084# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set 1121# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
1085# CONFIG_DEBUG_KOBJECT is not set 1122# CONFIG_DEBUG_KOBJECT is not set
@@ -1094,8 +1131,11 @@ CONFIG_FORCED_INLINING=y
1094# CONFIG_RCU_TORTURE_TEST is not set 1131# CONFIG_RCU_TORTURE_TEST is not set
1095# CONFIG_FAULT_INJECTION is not set 1132# CONFIG_FAULT_INJECTION is not set
1096# CONFIG_SAMPLES is not set 1133# CONFIG_SAMPLES is not set
1097# CONFIG_EARLY_PRINTK is not set 1134# CONFIG_SH_STANDARD_BIOS is not set
1098CONFIG_SH64_PROC_TLB=y 1135# CONFIG_EARLY_SCIF_CONSOLE is not set
1136# CONFIG_DEBUG_BOOTMEM is not set
1137# CONFIG_DEBUG_STACK_USAGE is not set
1138# CONFIG_4KSTACKS is not set
1099CONFIG_SH64_PROC_ASIDS=y 1139CONFIG_SH64_PROC_ASIDS=y
1100CONFIG_SH64_SR_WATCH=y 1140CONFIG_SH64_SR_WATCH=y
1101# CONFIG_POOR_MANS_STRACE is not set 1141# CONFIG_POOR_MANS_STRACE is not set
diff --git a/arch/sh/configs/hs7751rvoip_defconfig b/arch/sh/configs/hs7751rvoip_defconfig
deleted file mode 100644
index 5d9da5a02759..000000000000
--- a/arch/sh/configs/hs7751rvoip_defconfig
+++ /dev/null
@@ -1,908 +0,0 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.18
4# Tue Oct 3 13:04:52 2006
5#
6CONFIG_SUPERH=y
7CONFIG_RWSEM_GENERIC_SPINLOCK=y
8CONFIG_GENERIC_FIND_NEXT_BIT=y
9CONFIG_GENERIC_HWEIGHT=y
10CONFIG_GENERIC_HARDIRQS=y
11CONFIG_GENERIC_IRQ_PROBE=y
12CONFIG_GENERIC_CALIBRATE_DELAY=y
13CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
14
15#
16# Code maturity level options
17#
18CONFIG_EXPERIMENTAL=y
19CONFIG_BROKEN_ON_SMP=y
20CONFIG_LOCK_KERNEL=y
21CONFIG_INIT_ENV_ARG_LIMIT=32
22
23#
24# General setup
25#
26CONFIG_LOCALVERSION=""
27CONFIG_LOCALVERSION_AUTO=y
28CONFIG_SWAP=y
29CONFIG_SYSVIPC=y
30# CONFIG_IPC_NS is not set
31CONFIG_POSIX_MQUEUE=y
32CONFIG_BSD_PROCESS_ACCT=y
33# CONFIG_BSD_PROCESS_ACCT_V3 is not set
34# CONFIG_TASKSTATS is not set
35# CONFIG_UTS_NS is not set
36# CONFIG_AUDIT is not set
37# CONFIG_IKCONFIG is not set
38# CONFIG_RELAY is not set
39CONFIG_INITRAMFS_SOURCE=""
40# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
41CONFIG_SYSCTL=y
42CONFIG_EMBEDDED=y
43CONFIG_UID16=y
44# CONFIG_SYSCTL_SYSCALL is not set
45# CONFIG_KALLSYMS is not set
46CONFIG_HOTPLUG=y
47CONFIG_PRINTK=y
48CONFIG_BUG=y
49CONFIG_ELF_CORE=y
50CONFIG_BASE_FULL=y
51CONFIG_FUTEX=y
52CONFIG_EPOLL=y
53CONFIG_SHMEM=y
54CONFIG_SLAB=y
55CONFIG_VM_EVENT_COUNTERS=y
56CONFIG_RT_MUTEXES=y
57# CONFIG_TINY_SHMEM is not set
58CONFIG_BASE_SMALL=0
59# CONFIG_SLOB is not set
60
61#
62# Loadable module support
63#
64CONFIG_MODULES=y
65CONFIG_MODULE_UNLOAD=y
66# CONFIG_MODULE_FORCE_UNLOAD is not set
67# CONFIG_MODVERSIONS is not set
68# CONFIG_MODULE_SRCVERSION_ALL is not set
69CONFIG_KMOD=y
70
71#
72# Block layer
73#
74CONFIG_BLOCK=y
75# CONFIG_LBD is not set
76# CONFIG_BLK_DEV_IO_TRACE is not set
77# CONFIG_LSF is not set
78
79#
80# IO Schedulers
81#
82CONFIG_IOSCHED_NOOP=y
83CONFIG_IOSCHED_AS=y
84CONFIG_IOSCHED_DEADLINE=y
85CONFIG_IOSCHED_CFQ=y
86CONFIG_DEFAULT_AS=y
87# CONFIG_DEFAULT_DEADLINE is not set
88# CONFIG_DEFAULT_CFQ is not set
89# CONFIG_DEFAULT_NOOP is not set
90CONFIG_DEFAULT_IOSCHED="anticipatory"
91
92#
93# System type
94#
95# CONFIG_SH_SOLUTION_ENGINE is not set
96# CONFIG_SH_7751_SOLUTION_ENGINE is not set
97# CONFIG_SH_7300_SOLUTION_ENGINE is not set
98# CONFIG_SH_7343_SOLUTION_ENGINE is not set
99# CONFIG_SH_73180_SOLUTION_ENGINE is not set
100# CONFIG_SH_7751_SYSTEMH is not set
101# CONFIG_SH_HP6XX is not set
102# CONFIG_SH_EC3104 is not set
103# CONFIG_SH_SATURN is not set
104# CONFIG_SH_DREAMCAST is not set
105# CONFIG_SH_BIGSUR is not set
106# CONFIG_SH_MPC1211 is not set
107# CONFIG_SH_SH03 is not set
108# CONFIG_SH_SECUREEDGE5410 is not set
109CONFIG_SH_HS7751RVOIP=y
110# CONFIG_SH_7710VOIPGW is not set
111# CONFIG_SH_RTS7751R2D is not set
112# CONFIG_SH_R7780RP is not set
113# CONFIG_SH_EDOSK7705 is not set
114# CONFIG_SH_SH4202_MICRODEV is not set
115# CONFIG_SH_LANDISK is not set
116# CONFIG_SH_TITAN is not set
117# CONFIG_SH_SHMIN is not set
118# CONFIG_SH_UNKNOWN is not set
119
120#
121# Processor selection
122#
123CONFIG_CPU_SH4=y
124
125#
126# SH-2 Processor Support
127#
128# CONFIG_CPU_SUBTYPE_SH7604 is not set
129
130#
131# SH-3 Processor Support
132#
133# CONFIG_CPU_SUBTYPE_SH7300 is not set
134# CONFIG_CPU_SUBTYPE_SH7705 is not set
135# CONFIG_CPU_SUBTYPE_SH7706 is not set
136# CONFIG_CPU_SUBTYPE_SH7707 is not set
137# CONFIG_CPU_SUBTYPE_SH7708 is not set
138# CONFIG_CPU_SUBTYPE_SH7709 is not set
139# CONFIG_CPU_SUBTYPE_SH7710 is not set
140
141#
142# SH-4 Processor Support
143#
144# CONFIG_CPU_SUBTYPE_SH7750 is not set
145# CONFIG_CPU_SUBTYPE_SH7091 is not set
146# CONFIG_CPU_SUBTYPE_SH7750R is not set
147# CONFIG_CPU_SUBTYPE_SH7750S is not set
148# CONFIG_CPU_SUBTYPE_SH7751 is not set
149CONFIG_CPU_SUBTYPE_SH7751R=y
150# CONFIG_CPU_SUBTYPE_SH7760 is not set
151# CONFIG_CPU_SUBTYPE_SH4_202 is not set
152
153#
154# ST40 Processor Support
155#
156# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
157# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
158
159#
160# SH-4A Processor Support
161#
162# CONFIG_CPU_SUBTYPE_SH7770 is not set
163# CONFIG_CPU_SUBTYPE_SH7780 is not set
164
165#
166# SH4AL-DSP Processor Support
167#
168# CONFIG_CPU_SUBTYPE_SH73180 is not set
169# CONFIG_CPU_SUBTYPE_SH7343 is not set
170
171#
172# Memory management options
173#
174CONFIG_MMU=y
175CONFIG_PAGE_OFFSET=0x80000000
176CONFIG_MEMORY_START=0x0c000000
177CONFIG_MEMORY_SIZE=0x04000000
178CONFIG_VSYSCALL=y
179CONFIG_SELECT_MEMORY_MODEL=y
180CONFIG_FLATMEM_MANUAL=y
181# CONFIG_DISCONTIGMEM_MANUAL is not set
182# CONFIG_SPARSEMEM_MANUAL is not set
183CONFIG_FLATMEM=y
184CONFIG_FLAT_NODE_MEM_MAP=y
185# CONFIG_SPARSEMEM_STATIC is not set
186CONFIG_SPLIT_PTLOCK_CPUS=4
187# CONFIG_RESOURCES_64BIT is not set
188
189#
190# Cache configuration
191#
192# CONFIG_SH_DIRECT_MAPPED is not set
193# CONFIG_SH_WRITETHROUGH is not set
194# CONFIG_SH_OCRAM is not set
195
196#
197# Processor features
198#
199CONFIG_CPU_LITTLE_ENDIAN=y
200CONFIG_SH_FPU=y
201# CONFIG_SH_DSP is not set
202# CONFIG_SH_STORE_QUEUES is not set
203CONFIG_CPU_HAS_INTEVT=y
204CONFIG_CPU_HAS_SR_RB=y
205
206#
207# Timer support
208#
209CONFIG_SH_TMU=y
210
211#
212# HS7751RVoIP options
213#
214CONFIG_HS7751RVOIP_CODEC=y
215CONFIG_SH_PCLK_FREQ=60000000
216
217#
218# CPU Frequency scaling
219#
220# CONFIG_CPU_FREQ is not set
221
222#
223# DMA support
224#
225# CONFIG_SH_DMA is not set
226
227#
228# Companion Chips
229#
230# CONFIG_HD6446X_SERIES is not set
231
232#
233# Kernel features
234#
235# CONFIG_HZ_100 is not set
236CONFIG_HZ_250=y
237# CONFIG_HZ_1000 is not set
238CONFIG_HZ=250
239# CONFIG_KEXEC is not set
240# CONFIG_SMP is not set
241# CONFIG_PREEMPT_NONE is not set
242# CONFIG_PREEMPT_VOLUNTARY is not set
243CONFIG_PREEMPT=y
244CONFIG_PREEMPT_BKL=y
245
246#
247# Boot options
248#
249CONFIG_ZERO_PAGE_OFFSET=0x00001000
250CONFIG_BOOT_LINK_OFFSET=0x00800000
251# CONFIG_UBC_WAKEUP is not set
252CONFIG_CMDLINE_BOOL=y
253CONFIG_CMDLINE="mem=64M console=ttySC1,115200 root=/dev/hda1"
254
255#
256# Bus options
257#
258# CONFIG_PCI is not set
259
260#
261# PCCARD (PCMCIA/CardBus) support
262#
263# CONFIG_PCCARD is not set
264
265#
266# PCI Hotplug Support
267#
268
269#
270# Executable file formats
271#
272CONFIG_BINFMT_ELF=y
273# CONFIG_BINFMT_FLAT is not set
274# CONFIG_BINFMT_MISC is not set
275
276#
277# Power management options (EXPERIMENTAL)
278#
279# CONFIG_PM is not set
280
281#
282# Networking
283#
284CONFIG_NET=y
285
286#
287# Networking options
288#
289# CONFIG_NETDEBUG is not set
290CONFIG_PACKET=y
291CONFIG_PACKET_MMAP=y
292CONFIG_UNIX=y
293CONFIG_XFRM=y
294# CONFIG_XFRM_USER is not set
295# CONFIG_XFRM_SUB_POLICY is not set
296# CONFIG_NET_KEY is not set
297CONFIG_INET=y
298CONFIG_IP_MULTICAST=y
299CONFIG_IP_ADVANCED_ROUTER=y
300CONFIG_ASK_IP_FIB_HASH=y
301# CONFIG_IP_FIB_TRIE is not set
302CONFIG_IP_FIB_HASH=y
303# CONFIG_IP_MULTIPLE_TABLES is not set
304# CONFIG_IP_ROUTE_MULTIPATH is not set
305# CONFIG_IP_ROUTE_VERBOSE is not set
306# CONFIG_IP_PNP is not set
307# CONFIG_NET_IPIP is not set
308# CONFIG_NET_IPGRE is not set
309# CONFIG_IP_MROUTE is not set
310# CONFIG_ARPD is not set
311# CONFIG_SYN_COOKIES is not set
312# CONFIG_INET_AH is not set
313# CONFIG_INET_ESP is not set
314# CONFIG_INET_IPCOMP is not set
315# CONFIG_INET_XFRM_TUNNEL is not set
316# CONFIG_INET_TUNNEL is not set
317CONFIG_INET_XFRM_MODE_TRANSPORT=y
318CONFIG_INET_XFRM_MODE_TUNNEL=y
319CONFIG_INET_DIAG=y
320CONFIG_INET_TCP_DIAG=y
321# CONFIG_TCP_CONG_ADVANCED is not set
322CONFIG_TCP_CONG_CUBIC=y
323CONFIG_DEFAULT_TCP_CONG="cubic"
324# CONFIG_IPV6 is not set
325# CONFIG_INET6_XFRM_TUNNEL is not set
326# CONFIG_INET6_TUNNEL is not set
327# CONFIG_NETWORK_SECMARK is not set
328# CONFIG_NETFILTER is not set
329
330#
331# DCCP Configuration (EXPERIMENTAL)
332#
333# CONFIG_IP_DCCP is not set
334
335#
336# SCTP Configuration (EXPERIMENTAL)
337#
338# CONFIG_IP_SCTP is not set
339
340#
341# TIPC Configuration (EXPERIMENTAL)
342#
343# CONFIG_TIPC is not set
344# CONFIG_ATM is not set
345# CONFIG_BRIDGE is not set
346# CONFIG_VLAN_8021Q is not set
347# CONFIG_DECNET is not set
348# CONFIG_LLC2 is not set
349# CONFIG_IPX is not set
350# CONFIG_ATALK is not set
351# CONFIG_X25 is not set
352# CONFIG_LAPB is not set
353# CONFIG_ECONET is not set
354# CONFIG_WAN_ROUTER is not set
355
356#
357# QoS and/or fair queueing
358#
359# CONFIG_NET_SCHED is not set
360
361#
362# Network testing
363#
364# CONFIG_NET_PKTGEN is not set
365# CONFIG_HAMRADIO is not set
366# CONFIG_IRDA is not set
367# CONFIG_BT is not set
368# CONFIG_IEEE80211 is not set
369
370#
371# Device Drivers
372#
373
374#
375# Generic Driver Options
376#
377CONFIG_STANDALONE=y
378CONFIG_PREVENT_FIRMWARE_BUILD=y
379CONFIG_FW_LOADER=m
380# CONFIG_SYS_HYPERVISOR is not set
381
382#
383# Connector - unified userspace <-> kernelspace linker
384#
385# CONFIG_CONNECTOR is not set
386
387#
388# Memory Technology Devices (MTD)
389#
390# CONFIG_MTD is not set
391
392#
393# Parallel port support
394#
395# CONFIG_PARPORT is not set
396
397#
398# Plug and Play support
399#
400
401#
402# Block devices
403#
404# CONFIG_BLK_DEV_COW_COMMON is not set
405# CONFIG_BLK_DEV_LOOP is not set
406# CONFIG_BLK_DEV_NBD is not set
407# CONFIG_BLK_DEV_RAM is not set
408# CONFIG_BLK_DEV_INITRD is not set
409# CONFIG_CDROM_PKTCDVD is not set
410# CONFIG_ATA_OVER_ETH is not set
411
412#
413# ATA/ATAPI/MFM/RLL support
414#
415CONFIG_IDE=y
416CONFIG_IDE_MAX_HWIFS=1
417CONFIG_BLK_DEV_IDE=y
418
419#
420# Please see Documentation/ide.txt for help/info on IDE drives
421#
422# CONFIG_BLK_DEV_IDE_SATA is not set
423CONFIG_BLK_DEV_IDEDISK=y
424# CONFIG_IDEDISK_MULTI_MODE is not set
425# CONFIG_BLK_DEV_IDECD is not set
426# CONFIG_BLK_DEV_IDETAPE is not set
427# CONFIG_BLK_DEV_IDEFLOPPY is not set
428# CONFIG_IDE_TASK_IOCTL is not set
429
430#
431# IDE chipset support/bugfixes
432#
433CONFIG_IDE_GENERIC=y
434# CONFIG_IDE_ARM is not set
435# CONFIG_BLK_DEV_IDEDMA is not set
436# CONFIG_IDEDMA_AUTO is not set
437# CONFIG_BLK_DEV_HD is not set
438
439#
440# SCSI device support
441#
442# CONFIG_RAID_ATTRS is not set
443# CONFIG_SCSI is not set
444# CONFIG_SCSI_NETLINK is not set
445
446#
447# Serial ATA (prod) and Parallel ATA (experimental) drivers
448#
449# CONFIG_ATA is not set
450
451#
452# Multi-device support (RAID and LVM)
453#
454# CONFIG_MD is not set
455
456#
457# Fusion MPT device support
458#
459# CONFIG_FUSION is not set
460
461#
462# IEEE 1394 (FireWire) support
463#
464
465#
466# I2O device support
467#
468
469#
470# Network device support
471#
472CONFIG_NETDEVICES=y
473# CONFIG_DUMMY is not set
474# CONFIG_BONDING is not set
475# CONFIG_EQUALIZER is not set
476# CONFIG_TUN is not set
477
478#
479# PHY device support
480#
481# CONFIG_PHYLIB is not set
482
483#
484# Ethernet (10 or 100Mbit)
485#
486CONFIG_NET_ETHERNET=y
487CONFIG_MII=y
488# CONFIG_STNIC is not set
489# CONFIG_SMC91X is not set
490
491#
492# Ethernet (1000 Mbit)
493#
494
495#
496# Ethernet (10000 Mbit)
497#
498
499#
500# Token Ring devices
501#
502
503#
504# Wireless LAN (non-hamradio)
505#
506# CONFIG_NET_RADIO is not set
507
508#
509# Wan interfaces
510#
511# CONFIG_WAN is not set
512# CONFIG_PPP is not set
513# CONFIG_SLIP is not set
514# CONFIG_SHAPER is not set
515# CONFIG_NETCONSOLE is not set
516# CONFIG_NETPOLL is not set
517# CONFIG_NET_POLL_CONTROLLER is not set
518
519#
520# ISDN subsystem
521#
522# CONFIG_ISDN is not set
523
524#
525# Telephony Support
526#
527# CONFIG_PHONE is not set
528
529#
530# Input device support
531#
532CONFIG_INPUT=y
533# CONFIG_INPUT_FF_MEMLESS is not set
534
535#
536# Userland interfaces
537#
538# CONFIG_INPUT_MOUSEDEV is not set
539# CONFIG_INPUT_JOYDEV is not set
540# CONFIG_INPUT_TSDEV is not set
541# CONFIG_INPUT_EVDEV is not set
542# CONFIG_INPUT_EVBUG is not set
543
544#
545# Input Device Drivers
546#
547# CONFIG_INPUT_KEYBOARD is not set
548# CONFIG_INPUT_MOUSE is not set
549# CONFIG_INPUT_JOYSTICK is not set
550# CONFIG_INPUT_TOUCHSCREEN is not set
551# CONFIG_INPUT_MISC is not set
552
553#
554# Hardware I/O ports
555#
556CONFIG_SERIO=y
557CONFIG_SERIO_I8042=y
558CONFIG_SERIO_SERPORT=y
559# CONFIG_SERIO_LIBPS2 is not set
560# CONFIG_SERIO_RAW is not set
561# CONFIG_GAMEPORT is not set
562
563#
564# Character devices
565#
566# CONFIG_VT is not set
567# CONFIG_SERIAL_NONSTANDARD is not set
568
569#
570# Serial drivers
571#
572# CONFIG_SERIAL_8250 is not set
573
574#
575# Non-8250 serial port support
576#
577CONFIG_SERIAL_SH_SCI=y
578CONFIG_SERIAL_SH_SCI_NR_UARTS=2
579CONFIG_SERIAL_SH_SCI_CONSOLE=y
580CONFIG_SERIAL_CORE=y
581CONFIG_SERIAL_CORE_CONSOLE=y
582CONFIG_UNIX98_PTYS=y
583# CONFIG_LEGACY_PTYS is not set
584
585#
586# IPMI
587#
588# CONFIG_IPMI_HANDLER is not set
589
590#
591# Watchdog Cards
592#
593# CONFIG_WATCHDOG is not set
594CONFIG_HW_RANDOM=y
595# CONFIG_GEN_RTC is not set
596# CONFIG_DTLK is not set
597# CONFIG_R3964 is not set
598
599#
600# Ftape, the floppy tape device driver
601#
602# CONFIG_RAW_DRIVER is not set
603
604#
605# TPM devices
606#
607# CONFIG_TCG_TPM is not set
608# CONFIG_TELCLOCK is not set
609
610#
611# I2C support
612#
613# CONFIG_I2C is not set
614
615#
616# SPI support
617#
618# CONFIG_SPI is not set
619# CONFIG_SPI_MASTER is not set
620
621#
622# Dallas's 1-wire bus
623#
624
625#
626# Hardware Monitoring support
627#
628CONFIG_HWMON=y
629# CONFIG_HWMON_VID is not set
630# CONFIG_SENSORS_ABITUGURU is not set
631# CONFIG_SENSORS_F71805F is not set
632# CONFIG_SENSORS_VT1211 is not set
633# CONFIG_HWMON_DEBUG_CHIP is not set
634
635#
636# Misc devices
637#
638
639#
640# Multimedia devices
641#
642# CONFIG_VIDEO_DEV is not set
643CONFIG_VIDEO_V4L2=y
644
645#
646# Digital Video Broadcasting Devices
647#
648# CONFIG_DVB is not set
649
650#
651# Graphics support
652#
653CONFIG_FIRMWARE_EDID=y
654# CONFIG_FB is not set
655# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
656
657#
658# Sound
659#
660# CONFIG_SOUND is not set
661
662#
663# USB support
664#
665# CONFIG_USB_ARCH_HAS_HCD is not set
666# CONFIG_USB_ARCH_HAS_OHCI is not set
667# CONFIG_USB_ARCH_HAS_EHCI is not set
668
669#
670# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
671#
672
673#
674# USB Gadget Support
675#
676# CONFIG_USB_GADGET is not set
677
678#
679# MMC/SD Card support
680#
681# CONFIG_MMC is not set
682
683#
684# LED devices
685#
686# CONFIG_NEW_LEDS is not set
687
688#
689# LED drivers
690#
691
692#
693# LED Triggers
694#
695
696#
697# InfiniBand support
698#
699
700#
701# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
702#
703
704#
705# Real Time Clock
706#
707# CONFIG_RTC_CLASS is not set
708
709#
710# DMA Engine support
711#
712# CONFIG_DMA_ENGINE is not set
713
714#
715# DMA Clients
716#
717
718#
719# DMA Devices
720#
721
722#
723# File systems
724#
725CONFIG_EXT2_FS=y
726# CONFIG_EXT2_FS_XATTR is not set
727# CONFIG_EXT2_FS_XIP is not set
728# CONFIG_EXT3_FS is not set
729# CONFIG_REISERFS_FS is not set
730# CONFIG_JFS_FS is not set
731# CONFIG_FS_POSIX_ACL is not set
732# CONFIG_XFS_FS is not set
733# CONFIG_OCFS2_FS is not set
734# CONFIG_MINIX_FS is not set
735# CONFIG_ROMFS_FS is not set
736CONFIG_INOTIFY=y
737CONFIG_INOTIFY_USER=y
738# CONFIG_QUOTA is not set
739CONFIG_DNOTIFY=y
740# CONFIG_AUTOFS_FS is not set
741# CONFIG_AUTOFS4_FS is not set
742# CONFIG_FUSE_FS is not set
743
744#
745# CD-ROM/DVD Filesystems
746#
747# CONFIG_ISO9660_FS is not set
748# CONFIG_UDF_FS is not set
749
750#
751# DOS/FAT/NT Filesystems
752#
753# CONFIG_MSDOS_FS is not set
754# CONFIG_VFAT_FS is not set
755# CONFIG_NTFS_FS is not set
756
757#
758# Pseudo filesystems
759#
760CONFIG_PROC_FS=y
761CONFIG_PROC_KCORE=y
762CONFIG_PROC_SYSCTL=y
763CONFIG_SYSFS=y
764CONFIG_TMPFS=y
765# CONFIG_TMPFS_POSIX_ACL is not set
766# CONFIG_HUGETLBFS is not set
767# CONFIG_HUGETLB_PAGE is not set
768CONFIG_RAMFS=y
769# CONFIG_CONFIGFS_FS is not set
770
771#
772# Miscellaneous filesystems
773#
774# CONFIG_ADFS_FS is not set
775# CONFIG_AFFS_FS is not set
776# CONFIG_HFS_FS is not set
777# CONFIG_HFSPLUS_FS is not set
778# CONFIG_BEFS_FS is not set
779# CONFIG_BFS_FS is not set
780# CONFIG_EFS_FS is not set
781# CONFIG_CRAMFS is not set
782# CONFIG_VXFS_FS is not set
783# CONFIG_HPFS_FS is not set
784# CONFIG_QNX4FS_FS is not set
785# CONFIG_SYSV_FS is not set
786# CONFIG_UFS_FS is not set
787
788#
789# Network File Systems
790#
791CONFIG_NFS_FS=y
792CONFIG_NFS_V3=y
793# CONFIG_NFS_V3_ACL is not set
794CONFIG_NFS_V4=y
795CONFIG_NFS_DIRECTIO=y
796# CONFIG_NFSD is not set
797CONFIG_LOCKD=y
798CONFIG_LOCKD_V4=y
799CONFIG_NFS_COMMON=y
800CONFIG_SUNRPC=y
801CONFIG_SUNRPC_GSS=y
802CONFIG_RPCSEC_GSS_KRB5=y
803# CONFIG_RPCSEC_GSS_SPKM3 is not set
804# CONFIG_SMB_FS is not set
805# CONFIG_CIFS is not set
806# CONFIG_NCP_FS is not set
807# CONFIG_CODA_FS is not set
808# CONFIG_AFS_FS is not set
809# CONFIG_9P_FS is not set
810
811#
812# Partition Types
813#
814CONFIG_PARTITION_ADVANCED=y
815# CONFIG_ACORN_PARTITION is not set
816# CONFIG_OSF_PARTITION is not set
817# CONFIG_AMIGA_PARTITION is not set
818# CONFIG_ATARI_PARTITION is not set
819# CONFIG_MAC_PARTITION is not set
820CONFIG_MSDOS_PARTITION=y
821# CONFIG_BSD_DISKLABEL is not set
822# CONFIG_MINIX_SUBPARTITION is not set
823# CONFIG_SOLARIS_X86_PARTITION is not set
824# CONFIG_UNIXWARE_DISKLABEL is not set
825# CONFIG_LDM_PARTITION is not set
826# CONFIG_SGI_PARTITION is not set
827# CONFIG_ULTRIX_PARTITION is not set
828# CONFIG_SUN_PARTITION is not set
829# CONFIG_KARMA_PARTITION is not set
830# CONFIG_EFI_PARTITION is not set
831
832#
833# Native Language Support
834#
835# CONFIG_NLS is not set
836
837#
838# Profiling support
839#
840# CONFIG_PROFILING is not set
841
842#
843# Kernel hacking
844#
845# CONFIG_PRINTK_TIME is not set
846CONFIG_ENABLE_MUST_CHECK=y
847# CONFIG_MAGIC_SYSRQ is not set
848# CONFIG_UNUSED_SYMBOLS is not set
849# CONFIG_DEBUG_KERNEL is not set
850CONFIG_LOG_BUF_SHIFT=14
851# CONFIG_DEBUG_BUGVERBOSE is not set
852# CONFIG_DEBUG_FS is not set
853# CONFIG_SH_STANDARD_BIOS is not set
854# CONFIG_EARLY_SCIF_CONSOLE is not set
855# CONFIG_KGDB is not set
856
857#
858# Security options
859#
860# CONFIG_KEYS is not set
861# CONFIG_SECURITY is not set
862
863#
864# Cryptographic options
865#
866CONFIG_CRYPTO=y
867CONFIG_CRYPTO_ALGAPI=y
868CONFIG_CRYPTO_BLKCIPHER=m
869CONFIG_CRYPTO_MANAGER=m
870# CONFIG_CRYPTO_HMAC is not set
871# CONFIG_CRYPTO_NULL is not set
872# CONFIG_CRYPTO_MD4 is not set
873CONFIG_CRYPTO_MD5=y
874# CONFIG_CRYPTO_SHA1 is not set
875# CONFIG_CRYPTO_SHA256 is not set
876# CONFIG_CRYPTO_SHA512 is not set
877# CONFIG_CRYPTO_WP512 is not set
878# CONFIG_CRYPTO_TGR192 is not set
879CONFIG_CRYPTO_ECB=m
880CONFIG_CRYPTO_CBC=m
881CONFIG_CRYPTO_DES=y
882# CONFIG_CRYPTO_BLOWFISH is not set
883# CONFIG_CRYPTO_TWOFISH is not set
884# CONFIG_CRYPTO_SERPENT is not set
885# CONFIG_CRYPTO_AES is not set
886# CONFIG_CRYPTO_CAST5 is not set
887# CONFIG_CRYPTO_CAST6 is not set
888# CONFIG_CRYPTO_TEA is not set
889# CONFIG_CRYPTO_ARC4 is not set
890# CONFIG_CRYPTO_KHAZAD is not set
891# CONFIG_CRYPTO_ANUBIS is not set
892# CONFIG_CRYPTO_DEFLATE is not set
893# CONFIG_CRYPTO_MICHAEL_MIC is not set
894# CONFIG_CRYPTO_CRC32C is not set
895# CONFIG_CRYPTO_TEST is not set
896
897#
898# Hardware crypto devices
899#
900
901#
902# Library routines
903#
904# CONFIG_CRC_CCITT is not set
905# CONFIG_CRC16 is not set
906CONFIG_CRC32=y
907# CONFIG_LIBCRC32C is not set
908CONFIG_PLIST=y
diff --git a/arch/sh/configs/r7785rp_defconfig b/arch/sh/configs/r7785rp_defconfig
index 2e43a2a971a9..0dc1ce7b9349 100644
--- a/arch/sh/configs/r7785rp_defconfig
+++ b/arch/sh/configs/r7785rp_defconfig
@@ -1,9 +1,10 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.24-rc2 3# Linux kernel version: 2.6.24-rc3
4# Tue Nov 13 20:34:57 2007 4# Fri Nov 23 14:03:57 2007
5# 5#
6CONFIG_SUPERH=y 6CONFIG_SUPERH=y
7CONFIG_SUPERH32=y
7CONFIG_RWSEM_GENERIC_SPINLOCK=y 8CONFIG_RWSEM_GENERIC_SPINLOCK=y
8CONFIG_GENERIC_BUG=y 9CONFIG_GENERIC_BUG=y
9CONFIG_GENERIC_FIND_NEXT_BIT=y 10CONFIG_GENERIC_FIND_NEXT_BIT=y
@@ -39,6 +40,7 @@ CONFIG_BSD_PROCESS_ACCT=y
39# CONFIG_BSD_PROCESS_ACCT_V3 is not set 40# CONFIG_BSD_PROCESS_ACCT_V3 is not set
40# CONFIG_TASKSTATS is not set 41# CONFIG_TASKSTATS is not set
41# CONFIG_USER_NS is not set 42# CONFIG_USER_NS is not set
43# CONFIG_PID_NS is not set
42# CONFIG_AUDIT is not set 44# CONFIG_AUDIT is not set
43CONFIG_IKCONFIG=y 45CONFIG_IKCONFIG=y
44CONFIG_IKCONFIG_PROC=y 46CONFIG_IKCONFIG_PROC=y
@@ -130,6 +132,8 @@ CONFIG_CPU_SUBTYPE_SH7785=y
130# CONFIG_CPU_SUBTYPE_SHX3 is not set 132# CONFIG_CPU_SUBTYPE_SHX3 is not set
131# CONFIG_CPU_SUBTYPE_SH7343 is not set 133# CONFIG_CPU_SUBTYPE_SH7343 is not set
132# CONFIG_CPU_SUBTYPE_SH7722 is not set 134# CONFIG_CPU_SUBTYPE_SH7722 is not set
135# CONFIG_CPU_SUBTYPE_SH5_101 is not set
136# CONFIG_CPU_SUBTYPE_SH5_103 is not set
133 137
134# 138#
135# Memory management options 139# Memory management options
@@ -139,7 +143,8 @@ CONFIG_MMU=y
139CONFIG_PAGE_OFFSET=0x80000000 143CONFIG_PAGE_OFFSET=0x80000000
140CONFIG_MEMORY_START=0x08000000 144CONFIG_MEMORY_START=0x08000000
141CONFIG_MEMORY_SIZE=0x08000000 145CONFIG_MEMORY_SIZE=0x08000000
142# CONFIG_32BIT is not set 146CONFIG_29BIT=y
147# CONFIG_PMB is not set
143# CONFIG_X2TLB is not set 148# CONFIG_X2TLB is not set
144CONFIG_VSYSCALL=y 149CONFIG_VSYSCALL=y
145# CONFIG_NUMA is not set 150# CONFIG_NUMA is not set
@@ -158,6 +163,7 @@ CONFIG_PAGE_SIZE_4KB=y
158CONFIG_HUGETLB_PAGE_SIZE_1MB=y 163CONFIG_HUGETLB_PAGE_SIZE_1MB=y
159# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set 164# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set
160# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set 165# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set
166# CONFIG_HUGETLB_PAGE_SIZE_512MB is not set
161CONFIG_SELECT_MEMORY_MODEL=y 167CONFIG_SELECT_MEMORY_MODEL=y
162# CONFIG_FLATMEM_MANUAL is not set 168# CONFIG_FLATMEM_MANUAL is not set
163# CONFIG_DISCONTIGMEM_MANUAL is not set 169# CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -701,6 +707,7 @@ CONFIG_DEVPORT=y
701# CONFIG_POWER_SUPPLY is not set 707# CONFIG_POWER_SUPPLY is not set
702CONFIG_HWMON=y 708CONFIG_HWMON=y
703# CONFIG_HWMON_VID is not set 709# CONFIG_HWMON_VID is not set
710# CONFIG_SENSORS_I5K_AMB is not set
704# CONFIG_SENSORS_F71805F is not set 711# CONFIG_SENSORS_F71805F is not set
705# CONFIG_SENSORS_F71882FG is not set 712# CONFIG_SENSORS_F71882FG is not set
706# CONFIG_SENSORS_IT87 is not set 713# CONFIG_SENSORS_IT87 is not set
diff --git a/arch/sh/configs/r7780rp_defconfig b/arch/sh/configs/sdk7780_defconfig
index 12cc01910cf8..bb9bcd6591ab 100644
--- a/arch/sh/configs/r7780rp_defconfig
+++ b/arch/sh/configs/sdk7780_defconfig
@@ -1,9 +1,10 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.21-rc7 3# Linux kernel version: 2.6.24-rc7
4# Tue May 1 12:28:39 2007 4# Tue Jan 22 11:34:03 2008
5# 5#
6CONFIG_SUPERH=y 6CONFIG_SUPERH=y
7CONFIG_SUPERH32=y
7CONFIG_RWSEM_GENERIC_SPINLOCK=y 8CONFIG_RWSEM_GENERIC_SPINLOCK=y
8CONFIG_GENERIC_BUG=y 9CONFIG_GENERIC_BUG=y
9CONFIG_GENERIC_FIND_NEXT_BIT=y 10CONFIG_GENERIC_FIND_NEXT_BIT=y
@@ -11,149 +12,107 @@ CONFIG_GENERIC_HWEIGHT=y
11CONFIG_GENERIC_HARDIRQS=y 12CONFIG_GENERIC_HARDIRQS=y
12CONFIG_GENERIC_IRQ_PROBE=y 13CONFIG_GENERIC_IRQ_PROBE=y
13CONFIG_GENERIC_CALIBRATE_DELAY=y 14CONFIG_GENERIC_CALIBRATE_DELAY=y
14# CONFIG_GENERIC_TIME is not set 15CONFIG_GENERIC_TIME=y
16CONFIG_GENERIC_CLOCKEVENTS=y
17CONFIG_SYS_SUPPORTS_PCI=y
15CONFIG_STACKTRACE_SUPPORT=y 18CONFIG_STACKTRACE_SUPPORT=y
16CONFIG_LOCKDEP_SUPPORT=y 19CONFIG_LOCKDEP_SUPPORT=y
17# CONFIG_ARCH_HAS_ILOG2_U32 is not set 20# CONFIG_ARCH_HAS_ILOG2_U32 is not set
18# CONFIG_ARCH_HAS_ILOG2_U64 is not set 21# CONFIG_ARCH_HAS_ILOG2_U64 is not set
22CONFIG_ARCH_NO_VIRT_TO_BUS=y
19CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" 23CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
20 24
21# 25#
22# Code maturity level options 26# General setup
23# 27#
24CONFIG_EXPERIMENTAL=y 28CONFIG_EXPERIMENTAL=y
25CONFIG_BROKEN_ON_SMP=y 29CONFIG_BROKEN_ON_SMP=y
26CONFIG_LOCK_KERNEL=y 30CONFIG_LOCK_KERNEL=y
27CONFIG_INIT_ENV_ARG_LIMIT=32 31CONFIG_INIT_ENV_ARG_LIMIT=32
28 32CONFIG_LOCALVERSION="_SDK7780"
29#
30# General setup
31#
32CONFIG_LOCALVERSION=""
33CONFIG_LOCALVERSION_AUTO=y 33CONFIG_LOCALVERSION_AUTO=y
34CONFIG_SWAP=y 34CONFIG_SWAP=y
35CONFIG_SYSVIPC=y 35CONFIG_SYSVIPC=y
36# CONFIG_IPC_NS is not set
37CONFIG_SYSVIPC_SYSCTL=y 36CONFIG_SYSVIPC_SYSCTL=y
38# CONFIG_POSIX_MQUEUE is not set 37CONFIG_POSIX_MQUEUE=y
39CONFIG_BSD_PROCESS_ACCT=y 38CONFIG_BSD_PROCESS_ACCT=y
40# CONFIG_BSD_PROCESS_ACCT_V3 is not set 39# CONFIG_BSD_PROCESS_ACCT_V3 is not set
41# CONFIG_TASKSTATS is not set 40# CONFIG_TASKSTATS is not set
42# CONFIG_UTS_NS is not set 41# CONFIG_USER_NS is not set
42# CONFIG_PID_NS is not set
43# CONFIG_AUDIT is not set 43# CONFIG_AUDIT is not set
44CONFIG_IKCONFIG=y 44CONFIG_IKCONFIG=y
45CONFIG_IKCONFIG_PROC=y 45CONFIG_IKCONFIG_PROC=y
46# CONFIG_SYSFS_DEPRECATED is not set 46CONFIG_LOG_BUF_SHIFT=18
47# CONFIG_RELAY is not set 47# CONFIG_CGROUPS is not set
48CONFIG_FAIR_GROUP_SCHED=y
49CONFIG_FAIR_USER_SCHED=y
50# CONFIG_FAIR_CGROUP_SCHED is not set
51CONFIG_SYSFS_DEPRECATED=y
52CONFIG_RELAY=y
48# CONFIG_BLK_DEV_INITRD is not set 53# CONFIG_BLK_DEV_INITRD is not set
49CONFIG_CC_OPTIMIZE_FOR_SIZE=y 54CONFIG_CC_OPTIMIZE_FOR_SIZE=y
50CONFIG_SYSCTL=y 55CONFIG_SYSCTL=y
51CONFIG_EMBEDDED=y 56CONFIG_EMBEDDED=y
52CONFIG_UID16=y 57CONFIG_UID16=y
53# CONFIG_SYSCTL_SYSCALL is not set 58CONFIG_SYSCTL_SYSCALL=y
54CONFIG_KALLSYMS=y 59CONFIG_KALLSYMS=y
55# CONFIG_KALLSYMS_ALL is not set 60CONFIG_KALLSYMS_ALL=y
56# CONFIG_KALLSYMS_EXTRA_PASS is not set 61# CONFIG_KALLSYMS_EXTRA_PASS is not set
57CONFIG_HOTPLUG=y 62CONFIG_HOTPLUG=y
58CONFIG_PRINTK=y 63CONFIG_PRINTK=y
59CONFIG_BUG=y 64CONFIG_BUG=y
60CONFIG_ELF_CORE=y 65CONFIG_ELF_CORE=y
61CONFIG_BASE_FULL=y 66CONFIG_BASE_FULL=y
62# CONFIG_FUTEX is not set 67CONFIG_FUTEX=y
63# CONFIG_EPOLL is not set 68CONFIG_ANON_INODES=y
69CONFIG_EPOLL=y
70CONFIG_SIGNALFD=y
71CONFIG_EVENTFD=y
64CONFIG_SHMEM=y 72CONFIG_SHMEM=y
65CONFIG_SLAB=y
66CONFIG_VM_EVENT_COUNTERS=y 73CONFIG_VM_EVENT_COUNTERS=y
74CONFIG_SLUB_DEBUG=y
75# CONFIG_SLAB is not set
76CONFIG_SLUB=y
77# CONFIG_SLOB is not set
78CONFIG_SLABINFO=y
79CONFIG_RT_MUTEXES=y
67# CONFIG_TINY_SHMEM is not set 80# CONFIG_TINY_SHMEM is not set
68CONFIG_BASE_SMALL=0 81CONFIG_BASE_SMALL=0
69# CONFIG_SLOB is not set
70
71#
72# Loadable module support
73#
74CONFIG_MODULES=y 82CONFIG_MODULES=y
75CONFIG_MODULE_UNLOAD=y 83CONFIG_MODULE_UNLOAD=y
76# CONFIG_MODULE_FORCE_UNLOAD is not set 84CONFIG_MODULE_FORCE_UNLOAD=y
77# CONFIG_MODVERSIONS is not set 85# CONFIG_MODVERSIONS is not set
78# CONFIG_MODULE_SRCVERSION_ALL is not set 86# CONFIG_MODULE_SRCVERSION_ALL is not set
79CONFIG_KMOD=y 87CONFIG_KMOD=y
80
81#
82# Block layer
83#
84CONFIG_BLOCK=y 88CONFIG_BLOCK=y
85# CONFIG_LBD is not set 89CONFIG_LBD=y
86# CONFIG_BLK_DEV_IO_TRACE is not set 90# CONFIG_BLK_DEV_IO_TRACE is not set
87# CONFIG_LSF is not set 91# CONFIG_LSF is not set
92# CONFIG_BLK_DEV_BSG is not set
88 93
89# 94#
90# IO Schedulers 95# IO Schedulers
91# 96#
92CONFIG_IOSCHED_NOOP=y 97CONFIG_IOSCHED_NOOP=y
93# CONFIG_IOSCHED_AS is not set 98CONFIG_IOSCHED_AS=y
94# CONFIG_IOSCHED_DEADLINE is not set 99CONFIG_IOSCHED_DEADLINE=y
95# CONFIG_IOSCHED_CFQ is not set 100CONFIG_IOSCHED_CFQ=y
96# CONFIG_DEFAULT_AS is not set 101CONFIG_DEFAULT_AS=y
97# CONFIG_DEFAULT_DEADLINE is not set 102# CONFIG_DEFAULT_DEADLINE is not set
98# CONFIG_DEFAULT_CFQ is not set 103# CONFIG_DEFAULT_CFQ is not set
99CONFIG_DEFAULT_NOOP=y 104# CONFIG_DEFAULT_NOOP is not set
100CONFIG_DEFAULT_IOSCHED="noop" 105CONFIG_DEFAULT_IOSCHED="anticipatory"
101 106
102# 107#
103# System type 108# System type
104# 109#
105# CONFIG_SH_SOLUTION_ENGINE is not set
106# CONFIG_SH_7722_SOLUTION_ENGINE is not set
107# CONFIG_SH_7751_SOLUTION_ENGINE is not set
108# CONFIG_SH_7780_SOLUTION_ENGINE is not set
109# CONFIG_SH_7300_SOLUTION_ENGINE is not set
110# CONFIG_SH_7343_SOLUTION_ENGINE is not set
111# CONFIG_SH_73180_SOLUTION_ENGINE is not set
112# CONFIG_SH_7751_SYSTEMH is not set
113# CONFIG_SH_HP6XX is not set
114# CONFIG_SH_SATURN is not set
115# CONFIG_SH_DREAMCAST is not set
116# CONFIG_SH_MPC1211 is not set
117# CONFIG_SH_SH03 is not set
118# CONFIG_SH_SECUREEDGE5410 is not set
119# CONFIG_SH_HS7751RVOIP is not set
120# CONFIG_SH_7710VOIPGW is not set
121# CONFIG_SH_RTS7751R2D is not set
122CONFIG_SH_HIGHLANDER=y
123# CONFIG_SH_EDOSK7705 is not set
124# CONFIG_SH_SH4202_MICRODEV is not set
125# CONFIG_SH_LANDISK is not set
126# CONFIG_SH_TITAN is not set
127# CONFIG_SH_SHMIN is not set
128# CONFIG_SH_7206_SOLUTION_ENGINE is not set
129# CONFIG_SH_7619_SOLUTION_ENGINE is not set
130# CONFIG_SH_LBOX_RE2 is not set
131# CONFIG_SH_UNKNOWN is not set
132CONFIG_SH_R7780RP=y
133# CONFIG_SH_R7780MP is not set
134# CONFIG_SH_R7785RP is not set
135
136#
137# Processor selection
138#
139CONFIG_CPU_SH4=y 110CONFIG_CPU_SH4=y
140CONFIG_CPU_SH4A=y 111CONFIG_CPU_SH4A=y
141
142#
143# SH-2 Processor Support
144#
145# CONFIG_CPU_SUBTYPE_SH7604 is not set
146# CONFIG_CPU_SUBTYPE_SH7619 is not set 112# CONFIG_CPU_SUBTYPE_SH7619 is not set
147 113# CONFIG_CPU_SUBTYPE_SH7203 is not set
148#
149# SH-2A Processor Support
150#
151# CONFIG_CPU_SUBTYPE_SH7206 is not set 114# CONFIG_CPU_SUBTYPE_SH7206 is not set
152 115# CONFIG_CPU_SUBTYPE_SH7263 is not set
153#
154# SH-3 Processor Support
155#
156# CONFIG_CPU_SUBTYPE_SH7300 is not set
157# CONFIG_CPU_SUBTYPE_SH7705 is not set 116# CONFIG_CPU_SUBTYPE_SH7705 is not set
158# CONFIG_CPU_SUBTYPE_SH7706 is not set 117# CONFIG_CPU_SUBTYPE_SH7706 is not set
159# CONFIG_CPU_SUBTYPE_SH7707 is not set 118# CONFIG_CPU_SUBTYPE_SH7707 is not set
@@ -161,10 +120,8 @@ CONFIG_CPU_SH4A=y
161# CONFIG_CPU_SUBTYPE_SH7709 is not set 120# CONFIG_CPU_SUBTYPE_SH7709 is not set
162# CONFIG_CPU_SUBTYPE_SH7710 is not set 121# CONFIG_CPU_SUBTYPE_SH7710 is not set
163# CONFIG_CPU_SUBTYPE_SH7712 is not set 122# CONFIG_CPU_SUBTYPE_SH7712 is not set
164 123# CONFIG_CPU_SUBTYPE_SH7720 is not set
165# 124# CONFIG_CPU_SUBTYPE_SH7721 is not set
166# SH-4 Processor Support
167#
168# CONFIG_CPU_SUBTYPE_SH7750 is not set 125# CONFIG_CPU_SUBTYPE_SH7750 is not set
169# CONFIG_CPU_SUBTYPE_SH7091 is not set 126# CONFIG_CPU_SUBTYPE_SH7091 is not set
170# CONFIG_CPU_SUBTYPE_SH7750R is not set 127# CONFIG_CPU_SUBTYPE_SH7750R is not set
@@ -173,38 +130,33 @@ CONFIG_CPU_SH4A=y
173# CONFIG_CPU_SUBTYPE_SH7751R is not set 130# CONFIG_CPU_SUBTYPE_SH7751R is not set
174# CONFIG_CPU_SUBTYPE_SH7760 is not set 131# CONFIG_CPU_SUBTYPE_SH7760 is not set
175# CONFIG_CPU_SUBTYPE_SH4_202 is not set 132# CONFIG_CPU_SUBTYPE_SH4_202 is not set
176 133# CONFIG_CPU_SUBTYPE_SH7763 is not set
177#
178# ST40 Processor Support
179#
180# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
181# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
182
183#
184# SH-4A Processor Support
185#
186# CONFIG_CPU_SUBTYPE_SH7770 is not set 134# CONFIG_CPU_SUBTYPE_SH7770 is not set
187CONFIG_CPU_SUBTYPE_SH7780=y 135CONFIG_CPU_SUBTYPE_SH7780=y
188# CONFIG_CPU_SUBTYPE_SH7785 is not set 136# CONFIG_CPU_SUBTYPE_SH7785 is not set
189 137# CONFIG_CPU_SUBTYPE_SHX3 is not set
190#
191# SH4AL-DSP Processor Support
192#
193# CONFIG_CPU_SUBTYPE_SH73180 is not set
194# CONFIG_CPU_SUBTYPE_SH7343 is not set 138# CONFIG_CPU_SUBTYPE_SH7343 is not set
195# CONFIG_CPU_SUBTYPE_SH7722 is not set 139# CONFIG_CPU_SUBTYPE_SH7722 is not set
140# CONFIG_CPU_SUBTYPE_SH5_101 is not set
141# CONFIG_CPU_SUBTYPE_SH5_103 is not set
196 142
197# 143#
198# Memory management options 144# Memory management options
199# 145#
146CONFIG_QUICKLIST=y
200CONFIG_MMU=y 147CONFIG_MMU=y
201CONFIG_PAGE_OFFSET=0x80000000 148CONFIG_PAGE_OFFSET=0x80000000
202CONFIG_MEMORY_START=0x08000000 149CONFIG_MEMORY_START=0x08000000
203CONFIG_MEMORY_SIZE=0x08000000 150CONFIG_MEMORY_SIZE=0x08000000
204# CONFIG_32BIT is not set 151CONFIG_29BIT=y
152# CONFIG_PMB is not set
205CONFIG_VSYSCALL=y 153CONFIG_VSYSCALL=y
206CONFIG_ARCH_FLATMEM_ENABLE=y 154CONFIG_ARCH_FLATMEM_ENABLE=y
155CONFIG_ARCH_SPARSEMEM_ENABLE=y
156CONFIG_ARCH_SPARSEMEM_DEFAULT=y
157CONFIG_MAX_ACTIVE_REGIONS=1
207CONFIG_ARCH_POPULATES_NODE_MAP=y 158CONFIG_ARCH_POPULATES_NODE_MAP=y
159CONFIG_ARCH_SELECT_MEMORY_MODEL=y
208CONFIG_PAGE_SIZE_4KB=y 160CONFIG_PAGE_SIZE_4KB=y
209# CONFIG_PAGE_SIZE_8KB is not set 161# CONFIG_PAGE_SIZE_8KB is not set
210# CONFIG_PAGE_SIZE_64KB is not set 162# CONFIG_PAGE_SIZE_64KB is not set
@@ -213,23 +165,27 @@ CONFIG_HUGETLB_PAGE_SIZE_64K=y
213# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set 165# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
214# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set 166# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set
215# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set 167# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set
168# CONFIG_HUGETLB_PAGE_SIZE_512MB is not set
216CONFIG_SELECT_MEMORY_MODEL=y 169CONFIG_SELECT_MEMORY_MODEL=y
217CONFIG_FLATMEM_MANUAL=y 170CONFIG_FLATMEM_MANUAL=y
218# CONFIG_DISCONTIGMEM_MANUAL is not set 171# CONFIG_DISCONTIGMEM_MANUAL is not set
219# CONFIG_SPARSEMEM_MANUAL is not set 172# CONFIG_SPARSEMEM_MANUAL is not set
220CONFIG_FLATMEM=y 173CONFIG_FLATMEM=y
221CONFIG_FLAT_NODE_MEM_MAP=y 174CONFIG_FLAT_NODE_MEM_MAP=y
222# CONFIG_SPARSEMEM_STATIC is not set 175CONFIG_SPARSEMEM_STATIC=y
176# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
223CONFIG_SPLIT_PTLOCK_CPUS=4 177CONFIG_SPLIT_PTLOCK_CPUS=4
224# CONFIG_RESOURCES_64BIT is not set 178CONFIG_RESOURCES_64BIT=y
225CONFIG_ZONE_DMA_FLAG=0 179CONFIG_ZONE_DMA_FLAG=0
180CONFIG_NR_QUICK=2
226 181
227# 182#
228# Cache configuration 183# Cache configuration
229# 184#
230# CONFIG_SH_DIRECT_MAPPED is not set 185# CONFIG_SH_DIRECT_MAPPED is not set
231# CONFIG_SH_WRITETHROUGH is not set 186CONFIG_CACHE_WRITEBACK=y
232# CONFIG_SH_OCRAM is not set 187# CONFIG_CACHE_WRITETHROUGH is not set
188# CONFIG_CACHE_OFF is not set
233 189
234# 190#
235# Processor features 191# Processor features
@@ -237,20 +193,31 @@ CONFIG_ZONE_DMA_FLAG=0
237CONFIG_CPU_LITTLE_ENDIAN=y 193CONFIG_CPU_LITTLE_ENDIAN=y
238# CONFIG_CPU_BIG_ENDIAN is not set 194# CONFIG_CPU_BIG_ENDIAN is not set
239CONFIG_SH_FPU=y 195CONFIG_SH_FPU=y
240# CONFIG_SH_DSP is not set
241CONFIG_SH_STORE_QUEUES=y 196CONFIG_SH_STORE_QUEUES=y
242CONFIG_SPECULATIVE_EXECUTION=y 197# CONFIG_SPECULATIVE_EXECUTION is not set
243CONFIG_CPU_HAS_INTEVT=y 198CONFIG_CPU_HAS_INTEVT=y
244CONFIG_CPU_HAS_INTC_IRQ=y
245CONFIG_CPU_HAS_SR_RB=y 199CONFIG_CPU_HAS_SR_RB=y
200CONFIG_CPU_HAS_FPU=y
201
202#
203# Board support
204#
205# CONFIG_SH_7780_SOLUTION_ENGINE is not set
206CONFIG_SH_SDK7780=y
207# CONFIG_SH_HIGHLANDER is not set
208# CONFIG_SH_SDK7780_STANDALONE is not set
209CONFIG_SH_SDK7780_BASE=y
246 210
247# 211#
248# Timer and clock configuration 212# Timer and clock configuration
249# 213#
250CONFIG_SH_TMU=y 214CONFIG_SH_TMU=y
251CONFIG_SH_TIMER_IRQ=28 215CONFIG_SH_TIMER_IRQ=28
252CONFIG_NO_IDLE_HZ=y 216CONFIG_SH_PCLK_FREQ=33333333
253CONFIG_SH_PCLK_FREQ=32000000 217CONFIG_TICK_ONESHOT=y
218# CONFIG_NO_HZ is not set
219CONFIG_HIGH_RES_TIMERS=y
220CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
254 221
255# 222#
256# CPU Frequency scaling 223# CPU Frequency scaling
@@ -260,18 +227,20 @@ CONFIG_SH_PCLK_FREQ=32000000
260# 227#
261# DMA support 228# DMA support
262# 229#
263# CONFIG_SH_DMA is not set 230CONFIG_SH_DMA_API=y
231CONFIG_SH_DMA=y
232CONFIG_NR_ONCHIP_DMA_CHANNELS=12
233# CONFIG_NR_DMA_CHANNELS_BOOL is not set
264 234
265# 235#
266# Companion Chips 236# Companion Chips
267# 237#
268# CONFIG_HD6446X_SERIES is not set
269 238
270# 239#
271# Additional SuperH Device Drivers 240# Additional SuperH Device Drivers
272# 241#
273# CONFIG_HEARTBEAT is not set 242CONFIG_HEARTBEAT=y
274CONFIG_PUSH_SWITCH=y 243# CONFIG_PUSH_SWITCH is not set
275 244
276# 245#
277# Kernel features 246# Kernel features
@@ -281,22 +250,21 @@ CONFIG_HZ_250=y
281# CONFIG_HZ_300 is not set 250# CONFIG_HZ_300 is not set
282# CONFIG_HZ_1000 is not set 251# CONFIG_HZ_1000 is not set
283CONFIG_HZ=250 252CONFIG_HZ=250
284CONFIG_KEXEC=y 253# CONFIG_KEXEC is not set
285# CONFIG_CRASH_DUMP is not set 254# CONFIG_CRASH_DUMP is not set
286# CONFIG_SMP is not set
287# CONFIG_PREEMPT_NONE is not set 255# CONFIG_PREEMPT_NONE is not set
288# CONFIG_PREEMPT_VOLUNTARY is not set 256# CONFIG_PREEMPT_VOLUNTARY is not set
289CONFIG_PREEMPT=y 257CONFIG_PREEMPT=y
290CONFIG_PREEMPT_BKL=y 258CONFIG_PREEMPT_BKL=y
259CONFIG_GUSA=y
291 260
292# 261#
293# Boot options 262# Boot options
294# 263#
295CONFIG_ZERO_PAGE_OFFSET=0x00001000 264CONFIG_ZERO_PAGE_OFFSET=0x00001000
296CONFIG_BOOT_LINK_OFFSET=0x00800000 265CONFIG_BOOT_LINK_OFFSET=0x01800000
297# CONFIG_UBC_WAKEUP is not set
298CONFIG_CMDLINE_BOOL=y 266CONFIG_CMDLINE_BOOL=y
299CONFIG_CMDLINE="mem=128M console=ttySC0,115200 root=/dev/sda1" 267CONFIG_CMDLINE="mem=128M console=tty0 console=ttySC0,115200 ip=bootp root=/dev/nfs nfsroot=192.168.0.1:/home/rootfs"
300 268
301# 269#
302# Bus options 270# Bus options
@@ -305,31 +273,40 @@ CONFIG_PCI=y
305CONFIG_SH_PCIDMA_NONCOHERENT=y 273CONFIG_SH_PCIDMA_NONCOHERENT=y
306CONFIG_PCI_AUTO=y 274CONFIG_PCI_AUTO=y
307CONFIG_PCI_AUTO_UPDATE_RESOURCES=y 275CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
308# CONFIG_PCI_DEBUG is not set 276# CONFIG_ARCH_SUPPORTS_MSI is not set
309 277# CONFIG_PCI_LEGACY is not set
310# 278CONFIG_PCI_DEBUG=y
311# PCCARD (PCMCIA/CardBus) support 279CONFIG_PCCARD=y
312# 280# CONFIG_PCMCIA_DEBUG is not set
313# CONFIG_PCCARD is not set 281CONFIG_PCMCIA=y
314 282CONFIG_PCMCIA_LOAD_CIS=y
315# 283CONFIG_PCMCIA_IOCTL=y
316# PCI Hotplug Support 284CONFIG_CARDBUS=y
317# 285
318# CONFIG_HOTPLUG_PCI is not set 286#
287# PC-card bridges
288#
289CONFIG_YENTA=y
290CONFIG_YENTA_O2=y
291CONFIG_YENTA_RICOH=y
292CONFIG_YENTA_TI=y
293CONFIG_YENTA_ENE_TUNE=y
294CONFIG_YENTA_TOSHIBA=y
295# CONFIG_PD6729 is not set
296# CONFIG_I82092 is not set
297CONFIG_PCCARD_NONSTATIC=y
298CONFIG_HOTPLUG_PCI=y
299# CONFIG_HOTPLUG_PCI_FAKE is not set
300# CONFIG_HOTPLUG_PCI_CPCI is not set
301# CONFIG_HOTPLUG_PCI_SHPC is not set
319 302
320# 303#
321# Executable file formats 304# Executable file formats
322# 305#
323CONFIG_BINFMT_ELF=y 306CONFIG_BINFMT_ELF=y
324# CONFIG_BINFMT_FLAT is not set
325# CONFIG_BINFMT_MISC is not set 307# CONFIG_BINFMT_MISC is not set
326 308
327# 309#
328# Power management options (EXPERIMENTAL)
329#
330# CONFIG_PM is not set
331
332#
333# Networking 310# Networking
334# 311#
335CONFIG_NET=y 312CONFIG_NET=y
@@ -337,7 +314,6 @@ CONFIG_NET=y
337# 314#
338# Networking options 315# Networking options
339# 316#
340# CONFIG_NETDEBUG is not set
341CONFIG_PACKET=y 317CONFIG_PACKET=y
342# CONFIG_PACKET_MMAP is not set 318# CONFIG_PACKET_MMAP is not set
343CONFIG_UNIX=y 319CONFIG_UNIX=y
@@ -347,7 +323,7 @@ CONFIG_XFRM=y
347# CONFIG_XFRM_MIGRATE is not set 323# CONFIG_XFRM_MIGRATE is not set
348# CONFIG_NET_KEY is not set 324# CONFIG_NET_KEY is not set
349CONFIG_INET=y 325CONFIG_INET=y
350# CONFIG_IP_MULTICAST is not set 326CONFIG_IP_MULTICAST=y
351CONFIG_IP_ADVANCED_ROUTER=y 327CONFIG_IP_ADVANCED_ROUTER=y
352CONFIG_ASK_IP_FIB_HASH=y 328CONFIG_ASK_IP_FIB_HASH=y
353# CONFIG_IP_FIB_TRIE is not set 329# CONFIG_IP_FIB_TRIE is not set
@@ -356,52 +332,55 @@ CONFIG_IP_FIB_HASH=y
356# CONFIG_IP_ROUTE_MULTIPATH is not set 332# CONFIG_IP_ROUTE_MULTIPATH is not set
357# CONFIG_IP_ROUTE_VERBOSE is not set 333# CONFIG_IP_ROUTE_VERBOSE is not set
358CONFIG_IP_PNP=y 334CONFIG_IP_PNP=y
359CONFIG_IP_PNP_DHCP=y 335# CONFIG_IP_PNP_DHCP is not set
360# CONFIG_IP_PNP_BOOTP is not set 336CONFIG_IP_PNP_BOOTP=y
361# CONFIG_IP_PNP_RARP is not set 337# CONFIG_IP_PNP_RARP is not set
362# CONFIG_NET_IPIP is not set 338# CONFIG_NET_IPIP is not set
363# CONFIG_NET_IPGRE is not set 339# CONFIG_NET_IPGRE is not set
340# CONFIG_IP_MROUTE is not set
364# CONFIG_ARPD is not set 341# CONFIG_ARPD is not set
365# CONFIG_SYN_COOKIES is not set 342# CONFIG_SYN_COOKIES is not set
366# CONFIG_INET_AH is not set 343# CONFIG_INET_AH is not set
367# CONFIG_INET_ESP is not set 344# CONFIG_INET_ESP is not set
368# CONFIG_INET_IPCOMP is not set 345# CONFIG_INET_IPCOMP is not set
369# CONFIG_INET_XFRM_TUNNEL is not set 346# CONFIG_INET_XFRM_TUNNEL is not set
370# CONFIG_INET_TUNNEL is not set 347CONFIG_INET_TUNNEL=y
371CONFIG_INET_XFRM_MODE_TRANSPORT=y 348CONFIG_INET_XFRM_MODE_TRANSPORT=y
372CONFIG_INET_XFRM_MODE_TUNNEL=y 349CONFIG_INET_XFRM_MODE_TUNNEL=y
373CONFIG_INET_XFRM_MODE_BEET=y 350# CONFIG_INET_XFRM_MODE_BEET is not set
351# CONFIG_INET_LRO is not set
374CONFIG_INET_DIAG=y 352CONFIG_INET_DIAG=y
375CONFIG_INET_TCP_DIAG=y 353CONFIG_INET_TCP_DIAG=y
376# CONFIG_TCP_CONG_ADVANCED is not set 354# CONFIG_TCP_CONG_ADVANCED is not set
377CONFIG_TCP_CONG_CUBIC=y 355CONFIG_TCP_CONG_CUBIC=y
378CONFIG_DEFAULT_TCP_CONG="cubic" 356CONFIG_DEFAULT_TCP_CONG="cubic"
379# CONFIG_TCP_MD5SIG is not set 357# CONFIG_TCP_MD5SIG is not set
380# CONFIG_IPV6 is not set 358CONFIG_IPV6=y
359# CONFIG_IPV6_PRIVACY is not set
360# CONFIG_IPV6_ROUTER_PREF is not set
361# CONFIG_IPV6_OPTIMISTIC_DAD is not set
362# CONFIG_INET6_AH is not set
363# CONFIG_INET6_ESP is not set
364# CONFIG_INET6_IPCOMP is not set
365# CONFIG_IPV6_MIP6 is not set
381# CONFIG_INET6_XFRM_TUNNEL is not set 366# CONFIG_INET6_XFRM_TUNNEL is not set
382# CONFIG_INET6_TUNNEL is not set 367# CONFIG_INET6_TUNNEL is not set
368CONFIG_INET6_XFRM_MODE_TRANSPORT=y
369CONFIG_INET6_XFRM_MODE_TUNNEL=y
370# CONFIG_INET6_XFRM_MODE_BEET is not set
371# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
372CONFIG_IPV6_SIT=y
373# CONFIG_IPV6_TUNNEL is not set
374# CONFIG_IPV6_MULTIPLE_TABLES is not set
383# CONFIG_NETWORK_SECMARK is not set 375# CONFIG_NETWORK_SECMARK is not set
384# CONFIG_NETFILTER is not set 376# CONFIG_NETFILTER is not set
385
386#
387# DCCP Configuration (EXPERIMENTAL)
388#
389# CONFIG_IP_DCCP is not set 377# CONFIG_IP_DCCP is not set
390
391#
392# SCTP Configuration (EXPERIMENTAL)
393#
394# CONFIG_IP_SCTP is not set 378# CONFIG_IP_SCTP is not set
395
396#
397# TIPC Configuration (EXPERIMENTAL)
398#
399# CONFIG_TIPC is not set 379# CONFIG_TIPC is not set
400# CONFIG_ATM is not set 380# CONFIG_ATM is not set
401CONFIG_BRIDGE=m 381# CONFIG_BRIDGE is not set
402# CONFIG_VLAN_8021Q is not set 382# CONFIG_VLAN_8021Q is not set
403# CONFIG_DECNET is not set 383# CONFIG_DECNET is not set
404CONFIG_LLC=m
405# CONFIG_LLC2 is not set 384# CONFIG_LLC2 is not set
406# CONFIG_IPX is not set 385# CONFIG_IPX is not set
407# CONFIG_ATALK is not set 386# CONFIG_ATALK is not set
@@ -409,11 +388,39 @@ CONFIG_LLC=m
409# CONFIG_LAPB is not set 388# CONFIG_LAPB is not set
410# CONFIG_ECONET is not set 389# CONFIG_ECONET is not set
411# CONFIG_WAN_ROUTER is not set 390# CONFIG_WAN_ROUTER is not set
391CONFIG_NET_SCHED=y
392
393#
394# Queueing/Scheduling
395#
396# CONFIG_NET_SCH_CBQ is not set
397# CONFIG_NET_SCH_HTB is not set
398# CONFIG_NET_SCH_HFSC is not set
399# CONFIG_NET_SCH_PRIO is not set
400# CONFIG_NET_SCH_RR is not set
401# CONFIG_NET_SCH_RED is not set
402# CONFIG_NET_SCH_SFQ is not set
403# CONFIG_NET_SCH_TEQL is not set
404# CONFIG_NET_SCH_TBF is not set
405# CONFIG_NET_SCH_GRED is not set
406# CONFIG_NET_SCH_DSMARK is not set
407# CONFIG_NET_SCH_NETEM is not set
408# CONFIG_NET_SCH_INGRESS is not set
412 409
413# 410#
414# QoS and/or fair queueing 411# Classification
415# 412#
416# CONFIG_NET_SCHED is not set 413# CONFIG_NET_CLS_BASIC is not set
414# CONFIG_NET_CLS_TCINDEX is not set
415# CONFIG_NET_CLS_ROUTE4 is not set
416# CONFIG_NET_CLS_FW is not set
417# CONFIG_NET_CLS_U32 is not set
418# CONFIG_NET_CLS_RSVP is not set
419# CONFIG_NET_CLS_RSVP6 is not set
420# CONFIG_NET_EMATCH is not set
421# CONFIG_NET_CLS_ACT is not set
422# CONFIG_NET_CLS_POLICE is not set
423CONFIG_NET_SCH_FIFO=y
417 424
418# 425#
419# Network testing 426# Network testing
@@ -422,8 +429,17 @@ CONFIG_LLC=m
422# CONFIG_HAMRADIO is not set 429# CONFIG_HAMRADIO is not set
423# CONFIG_IRDA is not set 430# CONFIG_IRDA is not set
424# CONFIG_BT is not set 431# CONFIG_BT is not set
432# CONFIG_AF_RXRPC is not set
433
434#
435# Wireless
436#
437# CONFIG_CFG80211 is not set
438# CONFIG_WIRELESS_EXT is not set
439# CONFIG_MAC80211 is not set
425# CONFIG_IEEE80211 is not set 440# CONFIG_IEEE80211 is not set
426CONFIG_WIRELESS_EXT=y 441# CONFIG_RFKILL is not set
442# CONFIG_NET_9P is not set
427 443
428# 444#
429# Device Drivers 445# Device Drivers
@@ -432,69 +448,108 @@ CONFIG_WIRELESS_EXT=y
432# 448#
433# Generic Driver Options 449# Generic Driver Options
434# 450#
451CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
435CONFIG_STANDALONE=y 452CONFIG_STANDALONE=y
436CONFIG_PREVENT_FIRMWARE_BUILD=y 453CONFIG_PREVENT_FIRMWARE_BUILD=y
437CONFIG_FW_LOADER=m 454CONFIG_FW_LOADER=y
438# CONFIG_DEBUG_DRIVER is not set 455# CONFIG_DEBUG_DRIVER is not set
439# CONFIG_DEBUG_DEVRES is not set 456# CONFIG_DEBUG_DEVRES is not set
440# CONFIG_SYS_HYPERVISOR is not set 457# CONFIG_SYS_HYPERVISOR is not set
441
442#
443# Connector - unified userspace <-> kernelspace linker
444#
445# CONFIG_CONNECTOR is not set 458# CONFIG_CONNECTOR is not set
446
447#
448# Memory Technology Devices (MTD)
449#
450# CONFIG_MTD is not set 459# CONFIG_MTD is not set
451 460CONFIG_PARPORT=y
452# 461# CONFIG_PARPORT_PC is not set
453# Parallel port support 462# CONFIG_PARPORT_GSC is not set
454# 463# CONFIG_PARPORT_AX88796 is not set
455# CONFIG_PARPORT is not set 464# CONFIG_PARPORT_1284 is not set
456 465CONFIG_BLK_DEV=y
457#
458# Plug and Play support
459#
460# CONFIG_PNPACPI is not set
461
462#
463# Block devices
464#
465# CONFIG_BLK_CPQ_DA is not set
466# CONFIG_BLK_CPQ_CISS_DA is not set 466# CONFIG_BLK_CPQ_CISS_DA is not set
467# CONFIG_BLK_DEV_DAC960 is not set 467# CONFIG_BLK_DEV_DAC960 is not set
468# CONFIG_BLK_DEV_UMEM is not set 468# CONFIG_BLK_DEV_UMEM is not set
469# CONFIG_BLK_DEV_COW_COMMON is not set 469# CONFIG_BLK_DEV_COW_COMMON is not set
470# CONFIG_BLK_DEV_LOOP is not set 470CONFIG_BLK_DEV_LOOP=y
471# CONFIG_BLK_DEV_CRYPTOLOOP is not set
471# CONFIG_BLK_DEV_NBD is not set 472# CONFIG_BLK_DEV_NBD is not set
472# CONFIG_BLK_DEV_SX8 is not set 473# CONFIG_BLK_DEV_SX8 is not set
474# CONFIG_BLK_DEV_UB is not set
473CONFIG_BLK_DEV_RAM=y 475CONFIG_BLK_DEV_RAM=y
474CONFIG_BLK_DEV_RAM_COUNT=16 476CONFIG_BLK_DEV_RAM_COUNT=16
475CONFIG_BLK_DEV_RAM_SIZE=4096 477CONFIG_BLK_DEV_RAM_SIZE=4096
476CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 478CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
477# CONFIG_CDROM_PKTCDVD is not set 479# CONFIG_CDROM_PKTCDVD is not set
478# CONFIG_ATA_OVER_ETH is not set 480# CONFIG_ATA_OVER_ETH is not set
479 481# CONFIG_MISC_DEVICES is not set
480# 482CONFIG_IDE=y
481# Misc devices 483CONFIG_IDE_MAX_HWIFS=4
482# 484CONFIG_BLK_DEV_IDE=y
483# CONFIG_SGI_IOC4 is not set 485
484# CONFIG_TIFM_CORE is not set 486#
485 487# Please see Documentation/ide.txt for help/info on IDE drives
486# 488#
487# ATA/ATAPI/MFM/RLL support 489# CONFIG_BLK_DEV_IDE_SATA is not set
488# 490CONFIG_BLK_DEV_IDEDISK=y
489# CONFIG_IDE is not set 491CONFIG_IDEDISK_MULTI_MODE=y
492# CONFIG_BLK_DEV_IDECS is not set
493# CONFIG_BLK_DEV_DELKIN is not set
494CONFIG_BLK_DEV_IDECD=y
495# CONFIG_BLK_DEV_IDETAPE is not set
496# CONFIG_BLK_DEV_IDEFLOPPY is not set
497# CONFIG_BLK_DEV_IDESCSI is not set
498# CONFIG_IDE_TASK_IOCTL is not set
499CONFIG_IDE_PROC_FS=y
500
501#
502# IDE chipset support/bugfixes
503#
504CONFIG_IDE_GENERIC=y
505CONFIG_BLK_DEV_PLATFORM=y
506
507#
508# PCI IDE chipsets support
509#
510CONFIG_BLK_DEV_IDEPCI=y
511# CONFIG_IDEPCI_SHARE_IRQ is not set
512CONFIG_IDEPCI_PCIBUS_ORDER=y
513# CONFIG_BLK_DEV_OFFBOARD is not set
514CONFIG_BLK_DEV_GENERIC=y
515# CONFIG_BLK_DEV_OPTI621 is not set
516# CONFIG_BLK_DEV_AEC62XX is not set
517# CONFIG_BLK_DEV_ALI15X3 is not set
518# CONFIG_BLK_DEV_AMD74XX is not set
519# CONFIG_BLK_DEV_CMD64X is not set
520# CONFIG_BLK_DEV_TRIFLEX is not set
521# CONFIG_BLK_DEV_CY82C693 is not set
522# CONFIG_BLK_DEV_CS5520 is not set
523# CONFIG_BLK_DEV_CS5530 is not set
524# CONFIG_BLK_DEV_HPT34X is not set
525# CONFIG_BLK_DEV_HPT366 is not set
526# CONFIG_BLK_DEV_JMICRON is not set
527# CONFIG_BLK_DEV_SC1200 is not set
528# CONFIG_BLK_DEV_PIIX is not set
529# CONFIG_BLK_DEV_IT8213 is not set
530# CONFIG_BLK_DEV_IT821X is not set
531# CONFIG_BLK_DEV_NS87415 is not set
532# CONFIG_BLK_DEV_PDC202XX_OLD is not set
533# CONFIG_BLK_DEV_PDC202XX_NEW is not set
534# CONFIG_BLK_DEV_SVWKS is not set
535# CONFIG_BLK_DEV_SIIMAGE is not set
536# CONFIG_BLK_DEV_SLC90E66 is not set
537# CONFIG_BLK_DEV_TRM290 is not set
538# CONFIG_BLK_DEV_VIA82CXXX is not set
539# CONFIG_BLK_DEV_TC86C001 is not set
540# CONFIG_IDE_ARM is not set
541# CONFIG_BLK_DEV_IDEDMA is not set
542# CONFIG_IDE_ARCH_OBSOLETE_INIT is not set
543# CONFIG_BLK_DEV_HD is not set
490 544
491# 545#
492# SCSI device support 546# SCSI device support
493# 547#
494# CONFIG_RAID_ATTRS is not set 548# CONFIG_RAID_ATTRS is not set
495CONFIG_SCSI=y 549CONFIG_SCSI=y
550CONFIG_SCSI_DMA=y
496# CONFIG_SCSI_TGT is not set 551# CONFIG_SCSI_TGT is not set
497# CONFIG_SCSI_NETLINK is not set 552CONFIG_SCSI_NETLINK=y
498CONFIG_SCSI_PROC_FS=y 553CONFIG_SCSI_PROC_FS=y
499 554
500# 555#
@@ -503,8 +558,9 @@ CONFIG_SCSI_PROC_FS=y
503CONFIG_BLK_DEV_SD=y 558CONFIG_BLK_DEV_SD=y
504# CONFIG_CHR_DEV_ST is not set 559# CONFIG_CHR_DEV_ST is not set
505# CONFIG_CHR_DEV_OSST is not set 560# CONFIG_CHR_DEV_OSST is not set
506# CONFIG_BLK_DEV_SR is not set 561CONFIG_BLK_DEV_SR=y
507CONFIG_CHR_DEV_SG=m 562# CONFIG_BLK_DEV_SR_VENDOR is not set
563CONFIG_CHR_DEV_SG=y
508# CONFIG_CHR_DEV_SCH is not set 564# CONFIG_CHR_DEV_SCH is not set
509 565
510# 566#
@@ -514,19 +570,17 @@ CONFIG_CHR_DEV_SG=m
514# CONFIG_SCSI_CONSTANTS is not set 570# CONFIG_SCSI_CONSTANTS is not set
515# CONFIG_SCSI_LOGGING is not set 571# CONFIG_SCSI_LOGGING is not set
516# CONFIG_SCSI_SCAN_ASYNC is not set 572# CONFIG_SCSI_SCAN_ASYNC is not set
573CONFIG_SCSI_WAIT_SCAN=m
517 574
518# 575#
519# SCSI Transports 576# SCSI Transports
520# 577#
521# CONFIG_SCSI_SPI_ATTRS is not set 578CONFIG_SCSI_SPI_ATTRS=y
522# CONFIG_SCSI_FC_ATTRS is not set 579CONFIG_SCSI_FC_ATTRS=y
523# CONFIG_SCSI_ISCSI_ATTRS is not set 580# CONFIG_SCSI_ISCSI_ATTRS is not set
524# CONFIG_SCSI_SAS_ATTRS is not set
525# CONFIG_SCSI_SAS_LIBSAS is not set 581# CONFIG_SCSI_SAS_LIBSAS is not set
526 582# CONFIG_SCSI_SRP_ATTRS is not set
527# 583CONFIG_SCSI_LOWLEVEL=y
528# SCSI low-level drivers
529#
530# CONFIG_ISCSI_TCP is not set 584# CONFIG_ISCSI_TCP is not set
531# CONFIG_BLK_DEV_3W_XXXX_RAID is not set 585# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
532# CONFIG_SCSI_3W_9XXX is not set 586# CONFIG_SCSI_3W_9XXX is not set
@@ -536,7 +590,6 @@ CONFIG_CHR_DEV_SG=m
536# CONFIG_SCSI_AIC7XXX_OLD is not set 590# CONFIG_SCSI_AIC7XXX_OLD is not set
537# CONFIG_SCSI_AIC79XX is not set 591# CONFIG_SCSI_AIC79XX is not set
538# CONFIG_SCSI_AIC94XX is not set 592# CONFIG_SCSI_AIC94XX is not set
539# CONFIG_SCSI_DPT_I2O is not set
540# CONFIG_SCSI_ARCMSR is not set 593# CONFIG_SCSI_ARCMSR is not set
541# CONFIG_MEGARAID_NEWGEN is not set 594# CONFIG_MEGARAID_NEWGEN is not set
542# CONFIG_MEGARAID_LEGACY is not set 595# CONFIG_MEGARAID_LEGACY is not set
@@ -559,10 +612,7 @@ CONFIG_CHR_DEV_SG=m
559# CONFIG_SCSI_NSP32 is not set 612# CONFIG_SCSI_NSP32 is not set
560# CONFIG_SCSI_DEBUG is not set 613# CONFIG_SCSI_DEBUG is not set
561# CONFIG_SCSI_SRP is not set 614# CONFIG_SCSI_SRP is not set
562 615# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
563#
564# Serial ATA (prod) and Parallel ATA (experimental) drivers
565#
566CONFIG_ATA=y 616CONFIG_ATA=y
567# CONFIG_ATA_NONSTANDARD is not set 617# CONFIG_ATA_NONSTANDARD is not set
568# CONFIG_SATA_AHCI is not set 618# CONFIG_SATA_AHCI is not set
@@ -574,7 +624,7 @@ CONFIG_ATA=y
574# CONFIG_SATA_QSTOR is not set 624# CONFIG_SATA_QSTOR is not set
575# CONFIG_SATA_PROMISE is not set 625# CONFIG_SATA_PROMISE is not set
576# CONFIG_SATA_SX4 is not set 626# CONFIG_SATA_SX4 is not set
577CONFIG_SATA_SIL=y 627# CONFIG_SATA_SIL is not set
578# CONFIG_SATA_SIL24 is not set 628# CONFIG_SATA_SIL24 is not set
579# CONFIG_SATA_SIS is not set 629# CONFIG_SATA_SIS is not set
580# CONFIG_SATA_ULI is not set 630# CONFIG_SATA_ULI is not set
@@ -585,6 +635,7 @@ CONFIG_SATA_SIL=y
585# CONFIG_PATA_AMD is not set 635# CONFIG_PATA_AMD is not set
586# CONFIG_PATA_ARTOP is not set 636# CONFIG_PATA_ARTOP is not set
587# CONFIG_PATA_ATIIXP is not set 637# CONFIG_PATA_ATIIXP is not set
638# CONFIG_PATA_CMD640_PCI is not set
588# CONFIG_PATA_CMD64X is not set 639# CONFIG_PATA_CMD64X is not set
589# CONFIG_PATA_CS5520 is not set 640# CONFIG_PATA_CS5520 is not set
590# CONFIG_PATA_CS5530 is not set 641# CONFIG_PATA_CS5530 is not set
@@ -604,8 +655,10 @@ CONFIG_SATA_SIL=y
604# CONFIG_PATA_OLDPIIX is not set 655# CONFIG_PATA_OLDPIIX is not set
605# CONFIG_PATA_NETCELL is not set 656# CONFIG_PATA_NETCELL is not set
606# CONFIG_PATA_NS87410 is not set 657# CONFIG_PATA_NS87410 is not set
658# CONFIG_PATA_NS87415 is not set
607# CONFIG_PATA_OPTI is not set 659# CONFIG_PATA_OPTI is not set
608# CONFIG_PATA_OPTIDMA is not set 660# CONFIG_PATA_OPTIDMA is not set
661# CONFIG_PATA_PCMCIA is not set
609# CONFIG_PATA_PDC_OLD is not set 662# CONFIG_PATA_PDC_OLD is not set
610# CONFIG_PATA_RADISYS is not set 663# CONFIG_PATA_RADISYS is not set
611# CONFIG_PATA_RZ1000 is not set 664# CONFIG_PATA_RZ1000 is not set
@@ -616,185 +669,87 @@ CONFIG_SATA_SIL=y
616# CONFIG_PATA_SIS is not set 669# CONFIG_PATA_SIS is not set
617# CONFIG_PATA_VIA is not set 670# CONFIG_PATA_VIA is not set
618# CONFIG_PATA_WINBOND is not set 671# CONFIG_PATA_WINBOND is not set
619CONFIG_PATA_PLATFORM=y 672# CONFIG_PATA_PLATFORM is not set
620 673CONFIG_MD=y
621# 674# CONFIG_BLK_DEV_MD is not set
622# Multi-device support (RAID and LVM) 675CONFIG_BLK_DEV_DM=y
623# 676# CONFIG_DM_DEBUG is not set
624# CONFIG_MD is not set 677# CONFIG_DM_CRYPT is not set
625 678# CONFIG_DM_SNAPSHOT is not set
626# 679# CONFIG_DM_MIRROR is not set
627# Fusion MPT device support 680# CONFIG_DM_ZERO is not set
628# 681# CONFIG_DM_MULTIPATH is not set
682# CONFIG_DM_DELAY is not set
683# CONFIG_DM_UEVENT is not set
629# CONFIG_FUSION is not set 684# CONFIG_FUSION is not set
630# CONFIG_FUSION_SPI is not set
631# CONFIG_FUSION_FC is not set
632# CONFIG_FUSION_SAS is not set
633 685
634# 686#
635# IEEE 1394 (FireWire) support 687# IEEE 1394 (FireWire) support
636# 688#
689# CONFIG_FIREWIRE is not set
637# CONFIG_IEEE1394 is not set 690# CONFIG_IEEE1394 is not set
638
639#
640# I2O device support
641#
642# CONFIG_I2O is not set 691# CONFIG_I2O is not set
643
644#
645# Network device support
646#
647CONFIG_NETDEVICES=y 692CONFIG_NETDEVICES=y
693# CONFIG_NETDEVICES_MULTIQUEUE is not set
648# CONFIG_DUMMY is not set 694# CONFIG_DUMMY is not set
649# CONFIG_BONDING is not set 695# CONFIG_BONDING is not set
696# CONFIG_MACVLAN is not set
650# CONFIG_EQUALIZER is not set 697# CONFIG_EQUALIZER is not set
651# CONFIG_TUN is not set 698# CONFIG_TUN is not set
652 699# CONFIG_VETH is not set
653#
654# ARCnet devices
655#
656# CONFIG_ARCNET is not set 700# CONFIG_ARCNET is not set
657
658#
659# PHY device support
660#
661# CONFIG_PHYLIB is not set 701# CONFIG_PHYLIB is not set
662
663#
664# Ethernet (10 or 100Mbit)
665#
666CONFIG_NET_ETHERNET=y 702CONFIG_NET_ETHERNET=y
667CONFIG_MII=y 703CONFIG_MII=y
704# CONFIG_AX88796 is not set
668# CONFIG_STNIC is not set 705# CONFIG_STNIC is not set
669# CONFIG_HAPPYMEAL is not set 706# CONFIG_HAPPYMEAL is not set
670# CONFIG_SUNGEM is not set 707# CONFIG_SUNGEM is not set
671# CONFIG_CASSINI is not set 708# CONFIG_CASSINI is not set
672# CONFIG_NET_VENDOR_3COM is not set 709# CONFIG_NET_VENDOR_3COM is not set
673# CONFIG_SMC91X is not set 710CONFIG_SMC91X=y
674
675#
676# Tulip family network device support
677#
678# CONFIG_NET_TULIP is not set 711# CONFIG_NET_TULIP is not set
679# CONFIG_HP100 is not set 712# CONFIG_HP100 is not set
680CONFIG_NET_PCI=y 713# CONFIG_IBM_NEW_EMAC_ZMII is not set
681CONFIG_PCNET32=m 714# CONFIG_IBM_NEW_EMAC_RGMII is not set
682# CONFIG_PCNET32_NAPI is not set 715# CONFIG_IBM_NEW_EMAC_TAH is not set
683# CONFIG_AMD8111_ETH is not set 716# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
684# CONFIG_ADAPTEC_STARFIRE is not set 717# CONFIG_NET_PCI is not set
685# CONFIG_B44 is not set 718# CONFIG_B44 is not set
686# CONFIG_FORCEDETH is not set 719# CONFIG_NET_POCKET is not set
687# CONFIG_DGRS is not set 720# CONFIG_NETDEV_1000 is not set
688# CONFIG_EEPRO100 is not set 721# CONFIG_NETDEV_10000 is not set
689# CONFIG_E100 is not set
690# CONFIG_FEALNX is not set
691# CONFIG_NATSEMI is not set
692# CONFIG_NE2K_PCI is not set
693CONFIG_8139CP=m
694CONFIG_8139TOO=m
695# CONFIG_8139TOO_PIO is not set
696# CONFIG_8139TOO_TUNE_TWISTER is not set
697CONFIG_8139TOO_8129=y
698# CONFIG_8139_OLD_RX_RESET is not set
699# CONFIG_SIS900 is not set
700# CONFIG_EPIC100 is not set
701# CONFIG_SUNDANCE is not set
702# CONFIG_TLAN is not set
703CONFIG_VIA_RHINE=m
704CONFIG_VIA_RHINE_MMIO=y
705# CONFIG_VIA_RHINE_NAPI is not set
706# CONFIG_SC92031 is not set
707
708#
709# Ethernet (1000 Mbit)
710#
711# CONFIG_ACENIC is not set
712# CONFIG_DL2K is not set
713CONFIG_E1000=m
714# CONFIG_E1000_NAPI is not set
715# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
716# CONFIG_NS83820 is not set
717# CONFIG_HAMACHI is not set
718# CONFIG_YELLOWFIN is not set
719CONFIG_R8169=y
720# CONFIG_R8169_NAPI is not set
721# CONFIG_SIS190 is not set
722# CONFIG_SKGE is not set
723# CONFIG_SKY2 is not set
724# CONFIG_SK98LIN is not set
725# CONFIG_VIA_VELOCITY is not set
726# CONFIG_TIGON3 is not set
727# CONFIG_BNX2 is not set
728# CONFIG_QLA3XXX is not set
729# CONFIG_ATL1 is not set
730
731#
732# Ethernet (10000 Mbit)
733#
734# CONFIG_CHELSIO_T1 is not set
735# CONFIG_CHELSIO_T3 is not set
736# CONFIG_IXGB is not set
737# CONFIG_S2IO is not set
738# CONFIG_MYRI10GE is not set
739# CONFIG_NETXEN_NIC is not set
740
741#
742# Token Ring devices
743#
744# CONFIG_TR is not set 722# CONFIG_TR is not set
745 723
746# 724#
747# Wireless LAN (non-hamradio) 725# Wireless LAN
748#
749CONFIG_NET_RADIO=y
750# CONFIG_NET_WIRELESS_RTNETLINK is not set
751
752#
753# Obsolete Wireless cards support (pre-802.11)
754#
755# CONFIG_STRIP is not set
756
757#
758# Wireless 802.11b ISA/PCI cards support
759#
760# CONFIG_IPW2100 is not set
761# CONFIG_IPW2200 is not set
762CONFIG_HERMES=m
763# CONFIG_PLX_HERMES is not set
764# CONFIG_TMD_HERMES is not set
765# CONFIG_NORTEL_HERMES is not set
766# CONFIG_PCI_HERMES is not set
767# CONFIG_ATMEL is not set
768
769#
770# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
771# 726#
772CONFIG_PRISM54=m 727# CONFIG_WLAN_PRE80211 is not set
773# CONFIG_HOSTAP is not set 728# CONFIG_WLAN_80211 is not set
774CONFIG_NET_WIRELESS=y
775 729
776# 730#
777# Wan interfaces 731# USB Network Adapters
778# 732#
733# CONFIG_USB_CATC is not set
734# CONFIG_USB_KAWETH is not set
735# CONFIG_USB_PEGASUS is not set
736# CONFIG_USB_RTL8150 is not set
737# CONFIG_USB_USBNET is not set
738# CONFIG_NET_PCMCIA is not set
779# CONFIG_WAN is not set 739# CONFIG_WAN is not set
780# CONFIG_FDDI is not set 740# CONFIG_FDDI is not set
781# CONFIG_HIPPI is not set 741# CONFIG_HIPPI is not set
742# CONFIG_PLIP is not set
782# CONFIG_PPP is not set 743# CONFIG_PPP is not set
783# CONFIG_SLIP is not set 744# CONFIG_SLIP is not set
784# CONFIG_NET_FC is not set 745# CONFIG_NET_FC is not set
785# CONFIG_SHAPER is not set 746# CONFIG_SHAPER is not set
786# CONFIG_NETCONSOLE is not set 747CONFIG_NETCONSOLE=y
787# CONFIG_NETPOLL is not set 748# CONFIG_NETCONSOLE_DYNAMIC is not set
788# CONFIG_NET_POLL_CONTROLLER is not set 749CONFIG_NETPOLL=y
789 750# CONFIG_NETPOLL_TRAP is not set
790# 751CONFIG_NET_POLL_CONTROLLER=y
791# ISDN subsystem
792#
793# CONFIG_ISDN is not set 752# CONFIG_ISDN is not set
794
795#
796# Telephony Support
797#
798# CONFIG_PHONE is not set 753# CONFIG_PHONE is not set
799 754
800# 755#
@@ -802,17 +757,17 @@ CONFIG_NET_WIRELESS=y
802# 757#
803CONFIG_INPUT=y 758CONFIG_INPUT=y
804# CONFIG_INPUT_FF_MEMLESS is not set 759# CONFIG_INPUT_FF_MEMLESS is not set
760# CONFIG_INPUT_POLLDEV is not set
805 761
806# 762#
807# Userland interfaces 763# Userland interfaces
808# 764#
809CONFIG_INPUT_MOUSEDEV=y 765CONFIG_INPUT_MOUSEDEV=y
810# CONFIG_INPUT_MOUSEDEV_PSAUX is not set 766CONFIG_INPUT_MOUSEDEV_PSAUX=y
811CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 767CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
812CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 768CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
813# CONFIG_INPUT_JOYDEV is not set 769# CONFIG_INPUT_JOYDEV is not set
814# CONFIG_INPUT_TSDEV is not set 770CONFIG_INPUT_EVDEV=y
815# CONFIG_INPUT_EVDEV is not set
816# CONFIG_INPUT_EVBUG is not set 771# CONFIG_INPUT_EVBUG is not set
817 772
818# 773#
@@ -825,8 +780,19 @@ CONFIG_KEYBOARD_ATKBD=y
825# CONFIG_KEYBOARD_XTKBD is not set 780# CONFIG_KEYBOARD_XTKBD is not set
826# CONFIG_KEYBOARD_NEWTON is not set 781# CONFIG_KEYBOARD_NEWTON is not set
827# CONFIG_KEYBOARD_STOWAWAY is not set 782# CONFIG_KEYBOARD_STOWAWAY is not set
828# CONFIG_INPUT_MOUSE is not set 783CONFIG_INPUT_MOUSE=y
784CONFIG_MOUSE_PS2=y
785CONFIG_MOUSE_PS2_ALPS=y
786CONFIG_MOUSE_PS2_LOGIPS2PP=y
787CONFIG_MOUSE_PS2_SYNAPTICS=y
788CONFIG_MOUSE_PS2_LIFEBOOK=y
789CONFIG_MOUSE_PS2_TRACKPOINT=y
790# CONFIG_MOUSE_PS2_TOUCHKIT is not set
791# CONFIG_MOUSE_SERIAL is not set
792# CONFIG_MOUSE_APPLETOUCH is not set
793# CONFIG_MOUSE_VSXXXAA is not set
829# CONFIG_INPUT_JOYSTICK is not set 794# CONFIG_INPUT_JOYSTICK is not set
795# CONFIG_INPUT_TABLET is not set
830# CONFIG_INPUT_TOUCHSCREEN is not set 796# CONFIG_INPUT_TOUCHSCREEN is not set
831# CONFIG_INPUT_MISC is not set 797# CONFIG_INPUT_MISC is not set
832 798
@@ -836,6 +802,7 @@ CONFIG_KEYBOARD_ATKBD=y
836CONFIG_SERIO=y 802CONFIG_SERIO=y
837# CONFIG_SERIO_I8042 is not set 803# CONFIG_SERIO_I8042 is not set
838# CONFIG_SERIO_SERPORT is not set 804# CONFIG_SERIO_SERPORT is not set
805# CONFIG_SERIO_PARKBD is not set
839# CONFIG_SERIO_PCIPS2 is not set 806# CONFIG_SERIO_PCIPS2 is not set
840CONFIG_SERIO_LIBPS2=y 807CONFIG_SERIO_LIBPS2=y
841# CONFIG_SERIO_RAW is not set 808# CONFIG_SERIO_RAW is not set
@@ -844,7 +811,10 @@ CONFIG_SERIO_LIBPS2=y
844# 811#
845# Character devices 812# Character devices
846# 813#
847# CONFIG_VT is not set 814CONFIG_VT=y
815CONFIG_VT_CONSOLE=y
816CONFIG_HW_CONSOLE=y
817# CONFIG_VT_HW_CONSOLE_BINDING is not set
848# CONFIG_SERIAL_NONSTANDARD is not set 818# CONFIG_SERIAL_NONSTANDARD is not set
849 819
850# 820#
@@ -864,32 +834,22 @@ CONFIG_SERIAL_CORE_CONSOLE=y
864CONFIG_UNIX98_PTYS=y 834CONFIG_UNIX98_PTYS=y
865CONFIG_LEGACY_PTYS=y 835CONFIG_LEGACY_PTYS=y
866CONFIG_LEGACY_PTY_COUNT=256 836CONFIG_LEGACY_PTY_COUNT=256
867 837# CONFIG_PRINTER is not set
868# 838# CONFIG_PPDEV is not set
869# IPMI
870#
871# CONFIG_IPMI_HANDLER is not set 839# CONFIG_IPMI_HANDLER is not set
872
873#
874# Watchdog Cards
875#
876# CONFIG_WATCHDOG is not set
877CONFIG_HW_RANDOM=y 840CONFIG_HW_RANDOM=y
878# CONFIG_GEN_RTC is not set
879# CONFIG_DTLK is not set
880# CONFIG_R3964 is not set 841# CONFIG_R3964 is not set
881# CONFIG_APPLICOM is not set 842# CONFIG_APPLICOM is not set
882# CONFIG_DRM is not set
883# CONFIG_RAW_DRIVER is not set
884 843
885# 844#
886# TPM devices 845# PCMCIA character devices
887# 846#
847# CONFIG_SYNCLINK_CS is not set
848# CONFIG_CARDMAN_4000 is not set
849# CONFIG_CARDMAN_4040 is not set
850# CONFIG_RAW_DRIVER is not set
888# CONFIG_TCG_TPM is not set 851# CONFIG_TCG_TPM is not set
889 852CONFIG_DEVPORT=y
890#
891# I2C support
892#
893# CONFIG_I2C is not set 853# CONFIG_I2C is not set
894 854
895# 855#
@@ -897,22 +857,27 @@ CONFIG_HW_RANDOM=y
897# 857#
898# CONFIG_SPI is not set 858# CONFIG_SPI is not set
899# CONFIG_SPI_MASTER is not set 859# CONFIG_SPI_MASTER is not set
900
901#
902# Dallas's 1-wire bus
903#
904# CONFIG_W1 is not set 860# CONFIG_W1 is not set
861CONFIG_POWER_SUPPLY=y
862# CONFIG_POWER_SUPPLY_DEBUG is not set
863# CONFIG_PDA_POWER is not set
864# CONFIG_BATTERY_DS2760 is not set
865# CONFIG_HWMON is not set
866# CONFIG_WATCHDOG is not set
905 867
906# 868#
907# Hardware Monitoring support 869# Sonics Silicon Backplane
908# 870#
909CONFIG_HWMON=y 871CONFIG_SSB_POSSIBLE=y
910# CONFIG_HWMON_VID is not set 872CONFIG_SSB=y
911# CONFIG_SENSORS_ABITUGURU is not set 873CONFIG_SSB_PCIHOST_POSSIBLE=y
912# CONFIG_SENSORS_F71805F is not set 874CONFIG_SSB_PCIHOST=y
913# CONFIG_SENSORS_PC87427 is not set 875CONFIG_SSB_PCMCIAHOST_POSSIBLE=y
914# CONFIG_SENSORS_VT1211 is not set 876# CONFIG_SSB_PCMCIAHOST is not set
915# CONFIG_HWMON_DEBUG_CHIP is not set 877# CONFIG_SSB_SILENT is not set
878# CONFIG_SSB_DEBUG is not set
879CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
880CONFIG_SSB_DRIVER_PCICORE=y
916 881
917# 882#
918# Multifunction device drivers 883# Multifunction device drivers
@@ -923,22 +888,93 @@ CONFIG_HWMON=y
923# Multimedia devices 888# Multimedia devices
924# 889#
925# CONFIG_VIDEO_DEV is not set 890# CONFIG_VIDEO_DEV is not set
891# CONFIG_DVB_CORE is not set
892# CONFIG_DAB is not set
893
894#
895# Graphics support
896#
897# CONFIG_DRM is not set
898# CONFIG_VGASTATE is not set
899# CONFIG_VIDEO_OUTPUT_CONTROL is not set
900CONFIG_FB=y
901# CONFIG_FIRMWARE_EDID is not set
902# CONFIG_FB_DDC is not set
903# CONFIG_FB_CFB_FILLRECT is not set
904# CONFIG_FB_CFB_COPYAREA is not set
905# CONFIG_FB_CFB_IMAGEBLIT is not set
906# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
907# CONFIG_FB_SYS_FILLRECT is not set
908# CONFIG_FB_SYS_COPYAREA is not set
909# CONFIG_FB_SYS_IMAGEBLIT is not set
910# CONFIG_FB_SYS_FOPS is not set
911CONFIG_FB_DEFERRED_IO=y
912# CONFIG_FB_SVGALIB is not set
913# CONFIG_FB_MACMODES is not set
914# CONFIG_FB_BACKLIGHT is not set
915# CONFIG_FB_MODE_HELPERS is not set
916# CONFIG_FB_TILEBLITTING is not set
917
918#
919# Frame buffer hardware drivers
920#
921# CONFIG_FB_CIRRUS is not set
922# CONFIG_FB_PM2 is not set
923# CONFIG_FB_CYBER2000 is not set
924# CONFIG_FB_ASILIANT is not set
925# CONFIG_FB_IMSTT is not set
926# CONFIG_FB_S1D13XXX is not set
927# CONFIG_FB_NVIDIA is not set
928# CONFIG_FB_RIVA is not set
929# CONFIG_FB_MATROX is not set
930# CONFIG_FB_RADEON is not set
931# CONFIG_FB_ATY128 is not set
932# CONFIG_FB_ATY is not set
933# CONFIG_FB_S3 is not set
934# CONFIG_FB_SAVAGE is not set
935# CONFIG_FB_SIS is not set
936# CONFIG_FB_NEOMAGIC is not set
937# CONFIG_FB_KYRO is not set
938# CONFIG_FB_3DFX is not set
939# CONFIG_FB_VOODOO1 is not set
940# CONFIG_FB_VT8623 is not set
941# CONFIG_FB_TRIDENT is not set
942# CONFIG_FB_ARK is not set
943# CONFIG_FB_PM3 is not set
944# CONFIG_FB_VIRTUAL is not set
945# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
926 946
927# 947#
928# Digital Video Broadcasting Devices 948# Display device support
929# 949#
930# CONFIG_DVB is not set 950CONFIG_DISPLAY_SUPPORT=y
931 951
932# 952#
933# Graphics support 953# Display hardware drivers
934# 954#
935# CONFIG_BACKLIGHT_LCD_SUPPORT is not set 955
936# CONFIG_FB is not set 956#
957# Console display driver support
958#
959CONFIG_DUMMY_CONSOLE=y
960CONFIG_FRAMEBUFFER_CONSOLE=y
961CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
962# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
963# CONFIG_FONTS is not set
964CONFIG_FONT_8x8=y
965CONFIG_FONT_8x16=y
966CONFIG_LOGO=y
967CONFIG_LOGO_LINUX_MONO=y
968CONFIG_LOGO_LINUX_VGA16=y
969CONFIG_LOGO_LINUX_CLUT224=y
970CONFIG_LOGO_SUPERH_MONO=y
971CONFIG_LOGO_SUPERH_VGA16=y
972CONFIG_LOGO_SUPERH_CLUT224=y
937 973
938# 974#
939# Sound 975# Sound
940# 976#
941CONFIG_SOUND=m 977CONFIG_SOUND=y
942 978
943# 979#
944# Advanced Linux Sound Architecture 980# Advanced Linux Sound Architecture
@@ -948,126 +984,162 @@ CONFIG_SOUND=m
948# 984#
949# Open Sound System 985# Open Sound System
950# 986#
951CONFIG_SOUND_PRIME=m 987CONFIG_SOUND_PRIME=y
952# CONFIG_OBSOLETE_OSS is not set
953# CONFIG_SOUND_BT878 is not set
954# CONFIG_SOUND_ICH is not set
955# CONFIG_SOUND_TRIDENT is not set 988# CONFIG_SOUND_TRIDENT is not set
956# CONFIG_SOUND_MSNDCLAS is not set 989# CONFIG_SOUND_MSNDCLAS is not set
957# CONFIG_SOUND_MSNDPIN is not set 990# CONFIG_SOUND_MSNDPIN is not set
958# CONFIG_SOUND_VIA82CXXX is not set 991CONFIG_HID_SUPPORT=y
959
960#
961# HID Devices
962#
963CONFIG_HID=y 992CONFIG_HID=y
964# CONFIG_HID_DEBUG is not set 993# CONFIG_HID_DEBUG is not set
994# CONFIG_HIDRAW is not set
965 995
966# 996#
967# USB support 997# USB Input Devices
968# 998#
999CONFIG_USB_HID=y
1000# CONFIG_USB_HIDINPUT_POWERBOOK is not set
1001# CONFIG_HID_FF is not set
1002# CONFIG_USB_HIDDEV is not set
1003CONFIG_USB_SUPPORT=y
969CONFIG_USB_ARCH_HAS_HCD=y 1004CONFIG_USB_ARCH_HAS_HCD=y
970CONFIG_USB_ARCH_HAS_OHCI=y 1005CONFIG_USB_ARCH_HAS_OHCI=y
971CONFIG_USB_ARCH_HAS_EHCI=y 1006CONFIG_USB_ARCH_HAS_EHCI=y
972# CONFIG_USB is not set 1007CONFIG_USB=y
1008CONFIG_USB_DEBUG=y
973 1009
974# 1010#
975# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' 1011# Miscellaneous USB options
976# 1012#
1013CONFIG_USB_DEVICEFS=y
1014# CONFIG_USB_DEVICE_CLASS is not set
1015# CONFIG_USB_DYNAMIC_MINORS is not set
1016# CONFIG_USB_OTG is not set
977 1017
978# 1018#
979# USB Gadget Support 1019# USB Host Controller Drivers
980#
981# CONFIG_USB_GADGET is not set
982
983#
984# MMC/SD Card support
985#
986# CONFIG_MMC is not set
987
988#
989# LED devices
990# 1020#
991# CONFIG_NEW_LEDS is not set 1021CONFIG_USB_EHCI_HCD=y
1022# CONFIG_USB_EHCI_SPLIT_ISO is not set
1023# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
1024# CONFIG_USB_EHCI_TT_NEWSCHED is not set
1025# CONFIG_USB_ISP116X_HCD is not set
1026# CONFIG_USB_OHCI_HCD is not set
1027# CONFIG_USB_UHCI_HCD is not set
1028# CONFIG_USB_SL811_HCD is not set
1029# CONFIG_USB_R8A66597_HCD is not set
992 1030
993# 1031#
994# LED drivers 1032# USB Device Class drivers
995# 1033#
1034# CONFIG_USB_ACM is not set
1035CONFIG_USB_PRINTER=y
996 1036
997# 1037#
998# LED Triggers 1038# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
999# 1039#
1000 1040
1001# 1041#
1002# InfiniBand support 1042# may also be needed; see USB_STORAGE Help for more information
1003# 1043#
1004# CONFIG_INFINIBAND is not set 1044CONFIG_USB_STORAGE=y
1045# CONFIG_USB_STORAGE_DEBUG is not set
1046# CONFIG_USB_STORAGE_DATAFAB is not set
1047# CONFIG_USB_STORAGE_FREECOM is not set
1048# CONFIG_USB_STORAGE_ISD200 is not set
1049# CONFIG_USB_STORAGE_DPCM is not set
1050# CONFIG_USB_STORAGE_USBAT is not set
1051# CONFIG_USB_STORAGE_SDDR09 is not set
1052# CONFIG_USB_STORAGE_SDDR55 is not set
1053# CONFIG_USB_STORAGE_JUMPSHOT is not set
1054# CONFIG_USB_STORAGE_ALAUDA is not set
1055# CONFIG_USB_STORAGE_ONETOUCH is not set
1056# CONFIG_USB_STORAGE_KARMA is not set
1057# CONFIG_USB_LIBUSUAL is not set
1005 1058
1006# 1059#
1007# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) 1060# USB Imaging devices
1008# 1061#
1062# CONFIG_USB_MDC800 is not set
1063# CONFIG_USB_MICROTEK is not set
1064CONFIG_USB_MON=y
1009 1065
1010# 1066#
1011# Real Time Clock 1067# USB port drivers
1012# 1068#
1013CONFIG_RTC_LIB=y 1069# CONFIG_USB_USS720 is not set
1014CONFIG_RTC_CLASS=y
1015CONFIG_RTC_HCTOSYS=y
1016CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
1017# CONFIG_RTC_DEBUG is not set
1018 1070
1019# 1071#
1020# RTC interfaces 1072# USB Serial Converter support
1021# 1073#
1022CONFIG_RTC_INTF_SYSFS=y 1074# CONFIG_USB_SERIAL is not set
1023CONFIG_RTC_INTF_PROC=y
1024CONFIG_RTC_INTF_DEV=y
1025# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
1026 1075
1027# 1076#
1028# RTC drivers 1077# USB Miscellaneous drivers
1029# 1078#
1030# CONFIG_RTC_DRV_DS1553 is not set 1079# CONFIG_USB_EMI62 is not set
1031# CONFIG_RTC_DRV_DS1742 is not set 1080# CONFIG_USB_EMI26 is not set
1032# CONFIG_RTC_DRV_M48T86 is not set 1081# CONFIG_USB_ADUTUX is not set
1033CONFIG_RTC_DRV_SH=y 1082# CONFIG_USB_AUERSWALD is not set
1034# CONFIG_RTC_DRV_TEST is not set 1083# CONFIG_USB_RIO500 is not set
1035# CONFIG_RTC_DRV_V3020 is not set 1084# CONFIG_USB_LEGOTOWER is not set
1085# CONFIG_USB_LCD is not set
1086# CONFIG_USB_BERRY_CHARGE is not set
1087# CONFIG_USB_LED is not set
1088# CONFIG_USB_CYPRESS_CY7C63 is not set
1089# CONFIG_USB_CYTHERM is not set
1090# CONFIG_USB_PHIDGET is not set
1091# CONFIG_USB_IDMOUSE is not set
1092# CONFIG_USB_FTDI_ELAN is not set
1093# CONFIG_USB_APPLEDISPLAY is not set
1094# CONFIG_USB_SISUSBVGA is not set
1095# CONFIG_USB_LD is not set
1096# CONFIG_USB_TRANCEVIBRATOR is not set
1097# CONFIG_USB_IOWARRIOR is not set
1098# CONFIG_USB_TEST is not set
1036 1099
1037# 1100#
1038# DMA Engine support 1101# USB DSL modem support
1039# 1102#
1040# CONFIG_DMA_ENGINE is not set
1041 1103
1042# 1104#
1043# DMA Clients 1105# USB Gadget Support
1044# 1106#
1107# CONFIG_USB_GADGET is not set
1108# CONFIG_MMC is not set
1109CONFIG_NEW_LEDS=y
1110CONFIG_LEDS_CLASS=y
1045 1111
1046# 1112#
1047# DMA Devices 1113# LED drivers
1048# 1114#
1049 1115
1050# 1116#
1051# Auxiliary Display support 1117# LED Triggers
1052# 1118#
1119# CONFIG_LEDS_TRIGGERS is not set
1120# CONFIG_INFINIBAND is not set
1121# CONFIG_RTC_CLASS is not set
1122# CONFIG_AUXDISPLAY is not set
1053 1123
1054# 1124#
1055# Virtualization 1125# Userspace I/O
1056# 1126#
1127# CONFIG_UIO is not set
1057 1128
1058# 1129#
1059# File systems 1130# File systems
1060# 1131#
1061CONFIG_EXT2_FS=y 1132CONFIG_EXT2_FS=y
1062# CONFIG_EXT2_FS_XATTR is not set 1133CONFIG_EXT2_FS_XATTR=y
1134CONFIG_EXT2_FS_POSIX_ACL=y
1135# CONFIG_EXT2_FS_SECURITY is not set
1063# CONFIG_EXT2_FS_XIP is not set 1136# CONFIG_EXT2_FS_XIP is not set
1064CONFIG_EXT3_FS=y 1137CONFIG_EXT3_FS=y
1065CONFIG_EXT3_FS_XATTR=y 1138CONFIG_EXT3_FS_XATTR=y
1066# CONFIG_EXT3_FS_POSIX_ACL is not set 1139CONFIG_EXT3_FS_POSIX_ACL=y
1067# CONFIG_EXT3_FS_SECURITY is not set 1140# CONFIG_EXT3_FS_SECURITY is not set
1068# CONFIG_EXT4DEV_FS is not set 1141# CONFIG_EXT4DEV_FS is not set
1069CONFIG_JBD=y 1142CONFIG_JBD=y
1070# CONFIG_JBD_DEBUG is not set
1071CONFIG_FS_MBCACHE=y 1143CONFIG_FS_MBCACHE=y
1072# CONFIG_REISERFS_FS is not set 1144# CONFIG_REISERFS_FS is not set
1073# CONFIG_JFS_FS is not set 1145# CONFIG_JFS_FS is not set
@@ -1082,13 +1154,16 @@ CONFIG_INOTIFY_USER=y
1082# CONFIG_QUOTA is not set 1154# CONFIG_QUOTA is not set
1083CONFIG_DNOTIFY=y 1155CONFIG_DNOTIFY=y
1084# CONFIG_AUTOFS_FS is not set 1156# CONFIG_AUTOFS_FS is not set
1085# CONFIG_AUTOFS4_FS is not set 1157CONFIG_AUTOFS4_FS=y
1086CONFIG_FUSE_FS=m 1158# CONFIG_FUSE_FS is not set
1159CONFIG_GENERIC_ACL=y
1087 1160
1088# 1161#
1089# CD-ROM/DVD Filesystems 1162# CD-ROM/DVD Filesystems
1090# 1163#
1091# CONFIG_ISO9660_FS is not set 1164CONFIG_ISO9660_FS=y
1165# CONFIG_JOLIET is not set
1166# CONFIG_ZISOFS is not set
1092# CONFIG_UDF_FS is not set 1167# CONFIG_UDF_FS is not set
1093 1168
1094# 1169#
@@ -1100,22 +1175,21 @@ CONFIG_VFAT_FS=y
1100CONFIG_FAT_DEFAULT_CODEPAGE=437 1175CONFIG_FAT_DEFAULT_CODEPAGE=437
1101CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" 1176CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
1102CONFIG_NTFS_FS=y 1177CONFIG_NTFS_FS=y
1103# CONFIG_NTFS_DEBUG is not set 1178CONFIG_NTFS_DEBUG=y
1104CONFIG_NTFS_RW=y 1179CONFIG_NTFS_RW=y
1105 1180
1106# 1181#
1107# Pseudo filesystems 1182# Pseudo filesystems
1108# 1183#
1109CONFIG_PROC_FS=y 1184CONFIG_PROC_FS=y
1110CONFIG_PROC_KCORE=y 1185# CONFIG_PROC_KCORE is not set
1111CONFIG_PROC_SYSCTL=y 1186CONFIG_PROC_SYSCTL=y
1112CONFIG_SYSFS=y 1187CONFIG_SYSFS=y
1113CONFIG_TMPFS=y 1188CONFIG_TMPFS=y
1114# CONFIG_TMPFS_POSIX_ACL is not set 1189CONFIG_TMPFS_POSIX_ACL=y
1115CONFIG_HUGETLBFS=y 1190CONFIG_HUGETLBFS=y
1116CONFIG_HUGETLB_PAGE=y 1191CONFIG_HUGETLB_PAGE=y
1117CONFIG_RAMFS=y 1192# CONFIG_CONFIGFS_FS is not set
1118CONFIG_CONFIGFS_FS=m
1119 1193
1120# 1194#
1121# Miscellaneous filesystems 1195# Miscellaneous filesystems
@@ -1133,19 +1207,16 @@ CONFIG_CONFIGFS_FS=m
1133# CONFIG_QNX4FS_FS is not set 1207# CONFIG_QNX4FS_FS is not set
1134# CONFIG_SYSV_FS is not set 1208# CONFIG_SYSV_FS is not set
1135# CONFIG_UFS_FS is not set 1209# CONFIG_UFS_FS is not set
1136 1210CONFIG_NETWORK_FILESYSTEMS=y
1137#
1138# Network File Systems
1139#
1140CONFIG_NFS_FS=y 1211CONFIG_NFS_FS=y
1141CONFIG_NFS_V3=y 1212CONFIG_NFS_V3=y
1142# CONFIG_NFS_V3_ACL is not set 1213# CONFIG_NFS_V3_ACL is not set
1143CONFIG_NFS_V4=y 1214# CONFIG_NFS_V4 is not set
1144# CONFIG_NFS_DIRECTIO is not set 1215# CONFIG_NFS_DIRECTIO is not set
1145CONFIG_NFSD=y 1216CONFIG_NFSD=y
1146CONFIG_NFSD_V3=y 1217CONFIG_NFSD_V3=y
1147# CONFIG_NFSD_V3_ACL is not set 1218# CONFIG_NFSD_V3_ACL is not set
1148CONFIG_NFSD_V4=y 1219# CONFIG_NFSD_V4 is not set
1149CONFIG_NFSD_TCP=y 1220CONFIG_NFSD_TCP=y
1150CONFIG_ROOT_NFS=y 1221CONFIG_ROOT_NFS=y
1151CONFIG_LOCKD=y 1222CONFIG_LOCKD=y
@@ -1153,25 +1224,20 @@ CONFIG_LOCKD_V4=y
1153CONFIG_EXPORTFS=y 1224CONFIG_EXPORTFS=y
1154CONFIG_NFS_COMMON=y 1225CONFIG_NFS_COMMON=y
1155CONFIG_SUNRPC=y 1226CONFIG_SUNRPC=y
1156CONFIG_SUNRPC_GSS=y 1227# CONFIG_SUNRPC_BIND34 is not set
1157CONFIG_RPCSEC_GSS_KRB5=y 1228# CONFIG_RPCSEC_GSS_KRB5 is not set
1158# CONFIG_RPCSEC_GSS_SPKM3 is not set 1229# CONFIG_RPCSEC_GSS_SPKM3 is not set
1159# CONFIG_SMB_FS is not set 1230# CONFIG_SMB_FS is not set
1160# CONFIG_CIFS is not set 1231# CONFIG_CIFS is not set
1161# CONFIG_NCP_FS is not set 1232# CONFIG_NCP_FS is not set
1162# CONFIG_CODA_FS is not set 1233# CONFIG_CODA_FS is not set
1163# CONFIG_AFS_FS is not set 1234# CONFIG_AFS_FS is not set
1164# CONFIG_9P_FS is not set
1165 1235
1166# 1236#
1167# Partition Types 1237# Partition Types
1168# 1238#
1169# CONFIG_PARTITION_ADVANCED is not set 1239# CONFIG_PARTITION_ADVANCED is not set
1170CONFIG_MSDOS_PARTITION=y 1240CONFIG_MSDOS_PARTITION=y
1171
1172#
1173# Native Language Support
1174#
1175CONFIG_NLS=y 1241CONFIG_NLS=y
1176CONFIG_NLS_DEFAULT="iso8859-1" 1242CONFIG_NLS_DEFAULT="iso8859-1"
1177CONFIG_NLS_CODEPAGE_437=y 1243CONFIG_NLS_CODEPAGE_437=y
@@ -1191,13 +1257,13 @@ CONFIG_NLS_CODEPAGE_437=y
1191# CONFIG_NLS_CODEPAGE_869 is not set 1257# CONFIG_NLS_CODEPAGE_869 is not set
1192# CONFIG_NLS_CODEPAGE_936 is not set 1258# CONFIG_NLS_CODEPAGE_936 is not set
1193# CONFIG_NLS_CODEPAGE_950 is not set 1259# CONFIG_NLS_CODEPAGE_950 is not set
1194CONFIG_NLS_CODEPAGE_932=y 1260# CONFIG_NLS_CODEPAGE_932 is not set
1195# CONFIG_NLS_CODEPAGE_949 is not set 1261# CONFIG_NLS_CODEPAGE_949 is not set
1196# CONFIG_NLS_CODEPAGE_874 is not set 1262# CONFIG_NLS_CODEPAGE_874 is not set
1197# CONFIG_NLS_ISO8859_8 is not set 1263# CONFIG_NLS_ISO8859_8 is not set
1198# CONFIG_NLS_CODEPAGE_1250 is not set 1264# CONFIG_NLS_CODEPAGE_1250 is not set
1199# CONFIG_NLS_CODEPAGE_1251 is not set 1265# CONFIG_NLS_CODEPAGE_1251 is not set
1200# CONFIG_NLS_ASCII is not set 1266CONFIG_NLS_ASCII=y
1201CONFIG_NLS_ISO8859_1=y 1267CONFIG_NLS_ISO8859_1=y
1202# CONFIG_NLS_ISO8859_2 is not set 1268# CONFIG_NLS_ISO8859_2 is not set
1203# CONFIG_NLS_ISO8859_3 is not set 1269# CONFIG_NLS_ISO8859_3 is not set
@@ -1208,44 +1274,39 @@ CONFIG_NLS_ISO8859_1=y
1208# CONFIG_NLS_ISO8859_9 is not set 1274# CONFIG_NLS_ISO8859_9 is not set
1209# CONFIG_NLS_ISO8859_13 is not set 1275# CONFIG_NLS_ISO8859_13 is not set
1210# CONFIG_NLS_ISO8859_14 is not set 1276# CONFIG_NLS_ISO8859_14 is not set
1211# CONFIG_NLS_ISO8859_15 is not set 1277CONFIG_NLS_ISO8859_15=y
1212# CONFIG_NLS_KOI8_R is not set 1278# CONFIG_NLS_KOI8_R is not set
1213# CONFIG_NLS_KOI8_U is not set 1279# CONFIG_NLS_KOI8_U is not set
1214# CONFIG_NLS_UTF8 is not set 1280CONFIG_NLS_UTF8=y
1215
1216#
1217# Distributed Lock Manager
1218#
1219# CONFIG_DLM is not set 1281# CONFIG_DLM is not set
1220 1282# CONFIG_INSTRUMENTATION is not set
1221#
1222# Profiling support
1223#
1224CONFIG_PROFILING=y
1225CONFIG_OPROFILE=m
1226 1283
1227# 1284#
1228# Kernel hacking 1285# Kernel hacking
1229# 1286#
1230CONFIG_TRACE_IRQFLAGS_SUPPORT=y 1287CONFIG_TRACE_IRQFLAGS_SUPPORT=y
1231# CONFIG_PRINTK_TIME is not set 1288# CONFIG_PRINTK_TIME is not set
1232CONFIG_ENABLE_MUST_CHECK=y 1289CONFIG_ENABLE_WARN_DEPRECATED=y
1290# CONFIG_ENABLE_MUST_CHECK is not set
1233CONFIG_MAGIC_SYSRQ=y 1291CONFIG_MAGIC_SYSRQ=y
1234# CONFIG_UNUSED_SYMBOLS is not set 1292CONFIG_UNUSED_SYMBOLS=y
1235CONFIG_DEBUG_FS=y 1293# CONFIG_DEBUG_FS is not set
1236# CONFIG_HEADERS_CHECK is not set 1294# CONFIG_HEADERS_CHECK is not set
1237CONFIG_DEBUG_KERNEL=y 1295CONFIG_DEBUG_KERNEL=y
1238# CONFIG_DEBUG_SHIRQ is not set 1296# CONFIG_DEBUG_SHIRQ is not set
1239CONFIG_LOG_BUF_SHIFT=14
1240CONFIG_DETECT_SOFTLOCKUP=y 1297CONFIG_DETECT_SOFTLOCKUP=y
1298# CONFIG_SCHED_DEBUG is not set
1241# CONFIG_SCHEDSTATS is not set 1299# CONFIG_SCHEDSTATS is not set
1242# CONFIG_TIMER_STATS is not set 1300CONFIG_TIMER_STATS=y
1243# CONFIG_DEBUG_SLAB is not set 1301# CONFIG_SLUB_DEBUG_ON is not set
1244# CONFIG_DEBUG_PREEMPT is not set 1302CONFIG_DEBUG_PREEMPT=y
1303# CONFIG_DEBUG_RT_MUTEXES is not set
1304# CONFIG_RT_MUTEX_TESTER is not set
1245# CONFIG_DEBUG_SPINLOCK is not set 1305# CONFIG_DEBUG_SPINLOCK is not set
1246# CONFIG_DEBUG_MUTEXES is not set 1306# CONFIG_DEBUG_MUTEXES is not set
1247# CONFIG_DEBUG_LOCK_ALLOC is not set 1307# CONFIG_DEBUG_LOCK_ALLOC is not set
1248# CONFIG_PROVE_LOCKING is not set 1308# CONFIG_PROVE_LOCKING is not set
1309# CONFIG_LOCK_STAT is not set
1249# CONFIG_DEBUG_SPINLOCK_SLEEP is not set 1310# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1250# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set 1311# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
1251# CONFIG_DEBUG_KOBJECT is not set 1312# CONFIG_DEBUG_KOBJECT is not set
@@ -1253,16 +1314,21 @@ CONFIG_DEBUG_BUGVERBOSE=y
1253CONFIG_DEBUG_INFO=y 1314CONFIG_DEBUG_INFO=y
1254# CONFIG_DEBUG_VM is not set 1315# CONFIG_DEBUG_VM is not set
1255# CONFIG_DEBUG_LIST is not set 1316# CONFIG_DEBUG_LIST is not set
1317# CONFIG_DEBUG_SG is not set
1256# CONFIG_FRAME_POINTER is not set 1318# CONFIG_FRAME_POINTER is not set
1257CONFIG_FORCED_INLINING=y 1319# CONFIG_FORCED_INLINING is not set
1320# CONFIG_BOOT_PRINTK_DELAY is not set
1258# CONFIG_RCU_TORTURE_TEST is not set 1321# CONFIG_RCU_TORTURE_TEST is not set
1259# CONFIG_FAULT_INJECTION is not set 1322# CONFIG_FAULT_INJECTION is not set
1323# CONFIG_SAMPLES is not set
1260CONFIG_SH_STANDARD_BIOS=y 1324CONFIG_SH_STANDARD_BIOS=y
1261# CONFIG_EARLY_SCIF_CONSOLE is not set 1325# CONFIG_EARLY_SCIF_CONSOLE is not set
1262CONFIG_EARLY_PRINTK=y 1326# CONFIG_EARLY_PRINTK is not set
1327# CONFIG_DEBUG_BOOTMEM is not set
1263CONFIG_DEBUG_STACKOVERFLOW=y 1328CONFIG_DEBUG_STACKOVERFLOW=y
1264# CONFIG_DEBUG_STACK_USAGE is not set 1329# CONFIG_DEBUG_STACK_USAGE is not set
1265# CONFIG_4KSTACKS is not set 1330# CONFIG_4KSTACKS is not set
1331# CONFIG_IRQSTACKS is not set
1266# CONFIG_SH_KGDB is not set 1332# CONFIG_SH_KGDB is not set
1267 1333
1268# 1334#
@@ -1270,16 +1336,11 @@ CONFIG_DEBUG_STACKOVERFLOW=y
1270# 1336#
1271# CONFIG_KEYS is not set 1337# CONFIG_KEYS is not set
1272# CONFIG_SECURITY is not set 1338# CONFIG_SECURITY is not set
1273 1339# CONFIG_SECURITY_FILE_CAPABILITIES is not set
1274#
1275# Cryptographic options
1276#
1277CONFIG_CRYPTO=y 1340CONFIG_CRYPTO=y
1278CONFIG_CRYPTO_ALGAPI=y 1341CONFIG_CRYPTO_ALGAPI=y
1279CONFIG_CRYPTO_BLKCIPHER=y 1342# CONFIG_CRYPTO_MANAGER is not set
1280CONFIG_CRYPTO_HASH=y 1343# CONFIG_CRYPTO_HMAC is not set
1281CONFIG_CRYPTO_MANAGER=y
1282CONFIG_CRYPTO_HMAC=y
1283# CONFIG_CRYPTO_XCBC is not set 1344# CONFIG_CRYPTO_XCBC is not set
1284# CONFIG_CRYPTO_NULL is not set 1345# CONFIG_CRYPTO_NULL is not set
1285# CONFIG_CRYPTO_MD4 is not set 1346# CONFIG_CRYPTO_MD4 is not set
@@ -1290,10 +1351,12 @@ CONFIG_CRYPTO_MD5=y
1290# CONFIG_CRYPTO_WP512 is not set 1351# CONFIG_CRYPTO_WP512 is not set
1291# CONFIG_CRYPTO_TGR192 is not set 1352# CONFIG_CRYPTO_TGR192 is not set
1292# CONFIG_CRYPTO_GF128MUL is not set 1353# CONFIG_CRYPTO_GF128MUL is not set
1293CONFIG_CRYPTO_ECB=m 1354# CONFIG_CRYPTO_ECB is not set
1294CONFIG_CRYPTO_CBC=y 1355# CONFIG_CRYPTO_CBC is not set
1295CONFIG_CRYPTO_PCBC=m 1356# CONFIG_CRYPTO_PCBC is not set
1296# CONFIG_CRYPTO_LRW is not set 1357# CONFIG_CRYPTO_LRW is not set
1358# CONFIG_CRYPTO_XTS is not set
1359# CONFIG_CRYPTO_CRYPTD is not set
1297CONFIG_CRYPTO_DES=y 1360CONFIG_CRYPTO_DES=y
1298# CONFIG_CRYPTO_FCRYPT is not set 1361# CONFIG_CRYPTO_FCRYPT is not set
1299# CONFIG_CRYPTO_BLOWFISH is not set 1362# CONFIG_CRYPTO_BLOWFISH is not set
@@ -1306,15 +1369,14 @@ CONFIG_CRYPTO_DES=y
1306# CONFIG_CRYPTO_ARC4 is not set 1369# CONFIG_CRYPTO_ARC4 is not set
1307# CONFIG_CRYPTO_KHAZAD is not set 1370# CONFIG_CRYPTO_KHAZAD is not set
1308# CONFIG_CRYPTO_ANUBIS is not set 1371# CONFIG_CRYPTO_ANUBIS is not set
1372# CONFIG_CRYPTO_SEED is not set
1309# CONFIG_CRYPTO_DEFLATE is not set 1373# CONFIG_CRYPTO_DEFLATE is not set
1310# CONFIG_CRYPTO_MICHAEL_MIC is not set 1374# CONFIG_CRYPTO_MICHAEL_MIC is not set
1311# CONFIG_CRYPTO_CRC32C is not set 1375# CONFIG_CRYPTO_CRC32C is not set
1312# CONFIG_CRYPTO_CAMELLIA is not set 1376# CONFIG_CRYPTO_CAMELLIA is not set
1313# CONFIG_CRYPTO_TEST is not set 1377# CONFIG_CRYPTO_TEST is not set
1314 1378# CONFIG_CRYPTO_AUTHENC is not set
1315# 1379CONFIG_CRYPTO_HW=y
1316# Hardware crypto devices
1317#
1318 1380
1319# 1381#
1320# Library routines 1382# Library routines
@@ -1322,7 +1384,11 @@ CONFIG_CRYPTO_DES=y
1322CONFIG_BITREVERSE=y 1384CONFIG_BITREVERSE=y
1323# CONFIG_CRC_CCITT is not set 1385# CONFIG_CRC_CCITT is not set
1324# CONFIG_CRC16 is not set 1386# CONFIG_CRC16 is not set
1387# CONFIG_CRC_ITU_T is not set
1325CONFIG_CRC32=y 1388CONFIG_CRC32=y
1389# CONFIG_CRC7 is not set
1326# CONFIG_LIBCRC32C is not set 1390# CONFIG_LIBCRC32C is not set
1391CONFIG_PLIST=y
1327CONFIG_HAS_IOMEM=y 1392CONFIG_HAS_IOMEM=y
1328CONFIG_HAS_IOPORT=y 1393CONFIG_HAS_IOPORT=y
1394CONFIG_HAS_DMA=y
diff --git a/arch/sh/configs/se7712_defconfig b/arch/sh/configs/se7712_defconfig
index a5e37dbc5353..240a1cef69aa 100644
--- a/arch/sh/configs/se7712_defconfig
+++ b/arch/sh/configs/se7712_defconfig
@@ -237,7 +237,7 @@ CONFIG_CPU_HAS_SR_RB=y
237CONFIG_SH_TMU=y 237CONFIG_SH_TMU=y
238CONFIG_SH_TIMER_IRQ=16 238CONFIG_SH_TIMER_IRQ=16
239# CONFIG_NO_IDLE_HZ is not set 239# CONFIG_NO_IDLE_HZ is not set
240CONFIG_SH_PCLK_FREQ=33333333 240CONFIG_SH_PCLK_FREQ=66666666
241 241
242# 242#
243# CPU Frequency scaling 243# CPU Frequency scaling
diff --git a/arch/sh/drivers/dma/Kconfig b/arch/sh/drivers/dma/Kconfig
index 4e711a0c3dae..01936368b8b0 100644
--- a/arch/sh/drivers/dma/Kconfig
+++ b/arch/sh/drivers/dma/Kconfig
@@ -12,7 +12,7 @@ config SH_DMA
12config NR_ONCHIP_DMA_CHANNELS 12config NR_ONCHIP_DMA_CHANNELS
13 int 13 int
14 depends on SH_DMA 14 depends on SH_DMA
15 default "6" if CPU_SUBTYPE_SH7720 15 default "6" if CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721
16 default "8" if CPU_SUBTYPE_SH7750R || CPU_SUBTYPE_SH7751R 16 default "8" if CPU_SUBTYPE_SH7750R || CPU_SUBTYPE_SH7751R
17 default "12" if CPU_SUBTYPE_SH7780 17 default "12" if CPU_SUBTYPE_SH7780
18 default "4" 18 default "4"
diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c
index 958bac1c585a..5c3359756a92 100644
--- a/arch/sh/drivers/dma/dma-sh.c
+++ b/arch/sh/drivers/dma/dma-sh.c
@@ -25,6 +25,7 @@ static int dmte_irq_map[] = {
25 DMTE2_IRQ, 25 DMTE2_IRQ,
26 DMTE3_IRQ, 26 DMTE3_IRQ,
27#if defined(CONFIG_CPU_SUBTYPE_SH7720) || \ 27#if defined(CONFIG_CPU_SUBTYPE_SH7720) || \
28 defined(CONFIG_CPU_SUBTYPE_SH7721) || \
28 defined(CONFIG_CPU_SUBTYPE_SH7751R) || \ 29 defined(CONFIG_CPU_SUBTYPE_SH7751R) || \
29 defined(CONFIG_CPU_SUBTYPE_SH7760) || \ 30 defined(CONFIG_CPU_SUBTYPE_SH7760) || \
30 defined(CONFIG_CPU_SUBTYPE_SH7709) || \ 31 defined(CONFIG_CPU_SUBTYPE_SH7709) || \
@@ -203,6 +204,7 @@ static int sh_dmac_get_dma_residue(struct dma_channel *chan)
203} 204}
204 205
205#if defined(CONFIG_CPU_SUBTYPE_SH7720) || \ 206#if defined(CONFIG_CPU_SUBTYPE_SH7720) || \
207 defined(CONFIG_CPU_SUBTYPE_SH7721) || \
206 defined(CONFIG_CPU_SUBTYPE_SH7780) 208 defined(CONFIG_CPU_SUBTYPE_SH7780)
207#define dmaor_read_reg() ctrl_inw(DMAOR) 209#define dmaor_read_reg() ctrl_inw(DMAOR)
208#define dmaor_write_reg(data) ctrl_outw(data, DMAOR) 210#define dmaor_write_reg(data) ctrl_outw(data, DMAOR)
diff --git a/arch/sh/drivers/dma/dma-sysfs.c b/arch/sh/drivers/dma/dma-sysfs.c
index eebcd4768bbf..51b57c0d1a3c 100644
--- a/arch/sh/drivers/dma/dma-sysfs.c
+++ b/arch/sh/drivers/dma/dma-sysfs.c
@@ -19,7 +19,7 @@
19#include <asm/dma.h> 19#include <asm/dma.h>
20 20
21static struct sysdev_class dma_sysclass = { 21static struct sysdev_class dma_sysclass = {
22 set_kset_name("dma"), 22 .name = "dma",
23}; 23};
24EXPORT_SYMBOL(dma_sysclass); 24EXPORT_SYMBOL(dma_sysclass);
25 25
diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile
index fba6b5ba0b3a..0718805774e8 100644
--- a/arch/sh/drivers/pci/Makefile
+++ b/arch/sh/drivers/pci/Makefile
@@ -7,16 +7,19 @@ obj-$(CONFIG_PCI_AUTO) += pci-auto.o
7 7
8obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o ops-sh4.o 8obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o ops-sh4.o
9obj-$(CONFIG_CPU_SUBTYPE_SH7751R) += pci-sh7751.o ops-sh4.o 9obj-$(CONFIG_CPU_SUBTYPE_SH7751R) += pci-sh7751.o ops-sh4.o
10obj-$(CONFIG_CPU_SUBTYPE_SH7763) += pci-sh7780.o ops-sh4.o
10obj-$(CONFIG_CPU_SUBTYPE_SH7780) += pci-sh7780.o ops-sh4.o 11obj-$(CONFIG_CPU_SUBTYPE_SH7780) += pci-sh7780.o ops-sh4.o
11obj-$(CONFIG_CPU_SUBTYPE_SH7785) += pci-sh7780.o ops-sh4.o 12obj-$(CONFIG_CPU_SUBTYPE_SH7785) += pci-sh7780.o ops-sh4.o
13obj-$(CONFIG_CPU_SH5) += pci-sh5.o ops-sh5.o
12 14
13obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o \ 15obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o
14 dma-dreamcast.o
15obj-$(CONFIG_SH_SECUREEDGE5410) += ops-snapgear.o 16obj-$(CONFIG_SH_SECUREEDGE5410) += ops-snapgear.o
16obj-$(CONFIG_SH_RTS7751R2D) += ops-rts7751r2d.o fixups-rts7751r2d.o 17obj-$(CONFIG_SH_RTS7751R2D) += ops-rts7751r2d.o fixups-rts7751r2d.o
17obj-$(CONFIG_SH_SH03) += ops-sh03.o fixups-sh03.o 18obj-$(CONFIG_SH_SH03) += ops-sh03.o fixups-sh03.o
18obj-$(CONFIG_SH_HIGHLANDER) += ops-r7780rp.o fixups-r7780rp.o 19obj-$(CONFIG_SH_HIGHLANDER) += ops-r7780rp.o fixups-r7780rp.o
20obj-$(CONFIG_SH_SDK7780) += ops-sdk7780.o fixups-sdk7780.o
19obj-$(CONFIG_SH_TITAN) += ops-titan.o 21obj-$(CONFIG_SH_TITAN) += ops-titan.o
20obj-$(CONFIG_SH_LANDISK) += ops-landisk.o 22obj-$(CONFIG_SH_LANDISK) += ops-landisk.o
21obj-$(CONFIG_SH_LBOX_RE2) += ops-lboxre2.o fixups-lboxre2.o 23obj-$(CONFIG_SH_LBOX_RE2) += ops-lboxre2.o fixups-lboxre2.o
22obj-$(CONFIG_SH_7780_SOLUTION_ENGINE) += ops-se7780.o fixups-se7780.o 24obj-$(CONFIG_SH_7780_SOLUTION_ENGINE) += ops-se7780.o fixups-se7780.o
25obj-$(CONFIG_SH_CAYMAN) += ops-cayman.o
diff --git a/arch/sh/drivers/pci/dma-dreamcast.c b/arch/sh/drivers/pci/dma-dreamcast.c
deleted file mode 100644
index 888a34050599..000000000000
--- a/arch/sh/drivers/pci/dma-dreamcast.c
+++ /dev/null
@@ -1,70 +0,0 @@
1/*
2 * arch/sh/drivers/pci/dma-dreamcast.c
3 *
4 * PCI DMA support for the Sega Dreamcast
5 *
6 * Copyright (C) 2001, 2002 M. R. Brown
7 * Copyright (C) 2002, 2003 Paul Mundt
8 *
9 * This file originally bore the message (with enclosed-$):
10 * Id: pci.c,v 1.3 2003/05/04 19:29:46 lethal Exp
11 * Dreamcast PCI: Supports SEGA Broadband Adaptor only.
12 *
13 * This file is subject to the terms and conditions of the GNU General Public
14 * License. See the file "COPYING" in the main directory of this archive
15 * for more details.
16 */
17
18#include <linux/sched.h>
19#include <linux/kernel.h>
20#include <linux/param.h>
21#include <linux/interrupt.h>
22#include <linux/init.h>
23#include <linux/irq.h>
24#include <linux/pci.h>
25#include <linux/dma-mapping.h>
26#include <linux/device.h>
27
28#include <asm/io.h>
29#include <asm/irq.h>
30#include <asm/mach/pci.h>
31
32static int gapspci_dma_used = 0;
33
34void *dreamcast_consistent_alloc(struct device *dev, size_t size,
35 dma_addr_t *dma_handle, gfp_t flag)
36{
37 unsigned long buf;
38
39 if (dev && dev->bus != &pci_bus_type)
40 return NULL;
41
42 if (gapspci_dma_used + size > GAPSPCI_DMA_SIZE)
43 return ERR_PTR(-EINVAL);
44
45 buf = GAPSPCI_DMA_BASE + gapspci_dma_used;
46
47 gapspci_dma_used = PAGE_ALIGN(gapspci_dma_used+size);
48
49 *dma_handle = (dma_addr_t)buf;
50
51 buf = P2SEGADDR(buf);
52
53 /* Flush the dcache before we hand off the buffer */
54 __flush_purge_region((void *)buf, size);
55
56 return (void *)buf;
57}
58
59int dreamcast_consistent_free(struct device *dev, size_t size,
60 void *vaddr, dma_addr_t dma_handle)
61{
62 if (dev && dev->bus != &pci_bus_type)
63 return -EINVAL;
64
65 /* XXX */
66 gapspci_dma_used = 0;
67
68 return 0;
69}
70
diff --git a/arch/sh/drivers/pci/fixups-dreamcast.c b/arch/sh/drivers/pci/fixups-dreamcast.c
index 6f53f8200dc3..c44699301eeb 100644
--- a/arch/sh/drivers/pci/fixups-dreamcast.c
+++ b/arch/sh/drivers/pci/fixups-dreamcast.c
@@ -22,6 +22,7 @@
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/irq.h> 23#include <linux/irq.h>
24#include <linux/pci.h> 24#include <linux/pci.h>
25#include <linux/dma-mapping.h>
25 26
26#include <asm/io.h> 27#include <asm/io.h>
27#include <asm/irq.h> 28#include <asm/irq.h>
@@ -40,6 +41,15 @@ static void __init gapspci_fixup_resources(struct pci_dev *dev)
40 */ 41 */
41 dev->resource[1].start = p->io_resource->start + 0x100; 42 dev->resource[1].start = p->io_resource->start + 0x100;
42 dev->resource[1].end = dev->resource[1].start + 0x200 - 1; 43 dev->resource[1].end = dev->resource[1].start + 0x200 - 1;
44 /*
45 * Redirect dma memory allocations to special memory window.
46 */
47 BUG_ON(!dma_declare_coherent_memory(&dev->dev,
48 GAPSPCI_DMA_BASE,
49 GAPSPCI_DMA_BASE,
50 GAPSPCI_DMA_SIZE,
51 DMA_MEMORY_MAP |
52 DMA_MEMORY_EXCLUSIVE));
43 break; 53 break;
44 default: 54 default:
45 printk("PCI: Failed resource fixup\n"); 55 printk("PCI: Failed resource fixup\n");
diff --git a/arch/sh/drivers/pci/fixups-sdk7780.c b/arch/sh/drivers/pci/fixups-sdk7780.c
new file mode 100644
index 000000000000..2f8863099dd1
--- /dev/null
+++ b/arch/sh/drivers/pci/fixups-sdk7780.c
@@ -0,0 +1,59 @@
1/*
2 * arch/sh/drivers/pci/fixups-sdk7780.c
3 *
4 * PCI fixups for the SDK7780SE03
5 *
6 * Copyright (C) 2003 Lineo uSolutions, Inc.
7 * Copyright (C) 2004 - 2006 Paul Mundt
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 */
13#include <linux/pci.h>
14#include "pci-sh4.h"
15#include <asm/io.h>
16
17int pci_fixup_pcic(void)
18{
19 ctrl_outl(0x00000001, SH7780_PCI_VCR2);
20
21 /* Enable all interrupts, so we know what to fix */
22 pci_write_reg(0x0000C3FF, SH7780_PCIIMR);
23 pci_write_reg(0x0000380F, SH7780_PCIAINTM);
24
25 /* Set up standard PCI config registers */
26 pci_write_reg(0xFB00, SH7780_PCISTATUS);
27 pci_write_reg(0x0047, SH7780_PCICMD);
28 pci_write_reg(0x00, SH7780_PCIPIF);
29 pci_write_reg(0x00, SH7780_PCISUB);
30 pci_write_reg(0x06, SH7780_PCIBCC);
31 pci_write_reg(0x1912, SH7780_PCISVID);
32 pci_write_reg(0x0001, SH7780_PCISID);
33
34 pci_write_reg(0x08000000, SH7780_PCIMBAR0); /* PCI */
35 pci_write_reg(0x08000000, SH7780_PCILAR0); /* SHwy */
36 pci_write_reg(0x07F00001, SH7780_PCILSR); /* size 128M w/ MBAR */
37
38 pci_write_reg(0x00000000, SH7780_PCIMBAR1);
39 pci_write_reg(0x00000000, SH7780_PCILAR1);
40 pci_write_reg(0x00000000, SH7780_PCILSR1);
41
42 pci_write_reg(0xAB000801, SH7780_PCIIBAR);
43
44 /*
45 * Set the MBR so PCI address is one-to-one with window,
46 * meaning all calls go straight through... use ifdef to
47 * catch erroneous assumption.
48 */
49 pci_write_reg(0xFD000000 , SH7780_PCIMBR0);
50 pci_write_reg(0x00FC0000 , SH7780_PCIMBMR0); /* 16M */
51
52 /* Set IOBR for window containing area specified in pci.h */
53 pci_write_reg(PCIBIOS_MIN_IO & ~(SH7780_PCI_IO_SIZE-1), SH7780_PCIIOBR);
54 pci_write_reg((SH7780_PCI_IO_SIZE-1) & (7 << 18), SH7780_PCIIOBMR);
55
56 pci_write_reg(0xA5000C01, SH7780_PCICR);
57
58 return 0;
59}
diff --git a/arch/sh/drivers/pci/ops-cayman.c b/arch/sh/drivers/pci/ops-cayman.c
new file mode 100644
index 000000000000..980275ffa30b
--- /dev/null
+++ b/arch/sh/drivers/pci/ops-cayman.c
@@ -0,0 +1,94 @@
1#include <linux/kernel.h>
2#include <linux/init.h>
3#include <linux/pci.h>
4#include <linux/types.h>
5#include <asm/cpu/irq.h>
6#include "pci-sh5.h"
7
8static inline u8 bridge_swizzle(u8 pin, u8 slot)
9{
10 return (((pin - 1) + slot) % 4) + 1;
11}
12
13int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin)
14{
15 int result = -1;
16
17 /* The complication here is that the PCI IRQ lines from the Cayman's 2
18 5V slots get into the CPU via a different path from the IRQ lines
19 from the 3 3.3V slots. Thus, we have to detect whether the card's
20 interrupts go via the 5V or 3.3V path, i.e. the 'bridge swizzling'
21 at the point where we cross from 5V to 3.3V is not the normal case.
22
23 The added complication is that we don't know that the 5V slots are
24 always bus 2, because a card containing a PCI-PCI bridge may be
25 plugged into a 3.3V slot, and this changes the bus numbering.
26
27 Also, the Cayman has an intermediate PCI bus that goes a custom
28 expansion board header (and to the secondary bridge). This bus has
29 never been used in practice.
30
31 The 1ary onboard PCI-PCI bridge is device 3 on bus 0
32 The 2ary onboard PCI-PCI bridge is device 0 on the 2ary bus of
33 the 1ary bridge.
34 */
35
36 struct slot_pin {
37 int slot;
38 int pin;
39 } path[4];
40 int i=0;
41
42 while (dev->bus->number > 0) {
43
44 slot = path[i].slot = PCI_SLOT(dev->devfn);
45 pin = path[i].pin = bridge_swizzle(pin, slot);
46 dev = dev->bus->self;
47 i++;
48 if (i > 3) panic("PCI path to root bus too long!\n");
49 }
50
51 slot = PCI_SLOT(dev->devfn);
52 /* This is the slot on bus 0 through which the device is eventually
53 reachable. */
54
55 /* Now work back up. */
56 if ((slot < 3) || (i == 0)) {
57 /* Bus 0 (incl. PCI-PCI bridge itself) : perform the final
58 swizzle now. */
59 result = IRQ_INTA + bridge_swizzle(pin, slot) - 1;
60 } else {
61 i--;
62 slot = path[i].slot;
63 pin = path[i].pin;
64 if (slot > 0) {
65 panic("PCI expansion bus device found - not handled!\n");
66 } else {
67 if (i > 0) {
68 /* 5V slots */
69 i--;
70 slot = path[i].slot;
71 pin = path[i].pin;
72 /* 'pin' was swizzled earlier wrt slot, don't do it again. */
73 result = IRQ_P2INTA + (pin - 1);
74 } else {
75 /* IRQ for 2ary PCI-PCI bridge : unused */
76 result = -1;
77 }
78 }
79 }
80
81 return result;
82}
83
84struct pci_channel board_pci_channels[] = {
85 { &sh5_pci_ops, NULL, NULL, 0, 0xff },
86 { NULL, NULL, NULL, 0, 0 },
87};
88EXPORT_SYMBOL(board_pci_channels);
89
90int __init pcibios_init_platform(void)
91{
92 return sh5pci_init(__pa(memory_start),
93 __pa(memory_end) - __pa(memory_start));
94}
diff --git a/arch/sh/drivers/pci/ops-r7780rp.c b/arch/sh/drivers/pci/ops-r7780rp.c
index 48fe4032ebea..5fdadaeed6fc 100644
--- a/arch/sh/drivers/pci/ops-r7780rp.c
+++ b/arch/sh/drivers/pci/ops-r7780rp.c
@@ -17,25 +17,13 @@
17#include <asm/io.h> 17#include <asm/io.h>
18#include "pci-sh4.h" 18#include "pci-sh4.h"
19 19
20static char r7780rp_irq_tab[] __initdata = { 20static char irq_tab[] __initdata = {
21 0, 1, 2, 3,
22};
23
24static char r7780mp_irq_tab[] __initdata = {
25 65, 66, 67, 68, 21 65, 66, 67, 68,
26}; 22};
27 23
28int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) 24int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
29{ 25{
30 if (mach_is_r7780rp()) 26 return irq_tab[slot];
31 return r7780rp_irq_tab[slot];
32 if (mach_is_r7780mp() || mach_is_r7785rp())
33 return r7780mp_irq_tab[slot];
34
35 printk(KERN_ERR "PCI: Bad IRQ mapping "
36 "request for slot %d, func %d\n", slot, pin-1);
37
38 return -1;
39} 27}
40 28
41static struct resource sh7780_io_resource = { 29static struct resource sh7780_io_resource = {
diff --git a/arch/sh/drivers/pci/ops-sdk7780.c b/arch/sh/drivers/pci/ops-sdk7780.c
new file mode 100644
index 000000000000..66a9b4047f26
--- /dev/null
+++ b/arch/sh/drivers/pci/ops-sdk7780.c
@@ -0,0 +1,73 @@
1/*
2 * linux/arch/sh/drivers/pci/ops-sdk7780.c
3 *
4 * Copyright (C) 2006 Nobuhiro Iwamatsu
5 *
6 * PCI initialization for the SDK7780SE03
7 *
8 * May be copied or modified under the terms of the GNU General Public
9 * License. See linux/COPYING for more information.
10 */
11#include <linux/kernel.h>
12#include <linux/types.h>
13#include <linux/init.h>
14#include <linux/delay.h>
15#include <linux/pci.h>
16#include <asm/sdk7780.h>
17#include <asm/io.h>
18#include "pci-sh4.h"
19
20/* IDSEL [16][17][18][19][20][21][22][23][24][25][26][27][28][29][30][31] */
21static char sdk7780_irq_tab[4][16] __initdata = {
22 /* INTA */
23 { 65, 68, 67, 68, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
24 /* INTB */
25 { 66, 65, -1, 65, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
26 /* INTC */
27 { 67, 66, -1, 66, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
28 /* INTD */
29 { 68, 67, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
30};
31
32int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
33{
34 return sdk7780_irq_tab[pin-1][slot];
35}
36
37static struct resource sdk7780_io_resource = {
38 .name = "SH7780_IO",
39 .start = SH7780_PCI_IO_BASE,
40 .end = SH7780_PCI_IO_BASE + SH7780_PCI_IO_SIZE - 1,
41 .flags = IORESOURCE_IO
42};
43
44static struct resource sdk7780_mem_resource = {
45 .name = "SH7780_mem",
46 .start = SH7780_PCI_MEMORY_BASE,
47 .end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1,
48 .flags = IORESOURCE_MEM
49};
50
51struct pci_channel board_pci_channels[] = {
52 { &sh4_pci_ops, &sdk7780_io_resource, &sdk7780_mem_resource, 0, 0xff },
53 { NULL, NULL, NULL, 0, 0 },
54};
55EXPORT_SYMBOL(board_pci_channels);
56
57static struct sh4_pci_address_map sdk7780_pci_map = {
58 .window0 = {
59 .base = SH7780_CS2_BASE_ADDR,
60 .size = 0x04000000,
61 },
62 .window1 = {
63 .base = SH7780_CS3_BASE_ADDR,
64 .size = 0x04000000,
65 },
66 .flags = SH4_PCIC_NO_RESET,
67};
68
69int __init pcibios_init_platform(void)
70{
71 printk(KERN_INFO "SH7780 PCI: Finished initializing PCI controller\n");
72 return sh7780_pcic_init(&sdk7780_pci_map);
73}
diff --git a/arch/sh/drivers/pci/ops-sh5.c b/arch/sh/drivers/pci/ops-sh5.c
new file mode 100644
index 000000000000..729e38a6fe07
--- /dev/null
+++ b/arch/sh/drivers/pci/ops-sh5.c
@@ -0,0 +1,93 @@
1/*
2 * Support functions for the SH5 PCI hardware.
3 *
4 * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
5 * Copyright (C) 2003, 2004 Paul Mundt
6 * Copyright (C) 2004 Richard Curnow
7 *
8 * May be copied or modified under the terms of the GNU General Public
9 * License. See linux/COPYING for more information.
10 */
11#include <linux/kernel.h>
12#include <linux/rwsem.h>
13#include <linux/smp.h>
14#include <linux/interrupt.h>
15#include <linux/init.h>
16#include <linux/errno.h>
17#include <linux/pci.h>
18#include <linux/delay.h>
19#include <linux/types.h>
20#include <linux/irq.h>
21#include <asm/pci.h>
22#include <asm/io.h>
23#include "pci-sh5.h"
24
25static void __init pci_fixup_ide_bases(struct pci_dev *d)
26{
27 int i;
28
29 /*
30 * PCI IDE controllers use non-standard I/O port decoding, respect it.
31 */
32 if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
33 return;
34 printk("PCI: IDE base address fixup for %s\n", pci_name(d));
35 for(i=0; i<4; i++) {
36 struct resource *r = &d->resource[i];
37 if ((r->start & ~0x80) == 0x374) {
38 r->start |= 2;
39 r->end = r->start;
40 }
41 }
42}
43DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases);
44
45char * __devinit pcibios_setup(char *str)
46{
47 return str;
48}
49
50static int sh5pci_read(struct pci_bus *bus, unsigned int devfn, int where,
51 int size, u32 *val)
52{
53 SH5PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
54
55 switch (size) {
56 case 1:
57 *val = (u8)SH5PCI_READ_BYTE(PDR + (where & 3));
58 break;
59 case 2:
60 *val = (u16)SH5PCI_READ_SHORT(PDR + (where & 2));
61 break;
62 case 4:
63 *val = SH5PCI_READ(PDR);
64 break;
65 }
66
67 return PCIBIOS_SUCCESSFUL;
68}
69
70static int sh5pci_write(struct pci_bus *bus, unsigned int devfn, int where,
71 int size, u32 val)
72{
73 SH5PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
74
75 switch (size) {
76 case 1:
77 SH5PCI_WRITE_BYTE(PDR + (where & 3), (u8)val);
78 break;
79 case 2:
80 SH5PCI_WRITE_SHORT(PDR + (where & 2), (u16)val);
81 break;
82 case 4:
83 SH5PCI_WRITE(PDR, val);
84 break;
85 }
86
87 return PCIBIOS_SUCCESSFUL;
88}
89
90struct pci_ops sh5_pci_ops = {
91 .read = sh5pci_read,
92 .write = sh5pci_write,
93};
diff --git a/arch/sh/drivers/pci/pci-auto.c b/arch/sh/drivers/pci/pci-auto.c
index 224e007736fb..ea404704ace8 100644
--- a/arch/sh/drivers/pci/pci-auto.c
+++ b/arch/sh/drivers/pci/pci-auto.c
@@ -516,10 +516,8 @@ pciauto_bus_scan(struct pci_channel *hose, int top_bus, int current_bus)
516 PCI_COMMAND, cmdstat | PCI_COMMAND_IO | 516 PCI_COMMAND, cmdstat | PCI_COMMAND_IO |
517 PCI_COMMAND_MEMORY | 517 PCI_COMMAND_MEMORY |
518 PCI_COMMAND_MASTER); 518 PCI_COMMAND_MASTER);
519#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D)
520 early_write_config_byte(hose, top_bus, current_bus, pci_devfn, 519 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
521 PCI_LATENCY_TIMER, 0x80); 520 PCI_LATENCY_TIMER, 0x80);
522#endif
523 521
524 /* Allocate PCI I/O and/or memory space */ 522 /* Allocate PCI I/O and/or memory space */
525 pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_5); 523 pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_5);
diff --git a/arch/sh/drivers/pci/pci-sh4.h b/arch/sh/drivers/pci/pci-sh4.h
index 1901c33cde6a..4925c79ea959 100644
--- a/arch/sh/drivers/pci/pci-sh4.h
+++ b/arch/sh/drivers/pci/pci-sh4.h
@@ -1,7 +1,9 @@
1#ifndef __PCI_SH4_H 1#ifndef __PCI_SH4_H
2#define __PCI_SH4_H 2#define __PCI_SH4_H
3 3
4#if defined(CONFIG_CPU_SUBTYPE_SH7780) || defined(CONFIG_CPU_SUBTYPE_SH7785) 4#if defined(CONFIG_CPU_SUBTYPE_SH7780) || \
5 defined(CONFIG_CPU_SUBTYPE_SH7785) || \
6 defined(CONFIG_CPU_SUBTYPE_SH7763)
5#include "pci-sh7780.h" 7#include "pci-sh7780.h"
6#else 8#else
7#include "pci-sh7751.h" 9#include "pci-sh7751.h"
diff --git a/arch/sh/drivers/pci/pci-sh5.c b/arch/sh/drivers/pci/pci-sh5.c
new file mode 100644
index 000000000000..a00a4df8c02d
--- /dev/null
+++ b/arch/sh/drivers/pci/pci-sh5.c
@@ -0,0 +1,228 @@
1/*
2 * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
3 * Copyright (C) 2003, 2004 Paul Mundt
4 * Copyright (C) 2004 Richard Curnow
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * Support functions for the SH5 PCI hardware.
10 */
11
12#include <linux/kernel.h>
13#include <linux/rwsem.h>
14#include <linux/smp.h>
15#include <linux/interrupt.h>
16#include <linux/init.h>
17#include <linux/errno.h>
18#include <linux/pci.h>
19#include <linux/delay.h>
20#include <linux/types.h>
21#include <linux/irq.h>
22#include <asm/cpu/irq.h>
23#include <asm/pci.h>
24#include <asm/io.h>
25#include "pci-sh5.h"
26
27unsigned long pcicr_virt;
28unsigned long PCI_IO_AREA;
29
30/* Rounds a number UP to the nearest power of two. Used for
31 * sizing the PCI window.
32 */
33static u32 __init r2p2(u32 num)
34{
35 int i = 31;
36 u32 tmp = num;
37
38 if (num == 0)
39 return 0;
40
41 do {
42 if (tmp & (1 << 31))
43 break;
44 i--;
45 tmp <<= 1;
46 } while (i >= 0);
47
48 tmp = 1 << i;
49 /* If the original number isn't a power of 2, round it up */
50 if (tmp != num)
51 tmp <<= 1;
52
53 return tmp;
54}
55
56static irqreturn_t pcish5_err_irq(int irq, void *dev_id)
57{
58 struct pt_regs *regs = get_irq_regs();
59 unsigned pci_int, pci_air, pci_cir, pci_aint;
60
61 pci_int = SH5PCI_READ(INT);
62 pci_cir = SH5PCI_READ(CIR);
63 pci_air = SH5PCI_READ(AIR);
64
65 if (pci_int) {
66 printk("PCI INTERRUPT (at %08llx)!\n", regs->pc);
67 printk("PCI INT -> 0x%x\n", pci_int & 0xffff);
68 printk("PCI AIR -> 0x%x\n", pci_air);
69 printk("PCI CIR -> 0x%x\n", pci_cir);
70 SH5PCI_WRITE(INT, ~0);
71 }
72
73 pci_aint = SH5PCI_READ(AINT);
74 if (pci_aint) {
75 printk("PCI ARB INTERRUPT!\n");
76 printk("PCI AINT -> 0x%x\n", pci_aint);
77 printk("PCI AIR -> 0x%x\n", pci_air);
78 printk("PCI CIR -> 0x%x\n", pci_cir);
79 SH5PCI_WRITE(AINT, ~0);
80 }
81
82 return IRQ_HANDLED;
83}
84
85static irqreturn_t pcish5_serr_irq(int irq, void *dev_id)
86{
87 printk("SERR IRQ\n");
88
89 return IRQ_NONE;
90}
91
92int __init sh5pci_init(unsigned long memStart, unsigned long memSize)
93{
94 u32 lsr0;
95 u32 uval;
96
97 if (request_irq(IRQ_ERR, pcish5_err_irq,
98 IRQF_DISABLED, "PCI Error",NULL) < 0) {
99 printk(KERN_ERR "PCISH5: Cannot hook PCI_PERR interrupt\n");
100 return -EINVAL;
101 }
102
103 if (request_irq(IRQ_SERR, pcish5_serr_irq,
104 IRQF_DISABLED, "PCI SERR interrupt", NULL) < 0) {
105 printk(KERN_ERR "PCISH5: Cannot hook PCI_SERR interrupt\n");
106 return -EINVAL;
107 }
108
109 pcicr_virt = onchip_remap(SH5PCI_ICR_BASE, 1024, "PCICR");
110 if (!pcicr_virt) {
111 panic("Unable to remap PCICR\n");
112 }
113
114 PCI_IO_AREA = onchip_remap(SH5PCI_IO_BASE, 0x10000, "PCIIO");
115 if (!PCI_IO_AREA) {
116 panic("Unable to remap PCIIO\n");
117 }
118
119 /* Clear snoop registers */
120 SH5PCI_WRITE(CSCR0, 0);
121 SH5PCI_WRITE(CSCR1, 0);
122
123 /* Switch off interrupts */
124 SH5PCI_WRITE(INTM, 0);
125 SH5PCI_WRITE(AINTM, 0);
126 SH5PCI_WRITE(PINTM, 0);
127
128 /* Set bus active, take it out of reset */
129 uval = SH5PCI_READ(CR);
130
131 /* Set command Register */
132 SH5PCI_WRITE(CR, uval | CR_LOCK_MASK | CR_CFINT| CR_FTO | CR_PFE |
133 CR_PFCS | CR_BMAM);
134
135 uval=SH5PCI_READ(CR);
136
137 /* Allow it to be a master */
138 /* NB - WE DISABLE I/O ACCESS to stop overlap */
139 /* set WAIT bit to enable stepping, an attempt to improve stability */
140 SH5PCI_WRITE_SHORT(CSR_CMD,
141 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
142 PCI_COMMAND_WAIT);
143
144 /*
145 ** Set translation mapping memory in order to convert the address
146 ** used for the main bus, to the PCI internal address.
147 */
148 SH5PCI_WRITE(MBR,0x40000000);
149
150 /* Always set the max size 512M */
151 SH5PCI_WRITE(MBMR, PCISH5_MEM_SIZCONV(512*1024*1024));
152
153 /*
154 ** I/O addresses are mapped at internal PCI specific address
155 ** as is described into the configuration bridge table.
156 ** These are changed to 0, to allow cards that have legacy
157 ** io such as vga to function correctly. We set the SH5 IOBAR to
158 ** 256K, which is a bit big as we can only have 64K of address space
159 */
160
161 SH5PCI_WRITE(IOBR,0x0);
162
163 /* Set up a 256K window. Totally pointless waste of address space */
164 SH5PCI_WRITE(IOBMR,0);
165
166 /* The SH5 has a HUGE 256K I/O region, which breaks the PCI spec.
167 * Ideally, we would want to map the I/O region somewhere, but it
168 * is so big this is not that easy!
169 */
170 SH5PCI_WRITE(CSR_IBAR0,~0);
171 /* Set memory size value */
172 memSize = memory_end - memory_start;
173
174 /* Now we set up the mbars so the PCI bus can see the memory of
175 * the machine */
176 if (memSize < (1024 * 1024)) {
177 printk(KERN_ERR "PCISH5: Ridiculous memory size of 0x%lx?\n",
178 memSize);
179 return -EINVAL;
180 }
181
182 /* Set LSR 0 */
183 lsr0 = (memSize > (512 * 1024 * 1024)) ? 0x1ff00001 :
184 ((r2p2(memSize) - 0x100000) | 0x1);
185 SH5PCI_WRITE(LSR0, lsr0);
186
187 /* Set MBAR 0 */
188 SH5PCI_WRITE(CSR_MBAR0, memory_start);
189 SH5PCI_WRITE(LAR0, memory_start);
190
191 SH5PCI_WRITE(CSR_MBAR1,0);
192 SH5PCI_WRITE(LAR1,0);
193 SH5PCI_WRITE(LSR1,0);
194
195 /* Enable the PCI interrupts on the device */
196 SH5PCI_WRITE(INTM, ~0);
197 SH5PCI_WRITE(AINTM, ~0);
198 SH5PCI_WRITE(PINTM, ~0);
199
200 return 0;
201}
202
203void __devinit pcibios_fixup_bus(struct pci_bus *bus)
204{
205 struct pci_dev *dev = bus->self;
206 int i;
207
208 if (dev) {
209 for (i= 0; i < 3; i++) {
210 bus->resource[i] =
211 &dev->resource[PCI_BRIDGE_RESOURCES+i];
212 bus->resource[i]->name = bus->name;
213 }
214 bus->resource[0]->flags |= IORESOURCE_IO;
215 bus->resource[1]->flags |= IORESOURCE_MEM;
216
217 /* For now, propagate host limits to the bus;
218 * we'll adjust them later. */
219 bus->resource[0]->end = 64*1024 - 1 ;
220 bus->resource[1]->end = PCIBIOS_MIN_MEM+(256*1024*1024)-1;
221 bus->resource[0]->start = PCIBIOS_MIN_IO;
222 bus->resource[1]->start = PCIBIOS_MIN_MEM;
223
224 /* Turn off downstream PF memory address range by default */
225 bus->resource[2]->start = 1024*1024;
226 bus->resource[2]->end = bus->resource[2]->start - 1;
227 }
228}
diff --git a/arch/sh64/kernel/pci_sh5.h b/arch/sh/drivers/pci/pci-sh5.h
index c71159dd04b9..7cff3fc04d30 100644
--- a/arch/sh64/kernel/pci_sh5.h
+++ b/arch/sh/drivers/pci/pci-sh5.h
@@ -6,6 +6,8 @@
6 * 6 *
7 * Definitions for the SH5 PCI hardware. 7 * Definitions for the SH5 PCI hardware.
8 */ 8 */
9#ifndef __PCI_SH5_H
10#define __PCI_SH5_H
9 11
10/* Product ID */ 12/* Product ID */
11#define PCISH5_PID 0x350d 13#define PCISH5_PID 0x350d
@@ -73,13 +75,12 @@
73#define PCISH5_ICR_CSR_MBAR0 0x014 /* First Memory base address register */ 75#define PCISH5_ICR_CSR_MBAR0 0x014 /* First Memory base address register */
74#define PCISH5_ICR_CSR_MBAR1 0x018 /* Second Memory base address register */ 76#define PCISH5_ICR_CSR_MBAR1 0x018 /* Second Memory base address register */
75 77
76
77
78/* Base address of registers */ 78/* Base address of registers */
79#define SH5PCI_ICR_BASE (PHYS_PCI_BLOCK + 0x00040000) 79#define SH5PCI_ICR_BASE (PHYS_PCI_BLOCK + 0x00040000)
80#define SH5PCI_IO_BASE (PHYS_PCI_BLOCK + 0x00800000) 80#define SH5PCI_IO_BASE (PHYS_PCI_BLOCK + 0x00800000)
81/* #define SH5PCI_VCR_BASE (P2SEG_PCICB_BLOCK + P2SEG) */ 81/* #define SH5PCI_VCR_BASE (P2SEG_PCICB_BLOCK + P2SEG) */
82 82
83extern unsigned long pcicr_virt;
83/* Register selection macro */ 84/* Register selection macro */
84#define PCISH5_ICR_REG(x) ( pcicr_virt + (PCISH5_ICR_##x)) 85#define PCISH5_ICR_REG(x) ( pcicr_virt + (PCISH5_ICR_##x))
85/* #define PCISH5_VCR_REG(x) ( SH5PCI_VCR_BASE (PCISH5_VCR_##x)) */ 86/* #define PCISH5_VCR_REG(x) ( SH5PCI_VCR_BASE (PCISH5_VCR_##x)) */
@@ -104,4 +105,9 @@
104#define PCISH5_MEM_SIZCONV(x) (((x / 0x40000) - 1) << 18) 105#define PCISH5_MEM_SIZCONV(x) (((x / 0x40000) - 1) << 18)
105#define PCISH5_IO_SIZCONV(x) (((x / 0x40000) - 1) << 18) 106#define PCISH5_IO_SIZCONV(x) (((x / 0x40000) - 1) << 18)
106 107
108extern struct pci_ops sh5_pci_ops;
109
110/* arch/sh/drivers/pci/pci-sh5.c */
111int sh5pci_init(unsigned long memStart, unsigned long memSize);
107 112
113#endif /* __PCI_SH5_H */
diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c
index e516087fb435..7d797f4de5e7 100644
--- a/arch/sh/drivers/pci/pci-sh7780.c
+++ b/arch/sh/drivers/pci/pci-sh7780.c
@@ -58,6 +58,7 @@ static int __init sh7780_pci_init(void)
58 id = pci_read_reg(SH7780_PCIVID); 58 id = pci_read_reg(SH7780_PCIVID);
59 if ((id & 0xffff) == SH7780_VENDOR_ID) { 59 if ((id & 0xffff) == SH7780_VENDOR_ID) {
60 switch ((id >> 16) & 0xffff) { 60 switch ((id >> 16) & 0xffff) {
61 case SH7763_DEVICE_ID:
61 case SH7780_DEVICE_ID: 62 case SH7780_DEVICE_ID:
62 case SH7781_DEVICE_ID: 63 case SH7781_DEVICE_ID:
63 case SH7785_DEVICE_ID: 64 case SH7785_DEVICE_ID:
diff --git a/arch/sh/drivers/pci/pci-sh7780.h b/arch/sh/drivers/pci/pci-sh7780.h
index 1d069a859de2..97b2c98f05c4 100644
--- a/arch/sh/drivers/pci/pci-sh7780.h
+++ b/arch/sh/drivers/pci/pci-sh7780.h
@@ -16,6 +16,7 @@
16#define SH7780_VENDOR_ID 0x1912 16#define SH7780_VENDOR_ID 0x1912
17#define SH7781_DEVICE_ID 0x0001 17#define SH7781_DEVICE_ID 0x0001
18#define SH7780_DEVICE_ID 0x0002 18#define SH7780_DEVICE_ID 0x0002
19#define SH7763_DEVICE_ID 0x0004
19#define SH7785_DEVICE_ID 0x0007 20#define SH7785_DEVICE_ID 0x0007
20 21
21/* SH7780 Control Registers */ 22/* SH7780 Control Registers */
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c
index ccaba368ac9b..49b435c3a57a 100644
--- a/arch/sh/drivers/pci/pci.c
+++ b/arch/sh/drivers/pci/pci.c
@@ -71,7 +71,7 @@ subsys_initcall(pcibios_init);
71 * Called after each bus is probed, but before its children 71 * Called after each bus is probed, but before its children
72 * are examined. 72 * are examined.
73 */ 73 */
74void __devinit pcibios_fixup_bus(struct pci_bus *bus) 74void __devinit __weak pcibios_fixup_bus(struct pci_bus *bus)
75{ 75{
76 pci_read_bridge_bases(bus); 76 pci_read_bridge_bases(bus);
77} 77}
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index 4b81d9c47b00..349d833deab5 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -1,25 +1,5 @@
1# 1ifeq ($(CONFIG_SUPERH32),y)
2# Makefile for the Linux/SuperH kernel. 2include ${srctree}/arch/sh/kernel/Makefile_32
3# 3else
4 4include ${srctree}/arch/sh/kernel/Makefile_64
5extra-y := head.o init_task.o vmlinux.lds 5endif
6
7obj-y := debugtraps.o io.o io_generic.o irq.o machvec.o process.o ptrace.o \
8 semaphore.o setup.o signal.o sys_sh.o syscalls.o \
9 time.o topology.o traps.o
10
11obj-y += cpu/ timers/
12obj-$(CONFIG_VSYSCALL) += vsyscall/
13obj-$(CONFIG_SMP) += smp.o
14obj-$(CONFIG_CF_ENABLER) += cf-enabler.o
15obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o
16obj-$(CONFIG_SH_KGDB) += kgdb_stub.o kgdb_jmp.o
17obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o
18obj-$(CONFIG_MODULES) += sh_ksyms.o module.o
19obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
20obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
21obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
22obj-$(CONFIG_PM) += pm.o
23obj-$(CONFIG_STACKTRACE) += stacktrace.o
24
25EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/kernel/Makefile_32 b/arch/sh/kernel/Makefile_32
new file mode 100644
index 000000000000..c89289831053
--- /dev/null
+++ b/arch/sh/kernel/Makefile_32
@@ -0,0 +1,26 @@
1#
2# Makefile for the Linux/SuperH kernel.
3#
4
5extra-y := head_32.o init_task.o vmlinux.lds
6
7obj-y := debugtraps.o io.o io_generic.o irq.o machvec.o process_32.o \
8 ptrace_32.o semaphore.o setup.o signal_32.o sys_sh.o sys_sh32.o \
9 syscalls_32.o time_32.o topology.o traps.o traps_32.o
10
11obj-y += cpu/ timers/
12obj-$(CONFIG_VSYSCALL) += vsyscall/
13obj-$(CONFIG_SMP) += smp.o
14obj-$(CONFIG_CF_ENABLER) += cf-enabler.o
15obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o
16obj-$(CONFIG_SH_KGDB) += kgdb_stub.o kgdb_jmp.o
17obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o
18obj-$(CONFIG_MODULES) += sh_ksyms_32.o module.o
19obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
20obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
21obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
22obj-$(CONFIG_PM) += pm.o
23obj-$(CONFIG_STACKTRACE) += stacktrace.o
24obj-$(CONFIG_BINFMT_ELF) += dump_task.o
25
26EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/kernel/Makefile_64 b/arch/sh/kernel/Makefile_64
new file mode 100644
index 000000000000..1ef21cc087f3
--- /dev/null
+++ b/arch/sh/kernel/Makefile_64
@@ -0,0 +1,22 @@
1extra-y := head_64.o init_task.o vmlinux.lds
2
3obj-y := debugtraps.o io.o io_generic.o irq.o machvec.o process_64.o \
4 ptrace_64.o semaphore.o setup.o signal_64.o sys_sh.o sys_sh64.o \
5 syscalls_64.o time_64.o topology.o traps.o traps_64.o
6
7obj-y += cpu/ timers/
8obj-$(CONFIG_VSYSCALL) += vsyscall/
9obj-$(CONFIG_SMP) += smp.o
10obj-$(CONFIG_CF_ENABLER) += cf-enabler.o
11obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o
12obj-$(CONFIG_SH_KGDB) += kgdb_stub.o kgdb_jmp.o
13obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o
14obj-$(CONFIG_MODULES) += sh_ksyms_64.o module.o
15obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
16obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
17obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
18obj-$(CONFIG_PM) += pm.o
19obj-$(CONFIG_STACKTRACE) += stacktrace.o
20obj-$(CONFIG_BINFMT_ELF) += dump_task.o
21
22EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile
index d055a3ea6b4b..f471d242774e 100644
--- a/arch/sh/kernel/cpu/Makefile
+++ b/arch/sh/kernel/cpu/Makefile
@@ -6,8 +6,14 @@ obj-$(CONFIG_CPU_SH2) = sh2/
6obj-$(CONFIG_CPU_SH2A) = sh2a/ 6obj-$(CONFIG_CPU_SH2A) = sh2a/
7obj-$(CONFIG_CPU_SH3) = sh3/ 7obj-$(CONFIG_CPU_SH3) = sh3/
8obj-$(CONFIG_CPU_SH4) = sh4/ 8obj-$(CONFIG_CPU_SH4) = sh4/
9obj-$(CONFIG_CPU_SH5) = sh5/
10
11# Special cases for family ancestry.
12
9obj-$(CONFIG_CPU_SH4A) += sh4a/ 13obj-$(CONFIG_CPU_SH4A) += sh4a/
10 14
15# Common interfaces.
16
11obj-$(CONFIG_UBC_WAKEUP) += ubc.o 17obj-$(CONFIG_UBC_WAKEUP) += ubc.o
12obj-$(CONFIG_SH_ADC) += adc.o 18obj-$(CONFIG_SH_ADC) += adc.o
13 19
diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c
index c217c4bf0085..80a31329ead9 100644
--- a/arch/sh/kernel/cpu/init.c
+++ b/arch/sh/kernel/cpu/init.c
@@ -13,6 +13,7 @@
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/mm.h> 15#include <linux/mm.h>
16#include <linux/log2.h>
16#include <asm/mmu_context.h> 17#include <asm/mmu_context.h>
17#include <asm/processor.h> 18#include <asm/processor.h>
18#include <asm/uaccess.h> 19#include <asm/uaccess.h>
@@ -20,9 +21,12 @@
20#include <asm/system.h> 21#include <asm/system.h>
21#include <asm/cacheflush.h> 22#include <asm/cacheflush.h>
22#include <asm/cache.h> 23#include <asm/cache.h>
24#include <asm/elf.h>
23#include <asm/io.h> 25#include <asm/io.h>
24#include <asm/ubc.h>
25#include <asm/smp.h> 26#include <asm/smp.h>
27#ifdef CONFIG_SUPERH32
28#include <asm/ubc.h>
29#endif
26 30
27/* 31/*
28 * Generic wrapper for command line arguments to disable on-chip 32 * Generic wrapper for command line arguments to disable on-chip
@@ -61,25 +65,12 @@ static void __init speculative_execution_init(void)
61/* 65/*
62 * Generic first-level cache init 66 * Generic first-level cache init
63 */ 67 */
64static void __init cache_init(void) 68#ifdef CONFIG_SUPERH32
69static void __uses_jump_to_uncached cache_init(void)
65{ 70{
66 unsigned long ccr, flags; 71 unsigned long ccr, flags;
67 72
68 /* First setup the rest of the I-cache info */ 73 jump_to_uncached();
69 current_cpu_data.icache.entry_mask = current_cpu_data.icache.way_incr -
70 current_cpu_data.icache.linesz;
71
72 current_cpu_data.icache.way_size = current_cpu_data.icache.sets *
73 current_cpu_data.icache.linesz;
74
75 /* And the D-cache too */
76 current_cpu_data.dcache.entry_mask = current_cpu_data.dcache.way_incr -
77 current_cpu_data.dcache.linesz;
78
79 current_cpu_data.dcache.way_size = current_cpu_data.dcache.sets *
80 current_cpu_data.dcache.linesz;
81
82 jump_to_P2();
83 ccr = ctrl_inl(CCR); 74 ccr = ctrl_inl(CCR);
84 75
85 /* 76 /*
@@ -156,7 +147,31 @@ static void __init cache_init(void)
156#endif 147#endif
157 148
158 ctrl_outl(flags, CCR); 149 ctrl_outl(flags, CCR);
159 back_to_P1(); 150 back_to_cached();
151}
152#else
153#define cache_init() do { } while (0)
154#endif
155
156#define CSHAPE(totalsize, linesize, assoc) \
157 ((totalsize & ~0xff) | (linesize << 4) | assoc)
158
159#define CACHE_DESC_SHAPE(desc) \
160 CSHAPE((desc).way_size * (desc).ways, ilog2((desc).linesz), (desc).ways)
161
162static void detect_cache_shape(void)
163{
164 l1d_cache_shape = CACHE_DESC_SHAPE(current_cpu_data.dcache);
165
166 if (current_cpu_data.dcache.flags & SH_CACHE_COMBINED)
167 l1i_cache_shape = l1d_cache_shape;
168 else
169 l1i_cache_shape = CACHE_DESC_SHAPE(current_cpu_data.icache);
170
171 if (current_cpu_data.flags & CPU_HAS_L2_CACHE)
172 l2_cache_shape = CACHE_DESC_SHAPE(current_cpu_data.scache);
173 else
174 l2_cache_shape = -1; /* No S-cache */
160} 175}
161 176
162#ifdef CONFIG_SH_DSP 177#ifdef CONFIG_SH_DSP
@@ -228,14 +243,32 @@ asmlinkage void __cpuinit sh_cpu_init(void)
228 if (current_cpu_data.type == CPU_SH_NONE) 243 if (current_cpu_data.type == CPU_SH_NONE)
229 panic("Unknown CPU"); 244 panic("Unknown CPU");
230 245
246 /* First setup the rest of the I-cache info */
247 current_cpu_data.icache.entry_mask = current_cpu_data.icache.way_incr -
248 current_cpu_data.icache.linesz;
249
250 current_cpu_data.icache.way_size = current_cpu_data.icache.sets *
251 current_cpu_data.icache.linesz;
252
253 /* And the D-cache too */
254 current_cpu_data.dcache.entry_mask = current_cpu_data.dcache.way_incr -
255 current_cpu_data.dcache.linesz;
256
257 current_cpu_data.dcache.way_size = current_cpu_data.dcache.sets *
258 current_cpu_data.dcache.linesz;
259
231 /* Init the cache */ 260 /* Init the cache */
232 cache_init(); 261 cache_init();
233 262
234 if (raw_smp_processor_id() == 0) 263 if (raw_smp_processor_id() == 0) {
235 shm_align_mask = max_t(unsigned long, 264 shm_align_mask = max_t(unsigned long,
236 current_cpu_data.dcache.way_size - 1, 265 current_cpu_data.dcache.way_size - 1,
237 PAGE_SIZE - 1); 266 PAGE_SIZE - 1);
238 267
268 /* Boot CPU sets the cache shape */
269 detect_cache_shape();
270 }
271
239 /* Disable the FPU */ 272 /* Disable the FPU */
240 if (fpu_disabled) { 273 if (fpu_disabled) {
241 printk("FPU Disabled\n"); 274 printk("FPU Disabled\n");
@@ -273,7 +306,10 @@ asmlinkage void __cpuinit sh_cpu_init(void)
273 * like PTRACE_SINGLESTEP or doing hardware watchpoints in GDB. So .. 306 * like PTRACE_SINGLESTEP or doing hardware watchpoints in GDB. So ..
274 * we wake it up and hope that all is well. 307 * we wake it up and hope that all is well.
275 */ 308 */
309#ifdef CONFIG_SUPERH32
276 if (raw_smp_processor_id() == 0) 310 if (raw_smp_processor_id() == 0)
277 ubc_wakeup(); 311 ubc_wakeup();
312#endif
313
278 speculative_execution_init(); 314 speculative_execution_init();
279} 315}
diff --git a/arch/sh/kernel/cpu/irq/Makefile b/arch/sh/kernel/cpu/irq/Makefile
index 8da8e178f09c..cc1836e47a5d 100644
--- a/arch/sh/kernel/cpu/irq/Makefile
+++ b/arch/sh/kernel/cpu/irq/Makefile
@@ -1,7 +1,9 @@
1# 1#
2# Makefile for the Linux/SuperH CPU-specifc IRQ handlers. 2# Makefile for the Linux/SuperH CPU-specifc IRQ handlers.
3# 3#
4obj-y += imask.o intc.o 4obj-y += intc.o
5 5
6obj-$(CONFIG_SUPERH32) += imask.o
7obj-$(CONFIG_CPU_SH5) += intc-sh5.o
6obj-$(CONFIG_CPU_HAS_IPR_IRQ) += ipr.o 8obj-$(CONFIG_CPU_HAS_IPR_IRQ) += ipr.o
7obj-$(CONFIG_CPU_HAS_MASKREG_IRQ) += maskreg.o 9obj-$(CONFIG_CPU_HAS_MASKREG_IRQ) += maskreg.o
diff --git a/arch/sh64/kernel/irq_intc.c b/arch/sh/kernel/cpu/irq/intc-sh5.c
index 3b63a93198f2..43ee7a9a4f0b 100644
--- a/arch/sh64/kernel/irq_intc.c
+++ b/arch/sh/kernel/cpu/irq/intc-sh5.c
@@ -1,34 +1,27 @@
1/* 1/*
2 * This file is subject to the terms and conditions of the GNU General Public 2 * arch/sh/kernel/cpu/irq/intc-sh5.c
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 * 3 *
6 * arch/sh64/kernel/irq_intc.c 4 * Interrupt Controller support for SH5 INTC.
7 * 5 *
8 * Copyright (C) 2000, 2001 Paolo Alberelli 6 * Copyright (C) 2000, 2001 Paolo Alberelli
9 * Copyright (C) 2003 Paul Mundt 7 * Copyright (C) 2003 Paul Mundt
10 * 8 *
11 * Interrupt Controller support for SH5 INTC.
12 * Per-interrupt selective. IRLM=0 (Fixed priority) is not 9 * Per-interrupt selective. IRLM=0 (Fixed priority) is not
13 * supported being useless without a cascaded interrupt 10 * supported being useless without a cascaded interrupt
14 * controller. 11 * controller.
15 * 12 *
13 * This file is subject to the terms and conditions of the GNU General Public
14 * License. See the file "COPYING" in the main directory of this archive
15 * for more details.
16 */ 16 */
17
18#include <linux/init.h> 17#include <linux/init.h>
19#include <linux/interrupt.h> 18#include <linux/interrupt.h>
20#include <linux/irq.h> 19#include <linux/irq.h>
20#include <linux/io.h>
21#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/stddef.h> 22#include <linux/bitops.h>
23#include <linux/bitops.h> /* this includes also <asm/registers.h */ 23#include <asm/cpu/irq.h>
24 /* which is required to remap register */
25 /* names used into __asm__ blocks... */
26
27#include <asm/hardware.h>
28#include <asm/platform.h>
29#include <asm/page.h> 24#include <asm/page.h>
30#include <asm/io.h>
31#include <asm/irq.h>
32 25
33/* 26/*
34 * Maybe the generic Peripheral block could move to a more 27 * Maybe the generic Peripheral block could move to a more
@@ -192,7 +185,7 @@ int intc_irq_describe(char* p, int irq)
192} 185}
193#endif 186#endif
194 187
195void __init init_IRQ(void) 188void __init plat_irq_setup(void)
196{ 189{
197 unsigned long long __dummy0, __dummy1=~0x00000000100000f0; 190 unsigned long long __dummy0, __dummy1=~0x00000000100000f0;
198 unsigned long reg; 191 unsigned long reg;
@@ -251,14 +244,6 @@ void __init init_IRQ(void)
251 } 244 }
252 } 245 }
253 246
254#ifdef CONFIG_SH_CAYMAN
255 {
256 extern void init_cayman_irq(void);
257
258 init_cayman_irq();
259 }
260#endif
261
262 /* 247 /*
263 * And now let interrupts come in. 248 * And now let interrupts come in.
264 * sti() is not enough, we need to 249 * sti() is not enough, we need to
diff --git a/arch/sh/kernel/cpu/irq/intc.c b/arch/sh/kernel/cpu/irq/intc.c
index 6ac018c15e03..84806b2027f8 100644
--- a/arch/sh/kernel/cpu/irq/intc.c
+++ b/arch/sh/kernel/cpu/irq/intc.c
@@ -335,31 +335,6 @@ static intc_enum __init intc_grp_id(struct intc_desc *desc,
335 return 0; 335 return 0;
336} 336}
337 337
338static unsigned int __init intc_prio_value(struct intc_desc *desc,
339 intc_enum enum_id, int do_grps)
340{
341 struct intc_prio *p = desc->priorities;
342 unsigned int i;
343
344 for (i = 0; p && enum_id && i < desc->nr_priorities; i++) {
345 p = desc->priorities + i;
346
347 if (p->enum_id != enum_id)
348 continue;
349
350 return p->priority;
351 }
352
353 if (do_grps)
354 return intc_prio_value(desc, intc_grp_id(desc, enum_id), 0);
355
356 /* default to the lowest priority possible if no priority is set
357 * - this needs to be at least 2 for 5-bit priorities on 7780
358 */
359
360 return 2;
361}
362
363static unsigned int __init intc_mask_data(struct intc_desc *desc, 338static unsigned int __init intc_mask_data(struct intc_desc *desc,
364 struct intc_desc_int *d, 339 struct intc_desc_int *d,
365 intc_enum enum_id, int do_grps) 340 intc_enum enum_id, int do_grps)
@@ -518,8 +493,10 @@ static void __init intc_register_irq(struct intc_desc *desc,
518 handle_level_irq, "level"); 493 handle_level_irq, "level");
519 set_irq_chip_data(irq, (void *)data[primary]); 494 set_irq_chip_data(irq, (void *)data[primary]);
520 495
521 /* record the desired priority level */ 496 /* set priority level
522 intc_prio_level[irq] = intc_prio_value(desc, enum_id, 1); 497 * - this needs to be at least 2 for 5-bit priorities on 7780
498 */
499 intc_prio_level[irq] = 2;
523 500
524 /* enable secondary masking method if present */ 501 /* enable secondary masking method if present */
525 if (data[!primary]) 502 if (data[!primary])
diff --git a/arch/sh/kernel/cpu/sh2/entry.S b/arch/sh/kernel/cpu/sh2/entry.S
index ee8f1fe84b08..7a26569e7956 100644
--- a/arch/sh/kernel/cpu/sh2/entry.S
+++ b/arch/sh/kernel/cpu/sh2/entry.S
@@ -149,6 +149,14 @@ ENTRY(exception_handler)
149 mov #32,r8 149 mov #32,r8
150 cmp/hs r8,r9 150 cmp/hs r8,r9
151 bt trap_entry ! 64 > vec >= 32 is trap 151 bt trap_entry ! 64 > vec >= 32 is trap
152
153#if defined(CONFIG_SH_FPU)
154 mov #13,r8
155 cmp/eq r8,r9
156 bt 10f ! fpu
157 nop
158#endif
159
152 mov.l 4f,r8 160 mov.l 4f,r8
153 mov r9,r4 161 mov r9,r4
154 shll2 r9 162 shll2 r9
@@ -158,6 +166,10 @@ ENTRY(exception_handler)
158 cmp/eq r9,r8 166 cmp/eq r9,r8
159 bf 3f 167 bf 3f
160 mov.l 8f,r8 ! unhandled exception 168 mov.l 8f,r8 ! unhandled exception
169#if defined(CONFIG_SH_FPU)
17010:
171 mov.l 9f, r8 ! unhandled exception
172#endif
1613: 1733:
162 mov.l 5f,r10 174 mov.l 5f,r10
163 jmp @r8 175 jmp @r8
@@ -177,7 +189,10 @@ interrupt_entry:
1776: .long ret_from_irq 1896: .long ret_from_irq
1787: .long do_IRQ 1907: .long do_IRQ
1798: .long do_exception_error 1918: .long do_exception_error
180 192#ifdef CONFIG_SH_FPU
1939: .long fpu_error_trap_handler
194#endif
195
181trap_entry: 196trap_entry:
182 mov #0x30,r8 197 mov #0x30,r8
183 cmp/ge r8,r9 ! vector 0x20-0x2f is systemcall 198 cmp/ge r8,r9 ! vector 0x20-0x2f is systemcall
@@ -250,7 +265,7 @@ ENTRY(sh_bios_handler)
2501: .long gdb_vbr_vector 2651: .long gdb_vbr_vector
251#endif /* CONFIG_SH_STANDARD_BIOS */ 266#endif /* CONFIG_SH_STANDARD_BIOS */
252 267
253ENTRY(address_error_handler) 268ENTRY(address_error_trap_handler)
254 mov r15,r4 ! regs 269 mov r15,r4 ! regs
255 add #4,r4 270 add #4,r4
256 mov #OFF_PC,r0 271 mov #OFF_PC,r0
diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c
index ec6adc3f306f..b230eb278cef 100644
--- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c
+++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c
@@ -65,7 +65,7 @@ static struct intc_prio_reg prio_registers[] __initdata = {
65}; 65};
66 66
67static DECLARE_INTC_DESC(intc_desc, "sh7619", vectors, groups, 67static DECLARE_INTC_DESC(intc_desc, "sh7619", vectors, groups,
68 NULL, NULL, prio_registers, NULL); 68 NULL, prio_registers, NULL);
69 69
70static struct plat_sci_port sci_platform_data[] = { 70static struct plat_sci_port sci_platform_data[] = {
71 { 71 {
diff --git a/arch/sh/kernel/cpu/sh2a/Makefile b/arch/sh/kernel/cpu/sh2a/Makefile
index 965fa2572b23..b279cdc3a233 100644
--- a/arch/sh/kernel/cpu/sh2a/Makefile
+++ b/arch/sh/kernel/cpu/sh2a/Makefile
@@ -6,4 +6,8 @@ obj-y := common.o probe.o opcode_helper.o
6 6
7common-y += $(addprefix ../sh2/, ex.o entry.o) 7common-y += $(addprefix ../sh2/, ex.o entry.o)
8 8
9obj-$(CONFIG_SH_FPU) += fpu.o
10
9obj-$(CONFIG_CPU_SUBTYPE_SH7206) += setup-sh7206.o clock-sh7206.o 11obj-$(CONFIG_CPU_SUBTYPE_SH7206) += setup-sh7206.o clock-sh7206.o
12obj-$(CONFIG_CPU_SUBTYPE_SH7203) += setup-sh7203.o clock-sh7203.o
13obj-$(CONFIG_CPU_SUBTYPE_SH7263) += setup-sh7203.o clock-sh7203.o
diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7203.c b/arch/sh/kernel/cpu/sh2a/clock-sh7203.c
new file mode 100644
index 000000000000..3feb95a4fcbc
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh2a/clock-sh7203.c
@@ -0,0 +1,89 @@
1/*
2 * arch/sh/kernel/cpu/sh2a/clock-sh7203.c
3 *
4 * SH7203 support for the clock framework
5 *
6 * Copyright (C) 2007 Kieran Bingham (MPC-Data Ltd)
7 *
8 * Based on clock-sh7263.c
9 * Copyright (C) 2006 Yoshinori Sato
10 *
11 * Based on clock-sh4.c
12 * Copyright (C) 2005 Paul Mundt
13 *
14 * This file is subject to the terms and conditions of the GNU General Public
15 * License. See the file "COPYING" in the main directory of this archive
16 * for more details.
17 */
18#include <linux/init.h>
19#include <linux/kernel.h>
20#include <asm/clock.h>
21#include <asm/freq.h>
22#include <asm/io.h>
23
24const static int pll1rate[]={8,12,16,0};
25const static int pfc_divisors[]={1,2,3,4,6,8,12};
26#define ifc_divisors pfc_divisors
27
28#if (CONFIG_SH_CLK_MD == 0)
29#define PLL2 (1)
30#elif (CONFIG_SH_CLK_MD == 1)
31#define PLL2 (2)
32#elif (CONFIG_SH_CLK_MD == 2)
33#define PLL2 (4)
34#elif (CONFIG_SH_CLK_MD == 3)
35#define PLL2 (4)
36#else
37#error "Illegal Clock Mode!"
38#endif
39
40static void master_clk_init(struct clk *clk)
41{
42 clk->rate *= pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0003] * PLL2 ;
43}
44
45static struct clk_ops sh7203_master_clk_ops = {
46 .init = master_clk_init,
47};
48
49static void module_clk_recalc(struct clk *clk)
50{
51 int idx = (ctrl_inw(FREQCR) & 0x0007);
52 clk->rate = clk->parent->rate / pfc_divisors[idx];
53}
54
55static struct clk_ops sh7203_module_clk_ops = {
56 .recalc = module_clk_recalc,
57};
58
59static void bus_clk_recalc(struct clk *clk)
60{
61 int idx = (ctrl_inw(FREQCR) & 0x0007);
62 clk->rate = clk->parent->rate / pfc_divisors[idx-2];
63}
64
65static struct clk_ops sh7203_bus_clk_ops = {
66 .recalc = bus_clk_recalc,
67};
68
69static void cpu_clk_recalc(struct clk *clk)
70{
71 clk->rate = clk->parent->rate;
72}
73
74static struct clk_ops sh7203_cpu_clk_ops = {
75 .recalc = cpu_clk_recalc,
76};
77
78static struct clk_ops *sh7203_clk_ops[] = {
79 &sh7203_master_clk_ops,
80 &sh7203_module_clk_ops,
81 &sh7203_bus_clk_ops,
82 &sh7203_cpu_clk_ops,
83};
84
85void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
86{
87 if (idx < ARRAY_SIZE(sh7203_clk_ops))
88 *ops = sh7203_clk_ops[idx];
89}
diff --git a/arch/sh/kernel/cpu/sh2a/fpu.c b/arch/sh/kernel/cpu/sh2a/fpu.c
new file mode 100644
index 000000000000..ff99562456fb
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh2a/fpu.c
@@ -0,0 +1,633 @@
1/*
2 * Save/restore floating point context for signal handlers.
3 *
4 * Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * FIXME! These routines can be optimized in big endian case.
11 */
12#include <linux/sched.h>
13#include <linux/signal.h>
14#include <asm/processor.h>
15#include <asm/io.h>
16
17/* The PR (precision) bit in the FP Status Register must be clear when
18 * an frchg instruction is executed, otherwise the instruction is undefined.
19 * Executing frchg with PR set causes a trap on some SH4 implementations.
20 */
21
22#define FPSCR_RCHG 0x00000000
23
24
25/*
26 * Save FPU registers onto task structure.
27 * Assume called with FPU enabled (SR.FD=0).
28 */
29void
30save_fpu(struct task_struct *tsk, struct pt_regs *regs)
31{
32 unsigned long dummy;
33
34 clear_tsk_thread_flag(tsk, TIF_USEDFPU);
35 enable_fpu();
36 asm volatile("sts.l fpul, @-%0\n\t"
37 "sts.l fpscr, @-%0\n\t"
38 "fmov.s fr15, @-%0\n\t"
39 "fmov.s fr14, @-%0\n\t"
40 "fmov.s fr13, @-%0\n\t"
41 "fmov.s fr12, @-%0\n\t"
42 "fmov.s fr11, @-%0\n\t"
43 "fmov.s fr10, @-%0\n\t"
44 "fmov.s fr9, @-%0\n\t"
45 "fmov.s fr8, @-%0\n\t"
46 "fmov.s fr7, @-%0\n\t"
47 "fmov.s fr6, @-%0\n\t"
48 "fmov.s fr5, @-%0\n\t"
49 "fmov.s fr4, @-%0\n\t"
50 "fmov.s fr3, @-%0\n\t"
51 "fmov.s fr2, @-%0\n\t"
52 "fmov.s fr1, @-%0\n\t"
53 "fmov.s fr0, @-%0\n\t"
54 "lds %3, fpscr\n\t"
55 : "=r" (dummy)
56 : "0" ((char *)(&tsk->thread.fpu.hard.status)),
57 "r" (FPSCR_RCHG),
58 "r" (FPSCR_INIT)
59 : "memory");
60
61 disable_fpu();
62 release_fpu(regs);
63}
64
65static void
66restore_fpu(struct task_struct *tsk)
67{
68 unsigned long dummy;
69
70 enable_fpu();
71 asm volatile("fmov.s @%0+, fr0\n\t"
72 "fmov.s @%0+, fr1\n\t"
73 "fmov.s @%0+, fr2\n\t"
74 "fmov.s @%0+, fr3\n\t"
75 "fmov.s @%0+, fr4\n\t"
76 "fmov.s @%0+, fr5\n\t"
77 "fmov.s @%0+, fr6\n\t"
78 "fmov.s @%0+, fr7\n\t"
79 "fmov.s @%0+, fr8\n\t"
80 "fmov.s @%0+, fr9\n\t"
81 "fmov.s @%0+, fr10\n\t"
82 "fmov.s @%0+, fr11\n\t"
83 "fmov.s @%0+, fr12\n\t"
84 "fmov.s @%0+, fr13\n\t"
85 "fmov.s @%0+, fr14\n\t"
86 "fmov.s @%0+, fr15\n\t"
87 "lds.l @%0+, fpscr\n\t"
88 "lds.l @%0+, fpul\n\t"
89 : "=r" (dummy)
90 : "0" (&tsk->thread.fpu), "r" (FPSCR_RCHG)
91 : "memory");
92 disable_fpu();
93}
94
95/*
96 * Load the FPU with signalling NANS. This bit pattern we're using
97 * has the property that no matter wether considered as single or as
98 * double precission represents signaling NANS.
99 */
100
101static void
102fpu_init(void)
103{
104 enable_fpu();
105 asm volatile("lds %0, fpul\n\t"
106 "fsts fpul, fr0\n\t"
107 "fsts fpul, fr1\n\t"
108 "fsts fpul, fr2\n\t"
109 "fsts fpul, fr3\n\t"
110 "fsts fpul, fr4\n\t"
111 "fsts fpul, fr5\n\t"
112 "fsts fpul, fr6\n\t"
113 "fsts fpul, fr7\n\t"
114 "fsts fpul, fr8\n\t"
115 "fsts fpul, fr9\n\t"
116 "fsts fpul, fr10\n\t"
117 "fsts fpul, fr11\n\t"
118 "fsts fpul, fr12\n\t"
119 "fsts fpul, fr13\n\t"
120 "fsts fpul, fr14\n\t"
121 "fsts fpul, fr15\n\t"
122 "lds %2, fpscr\n\t"
123 : /* no output */
124 : "r" (0), "r" (FPSCR_RCHG), "r" (FPSCR_INIT));
125 disable_fpu();
126}
127
128/*
129 * Emulate arithmetic ops on denormalized number for some FPU insns.
130 */
131
132/* denormalized float * float */
133static int denormal_mulf(int hx, int hy)
134{
135 unsigned int ix, iy;
136 unsigned long long m, n;
137 int exp, w;
138
139 ix = hx & 0x7fffffff;
140 iy = hy & 0x7fffffff;
141 if (iy < 0x00800000 || ix == 0)
142 return ((hx ^ hy) & 0x80000000);
143
144 exp = (iy & 0x7f800000) >> 23;
145 ix &= 0x007fffff;
146 iy = (iy & 0x007fffff) | 0x00800000;
147 m = (unsigned long long)ix * iy;
148 n = m;
149 w = -1;
150 while (n) { n >>= 1; w++; }
151
152 /* FIXME: use guard bits */
153 exp += w - 126 - 46;
154 if (exp > 0)
155 ix = ((int) (m >> (w - 23)) & 0x007fffff) | (exp << 23);
156 else if (exp + 22 >= 0)
157 ix = (int) (m >> (w - 22 - exp)) & 0x007fffff;
158 else
159 ix = 0;
160
161 ix |= (hx ^ hy) & 0x80000000;
162 return ix;
163}
164
165/* denormalized double * double */
166static void mult64(unsigned long long x, unsigned long long y,
167 unsigned long long *highp, unsigned long long *lowp)
168{
169 unsigned long long sub0, sub1, sub2, sub3;
170 unsigned long long high, low;
171
172 sub0 = (x >> 32) * (unsigned long) (y >> 32);
173 sub1 = (x & 0xffffffffLL) * (unsigned long) (y >> 32);
174 sub2 = (x >> 32) * (unsigned long) (y & 0xffffffffLL);
175 sub3 = (x & 0xffffffffLL) * (unsigned long) (y & 0xffffffffLL);
176 low = sub3;
177 high = 0LL;
178 sub3 += (sub1 << 32);
179 if (low > sub3)
180 high++;
181 low = sub3;
182 sub3 += (sub2 << 32);
183 if (low > sub3)
184 high++;
185 low = sub3;
186 high += (sub1 >> 32) + (sub2 >> 32);
187 high += sub0;
188 *lowp = low;
189 *highp = high;
190}
191
192static inline long long rshift64(unsigned long long mh,
193 unsigned long long ml, int n)
194{
195 if (n >= 64)
196 return mh >> (n - 64);
197 return (mh << (64 - n)) | (ml >> n);
198}
199
200static long long denormal_muld(long long hx, long long hy)
201{
202 unsigned long long ix, iy;
203 unsigned long long mh, ml, nh, nl;
204 int exp, w;
205
206 ix = hx & 0x7fffffffffffffffLL;
207 iy = hy & 0x7fffffffffffffffLL;
208 if (iy < 0x0010000000000000LL || ix == 0)
209 return ((hx ^ hy) & 0x8000000000000000LL);
210
211 exp = (iy & 0x7ff0000000000000LL) >> 52;
212 ix &= 0x000fffffffffffffLL;
213 iy = (iy & 0x000fffffffffffffLL) | 0x0010000000000000LL;
214 mult64(ix, iy, &mh, &ml);
215 nh = mh;
216 nl = ml;
217 w = -1;
218 if (nh) {
219 while (nh) { nh >>= 1; w++;}
220 w += 64;
221 } else
222 while (nl) { nl >>= 1; w++;}
223
224 /* FIXME: use guard bits */
225 exp += w - 1022 - 52 * 2;
226 if (exp > 0)
227 ix = (rshift64(mh, ml, w - 52) & 0x000fffffffffffffLL)
228 | ((long long)exp << 52);
229 else if (exp + 51 >= 0)
230 ix = rshift64(mh, ml, w - 51 - exp) & 0x000fffffffffffffLL;
231 else
232 ix = 0;
233
234 ix |= (hx ^ hy) & 0x8000000000000000LL;
235 return ix;
236}
237
238/* ix - iy where iy: denormal and ix, iy >= 0 */
239static int denormal_subf1(unsigned int ix, unsigned int iy)
240{
241 int frac;
242 int exp;
243
244 if (ix < 0x00800000)
245 return ix - iy;
246
247 exp = (ix & 0x7f800000) >> 23;
248 if (exp - 1 > 31)
249 return ix;
250 iy >>= exp - 1;
251 if (iy == 0)
252 return ix;
253
254 frac = (ix & 0x007fffff) | 0x00800000;
255 frac -= iy;
256 while (frac < 0x00800000) {
257 if (--exp == 0)
258 return frac;
259 frac <<= 1;
260 }
261
262 return (exp << 23) | (frac & 0x007fffff);
263}
264
265/* ix + iy where iy: denormal and ix, iy >= 0 */
266static int denormal_addf1(unsigned int ix, unsigned int iy)
267{
268 int frac;
269 int exp;
270
271 if (ix < 0x00800000)
272 return ix + iy;
273
274 exp = (ix & 0x7f800000) >> 23;
275 if (exp - 1 > 31)
276 return ix;
277 iy >>= exp - 1;
278 if (iy == 0)
279 return ix;
280
281 frac = (ix & 0x007fffff) | 0x00800000;
282 frac += iy;
283 if (frac >= 0x01000000) {
284 frac >>= 1;
285 ++exp;
286 }
287
288 return (exp << 23) | (frac & 0x007fffff);
289}
290
291static int denormal_addf(int hx, int hy)
292{
293 unsigned int ix, iy;
294 int sign;
295
296 if ((hx ^ hy) & 0x80000000) {
297 sign = hx & 0x80000000;
298 ix = hx & 0x7fffffff;
299 iy = hy & 0x7fffffff;
300 if (iy < 0x00800000) {
301 ix = denormal_subf1(ix, iy);
302 if (ix < 0) {
303 ix = -ix;
304 sign ^= 0x80000000;
305 }
306 } else {
307 ix = denormal_subf1(iy, ix);
308 sign ^= 0x80000000;
309 }
310 } else {
311 sign = hx & 0x80000000;
312 ix = hx & 0x7fffffff;
313 iy = hy & 0x7fffffff;
314 if (iy < 0x00800000)
315 ix = denormal_addf1(ix, iy);
316 else
317 ix = denormal_addf1(iy, ix);
318 }
319
320 return sign | ix;
321}
322
323/* ix - iy where iy: denormal and ix, iy >= 0 */
324static long long denormal_subd1(unsigned long long ix, unsigned long long iy)
325{
326 long long frac;
327 int exp;
328
329 if (ix < 0x0010000000000000LL)
330 return ix - iy;
331
332 exp = (ix & 0x7ff0000000000000LL) >> 52;
333 if (exp - 1 > 63)
334 return ix;
335 iy >>= exp - 1;
336 if (iy == 0)
337 return ix;
338
339 frac = (ix & 0x000fffffffffffffLL) | 0x0010000000000000LL;
340 frac -= iy;
341 while (frac < 0x0010000000000000LL) {
342 if (--exp == 0)
343 return frac;
344 frac <<= 1;
345 }
346
347 return ((long long)exp << 52) | (frac & 0x000fffffffffffffLL);
348}
349
350/* ix + iy where iy: denormal and ix, iy >= 0 */
351static long long denormal_addd1(unsigned long long ix, unsigned long long iy)
352{
353 long long frac;
354 long long exp;
355
356 if (ix < 0x0010000000000000LL)
357 return ix + iy;
358
359 exp = (ix & 0x7ff0000000000000LL) >> 52;
360 if (exp - 1 > 63)
361 return ix;
362 iy >>= exp - 1;
363 if (iy == 0)
364 return ix;
365
366 frac = (ix & 0x000fffffffffffffLL) | 0x0010000000000000LL;
367 frac += iy;
368 if (frac >= 0x0020000000000000LL) {
369 frac >>= 1;
370 ++exp;
371 }
372
373 return (exp << 52) | (frac & 0x000fffffffffffffLL);
374}
375
376static long long denormal_addd(long long hx, long long hy)
377{
378 unsigned long long ix, iy;
379 long long sign;
380
381 if ((hx ^ hy) & 0x8000000000000000LL) {
382 sign = hx & 0x8000000000000000LL;
383 ix = hx & 0x7fffffffffffffffLL;
384 iy = hy & 0x7fffffffffffffffLL;
385 if (iy < 0x0010000000000000LL) {
386 ix = denormal_subd1(ix, iy);
387 if (ix < 0) {
388 ix = -ix;
389 sign ^= 0x8000000000000000LL;
390 }
391 } else {
392 ix = denormal_subd1(iy, ix);
393 sign ^= 0x8000000000000000LL;
394 }
395 } else {
396 sign = hx & 0x8000000000000000LL;
397 ix = hx & 0x7fffffffffffffffLL;
398 iy = hy & 0x7fffffffffffffffLL;
399 if (iy < 0x0010000000000000LL)
400 ix = denormal_addd1(ix, iy);
401 else
402 ix = denormal_addd1(iy, ix);
403 }
404
405 return sign | ix;
406}
407
408/**
409 * denormal_to_double - Given denormalized float number,
410 * store double float
411 *
412 * @fpu: Pointer to sh_fpu_hard structure
413 * @n: Index to FP register
414 */
415static void
416denormal_to_double (struct sh_fpu_hard_struct *fpu, int n)
417{
418 unsigned long du, dl;
419 unsigned long x = fpu->fpul;
420 int exp = 1023 - 126;
421
422 if (x != 0 && (x & 0x7f800000) == 0) {
423 du = (x & 0x80000000);
424 while ((x & 0x00800000) == 0) {
425 x <<= 1;
426 exp--;
427 }
428 x &= 0x007fffff;
429 du |= (exp << 20) | (x >> 3);
430 dl = x << 29;
431
432 fpu->fp_regs[n] = du;
433 fpu->fp_regs[n+1] = dl;
434 }
435}
436
437/**
438 * ieee_fpe_handler - Handle denormalized number exception
439 *
440 * @regs: Pointer to register structure
441 *
442 * Returns 1 when it's handled (should not cause exception).
443 */
444static int
445ieee_fpe_handler (struct pt_regs *regs)
446{
447 unsigned short insn = *(unsigned short *) regs->pc;
448 unsigned short finsn;
449 unsigned long nextpc;
450 int nib[4] = {
451 (insn >> 12) & 0xf,
452 (insn >> 8) & 0xf,
453 (insn >> 4) & 0xf,
454 insn & 0xf};
455
456 if (nib[0] == 0xb ||
457 (nib[0] == 0x4 && nib[2] == 0x0 && nib[3] == 0xb)) /* bsr & jsr */
458 regs->pr = regs->pc + 4;
459 if (nib[0] == 0xa || nib[0] == 0xb) { /* bra & bsr */
460 nextpc = regs->pc + 4 + ((short) ((insn & 0xfff) << 4) >> 3);
461 finsn = *(unsigned short *) (regs->pc + 2);
462 } else if (nib[0] == 0x8 && nib[1] == 0xd) { /* bt/s */
463 if (regs->sr & 1)
464 nextpc = regs->pc + 4 + ((char) (insn & 0xff) << 1);
465 else
466 nextpc = regs->pc + 4;
467 finsn = *(unsigned short *) (regs->pc + 2);
468 } else if (nib[0] == 0x8 && nib[1] == 0xf) { /* bf/s */
469 if (regs->sr & 1)
470 nextpc = regs->pc + 4;
471 else
472 nextpc = regs->pc + 4 + ((char) (insn & 0xff) << 1);
473 finsn = *(unsigned short *) (regs->pc + 2);
474 } else if (nib[0] == 0x4 && nib[3] == 0xb &&
475 (nib[2] == 0x0 || nib[2] == 0x2)) { /* jmp & jsr */
476 nextpc = regs->regs[nib[1]];
477 finsn = *(unsigned short *) (regs->pc + 2);
478 } else if (nib[0] == 0x0 && nib[3] == 0x3 &&
479 (nib[2] == 0x0 || nib[2] == 0x2)) { /* braf & bsrf */
480 nextpc = regs->pc + 4 + regs->regs[nib[1]];
481 finsn = *(unsigned short *) (regs->pc + 2);
482 } else if (insn == 0x000b) { /* rts */
483 nextpc = regs->pr;
484 finsn = *(unsigned short *) (regs->pc + 2);
485 } else {
486 nextpc = regs->pc + 2;
487 finsn = insn;
488 }
489
490#define FPSCR_FPU_ERROR (1 << 17)
491
492 if ((finsn & 0xf1ff) == 0xf0ad) { /* fcnvsd */
493 struct task_struct *tsk = current;
494
495 if ((tsk->thread.fpu.hard.fpscr & FPSCR_FPU_ERROR)) {
496 /* FPU error */
497 denormal_to_double (&tsk->thread.fpu.hard,
498 (finsn >> 8) & 0xf);
499 } else
500 return 0;
501
502 regs->pc = nextpc;
503 return 1;
504 } else if ((finsn & 0xf00f) == 0xf002) { /* fmul */
505 struct task_struct *tsk = current;
506 int fpscr;
507 int n, m, prec;
508 unsigned int hx, hy;
509
510 n = (finsn >> 8) & 0xf;
511 m = (finsn >> 4) & 0xf;
512 hx = tsk->thread.fpu.hard.fp_regs[n];
513 hy = tsk->thread.fpu.hard.fp_regs[m];
514 fpscr = tsk->thread.fpu.hard.fpscr;
515 prec = fpscr & (1 << 19);
516
517 if ((fpscr & FPSCR_FPU_ERROR)
518 && (prec && ((hx & 0x7fffffff) < 0x00100000
519 || (hy & 0x7fffffff) < 0x00100000))) {
520 long long llx, lly;
521
522 /* FPU error because of denormal */
523 llx = ((long long) hx << 32)
524 | tsk->thread.fpu.hard.fp_regs[n+1];
525 lly = ((long long) hy << 32)
526 | tsk->thread.fpu.hard.fp_regs[m+1];
527 if ((hx & 0x7fffffff) >= 0x00100000)
528 llx = denormal_muld(lly, llx);
529 else
530 llx = denormal_muld(llx, lly);
531 tsk->thread.fpu.hard.fp_regs[n] = llx >> 32;
532 tsk->thread.fpu.hard.fp_regs[n+1] = llx & 0xffffffff;
533 } else if ((fpscr & FPSCR_FPU_ERROR)
534 && (!prec && ((hx & 0x7fffffff) < 0x00800000
535 || (hy & 0x7fffffff) < 0x00800000))) {
536 /* FPU error because of denormal */
537 if ((hx & 0x7fffffff) >= 0x00800000)
538 hx = denormal_mulf(hy, hx);
539 else
540 hx = denormal_mulf(hx, hy);
541 tsk->thread.fpu.hard.fp_regs[n] = hx;
542 } else
543 return 0;
544
545 regs->pc = nextpc;
546 return 1;
547 } else if ((finsn & 0xf00e) == 0xf000) { /* fadd, fsub */
548 struct task_struct *tsk = current;
549 int fpscr;
550 int n, m, prec;
551 unsigned int hx, hy;
552
553 n = (finsn >> 8) & 0xf;
554 m = (finsn >> 4) & 0xf;
555 hx = tsk->thread.fpu.hard.fp_regs[n];
556 hy = tsk->thread.fpu.hard.fp_regs[m];
557 fpscr = tsk->thread.fpu.hard.fpscr;
558 prec = fpscr & (1 << 19);
559
560 if ((fpscr & FPSCR_FPU_ERROR)
561 && (prec && ((hx & 0x7fffffff) < 0x00100000
562 || (hy & 0x7fffffff) < 0x00100000))) {
563 long long llx, lly;
564
565 /* FPU error because of denormal */
566 llx = ((long long) hx << 32)
567 | tsk->thread.fpu.hard.fp_regs[n+1];
568 lly = ((long long) hy << 32)
569 | tsk->thread.fpu.hard.fp_regs[m+1];
570 if ((finsn & 0xf00f) == 0xf000)
571 llx = denormal_addd(llx, lly);
572 else
573 llx = denormal_addd(llx, lly ^ (1LL << 63));
574 tsk->thread.fpu.hard.fp_regs[n] = llx >> 32;
575 tsk->thread.fpu.hard.fp_regs[n+1] = llx & 0xffffffff;
576 } else if ((fpscr & FPSCR_FPU_ERROR)
577 && (!prec && ((hx & 0x7fffffff) < 0x00800000
578 || (hy & 0x7fffffff) < 0x00800000))) {
579 /* FPU error because of denormal */
580 if ((finsn & 0xf00f) == 0xf000)
581 hx = denormal_addf(hx, hy);
582 else
583 hx = denormal_addf(hx, hy ^ 0x80000000);
584 tsk->thread.fpu.hard.fp_regs[n] = hx;
585 } else
586 return 0;
587
588 regs->pc = nextpc;
589 return 1;
590 }
591
592 return 0;
593}
594
595BUILD_TRAP_HANDLER(fpu_error)
596{
597 struct task_struct *tsk = current;
598 TRAP_HANDLER_DECL;
599
600 save_fpu(tsk, regs);
601 if (ieee_fpe_handler(regs)) {
602 tsk->thread.fpu.hard.fpscr &=
603 ~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK);
604 grab_fpu(regs);
605 restore_fpu(tsk);
606 set_tsk_thread_flag(tsk, TIF_USEDFPU);
607 return;
608 }
609
610 force_sig(SIGFPE, tsk);
611}
612
613BUILD_TRAP_HANDLER(fpu_state_restore)
614{
615 struct task_struct *tsk = current;
616 TRAP_HANDLER_DECL;
617
618 grab_fpu(regs);
619 if (!user_mode(regs)) {
620 printk(KERN_ERR "BUG: FPU is used in kernel mode.\n");
621 return;
622 }
623
624 if (used_math()) {
625 /* Using the FPU again. */
626 restore_fpu(tsk);
627 } else {
628 /* First time FPU user. */
629 fpu_init();
630 set_used_math();
631 }
632 set_tsk_thread_flag(tsk, TIF_USEDFPU);
633}
diff --git a/arch/sh/kernel/cpu/sh2a/probe.c b/arch/sh/kernel/cpu/sh2a/probe.c
index 6d02465704b9..6910e2664468 100644
--- a/arch/sh/kernel/cpu/sh2a/probe.c
+++ b/arch/sh/kernel/cpu/sh2a/probe.c
@@ -3,25 +3,36 @@
3 * 3 *
4 * CPU Subtype Probing for SH-2A. 4 * CPU Subtype Probing for SH-2A.
5 * 5 *
6 * Copyright (C) 2004, 2005 Paul Mundt 6 * Copyright (C) 2004 - 2007 Paul Mundt
7 * 7 *
8 * This file is subject to the terms and conditions of the GNU General Public 8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive 9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details. 10 * for more details.
11 */ 11 */
12
13#include <linux/init.h> 12#include <linux/init.h>
14#include <asm/processor.h> 13#include <asm/processor.h>
15#include <asm/cache.h> 14#include <asm/cache.h>
16 15
17int __init detect_cpu_and_cache_system(void) 16int __init detect_cpu_and_cache_system(void)
18{ 17{
19 /* Just SH7206 for now .. */ 18 /* All SH-2A CPUs have support for 16 and 32-bit opcodes.. */
20 boot_cpu_data.type = CPU_SH7206;
21 boot_cpu_data.flags |= CPU_HAS_OP32; 19 boot_cpu_data.flags |= CPU_HAS_OP32;
22 20
21#if defined(CONFIG_CPU_SUBTYPE_SH7203)
22 boot_cpu_data.type = CPU_SH7203;
23 /* SH7203 has an FPU.. */
24 boot_cpu_data.flags |= CPU_HAS_FPU;
25#elif defined(CONFIG_CPU_SUBTYPE_SH7263)
26 boot_cpu_data.type = CPU_SH7263;
27 boot_cpu_data.flags |= CPU_HAS_FPU;
28#elif defined(CONFIG_CPU_SUBTYPE_SH7206)
29 boot_cpu_data.type = CPU_SH7206;
30 /* While SH7206 has a DSP.. */
31 boot_cpu_data.flags |= CPU_HAS_DSP;
32#endif
33
23 boot_cpu_data.dcache.ways = 4; 34 boot_cpu_data.dcache.ways = 4;
24 boot_cpu_data.dcache.way_incr = (1 << 11); 35 boot_cpu_data.dcache.way_incr = (1 << 11);
25 boot_cpu_data.dcache.sets = 128; 36 boot_cpu_data.dcache.sets = 128;
26 boot_cpu_data.dcache.entry_shift = 4; 37 boot_cpu_data.dcache.entry_shift = 4;
27 boot_cpu_data.dcache.linesz = L1_CACHE_BYTES; 38 boot_cpu_data.dcache.linesz = L1_CACHE_BYTES;
@@ -37,4 +48,3 @@ int __init detect_cpu_and_cache_system(void)
37 48
38 return 0; 49 return 0;
39} 50}
40
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
new file mode 100644
index 000000000000..db6ef5cecde1
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
@@ -0,0 +1,319 @@
1/*
2 * SH7203 and SH7263 Setup
3 *
4 * Copyright (C) 2007 Paul Mundt
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/platform_device.h>
11#include <linux/init.h>
12#include <linux/serial.h>
13#include <asm/sci.h>
14
15enum {
16 UNUSED = 0,
17
18 /* interrupt sources */
19 IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
20 PINT0, PINT1, PINT2, PINT3, PINT4, PINT5, PINT6, PINT7,
21 DMAC0_DEI, DMAC0_HEI, DMAC1_DEI, DMAC1_HEI,
22 DMAC2_DEI, DMAC2_HEI, DMAC3_DEI, DMAC3_HEI,
23 DMAC4_DEI, DMAC4_HEI, DMAC5_DEI, DMAC5_HEI,
24 DMAC6_DEI, DMAC6_HEI, DMAC7_DEI, DMAC7_HEI,
25 USB, LCDC, CMT0, CMT1, BSC, WDT,
26 MTU2_TGI0A, MTU2_TGI0B, MTU2_TGI0C, MTU2_TGI0D,
27 MTU2_TCI0V, MTU2_TGI0E, MTU2_TGI0F,
28 MTU2_TGI1A, MTU2_TGI1B, MTU2_TCI1V, MTU2_TCI1U,
29 MTU2_TGI2A, MTU2_TGI2B, MTU2_TCI2V, MTU2_TCI2U,
30 MTU2_TGI3A, MTU2_TGI3B, MTU2_TGI3C, MTU2_TGI3D, MTU2_TCI3V,
31 MTU2_TGI4A, MTU2_TGI4B, MTU2_TGI4C, MTU2_TGI4D, MTU2_TCI4V,
32 ADC_ADI,
33 IIC30_STPI, IIC30_NAKI, IIC30_RXI, IIC30_TXI, IIC30_TEI,
34 IIC31_STPI, IIC31_NAKI, IIC31_RXI, IIC31_TXI, IIC31_TEI,
35 IIC32_STPI, IIC32_NAKI, IIC32_RXI, IIC32_TXI, IIC32_TEI,
36 IIC33_STPI, IIC33_NAKI, IIC33_RXI, IIC33_TXI, IIC33_TEI,
37 SCIF0_BRI, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI,
38 SCIF1_BRI, SCIF1_ERI, SCIF1_RXI, SCIF1_TXI,
39 SCIF2_BRI, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI,
40 SCIF3_BRI, SCIF3_ERI, SCIF3_RXI, SCIF3_TXI,
41 SSU0_SSERI, SSU0_SSRXI, SSU0_SSTXI,
42 SSU1_SSERI, SSU1_SSRXI, SSU1_SSTXI,
43 SSI0_SSII, SSI1_SSII, SSI2_SSII, SSI3_SSII,
44
45 /* ROM-DEC, SDHI, SRC, and IEB are SH7263 specific */
46 ROMDEC_ISY, ROMDEC_IERR, ROMDEC_IARG, ROMDEC_ISEC, ROMDEC_IBUF,
47 ROMDEC_IREADY,
48
49 FLCTL_FLSTEI, FLCTL_FLTENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I,
50
51 SDHI3, SDHI0, SDHI1,
52
53 RTC_ARM, RTC_PRD, RTC_CUP,
54 RCAN0_ERS, RCAN0_OVR, RCAN0_RM0, RCAN0_RM1, RCAN0_SLE,
55 RCAN1_ERS, RCAN1_OVR, RCAN1_RM0, RCAN1_RM1, RCAN1_SLE,
56
57 SRC_OVF, SRC_ODFI, SRC_IDEI, IEBI,
58
59 /* interrupt groups */
60 PINT, DMAC0, DMAC1, DMAC2, DMAC3, DMAC4, DMAC5, DMAC6, DMAC7,
61 MTU0_ABCD, MTU0_VEF, MTU1_AB, MTU1_VU, MTU2_AB, MTU2_VU,
62 MTU3_ABCD, MTU4_ABCD,
63 IIC30, IIC31, IIC32, IIC33, SCIF0, SCIF1, SCIF2, SCIF3,
64 SSU0, SSU1, ROMDEC, SDHI, FLCTL, RTC, RCAN0, RCAN1, SRC
65};
66
67static struct intc_vect vectors[] __initdata = {
68 INTC_IRQ(IRQ0, 64), INTC_IRQ(IRQ1, 65),
69 INTC_IRQ(IRQ2, 66), INTC_IRQ(IRQ3, 67),
70 INTC_IRQ(IRQ4, 68), INTC_IRQ(IRQ5, 69),
71 INTC_IRQ(IRQ6, 70), INTC_IRQ(IRQ7, 71),
72 INTC_IRQ(PINT0, 80), INTC_IRQ(PINT1, 81),
73 INTC_IRQ(PINT2, 82), INTC_IRQ(PINT3, 83),
74 INTC_IRQ(PINT4, 84), INTC_IRQ(PINT5, 85),
75 INTC_IRQ(PINT6, 86), INTC_IRQ(PINT7, 87),
76 INTC_IRQ(DMAC0_DEI, 108), INTC_IRQ(DMAC0_HEI, 109),
77 INTC_IRQ(DMAC1_DEI, 112), INTC_IRQ(DMAC1_HEI, 113),
78 INTC_IRQ(DMAC2_DEI, 116), INTC_IRQ(DMAC2_HEI, 117),
79 INTC_IRQ(DMAC3_DEI, 120), INTC_IRQ(DMAC3_HEI, 121),
80 INTC_IRQ(DMAC4_DEI, 124), INTC_IRQ(DMAC4_HEI, 125),
81 INTC_IRQ(DMAC5_DEI, 128), INTC_IRQ(DMAC5_HEI, 129),
82 INTC_IRQ(DMAC6_DEI, 132), INTC_IRQ(DMAC6_HEI, 133),
83 INTC_IRQ(DMAC7_DEI, 136), INTC_IRQ(DMAC7_HEI, 137),
84 INTC_IRQ(USB, 140), INTC_IRQ(LCDC, 141),
85 INTC_IRQ(CMT0, 142), INTC_IRQ(CMT1, 143),
86 INTC_IRQ(BSC, 144), INTC_IRQ(WDT, 145),
87 INTC_IRQ(MTU2_TGI0A, 146), INTC_IRQ(MTU2_TGI0B, 147),
88 INTC_IRQ(MTU2_TGI0C, 148), INTC_IRQ(MTU2_TGI0D, 149),
89 INTC_IRQ(MTU2_TCI0V, 150),
90 INTC_IRQ(MTU2_TGI0E, 151), INTC_IRQ(MTU2_TGI0F, 152),
91 INTC_IRQ(MTU2_TGI1A, 153), INTC_IRQ(MTU2_TGI1B, 154),
92 INTC_IRQ(MTU2_TCI1V, 155), INTC_IRQ(MTU2_TCI1U, 156),
93 INTC_IRQ(MTU2_TGI2A, 157), INTC_IRQ(MTU2_TGI2B, 158),
94 INTC_IRQ(MTU2_TCI2V, 159), INTC_IRQ(MTU2_TCI2U, 160),
95 INTC_IRQ(MTU2_TGI3A, 161), INTC_IRQ(MTU2_TGI3B, 162),
96 INTC_IRQ(MTU2_TGI3C, 163), INTC_IRQ(MTU2_TGI3D, 164),
97 INTC_IRQ(MTU2_TCI3V, 165),
98 INTC_IRQ(MTU2_TGI4A, 166), INTC_IRQ(MTU2_TGI4B, 167),
99 INTC_IRQ(MTU2_TGI4C, 168), INTC_IRQ(MTU2_TGI4D, 169),
100 INTC_IRQ(MTU2_TCI4V, 170),
101 INTC_IRQ(ADC_ADI, 171),
102 INTC_IRQ(IIC30_STPI, 172), INTC_IRQ(IIC30_NAKI, 173),
103 INTC_IRQ(IIC30_RXI, 174), INTC_IRQ(IIC30_TXI, 175),
104 INTC_IRQ(IIC30_TEI, 176),
105 INTC_IRQ(IIC31_STPI, 177), INTC_IRQ(IIC31_NAKI, 178),
106 INTC_IRQ(IIC31_RXI, 179), INTC_IRQ(IIC31_TXI, 180),
107 INTC_IRQ(IIC31_TEI, 181),
108 INTC_IRQ(IIC32_STPI, 182), INTC_IRQ(IIC32_NAKI, 183),
109 INTC_IRQ(IIC32_RXI, 184), INTC_IRQ(IIC32_TXI, 185),
110 INTC_IRQ(IIC32_TEI, 186),
111 INTC_IRQ(IIC33_STPI, 187), INTC_IRQ(IIC33_NAKI, 188),
112 INTC_IRQ(IIC33_RXI, 189), INTC_IRQ(IIC33_TXI, 190),
113 INTC_IRQ(IIC33_TEI, 191),
114 INTC_IRQ(SCIF0_BRI, 192), INTC_IRQ(SCIF0_ERI, 193),
115 INTC_IRQ(SCIF0_RXI, 194), INTC_IRQ(SCIF0_TXI, 195),
116 INTC_IRQ(SCIF1_BRI, 196), INTC_IRQ(SCIF1_ERI, 197),
117 INTC_IRQ(SCIF1_RXI, 198), INTC_IRQ(SCIF1_TXI, 199),
118 INTC_IRQ(SCIF2_BRI, 200), INTC_IRQ(SCIF2_ERI, 201),
119 INTC_IRQ(SCIF2_RXI, 202), INTC_IRQ(SCIF2_TXI, 203),
120 INTC_IRQ(SCIF3_BRI, 204), INTC_IRQ(SCIF3_ERI, 205),
121 INTC_IRQ(SCIF3_RXI, 206), INTC_IRQ(SCIF3_TXI, 207),
122 INTC_IRQ(SSU0_SSERI, 208), INTC_IRQ(SSU0_SSRXI, 209),
123 INTC_IRQ(SSU0_SSTXI, 210),
124 INTC_IRQ(SSU1_SSERI, 211), INTC_IRQ(SSU1_SSRXI, 212),
125 INTC_IRQ(SSU1_SSTXI, 213),
126 INTC_IRQ(SSI0_SSII, 214), INTC_IRQ(SSI1_SSII, 215),
127 INTC_IRQ(SSI2_SSII, 216), INTC_IRQ(SSI3_SSII, 217),
128 INTC_IRQ(FLCTL_FLSTEI, 224), INTC_IRQ(FLCTL_FLTENDI, 225),
129 INTC_IRQ(FLCTL_FLTREQ0I, 226), INTC_IRQ(FLCTL_FLTREQ1I, 227),
130 INTC_IRQ(RTC_ARM, 231), INTC_IRQ(RTC_PRD, 232),
131 INTC_IRQ(RTC_CUP, 233),
132 INTC_IRQ(RCAN0_ERS, 234), INTC_IRQ(RCAN0_OVR, 235),
133 INTC_IRQ(RCAN0_RM0, 236), INTC_IRQ(RCAN0_RM1, 237),
134 INTC_IRQ(RCAN0_SLE, 238),
135 INTC_IRQ(RCAN1_ERS, 239), INTC_IRQ(RCAN1_OVR, 240),
136 INTC_IRQ(RCAN1_RM0, 241), INTC_IRQ(RCAN1_RM1, 242),
137 INTC_IRQ(RCAN1_SLE, 243),
138
139 /* SH7263-specific trash */
140#ifdef CONFIG_CPU_SUBTYPE_SH7263
141 INTC_IRQ(ROMDEC_ISY, 218), INTC_IRQ(ROMDEC_IERR, 219),
142 INTC_IRQ(ROMDEC_IARG, 220), INTC_IRQ(ROMDEC_ISEC, 221),
143 INTC_IRQ(ROMDEC_IBUF, 222), INTC_IRQ(ROMDEC_IREADY, 223),
144
145 INTC_IRQ(SDHI3, 228), INTC_IRQ(SDHI0, 229), INTC_IRQ(SDHI1, 230),
146
147 INTC_IRQ(SRC_OVF, 244), INTC_IRQ(SRC_ODFI, 245),
148 INTC_IRQ(SRC_IDEI, 246),
149
150 INTC_IRQ(IEBI, 247),
151#endif
152};
153
154static struct intc_group groups[] __initdata = {
155 INTC_GROUP(PINT, PINT0, PINT1, PINT2, PINT3,
156 PINT4, PINT5, PINT6, PINT7),
157 INTC_GROUP(DMAC0, DMAC0_DEI, DMAC0_HEI),
158 INTC_GROUP(DMAC1, DMAC1_DEI, DMAC1_HEI),
159 INTC_GROUP(DMAC2, DMAC2_DEI, DMAC2_HEI),
160 INTC_GROUP(DMAC3, DMAC3_DEI, DMAC3_HEI),
161 INTC_GROUP(DMAC4, DMAC4_DEI, DMAC4_HEI),
162 INTC_GROUP(DMAC5, DMAC5_DEI, DMAC5_HEI),
163 INTC_GROUP(DMAC6, DMAC6_DEI, DMAC6_HEI),
164 INTC_GROUP(DMAC7, DMAC7_DEI, DMAC7_HEI),
165 INTC_GROUP(MTU0_ABCD, MTU2_TGI0A, MTU2_TGI0B, MTU2_TGI0C, MTU2_TGI0D),
166 INTC_GROUP(MTU0_VEF, MTU2_TCI0V, MTU2_TGI0E, MTU2_TGI0F),
167 INTC_GROUP(MTU1_AB, MTU2_TGI1A, MTU2_TGI1B),
168 INTC_GROUP(MTU1_VU, MTU2_TCI1V, MTU2_TCI1U),
169 INTC_GROUP(MTU2_AB, MTU2_TGI2A, MTU2_TGI2B),
170 INTC_GROUP(MTU2_VU, MTU2_TCI2V, MTU2_TCI2U),
171 INTC_GROUP(MTU3_ABCD, MTU2_TGI3A, MTU2_TGI3B, MTU2_TGI3C, MTU2_TGI3D),
172 INTC_GROUP(MTU4_ABCD, MTU2_TGI4A, MTU2_TGI4B, MTU2_TGI4C, MTU2_TGI4D),
173 INTC_GROUP(IIC30, IIC30_STPI, IIC30_NAKI, IIC30_RXI, IIC30_TXI,
174 IIC30_TEI),
175 INTC_GROUP(IIC31, IIC31_STPI, IIC31_NAKI, IIC31_RXI, IIC31_TXI,
176 IIC31_TEI),
177 INTC_GROUP(IIC32, IIC32_STPI, IIC32_NAKI, IIC32_RXI, IIC32_TXI,
178 IIC32_TEI),
179 INTC_GROUP(IIC33, IIC33_STPI, IIC33_NAKI, IIC33_RXI, IIC33_TXI,
180 IIC33_TEI),
181 INTC_GROUP(SCIF0, SCIF0_BRI, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI),
182 INTC_GROUP(SCIF1, SCIF1_BRI, SCIF1_ERI, SCIF1_RXI, SCIF1_TXI),
183 INTC_GROUP(SCIF2, SCIF2_BRI, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI),
184 INTC_GROUP(SCIF3, SCIF3_BRI, SCIF3_ERI, SCIF3_RXI, SCIF3_TXI),
185 INTC_GROUP(SSU0, SSU0_SSERI, SSU0_SSRXI, SSU0_SSTXI),
186 INTC_GROUP(SSU1, SSU1_SSERI, SSU1_SSRXI, SSU1_SSTXI),
187 INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLTENDI, FLCTL_FLTREQ0I,
188 FLCTL_FLTREQ1I),
189 INTC_GROUP(RTC, RTC_ARM, RTC_PRD, RTC_CUP),
190 INTC_GROUP(RCAN0, RCAN0_ERS, RCAN0_OVR, RCAN0_RM0, RCAN0_RM1,
191 RCAN0_SLE),
192 INTC_GROUP(RCAN1, RCAN1_ERS, RCAN1_OVR, RCAN1_RM0, RCAN1_RM1,
193 RCAN1_SLE),
194
195#ifdef CONFIG_CPU_SUBTYPE_SH7263
196 INTC_GROUP(ROMDEC, ROMDEC_ISY, ROMDEC_IERR, ROMDEC_IARG,
197 ROMDEC_ISEC, ROMDEC_IBUF, ROMDEC_IREADY),
198 INTC_GROUP(SDHI, SDHI3, SDHI0, SDHI1),
199 INTC_GROUP(SRC, SRC_OVF, SRC_ODFI, SRC_IDEI),
200#endif
201};
202
203static struct intc_prio_reg prio_registers[] __initdata = {
204 { 0xfffe0818, 0, 16, 4, /* IPR01 */ { IRQ0, IRQ1, IRQ2, IRQ3 } },
205 { 0xfffe081a, 0, 16, 4, /* IPR02 */ { IRQ4, IRQ5, IRQ6, IRQ7 } },
206 { 0xfffe0820, 0, 16, 4, /* IPR05 */ { PINT, 0, 0, 0 } },
207 { 0xfffe0c00, 0, 16, 4, /* IPR06 */ { DMAC0, DMAC1, DMAC2, DMAC3 } },
208 { 0xfffe0c02, 0, 16, 4, /* IPR07 */ { DMAC4, DMAC5, DMAC6, DMAC7 } },
209 { 0xfffe0c04, 0, 16, 4, /* IPR08 */ { USB, LCDC, CMT0, CMT1 } },
210 { 0xfffe0c06, 0, 16, 4, /* IPR09 */ { BSC, WDT, MTU0_ABCD, MTU0_VEF } },
211 { 0xfffe0c08, 0, 16, 4, /* IPR10 */ { MTU1_AB, MTU1_VU, MTU2_AB,
212 MTU2_VU } },
213 { 0xfffe0c0a, 0, 16, 4, /* IPR11 */ { MTU3_ABCD, MTU2_TCI3V, MTU4_ABCD,
214 MTU2_TCI4V } },
215 { 0xfffe0c0c, 0, 16, 4, /* IPR12 */ { ADC_ADI, IIC30, IIC31, IIC32 } },
216 { 0xfffe0c0e, 0, 16, 4, /* IPR13 */ { IIC33, SCIF0, SCIF1, SCIF2 } },
217 { 0xfffe0c10, 0, 16, 4, /* IPR14 */ { SCIF3, SSU0, SSU1, SSI0_SSII } },
218#ifdef CONFIG_CPU_SUBTYPE_SH7203
219 { 0xfffe0c12, 0, 16, 4, /* IPR15 */ { SSI1_SSII, SSI2_SSII,
220 SSI3_SSII, 0 } },
221 { 0xfffe0c14, 0, 16, 4, /* IPR16 */ { FLCTL, 0, RTC, RCAN0 } },
222 { 0xfffe0c16, 0, 16, 4, /* IPR17 */ { RCAN1, 0, 0, 0 } },
223#else
224 { 0xfffe0c12, 0, 16, 4, /* IPR15 */ { SSI1_SSII, SSI2_SSII,
225 SSI3_SSII, ROMDEC } },
226 { 0xfffe0c14, 0, 16, 4, /* IPR16 */ { FLCTL, SDHI, RTC, RCAN0 } },
227 { 0xfffe0c16, 0, 16, 4, /* IPR17 */ { RCAN1, SRC, IEBI, 0 } },
228#endif
229};
230
231static struct intc_mask_reg mask_registers[] __initdata = {
232 { 0xfffe0808, 0, 16, /* PINTER */
233 { 0, 0, 0, 0, 0, 0, 0, 0,
234 PINT7, PINT6, PINT5, PINT4, PINT3, PINT2, PINT1, PINT0 } },
235};
236
237static DECLARE_INTC_DESC(intc_desc, "sh7203", vectors, groups,
238 mask_registers, prio_registers, NULL);
239
240static struct plat_sci_port sci_platform_data[] = {
241 {
242 .mapbase = 0xfffe8000,
243 .flags = UPF_BOOT_AUTOCONF,
244 .type = PORT_SCIF,
245 .irqs = { 193, 194, 195, 192 },
246 }, {
247 .mapbase = 0xfffe8800,
248 .flags = UPF_BOOT_AUTOCONF,
249 .type = PORT_SCIF,
250 .irqs = { 197, 198, 199, 196 },
251 }, {
252 .mapbase = 0xfffe9000,
253 .flags = UPF_BOOT_AUTOCONF,
254 .type = PORT_SCIF,
255 .irqs = { 201, 202, 203, 200 },
256 }, {
257 .mapbase = 0xfffe9800,
258 .flags = UPF_BOOT_AUTOCONF,
259 .type = PORT_SCIF,
260 .irqs = { 205, 206, 207, 204 },
261 }, {
262 .flags = 0,
263 }
264};
265
266static struct platform_device sci_device = {
267 .name = "sh-sci",
268 .id = -1,
269 .dev = {
270 .platform_data = sci_platform_data,
271 },
272};
273
274static struct resource rtc_resources[] = {
275 [0] = {
276 .start = 0xffff2000,
277 .end = 0xffff2000 + 0x58 - 1,
278 .flags = IORESOURCE_IO,
279 },
280 [1] = {
281 /* Period IRQ */
282 .start = 232,
283 .flags = IORESOURCE_IRQ,
284 },
285 [2] = {
286 /* Carry IRQ */
287 .start = 233,
288 .flags = IORESOURCE_IRQ,
289 },
290 [3] = {
291 /* Alarm IRQ */
292 .start = 231,
293 .flags = IORESOURCE_IRQ,
294 },
295};
296
297static struct platform_device rtc_device = {
298 .name = "sh-rtc",
299 .id = -1,
300 .num_resources = ARRAY_SIZE(rtc_resources),
301 .resource = rtc_resources,
302};
303
304static struct platform_device *sh7203_devices[] __initdata = {
305 &sci_device,
306 &rtc_device,
307};
308
309static int __init sh7203_devices_setup(void)
310{
311 return platform_add_devices(sh7203_devices,
312 ARRAY_SIZE(sh7203_devices));
313}
314__initcall(sh7203_devices_setup);
315
316void __init plat_irq_setup(void)
317{
318 register_intc_controller(&intc_desc);
319}
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
index bd745aa87222..a564425b905f 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
@@ -167,7 +167,7 @@ static struct intc_mask_reg mask_registers[] __initdata = {
167}; 167};
168 168
169static DECLARE_INTC_DESC(intc_desc, "sh7206", vectors, groups, 169static DECLARE_INTC_DESC(intc_desc, "sh7206", vectors, groups,
170 NULL, mask_registers, prio_registers, NULL); 170 mask_registers, prio_registers, NULL);
171 171
172static struct plat_sci_port sci_platform_data[] = { 172static struct plat_sci_port sci_platform_data[] = {
173 { 173 {
diff --git a/arch/sh/kernel/cpu/sh3/Makefile b/arch/sh/kernel/cpu/sh3/Makefile
index 646eb6933614..3ae4d9111f19 100644
--- a/arch/sh/kernel/cpu/sh3/Makefile
+++ b/arch/sh/kernel/cpu/sh3/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7709) += setup-sh770x.o
13obj-$(CONFIG_CPU_SUBTYPE_SH7710) += setup-sh7710.o 13obj-$(CONFIG_CPU_SUBTYPE_SH7710) += setup-sh7710.o
14obj-$(CONFIG_CPU_SUBTYPE_SH7712) += setup-sh7710.o 14obj-$(CONFIG_CPU_SUBTYPE_SH7712) += setup-sh7710.o
15obj-$(CONFIG_CPU_SUBTYPE_SH7720) += setup-sh7720.o 15obj-$(CONFIG_CPU_SUBTYPE_SH7720) += setup-sh7720.o
16obj-$(CONFIG_CPU_SUBTYPE_SH7721) += setup-sh7720.o
16 17
17# Primary on-chip clocks (common) 18# Primary on-chip clocks (common)
18clock-$(CONFIG_CPU_SH3) := clock-sh3.o 19clock-$(CONFIG_CPU_SH3) := clock-sh3.o
@@ -21,5 +22,6 @@ clock-$(CONFIG_CPU_SUBTYPE_SH7706) := clock-sh7706.o
21clock-$(CONFIG_CPU_SUBTYPE_SH7709) := clock-sh7709.o 22clock-$(CONFIG_CPU_SUBTYPE_SH7709) := clock-sh7709.o
22clock-$(CONFIG_CPU_SUBTYPE_SH7710) := clock-sh7710.o 23clock-$(CONFIG_CPU_SUBTYPE_SH7710) := clock-sh7710.o
23clock-$(CONFIG_CPU_SUBTYPE_SH7720) := clock-sh7710.o 24clock-$(CONFIG_CPU_SUBTYPE_SH7720) := clock-sh7710.o
25clock-$(CONFIG_CPU_SUBTYPE_SH7712) := clock-sh7712.o
24 26
25obj-y += $(clock-y) 27obj-y += $(clock-y)
diff --git a/arch/sh/kernel/cpu/sh3/clock-sh7712.c b/arch/sh/kernel/cpu/sh3/clock-sh7712.c
new file mode 100644
index 000000000000..54f54df51ef0
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh3/clock-sh7712.c
@@ -0,0 +1,71 @@
1/*
2 * arch/sh/kernel/cpu/sh3/clock-sh7712.c
3 *
4 * SH7712 support for the clock framework
5 *
6 * Copyright (C) 2007 Andrew Murray <amurray@mpc-data.co.uk>
7 *
8 * Based on arch/sh/kernel/cpu/sh3/clock-sh3.c
9 * Copyright (C) 2005 Paul Mundt
10 *
11 * This file is subject to the terms and conditions of the GNU General Public
12 * License. See the file "COPYING" in the main directory of this archive
13 * for more details.
14 */
15#include <linux/init.h>
16#include <linux/kernel.h>
17#include <asm/clock.h>
18#include <asm/freq.h>
19#include <asm/io.h>
20
21static int multipliers[] = { 1, 2, 3 };
22static int divisors[] = { 1, 2, 3, 4, 6 };
23
24static void master_clk_init(struct clk *clk)
25{
26 int frqcr = ctrl_inw(FRQCR);
27 int idx = (frqcr & 0x0300) >> 8;
28
29 clk->rate *= multipliers[idx];
30}
31
32static struct clk_ops sh7712_master_clk_ops = {
33 .init = master_clk_init,
34};
35
36static void module_clk_recalc(struct clk *clk)
37{
38 int frqcr = ctrl_inw(FRQCR);
39 int idx = frqcr & 0x0007;
40
41 clk->rate = clk->parent->rate / divisors[idx];
42}
43
44static struct clk_ops sh7712_module_clk_ops = {
45 .recalc = module_clk_recalc,
46};
47
48static void cpu_clk_recalc(struct clk *clk)
49{
50 int frqcr = ctrl_inw(FRQCR);
51 int idx = (frqcr & 0x0030) >> 4;
52
53 clk->rate = clk->parent->rate / divisors[idx];
54}
55
56static struct clk_ops sh7712_cpu_clk_ops = {
57 .recalc = cpu_clk_recalc,
58};
59
60static struct clk_ops *sh7712_clk_ops[] = {
61 &sh7712_master_clk_ops,
62 &sh7712_module_clk_ops,
63 &sh7712_cpu_clk_ops,
64};
65
66void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
67{
68 if (idx < ARRAY_SIZE(sh7712_clk_ops))
69 *ops = sh7712_clk_ops[idx];
70}
71
diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S
index 0d12a124055c..4004073f98cd 100644
--- a/arch/sh/kernel/cpu/sh3/entry.S
+++ b/arch/sh/kernel/cpu/sh3/entry.S
@@ -13,8 +13,9 @@
13#include <linux/linkage.h> 13#include <linux/linkage.h>
14#include <asm/asm-offsets.h> 14#include <asm/asm-offsets.h>
15#include <asm/thread_info.h> 15#include <asm/thread_info.h>
16#include <asm/cpu/mmu_context.h>
17#include <asm/unistd.h> 16#include <asm/unistd.h>
17#include <asm/cpu/mmu_context.h>
18#include <asm/page.h>
18 19
19! NOTE: 20! NOTE:
20! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address 21! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address
@@ -409,6 +410,27 @@ ENTRY(handle_exception)
409 ! Using k0, k1 for scratch registers (r0_bank1, r1_bank), 410 ! Using k0, k1 for scratch registers (r0_bank1, r1_bank),
410 ! save all registers onto stack. 411 ! save all registers onto stack.
411 ! 412 !
413
414#ifdef CONFIG_GUSA
415 ! Check for roll back gRB (User and Kernel)
416 mov r15, k0
417 shll k0
418 bf/s 1f
419 shll k0
420 bf/s 1f
421 stc spc, k1
422 stc r0_bank, k0
423 cmp/hs k0, k1 ! test k1 (saved PC) >= k0 (saved r0)
424 bt/s 2f
425 stc r1_bank, k1
426
427 add #-2, k0
428 add r15, k0
429 ldc k0, spc ! PC = saved r0 + r15 - 2
4302: mov k1, r15 ! SP = r1
4311:
432#endif
433
412 stc ssr, k0 ! Is it from kernel space? 434 stc ssr, k0 ! Is it from kernel space?
413 shll k0 ! Check MD bit (bit30) by shifting it into... 435 shll k0 ! Check MD bit (bit30) by shifting it into...
414 shll k0 ! ...the T bit 436 shll k0 ! ...the T bit
diff --git a/arch/sh/kernel/cpu/sh3/ex.S b/arch/sh/kernel/cpu/sh3/ex.S
index b6abf38d3a8d..11b6d9c6edae 100644
--- a/arch/sh/kernel/cpu/sh3/ex.S
+++ b/arch/sh/kernel/cpu/sh3/ex.S
@@ -36,7 +36,7 @@ ENTRY(exception_handling_table)
36 .long exception_error ! address error store /* 100 */ 36 .long exception_error ! address error store /* 100 */
37#endif 37#endif
38#if defined(CONFIG_SH_FPU) 38#if defined(CONFIG_SH_FPU)
39 .long do_fpu_error /* 120 */ 39 .long fpu_error_trap_handler /* 120 */
40#else 40#else
41 .long exception_error /* 120 */ 41 .long exception_error /* 120 */
42#endif 42#endif
diff --git a/arch/sh/kernel/cpu/sh3/probe.c b/arch/sh/kernel/cpu/sh3/probe.c
index bf579e061e09..fcc80bb7bee7 100644
--- a/arch/sh/kernel/cpu/sh3/probe.c
+++ b/arch/sh/kernel/cpu/sh3/probe.c
@@ -16,11 +16,11 @@
16#include <asm/cache.h> 16#include <asm/cache.h>
17#include <asm/io.h> 17#include <asm/io.h>
18 18
19int __init detect_cpu_and_cache_system(void) 19int __uses_jump_to_uncached detect_cpu_and_cache_system(void)
20{ 20{
21 unsigned long addr0, addr1, data0, data1, data2, data3; 21 unsigned long addr0, addr1, data0, data1, data2, data3;
22 22
23 jump_to_P2(); 23 jump_to_uncached();
24 /* 24 /*
25 * Check if the entry shadows or not. 25 * Check if the entry shadows or not.
26 * When shadowed, it's 128-entry system. 26 * When shadowed, it's 128-entry system.
@@ -48,7 +48,7 @@ int __init detect_cpu_and_cache_system(void)
48 ctrl_outl(data0&~SH_CACHE_VALID, addr0); 48 ctrl_outl(data0&~SH_CACHE_VALID, addr0);
49 ctrl_outl(data2&~SH_CACHE_VALID, addr1); 49 ctrl_outl(data2&~SH_CACHE_VALID, addr1);
50 50
51 back_to_P1(); 51 back_to_cached();
52 52
53 boot_cpu_data.dcache.ways = 4; 53 boot_cpu_data.dcache.ways = 4;
54 boot_cpu_data.dcache.entry_shift = 4; 54 boot_cpu_data.dcache.entry_shift = 4;
@@ -84,6 +84,9 @@ int __init detect_cpu_and_cache_system(void)
84#if defined(CONFIG_CPU_SUBTYPE_SH7720) 84#if defined(CONFIG_CPU_SUBTYPE_SH7720)
85 boot_cpu_data.type = CPU_SH7720; 85 boot_cpu_data.type = CPU_SH7720;
86#endif 86#endif
87#if defined(CONFIG_CPU_SUBTYPE_SH7721)
88 boot_cpu_data.type = CPU_SH7721;
89#endif
87#if defined(CONFIG_CPU_SUBTYPE_SH7705) 90#if defined(CONFIG_CPU_SUBTYPE_SH7705)
88 boot_cpu_data.type = CPU_SH7705; 91 boot_cpu_data.type = CPU_SH7705;
89 92
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c
index f6c65f2659e9..dd0a20a685f7 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c
@@ -66,12 +66,6 @@ static struct intc_group groups[] __initdata = {
66 INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI), 66 INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI),
67}; 67};
68 68
69static struct intc_prio priorities[] __initdata = {
70 INTC_PRIO(DMAC, 7),
71 INTC_PRIO(SCIF2, 3),
72 INTC_PRIO(SCIF0, 3),
73};
74
75static struct intc_prio_reg prio_registers[] __initdata = { 69static struct intc_prio_reg prio_registers[] __initdata = {
76 { 0xfffffee2, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } }, 70 { 0xfffffee2, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } },
77 { 0xfffffee4, 0, 16, 4, /* IPRB */ { WDT, REF_RCMI, 0, 0 } }, 71 { 0xfffffee4, 0, 16, 4, /* IPRB */ { WDT, REF_RCMI, 0, 0 } },
@@ -85,7 +79,7 @@ static struct intc_prio_reg prio_registers[] __initdata = {
85}; 79};
86 80
87static DECLARE_INTC_DESC(intc_desc, "sh7705", vectors, groups, 81static DECLARE_INTC_DESC(intc_desc, "sh7705", vectors, groups,
88 priorities, NULL, prio_registers, NULL); 82 NULL, prio_registers, NULL);
89 83
90static struct intc_vect vectors_irq[] __initdata = { 84static struct intc_vect vectors_irq[] __initdata = {
91 INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620), 85 INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620),
@@ -93,7 +87,7 @@ static struct intc_vect vectors_irq[] __initdata = {
93}; 87};
94 88
95static DECLARE_INTC_DESC(intc_desc_irq, "sh7705-irq", vectors_irq, NULL, 89static DECLARE_INTC_DESC(intc_desc_irq, "sh7705-irq", vectors_irq, NULL,
96 priorities, NULL, prio_registers, NULL); 90 NULL, prio_registers, NULL);
97 91
98static struct plat_sci_port sci_platform_data[] = { 92static struct plat_sci_port sci_platform_data[] = {
99 { 93 {
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c
index 60b04b1f9453..969804bb523b 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c
@@ -81,13 +81,6 @@ static struct intc_group groups[] __initdata = {
81 INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI), 81 INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI),
82}; 82};
83 83
84static struct intc_prio priorities[] __initdata = {
85 INTC_PRIO(DMAC, 7),
86 INTC_PRIO(SCI, 3),
87 INTC_PRIO(SCIF2, 3),
88 INTC_PRIO(SCIF0, 3),
89};
90
91static struct intc_prio_reg prio_registers[] __initdata = { 84static struct intc_prio_reg prio_registers[] __initdata = {
92 { 0xfffffee2, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } }, 85 { 0xfffffee2, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } },
93 { 0xfffffee4, 0, 16, 4, /* IPRB */ { WDT, REF, SCI, 0 } }, 86 { 0xfffffee4, 0, 16, 4, /* IPRB */ { WDT, REF, SCI, 0 } },
@@ -109,7 +102,7 @@ static struct intc_prio_reg prio_registers[] __initdata = {
109}; 102};
110 103
111static DECLARE_INTC_DESC(intc_desc, "sh770x", vectors, groups, 104static DECLARE_INTC_DESC(intc_desc, "sh770x", vectors, groups,
112 priorities, NULL, prio_registers, NULL); 105 NULL, prio_registers, NULL);
113 106
114#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \ 107#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \
115 defined(CONFIG_CPU_SUBTYPE_SH7707) || \ 108 defined(CONFIG_CPU_SUBTYPE_SH7707) || \
@@ -120,7 +113,7 @@ static struct intc_vect vectors_irq[] __initdata = {
120}; 113};
121 114
122static DECLARE_INTC_DESC(intc_desc_irq, "sh770x-irq", vectors_irq, NULL, 115static DECLARE_INTC_DESC(intc_desc_irq, "sh770x-irq", vectors_irq, NULL,
123 priorities, NULL, prio_registers, NULL); 116 NULL, prio_registers, NULL);
124#endif 117#endif
125 118
126static struct resource rtc_resources[] = { 119static struct resource rtc_resources[] = {
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c
index 84e5629fa841..0cc0e2bf135d 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c
@@ -73,18 +73,6 @@ static struct intc_group groups[] __initdata = {
73 INTC_GROUP(SIOF1, SIOF1_ERI, SIOF1_TXI, SIOF1_RXI, SIOF1_CCI), 73 INTC_GROUP(SIOF1, SIOF1_ERI, SIOF1_TXI, SIOF1_RXI, SIOF1_CCI),
74}; 74};
75 75
76static struct intc_prio priorities[] __initdata = {
77 INTC_PRIO(DMAC1, 7),
78 INTC_PRIO(DMAC2, 7),
79 INTC_PRIO(SCIF0, 3),
80 INTC_PRIO(SCIF1, 3),
81 INTC_PRIO(SIOF0, 3),
82 INTC_PRIO(SIOF1, 3),
83 INTC_PRIO(EDMAC0, 5),
84 INTC_PRIO(EDMAC1, 5),
85 INTC_PRIO(EDMAC2, 5),
86};
87
88static struct intc_prio_reg prio_registers[] __initdata = { 76static struct intc_prio_reg prio_registers[] __initdata = {
89 { 0xfffffee2, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } }, 77 { 0xfffffee2, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } },
90 { 0xfffffee4, 0, 16, 4, /* IPRB */ { WDT, REF, 0, 0 } }, 78 { 0xfffffee4, 0, 16, 4, /* IPRB */ { WDT, REF, 0, 0 } },
@@ -101,7 +89,7 @@ static struct intc_prio_reg prio_registers[] __initdata = {
101}; 89};
102 90
103static DECLARE_INTC_DESC(intc_desc, "sh7710", vectors, groups, 91static DECLARE_INTC_DESC(intc_desc, "sh7710", vectors, groups,
104 priorities, NULL, prio_registers, NULL); 92 NULL, prio_registers, NULL);
105 93
106static struct intc_vect vectors_irq[] __initdata = { 94static struct intc_vect vectors_irq[] __initdata = {
107 INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620), 95 INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620),
@@ -109,7 +97,7 @@ static struct intc_vect vectors_irq[] __initdata = {
109}; 97};
110 98
111static DECLARE_INTC_DESC(intc_desc_irq, "sh7710-irq", vectors_irq, NULL, 99static DECLARE_INTC_DESC(intc_desc_irq, "sh7710-irq", vectors_irq, NULL,
112 priorities, NULL, prio_registers, NULL); 100 NULL, prio_registers, NULL);
113 101
114static struct resource rtc_resources[] = { 102static struct resource rtc_resources[] = {
115 [0] = { 103 [0] = {
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c
index a0929b8a95ae..3855ea4c21c8 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c
@@ -85,9 +85,62 @@ static struct platform_device sci_device = {
85 }, 85 },
86}; 86};
87 87
88static struct resource usb_ohci_resources[] = {
89 [0] = {
90 .start = 0xA4428000,
91 .end = 0xA44280FF,
92 .flags = IORESOURCE_MEM,
93 },
94 [1] = {
95 .start = 67,
96 .end = 67,
97 .flags = IORESOURCE_IRQ,
98 },
99};
100
101static u64 usb_ohci_dma_mask = 0xffffffffUL;
102static struct platform_device usb_ohci_device = {
103 .name = "sh_ohci",
104 .id = -1,
105 .dev = {
106 .dma_mask = &usb_ohci_dma_mask,
107 .coherent_dma_mask = 0xffffffff,
108 },
109 .num_resources = ARRAY_SIZE(usb_ohci_resources),
110 .resource = usb_ohci_resources,
111};
112
113static struct resource usbf_resources[] = {
114 [0] = {
115 .name = "sh_udc",
116 .start = 0xA4420000,
117 .end = 0xA44200FF,
118 .flags = IORESOURCE_MEM,
119 },
120 [1] = {
121 .name = "sh_udc",
122 .start = 65,
123 .end = 65,
124 .flags = IORESOURCE_IRQ,
125 },
126};
127
128static struct platform_device usbf_device = {
129 .name = "sh_udc",
130 .id = -1,
131 .dev = {
132 .dma_mask = NULL,
133 .coherent_dma_mask = 0xffffffff,
134 },
135 .num_resources = ARRAY_SIZE(usbf_resources),
136 .resource = usbf_resources,
137};
138
88static struct platform_device *sh7720_devices[] __initdata = { 139static struct platform_device *sh7720_devices[] __initdata = {
89 &rtc_device, 140 &rtc_device,
90 &sci_device, 141 &sci_device,
142 &usb_ohci_device,
143 &usbf_device,
91}; 144};
92 145
93static int __init sh7720_devices_setup(void) 146static int __init sh7720_devices_setup(void)
@@ -127,8 +180,11 @@ static struct intc_vect vectors[] __initdata = {
127 INTC_VECT(USBF_SPD, 0x6e0), INTC_VECT(DMAC1_DEI0, 0x800), 180 INTC_VECT(USBF_SPD, 0x6e0), INTC_VECT(DMAC1_DEI0, 0x800),
128 INTC_VECT(DMAC1_DEI1, 0x820), INTC_VECT(DMAC1_DEI2, 0x840), 181 INTC_VECT(DMAC1_DEI1, 0x820), INTC_VECT(DMAC1_DEI2, 0x840),
129 INTC_VECT(DMAC1_DEI3, 0x860), INTC_VECT(LCDC, 0x900), 182 INTC_VECT(DMAC1_DEI3, 0x860), INTC_VECT(LCDC, 0x900),
130 INTC_VECT(SSL, 0x980), INTC_VECT(USBFI0, 0xa20), 183#if defined(CONFIG_CPU_SUBTYPE_SH7720)
131 INTC_VECT(USBFI1, 0xa40), INTC_VECT(USBHI, 0xa60), 184 INTC_VECT(SSL, 0x980),
185#endif
186 INTC_VECT(USBFI0, 0xa20), INTC_VECT(USBFI1, 0xa40),
187 INTC_VECT(USBHI, 0xa60),
132 INTC_VECT(DMAC2_DEI4, 0xb80), INTC_VECT(DMAC2_DEI5, 0xba0), 188 INTC_VECT(DMAC2_DEI4, 0xb80), INTC_VECT(DMAC2_DEI5, 0xba0),
133 INTC_VECT(ADC, 0xbe0), INTC_VECT(SCIF0, 0xc00), 189 INTC_VECT(ADC, 0xbe0), INTC_VECT(SCIF0, 0xc00),
134 INTC_VECT(SCIF1, 0xc20), INTC_VECT(PINT07, 0xc80), 190 INTC_VECT(SCIF1, 0xc20), INTC_VECT(PINT07, 0xc80),
@@ -153,22 +209,16 @@ static struct intc_group groups[] __initdata = {
153 INTC_GROUP(MMC, MMCI0, MMCI1, MMCI2, MMCI3), 209 INTC_GROUP(MMC, MMCI0, MMCI1, MMCI2, MMCI3),
154}; 210};
155 211
156static struct intc_prio priorities[] __initdata = {
157 INTC_PRIO(SCIF0, 2),
158 INTC_PRIO(SCIF1, 2),
159 INTC_PRIO(DMAC1, 1),
160 INTC_PRIO(DMAC2, 1),
161 INTC_PRIO(RTC, 2),
162 INTC_PRIO(TMU, 2),
163 INTC_PRIO(TPU, 2),
164};
165
166static struct intc_prio_reg prio_registers[] __initdata = { 212static struct intc_prio_reg prio_registers[] __initdata = {
167 { 0xA414FEE2UL, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } }, 213 { 0xA414FEE2UL, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } },
168 { 0xA414FEE4UL, 0, 16, 4, /* IPRB */ { WDT, REF_RCMI, SIM, 0 } }, 214 { 0xA414FEE4UL, 0, 16, 4, /* IPRB */ { WDT, REF_RCMI, SIM, 0 } },
169 { 0xA4140016UL, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } }, 215 { 0xA4140016UL, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } },
170 { 0xA4140018UL, 0, 16, 4, /* IPRD */ { USBF_SPD, TMU_SUNI, IRQ5, IRQ4 } }, 216 { 0xA4140018UL, 0, 16, 4, /* IPRD */ { USBF_SPD, TMU_SUNI, IRQ5, IRQ4 } },
217#if defined(CONFIG_CPU_SUBTYPE_SH7720)
171 { 0xA414001AUL, 0, 16, 4, /* IPRE */ { DMAC1, 0, LCDC, SSL } }, 218 { 0xA414001AUL, 0, 16, 4, /* IPRE */ { DMAC1, 0, LCDC, SSL } },
219#else
220 { 0xA414001AUL, 0, 16, 4, /* IPRE */ { DMAC1, 0, LCDC, 0 } },
221#endif
172 { 0xA4080000UL, 0, 16, 4, /* IPRF */ { ADC, DMAC2, USBFI, CMT } }, 222 { 0xA4080000UL, 0, 16, 4, /* IPRF */ { ADC, DMAC2, USBFI, CMT } },
173 { 0xA4080002UL, 0, 16, 4, /* IPRG */ { SCIF0, SCIF1, 0, 0 } }, 223 { 0xA4080002UL, 0, 16, 4, /* IPRG */ { SCIF0, SCIF1, 0, 0 } },
174 { 0xA4080004UL, 0, 16, 4, /* IPRH */ { PINT07, PINT815, TPU, IIC } }, 224 { 0xA4080004UL, 0, 16, 4, /* IPRH */ { PINT07, PINT815, TPU, IIC } },
@@ -177,7 +227,7 @@ static struct intc_prio_reg prio_registers[] __initdata = {
177}; 227};
178 228
179static DECLARE_INTC_DESC(intc_desc, "sh7720", vectors, groups, 229static DECLARE_INTC_DESC(intc_desc, "sh7720", vectors, groups,
180 priorities, NULL, prio_registers, NULL); 230 NULL, prio_registers, NULL);
181 231
182static struct intc_sense_reg sense_registers[] __initdata = { 232static struct intc_sense_reg sense_registers[] __initdata = {
183 { INTC_ICR1, 16, 2, { 0, 0, IRQ5, IRQ4, IRQ3, IRQ2, IRQ1, IRQ0 } }, 233 { INTC_ICR1, 16, 2, { 0, 0, IRQ5, IRQ4, IRQ3, IRQ2, IRQ1, IRQ0 } },
@@ -190,7 +240,7 @@ static struct intc_vect vectors_irq[] __initdata = {
190}; 240};
191 241
192static DECLARE_INTC_DESC(intc_irq_desc, "sh7720-irq", vectors_irq, 242static DECLARE_INTC_DESC(intc_irq_desc, "sh7720-irq", vectors_irq,
193 NULL, priorities, NULL, prio_registers, sense_registers); 243 NULL, NULL, prio_registers, sense_registers);
194 244
195void __init plat_irq_setup_pins(int mode) 245void __init plat_irq_setup_pins(int mode)
196{ 246{
diff --git a/arch/sh/kernel/cpu/sh4/Makefile b/arch/sh/kernel/cpu/sh4/Makefile
index dadd6bffc128..d608557c7a3f 100644
--- a/arch/sh/kernel/cpu/sh4/Makefile
+++ b/arch/sh/kernel/cpu/sh4/Makefile
@@ -5,7 +5,7 @@
5obj-y := probe.o common.o 5obj-y := probe.o common.o
6common-y += $(addprefix ../sh3/, entry.o ex.o) 6common-y += $(addprefix ../sh3/, entry.o ex.o)
7 7
8obj-$(CONFIG_SH_FPU) += fpu.o 8obj-$(CONFIG_SH_FPU) += fpu.o softfloat.o
9obj-$(CONFIG_SH_STORE_QUEUES) += sq.o 9obj-$(CONFIG_SH_STORE_QUEUES) += sq.o
10 10
11# CPU subtype setup 11# CPU subtype setup
diff --git a/arch/sh/kernel/cpu/sh4/fpu.c b/arch/sh/kernel/cpu/sh4/fpu.c
index c5a4fc77fa06..817f9939cda6 100644
--- a/arch/sh/kernel/cpu/sh4/fpu.c
+++ b/arch/sh/kernel/cpu/sh4/fpu.c
@@ -1,7 +1,4 @@
1/* $Id: fpu.c,v 1.4 2004/01/13 05:52:11 kkojima Exp $ 1/*
2 *
3 * linux/arch/sh/kernel/fpu.c
4 *
5 * Save/restore floating point context for signal handlers. 2 * Save/restore floating point context for signal handlers.
6 * 3 *
7 * This file is subject to the terms and conditions of the GNU General Public 4 * This file is subject to the terms and conditions of the GNU General Public
@@ -9,15 +6,16 @@
9 * for more details. 6 * for more details.
10 * 7 *
11 * Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka 8 * Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka
9 * Copyright (C) 2006 ST Microelectronics Ltd. (denorm support)
12 * 10 *
13 * FIXME! These routines can be optimized in big endian case. 11 * FIXME! These routines have not been tested for big endian case.
14 */ 12 */
15
16#include <linux/sched.h> 13#include <linux/sched.h>
17#include <linux/signal.h> 14#include <linux/signal.h>
15#include <linux/io.h>
16#include <asm/cpu/fpu.h>
18#include <asm/processor.h> 17#include <asm/processor.h>
19#include <asm/system.h> 18#include <asm/system.h>
20#include <asm/io.h>
21 19
22/* The PR (precision) bit in the FP Status Register must be clear when 20/* The PR (precision) bit in the FP Status Register must be clear when
23 * an frchg instruction is executed, otherwise the instruction is undefined. 21 * an frchg instruction is executed, otherwise the instruction is undefined.
@@ -25,177 +23,184 @@
25 */ 23 */
26 24
27#define FPSCR_RCHG 0x00000000 25#define FPSCR_RCHG 0x00000000
26extern unsigned long long float64_div(unsigned long long a,
27 unsigned long long b);
28extern unsigned long int float32_div(unsigned long int a, unsigned long int b);
29extern unsigned long long float64_mul(unsigned long long a,
30 unsigned long long b);
31extern unsigned long int float32_mul(unsigned long int a, unsigned long int b);
32extern unsigned long long float64_add(unsigned long long a,
33 unsigned long long b);
34extern unsigned long int float32_add(unsigned long int a, unsigned long int b);
35extern unsigned long long float64_sub(unsigned long long a,
36 unsigned long long b);
37extern unsigned long int float32_sub(unsigned long int a, unsigned long int b);
28 38
39static unsigned int fpu_exception_flags;
29 40
30/* 41/*
31 * Save FPU registers onto task structure. 42 * Save FPU registers onto task structure.
32 * Assume called with FPU enabled (SR.FD=0). 43 * Assume called with FPU enabled (SR.FD=0).
33 */ 44 */
34void 45void save_fpu(struct task_struct *tsk, struct pt_regs *regs)
35save_fpu(struct task_struct *tsk, struct pt_regs *regs)
36{ 46{
37 unsigned long dummy; 47 unsigned long dummy;
38 48
39 clear_tsk_thread_flag(tsk, TIF_USEDFPU); 49 clear_tsk_thread_flag(tsk, TIF_USEDFPU);
40 enable_fpu(); 50 enable_fpu();
41 asm volatile("sts.l fpul, @-%0\n\t" 51 asm volatile ("sts.l fpul, @-%0\n\t"
42 "sts.l fpscr, @-%0\n\t" 52 "sts.l fpscr, @-%0\n\t"
43 "lds %2, fpscr\n\t" 53 "lds %2, fpscr\n\t"
44 "frchg\n\t" 54 "frchg\n\t"
45 "fmov.s fr15, @-%0\n\t" 55 "fmov.s fr15, @-%0\n\t"
46 "fmov.s fr14, @-%0\n\t" 56 "fmov.s fr14, @-%0\n\t"
47 "fmov.s fr13, @-%0\n\t" 57 "fmov.s fr13, @-%0\n\t"
48 "fmov.s fr12, @-%0\n\t" 58 "fmov.s fr12, @-%0\n\t"
49 "fmov.s fr11, @-%0\n\t" 59 "fmov.s fr11, @-%0\n\t"
50 "fmov.s fr10, @-%0\n\t" 60 "fmov.s fr10, @-%0\n\t"
51 "fmov.s fr9, @-%0\n\t" 61 "fmov.s fr9, @-%0\n\t"
52 "fmov.s fr8, @-%0\n\t" 62 "fmov.s fr8, @-%0\n\t"
53 "fmov.s fr7, @-%0\n\t" 63 "fmov.s fr7, @-%0\n\t"
54 "fmov.s fr6, @-%0\n\t" 64 "fmov.s fr6, @-%0\n\t"
55 "fmov.s fr5, @-%0\n\t" 65 "fmov.s fr5, @-%0\n\t"
56 "fmov.s fr4, @-%0\n\t" 66 "fmov.s fr4, @-%0\n\t"
57 "fmov.s fr3, @-%0\n\t" 67 "fmov.s fr3, @-%0\n\t"
58 "fmov.s fr2, @-%0\n\t" 68 "fmov.s fr2, @-%0\n\t"
59 "fmov.s fr1, @-%0\n\t" 69 "fmov.s fr1, @-%0\n\t"
60 "fmov.s fr0, @-%0\n\t" 70 "fmov.s fr0, @-%0\n\t"
61 "frchg\n\t" 71 "frchg\n\t"
62 "fmov.s fr15, @-%0\n\t" 72 "fmov.s fr15, @-%0\n\t"
63 "fmov.s fr14, @-%0\n\t" 73 "fmov.s fr14, @-%0\n\t"
64 "fmov.s fr13, @-%0\n\t" 74 "fmov.s fr13, @-%0\n\t"
65 "fmov.s fr12, @-%0\n\t" 75 "fmov.s fr12, @-%0\n\t"
66 "fmov.s fr11, @-%0\n\t" 76 "fmov.s fr11, @-%0\n\t"
67 "fmov.s fr10, @-%0\n\t" 77 "fmov.s fr10, @-%0\n\t"
68 "fmov.s fr9, @-%0\n\t" 78 "fmov.s fr9, @-%0\n\t"
69 "fmov.s fr8, @-%0\n\t" 79 "fmov.s fr8, @-%0\n\t"
70 "fmov.s fr7, @-%0\n\t" 80 "fmov.s fr7, @-%0\n\t"
71 "fmov.s fr6, @-%0\n\t" 81 "fmov.s fr6, @-%0\n\t"
72 "fmov.s fr5, @-%0\n\t" 82 "fmov.s fr5, @-%0\n\t"
73 "fmov.s fr4, @-%0\n\t" 83 "fmov.s fr4, @-%0\n\t"
74 "fmov.s fr3, @-%0\n\t" 84 "fmov.s fr3, @-%0\n\t"
75 "fmov.s fr2, @-%0\n\t" 85 "fmov.s fr2, @-%0\n\t"
76 "fmov.s fr1, @-%0\n\t" 86 "fmov.s fr1, @-%0\n\t"
77 "fmov.s fr0, @-%0\n\t" 87 "fmov.s fr0, @-%0\n\t"
78 "lds %3, fpscr\n\t" 88 "lds %3, fpscr\n\t":"=r" (dummy)
79 : "=r" (dummy) 89 :"0"((char *)(&tsk->thread.fpu.hard.status)),
80 : "0" ((char *)(&tsk->thread.fpu.hard.status)), 90 "r"(FPSCR_RCHG), "r"(FPSCR_INIT)
81 "r" (FPSCR_RCHG), 91 :"memory");
82 "r" (FPSCR_INIT) 92
83 : "memory"); 93 disable_fpu();
84 94 release_fpu(regs);
85 disable_fpu();
86 release_fpu(regs);
87} 95}
88 96
89static void 97static void restore_fpu(struct task_struct *tsk)
90restore_fpu(struct task_struct *tsk)
91{ 98{
92 unsigned long dummy; 99 unsigned long dummy;
93 100
94 enable_fpu(); 101 enable_fpu();
95 asm volatile("lds %2, fpscr\n\t" 102 asm volatile ("lds %2, fpscr\n\t"
96 "fmov.s @%0+, fr0\n\t" 103 "fmov.s @%0+, fr0\n\t"
97 "fmov.s @%0+, fr1\n\t" 104 "fmov.s @%0+, fr1\n\t"
98 "fmov.s @%0+, fr2\n\t" 105 "fmov.s @%0+, fr2\n\t"
99 "fmov.s @%0+, fr3\n\t" 106 "fmov.s @%0+, fr3\n\t"
100 "fmov.s @%0+, fr4\n\t" 107 "fmov.s @%0+, fr4\n\t"
101 "fmov.s @%0+, fr5\n\t" 108 "fmov.s @%0+, fr5\n\t"
102 "fmov.s @%0+, fr6\n\t" 109 "fmov.s @%0+, fr6\n\t"
103 "fmov.s @%0+, fr7\n\t" 110 "fmov.s @%0+, fr7\n\t"
104 "fmov.s @%0+, fr8\n\t" 111 "fmov.s @%0+, fr8\n\t"
105 "fmov.s @%0+, fr9\n\t" 112 "fmov.s @%0+, fr9\n\t"
106 "fmov.s @%0+, fr10\n\t" 113 "fmov.s @%0+, fr10\n\t"
107 "fmov.s @%0+, fr11\n\t" 114 "fmov.s @%0+, fr11\n\t"
108 "fmov.s @%0+, fr12\n\t" 115 "fmov.s @%0+, fr12\n\t"
109 "fmov.s @%0+, fr13\n\t" 116 "fmov.s @%0+, fr13\n\t"
110 "fmov.s @%0+, fr14\n\t" 117 "fmov.s @%0+, fr14\n\t"
111 "fmov.s @%0+, fr15\n\t" 118 "fmov.s @%0+, fr15\n\t"
112 "frchg\n\t" 119 "frchg\n\t"
113 "fmov.s @%0+, fr0\n\t" 120 "fmov.s @%0+, fr0\n\t"
114 "fmov.s @%0+, fr1\n\t" 121 "fmov.s @%0+, fr1\n\t"
115 "fmov.s @%0+, fr2\n\t" 122 "fmov.s @%0+, fr2\n\t"
116 "fmov.s @%0+, fr3\n\t" 123 "fmov.s @%0+, fr3\n\t"
117 "fmov.s @%0+, fr4\n\t" 124 "fmov.s @%0+, fr4\n\t"
118 "fmov.s @%0+, fr5\n\t" 125 "fmov.s @%0+, fr5\n\t"
119 "fmov.s @%0+, fr6\n\t" 126 "fmov.s @%0+, fr6\n\t"
120 "fmov.s @%0+, fr7\n\t" 127 "fmov.s @%0+, fr7\n\t"
121 "fmov.s @%0+, fr8\n\t" 128 "fmov.s @%0+, fr8\n\t"
122 "fmov.s @%0+, fr9\n\t" 129 "fmov.s @%0+, fr9\n\t"
123 "fmov.s @%0+, fr10\n\t" 130 "fmov.s @%0+, fr10\n\t"
124 "fmov.s @%0+, fr11\n\t" 131 "fmov.s @%0+, fr11\n\t"
125 "fmov.s @%0+, fr12\n\t" 132 "fmov.s @%0+, fr12\n\t"
126 "fmov.s @%0+, fr13\n\t" 133 "fmov.s @%0+, fr13\n\t"
127 "fmov.s @%0+, fr14\n\t" 134 "fmov.s @%0+, fr14\n\t"
128 "fmov.s @%0+, fr15\n\t" 135 "fmov.s @%0+, fr15\n\t"
129 "frchg\n\t" 136 "frchg\n\t"
130 "lds.l @%0+, fpscr\n\t" 137 "lds.l @%0+, fpscr\n\t"
131 "lds.l @%0+, fpul\n\t" 138 "lds.l @%0+, fpul\n\t"
132 : "=r" (dummy) 139 :"=r" (dummy)
133 : "0" (&tsk->thread.fpu), "r" (FPSCR_RCHG) 140 :"0"(&tsk->thread.fpu), "r"(FPSCR_RCHG)
134 : "memory"); 141 :"memory");
135 disable_fpu(); 142 disable_fpu();
136} 143}
137 144
138/* 145/*
139 * Load the FPU with signalling NANS. This bit pattern we're using 146 * Load the FPU with signalling NANS. This bit pattern we're using
140 * has the property that no matter wether considered as single or as 147 * has the property that no matter wether considered as single or as
141 * double precision represents signaling NANS. 148 * double precision represents signaling NANS.
142 */ 149 */
143 150
144static void 151static void fpu_init(void)
145fpu_init(void)
146{ 152{
147 enable_fpu(); 153 enable_fpu();
148 asm volatile("lds %0, fpul\n\t" 154 asm volatile ( "lds %0, fpul\n\t"
149 "lds %1, fpscr\n\t" 155 "lds %1, fpscr\n\t"
150 "fsts fpul, fr0\n\t" 156 "fsts fpul, fr0\n\t"
151 "fsts fpul, fr1\n\t" 157 "fsts fpul, fr1\n\t"
152 "fsts fpul, fr2\n\t" 158 "fsts fpul, fr2\n\t"
153 "fsts fpul, fr3\n\t" 159 "fsts fpul, fr3\n\t"
154 "fsts fpul, fr4\n\t" 160 "fsts fpul, fr4\n\t"
155 "fsts fpul, fr5\n\t" 161 "fsts fpul, fr5\n\t"
156 "fsts fpul, fr6\n\t" 162 "fsts fpul, fr6\n\t"
157 "fsts fpul, fr7\n\t" 163 "fsts fpul, fr7\n\t"
158 "fsts fpul, fr8\n\t" 164 "fsts fpul, fr8\n\t"
159 "fsts fpul, fr9\n\t" 165 "fsts fpul, fr9\n\t"
160 "fsts fpul, fr10\n\t" 166 "fsts fpul, fr10\n\t"
161 "fsts fpul, fr11\n\t" 167 "fsts fpul, fr11\n\t"
162 "fsts fpul, fr12\n\t" 168 "fsts fpul, fr12\n\t"
163 "fsts fpul, fr13\n\t" 169 "fsts fpul, fr13\n\t"
164 "fsts fpul, fr14\n\t" 170 "fsts fpul, fr14\n\t"
165 "fsts fpul, fr15\n\t" 171 "fsts fpul, fr15\n\t"
166 "frchg\n\t" 172 "frchg\n\t"
167 "fsts fpul, fr0\n\t" 173 "fsts fpul, fr0\n\t"
168 "fsts fpul, fr1\n\t" 174 "fsts fpul, fr1\n\t"
169 "fsts fpul, fr2\n\t" 175 "fsts fpul, fr2\n\t"
170 "fsts fpul, fr3\n\t" 176 "fsts fpul, fr3\n\t"
171 "fsts fpul, fr4\n\t" 177 "fsts fpul, fr4\n\t"
172 "fsts fpul, fr5\n\t" 178 "fsts fpul, fr5\n\t"
173 "fsts fpul, fr6\n\t" 179 "fsts fpul, fr6\n\t"
174 "fsts fpul, fr7\n\t" 180 "fsts fpul, fr7\n\t"
175 "fsts fpul, fr8\n\t" 181 "fsts fpul, fr8\n\t"
176 "fsts fpul, fr9\n\t" 182 "fsts fpul, fr9\n\t"
177 "fsts fpul, fr10\n\t" 183 "fsts fpul, fr10\n\t"
178 "fsts fpul, fr11\n\t" 184 "fsts fpul, fr11\n\t"
179 "fsts fpul, fr12\n\t" 185 "fsts fpul, fr12\n\t"
180 "fsts fpul, fr13\n\t" 186 "fsts fpul, fr13\n\t"
181 "fsts fpul, fr14\n\t" 187 "fsts fpul, fr14\n\t"
182 "fsts fpul, fr15\n\t" 188 "fsts fpul, fr15\n\t"
183 "frchg\n\t" 189 "frchg\n\t"
184 "lds %2, fpscr\n\t" 190 "lds %2, fpscr\n\t"
185 : /* no output */ 191 : /* no output */
186 : "r" (0), "r" (FPSCR_RCHG), "r" (FPSCR_INIT)); 192 :"r" (0), "r"(FPSCR_RCHG), "r"(FPSCR_INIT));
187 disable_fpu(); 193 disable_fpu();
188} 194}
189 195
190/** 196/**
191 * denormal_to_double - Given denormalized float number, 197 * denormal_to_double - Given denormalized float number,
192 * store double float 198 * store double float
193 * 199 *
194 * @fpu: Pointer to sh_fpu_hard structure 200 * @fpu: Pointer to sh_fpu_hard structure
195 * @n: Index to FP register 201 * @n: Index to FP register
196 */ 202 */
197static void 203static void denormal_to_double(struct sh_fpu_hard_struct *fpu, int n)
198denormal_to_double (struct sh_fpu_hard_struct *fpu, int n)
199{ 204{
200 unsigned long du, dl; 205 unsigned long du, dl;
201 unsigned long x = fpu->fpul; 206 unsigned long x = fpu->fpul;
@@ -212,7 +217,7 @@ denormal_to_double (struct sh_fpu_hard_struct *fpu, int n)
212 dl = x << 29; 217 dl = x << 29;
213 218
214 fpu->fp_regs[n] = du; 219 fpu->fp_regs[n] = du;
215 fpu->fp_regs[n+1] = dl; 220 fpu->fp_regs[n + 1] = dl;
216 } 221 }
217} 222}
218 223
@@ -223,68 +228,191 @@ denormal_to_double (struct sh_fpu_hard_struct *fpu, int n)
223 * 228 *
224 * Returns 1 when it's handled (should not cause exception). 229 * Returns 1 when it's handled (should not cause exception).
225 */ 230 */
226static int 231static int ieee_fpe_handler(struct pt_regs *regs)
227ieee_fpe_handler (struct pt_regs *regs)
228{ 232{
229 unsigned short insn = *(unsigned short *) regs->pc; 233 unsigned short insn = *(unsigned short *)regs->pc;
230 unsigned short finsn; 234 unsigned short finsn;
231 unsigned long nextpc; 235 unsigned long nextpc;
232 int nib[4] = { 236 int nib[4] = {
233 (insn >> 12) & 0xf, 237 (insn >> 12) & 0xf,
234 (insn >> 8) & 0xf, 238 (insn >> 8) & 0xf,
235 (insn >> 4) & 0xf, 239 (insn >> 4) & 0xf,
236 insn & 0xf}; 240 insn & 0xf
237 241 };
238 if (nib[0] == 0xb || 242
239 (nib[0] == 0x4 && nib[2] == 0x0 && nib[3] == 0xb)) /* bsr & jsr */ 243 if (nib[0] == 0xb || (nib[0] == 0x4 && nib[2] == 0x0 && nib[3] == 0xb))
240 regs->pr = regs->pc + 4; 244 regs->pr = regs->pc + 4; /* bsr & jsr */
241 245
242 if (nib[0] == 0xa || nib[0] == 0xb) { /* bra & bsr */ 246 if (nib[0] == 0xa || nib[0] == 0xb) {
243 nextpc = regs->pc + 4 + ((short) ((insn & 0xfff) << 4) >> 3); 247 /* bra & bsr */
244 finsn = *(unsigned short *) (regs->pc + 2); 248 nextpc = regs->pc + 4 + ((short)((insn & 0xfff) << 4) >> 3);
245 } else if (nib[0] == 0x8 && nib[1] == 0xd) { /* bt/s */ 249 finsn = *(unsigned short *)(regs->pc + 2);
250 } else if (nib[0] == 0x8 && nib[1] == 0xd) {
251 /* bt/s */
246 if (regs->sr & 1) 252 if (regs->sr & 1)
247 nextpc = regs->pc + 4 + ((char) (insn & 0xff) << 1); 253 nextpc = regs->pc + 4 + ((char)(insn & 0xff) << 1);
248 else 254 else
249 nextpc = regs->pc + 4; 255 nextpc = regs->pc + 4;
250 finsn = *(unsigned short *) (regs->pc + 2); 256 finsn = *(unsigned short *)(regs->pc + 2);
251 } else if (nib[0] == 0x8 && nib[1] == 0xf) { /* bf/s */ 257 } else if (nib[0] == 0x8 && nib[1] == 0xf) {
258 /* bf/s */
252 if (regs->sr & 1) 259 if (regs->sr & 1)
253 nextpc = regs->pc + 4; 260 nextpc = regs->pc + 4;
254 else 261 else
255 nextpc = regs->pc + 4 + ((char) (insn & 0xff) << 1); 262 nextpc = regs->pc + 4 + ((char)(insn & 0xff) << 1);
256 finsn = *(unsigned short *) (regs->pc + 2); 263 finsn = *(unsigned short *)(regs->pc + 2);
257 } else if (nib[0] == 0x4 && nib[3] == 0xb && 264 } else if (nib[0] == 0x4 && nib[3] == 0xb &&
258 (nib[2] == 0x0 || nib[2] == 0x2)) { /* jmp & jsr */ 265 (nib[2] == 0x0 || nib[2] == 0x2)) {
266 /* jmp & jsr */
259 nextpc = regs->regs[nib[1]]; 267 nextpc = regs->regs[nib[1]];
260 finsn = *(unsigned short *) (regs->pc + 2); 268 finsn = *(unsigned short *)(regs->pc + 2);
261 } else if (nib[0] == 0x0 && nib[3] == 0x3 && 269 } else if (nib[0] == 0x0 && nib[3] == 0x3 &&
262 (nib[2] == 0x0 || nib[2] == 0x2)) { /* braf & bsrf */ 270 (nib[2] == 0x0 || nib[2] == 0x2)) {
271 /* braf & bsrf */
263 nextpc = regs->pc + 4 + regs->regs[nib[1]]; 272 nextpc = regs->pc + 4 + regs->regs[nib[1]];
264 finsn = *(unsigned short *) (regs->pc + 2); 273 finsn = *(unsigned short *)(regs->pc + 2);
265 } else if (insn == 0x000b) { /* rts */ 274 } else if (insn == 0x000b) {
275 /* rts */
266 nextpc = regs->pr; 276 nextpc = regs->pr;
267 finsn = *(unsigned short *) (regs->pc + 2); 277 finsn = *(unsigned short *)(regs->pc + 2);
268 } else { 278 } else {
269 nextpc = regs->pc + instruction_size(insn); 279 nextpc = regs->pc + instruction_size(insn);
270 finsn = insn; 280 finsn = insn;
271 } 281 }
272 282
273 if ((finsn & 0xf1ff) == 0xf0ad) { /* fcnvsd */ 283 if ((finsn & 0xf1ff) == 0xf0ad) {
284 /* fcnvsd */
274 struct task_struct *tsk = current; 285 struct task_struct *tsk = current;
275 286
276 save_fpu(tsk, regs); 287 save_fpu(tsk, regs);
277 if ((tsk->thread.fpu.hard.fpscr & (1 << 17))) { 288 if ((tsk->thread.fpu.hard.fpscr & FPSCR_CAUSE_ERROR))
278 /* FPU error */ 289 /* FPU error */
279 denormal_to_double (&tsk->thread.fpu.hard, 290 denormal_to_double(&tsk->thread.fpu.hard,
280 (finsn >> 8) & 0xf); 291 (finsn >> 8) & 0xf);
281 tsk->thread.fpu.hard.fpscr &= 292 else
282 ~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK); 293 return 0;
283 grab_fpu(regs); 294
284 restore_fpu(tsk); 295 regs->pc = nextpc;
285 set_tsk_thread_flag(tsk, TIF_USEDFPU); 296 return 1;
297 } else if ((finsn & 0xf00f) == 0xf002) {
298 /* fmul */
299 struct task_struct *tsk = current;
300 int fpscr;
301 int n, m, prec;
302 unsigned int hx, hy;
303
304 n = (finsn >> 8) & 0xf;
305 m = (finsn >> 4) & 0xf;
306 hx = tsk->thread.fpu.hard.fp_regs[n];
307 hy = tsk->thread.fpu.hard.fp_regs[m];
308 fpscr = tsk->thread.fpu.hard.fpscr;
309 prec = fpscr & FPSCR_DBL_PRECISION;
310
311 if ((fpscr & FPSCR_CAUSE_ERROR)
312 && (prec && ((hx & 0x7fffffff) < 0x00100000
313 || (hy & 0x7fffffff) < 0x00100000))) {
314 long long llx, lly;
315
316 /* FPU error because of denormal (doubles) */
317 llx = ((long long)hx << 32)
318 | tsk->thread.fpu.hard.fp_regs[n + 1];
319 lly = ((long long)hy << 32)
320 | tsk->thread.fpu.hard.fp_regs[m + 1];
321 llx = float64_mul(llx, lly);
322 tsk->thread.fpu.hard.fp_regs[n] = llx >> 32;
323 tsk->thread.fpu.hard.fp_regs[n + 1] = llx & 0xffffffff;
324 } else if ((fpscr & FPSCR_CAUSE_ERROR)
325 && (!prec && ((hx & 0x7fffffff) < 0x00800000
326 || (hy & 0x7fffffff) < 0x00800000))) {
327 /* FPU error because of denormal (floats) */
328 hx = float32_mul(hx, hy);
329 tsk->thread.fpu.hard.fp_regs[n] = hx;
330 } else
331 return 0;
332
333 regs->pc = nextpc;
334 return 1;
335 } else if ((finsn & 0xf00e) == 0xf000) {
336 /* fadd, fsub */
337 struct task_struct *tsk = current;
338 int fpscr;
339 int n, m, prec;
340 unsigned int hx, hy;
341
342 n = (finsn >> 8) & 0xf;
343 m = (finsn >> 4) & 0xf;
344 hx = tsk->thread.fpu.hard.fp_regs[n];
345 hy = tsk->thread.fpu.hard.fp_regs[m];
346 fpscr = tsk->thread.fpu.hard.fpscr;
347 prec = fpscr & FPSCR_DBL_PRECISION;
348
349 if ((fpscr & FPSCR_CAUSE_ERROR)
350 && (prec && ((hx & 0x7fffffff) < 0x00100000
351 || (hy & 0x7fffffff) < 0x00100000))) {
352 long long llx, lly;
353
354 /* FPU error because of denormal (doubles) */
355 llx = ((long long)hx << 32)
356 | tsk->thread.fpu.hard.fp_regs[n + 1];
357 lly = ((long long)hy << 32)
358 | tsk->thread.fpu.hard.fp_regs[m + 1];
359 if ((finsn & 0xf00f) == 0xf000)
360 llx = float64_add(llx, lly);
361 else
362 llx = float64_sub(llx, lly);
363 tsk->thread.fpu.hard.fp_regs[n] = llx >> 32;
364 tsk->thread.fpu.hard.fp_regs[n + 1] = llx & 0xffffffff;
365 } else if ((fpscr & FPSCR_CAUSE_ERROR)
366 && (!prec && ((hx & 0x7fffffff) < 0x00800000
367 || (hy & 0x7fffffff) < 0x00800000))) {
368 /* FPU error because of denormal (floats) */
369 if ((finsn & 0xf00f) == 0xf000)
370 hx = float32_add(hx, hy);
371 else
372 hx = float32_sub(hx, hy);
373 tsk->thread.fpu.hard.fp_regs[n] = hx;
374 } else
375 return 0;
376
377 regs->pc = nextpc;
378 return 1;
379 } else if ((finsn & 0xf003) == 0xf003) {
380 /* fdiv */
381 struct task_struct *tsk = current;
382 int fpscr;
383 int n, m, prec;
384 unsigned int hx, hy;
385
386 n = (finsn >> 8) & 0xf;
387 m = (finsn >> 4) & 0xf;
388 hx = tsk->thread.fpu.hard.fp_regs[n];
389 hy = tsk->thread.fpu.hard.fp_regs[m];
390 fpscr = tsk->thread.fpu.hard.fpscr;
391 prec = fpscr & FPSCR_DBL_PRECISION;
392
393 if ((fpscr & FPSCR_CAUSE_ERROR)
394 && (prec && ((hx & 0x7fffffff) < 0x00100000
395 || (hy & 0x7fffffff) < 0x00100000))) {
396 long long llx, lly;
397
398 /* FPU error because of denormal (doubles) */
399 llx = ((long long)hx << 32)
400 | tsk->thread.fpu.hard.fp_regs[n + 1];
401 lly = ((long long)hy << 32)
402 | tsk->thread.fpu.hard.fp_regs[m + 1];
403
404 llx = float64_div(llx, lly);
405
406 tsk->thread.fpu.hard.fp_regs[n] = llx >> 32;
407 tsk->thread.fpu.hard.fp_regs[n + 1] = llx & 0xffffffff;
408 } else if ((fpscr & FPSCR_CAUSE_ERROR)
409 && (!prec && ((hx & 0x7fffffff) < 0x00800000
410 || (hy & 0x7fffffff) < 0x00800000))) {
411 /* FPU error because of denormal (floats) */
412 hx = float32_div(hx, hy);
413 tsk->thread.fpu.hard.fp_regs[n] = hx;
286 } else 414 } else
287 force_sig(SIGFPE, tsk); 415 return 0;
288 416
289 regs->pc = nextpc; 417 regs->pc = nextpc;
290 return 1; 418 return 1;
@@ -293,27 +421,48 @@ ieee_fpe_handler (struct pt_regs *regs)
293 return 0; 421 return 0;
294} 422}
295 423
296asmlinkage void 424void float_raise(unsigned int flags)
297do_fpu_error(unsigned long r4, unsigned long r5, unsigned long r6, 425{
298 unsigned long r7, struct pt_regs __regs) 426 fpu_exception_flags |= flags;
427}
428
429int float_rounding_mode(void)
299{ 430{
300 struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
301 struct task_struct *tsk = current; 431 struct task_struct *tsk = current;
432 int roundingMode = FPSCR_ROUNDING_MODE(tsk->thread.fpu.hard.fpscr);
433 return roundingMode;
434}
302 435
303 if (ieee_fpe_handler(regs)) 436BUILD_TRAP_HANDLER(fpu_error)
304 return; 437{
438 struct task_struct *tsk = current;
439 TRAP_HANDLER_DECL;
305 440
306 regs->pc += 2;
307 save_fpu(tsk, regs); 441 save_fpu(tsk, regs);
442 fpu_exception_flags = 0;
443 if (ieee_fpe_handler(regs)) {
444 tsk->thread.fpu.hard.fpscr &=
445 ~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK);
446 tsk->thread.fpu.hard.fpscr |= fpu_exception_flags;
447 /* Set the FPSCR flag as well as cause bits - simply
448 * replicate the cause */
449 tsk->thread.fpu.hard.fpscr |= (fpu_exception_flags >> 10);
450 grab_fpu(regs);
451 restore_fpu(tsk);
452 set_tsk_thread_flag(tsk, TIF_USEDFPU);
453 if ((((tsk->thread.fpu.hard.fpscr & FPSCR_ENABLE_MASK) >> 7) &
454 (fpu_exception_flags >> 2)) == 0) {
455 return;
456 }
457 }
458
308 force_sig(SIGFPE, tsk); 459 force_sig(SIGFPE, tsk);
309} 460}
310 461
311asmlinkage void 462BUILD_TRAP_HANDLER(fpu_state_restore)
312do_fpu_state_restore(unsigned long r4, unsigned long r5, unsigned long r6,
313 unsigned long r7, struct pt_regs __regs)
314{ 463{
315 struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
316 struct task_struct *tsk = current; 464 struct task_struct *tsk = current;
465 TRAP_HANDLER_DECL;
317 466
318 grab_fpu(regs); 467 grab_fpu(regs);
319 if (!user_mode(regs)) { 468 if (!user_mode(regs)) {
@@ -324,7 +473,7 @@ do_fpu_state_restore(unsigned long r4, unsigned long r5, unsigned long r6,
324 if (used_math()) { 473 if (used_math()) {
325 /* Using the FPU again. */ 474 /* Using the FPU again. */
326 restore_fpu(tsk); 475 restore_fpu(tsk);
327 } else { 476 } else {
328 /* First time FPU user. */ 477 /* First time FPU user. */
329 fpu_init(); 478 fpu_init();
330 set_used_math(); 479 set_used_math();
diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c
index bc9c28a69bf1..f2b9238cda04 100644
--- a/arch/sh/kernel/cpu/sh4/probe.c
+++ b/arch/sh/kernel/cpu/sh4/probe.c
@@ -98,6 +98,8 @@ int __init detect_cpu_and_cache_system(void)
98 case 0x200A: 98 case 0x200A:
99 if (prr == 0x61) 99 if (prr == 0x61)
100 boot_cpu_data.type = CPU_SH7781; 100 boot_cpu_data.type = CPU_SH7781;
101 else if (prr == 0xa1)
102 boot_cpu_data.type = CPU_SH7763;
101 else 103 else
102 boot_cpu_data.type = CPU_SH7780; 104 boot_cpu_data.type = CPU_SH7780;
103 105
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c
index 523f68a9ce0e..ae3603aca615 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c
@@ -126,12 +126,6 @@ static struct intc_group groups[] __initdata = {
126 INTC_GROUP(REF, REF_RCMI, REF_ROVI), 126 INTC_GROUP(REF, REF_RCMI, REF_ROVI),
127}; 127};
128 128
129static struct intc_prio priorities[] __initdata = {
130 INTC_PRIO(SCIF, 3),
131 INTC_PRIO(SCI1, 3),
132 INTC_PRIO(DMAC, 7),
133};
134
135static struct intc_prio_reg prio_registers[] __initdata = { 129static struct intc_prio_reg prio_registers[] __initdata = {
136 { 0xffd00004, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } }, 130 { 0xffd00004, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } },
137 { 0xffd00008, 0, 16, 4, /* IPRB */ { WDT, REF, SCI1, 0 } }, 131 { 0xffd00008, 0, 16, 4, /* IPRB */ { WDT, REF, SCI1, 0 } },
@@ -143,7 +137,7 @@ static struct intc_prio_reg prio_registers[] __initdata = {
143}; 137};
144 138
145static DECLARE_INTC_DESC(intc_desc, "sh7750", vectors, groups, 139static DECLARE_INTC_DESC(intc_desc, "sh7750", vectors, groups,
146 priorities, NULL, prio_registers, NULL); 140 NULL, prio_registers, NULL);
147 141
148/* SH7750, SH7750S, SH7751 and SH7091 all have 4-channel DMA controllers */ 142/* SH7750, SH7750S, SH7751 and SH7091 all have 4-channel DMA controllers */
149#if defined(CONFIG_CPU_SUBTYPE_SH7750) || \ 143#if defined(CONFIG_CPU_SUBTYPE_SH7750) || \
@@ -163,7 +157,7 @@ static struct intc_group groups_dma4[] __initdata = {
163 157
164static DECLARE_INTC_DESC(intc_desc_dma4, "sh7750_dma4", 158static DECLARE_INTC_DESC(intc_desc_dma4, "sh7750_dma4",
165 vectors_dma4, groups_dma4, 159 vectors_dma4, groups_dma4,
166 priorities, NULL, prio_registers, NULL); 160 NULL, prio_registers, NULL);
167#endif 161#endif
168 162
169/* SH7750R and SH7751R both have 8-channel DMA controllers */ 163/* SH7750R and SH7751R both have 8-channel DMA controllers */
@@ -184,7 +178,7 @@ static struct intc_group groups_dma8[] __initdata = {
184 178
185static DECLARE_INTC_DESC(intc_desc_dma8, "sh7750_dma8", 179static DECLARE_INTC_DESC(intc_desc_dma8, "sh7750_dma8",
186 vectors_dma8, groups_dma8, 180 vectors_dma8, groups_dma8,
187 priorities, NULL, prio_registers, NULL); 181 NULL, prio_registers, NULL);
188#endif 182#endif
189 183
190/* SH7750R, SH7751 and SH7751R all have two extra timer channels */ 184/* SH7750R, SH7751 and SH7751R all have two extra timer channels */
@@ -205,7 +199,7 @@ static struct intc_mask_reg mask_registers[] __initdata = {
205}; 199};
206 200
207static DECLARE_INTC_DESC(intc_desc_tmu34, "sh7750_tmu34", 201static DECLARE_INTC_DESC(intc_desc_tmu34, "sh7750_tmu34",
208 vectors_tmu34, NULL, priorities, 202 vectors_tmu34, NULL,
209 mask_registers, prio_registers, NULL); 203 mask_registers, prio_registers, NULL);
210#endif 204#endif
211 205
@@ -216,7 +210,7 @@ static struct intc_vect vectors_irlm[] __initdata = {
216}; 210};
217 211
218static DECLARE_INTC_DESC(intc_desc_irlm, "sh7750_irlm", vectors_irlm, NULL, 212static DECLARE_INTC_DESC(intc_desc_irlm, "sh7750_irlm", vectors_irlm, NULL,
219 priorities, NULL, prio_registers, NULL); 213 NULL, prio_registers, NULL);
220 214
221/* SH7751 and SH7751R both have PCI */ 215/* SH7751 and SH7751R both have PCI */
222#if defined(CONFIG_CPU_SUBTYPE_SH7751) || defined(CONFIG_CPU_SUBTYPE_SH7751R) 216#if defined(CONFIG_CPU_SUBTYPE_SH7751) || defined(CONFIG_CPU_SUBTYPE_SH7751R)
@@ -233,7 +227,7 @@ static struct intc_group groups_pci[] __initdata = {
233}; 227};
234 228
235static DECLARE_INTC_DESC(intc_desc_pci, "sh7750_pci", vectors_pci, groups_pci, 229static DECLARE_INTC_DESC(intc_desc_pci, "sh7750_pci", vectors_pci, groups_pci,
236 priorities, mask_registers, prio_registers, NULL); 230 mask_registers, prio_registers, NULL);
237#endif 231#endif
238 232
239#if defined(CONFIG_CPU_SUBTYPE_SH7750) || \ 233#if defined(CONFIG_CPU_SUBTYPE_SH7750) || \
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c
index 7a898cb1d940..85f81579b97e 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c
@@ -92,15 +92,6 @@ static struct intc_group groups[] __initdata = {
92 INTC_GROUP(REF, REF_RCMI, REF_ROVI), 92 INTC_GROUP(REF, REF_RCMI, REF_ROVI),
93}; 93};
94 94
95static struct intc_prio priorities[] __initdata = {
96 INTC_PRIO(SCIF0, 3),
97 INTC_PRIO(SCIF1, 3),
98 INTC_PRIO(SCIF2, 3),
99 INTC_PRIO(SIM, 3),
100 INTC_PRIO(DMAC, 7),
101 INTC_PRIO(DMABRG, 13),
102};
103
104static struct intc_mask_reg mask_registers[] __initdata = { 95static struct intc_mask_reg mask_registers[] __initdata = {
105 { 0xfe080040, 0xfe080060, 32, /* INTMSK00 / INTMSKCLR00 */ 96 { 0xfe080040, 0xfe080060, 32, /* INTMSK00 / INTMSKCLR00 */
106 { IRQ4, IRQ5, IRQ6, IRQ7, 0, 0, HCAN20, HCAN21, 97 { IRQ4, IRQ5, IRQ6, IRQ7, 0, 0, HCAN20, HCAN21,
@@ -132,7 +123,7 @@ static struct intc_prio_reg prio_registers[] __initdata = {
132}; 123};
133 124
134static DECLARE_INTC_DESC(intc_desc, "sh7760", vectors, groups, 125static DECLARE_INTC_DESC(intc_desc, "sh7760", vectors, groups,
135 priorities, mask_registers, prio_registers, NULL); 126 mask_registers, prio_registers, NULL);
136 127
137static struct intc_vect vectors_irq[] __initdata = { 128static struct intc_vect vectors_irq[] __initdata = {
138 INTC_VECT(IRL0, 0x240), INTC_VECT(IRL1, 0x2a0), 129 INTC_VECT(IRL0, 0x240), INTC_VECT(IRL1, 0x2a0),
@@ -140,7 +131,7 @@ static struct intc_vect vectors_irq[] __initdata = {
140}; 131};
141 132
142static DECLARE_INTC_DESC(intc_desc_irq, "sh7760-irq", vectors_irq, groups, 133static DECLARE_INTC_DESC(intc_desc_irq, "sh7760-irq", vectors_irq, groups,
143 priorities, mask_registers, prio_registers, NULL); 134 mask_registers, prio_registers, NULL);
144 135
145static struct plat_sci_port sci_platform_data[] = { 136static struct plat_sci_port sci_platform_data[] = {
146 { 137 {
diff --git a/arch/sh/kernel/cpu/sh4/softfloat.c b/arch/sh/kernel/cpu/sh4/softfloat.c
new file mode 100644
index 000000000000..7b2d337ee412
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4/softfloat.c
@@ -0,0 +1,892 @@
1/*
2 * Floating point emulation support for subnormalised numbers on SH4
3 * architecture This file is derived from the SoftFloat IEC/IEEE
4 * Floating-point Arithmetic Package, Release 2 the original license of
5 * which is reproduced below.
6 *
7 * ========================================================================
8 *
9 * This C source file is part of the SoftFloat IEC/IEEE Floating-point
10 * Arithmetic Package, Release 2.
11 *
12 * Written by John R. Hauser. This work was made possible in part by the
13 * International Computer Science Institute, located at Suite 600, 1947 Center
14 * Street, Berkeley, California 94704. Funding was partially provided by the
15 * National Science Foundation under grant MIP-9311980. The original version
16 * of this code was written as part of a project to build a fixed-point vector
17 * processor in collaboration with the University of California at Berkeley,
18 * overseen by Profs. Nelson Morgan and John Wawrzynek. More information
19 * is available through the web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
20 * arithmetic/softfloat.html'.
21 *
22 * THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
23 * has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
24 * TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
25 * PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
26 * AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
27 *
28 * Derivative works are acceptable, even for commercial purposes, so long as
29 * (1) they include prominent notice that the work is derivative, and (2) they
30 * include prominent notice akin to these three paragraphs for those parts of
31 * this code that are retained.
32 *
33 * ========================================================================
34 *
35 * SH4 modifications by Ismail Dhaoui <ismail.dhaoui@st.com>
36 * and Kamel Khelifi <kamel.khelifi@st.com>
37 */
38#include <linux/kernel.h>
39#include <asm/cpu/fpu.h>
40
41#define LIT64( a ) a##LL
42
43typedef char flag;
44typedef unsigned char uint8;
45typedef signed char int8;
46typedef int uint16;
47typedef int int16;
48typedef unsigned int uint32;
49typedef signed int int32;
50
51typedef unsigned long long int bits64;
52typedef signed long long int sbits64;
53
54typedef unsigned char bits8;
55typedef signed char sbits8;
56typedef unsigned short int bits16;
57typedef signed short int sbits16;
58typedef unsigned int bits32;
59typedef signed int sbits32;
60
61typedef unsigned long long int uint64;
62typedef signed long long int int64;
63
64typedef unsigned long int float32;
65typedef unsigned long long float64;
66
67extern void float_raise(unsigned int flags); /* in fpu.c */
68extern int float_rounding_mode(void); /* in fpu.c */
69
70inline bits64 extractFloat64Frac(float64 a);
71inline flag extractFloat64Sign(float64 a);
72inline int16 extractFloat64Exp(float64 a);
73inline int16 extractFloat32Exp(float32 a);
74inline flag extractFloat32Sign(float32 a);
75inline bits32 extractFloat32Frac(float32 a);
76inline float64 packFloat64(flag zSign, int16 zExp, bits64 zSig);
77inline void shift64RightJamming(bits64 a, int16 count, bits64 * zPtr);
78inline float32 packFloat32(flag zSign, int16 zExp, bits32 zSig);
79inline void shift32RightJamming(bits32 a, int16 count, bits32 * zPtr);
80float64 float64_sub(float64 a, float64 b);
81float32 float32_sub(float32 a, float32 b);
82float32 float32_add(float32 a, float32 b);
83float64 float64_add(float64 a, float64 b);
84float64 float64_div(float64 a, float64 b);
85float32 float32_div(float32 a, float32 b);
86float32 float32_mul(float32 a, float32 b);
87float64 float64_mul(float64 a, float64 b);
88inline void add128(bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr,
89 bits64 * z1Ptr);
90inline void sub128(bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr,
91 bits64 * z1Ptr);
92inline void mul64To128(bits64 a, bits64 b, bits64 * z0Ptr, bits64 * z1Ptr);
93
94static int8 countLeadingZeros32(bits32 a);
95static int8 countLeadingZeros64(bits64 a);
96static float64 normalizeRoundAndPackFloat64(flag zSign, int16 zExp,
97 bits64 zSig);
98static float64 subFloat64Sigs(float64 a, float64 b, flag zSign);
99static float64 addFloat64Sigs(float64 a, float64 b, flag zSign);
100static float32 roundAndPackFloat32(flag zSign, int16 zExp, bits32 zSig);
101static float32 normalizeRoundAndPackFloat32(flag zSign, int16 zExp,
102 bits32 zSig);
103static float64 roundAndPackFloat64(flag zSign, int16 zExp, bits64 zSig);
104static float32 subFloat32Sigs(float32 a, float32 b, flag zSign);
105static float32 addFloat32Sigs(float32 a, float32 b, flag zSign);
106static void normalizeFloat64Subnormal(bits64 aSig, int16 * zExpPtr,
107 bits64 * zSigPtr);
108static bits64 estimateDiv128To64(bits64 a0, bits64 a1, bits64 b);
109static void normalizeFloat32Subnormal(bits32 aSig, int16 * zExpPtr,
110 bits32 * zSigPtr);
111
112inline bits64 extractFloat64Frac(float64 a)
113{
114 return a & LIT64(0x000FFFFFFFFFFFFF);
115}
116
117inline flag extractFloat64Sign(float64 a)
118{
119 return a >> 63;
120}
121
122inline int16 extractFloat64Exp(float64 a)
123{
124 return (a >> 52) & 0x7FF;
125}
126
127inline int16 extractFloat32Exp(float32 a)
128{
129 return (a >> 23) & 0xFF;
130}
131
132inline flag extractFloat32Sign(float32 a)
133{
134 return a >> 31;
135}
136
137inline bits32 extractFloat32Frac(float32 a)
138{
139 return a & 0x007FFFFF;
140}
141
142inline float64 packFloat64(flag zSign, int16 zExp, bits64 zSig)
143{
144 return (((bits64) zSign) << 63) + (((bits64) zExp) << 52) + zSig;
145}
146
147inline void shift64RightJamming(bits64 a, int16 count, bits64 * zPtr)
148{
149 bits64 z;
150
151 if (count == 0) {
152 z = a;
153 } else if (count < 64) {
154 z = (a >> count) | ((a << ((-count) & 63)) != 0);
155 } else {
156 z = (a != 0);
157 }
158 *zPtr = z;
159}
160
161static int8 countLeadingZeros32(bits32 a)
162{
163 static const int8 countLeadingZerosHigh[] = {
164 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
165 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
166 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
167 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
168 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
169 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
170 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
171 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
172 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
173 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
174 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
175 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
176 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
177 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
178 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
179 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
180 };
181 int8 shiftCount;
182
183 shiftCount = 0;
184 if (a < 0x10000) {
185 shiftCount += 16;
186 a <<= 16;
187 }
188 if (a < 0x1000000) {
189 shiftCount += 8;
190 a <<= 8;
191 }
192 shiftCount += countLeadingZerosHigh[a >> 24];
193 return shiftCount;
194
195}
196
197static int8 countLeadingZeros64(bits64 a)
198{
199 int8 shiftCount;
200
201 shiftCount = 0;
202 if (a < ((bits64) 1) << 32) {
203 shiftCount += 32;
204 } else {
205 a >>= 32;
206 }
207 shiftCount += countLeadingZeros32(a);
208 return shiftCount;
209
210}
211
212static float64 normalizeRoundAndPackFloat64(flag zSign, int16 zExp, bits64 zSig)
213{
214 int8 shiftCount;
215
216 shiftCount = countLeadingZeros64(zSig) - 1;
217 return roundAndPackFloat64(zSign, zExp - shiftCount,
218 zSig << shiftCount);
219
220}
221
222static float64 subFloat64Sigs(float64 a, float64 b, flag zSign)
223{
224 int16 aExp, bExp, zExp;
225 bits64 aSig, bSig, zSig;
226 int16 expDiff;
227
228 aSig = extractFloat64Frac(a);
229 aExp = extractFloat64Exp(a);
230 bSig = extractFloat64Frac(b);
231 bExp = extractFloat64Exp(b);
232 expDiff = aExp - bExp;
233 aSig <<= 10;
234 bSig <<= 10;
235 if (0 < expDiff)
236 goto aExpBigger;
237 if (expDiff < 0)
238 goto bExpBigger;
239 if (aExp == 0) {
240 aExp = 1;
241 bExp = 1;
242 }
243 if (bSig < aSig)
244 goto aBigger;
245 if (aSig < bSig)
246 goto bBigger;
247 return packFloat64(float_rounding_mode() == FPSCR_RM_ZERO, 0, 0);
248 bExpBigger:
249 if (bExp == 0x7FF) {
250 return packFloat64(zSign ^ 1, 0x7FF, 0);
251 }
252 if (aExp == 0) {
253 ++expDiff;
254 } else {
255 aSig |= LIT64(0x4000000000000000);
256 }
257 shift64RightJamming(aSig, -expDiff, &aSig);
258 bSig |= LIT64(0x4000000000000000);
259 bBigger:
260 zSig = bSig - aSig;
261 zExp = bExp;
262 zSign ^= 1;
263 goto normalizeRoundAndPack;
264 aExpBigger:
265 if (aExp == 0x7FF) {
266 return a;
267 }
268 if (bExp == 0) {
269 --expDiff;
270 } else {
271 bSig |= LIT64(0x4000000000000000);
272 }
273 shift64RightJamming(bSig, expDiff, &bSig);
274 aSig |= LIT64(0x4000000000000000);
275 aBigger:
276 zSig = aSig - bSig;
277 zExp = aExp;
278 normalizeRoundAndPack:
279 --zExp;
280 return normalizeRoundAndPackFloat64(zSign, zExp, zSig);
281
282}
283static float64 addFloat64Sigs(float64 a, float64 b, flag zSign)
284{
285 int16 aExp, bExp, zExp;
286 bits64 aSig, bSig, zSig;
287 int16 expDiff;
288
289 aSig = extractFloat64Frac(a);
290 aExp = extractFloat64Exp(a);
291 bSig = extractFloat64Frac(b);
292 bExp = extractFloat64Exp(b);
293 expDiff = aExp - bExp;
294 aSig <<= 9;
295 bSig <<= 9;
296 if (0 < expDiff) {
297 if (aExp == 0x7FF) {
298 return a;
299 }
300 if (bExp == 0) {
301 --expDiff;
302 } else {
303 bSig |= LIT64(0x2000000000000000);
304 }
305 shift64RightJamming(bSig, expDiff, &bSig);
306 zExp = aExp;
307 } else if (expDiff < 0) {
308 if (bExp == 0x7FF) {
309 return packFloat64(zSign, 0x7FF, 0);
310 }
311 if (aExp == 0) {
312 ++expDiff;
313 } else {
314 aSig |= LIT64(0x2000000000000000);
315 }
316 shift64RightJamming(aSig, -expDiff, &aSig);
317 zExp = bExp;
318 } else {
319 if (aExp == 0x7FF) {
320 return a;
321 }
322 if (aExp == 0)
323 return packFloat64(zSign, 0, (aSig + bSig) >> 9);
324 zSig = LIT64(0x4000000000000000) + aSig + bSig;
325 zExp = aExp;
326 goto roundAndPack;
327 }
328 aSig |= LIT64(0x2000000000000000);
329 zSig = (aSig + bSig) << 1;
330 --zExp;
331 if ((sbits64) zSig < 0) {
332 zSig = aSig + bSig;
333 ++zExp;
334 }
335 roundAndPack:
336 return roundAndPackFloat64(zSign, zExp, zSig);
337
338}
339
340inline float32 packFloat32(flag zSign, int16 zExp, bits32 zSig)
341{
342 return (((bits32) zSign) << 31) + (((bits32) zExp) << 23) + zSig;
343}
344
345inline void shift32RightJamming(bits32 a, int16 count, bits32 * zPtr)
346{
347 bits32 z;
348 if (count == 0) {
349 z = a;
350 } else if (count < 32) {
351 z = (a >> count) | ((a << ((-count) & 31)) != 0);
352 } else {
353 z = (a != 0);
354 }
355 *zPtr = z;
356}
357
358static float32 roundAndPackFloat32(flag zSign, int16 zExp, bits32 zSig)
359{
360 flag roundNearestEven;
361 int8 roundIncrement, roundBits;
362 flag isTiny;
363
364 /* SH4 has only 2 rounding modes - round to nearest and round to zero */
365 roundNearestEven = (float_rounding_mode() == FPSCR_RM_NEAREST);
366 roundIncrement = 0x40;
367 if (!roundNearestEven) {
368 roundIncrement = 0;
369 }
370 roundBits = zSig & 0x7F;
371 if (0xFD <= (bits16) zExp) {
372 if ((0xFD < zExp)
373 || ((zExp == 0xFD)
374 && ((sbits32) (zSig + roundIncrement) < 0))
375 ) {
376 float_raise(FPSCR_CAUSE_OVERFLOW | FPSCR_CAUSE_INEXACT);
377 return packFloat32(zSign, 0xFF,
378 0) - (roundIncrement == 0);
379 }
380 if (zExp < 0) {
381 isTiny = (zExp < -1)
382 || (zSig + roundIncrement < 0x80000000);
383 shift32RightJamming(zSig, -zExp, &zSig);
384 zExp = 0;
385 roundBits = zSig & 0x7F;
386 if (isTiny && roundBits)
387 float_raise(FPSCR_CAUSE_UNDERFLOW);
388 }
389 }
390 if (roundBits)
391 float_raise(FPSCR_CAUSE_INEXACT);
392 zSig = (zSig + roundIncrement) >> 7;
393 zSig &= ~(((roundBits ^ 0x40) == 0) & roundNearestEven);
394 if (zSig == 0)
395 zExp = 0;
396 return packFloat32(zSign, zExp, zSig);
397
398}
399
400static float32 normalizeRoundAndPackFloat32(flag zSign, int16 zExp, bits32 zSig)
401{
402 int8 shiftCount;
403
404 shiftCount = countLeadingZeros32(zSig) - 1;
405 return roundAndPackFloat32(zSign, zExp - shiftCount,
406 zSig << shiftCount);
407}
408
409static float64 roundAndPackFloat64(flag zSign, int16 zExp, bits64 zSig)
410{
411 flag roundNearestEven;
412 int16 roundIncrement, roundBits;
413 flag isTiny;
414
415 /* SH4 has only 2 rounding modes - round to nearest and round to zero */
416 roundNearestEven = (float_rounding_mode() == FPSCR_RM_NEAREST);
417 roundIncrement = 0x200;
418 if (!roundNearestEven) {
419 roundIncrement = 0;
420 }
421 roundBits = zSig & 0x3FF;
422 if (0x7FD <= (bits16) zExp) {
423 if ((0x7FD < zExp)
424 || ((zExp == 0x7FD)
425 && ((sbits64) (zSig + roundIncrement) < 0))
426 ) {
427 float_raise(FPSCR_CAUSE_OVERFLOW | FPSCR_CAUSE_INEXACT);
428 return packFloat64(zSign, 0x7FF,
429 0) - (roundIncrement == 0);
430 }
431 if (zExp < 0) {
432 isTiny = (zExp < -1)
433 || (zSig + roundIncrement <
434 LIT64(0x8000000000000000));
435 shift64RightJamming(zSig, -zExp, &zSig);
436 zExp = 0;
437 roundBits = zSig & 0x3FF;
438 if (isTiny && roundBits)
439 float_raise(FPSCR_CAUSE_UNDERFLOW);
440 }
441 }
442 if (roundBits)
443 float_raise(FPSCR_CAUSE_INEXACT);
444 zSig = (zSig + roundIncrement) >> 10;
445 zSig &= ~(((roundBits ^ 0x200) == 0) & roundNearestEven);
446 if (zSig == 0)
447 zExp = 0;
448 return packFloat64(zSign, zExp, zSig);
449
450}
451
452static float32 subFloat32Sigs(float32 a, float32 b, flag zSign)
453{
454 int16 aExp, bExp, zExp;
455 bits32 aSig, bSig, zSig;
456 int16 expDiff;
457
458 aSig = extractFloat32Frac(a);
459 aExp = extractFloat32Exp(a);
460 bSig = extractFloat32Frac(b);
461 bExp = extractFloat32Exp(b);
462 expDiff = aExp - bExp;
463 aSig <<= 7;
464 bSig <<= 7;
465 if (0 < expDiff)
466 goto aExpBigger;
467 if (expDiff < 0)
468 goto bExpBigger;
469 if (aExp == 0) {
470 aExp = 1;
471 bExp = 1;
472 }
473 if (bSig < aSig)
474 goto aBigger;
475 if (aSig < bSig)
476 goto bBigger;
477 return packFloat32(float_rounding_mode() == FPSCR_RM_ZERO, 0, 0);
478 bExpBigger:
479 if (bExp == 0xFF) {
480 return packFloat32(zSign ^ 1, 0xFF, 0);
481 }
482 if (aExp == 0) {
483 ++expDiff;
484 } else {
485 aSig |= 0x40000000;
486 }
487 shift32RightJamming(aSig, -expDiff, &aSig);
488 bSig |= 0x40000000;
489 bBigger:
490 zSig = bSig - aSig;
491 zExp = bExp;
492 zSign ^= 1;
493 goto normalizeRoundAndPack;
494 aExpBigger:
495 if (aExp == 0xFF) {
496 return a;
497 }
498 if (bExp == 0) {
499 --expDiff;
500 } else {
501 bSig |= 0x40000000;
502 }
503 shift32RightJamming(bSig, expDiff, &bSig);
504 aSig |= 0x40000000;
505 aBigger:
506 zSig = aSig - bSig;
507 zExp = aExp;
508 normalizeRoundAndPack:
509 --zExp;
510 return normalizeRoundAndPackFloat32(zSign, zExp, zSig);
511
512}
513
514static float32 addFloat32Sigs(float32 a, float32 b, flag zSign)
515{
516 int16 aExp, bExp, zExp;
517 bits32 aSig, bSig, zSig;
518 int16 expDiff;
519
520 aSig = extractFloat32Frac(a);
521 aExp = extractFloat32Exp(a);
522 bSig = extractFloat32Frac(b);
523 bExp = extractFloat32Exp(b);
524 expDiff = aExp - bExp;
525 aSig <<= 6;
526 bSig <<= 6;
527 if (0 < expDiff) {
528 if (aExp == 0xFF) {
529 return a;
530 }
531 if (bExp == 0) {
532 --expDiff;
533 } else {
534 bSig |= 0x20000000;
535 }
536 shift32RightJamming(bSig, expDiff, &bSig);
537 zExp = aExp;
538 } else if (expDiff < 0) {
539 if (bExp == 0xFF) {
540 return packFloat32(zSign, 0xFF, 0);
541 }
542 if (aExp == 0) {
543 ++expDiff;
544 } else {
545 aSig |= 0x20000000;
546 }
547 shift32RightJamming(aSig, -expDiff, &aSig);
548 zExp = bExp;
549 } else {
550 if (aExp == 0xFF) {
551 return a;
552 }
553 if (aExp == 0)
554 return packFloat32(zSign, 0, (aSig + bSig) >> 6);
555 zSig = 0x40000000 + aSig + bSig;
556 zExp = aExp;
557 goto roundAndPack;
558 }
559 aSig |= 0x20000000;
560 zSig = (aSig + bSig) << 1;
561 --zExp;
562 if ((sbits32) zSig < 0) {
563 zSig = aSig + bSig;
564 ++zExp;
565 }
566 roundAndPack:
567 return roundAndPackFloat32(zSign, zExp, zSig);
568
569}
570
571float64 float64_sub(float64 a, float64 b)
572{
573 flag aSign, bSign;
574
575 aSign = extractFloat64Sign(a);
576 bSign = extractFloat64Sign(b);
577 if (aSign == bSign) {
578 return subFloat64Sigs(a, b, aSign);
579 } else {
580 return addFloat64Sigs(a, b, aSign);
581 }
582
583}
584
585float32 float32_sub(float32 a, float32 b)
586{
587 flag aSign, bSign;
588
589 aSign = extractFloat32Sign(a);
590 bSign = extractFloat32Sign(b);
591 if (aSign == bSign) {
592 return subFloat32Sigs(a, b, aSign);
593 } else {
594 return addFloat32Sigs(a, b, aSign);
595 }
596
597}
598
599float32 float32_add(float32 a, float32 b)
600{
601 flag aSign, bSign;
602
603 aSign = extractFloat32Sign(a);
604 bSign = extractFloat32Sign(b);
605 if (aSign == bSign) {
606 return addFloat32Sigs(a, b, aSign);
607 } else {
608 return subFloat32Sigs(a, b, aSign);
609 }
610
611}
612
613float64 float64_add(float64 a, float64 b)
614{
615 flag aSign, bSign;
616
617 aSign = extractFloat64Sign(a);
618 bSign = extractFloat64Sign(b);
619 if (aSign == bSign) {
620 return addFloat64Sigs(a, b, aSign);
621 } else {
622 return subFloat64Sigs(a, b, aSign);
623 }
624}
625
626static void
627normalizeFloat64Subnormal(bits64 aSig, int16 * zExpPtr, bits64 * zSigPtr)
628{
629 int8 shiftCount;
630
631 shiftCount = countLeadingZeros64(aSig) - 11;
632 *zSigPtr = aSig << shiftCount;
633 *zExpPtr = 1 - shiftCount;
634}
635
636inline void add128(bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr,
637 bits64 * z1Ptr)
638{
639 bits64 z1;
640
641 z1 = a1 + b1;
642 *z1Ptr = z1;
643 *z0Ptr = a0 + b0 + (z1 < a1);
644}
645
646inline void
647sub128(bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr,
648 bits64 * z1Ptr)
649{
650 *z1Ptr = a1 - b1;
651 *z0Ptr = a0 - b0 - (a1 < b1);
652}
653
654static bits64 estimateDiv128To64(bits64 a0, bits64 a1, bits64 b)
655{
656 bits64 b0, b1;
657 bits64 rem0, rem1, term0, term1;
658 bits64 z;
659 if (b <= a0)
660 return LIT64(0xFFFFFFFFFFFFFFFF);
661 b0 = b >> 32;
662 z = (b0 << 32 <= a0) ? LIT64(0xFFFFFFFF00000000) : (a0 / b0) << 32;
663 mul64To128(b, z, &term0, &term1);
664 sub128(a0, a1, term0, term1, &rem0, &rem1);
665 while (((sbits64) rem0) < 0) {
666 z -= LIT64(0x100000000);
667 b1 = b << 32;
668 add128(rem0, rem1, b0, b1, &rem0, &rem1);
669 }
670 rem0 = (rem0 << 32) | (rem1 >> 32);
671 z |= (b0 << 32 <= rem0) ? 0xFFFFFFFF : rem0 / b0;
672 return z;
673}
674
675inline void mul64To128(bits64 a, bits64 b, bits64 * z0Ptr, bits64 * z1Ptr)
676{
677 bits32 aHigh, aLow, bHigh, bLow;
678 bits64 z0, zMiddleA, zMiddleB, z1;
679
680 aLow = a;
681 aHigh = a >> 32;
682 bLow = b;
683 bHigh = b >> 32;
684 z1 = ((bits64) aLow) * bLow;
685 zMiddleA = ((bits64) aLow) * bHigh;
686 zMiddleB = ((bits64) aHigh) * bLow;
687 z0 = ((bits64) aHigh) * bHigh;
688 zMiddleA += zMiddleB;
689 z0 += (((bits64) (zMiddleA < zMiddleB)) << 32) + (zMiddleA >> 32);
690 zMiddleA <<= 32;
691 z1 += zMiddleA;
692 z0 += (z1 < zMiddleA);
693 *z1Ptr = z1;
694 *z0Ptr = z0;
695
696}
697
698static void normalizeFloat32Subnormal(bits32 aSig, int16 * zExpPtr,
699 bits32 * zSigPtr)
700{
701 int8 shiftCount;
702
703 shiftCount = countLeadingZeros32(aSig) - 8;
704 *zSigPtr = aSig << shiftCount;
705 *zExpPtr = 1 - shiftCount;
706
707}
708
709float64 float64_div(float64 a, float64 b)
710{
711 flag aSign, bSign, zSign;
712 int16 aExp, bExp, zExp;
713 bits64 aSig, bSig, zSig;
714 bits64 rem0, rem1;
715 bits64 term0, term1;
716
717 aSig = extractFloat64Frac(a);
718 aExp = extractFloat64Exp(a);
719 aSign = extractFloat64Sign(a);
720 bSig = extractFloat64Frac(b);
721 bExp = extractFloat64Exp(b);
722 bSign = extractFloat64Sign(b);
723 zSign = aSign ^ bSign;
724 if (aExp == 0x7FF) {
725 if (bExp == 0x7FF) {
726 }
727 return packFloat64(zSign, 0x7FF, 0);
728 }
729 if (bExp == 0x7FF) {
730 return packFloat64(zSign, 0, 0);
731 }
732 if (bExp == 0) {
733 if (bSig == 0) {
734 if ((aExp | aSig) == 0) {
735 float_raise(FPSCR_CAUSE_INVALID);
736 }
737 return packFloat64(zSign, 0x7FF, 0);
738 }
739 normalizeFloat64Subnormal(bSig, &bExp, &bSig);
740 }
741 if (aExp == 0) {
742 if (aSig == 0)
743 return packFloat64(zSign, 0, 0);
744 normalizeFloat64Subnormal(aSig, &aExp, &aSig);
745 }
746 zExp = aExp - bExp + 0x3FD;
747 aSig = (aSig | LIT64(0x0010000000000000)) << 10;
748 bSig = (bSig | LIT64(0x0010000000000000)) << 11;
749 if (bSig <= (aSig + aSig)) {
750 aSig >>= 1;
751 ++zExp;
752 }
753 zSig = estimateDiv128To64(aSig, 0, bSig);
754 if ((zSig & 0x1FF) <= 2) {
755 mul64To128(bSig, zSig, &term0, &term1);
756 sub128(aSig, 0, term0, term1, &rem0, &rem1);
757 while ((sbits64) rem0 < 0) {
758 --zSig;
759 add128(rem0, rem1, 0, bSig, &rem0, &rem1);
760 }
761 zSig |= (rem1 != 0);
762 }
763 return roundAndPackFloat64(zSign, zExp, zSig);
764
765}
766
767float32 float32_div(float32 a, float32 b)
768{
769 flag aSign, bSign, zSign;
770 int16 aExp, bExp, zExp;
771 bits32 aSig, bSig, zSig;
772
773 aSig = extractFloat32Frac(a);
774 aExp = extractFloat32Exp(a);
775 aSign = extractFloat32Sign(a);
776 bSig = extractFloat32Frac(b);
777 bExp = extractFloat32Exp(b);
778 bSign = extractFloat32Sign(b);
779 zSign = aSign ^ bSign;
780 if (aExp == 0xFF) {
781 if (bExp == 0xFF) {
782 }
783 return packFloat32(zSign, 0xFF, 0);
784 }
785 if (bExp == 0xFF) {
786 return packFloat32(zSign, 0, 0);
787 }
788 if (bExp == 0) {
789 if (bSig == 0) {
790 return packFloat32(zSign, 0xFF, 0);
791 }
792 normalizeFloat32Subnormal(bSig, &bExp, &bSig);
793 }
794 if (aExp == 0) {
795 if (aSig == 0)
796 return packFloat32(zSign, 0, 0);
797 normalizeFloat32Subnormal(aSig, &aExp, &aSig);
798 }
799 zExp = aExp - bExp + 0x7D;
800 aSig = (aSig | 0x00800000) << 7;
801 bSig = (bSig | 0x00800000) << 8;
802 if (bSig <= (aSig + aSig)) {
803 aSig >>= 1;
804 ++zExp;
805 }
806 zSig = (((bits64) aSig) << 32) / bSig;
807 if ((zSig & 0x3F) == 0) {
808 zSig |= (((bits64) bSig) * zSig != ((bits64) aSig) << 32);
809 }
810 return roundAndPackFloat32(zSign, zExp, zSig);
811
812}
813
814float32 float32_mul(float32 a, float32 b)
815{
816 char aSign, bSign, zSign;
817 int aExp, bExp, zExp;
818 unsigned int aSig, bSig;
819 unsigned long long zSig64;
820 unsigned int zSig;
821
822 aSig = extractFloat32Frac(a);
823 aExp = extractFloat32Exp(a);
824 aSign = extractFloat32Sign(a);
825 bSig = extractFloat32Frac(b);
826 bExp = extractFloat32Exp(b);
827 bSign = extractFloat32Sign(b);
828 zSign = aSign ^ bSign;
829 if (aExp == 0) {
830 if (aSig == 0)
831 return packFloat32(zSign, 0, 0);
832 normalizeFloat32Subnormal(aSig, &aExp, &aSig);
833 }
834 if (bExp == 0) {
835 if (bSig == 0)
836 return packFloat32(zSign, 0, 0);
837 normalizeFloat32Subnormal(bSig, &bExp, &bSig);
838 }
839 if ((bExp == 0xff && bSig == 0) || (aExp == 0xff && aSig == 0))
840 return roundAndPackFloat32(zSign, 0xff, 0);
841
842 zExp = aExp + bExp - 0x7F;
843 aSig = (aSig | 0x00800000) << 7;
844 bSig = (bSig | 0x00800000) << 8;
845 shift64RightJamming(((unsigned long long)aSig) * bSig, 32, &zSig64);
846 zSig = zSig64;
847 if (0 <= (signed int)(zSig << 1)) {
848 zSig <<= 1;
849 --zExp;
850 }
851 return roundAndPackFloat32(zSign, zExp, zSig);
852
853}
854
855float64 float64_mul(float64 a, float64 b)
856{
857 char aSign, bSign, zSign;
858 int aExp, bExp, zExp;
859 unsigned long long int aSig, bSig, zSig0, zSig1;
860
861 aSig = extractFloat64Frac(a);
862 aExp = extractFloat64Exp(a);
863 aSign = extractFloat64Sign(a);
864 bSig = extractFloat64Frac(b);
865 bExp = extractFloat64Exp(b);
866 bSign = extractFloat64Sign(b);
867 zSign = aSign ^ bSign;
868
869 if (aExp == 0) {
870 if (aSig == 0)
871 return packFloat64(zSign, 0, 0);
872 normalizeFloat64Subnormal(aSig, &aExp, &aSig);
873 }
874 if (bExp == 0) {
875 if (bSig == 0)
876 return packFloat64(zSign, 0, 0);
877 normalizeFloat64Subnormal(bSig, &bExp, &bSig);
878 }
879 if ((aExp == 0x7ff && aSig == 0) || (bExp == 0x7ff && bSig == 0))
880 return roundAndPackFloat64(zSign, 0x7ff, 0);
881
882 zExp = aExp + bExp - 0x3FF;
883 aSig = (aSig | 0x0010000000000000LL) << 10;
884 bSig = (bSig | 0x0010000000000000LL) << 11;
885 mul64To128(aSig, bSig, &zSig0, &zSig1);
886 zSig0 |= (zSig1 != 0);
887 if (0 <= (signed long long int)(zSig0 << 1)) {
888 zSig0 <<= 1;
889 --zExp;
890 }
891 return roundAndPackFloat64(zSign, zExp, zSig0);
892}
diff --git a/arch/sh/kernel/cpu/sh4/sq.c b/arch/sh/kernel/cpu/sh4/sq.c
index b22a78c807e6..3008c00eea6b 100644
--- a/arch/sh/kernel/cpu/sh4/sq.c
+++ b/arch/sh/kernel/cpu/sh4/sq.c
@@ -341,17 +341,18 @@ static int __devinit sq_sysdev_add(struct sys_device *sysdev)
341{ 341{
342 unsigned int cpu = sysdev->id; 342 unsigned int cpu = sysdev->id;
343 struct kobject *kobj; 343 struct kobject *kobj;
344 int error;
344 345
345 sq_kobject[cpu] = kzalloc(sizeof(struct kobject), GFP_KERNEL); 346 sq_kobject[cpu] = kzalloc(sizeof(struct kobject), GFP_KERNEL);
346 if (unlikely(!sq_kobject[cpu])) 347 if (unlikely(!sq_kobject[cpu]))
347 return -ENOMEM; 348 return -ENOMEM;
348 349
349 kobj = sq_kobject[cpu]; 350 kobj = sq_kobject[cpu];
350 kobj->parent = &sysdev->kobj; 351 error = kobject_init_and_add(kobj, &ktype_percpu_entry, &sysdev->kobj,
351 kobject_set_name(kobj, "%s", "sq"); 352 "%s", "sq");
352 kobj->ktype = &ktype_percpu_entry; 353 if (!error)
353 354 kobject_uevent(kobj, KOBJ_ADD);
354 return kobject_register(kobj); 355 return error;
355} 356}
356 357
357static int __devexit sq_sysdev_remove(struct sys_device *sysdev) 358static int __devexit sq_sysdev_remove(struct sys_device *sysdev)
@@ -359,7 +360,7 @@ static int __devexit sq_sysdev_remove(struct sys_device *sysdev)
359 unsigned int cpu = sysdev->id; 360 unsigned int cpu = sysdev->id;
360 struct kobject *kobj = sq_kobject[cpu]; 361 struct kobject *kobj = sq_kobject[cpu];
361 362
362 kobject_unregister(kobj); 363 kobject_put(kobj);
363 return 0; 364 return 0;
364} 365}
365 366
diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile
index 24539873943a..08ac6387bf17 100644
--- a/arch/sh/kernel/cpu/sh4a/Makefile
+++ b/arch/sh/kernel/cpu/sh4a/Makefile
@@ -3,6 +3,7 @@
3# 3#
4 4
5# CPU subtype setup 5# CPU subtype setup
6obj-$(CONFIG_CPU_SUBTYPE_SH7763) += setup-sh7763.o
6obj-$(CONFIG_CPU_SUBTYPE_SH7770) += setup-sh7770.o 7obj-$(CONFIG_CPU_SUBTYPE_SH7770) += setup-sh7770.o
7obj-$(CONFIG_CPU_SUBTYPE_SH7780) += setup-sh7780.o 8obj-$(CONFIG_CPU_SUBTYPE_SH7780) += setup-sh7780.o
8obj-$(CONFIG_CPU_SUBTYPE_SH7785) += setup-sh7785.o 9obj-$(CONFIG_CPU_SUBTYPE_SH7785) += setup-sh7785.o
@@ -14,6 +15,7 @@ obj-$(CONFIG_CPU_SUBTYPE_SHX3) += setup-shx3.o
14smp-$(CONFIG_CPU_SUBTYPE_SHX3) := smp-shx3.o 15smp-$(CONFIG_CPU_SUBTYPE_SHX3) := smp-shx3.o
15 16
16# Primary on-chip clocks (common) 17# Primary on-chip clocks (common)
18clock-$(CONFIG_CPU_SUBTYPE_SH7763) := clock-sh7763.o
17clock-$(CONFIG_CPU_SUBTYPE_SH7770) := clock-sh7770.o 19clock-$(CONFIG_CPU_SUBTYPE_SH7770) := clock-sh7770.o
18clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o 20clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o
19clock-$(CONFIG_CPU_SUBTYPE_SH7785) := clock-sh7785.o 21clock-$(CONFIG_CPU_SUBTYPE_SH7785) := clock-sh7785.o
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7763.c b/arch/sh/kernel/cpu/sh4a/clock-sh7763.c
new file mode 100644
index 000000000000..45889d412c80
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7763.c
@@ -0,0 +1,126 @@
1/*
2 * arch/sh/kernel/cpu/sh4a/clock-sh7763.c
3 *
4 * SH7763 support for the clock framework
5 *
6 * Copyright (C) 2005 Paul Mundt
7 * Copyright (C) 2007 Yoshihiro Shimoda
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 */
13#include <linux/init.h>
14#include <linux/kernel.h>
15#include <asm/clock.h>
16#include <asm/freq.h>
17#include <asm/io.h>
18
19static int bfc_divisors[] = { 1, 1, 1, 8, 1, 1, 1, 1 };
20static int p0fc_divisors[] = { 1, 1, 1, 8, 1, 1, 1, 1 };
21static int p1fc_divisors[] = { 1, 1, 1, 16, 1, 1, 1, 1 };
22static int cfc_divisors[] = { 1, 1, 4, 1, 1, 1, 1, 1 };
23
24static void master_clk_init(struct clk *clk)
25{
26 clk->rate *= p0fc_divisors[(ctrl_inl(FRQCR) >> 4) & 0x07];
27}
28
29static struct clk_ops sh7763_master_clk_ops = {
30 .init = master_clk_init,
31};
32
33static void module_clk_recalc(struct clk *clk)
34{
35 int idx = ((ctrl_inl(FRQCR) >> 4) & 0x07);
36 clk->rate = clk->parent->rate / p0fc_divisors[idx];
37}
38
39static struct clk_ops sh7763_module_clk_ops = {
40 .recalc = module_clk_recalc,
41};
42
43static void bus_clk_recalc(struct clk *clk)
44{
45 int idx = ((ctrl_inl(FRQCR) >> 16) & 0x07);
46 clk->rate = clk->parent->rate / bfc_divisors[idx];
47}
48
49static struct clk_ops sh7763_bus_clk_ops = {
50 .recalc = bus_clk_recalc,
51};
52
53static void cpu_clk_recalc(struct clk *clk)
54{
55 clk->rate = clk->parent->rate;
56}
57
58static struct clk_ops sh7763_cpu_clk_ops = {
59 .recalc = cpu_clk_recalc,
60};
61
62static struct clk_ops *sh7763_clk_ops[] = {
63 &sh7763_master_clk_ops,
64 &sh7763_module_clk_ops,
65 &sh7763_bus_clk_ops,
66 &sh7763_cpu_clk_ops,
67};
68
69void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
70{
71 if (idx < ARRAY_SIZE(sh7763_clk_ops))
72 *ops = sh7763_clk_ops[idx];
73}
74
75static void shyway_clk_recalc(struct clk *clk)
76{
77 int idx = ((ctrl_inl(FRQCR) >> 20) & 0x07);
78 clk->rate = clk->parent->rate / cfc_divisors[idx];
79}
80
81static struct clk_ops sh7763_shyway_clk_ops = {
82 .recalc = shyway_clk_recalc,
83};
84
85static struct clk sh7763_shyway_clk = {
86 .name = "shyway_clk",
87 .flags = CLK_ALWAYS_ENABLED,
88 .ops = &sh7763_shyway_clk_ops,
89};
90
91/*
92 * Additional SH7763-specific on-chip clocks that aren't already part of the
93 * clock framework
94 */
95static struct clk *sh7763_onchip_clocks[] = {
96 &sh7763_shyway_clk,
97};
98
99static int __init sh7763_clk_init(void)
100{
101 struct clk *clk = clk_get(NULL, "master_clk");
102 int i;
103
104 for (i = 0; i < ARRAY_SIZE(sh7763_onchip_clocks); i++) {
105 struct clk *clkp = sh7763_onchip_clocks[i];
106
107 clkp->parent = clk;
108 clk_register(clkp);
109 clk_enable(clkp);
110 }
111
112 /*
113 * Now that we have the rest of the clocks registered, we need to
114 * force the parent clock to propagate so that these clocks will
115 * automatically figure out their rate. We cheat by handing the
116 * parent clock its current rate and forcing child propagation.
117 */
118 clk_set_rate(clk, clk_get_rate(clk));
119
120 clk_put(clk);
121
122 return 0;
123}
124
125arch_initcall(sh7763_clk_init);
126
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
index b9c6547c4a90..73c778d40d13 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
@@ -157,14 +157,6 @@ static struct intc_group groups[] __initdata = {
157 INTC_GROUP(SDHI, SDHI0, SDHI1, SDHI2, SDHI3), 157 INTC_GROUP(SDHI, SDHI0, SDHI1, SDHI2, SDHI3),
158}; 158};
159 159
160static struct intc_prio priorities[] __initdata = {
161 INTC_PRIO(SCIF0, 3),
162 INTC_PRIO(SCIF1, 3),
163 INTC_PRIO(SCIF2, 3),
164 INTC_PRIO(TMU0, 2),
165 INTC_PRIO(TMU1, 2),
166};
167
168static struct intc_mask_reg mask_registers[] __initdata = { 160static struct intc_mask_reg mask_registers[] __initdata = {
169 { 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */ 161 { 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */
170 { } }, 162 { } },
@@ -217,7 +209,7 @@ static struct intc_sense_reg sense_registers[] __initdata = {
217 { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, 209 { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
218}; 210};
219 211
220static DECLARE_INTC_DESC(intc_desc, "sh7722", vectors, groups, priorities, 212static DECLARE_INTC_DESC(intc_desc, "sh7722", vectors, groups,
221 mask_registers, prio_registers, sense_registers); 213 mask_registers, prio_registers, sense_registers);
222 214
223void __init plat_irq_setup(void) 215void __init plat_irq_setup(void)
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
new file mode 100644
index 000000000000..eabd5386812d
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
@@ -0,0 +1,390 @@
1/*
2 * SH7763 Setup
3 *
4 * Copyright (C) 2006 Paul Mundt
5 * Copyright (C) 2007 Yoshihiro Shimoda
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 */
11#include <linux/platform_device.h>
12#include <linux/init.h>
13#include <linux/serial.h>
14#include <linux/io.h>
15#include <asm/sci.h>
16
17static struct resource rtc_resources[] = {
18 [0] = {
19 .start = 0xffe80000,
20 .end = 0xffe80000 + 0x58 - 1,
21 .flags = IORESOURCE_IO,
22 },
23 [1] = {
24 /* Period IRQ */
25 .start = 21,
26 .flags = IORESOURCE_IRQ,
27 },
28 [2] = {
29 /* Carry IRQ */
30 .start = 22,
31 .flags = IORESOURCE_IRQ,
32 },
33 [3] = {
34 /* Alarm IRQ */
35 .start = 20,
36 .flags = IORESOURCE_IRQ,
37 },
38};
39
40static struct platform_device rtc_device = {
41 .name = "sh-rtc",
42 .id = -1,
43 .num_resources = ARRAY_SIZE(rtc_resources),
44 .resource = rtc_resources,
45};
46
47static struct plat_sci_port sci_platform_data[] = {
48 {
49 .mapbase = 0xffe00000,
50 .flags = UPF_BOOT_AUTOCONF,
51 .type = PORT_SCIF,
52 .irqs = { 40, 41, 43, 42 },
53 }, {
54 .mapbase = 0xffe08000,
55 .flags = UPF_BOOT_AUTOCONF,
56 .type = PORT_SCIF,
57 .irqs = { 76, 77, 79, 78 },
58 }, {
59 .flags = 0,
60 }
61};
62
63static struct platform_device sci_device = {
64 .name = "sh-sci",
65 .id = -1,
66 .dev = {
67 .platform_data = sci_platform_data,
68 },
69};
70
71static struct resource usb_ohci_resources[] = {
72 [0] = {
73 .start = 0xffec8000,
74 .end = 0xffec80ff,
75 .flags = IORESOURCE_MEM,
76 },
77 [1] = {
78 .start = 83,
79 .end = 83,
80 .flags = IORESOURCE_IRQ,
81 },
82};
83
84static u64 usb_ohci_dma_mask = 0xffffffffUL;
85static struct platform_device usb_ohci_device = {
86 .name = "sh_ohci",
87 .id = -1,
88 .dev = {
89 .dma_mask = &usb_ohci_dma_mask,
90 .coherent_dma_mask = 0xffffffff,
91 },
92 .num_resources = ARRAY_SIZE(usb_ohci_resources),
93 .resource = usb_ohci_resources,
94};
95
96static struct resource usbf_resources[] = {
97 [0] = {
98 .start = 0xffec0000,
99 .end = 0xffec00ff,
100 .flags = IORESOURCE_MEM,
101 },
102 [1] = {
103 .start = 84,
104 .end = 84,
105 .flags = IORESOURCE_IRQ,
106 },
107};
108
109static struct platform_device usbf_device = {
110 .name = "sh_udc",
111 .id = -1,
112 .dev = {
113 .dma_mask = NULL,
114 .coherent_dma_mask = 0xffffffff,
115 },
116 .num_resources = ARRAY_SIZE(usbf_resources),
117 .resource = usbf_resources,
118};
119
120static struct platform_device *sh7763_devices[] __initdata = {
121 &rtc_device,
122 &sci_device,
123 &usb_ohci_device,
124 &usbf_device,
125};
126
127static int __init sh7763_devices_setup(void)
128{
129 return platform_add_devices(sh7763_devices,
130 ARRAY_SIZE(sh7763_devices));
131}
132__initcall(sh7763_devices_setup);
133
134enum {
135 UNUSED = 0,
136
137 /* interrupt sources */
138
139 IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
140 IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
141 IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
142 IRL_HHLL, IRL_HHLH, IRL_HHHL,
143
144 IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
145 RTC_ATI, RTC_PRI, RTC_CUI,
146 WDT, TMU0, TMU1, TMU2, TMU2_TICPI,
147 HUDI, LCDC,
148 DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, DMAC0_DMINT3, DMAC0_DMAE,
149 SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
150 DMAC0_DMINT4, DMAC0_DMINT5,
151 IIC0, IIC1,
152 CMT,
153 GEINT0, GEINT1, GEINT2,
154 HAC,
155 PCISERR, PCIINTA, PCIINTB, PCIINTC, PCIINTD,
156 PCIERR, PCIPWD3, PCIPWD2, PCIPWD1, PCIPWD0,
157 STIF0, STIF1,
158 SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI,
159 SIOF0, SIOF1, SIOF2,
160 USBH, USBFI0, USBFI1,
161 TPU, PCC,
162 MMCIF_FSTAT, MMCIF_TRAN, MMCIF_ERR, MMCIF_FRDY,
163 SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEND,
164 TMU3, TMU4, TMU5, ADC, SSI0, SSI1, SSI2, SSI3,
165 SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI,
166 GPIO_CH0, GPIO_CH1, GPIO_CH2, GPIO_CH3,
167
168 /* interrupt groups */
169
170 TMU012, TMU345, RTC, DMAC, SCIF0, GETHER, PCIC5,
171 SCIF1, USBF, MMCIF, SIM, SCIF2, GPIO,
172};
173
174static struct intc_vect vectors[] __initdata = {
175 INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0),
176 INTC_VECT(RTC_CUI, 0x4c0),
177 INTC_VECT(WDT, 0x560), INTC_VECT(TMU0, 0x580),
178 INTC_VECT(TMU1, 0x5a0), INTC_VECT(TMU2, 0x5c0),
179 INTC_VECT(TMU2_TICPI, 0x5e0), INTC_VECT(HUDI, 0x600),
180 INTC_VECT(LCDC, 0x620),
181 INTC_VECT(DMAC0_DMINT0, 0x640), INTC_VECT(DMAC0_DMINT1, 0x660),
182 INTC_VECT(DMAC0_DMINT2, 0x680), INTC_VECT(DMAC0_DMINT3, 0x6a0),
183 INTC_VECT(DMAC0_DMAE, 0x6c0),
184 INTC_VECT(SCIF0_ERI, 0x700), INTC_VECT(SCIF0_RXI, 0x720),
185 INTC_VECT(SCIF0_BRI, 0x740), INTC_VECT(SCIF0_TXI, 0x760),
186 INTC_VECT(DMAC0_DMINT4, 0x780), INTC_VECT(DMAC0_DMINT5, 0x7a0),
187 INTC_VECT(IIC0, 0x8A0), INTC_VECT(IIC1, 0x8C0),
188 INTC_VECT(CMT, 0x900), INTC_VECT(GEINT0, 0x920),
189 INTC_VECT(GEINT1, 0x940), INTC_VECT(GEINT2, 0x960),
190 INTC_VECT(HAC, 0x980),
191 INTC_VECT(PCISERR, 0xa00), INTC_VECT(PCIINTA, 0xa20),
192 INTC_VECT(PCIINTB, 0xa40), INTC_VECT(PCIINTC, 0xa60),
193 INTC_VECT(PCIINTD, 0xa80), INTC_VECT(PCIERR, 0xaa0),
194 INTC_VECT(PCIPWD3, 0xac0), INTC_VECT(PCIPWD2, 0xae0),
195 INTC_VECT(PCIPWD1, 0xb00), INTC_VECT(PCIPWD0, 0xb20),
196 INTC_VECT(STIF0, 0xb40), INTC_VECT(STIF1, 0xb60),
197 INTC_VECT(SCIF1_ERI, 0xb80), INTC_VECT(SCIF1_RXI, 0xba0),
198 INTC_VECT(SCIF1_BRI, 0xbc0), INTC_VECT(SCIF1_TXI, 0xbe0),
199 INTC_VECT(SIOF0, 0xc00), INTC_VECT(SIOF1, 0xc20),
200 INTC_VECT(USBH, 0xc60), INTC_VECT(USBFI0, 0xc80),
201 INTC_VECT(USBFI1, 0xca0),
202 INTC_VECT(TPU, 0xcc0), INTC_VECT(PCC, 0xce0),
203 INTC_VECT(MMCIF_FSTAT, 0xd00), INTC_VECT(MMCIF_TRAN, 0xd20),
204 INTC_VECT(MMCIF_ERR, 0xd40), INTC_VECT(MMCIF_FRDY, 0xd60),
205 INTC_VECT(SIM_ERI, 0xd80), INTC_VECT(SIM_RXI, 0xda0),
206 INTC_VECT(SIM_TXI, 0xdc0), INTC_VECT(SIM_TEND, 0xde0),
207 INTC_VECT(TMU3, 0xe00), INTC_VECT(TMU4, 0xe20),
208 INTC_VECT(TMU5, 0xe40), INTC_VECT(ADC, 0xe60),
209 INTC_VECT(SSI0, 0xe80), INTC_VECT(SSI1, 0xea0),
210 INTC_VECT(SSI2, 0xec0), INTC_VECT(SSI3, 0xee0),
211 INTC_VECT(SCIF1_ERI, 0xf00), INTC_VECT(SCIF1_RXI, 0xf20),
212 INTC_VECT(SCIF1_BRI, 0xf40), INTC_VECT(SCIF1_TXI, 0xf60),
213 INTC_VECT(GPIO_CH0, 0xf80), INTC_VECT(GPIO_CH1, 0xfa0),
214 INTC_VECT(GPIO_CH2, 0xfc0), INTC_VECT(GPIO_CH3, 0xfe0),
215};
216
217static struct intc_group groups[] __initdata = {
218 INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI),
219 INTC_GROUP(TMU345, TMU3, TMU4, TMU5),
220 INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
221 INTC_GROUP(DMAC, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2,
222 DMAC0_DMINT3, DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE),
223 INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
224 INTC_GROUP(GETHER, GEINT0, GEINT1, GEINT2),
225 INTC_GROUP(PCIC5, PCIERR, PCIPWD3, PCIPWD2, PCIPWD1, PCIPWD0),
226 INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI),
227 INTC_GROUP(USBF, USBFI0, USBFI1),
228 INTC_GROUP(MMCIF, MMCIF_FSTAT, MMCIF_TRAN, MMCIF_ERR, MMCIF_FRDY),
229 INTC_GROUP(SIM, SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEND),
230 INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI),
231 INTC_GROUP(GPIO, GPIO_CH0, GPIO_CH1, GPIO_CH2, GPIO_CH3),
232};
233
234static struct intc_prio priorities[] __initdata = {
235 INTC_PRIO(SCIF0, 3),
236 INTC_PRIO(SCIF1, 3),
237 INTC_PRIO(SCIF2, 3),
238};
239
240static struct intc_mask_reg mask_registers[] __initdata = {
241 { 0xffd40038, 0xffd4003c, 32, /* INT2MSKR / INT2MSKCR */
242 { 0, 0, 0, 0, 0, 0, GPIO, 0,
243 SSI0, MMCIF, 0, SIOF0, PCIC5, PCIINTD, PCIINTC, PCIINTB,
244 PCIINTA, PCISERR, HAC, CMT, 0, 0, 0, DMAC,
245 HUDI, 0, WDT, SCIF1, SCIF0, RTC, TMU345, TMU012 } },
246 { 0xffd400d0, 0xffd400d4, 32, /* INT2MSKR1 / INT2MSKCR1 */
247 { 0, 0, 0, 0, 0, 0, SCIF2, USBF,
248 0, 0, STIF1, STIF0, 0, 0, USBH, GETHER,
249 PCC, 0, 0, ADC, TPU, SIM, SIOF2, SIOF1,
250 LCDC, 0, IIC1, IIC0, SSI3, SSI2, SSI1, 0 } },
251};
252
253static struct intc_prio_reg prio_registers[] __initdata = {
254 { 0xffd40000, 0, 32, 8, /* INT2PRI0 */ { TMU0, TMU1,
255 TMU2, TMU2_TICPI } },
256 { 0xffd40004, 0, 32, 8, /* INT2PRI1 */ { TMU3, TMU4, TMU5, RTC } },
257 { 0xffd40008, 0, 32, 8, /* INT2PRI2 */ { SCIF0, SCIF1, WDT } },
258 { 0xffd4000c, 0, 32, 8, /* INT2PRI3 */ { HUDI, DMAC, ADC } },
259 { 0xffd40010, 0, 32, 8, /* INT2PRI4 */ { CMT, HAC,
260 PCISERR, PCIINTA } },
261 { 0xffd40014, 0, 32, 8, /* INT2PRI5 */ { PCIINTB, PCIINTC,
262 PCIINTD, PCIC5 } },
263 { 0xffd40018, 0, 32, 8, /* INT2PRI6 */ { SIOF0, USBF, MMCIF, SSI0 } },
264 { 0xffd4001c, 0, 32, 8, /* INT2PRI7 */ { SCIF2, GPIO } },
265 { 0xffd400a0, 0, 32, 8, /* INT2PRI8 */ { SSI3, SSI2, SSI1, 0 } },
266 { 0xffd400a4, 0, 32, 8, /* INT2PRI9 */ { LCDC, 0, IIC1, IIC0 } },
267 { 0xffd400a8, 0, 32, 8, /* INT2PRI10 */ { TPU, SIM, SIOF2, SIOF1 } },
268 { 0xffd400ac, 0, 32, 8, /* INT2PRI11 */ { PCC } },
269 { 0xffd400b0, 0, 32, 8, /* INT2PRI12 */ { 0, 0, USBH, GETHER } },
270 { 0xffd400b4, 0, 32, 8, /* INT2PRI13 */ { 0, 0, STIF1, STIF0 } },
271};
272
273static DECLARE_INTC_DESC(intc_desc, "sh7763", vectors, groups, priorities,
274 mask_registers, prio_registers, NULL);
275
276/* Support for external interrupt pins in IRQ mode */
277
278static struct intc_vect irq_vectors[] __initdata = {
279 INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280),
280 INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300),
281 INTC_VECT(IRQ4, 0x340), INTC_VECT(IRQ5, 0x380),
282 INTC_VECT(IRQ6, 0x3c0), INTC_VECT(IRQ7, 0x200),
283};
284
285static struct intc_mask_reg irq_mask_registers[] __initdata = {
286 { 0xffd00044, 0xffd00064, 32, /* INTMSK0 / INTMSKCLR0 */
287 { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
288};
289
290static struct intc_prio_reg irq_prio_registers[] __initdata = {
291 { 0xffd00010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3,
292 IRQ4, IRQ5, IRQ6, IRQ7 } },
293};
294
295static struct intc_sense_reg irq_sense_registers[] __initdata = {
296 { 0xffd0001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3,
297 IRQ4, IRQ5, IRQ6, IRQ7 } },
298};
299
300static DECLARE_INTC_DESC(intc_irq_desc, "sh7763-irq", irq_vectors,
301 NULL, NULL, irq_mask_registers, irq_prio_registers,
302 irq_sense_registers);
303
304/* External interrupt pins in IRL mode */
305
306static struct intc_vect irl_vectors[] __initdata = {
307 INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220),
308 INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260),
309 INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0),
310 INTC_VECT(IRL_LHHL, 0x2c0), INTC_VECT(IRL_LHHH, 0x2e0),
311 INTC_VECT(IRL_HLLL, 0x300), INTC_VECT(IRL_HLLH, 0x320),
312 INTC_VECT(IRL_HLHL, 0x340), INTC_VECT(IRL_HLHH, 0x360),
313 INTC_VECT(IRL_HHLL, 0x380), INTC_VECT(IRL_HHLH, 0x3a0),
314 INTC_VECT(IRL_HHHL, 0x3c0),
315};
316
317static struct intc_mask_reg irl3210_mask_registers[] __initdata = {
318 { 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */
319 { IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
320 IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
321 IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
322 IRL_HHLL, IRL_HHLH, IRL_HHHL, } },
323};
324
325static struct intc_mask_reg irl7654_mask_registers[] __initdata = {
326 { 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */
327 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
328 IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
329 IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
330 IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
331 IRL_HHLL, IRL_HHLH, IRL_HHHL, } },
332};
333
334static DECLARE_INTC_DESC(intc_irl7654_desc, "sh7763-irl7654", irl_vectors,
335 NULL, NULL, irl7654_mask_registers, NULL, NULL);
336
337static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7763-irl3210", irl_vectors,
338 NULL, NULL, irl3210_mask_registers, NULL, NULL);
339
340#define INTC_ICR0 0xffd00000
341#define INTC_INTMSK0 0xffd00044
342#define INTC_INTMSK1 0xffd00048
343#define INTC_INTMSK2 0xffd40080
344#define INTC_INTMSKCLR1 0xffd00068
345#define INTC_INTMSKCLR2 0xffd40084
346
347void __init plat_irq_setup(void)
348{
349 /* disable IRQ7-0 */
350 ctrl_outl(0xff000000, INTC_INTMSK0);
351
352 /* disable IRL3-0 + IRL7-4 */
353 ctrl_outl(0xc0000000, INTC_INTMSK1);
354 ctrl_outl(0xfffefffe, INTC_INTMSK2);
355
356 register_intc_controller(&intc_desc);
357}
358
359void __init plat_irq_setup_pins(int mode)
360{
361 switch (mode) {
362 case IRQ_MODE_IRQ:
363 /* select IRQ mode for IRL3-0 + IRL7-4 */
364 ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00c00000, INTC_ICR0);
365 register_intc_controller(&intc_irq_desc);
366 break;
367 case IRQ_MODE_IRL7654:
368 /* enable IRL7-4 but don't provide any masking */
369 ctrl_outl(0x40000000, INTC_INTMSKCLR1);
370 ctrl_outl(0x0000fffe, INTC_INTMSKCLR2);
371 break;
372 case IRQ_MODE_IRL3210:
373 /* enable IRL0-3 but don't provide any masking */
374 ctrl_outl(0x80000000, INTC_INTMSKCLR1);
375 ctrl_outl(0xfffe0000, INTC_INTMSKCLR2);
376 break;
377 case IRQ_MODE_IRL7654_MASK:
378 /* enable IRL7-4 and mask using cpu intc controller */
379 ctrl_outl(0x40000000, INTC_INTMSKCLR1);
380 register_intc_controller(&intc_irl7654_desc);
381 break;
382 case IRQ_MODE_IRL3210_MASK:
383 /* enable IRL0-3 and mask using cpu intc controller */
384 ctrl_outl(0x80000000, INTC_INTMSKCLR1);
385 register_intc_controller(&intc_irl3210_desc);
386 break;
387 default:
388 BUG();
389 }
390}
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
index e8fd33ff0605..293004b526ff 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
@@ -168,11 +168,6 @@ static struct intc_group groups[] __initdata = {
168 INTC_GROUP(GPIO, GPIOI0, GPIOI1, GPIOI2, GPIOI3), 168 INTC_GROUP(GPIO, GPIOI0, GPIOI1, GPIOI2, GPIOI3),
169}; 169};
170 170
171static struct intc_prio priorities[] __initdata = {
172 INTC_PRIO(SCIF0, 3),
173 INTC_PRIO(SCIF1, 3),
174};
175
176static struct intc_mask_reg mask_registers[] __initdata = { 171static struct intc_mask_reg mask_registers[] __initdata = {
177 { 0xffd40038, 0xffd4003c, 32, /* INT2MSKR / INT2MSKCR */ 172 { 0xffd40038, 0xffd4003c, 32, /* INT2MSKR / INT2MSKCR */
178 { 0, 0, 0, 0, 0, 0, GPIO, FLCTL, 173 { 0, 0, 0, 0, 0, 0, GPIO, FLCTL,
@@ -195,7 +190,7 @@ static struct intc_prio_reg prio_registers[] __initdata = {
195 { 0xffd4001c, 0, 32, 8, /* INT2PRI7 */ { FLCTL, GPIO } }, 190 { 0xffd4001c, 0, 32, 8, /* INT2PRI7 */ { FLCTL, GPIO } },
196}; 191};
197 192
198static DECLARE_INTC_DESC(intc_desc, "sh7780", vectors, groups, priorities, 193static DECLARE_INTC_DESC(intc_desc, "sh7780", vectors, groups,
199 mask_registers, prio_registers, NULL); 194 mask_registers, prio_registers, NULL);
200 195
201/* Support for external interrupt pins in IRQ mode */ 196/* Support for external interrupt pins in IRQ mode */
@@ -223,7 +218,7 @@ static struct intc_sense_reg irq_sense_registers[] __initdata = {
223}; 218};
224 219
225static DECLARE_INTC_DESC(intc_irq_desc, "sh7780-irq", irq_vectors, 220static DECLARE_INTC_DESC(intc_irq_desc, "sh7780-irq", irq_vectors,
226 NULL, NULL, irq_mask_registers, irq_prio_registers, 221 NULL, irq_mask_registers, irq_prio_registers,
227 irq_sense_registers); 222 irq_sense_registers);
228 223
229/* External interrupt pins in IRL mode */ 224/* External interrupt pins in IRL mode */
@@ -257,10 +252,10 @@ static struct intc_mask_reg irl7654_mask_registers[] __initdata = {
257}; 252};
258 253
259static DECLARE_INTC_DESC(intc_irl7654_desc, "sh7780-irl7654", irl_vectors, 254static DECLARE_INTC_DESC(intc_irl7654_desc, "sh7780-irl7654", irl_vectors,
260 NULL, NULL, irl7654_mask_registers, NULL, NULL); 255 NULL, irl7654_mask_registers, NULL, NULL);
261 256
262static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7780-irl3210", irl_vectors, 257static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7780-irl3210", irl_vectors,
263 NULL, NULL, irl3210_mask_registers, NULL, NULL); 258 NULL, irl3210_mask_registers, NULL, NULL);
264 259
265#define INTC_ICR0 0xffd00000 260#define INTC_ICR0 0xffd00000
266#define INTC_INTMSK0 0xffd00044 261#define INTC_INTMSK0 0xffd00044
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
index 39b215d6cee5..74b60e96cdf4 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
@@ -178,15 +178,6 @@ static struct intc_group groups[] __initdata = {
178 INTC_GROUP(GPIO, GPIOI0, GPIOI1, GPIOI2, GPIOI3), 178 INTC_GROUP(GPIO, GPIOI0, GPIOI1, GPIOI2, GPIOI3),
179}; 179};
180 180
181static struct intc_prio priorities[] __initdata = {
182 INTC_PRIO(SCIF0, 3),
183 INTC_PRIO(SCIF1, 3),
184 INTC_PRIO(SCIF2, 3),
185 INTC_PRIO(SCIF3, 3),
186 INTC_PRIO(SCIF4, 3),
187 INTC_PRIO(SCIF5, 3),
188};
189
190static struct intc_mask_reg mask_registers[] __initdata = { 181static struct intc_mask_reg mask_registers[] __initdata = {
191 { 0xffd00044, 0xffd00064, 32, /* INTMSK0 / INTMSKCLR0 */ 182 { 0xffd00044, 0xffd00064, 32, /* INTMSK0 / INTMSKCLR0 */
192 { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, 183 { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
@@ -227,7 +218,7 @@ static struct intc_prio_reg prio_registers[] __initdata = {
227 { 0xffd40024, 0, 32, 8, /* INT2PRI9 */ { DU, GDTA, } }, 218 { 0xffd40024, 0, 32, 8, /* INT2PRI9 */ { DU, GDTA, } },
228}; 219};
229 220
230static DECLARE_INTC_DESC(intc_desc, "sh7785", vectors, groups, priorities, 221static DECLARE_INTC_DESC(intc_desc, "sh7785", vectors, groups,
231 mask_registers, prio_registers, NULL); 222 mask_registers, prio_registers, NULL);
232 223
233/* Support for external interrupt pins in IRQ mode */ 224/* Support for external interrupt pins in IRQ mode */
@@ -248,11 +239,11 @@ static struct intc_sense_reg sense_registers[] __initdata = {
248}; 239};
249 240
250static DECLARE_INTC_DESC(intc_desc_irq0123, "sh7785-irq0123", vectors_irq0123, 241static DECLARE_INTC_DESC(intc_desc_irq0123, "sh7785-irq0123", vectors_irq0123,
251 NULL, NULL, mask_registers, prio_registers, 242 NULL, mask_registers, prio_registers,
252 sense_registers); 243 sense_registers);
253 244
254static DECLARE_INTC_DESC(intc_desc_irq4567, "sh7785-irq4567", vectors_irq4567, 245static DECLARE_INTC_DESC(intc_desc_irq4567, "sh7785-irq4567", vectors_irq4567,
255 NULL, NULL, mask_registers, prio_registers, 246 NULL, mask_registers, prio_registers,
256 sense_registers); 247 sense_registers);
257 248
258/* External interrupt pins in IRL mode */ 249/* External interrupt pins in IRL mode */
@@ -280,10 +271,10 @@ static struct intc_vect vectors_irl4567[] __initdata = {
280}; 271};
281 272
282static DECLARE_INTC_DESC(intc_desc_irl0123, "sh7785-irl0123", vectors_irl0123, 273static DECLARE_INTC_DESC(intc_desc_irl0123, "sh7785-irl0123", vectors_irl0123,
283 NULL, NULL, mask_registers, NULL, NULL); 274 NULL, mask_registers, NULL, NULL);
284 275
285static DECLARE_INTC_DESC(intc_desc_irl4567, "sh7785-irl4567", vectors_irl4567, 276static DECLARE_INTC_DESC(intc_desc_irl4567, "sh7785-irl4567", vectors_irl4567,
286 NULL, NULL, mask_registers, NULL, NULL); 277 NULL, mask_registers, NULL, NULL);
287 278
288#define INTC_ICR0 0xffd00000 279#define INTC_ICR0 0xffd00000
289#define INTC_INTMSK0 0xffd00044 280#define INTC_INTMSK0 0xffd00044
diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c
index c6cdd7e3b049..4dc958b6b314 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-shx3.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c
@@ -165,13 +165,6 @@ static struct intc_group groups[] __initdata = {
165 INTC_GROUP(DTU3, DTU3_TEND, DTU3_AE, DTU3_TMISS), 165 INTC_GROUP(DTU3, DTU3_TEND, DTU3_AE, DTU3_TMISS),
166}; 166};
167 167
168static struct intc_prio priorities[] __initdata = {
169 INTC_PRIO(SCIF0, 3),
170 INTC_PRIO(SCIF1, 3),
171 INTC_PRIO(SCIF2, 3),
172 INTC_PRIO(SCIF3, 3),
173};
174
175static struct intc_mask_reg mask_registers[] __initdata = { 168static struct intc_mask_reg mask_registers[] __initdata = {
176 { 0xfe410030, 0xfe410050, 32, /* CnINTMSK0 / CnINTMSKCLR0 */ 169 { 0xfe410030, 0xfe410050, 32, /* CnINTMSK0 / CnINTMSKCLR0 */
177 { IRQ0, IRQ1, IRQ2, IRQ3 } }, 170 { IRQ0, IRQ1, IRQ2, IRQ3 } },
@@ -218,7 +211,7 @@ static struct intc_prio_reg prio_registers[] __initdata = {
218 INTICI3, INTICI2, INTICI1, INTICI0 }, INTC_SMP(4, 4) }, 211 INTICI3, INTICI2, INTICI1, INTICI0 }, INTC_SMP(4, 4) },
219}; 212};
220 213
221static DECLARE_INTC_DESC(intc_desc, "shx3", vectors, groups, priorities, 214static DECLARE_INTC_DESC(intc_desc, "shx3", vectors, groups,
222 mask_registers, prio_registers, NULL); 215 mask_registers, prio_registers, NULL);
223 216
224/* Support for external interrupt pins in IRQ mode */ 217/* Support for external interrupt pins in IRQ mode */
@@ -232,8 +225,7 @@ static struct intc_sense_reg sense_registers[] __initdata = {
232}; 225};
233 226
234static DECLARE_INTC_DESC(intc_desc_irq, "shx3-irq", vectors_irq, groups, 227static DECLARE_INTC_DESC(intc_desc_irq, "shx3-irq", vectors_irq, groups,
235 priorities, mask_registers, prio_registers, 228 mask_registers, prio_registers, sense_registers);
236 sense_registers);
237 229
238/* External interrupt pins in IRL mode */ 230/* External interrupt pins in IRL mode */
239static struct intc_vect vectors_irl[] __initdata = { 231static struct intc_vect vectors_irl[] __initdata = {
@@ -248,7 +240,7 @@ static struct intc_vect vectors_irl[] __initdata = {
248}; 240};
249 241
250static DECLARE_INTC_DESC(intc_desc_irl, "shx3-irl", vectors_irl, groups, 242static DECLARE_INTC_DESC(intc_desc_irl, "shx3-irl", vectors_irl, groups,
251 priorities, mask_registers, prio_registers, NULL); 243 mask_registers, prio_registers, NULL);
252 244
253void __init plat_irq_setup_pins(int mode) 245void __init plat_irq_setup_pins(int mode)
254{ 246{
diff --git a/arch/sh/kernel/cpu/sh5/Makefile b/arch/sh/kernel/cpu/sh5/Makefile
new file mode 100644
index 000000000000..8646363e9ded
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh5/Makefile
@@ -0,0 +1,7 @@
1#
2# Makefile for the Linux/SuperH SH-5 backends.
3#
4obj-y := entry.o probe.o switchto.o
5
6obj-$(CONFIG_SH_FPU) += fpu.o
7obj-$(CONFIG_KALLSYMS) += unwind.o
diff --git a/arch/sh64/kernel/entry.S b/arch/sh/kernel/cpu/sh5/entry.S
index 7013fcb6665c..ba8750176d91 100644
--- a/arch/sh64/kernel/entry.S
+++ b/arch/sh/kernel/cpu/sh5/entry.S
@@ -1,21 +1,18 @@
1/* 1/*
2 * This file is subject to the terms and conditions of the GNU General Public 2 * arch/sh/kernel/cpu/sh5/entry.S
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * arch/sh64/kernel/entry.S
7 * 3 *
8 * Copyright (C) 2000, 2001 Paolo Alberelli 4 * Copyright (C) 2000, 2001 Paolo Alberelli
9 * Copyright (C) 2004, 2005 Paul Mundt 5 * Copyright (C) 2004 - 2007 Paul Mundt
10 * Copyright (C) 2003, 2004 Richard Curnow 6 * Copyright (C) 2003, 2004 Richard Curnow
11 * 7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
12 */ 11 */
13
14#include <linux/errno.h> 12#include <linux/errno.h>
15#include <linux/sys.h> 13#include <linux/sys.h>
16 14#include <asm/cpu/registers.h>
17#include <asm/processor.h> 15#include <asm/processor.h>
18#include <asm/registers.h>
19#include <asm/unistd.h> 16#include <asm/unistd.h>
20#include <asm/thread_info.h> 17#include <asm/thread_info.h>
21#include <asm/asm-offsets.h> 18#include <asm/asm-offsets.h>
@@ -163,7 +160,7 @@ trap_jtable:
163 .long system_call /* 0x160 */ 160 .long system_call /* 0x160 */
164 .long do_reserved_inst /* 0x180 */ 161 .long do_reserved_inst /* 0x180 */
165 .long do_illegal_slot_inst /* 0x1A0 */ 162 .long do_illegal_slot_inst /* 0x1A0 */
166 .long do_NMI /* 0x1C0 */ 163 .long do_exception_error /* 0x1C0 - NMI */
167 .long do_exception_error /* 0x1E0 */ 164 .long do_exception_error /* 0x1E0 */
168 .rept 15 165 .rept 15
169 .long do_IRQ /* 0x200 - 0x3C0 */ 166 .long do_IRQ /* 0x200 - 0x3C0 */
@@ -434,7 +431,7 @@ reset_or_panic:
434 synco /* TAKum03020 (but probably a good idea anyway.) */ 431 synco /* TAKum03020 (but probably a good idea anyway.) */
435 putcon SP, DCR 432 putcon SP, DCR
436 /* First save r0-1 and tr0, as we need to use these */ 433 /* First save r0-1 and tr0, as we need to use these */
437 movi resvec_save_area-CONFIG_CACHED_MEMORY_OFFSET, SP 434 movi resvec_save_area-CONFIG_PAGE_OFFSET, SP
438 st.q SP, 0, r0 435 st.q SP, 0, r0
439 st.q SP, 8, r1 436 st.q SP, 8, r1
440 gettr tr0, r0 437 gettr tr0, r0
@@ -444,7 +441,7 @@ reset_or_panic:
444 getcon EXPEVT, r0 441 getcon EXPEVT, r0
445 movi RESET_CAUSE, r1 442 movi RESET_CAUSE, r1
446 sub r1, r0, r1 /* r1=0 if reset */ 443 sub r1, r0, r1 /* r1=0 if reset */
447 movi _stext-CONFIG_CACHED_MEMORY_OFFSET, r0 444 movi _stext-CONFIG_PAGE_OFFSET, r0
448 ori r0, 1, r0 445 ori r0, 1, r0
449 ptabs r0, tr0 446 ptabs r0, tr0
450 beqi r1, 0, tr0 /* Jump to start address if reset */ 447 beqi r1, 0, tr0 /* Jump to start address if reset */
@@ -456,7 +453,7 @@ reset_or_panic:
456 beqi r1, 0, tr0 /* jump if single step */ 453 beqi r1, 0, tr0 /* jump if single step */
457 454
458 /* Now jump to where we save the registers. */ 455 /* Now jump to where we save the registers. */
459 movi panic_stash_regs-CONFIG_CACHED_MEMORY_OFFSET, r1 456 movi panic_stash_regs-CONFIG_PAGE_OFFSET, r1
460 ptabs r1, tr0 457 ptabs r1, tr0
461 blink tr0, r63 458 blink tr0, r63
462 459
@@ -492,7 +489,7 @@ debug_exception:
492 */ 489 */
493 putcon SP, DCR 490 putcon SP, DCR
494 /* Save SSR & SPC, together with R0 & R1, as we need to use 2 regs. */ 491 /* Save SSR & SPC, together with R0 & R1, as we need to use 2 regs. */
495 movi resvec_save_area-CONFIG_CACHED_MEMORY_OFFSET, SP 492 movi resvec_save_area-CONFIG_PAGE_OFFSET, SP
496 493
497 /* With the MMU off, we are bypassing the cache, so purge any 494 /* With the MMU off, we are bypassing the cache, so purge any
498 * data that will be made stale by the following stores. 495 * data that will be made stale by the following stores.
@@ -560,7 +557,7 @@ debug_interrupt:
560 /* Save original stack pointer into KCR1 */ 557 /* Save original stack pointer into KCR1 */
561 synco 558 synco
562 putcon SP, KCR1 559 putcon SP, KCR1
563 movi resvec_save_area-CONFIG_CACHED_MEMORY_OFFSET, SP 560 movi resvec_save_area-CONFIG_PAGE_OFFSET, SP
564 ocbp SP, 0 561 ocbp SP, 0
565 ocbp SP, 32 562 ocbp SP, 32
566 synco 563 synco
@@ -609,7 +606,7 @@ debug_interrupt:
609 movi EVENT_FAULT_NOT_TLB, r4 606 movi EVENT_FAULT_NOT_TLB, r4
610 607
611 or SP, ZERO, r5 608 or SP, ZERO, r5
612 movi CONFIG_CACHED_MEMORY_OFFSET, r6 609 movi CONFIG_PAGE_OFFSET, r6
613 add r6, r5, r5 610 add r6, r5, r5
614 getcon KCR1, SP 611 getcon KCR1, SP
615 612
@@ -944,9 +941,6 @@ ret_with_reschedule:
944 getcon KCR0, r6 ! r6 contains current_thread_info 941 getcon KCR0, r6 ! r6 contains current_thread_info
945 ld.l r6, TI_FLAGS, r7 ! r7 contains current_thread_info->flags 942 ld.l r6, TI_FLAGS, r7 ! r7 contains current_thread_info->flags
946 943
947 ! FIXME:!!!
948 ! no handling of TIF_SYSCALL_TRACE yet!!
949
950 movi _TIF_NEED_RESCHED, r8 944 movi _TIF_NEED_RESCHED, r8
951 and r8, r7, r8 945 and r8, r7, r8
952 pta work_resched, tr0 946 pta work_resched, tr0
@@ -1282,14 +1276,17 @@ syscall_allowed:
1282 1276
1283 getcon KCR0, r2 1277 getcon KCR0, r2
1284 ld.l r2, TI_FLAGS, r4 1278 ld.l r2, TI_FLAGS, r4
1285 movi (1 << TIF_SYSCALL_TRACE), r6 1279 movi (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | _TIF_SYSCALL_AUDIT), r6
1286 and r6, r4, r6 1280 and r6, r4, r6
1287 beq/l r6, ZERO, tr0 1281 beq/l r6, ZERO, tr0
1288 1282
1289 /* Trace it by calling syscall_trace before and after */ 1283 /* Trace it by calling syscall_trace before and after */
1290 movi syscall_trace, r4 1284 movi syscall_trace, r4
1285 or SP, ZERO, r2
1286 or ZERO, ZERO, r3
1291 ptabs r4, tr0 1287 ptabs r4, tr0
1292 blink tr0, LINK 1288 blink tr0, LINK
1289
1293 /* Reload syscall number as r5 is trashed by syscall_trace */ 1290 /* Reload syscall number as r5 is trashed by syscall_trace */
1294 ld.q SP, FRAME_S(FSYSCALL_ID), r5 1291 ld.q SP, FRAME_S(FSYSCALL_ID), r5
1295 andi r5, 0x1ff, r5 1292 andi r5, 0x1ff, r5
@@ -1323,6 +1320,8 @@ syscall_ret_trace:
1323 st.q SP, FRAME_R(9), r2 /* Save return value */ 1320 st.q SP, FRAME_R(9), r2 /* Save return value */
1324 1321
1325 movi syscall_trace, LINK 1322 movi syscall_trace, LINK
1323 or SP, ZERO, r2
1324 movi 1, r3
1326 ptabs LINK, tr0 1325 ptabs LINK, tr0
1327 blink tr0, LINK 1326 blink tr0, LINK
1328 1327
@@ -1368,7 +1367,7 @@ route_to_panic_handler:
1368 last-chance debugging, e.g. if no output wants to go to the console. 1367 last-chance debugging, e.g. if no output wants to go to the console.
1369 */ 1368 */
1370 1369
1371 movi panic_handler - CONFIG_CACHED_MEMORY_OFFSET, r1 1370 movi panic_handler - CONFIG_PAGE_OFFSET, r1
1372 ptabs r1, tr0 1371 ptabs r1, tr0
1373 pta 1f, tr1 1372 pta 1f, tr1
1374 gettr tr1, r0 1373 gettr tr1, r0
@@ -1410,7 +1409,7 @@ peek_real_address_q:
1410 andc r1, r36, r1 /* turn sr.mmu off in real mode section */ 1409 andc r1, r36, r1 /* turn sr.mmu off in real mode section */
1411 1410
1412 putcon r1, ssr 1411 putcon r1, ssr
1413 movi .peek0 - CONFIG_CACHED_MEMORY_OFFSET, r36 /* real mode target address */ 1412 movi .peek0 - CONFIG_PAGE_OFFSET, r36 /* real mode target address */
1414 movi 1f, r37 /* virtual mode return addr */ 1413 movi 1f, r37 /* virtual mode return addr */
1415 putcon r36, spc 1414 putcon r36, spc
1416 1415
@@ -1459,7 +1458,7 @@ poke_real_address_q:
1459 andc r1, r36, r1 /* turn sr.mmu off in real mode section */ 1458 andc r1, r36, r1 /* turn sr.mmu off in real mode section */
1460 1459
1461 putcon r1, ssr 1460 putcon r1, ssr
1462 movi .poke0-CONFIG_CACHED_MEMORY_OFFSET, r36 /* real mode target address */ 1461 movi .poke0-CONFIG_PAGE_OFFSET, r36 /* real mode target address */
1463 movi 1f, r37 /* virtual mode return addr */ 1462 movi 1f, r37 /* virtual mode return addr */
1464 putcon r36, spc 1463 putcon r36, spc
1465 1464
@@ -1956,7 +1955,7 @@ panic_stash_regs:
1956 getcon SSR,r3 1955 getcon SSR,r3
1957 getcon EXPEVT,r4 1956 getcon EXPEVT,r4
1958 /* Prepare to jump to C - physical address */ 1957 /* Prepare to jump to C - physical address */
1959 movi panic_handler-CONFIG_CACHED_MEMORY_OFFSET, r1 1958 movi panic_handler-CONFIG_PAGE_OFFSET, r1
1960 ori r1, 1, r1 1959 ori r1, 1, r1
1961 ptabs r1, tr0 1960 ptabs r1, tr0
1962 getcon DCR, SP 1961 getcon DCR, SP
@@ -2057,7 +2056,7 @@ trap_init:
2057 andi r19, -4, r19 /* reset MMUOFF + reserved */ 2056 andi r19, -4, r19 /* reset MMUOFF + reserved */
2058 /* For RESVEC exceptions we force the MMU off, which means we need the 2057 /* For RESVEC exceptions we force the MMU off, which means we need the
2059 physical address. */ 2058 physical address. */
2060 movi LRESVEC_block-CONFIG_CACHED_MEMORY_OFFSET, r20 2059 movi LRESVEC_block-CONFIG_PAGE_OFFSET, r20
2061 andi r20, -4, r20 /* reset reserved */ 2060 andi r20, -4, r20 /* reset reserved */
2062 ori r20, 1, r20 /* set MMUOFF */ 2061 ori r20, 1, r20 /* set MMUOFF */
2063 putcon r19, VBR 2062 putcon r19, VBR
diff --git a/arch/sh64/kernel/fpu.c b/arch/sh/kernel/cpu/sh5/fpu.c
index 8ad4ed6a6c9b..30b76a94abf2 100644
--- a/arch/sh64/kernel/fpu.c
+++ b/arch/sh/kernel/cpu/sh5/fpu.c
@@ -1,9 +1,5 @@
1/* 1/*
2 * This file is subject to the terms and conditions of the GNU General Public 2 * arch/sh/kernel/cpu/sh5/fpu.c
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * arch/sh64/kernel/fpu.c
7 * 3 *
8 * Copyright (C) 2001 Manuela Cirronis, Paolo Alberelli 4 * Copyright (C) 2001 Manuela Cirronis, Paolo Alberelli
9 * Copyright (C) 2002 STMicroelectronics Limited 5 * Copyright (C) 2002 STMicroelectronics Limited
@@ -12,8 +8,10 @@
12 * Started from SH4 version: 8 * Started from SH4 version:
13 * Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka 9 * Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka
14 * 10 *
11 * This file is subject to the terms and conditions of the GNU General Public
12 * License. See the file "COPYING" in the main directory of this archive
13 * for more details.
15 */ 14 */
16
17#include <linux/sched.h> 15#include <linux/sched.h>
18#include <linux/signal.h> 16#include <linux/signal.h>
19#include <asm/processor.h> 17#include <asm/processor.h>
@@ -30,12 +28,12 @@
30 28
31static union sh_fpu_union init_fpuregs = { 29static union sh_fpu_union init_fpuregs = {
32 .hard = { 30 .hard = {
33 .fp_regs = { [0 ... 63] = sNAN32 }, 31 .fp_regs = { [0 ... 63] = sNAN32 },
34 .fpscr = FPSCR_INIT 32 .fpscr = FPSCR_INIT
35 } 33 }
36}; 34};
37 35
38inline void fpsave(struct sh_fpu_hard_struct *fpregs) 36void save_fpu(struct task_struct *tsk, struct pt_regs *regs)
39{ 37{
40 asm volatile("fst.p %0, (0*8), fp0\n\t" 38 asm volatile("fst.p %0, (0*8), fp0\n\t"
41 "fst.p %0, (1*8), fp2\n\t" 39 "fst.p %0, (1*8), fp2\n\t"
@@ -73,11 +71,10 @@ inline void fpsave(struct sh_fpu_hard_struct *fpregs)
73 "fgetscr fr63\n\t" 71 "fgetscr fr63\n\t"
74 "fst.s %0, (32*8), fr63\n\t" 72 "fst.s %0, (32*8), fr63\n\t"
75 : /* no output */ 73 : /* no output */
76 : "r" (fpregs) 74 : "r" (&tsk->thread.fpu.hard)
77 : "memory"); 75 : "memory");
78} 76}
79 77
80
81static inline void 78static inline void
82fpload(struct sh_fpu_hard_struct *fpregs) 79fpload(struct sh_fpu_hard_struct *fpregs)
83{ 80{
@@ -152,11 +149,11 @@ do_fpu_state_restore(unsigned long ex, struct pt_regs *regs)
152 if (last_task_used_math == current) 149 if (last_task_used_math == current)
153 return; 150 return;
154 151
155 grab_fpu(); 152 enable_fpu();
156 if (last_task_used_math != NULL) { 153 if (last_task_used_math != NULL)
157 /* Other processes fpu state, save away */ 154 /* Other processes fpu state, save away */
158 fpsave(&last_task_used_math->thread.fpu.hard); 155 save_fpu(last_task_used_math, regs);
159 } 156
160 last_task_used_math = current; 157 last_task_used_math = current;
161 if (used_math()) { 158 if (used_math()) {
162 fpload(&current->thread.fpu.hard); 159 fpload(&current->thread.fpu.hard);
@@ -165,6 +162,5 @@ do_fpu_state_restore(unsigned long ex, struct pt_regs *regs)
165 fpload(&init_fpuregs.hard); 162 fpload(&init_fpuregs.hard);
166 set_used_math(); 163 set_used_math();
167 } 164 }
168 release_fpu(); 165 disable_fpu();
169} 166}
170
diff --git a/arch/sh/kernel/cpu/sh5/probe.c b/arch/sh/kernel/cpu/sh5/probe.c
new file mode 100644
index 000000000000..15d167fd0ae7
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh5/probe.c
@@ -0,0 +1,76 @@
1/*
2 * arch/sh/kernel/cpu/sh5/probe.c
3 *
4 * CPU Subtype Probing for SH-5.
5 *
6 * Copyright (C) 2000, 2001 Paolo Alberelli
7 * Copyright (C) 2003 - 2007 Paul Mundt
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 */
13#include <linux/init.h>
14#include <linux/io.h>
15#include <linux/string.h>
16#include <asm/processor.h>
17#include <asm/cache.h>
18
19int __init detect_cpu_and_cache_system(void)
20{
21 unsigned long long cir;
22
23 /* Do peeks in real mode to avoid having to set up a mapping for the
24 WPC registers. On SH5-101 cut2, such a mapping would be exposed to
25 an address translation erratum which would make it hard to set up
26 correctly. */
27 cir = peek_real_address_q(0x0d000008);
28 if ((cir & 0xffff) == 0x5103) {
29 boot_cpu_data.type = CPU_SH5_103;
30 } else if (((cir >> 32) & 0xffff) == 0x51e2) {
31 /* CPU.VCR aliased at CIR address on SH5-101 */
32 boot_cpu_data.type = CPU_SH5_101;
33 } else {
34 boot_cpu_data.type = CPU_SH_NONE;
35 }
36
37 /*
38 * First, setup some sane values for the I-cache.
39 */
40 boot_cpu_data.icache.ways = 4;
41 boot_cpu_data.icache.sets = 256;
42 boot_cpu_data.icache.linesz = L1_CACHE_BYTES;
43
44#if 0
45 /*
46 * FIXME: This can probably be cleaned up a bit as well.. for example,
47 * do we really need the way shift _and_ the way_step_shift ?? Judging
48 * by the existing code, I would guess no.. is there any valid reason
49 * why we need to be tracking this around?
50 */
51 boot_cpu_data.icache.way_shift = 13;
52 boot_cpu_data.icache.entry_shift = 5;
53 boot_cpu_data.icache.set_shift = 4;
54 boot_cpu_data.icache.way_step_shift = 16;
55 boot_cpu_data.icache.asid_shift = 2;
56
57 /*
58 * way offset = cache size / associativity, so just don't factor in
59 * associativity in the first place..
60 */
61 boot_cpu_data.icache.way_ofs = boot_cpu_data.icache.sets *
62 boot_cpu_data.icache.linesz;
63
64 boot_cpu_data.icache.asid_mask = 0x3fc;
65 boot_cpu_data.icache.idx_mask = 0x1fe0;
66 boot_cpu_data.icache.epn_mask = 0xffffe000;
67#endif
68
69 boot_cpu_data.icache.flags = 0;
70
71 /* A trivial starting point.. */
72 memcpy(&boot_cpu_data.dcache,
73 &boot_cpu_data.icache, sizeof(struct cache_info));
74
75 return 0;
76}
diff --git a/arch/sh64/kernel/switchto.S b/arch/sh/kernel/cpu/sh5/switchto.S
index 45b2d90eed7d..45c351b0f1ba 100644
--- a/arch/sh64/kernel/switchto.S
+++ b/arch/sh/kernel/cpu/sh5/switchto.S
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/sh64/kernel/switchto.S 2 * arch/sh/kernel/cpu/sh5/switchto.S
3 * 3 *
4 * sh64 context switch 4 * sh64 context switch
5 * 5 *
diff --git a/arch/sh64/kernel/unwind.c b/arch/sh/kernel/cpu/sh5/unwind.c
index 1214c78e3584..119c20afd4e5 100644
--- a/arch/sh64/kernel/unwind.c
+++ b/arch/sh/kernel/cpu/sh5/unwind.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/sh64/kernel/unwind.c 2 * arch/sh/kernel/cpu/sh5/unwind.c
3 * 3 *
4 * Copyright (C) 2004 Paul Mundt 4 * Copyright (C) 2004 Paul Mundt
5 * Copyright (C) 2004 Richard Curnow 5 * Copyright (C) 2004 Richard Curnow
diff --git a/arch/sh/kernel/dump_task.c b/arch/sh/kernel/dump_task.c
new file mode 100644
index 000000000000..4a8a4083ff0b
--- /dev/null
+++ b/arch/sh/kernel/dump_task.c
@@ -0,0 +1,31 @@
1#include <linux/elfcore.h>
2#include <linux/sched.h>
3
4/*
5 * Capture the user space registers if the task is not running (in user space)
6 */
7int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
8{
9 struct pt_regs ptregs;
10
11 ptregs = *task_pt_regs(tsk);
12 elf_core_copy_regs(regs, &ptregs);
13
14 return 1;
15}
16
17int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpu)
18{
19 int fpvalid = 0;
20
21#if defined(CONFIG_SH_FPU)
22 fpvalid = !!tsk_used_math(tsk);
23 if (fpvalid) {
24 unlazy_fpu(tsk, task_pt_regs(tsk));
25 memcpy(fpu, &tsk->thread.fpu.hard, sizeof(*fpu));
26 }
27#endif
28
29 return fpvalid;
30}
31
diff --git a/arch/sh/kernel/early_printk.c b/arch/sh/kernel/early_printk.c
index 2f30977558ad..957f25611543 100644
--- a/arch/sh/kernel/early_printk.c
+++ b/arch/sh/kernel/early_printk.c
@@ -63,7 +63,8 @@ static struct console bios_console = {
63#include <linux/serial_core.h> 63#include <linux/serial_core.h>
64#include "../../../drivers/serial/sh-sci.h" 64#include "../../../drivers/serial/sh-sci.h"
65 65
66#if defined(CONFIG_CPU_SUBTYPE_SH7720) 66#if defined(CONFIG_CPU_SUBTYPE_SH7720) || \
67 defined(CONFIG_CPU_SUBTYPE_SH7721)
67#define EPK_SCSMR_VALUE 0x000 68#define EPK_SCSMR_VALUE 0x000
68#define EPK_SCBRR_VALUE 0x00C 69#define EPK_SCBRR_VALUE 0x00C
69#define EPK_FIFO_SIZE 64 70#define EPK_FIFO_SIZE 64
@@ -117,7 +118,8 @@ static struct console scif_console = {
117}; 118};
118 119
119#if !defined(CONFIG_SH_STANDARD_BIOS) 120#if !defined(CONFIG_SH_STANDARD_BIOS)
120#if defined(CONFIG_CPU_SUBTYPE_SH7720) 121#if defined(CONFIG_CPU_SUBTYPE_SH7720) || \
122 defined(CONFIG_CPU_SUBTYPE_SH7721)
121static void scif_sercon_init(char *s) 123static void scif_sercon_init(char *s)
122{ 124{
123 sci_out(&scif_port, SCSCR, 0x0000); /* clear TE and RE */ 125 sci_out(&scif_port, SCSCR, 0x0000); /* clear TE and RE */
@@ -208,10 +210,12 @@ static int __init setup_early_printk(char *buf)
208 if (!strncmp(buf, "serial", 6)) { 210 if (!strncmp(buf, "serial", 6)) {
209 early_console = &scif_console; 211 early_console = &scif_console;
210 212
211#if (defined(CONFIG_CPU_SH4) || defined(CONFIG_CPU_SUBTYPE_SH7720)) && \ 213#if !defined(CONFIG_SH_STANDARD_BIOS)
212 !defined(CONFIG_SH_STANDARD_BIOS) 214#if defined(CONFIG_CPU_SH4) || defined(CONFIG_CPU_SUBTYPE_SH7720) || \
215 defined(CONFIG_CPU_SUBTYPE_SH7721)
213 scif_sercon_init(buf + 6); 216 scif_sercon_init(buf + 6);
214#endif 217#endif
218#endif
215 } 219 }
216#endif 220#endif
217 221
diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S
index e0317ed080c3..926b2e7b11c1 100644
--- a/arch/sh/kernel/entry-common.S
+++ b/arch/sh/kernel/entry-common.S
@@ -176,25 +176,6 @@ work_notifysig:
176 jmp @r1 176 jmp @r1
177 lds r0, pr 177 lds r0, pr
178work_resched: 178work_resched:
179#if defined(CONFIG_GUSA) && !defined(CONFIG_PREEMPT)
180 ! gUSA handling
181 mov.l @(OFF_SP,r15), r0 ! get user space stack pointer
182 mov r0, r1
183 shll r0
184 bf/s 1f
185 shll r0
186 bf/s 1f
187 mov #OFF_PC, r0
188 ! SP >= 0xc0000000 : gUSA mark
189 mov.l @(r0,r15), r2 ! get user space PC (program counter)
190 mov.l @(OFF_R0,r15), r3 ! end point
191 cmp/hs r3, r2 ! r2 >= r3?
192 bt 1f
193 add r3, r1 ! rewind point #2
194 mov.l r1, @(r0,r15) ! reset PC to rewind point #2
195 !
1961:
197#endif
198 mov.l 1f, r1 179 mov.l 1f, r1
199 jsr @r1 ! schedule 180 jsr @r1 ! schedule
200 nop 181 nop
@@ -224,7 +205,7 @@ work_resched:
224syscall_exit_work: 205syscall_exit_work:
225 ! r0: current_thread_info->flags 206 ! r0: current_thread_info->flags
226 ! r8: current_thread_info 207 ! r8: current_thread_info
227 tst #_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP, r0 208 tst #_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | _TIF_SYSCALL_AUDIT, r0
228 bt/s work_pending 209 bt/s work_pending
229 tst #_TIF_NEED_RESCHED, r0 210 tst #_TIF_NEED_RESCHED, r0
230#ifdef CONFIG_TRACE_IRQFLAGS 211#ifdef CONFIG_TRACE_IRQFLAGS
@@ -234,6 +215,8 @@ syscall_exit_work:
234#endif 215#endif
235 sti 216 sti
236 ! XXX setup arguments... 217 ! XXX setup arguments...
218 mov r15, r4
219 mov #1, r5
237 mov.l 4f, r0 ! do_syscall_trace 220 mov.l 4f, r0 ! do_syscall_trace
238 jsr @r0 221 jsr @r0
239 nop 222 nop
@@ -244,6 +227,8 @@ syscall_exit_work:
244syscall_trace_entry: 227syscall_trace_entry:
245 ! Yes it is traced. 228 ! Yes it is traced.
246 ! XXX setup arguments... 229 ! XXX setup arguments...
230 mov r15, r4
231 mov #0, r5
247 mov.l 4f, r11 ! Call do_syscall_trace which notifies 232 mov.l 4f, r11 ! Call do_syscall_trace which notifies
248 jsr @r11 ! superior (will chomp R[0-7]) 233 jsr @r11 ! superior (will chomp R[0-7])
249 nop 234 nop
@@ -366,7 +351,7 @@ ENTRY(system_call)
366 ! 351 !
367 get_current_thread_info r8, r10 352 get_current_thread_info r8, r10
368 mov.l @(TI_FLAGS,r8), r8 353 mov.l @(TI_FLAGS,r8), r8
369 mov #_TIF_SYSCALL_TRACE, r10 354 mov #(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT), r10
370 tst r10, r8 355 tst r10, r8
371 bf syscall_trace_entry 356 bf syscall_trace_entry
372 ! 357 !
diff --git a/arch/sh/kernel/head.S b/arch/sh/kernel/head_32.S
index 3338239717f1..d67d7ed09f22 100644
--- a/arch/sh/kernel/head.S
+++ b/arch/sh/kernel/head_32.S
@@ -32,7 +32,11 @@ ENTRY(empty_zero_page)
32 .long 1 /* LOADER_TYPE */ 32 .long 1 /* LOADER_TYPE */
33 .long 0x00360000 /* INITRD_START */ 33 .long 0x00360000 /* INITRD_START */
34 .long 0x000a0000 /* INITRD_SIZE */ 34 .long 0x000a0000 /* INITRD_SIZE */
35 .long 0 35#ifdef CONFIG_32BIT
36 .long 0x53453f00 + 32 /* "SE?" = 32 bit */
37#else
38 .long 0x53453f00 + 29 /* "SE?" = 29 bit */
39#endif
361: 401:
37 .skip PAGE_SIZE - empty_zero_page - 1b 41 .skip PAGE_SIZE - empty_zero_page - 1b
38 42
diff --git a/arch/sh64/kernel/head.S b/arch/sh/kernel/head_64.S
index 186406d3ad9c..f42d4c0feb76 100644
--- a/arch/sh64/kernel/head.S
+++ b/arch/sh/kernel/head_64.S
@@ -1,32 +1,18 @@
1/* 1/*
2 * This file is subject to the terms and conditions of the GNU General Public 2 * arch/sh/kernel/head_64.S
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * arch/sh64/kernel/head.S
7 * 3 *
8 * Copyright (C) 2000, 2001 Paolo Alberelli 4 * Copyright (C) 2000, 2001 Paolo Alberelli
9 * Copyright (C) 2003, 2004 Paul Mundt 5 * Copyright (C) 2003, 2004 Paul Mundt
10 * 6 *
11 * 7 * This file is subject to the terms and conditions of the GNU General Public
12 * benedict.gaster@superh.com: 2nd May 2002 8 * License. See the file "COPYING" in the main directory of this archive
13 * Moved definition of empty_zero_page to its own section allowing 9 * for more details.
14 * it to be placed at an absolute address known at load time.
15 *
16 * lethal@linux-sh.org: 9th May 2003
17 * Kill off GLOBAL_NAME() usage.
18 *
19 * lethal@linux-sh.org: 8th May 2004
20 * Add early SCIF console DTLB mapping.
21 */ 10 */
22
23
24#include <asm/page.h> 11#include <asm/page.h>
25#include <asm/mmu_context.h>
26#include <asm/cache.h> 12#include <asm/cache.h>
27#include <asm/tlb.h> 13#include <asm/tlb.h>
28#include <asm/processor.h> 14#include <asm/cpu/registers.h>
29#include <asm/registers.h> 15#include <asm/cpu/mmu_context.h>
30#include <asm/thread_info.h> 16#include <asm/thread_info.h>
31 17
32/* 18/*
@@ -41,9 +27,9 @@
41#define MMUDR_END DTLB_LAST_VAR_UNRESTRICTED+TLB_STEP 27#define MMUDR_END DTLB_LAST_VAR_UNRESTRICTED+TLB_STEP
42#define MMUDR_STEP TLB_STEP 28#define MMUDR_STEP TLB_STEP
43 29
44/* Safety check : CONFIG_CACHED_MEMORY_OFFSET has to be a multiple of 512Mb */ 30/* Safety check : CONFIG_PAGE_OFFSET has to be a multiple of 512Mb */
45#if (CONFIG_CACHED_MEMORY_OFFSET & ((1UL<<29)-1)) 31#if (CONFIG_PAGE_OFFSET & ((1UL<<29)-1))
46#error "CONFIG_CACHED_MEMORY_OFFSET must be a multiple of 512Mb" 32#error "CONFIG_PAGE_OFFSET must be a multiple of 512Mb"
47#endif 33#endif
48 34
49/* 35/*
@@ -52,7 +38,7 @@
52/* Deal safely with the case where the base of RAM is not 512Mb aligned */ 38/* Deal safely with the case where the base of RAM is not 512Mb aligned */
53 39
54#define ALIGN_512M_MASK (0xffffffffe0000000) 40#define ALIGN_512M_MASK (0xffffffffe0000000)
55#define ALIGNED_EFFECTIVE ((CONFIG_CACHED_MEMORY_OFFSET + CONFIG_MEMORY_START) & ALIGN_512M_MASK) 41#define ALIGNED_EFFECTIVE ((CONFIG_PAGE_OFFSET + CONFIG_MEMORY_START) & ALIGN_512M_MASK)
56#define ALIGNED_PHYSICAL (CONFIG_MEMORY_START & ALIGN_512M_MASK) 42#define ALIGNED_PHYSICAL (CONFIG_MEMORY_START & ALIGN_512M_MASK)
57 43
58#define MMUIR_TEXT_H (0x0000000000000003 | ALIGNED_EFFECTIVE) 44#define MMUIR_TEXT_H (0x0000000000000003 | ALIGNED_EFFECTIVE)
@@ -66,23 +52,23 @@
66#define MMUDR_CACHED_L 0x000000000000015a | ALIGNED_PHYSICAL 52#define MMUDR_CACHED_L 0x000000000000015a | ALIGNED_PHYSICAL
67 /* 512 Mb, Cacheable, Write-back, read/write, Not User, Ph. Add. */ 53 /* 512 Mb, Cacheable, Write-back, read/write, Not User, Ph. Add. */
68 54
69#ifdef CONFIG_ICACHE_DISABLED 55#ifdef CONFIG_CACHE_OFF
70#define ICCR0_INIT_VAL ICCR0_OFF /* ICACHE off */ 56#define ICCR0_INIT_VAL ICCR0_OFF /* ICACHE off */
71#else 57#else
72#define ICCR0_INIT_VAL ICCR0_ON | ICCR0_ICI /* ICE + ICI */ 58#define ICCR0_INIT_VAL ICCR0_ON | ICCR0_ICI /* ICE + ICI */
73#endif 59#endif
74#define ICCR1_INIT_VAL ICCR1_NOLOCK /* No locking */ 60#define ICCR1_INIT_VAL ICCR1_NOLOCK /* No locking */
75 61
76#if defined (CONFIG_DCACHE_DISABLED) 62#if defined (CONFIG_CACHE_OFF)
77#define OCCR0_INIT_VAL OCCR0_OFF /* D-cache: off */ 63#define OCCR0_INIT_VAL OCCR0_OFF /* D-cache: off */
78#elif defined (CONFIG_DCACHE_WRITE_THROUGH) 64#elif defined (CONFIG_CACHE_WRITETHROUGH)
79#define OCCR0_INIT_VAL OCCR0_ON | OCCR0_OCI | OCCR0_WT /* D-cache: on, */ 65#define OCCR0_INIT_VAL OCCR0_ON | OCCR0_OCI | OCCR0_WT /* D-cache: on, */
80 /* WT, invalidate */ 66 /* WT, invalidate */
81#elif defined (CONFIG_DCACHE_WRITE_BACK) 67#elif defined (CONFIG_CACHE_WRITEBACK)
82#define OCCR0_INIT_VAL OCCR0_ON | OCCR0_OCI | OCCR0_WB /* D-cache: on, */ 68#define OCCR0_INIT_VAL OCCR0_ON | OCCR0_OCI | OCCR0_WB /* D-cache: on, */
83 /* WB, invalidate */ 69 /* WB, invalidate */
84#else 70#else
85#error preprocessor flag CONFIG_DCACHE_... not recognized! 71#error preprocessor flag CONFIG_CACHE_... not recognized!
86#endif 72#endif
87 73
88#define OCCR1_INIT_VAL OCCR1_NOLOCK /* No locking */ 74#define OCCR1_INIT_VAL OCCR1_NOLOCK /* No locking */
@@ -108,8 +94,8 @@ empty_zero_page:
108 .section .data, "aw" 94 .section .data, "aw"
109 .balign PAGE_SIZE 95 .balign PAGE_SIZE
110 96
111 .global swapper_pg_dir 97 .global mmu_pdtp_cache
112swapper_pg_dir: 98mmu_pdtp_cache:
113 .space PAGE_SIZE, 0 99 .space PAGE_SIZE, 0
114 100
115 .global empty_bad_page 101 .global empty_bad_page
@@ -368,5 +354,3 @@ hopeless:
368 * (r32) _start_kernel address 354 * (r32) _start_kernel address
369 */ 355 */
370 blink tr7, ZERO 356 blink tr7, ZERO
371
372
diff --git a/arch/sh/kernel/init_task.c b/arch/sh/kernel/init_task.c
index 4b449c4a6bad..f9bcc606127e 100644
--- a/arch/sh/kernel/init_task.c
+++ b/arch/sh/kernel/init_task.c
@@ -11,8 +11,8 @@ static struct fs_struct init_fs = INIT_FS;
11static struct files_struct init_files = INIT_FILES; 11static struct files_struct init_files = INIT_FILES;
12static struct signal_struct init_signals = INIT_SIGNALS(init_signals); 12static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
13static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); 13static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
14struct pt_regs fake_swapper_regs;
14struct mm_struct init_mm = INIT_MM(init_mm); 15struct mm_struct init_mm = INIT_MM(init_mm);
15
16EXPORT_SYMBOL(init_mm); 16EXPORT_SYMBOL(init_mm);
17 17
18/* 18/*
@@ -22,7 +22,7 @@ EXPORT_SYMBOL(init_mm);
22 * way process stacks are handled. This is done by having a special 22 * way process stacks are handled. This is done by having a special
23 * "init_task" linker map entry.. 23 * "init_task" linker map entry..
24 */ 24 */
25union thread_union init_thread_union 25union thread_union init_thread_union
26 __attribute__((__section__(".data.init_task"))) = 26 __attribute__((__section__(".data.init_task"))) =
27 { INIT_THREAD_INFO(init_task) }; 27 { INIT_THREAD_INFO(init_task) };
28 28
diff --git a/arch/sh/kernel/io.c b/arch/sh/kernel/io.c
index 501fe03e3715..71c9fde2fd90 100644
--- a/arch/sh/kernel/io.c
+++ b/arch/sh/kernel/io.c
@@ -61,73 +61,6 @@ void memset_io(volatile void __iomem *dst, int c, unsigned long count)
61} 61}
62EXPORT_SYMBOL(memset_io); 62EXPORT_SYMBOL(memset_io);
63 63
64void __raw_readsl(unsigned long addr, void *datap, int len)
65{
66 u32 *data;
67
68 for (data = datap; (len != 0) && (((u32)data & 0x1f) != 0); len--)
69 *data++ = ctrl_inl(addr);
70
71 if (likely(len >= (0x20 >> 2))) {
72 int tmp2, tmp3, tmp4, tmp5, tmp6;
73
74 __asm__ __volatile__(
75 "1: \n\t"
76 "mov.l @%7, r0 \n\t"
77 "mov.l @%7, %2 \n\t"
78#ifdef CONFIG_CPU_SH4
79 "movca.l r0, @%0 \n\t"
80#else
81 "mov.l r0, @%0 \n\t"
82#endif
83 "mov.l @%7, %3 \n\t"
84 "mov.l @%7, %4 \n\t"
85 "mov.l @%7, %5 \n\t"
86 "mov.l @%7, %6 \n\t"
87 "mov.l @%7, r7 \n\t"
88 "mov.l @%7, r0 \n\t"
89 "mov.l %2, @(0x04,%0) \n\t"
90 "mov #0x20>>2, %2 \n\t"
91 "mov.l %3, @(0x08,%0) \n\t"
92 "sub %2, %1 \n\t"
93 "mov.l %4, @(0x0c,%0) \n\t"
94 "cmp/hi %1, %2 ! T if 32 > len \n\t"
95 "mov.l %5, @(0x10,%0) \n\t"
96 "mov.l %6, @(0x14,%0) \n\t"
97 "mov.l r7, @(0x18,%0) \n\t"
98 "mov.l r0, @(0x1c,%0) \n\t"
99 "bf.s 1b \n\t"
100 " add #0x20, %0 \n\t"
101 : "=&r" (data), "=&r" (len),
102 "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4),
103 "=&r" (tmp5), "=&r" (tmp6)
104 : "r"(addr), "0" (data), "1" (len)
105 : "r0", "r7", "t", "memory");
106 }
107
108 for (; len != 0; len--)
109 *data++ = ctrl_inl(addr);
110}
111EXPORT_SYMBOL(__raw_readsl);
112
113void __raw_writesl(unsigned long addr, const void *data, int len)
114{
115 if (likely(len != 0)) {
116 int tmp1;
117
118 __asm__ __volatile__ (
119 "1: \n\t"
120 "mov.l @%0+, %1 \n\t"
121 "dt %3 \n\t"
122 "bf.s 1b \n\t"
123 " mov.l %1, @%4 \n\t"
124 : "=&r" (data), "=&r" (tmp1)
125 : "0" (data), "r" (len), "r"(addr)
126 : "t", "memory");
127 }
128}
129EXPORT_SYMBOL(__raw_writesl);
130
131void __iomem *ioport_map(unsigned long port, unsigned int nr) 64void __iomem *ioport_map(unsigned long port, unsigned int nr)
132{ 65{
133 return sh_mv.mv_ioport_map(port, nr); 66 return sh_mv.mv_ioport_map(port, nr);
diff --git a/arch/sh/kernel/module.c b/arch/sh/kernel/module.c
index 142a4e5b7ebc..b3d0a03b4c76 100644
--- a/arch/sh/kernel/module.c
+++ b/arch/sh/kernel/module.c
@@ -1,5 +1,15 @@
1/* Kernel module help for SH. 1/* Kernel module help for SH.
2 2
3 SHcompact version by Kaz Kojima and Paul Mundt.
4
5 SHmedia bits:
6
7 Copyright 2004 SuperH (UK) Ltd
8 Author: Richard Curnow
9
10 Based on the sh version, and on code from the sh64-specific parts of
11 modutils, originally written by Richard Curnow and Ben Gaster.
12
3 This program is free software; you can redistribute it and/or modify 13 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by 14 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2 of the License, or 15 the Free Software Foundation; either version 2 of the License, or
@@ -21,12 +31,6 @@
21#include <linux/string.h> 31#include <linux/string.h>
22#include <linux/kernel.h> 32#include <linux/kernel.h>
23 33
24#if 0
25#define DEBUGP printk
26#else
27#define DEBUGP(fmt...)
28#endif
29
30void *module_alloc(unsigned long size) 34void *module_alloc(unsigned long size)
31{ 35{
32 if (size == 0) 36 if (size == 0)
@@ -52,6 +56,7 @@ int module_frob_arch_sections(Elf_Ehdr *hdr,
52 return 0; 56 return 0;
53} 57}
54 58
59#ifdef CONFIG_SUPERH32
55#define COPY_UNALIGNED_WORD(sw, tw, align) \ 60#define COPY_UNALIGNED_WORD(sw, tw, align) \
56{ \ 61{ \
57 void *__s = &(sw), *__t = &(tw); \ 62 void *__s = &(sw), *__t = &(tw); \
@@ -74,6 +79,10 @@ int module_frob_arch_sections(Elf_Ehdr *hdr,
74 break; \ 79 break; \
75 } \ 80 } \
76} 81}
82#else
83/* One thing SHmedia doesn't screw up! */
84#define COPY_UNALIGNED_WORD(sw, tw, align) { (tw) = (sw); }
85#endif
77 86
78int apply_relocate_add(Elf32_Shdr *sechdrs, 87int apply_relocate_add(Elf32_Shdr *sechdrs,
79 const char *strtab, 88 const char *strtab,
@@ -89,8 +98,8 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
89 uint32_t value; 98 uint32_t value;
90 int align; 99 int align;
91 100
92 DEBUGP("Applying relocate section %u to %u\n", relsec, 101 pr_debug("Applying relocate section %u to %u\n", relsec,
93 sechdrs[relsec].sh_info); 102 sechdrs[relsec].sh_info);
94 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { 103 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
95 /* This is where to make the change */ 104 /* This is where to make the change */
96 location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr 105 location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
@@ -102,17 +111,44 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
102 relocation = sym->st_value + rel[i].r_addend; 111 relocation = sym->st_value + rel[i].r_addend;
103 align = (int)location & 3; 112 align = (int)location & 3;
104 113
114#ifdef CONFIG_SUPERH64
115 /* For text addresses, bit2 of the st_other field indicates
116 * whether the symbol is SHmedia (1) or SHcompact (0). If
117 * SHmedia, the LSB of the symbol needs to be asserted
118 * for the CPU to be in SHmedia mode when it starts executing
119 * the branch target. */
120 relocation |= (sym->st_other & 4);
121#endif
122
105 switch (ELF32_R_TYPE(rel[i].r_info)) { 123 switch (ELF32_R_TYPE(rel[i].r_info)) {
106 case R_SH_DIR32: 124 case R_SH_DIR32:
107 COPY_UNALIGNED_WORD (*location, value, align); 125 COPY_UNALIGNED_WORD (*location, value, align);
108 value += relocation; 126 value += relocation;
109 COPY_UNALIGNED_WORD (value, *location, align); 127 COPY_UNALIGNED_WORD (value, *location, align);
110 break; 128 break;
111 case R_SH_REL32: 129 case R_SH_REL32:
112 relocation = (relocation - (Elf32_Addr) location); 130 relocation = (relocation - (Elf32_Addr) location);
113 COPY_UNALIGNED_WORD (*location, value, align); 131 COPY_UNALIGNED_WORD (*location, value, align);
114 value += relocation; 132 value += relocation;
115 COPY_UNALIGNED_WORD (value, *location, align); 133 COPY_UNALIGNED_WORD (value, *location, align);
134 break;
135 case R_SH_IMM_LOW16:
136 *location = (*location & ~0x3fffc00) |
137 ((relocation & 0xffff) << 10);
138 break;
139 case R_SH_IMM_MEDLOW16:
140 *location = (*location & ~0x3fffc00) |
141 (((relocation >> 16) & 0xffff) << 10);
142 break;
143 case R_SH_IMM_LOW16_PCREL:
144 relocation -= (Elf32_Addr) location;
145 *location = (*location & ~0x3fffc00) |
146 ((relocation & 0xffff) << 10);
147 break;
148 case R_SH_IMM_MEDLOW16_PCREL:
149 relocation -= (Elf32_Addr) location;
150 *location = (*location & ~0x3fffc00) |
151 (((relocation >> 16) & 0xffff) << 10);
116 break; 152 break;
117 default: 153 default:
118 printk(KERN_ERR "module %s: Unknown relocation: %u\n", 154 printk(KERN_ERR "module %s: Unknown relocation: %u\n",
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process_32.c
index 6d7f2b07e491..9ab1926b9d10 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process_32.c
@@ -230,34 +230,6 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
230 return fpvalid; 230 return fpvalid;
231} 231}
232 232
233/*
234 * Capture the user space registers if the task is not running (in user space)
235 */
236int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
237{
238 struct pt_regs ptregs;
239
240 ptregs = *task_pt_regs(tsk);
241 elf_core_copy_regs(regs, &ptregs);
242
243 return 1;
244}
245
246int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpu)
247{
248 int fpvalid = 0;
249
250#if defined(CONFIG_SH_FPU)
251 fpvalid = !!tsk_used_math(tsk);
252 if (fpvalid) {
253 unlazy_fpu(tsk, task_pt_regs(tsk));
254 memcpy(fpu, &tsk->thread.fpu.hard, sizeof(*fpu));
255 }
256#endif
257
258 return fpvalid;
259}
260
261asmlinkage void ret_from_fork(void); 233asmlinkage void ret_from_fork(void);
262 234
263int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, 235int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
@@ -350,25 +322,6 @@ struct task_struct *__switch_to(struct task_struct *prev,
350 unlazy_fpu(prev, task_pt_regs(prev)); 322 unlazy_fpu(prev, task_pt_regs(prev));
351#endif 323#endif
352 324
353#if defined(CONFIG_GUSA) && defined(CONFIG_PREEMPT)
354 {
355 struct pt_regs *regs;
356
357 preempt_disable();
358 regs = task_pt_regs(prev);
359 if (user_mode(regs) && regs->regs[15] >= 0xc0000000) {
360 int offset = (int)regs->regs[15];
361
362 /* Reset stack pointer: clear critical region mark */
363 regs->regs[15] = regs->regs[1];
364 if (regs->pc < regs->regs[0])
365 /* Go to rewind point */
366 regs->pc = regs->regs[0] + offset;
367 }
368 preempt_enable_no_resched();
369 }
370#endif
371
372#ifdef CONFIG_MMU 325#ifdef CONFIG_MMU
373 /* 326 /*
374 * Restore the kernel mode register 327 * Restore the kernel mode register
@@ -510,49 +463,3 @@ asmlinkage void break_point_trap(void)
510 463
511 force_sig(SIGTRAP, current); 464 force_sig(SIGTRAP, current);
512} 465}
513
514/*
515 * Generic trap handler.
516 */
517asmlinkage void debug_trap_handler(unsigned long r4, unsigned long r5,
518 unsigned long r6, unsigned long r7,
519 struct pt_regs __regs)
520{
521 struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
522
523 /* Rewind */
524 regs->pc -= instruction_size(ctrl_inw(regs->pc - 4));
525
526 if (notify_die(DIE_TRAP, "debug trap", regs, 0, regs->tra & 0xff,
527 SIGTRAP) == NOTIFY_STOP)
528 return;
529
530 force_sig(SIGTRAP, current);
531}
532
533/*
534 * Special handler for BUG() traps.
535 */
536asmlinkage void bug_trap_handler(unsigned long r4, unsigned long r5,
537 unsigned long r6, unsigned long r7,
538 struct pt_regs __regs)
539{
540 struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
541
542 /* Rewind */
543 regs->pc -= instruction_size(ctrl_inw(regs->pc - 4));
544
545 if (notify_die(DIE_TRAP, "bug trap", regs, 0, TRAPA_BUG_OPCODE & 0xff,
546 SIGTRAP) == NOTIFY_STOP)
547 return;
548
549#ifdef CONFIG_BUG
550 if (__kernel_text_address(instruction_pointer(regs))) {
551 u16 insn = *(u16 *)instruction_pointer(regs);
552 if (insn == TRAPA_BUG_OPCODE)
553 handle_BUG(regs);
554 }
555#endif
556
557 force_sig(SIGTRAP, current);
558}
diff --git a/arch/sh64/kernel/process.c b/arch/sh/kernel/process_64.c
index 0761af4d2a42..cff3b7dc9c56 100644
--- a/arch/sh64/kernel/process.c
+++ b/arch/sh/kernel/process_64.c
@@ -1,12 +1,10 @@
1/* 1/*
2 * This file is subject to the terms and conditions of the GNU General Public 2 * arch/sh/kernel/process_64.c
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 * 3 *
6 * arch/sh64/kernel/process.c 4 * This file handles the architecture-dependent parts of process handling..
7 * 5 *
8 * Copyright (C) 2000, 2001 Paolo Alberelli 6 * Copyright (C) 2000, 2001 Paolo Alberelli
9 * Copyright (C) 2003 Paul Mundt 7 * Copyright (C) 2003 - 2007 Paul Mundt
10 * Copyright (C) 2003, 2004 Richard Curnow 8 * Copyright (C) 2003, 2004 Richard Curnow
11 * 9 *
12 * Started from SH3/4 version: 10 * Started from SH3/4 version:
@@ -15,10 +13,9 @@
15 * In turn started from i386 version: 13 * In turn started from i386 version:
16 * Copyright (C) 1995 Linus Torvalds 14 * Copyright (C) 1995 Linus Torvalds
17 * 15 *
18 */ 16 * This file is subject to the terms and conditions of the GNU General Public
19 17 * License. See the file "COPYING" in the main directory of this archive
20/* 18 * for more details.
21 * This file handles the architecture-dependent parts of process handling..
22 */ 19 */
23#include <linux/mm.h> 20#include <linux/mm.h>
24#include <linux/fs.h> 21#include <linux/fs.h>
@@ -27,8 +24,10 @@
27#include <linux/init.h> 24#include <linux/init.h>
28#include <linux/module.h> 25#include <linux/module.h>
29#include <linux/proc_fs.h> 26#include <linux/proc_fs.h>
27#include <linux/io.h>
30#include <asm/uaccess.h> 28#include <asm/uaccess.h>
31#include <asm/pgtable.h> 29#include <asm/pgtable.h>
30#include <asm/mmu_context.h>
32 31
33struct task_struct *last_task_used_math = NULL; 32struct task_struct *last_task_used_math = NULL;
34 33
@@ -106,9 +105,20 @@ void machine_halt(void)
106 105
107void machine_power_off(void) 106void machine_power_off(void)
108{ 107{
109 extern void enter_deep_standby(void); 108#if 0
109 /* Disable watchdog timer */
110 ctrl_outl(0xa5000000, WTCSR);
111 /* Configure deep standby on sleep */
112 ctrl_outl(0x03, STBCR);
113#endif
114
115 __asm__ __volatile__ (
116 "sleep\n\t"
117 "synci\n\t"
118 "nop;nop;nop;nop\n\t"
119 );
110 120
111 enter_deep_standby(); 121 panic("Unexpected wakeup!\n");
112} 122}
113 123
114void (*pm_power_off)(void) = machine_power_off; 124void (*pm_power_off)(void) = machine_power_off;
@@ -411,19 +421,22 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
411 */ 421 */
412void exit_thread(void) 422void exit_thread(void)
413{ 423{
414 /* See arch/sparc/kernel/process.c for the precedent for doing this -- RPC. 424 /*
415 425 * See arch/sparc/kernel/process.c for the precedent for doing
416 The SH-5 FPU save/restore approach relies on last_task_used_math 426 * this -- RPC.
417 pointing to a live task_struct. When another task tries to use the 427 *
418 FPU for the 1st time, the FPUDIS trap handling (see 428 * The SH-5 FPU save/restore approach relies on
419 arch/sh64/kernel/fpu.c) will save the existing FPU state to the 429 * last_task_used_math pointing to a live task_struct. When
420 FP regs field within last_task_used_math before re-loading the new 430 * another task tries to use the FPU for the 1st time, the FPUDIS
421 task's FPU state (or initialising it if the FPU has been used 431 * trap handling (see arch/sh/kernel/cpu/sh5/fpu.c) will save the
422 before). So if last_task_used_math is stale, and its page has already been 432 * existing FPU state to the FP regs field within
423 re-allocated for another use, the consequences are rather grim. Unless we 433 * last_task_used_math before re-loading the new task's FPU state
424 null it here, there is no other path through which it would get safely 434 * (or initialising it if the FPU has been used before). So if
425 nulled. */ 435 * last_task_used_math is stale, and its page has already been
426 436 * re-allocated for another use, the consequences are rather
437 * grim. Unless we null it here, there is no other path through
438 * which it would get safely nulled.
439 */
427#ifdef CONFIG_SH_FPU 440#ifdef CONFIG_SH_FPU
428 if (last_task_used_math == current) { 441 if (last_task_used_math == current) {
429 last_task_used_math = NULL; 442 last_task_used_math = NULL;
@@ -469,9 +482,9 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
469 fpvalid = !!tsk_used_math(tsk); 482 fpvalid = !!tsk_used_math(tsk);
470 if (fpvalid) { 483 if (fpvalid) {
471 if (current == last_task_used_math) { 484 if (current == last_task_used_math) {
472 grab_fpu(); 485 enable_fpu();
473 fpsave(&tsk->thread.fpu.hard); 486 save_fpu(tsk, regs);
474 release_fpu(); 487 disable_fpu();
475 last_task_used_math = 0; 488 last_task_used_math = 0;
476 regs->sr |= SR_FD; 489 regs->sr |= SR_FD;
477 } 490 }
@@ -496,9 +509,9 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
496 509
497#ifdef CONFIG_SH_FPU 510#ifdef CONFIG_SH_FPU
498 if(last_task_used_math == current) { 511 if(last_task_used_math == current) {
499 grab_fpu(); 512 enable_fpu();
500 fpsave(&current->thread.fpu.hard); 513 save_fpu(current, regs);
501 release_fpu(); 514 disable_fpu();
502 last_task_used_math = NULL; 515 last_task_used_math = NULL;
503 regs->sr |= SR_FD; 516 regs->sr |= SR_FD;
504 } 517 }
@@ -665,17 +678,14 @@ asids_proc_info(char *buf, char **start, off_t fpos, int length, int *eof, void
665 read_lock(&tasklist_lock); 678 read_lock(&tasklist_lock);
666 for_each_process(p) { 679 for_each_process(p) {
667 int pid = p->pid; 680 int pid = p->pid;
668 struct mm_struct *mm; 681
669 if (!pid) continue; 682 if (!pid)
670 mm = p->mm; 683 continue;
671 if (mm) { 684 if (p->mm)
672 unsigned long asid, context; 685 len += sprintf(buf+len, "%5d : %02lx\n", pid,
673 context = mm->context; 686 asid_cache(smp_processor_id()));
674 asid = (context & 0xff); 687 else
675 len += sprintf(buf+len, "%5d : %02lx\n", pid, asid);
676 } else {
677 len += sprintf(buf+len, "%5d : (none)\n", pid); 688 len += sprintf(buf+len, "%5d : (none)\n", pid);
678 }
679 } 689 }
680 read_unlock(&tasklist_lock); 690 read_unlock(&tasklist_lock);
681 *eof = 1; 691 *eof = 1;
diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace_32.c
index ac725f0aeb72..ce0664a58b49 100644
--- a/arch/sh/kernel/ptrace.c
+++ b/arch/sh/kernel/ptrace_32.c
@@ -6,7 +6,7 @@
6 * edited by Linus Torvalds 6 * edited by Linus Torvalds
7 * 7 *
8 * SuperH version: Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka 8 * SuperH version: Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka
9 * 9 * Audit support: Yuichi Nakamura <ynakam@hitachisoft.jp>
10 */ 10 */
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/sched.h> 12#include <linux/sched.h>
@@ -19,6 +19,7 @@
19#include <linux/security.h> 19#include <linux/security.h>
20#include <linux/signal.h> 20#include <linux/signal.h>
21#include <linux/io.h> 21#include <linux/io.h>
22#include <linux/audit.h>
22#include <asm/uaccess.h> 23#include <asm/uaccess.h>
23#include <asm/pgtable.h> 24#include <asm/pgtable.h>
24#include <asm/system.h> 25#include <asm/system.h>
@@ -248,15 +249,20 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
248 return ret; 249 return ret;
249} 250}
250 251
251asmlinkage void do_syscall_trace(void) 252asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
252{ 253{
253 struct task_struct *tsk = current; 254 struct task_struct *tsk = current;
254 255
256 if (unlikely(current->audit_context) && entryexit)
257 audit_syscall_exit(AUDITSC_RESULT(regs->regs[0]),
258 regs->regs[0]);
259
255 if (!test_thread_flag(TIF_SYSCALL_TRACE) && 260 if (!test_thread_flag(TIF_SYSCALL_TRACE) &&
256 !test_thread_flag(TIF_SINGLESTEP)) 261 !test_thread_flag(TIF_SINGLESTEP))
257 return; 262 goto out;
258 if (!(tsk->ptrace & PT_PTRACED)) 263 if (!(tsk->ptrace & PT_PTRACED))
259 return; 264 goto out;
265
260 /* the 0x80 provides a way for the tracing parent to distinguish 266 /* the 0x80 provides a way for the tracing parent to distinguish
261 between a syscall stop and SIGTRAP delivery */ 267 between a syscall stop and SIGTRAP delivery */
262 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) && 268 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) &&
@@ -271,4 +277,11 @@ asmlinkage void do_syscall_trace(void)
271 send_sig(tsk->exit_code, tsk, 1); 277 send_sig(tsk->exit_code, tsk, 1);
272 tsk->exit_code = 0; 278 tsk->exit_code = 0;
273 } 279 }
280
281out:
282 if (unlikely(current->audit_context) && !entryexit)
283 audit_syscall_entry(AUDIT_ARCH_SH, regs->regs[3],
284 regs->regs[4], regs->regs[5],
285 regs->regs[6], regs->regs[7]);
286
274} 287}
diff --git a/arch/sh64/kernel/ptrace.c b/arch/sh/kernel/ptrace_64.c
index 8a2d339cf760..f6fbdfa6876d 100644
--- a/arch/sh64/kernel/ptrace.c
+++ b/arch/sh/kernel/ptrace_64.c
@@ -1,12 +1,8 @@
1/* 1/*
2 * This file is subject to the terms and conditions of the GNU General Public 2 * arch/sh/kernel/ptrace_64.c
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * arch/sh64/kernel/ptrace.c
7 * 3 *
8 * Copyright (C) 2000, 2001 Paolo Alberelli 4 * Copyright (C) 2000, 2001 Paolo Alberelli
9 * Copyright (C) 2003 Paul Mundt 5 * Copyright (C) 2003 - 2007 Paul Mundt
10 * 6 *
11 * Started from SH3/4 version: 7 * Started from SH3/4 version:
12 * SuperH version: Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka 8 * SuperH version: Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka
@@ -15,8 +11,10 @@
15 * By Ross Biro 1/23/92 11 * By Ross Biro 1/23/92
16 * edited by Linus Torvalds 12 * edited by Linus Torvalds
17 * 13 *
14 * This file is subject to the terms and conditions of the GNU General Public
15 * License. See the file "COPYING" in the main directory of this archive
16 * for more details.
18 */ 17 */
19
20#include <linux/kernel.h> 18#include <linux/kernel.h>
21#include <linux/rwsem.h> 19#include <linux/rwsem.h>
22#include <linux/sched.h> 20#include <linux/sched.h>
@@ -28,7 +26,7 @@
28#include <linux/user.h> 26#include <linux/user.h>
29#include <linux/signal.h> 27#include <linux/signal.h>
30#include <linux/syscalls.h> 28#include <linux/syscalls.h>
31 29#include <linux/audit.h>
32#include <asm/io.h> 30#include <asm/io.h>
33#include <asm/uaccess.h> 31#include <asm/uaccess.h>
34#include <asm/pgtable.h> 32#include <asm/pgtable.h>
@@ -74,9 +72,9 @@ get_fpu_long(struct task_struct *task, unsigned long addr)
74 } 72 }
75 73
76 if (last_task_used_math == task) { 74 if (last_task_used_math == task) {
77 grab_fpu(); 75 enable_fpu();
78 fpsave(&task->thread.fpu.hard); 76 save_fpu(task, regs);
79 release_fpu(); 77 disable_fpu();
80 last_task_used_math = 0; 78 last_task_used_math = 0;
81 regs->sr |= SR_FD; 79 regs->sr |= SR_FD;
82 } 80 }
@@ -110,9 +108,9 @@ put_fpu_long(struct task_struct *task, unsigned long addr, unsigned long data)
110 fpinit(&task->thread.fpu.hard); 108 fpinit(&task->thread.fpu.hard);
111 set_stopped_child_used_math(task); 109 set_stopped_child_used_math(task);
112 } else if (last_task_used_math == task) { 110 } else if (last_task_used_math == task) {
113 grab_fpu(); 111 enable_fpu();
114 fpsave(&task->thread.fpu.hard); 112 save_fpu(task, regs);
115 release_fpu(); 113 disable_fpu();
116 last_task_used_math = 0; 114 last_task_used_math = 0;
117 regs->sr |= SR_FD; 115 regs->sr |= SR_FD;
118 } 116 }
@@ -253,7 +251,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
253 251
254asmlinkage int sh64_ptrace(long request, long pid, long addr, long data) 252asmlinkage int sh64_ptrace(long request, long pid, long addr, long data)
255{ 253{
256 extern void poke_real_address_q(unsigned long long addr, unsigned long long data);
257#define WPC_DBRMODE 0x0d104008 254#define WPC_DBRMODE 0x0d104008
258 static int first_call = 1; 255 static int first_call = 1;
259 256
@@ -275,17 +272,23 @@ asmlinkage int sh64_ptrace(long request, long pid, long addr, long data)
275 return sys_ptrace(request, pid, addr, data); 272 return sys_ptrace(request, pid, addr, data);
276} 273}
277 274
278asmlinkage void syscall_trace(void) 275asmlinkage void syscall_trace(struct pt_regs *regs, int entryexit)
279{ 276{
280 struct task_struct *tsk = current; 277 struct task_struct *tsk = current;
281 278
282 if (!test_thread_flag(TIF_SYSCALL_TRACE)) 279 if (unlikely(current->audit_context) && entryexit)
283 return; 280 audit_syscall_exit(AUDITSC_RESULT(regs->regs[9]),
281 regs->regs[9]);
282
283 if (!test_thread_flag(TIF_SYSCALL_TRACE) &&
284 !test_thread_flag(TIF_SINGLESTEP))
285 goto out;
284 if (!(tsk->ptrace & PT_PTRACED)) 286 if (!(tsk->ptrace & PT_PTRACED))
285 return; 287 goto out;
288
289 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) &&
290 !test_thread_flag(TIF_SINGLESTEP) ? 0x80 : 0));
286 291
287 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
288 ? 0x80 : 0));
289 /* 292 /*
290 * this isn't the same as continuing with a signal, but it will do 293 * this isn't the same as continuing with a signal, but it will do
291 * for normal use. strace only continues with a signal if the 294 * for normal use. strace only continues with a signal if the
@@ -295,6 +298,12 @@ asmlinkage void syscall_trace(void)
295 send_sig(tsk->exit_code, tsk, 1); 298 send_sig(tsk->exit_code, tsk, 1);
296 tsk->exit_code = 0; 299 tsk->exit_code = 0;
297 } 300 }
301
302out:
303 if (unlikely(current->audit_context) && !entryexit)
304 audit_syscall_entry(AUDIT_ARCH_SH, regs->regs[1],
305 regs->regs[2], regs->regs[3],
306 regs->regs[4], regs->regs[5]);
298} 307}
299 308
300/* Called with interrupts disabled */ 309/* Called with interrupts disabled */
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 4156aac8c27d..855cdf9d85b1 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -26,6 +26,7 @@
26#include <asm/uaccess.h> 26#include <asm/uaccess.h>
27#include <asm/io.h> 27#include <asm/io.h>
28#include <asm/page.h> 28#include <asm/page.h>
29#include <asm/elf.h>
29#include <asm/sections.h> 30#include <asm/sections.h>
30#include <asm/irq.h> 31#include <asm/irq.h>
31#include <asm/setup.h> 32#include <asm/setup.h>
@@ -78,12 +79,25 @@ EXPORT_SYMBOL(memory_start);
78unsigned long memory_end = 0; 79unsigned long memory_end = 0;
79EXPORT_SYMBOL(memory_end); 80EXPORT_SYMBOL(memory_end);
80 81
82int l1i_cache_shape, l1d_cache_shape, l2_cache_shape;
83
81static int __init early_parse_mem(char *p) 84static int __init early_parse_mem(char *p)
82{ 85{
83 unsigned long size; 86 unsigned long size;
84 87
85 memory_start = (unsigned long)PAGE_OFFSET+__MEMORY_START; 88 memory_start = (unsigned long)__va(__MEMORY_START);
86 size = memparse(p, &p); 89 size = memparse(p, &p);
90
91 if (size > __MEMORY_SIZE) {
92 static char msg[] __initdata = KERN_ERR
93 "Using mem= to increase the size of kernel memory "
94 "is not allowed.\n"
95 " Recompile the kernel with the correct value for "
96 "CONFIG_MEMORY_SIZE.\n";
97 printk(msg);
98 return 0;
99 }
100
87 memory_end = memory_start + size; 101 memory_end = memory_start + size;
88 102
89 return 0; 103 return 0;
@@ -243,7 +257,7 @@ void __init setup_arch(char **cmdline_p)
243 data_resource.start = virt_to_phys(_etext); 257 data_resource.start = virt_to_phys(_etext);
244 data_resource.end = virt_to_phys(_edata)-1; 258 data_resource.end = virt_to_phys(_edata)-1;
245 259
246 memory_start = (unsigned long)PAGE_OFFSET+__MEMORY_START; 260 memory_start = (unsigned long)__va(__MEMORY_START);
247 if (!memory_end) 261 if (!memory_end)
248 memory_end = memory_start + __MEMORY_SIZE; 262 memory_end = memory_start + __MEMORY_SIZE;
249 263
@@ -294,20 +308,23 @@ void __init setup_arch(char **cmdline_p)
294} 308}
295 309
296static const char *cpu_name[] = { 310static const char *cpu_name[] = {
311 [CPU_SH7203] = "SH7203", [CPU_SH7263] = "SH7263",
297 [CPU_SH7206] = "SH7206", [CPU_SH7619] = "SH7619", 312 [CPU_SH7206] = "SH7206", [CPU_SH7619] = "SH7619",
298 [CPU_SH7705] = "SH7705", [CPU_SH7706] = "SH7706", 313 [CPU_SH7705] = "SH7705", [CPU_SH7706] = "SH7706",
299 [CPU_SH7707] = "SH7707", [CPU_SH7708] = "SH7708", 314 [CPU_SH7707] = "SH7707", [CPU_SH7708] = "SH7708",
300 [CPU_SH7709] = "SH7709", [CPU_SH7710] = "SH7710", 315 [CPU_SH7709] = "SH7709", [CPU_SH7710] = "SH7710",
301 [CPU_SH7712] = "SH7712", [CPU_SH7720] = "SH7720", 316 [CPU_SH7712] = "SH7712", [CPU_SH7720] = "SH7720",
302 [CPU_SH7729] = "SH7729", [CPU_SH7750] = "SH7750", 317 [CPU_SH7721] = "SH7721", [CPU_SH7729] = "SH7729",
303 [CPU_SH7750S] = "SH7750S", [CPU_SH7750R] = "SH7750R", 318 [CPU_SH7750] = "SH7750", [CPU_SH7750S] = "SH7750S",
304 [CPU_SH7751] = "SH7751", [CPU_SH7751R] = "SH7751R", 319 [CPU_SH7750R] = "SH7750R", [CPU_SH7751] = "SH7751",
305 [CPU_SH7760] = "SH7760", 320 [CPU_SH7751R] = "SH7751R", [CPU_SH7760] = "SH7760",
306 [CPU_SH4_202] = "SH4-202", [CPU_SH4_501] = "SH4-501", 321 [CPU_SH4_202] = "SH4-202", [CPU_SH4_501] = "SH4-501",
307 [CPU_SH7770] = "SH7770", [CPU_SH7780] = "SH7780", 322 [CPU_SH7763] = "SH7763", [CPU_SH7770] = "SH7770",
308 [CPU_SH7781] = "SH7781", [CPU_SH7343] = "SH7343", 323 [CPU_SH7780] = "SH7780", [CPU_SH7781] = "SH7781",
309 [CPU_SH7785] = "SH7785", [CPU_SH7722] = "SH7722", 324 [CPU_SH7343] = "SH7343", [CPU_SH7785] = "SH7785",
310 [CPU_SHX3] = "SH-X3", [CPU_SH_NONE] = "Unknown" 325 [CPU_SH7722] = "SH7722", [CPU_SHX3] = "SH-X3",
326 [CPU_SH5_101] = "SH5-101", [CPU_SH5_103] = "SH5-103",
327 [CPU_SH_NONE] = "Unknown"
311}; 328};
312 329
313const char *get_cpu_subtype(struct sh_cpuinfo *c) 330const char *get_cpu_subtype(struct sh_cpuinfo *c)
@@ -410,7 +427,7 @@ static void *c_next(struct seq_file *m, void *v, loff_t *pos)
410static void c_stop(struct seq_file *m, void *v) 427static void c_stop(struct seq_file *m, void *v)
411{ 428{
412} 429}
413struct seq_operations cpuinfo_op = { 430const struct seq_operations cpuinfo_op = {
414 .start = c_start, 431 .start = c_start,
415 .next = c_next, 432 .next = c_next,
416 .stop = c_stop, 433 .stop = c_stop,
diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms_32.c
index e1a6de9088b5..e1a6de9088b5 100644
--- a/arch/sh/kernel/sh_ksyms.c
+++ b/arch/sh/kernel/sh_ksyms_32.c
diff --git a/arch/sh64/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms_64.c
index b1705acc8e64..8004c38d3d37 100644
--- a/arch/sh64/kernel/sh_ksyms.c
+++ b/arch/sh/kernel/sh_ksyms_64.c
@@ -1,14 +1,12 @@
1/* 1/*
2 * This file is subject to the terms and conditions of the GNU General Public 2 * arch/sh/kernel/sh_ksyms_64.c
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * arch/sh64/kernel/sh_ksyms.c
7 * 3 *
8 * Copyright (C) 2000, 2001 Paolo Alberelli 4 * Copyright (C) 2000, 2001 Paolo Alberelli
9 * 5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
10 */ 9 */
11
12#include <linux/rwsem.h> 10#include <linux/rwsem.h>
13#include <linux/module.h> 11#include <linux/module.h>
14#include <linux/smp.h> 12#include <linux/smp.h>
@@ -18,7 +16,6 @@
18#include <linux/in6.h> 16#include <linux/in6.h>
19#include <linux/interrupt.h> 17#include <linux/interrupt.h>
20#include <linux/screen_info.h> 18#include <linux/screen_info.h>
21
22#include <asm/semaphore.h> 19#include <asm/semaphore.h>
23#include <asm/processor.h> 20#include <asm/processor.h>
24#include <asm/uaccess.h> 21#include <asm/uaccess.h>
@@ -47,12 +44,8 @@ EXPORT_SYMBOL(__put_user_asm_l);
47EXPORT_SYMBOL(__get_user_asm_l); 44EXPORT_SYMBOL(__get_user_asm_l);
48EXPORT_SYMBOL(__copy_user); 45EXPORT_SYMBOL(__copy_user);
49EXPORT_SYMBOL(memcpy); 46EXPORT_SYMBOL(memcpy);
50EXPORT_SYMBOL(udelay);
51EXPORT_SYMBOL(__udelay); 47EXPORT_SYMBOL(__udelay);
52EXPORT_SYMBOL(ndelay);
53EXPORT_SYMBOL(__ndelay); 48EXPORT_SYMBOL(__ndelay);
54EXPORT_SYMBOL(flush_dcache_page);
55EXPORT_SYMBOL(sh64_page_clear);
56 49
57/* Ugh. These come in from libgcc.a at link time. */ 50/* Ugh. These come in from libgcc.a at link time. */
58#define DECLARE_EXPORT(name) extern void name(void);EXPORT_SYMBOL(name) 51#define DECLARE_EXPORT(name) extern void name(void);EXPORT_SYMBOL(name)
diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal_32.c
index ca754fd42437..f6b5fbfe75c4 100644
--- a/arch/sh/kernel/signal.c
+++ b/arch/sh/kernel/signal_32.c
@@ -507,24 +507,6 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
507 ctrl_inw(regs->pc - 4)); 507 ctrl_inw(regs->pc - 4));
508 break; 508 break;
509 } 509 }
510#ifdef CONFIG_GUSA
511 } else {
512 /* gUSA handling */
513 preempt_disable();
514
515 if (regs->regs[15] >= 0xc0000000) {
516 int offset = (int)regs->regs[15];
517
518 /* Reset stack pointer: clear critical region mark */
519 regs->regs[15] = regs->regs[1];
520 if (regs->pc < regs->regs[0])
521 /* Go to rewind point #1 */
522 regs->pc = regs->regs[0] + offset -
523 instruction_size(ctrl_inw(regs->pc-4));
524 }
525
526 preempt_enable_no_resched();
527#endif
528 } 510 }
529 511
530 /* Set up the stack frame */ 512 /* Set up the stack frame */
diff --git a/arch/sh64/kernel/signal.c b/arch/sh/kernel/signal_64.c
index 79fc48cf54c6..80bde19d445b 100644
--- a/arch/sh64/kernel/signal.c
+++ b/arch/sh/kernel/signal_64.c
@@ -1,16 +1,13 @@
1/* 1/*
2 * This file is subject to the terms and conditions of the GNU General Public 2 * arch/sh/kernel/signal_64.c
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * arch/sh64/kernel/signal.c
7 * 3 *
8 * Copyright (C) 2000, 2001 Paolo Alberelli 4 * Copyright (C) 2000, 2001 Paolo Alberelli
9 * Copyright (C) 2003 Paul Mundt 5 * Copyright (C) 2003 Paul Mundt
10 * Copyright (C) 2004 Richard Curnow 6 * Copyright (C) 2004 Richard Curnow
11 * 7 *
12 * Started from sh version. 8 * This file is subject to the terms and conditions of the GNU General Public
13 * 9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
14 */ 11 */
15#include <linux/rwsem.h> 12#include <linux/rwsem.h>
16#include <linux/sched.h> 13#include <linux/sched.h>
@@ -28,7 +25,7 @@
28#include <asm/ucontext.h> 25#include <asm/ucontext.h>
29#include <asm/uaccess.h> 26#include <asm/uaccess.h>
30#include <asm/pgtable.h> 27#include <asm/pgtable.h>
31 28#include <asm/cacheflush.h>
32 29
33#define REG_RET 9 30#define REG_RET 9
34#define REG_ARG1 2 31#define REG_ARG1 2
@@ -211,9 +208,9 @@ setup_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc)
211 return err; 208 return err;
212 209
213 if (current == last_task_used_math) { 210 if (current == last_task_used_math) {
214 grab_fpu(); 211 enable_fpu();
215 fpsave(&current->thread.fpu.hard); 212 save_fpu(current, regs);
216 release_fpu(); 213 disable_fpu();
217 last_task_used_math = NULL; 214 last_task_used_math = NULL;
218 regs->sr |= SR_FD; 215 regs->sr |= SR_FD;
219 } 216 }
@@ -227,10 +224,14 @@ setup_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc)
227#else 224#else
228static inline int 225static inline int
229restore_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc) 226restore_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc)
230{} 227{
228 return 0;
229}
231static inline int 230static inline int
232setup_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc) 231setup_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc)
233{} 232{
233 return 0;
234}
234#endif 235#endif
235 236
236static int 237static int
@@ -477,7 +478,7 @@ static void setup_frame(int sig, struct k_sigaction *ka,
477 goto give_sigsegv; 478 goto give_sigsegv;
478 479
479 /* Cohere the trampoline with the I-cache. */ 480 /* Cohere the trampoline with the I-cache. */
480 flush_cache_sigtramp(DEREF_REG_PR-1, DEREF_REG_PR-1+16); 481 flush_cache_sigtramp(DEREF_REG_PR-1);
481 } 482 }
482 483
483 /* 484 /*
diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c
index d545a686a201..59cd2859ce9b 100644
--- a/arch/sh/kernel/sys_sh.c
+++ b/arch/sh/kernel/sys_sh.c
@@ -7,7 +7,6 @@
7 * 7 *
8 * Taken from i386 version. 8 * Taken from i386 version.
9 */ 9 */
10
11#include <linux/errno.h> 10#include <linux/errno.h>
12#include <linux/sched.h> 11#include <linux/sched.h>
13#include <linux/mm.h> 12#include <linux/mm.h>
@@ -27,28 +26,7 @@
27#include <asm/uaccess.h> 26#include <asm/uaccess.h>
28#include <asm/unistd.h> 27#include <asm/unistd.h>
29 28
30/*
31 * sys_pipe() is the normal C calling standard for creating
32 * a pipe. It's not the way Unix traditionally does this, though.
33 */
34asmlinkage int sys_pipe(unsigned long r4, unsigned long r5,
35 unsigned long r6, unsigned long r7,
36 struct pt_regs __regs)
37{
38 struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
39 int fd[2];
40 int error;
41
42 error = do_pipe(fd);
43 if (!error) {
44 regs->regs[1] = fd[1];
45 return fd[0];
46 }
47 return error;
48}
49
50unsigned long shm_align_mask = PAGE_SIZE - 1; /* Sane caches */ 29unsigned long shm_align_mask = PAGE_SIZE - 1; /* Sane caches */
51
52EXPORT_SYMBOL(shm_align_mask); 30EXPORT_SYMBOL(shm_align_mask);
53 31
54#ifdef CONFIG_MMU 32#ifdef CONFIG_MMU
@@ -140,7 +118,7 @@ full_search:
140#endif /* CONFIG_MMU */ 118#endif /* CONFIG_MMU */
141 119
142static inline long 120static inline long
143do_mmap2(unsigned long addr, unsigned long len, unsigned long prot, 121do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
144 unsigned long flags, int fd, unsigned long pgoff) 122 unsigned long flags, int fd, unsigned long pgoff)
145{ 123{
146 int error = -EBADF; 124 int error = -EBADF;
@@ -195,12 +173,13 @@ asmlinkage int sys_ipc(uint call, int first, int second,
195 if (call <= SEMCTL) 173 if (call <= SEMCTL)
196 switch (call) { 174 switch (call) {
197 case SEMOP: 175 case SEMOP:
198 return sys_semtimedop(first, (struct sembuf __user *)ptr, 176 return sys_semtimedop(first,
177 (struct sembuf __user *)ptr,
199 second, NULL); 178 second, NULL);
200 case SEMTIMEDOP: 179 case SEMTIMEDOP:
201 return sys_semtimedop(first, (struct sembuf __user *)ptr, 180 return sys_semtimedop(first,
202 second, 181 (struct sembuf __user *)ptr, second,
203 (const struct timespec __user *)fifth); 182 (const struct timespec __user *)fifth);
204 case SEMGET: 183 case SEMGET:
205 return sys_semget (first, second, third); 184 return sys_semget (first, second, third);
206 case SEMCTL: { 185 case SEMCTL: {
@@ -215,25 +194,28 @@ asmlinkage int sys_ipc(uint call, int first, int second,
215 return -EINVAL; 194 return -EINVAL;
216 } 195 }
217 196
218 if (call <= MSGCTL) 197 if (call <= MSGCTL)
219 switch (call) { 198 switch (call) {
220 case MSGSND: 199 case MSGSND:
221 return sys_msgsnd (first, (struct msgbuf __user *) ptr, 200 return sys_msgsnd (first, (struct msgbuf __user *) ptr,
222 second, third); 201 second, third);
223 case MSGRCV: 202 case MSGRCV:
224 switch (version) { 203 switch (version) {
225 case 0: { 204 case 0:
205 {
226 struct ipc_kludge tmp; 206 struct ipc_kludge tmp;
207
227 if (!ptr) 208 if (!ptr)
228 return -EINVAL; 209 return -EINVAL;
229 210
230 if (copy_from_user(&tmp, 211 if (copy_from_user(&tmp,
231 (struct ipc_kludge __user *) ptr, 212 (struct ipc_kludge __user *) ptr,
232 sizeof (tmp))) 213 sizeof (tmp)))
233 return -EFAULT; 214 return -EFAULT;
215
234 return sys_msgrcv (first, tmp.msgp, second, 216 return sys_msgrcv (first, tmp.msgp, second,
235 tmp.msgtyp, third); 217 tmp.msgtyp, third);
236 } 218 }
237 default: 219 default:
238 return sys_msgrcv (first, 220 return sys_msgrcv (first,
239 (struct msgbuf __user *) ptr, 221 (struct msgbuf __user *) ptr,
@@ -247,7 +229,7 @@ asmlinkage int sys_ipc(uint call, int first, int second,
247 default: 229 default:
248 return -EINVAL; 230 return -EINVAL;
249 } 231 }
250 if (call <= SHMCTL) 232 if (call <= SHMCTL)
251 switch (call) { 233 switch (call) {
252 case SHMAT: 234 case SHMAT:
253 switch (version) { 235 switch (version) {
@@ -265,7 +247,7 @@ asmlinkage int sys_ipc(uint call, int first, int second,
265 return do_shmat (first, (char __user *) ptr, 247 return do_shmat (first, (char __user *) ptr,
266 second, (ulong *) third); 248 second, (ulong *) third);
267 } 249 }
268 case SHMDT: 250 case SHMDT:
269 return sys_shmdt ((char __user *)ptr); 251 return sys_shmdt ((char __user *)ptr);
270 case SHMGET: 252 case SHMGET:
271 return sys_shmget (first, second, third); 253 return sys_shmget (first, second, third);
@@ -275,7 +257,7 @@ asmlinkage int sys_ipc(uint call, int first, int second,
275 default: 257 default:
276 return -EINVAL; 258 return -EINVAL;
277 } 259 }
278 260
279 return -EINVAL; 261 return -EINVAL;
280} 262}
281 263
@@ -289,49 +271,3 @@ asmlinkage int sys_uname(struct old_utsname * name)
289 up_read(&uts_sem); 271 up_read(&uts_sem);
290 return err?-EFAULT:0; 272 return err?-EFAULT:0;
291} 273}
292
293asmlinkage ssize_t sys_pread_wrapper(unsigned int fd, char * buf,
294 size_t count, long dummy, loff_t pos)
295{
296 return sys_pread64(fd, buf, count, pos);
297}
298
299asmlinkage ssize_t sys_pwrite_wrapper(unsigned int fd, const char * buf,
300 size_t count, long dummy, loff_t pos)
301{
302 return sys_pwrite64(fd, buf, count, pos);
303}
304
305asmlinkage int sys_fadvise64_64_wrapper(int fd, u32 offset0, u32 offset1,
306 u32 len0, u32 len1, int advice)
307{
308#ifdef __LITTLE_ENDIAN__
309 return sys_fadvise64_64(fd, (u64)offset1 << 32 | offset0,
310 (u64)len1 << 32 | len0, advice);
311#else
312 return sys_fadvise64_64(fd, (u64)offset0 << 32 | offset1,
313 (u64)len0 << 32 | len1, advice);
314#endif
315}
316
317#if defined(CONFIG_CPU_SH2) || defined(CONFIG_CPU_SH2A)
318#define SYSCALL_ARG3 "trapa #0x23"
319#else
320#define SYSCALL_ARG3 "trapa #0x13"
321#endif
322
323/*
324 * Do a system call from kernel instead of calling sys_execve so we
325 * end up with proper pt_regs.
326 */
327int kernel_execve(const char *filename, char *const argv[], char *const envp[])
328{
329 register long __sc0 __asm__ ("r3") = __NR_execve;
330 register long __sc4 __asm__ ("r4") = (long) filename;
331 register long __sc5 __asm__ ("r5") = (long) argv;
332 register long __sc6 __asm__ ("r6") = (long) envp;
333 __asm__ __volatile__ (SYSCALL_ARG3 : "=z" (__sc0)
334 : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6)
335 : "memory");
336 return __sc0;
337}
diff --git a/arch/sh/kernel/sys_sh32.c b/arch/sh/kernel/sys_sh32.c
new file mode 100644
index 000000000000..125e493ead82
--- /dev/null
+++ b/arch/sh/kernel/sys_sh32.c
@@ -0,0 +1,84 @@
1#include <linux/errno.h>
2#include <linux/sched.h>
3#include <linux/mm.h>
4#include <linux/smp.h>
5#include <linux/sem.h>
6#include <linux/msg.h>
7#include <linux/shm.h>
8#include <linux/stat.h>
9#include <linux/syscalls.h>
10#include <linux/mman.h>
11#include <linux/file.h>
12#include <linux/utsname.h>
13#include <linux/module.h>
14#include <linux/fs.h>
15#include <linux/ipc.h>
16#include <asm/cacheflush.h>
17#include <asm/uaccess.h>
18#include <asm/unistd.h>
19
20/*
21 * sys_pipe() is the normal C calling standard for creating
22 * a pipe. It's not the way Unix traditionally does this, though.
23 */
24asmlinkage int sys_pipe(unsigned long r4, unsigned long r5,
25 unsigned long r6, unsigned long r7,
26 struct pt_regs __regs)
27{
28 struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
29 int fd[2];
30 int error;
31
32 error = do_pipe(fd);
33 if (!error) {
34 regs->regs[1] = fd[1];
35 return fd[0];
36 }
37 return error;
38}
39
40asmlinkage ssize_t sys_pread_wrapper(unsigned int fd, char * buf,
41 size_t count, long dummy, loff_t pos)
42{
43 return sys_pread64(fd, buf, count, pos);
44}
45
46asmlinkage ssize_t sys_pwrite_wrapper(unsigned int fd, const char * buf,
47 size_t count, long dummy, loff_t pos)
48{
49 return sys_pwrite64(fd, buf, count, pos);
50}
51
52asmlinkage int sys_fadvise64_64_wrapper(int fd, u32 offset0, u32 offset1,
53 u32 len0, u32 len1, int advice)
54{
55#ifdef __LITTLE_ENDIAN__
56 return sys_fadvise64_64(fd, (u64)offset1 << 32 | offset0,
57 (u64)len1 << 32 | len0, advice);
58#else
59 return sys_fadvise64_64(fd, (u64)offset0 << 32 | offset1,
60 (u64)len0 << 32 | len1, advice);
61#endif
62}
63
64#if defined(CONFIG_CPU_SH2) || defined(CONFIG_CPU_SH2A)
65#define SYSCALL_ARG3 "trapa #0x23"
66#else
67#define SYSCALL_ARG3 "trapa #0x13"
68#endif
69
70/*
71 * Do a system call from kernel instead of calling sys_execve so we
72 * end up with proper pt_regs.
73 */
74int kernel_execve(const char *filename, char *const argv[], char *const envp[])
75{
76 register long __sc0 __asm__ ("r3") = __NR_execve;
77 register long __sc4 __asm__ ("r4") = (long) filename;
78 register long __sc5 __asm__ ("r5") = (long) argv;
79 register long __sc6 __asm__ ("r6") = (long) envp;
80 __asm__ __volatile__ (SYSCALL_ARG3 : "=z" (__sc0)
81 : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6)
82 : "memory");
83 return __sc0;
84}
diff --git a/arch/sh/kernel/sys_sh64.c b/arch/sh/kernel/sys_sh64.c
new file mode 100644
index 000000000000..578004d71e02
--- /dev/null
+++ b/arch/sh/kernel/sys_sh64.c
@@ -0,0 +1,66 @@
1/*
2 * arch/sh/kernel/sys_sh64.c
3 *
4 * Copyright (C) 2000, 2001 Paolo Alberelli
5 *
6 * This file contains various random system calls that
7 * have a non-standard calling sequence on the Linux/SH5
8 * platform.
9 *
10 * This file is subject to the terms and conditions of the GNU General Public
11 * License. See the file "COPYING" in the main directory of this archive
12 * for more details.
13 */
14#include <linux/errno.h>
15#include <linux/rwsem.h>
16#include <linux/sched.h>
17#include <linux/mm.h>
18#include <linux/fs.h>
19#include <linux/smp.h>
20#include <linux/sem.h>
21#include <linux/msg.h>
22#include <linux/shm.h>
23#include <linux/stat.h>
24#include <linux/mman.h>
25#include <linux/file.h>
26#include <linux/utsname.h>
27#include <linux/syscalls.h>
28#include <linux/ipc.h>
29#include <asm/uaccess.h>
30#include <asm/ptrace.h>
31#include <asm/unistd.h>
32
33/*
34 * sys_pipe() is the normal C calling standard for creating
35 * a pipe. It's not the way Unix traditionally does this, though.
36 */
37asmlinkage int sys_pipe(unsigned long * fildes)
38{
39 int fd[2];
40 int error;
41
42 error = do_pipe(fd);
43 if (!error) {
44 if (copy_to_user(fildes, fd, 2*sizeof(int)))
45 error = -EFAULT;
46 }
47 return error;
48}
49
50/*
51 * Do a system call from kernel instead of calling sys_execve so we
52 * end up with proper pt_regs.
53 */
54int kernel_execve(const char *filename, char *const argv[], char *const envp[])
55{
56 register unsigned long __sc0 __asm__ ("r9") = ((0x13 << 16) | __NR_execve);
57 register unsigned long __sc2 __asm__ ("r2") = (unsigned long) filename;
58 register unsigned long __sc3 __asm__ ("r3") = (unsigned long) argv;
59 register unsigned long __sc4 __asm__ ("r4") = (unsigned long) envp;
60 __asm__ __volatile__ ("trapa %1 !\t\t\t execve(%2,%3,%4)"
61 : "=r" (__sc0)
62 : "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4) );
63 __asm__ __volatile__ ("!dummy %0 %1 %2 %3"
64 : : "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4) : "memory");
65 return __sc0;
66}
diff --git a/arch/sh/kernel/syscalls.S b/arch/sh/kernel/syscalls_32.S
index 10bec45415ba..10bec45415ba 100644
--- a/arch/sh/kernel/syscalls.S
+++ b/arch/sh/kernel/syscalls_32.S
diff --git a/arch/sh64/kernel/syscalls.S b/arch/sh/kernel/syscalls_64.S
index abb94c05d07a..98a93efe3691 100644
--- a/arch/sh64/kernel/syscalls.S
+++ b/arch/sh/kernel/syscalls_64.S
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/sh64/kernel/syscalls.S 2 * arch/sh/kernel/syscalls_64.S
3 * 3 *
4 * Copyright (C) 2000, 2001 Paolo Alberelli 4 * Copyright (C) 2000, 2001 Paolo Alberelli
5 * Copyright (C) 2004 - 2007 Paul Mundt 5 * Copyright (C) 2004 - 2007 Paul Mundt
diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time_32.c
index a3a67d151e52..2bc04bfee738 100644
--- a/arch/sh/kernel/time.c
+++ b/arch/sh/kernel/time_32.c
@@ -174,7 +174,7 @@ int timer_resume(struct sys_device *dev)
174#endif 174#endif
175 175
176static struct sysdev_class timer_sysclass = { 176static struct sysdev_class timer_sysclass = {
177 set_kset_name("timer"), 177 .name = "timer",
178 .suspend = timer_suspend, 178 .suspend = timer_suspend,
179 .resume = timer_resume, 179 .resume = timer_resume,
180}; 180};
diff --git a/arch/sh64/kernel/time.c b/arch/sh/kernel/time_64.c
index 06f3c179e345..f819ba38a6ce 100644
--- a/arch/sh64/kernel/time.c
+++ b/arch/sh/kernel/time_64.c
@@ -1,20 +1,19 @@
1/* 1/*
2 * This file is subject to the terms and conditions of the GNU General Public 2 * arch/sh/kernel/time_64.c
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * arch/sh64/kernel/time.c
7 * 3 *
8 * Copyright (C) 2000, 2001 Paolo Alberelli 4 * Copyright (C) 2000, 2001 Paolo Alberelli
9 * Copyright (C) 2003, 2004 Paul Mundt 5 * Copyright (C) 2003 - 2007 Paul Mundt
10 * Copyright (C) 2003 Richard Curnow 6 * Copyright (C) 2003 Richard Curnow
11 * 7 *
12 * Original TMU/RTC code taken from sh version. 8 * Original TMU/RTC code taken from sh version.
13 * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka 9 * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka
14 * Some code taken from i386 version. 10 * Some code taken from i386 version.
15 * Copyright (C) 1991, 1992, 1995 Linus Torvalds 11 * Copyright (C) 1991, 1992, 1995 Linus Torvalds
12 *
13 * This file is subject to the terms and conditions of the GNU General Public
14 * License. See the file "COPYING" in the main directory of this archive
15 * for more details.
16 */ 16 */
17
18#include <linux/errno.h> 17#include <linux/errno.h>
19#include <linux/rwsem.h> 18#include <linux/rwsem.h>
20#include <linux/sched.h> 19#include <linux/sched.h>
@@ -30,37 +29,27 @@
30#include <linux/smp.h> 29#include <linux/smp.h>
31#include <linux/module.h> 30#include <linux/module.h>
32#include <linux/bcd.h> 31#include <linux/bcd.h>
33 32#include <linux/timex.h>
34#include <asm/registers.h> /* required by inline __asm__ stmt. */ 33#include <linux/irq.h>
35 34#include <linux/io.h>
35#include <linux/platform_device.h>
36#include <asm/cpu/registers.h> /* required by inline __asm__ stmt. */
37#include <asm/cpu/irq.h>
38#include <asm/addrspace.h>
36#include <asm/processor.h> 39#include <asm/processor.h>
37#include <asm/uaccess.h> 40#include <asm/uaccess.h>
38#include <asm/io.h>
39#include <asm/irq.h>
40#include <asm/delay.h> 41#include <asm/delay.h>
41 42
42#include <linux/timex.h>
43#include <linux/irq.h>
44#include <asm/hardware.h>
45
46#define TMU_TOCR_INIT 0x00 43#define TMU_TOCR_INIT 0x00
47#define TMU0_TCR_INIT 0x0020 44#define TMU0_TCR_INIT 0x0020
48#define TMU_TSTR_INIT 1 45#define TMU_TSTR_INIT 1
49#define TMU_TSTR_OFF 0 46#define TMU_TSTR_OFF 0
50 47
51/* RCR1 Bits */ 48/* Real Time Clock */
52#define RCR1_CF 0x80 /* Carry Flag */ 49#define RTC_BLOCK_OFF 0x01040000
53#define RCR1_CIE 0x10 /* Carry Interrupt Enable */ 50#define RTC_BASE PHYS_PERIPHERAL_BLOCK + RTC_BLOCK_OFF
54#define RCR1_AIE 0x08 /* Alarm Interrupt Enable */ 51#define RTC_RCR1_CIE 0x10 /* Carry Interrupt Enable */
55#define RCR1_AF 0x01 /* Alarm Flag */ 52#define RTC_RCR1 (rtc_base + 0x38)
56
57/* RCR2 Bits */
58#define RCR2_PEF 0x80 /* PEriodic interrupt Flag */
59#define RCR2_PESMASK 0x70 /* Periodic interrupt Set */
60#define RCR2_RTCEN 0x08 /* ENable RTC */
61#define RCR2_ADJ 0x04 /* ADJustment (30-second) */
62#define RCR2_RESET 0x02 /* Reset bit */
63#define RCR2_START 0x01 /* Start bit */
64 53
65/* Clock, Power and Reset Controller */ 54/* Clock, Power and Reset Controller */
66#define CPRC_BLOCK_OFF 0x01010000 55#define CPRC_BLOCK_OFF 0x01010000
@@ -84,27 +73,6 @@
84#define TMU0_TCNT TMU0_BASE+0x4 /* Long access */ 73#define TMU0_TCNT TMU0_BASE+0x4 /* Long access */
85#define TMU0_TCR TMU0_BASE+0x8 /* Word access */ 74#define TMU0_TCR TMU0_BASE+0x8 /* Word access */
86 75
87/* Real Time Clock */
88#define RTC_BLOCK_OFF 0x01040000
89#define RTC_BASE PHYS_PERIPHERAL_BLOCK + RTC_BLOCK_OFF
90
91#define R64CNT rtc_base+0x00
92#define RSECCNT rtc_base+0x04
93#define RMINCNT rtc_base+0x08
94#define RHRCNT rtc_base+0x0c
95#define RWKCNT rtc_base+0x10
96#define RDAYCNT rtc_base+0x14
97#define RMONCNT rtc_base+0x18
98#define RYRCNT rtc_base+0x1c /* 16bit */
99#define RSECAR rtc_base+0x20
100#define RMINAR rtc_base+0x24
101#define RHRAR rtc_base+0x28
102#define RWKAR rtc_base+0x2c
103#define RDAYAR rtc_base+0x30
104#define RMONAR rtc_base+0x34
105#define RCR1 rtc_base+0x38
106#define RCR2 rtc_base+0x3c
107
108#define TICK_SIZE (tick_nsec / 1000) 76#define TICK_SIZE (tick_nsec / 1000)
109 77
110static unsigned long tmu_base, rtc_base; 78static unsigned long tmu_base, rtc_base;
@@ -236,47 +204,23 @@ int do_settimeofday(struct timespec *tv)
236} 204}
237EXPORT_SYMBOL(do_settimeofday); 205EXPORT_SYMBOL(do_settimeofday);
238 206
239static int set_rtc_time(unsigned long nowtime) 207/* Dummy RTC ops */
208static void null_rtc_get_time(struct timespec *tv)
240{ 209{
241 int retval = 0; 210 tv->tv_sec = mktime(2000, 1, 1, 0, 0, 0);
242 int real_seconds, real_minutes, cmos_minutes; 211 tv->tv_nsec = 0;
243 212}
244 ctrl_outb(RCR2_RESET, RCR2); /* Reset pre-scaler & stop RTC */
245
246 cmos_minutes = ctrl_inb(RMINCNT);
247 BCD_TO_BIN(cmos_minutes);
248
249 /*
250 * since we're only adjusting minutes and seconds,
251 * don't interfere with hour overflow. This avoids
252 * messing with unknown time zones but requires your
253 * RTC not to be off by more than 15 minutes
254 */
255 real_seconds = nowtime % 60;
256 real_minutes = nowtime / 60;
257 if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
258 real_minutes += 30; /* correct for half hour time zone */
259 real_minutes %= 60;
260
261 if (abs(real_minutes - cmos_minutes) < 30) {
262 BIN_TO_BCD(real_seconds);
263 BIN_TO_BCD(real_minutes);
264 ctrl_outb(real_seconds, RSECCNT);
265 ctrl_outb(real_minutes, RMINCNT);
266 } else {
267 printk(KERN_WARNING
268 "set_rtc_time: can't update from %d to %d\n",
269 cmos_minutes, real_minutes);
270 retval = -1;
271 }
272
273 ctrl_outb(RCR2_RTCEN|RCR2_START, RCR2); /* Start RTC */
274 213
275 return retval; 214static int null_rtc_set_time(const time_t secs)
215{
216 return 0;
276} 217}
277 218
219void (*rtc_sh_get_time)(struct timespec *) = null_rtc_get_time;
220int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time;
221
278/* last time the RTC clock got updated */ 222/* last time the RTC clock got updated */
279static long last_rtc_update = 0; 223static long last_rtc_update;
280 224
281/* 225/*
282 * timer_interrupt() needs to keep up the real-time clock, 226 * timer_interrupt() needs to keep up the real-time clock,
@@ -296,11 +240,8 @@ static inline void do_timer_interrupt(void)
296 profile_tick(CPU_PROFILING); 240 profile_tick(CPU_PROFILING);
297 241
298#ifdef CONFIG_HEARTBEAT 242#ifdef CONFIG_HEARTBEAT
299 { 243 if (sh_mv.mv_heartbeat != NULL)
300 extern void heartbeat(void); 244 sh_mv.mv_heartbeat();
301
302 heartbeat();
303 }
304#endif 245#endif
305 246
306 /* 247 /*
@@ -312,10 +253,11 @@ static inline void do_timer_interrupt(void)
312 xtime.tv_sec > last_rtc_update + 660 && 253 xtime.tv_sec > last_rtc_update + 660 &&
313 (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 && 254 (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
314 (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) { 255 (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) {
315 if (set_rtc_time(xtime.tv_sec) == 0) 256 if (rtc_sh_set_time(xtime.tv_sec) == 0)
316 last_rtc_update = xtime.tv_sec; 257 last_rtc_update = xtime.tv_sec;
317 else 258 else
318 last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ 259 /* do it again in 60 s */
260 last_rtc_update = xtime.tv_sec - 600;
319 } 261 }
320} 262}
321 263
@@ -347,50 +289,6 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id)
347 return IRQ_HANDLED; 289 return IRQ_HANDLED;
348} 290}
349 291
350static unsigned long get_rtc_time(void)
351{
352 unsigned int sec, min, hr, wk, day, mon, yr, yr100;
353
354 again:
355 do {
356 ctrl_outb(0, RCR1); /* Clear CF-bit */
357 sec = ctrl_inb(RSECCNT);
358 min = ctrl_inb(RMINCNT);
359 hr = ctrl_inb(RHRCNT);
360 wk = ctrl_inb(RWKCNT);
361 day = ctrl_inb(RDAYCNT);
362 mon = ctrl_inb(RMONCNT);
363 yr = ctrl_inw(RYRCNT);
364 yr100 = (yr >> 8);
365 yr &= 0xff;
366 } while ((ctrl_inb(RCR1) & RCR1_CF) != 0);
367
368 BCD_TO_BIN(yr100);
369 BCD_TO_BIN(yr);
370 BCD_TO_BIN(mon);
371 BCD_TO_BIN(day);
372 BCD_TO_BIN(hr);
373 BCD_TO_BIN(min);
374 BCD_TO_BIN(sec);
375
376 if (yr > 99 || mon < 1 || mon > 12 || day > 31 || day < 1 ||
377 hr > 23 || min > 59 || sec > 59) {
378 printk(KERN_ERR
379 "SH RTC: invalid value, resetting to 1 Jan 2000\n");
380 ctrl_outb(RCR2_RESET, RCR2); /* Reset & Stop */
381 ctrl_outb(0, RSECCNT);
382 ctrl_outb(0, RMINCNT);
383 ctrl_outb(0, RHRCNT);
384 ctrl_outb(6, RWKCNT);
385 ctrl_outb(1, RDAYCNT);
386 ctrl_outb(1, RMONCNT);
387 ctrl_outw(0x2000, RYRCNT);
388 ctrl_outb(RCR2_RTCEN|RCR2_START, RCR2); /* Start */
389 goto again;
390 }
391
392 return mktime(yr100 * 100 + yr, mon, day, hr, min, sec);
393}
394 292
395static __init unsigned int get_cpu_hz(void) 293static __init unsigned int get_cpu_hz(void)
396{ 294{
@@ -406,8 +304,8 @@ static __init unsigned int get_cpu_hz(void)
406 register unsigned long long __rtc_irq_flag __asm__ ("r3"); 304 register unsigned long long __rtc_irq_flag __asm__ ("r3");
407 305
408 local_irq_enable(); 306 local_irq_enable();
409 do {} while (ctrl_inb(R64CNT) != 0); 307 do {} while (ctrl_inb(rtc_base) != 0);
410 ctrl_outb(RCR1_CIE, RCR1); /* Enable carry interrupt */ 308 ctrl_outb(RTC_RCR1_CIE, RTC_RCR1); /* Enable carry interrupt */
411 309
412 /* 310 /*
413 * r3 is arbitrary. CDC does not support "=z". 311 * r3 is arbitrary. CDC does not support "=z".
@@ -449,28 +347,19 @@ static __init unsigned int get_cpu_hz(void)
449 347
450 count = ctc_val_init - ctc_val; /* CTC counts down */ 348 count = ctc_val_init - ctc_val; /* CTC counts down */
451 349
452#if defined (CONFIG_SH_SIMULATOR)
453 /*
454 * Let's pretend we are a 5MHz SH-5 to avoid a too
455 * little timer interval. Also to keep delay
456 * calibration within a reasonable time.
457 */
458 return 5000000;
459#else
460 /* 350 /*
461 * This really is count by the number of clock cycles 351 * This really is count by the number of clock cycles
462 * by the ratio between a complete R64CNT 352 * by the ratio between a complete R64CNT
463 * wrap-around (128) and CUI interrupt being raised (64). 353 * wrap-around (128) and CUI interrupt being raised (64).
464 */ 354 */
465 return count*2; 355 return count*2;
466#endif
467} 356}
468 357
469static irqreturn_t sh64_rtc_interrupt(int irq, void *dev_id) 358static irqreturn_t sh64_rtc_interrupt(int irq, void *dev_id)
470{ 359{
471 struct pt_regs *regs = get_irq_regs(); 360 struct pt_regs *regs = get_irq_regs();
472 361
473 ctrl_outb(0, RCR1); /* Disable Carry Interrupts */ 362 ctrl_outb(0, RTC_RCR1); /* Disable Carry Interrupts */
474 regs->regs[3] = 1; /* Using r3 */ 363 regs->regs[3] = 1; /* Using r3 */
475 364
476 return IRQ_HANDLED; 365 return IRQ_HANDLED;
@@ -513,8 +402,7 @@ void __init time_init(void)
513 panic("Unable to remap CPRC\n"); 402 panic("Unable to remap CPRC\n");
514 } 403 }
515 404
516 xtime.tv_sec = get_rtc_time(); 405 rtc_sh_get_time(&xtime);
517 xtime.tv_nsec = 0;
518 406
519 setup_irq(TIMER_IRQ, &irq0); 407 setup_irq(TIMER_IRQ, &irq0);
520 setup_irq(RTC_IRQ, &irq1); 408 setup_irq(RTC_IRQ, &irq1);
@@ -525,7 +413,7 @@ void __init time_init(void)
525 /* Note careful order of operations to maintain reasonable precision and avoid overflow. */ 413 /* Note careful order of operations to maintain reasonable precision and avoid overflow. */
526 scaled_recip_ctc_ticks_per_jiffy = ((1ULL << CTC_JIFFY_SCALE_SHIFT) / (unsigned long long)(cpu_clock / HZ)); 414 scaled_recip_ctc_ticks_per_jiffy = ((1ULL << CTC_JIFFY_SCALE_SHIFT) / (unsigned long long)(cpu_clock / HZ));
527 415
528 disable_irq(RTC_IRQ); 416 free_irq(RTC_IRQ, NULL);
529 417
530 printk("CPU clock: %d.%02dMHz\n", 418 printk("CPU clock: %d.%02dMHz\n",
531 (cpu_clock / 1000000), (cpu_clock % 1000000)/10000); 419 (cpu_clock / 1000000), (cpu_clock % 1000000)/10000);
@@ -591,3 +479,41 @@ void enter_deep_standby(void)
591 asm __volatile__ ("nop"); 479 asm __volatile__ ("nop");
592 panic("Unexpected wakeup!\n"); 480 panic("Unexpected wakeup!\n");
593} 481}
482
483static struct resource rtc_resources[] = {
484 [0] = {
485 /* RTC base, filled in by rtc_init */
486 .flags = IORESOURCE_IO,
487 },
488 [1] = {
489 /* Period IRQ */
490 .start = IRQ_PRI,
491 .flags = IORESOURCE_IRQ,
492 },
493 [2] = {
494 /* Carry IRQ */
495 .start = IRQ_CUI,
496 .flags = IORESOURCE_IRQ,
497 },
498 [3] = {
499 /* Alarm IRQ */
500 .start = IRQ_ATI,
501 .flags = IORESOURCE_IRQ,
502 },
503};
504
505static struct platform_device rtc_device = {
506 .name = "sh-rtc",
507 .id = -1,
508 .num_resources = ARRAY_SIZE(rtc_resources),
509 .resource = rtc_resources,
510};
511
512static int __init rtc_init(void)
513{
514 rtc_resources[0].start = rtc_base;
515 rtc_resources[0].end = rtc_resources[0].start + 0x58 - 1;
516
517 return platform_device_register(&rtc_device);
518}
519device_initcall(rtc_init);
diff --git a/arch/sh/kernel/timers/timer-cmt.c b/arch/sh/kernel/timers/timer-cmt.c
index 82de6895ade5..499e07beebe2 100644
--- a/arch/sh/kernel/timers/timer-cmt.c
+++ b/arch/sh/kernel/timers/timer-cmt.c
@@ -31,7 +31,9 @@
31#define cmt_clock_enable() do { ctrl_outb(ctrl_inb(STBCR3) & ~0x10, STBCR3); } while(0) 31#define cmt_clock_enable() do { ctrl_outb(ctrl_inb(STBCR3) & ~0x10, STBCR3); } while(0)
32#define CMT_CMCSR_INIT 0x0040 32#define CMT_CMCSR_INIT 0x0040
33#define CMT_CMCSR_CALIB 0x0000 33#define CMT_CMCSR_CALIB 0x0000
34#elif defined(CONFIG_CPU_SUBTYPE_SH7206) 34#elif defined(CONFIG_CPU_SUBTYPE_SH7203) || \
35 defined(CONFIG_CPU_SUBTYPE_SH7206) || \
36 defined(CONFIG_CPU_SUBTYPE_SH7263)
35#define CMT_CMSTR 0xfffec000 37#define CMT_CMSTR 0xfffec000
36#define CMT_CMCSR_0 0xfffec002 38#define CMT_CMCSR_0 0xfffec002
37#define CMT_CMCNT_0 0xfffec004 39#define CMT_CMCNT_0 0xfffec004
diff --git a/arch/sh/kernel/timers/timer-tmu.c b/arch/sh/kernel/timers/timer-tmu.c
index 628ec9a15e38..8935570008d2 100644
--- a/arch/sh/kernel/timers/timer-tmu.c
+++ b/arch/sh/kernel/timers/timer-tmu.c
@@ -174,6 +174,7 @@ static int tmu_timer_init(void)
174 tmu_timer_stop(); 174 tmu_timer_stop();
175 175
176#if !defined(CONFIG_CPU_SUBTYPE_SH7720) && \ 176#if !defined(CONFIG_CPU_SUBTYPE_SH7720) && \
177 !defined(CONFIG_CPU_SUBTYPE_SH7721) && \
177 !defined(CONFIG_CPU_SUBTYPE_SH7760) && \ 178 !defined(CONFIG_CPU_SUBTYPE_SH7760) && \
178 !defined(CONFIG_CPU_SUBTYPE_SH7785) && \ 179 !defined(CONFIG_CPU_SUBTYPE_SH7785) && \
179 !defined(CONFIG_CPU_SUBTYPE_SHX3) 180 !defined(CONFIG_CPU_SUBTYPE_SHX3)
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c
index cf99111cb33f..a3bdc68ef02c 100644
--- a/arch/sh/kernel/traps.c
+++ b/arch/sh/kernel/traps.c
@@ -1,947 +1,68 @@
1/*
2 * 'traps.c' handles hardware traps and faults after we have saved some
3 * state in 'entry.S'.
4 *
5 * SuperH version: Copyright (C) 1999 Niibe Yutaka
6 * Copyright (C) 2000 Philipp Rumpf
7 * Copyright (C) 2000 David Howells
8 * Copyright (C) 2002 - 2007 Paul Mundt
9 *
10 * This file is subject to the terms and conditions of the GNU General Public
11 * License. See the file "COPYING" in the main directory of this archive
12 * for more details.
13 */
14#include <linux/kernel.h>
15#include <linux/ptrace.h>
16#include <linux/init.h>
17#include <linux/spinlock.h>
18#include <linux/module.h>
19#include <linux/kallsyms.h>
20#include <linux/io.h>
21#include <linux/bug.h> 1#include <linux/bug.h>
22#include <linux/debug_locks.h> 2#include <linux/io.h>
3#include <linux/types.h>
23#include <linux/kdebug.h> 4#include <linux/kdebug.h>
24#include <linux/kexec.h> 5#include <linux/signal.h>
25#include <linux/limits.h> 6#include <linux/sched.h>
26#include <asm/system.h> 7#include <asm/system.h>
27#include <asm/uaccess.h>
28
29#ifdef CONFIG_SH_KGDB
30#include <asm/kgdb.h>
31#define CHK_REMOTE_DEBUG(regs) \
32{ \
33 if (kgdb_debug_hook && !user_mode(regs))\
34 (*kgdb_debug_hook)(regs); \
35}
36#else
37#define CHK_REMOTE_DEBUG(regs)
38#endif
39
40#ifdef CONFIG_CPU_SH2
41# define TRAP_RESERVED_INST 4
42# define TRAP_ILLEGAL_SLOT_INST 6
43# define TRAP_ADDRESS_ERROR 9
44# ifdef CONFIG_CPU_SH2A
45# define TRAP_DIVZERO_ERROR 17
46# define TRAP_DIVOVF_ERROR 18
47# endif
48#else
49#define TRAP_RESERVED_INST 12
50#define TRAP_ILLEGAL_SLOT_INST 13
51#endif
52
53static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
54{
55 unsigned long p;
56 int i;
57
58 printk("%s(0x%08lx to 0x%08lx)\n", str, bottom, top);
59
60 for (p = bottom & ~31; p < top; ) {
61 printk("%04lx: ", p & 0xffff);
62
63 for (i = 0; i < 8; i++, p += 4) {
64 unsigned int val;
65
66 if (p < bottom || p >= top)
67 printk(" ");
68 else {
69 if (__get_user(val, (unsigned int __user *)p)) {
70 printk("\n");
71 return;
72 }
73 printk("%08x ", val);
74 }
75 }
76 printk("\n");
77 }
78}
79
80static DEFINE_SPINLOCK(die_lock);
81
82void die(const char * str, struct pt_regs * regs, long err)
83{
84 static int die_counter;
85
86 oops_enter();
87
88 console_verbose();
89 spin_lock_irq(&die_lock);
90 bust_spinlocks(1);
91
92 printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
93
94 CHK_REMOTE_DEBUG(regs);
95 print_modules();
96 show_regs(regs);
97
98 printk("Process: %s (pid: %d, stack limit = %p)\n", current->comm,
99 task_pid_nr(current), task_stack_page(current) + 1);
100
101 if (!user_mode(regs) || in_interrupt())
102 dump_mem("Stack: ", regs->regs[15], THREAD_SIZE +
103 (unsigned long)task_stack_page(current));
104
105 bust_spinlocks(0);
106 add_taint(TAINT_DIE);
107 spin_unlock_irq(&die_lock);
108
109 if (kexec_should_crash(current))
110 crash_kexec(regs);
111
112 if (in_interrupt())
113 panic("Fatal exception in interrupt");
114
115 if (panic_on_oops)
116 panic("Fatal exception");
117
118 oops_exit();
119 do_exit(SIGSEGV);
120}
121
122static inline void die_if_kernel(const char *str, struct pt_regs *regs,
123 long err)
124{
125 if (!user_mode(regs))
126 die(str, regs, err);
127}
128
129/*
130 * try and fix up kernelspace address errors
131 * - userspace errors just cause EFAULT to be returned, resulting in SEGV
132 * - kernel/userspace interfaces cause a jump to an appropriate handler
133 * - other kernel errors are bad
134 * - return 0 if fixed-up, -EFAULT if non-fatal (to the kernel) fault
135 */
136static int die_if_no_fixup(const char * str, struct pt_regs * regs, long err)
137{
138 if (!user_mode(regs)) {
139 const struct exception_table_entry *fixup;
140 fixup = search_exception_tables(regs->pc);
141 if (fixup) {
142 regs->pc = fixup->fixup;
143 return 0;
144 }
145 die(str, regs, err);
146 }
147 return -EFAULT;
148}
149
150/*
151 * handle an instruction that does an unaligned memory access by emulating the
152 * desired behaviour
153 * - note that PC _may not_ point to the faulting instruction
154 * (if that instruction is in a branch delay slot)
155 * - return 0 if emulation okay, -EFAULT on existential error
156 */
157static int handle_unaligned_ins(u16 instruction, struct pt_regs *regs)
158{
159 int ret, index, count;
160 unsigned long *rm, *rn;
161 unsigned char *src, *dst;
162
163 index = (instruction>>8)&15; /* 0x0F00 */
164 rn = &regs->regs[index];
165
166 index = (instruction>>4)&15; /* 0x00F0 */
167 rm = &regs->regs[index];
168
169 count = 1<<(instruction&3);
170
171 ret = -EFAULT;
172 switch (instruction>>12) {
173 case 0: /* mov.[bwl] to/from memory via r0+rn */
174 if (instruction & 8) {
175 /* from memory */
176 src = (unsigned char*) *rm;
177 src += regs->regs[0];
178 dst = (unsigned char*) rn;
179 *(unsigned long*)dst = 0;
180
181#ifdef __LITTLE_ENDIAN__
182 if (copy_from_user(dst, src, count))
183 goto fetch_fault;
184
185 if ((count == 2) && dst[1] & 0x80) {
186 dst[2] = 0xff;
187 dst[3] = 0xff;
188 }
189#else
190 dst += 4-count;
191
192 if (__copy_user(dst, src, count))
193 goto fetch_fault;
194
195 if ((count == 2) && dst[2] & 0x80) {
196 dst[0] = 0xff;
197 dst[1] = 0xff;
198 }
199#endif
200 } else {
201 /* to memory */
202 src = (unsigned char*) rm;
203#if !defined(__LITTLE_ENDIAN__)
204 src += 4-count;
205#endif
206 dst = (unsigned char*) *rn;
207 dst += regs->regs[0];
208
209 if (copy_to_user(dst, src, count))
210 goto fetch_fault;
211 }
212 ret = 0;
213 break;
214
215 case 1: /* mov.l Rm,@(disp,Rn) */
216 src = (unsigned char*) rm;
217 dst = (unsigned char*) *rn;
218 dst += (instruction&0x000F)<<2;
219
220 if (copy_to_user(dst,src,4))
221 goto fetch_fault;
222 ret = 0;
223 break;
224
225 case 2: /* mov.[bwl] to memory, possibly with pre-decrement */
226 if (instruction & 4)
227 *rn -= count;
228 src = (unsigned char*) rm;
229 dst = (unsigned char*) *rn;
230#if !defined(__LITTLE_ENDIAN__)
231 src += 4-count;
232#endif
233 if (copy_to_user(dst, src, count))
234 goto fetch_fault;
235 ret = 0;
236 break;
237
238 case 5: /* mov.l @(disp,Rm),Rn */
239 src = (unsigned char*) *rm;
240 src += (instruction&0x000F)<<2;
241 dst = (unsigned char*) rn;
242 *(unsigned long*)dst = 0;
243
244 if (copy_from_user(dst,src,4))
245 goto fetch_fault;
246 ret = 0;
247 break;
248 8
249 case 6: /* mov.[bwl] from memory, possibly with post-increment */ 9#ifdef CONFIG_BUG
250 src = (unsigned char*) *rm; 10static void handle_BUG(struct pt_regs *regs)
251 if (instruction & 4)
252 *rm += count;
253 dst = (unsigned char*) rn;
254 *(unsigned long*)dst = 0;
255
256#ifdef __LITTLE_ENDIAN__
257 if (copy_from_user(dst, src, count))
258 goto fetch_fault;
259
260 if ((count == 2) && dst[1] & 0x80) {
261 dst[2] = 0xff;
262 dst[3] = 0xff;
263 }
264#else
265 dst += 4-count;
266
267 if (copy_from_user(dst, src, count))
268 goto fetch_fault;
269
270 if ((count == 2) && dst[2] & 0x80) {
271 dst[0] = 0xff;
272 dst[1] = 0xff;
273 }
274#endif
275 ret = 0;
276 break;
277
278 case 8:
279 switch ((instruction&0xFF00)>>8) {
280 case 0x81: /* mov.w R0,@(disp,Rn) */
281 src = (unsigned char*) &regs->regs[0];
282#if !defined(__LITTLE_ENDIAN__)
283 src += 2;
284#endif
285 dst = (unsigned char*) *rm; /* called Rn in the spec */
286 dst += (instruction&0x000F)<<1;
287
288 if (copy_to_user(dst, src, 2))
289 goto fetch_fault;
290 ret = 0;
291 break;
292
293 case 0x85: /* mov.w @(disp,Rm),R0 */
294 src = (unsigned char*) *rm;
295 src += (instruction&0x000F)<<1;
296 dst = (unsigned char*) &regs->regs[0];
297 *(unsigned long*)dst = 0;
298
299#if !defined(__LITTLE_ENDIAN__)
300 dst += 2;
301#endif
302
303 if (copy_from_user(dst, src, 2))
304 goto fetch_fault;
305
306#ifdef __LITTLE_ENDIAN__
307 if (dst[1] & 0x80) {
308 dst[2] = 0xff;
309 dst[3] = 0xff;
310 }
311#else
312 if (dst[2] & 0x80) {
313 dst[0] = 0xff;
314 dst[1] = 0xff;
315 }
316#endif
317 ret = 0;
318 break;
319 }
320 break;
321 }
322 return ret;
323
324 fetch_fault:
325 /* Argh. Address not only misaligned but also non-existent.
326 * Raise an EFAULT and see if it's trapped
327 */
328 return die_if_no_fixup("Fault in unaligned fixup", regs, 0);
329}
330
331/*
332 * emulate the instruction in the delay slot
333 * - fetches the instruction from PC+2
334 */
335static inline int handle_unaligned_delayslot(struct pt_regs *regs)
336{ 11{
337 u16 instruction; 12 enum bug_trap_type tt;
338 13 tt = report_bug(regs->pc, regs);
339 if (copy_from_user(&instruction, (u16 *)(regs->pc+2), 2)) { 14 if (tt == BUG_TRAP_TYPE_WARN) {
340 /* the instruction-fetch faulted */ 15 regs->pc += instruction_size(regs->pc);
341 if (user_mode(regs)) 16 return;
342 return -EFAULT;
343
344 /* kernel */
345 die("delay-slot-insn faulting in handle_unaligned_delayslot",
346 regs, 0);
347 } 17 }
348 18
349 return handle_unaligned_ins(instruction,regs); 19 die("Kernel BUG", regs, TRAPA_BUG_OPCODE & 0xff);
350} 20}
351 21
352/* 22int is_valid_bugaddr(unsigned long addr)
353 * handle an instruction that does an unaligned memory access
354 * - have to be careful of branch delay-slot instructions that fault
355 * SH3:
356 * - if the branch would be taken PC points to the branch
357 * - if the branch would not be taken, PC points to delay-slot
358 * SH4:
359 * - PC always points to delayed branch
360 * - return 0 if handled, -EFAULT if failed (may not return if in kernel)
361 */
362
363/* Macros to determine offset from current PC for branch instructions */
364/* Explicit type coercion is used to force sign extension where needed */
365#define SH_PC_8BIT_OFFSET(instr) ((((signed char)(instr))*2) + 4)
366#define SH_PC_12BIT_OFFSET(instr) ((((signed short)(instr<<4))>>3) + 4)
367
368/*
369 * XXX: SH-2A needs this too, but it needs an overhaul thanks to mixed 32-bit
370 * opcodes..
371 */
372#ifndef CONFIG_CPU_SH2A
373static int handle_unaligned_notify_count = 10;
374
375static int handle_unaligned_access(u16 instruction, struct pt_regs *regs)
376{ 23{
377 u_int rm; 24 return addr >= PAGE_OFFSET;
378 int ret, index;
379
380 index = (instruction>>8)&15; /* 0x0F00 */
381 rm = regs->regs[index];
382
383 /* shout about the first ten userspace fixups */
384 if (user_mode(regs) && handle_unaligned_notify_count>0) {
385 handle_unaligned_notify_count--;
386
387 printk(KERN_NOTICE "Fixing up unaligned userspace access "
388 "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
389 current->comm, task_pid_nr(current),
390 (u16 *)regs->pc, instruction);
391 }
392
393 ret = -EFAULT;
394 switch (instruction&0xF000) {
395 case 0x0000:
396 if (instruction==0x000B) {
397 /* rts */
398 ret = handle_unaligned_delayslot(regs);
399 if (ret==0)
400 regs->pc = regs->pr;
401 }
402 else if ((instruction&0x00FF)==0x0023) {
403 /* braf @Rm */
404 ret = handle_unaligned_delayslot(regs);
405 if (ret==0)
406 regs->pc += rm + 4;
407 }
408 else if ((instruction&0x00FF)==0x0003) {
409 /* bsrf @Rm */
410 ret = handle_unaligned_delayslot(regs);
411 if (ret==0) {
412 regs->pr = regs->pc + 4;
413 regs->pc += rm + 4;
414 }
415 }
416 else {
417 /* mov.[bwl] to/from memory via r0+rn */
418 goto simple;
419 }
420 break;
421
422 case 0x1000: /* mov.l Rm,@(disp,Rn) */
423 goto simple;
424
425 case 0x2000: /* mov.[bwl] to memory, possibly with pre-decrement */
426 goto simple;
427
428 case 0x4000:
429 if ((instruction&0x00FF)==0x002B) {
430 /* jmp @Rm */
431 ret = handle_unaligned_delayslot(regs);
432 if (ret==0)
433 regs->pc = rm;
434 }
435 else if ((instruction&0x00FF)==0x000B) {
436 /* jsr @Rm */
437 ret = handle_unaligned_delayslot(regs);
438 if (ret==0) {
439 regs->pr = regs->pc + 4;
440 regs->pc = rm;
441 }
442 }
443 else {
444 /* mov.[bwl] to/from memory via r0+rn */
445 goto simple;
446 }
447 break;
448
449 case 0x5000: /* mov.l @(disp,Rm),Rn */
450 goto simple;
451
452 case 0x6000: /* mov.[bwl] from memory, possibly with post-increment */
453 goto simple;
454
455 case 0x8000: /* bf lab, bf/s lab, bt lab, bt/s lab */
456 switch (instruction&0x0F00) {
457 case 0x0100: /* mov.w R0,@(disp,Rm) */
458 goto simple;
459 case 0x0500: /* mov.w @(disp,Rm),R0 */
460 goto simple;
461 case 0x0B00: /* bf lab - no delayslot*/
462 break;
463 case 0x0F00: /* bf/s lab */
464 ret = handle_unaligned_delayslot(regs);
465 if (ret==0) {
466#if defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB)
467 if ((regs->sr & 0x00000001) != 0)
468 regs->pc += 4; /* next after slot */
469 else
470#endif
471 regs->pc += SH_PC_8BIT_OFFSET(instruction);
472 }
473 break;
474 case 0x0900: /* bt lab - no delayslot */
475 break;
476 case 0x0D00: /* bt/s lab */
477 ret = handle_unaligned_delayslot(regs);
478 if (ret==0) {
479#if defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB)
480 if ((regs->sr & 0x00000001) == 0)
481 regs->pc += 4; /* next after slot */
482 else
483#endif
484 regs->pc += SH_PC_8BIT_OFFSET(instruction);
485 }
486 break;
487 }
488 break;
489
490 case 0xA000: /* bra label */
491 ret = handle_unaligned_delayslot(regs);
492 if (ret==0)
493 regs->pc += SH_PC_12BIT_OFFSET(instruction);
494 break;
495
496 case 0xB000: /* bsr label */
497 ret = handle_unaligned_delayslot(regs);
498 if (ret==0) {
499 regs->pr = regs->pc + 4;
500 regs->pc += SH_PC_12BIT_OFFSET(instruction);
501 }
502 break;
503 }
504 return ret;
505
506 /* handle non-delay-slot instruction */
507 simple:
508 ret = handle_unaligned_ins(instruction,regs);
509 if (ret==0)
510 regs->pc += instruction_size(instruction);
511 return ret;
512} 25}
513#endif /* CONFIG_CPU_SH2A */
514
515#ifdef CONFIG_CPU_HAS_SR_RB
516#define lookup_exception_vector(x) \
517 __asm__ __volatile__ ("stc r2_bank, %0\n\t" : "=r" ((x)))
518#else
519#define lookup_exception_vector(x) \
520 __asm__ __volatile__ ("mov r4, %0\n\t" : "=r" ((x)))
521#endif 26#endif
522 27
523/* 28/*
524 * Handle various address error exceptions: 29 * Generic trap handler.
525 * - instruction address error:
526 * misaligned PC
527 * PC >= 0x80000000 in user mode
528 * - data address error (read and write)
529 * misaligned data access
530 * access to >= 0x80000000 is user mode
531 * Unfortuntaly we can't distinguish between instruction address error
532 * and data address errors caused by read accesses.
533 */ 30 */
534asmlinkage void do_address_error(struct pt_regs *regs, 31BUILD_TRAP_HANDLER(debug)
535 unsigned long writeaccess,
536 unsigned long address)
537{ 32{
538 unsigned long error_code = 0; 33 TRAP_HANDLER_DECL;
539 mm_segment_t oldfs;
540 siginfo_t info;
541#ifndef CONFIG_CPU_SH2A
542 u16 instruction;
543 int tmp;
544#endif
545
546 /* Intentional ifdef */
547#ifdef CONFIG_CPU_HAS_SR_RB
548 lookup_exception_vector(error_code);
549#endif
550
551 oldfs = get_fs();
552
553 if (user_mode(regs)) {
554 int si_code = BUS_ADRERR;
555
556 local_irq_enable();
557 34
558 /* bad PC is not something we can fix */ 35 /* Rewind */
559 if (regs->pc & 1) { 36 regs->pc -= instruction_size(ctrl_inw(regs->pc - 4));
560 si_code = BUS_ADRALN;
561 goto uspace_segv;
562 }
563 37
564#ifndef CONFIG_CPU_SH2A 38 if (notify_die(DIE_TRAP, "debug trap", regs, 0, vec & 0xff,
565 set_fs(USER_DS); 39 SIGTRAP) == NOTIFY_STOP)
566 if (copy_from_user(&instruction, (u16 *)(regs->pc), 2)) { 40 return;
567 /* Argh. Fault on the instruction itself.
568 This should never happen non-SMP
569 */
570 set_fs(oldfs);
571 goto uspace_segv;
572 }
573
574 tmp = handle_unaligned_access(instruction, regs);
575 set_fs(oldfs);
576
577 if (tmp==0)
578 return; /* sorted */
579#endif
580
581uspace_segv:
582 printk(KERN_NOTICE "Sending SIGBUS to \"%s\" due to unaligned "
583 "access (PC %lx PR %lx)\n", current->comm, regs->pc,
584 regs->pr);
585
586 info.si_signo = SIGBUS;
587 info.si_errno = 0;
588 info.si_code = si_code;
589 info.si_addr = (void __user *)address;
590 force_sig_info(SIGBUS, &info, current);
591 } else {
592 if (regs->pc & 1)
593 die("unaligned program counter", regs, error_code);
594
595#ifndef CONFIG_CPU_SH2A
596 set_fs(KERNEL_DS);
597 if (copy_from_user(&instruction, (u16 *)(regs->pc), 2)) {
598 /* Argh. Fault on the instruction itself.
599 This should never happen non-SMP
600 */
601 set_fs(oldfs);
602 die("insn faulting in do_address_error", regs, 0);
603 }
604
605 handle_unaligned_access(instruction, regs);
606 set_fs(oldfs);
607#else
608 printk(KERN_NOTICE "Killing process \"%s\" due to unaligned "
609 "access\n", current->comm);
610 41
611 force_sig(SIGSEGV, current); 42 force_sig(SIGTRAP, current);
612#endif
613 }
614} 43}
615 44
616#ifdef CONFIG_SH_DSP
617/* 45/*
618 * SH-DSP support gerg@snapgear.com. 46 * Special handler for BUG() traps.
619 */ 47 */
620int is_dsp_inst(struct pt_regs *regs) 48BUILD_TRAP_HANDLER(bug)
621{ 49{
622 unsigned short inst = 0; 50 TRAP_HANDLER_DECL;
623
624 /*
625 * Safe guard if DSP mode is already enabled or we're lacking
626 * the DSP altogether.
627 */
628 if (!(current_cpu_data.flags & CPU_HAS_DSP) || (regs->sr & SR_DSP))
629 return 0;
630
631 get_user(inst, ((unsigned short *) regs->pc));
632
633 inst &= 0xf000;
634
635 /* Check for any type of DSP or support instruction */
636 if ((inst == 0xf000) || (inst == 0x4000))
637 return 1;
638
639 return 0;
640}
641#else
642#define is_dsp_inst(regs) (0)
643#endif /* CONFIG_SH_DSP */
644 51
645#ifdef CONFIG_CPU_SH2A 52 /* Rewind */
646asmlinkage void do_divide_error(unsigned long r4, unsigned long r5, 53 regs->pc -= instruction_size(ctrl_inw(regs->pc - 4));
647 unsigned long r6, unsigned long r7,
648 struct pt_regs __regs)
649{
650 siginfo_t info;
651
652 switch (r4) {
653 case TRAP_DIVZERO_ERROR:
654 info.si_code = FPE_INTDIV;
655 break;
656 case TRAP_DIVOVF_ERROR:
657 info.si_code = FPE_INTOVF;
658 break;
659 }
660
661 force_sig_info(SIGFPE, &info, current);
662}
663#endif
664
665/* arch/sh/kernel/cpu/sh4/fpu.c */
666extern int do_fpu_inst(unsigned short, struct pt_regs *);
667extern asmlinkage void do_fpu_state_restore(unsigned long r4, unsigned long r5,
668 unsigned long r6, unsigned long r7, struct pt_regs __regs);
669
670asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5,
671 unsigned long r6, unsigned long r7,
672 struct pt_regs __regs)
673{
674 struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
675 unsigned long error_code;
676 struct task_struct *tsk = current;
677
678#ifdef CONFIG_SH_FPU_EMU
679 unsigned short inst = 0;
680 int err;
681
682 get_user(inst, (unsigned short*)regs->pc);
683
684 err = do_fpu_inst(inst, regs);
685 if (!err) {
686 regs->pc += instruction_size(inst);
687 return;
688 }
689 /* not a FPU inst. */
690#endif
691 54
692#ifdef CONFIG_SH_DSP 55 if (notify_die(DIE_TRAP, "bug trap", regs, 0, TRAPA_BUG_OPCODE & 0xff,
693 /* Check if it's a DSP instruction */ 56 SIGTRAP) == NOTIFY_STOP)
694 if (is_dsp_inst(regs)) {
695 /* Enable DSP mode, and restart instruction. */
696 regs->sr |= SR_DSP;
697 return; 57 return;
698 }
699#endif
700
701 lookup_exception_vector(error_code);
702
703 local_irq_enable();
704 CHK_REMOTE_DEBUG(regs);
705 force_sig(SIGILL, tsk);
706 die_if_no_fixup("reserved instruction", regs, error_code);
707}
708
709#ifdef CONFIG_SH_FPU_EMU
710static int emulate_branch(unsigned short inst, struct pt_regs* regs)
711{
712 /*
713 * bfs: 8fxx: PC+=d*2+4;
714 * bts: 8dxx: PC+=d*2+4;
715 * bra: axxx: PC+=D*2+4;
716 * bsr: bxxx: PC+=D*2+4 after PR=PC+4;
717 * braf:0x23: PC+=Rn*2+4;
718 * bsrf:0x03: PC+=Rn*2+4 after PR=PC+4;
719 * jmp: 4x2b: PC=Rn;
720 * jsr: 4x0b: PC=Rn after PR=PC+4;
721 * rts: 000b: PC=PR;
722 */
723 if ((inst & 0xfd00) == 0x8d00) {
724 regs->pc += SH_PC_8BIT_OFFSET(inst);
725 return 0;
726 }
727
728 if ((inst & 0xe000) == 0xa000) {
729 regs->pc += SH_PC_12BIT_OFFSET(inst);
730 return 0;
731 }
732
733 if ((inst & 0xf0df) == 0x0003) {
734 regs->pc += regs->regs[(inst & 0x0f00) >> 8] + 4;
735 return 0;
736 }
737
738 if ((inst & 0xf0df) == 0x400b) {
739 regs->pc = regs->regs[(inst & 0x0f00) >> 8];
740 return 0;
741 }
742
743 if ((inst & 0xffff) == 0x000b) {
744 regs->pc = regs->pr;
745 return 0;
746 }
747
748 return 1;
749}
750#endif
751
752asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5,
753 unsigned long r6, unsigned long r7,
754 struct pt_regs __regs)
755{
756 struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
757 unsigned long error_code;
758 struct task_struct *tsk = current;
759#ifdef CONFIG_SH_FPU_EMU
760 unsigned short inst = 0;
761
762 get_user(inst, (unsigned short *)regs->pc + 1);
763 if (!do_fpu_inst(inst, regs)) {
764 get_user(inst, (unsigned short *)regs->pc);
765 if (!emulate_branch(inst, regs))
766 return;
767 /* fault in branch.*/
768 }
769 /* not a FPU inst. */
770#endif
771
772 lookup_exception_vector(error_code);
773
774 local_irq_enable();
775 CHK_REMOTE_DEBUG(regs);
776 force_sig(SIGILL, tsk);
777 die_if_no_fixup("illegal slot instruction", regs, error_code);
778}
779
780asmlinkage void do_exception_error(unsigned long r4, unsigned long r5,
781 unsigned long r6, unsigned long r7,
782 struct pt_regs __regs)
783{
784 struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
785 long ex;
786
787 lookup_exception_vector(ex);
788 die_if_kernel("exception", regs, ex);
789}
790
791#if defined(CONFIG_SH_STANDARD_BIOS)
792void *gdb_vbr_vector;
793
794static inline void __init gdb_vbr_init(void)
795{
796 register unsigned long vbr;
797
798 /*
799 * Read the old value of the VBR register to initialise
800 * the vector through which debug and BIOS traps are
801 * delegated by the Linux trap handler.
802 */
803 asm volatile("stc vbr, %0" : "=r" (vbr));
804
805 gdb_vbr_vector = (void *)(vbr + 0x100);
806 printk("Setting GDB trap vector to 0x%08lx\n",
807 (unsigned long)gdb_vbr_vector);
808}
809#endif
810
811void __cpuinit per_cpu_trap_init(void)
812{
813 extern void *vbr_base;
814
815#ifdef CONFIG_SH_STANDARD_BIOS
816 if (raw_smp_processor_id() == 0)
817 gdb_vbr_init();
818#endif
819
820 /* NOTE: The VBR value should be at P1
821 (or P2, virtural "fixed" address space).
822 It's definitely should not in physical address. */
823
824 asm volatile("ldc %0, vbr"
825 : /* no output */
826 : "r" (&vbr_base)
827 : "memory");
828}
829
830void *set_exception_table_vec(unsigned int vec, void *handler)
831{
832 extern void *exception_handling_table[];
833 void *old_handler;
834
835 old_handler = exception_handling_table[vec];
836 exception_handling_table[vec] = handler;
837 return old_handler;
838}
839
840extern asmlinkage void address_error_handler(unsigned long r4, unsigned long r5,
841 unsigned long r6, unsigned long r7,
842 struct pt_regs __regs);
843
844void __init trap_init(void)
845{
846 set_exception_table_vec(TRAP_RESERVED_INST, do_reserved_inst);
847 set_exception_table_vec(TRAP_ILLEGAL_SLOT_INST, do_illegal_slot_inst);
848
849#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_FPU) || \
850 defined(CONFIG_SH_FPU_EMU)
851 /*
852 * For SH-4 lacking an FPU, treat floating point instructions as
853 * reserved. They'll be handled in the math-emu case, or faulted on
854 * otherwise.
855 */
856 set_exception_table_evt(0x800, do_reserved_inst);
857 set_exception_table_evt(0x820, do_illegal_slot_inst);
858#elif defined(CONFIG_SH_FPU)
859#ifdef CONFIG_CPU_SUBTYPE_SHX3
860 set_exception_table_evt(0xd80, do_fpu_state_restore);
861 set_exception_table_evt(0xda0, do_fpu_state_restore);
862#else
863 set_exception_table_evt(0x800, do_fpu_state_restore);
864 set_exception_table_evt(0x820, do_fpu_state_restore);
865#endif
866#endif
867
868#ifdef CONFIG_CPU_SH2
869 set_exception_table_vec(TRAP_ADDRESS_ERROR, address_error_handler);
870#endif
871#ifdef CONFIG_CPU_SH2A
872 set_exception_table_vec(TRAP_DIVZERO_ERROR, do_divide_error);
873 set_exception_table_vec(TRAP_DIVOVF_ERROR, do_divide_error);
874#endif
875
876 /* Setup VBR for boot cpu */
877 per_cpu_trap_init();
878}
879 58
880#ifdef CONFIG_BUG 59#ifdef CONFIG_BUG
881void handle_BUG(struct pt_regs *regs) 60 if (__kernel_text_address(instruction_pointer(regs))) {
882{ 61 opcode_t insn = *(opcode_t *)instruction_pointer(regs);
883 enum bug_trap_type tt; 62 if (insn == TRAPA_BUG_OPCODE)
884 tt = report_bug(regs->pc, regs); 63 handle_BUG(regs);
885 if (tt == BUG_TRAP_TYPE_WARN) {
886 regs->pc += 2;
887 return;
888 } 64 }
889
890 die("Kernel BUG", regs, TRAPA_BUG_OPCODE & 0xff);
891}
892
893int is_valid_bugaddr(unsigned long addr)
894{
895 return addr >= PAGE_OFFSET;
896}
897#endif
898
899void show_trace(struct task_struct *tsk, unsigned long *sp,
900 struct pt_regs *regs)
901{
902 unsigned long addr;
903
904 if (regs && user_mode(regs))
905 return;
906
907 printk("\nCall trace: ");
908#ifdef CONFIG_KALLSYMS
909 printk("\n");
910#endif 65#endif
911 66
912 while (!kstack_end(sp)) { 67 force_sig(SIGTRAP, current);
913 addr = *sp++;
914 if (kernel_text_address(addr))
915 print_ip_sym(addr);
916 }
917
918 printk("\n");
919
920 if (!tsk)
921 tsk = current;
922
923 debug_show_held_locks(tsk);
924}
925
926void show_stack(struct task_struct *tsk, unsigned long *sp)
927{
928 unsigned long stack;
929
930 if (!tsk)
931 tsk = current;
932 if (tsk == current)
933 sp = (unsigned long *)current_stack_pointer;
934 else
935 sp = (unsigned long *)tsk->thread.sp;
936
937 stack = (unsigned long)sp;
938 dump_mem("Stack: ", stack, THREAD_SIZE +
939 (unsigned long)task_stack_page(tsk));
940 show_trace(tsk, sp, NULL);
941}
942
943void dump_stack(void)
944{
945 show_stack(NULL, NULL);
946} 68}
947EXPORT_SYMBOL(dump_stack);
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
new file mode 100644
index 000000000000..2e58f7a6b746
--- /dev/null
+++ b/arch/sh/kernel/traps_32.c
@@ -0,0 +1,919 @@
1/*
2 * 'traps.c' handles hardware traps and faults after we have saved some
3 * state in 'entry.S'.
4 *
5 * SuperH version: Copyright (C) 1999 Niibe Yutaka
6 * Copyright (C) 2000 Philipp Rumpf
7 * Copyright (C) 2000 David Howells
8 * Copyright (C) 2002 - 2007 Paul Mundt
9 *
10 * This file is subject to the terms and conditions of the GNU General Public
11 * License. See the file "COPYING" in the main directory of this archive
12 * for more details.
13 */
14#include <linux/kernel.h>
15#include <linux/ptrace.h>
16#include <linux/init.h>
17#include <linux/spinlock.h>
18#include <linux/module.h>
19#include <linux/kallsyms.h>
20#include <linux/io.h>
21#include <linux/bug.h>
22#include <linux/debug_locks.h>
23#include <linux/kdebug.h>
24#include <linux/kexec.h>
25#include <linux/limits.h>
26#include <asm/system.h>
27#include <asm/uaccess.h>
28
29#ifdef CONFIG_SH_KGDB
30#include <asm/kgdb.h>
31#define CHK_REMOTE_DEBUG(regs) \
32{ \
33 if (kgdb_debug_hook && !user_mode(regs))\
34 (*kgdb_debug_hook)(regs); \
35}
36#else
37#define CHK_REMOTE_DEBUG(regs)
38#endif
39
40#ifdef CONFIG_CPU_SH2
41# define TRAP_RESERVED_INST 4
42# define TRAP_ILLEGAL_SLOT_INST 6
43# define TRAP_ADDRESS_ERROR 9
44# ifdef CONFIG_CPU_SH2A
45# define TRAP_DIVZERO_ERROR 17
46# define TRAP_DIVOVF_ERROR 18
47# endif
48#else
49#define TRAP_RESERVED_INST 12
50#define TRAP_ILLEGAL_SLOT_INST 13
51#endif
52
53static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
54{
55 unsigned long p;
56 int i;
57
58 printk("%s(0x%08lx to 0x%08lx)\n", str, bottom, top);
59
60 for (p = bottom & ~31; p < top; ) {
61 printk("%04lx: ", p & 0xffff);
62
63 for (i = 0; i < 8; i++, p += 4) {
64 unsigned int val;
65
66 if (p < bottom || p >= top)
67 printk(" ");
68 else {
69 if (__get_user(val, (unsigned int __user *)p)) {
70 printk("\n");
71 return;
72 }
73 printk("%08x ", val);
74 }
75 }
76 printk("\n");
77 }
78}
79
80static DEFINE_SPINLOCK(die_lock);
81
82void die(const char * str, struct pt_regs * regs, long err)
83{
84 static int die_counter;
85
86 oops_enter();
87
88 console_verbose();
89 spin_lock_irq(&die_lock);
90 bust_spinlocks(1);
91
92 printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
93
94 CHK_REMOTE_DEBUG(regs);
95 print_modules();
96 show_regs(regs);
97
98 printk("Process: %s (pid: %d, stack limit = %p)\n", current->comm,
99 task_pid_nr(current), task_stack_page(current) + 1);
100
101 if (!user_mode(regs) || in_interrupt())
102 dump_mem("Stack: ", regs->regs[15], THREAD_SIZE +
103 (unsigned long)task_stack_page(current));
104
105 bust_spinlocks(0);
106 add_taint(TAINT_DIE);
107 spin_unlock_irq(&die_lock);
108
109 if (kexec_should_crash(current))
110 crash_kexec(regs);
111
112 if (in_interrupt())
113 panic("Fatal exception in interrupt");
114
115 if (panic_on_oops)
116 panic("Fatal exception");
117
118 oops_exit();
119 do_exit(SIGSEGV);
120}
121
122static inline void die_if_kernel(const char *str, struct pt_regs *regs,
123 long err)
124{
125 if (!user_mode(regs))
126 die(str, regs, err);
127}
128
129/*
130 * try and fix up kernelspace address errors
131 * - userspace errors just cause EFAULT to be returned, resulting in SEGV
132 * - kernel/userspace interfaces cause a jump to an appropriate handler
133 * - other kernel errors are bad
134 * - return 0 if fixed-up, -EFAULT if non-fatal (to the kernel) fault
135 */
136static int die_if_no_fixup(const char * str, struct pt_regs * regs, long err)
137{
138 if (!user_mode(regs)) {
139 const struct exception_table_entry *fixup;
140 fixup = search_exception_tables(regs->pc);
141 if (fixup) {
142 regs->pc = fixup->fixup;
143 return 0;
144 }
145 die(str, regs, err);
146 }
147 return -EFAULT;
148}
149
150/*
151 * handle an instruction that does an unaligned memory access by emulating the
152 * desired behaviour
153 * - note that PC _may not_ point to the faulting instruction
154 * (if that instruction is in a branch delay slot)
155 * - return 0 if emulation okay, -EFAULT on existential error
156 */
157static int handle_unaligned_ins(u16 instruction, struct pt_regs *regs)
158{
159 int ret, index, count;
160 unsigned long *rm, *rn;
161 unsigned char *src, *dst;
162
163 index = (instruction>>8)&15; /* 0x0F00 */
164 rn = &regs->regs[index];
165
166 index = (instruction>>4)&15; /* 0x00F0 */
167 rm = &regs->regs[index];
168
169 count = 1<<(instruction&3);
170
171 ret = -EFAULT;
172 switch (instruction>>12) {
173 case 0: /* mov.[bwl] to/from memory via r0+rn */
174 if (instruction & 8) {
175 /* from memory */
176 src = (unsigned char*) *rm;
177 src += regs->regs[0];
178 dst = (unsigned char*) rn;
179 *(unsigned long*)dst = 0;
180
181#ifdef __LITTLE_ENDIAN__
182 if (copy_from_user(dst, src, count))
183 goto fetch_fault;
184
185 if ((count == 2) && dst[1] & 0x80) {
186 dst[2] = 0xff;
187 dst[3] = 0xff;
188 }
189#else
190 dst += 4-count;
191
192 if (__copy_user(dst, src, count))
193 goto fetch_fault;
194
195 if ((count == 2) && dst[2] & 0x80) {
196 dst[0] = 0xff;
197 dst[1] = 0xff;
198 }
199#endif
200 } else {
201 /* to memory */
202 src = (unsigned char*) rm;
203#if !defined(__LITTLE_ENDIAN__)
204 src += 4-count;
205#endif
206 dst = (unsigned char*) *rn;
207 dst += regs->regs[0];
208
209 if (copy_to_user(dst, src, count))
210 goto fetch_fault;
211 }
212 ret = 0;
213 break;
214
215 case 1: /* mov.l Rm,@(disp,Rn) */
216 src = (unsigned char*) rm;
217 dst = (unsigned char*) *rn;
218 dst += (instruction&0x000F)<<2;
219
220 if (copy_to_user(dst,src,4))
221 goto fetch_fault;
222 ret = 0;
223 break;
224
225 case 2: /* mov.[bwl] to memory, possibly with pre-decrement */
226 if (instruction & 4)
227 *rn -= count;
228 src = (unsigned char*) rm;
229 dst = (unsigned char*) *rn;
230#if !defined(__LITTLE_ENDIAN__)
231 src += 4-count;
232#endif
233 if (copy_to_user(dst, src, count))
234 goto fetch_fault;
235 ret = 0;
236 break;
237
238 case 5: /* mov.l @(disp,Rm),Rn */
239 src = (unsigned char*) *rm;
240 src += (instruction&0x000F)<<2;
241 dst = (unsigned char*) rn;
242 *(unsigned long*)dst = 0;
243
244 if (copy_from_user(dst,src,4))
245 goto fetch_fault;
246 ret = 0;
247 break;
248
249 case 6: /* mov.[bwl] from memory, possibly with post-increment */
250 src = (unsigned char*) *rm;
251 if (instruction & 4)
252 *rm += count;
253 dst = (unsigned char*) rn;
254 *(unsigned long*)dst = 0;
255
256#ifdef __LITTLE_ENDIAN__
257 if (copy_from_user(dst, src, count))
258 goto fetch_fault;
259
260 if ((count == 2) && dst[1] & 0x80) {
261 dst[2] = 0xff;
262 dst[3] = 0xff;
263 }
264#else
265 dst += 4-count;
266
267 if (copy_from_user(dst, src, count))
268 goto fetch_fault;
269
270 if ((count == 2) && dst[2] & 0x80) {
271 dst[0] = 0xff;
272 dst[1] = 0xff;
273 }
274#endif
275 ret = 0;
276 break;
277
278 case 8:
279 switch ((instruction&0xFF00)>>8) {
280 case 0x81: /* mov.w R0,@(disp,Rn) */
281 src = (unsigned char*) &regs->regs[0];
282#if !defined(__LITTLE_ENDIAN__)
283 src += 2;
284#endif
285 dst = (unsigned char*) *rm; /* called Rn in the spec */
286 dst += (instruction&0x000F)<<1;
287
288 if (copy_to_user(dst, src, 2))
289 goto fetch_fault;
290 ret = 0;
291 break;
292
293 case 0x85: /* mov.w @(disp,Rm),R0 */
294 src = (unsigned char*) *rm;
295 src += (instruction&0x000F)<<1;
296 dst = (unsigned char*) &regs->regs[0];
297 *(unsigned long*)dst = 0;
298
299#if !defined(__LITTLE_ENDIAN__)
300 dst += 2;
301#endif
302
303 if (copy_from_user(dst, src, 2))
304 goto fetch_fault;
305
306#ifdef __LITTLE_ENDIAN__
307 if (dst[1] & 0x80) {
308 dst[2] = 0xff;
309 dst[3] = 0xff;
310 }
311#else
312 if (dst[2] & 0x80) {
313 dst[0] = 0xff;
314 dst[1] = 0xff;
315 }
316#endif
317 ret = 0;
318 break;
319 }
320 break;
321 }
322 return ret;
323
324 fetch_fault:
325 /* Argh. Address not only misaligned but also non-existent.
326 * Raise an EFAULT and see if it's trapped
327 */
328 return die_if_no_fixup("Fault in unaligned fixup", regs, 0);
329}
330
331/*
332 * emulate the instruction in the delay slot
333 * - fetches the instruction from PC+2
334 */
335static inline int handle_unaligned_delayslot(struct pt_regs *regs)
336{
337 u16 instruction;
338
339 if (copy_from_user(&instruction, (u16 *)(regs->pc+2), 2)) {
340 /* the instruction-fetch faulted */
341 if (user_mode(regs))
342 return -EFAULT;
343
344 /* kernel */
345 die("delay-slot-insn faulting in handle_unaligned_delayslot",
346 regs, 0);
347 }
348
349 return handle_unaligned_ins(instruction,regs);
350}
351
352/*
353 * handle an instruction that does an unaligned memory access
354 * - have to be careful of branch delay-slot instructions that fault
355 * SH3:
356 * - if the branch would be taken PC points to the branch
357 * - if the branch would not be taken, PC points to delay-slot
358 * SH4:
359 * - PC always points to delayed branch
360 * - return 0 if handled, -EFAULT if failed (may not return if in kernel)
361 */
362
363/* Macros to determine offset from current PC for branch instructions */
364/* Explicit type coercion is used to force sign extension where needed */
365#define SH_PC_8BIT_OFFSET(instr) ((((signed char)(instr))*2) + 4)
366#define SH_PC_12BIT_OFFSET(instr) ((((signed short)(instr<<4))>>3) + 4)
367
368/*
369 * XXX: SH-2A needs this too, but it needs an overhaul thanks to mixed 32-bit
370 * opcodes..
371 */
372#ifndef CONFIG_CPU_SH2A
373static int handle_unaligned_notify_count = 10;
374
375static int handle_unaligned_access(u16 instruction, struct pt_regs *regs)
376{
377 u_int rm;
378 int ret, index;
379
380 index = (instruction>>8)&15; /* 0x0F00 */
381 rm = regs->regs[index];
382
383 /* shout about the first ten userspace fixups */
384 if (user_mode(regs) && handle_unaligned_notify_count>0) {
385 handle_unaligned_notify_count--;
386
387 printk(KERN_NOTICE "Fixing up unaligned userspace access "
388 "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
389 current->comm, task_pid_nr(current),
390 (u16 *)regs->pc, instruction);
391 }
392
393 ret = -EFAULT;
394 switch (instruction&0xF000) {
395 case 0x0000:
396 if (instruction==0x000B) {
397 /* rts */
398 ret = handle_unaligned_delayslot(regs);
399 if (ret==0)
400 regs->pc = regs->pr;
401 }
402 else if ((instruction&0x00FF)==0x0023) {
403 /* braf @Rm */
404 ret = handle_unaligned_delayslot(regs);
405 if (ret==0)
406 regs->pc += rm + 4;
407 }
408 else if ((instruction&0x00FF)==0x0003) {
409 /* bsrf @Rm */
410 ret = handle_unaligned_delayslot(regs);
411 if (ret==0) {
412 regs->pr = regs->pc + 4;
413 regs->pc += rm + 4;
414 }
415 }
416 else {
417 /* mov.[bwl] to/from memory via r0+rn */
418 goto simple;
419 }
420 break;
421
422 case 0x1000: /* mov.l Rm,@(disp,Rn) */
423 goto simple;
424
425 case 0x2000: /* mov.[bwl] to memory, possibly with pre-decrement */
426 goto simple;
427
428 case 0x4000:
429 if ((instruction&0x00FF)==0x002B) {
430 /* jmp @Rm */
431 ret = handle_unaligned_delayslot(regs);
432 if (ret==0)
433 regs->pc = rm;
434 }
435 else if ((instruction&0x00FF)==0x000B) {
436 /* jsr @Rm */
437 ret = handle_unaligned_delayslot(regs);
438 if (ret==0) {
439 regs->pr = regs->pc + 4;
440 regs->pc = rm;
441 }
442 }
443 else {
444 /* mov.[bwl] to/from memory via r0+rn */
445 goto simple;
446 }
447 break;
448
449 case 0x5000: /* mov.l @(disp,Rm),Rn */
450 goto simple;
451
452 case 0x6000: /* mov.[bwl] from memory, possibly with post-increment */
453 goto simple;
454
455 case 0x8000: /* bf lab, bf/s lab, bt lab, bt/s lab */
456 switch (instruction&0x0F00) {
457 case 0x0100: /* mov.w R0,@(disp,Rm) */
458 goto simple;
459 case 0x0500: /* mov.w @(disp,Rm),R0 */
460 goto simple;
461 case 0x0B00: /* bf lab - no delayslot*/
462 break;
463 case 0x0F00: /* bf/s lab */
464 ret = handle_unaligned_delayslot(regs);
465 if (ret==0) {
466#if defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB)
467 if ((regs->sr & 0x00000001) != 0)
468 regs->pc += 4; /* next after slot */
469 else
470#endif
471 regs->pc += SH_PC_8BIT_OFFSET(instruction);
472 }
473 break;
474 case 0x0900: /* bt lab - no delayslot */
475 break;
476 case 0x0D00: /* bt/s lab */
477 ret = handle_unaligned_delayslot(regs);
478 if (ret==0) {
479#if defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB)
480 if ((regs->sr & 0x00000001) == 0)
481 regs->pc += 4; /* next after slot */
482 else
483#endif
484 regs->pc += SH_PC_8BIT_OFFSET(instruction);
485 }
486 break;
487 }
488 break;
489
490 case 0xA000: /* bra label */
491 ret = handle_unaligned_delayslot(regs);
492 if (ret==0)
493 regs->pc += SH_PC_12BIT_OFFSET(instruction);
494 break;
495
496 case 0xB000: /* bsr label */
497 ret = handle_unaligned_delayslot(regs);
498 if (ret==0) {
499 regs->pr = regs->pc + 4;
500 regs->pc += SH_PC_12BIT_OFFSET(instruction);
501 }
502 break;
503 }
504 return ret;
505
506 /* handle non-delay-slot instruction */
507 simple:
508 ret = handle_unaligned_ins(instruction,regs);
509 if (ret==0)
510 regs->pc += instruction_size(instruction);
511 return ret;
512}
513#endif /* CONFIG_CPU_SH2A */
514
515#ifdef CONFIG_CPU_HAS_SR_RB
516#define lookup_exception_vector(x) \
517 __asm__ __volatile__ ("stc r2_bank, %0\n\t" : "=r" ((x)))
518#else
519#define lookup_exception_vector(x) \
520 __asm__ __volatile__ ("mov r4, %0\n\t" : "=r" ((x)))
521#endif
522
523/*
524 * Handle various address error exceptions:
525 * - instruction address error:
526 * misaligned PC
527 * PC >= 0x80000000 in user mode
528 * - data address error (read and write)
529 * misaligned data access
530 * access to >= 0x80000000 is user mode
531 * Unfortuntaly we can't distinguish between instruction address error
532 * and data address errors caused by read accesses.
533 */
534asmlinkage void do_address_error(struct pt_regs *regs,
535 unsigned long writeaccess,
536 unsigned long address)
537{
538 unsigned long error_code = 0;
539 mm_segment_t oldfs;
540 siginfo_t info;
541#ifndef CONFIG_CPU_SH2A
542 u16 instruction;
543 int tmp;
544#endif
545
546 /* Intentional ifdef */
547#ifdef CONFIG_CPU_HAS_SR_RB
548 lookup_exception_vector(error_code);
549#endif
550
551 oldfs = get_fs();
552
553 if (user_mode(regs)) {
554 int si_code = BUS_ADRERR;
555
556 local_irq_enable();
557
558 /* bad PC is not something we can fix */
559 if (regs->pc & 1) {
560 si_code = BUS_ADRALN;
561 goto uspace_segv;
562 }
563
564#ifndef CONFIG_CPU_SH2A
565 set_fs(USER_DS);
566 if (copy_from_user(&instruction, (u16 *)(regs->pc), 2)) {
567 /* Argh. Fault on the instruction itself.
568 This should never happen non-SMP
569 */
570 set_fs(oldfs);
571 goto uspace_segv;
572 }
573
574 tmp = handle_unaligned_access(instruction, regs);
575 set_fs(oldfs);
576
577 if (tmp==0)
578 return; /* sorted */
579#endif
580
581uspace_segv:
582 printk(KERN_NOTICE "Sending SIGBUS to \"%s\" due to unaligned "
583 "access (PC %lx PR %lx)\n", current->comm, regs->pc,
584 regs->pr);
585
586 info.si_signo = SIGBUS;
587 info.si_errno = 0;
588 info.si_code = si_code;
589 info.si_addr = (void __user *)address;
590 force_sig_info(SIGBUS, &info, current);
591 } else {
592 if (regs->pc & 1)
593 die("unaligned program counter", regs, error_code);
594
595#ifndef CONFIG_CPU_SH2A
596 set_fs(KERNEL_DS);
597 if (copy_from_user(&instruction, (u16 *)(regs->pc), 2)) {
598 /* Argh. Fault on the instruction itself.
599 This should never happen non-SMP
600 */
601 set_fs(oldfs);
602 die("insn faulting in do_address_error", regs, 0);
603 }
604
605 handle_unaligned_access(instruction, regs);
606 set_fs(oldfs);
607#else
608 printk(KERN_NOTICE "Killing process \"%s\" due to unaligned "
609 "access\n", current->comm);
610
611 force_sig(SIGSEGV, current);
612#endif
613 }
614}
615
616#ifdef CONFIG_SH_DSP
617/*
618 * SH-DSP support gerg@snapgear.com.
619 */
620int is_dsp_inst(struct pt_regs *regs)
621{
622 unsigned short inst = 0;
623
624 /*
625 * Safe guard if DSP mode is already enabled or we're lacking
626 * the DSP altogether.
627 */
628 if (!(current_cpu_data.flags & CPU_HAS_DSP) || (regs->sr & SR_DSP))
629 return 0;
630
631 get_user(inst, ((unsigned short *) regs->pc));
632
633 inst &= 0xf000;
634
635 /* Check for any type of DSP or support instruction */
636 if ((inst == 0xf000) || (inst == 0x4000))
637 return 1;
638
639 return 0;
640}
641#else
642#define is_dsp_inst(regs) (0)
643#endif /* CONFIG_SH_DSP */
644
645#ifdef CONFIG_CPU_SH2A
646asmlinkage void do_divide_error(unsigned long r4, unsigned long r5,
647 unsigned long r6, unsigned long r7,
648 struct pt_regs __regs)
649{
650 siginfo_t info;
651
652 switch (r4) {
653 case TRAP_DIVZERO_ERROR:
654 info.si_code = FPE_INTDIV;
655 break;
656 case TRAP_DIVOVF_ERROR:
657 info.si_code = FPE_INTOVF;
658 break;
659 }
660
661 force_sig_info(SIGFPE, &info, current);
662}
663#endif
664
665asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5,
666 unsigned long r6, unsigned long r7,
667 struct pt_regs __regs)
668{
669 struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
670 unsigned long error_code;
671 struct task_struct *tsk = current;
672
673#ifdef CONFIG_SH_FPU_EMU
674 unsigned short inst = 0;
675 int err;
676
677 get_user(inst, (unsigned short*)regs->pc);
678
679 err = do_fpu_inst(inst, regs);
680 if (!err) {
681 regs->pc += instruction_size(inst);
682 return;
683 }
684 /* not a FPU inst. */
685#endif
686
687#ifdef CONFIG_SH_DSP
688 /* Check if it's a DSP instruction */
689 if (is_dsp_inst(regs)) {
690 /* Enable DSP mode, and restart instruction. */
691 regs->sr |= SR_DSP;
692 return;
693 }
694#endif
695
696 lookup_exception_vector(error_code);
697
698 local_irq_enable();
699 CHK_REMOTE_DEBUG(regs);
700 force_sig(SIGILL, tsk);
701 die_if_no_fixup("reserved instruction", regs, error_code);
702}
703
704#ifdef CONFIG_SH_FPU_EMU
705static int emulate_branch(unsigned short inst, struct pt_regs* regs)
706{
707 /*
708 * bfs: 8fxx: PC+=d*2+4;
709 * bts: 8dxx: PC+=d*2+4;
710 * bra: axxx: PC+=D*2+4;
711 * bsr: bxxx: PC+=D*2+4 after PR=PC+4;
712 * braf:0x23: PC+=Rn*2+4;
713 * bsrf:0x03: PC+=Rn*2+4 after PR=PC+4;
714 * jmp: 4x2b: PC=Rn;
715 * jsr: 4x0b: PC=Rn after PR=PC+4;
716 * rts: 000b: PC=PR;
717 */
718 if ((inst & 0xfd00) == 0x8d00) {
719 regs->pc += SH_PC_8BIT_OFFSET(inst);
720 return 0;
721 }
722
723 if ((inst & 0xe000) == 0xa000) {
724 regs->pc += SH_PC_12BIT_OFFSET(inst);
725 return 0;
726 }
727
728 if ((inst & 0xf0df) == 0x0003) {
729 regs->pc += regs->regs[(inst & 0x0f00) >> 8] + 4;
730 return 0;
731 }
732
733 if ((inst & 0xf0df) == 0x400b) {
734 regs->pc = regs->regs[(inst & 0x0f00) >> 8];
735 return 0;
736 }
737
738 if ((inst & 0xffff) == 0x000b) {
739 regs->pc = regs->pr;
740 return 0;
741 }
742
743 return 1;
744}
745#endif
746
747asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5,
748 unsigned long r6, unsigned long r7,
749 struct pt_regs __regs)
750{
751 struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
752 unsigned long error_code;
753 struct task_struct *tsk = current;
754#ifdef CONFIG_SH_FPU_EMU
755 unsigned short inst = 0;
756
757 get_user(inst, (unsigned short *)regs->pc + 1);
758 if (!do_fpu_inst(inst, regs)) {
759 get_user(inst, (unsigned short *)regs->pc);
760 if (!emulate_branch(inst, regs))
761 return;
762 /* fault in branch.*/
763 }
764 /* not a FPU inst. */
765#endif
766
767 lookup_exception_vector(error_code);
768
769 local_irq_enable();
770 CHK_REMOTE_DEBUG(regs);
771 force_sig(SIGILL, tsk);
772 die_if_no_fixup("illegal slot instruction", regs, error_code);
773}
774
775asmlinkage void do_exception_error(unsigned long r4, unsigned long r5,
776 unsigned long r6, unsigned long r7,
777 struct pt_regs __regs)
778{
779 struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
780 long ex;
781
782 lookup_exception_vector(ex);
783 die_if_kernel("exception", regs, ex);
784}
785
786#if defined(CONFIG_SH_STANDARD_BIOS)
787void *gdb_vbr_vector;
788
789static inline void __init gdb_vbr_init(void)
790{
791 register unsigned long vbr;
792
793 /*
794 * Read the old value of the VBR register to initialise
795 * the vector through which debug and BIOS traps are
796 * delegated by the Linux trap handler.
797 */
798 asm volatile("stc vbr, %0" : "=r" (vbr));
799
800 gdb_vbr_vector = (void *)(vbr + 0x100);
801 printk("Setting GDB trap vector to 0x%08lx\n",
802 (unsigned long)gdb_vbr_vector);
803}
804#endif
805
806void __cpuinit per_cpu_trap_init(void)
807{
808 extern void *vbr_base;
809
810#ifdef CONFIG_SH_STANDARD_BIOS
811 if (raw_smp_processor_id() == 0)
812 gdb_vbr_init();
813#endif
814
815 /* NOTE: The VBR value should be at P1
816 (or P2, virtural "fixed" address space).
817 It's definitely should not in physical address. */
818
819 asm volatile("ldc %0, vbr"
820 : /* no output */
821 : "r" (&vbr_base)
822 : "memory");
823}
824
825void *set_exception_table_vec(unsigned int vec, void *handler)
826{
827 extern void *exception_handling_table[];
828 void *old_handler;
829
830 old_handler = exception_handling_table[vec];
831 exception_handling_table[vec] = handler;
832 return old_handler;
833}
834
835void __init trap_init(void)
836{
837 set_exception_table_vec(TRAP_RESERVED_INST, do_reserved_inst);
838 set_exception_table_vec(TRAP_ILLEGAL_SLOT_INST, do_illegal_slot_inst);
839
840#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_FPU) || \
841 defined(CONFIG_SH_FPU_EMU)
842 /*
843 * For SH-4 lacking an FPU, treat floating point instructions as
844 * reserved. They'll be handled in the math-emu case, or faulted on
845 * otherwise.
846 */
847 set_exception_table_evt(0x800, do_reserved_inst);
848 set_exception_table_evt(0x820, do_illegal_slot_inst);
849#elif defined(CONFIG_SH_FPU)
850#ifdef CONFIG_CPU_SUBTYPE_SHX3
851 set_exception_table_evt(0xd80, fpu_state_restore_trap_handler);
852 set_exception_table_evt(0xda0, fpu_state_restore_trap_handler);
853#else
854 set_exception_table_evt(0x800, fpu_state_restore_trap_handler);
855 set_exception_table_evt(0x820, fpu_state_restore_trap_handler);
856#endif
857#endif
858
859#ifdef CONFIG_CPU_SH2
860 set_exception_table_vec(TRAP_ADDRESS_ERROR, address_error_trap_handler);
861#endif
862#ifdef CONFIG_CPU_SH2A
863 set_exception_table_vec(TRAP_DIVZERO_ERROR, do_divide_error);
864 set_exception_table_vec(TRAP_DIVOVF_ERROR, do_divide_error);
865#endif
866
867 /* Setup VBR for boot cpu */
868 per_cpu_trap_init();
869}
870
871void show_trace(struct task_struct *tsk, unsigned long *sp,
872 struct pt_regs *regs)
873{
874 unsigned long addr;
875
876 if (regs && user_mode(regs))
877 return;
878
879 printk("\nCall trace: ");
880#ifdef CONFIG_KALLSYMS
881 printk("\n");
882#endif
883
884 while (!kstack_end(sp)) {
885 addr = *sp++;
886 if (kernel_text_address(addr))
887 print_ip_sym(addr);
888 }
889
890 printk("\n");
891
892 if (!tsk)
893 tsk = current;
894
895 debug_show_held_locks(tsk);
896}
897
898void show_stack(struct task_struct *tsk, unsigned long *sp)
899{
900 unsigned long stack;
901
902 if (!tsk)
903 tsk = current;
904 if (tsk == current)
905 sp = (unsigned long *)current_stack_pointer;
906 else
907 sp = (unsigned long *)tsk->thread.sp;
908
909 stack = (unsigned long)sp;
910 dump_mem("Stack: ", stack, THREAD_SIZE +
911 (unsigned long)task_stack_page(tsk));
912 show_trace(tsk, sp, NULL);
913}
914
915void dump_stack(void)
916{
917 show_stack(NULL, NULL);
918}
919EXPORT_SYMBOL(dump_stack);
diff --git a/arch/sh64/kernel/traps.c b/arch/sh/kernel/traps_64.c
index f32df3831f45..c0b3c6f6edb5 100644
--- a/arch/sh64/kernel/traps.c
+++ b/arch/sh/kernel/traps_64.c
@@ -1,19 +1,13 @@
1/* 1/*
2 * This file is subject to the terms and conditions of the GNU General Public 2 * arch/sh/kernel/traps_64.c
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * arch/sh64/kernel/traps.c
7 * 3 *
8 * Copyright (C) 2000, 2001 Paolo Alberelli 4 * Copyright (C) 2000, 2001 Paolo Alberelli
9 * Copyright (C) 2003, 2004 Paul Mundt 5 * Copyright (C) 2003, 2004 Paul Mundt
10 * Copyright (C) 2003, 2004 Richard Curnow 6 * Copyright (C) 2003, 2004 Richard Curnow
11 * 7 *
12 */ 8 * This file is subject to the terms and conditions of the GNU General Public
13 9 * License. See the file "COPYING" in the main directory of this archive
14/* 10 * for more details.
15 * 'Traps.c' handles hardware traps and faults after we have saved some
16 * state in 'entry.S'.
17 */ 11 */
18#include <linux/sched.h> 12#include <linux/sched.h>
19#include <linux/kernel.h> 13#include <linux/kernel.h>
@@ -244,7 +238,6 @@ DO_ERROR(12, SIGILL, "reserved instruction", reserved_inst, current)
244/* Called with interrupts disabled */ 238/* Called with interrupts disabled */
245asmlinkage void do_exception_error(unsigned long ex, struct pt_regs *regs) 239asmlinkage void do_exception_error(unsigned long ex, struct pt_regs *regs)
246{ 240{
247 PLS();
248 show_excp_regs(__FUNCTION__, -1, -1, regs); 241 show_excp_regs(__FUNCTION__, -1, -1, regs);
249 die_if_kernel("exception", regs, ex); 242 die_if_kernel("exception", regs, ex);
250} 243}
@@ -618,9 +611,9 @@ static int misaligned_fpu_load(struct pt_regs *regs,
618 context switch the registers into memory so they can be 611 context switch the registers into memory so they can be
619 indexed by register number. */ 612 indexed by register number. */
620 if (last_task_used_math == current) { 613 if (last_task_used_math == current) {
621 grab_fpu(); 614 enable_fpu();
622 fpsave(&current->thread.fpu.hard); 615 save_fpu(current, regs);
623 release_fpu(); 616 disable_fpu();
624 last_task_used_math = NULL; 617 last_task_used_math = NULL;
625 regs->sr |= SR_FD; 618 regs->sr |= SR_FD;
626 } 619 }
@@ -691,9 +684,9 @@ static int misaligned_fpu_store(struct pt_regs *regs,
691 context switch the registers into memory so they can be 684 context switch the registers into memory so they can be
692 indexed by register number. */ 685 indexed by register number. */
693 if (last_task_used_math == current) { 686 if (last_task_used_math == current) {
694 grab_fpu(); 687 enable_fpu();
695 fpsave(&current->thread.fpu.hard); 688 save_fpu(current, regs);
696 release_fpu(); 689 disable_fpu();
697 last_task_used_math = NULL; 690 last_task_used_math = NULL;
698 regs->sr |= SR_FD; 691 regs->sr |= SR_FD;
699 } 692 }
diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S
index 0956fb3681a3..d7d4991f32af 100644
--- a/arch/sh/kernel/vmlinux.lds.S
+++ b/arch/sh/kernel/vmlinux.lds.S
@@ -1,138 +1,5 @@
1/* 1#ifdef CONFIG_SUPERH32
2 * ld script to make SuperH Linux kernel 2# include "vmlinux_32.lds.S"
3 * Written by Niibe Yutaka
4 */
5#include <asm/thread_info.h>
6#include <asm/cache.h>
7#include <asm-generic/vmlinux.lds.h>
8
9#ifdef CONFIG_CPU_LITTLE_ENDIAN
10OUTPUT_FORMAT("elf32-sh-linux", "elf32-sh-linux", "elf32-sh-linux")
11#else 3#else
12OUTPUT_FORMAT("elf32-shbig-linux", "elf32-shbig-linux", "elf32-shbig-linux") 4# include "vmlinux_64.lds.S"
13#endif 5#endif
14OUTPUT_ARCH(sh)
15ENTRY(_start)
16SECTIONS
17{
18 . = CONFIG_PAGE_OFFSET + CONFIG_MEMORY_START + CONFIG_ZERO_PAGE_OFFSET;
19 _text = .; /* Text and read-only data */
20
21 .empty_zero_page : {
22 *(.empty_zero_page)
23 } = 0
24
25 .text : {
26 *(.text.head)
27 TEXT_TEXT
28 SCHED_TEXT
29 LOCK_TEXT
30 KPROBES_TEXT
31 *(.fixup)
32 *(.gnu.warning)
33 } = 0x0009
34
35 . = ALIGN(16); /* Exception table */
36 __start___ex_table = .;
37 __ex_table : { *(__ex_table) }
38 __stop___ex_table = .;
39
40 _etext = .; /* End of text section */
41
42 BUG_TABLE
43 NOTES
44 RO_DATA(PAGE_SIZE)
45
46 . = ALIGN(THREAD_SIZE);
47 .data : { /* Data */
48 *(.data.init_task)
49
50 . = ALIGN(L1_CACHE_BYTES);
51 *(.data.cacheline_aligned)
52
53 . = ALIGN(L1_CACHE_BYTES);
54 *(.data.read_mostly)
55
56 . = ALIGN(PAGE_SIZE);
57 *(.data.page_aligned)
58
59 __nosave_begin = .;
60 *(.data.nosave)
61 . = ALIGN(PAGE_SIZE);
62 __nosave_end = .;
63
64 DATA_DATA
65 CONSTRUCTORS
66 }
67
68 _edata = .; /* End of data section */
69
70 . = ALIGN(PAGE_SIZE); /* Init code and data */
71 __init_begin = .;
72 _sinittext = .;
73 .init.text : { *(.init.text) }
74 _einittext = .;
75 .init.data : { *(.init.data) }
76
77 . = ALIGN(16);
78 __setup_start = .;
79 .init.setup : { *(.init.setup) }
80 __setup_end = .;
81
82 __initcall_start = .;
83 .initcall.init : {
84 INITCALLS
85 }
86 __initcall_end = .;
87 __con_initcall_start = .;
88 .con_initcall.init : { *(.con_initcall.init) }
89 __con_initcall_end = .;
90
91 SECURITY_INIT
92
93#ifdef CONFIG_BLK_DEV_INITRD
94 . = ALIGN(PAGE_SIZE);
95 __initramfs_start = .;
96 .init.ramfs : { *(.init.ramfs) }
97 __initramfs_end = .;
98#endif
99
100 . = ALIGN(4);
101 __machvec_start = .;
102 .machvec.init : { *(.machvec.init) }
103 __machvec_end = .;
104
105 PERCPU(PAGE_SIZE)
106
107 /*
108 * .exit.text is discarded at runtime, not link time, to deal with
109 * references from __bug_table
110 */
111 .exit.text : { *(.exit.text) }
112 .exit.data : { *(.exit.data) }
113
114 . = ALIGN(PAGE_SIZE);
115 .bss : {
116 __init_end = .;
117 __bss_start = .; /* BSS */
118 *(.bss.page_aligned)
119 *(.bss)
120 *(COMMON)
121 . = ALIGN(4);
122 _ebss = .; /* uClinux MTD sucks */
123 _end = . ;
124 }
125
126 /*
127 * When something in the kernel is NOT compiled as a module, the
128 * module cleanup code and data are put into these segments. Both
129 * can then be thrown away, as cleanup code is never called unless
130 * it's a module.
131 */
132 /DISCARD/ : {
133 *(.exitcall.exit)
134 }
135
136 STABS_DEBUG
137 DWARF_DEBUG
138}
diff --git a/arch/sh/kernel/vmlinux_32.lds.S b/arch/sh/kernel/vmlinux_32.lds.S
new file mode 100644
index 000000000000..c7113786ecd4
--- /dev/null
+++ b/arch/sh/kernel/vmlinux_32.lds.S
@@ -0,0 +1,152 @@
1/*
2 * ld script to make SuperH Linux kernel
3 * Written by Niibe Yutaka
4 */
5#include <asm/thread_info.h>
6#include <asm/cache.h>
7#include <asm-generic/vmlinux.lds.h>
8
9#ifdef CONFIG_CPU_LITTLE_ENDIAN
10OUTPUT_FORMAT("elf32-sh-linux", "elf32-sh-linux", "elf32-sh-linux")
11#else
12OUTPUT_FORMAT("elf32-shbig-linux", "elf32-shbig-linux", "elf32-shbig-linux")
13#endif
14OUTPUT_ARCH(sh)
15ENTRY(_start)
16SECTIONS
17{
18#ifdef CONFIG_32BIT
19 . = CONFIG_PAGE_OFFSET + CONFIG_ZERO_PAGE_OFFSET;
20#else
21 . = CONFIG_PAGE_OFFSET + CONFIG_MEMORY_START + CONFIG_ZERO_PAGE_OFFSET;
22#endif
23
24 _text = .; /* Text and read-only data */
25
26 .empty_zero_page : {
27 *(.empty_zero_page)
28 } = 0
29
30 .text : {
31 *(.text.head)
32 TEXT_TEXT
33 SCHED_TEXT
34 LOCK_TEXT
35 KPROBES_TEXT
36 *(.fixup)
37 *(.gnu.warning)
38 } = 0x0009
39
40 . = ALIGN(16); /* Exception table */
41 __start___ex_table = .;
42 __ex_table : { *(__ex_table) }
43 __stop___ex_table = .;
44
45 _etext = .; /* End of text section */
46
47 BUG_TABLE
48 NOTES
49 RO_DATA(PAGE_SIZE)
50
51 /*
52 * Code which must be executed uncached and the associated data
53 */
54 . = ALIGN(PAGE_SIZE);
55 __uncached_start = .;
56 .uncached.text : { *(.uncached.text) }
57 .uncached.data : { *(.uncached.data) }
58 __uncached_end = .;
59
60 . = ALIGN(THREAD_SIZE);
61 .data : { /* Data */
62 *(.data.init_task)
63
64 . = ALIGN(L1_CACHE_BYTES);
65 *(.data.cacheline_aligned)
66
67 . = ALIGN(L1_CACHE_BYTES);
68 *(.data.read_mostly)
69
70 . = ALIGN(PAGE_SIZE);
71 *(.data.page_aligned)
72
73 __nosave_begin = .;
74 *(.data.nosave)
75 . = ALIGN(PAGE_SIZE);
76 __nosave_end = .;
77
78 DATA_DATA
79 CONSTRUCTORS
80 }
81
82 _edata = .; /* End of data section */
83
84 . = ALIGN(PAGE_SIZE); /* Init code and data */
85 __init_begin = .;
86 _sinittext = .;
87 .init.text : { INIT_TEXT }
88 _einittext = .;
89 .init.data : { INIT_DATA }
90
91 . = ALIGN(16);
92 __setup_start = .;
93 .init.setup : { *(.init.setup) }
94 __setup_end = .;
95
96 __initcall_start = .;
97 .initcall.init : {
98 INITCALLS
99 }
100 __initcall_end = .;
101 __con_initcall_start = .;
102 .con_initcall.init : { *(.con_initcall.init) }
103 __con_initcall_end = .;
104
105 SECURITY_INIT
106
107#ifdef CONFIG_BLK_DEV_INITRD
108 . = ALIGN(PAGE_SIZE);
109 __initramfs_start = .;
110 .init.ramfs : { *(.init.ramfs) }
111 __initramfs_end = .;
112#endif
113
114 . = ALIGN(4);
115 __machvec_start = .;
116 .machvec.init : { *(.machvec.init) }
117 __machvec_end = .;
118
119 PERCPU(PAGE_SIZE)
120
121 /*
122 * .exit.text is discarded at runtime, not link time, to deal with
123 * references from __bug_table
124 */
125 .exit.text : { EXIT_TEXT }
126 .exit.data : { EXIT_DATA }
127
128 . = ALIGN(PAGE_SIZE);
129 .bss : {
130 __init_end = .;
131 __bss_start = .; /* BSS */
132 *(.bss.page_aligned)
133 *(.bss)
134 *(COMMON)
135 . = ALIGN(4);
136 _ebss = .; /* uClinux MTD sucks */
137 _end = . ;
138 }
139
140 /*
141 * When something in the kernel is NOT compiled as a module, the
142 * module cleanup code and data are put into these segments. Both
143 * can then be thrown away, as cleanup code is never called unless
144 * it's a module.
145 */
146 /DISCARD/ : {
147 *(.exitcall.exit)
148 }
149
150 STABS_DEBUG
151 DWARF_DEBUG
152}
diff --git a/arch/sh/kernel/vmlinux_64.lds.S b/arch/sh/kernel/vmlinux_64.lds.S
new file mode 100644
index 000000000000..3f1bd6392bb3
--- /dev/null
+++ b/arch/sh/kernel/vmlinux_64.lds.S
@@ -0,0 +1,164 @@
1/*
2 * ld script to make SH64 Linux kernel
3 *
4 * Copyright (C) 2000, 2001 Paolo Alberelli
5 *
6 * benedict.gaster@superh.com: 2nd May 2002
7 * Add definition of empty_zero_page to be the first page of kernel image.
8 *
9 * benedict.gaster@superh.com: 3rd May 2002
10 * Added support for ramdisk, removing statically linked romfs at the
11 * same time.
12 *
13 * lethal@linux-sh.org: 9th May 2003
14 * Kill off GLOBAL_NAME() usage and other CDC-isms.
15 *
16 * lethal@linux-sh.org: 19th May 2003
17 * Remove support for ancient toolchains.
18 *
19 * This file is subject to the terms and conditions of the GNU General Public
20 * License. See the file "COPYING" in the main directory of this archive
21 * for more details.
22 */
23#include <asm/page.h>
24#include <asm/cache.h>
25#include <asm/thread_info.h>
26
27#define LOAD_OFFSET CONFIG_PAGE_OFFSET
28#include <asm-generic/vmlinux.lds.h>
29
30OUTPUT_ARCH(sh:sh5)
31
32#define C_PHYS(x) AT (ADDR(x) - LOAD_OFFSET)
33
34ENTRY(__start)
35SECTIONS
36{
37 . = CONFIG_PAGE_OFFSET + CONFIG_MEMORY_START + PAGE_SIZE;
38 _text = .; /* Text and read-only data */
39
40 .empty_zero_page : C_PHYS(.empty_zero_page) {
41 *(.empty_zero_page)
42 } = 0
43
44 .text : C_PHYS(.text) {
45 *(.text.head)
46 TEXT_TEXT
47 *(.text64)
48 *(.text..SHmedia32)
49 SCHED_TEXT
50 LOCK_TEXT
51 KPROBES_TEXT
52 *(.fixup)
53 *(.gnu.warning)
54#ifdef CONFIG_LITTLE_ENDIAN
55 } = 0x6ff0fff0
56#else
57 } = 0xf0fff06f
58#endif
59
60 /* We likely want __ex_table to be Cache Line aligned */
61 . = ALIGN(L1_CACHE_BYTES); /* Exception table */
62 __start___ex_table = .;
63 __ex_table : C_PHYS(__ex_table) { *(__ex_table) }
64 __stop___ex_table = .;
65
66 _etext = .; /* End of text section */
67
68 BUG_TABLE
69 NOTES
70 RO_DATA(PAGE_SIZE)
71
72 . = ALIGN(THREAD_SIZE);
73 .data : C_PHYS(.data) { /* Data */
74 *(.data.init_task)
75
76 . = ALIGN(L1_CACHE_BYTES);
77 *(.data.cacheline_aligned)
78
79 . = ALIGN(L1_CACHE_BYTES);
80 *(.data.read_mostly)
81
82 . = ALIGN(PAGE_SIZE);
83 *(.data.page_aligned)
84
85 __nosave_begin = .;
86 *(.data.nosave)
87 . = ALIGN(PAGE_SIZE);
88 __nosave_end = .;
89
90 DATA_DATA
91 CONSTRUCTORS
92 }
93
94 _edata = .; /* End of data section */
95
96 . = ALIGN(PAGE_SIZE); /* Init code and data */
97 __init_begin = .;
98 _sinittext = .;
99 .init.text : C_PHYS(.init.text) { INIT_TEXT }
100 _einittext = .;
101 .init.data : C_PHYS(.init.data) { INIT_DATA }
102 . = ALIGN(L1_CACHE_BYTES); /* Better if Cache Line aligned */
103 __setup_start = .;
104 .init.setup : C_PHYS(.init.setup) { *(.init.setup) }
105 __setup_end = .;
106 __initcall_start = .;
107 .initcall.init : C_PHYS(.initcall.init) {
108 INITCALLS
109 }
110 __initcall_end = .;
111 __con_initcall_start = .;
112 .con_initcall.init : C_PHYS(.con_initcall.init) {
113 *(.con_initcall.init)
114 }
115 __con_initcall_end = .;
116
117 SECURITY_INIT
118
119#ifdef CONFIG_BLK_DEV_INITRD
120 . = ALIGN(PAGE_SIZE);
121 __initramfs_start = .;
122 .init.ramfs : C_PHYS(.init.ramfs) { *(.init.ramfs) }
123 __initramfs_end = .;
124#endif
125
126 . = ALIGN(8);
127 __machvec_start = .;
128 .machvec.init : C_PHYS(.machvec.init) { *(.machvec.init) }
129 __machvec_end = .;
130
131 PERCPU(PAGE_SIZE)
132
133 /*
134 * .exit.text is discarded at runtime, not link time, to deal with
135 * references from __bug_table
136 */
137 .exit.text : C_PHYS(.exit.text) { EXIT_TEXT }
138 .exit.data : C_PHYS(.exit.data) { EXIT_DATA }
139
140 . = ALIGN(PAGE_SIZE);
141 .bss : C_PHYS(.bss) {
142 __init_end = .;
143 __bss_start = .; /* BSS */
144 *(.bss.page_aligned)
145 *(.bss)
146 *(COMMON)
147 . = ALIGN(4);
148 _ebss = .; /* uClinux MTD sucks */
149 _end = . ;
150 }
151
152 /*
153 * When something in the kernel is NOT compiled as a module, the
154 * module cleanup code and data are put into these segments. Both
155 * can then be thrown away, as cleanup code is never called unless
156 * it's a module.
157 */
158 /DISCARD/ : {
159 *(.exitcall.exit)
160 }
161
162 STABS_DEBUG
163 DWARF_DEBUG
164}
diff --git a/arch/sh/lib/Makefile b/arch/sh/lib/Makefile
index 9dc7b6985052..ebb55d1149f5 100644
--- a/arch/sh/lib/Makefile
+++ b/arch/sh/lib/Makefile
@@ -2,12 +2,13 @@
2# Makefile for SuperH-specific library files.. 2# Makefile for SuperH-specific library files..
3# 3#
4 4
5lib-y = delay.o memset.o memmove.o memchr.o \ 5lib-y = delay.o io.o memset.o memmove.o memchr.o \
6 checksum.o strlen.o div64.o div64-generic.o 6 checksum.o strlen.o div64.o div64-generic.o
7 7
8memcpy-y := memcpy.o 8memcpy-y := memcpy.o
9memcpy-$(CONFIG_CPU_SH4) := memcpy-sh4.o 9memcpy-$(CONFIG_CPU_SH4) := memcpy-sh4.o
10 10
11lib-y += $(memcpy-y) 11lib-$(CONFIG_MMU) += copy_page.o clear_page.o
12lib-y += $(memcpy-y)
12 13
13EXTRA_CFLAGS += -Werror 14EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/mm/clear_page.S b/arch/sh/lib/clear_page.S
index 7a7c81ee3f01..3539123fe517 100644
--- a/arch/sh/mm/clear_page.S
+++ b/arch/sh/lib/clear_page.S
@@ -9,10 +9,10 @@
9#include <asm/page.h> 9#include <asm/page.h>
10 10
11/* 11/*
12 * clear_page_slow 12 * clear_page
13 * @to: P1 address 13 * @to: P1 address
14 * 14 *
15 * void clear_page_slow(void *to) 15 * void clear_page(void *to)
16 */ 16 */
17 17
18/* 18/*
@@ -20,7 +20,7 @@
20 * r4 --- to 20 * r4 --- to
21 * r5 --- to + PAGE_SIZE 21 * r5 --- to + PAGE_SIZE
22 */ 22 */
23ENTRY(clear_page_slow) 23ENTRY(clear_page)
24 mov r4,r5 24 mov r4,r5
25 mov.l .Llimit,r0 25 mov.l .Llimit,r0
26 add r0,r5 26 add r0,r5
@@ -50,6 +50,8 @@ ENTRY(clear_page_slow)
50 ! 50 !
51 rts 51 rts
52 nop 52 nop
53
54 .balign 4
53.Llimit: .long (PAGE_SIZE-28) 55.Llimit: .long (PAGE_SIZE-28)
54 56
55ENTRY(__clear_user) 57ENTRY(__clear_user)
diff --git a/arch/sh/mm/copy_page.S b/arch/sh/lib/copy_page.S
index 40685018b952..e002b91c8752 100644
--- a/arch/sh/mm/copy_page.S
+++ b/arch/sh/lib/copy_page.S
@@ -9,11 +9,11 @@
9#include <asm/page.h> 9#include <asm/page.h>
10 10
11/* 11/*
12 * copy_page_slow 12 * copy_page
13 * @to: P1 address 13 * @to: P1 address
14 * @from: P1 address 14 * @from: P1 address
15 * 15 *
16 * void copy_page_slow(void *to, void *from) 16 * void copy_page(void *to, void *from)
17 */ 17 */
18 18
19/* 19/*
@@ -23,7 +23,7 @@
23 * r10 --- to 23 * r10 --- to
24 * r11 --- from 24 * r11 --- from
25 */ 25 */
26ENTRY(copy_page_slow) 26ENTRY(copy_page)
27 mov.l r8,@-r15 27 mov.l r8,@-r15
28 mov.l r10,@-r15 28 mov.l r10,@-r15
29 mov.l r11,@-r15 29 mov.l r11,@-r15
@@ -68,8 +68,9 @@ ENTRY(copy_page_slow)
68 rts 68 rts
69 nop 69 nop
70 70
71 .align 2 71 .balign 4
72.Lpsz: .long PAGE_SIZE 72.Lpsz: .long PAGE_SIZE
73
73/* 74/*
74 * __kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n); 75 * __kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n);
75 * Return the number of bytes NOT copied 76 * Return the number of bytes NOT copied
diff --git a/arch/sh/lib/io.c b/arch/sh/lib/io.c
new file mode 100644
index 000000000000..4f54ec43516f
--- /dev/null
+++ b/arch/sh/lib/io.c
@@ -0,0 +1,82 @@
1/*
2 * arch/sh/lib/io.c - SH32 optimized I/O routines
3 *
4 * Copyright (C) 2000 Stuart Menefy
5 * Copyright (C) 2005 Paul Mundt
6 *
7 * Provide real functions which expand to whatever the header file defined.
8 * Also definitions of machine independent IO functions.
9 *
10 * This file is subject to the terms and conditions of the GNU General Public
11 * License. See the file "COPYING" in the main directory of this archive
12 * for more details.
13 */
14#include <linux/module.h>
15#include <linux/io.h>
16
17void __raw_readsl(unsigned long addr, void *datap, int len)
18{
19 u32 *data;
20
21 for (data = datap; (len != 0) && (((u32)data & 0x1f) != 0); len--)
22 *data++ = ctrl_inl(addr);
23
24 if (likely(len >= (0x20 >> 2))) {
25 int tmp2, tmp3, tmp4, tmp5, tmp6;
26
27 __asm__ __volatile__(
28 "1: \n\t"
29 "mov.l @%7, r0 \n\t"
30 "mov.l @%7, %2 \n\t"
31#ifdef CONFIG_CPU_SH4
32 "movca.l r0, @%0 \n\t"
33#else
34 "mov.l r0, @%0 \n\t"
35#endif
36 "mov.l @%7, %3 \n\t"
37 "mov.l @%7, %4 \n\t"
38 "mov.l @%7, %5 \n\t"
39 "mov.l @%7, %6 \n\t"
40 "mov.l @%7, r7 \n\t"
41 "mov.l @%7, r0 \n\t"
42 "mov.l %2, @(0x04,%0) \n\t"
43 "mov #0x20>>2, %2 \n\t"
44 "mov.l %3, @(0x08,%0) \n\t"
45 "sub %2, %1 \n\t"
46 "mov.l %4, @(0x0c,%0) \n\t"
47 "cmp/hi %1, %2 ! T if 32 > len \n\t"
48 "mov.l %5, @(0x10,%0) \n\t"
49 "mov.l %6, @(0x14,%0) \n\t"
50 "mov.l r7, @(0x18,%0) \n\t"
51 "mov.l r0, @(0x1c,%0) \n\t"
52 "bf.s 1b \n\t"
53 " add #0x20, %0 \n\t"
54 : "=&r" (data), "=&r" (len),
55 "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4),
56 "=&r" (tmp5), "=&r" (tmp6)
57 : "r"(addr), "0" (data), "1" (len)
58 : "r0", "r7", "t", "memory");
59 }
60
61 for (; len != 0; len--)
62 *data++ = ctrl_inl(addr);
63}
64EXPORT_SYMBOL(__raw_readsl);
65
66void __raw_writesl(unsigned long addr, const void *data, int len)
67{
68 if (likely(len != 0)) {
69 int tmp1;
70
71 __asm__ __volatile__ (
72 "1: \n\t"
73 "mov.l @%0+, %1 \n\t"
74 "dt %3 \n\t"
75 "bf.s 1b \n\t"
76 " mov.l %1, @%4 \n\t"
77 : "=&r" (data), "=&r" (tmp1)
78 : "0" (data), "r" (len), "r"(addr)
79 : "t", "memory");
80 }
81}
82EXPORT_SYMBOL(__raw_writesl);
diff --git a/arch/sh64/lib/.gitignore b/arch/sh/lib64/.gitignore
index 3508c2cb23c4..3508c2cb23c4 100644
--- a/arch/sh64/lib/.gitignore
+++ b/arch/sh/lib64/.gitignore
diff --git a/arch/sh/lib64/Makefile b/arch/sh/lib64/Makefile
new file mode 100644
index 000000000000..9950966923a0
--- /dev/null
+++ b/arch/sh/lib64/Makefile
@@ -0,0 +1,15 @@
1#
2# Makefile for the SH-5 specific library files..
3#
4# Copyright (C) 2000, 2001 Paolo Alberelli
5# Copyright (C) 2003 Paul Mundt
6#
7# This file is subject to the terms and conditions of the GNU General Public
8# License. See the file "COPYING" in the main directory of this archive
9# for more details.
10#
11
12# Panic should really be compiled as PIC
13lib-y := udelay.o c-checksum.o dbg.o panic.o memcpy.o copy_user_memcpy.o \
14 copy_page.o clear_page.o
15
diff --git a/arch/sh64/lib/c-checksum.c b/arch/sh/lib64/c-checksum.c
index 053137abd8a0..5dfbd8b5e558 100644
--- a/arch/sh64/lib/c-checksum.c
+++ b/arch/sh/lib64/c-checksum.c
@@ -1,12 +1,9 @@
1/* 1/*
2 * arch/sh64/lib/c-checksum.c 2 * arch/sh/lib64/c-checksum.c
3 * 3 *
4 * This file contains network checksum routines that are better done 4 * This file contains network checksum routines that are better done
5 * in an architecture-specific manner due to speed.. 5 * in an architecture-specific manner due to speed..
6 */ 6 */
7
8#undef DEBUG
9
10#include <linux/string.h> 7#include <linux/string.h>
11#include <linux/errno.h> 8#include <linux/errno.h>
12#include <linux/kernel.h> 9#include <linux/kernel.h>
diff --git a/arch/sh64/lib/page_clear.S b/arch/sh/lib64/clear_page.S
index ac0111d669a3..007ab48ecc1c 100644
--- a/arch/sh64/lib/page_clear.S
+++ b/arch/sh/lib64/clear_page.S
@@ -25,8 +25,8 @@
25 .little 25 .little
26 26
27 .balign 8 27 .balign 8
28 .global sh64_page_clear 28 .global clear_page
29sh64_page_clear: 29clear_page:
30 pta/l 1f, tr1 30 pta/l 1f, tr1
31 pta/l 2f, tr2 31 pta/l 2f, tr2
32 ptabs/l r18, tr0 32 ptabs/l r18, tr0
diff --git a/arch/sh64/lib/page_copy.S b/arch/sh/lib64/copy_page.S
index e159c3cd2582..0ec6fca63b56 100644
--- a/arch/sh64/lib/page_copy.S
+++ b/arch/sh/lib64/copy_page.S
@@ -10,8 +10,8 @@
10 of SH5-101 cut2 eval chip with Cayman board DDR memory. 10 of SH5-101 cut2 eval chip with Cayman board DDR memory.
11 11
12 Parameters: 12 Parameters:
13 r2 : source effective address (start of page) 13 r2 : destination effective address (start of page)
14 r3 : destination effective address (start of page) 14 r3 : source effective address (start of page)
15 15
16 Always copies 4096 bytes. 16 Always copies 4096 bytes.
17 17
@@ -27,10 +27,10 @@
27 .little 27 .little
28 28
29 .balign 8 29 .balign 8
30 .global sh64_page_copy 30 .global copy_page
31sh64_page_copy: 31copy_page:
32 32
33 /* Copy 4096 bytes worth of data from r2 to r3. 33 /* Copy 4096 bytes worth of data from r3 to r2.
34 Do prefetches 4 lines ahead. 34 Do prefetches 4 lines ahead.
35 Do alloco 2 lines ahead */ 35 Do alloco 2 lines ahead */
36 36
@@ -41,21 +41,21 @@ sh64_page_copy:
41 41
42#if 0 42#if 0
43 /* TAKum03020 */ 43 /* TAKum03020 */
44 ld.q r2, 0x00, r63 44 ld.q r3, 0x00, r63
45 ld.q r2, 0x20, r63 45 ld.q r3, 0x20, r63
46 ld.q r2, 0x40, r63 46 ld.q r3, 0x40, r63
47 ld.q r2, 0x60, r63 47 ld.q r3, 0x60, r63
48#endif 48#endif
49 alloco r3, 0x00 49 alloco r2, 0x00
50 synco ! TAKum03020 50 synco ! TAKum03020
51 alloco r3, 0x20 51 alloco r2, 0x20
52 synco ! TAKum03020 52 synco ! TAKum03020
53 53
54 movi 3968, r6 54 movi 3968, r6
55 add r3, r6, r6 55 add r2, r6, r6
56 addi r6, 64, r7 56 addi r6, 64, r7
57 addi r7, 64, r8 57 addi r7, 64, r8
58 sub r2, r3, r60 58 sub r3, r2, r60
59 addi r60, 8, r61 59 addi r60, 8, r61
60 addi r61, 8, r62 60 addi r61, 8, r62
61 addi r62, 8, r23 61 addi r62, 8, r23
@@ -67,25 +67,23 @@ sh64_page_copy:
671: 671:
68#if 0 68#if 0
69 /* TAKum03020 */ 69 /* TAKum03020 */
70 bge/u r3, r6, tr2 ! skip prefetch for last 4 lines 70 bge/u r2, r6, tr2 ! skip prefetch for last 4 lines
71 ldx.q r3, r22, r63 ! prefetch 4 lines hence 71 ldx.q r2, r22, r63 ! prefetch 4 lines hence
72#endif 72#endif
732: 732:
74 bge/u r3, r7, tr3 ! skip alloco for last 2 lines 74 bge/u r2, r7, tr3 ! skip alloco for last 2 lines
75 alloco r3, 0x40 ! alloc destination line 2 lines ahead 75 alloco r2, 0x40 ! alloc destination line 2 lines ahead
76 synco ! TAKum03020 76 synco ! TAKum03020
773: 773:
78 ldx.q r3, r60, r36 78 ldx.q r2, r60, r36
79 ldx.q r3, r61, r37 79 ldx.q r2, r61, r37
80 ldx.q r3, r62, r38 80 ldx.q r2, r62, r38
81 ldx.q r3, r23, r39 81 ldx.q r2, r23, r39
82 st.q r3, 0, r36 82 st.q r2, 0, r36
83 st.q r3, 8, r37 83 st.q r2, 8, r37
84 st.q r3, 16, r38 84 st.q r2, 16, r38
85 st.q r3, 24, r39 85 st.q r2, 24, r39
86 addi r3, 32, r3 86 addi r2, 32, r2
87 bgt/l r8, r3, tr1 87 bgt/l r8, r2, tr1
88 88
89 blink tr0, r63 ! return 89 blink tr0, r63 ! return
90
91
diff --git a/arch/sh64/lib/copy_user_memcpy.S b/arch/sh/lib64/copy_user_memcpy.S
index 2a62816d2ddd..2a62816d2ddd 100644
--- a/arch/sh64/lib/copy_user_memcpy.S
+++ b/arch/sh/lib64/copy_user_memcpy.S
diff --git a/arch/sh64/lib/dbg.c b/arch/sh/lib64/dbg.c
index 97816e0baf19..75825ef6e084 100644
--- a/arch/sh64/lib/dbg.c
+++ b/arch/sh/lib64/dbg.c
@@ -2,7 +2,7 @@
2-- 2--
3-- Identity : Linux50 Debug Funcions 3-- Identity : Linux50 Debug Funcions
4-- 4--
5-- File : arch/sh64/lib/dbg.C 5-- File : arch/sh/lib64/dbg.c
6-- 6--
7-- Copyright 2000, 2001 STMicroelectronics Limited. 7-- Copyright 2000, 2001 STMicroelectronics Limited.
8-- Copyright 2004 Richard Curnow (evt_debug etc) 8-- Copyright 2004 Richard Curnow (evt_debug etc)
diff --git a/arch/sh64/lib/memcpy.c b/arch/sh/lib64/memcpy.c
index fba436a92bfa..fba436a92bfa 100644
--- a/arch/sh64/lib/memcpy.c
+++ b/arch/sh/lib64/memcpy.c
diff --git a/arch/sh64/lib/panic.c b/arch/sh/lib64/panic.c
index c9eb1cb50d97..ff559e2a96f7 100644
--- a/arch/sh64/lib/panic.c
+++ b/arch/sh/lib64/panic.c
@@ -8,7 +8,7 @@
8 8
9#include <linux/kernel.h> 9#include <linux/kernel.h>
10#include <asm/io.h> 10#include <asm/io.h>
11#include <asm/registers.h> 11#include <asm/cpu/registers.h>
12 12
13/* THIS IS A PHYSICAL ADDRESS */ 13/* THIS IS A PHYSICAL ADDRESS */
14#define HDSP2534_ADDR (0x04002100) 14#define HDSP2534_ADDR (0x04002100)
diff --git a/arch/sh64/lib/udelay.c b/arch/sh/lib64/udelay.c
index 327653914007..23c7d17fb9f7 100644
--- a/arch/sh64/lib/udelay.c
+++ b/arch/sh/lib64/udelay.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/sh64/lib/udelay.c 2 * arch/sh/lib64/udelay.c
3 * 3 *
4 * Delay routines, using a pre-computed "loops_per_jiffy" value. 4 * Delay routines, using a pre-computed "loops_per_jiffy" value.
5 * 5 *
@@ -13,8 +13,6 @@
13#include <linux/sched.h> 13#include <linux/sched.h>
14#include <asm/param.h> 14#include <asm/param.h>
15 15
16extern unsigned long loops_per_jiffy;
17
18/* 16/*
19 * Use only for very small delays (< 1 msec). 17 * Use only for very small delays (< 1 msec).
20 * 18 *
@@ -49,11 +47,10 @@ void __ndelay(unsigned long long nsecs, unsigned long lpj)
49 47
50void udelay(unsigned long usecs) 48void udelay(unsigned long usecs)
51{ 49{
52 __udelay(usecs, loops_per_jiffy); 50 __udelay(usecs, cpu_data[raw_smp_processor_id()].loops_per_jiffy);
53} 51}
54 52
55void ndelay(unsigned long nsecs) 53void ndelay(unsigned long nsecs)
56{ 54{
57 __ndelay(nsecs, loops_per_jiffy); 55 __ndelay(nsecs, cpu_data[raw_smp_processor_id()].loops_per_jiffy);
58} 56}
59
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig
index 1265f204f7d1..f549b8cd2501 100644
--- a/arch/sh/mm/Kconfig
+++ b/arch/sh/mm/Kconfig
@@ -1,193 +1,3 @@
1#
2# Processor families
3#
4config CPU_SH2
5 bool
6
7config CPU_SH2A
8 bool
9 select CPU_SH2
10
11config CPU_SH3
12 bool
13 select CPU_HAS_INTEVT
14 select CPU_HAS_SR_RB
15
16config CPU_SH4
17 bool
18 select CPU_HAS_INTEVT
19 select CPU_HAS_SR_RB
20 select CPU_HAS_PTEA if !CPU_SH4A || CPU_SHX2
21 select CPU_HAS_FPU if !CPU_SH4AL_DSP
22
23config CPU_SH4A
24 bool
25 select CPU_SH4
26
27config CPU_SH4AL_DSP
28 bool
29 select CPU_SH4A
30 select CPU_HAS_DSP
31
32config CPU_SHX2
33 bool
34
35config CPU_SHX3
36 bool
37
38choice
39 prompt "Processor sub-type selection"
40
41#
42# Processor subtypes
43#
44
45# SH-2 Processor Support
46
47config CPU_SUBTYPE_SH7619
48 bool "Support SH7619 processor"
49 select CPU_SH2
50
51# SH-2A Processor Support
52
53config CPU_SUBTYPE_SH7206
54 bool "Support SH7206 processor"
55 select CPU_SH2A
56
57# SH-3 Processor Support
58
59config CPU_SUBTYPE_SH7705
60 bool "Support SH7705 processor"
61 select CPU_SH3
62
63config CPU_SUBTYPE_SH7706
64 bool "Support SH7706 processor"
65 select CPU_SH3
66 help
67 Select SH7706 if you have a 133 Mhz SH-3 HD6417706 CPU.
68
69config CPU_SUBTYPE_SH7707
70 bool "Support SH7707 processor"
71 select CPU_SH3
72 help
73 Select SH7707 if you have a 60 Mhz SH-3 HD6417707 CPU.
74
75config CPU_SUBTYPE_SH7708
76 bool "Support SH7708 processor"
77 select CPU_SH3
78 help
79 Select SH7708 if you have a 60 Mhz SH-3 HD6417708S or
80 if you have a 100 Mhz SH-3 HD6417708R CPU.
81
82config CPU_SUBTYPE_SH7709
83 bool "Support SH7709 processor"
84 select CPU_SH3
85 help
86 Select SH7709 if you have a 80 Mhz SH-3 HD6417709 CPU.
87
88config CPU_SUBTYPE_SH7710
89 bool "Support SH7710 processor"
90 select CPU_SH3
91 select CPU_HAS_DSP
92 help
93 Select SH7710 if you have a SH3-DSP SH7710 CPU.
94
95config CPU_SUBTYPE_SH7712
96 bool "Support SH7712 processor"
97 select CPU_SH3
98 select CPU_HAS_DSP
99 help
100 Select SH7712 if you have a SH3-DSP SH7712 CPU.
101
102config CPU_SUBTYPE_SH7720
103 bool "Support SH7720 processor"
104 select CPU_SH3
105 select CPU_HAS_DSP
106 help
107 Select SH7720 if you have a SH3-DSP SH7720 CPU.
108
109# SH-4 Processor Support
110
111config CPU_SUBTYPE_SH7750
112 bool "Support SH7750 processor"
113 select CPU_SH4
114 help
115 Select SH7750 if you have a 200 Mhz SH-4 HD6417750 CPU.
116
117config CPU_SUBTYPE_SH7091
118 bool "Support SH7091 processor"
119 select CPU_SH4
120 help
121 Select SH7091 if you have an SH-4 based Sega device (such as
122 the Dreamcast, Naomi, and Naomi 2).
123
124config CPU_SUBTYPE_SH7750R
125 bool "Support SH7750R processor"
126 select CPU_SH4
127
128config CPU_SUBTYPE_SH7750S
129 bool "Support SH7750S processor"
130 select CPU_SH4
131
132config CPU_SUBTYPE_SH7751
133 bool "Support SH7751 processor"
134 select CPU_SH4
135 help
136 Select SH7751 if you have a 166 Mhz SH-4 HD6417751 CPU,
137 or if you have a HD6417751R CPU.
138
139config CPU_SUBTYPE_SH7751R
140 bool "Support SH7751R processor"
141 select CPU_SH4
142
143config CPU_SUBTYPE_SH7760
144 bool "Support SH7760 processor"
145 select CPU_SH4
146
147config CPU_SUBTYPE_SH4_202
148 bool "Support SH4-202 processor"
149 select CPU_SH4
150
151# SH-4A Processor Support
152
153config CPU_SUBTYPE_SH7770
154 bool "Support SH7770 processor"
155 select CPU_SH4A
156
157config CPU_SUBTYPE_SH7780
158 bool "Support SH7780 processor"
159 select CPU_SH4A
160
161config CPU_SUBTYPE_SH7785
162 bool "Support SH7785 processor"
163 select CPU_SH4A
164 select CPU_SHX2
165 select ARCH_SPARSEMEM_ENABLE
166 select SYS_SUPPORTS_NUMA
167
168config CPU_SUBTYPE_SHX3
169 bool "Support SH-X3 processor"
170 select CPU_SH4A
171 select CPU_SHX3
172 select ARCH_SPARSEMEM_ENABLE
173 select SYS_SUPPORTS_NUMA
174 select SYS_SUPPORTS_SMP
175
176# SH4AL-DSP Processor Support
177
178config CPU_SUBTYPE_SH7343
179 bool "Support SH7343 processor"
180 select CPU_SH4AL_DSP
181
182config CPU_SUBTYPE_SH7722
183 bool "Support SH7722 processor"
184 select CPU_SH4AL_DSP
185 select CPU_SHX2
186 select ARCH_SPARSEMEM_ENABLE
187 select SYS_SUPPORTS_NUMA
188
189endchoice
190
191menu "Memory management options" 1menu "Memory management options"
192 2
193config QUICKLIST 3config QUICKLIST
@@ -207,7 +17,8 @@ config MMU
207 17
208config PAGE_OFFSET 18config PAGE_OFFSET
209 hex 19 hex
210 default "0x80000000" if MMU 20 default "0x80000000" if MMU && SUPERH32
21 default "0x20000000" if MMU && SUPERH64
211 default "0x00000000" 22 default "0x00000000"
212 23
213config MEMORY_START 24config MEMORY_START
@@ -228,17 +39,28 @@ config MEMORY_START
228 39
229config MEMORY_SIZE 40config MEMORY_SIZE
230 hex "Physical memory size" 41 hex "Physical memory size"
231 default "0x00400000" 42 default "0x04000000"
232 help 43 help
233 This sets the default memory size assumed by your SH kernel. It can 44 This sets the default memory size assumed by your SH kernel. It can
234 be overridden as normal by the 'mem=' argument on the kernel command 45 be overridden as normal by the 'mem=' argument on the kernel command
235 line. If unsure, consult your board specifications or just leave it 46 line. If unsure, consult your board specifications or just leave it
236 as 0x00400000 which was the default value before this became 47 as 0x04000000 which was the default value before this became
237 configurable. 48 configurable.
238 49
50# Physical addressing modes
51
52config 29BIT
53 def_bool !32BIT
54 depends on SUPERH32
55
239config 32BIT 56config 32BIT
57 bool
58 default y if CPU_SH5
59
60config PMB
240 bool "Support 32-bit physical addressing through PMB" 61 bool "Support 32-bit physical addressing through PMB"
241 depends on MMU && (CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785) 62 depends on MMU && (CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785)
63 select 32BIT
242 default y 64 default y
243 help 65 help
244 If you say Y here, physical addressing will be extended to 66 If you say Y here, physical addressing will be extended to
@@ -256,7 +78,7 @@ config X2TLB
256 78
257config VSYSCALL 79config VSYSCALL
258 bool "Support vsyscall page" 80 bool "Support vsyscall page"
259 depends on MMU 81 depends on MMU && (CPU_SH3 || CPU_SH4)
260 default y 82 default y
261 help 83 help
262 This will enable support for the kernel mapping a vDSO page 84 This will enable support for the kernel mapping a vDSO page
@@ -335,7 +157,7 @@ config PAGE_SIZE_8KB
335 157
336config PAGE_SIZE_64KB 158config PAGE_SIZE_64KB
337 bool "64kB" 159 bool "64kB"
338 depends on CPU_SH4 160 depends on CPU_SH4 || CPU_SH5
339 help 161 help
340 This enables support for 64kB pages, possible on all SH-4 162 This enables support for 64kB pages, possible on all SH-4
341 CPUs and later. 163 CPUs and later.
@@ -344,7 +166,7 @@ endchoice
344 166
345choice 167choice
346 prompt "HugeTLB page size" 168 prompt "HugeTLB page size"
347 depends on HUGETLB_PAGE && CPU_SH4 && MMU 169 depends on HUGETLB_PAGE && (CPU_SH4 || CPU_SH5) && MMU
348 default HUGETLB_PAGE_SIZE_64K 170 default HUGETLB_PAGE_SIZE_64K
349 171
350config HUGETLB_PAGE_SIZE_64K 172config HUGETLB_PAGE_SIZE_64K
@@ -365,6 +187,10 @@ config HUGETLB_PAGE_SIZE_64MB
365 bool "64MB" 187 bool "64MB"
366 depends on X2TLB 188 depends on X2TLB
367 189
190config HUGETLB_PAGE_SIZE_512MB
191 bool "512MB"
192 depends on CPU_SH5
193
368endchoice 194endchoice
369 195
370source "mm/Kconfig" 196source "mm/Kconfig"
@@ -392,12 +218,12 @@ config SH_DIRECT_MAPPED
392 218
393choice 219choice
394 prompt "Cache mode" 220 prompt "Cache mode"
395 default CACHE_WRITEBACK if CPU_SH2A || CPU_SH3 || CPU_SH4 221 default CACHE_WRITEBACK if CPU_SH2A || CPU_SH3 || CPU_SH4 || CPU_SH5
396 default CACHE_WRITETHROUGH if (CPU_SH2 && !CPU_SH2A) 222 default CACHE_WRITETHROUGH if (CPU_SH2 && !CPU_SH2A)
397 223
398config CACHE_WRITEBACK 224config CACHE_WRITEBACK
399 bool "Write-back" 225 bool "Write-back"
400 depends on CPU_SH2A || CPU_SH3 || CPU_SH4 226 depends on CPU_SH2A || CPU_SH3 || CPU_SH4 || CPU_SH5
401 227
402config CACHE_WRITETHROUGH 228config CACHE_WRITETHROUGH
403 bool "Write-through" 229 bool "Write-through"
diff --git a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile
index aa44607f072d..9f4bc3d90b1e 100644
--- a/arch/sh/mm/Makefile
+++ b/arch/sh/mm/Makefile
@@ -1,37 +1,5 @@
1# 1ifeq ($(CONFIG_SUPERH32),y)
2# Makefile for the Linux SuperH-specific parts of the memory manager. 2include ${srctree}/arch/sh/mm/Makefile_32
3# 3else
4 4include ${srctree}/arch/sh/mm/Makefile_64
5obj-y := init.o extable.o consistent.o
6
7ifndef CONFIG_CACHE_OFF
8obj-$(CONFIG_CPU_SH2) += cache-sh2.o
9obj-$(CONFIG_CPU_SH3) += cache-sh3.o
10obj-$(CONFIG_CPU_SH4) += cache-sh4.o
11obj-$(CONFIG_SH7705_CACHE_32KB) += cache-sh7705.o
12endif 5endif
13
14mmu-y := tlb-nommu.o pg-nommu.o
15mmu-$(CONFIG_MMU) := fault.o clear_page.o copy_page.o tlb-flush.o \
16 ioremap.o
17
18obj-y += $(mmu-y)
19
20ifdef CONFIG_DEBUG_FS
21obj-$(CONFIG_CPU_SH4) += cache-debugfs.o
22endif
23
24ifdef CONFIG_MMU
25obj-$(CONFIG_CPU_SH3) += tlb-sh3.o
26obj-$(CONFIG_CPU_SH4) += tlb-sh4.o
27ifndef CONFIG_CACHE_OFF
28obj-$(CONFIG_CPU_SH4) += pg-sh4.o
29obj-$(CONFIG_SH7705_CACHE_32KB) += pg-sh7705.o
30endif
31endif
32
33obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
34obj-$(CONFIG_32BIT) += pmb.o
35obj-$(CONFIG_NUMA) += numa.o
36
37EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/mm/Makefile_32 b/arch/sh/mm/Makefile_32
new file mode 100644
index 000000000000..e295db60b91b
--- /dev/null
+++ b/arch/sh/mm/Makefile_32
@@ -0,0 +1,36 @@
1#
2# Makefile for the Linux SuperH-specific parts of the memory manager.
3#
4
5obj-y := init.o extable_32.o consistent.o
6
7ifndef CONFIG_CACHE_OFF
8obj-$(CONFIG_CPU_SH2) += cache-sh2.o
9obj-$(CONFIG_CPU_SH3) += cache-sh3.o
10obj-$(CONFIG_CPU_SH4) += cache-sh4.o
11obj-$(CONFIG_SH7705_CACHE_32KB) += cache-sh7705.o
12endif
13
14mmu-y := tlb-nommu.o pg-nommu.o
15mmu-$(CONFIG_MMU) := fault_32.o tlbflush_32.o ioremap_32.o
16
17obj-y += $(mmu-y)
18
19ifdef CONFIG_DEBUG_FS
20obj-$(CONFIG_CPU_SH4) += cache-debugfs.o
21endif
22
23ifdef CONFIG_MMU
24obj-$(CONFIG_CPU_SH3) += tlb-sh3.o
25obj-$(CONFIG_CPU_SH4) += tlb-sh4.o
26ifndef CONFIG_CACHE_OFF
27obj-$(CONFIG_CPU_SH4) += pg-sh4.o
28obj-$(CONFIG_SH7705_CACHE_32KB) += pg-sh7705.o
29endif
30endif
31
32obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
33obj-$(CONFIG_PMB) += pmb.o
34obj-$(CONFIG_NUMA) += numa.o
35
36EXTRA_CFLAGS += -Werror
diff --git a/arch/sh64/mm/Makefile b/arch/sh/mm/Makefile_64
index d0e813632480..cbd6aa33c5ac 100644
--- a/arch/sh64/mm/Makefile
+++ b/arch/sh/mm/Makefile_64
@@ -1,24 +1,24 @@
1# 1#
2# This file is subject to the terms and conditions of the GNU General Public 2# Makefile for the Linux SuperH-specific parts of the memory manager.
3# License. See the file "COPYING" in the main directory of this archive
4# for more details.
5#
6# Copyright (C) 2000, 2001 Paolo Alberelli
7# Copyright (C) 2003, 2004 Paul Mundt
8#
9# Makefile for the sh64-specific parts of the Linux memory manager.
10#
11# Note! Dependencies are done automagically by 'make dep', which also
12# removes any old dependencies. DON'T put your own dependencies here
13# unless it's something special (ie not a .c file).
14# 3#
15 4
16obj-y := cache.o consistent.o extable.o fault.o init.o ioremap.o \ 5obj-y := init.o extable_64.o consistent.o
17 tlbmiss.o tlb.o 6
7mmu-y := tlb-nommu.o pg-nommu.o
8mmu-$(CONFIG_MMU) := fault_64.o ioremap_64.o tlbflush_64.o tlb-sh5.o
9
10ifndef CONFIG_CACHE_OFF
11obj-y += cache-sh5.o
12endif
13
14obj-y += $(mmu-y)
18 15
19obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o 16obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
17obj-$(CONFIG_NUMA) += numa.o
18
19EXTRA_CFLAGS += -Werror
20 20
21# Special flags for tlbmiss.o. This puts restrictions on the number of 21# Special flags for fault_64.o. This puts restrictions on the number of
22# caller-save registers that the compiler can target when building this file. 22# caller-save registers that the compiler can target when building this file.
23# This is required because the code is called from a context in entry.S where 23# This is required because the code is called from a context in entry.S where
24# very few registers have been saved in the exception handler (for speed 24# very few registers have been saved in the exception handler (for speed
@@ -33,7 +33,7 @@ obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
33# The resources not listed below are callee save, i.e. the compiler is free to 33# The resources not listed below are callee save, i.e. the compiler is free to
34# use any of them and will spill them to the stack itself. 34# use any of them and will spill them to the stack itself.
35 35
36CFLAGS_tlbmiss.o += -ffixed-r7 \ 36CFLAGS_fault_64.o += -ffixed-r7 \
37 -ffixed-r8 -ffixed-r9 -ffixed-r10 -ffixed-r11 -ffixed-r12 \ 37 -ffixed-r8 -ffixed-r9 -ffixed-r10 -ffixed-r11 -ffixed-r12 \
38 -ffixed-r13 -ffixed-r14 -ffixed-r16 -ffixed-r17 -ffixed-r19 \ 38 -ffixed-r13 -ffixed-r14 -ffixed-r16 -ffixed-r17 -ffixed-r19 \
39 -ffixed-r20 -ffixed-r21 -ffixed-r22 -ffixed-r23 \ 39 -ffixed-r20 -ffixed-r21 -ffixed-r22 -ffixed-r23 \
diff --git a/arch/sh/mm/cache-debugfs.c b/arch/sh/mm/cache-debugfs.c
index de6d2c9aa477..db6d950b6f5e 100644
--- a/arch/sh/mm/cache-debugfs.c
+++ b/arch/sh/mm/cache-debugfs.c
@@ -22,7 +22,8 @@ enum cache_type {
22 CACHE_TYPE_UNIFIED, 22 CACHE_TYPE_UNIFIED,
23}; 23};
24 24
25static int cache_seq_show(struct seq_file *file, void *iter) 25static int __uses_jump_to_uncached cache_seq_show(struct seq_file *file,
26 void *iter)
26{ 27{
27 unsigned int cache_type = (unsigned int)file->private; 28 unsigned int cache_type = (unsigned int)file->private;
28 struct cache_info *cache; 29 struct cache_info *cache;
@@ -34,11 +35,11 @@ static int cache_seq_show(struct seq_file *file, void *iter)
34 * Go uncached immediately so we don't skew the results any 35 * Go uncached immediately so we don't skew the results any
35 * more than we already are.. 36 * more than we already are..
36 */ 37 */
37 jump_to_P2(); 38 jump_to_uncached();
38 39
39 ccr = ctrl_inl(CCR); 40 ccr = ctrl_inl(CCR);
40 if ((ccr & CCR_CACHE_ENABLE) == 0) { 41 if ((ccr & CCR_CACHE_ENABLE) == 0) {
41 back_to_P1(); 42 back_to_cached();
42 43
43 seq_printf(file, "disabled\n"); 44 seq_printf(file, "disabled\n");
44 return 0; 45 return 0;
@@ -104,7 +105,7 @@ static int cache_seq_show(struct seq_file *file, void *iter)
104 addrstart += cache->way_incr; 105 addrstart += cache->way_incr;
105 } 106 }
106 107
107 back_to_P1(); 108 back_to_cached();
108 109
109 return 0; 110 return 0;
110} 111}
diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c
index 226b190c5b9c..43d7ff6b6ec7 100644
--- a/arch/sh/mm/cache-sh4.c
+++ b/arch/sh/mm/cache-sh4.c
@@ -190,7 +190,7 @@ void flush_icache_range(unsigned long start, unsigned long end)
190 * .. which happens to be the same behavior as flush_icache_range(). 190 * .. which happens to be the same behavior as flush_icache_range().
191 * So, we simply flush out a line. 191 * So, we simply flush out a line.
192 */ 192 */
193void flush_cache_sigtramp(unsigned long addr) 193void __uses_jump_to_uncached flush_cache_sigtramp(unsigned long addr)
194{ 194{
195 unsigned long v, index; 195 unsigned long v, index;
196 unsigned long flags; 196 unsigned long flags;
@@ -205,13 +205,13 @@ void flush_cache_sigtramp(unsigned long addr)
205 (v & boot_cpu_data.icache.entry_mask); 205 (v & boot_cpu_data.icache.entry_mask);
206 206
207 local_irq_save(flags); 207 local_irq_save(flags);
208 jump_to_P2(); 208 jump_to_uncached();
209 209
210 for (i = 0; i < boot_cpu_data.icache.ways; 210 for (i = 0; i < boot_cpu_data.icache.ways;
211 i++, index += boot_cpu_data.icache.way_incr) 211 i++, index += boot_cpu_data.icache.way_incr)
212 ctrl_outl(0, index); /* Clear out Valid-bit */ 212 ctrl_outl(0, index); /* Clear out Valid-bit */
213 213
214 back_to_P1(); 214 back_to_cached();
215 wmb(); 215 wmb();
216 local_irq_restore(flags); 216 local_irq_restore(flags);
217} 217}
@@ -256,12 +256,12 @@ void flush_dcache_page(struct page *page)
256} 256}
257 257
258/* TODO: Selective icache invalidation through IC address array.. */ 258/* TODO: Selective icache invalidation through IC address array.. */
259static inline void flush_icache_all(void) 259static inline void __uses_jump_to_uncached flush_icache_all(void)
260{ 260{
261 unsigned long flags, ccr; 261 unsigned long flags, ccr;
262 262
263 local_irq_save(flags); 263 local_irq_save(flags);
264 jump_to_P2(); 264 jump_to_uncached();
265 265
266 /* Flush I-cache */ 266 /* Flush I-cache */
267 ccr = ctrl_inl(CCR); 267 ccr = ctrl_inl(CCR);
@@ -269,11 +269,11 @@ static inline void flush_icache_all(void)
269 ctrl_outl(ccr, CCR); 269 ctrl_outl(ccr, CCR);
270 270
271 /* 271 /*
272 * back_to_P1() will take care of the barrier for us, don't add 272 * back_to_cached() will take care of the barrier for us, don't add
273 * another one! 273 * another one!
274 */ 274 */
275 275
276 back_to_P1(); 276 back_to_cached();
277 local_irq_restore(flags); 277 local_irq_restore(flags);
278} 278}
279 279
diff --git a/arch/sh64/mm/cache.c b/arch/sh/mm/cache-sh5.c
index 421487cfff4c..4617e3aeee73 100644
--- a/arch/sh64/mm/cache.c
+++ b/arch/sh/mm/cache-sh5.c
@@ -1,18 +1,15 @@
1/* 1/*
2 * This file is subject to the terms and conditions of the GNU General Public 2 * arch/sh/mm/cache-sh5.c
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * arch/sh64/mm/cache.c
7 * 3 *
8 * Original version Copyright (C) 2000, 2001 Paolo Alberelli 4 * Original version Copyright (C) 2000, 2001 Paolo Alberelli
9 * Second version Copyright (C) benedict.gaster@superh.com 2002 5 * Second version Copyright (C) benedict.gaster@superh.com 2002
10 * Third version Copyright Richard.Curnow@superh.com 2003 6 * Third version Copyright Richard.Curnow@superh.com 2003
11 * Hacks to third version Copyright (C) 2003 Paul Mundt 7 * Hacks to third version Copyright (C) 2003 Paul Mundt
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 */ 12 */
13
14/****************************************************************************/
15
16#include <linux/init.h> 13#include <linux/init.h>
17#include <linux/mman.h> 14#include <linux/mman.h>
18#include <linux/mm.h> 15#include <linux/mm.h>
@@ -146,7 +143,7 @@ int __init sh64_cache_init(void)
146/* The following group of functions deal with mapping and unmapping a temporary 143/* The following group of functions deal with mapping and unmapping a temporary
147 page into the DTLB slot that have been set aside for our exclusive use. */ 144 page into the DTLB slot that have been set aside for our exclusive use. */
148/* In order to accomplish this, we use the generic interface for adding and 145/* In order to accomplish this, we use the generic interface for adding and
149 removing a wired slot entry as defined in arch/sh64/mm/tlb.c */ 146 removing a wired slot entry as defined in arch/sh/mm/tlb-sh5.c */
150/****************************************************************************/ 147/****************************************************************************/
151 148
152static unsigned long slot_own_flags; 149static unsigned long slot_own_flags;
diff --git a/arch/sh/mm/cache-sh7705.c b/arch/sh/mm/cache-sh7705.c
index 4896d7376926..22dacc778823 100644
--- a/arch/sh/mm/cache-sh7705.c
+++ b/arch/sh/mm/cache-sh7705.c
@@ -71,7 +71,7 @@ void flush_icache_range(unsigned long start, unsigned long end)
71/* 71/*
72 * Writeback&Invalidate the D-cache of the page 72 * Writeback&Invalidate the D-cache of the page
73 */ 73 */
74static void __flush_dcache_page(unsigned long phys) 74static void __uses_jump_to_uncached __flush_dcache_page(unsigned long phys)
75{ 75{
76 unsigned long ways, waysize, addrstart; 76 unsigned long ways, waysize, addrstart;
77 unsigned long flags; 77 unsigned long flags;
@@ -92,7 +92,7 @@ static void __flush_dcache_page(unsigned long phys)
92 * possible. 92 * possible.
93 */ 93 */
94 local_irq_save(flags); 94 local_irq_save(flags);
95 jump_to_P2(); 95 jump_to_uncached();
96 96
97 ways = current_cpu_data.dcache.ways; 97 ways = current_cpu_data.dcache.ways;
98 waysize = current_cpu_data.dcache.sets; 98 waysize = current_cpu_data.dcache.sets;
@@ -118,7 +118,7 @@ static void __flush_dcache_page(unsigned long phys)
118 addrstart += current_cpu_data.dcache.way_incr; 118 addrstart += current_cpu_data.dcache.way_incr;
119 } while (--ways); 119 } while (--ways);
120 120
121 back_to_P1(); 121 back_to_cached();
122 local_irq_restore(flags); 122 local_irq_restore(flags);
123} 123}
124 124
@@ -132,15 +132,15 @@ void flush_dcache_page(struct page *page)
132 __flush_dcache_page(PHYSADDR(page_address(page))); 132 __flush_dcache_page(PHYSADDR(page_address(page)));
133} 133}
134 134
135void flush_cache_all(void) 135void __uses_jump_to_uncached flush_cache_all(void)
136{ 136{
137 unsigned long flags; 137 unsigned long flags;
138 138
139 local_irq_save(flags); 139 local_irq_save(flags);
140 jump_to_P2(); 140 jump_to_uncached();
141 141
142 cache_wback_all(); 142 cache_wback_all();
143 back_to_P1(); 143 back_to_cached();
144 local_irq_restore(flags); 144 local_irq_restore(flags);
145} 145}
146 146
diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c
index e220c29a3c00..7b2131c9eeda 100644
--- a/arch/sh/mm/consistent.c
+++ b/arch/sh/mm/consistent.c
@@ -1,7 +1,9 @@
1/* 1/*
2 * arch/sh/mm/consistent.c 2 * arch/sh/mm/consistent.c
3 * 3 *
4 * Copyright (C) 2004 Paul Mundt 4 * Copyright (C) 2004 - 2007 Paul Mundt
5 *
6 * Declared coherent memory functions based on arch/x86/kernel/pci-dma_32.c
5 * 7 *
6 * This file is subject to the terms and conditions of the GNU General Public 8 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive 9 * License. See the file "COPYING" in the main directory of this archive
@@ -13,58 +15,152 @@
13#include <asm/addrspace.h> 15#include <asm/addrspace.h>
14#include <asm/io.h> 16#include <asm/io.h>
15 17
16void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle) 18struct dma_coherent_mem {
19 void *virt_base;
20 u32 device_base;
21 int size;
22 int flags;
23 unsigned long *bitmap;
24};
25
26void *dma_alloc_coherent(struct device *dev, size_t size,
27 dma_addr_t *dma_handle, gfp_t gfp)
17{ 28{
18 struct page *page, *end, *free;
19 void *ret; 29 void *ret;
20 int order; 30 struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
31 int order = get_order(size);
21 32
22 size = PAGE_ALIGN(size); 33 if (mem) {
23 order = get_order(size); 34 int page = bitmap_find_free_region(mem->bitmap, mem->size,
35 order);
36 if (page >= 0) {
37 *dma_handle = mem->device_base + (page << PAGE_SHIFT);
38 ret = mem->virt_base + (page << PAGE_SHIFT);
39 memset(ret, 0, size);
40 return ret;
41 }
42 if (mem->flags & DMA_MEMORY_EXCLUSIVE)
43 return NULL;
44 }
24 45
25 page = alloc_pages(gfp, order); 46 ret = (void *)__get_free_pages(gfp, order);
26 if (!page)
27 return NULL;
28 split_page(page, order);
29 47
30 ret = page_address(page); 48 if (ret != NULL) {
31 memset(ret, 0, size); 49 memset(ret, 0, size);
32 *handle = virt_to_phys(ret); 50 /*
51 * Pages from the page allocator may have data present in
52 * cache. So flush the cache before using uncached memory.
53 */
54 dma_cache_sync(NULL, ret, size, DMA_BIDIRECTIONAL);
55 *dma_handle = virt_to_phys(ret);
56 }
57 return ret;
58}
59EXPORT_SYMBOL(dma_alloc_coherent);
33 60
34 /* 61void dma_free_coherent(struct device *dev, size_t size,
35 * We must flush the cache before we pass it on to the device 62 void *vaddr, dma_addr_t dma_handle)
36 */ 63{
37 __flush_purge_region(ret, size); 64 struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
65 int order = get_order(size);
38 66
39 page = virt_to_page(ret); 67 if (mem && vaddr >= mem->virt_base && vaddr < (mem->virt_base + (mem->size << PAGE_SHIFT))) {
40 free = page + (size >> PAGE_SHIFT); 68 int page = (vaddr - mem->virt_base) >> PAGE_SHIFT;
41 end = page + (1 << order);
42 69
43 while (++page < end) { 70 bitmap_release_region(mem->bitmap, page, order);
44 /* Free any unused pages */ 71 } else {
45 if (page >= free) { 72 WARN_ON(irqs_disabled()); /* for portability */
46 __free_page(page); 73 BUG_ON(mem && mem->flags & DMA_MEMORY_EXCLUSIVE);
47 } 74 free_pages((unsigned long)vaddr, order);
48 } 75 }
76}
77EXPORT_SYMBOL(dma_free_coherent);
78
79int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
80 dma_addr_t device_addr, size_t size, int flags)
81{
82 void __iomem *mem_base = NULL;
83 int pages = size >> PAGE_SHIFT;
84 int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
85
86 if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0)
87 goto out;
88 if (!size)
89 goto out;
90 if (dev->dma_mem)
91 goto out;
92
93 /* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */
49 94
50 return P2SEGADDR(ret); 95 mem_base = ioremap_nocache(bus_addr, size);
96 if (!mem_base)
97 goto out;
98
99 dev->dma_mem = kmalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL);
100 if (!dev->dma_mem)
101 goto out;
102 dev->dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
103 if (!dev->dma_mem->bitmap)
104 goto free1_out;
105
106 dev->dma_mem->virt_base = mem_base;
107 dev->dma_mem->device_base = device_addr;
108 dev->dma_mem->size = pages;
109 dev->dma_mem->flags = flags;
110
111 if (flags & DMA_MEMORY_MAP)
112 return DMA_MEMORY_MAP;
113
114 return DMA_MEMORY_IO;
115
116 free1_out:
117 kfree(dev->dma_mem);
118 out:
119 if (mem_base)
120 iounmap(mem_base);
121 return 0;
51} 122}
123EXPORT_SYMBOL(dma_declare_coherent_memory);
52 124
53void consistent_free(void *vaddr, size_t size) 125void dma_release_declared_memory(struct device *dev)
54{ 126{
55 unsigned long addr = P1SEGADDR((unsigned long)vaddr); 127 struct dma_coherent_mem *mem = dev->dma_mem;
56 struct page *page=virt_to_page(addr);
57 int num_pages=(size+PAGE_SIZE-1) >> PAGE_SHIFT;
58 int i;
59 128
60 for(i=0;i<num_pages;i++) { 129 if (!mem)
61 __free_page((page+i)); 130 return;
62 } 131 dev->dma_mem = NULL;
132 iounmap(mem->virt_base);
133 kfree(mem->bitmap);
134 kfree(mem);
63} 135}
136EXPORT_SYMBOL(dma_release_declared_memory);
64 137
65void consistent_sync(void *vaddr, size_t size, int direction) 138void *dma_mark_declared_memory_occupied(struct device *dev,
139 dma_addr_t device_addr, size_t size)
66{ 140{
67 void * p1addr = (void*) P1SEGADDR((unsigned long)vaddr); 141 struct dma_coherent_mem *mem = dev->dma_mem;
142 int pages = (size + (device_addr & ~PAGE_MASK) + PAGE_SIZE - 1) >> PAGE_SHIFT;
143 int pos, err;
144
145 if (!mem)
146 return ERR_PTR(-EINVAL);
147
148 pos = (device_addr - mem->device_base) >> PAGE_SHIFT;
149 err = bitmap_allocate_region(mem->bitmap, pos, get_order(pages));
150 if (err != 0)
151 return ERR_PTR(err);
152 return mem->virt_base + (pos << PAGE_SHIFT);
153}
154EXPORT_SYMBOL(dma_mark_declared_memory_occupied);
155
156void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
157 enum dma_data_direction direction)
158{
159#ifdef CONFIG_CPU_SH5
160 void *p1addr = vaddr;
161#else
162 void *p1addr = (void*) P1SEGADDR((unsigned long)vaddr);
163#endif
68 164
69 switch (direction) { 165 switch (direction) {
70 case DMA_FROM_DEVICE: /* invalidate only */ 166 case DMA_FROM_DEVICE: /* invalidate only */
@@ -80,8 +176,4 @@ void consistent_sync(void *vaddr, size_t size, int direction)
80 BUG(); 176 BUG();
81 } 177 }
82} 178}
83 179EXPORT_SYMBOL(dma_cache_sync);
84EXPORT_SYMBOL(consistent_alloc);
85EXPORT_SYMBOL(consistent_free);
86EXPORT_SYMBOL(consistent_sync);
87
diff --git a/arch/sh/mm/extable.c b/arch/sh/mm/extable_32.c
index c1cf4463d09d..c1cf4463d09d 100644
--- a/arch/sh/mm/extable.c
+++ b/arch/sh/mm/extable_32.c
diff --git a/arch/sh64/mm/extable.c b/arch/sh/mm/extable_64.c
index a2e6e0563772..f05499688d88 100644
--- a/arch/sh64/mm/extable.c
+++ b/arch/sh/mm/extable_64.c
@@ -1,14 +1,14 @@
1/* 1/*
2 * This file is subject to the terms and conditions of the GNU General Public 2 * arch/sh/mm/extable_64.c
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * arch/sh64/mm/extable.c
7 * 3 *
8 * Copyright (C) 2003 Richard Curnow 4 * Copyright (C) 2003 Richard Curnow
9 * Copyright (C) 2003, 2004 Paul Mundt 5 * Copyright (C) 2003, 2004 Paul Mundt
10 * 6 *
11 * Cloned from the 2.5 SH version.. 7 * Cloned from the 2.5 SH version..
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 */ 12 */
13#include <linux/rwsem.h> 13#include <linux/rwsem.h>
14#include <linux/module.h> 14#include <linux/module.h>
@@ -21,13 +21,16 @@ static const struct exception_table_entry __copy_user_fixup_ex = {
21 .fixup = (unsigned long)&__copy_user_fixup, 21 .fixup = (unsigned long)&__copy_user_fixup,
22}; 22};
23 23
24/* Some functions that may trap due to a bad user-mode address have too many loads 24/*
25 and stores in them to make it at all practical to label each one and put them all in 25 * Some functions that may trap due to a bad user-mode address have too
26 the main exception table. 26 * many loads and stores in them to make it at all practical to label
27 27 * each one and put them all in the main exception table.
28 In particular, the fast memcpy routine is like this. It's fix-up is just to fall back 28 *
29 to a slow byte-at-a-time copy, which is handled the conventional way. So it's functionally 29 * In particular, the fast memcpy routine is like this. It's fix-up is
30 OK to just handle any trap occurring in the fast memcpy with that fixup. */ 30 * just to fall back to a slow byte-at-a-time copy, which is handled the
31 * conventional way. So it's functionally OK to just handle any trap
32 * occurring in the fast memcpy with that fixup.
33 */
31static const struct exception_table_entry *check_exception_ranges(unsigned long addr) 34static const struct exception_table_entry *check_exception_ranges(unsigned long addr)
32{ 35{
33 if ((addr >= (unsigned long)&copy_user_memcpy) && 36 if ((addr >= (unsigned long)&copy_user_memcpy) &&
@@ -77,4 +80,3 @@ int fixup_exception(struct pt_regs *regs)
77 80
78 return 0; 81 return 0;
79} 82}
80
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault_32.c
index 60d74f793a1d..33b43d20e9f6 100644
--- a/arch/sh/mm/fault.c
+++ b/arch/sh/mm/fault_32.c
@@ -172,7 +172,7 @@ no_context:
172 bust_spinlocks(1); 172 bust_spinlocks(1);
173 173
174 if (oops_may_print()) { 174 if (oops_may_print()) {
175 __typeof__(pte_val(__pte(0))) page; 175 unsigned long page;
176 176
177 if (address < PAGE_SIZE) 177 if (address < PAGE_SIZE)
178 printk(KERN_ALERT "Unable to handle kernel NULL " 178 printk(KERN_ALERT "Unable to handle kernel NULL "
diff --git a/arch/sh64/mm/tlbmiss.c b/arch/sh/mm/fault_64.c
index b767d6cff72f..399d53710d2f 100644
--- a/arch/sh64/mm/tlbmiss.c
+++ b/arch/sh/mm/fault_64.c
@@ -1,9 +1,5 @@
1/* 1/*
2 * This file is subject to the terms and conditions of the GNU General Public 2 * The SH64 TLB miss.
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * arch/sh64/mm/tlbmiss.c
7 * 3 *
8 * Original code from fault.c 4 * Original code from fault.c
9 * Copyright (C) 2000, 2001 Paolo Alberelli 5 * Copyright (C) 2000, 2001 Paolo Alberelli
@@ -12,16 +8,20 @@
12 * Copyright (C) 2003 Richard.Curnow@superh.com 8 * Copyright (C) 2003 Richard.Curnow@superh.com
13 * 9 *
14 * IMPORTANT NOTES : 10 * IMPORTANT NOTES :
15 * The do_fast_page_fault function is called from a context in entry.S where very few registers 11 * The do_fast_page_fault function is called from a context in entry.S
16 * have been saved. In particular, the code in this file must be compiled not to use ANY 12 * where very few registers have been saved. In particular, the code in
17 * caller-save registers that are not part of the restricted save set. Also, it means that 13 * this file must be compiled not to use ANY caller-save registers that
18 * code in this file must not make calls to functions elsewhere in the kernel, or else the 14 * are not part of the restricted save set. Also, it means that code in
19 * excepting context will see corruption in its caller-save registers. Plus, the entry.S save 15 * this file must not make calls to functions elsewhere in the kernel, or
20 * area is non-reentrant, so this code has to run with SR.BL==1, i.e. no interrupts taken inside 16 * else the excepting context will see corruption in its caller-save
21 * it and panic on any exception. 17 * registers. Plus, the entry.S save area is non-reentrant, so this code
18 * has to run with SR.BL==1, i.e. no interrupts taken inside it and panic
19 * on any exception.
22 * 20 *
21 * This file is subject to the terms and conditions of the GNU General Public
22 * License. See the file "COPYING" in the main directory of this archive
23 * for more details.
23 */ 24 */
24
25#include <linux/signal.h> 25#include <linux/signal.h>
26#include <linux/sched.h> 26#include <linux/sched.h>
27#include <linux/kernel.h> 27#include <linux/kernel.h>
@@ -33,14 +33,13 @@
33#include <linux/mm.h> 33#include <linux/mm.h>
34#include <linux/smp.h> 34#include <linux/smp.h>
35#include <linux/interrupt.h> 35#include <linux/interrupt.h>
36
37#include <asm/system.h> 36#include <asm/system.h>
38#include <asm/tlb.h> 37#include <asm/tlb.h>
39#include <asm/io.h> 38#include <asm/io.h>
40#include <asm/uaccess.h> 39#include <asm/uaccess.h>
41#include <asm/pgalloc.h> 40#include <asm/pgalloc.h>
42#include <asm/mmu_context.h> 41#include <asm/mmu_context.h>
43#include <asm/registers.h> /* required by inline asm statements */ 42#include <asm/cpu/registers.h>
44 43
45/* Callable from fault.c, so not static */ 44/* Callable from fault.c, so not static */
46inline void __do_tlb_refill(unsigned long address, 45inline void __do_tlb_refill(unsigned long address,
@@ -88,48 +87,47 @@ inline void __do_tlb_refill(unsigned long address,
88 87
89} 88}
90 89
91static int handle_vmalloc_fault(struct mm_struct *mm, unsigned long protection_flags, 90static int handle_vmalloc_fault(struct mm_struct *mm,
91 unsigned long protection_flags,
92 unsigned long long textaccess, 92 unsigned long long textaccess,
93 unsigned long address) 93 unsigned long address)
94{ 94{
95 pgd_t *dir; 95 pgd_t *dir;
96 pud_t *pud;
96 pmd_t *pmd; 97 pmd_t *pmd;
97 static pte_t *pte; 98 static pte_t *pte;
98 pte_t entry; 99 pte_t entry;
99 100
100 dir = pgd_offset_k(address); 101 dir = pgd_offset_k(address);
101 pmd = pmd_offset(dir, address);
102 102
103 if (pmd_none(*pmd)) { 103 pud = pud_offset(dir, address);
104 if (pud_none_or_clear_bad(pud))
104 return 0; 105 return 0;
105 }
106 106
107 if (pmd_bad(*pmd)) { 107 pmd = pmd_offset(pud, address);
108 pmd_clear(pmd); 108 if (pmd_none_or_clear_bad(pmd))
109 return 0; 109 return 0;
110 }
111 110
112 pte = pte_offset_kernel(pmd, address); 111 pte = pte_offset_kernel(pmd, address);
113 entry = *pte; 112 entry = *pte;
114 113
115 if (pte_none(entry) || !pte_present(entry)) { 114 if (pte_none(entry) || !pte_present(entry))
116 return 0; 115 return 0;
117 } 116 if ((pte_val(entry) & protection_flags) != protection_flags)
118
119 if ((pte_val(entry) & protection_flags) != protection_flags) {
120 return 0; 117 return 0;
121 }
122 118
123 __do_tlb_refill(address, textaccess, pte); 119 __do_tlb_refill(address, textaccess, pte);
124 120
125 return 1; 121 return 1;
126} 122}
127 123
128static int handle_tlbmiss(struct mm_struct *mm, unsigned long long protection_flags, 124static int handle_tlbmiss(struct mm_struct *mm,
129 unsigned long long textaccess, 125 unsigned long long protection_flags,
130 unsigned long address) 126 unsigned long long textaccess,
127 unsigned long address)
131{ 128{
132 pgd_t *dir; 129 pgd_t *dir;
130 pud_t *pud;
133 pmd_t *pmd; 131 pmd_t *pmd;
134 pte_t *pte; 132 pte_t *pte;
135 pte_t entry; 133 pte_t entry;
@@ -144,49 +142,49 @@ static int handle_tlbmiss(struct mm_struct *mm, unsigned long long protection_fl
144 142
145 See how mm->pgd is allocated and initialised in pgd_alloc to see why 143 See how mm->pgd is allocated and initialised in pgd_alloc to see why
146 the next test is necessary. - RPC */ 144 the next test is necessary. - RPC */
147 if (address >= (unsigned long) TASK_SIZE) { 145 if (address >= (unsigned long) TASK_SIZE)
148 /* upper half - never has page table entries. */ 146 /* upper half - never has page table entries. */
149 return 0; 147 return 0;
150 } 148
151 dir = pgd_offset(mm, address); 149 dir = pgd_offset(mm, address);
152 if (pgd_none(*dir)) { 150 if (pgd_none(*dir) || !pgd_present(*dir))
153 return 0; 151 return 0;
154 } 152 if (!pgd_present(*dir))
155 if (!pgd_present(*dir)) {
156 return 0; 153 return 0;
157 }
158 154
159 pmd = pmd_offset(dir, address); 155 pud = pud_offset(dir, address);
160 if (pmd_none(*pmd)) { 156 if (pud_none(*pud) || !pud_present(*pud))
161 return 0; 157 return 0;
162 } 158
163 if (!pmd_present(*pmd)) { 159 pmd = pmd_offset(pud, address);
160 if (pmd_none(*pmd) || !pmd_present(*pmd))
164 return 0; 161 return 0;
165 } 162
166 pte = pte_offset_kernel(pmd, address); 163 pte = pte_offset_kernel(pmd, address);
167 entry = *pte; 164 entry = *pte;
168 if (pte_none(entry)) { 165
169 return 0; 166 if (pte_none(entry) || !pte_present(entry))
170 }
171 if (!pte_present(entry)) {
172 return 0; 167 return 0;
173 }
174 168
175 /* If the page doesn't have sufficient protection bits set to service the 169 /*
176 kind of fault being handled, there's not much point doing the TLB refill. 170 * If the page doesn't have sufficient protection bits set to
177 Punt the fault to the general handler. */ 171 * service the kind of fault being handled, there's not much
178 if ((pte_val(entry) & protection_flags) != protection_flags) { 172 * point doing the TLB refill. Punt the fault to the general
173 * handler.
174 */
175 if ((pte_val(entry) & protection_flags) != protection_flags)
179 return 0; 176 return 0;
180 }
181 177
182 __do_tlb_refill(address, textaccess, pte); 178 __do_tlb_refill(address, textaccess, pte);
183 179
184 return 1; 180 return 1;
185} 181}
186 182
187/* Put all this information into one structure so that everything is just arithmetic 183/*
188 relative to a single base address. This reduces the number of movi/shori pairs needed 184 * Put all this information into one structure so that everything is just
189 just to load addresses of static data. */ 185 * arithmetic relative to a single base address. This reduces the number
186 * of movi/shori pairs needed just to load addresses of static data.
187 */
190struct expevt_lookup { 188struct expevt_lookup {
191 unsigned short protection_flags[8]; 189 unsigned short protection_flags[8];
192 unsigned char is_text_access[8]; 190 unsigned char is_text_access[8];
@@ -216,7 +214,8 @@ static struct expevt_lookup expevt_lookup_table = {
216 general fault handling in fault.c which deals with mapping file-backed 214 general fault handling in fault.c which deals with mapping file-backed
217 pages, stack growth, segmentation faults, swapping etc etc) 215 pages, stack growth, segmentation faults, swapping etc etc)
218 */ 216 */
219asmlinkage int do_fast_page_fault(unsigned long long ssr_md, unsigned long long expevt, 217asmlinkage int do_fast_page_fault(unsigned long long ssr_md,
218 unsigned long long expevt,
220 unsigned long address) 219 unsigned long address)
221{ 220{
222 struct task_struct *tsk; 221 struct task_struct *tsk;
@@ -226,26 +225,23 @@ asmlinkage int do_fast_page_fault(unsigned long long ssr_md, unsigned long long
226 unsigned long long index; 225 unsigned long long index;
227 unsigned long long expevt4; 226 unsigned long long expevt4;
228 227
229 /* The next few lines implement a way of hashing EXPEVT into a small array index 228 /* The next few lines implement a way of hashing EXPEVT into a
230 which can be used to lookup parameters specific to the type of TLBMISS being 229 * small array index which can be used to lookup parameters
231 handled. Note: 230 * specific to the type of TLBMISS being handled.
232 ITLBMISS has EXPEVT==0xa40 231 *
233 RTLBMISS has EXPEVT==0x040 232 * Note:
234 WTLBMISS has EXPEVT==0x060 233 * ITLBMISS has EXPEVT==0xa40
235 */ 234 * RTLBMISS has EXPEVT==0x040
236 235 * WTLBMISS has EXPEVT==0x060
236 */
237 expevt4 = (expevt >> 4); 237 expevt4 = (expevt >> 4);
238 /* TODO : xor ssr_md into this expression too. Then we can check that PRU is set 238 /* TODO : xor ssr_md into this expression too. Then we can check
239 when it needs to be. */ 239 * that PRU is set when it needs to be. */
240 index = expevt4 ^ (expevt4 >> 5); 240 index = expevt4 ^ (expevt4 >> 5);
241 index &= 7; 241 index &= 7;
242 protection_flags = expevt_lookup_table.protection_flags[index]; 242 protection_flags = expevt_lookup_table.protection_flags[index];
243 textaccess = expevt_lookup_table.is_text_access[index]; 243 textaccess = expevt_lookup_table.is_text_access[index];
244 244
245#ifdef CONFIG_SH64_PROC_TLB
246 ++calls_to_do_fast_page_fault;
247#endif
248
249 /* SIM 245 /* SIM
250 * Note this is now called with interrupts still disabled 246 * Note this is now called with interrupts still disabled
251 * This is to cope with being called for a missing IO port 247 * This is to cope with being called for a missing IO port
@@ -262,18 +258,18 @@ asmlinkage int do_fast_page_fault(unsigned long long ssr_md, unsigned long long
262 258
263 if ((address >= VMALLOC_START && address < VMALLOC_END) || 259 if ((address >= VMALLOC_START && address < VMALLOC_END) ||
264 (address >= IOBASE_VADDR && address < IOBASE_END)) { 260 (address >= IOBASE_VADDR && address < IOBASE_END)) {
265 if (ssr_md) { 261 if (ssr_md)
266 /* Process-contexts can never have this address range mapped */ 262 /*
267 if (handle_vmalloc_fault(mm, protection_flags, textaccess, address)) { 263 * Process-contexts can never have this address
264 * range mapped
265 */
266 if (handle_vmalloc_fault(mm, protection_flags,
267 textaccess, address))
268 return 1; 268 return 1;
269 }
270 }
271 } else if (!in_interrupt() && mm) { 269 } else if (!in_interrupt() && mm) {
272 if (handle_tlbmiss(mm, protection_flags, textaccess, address)) { 270 if (handle_tlbmiss(mm, protection_flags, textaccess, address))
273 return 1; 271 return 1;
274 }
275 } 272 }
276 273
277 return 0; 274 return 0;
278} 275}
279
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index d5e160da64b2..2918c6b14659 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -23,9 +23,7 @@
23 23
24DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); 24DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
25pgd_t swapper_pg_dir[PTRS_PER_PGD]; 25pgd_t swapper_pg_dir[PTRS_PER_PGD];
26 26unsigned long cached_to_uncached = 0;
27void (*copy_page)(void *from, void *to);
28void (*clear_page)(void *to);
29 27
30void show_mem(void) 28void show_mem(void)
31{ 29{
@@ -102,7 +100,8 @@ static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot)
102 100
103 set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, prot)); 101 set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, prot));
104 102
105 flush_tlb_one(get_asid(), addr); 103 if (cached_to_uncached)
104 flush_tlb_one(get_asid(), addr);
106} 105}
107 106
108/* 107/*
@@ -131,6 +130,37 @@ void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
131 130
132 set_pte_phys(address, phys, prot); 131 set_pte_phys(address, phys, prot);
133} 132}
133
134void __init page_table_range_init(unsigned long start, unsigned long end,
135 pgd_t *pgd_base)
136{
137 pgd_t *pgd;
138 pud_t *pud;
139 pmd_t *pmd;
140 int pgd_idx;
141 unsigned long vaddr;
142
143 vaddr = start & PMD_MASK;
144 end = (end + PMD_SIZE - 1) & PMD_MASK;
145 pgd_idx = pgd_index(vaddr);
146 pgd = pgd_base + pgd_idx;
147
148 for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
149 BUG_ON(pgd_none(*pgd));
150 pud = pud_offset(pgd, 0);
151 BUG_ON(pud_none(*pud));
152 pmd = pmd_offset(pud, 0);
153
154 if (!pmd_present(*pmd)) {
155 pte_t *pte_table;
156 pte_table = (pte_t *)alloc_bootmem_low_pages(PAGE_SIZE);
157 memset(pte_table, 0, PAGE_SIZE);
158 pmd_populate_kernel(&init_mm, pmd, pte_table);
159 }
160
161 vaddr += PMD_SIZE;
162 }
163}
134#endif /* CONFIG_MMU */ 164#endif /* CONFIG_MMU */
135 165
136/* 166/*
@@ -150,6 +180,11 @@ void __init paging_init(void)
150 * check for a null value. */ 180 * check for a null value. */
151 set_TTB(swapper_pg_dir); 181 set_TTB(swapper_pg_dir);
152 182
183 /* Populate the relevant portions of swapper_pg_dir so that
184 * we can use the fixmap entries without calling kmalloc.
185 * pte's will be filled in by __set_fixmap(). */
186 page_table_range_init(FIXADDR_START, FIXADDR_TOP, swapper_pg_dir);
187
153 memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); 188 memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
154 189
155 for_each_online_node(nid) { 190 for_each_online_node(nid) {
@@ -167,9 +202,22 @@ void __init paging_init(void)
167 } 202 }
168 203
169 free_area_init_nodes(max_zone_pfns); 204 free_area_init_nodes(max_zone_pfns);
205
206 /* Set up the uncached fixmap */
207 set_fixmap_nocache(FIX_UNCACHED, __pa(&__uncached_start));
208
209#ifdef CONFIG_29BIT
210 /*
211 * Handle trivial transitions between cached and uncached
212 * segments, making use of the 1:1 mapping relationship in
213 * 512MB lowmem.
214 */
215 cached_to_uncached = P2SEG - P1SEG;
216#endif
170} 217}
171 218
172static struct kcore_list kcore_mem, kcore_vmalloc; 219static struct kcore_list kcore_mem, kcore_vmalloc;
220int after_bootmem = 0;
173 221
174void __init mem_init(void) 222void __init mem_init(void)
175{ 223{
@@ -202,17 +250,7 @@ void __init mem_init(void)
202 memset(empty_zero_page, 0, PAGE_SIZE); 250 memset(empty_zero_page, 0, PAGE_SIZE);
203 __flush_wback_region(empty_zero_page, PAGE_SIZE); 251 __flush_wback_region(empty_zero_page, PAGE_SIZE);
204 252
205 /* 253 after_bootmem = 1;
206 * Setup wrappers for copy/clear_page(), these will get overridden
207 * later in the boot process if a better method is available.
208 */
209#ifdef CONFIG_MMU
210 copy_page = copy_page_slow;
211 clear_page = clear_page_slow;
212#else
213 copy_page = copy_page_nommu;
214 clear_page = clear_page_nommu;
215#endif
216 254
217 codesize = (unsigned long) &_etext - (unsigned long) &_text; 255 codesize = (unsigned long) &_etext - (unsigned long) &_text;
218 datasize = (unsigned long) &_edata - (unsigned long) &_etext; 256 datasize = (unsigned long) &_edata - (unsigned long) &_etext;
diff --git a/arch/sh/mm/ioremap.c b/arch/sh/mm/ioremap_32.c
index 0c7b7e33abdc..0c7b7e33abdc 100644
--- a/arch/sh/mm/ioremap.c
+++ b/arch/sh/mm/ioremap_32.c
diff --git a/arch/sh64/mm/ioremap.c b/arch/sh/mm/ioremap_64.c
index 535304e6601f..e27d16519235 100644
--- a/arch/sh64/mm/ioremap.c
+++ b/arch/sh/mm/ioremap_64.c
@@ -1,30 +1,31 @@
1/* 1/*
2 * This file is subject to the terms and conditions of the GNU General Public 2 * arch/sh/mm/ioremap_64.c
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * arch/sh64/mm/ioremap.c
7 * 3 *
8 * Copyright (C) 2000, 2001 Paolo Alberelli 4 * Copyright (C) 2000, 2001 Paolo Alberelli
9 * Copyright (C) 2003, 2004 Paul Mundt 5 * Copyright (C) 2003 - 2007 Paul Mundt
10 * 6 *
11 * Mostly derived from arch/sh/mm/ioremap.c which, in turn is mostly 7 * Mostly derived from arch/sh/mm/ioremap.c which, in turn is mostly
12 * derived from arch/i386/mm/ioremap.c . 8 * derived from arch/i386/mm/ioremap.c .
13 * 9 *
14 * (C) Copyright 1995 1996 Linus Torvalds 10 * (C) Copyright 1995 1996 Linus Torvalds
11 *
12 * This file is subject to the terms and conditions of the GNU General Public
13 * License. See the file "COPYING" in the main directory of this archive
14 * for more details.
15 */ 15 */
16#include <linux/kernel.h>
17#include <linux/slab.h>
18#include <linux/vmalloc.h> 16#include <linux/vmalloc.h>
19#include <linux/sched.h>
20#include <linux/string.h>
21#include <linux/io.h>
22#include <linux/ioport.h> 17#include <linux/ioport.h>
18#include <linux/module.h>
19#include <linux/mm.h>
20#include <linux/io.h>
23#include <linux/bootmem.h> 21#include <linux/bootmem.h>
24#include <linux/proc_fs.h> 22#include <linux/proc_fs.h>
25#include <linux/module.h> 23#include <asm/page.h>
26#include <asm/pgalloc.h> 24#include <asm/pgalloc.h>
25#include <asm/addrspace.h>
26#include <asm/cacheflush.h>
27#include <asm/tlbflush.h> 27#include <asm/tlbflush.h>
28#include <asm/mmu.h>
28 29
29static void shmedia_mapioaddr(unsigned long, unsigned long); 30static void shmedia_mapioaddr(unsigned long, unsigned long);
30static unsigned long shmedia_ioremap(struct resource *, u32, int); 31static unsigned long shmedia_ioremap(struct resource *, u32, int);
@@ -42,7 +43,8 @@ static unsigned long shmedia_ioremap(struct resource *, u32, int);
42 * have to convert them into an offset in a page-aligned mapping, but the 43 * have to convert them into an offset in a page-aligned mapping, but the
43 * caller shouldn't need to know that small detail. 44 * caller shouldn't need to know that small detail.
44 */ 45 */
45void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags) 46void *__ioremap(unsigned long phys_addr, unsigned long size,
47 unsigned long flags)
46{ 48{
47 void * addr; 49 void * addr;
48 struct vm_struct * area; 50 struct vm_struct * area;
@@ -83,7 +85,7 @@ void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flag
83} 85}
84EXPORT_SYMBOL(__ioremap); 86EXPORT_SYMBOL(__ioremap);
85 87
86void iounmap(void *addr) 88void __iounmap(void *addr)
87{ 89{
88 struct vm_struct *area; 90 struct vm_struct *area;
89 91
@@ -96,7 +98,7 @@ void iounmap(void *addr)
96 98
97 kfree(area); 99 kfree(area);
98} 100}
99EXPORT_SYMBOL(iounmap); 101EXPORT_SYMBOL(__iounmap);
100 102
101static struct resource shmedia_iomap = { 103static struct resource shmedia_iomap = {
102 .name = "shmedia_iomap", 104 .name = "shmedia_iomap",
@@ -265,6 +267,7 @@ static __init_refok void *sh64_get_page(void)
265static void shmedia_mapioaddr(unsigned long pa, unsigned long va) 267static void shmedia_mapioaddr(unsigned long pa, unsigned long va)
266{ 268{
267 pgd_t *pgdp; 269 pgd_t *pgdp;
270 pud_t *pudp;
268 pmd_t *pmdp; 271 pmd_t *pmdp;
269 pte_t *ptep, pte; 272 pte_t *ptep, pte;
270 pgprot_t prot; 273 pgprot_t prot;
@@ -274,11 +277,17 @@ static void shmedia_mapioaddr(unsigned long pa, unsigned long va)
274 277
275 pgdp = pgd_offset_k(va); 278 pgdp = pgd_offset_k(va);
276 if (pgd_none(*pgdp) || !pgd_present(*pgdp)) { 279 if (pgd_none(*pgdp) || !pgd_present(*pgdp)) {
280 pudp = (pud_t *)sh64_get_page();
281 set_pgd(pgdp, __pgd((unsigned long)pudp | _KERNPG_TABLE));
282 }
283
284 pudp = pud_offset(pgdp, va);
285 if (pud_none(*pudp) || !pud_present(*pudp)) {
277 pmdp = (pmd_t *)sh64_get_page(); 286 pmdp = (pmd_t *)sh64_get_page();
278 set_pgd(pgdp, __pgd((unsigned long)pmdp | _KERNPG_TABLE)); 287 set_pud(pudp, __pud((unsigned long)pmdp | _KERNPG_TABLE));
279 } 288 }
280 289
281 pmdp = pmd_offset(pgdp, va); 290 pmdp = pmd_offset(pudp, va);
282 if (pmd_none(*pmdp) || !pmd_present(*pmdp) ) { 291 if (pmd_none(*pmdp) || !pmd_present(*pmdp) ) {
283 ptep = (pte_t *)sh64_get_page(); 292 ptep = (pte_t *)sh64_get_page();
284 set_pmd(pmdp, __pmd((unsigned long)ptep + _PAGE_TABLE)); 293 set_pmd(pmdp, __pmd((unsigned long)ptep + _PAGE_TABLE));
@@ -302,12 +311,19 @@ static void shmedia_mapioaddr(unsigned long pa, unsigned long va)
302static void shmedia_unmapioaddr(unsigned long vaddr) 311static void shmedia_unmapioaddr(unsigned long vaddr)
303{ 312{
304 pgd_t *pgdp; 313 pgd_t *pgdp;
314 pud_t *pudp;
305 pmd_t *pmdp; 315 pmd_t *pmdp;
306 pte_t *ptep; 316 pte_t *ptep;
307 317
308 pgdp = pgd_offset_k(vaddr); 318 pgdp = pgd_offset_k(vaddr);
309 pmdp = pmd_offset(pgdp, vaddr); 319 if (pgd_none(*pgdp) || pgd_bad(*pgdp))
320 return;
321
322 pudp = pud_offset(pgdp, vaddr);
323 if (pud_none(*pudp) || pud_bad(*pudp))
324 return;
310 325
326 pmdp = pmd_offset(pudp, vaddr);
311 if (pmd_none(*pmdp) || pmd_bad(*pmdp)) 327 if (pmd_none(*pmdp) || pmd_bad(*pmdp))
312 return; 328 return;
313 329
diff --git a/arch/sh/mm/pg-nommu.c b/arch/sh/mm/pg-nommu.c
index d15221beaa16..677dd57f0877 100644
--- a/arch/sh/mm/pg-nommu.c
+++ b/arch/sh/mm/pg-nommu.c
@@ -14,12 +14,12 @@
14#include <linux/string.h> 14#include <linux/string.h>
15#include <asm/page.h> 15#include <asm/page.h>
16 16
17void copy_page_nommu(void *to, void *from) 17void copy_page(void *to, void *from)
18{ 18{
19 memcpy(to, from, PAGE_SIZE); 19 memcpy(to, from, PAGE_SIZE);
20} 20}
21 21
22void clear_page_nommu(void *to) 22void clear_page(void *to)
23{ 23{
24 memset(to, 0, PAGE_SIZE); 24 memset(to, 0, PAGE_SIZE);
25} 25}
diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c
index 1d45b82f0a63..ab81c602295f 100644
--- a/arch/sh/mm/pmb.c
+++ b/arch/sh/mm/pmb.c
@@ -27,6 +27,7 @@
27#include <asm/pgtable.h> 27#include <asm/pgtable.h>
28#include <asm/mmu.h> 28#include <asm/mmu.h>
29#include <asm/io.h> 29#include <asm/io.h>
30#include <asm/mmu_context.h>
30 31
31#define NR_PMB_ENTRIES 16 32#define NR_PMB_ENTRIES 16
32 33
@@ -162,18 +163,18 @@ repeat:
162 return 0; 163 return 0;
163} 164}
164 165
165int set_pmb_entry(struct pmb_entry *pmbe) 166int __uses_jump_to_uncached set_pmb_entry(struct pmb_entry *pmbe)
166{ 167{
167 int ret; 168 int ret;
168 169
169 jump_to_P2(); 170 jump_to_uncached();
170 ret = __set_pmb_entry(pmbe->vpn, pmbe->ppn, pmbe->flags, &pmbe->entry); 171 ret = __set_pmb_entry(pmbe->vpn, pmbe->ppn, pmbe->flags, &pmbe->entry);
171 back_to_P1(); 172 back_to_cached();
172 173
173 return ret; 174 return ret;
174} 175}
175 176
176void clear_pmb_entry(struct pmb_entry *pmbe) 177void __uses_jump_to_uncached clear_pmb_entry(struct pmb_entry *pmbe)
177{ 178{
178 unsigned int entry = pmbe->entry; 179 unsigned int entry = pmbe->entry;
179 unsigned long addr; 180 unsigned long addr;
@@ -187,7 +188,7 @@ void clear_pmb_entry(struct pmb_entry *pmbe)
187 entry >= NR_PMB_ENTRIES)) 188 entry >= NR_PMB_ENTRIES))
188 return; 189 return;
189 190
190 jump_to_P2(); 191 jump_to_uncached();
191 192
192 /* Clear V-bit */ 193 /* Clear V-bit */
193 addr = mk_pmb_addr(entry); 194 addr = mk_pmb_addr(entry);
@@ -196,7 +197,7 @@ void clear_pmb_entry(struct pmb_entry *pmbe)
196 addr = mk_pmb_data(entry); 197 addr = mk_pmb_data(entry);
197 ctrl_outl(ctrl_inl(addr) & ~PMB_V, addr); 198 ctrl_outl(ctrl_inl(addr) & ~PMB_V, addr);
198 199
199 back_to_P1(); 200 back_to_cached();
200 201
201 clear_bit(entry, &pmb_map); 202 clear_bit(entry, &pmb_map);
202} 203}
@@ -301,17 +302,17 @@ static void pmb_cache_ctor(struct kmem_cache *cachep, void *pmb)
301 pmbe->entry = PMB_NO_ENTRY; 302 pmbe->entry = PMB_NO_ENTRY;
302} 303}
303 304
304static int __init pmb_init(void) 305static int __uses_jump_to_uncached pmb_init(void)
305{ 306{
306 unsigned int nr_entries = ARRAY_SIZE(pmb_init_map); 307 unsigned int nr_entries = ARRAY_SIZE(pmb_init_map);
307 unsigned int entry; 308 unsigned int entry, i;
308 309
309 BUG_ON(unlikely(nr_entries >= NR_PMB_ENTRIES)); 310 BUG_ON(unlikely(nr_entries >= NR_PMB_ENTRIES));
310 311
311 pmb_cache = kmem_cache_create("pmb", sizeof(struct pmb_entry), 0, 312 pmb_cache = kmem_cache_create("pmb", sizeof(struct pmb_entry), 0,
312 SLAB_PANIC, pmb_cache_ctor); 313 SLAB_PANIC, pmb_cache_ctor);
313 314
314 jump_to_P2(); 315 jump_to_uncached();
315 316
316 /* 317 /*
317 * Ordering is important, P2 must be mapped in the PMB before we 318 * Ordering is important, P2 must be mapped in the PMB before we
@@ -329,7 +330,12 @@ static int __init pmb_init(void)
329 /* PMB.SE and UB[7] */ 330 /* PMB.SE and UB[7] */
330 ctrl_outl((1 << 31) | (1 << 7), PMB_PASCR); 331 ctrl_outl((1 << 31) | (1 << 7), PMB_PASCR);
331 332
332 back_to_P1(); 333 /* Flush out the TLB */
334 i = ctrl_inl(MMUCR);
335 i |= MMUCR_TI;
336 ctrl_outl(i, MMUCR);
337
338 back_to_cached();
333 339
334 return 0; 340 return 0;
335} 341}
diff --git a/arch/sh/mm/tlb-nommu.c b/arch/sh/mm/tlb-nommu.c
index 1ccca7c0532e..15111bc7ddd6 100644
--- a/arch/sh/mm/tlb-nommu.c
+++ b/arch/sh/mm/tlb-nommu.c
@@ -9,6 +9,7 @@
9 */ 9 */
10#include <linux/kernel.h> 10#include <linux/kernel.h>
11#include <linux/mm.h> 11#include <linux/mm.h>
12#include <asm/pgtable.h>
12 13
13/* 14/*
14 * Nothing too terribly exciting here .. 15 * Nothing too terribly exciting here ..
@@ -49,3 +50,12 @@ void update_mmu_cache(struct vm_area_struct * vma,
49{ 50{
50 BUG(); 51 BUG();
51} 52}
53
54void __init page_table_range_init(unsigned long start, unsigned long end,
55 pgd_t *pgd_base)
56{
57}
58
59void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
60{
61}
diff --git a/arch/sh/mm/tlb-sh4.c b/arch/sh/mm/tlb-sh4.c
index 2d1dd6044307..f0c7b7397fa6 100644
--- a/arch/sh/mm/tlb-sh4.c
+++ b/arch/sh/mm/tlb-sh4.c
@@ -79,7 +79,8 @@ void update_mmu_cache(struct vm_area_struct * vma,
79 local_irq_restore(flags); 79 local_irq_restore(flags);
80} 80}
81 81
82void local_flush_tlb_one(unsigned long asid, unsigned long page) 82void __uses_jump_to_uncached local_flush_tlb_one(unsigned long asid,
83 unsigned long page)
83{ 84{
84 unsigned long addr, data; 85 unsigned long addr, data;
85 86
@@ -91,7 +92,7 @@ void local_flush_tlb_one(unsigned long asid, unsigned long page)
91 */ 92 */
92 addr = MMU_UTLB_ADDRESS_ARRAY | MMU_PAGE_ASSOC_BIT; 93 addr = MMU_UTLB_ADDRESS_ARRAY | MMU_PAGE_ASSOC_BIT;
93 data = page | asid; /* VALID bit is off */ 94 data = page | asid; /* VALID bit is off */
94 jump_to_P2(); 95 jump_to_uncached();
95 ctrl_outl(data, addr); 96 ctrl_outl(data, addr);
96 back_to_P1(); 97 back_to_cached();
97} 98}
diff --git a/arch/sh64/mm/tlb.c b/arch/sh/mm/tlb-sh5.c
index d517e7d70340..f34274a1ded3 100644
--- a/arch/sh64/mm/tlb.c
+++ b/arch/sh/mm/tlb-sh5.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/sh64/mm/tlb.c 2 * arch/sh/mm/tlb-sh5.c
3 * 3 *
4 * Copyright (C) 2003 Paul Mundt <lethal@linux-sh.org> 4 * Copyright (C) 2003 Paul Mundt <lethal@linux-sh.org>
5 * Copyright (C) 2003 Richard Curnow <richard.curnow@superh.com> 5 * Copyright (C) 2003 Richard Curnow <richard.curnow@superh.com>
@@ -7,7 +7,6 @@
7 * This file is subject to the terms and conditions of the GNU General Public 7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive 8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details. 9 * for more details.
10 *
11 */ 10 */
12#include <linux/mm.h> 11#include <linux/mm.h>
13#include <linux/init.h> 12#include <linux/init.h>
@@ -163,4 +162,3 @@ inline void sh64_setup_tlb_slot(unsigned long long config_addr,
163 */ 162 */
164inline void sh64_teardown_tlb_slot(unsigned long long config_addr) 163inline void sh64_teardown_tlb_slot(unsigned long long config_addr)
165 __attribute__ ((alias("__flush_tlb_slot"))); 164 __attribute__ ((alias("__flush_tlb_slot")));
166
diff --git a/arch/sh/mm/tlb-flush.c b/arch/sh/mm/tlbflush_32.c
index 6f45c1f8a7fe..6f45c1f8a7fe 100644
--- a/arch/sh/mm/tlb-flush.c
+++ b/arch/sh/mm/tlbflush_32.c
diff --git a/arch/sh64/mm/fault.c b/arch/sh/mm/tlbflush_64.c
index 7c79a1ba8059..2a98c9ec88ff 100644
--- a/arch/sh64/mm/fault.c
+++ b/arch/sh/mm/tlbflush_64.c
@@ -1,16 +1,14 @@
1/* 1/*
2 * This file is subject to the terms and conditions of the GNU General Public 2 * arch/sh/mm/tlb-flush_64.c
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * arch/sh64/mm/fault.c
7 * 3 *
8 * Copyright (C) 2000, 2001 Paolo Alberelli 4 * Copyright (C) 2000, 2001 Paolo Alberelli
9 * Copyright (C) 2003 Richard Curnow (/proc/tlb, bug fixes) 5 * Copyright (C) 2003 Richard Curnow (/proc/tlb, bug fixes)
10 * Copyright (C) 2003 Paul Mundt 6 * Copyright (C) 2003 Paul Mundt
11 * 7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
12 */ 11 */
13
14#include <linux/signal.h> 12#include <linux/signal.h>
15#include <linux/rwsem.h> 13#include <linux/rwsem.h>
16#include <linux/sched.h> 14#include <linux/sched.h>
@@ -23,39 +21,12 @@
23#include <linux/mm.h> 21#include <linux/mm.h>
24#include <linux/smp.h> 22#include <linux/smp.h>
25#include <linux/interrupt.h> 23#include <linux/interrupt.h>
26
27#include <asm/system.h> 24#include <asm/system.h>
28#include <asm/io.h> 25#include <asm/io.h>
29#include <asm/tlb.h> 26#include <asm/tlb.h>
30#include <asm/uaccess.h> 27#include <asm/uaccess.h>
31#include <asm/pgalloc.h> 28#include <asm/pgalloc.h>
32#include <asm/mmu_context.h> 29#include <asm/mmu_context.h>
33#include <asm/registers.h> /* required by inline asm statements */
34
35#if defined(CONFIG_SH64_PROC_TLB)
36#include <linux/init.h>
37#include <linux/proc_fs.h>
38/* Count numbers of tlb refills in each region */
39static unsigned long long calls_to_update_mmu_cache = 0ULL;
40static unsigned long long calls_to_flush_tlb_page = 0ULL;
41static unsigned long long calls_to_flush_tlb_range = 0ULL;
42static unsigned long long calls_to_flush_tlb_mm = 0ULL;
43static unsigned long long calls_to_flush_tlb_all = 0ULL;
44unsigned long long calls_to_do_slow_page_fault = 0ULL;
45unsigned long long calls_to_do_fast_page_fault = 0ULL;
46
47/* Count size of ranges for flush_tlb_range */
48static unsigned long long flush_tlb_range_1 = 0ULL;
49static unsigned long long flush_tlb_range_2 = 0ULL;
50static unsigned long long flush_tlb_range_3_4 = 0ULL;
51static unsigned long long flush_tlb_range_5_7 = 0ULL;
52static unsigned long long flush_tlb_range_8_11 = 0ULL;
53static unsigned long long flush_tlb_range_12_15 = 0ULL;
54static unsigned long long flush_tlb_range_16_up = 0ULL;
55
56static unsigned long long page_not_present = 0ULL;
57
58#endif
59 30
60extern void die(const char *,struct pt_regs *,long); 31extern void die(const char *,struct pt_regs *,long);
61 32
@@ -87,29 +58,27 @@ static inline void print_task(struct task_struct *tsk)
87static pte_t *lookup_pte(struct mm_struct *mm, unsigned long address) 58static pte_t *lookup_pte(struct mm_struct *mm, unsigned long address)
88{ 59{
89 pgd_t *dir; 60 pgd_t *dir;
61 pud_t *pud;
90 pmd_t *pmd; 62 pmd_t *pmd;
91 pte_t *pte; 63 pte_t *pte;
92 pte_t entry; 64 pte_t entry;
93 65
94 dir = pgd_offset(mm, address); 66 dir = pgd_offset(mm, address);
95 if (pgd_none(*dir)) { 67 if (pgd_none(*dir))
96 return NULL; 68 return NULL;
97 }
98 69
99 pmd = pmd_offset(dir, address); 70 pud = pud_offset(dir, address);
100 if (pmd_none(*pmd)) { 71 if (pud_none(*pud))
72 return NULL;
73
74 pmd = pmd_offset(pud, address);
75 if (pmd_none(*pmd))
101 return NULL; 76 return NULL;
102 }
103 77
104 pte = pte_offset_kernel(pmd, address); 78 pte = pte_offset_kernel(pmd, address);
105 entry = *pte; 79 entry = *pte;
106 80 if (pte_none(entry) || !pte_present(entry))
107 if (pte_none(entry)) {
108 return NULL; 81 return NULL;
109 }
110 if (!pte_present(entry)) {
111 return NULL;
112 }
113 82
114 return pte; 83 return pte;
115} 84}
@@ -129,10 +98,6 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
129 pte_t *pte; 98 pte_t *pte;
130 int fault; 99 int fault;
131 100
132#if defined(CONFIG_SH64_PROC_TLB)
133 ++calls_to_do_slow_page_fault;
134#endif
135
136 /* SIM 101 /* SIM
137 * Note this is now called with interrupts still disabled 102 * Note this is now called with interrupts still disabled
138 * This is to cope with being called for a missing IO port 103 * This is to cope with being called for a missing IO port
@@ -355,16 +320,9 @@ do_sigbus:
355 goto no_context; 320 goto no_context;
356} 321}
357 322
358
359void flush_tlb_all(void);
360
361void update_mmu_cache(struct vm_area_struct * vma, 323void update_mmu_cache(struct vm_area_struct * vma,
362 unsigned long address, pte_t pte) 324 unsigned long address, pte_t pte)
363{ 325{
364#if defined(CONFIG_SH64_PROC_TLB)
365 ++calls_to_update_mmu_cache;
366#endif
367
368 /* 326 /*
369 * This appears to get called once for every pte entry that gets 327 * This appears to get called once for every pte entry that gets
370 * established => I don't think it's efficient to try refilling the 328 * established => I don't think it's efficient to try refilling the
@@ -378,40 +336,29 @@ void update_mmu_cache(struct vm_area_struct * vma,
378 */ 336 */
379} 337}
380 338
381static void __flush_tlb_page(struct vm_area_struct *vma, unsigned long page) 339void local_flush_tlb_one(unsigned long asid, unsigned long page)
382{ 340{
383 unsigned long long match, pteh=0, lpage; 341 unsigned long long match, pteh=0, lpage;
384 unsigned long tlb; 342 unsigned long tlb;
385 struct mm_struct *mm;
386
387 mm = vma->vm_mm;
388
389 if (mm->context == NO_CONTEXT)
390 return;
391 343
392 /* 344 /*
393 * Sign-extend based on neff. 345 * Sign-extend based on neff.
394 */ 346 */
395 lpage = (page & NEFF_SIGN) ? (page | NEFF_MASK) : page; 347 lpage = (page & NEFF_SIGN) ? (page | NEFF_MASK) : page;
396 match = ((mm->context & MMU_CONTEXT_ASID_MASK) << PTEH_ASID_SHIFT) | PTEH_VALID; 348 match = (asid << PTEH_ASID_SHIFT) | PTEH_VALID;
397 match |= lpage; 349 match |= lpage;
398 350
399 /* Do ITLB : don't bother for pages in non-exectutable VMAs */ 351 for_each_itlb_entry(tlb) {
400 if (vma->vm_flags & VM_EXEC) { 352 asm volatile ("getcfg %1, 0, %0"
401 for_each_itlb_entry(tlb) { 353 : "=r" (pteh)
402 asm volatile ("getcfg %1, 0, %0" 354 : "r" (tlb) );
403 : "=r" (pteh)
404 : "r" (tlb) );
405
406 if (pteh == match) {
407 __flush_tlb_slot(tlb);
408 break;
409 }
410 355
356 if (pteh == match) {
357 __flush_tlb_slot(tlb);
358 break;
411 } 359 }
412 } 360 }
413 361
414 /* Do DTLB : any page could potentially be in here. */
415 for_each_dtlb_entry(tlb) { 362 for_each_dtlb_entry(tlb) {
416 asm volatile ("getcfg %1, 0, %0" 363 asm volatile ("getcfg %1, 0, %0"
417 : "=r" (pteh) 364 : "=r" (pteh)
@@ -425,52 +372,29 @@ static void __flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
425 } 372 }
426} 373}
427 374
428void flush_tlb_page(struct vm_area_struct *vma, unsigned long page) 375void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
429{ 376{
430 unsigned long flags; 377 unsigned long flags;
431 378
432#if defined(CONFIG_SH64_PROC_TLB)
433 ++calls_to_flush_tlb_page;
434#endif
435
436 if (vma->vm_mm) { 379 if (vma->vm_mm) {
437 page &= PAGE_MASK; 380 page &= PAGE_MASK;
438 local_irq_save(flags); 381 local_irq_save(flags);
439 __flush_tlb_page(vma, page); 382 local_flush_tlb_one(get_asid(), page);
440 local_irq_restore(flags); 383 local_irq_restore(flags);
441 } 384 }
442} 385}
443 386
444void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, 387void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
445 unsigned long end) 388 unsigned long end)
446{ 389{
447 unsigned long flags; 390 unsigned long flags;
448 unsigned long long match, pteh=0, pteh_epn, pteh_low; 391 unsigned long long match, pteh=0, pteh_epn, pteh_low;
449 unsigned long tlb; 392 unsigned long tlb;
393 unsigned int cpu = smp_processor_id();
450 struct mm_struct *mm; 394 struct mm_struct *mm;
451 395
452 mm = vma->vm_mm; 396 mm = vma->vm_mm;
453 397 if (cpu_context(cpu, mm) == NO_CONTEXT)
454#if defined(CONFIG_SH64_PROC_TLB)
455 ++calls_to_flush_tlb_range;
456
457 {
458 unsigned long size = (end - 1) - start;
459 size >>= 12; /* divide by PAGE_SIZE */
460 size++; /* end=start+4096 => 1 page */
461 switch (size) {
462 case 1 : flush_tlb_range_1++; break;
463 case 2 : flush_tlb_range_2++; break;
464 case 3 ... 4 : flush_tlb_range_3_4++; break;
465 case 5 ... 7 : flush_tlb_range_5_7++; break;
466 case 8 ... 11 : flush_tlb_range_8_11++; break;
467 case 12 ... 15 : flush_tlb_range_12_15++; break;
468 default : flush_tlb_range_16_up++; break;
469 }
470 }
471#endif
472
473 if (mm->context == NO_CONTEXT)
474 return; 398 return;
475 399
476 local_irq_save(flags); 400 local_irq_save(flags);
@@ -478,7 +402,7 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
478 start &= PAGE_MASK; 402 start &= PAGE_MASK;
479 end &= PAGE_MASK; 403 end &= PAGE_MASK;
480 404
481 match = ((mm->context & MMU_CONTEXT_ASID_MASK) << PTEH_ASID_SHIFT) | PTEH_VALID; 405 match = (cpu_asid(cpu, mm) << PTEH_ASID_SHIFT) | PTEH_VALID;
482 406
483 /* Flush ITLB */ 407 /* Flush ITLB */
484 for_each_itlb_entry(tlb) { 408 for_each_itlb_entry(tlb) {
@@ -509,94 +433,43 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
509 local_irq_restore(flags); 433 local_irq_restore(flags);
510} 434}
511 435
512void flush_tlb_mm(struct mm_struct *mm) 436void local_flush_tlb_mm(struct mm_struct *mm)
513{ 437{
514 unsigned long flags; 438 unsigned long flags;
439 unsigned int cpu = smp_processor_id();
515 440
516#if defined(CONFIG_SH64_PROC_TLB) 441 if (cpu_context(cpu, mm) == NO_CONTEXT)
517 ++calls_to_flush_tlb_mm;
518#endif
519
520 if (mm->context == NO_CONTEXT)
521 return; 442 return;
522 443
523 local_irq_save(flags); 444 local_irq_save(flags);
524 445
525 mm->context=NO_CONTEXT; 446 cpu_context(cpu, mm) = NO_CONTEXT;
526 if(mm==current->mm) 447 if (mm == current->mm)
527 activate_context(mm); 448 activate_context(mm, cpu);
528 449
529 local_irq_restore(flags); 450 local_irq_restore(flags);
530
531} 451}
532 452
533void flush_tlb_all(void) 453void local_flush_tlb_all(void)
534{ 454{
535 /* Invalidate all, including shared pages, excluding fixed TLBs */ 455 /* Invalidate all, including shared pages, excluding fixed TLBs */
536
537 unsigned long flags, tlb; 456 unsigned long flags, tlb;
538 457
539#if defined(CONFIG_SH64_PROC_TLB)
540 ++calls_to_flush_tlb_all;
541#endif
542
543 local_irq_save(flags); 458 local_irq_save(flags);
544 459
545 /* Flush each ITLB entry */ 460 /* Flush each ITLB entry */
546 for_each_itlb_entry(tlb) { 461 for_each_itlb_entry(tlb)
547 __flush_tlb_slot(tlb); 462 __flush_tlb_slot(tlb);
548 }
549 463
550 /* Flush each DTLB entry */ 464 /* Flush each DTLB entry */
551 for_each_dtlb_entry(tlb) { 465 for_each_dtlb_entry(tlb)
552 __flush_tlb_slot(tlb); 466 __flush_tlb_slot(tlb);
553 }
554 467
555 local_irq_restore(flags); 468 local_irq_restore(flags);
556} 469}
557 470
558void flush_tlb_kernel_range(unsigned long start, unsigned long end) 471void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
559{ 472{
560 /* FIXME: Optimize this later.. */ 473 /* FIXME: Optimize this later.. */
561 flush_tlb_all(); 474 flush_tlb_all();
562} 475}
563
564#if defined(CONFIG_SH64_PROC_TLB)
565/* Procfs interface to read the performance information */
566
567static int
568tlb_proc_info(char *buf, char **start, off_t fpos, int length, int *eof, void *data)
569{
570 int len=0;
571 len += sprintf(buf+len, "do_fast_page_fault called %12lld times\n", calls_to_do_fast_page_fault);
572 len += sprintf(buf+len, "do_slow_page_fault called %12lld times\n", calls_to_do_slow_page_fault);
573 len += sprintf(buf+len, "update_mmu_cache called %12lld times\n", calls_to_update_mmu_cache);
574 len += sprintf(buf+len, "flush_tlb_page called %12lld times\n", calls_to_flush_tlb_page);
575 len += sprintf(buf+len, "flush_tlb_range called %12lld times\n", calls_to_flush_tlb_range);
576 len += sprintf(buf+len, "flush_tlb_mm called %12lld times\n", calls_to_flush_tlb_mm);
577 len += sprintf(buf+len, "flush_tlb_all called %12lld times\n", calls_to_flush_tlb_all);
578 len += sprintf(buf+len, "flush_tlb_range_sizes\n"
579 " 1 : %12lld\n"
580 " 2 : %12lld\n"
581 " 3 - 4 : %12lld\n"
582 " 5 - 7 : %12lld\n"
583 " 8 - 11 : %12lld\n"
584 "12 - 15 : %12lld\n"
585 "16+ : %12lld\n",
586 flush_tlb_range_1, flush_tlb_range_2, flush_tlb_range_3_4,
587 flush_tlb_range_5_7, flush_tlb_range_8_11, flush_tlb_range_12_15,
588 flush_tlb_range_16_up);
589 len += sprintf(buf+len, "page not present %12lld times\n", page_not_present);
590 *eof = 1;
591 return len;
592}
593
594static int __init register_proc_tlb(void)
595{
596 create_proc_read_entry("tlb", 0, NULL, tlb_proc_info, NULL);
597 return 0;
598}
599
600__initcall(register_proc_tlb);
601
602#endif
diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types
index ff071693325c..25810670a0fa 100644
--- a/arch/sh/tools/mach-types
+++ b/arch/sh/tools/mach-types
@@ -29,7 +29,6 @@ HP6XX SH_HP6XX
29DREAMCAST SH_DREAMCAST 29DREAMCAST SH_DREAMCAST
30MPC1211 SH_MPC1211 30MPC1211 SH_MPC1211
31SNAPGEAR SH_SECUREEDGE5410 31SNAPGEAR SH_SECUREEDGE5410
32HS7751RVOIP SH_HS7751RVOIP
33EDOSK7705 SH_EDOSK7705 32EDOSK7705 SH_EDOSK7705
34SH4202_MICRODEV SH_SH4202_MICRODEV 33SH4202_MICRODEV SH_SH4202_MICRODEV
35SH03 SH_SH03 34SH03 SH_SH03
@@ -45,3 +44,4 @@ X3PROTO SH_X3PROTO
45MAGICPANELR2 SH_MAGIC_PANEL_R2 44MAGICPANELR2 SH_MAGIC_PANEL_R2
46R2D_PLUS RTS7751R2D_PLUS 45R2D_PLUS RTS7751R2D_PLUS
47R2D_1 RTS7751R2D_1 46R2D_1 RTS7751R2D_1
47CAYMAN SH_CAYMAN
diff --git a/arch/sh64/Kconfig b/arch/sh64/Kconfig
deleted file mode 100644
index 6884d5a518ad..000000000000
--- a/arch/sh64/Kconfig
+++ /dev/null
@@ -1,295 +0,0 @@
1#
2# For a description of the syntax of this configuration file,
3# see Documentation/kbuild/kconfig-language.txt.
4#
5
6mainmenu "Linux/SH64 Kernel Configuration"
7
8config SUPERH
9 bool
10 default y
11
12config SUPERH64
13 bool
14 default y
15
16config MMU
17 bool
18 default y
19
20config QUICKLIST
21 def_bool y
22
23config RWSEM_GENERIC_SPINLOCK
24 bool
25 default y
26
27config GENERIC_FIND_NEXT_BIT
28 bool
29 default y
30
31config GENERIC_HWEIGHT
32 bool
33 default y
34
35config GENERIC_CALIBRATE_DELAY
36 bool
37 default y
38
39config GENERIC_HARDIRQS
40 bool
41 default y
42
43config GENERIC_IRQ_PROBE
44 bool
45 default y
46
47config RWSEM_XCHGADD_ALGORITHM
48 bool
49
50config ARCH_HAS_ILOG2_U32
51 bool
52 default n
53
54config ARCH_HAS_ILOG2_U64
55 bool
56 default n
57
58config ARCH_NO_VIRT_TO_BUS
59 def_bool y
60
61source init/Kconfig
62
63menu "System type"
64
65choice
66 prompt "SuperH system type"
67 default SH_SIMULATOR
68
69config SH_SIMULATOR
70 bool "Simulator"
71
72config SH_CAYMAN
73 bool "Cayman"
74
75config SH_HARP
76 bool "ST50-Harp"
77
78endchoice
79
80choice
81 prompt "Processor family"
82 default CPU_SH5
83
84config CPU_SH5
85 bool "SH-5"
86
87endchoice
88
89choice
90 prompt "Processor type"
91
92config CPU_SUBTYPE_SH5_101
93 bool "SH5-101"
94 depends on CPU_SH5
95
96config CPU_SUBTYPE_SH5_103
97 bool "SH5-103"
98 depends on CPU_SH5
99
100endchoice
101
102choice
103 prompt "Endianness"
104 default LITTLE_ENDIAN
105
106config LITTLE_ENDIAN
107 bool "Little-Endian"
108
109config BIG_ENDIAN
110 bool "Big-Endian"
111
112endchoice
113
114config SH_FPU
115 bool "FPU support"
116 default y
117
118config SH64_FPU_DENORM_FLUSH
119 depends on SH_FPU
120 bool "Flush floating point denorms to zero"
121
122choice
123 prompt "Page table levels"
124 default SH64_PGTABLE_2_LEVEL
125
126config SH64_PGTABLE_2_LEVEL
127 bool "2"
128
129config SH64_PGTABLE_3_LEVEL
130 bool "3"
131
132endchoice
133
134choice
135 prompt "HugeTLB page size"
136 depends on HUGETLB_PAGE && MMU
137 default HUGETLB_PAGE_SIZE_64K
138
139config HUGETLB_PAGE_SIZE_64K
140 bool "64K"
141
142config HUGETLB_PAGE_SIZE_1MB
143 bool "1MB"
144
145config HUGETLB_PAGE_SIZE_512MB
146 bool "512MB"
147
148endchoice
149
150config SH64_USER_MISALIGNED_FIXUP
151 bool "Fixup misaligned loads/stores occurring in user mode"
152
153comment "Memory options"
154
155config CACHED_MEMORY_OFFSET
156 hex "Cached Area Offset"
157 default "20000000"
158
159config MEMORY_START
160 hex "Physical memory start address"
161 default "80000000"
162
163config MEMORY_SIZE_IN_MB
164 int "Memory size (in MB)"
165 default "8" if SH_SIMULATOR
166 default "64"
167
168comment "Cache options"
169
170choice
171 prompt "DCache mode"
172 default DCACHE_DISABLED if SH_SIMULATOR
173 default DCACHE_WRITE_BACK
174
175config DCACHE_WRITE_BACK
176 bool "Write-back"
177 depends on !SH_SIMULATOR
178
179config DCACHE_WRITE_THROUGH
180 bool "Write-through"
181 depends on !SH_SIMULATOR
182
183config DCACHE_DISABLED
184 bool "Disabled"
185
186endchoice
187
188config ICACHE_DISABLED
189 bool "ICache Disabling"
190
191config PCIDEVICE_MEMORY_START
192 hex
193 default "C0000000"
194
195config DEVICE_MEMORY_START
196 hex
197 default "E0000000"
198
199config FLASH_MEMORY_START
200 hex "Flash memory/on-chip devices start address"
201 default "00000000"
202
203config PCI_BLOCK_START
204 hex "PCI block start address"
205 default "40000000"
206
207comment "CPU Subtype specific options"
208
209config SH64_ID2815_WORKAROUND
210 bool "Include workaround for SH5-101 cut2 silicon defect ID2815"
211
212comment "Misc options"
213
214config HEARTBEAT
215 bool "Heartbeat LED"
216 depends on SH_CAYMAN
217
218config HDSP253_LED
219 bool "Support for HDSP-253 LED"
220 depends on SH_CAYMAN
221
222config SH_DMA
223 tristate "DMA controller (DMAC) support"
224
225config PREEMPT
226 bool "Preemptible Kernel (EXPERIMENTAL)"
227 depends on EXPERIMENTAL
228
229source "mm/Kconfig"
230
231endmenu
232
233menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)"
234
235config ISA
236 bool
237
238config SBUS
239 bool
240
241config PCI
242 bool "PCI support"
243 depends on SH_CAYMAN
244 help
245 Find out whether you have a PCI motherboard. PCI is the name of a
246 bus system, i.e. the way the CPU talks to the other stuff inside
247 your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
248 VESA. If you have PCI, say Y, otherwise N.
249
250 The PCI-HOWTO, available from
251 <http://www.tldp.org/docs.html#howto>, contains valuable
252 information about which PCI hardware does work under Linux and which
253 doesn't.
254
255config SH_PCIDMA_NONCOHERENT
256 bool "Cache and PCI noncoherent"
257 depends on PCI
258 default y
259 help
260 Enable this option if your platform does not have a CPU cache which
261 remains coherent with PCI DMA. It is safest to say 'Y', although you
262 will see better performance if you can say 'N', because the PCI DMA
263 code will not have to flush the CPU's caches. If you have a PCI host
264 bridge integrated with your SH CPU, refer carefully to the chip specs
265 to see if you can say 'N' here. Otherwise, leave it as 'Y'.
266
267source "drivers/pci/Kconfig"
268
269source "drivers/pcmcia/Kconfig"
270
271source "drivers/pci/hotplug/Kconfig"
272
273endmenu
274
275menu "Executable file formats"
276
277source "fs/Kconfig.binfmt"
278
279endmenu
280
281source "net/Kconfig"
282
283source "drivers/Kconfig"
284
285source "fs/Kconfig"
286
287source "kernel/Kconfig.instrumentation"
288
289source "arch/sh64/Kconfig.debug"
290
291source "security/Kconfig"
292
293source "crypto/Kconfig"
294
295source "lib/Kconfig"
diff --git a/arch/sh64/Kconfig.debug b/arch/sh64/Kconfig.debug
deleted file mode 100644
index 05c07c4e4ed6..000000000000
--- a/arch/sh64/Kconfig.debug
+++ /dev/null
@@ -1,33 +0,0 @@
1menu "Kernel hacking"
2
3source "lib/Kconfig.debug"
4
5config EARLY_PRINTK
6 bool "Early SCIF console support"
7
8config SH64_PROC_TLB
9 bool "Debug: report TLB fill/purge activity through /proc/tlb"
10 depends on PROC_FS
11
12config SH64_PROC_ASIDS
13 bool "Debug: report ASIDs through /proc/asids"
14 depends on PROC_FS
15
16config SH64_SR_WATCH
17 bool "Debug: set SR.WATCH to enable hardware watchpoints and trace"
18
19config POOR_MANS_STRACE
20 bool "Debug: enable rudimentary strace facility"
21 help
22 This option allows system calls to be traced to the console. It also
23 aids in detecting kernel stack underflow. It is useful for debugging
24 early-userland problems (e.g. init incurring fatal exceptions.)
25
26config SH_ALPHANUMERIC
27 bool "Enable debug outputs to on-board alphanumeric display"
28 depends on SH_CAYMAN
29
30config SH_NO_BSS_INIT
31 bool "Avoid zeroing BSS (to speed-up startup on suitable platforms)"
32
33endmenu
diff --git a/arch/sh64/Makefile b/arch/sh64/Makefile
deleted file mode 100644
index 8dac7e1a2be6..000000000000
--- a/arch/sh64/Makefile
+++ /dev/null
@@ -1,111 +0,0 @@
1#
2# This file is subject to the terms and conditions of the GNU General Public
3# License. See the file "COPYING" in the main directory of this archive
4# for more details.
5#
6# Copyright (C) 2000, 2001 Paolo Alberelli
7# Copyright (C) 2003, 2004 Paul Mundt
8#
9# This file is included by the global makefile so that you can add your own
10# architecture-specific flags and dependencies. Remember to do have actions
11# for "archclean" and "archdep" for cleaning up and making dependencies for
12# this architecture
13#
14
15cpu-y := -mb
16cpu-$(CONFIG_LITTLE_ENDIAN) := -ml
17
18cpu-$(CONFIG_CPU_SH5) += -m5-32media-nofpu
19
20ifdef CONFIG_LITTLE_ENDIAN
21LDFLAGS_vmlinux += --defsym 'jiffies=jiffies_64'
22LDFLAGS += -EL -mshlelf32_linux
23else
24LDFLAGS_vmlinux += --defsym 'jiffies=jiffies_64+4'
25LDFLAGS += -EB -mshelf32_linux
26endif
27
28# No requirements for endianess support from AFLAGS, 'as' always run through gcc
29KBUILD_CFLAGS += $(cpu-y)
30
31LDFLAGS_vmlinux += --defsym phys_stext=_stext-$(CONFIG_CACHED_MEMORY_OFFSET) \
32 --defsym phys_stext_shmedia=phys_stext+1 \
33 -e phys_stext_shmedia
34
35OBJCOPYFLAGS := -O binary -R .note -R .comment -R .stab -R .stabstr -S
36
37#
38# arch/sh64/defconfig never had any hope of being
39# frequently updated, so use one that does
40#
41KBUILD_DEFCONFIG := cayman_defconfig
42
43KBUILD_IMAGE := arch/$(ARCH)/boot/zImage
44
45ifdef LOADADDR
46LINKFLAGS += -Ttext $(word 1,$(LOADADDR))
47endif
48
49machine-$(CONFIG_SH_CAYMAN) := cayman
50machine-$(CONFIG_SH_SIMULATOR) := sim
51machine-$(CONFIG_SH_HARP) := harp
52
53head-y := arch/$(ARCH)/kernel/head.o arch/$(ARCH)/kernel/init_task.o
54
55core-y += arch/sh64/kernel/ arch/sh64/mm/
56
57ifneq ($(machine-y),)
58core-y += arch/sh64/mach-$(machine-y)/
59endif
60
61LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
62libs-y += arch/$(ARCH)/lib/ $(LIBGCC)
63
64drivers-$(CONFIG_OPROFILE) += arch/sh64/oprofile/
65
66boot := arch/$(ARCH)/boot
67
68zImage: vmlinux
69 $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
70
71compressed: zImage
72
73archclean:
74 $(Q)$(MAKE) $(clean)=$(boot)
75
76archprepare: arch/$(ARCH)/lib/syscalltab.h
77
78define filechk_gen-syscalltab
79 (set -e; \
80 echo "/*"; \
81 echo " * DO NOT MODIFY."; \
82 echo " *"; \
83 echo " * This file was generated by arch/$(ARCH)/Makefile"; \
84 echo " * Any changes will be reverted at build time."; \
85 echo " */"; \
86 echo ""; \
87 echo "#ifndef __SYSCALLTAB_H"; \
88 echo "#define __SYSCALLTAB_H"; \
89 echo ""; \
90 echo "#include <linux/kernel.h>"; \
91 echo ""; \
92 echo "struct syscall_info {"; \
93 echo " const char *name;"; \
94 echo "} syscall_info_table[] = {"; \
95 sed -e '/^.*\.long /!d;s// { "/;s/\(\([^/]*\)\/\)\{1\}.*/\2/; \
96 s/[ \t]*$$//g;s/$$/" },/;s/\("\)sys_/\1/g'; \
97 echo "};"; \
98 echo ""; \
99 echo "#define NUM_SYSCALL_INFO_ENTRIES ARRAY_SIZE(syscall_info_table)"; \
100 echo ""; \
101 echo "#endif /* __SYSCALLTAB_H */" )
102endef
103
104arch/$(ARCH)/lib/syscalltab.h: arch/sh64/kernel/syscalls.S
105 $(call filechk,gen-syscalltab)
106
107CLEAN_FILES += arch/$(ARCH)/lib/syscalltab.h
108
109define archhelp
110 @echo '* zImage - Compressed kernel image'
111endef
diff --git a/arch/sh64/boot/Makefile b/arch/sh64/boot/Makefile
deleted file mode 100644
index fb71087b7b8a..000000000000
--- a/arch/sh64/boot/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
1#
2# arch/sh64/boot/Makefile
3#
4# This file is subject to the terms and conditions of the GNU General Public
5# License. See the file "COPYING" in the main directory of this archive
6# for more details.
7#
8# Copyright (C) 2002 Stuart Menefy
9#
10
11targets := zImage
12subdir- := compressed
13
14$(obj)/zImage: $(obj)/compressed/vmlinux FORCE
15 $(call if_changed,objcopy)
16 @echo 'Kernel: $@ is ready'
17
18$(obj)/compressed/vmlinux: FORCE
19 $(Q)$(MAKE) $(build)=$(obj)/compressed $@
20
diff --git a/arch/sh64/boot/compressed/cache.c b/arch/sh64/boot/compressed/cache.c
deleted file mode 100644
index 708707355ffa..000000000000
--- a/arch/sh64/boot/compressed/cache.c
+++ /dev/null
@@ -1,39 +0,0 @@
1/*
2 * arch/shmedia/boot/compressed/cache.c -- simple cache management functions
3 *
4 * Code extracted from sh-ipl+g, sh-stub.c, which has the copyright:
5 *
6 * This is originally based on an m68k software stub written by Glenn
7 * Engel at HP, but has changed quite a bit.
8 *
9 * Modifications for the SH by Ben Lee and Steve Chamberlain
10 *
11****************************************************************************
12
13 THIS SOFTWARE IS NOT COPYRIGHTED
14
15 HP offers the following for use in the public domain. HP makes no
16 warranty with regard to the software or it's performance and the
17 user accepts the software "AS IS" with all faults.
18
19 HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
20 TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
21 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22
23****************************************************************************/
24
25#define CACHE_ENABLE 0
26#define CACHE_DISABLE 1
27
28int cache_control(unsigned int command)
29{
30 volatile unsigned int *p = (volatile unsigned int *) 0x80000000;
31 int i;
32
33 for (i = 0; i < (32 * 1024); i += 32) {
34 (void *) *p;
35 p += (32 / sizeof (int));
36 }
37
38 return 0;
39}
diff --git a/arch/sh64/boot/compressed/install.sh b/arch/sh64/boot/compressed/install.sh
deleted file mode 100644
index 90589f0fec12..000000000000
--- a/arch/sh64/boot/compressed/install.sh
+++ /dev/null
@@ -1,56 +0,0 @@
1#!/bin/sh
2#
3# arch/sh/boot/install.sh
4#
5# 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
7# for more details.
8#
9# Copyright (C) 1995 by Linus Torvalds
10#
11# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
12# Adapted from code in arch/i386/boot/install.sh by Russell King
13# Adapted from code in arch/arm/boot/install.sh by Stuart Menefy
14#
15# "make install" script for sh architecture
16#
17# Arguments:
18# $1 - kernel version
19# $2 - kernel image file
20# $3 - kernel map file
21# $4 - default install path (blank if root directory)
22#
23
24# User may have a custom install script
25
26if [ -x /sbin/installkernel ]; then
27 exec /sbin/installkernel "$@"
28fi
29
30if [ "$2" = "zImage" ]; then
31# Compressed install
32 echo "Installing compressed kernel"
33 if [ -f $4/vmlinuz-$1 ]; then
34 mv $4/vmlinuz-$1 $4/vmlinuz.old
35 fi
36
37 if [ -f $4/System.map-$1 ]; then
38 mv $4/System.map-$1 $4/System.old
39 fi
40
41 cat $2 > $4/vmlinuz-$1
42 cp $3 $4/System.map-$1
43else
44# Normal install
45 echo "Installing normal kernel"
46 if [ -f $4/vmlinux-$1 ]; then
47 mv $4/vmlinux-$1 $4/vmlinux.old
48 fi
49
50 if [ -f $4/System.map ]; then
51 mv $4/System.map $4/System.old
52 fi
53
54 cat $2 > $4/vmlinux-$1
55 cp $3 $4/System.map
56fi
diff --git a/arch/sh64/configs/sim_defconfig b/arch/sh64/configs/sim_defconfig
deleted file mode 100644
index 18476cc522c3..000000000000
--- a/arch/sh64/configs/sim_defconfig
+++ /dev/null
@@ -1,558 +0,0 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.24-rc1
4# Fri Nov 2 14:36:08 2007
5#
6CONFIG_SUPERH=y
7CONFIG_SUPERH64=y
8CONFIG_MMU=y
9CONFIG_QUICKLIST=y
10CONFIG_RWSEM_GENERIC_SPINLOCK=y
11CONFIG_GENERIC_FIND_NEXT_BIT=y
12CONFIG_GENERIC_HWEIGHT=y
13CONFIG_GENERIC_CALIBRATE_DELAY=y
14CONFIG_GENERIC_HARDIRQS=y
15CONFIG_GENERIC_IRQ_PROBE=y
16# CONFIG_ARCH_HAS_ILOG2_U32 is not set
17# CONFIG_ARCH_HAS_ILOG2_U64 is not set
18CONFIG_ARCH_NO_VIRT_TO_BUS=y
19CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
20
21#
22# General setup
23#
24CONFIG_EXPERIMENTAL=y
25CONFIG_BROKEN_ON_SMP=y
26CONFIG_LOCK_KERNEL=y
27CONFIG_INIT_ENV_ARG_LIMIT=32
28CONFIG_LOCALVERSION=""
29CONFIG_LOCALVERSION_AUTO=y
30CONFIG_SWAP=y
31# CONFIG_SYSVIPC is not set
32# CONFIG_BSD_PROCESS_ACCT is not set
33# CONFIG_USER_NS is not set
34# CONFIG_IKCONFIG is not set
35CONFIG_LOG_BUF_SHIFT=14
36# CONFIG_CGROUPS is not set
37CONFIG_FAIR_GROUP_SCHED=y
38CONFIG_FAIR_USER_SCHED=y
39# CONFIG_FAIR_CGROUP_SCHED is not set
40CONFIG_SYSFS_DEPRECATED=y
41# CONFIG_RELAY is not set
42# CONFIG_BLK_DEV_INITRD is not set
43# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
44CONFIG_SYSCTL=y
45# CONFIG_EMBEDDED is not set
46CONFIG_UID16=y
47CONFIG_SYSCTL_SYSCALL=y
48CONFIG_KALLSYMS=y
49# CONFIG_KALLSYMS_ALL is not set
50# CONFIG_KALLSYMS_EXTRA_PASS is not set
51CONFIG_HOTPLUG=y
52CONFIG_PRINTK=y
53CONFIG_BUG=y
54CONFIG_ELF_CORE=y
55CONFIG_BASE_FULL=y
56CONFIG_FUTEX=y
57CONFIG_ANON_INODES=y
58CONFIG_EPOLL=y
59CONFIG_SIGNALFD=y
60CONFIG_EVENTFD=y
61CONFIG_SHMEM=y
62CONFIG_VM_EVENT_COUNTERS=y
63CONFIG_SLAB=y
64# CONFIG_SLUB is not set
65# CONFIG_SLOB is not set
66CONFIG_RT_MUTEXES=y
67# CONFIG_TINY_SHMEM is not set
68CONFIG_BASE_SMALL=0
69# CONFIG_MODULES is not set
70CONFIG_BLOCK=y
71# CONFIG_LBD is not set
72# CONFIG_BLK_DEV_IO_TRACE is not set
73# CONFIG_LSF is not set
74# CONFIG_BLK_DEV_BSG is not set
75
76#
77# IO Schedulers
78#
79CONFIG_IOSCHED_NOOP=y
80CONFIG_IOSCHED_AS=y
81CONFIG_IOSCHED_DEADLINE=y
82CONFIG_IOSCHED_CFQ=y
83# CONFIG_DEFAULT_AS is not set
84# CONFIG_DEFAULT_DEADLINE is not set
85CONFIG_DEFAULT_CFQ=y
86# CONFIG_DEFAULT_NOOP is not set
87CONFIG_DEFAULT_IOSCHED="cfq"
88
89#
90# System type
91#
92CONFIG_SH_SIMULATOR=y
93# CONFIG_SH_CAYMAN is not set
94# CONFIG_SH_HARP is not set
95CONFIG_CPU_SH5=y
96CONFIG_CPU_SUBTYPE_SH5_101=y
97# CONFIG_CPU_SUBTYPE_SH5_103 is not set
98CONFIG_LITTLE_ENDIAN=y
99# CONFIG_BIG_ENDIAN is not set
100CONFIG_SH_FPU=y
101# CONFIG_SH64_FPU_DENORM_FLUSH is not set
102CONFIG_SH64_PGTABLE_2_LEVEL=y
103# CONFIG_SH64_PGTABLE_3_LEVEL is not set
104CONFIG_HUGETLB_PAGE_SIZE_64K=y
105# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
106# CONFIG_HUGETLB_PAGE_SIZE_512MB is not set
107CONFIG_SH64_USER_MISALIGNED_FIXUP=y
108
109#
110# Memory options
111#
112CONFIG_CACHED_MEMORY_OFFSET=0x20000000
113CONFIG_MEMORY_START=0x80000000
114CONFIG_MEMORY_SIZE_IN_MB=128
115
116#
117# Cache options
118#
119# CONFIG_DCACHE_WRITE_BACK is not set
120# CONFIG_DCACHE_WRITE_THROUGH is not set
121CONFIG_DCACHE_DISABLED=y
122# CONFIG_ICACHE_DISABLED is not set
123CONFIG_PCIDEVICE_MEMORY_START=C0000000
124CONFIG_DEVICE_MEMORY_START=E0000000
125CONFIG_FLASH_MEMORY_START=0x00000000
126CONFIG_PCI_BLOCK_START=0x40000000
127
128#
129# CPU Subtype specific options
130#
131CONFIG_SH64_ID2815_WORKAROUND=y
132
133#
134# Misc options
135#
136# CONFIG_SH_DMA is not set
137CONFIG_PREEMPT=y
138CONFIG_SELECT_MEMORY_MODEL=y
139CONFIG_FLATMEM_MANUAL=y
140# CONFIG_DISCONTIGMEM_MANUAL is not set
141# CONFIG_SPARSEMEM_MANUAL is not set
142CONFIG_FLATMEM=y
143CONFIG_FLAT_NODE_MEM_MAP=y
144# CONFIG_SPARSEMEM_STATIC is not set
145# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
146CONFIG_SPLIT_PTLOCK_CPUS=4
147# CONFIG_RESOURCES_64BIT is not set
148CONFIG_ZONE_DMA_FLAG=0
149CONFIG_NR_QUICK=1
150
151#
152# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
153#
154# CONFIG_ARCH_SUPPORTS_MSI is not set
155# CONFIG_PCCARD is not set
156
157#
158# Executable file formats
159#
160CONFIG_BINFMT_ELF=y
161# CONFIG_BINFMT_MISC is not set
162
163#
164# Networking
165#
166# CONFIG_NET is not set
167
168#
169# Device Drivers
170#
171
172#
173# Generic Driver Options
174#
175CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
176CONFIG_STANDALONE=y
177CONFIG_PREVENT_FIRMWARE_BUILD=y
178# CONFIG_FW_LOADER is not set
179# CONFIG_DEBUG_DRIVER is not set
180# CONFIG_DEBUG_DEVRES is not set
181# CONFIG_SYS_HYPERVISOR is not set
182# CONFIG_MTD is not set
183# CONFIG_PARPORT is not set
184# CONFIG_BLK_DEV is not set
185# CONFIG_MISC_DEVICES is not set
186# CONFIG_IDE is not set
187
188#
189# SCSI device support
190#
191# CONFIG_RAID_ATTRS is not set
192CONFIG_SCSI=y
193CONFIG_SCSI_DMA=y
194# CONFIG_SCSI_TGT is not set
195# CONFIG_SCSI_NETLINK is not set
196CONFIG_SCSI_PROC_FS=y
197
198#
199# SCSI support type (disk, tape, CD-ROM)
200#
201CONFIG_BLK_DEV_SD=y
202# CONFIG_CHR_DEV_ST is not set
203# CONFIG_CHR_DEV_OSST is not set
204# CONFIG_BLK_DEV_SR is not set
205# CONFIG_CHR_DEV_SG is not set
206# CONFIG_CHR_DEV_SCH is not set
207
208#
209# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
210#
211CONFIG_SCSI_MULTI_LUN=y
212# CONFIG_SCSI_CONSTANTS is not set
213# CONFIG_SCSI_LOGGING is not set
214# CONFIG_SCSI_SCAN_ASYNC is not set
215
216#
217# SCSI Transports
218#
219CONFIG_SCSI_SPI_ATTRS=y
220# CONFIG_SCSI_FC_ATTRS is not set
221# CONFIG_SCSI_SAS_LIBSAS is not set
222# CONFIG_SCSI_SRP_ATTRS is not set
223CONFIG_SCSI_LOWLEVEL=y
224# CONFIG_SCSI_DEBUG is not set
225# CONFIG_ATA is not set
226# CONFIG_MD is not set
227# CONFIG_PHONE is not set
228
229#
230# Input device support
231#
232CONFIG_INPUT=y
233# CONFIG_INPUT_FF_MEMLESS is not set
234# CONFIG_INPUT_POLLDEV is not set
235
236#
237# Userland interfaces
238#
239CONFIG_INPUT_MOUSEDEV=y
240# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
241CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
242CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
243# CONFIG_INPUT_JOYDEV is not set
244# CONFIG_INPUT_EVDEV is not set
245# CONFIG_INPUT_EVBUG is not set
246
247#
248# Input Device Drivers
249#
250# CONFIG_INPUT_KEYBOARD is not set
251# CONFIG_INPUT_MOUSE is not set
252# CONFIG_INPUT_JOYSTICK is not set
253# CONFIG_INPUT_TABLET is not set
254# CONFIG_INPUT_TOUCHSCREEN is not set
255# CONFIG_INPUT_MISC is not set
256
257#
258# Hardware I/O ports
259#
260# CONFIG_SERIO is not set
261# CONFIG_GAMEPORT is not set
262
263#
264# Character devices
265#
266CONFIG_VT=y
267CONFIG_VT_CONSOLE=y
268CONFIG_HW_CONSOLE=y
269# CONFIG_VT_HW_CONSOLE_BINDING is not set
270# CONFIG_SERIAL_NONSTANDARD is not set
271
272#
273# Serial drivers
274#
275# CONFIG_SERIAL_8250 is not set
276
277#
278# Non-8250 serial port support
279#
280CONFIG_SERIAL_SH_SCI=y
281CONFIG_SERIAL_SH_SCI_NR_UARTS=2
282CONFIG_SERIAL_SH_SCI_CONSOLE=y
283CONFIG_SERIAL_CORE=y
284CONFIG_SERIAL_CORE_CONSOLE=y
285CONFIG_UNIX98_PTYS=y
286# CONFIG_LEGACY_PTYS is not set
287# CONFIG_IPMI_HANDLER is not set
288# CONFIG_HW_RANDOM is not set
289# CONFIG_R3964 is not set
290# CONFIG_RAW_DRIVER is not set
291# CONFIG_TCG_TPM is not set
292# CONFIG_I2C is not set
293
294#
295# SPI support
296#
297# CONFIG_SPI is not set
298# CONFIG_SPI_MASTER is not set
299# CONFIG_W1 is not set
300# CONFIG_POWER_SUPPLY is not set
301# CONFIG_HWMON is not set
302# CONFIG_WATCHDOG is not set
303
304#
305# Sonics Silicon Backplane
306#
307CONFIG_SSB_POSSIBLE=y
308# CONFIG_SSB is not set
309
310#
311# Multifunction device drivers
312#
313# CONFIG_MFD_SM501 is not set
314
315#
316# Multimedia devices
317#
318# CONFIG_VIDEO_DEV is not set
319CONFIG_DAB=y
320
321#
322# Graphics support
323#
324# CONFIG_VGASTATE is not set
325CONFIG_VIDEO_OUTPUT_CONTROL=y
326CONFIG_FB=y
327CONFIG_FIRMWARE_EDID=y
328# CONFIG_FB_DDC is not set
329# CONFIG_FB_CFB_FILLRECT is not set
330# CONFIG_FB_CFB_COPYAREA is not set
331# CONFIG_FB_CFB_IMAGEBLIT is not set
332# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
333# CONFIG_FB_SYS_FILLRECT is not set
334# CONFIG_FB_SYS_COPYAREA is not set
335# CONFIG_FB_SYS_IMAGEBLIT is not set
336# CONFIG_FB_SYS_FOPS is not set
337CONFIG_FB_DEFERRED_IO=y
338# CONFIG_FB_SVGALIB is not set
339# CONFIG_FB_MACMODES is not set
340# CONFIG_FB_BACKLIGHT is not set
341CONFIG_FB_MODE_HELPERS=y
342# CONFIG_FB_TILEBLITTING is not set
343
344#
345# Frame buffer hardware drivers
346#
347# CONFIG_FB_S1D13XXX is not set
348# CONFIG_FB_VIRTUAL is not set
349# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
350
351#
352# Display device support
353#
354# CONFIG_DISPLAY_SUPPORT is not set
355
356#
357# Console display driver support
358#
359CONFIG_DUMMY_CONSOLE=y
360CONFIG_FRAMEBUFFER_CONSOLE=y
361# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
362# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
363CONFIG_FONTS=y
364# CONFIG_FONT_8x8 is not set
365CONFIG_FONT_8x16=y
366# CONFIG_FONT_6x11 is not set
367# CONFIG_FONT_7x14 is not set
368# CONFIG_FONT_PEARL_8x8 is not set
369# CONFIG_FONT_ACORN_8x8 is not set
370# CONFIG_FONT_MINI_4x6 is not set
371# CONFIG_FONT_SUN8x16 is not set
372# CONFIG_FONT_SUN12x22 is not set
373# CONFIG_FONT_10x18 is not set
374CONFIG_LOGO=y
375# CONFIG_LOGO_LINUX_MONO is not set
376# CONFIG_LOGO_LINUX_VGA16 is not set
377# CONFIG_LOGO_LINUX_CLUT224 is not set
378# CONFIG_LOGO_SUPERH_MONO is not set
379# CONFIG_LOGO_SUPERH_VGA16 is not set
380CONFIG_LOGO_SUPERH_CLUT224=y
381
382#
383# Sound
384#
385# CONFIG_SOUND is not set
386# CONFIG_HID_SUPPORT is not set
387# CONFIG_USB_SUPPORT is not set
388# CONFIG_MMC is not set
389# CONFIG_NEW_LEDS is not set
390# CONFIG_RTC_CLASS is not set
391
392#
393# Userspace I/O
394#
395# CONFIG_UIO is not set
396
397#
398# File systems
399#
400CONFIG_EXT2_FS=y
401# CONFIG_EXT2_FS_XATTR is not set
402# CONFIG_EXT2_FS_XIP is not set
403CONFIG_EXT3_FS=y
404CONFIG_EXT3_FS_XATTR=y
405# CONFIG_EXT3_FS_POSIX_ACL is not set
406# CONFIG_EXT3_FS_SECURITY is not set
407# CONFIG_EXT4DEV_FS is not set
408CONFIG_JBD=y
409# CONFIG_JBD_DEBUG is not set
410CONFIG_FS_MBCACHE=y
411# CONFIG_REISERFS_FS is not set
412# CONFIG_JFS_FS is not set
413# CONFIG_FS_POSIX_ACL is not set
414# CONFIG_XFS_FS is not set
415# CONFIG_GFS2_FS is not set
416CONFIG_MINIX_FS=y
417CONFIG_ROMFS_FS=y
418CONFIG_INOTIFY=y
419CONFIG_INOTIFY_USER=y
420# CONFIG_QUOTA is not set
421CONFIG_DNOTIFY=y
422# CONFIG_AUTOFS_FS is not set
423# CONFIG_AUTOFS4_FS is not set
424# CONFIG_FUSE_FS is not set
425
426#
427# CD-ROM/DVD Filesystems
428#
429# CONFIG_ISO9660_FS is not set
430# CONFIG_UDF_FS is not set
431
432#
433# DOS/FAT/NT Filesystems
434#
435# CONFIG_MSDOS_FS is not set
436# CONFIG_VFAT_FS is not set
437# CONFIG_NTFS_FS is not set
438
439#
440# Pseudo filesystems
441#
442CONFIG_PROC_FS=y
443CONFIG_PROC_KCORE=y
444CONFIG_PROC_SYSCTL=y
445CONFIG_SYSFS=y
446CONFIG_TMPFS=y
447# CONFIG_TMPFS_POSIX_ACL is not set
448CONFIG_HUGETLBFS=y
449CONFIG_HUGETLB_PAGE=y
450# CONFIG_CONFIGFS_FS is not set
451
452#
453# Miscellaneous filesystems
454#
455# CONFIG_ADFS_FS is not set
456# CONFIG_AFFS_FS is not set
457# CONFIG_HFS_FS is not set
458# CONFIG_HFSPLUS_FS is not set
459# CONFIG_BEFS_FS is not set
460# CONFIG_BFS_FS is not set
461# CONFIG_EFS_FS is not set
462# CONFIG_CRAMFS is not set
463# CONFIG_VXFS_FS is not set
464# CONFIG_HPFS_FS is not set
465# CONFIG_QNX4FS_FS is not set
466# CONFIG_SYSV_FS is not set
467# CONFIG_UFS_FS is not set
468
469#
470# Partition Types
471#
472CONFIG_PARTITION_ADVANCED=y
473# CONFIG_ACORN_PARTITION is not set
474# CONFIG_OSF_PARTITION is not set
475# CONFIG_AMIGA_PARTITION is not set
476# CONFIG_ATARI_PARTITION is not set
477# CONFIG_MAC_PARTITION is not set
478CONFIG_MSDOS_PARTITION=y
479# CONFIG_BSD_DISKLABEL is not set
480# CONFIG_MINIX_SUBPARTITION is not set
481# CONFIG_SOLARIS_X86_PARTITION is not set
482# CONFIG_UNIXWARE_DISKLABEL is not set
483# CONFIG_LDM_PARTITION is not set
484# CONFIG_SGI_PARTITION is not set
485# CONFIG_ULTRIX_PARTITION is not set
486# CONFIG_SUN_PARTITION is not set
487# CONFIG_KARMA_PARTITION is not set
488# CONFIG_EFI_PARTITION is not set
489# CONFIG_SYSV68_PARTITION is not set
490# CONFIG_NLS is not set
491CONFIG_INSTRUMENTATION=y
492CONFIG_PROFILING=y
493# CONFIG_OPROFILE is not set
494# CONFIG_MARKERS is not set
495
496#
497# Kernel hacking
498#
499# CONFIG_PRINTK_TIME is not set
500CONFIG_ENABLE_WARN_DEPRECATED=y
501CONFIG_ENABLE_MUST_CHECK=y
502CONFIG_MAGIC_SYSRQ=y
503# CONFIG_UNUSED_SYMBOLS is not set
504CONFIG_DEBUG_FS=y
505# CONFIG_HEADERS_CHECK is not set
506CONFIG_DEBUG_KERNEL=y
507# CONFIG_DEBUG_SHIRQ is not set
508CONFIG_DETECT_SOFTLOCKUP=y
509CONFIG_SCHED_DEBUG=y
510CONFIG_SCHEDSTATS=y
511# CONFIG_TIMER_STATS is not set
512# CONFIG_DEBUG_SLAB is not set
513# CONFIG_DEBUG_RT_MUTEXES is not set
514# CONFIG_RT_MUTEX_TESTER is not set
515# CONFIG_DEBUG_SPINLOCK is not set
516# CONFIG_DEBUG_MUTEXES is not set
517# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
518# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
519# CONFIG_DEBUG_KOBJECT is not set
520CONFIG_DEBUG_BUGVERBOSE=y
521# CONFIG_DEBUG_INFO is not set
522# CONFIG_DEBUG_VM is not set
523# CONFIG_DEBUG_LIST is not set
524# CONFIG_DEBUG_SG is not set
525CONFIG_FRAME_POINTER=y
526CONFIG_FORCED_INLINING=y
527# CONFIG_BOOT_PRINTK_DELAY is not set
528# CONFIG_FAULT_INJECTION is not set
529# CONFIG_SAMPLES is not set
530# CONFIG_EARLY_PRINTK is not set
531CONFIG_SH64_PROC_TLB=y
532CONFIG_SH64_PROC_ASIDS=y
533CONFIG_SH64_SR_WATCH=y
534# CONFIG_POOR_MANS_STRACE is not set
535CONFIG_SH_NO_BSS_INIT=y
536
537#
538# Security options
539#
540# CONFIG_KEYS is not set
541# CONFIG_SECURITY is not set
542# CONFIG_SECURITY_FILE_CAPABILITIES is not set
543# CONFIG_CRYPTO is not set
544
545#
546# Library routines
547#
548CONFIG_BITREVERSE=y
549# CONFIG_CRC_CCITT is not set
550# CONFIG_CRC16 is not set
551# CONFIG_CRC_ITU_T is not set
552CONFIG_CRC32=y
553# CONFIG_CRC7 is not set
554# CONFIG_LIBCRC32C is not set
555CONFIG_PLIST=y
556CONFIG_HAS_IOMEM=y
557CONFIG_HAS_IOPORT=y
558CONFIG_HAS_DMA=y
diff --git a/arch/sh64/kernel/Makefile b/arch/sh64/kernel/Makefile
deleted file mode 100644
index e3467bda6167..000000000000
--- a/arch/sh64/kernel/Makefile
+++ /dev/null
@@ -1,36 +0,0 @@
1#
2# This file is subject to the terms and conditions of the GNU General Public
3# License. See the file "COPYING" in the main directory of this archive
4# for more details.
5#
6# Copyright (C) 2000, 2001 Paolo Alberelli
7# Copyright (C) 2003 Paul Mundt
8#
9# Makefile for the Linux sh64 kernel.
10#
11# Note! Dependencies are done automagically by 'make dep', which also
12# removes any old dependencies. DON'T put your own dependencies here
13# unless it's something special (ie not a .c file).
14#
15
16extra-y := head.o init_task.o vmlinux.lds
17
18obj-y := process.o signal.o entry.o traps.o irq.o irq_intc.o \
19 ptrace.o setup.o time.o sys_sh64.o semaphore.o sh_ksyms.o \
20 switchto.o syscalls.o
21
22obj-$(CONFIG_HEARTBEAT) += led.o
23obj-$(CONFIG_SH_ALPHANUMERIC) += alphanum.o
24obj-$(CONFIG_SH_DMA) += dma.o
25obj-$(CONFIG_SH_FPU) += fpu.o
26obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
27obj-$(CONFIG_KALLSYMS) += unwind.o
28obj-$(CONFIG_PCI) += pcibios.o
29obj-$(CONFIG_MODULES) += module.o
30
31ifeq ($(CONFIG_PCI),y)
32obj-$(CONFIG_CPU_SH5) += pci_sh5.o
33endif
34
35USE_STANDARD_AS_RULE := true
36
diff --git a/arch/sh64/kernel/alphanum.c b/arch/sh64/kernel/alphanum.c
deleted file mode 100644
index d1619d95fbaa..000000000000
--- a/arch/sh64/kernel/alphanum.c
+++ /dev/null
@@ -1,43 +0,0 @@
1/*
2 * arch/sh64/kernel/alphanum.c
3 *
4 * Copyright (C) 2002 Stuart Menefy <stuart.menefy@st.com>
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * Machine-independent functions for handling 8-digit alphanumeric display
10 * (e.g. Agilent HDSP-253x)
11 */
12#include <linux/stddef.h>
13#include <linux/sched.h>
14
15void mach_alphanum(int pos, unsigned char val);
16
17void print_seg(char *file, int line)
18{
19 int i;
20 unsigned int nibble;
21
22 for (i = 0; i < 5; i++) {
23 mach_alphanum(i, file[i]);
24 }
25
26 for (i = 0; i < 3; i++) {
27 nibble = ((line >> (i * 4)) & 0xf);
28 mach_alphanum(7 - i, nibble + ((nibble > 9) ? 55 : 48));
29 }
30}
31
32void print_seg_num(unsigned num)
33{
34 int i;
35 unsigned int nibble;
36
37 for (i = 0; i < 8; i++) {
38 nibble = ((num >> (i * 4)) & 0xf);
39
40 mach_alphanum(7 - i, nibble + ((nibble > 9) ? 55 : 48));
41 }
42}
43
diff --git a/arch/sh64/kernel/asm-offsets.c b/arch/sh64/kernel/asm-offsets.c
deleted file mode 100644
index ca76537c16c0..000000000000
--- a/arch/sh64/kernel/asm-offsets.c
+++ /dev/null
@@ -1,33 +0,0 @@
1/*
2 * This program is used to generate definitions needed by
3 * assembly language modules.
4 *
5 * We use the technique used in the OSF Mach kernel code:
6 * generate asm statements containing #defines,
7 * compile this file to assembler, and then extract the
8 * #defines from the assembly-language output.
9 */
10
11#include <linux/stddef.h>
12#include <linux/types.h>
13#include <linux/mm.h>
14#include <asm/thread_info.h>
15
16#define DEFINE(sym, val) \
17 asm volatile("\n->" #sym " %0 " #val : : "i" (val))
18
19#define BLANK() asm volatile("\n->" : : )
20
21int main(void)
22{
23 /* offsets into the thread_info struct */
24 DEFINE(TI_TASK, offsetof(struct thread_info, task));
25 DEFINE(TI_EXEC_DOMAIN, offsetof(struct thread_info, exec_domain));
26 DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
27 DEFINE(TI_PRE_COUNT, offsetof(struct thread_info, preempt_count));
28 DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
29 DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit));
30 DEFINE(TI_RESTART_BLOCK,offsetof(struct thread_info, restart_block));
31
32 return 0;
33}
diff --git a/arch/sh64/kernel/dma.c b/arch/sh64/kernel/dma.c
deleted file mode 100644
index 32c6f0549bf1..000000000000
--- a/arch/sh64/kernel/dma.c
+++ /dev/null
@@ -1,297 +0,0 @@
1/*
2 * arch/sh64/kernel/dma.c
3 *
4 * DMA routines for the SH-5 DMAC.
5 *
6 * Copyright (C) 2003 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/init.h>
13#include <linux/module.h>
14#include <linux/interrupt.h>
15#include <linux/types.h>
16#include <linux/irq.h>
17#include <linux/spinlock.h>
18#include <linux/mm.h>
19#include <asm/hardware.h>
20#include <asm/dma.h>
21#include <asm/signal.h>
22#include <asm/errno.h>
23#include <asm/io.h>
24
25typedef struct {
26 unsigned long dev_addr;
27 unsigned long mem_addr;
28
29 unsigned int mode;
30 unsigned int count;
31} dma_info_t;
32
33static dma_info_t dma_info[MAX_DMA_CHANNELS];
34static DEFINE_SPINLOCK(dma_spin_lock);
35
36/* arch/sh64/kernel/irq_intc.c */
37extern void make_intc_irq(unsigned int irq);
38
39/* DMAC Interrupts */
40#define DMA_IRQ_DMTE0 18
41#define DMA_IRQ_DERR 22
42
43#define DMAC_COMMON_BASE (dmac_base + 0x08)
44#define DMAC_SAR_BASE (dmac_base + 0x10)
45#define DMAC_DAR_BASE (dmac_base + 0x18)
46#define DMAC_COUNT_BASE (dmac_base + 0x20)
47#define DMAC_CTRL_BASE (dmac_base + 0x28)
48#define DMAC_STATUS_BASE (dmac_base + 0x30)
49
50#define DMAC_SAR(n) (DMAC_SAR_BASE + ((n) * 0x28))
51#define DMAC_DAR(n) (DMAC_DAR_BASE + ((n) * 0x28))
52#define DMAC_COUNT(n) (DMAC_COUNT_BASE + ((n) * 0x28))
53#define DMAC_CTRL(n) (DMAC_CTRL_BASE + ((n) * 0x28))
54#define DMAC_STATUS(n) (DMAC_STATUS_BASE + ((n) * 0x28))
55
56/* DMAC.COMMON Bit Definitions */
57#define DMAC_COMMON_PR 0x00000001 /* Priority */
58 /* Bits 1-2 Reserved */
59#define DMAC_COMMON_ME 0x00000008 /* Master Enable */
60#define DMAC_COMMON_NMI 0x00000010 /* NMI Flag */
61 /* Bits 5-6 Reserved */
62#define DMAC_COMMON_ER 0x00000780 /* Error Response */
63#define DMAC_COMMON_AAE 0x00007800 /* Address Alignment Error */
64 /* Bits 15-63 Reserved */
65
66/* DMAC.SAR Bit Definitions */
67#define DMAC_SAR_ADDR 0xffffffff /* Source Address */
68
69/* DMAC.DAR Bit Definitions */
70#define DMAC_DAR_ADDR 0xffffffff /* Destination Address */
71
72/* DMAC.COUNT Bit Definitions */
73#define DMAC_COUNT_CNT 0xffffffff /* Transfer Count */
74
75/* DMAC.CTRL Bit Definitions */
76#define DMAC_CTRL_TS 0x00000007 /* Transfer Size */
77#define DMAC_CTRL_SI 0x00000018 /* Source Increment */
78#define DMAC_CTRL_DI 0x00000060 /* Destination Increment */
79#define DMAC_CTRL_RS 0x00000780 /* Resource Select */
80#define DMAC_CTRL_IE 0x00000800 /* Interrupt Enable */
81#define DMAC_CTRL_TE 0x00001000 /* Transfer Enable */
82 /* Bits 15-63 Reserved */
83
84/* DMAC.STATUS Bit Definitions */
85#define DMAC_STATUS_TE 0x00000001 /* Transfer End */
86#define DMAC_STATUS_AAE 0x00000002 /* Address Alignment Error */
87 /* Bits 2-63 Reserved */
88
89static unsigned long dmac_base;
90
91void set_dma_count(unsigned int chan, unsigned int count);
92void set_dma_addr(unsigned int chan, unsigned int addr);
93
94static irqreturn_t dma_mte(int irq, void *dev_id, struct pt_regs *regs)
95{
96 unsigned int chan = irq - DMA_IRQ_DMTE0;
97 dma_info_t *info = dma_info + chan;
98 u64 status;
99
100 if (info->mode & DMA_MODE_WRITE) {
101 sh64_out64(info->mem_addr & DMAC_SAR_ADDR, DMAC_SAR(chan));
102 } else {
103 sh64_out64(info->mem_addr & DMAC_DAR_ADDR, DMAC_DAR(chan));
104 }
105
106 set_dma_count(chan, info->count);
107
108 /* Clear the TE bit */
109 status = sh64_in64(DMAC_STATUS(chan));
110 status &= ~DMAC_STATUS_TE;
111 sh64_out64(status, DMAC_STATUS(chan));
112
113 return IRQ_HANDLED;
114}
115
116static struct irqaction irq_dmte = {
117 .handler = dma_mte,
118 .flags = IRQF_DISABLED,
119 .name = "DMA MTE",
120};
121
122static irqreturn_t dma_err(int irq, void *dev_id, struct pt_regs *regs)
123{
124 u64 tmp;
125 u8 chan;
126
127 printk(KERN_NOTICE "DMAC: Got a DMA Error!\n");
128
129 tmp = sh64_in64(DMAC_COMMON_BASE);
130
131 /* Check for the type of error */
132 if ((chan = tmp & DMAC_COMMON_AAE)) {
133 /* It's an address alignment error.. */
134 printk(KERN_NOTICE "DMAC: Alignment error on channel %d, ", chan);
135
136 printk(KERN_NOTICE "SAR: 0x%08llx, DAR: 0x%08llx, COUNT: %lld\n",
137 (sh64_in64(DMAC_SAR(chan)) & DMAC_SAR_ADDR),
138 (sh64_in64(DMAC_DAR(chan)) & DMAC_DAR_ADDR),
139 (sh64_in64(DMAC_COUNT(chan)) & DMAC_COUNT_CNT));
140
141 } else if ((chan = tmp & DMAC_COMMON_ER)) {
142 /* Something else went wrong.. */
143 printk(KERN_NOTICE "DMAC: Error on channel %d\n", chan);
144 }
145
146 /* Reset the ME bit to clear the interrupt */
147 tmp |= DMAC_COMMON_ME;
148 sh64_out64(tmp, DMAC_COMMON_BASE);
149
150 return IRQ_HANDLED;
151}
152
153static struct irqaction irq_derr = {
154 .handler = dma_err,
155 .flags = IRQF_DISABLED,
156 .name = "DMA Error",
157};
158
159static inline unsigned long calc_xmit_shift(unsigned int chan)
160{
161 return sh64_in64(DMAC_CTRL(chan)) & 0x03;
162}
163
164void setup_dma(unsigned int chan, dma_info_t *info)
165{
166 unsigned int irq = DMA_IRQ_DMTE0 + chan;
167 dma_info_t *dma = dma_info + chan;
168
169 make_intc_irq(irq);
170 setup_irq(irq, &irq_dmte);
171 dma = info;
172}
173
174void enable_dma(unsigned int chan)
175{
176 u64 ctrl;
177
178 ctrl = sh64_in64(DMAC_CTRL(chan));
179 ctrl |= DMAC_CTRL_TE;
180 sh64_out64(ctrl, DMAC_CTRL(chan));
181}
182
183void disable_dma(unsigned int chan)
184{
185 u64 ctrl;
186
187 ctrl = sh64_in64(DMAC_CTRL(chan));
188 ctrl &= ~DMAC_CTRL_TE;
189 sh64_out64(ctrl, DMAC_CTRL(chan));
190}
191
192void set_dma_mode(unsigned int chan, char mode)
193{
194 dma_info_t *info = dma_info + chan;
195
196 info->mode = mode;
197
198 set_dma_addr(chan, info->mem_addr);
199 set_dma_count(chan, info->count);
200}
201
202void set_dma_addr(unsigned int chan, unsigned int addr)
203{
204 dma_info_t *info = dma_info + chan;
205 unsigned long sar, dar;
206
207 info->mem_addr = addr;
208 sar = (info->mode & DMA_MODE_WRITE) ? info->mem_addr : info->dev_addr;
209 dar = (info->mode & DMA_MODE_WRITE) ? info->dev_addr : info->mem_addr;
210
211 sh64_out64(sar & DMAC_SAR_ADDR, DMAC_SAR(chan));
212 sh64_out64(dar & DMAC_SAR_ADDR, DMAC_DAR(chan));
213}
214
215void set_dma_count(unsigned int chan, unsigned int count)
216{
217 dma_info_t *info = dma_info + chan;
218 u64 tmp;
219
220 info->count = count;
221
222 tmp = (info->count >> calc_xmit_shift(chan)) & DMAC_COUNT_CNT;
223
224 sh64_out64(tmp, DMAC_COUNT(chan));
225}
226
227unsigned long claim_dma_lock(void)
228{
229 unsigned long flags;
230
231 spin_lock_irqsave(&dma_spin_lock, flags);
232
233 return flags;
234}
235
236void release_dma_lock(unsigned long flags)
237{
238 spin_unlock_irqrestore(&dma_spin_lock, flags);
239}
240
241int get_dma_residue(unsigned int chan)
242{
243 return sh64_in64(DMAC_COUNT(chan) << calc_xmit_shift(chan));
244}
245
246int __init init_dma(void)
247{
248 struct vcr_info vcr;
249 u64 tmp;
250
251 /* Remap the DMAC */
252 dmac_base = onchip_remap(PHYS_DMAC_BLOCK, 1024, "DMAC");
253 if (!dmac_base) {
254 printk(KERN_ERR "Unable to remap DMAC\n");
255 return -ENOMEM;
256 }
257
258 /* Report DMAC.VCR Info */
259 vcr = sh64_get_vcr_info(dmac_base);
260 printk("DMAC: Module ID: 0x%04x, Module version: 0x%04x\n",
261 vcr.mod_id, vcr.mod_vers);
262
263 /* Set the ME bit */
264 tmp = sh64_in64(DMAC_COMMON_BASE);
265 tmp |= DMAC_COMMON_ME;
266 sh64_out64(tmp, DMAC_COMMON_BASE);
267
268 /* Enable the DMAC Error Interrupt */
269 make_intc_irq(DMA_IRQ_DERR);
270 setup_irq(DMA_IRQ_DERR, &irq_derr);
271
272 return 0;
273}
274
275static void __exit exit_dma(void)
276{
277 onchip_unmap(dmac_base);
278 free_irq(DMA_IRQ_DERR, 0);
279}
280
281module_init(init_dma);
282module_exit(exit_dma);
283
284MODULE_AUTHOR("Paul Mundt");
285MODULE_DESCRIPTION("DMA API for SH-5 DMAC");
286MODULE_LICENSE("GPL");
287
288EXPORT_SYMBOL(setup_dma);
289EXPORT_SYMBOL(claim_dma_lock);
290EXPORT_SYMBOL(release_dma_lock);
291EXPORT_SYMBOL(enable_dma);
292EXPORT_SYMBOL(disable_dma);
293EXPORT_SYMBOL(set_dma_mode);
294EXPORT_SYMBOL(set_dma_addr);
295EXPORT_SYMBOL(set_dma_count);
296EXPORT_SYMBOL(get_dma_residue);
297
diff --git a/arch/sh64/kernel/early_printk.c b/arch/sh64/kernel/early_printk.c
deleted file mode 100644
index 4f9131123672..000000000000
--- a/arch/sh64/kernel/early_printk.c
+++ /dev/null
@@ -1,99 +0,0 @@
1/*
2 * arch/sh64/kernel/early_printk.c
3 *
4 * SH-5 Early SCIF console (cloned and hacked from sh implementation)
5 *
6 * Copyright (C) 2003, 2004 Paul Mundt <lethal@linux-sh.org>
7 * Copyright (C) 2002 M. R. Brown <mrbrown@0xd6.org>
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 */
13#include <linux/console.h>
14#include <linux/tty.h>
15#include <linux/init.h>
16#include <asm/io.h>
17#include <asm/hardware.h>
18
19#define SCIF_BASE_ADDR 0x01030000
20#define SCIF_ADDR_SH5 PHYS_PERIPHERAL_BLOCK+SCIF_BASE_ADDR
21
22/*
23 * Fixed virtual address where SCIF is mapped (should already be done
24 * in arch/sh64/kernel/head.S!).
25 */
26#define SCIF_REG 0xfa030000
27
28enum {
29 SCIF_SCSMR2 = SCIF_REG + 0x00,
30 SCIF_SCBRR2 = SCIF_REG + 0x04,
31 SCIF_SCSCR2 = SCIF_REG + 0x08,
32 SCIF_SCFTDR2 = SCIF_REG + 0x0c,
33 SCIF_SCFSR2 = SCIF_REG + 0x10,
34 SCIF_SCFRDR2 = SCIF_REG + 0x14,
35 SCIF_SCFCR2 = SCIF_REG + 0x18,
36 SCIF_SCFDR2 = SCIF_REG + 0x1c,
37 SCIF_SCSPTR2 = SCIF_REG + 0x20,
38 SCIF_SCLSR2 = SCIF_REG + 0x24,
39};
40
41static void sh_console_putc(int c)
42{
43 while (!(ctrl_inw(SCIF_SCFSR2) & 0x20))
44 cpu_relax();
45
46 ctrl_outb(c, SCIF_SCFTDR2);
47 ctrl_outw((ctrl_inw(SCIF_SCFSR2) & 0x9f), SCIF_SCFSR2);
48
49 if (c == '\n')
50 sh_console_putc('\r');
51}
52
53static void sh_console_flush(void)
54{
55 ctrl_outw((ctrl_inw(SCIF_SCFSR2) & 0xbf), SCIF_SCFSR2);
56
57 while (!(ctrl_inw(SCIF_SCFSR2) & 0x40))
58 cpu_relax();
59
60 ctrl_outw((ctrl_inw(SCIF_SCFSR2) & 0xbf), SCIF_SCFSR2);
61}
62
63static void sh_console_write(struct console *con, const char *s, unsigned count)
64{
65 while (count-- > 0)
66 sh_console_putc(*s++);
67
68 sh_console_flush();
69}
70
71static int __init sh_console_setup(struct console *con, char *options)
72{
73 con->cflag = CREAD | HUPCL | CLOCAL | B19200 | CS8;
74
75 return 0;
76}
77
78static struct console sh_console = {
79 .name = "scifcon",
80 .write = sh_console_write,
81 .setup = sh_console_setup,
82 .flags = CON_PRINTBUFFER | CON_BOOT,
83 .index = -1,
84};
85
86void __init enable_early_printk(void)
87{
88 ctrl_outb(0x2a, SCIF_SCBRR2); /* 19200bps */
89
90 ctrl_outw(0x04, SCIF_SCFCR2); /* Reset TFRST */
91 ctrl_outw(0x10, SCIF_SCFCR2); /* TTRG0=1 */
92
93 ctrl_outw(0, SCIF_SCSPTR2);
94 ctrl_outw(0x60, SCIF_SCFSR2);
95 ctrl_outw(0, SCIF_SCLSR2);
96 ctrl_outw(0x30, SCIF_SCSCR2);
97
98 register_console(&sh_console);
99}
diff --git a/arch/sh64/kernel/init_task.c b/arch/sh64/kernel/init_task.c
deleted file mode 100644
index deee8bfd3270..000000000000
--- a/arch/sh64/kernel/init_task.c
+++ /dev/null
@@ -1,46 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * arch/sh64/kernel/init_task.c
7 *
8 * Copyright (C) 2000, 2001 Paolo Alberelli
9 * Copyright (C) 2003 Paul Mundt
10 *
11 */
12#include <linux/rwsem.h>
13#include <linux/mm.h>
14#include <linux/sched.h>
15#include <linux/init_task.h>
16#include <linux/mqueue.h>
17#include <linux/fs.h>
18#include <asm/uaccess.h>
19#include <asm/pgtable.h>
20
21static struct fs_struct init_fs = INIT_FS;
22static struct files_struct init_files = INIT_FILES;
23static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
24static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
25struct mm_struct init_mm = INIT_MM(init_mm);
26
27struct pt_regs fake_swapper_regs;
28
29/*
30 * Initial thread structure.
31 *
32 * We need to make sure that this is THREAD_SIZE-byte aligned due
33 * to the way process stacks are handled. This is done by having a
34 * special "init_task" linker map entry..
35 */
36union thread_union init_thread_union
37 __attribute__((__section__(".data.init_task"))) =
38 { INIT_THREAD_INFO(init_task) };
39
40/*
41 * Initial task structure.
42 *
43 * All other task structs will be allocated on slabs in fork.c
44 */
45struct task_struct init_task = INIT_TASK(init_task);
46
diff --git a/arch/sh64/kernel/irq.c b/arch/sh64/kernel/irq.c
deleted file mode 100644
index 9412b7166700..000000000000
--- a/arch/sh64/kernel/irq.c
+++ /dev/null
@@ -1,115 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * arch/sh64/kernel/irq.c
7 *
8 * Copyright (C) 2000, 2001 Paolo Alberelli
9 * Copyright (C) 2003 Paul Mundt
10 *
11 */
12
13/*
14 * IRQs are in fact implemented a bit like signal handlers for the kernel.
15 * Naturally it's not a 1:1 relation, but there are similarities.
16 */
17
18#include <linux/errno.h>
19#include <linux/kernel_stat.h>
20#include <linux/signal.h>
21#include <linux/rwsem.h>
22#include <linux/sched.h>
23#include <linux/ioport.h>
24#include <linux/interrupt.h>
25#include <linux/timex.h>
26#include <linux/slab.h>
27#include <linux/random.h>
28#include <linux/smp.h>
29#include <linux/init.h>
30#include <linux/seq_file.h>
31#include <linux/bitops.h>
32#include <asm/system.h>
33#include <asm/io.h>
34#include <asm/smp.h>
35#include <asm/pgalloc.h>
36#include <asm/delay.h>
37#include <asm/irq.h>
38#include <linux/irq.h>
39
40void ack_bad_irq(unsigned int irq)
41{
42 printk("unexpected IRQ trap at irq %02x\n", irq);
43}
44
45#if defined(CONFIG_PROC_FS)
46int show_interrupts(struct seq_file *p, void *v)
47{
48 int i = *(loff_t *) v, j;
49 struct irqaction * action;
50 unsigned long flags;
51
52 if (i == 0) {
53 seq_puts(p, " ");
54 for_each_online_cpu(j)
55 seq_printf(p, "CPU%d ",j);
56 seq_putc(p, '\n');
57 }
58
59 if (i < NR_IRQS) {
60 spin_lock_irqsave(&irq_desc[i].lock, flags);
61 action = irq_desc[i].action;
62 if (!action)
63 goto unlock;
64 seq_printf(p, "%3d: ",i);
65 seq_printf(p, "%10u ", kstat_irqs(i));
66 seq_printf(p, " %14s", irq_desc[i].chip->typename);
67 seq_printf(p, " %s", action->name);
68
69 for (action=action->next; action; action = action->next)
70 seq_printf(p, ", %s", action->name);
71 seq_putc(p, '\n');
72unlock:
73 spin_unlock_irqrestore(&irq_desc[i].lock, flags);
74 }
75 return 0;
76}
77#endif
78
79/*
80 * do_NMI handles all Non-Maskable Interrupts.
81 */
82asmlinkage void do_NMI(unsigned long vector_num, struct pt_regs * regs)
83{
84 if (regs->sr & 0x40000000)
85 printk("unexpected NMI trap in system mode\n");
86 else
87 printk("unexpected NMI trap in user mode\n");
88
89 /* No statistics */
90}
91
92/*
93 * do_IRQ handles all normal device IRQ's.
94 */
95asmlinkage int do_IRQ(unsigned long vector_num, struct pt_regs * regs)
96{
97 struct pt_regs *old_regs = set_irq_regs(regs);
98 int irq;
99
100 irq_enter();
101
102 irq = irq_demux(vector_num);
103
104 if (irq >= 0) {
105 __do_IRQ(irq);
106 } else {
107 printk("unexpected IRQ trap at vector %03lx\n", vector_num);
108 }
109
110 irq_exit();
111
112 set_irq_regs(old_regs);
113 return 1;
114}
115
diff --git a/arch/sh64/kernel/led.c b/arch/sh64/kernel/led.c
deleted file mode 100644
index e35d3f667fb4..000000000000
--- a/arch/sh64/kernel/led.c
+++ /dev/null
@@ -1,40 +0,0 @@
1/*
2 * arch/sh64/kernel/led.c
3 *
4 * Copyright (C) 2002 Stuart Menefy <stuart.menefy@st.com>
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * Flash the LEDs
10 */
11#include <linux/stddef.h>
12#include <linux/sched.h>
13
14void mach_led(int pos, int val);
15
16/* acts like an actual heart beat -- ie thump-thump-pause... */
17void heartbeat(void)
18{
19 static unsigned int cnt = 0, period = 0, dist = 0;
20
21 if (cnt == 0 || cnt == dist) {
22 mach_led(-1, 1);
23 } else if (cnt == 7 || cnt == dist + 7) {
24 mach_led(-1, 0);
25 }
26
27 if (++cnt > period) {
28 cnt = 0;
29
30 /*
31 * The hyperbolic function below modifies the heartbeat period
32 * length in dependency of the current (5min) load. It goes
33 * through the points f(0)=126, f(1)=86, f(5)=51, f(inf)->30.
34 */
35 period = ((672 << FSHIFT) / (5 * avenrun[0] +
36 (7 << FSHIFT))) + 30;
37 dist = period / 4;
38 }
39}
40
diff --git a/arch/sh64/kernel/module.c b/arch/sh64/kernel/module.c
deleted file mode 100644
index 2598f6b88b44..000000000000
--- a/arch/sh64/kernel/module.c
+++ /dev/null
@@ -1,161 +0,0 @@
1/* Kernel module help for sh64.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2 of the License, or
6 (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
17 Copyright 2004 SuperH (UK) Ltd
18 Author: Richard Curnow
19
20 Based on the sh version, and on code from the sh64-specific parts of
21 modutils, originally written by Richard Curnow and Ben Gaster.
22
23*/
24#include <linux/moduleloader.h>
25#include <linux/elf.h>
26#include <linux/vmalloc.h>
27#include <linux/fs.h>
28#include <linux/string.h>
29#include <linux/kernel.h>
30
31#if 0
32#define DEBUGP printk
33#else
34#define DEBUGP(fmt...)
35#endif
36
37void *module_alloc(unsigned long size)
38{
39 if (size == 0)
40 return NULL;
41 return vmalloc(size);
42}
43
44
45/* Free memory returned from module_alloc */
46void module_free(struct module *mod, void *module_region)
47{
48 vfree(module_region);
49 /* FIXME: If module_region == mod->init_region, trim exception
50 table entries. */
51}
52
53/* We don't need anything special. */
54int module_frob_arch_sections(Elf_Ehdr *hdr,
55 Elf_Shdr *sechdrs,
56 char *secstrings,
57 struct module *mod)
58{
59 return 0;
60}
61
62int apply_relocate_add(Elf32_Shdr *sechdrs,
63 const char *strtab,
64 unsigned int symindex,
65 unsigned int relsec,
66 struct module *me)
67{
68 unsigned int i;
69 Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr;
70 Elf32_Sym *sym;
71 Elf32_Addr relocation;
72 uint32_t *location;
73 int align;
74 int is_shmedia;
75
76 DEBUGP("Applying relocate section %u to %u\n", relsec,
77 sechdrs[relsec].sh_info);
78 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
79 /* This is where to make the change */
80 location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
81 + rel[i].r_offset;
82 /* This is the symbol it is referring to. Note that all
83 undefined symbols have been resolved. */
84 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
85 + ELF32_R_SYM(rel[i].r_info);
86 relocation = sym->st_value + rel[i].r_addend;
87 align = (int)location & 3;
88
89 /* For text addresses, bit2 of the st_other field indicates
90 * whether the symbol is SHmedia (1) or SHcompact (0). If
91 * SHmedia, the LSB of the symbol needs to be asserted
92 * for the CPU to be in SHmedia mode when it starts executing
93 * the branch target. */
94 is_shmedia = (sym->st_other & 4) ? 1 : 0;
95 if (is_shmedia) {
96 relocation |= 1;
97 }
98
99 switch (ELF32_R_TYPE(rel[i].r_info)) {
100 case R_SH_DIR32:
101 DEBUGP("R_SH_DIR32 @%08lx = %08lx\n", (unsigned long) location, (unsigned long) relocation);
102 *location += relocation;
103 break;
104 case R_SH_REL32:
105 DEBUGP("R_SH_REL32 @%08lx = %08lx\n", (unsigned long) location, (unsigned long) relocation);
106 relocation -= (Elf32_Addr) location;
107 *location += relocation;
108 break;
109 case R_SH_IMM_LOW16:
110 DEBUGP("R_SH_IMM_LOW16 @%08lx = %08lx\n", (unsigned long) location, (unsigned long) relocation);
111 *location = (*location & ~0x3fffc00) |
112 ((relocation & 0xffff) << 10);
113 break;
114 case R_SH_IMM_MEDLOW16:
115 DEBUGP("R_SH_IMM_MEDLOW16 @%08lx = %08lx\n", (unsigned long) location, (unsigned long) relocation);
116 *location = (*location & ~0x3fffc00) |
117 (((relocation >> 16) & 0xffff) << 10);
118 break;
119 case R_SH_IMM_LOW16_PCREL:
120 DEBUGP("R_SH_IMM_LOW16_PCREL @%08lx = %08lx\n", (unsigned long) location, (unsigned long) relocation);
121 relocation -= (Elf32_Addr) location;
122 *location = (*location & ~0x3fffc00) |
123 ((relocation & 0xffff) << 10);
124 break;
125 case R_SH_IMM_MEDLOW16_PCREL:
126 DEBUGP("R_SH_IMM_MEDLOW16_PCREL @%08lx = %08lx\n", (unsigned long) location, (unsigned long) relocation);
127 relocation -= (Elf32_Addr) location;
128 *location = (*location & ~0x3fffc00) |
129 (((relocation >> 16) & 0xffff) << 10);
130 break;
131 default:
132 printk(KERN_ERR "module %s: Unknown relocation: %u\n",
133 me->name, ELF32_R_TYPE(rel[i].r_info));
134 return -ENOEXEC;
135 }
136 }
137 return 0;
138}
139
140int apply_relocate(Elf32_Shdr *sechdrs,
141 const char *strtab,
142 unsigned int symindex,
143 unsigned int relsec,
144 struct module *me)
145{
146 printk(KERN_ERR "module %s: REL RELOCATION unsupported\n",
147 me->name);
148 return -ENOEXEC;
149}
150
151int module_finalize(const Elf_Ehdr *hdr,
152 const Elf_Shdr *sechdrs,
153 struct module *me)
154{
155 return 0;
156}
157
158void module_arch_cleanup(struct module *mod)
159{
160}
161
diff --git a/arch/sh64/kernel/pci_sh5.c b/arch/sh64/kernel/pci_sh5.c
deleted file mode 100644
index b4d9534d2b0e..000000000000
--- a/arch/sh64/kernel/pci_sh5.c
+++ /dev/null
@@ -1,536 +0,0 @@
1/*
2 * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
3 * Copyright (C) 2003, 2004 Paul Mundt
4 * Copyright (C) 2004 Richard Curnow
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * Support functions for the SH5 PCI hardware.
10 */
11
12#include <linux/kernel.h>
13#include <linux/rwsem.h>
14#include <linux/smp.h>
15#include <linux/interrupt.h>
16#include <linux/init.h>
17#include <linux/errno.h>
18#include <linux/pci.h>
19#include <linux/delay.h>
20#include <linux/types.h>
21#include <asm/pci.h>
22#include <linux/irq.h>
23
24#include <asm/io.h>
25#include <asm/hardware.h>
26#include "pci_sh5.h"
27
28static unsigned long pcicr_virt;
29unsigned long pciio_virt;
30
31static void __init pci_fixup_ide_bases(struct pci_dev *d)
32{
33 int i;
34
35 /*
36 * PCI IDE controllers use non-standard I/O port decoding, respect it.
37 */
38 if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
39 return;
40 printk("PCI: IDE base address fixup for %s\n", pci_name(d));
41 for(i=0; i<4; i++) {
42 struct resource *r = &d->resource[i];
43 if ((r->start & ~0x80) == 0x374) {
44 r->start |= 2;
45 r->end = r->start;
46 }
47 }
48}
49DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases);
50
51char * __devinit pcibios_setup(char *str)
52{
53 return str;
54}
55
56/* Rounds a number UP to the nearest power of two. Used for
57 * sizing the PCI window.
58 */
59static u32 __init r2p2(u32 num)
60{
61 int i = 31;
62 u32 tmp = num;
63
64 if (num == 0)
65 return 0;
66
67 do {
68 if (tmp & (1 << 31))
69 break;
70 i--;
71 tmp <<= 1;
72 } while (i >= 0);
73
74 tmp = 1 << i;
75 /* If the original number isn't a power of 2, round it up */
76 if (tmp != num)
77 tmp <<= 1;
78
79 return tmp;
80}
81
82extern unsigned long long memory_start, memory_end;
83
84int __init sh5pci_init(unsigned memStart, unsigned memSize)
85{
86 u32 lsr0;
87 u32 uval;
88
89 pcicr_virt = onchip_remap(SH5PCI_ICR_BASE, 1024, "PCICR");
90 if (!pcicr_virt) {
91 panic("Unable to remap PCICR\n");
92 }
93
94 pciio_virt = onchip_remap(SH5PCI_IO_BASE, 0x10000, "PCIIO");
95 if (!pciio_virt) {
96 panic("Unable to remap PCIIO\n");
97 }
98
99 pr_debug("Register base addres is 0x%08lx\n", pcicr_virt);
100
101 /* Clear snoop registers */
102 SH5PCI_WRITE(CSCR0, 0);
103 SH5PCI_WRITE(CSCR1, 0);
104
105 pr_debug("Wrote to reg\n");
106
107 /* Switch off interrupts */
108 SH5PCI_WRITE(INTM, 0);
109 SH5PCI_WRITE(AINTM, 0);
110 SH5PCI_WRITE(PINTM, 0);
111
112 /* Set bus active, take it out of reset */
113 uval = SH5PCI_READ(CR);
114
115 /* Set command Register */
116 SH5PCI_WRITE(CR, uval | CR_LOCK_MASK | CR_CFINT| CR_FTO | CR_PFE | CR_PFCS | CR_BMAM);
117
118 uval=SH5PCI_READ(CR);
119 pr_debug("CR is actually 0x%08x\n",uval);
120
121 /* Allow it to be a master */
122 /* NB - WE DISABLE I/O ACCESS to stop overlap */
123 /* set WAIT bit to enable stepping, an attempt to improve stability */
124 SH5PCI_WRITE_SHORT(CSR_CMD,
125 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_WAIT);
126
127 /*
128 ** Set translation mapping memory in order to convert the address
129 ** used for the main bus, to the PCI internal address.
130 */
131 SH5PCI_WRITE(MBR,0x40000000);
132
133 /* Always set the max size 512M */
134 SH5PCI_WRITE(MBMR, PCISH5_MEM_SIZCONV(512*1024*1024));
135
136 /*
137 ** I/O addresses are mapped at internal PCI specific address
138 ** as is described into the configuration bridge table.
139 ** These are changed to 0, to allow cards that have legacy
140 ** io such as vga to function correctly. We set the SH5 IOBAR to
141 ** 256K, which is a bit big as we can only have 64K of address space
142 */
143
144 SH5PCI_WRITE(IOBR,0x0);
145
146 pr_debug("PCI:Writing 0x%08x to IOBR\n",0);
147
148 /* Set up a 256K window. Totally pointless waste of address space */
149 SH5PCI_WRITE(IOBMR,0);
150 pr_debug("PCI:Writing 0x%08x to IOBMR\n",0);
151
152 /* The SH5 has a HUGE 256K I/O region, which breaks the PCI spec. Ideally,
153 * we would want to map the I/O region somewhere, but it is so big this is not
154 * that easy!
155 */
156 SH5PCI_WRITE(CSR_IBAR0,~0);
157 /* Set memory size value */
158 memSize = memory_end - memory_start;
159
160 /* Now we set up the mbars so the PCI bus can see the memory of the machine */
161 if (memSize < (1024 * 1024)) {
162 printk(KERN_ERR "PCISH5: Ridiculous memory size of 0x%x?\n", memSize);
163 return -EINVAL;
164 }
165
166 /* Set LSR 0 */
167 lsr0 = (memSize > (512 * 1024 * 1024)) ? 0x1ff00001 : ((r2p2(memSize) - 0x100000) | 0x1);
168 SH5PCI_WRITE(LSR0, lsr0);
169
170 pr_debug("PCI:Writing 0x%08x to LSR0\n",lsr0);
171
172 /* Set MBAR 0 */
173 SH5PCI_WRITE(CSR_MBAR0, memory_start);
174 SH5PCI_WRITE(LAR0, memory_start);
175
176 SH5PCI_WRITE(CSR_MBAR1,0);
177 SH5PCI_WRITE(LAR1,0);
178 SH5PCI_WRITE(LSR1,0);
179
180 pr_debug("PCI:Writing 0x%08llx to CSR_MBAR0\n",memory_start);
181 pr_debug("PCI:Writing 0x%08llx to LAR0\n",memory_start);
182
183 /* Enable the PCI interrupts on the device */
184 SH5PCI_WRITE(INTM, ~0);
185 SH5PCI_WRITE(AINTM, ~0);
186 SH5PCI_WRITE(PINTM, ~0);
187
188 pr_debug("Switching on all error interrupts\n");
189
190 return(0);
191}
192
193static int sh5pci_read(struct pci_bus *bus, unsigned int devfn, int where,
194 int size, u32 *val)
195{
196 SH5PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
197
198 switch (size) {
199 case 1:
200 *val = (u8)SH5PCI_READ_BYTE(PDR + (where & 3));
201 break;
202 case 2:
203 *val = (u16)SH5PCI_READ_SHORT(PDR + (where & 2));
204 break;
205 case 4:
206 *val = SH5PCI_READ(PDR);
207 break;
208 }
209
210 return PCIBIOS_SUCCESSFUL;
211}
212
213static int sh5pci_write(struct pci_bus *bus, unsigned int devfn, int where,
214 int size, u32 val)
215{
216 SH5PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
217
218 switch (size) {
219 case 1:
220 SH5PCI_WRITE_BYTE(PDR + (where & 3), (u8)val);
221 break;
222 case 2:
223 SH5PCI_WRITE_SHORT(PDR + (where & 2), (u16)val);
224 break;
225 case 4:
226 SH5PCI_WRITE(PDR, val);
227 break;
228 }
229
230 return PCIBIOS_SUCCESSFUL;
231}
232
233static struct pci_ops pci_config_ops = {
234 .read = sh5pci_read,
235 .write = sh5pci_write,
236};
237
238/* Everything hangs off this */
239static struct pci_bus *pci_root_bus;
240
241
242static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin)
243{
244 pr_debug("swizzle for dev %d on bus %d slot %d pin is %d\n",
245 dev->devfn,dev->bus->number, PCI_SLOT(dev->devfn),*pin);
246 return PCI_SLOT(dev->devfn);
247}
248
249static inline u8 bridge_swizzle(u8 pin, u8 slot)
250{
251 return (((pin-1) + slot) % 4) + 1;
252}
253
254u8 __init common_swizzle(struct pci_dev *dev, u8 *pinp)
255{
256 if (dev->bus->number != 0) {
257 u8 pin = *pinp;
258 do {
259 pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
260 /* Move up the chain of bridges. */
261 dev = dev->bus->self;
262 } while (dev->bus->self);
263 *pinp = pin;
264
265 /* The slot is the slot of the last bridge. */
266 }
267
268 return PCI_SLOT(dev->devfn);
269}
270
271/* This needs to be shunted out of here into the board specific bit */
272
273static int __init map_cayman_irq(struct pci_dev *dev, u8 slot, u8 pin)
274{
275 int result = -1;
276
277 /* The complication here is that the PCI IRQ lines from the Cayman's 2
278 5V slots get into the CPU via a different path from the IRQ lines
279 from the 3 3.3V slots. Thus, we have to detect whether the card's
280 interrupts go via the 5V or 3.3V path, i.e. the 'bridge swizzling'
281 at the point where we cross from 5V to 3.3V is not the normal case.
282
283 The added complication is that we don't know that the 5V slots are
284 always bus 2, because a card containing a PCI-PCI bridge may be
285 plugged into a 3.3V slot, and this changes the bus numbering.
286
287 Also, the Cayman has an intermediate PCI bus that goes a custom
288 expansion board header (and to the secondary bridge). This bus has
289 never been used in practice.
290
291 The 1ary onboard PCI-PCI bridge is device 3 on bus 0
292 The 2ary onboard PCI-PCI bridge is device 0 on the 2ary bus of the 1ary bridge.
293 */
294
295 struct slot_pin {
296 int slot;
297 int pin;
298 } path[4];
299 int i=0;
300
301 while (dev->bus->number > 0) {
302
303 slot = path[i].slot = PCI_SLOT(dev->devfn);
304 pin = path[i].pin = bridge_swizzle(pin, slot);
305 dev = dev->bus->self;
306 i++;
307 if (i > 3) panic("PCI path to root bus too long!\n");
308 }
309
310 slot = PCI_SLOT(dev->devfn);
311 /* This is the slot on bus 0 through which the device is eventually
312 reachable. */
313
314 /* Now work back up. */
315 if ((slot < 3) || (i == 0)) {
316 /* Bus 0 (incl. PCI-PCI bridge itself) : perform the final
317 swizzle now. */
318 result = IRQ_INTA + bridge_swizzle(pin, slot) - 1;
319 } else {
320 i--;
321 slot = path[i].slot;
322 pin = path[i].pin;
323 if (slot > 0) {
324 panic("PCI expansion bus device found - not handled!\n");
325 } else {
326 if (i > 0) {
327 /* 5V slots */
328 i--;
329 slot = path[i].slot;
330 pin = path[i].pin;
331 /* 'pin' was swizzled earlier wrt slot, don't do it again. */
332 result = IRQ_P2INTA + (pin - 1);
333 } else {
334 /* IRQ for 2ary PCI-PCI bridge : unused */
335 result = -1;
336 }
337 }
338 }
339
340 return result;
341}
342
343static irqreturn_t pcish5_err_irq(int irq, void *dev_id)
344{
345 struct pt_regs *regs = get_irq_regs();
346 unsigned pci_int, pci_air, pci_cir, pci_aint;
347
348 pci_int = SH5PCI_READ(INT);
349 pci_cir = SH5PCI_READ(CIR);
350 pci_air = SH5PCI_READ(AIR);
351
352 if (pci_int) {
353 printk("PCI INTERRUPT (at %08llx)!\n", regs->pc);
354 printk("PCI INT -> 0x%x\n", pci_int & 0xffff);
355 printk("PCI AIR -> 0x%x\n", pci_air);
356 printk("PCI CIR -> 0x%x\n", pci_cir);
357 SH5PCI_WRITE(INT, ~0);
358 }
359
360 pci_aint = SH5PCI_READ(AINT);
361 if (pci_aint) {
362 printk("PCI ARB INTERRUPT!\n");
363 printk("PCI AINT -> 0x%x\n", pci_aint);
364 printk("PCI AIR -> 0x%x\n", pci_air);
365 printk("PCI CIR -> 0x%x\n", pci_cir);
366 SH5PCI_WRITE(AINT, ~0);
367 }
368
369 return IRQ_HANDLED;
370}
371
372static irqreturn_t pcish5_serr_irq(int irq, void *dev_id)
373{
374 printk("SERR IRQ\n");
375
376 return IRQ_NONE;
377}
378
379static void __init
380pcibios_size_bridge(struct pci_bus *bus, struct resource *ior,
381 struct resource *memr)
382{
383 struct resource io_res, mem_res;
384 struct pci_dev *dev;
385 struct pci_dev *bridge = bus->self;
386 struct list_head *ln;
387
388 if (!bridge)
389 return; /* host bridge, nothing to do */
390
391 /* set reasonable default locations for pcibios_align_resource */
392 io_res.start = PCIBIOS_MIN_IO;
393 mem_res.start = PCIBIOS_MIN_MEM;
394
395 io_res.end = io_res.start;
396 mem_res.end = mem_res.start;
397
398 /* Collect information about how our direct children are layed out. */
399 for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
400 int i;
401 dev = pci_dev_b(ln);
402
403 /* Skip bridges for now */
404 if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
405 continue;
406
407 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
408 struct resource res;
409 unsigned long size;
410
411 memcpy(&res, &dev->resource[i], sizeof(res));
412 size = res.end - res.start + 1;
413
414 if (res.flags & IORESOURCE_IO) {
415 res.start = io_res.end;
416 pcibios_align_resource(dev, &res, size, 0);
417 io_res.end = res.start + size;
418 } else if (res.flags & IORESOURCE_MEM) {
419 res.start = mem_res.end;
420 pcibios_align_resource(dev, &res, size, 0);
421 mem_res.end = res.start + size;
422 }
423 }
424 }
425
426 /* And for all of the subordinate busses. */
427 for (ln=bus->children.next; ln != &bus->children; ln=ln->next)
428 pcibios_size_bridge(pci_bus_b(ln), &io_res, &mem_res);
429
430 /* turn the ending locations into sizes (subtract start) */
431 io_res.end -= io_res.start;
432 mem_res.end -= mem_res.start;
433
434 /* Align the sizes up by bridge rules */
435 io_res.end = ALIGN(io_res.end, 4*1024) - 1;
436 mem_res.end = ALIGN(mem_res.end, 1*1024*1024) - 1;
437
438 /* Adjust the bridge's allocation requirements */
439 bridge->resource[0].end = bridge->resource[0].start + io_res.end;
440 bridge->resource[1].end = bridge->resource[1].start + mem_res.end;
441
442 bridge->resource[PCI_BRIDGE_RESOURCES].end =
443 bridge->resource[PCI_BRIDGE_RESOURCES].start + io_res.end;
444 bridge->resource[PCI_BRIDGE_RESOURCES+1].end =
445 bridge->resource[PCI_BRIDGE_RESOURCES+1].start + mem_res.end;
446
447 /* adjust parent's resource requirements */
448 if (ior) {
449 ior->end = ALIGN(ior->end, 4*1024);
450 ior->end += io_res.end;
451 }
452
453 if (memr) {
454 memr->end = ALIGN(memr->end, 1*1024*1024);
455 memr->end += mem_res.end;
456 }
457}
458
459static void __init pcibios_size_bridges(void)
460{
461 struct resource io_res, mem_res;
462
463 memset(&io_res, 0, sizeof(io_res));
464 memset(&mem_res, 0, sizeof(mem_res));
465
466 pcibios_size_bridge(pci_root_bus, &io_res, &mem_res);
467}
468
469static int __init pcibios_init(void)
470{
471 if (request_irq(IRQ_ERR, pcish5_err_irq,
472 IRQF_DISABLED, "PCI Error",NULL) < 0) {
473 printk(KERN_ERR "PCISH5: Cannot hook PCI_PERR interrupt\n");
474 return -EINVAL;
475 }
476
477 if (request_irq(IRQ_SERR, pcish5_serr_irq,
478 IRQF_DISABLED, "PCI SERR interrupt", NULL) < 0) {
479 printk(KERN_ERR "PCISH5: Cannot hook PCI_SERR interrupt\n");
480 return -EINVAL;
481 }
482
483 /* The pci subsystem needs to know where memory is and how much
484 * of it there is. I've simply made these globals. A better mechanism
485 * is probably needed.
486 */
487 sh5pci_init(__pa(memory_start),
488 __pa(memory_end) - __pa(memory_start));
489
490 pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL);
491 pcibios_size_bridges();
492 pci_assign_unassigned_resources();
493 pci_fixup_irqs(no_swizzle, map_cayman_irq);
494
495 return 0;
496}
497
498subsys_initcall(pcibios_init);
499
500void __devinit pcibios_fixup_bus(struct pci_bus *bus)
501{
502 struct pci_dev *dev = bus->self;
503 int i;
504
505#if 1
506 if(dev) {
507 for(i=0; i<3; i++) {
508 bus->resource[i] =
509 &dev->resource[PCI_BRIDGE_RESOURCES+i];
510 bus->resource[i]->name = bus->name;
511 }
512 bus->resource[0]->flags |= IORESOURCE_IO;
513 bus->resource[1]->flags |= IORESOURCE_MEM;
514
515 /* For now, propagate host limits to the bus;
516 * we'll adjust them later. */
517
518#if 1
519 bus->resource[0]->end = 64*1024 - 1 ;
520 bus->resource[1]->end = PCIBIOS_MIN_MEM+(256*1024*1024)-1;
521 bus->resource[0]->start = PCIBIOS_MIN_IO;
522 bus->resource[1]->start = PCIBIOS_MIN_MEM;
523#else
524 bus->resource[0]->end = 0;
525 bus->resource[1]->end = 0;
526 bus->resource[0]->start =0;
527 bus->resource[1]->start = 0;
528#endif
529 /* Turn off downstream PF memory address range by default */
530 bus->resource[2]->start = 1024*1024;
531 bus->resource[2]->end = bus->resource[2]->start - 1;
532 }
533#endif
534
535}
536
diff --git a/arch/sh64/kernel/pcibios.c b/arch/sh64/kernel/pcibios.c
deleted file mode 100644
index 945920bc24db..000000000000
--- a/arch/sh64/kernel/pcibios.c
+++ /dev/null
@@ -1,168 +0,0 @@
1/*
2 * $Id: pcibios.c,v 1.1 2001/08/24 12:38:19 dwmw2 Exp $
3 *
4 * arch/sh/kernel/pcibios.c
5 *
6 * Copyright (C) 2002 STMicroelectronics Limited
7 * Author : David J. McKay
8 *
9 * Copyright (C) 2004 Richard Curnow, SuperH UK Limited
10 *
11 * This file is subject to the terms and conditions of the GNU General Public
12 * License. See the file "COPYING" in the main directory of this archive
13 * for more details.
14 * This is GPL'd.
15 *
16 * Provided here are generic versions of:
17 * pcibios_update_resource()
18 * pcibios_align_resource()
19 * pcibios_enable_device()
20 * pcibios_set_master()
21 * pcibios_update_irq()
22 *
23 * These functions are collected here to reduce duplication of common
24 * code amongst the many platform-specific PCI support code files.
25 *
26 * Platform-specific files are expected to provide:
27 * pcibios_fixup_bus()
28 * pcibios_init()
29 * pcibios_setup()
30 * pcibios_fixup_pbus_ranges()
31 */
32
33#include <linux/kernel.h>
34#include <linux/pci.h>
35#include <linux/init.h>
36
37void
38pcibios_update_resource(struct pci_dev *dev, struct resource *root,
39 struct resource *res, int resource)
40{
41 u32 new, check;
42 int reg;
43
44 new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
45 if (resource < 6) {
46 reg = PCI_BASE_ADDRESS_0 + 4*resource;
47 } else if (resource == PCI_ROM_RESOURCE) {
48 res->flags |= IORESOURCE_ROM_ENABLE;
49 new |= PCI_ROM_ADDRESS_ENABLE;
50 reg = dev->rom_base_reg;
51 } else {
52 /* Somebody might have asked allocation of a non-standard resource */
53 return;
54 }
55
56 pci_write_config_dword(dev, reg, new);
57 pci_read_config_dword(dev, reg, &check);
58 if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
59 printk(KERN_ERR "PCI: Error while updating region "
60 "%s/%d (%08x != %08x)\n", pci_name(dev), resource,
61 new, check);
62 }
63}
64
65/*
66 * We need to avoid collisions with `mirrored' VGA ports
67 * and other strange ISA hardware, so we always want the
68 * addresses to be allocated in the 0x000-0x0ff region
69 * modulo 0x400.
70 */
71void pcibios_align_resource(void *data, struct resource *res,
72 resource_size_t size, resource_size_t align)
73{
74 if (res->flags & IORESOURCE_IO) {
75 resource_size_t start = res->start;
76
77 if (start & 0x300) {
78 start = (start + 0x3ff) & ~0x3ff;
79 res->start = start;
80 }
81 }
82}
83
84static void pcibios_enable_bridge(struct pci_dev *dev)
85{
86 struct pci_bus *bus = dev->subordinate;
87 u16 cmd, old_cmd;
88
89 pci_read_config_word(dev, PCI_COMMAND, &cmd);
90 old_cmd = cmd;
91
92 if (bus->resource[0]->flags & IORESOURCE_IO) {
93 cmd |= PCI_COMMAND_IO;
94 }
95 if ((bus->resource[1]->flags & IORESOURCE_MEM) ||
96 (bus->resource[2]->flags & IORESOURCE_PREFETCH)) {
97 cmd |= PCI_COMMAND_MEMORY;
98 }
99
100 if (cmd != old_cmd) {
101 pci_write_config_word(dev, PCI_COMMAND, cmd);
102 }
103
104 printk("PCI bridge %s, command register -> %04x\n",
105 pci_name(dev), cmd);
106
107}
108
109
110
111int pcibios_enable_device(struct pci_dev *dev, int mask)
112{
113 u16 cmd, old_cmd;
114 int idx;
115 struct resource *r;
116
117 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
118 pcibios_enable_bridge(dev);
119 }
120
121 pci_read_config_word(dev, PCI_COMMAND, &cmd);
122 old_cmd = cmd;
123 for(idx=0; idx<6; idx++) {
124 if (!(mask & (1 << idx)))
125 continue;
126 r = &dev->resource[idx];
127 if (!r->start && r->end) {
128 printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", pci_name(dev));
129 return -EINVAL;
130 }
131 if (r->flags & IORESOURCE_IO)
132 cmd |= PCI_COMMAND_IO;
133 if (r->flags & IORESOURCE_MEM)
134 cmd |= PCI_COMMAND_MEMORY;
135 }
136 if (dev->resource[PCI_ROM_RESOURCE].start)
137 cmd |= PCI_COMMAND_MEMORY;
138 if (cmd != old_cmd) {
139 printk(KERN_INFO "PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd);
140 pci_write_config_word(dev, PCI_COMMAND, cmd);
141 }
142 return 0;
143}
144
145/*
146 * If we set up a device for bus mastering, we need to check and set
147 * the latency timer as it may not be properly set.
148 */
149unsigned int pcibios_max_latency = 255;
150
151void pcibios_set_master(struct pci_dev *dev)
152{
153 u8 lat;
154 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
155 if (lat < 16)
156 lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
157 else if (lat > pcibios_max_latency)
158 lat = pcibios_max_latency;
159 else
160 return;
161 printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n", pci_name(dev), lat);
162 pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
163}
164
165void __init pcibios_update_irq(struct pci_dev *dev, int irq)
166{
167 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
168}
diff --git a/arch/sh64/kernel/semaphore.c b/arch/sh64/kernel/semaphore.c
deleted file mode 100644
index 72c16533436e..000000000000
--- a/arch/sh64/kernel/semaphore.c
+++ /dev/null
@@ -1,140 +0,0 @@
1/*
2 * Just taken from alpha implementation.
3 * This can't work well, perhaps.
4 */
5/*
6 * Generic semaphore code. Buyer beware. Do your own
7 * specific changes in <asm/semaphore-helper.h>
8 */
9
10#include <linux/errno.h>
11#include <linux/rwsem.h>
12#include <linux/sched.h>
13#include <linux/wait.h>
14#include <linux/init.h>
15#include <asm/semaphore.h>
16#include <asm/semaphore-helper.h>
17
18spinlock_t semaphore_wake_lock;
19
20/*
21 * Semaphores are implemented using a two-way counter:
22 * The "count" variable is decremented for each process
23 * that tries to sleep, while the "waking" variable is
24 * incremented when the "up()" code goes to wake up waiting
25 * processes.
26 *
27 * Notably, the inline "up()" and "down()" functions can
28 * efficiently test if they need to do any extra work (up
29 * needs to do something only if count was negative before
30 * the increment operation.
31 *
32 * waking_non_zero() (from asm/semaphore.h) must execute
33 * atomically.
34 *
35 * When __up() is called, the count was negative before
36 * incrementing it, and we need to wake up somebody.
37 *
38 * This routine adds one to the count of processes that need to
39 * wake up and exit. ALL waiting processes actually wake up but
40 * only the one that gets to the "waking" field first will gate
41 * through and acquire the semaphore. The others will go back
42 * to sleep.
43 *
44 * Note that these functions are only called when there is
45 * contention on the lock, and as such all this is the
46 * "non-critical" part of the whole semaphore business. The
47 * critical part is the inline stuff in <asm/semaphore.h>
48 * where we want to avoid any extra jumps and calls.
49 */
50void __up(struct semaphore *sem)
51{
52 wake_one_more(sem);
53 wake_up(&sem->wait);
54}
55
56/*
57 * Perform the "down" function. Return zero for semaphore acquired,
58 * return negative for signalled out of the function.
59 *
60 * If called from __down, the return is ignored and the wait loop is
61 * not interruptible. This means that a task waiting on a semaphore
62 * using "down()" cannot be killed until someone does an "up()" on
63 * the semaphore.
64 *
65 * If called from __down_interruptible, the return value gets checked
66 * upon return. If the return value is negative then the task continues
67 * with the negative value in the return register (it can be tested by
68 * the caller).
69 *
70 * Either form may be used in conjunction with "up()".
71 *
72 */
73
74#define DOWN_VAR \
75 struct task_struct *tsk = current; \
76 wait_queue_t wait; \
77 init_waitqueue_entry(&wait, tsk);
78
79#define DOWN_HEAD(task_state) \
80 \
81 \
82 tsk->state = (task_state); \
83 add_wait_queue(&sem->wait, &wait); \
84 \
85 /* \
86 * Ok, we're set up. sem->count is known to be less than zero \
87 * so we must wait. \
88 * \
89 * We can let go the lock for purposes of waiting. \
90 * We re-acquire it after awaking so as to protect \
91 * all semaphore operations. \
92 * \
93 * If "up()" is called before we call waking_non_zero() then \
94 * we will catch it right away. If it is called later then \
95 * we will have to go through a wakeup cycle to catch it. \
96 * \
97 * Multiple waiters contend for the semaphore lock to see \
98 * who gets to gate through and who has to wait some more. \
99 */ \
100 for (;;) {
101
102#define DOWN_TAIL(task_state) \
103 tsk->state = (task_state); \
104 } \
105 tsk->state = TASK_RUNNING; \
106 remove_wait_queue(&sem->wait, &wait);
107
108void __sched __down(struct semaphore * sem)
109{
110 DOWN_VAR
111 DOWN_HEAD(TASK_UNINTERRUPTIBLE)
112 if (waking_non_zero(sem))
113 break;
114 schedule();
115 DOWN_TAIL(TASK_UNINTERRUPTIBLE)
116}
117
118int __sched __down_interruptible(struct semaphore * sem)
119{
120 int ret = 0;
121 DOWN_VAR
122 DOWN_HEAD(TASK_INTERRUPTIBLE)
123
124 ret = waking_non_zero_interruptible(sem, tsk);
125 if (ret)
126 {
127 if (ret == 1)
128 /* ret != 0 only if we get interrupted -arca */
129 ret = 0;
130 break;
131 }
132 schedule();
133 DOWN_TAIL(TASK_INTERRUPTIBLE)
134 return ret;
135}
136
137int __down_trylock(struct semaphore * sem)
138{
139 return waking_non_zero_trylock(sem);
140}
diff --git a/arch/sh64/kernel/setup.c b/arch/sh64/kernel/setup.c
deleted file mode 100644
index 2b7264c0c6f7..000000000000
--- a/arch/sh64/kernel/setup.c
+++ /dev/null
@@ -1,379 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * arch/sh64/kernel/setup.c
7 *
8 * sh64 Arch Support
9 *
10 * This file handles the architecture-dependent parts of initialization
11 *
12 * Copyright (C) 2000, 2001 Paolo Alberelli
13 * Copyright (C) 2003, 2004 Paul Mundt
14 *
15 * benedict.gaster@superh.com: 2nd May 2002
16 * Modified to use the empty_zero_page to pass command line arguments.
17 *
18 * benedict.gaster@superh.com: 3rd May 2002
19 * Added support for ramdisk, removing statically linked romfs at the same time.
20 *
21 * lethal@linux-sh.org: 15th May 2003
22 * Added generic procfs cpuinfo reporting. Make boards just export their name.
23 *
24 * lethal@linux-sh.org: 25th May 2003
25 * Added generic get_cpu_subtype() for subtype reporting from cpu_data->type.
26 *
27 */
28#include <linux/errno.h>
29#include <linux/rwsem.h>
30#include <linux/sched.h>
31#include <linux/kernel.h>
32#include <linux/mm.h>
33#include <linux/stddef.h>
34#include <linux/unistd.h>
35#include <linux/ptrace.h>
36#include <linux/slab.h>
37#include <linux/user.h>
38#include <linux/a.out.h>
39#include <linux/screen_info.h>
40#include <linux/ioport.h>
41#include <linux/delay.h>
42#include <linux/init.h>
43#include <linux/seq_file.h>
44#include <linux/blkdev.h>
45#include <linux/bootmem.h>
46#include <linux/console.h>
47#include <linux/root_dev.h>
48#include <linux/cpu.h>
49#include <linux/initrd.h>
50#include <linux/pfn.h>
51#include <asm/processor.h>
52#include <asm/page.h>
53#include <asm/pgtable.h>
54#include <asm/platform.h>
55#include <asm/uaccess.h>
56#include <asm/system.h>
57#include <asm/io.h>
58#include <asm/sections.h>
59#include <asm/setup.h>
60#include <asm/smp.h>
61
62struct screen_info screen_info;
63
64#ifdef CONFIG_BLK_DEV_RAM
65extern int rd_doload; /* 1 = load ramdisk, 0 = don't load */
66extern int rd_prompt; /* 1 = prompt for ramdisk, 0 = don't prompt */
67extern int rd_image_start; /* starting block # of image */
68#endif
69
70extern int root_mountflags;
71extern char *get_system_type(void);
72extern void platform_setup(void);
73extern void platform_monitor(void);
74extern void platform_reserve(void);
75extern int sh64_cache_init(void);
76extern int sh64_tlb_init(void);
77
78#define RAMDISK_IMAGE_START_MASK 0x07FF
79#define RAMDISK_PROMPT_FLAG 0x8000
80#define RAMDISK_LOAD_FLAG 0x4000
81
82static char __initdata command_line[COMMAND_LINE_SIZE] = { 0, };
83unsigned long long memory_start = CONFIG_MEMORY_START;
84unsigned long long memory_end = CONFIG_MEMORY_START + (CONFIG_MEMORY_SIZE_IN_MB * 1024 * 1024);
85
86struct sh_cpuinfo boot_cpu_data;
87
88static inline void parse_mem_cmdline (char ** cmdline_p)
89{
90 char c = ' ', *to = command_line, *from = COMMAND_LINE;
91 int len = 0;
92
93 /* Save unparsed command line copy for /proc/cmdline */
94 memcpy(boot_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
95 boot_command_line[COMMAND_LINE_SIZE-1] = '\0';
96
97 for (;;) {
98 /*
99 * "mem=XXX[kKmM]" defines a size of memory.
100 */
101 if (c == ' ' && !memcmp(from, "mem=", 4)) {
102 if (to != command_line)
103 to--;
104 {
105 unsigned long mem_size;
106
107 mem_size = memparse(from+4, &from);
108 memory_end = memory_start + mem_size;
109 }
110 }
111 c = *(from++);
112 if (!c)
113 break;
114 if (COMMAND_LINE_SIZE <= ++len)
115 break;
116 *(to++) = c;
117 }
118 *to = '\0';
119
120 *cmdline_p = command_line;
121}
122
123static void __init sh64_cpu_type_detect(void)
124{
125 extern unsigned long long peek_real_address_q(unsigned long long addr);
126 unsigned long long cir;
127 /* Do peeks in real mode to avoid having to set up a mapping for the
128 WPC registers. On SH5-101 cut2, such a mapping would be exposed to
129 an address translation erratum which would make it hard to set up
130 correctly. */
131 cir = peek_real_address_q(0x0d000008);
132
133 if ((cir & 0xffff) == 0x5103) {
134 boot_cpu_data.type = CPU_SH5_103;
135 } else if (((cir >> 32) & 0xffff) == 0x51e2) {
136 /* CPU.VCR aliased at CIR address on SH5-101 */
137 boot_cpu_data.type = CPU_SH5_101;
138 } else {
139 boot_cpu_data.type = CPU_SH_NONE;
140 }
141}
142
143void __init setup_arch(char **cmdline_p)
144{
145 unsigned long bootmap_size, i;
146 unsigned long first_pfn, start_pfn, last_pfn, pages;
147
148#ifdef CONFIG_EARLY_PRINTK
149 extern void enable_early_printk(void);
150
151 /*
152 * Setup Early SCIF console
153 */
154 enable_early_printk();
155#endif
156
157 /*
158 * Setup TLB mappings
159 */
160 sh64_tlb_init();
161
162 /*
163 * Caches are already initialized by the time we get here, so we just
164 * fill in cpu_data info for the caches.
165 */
166 sh64_cache_init();
167
168 platform_setup();
169 platform_monitor();
170
171 sh64_cpu_type_detect();
172
173 ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
174
175#ifdef CONFIG_BLK_DEV_RAM
176 rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
177 rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
178 rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
179#endif
180
181 if (!MOUNT_ROOT_RDONLY)
182 root_mountflags &= ~MS_RDONLY;
183 init_mm.start_code = (unsigned long) _text;
184 init_mm.end_code = (unsigned long) _etext;
185 init_mm.end_data = (unsigned long) _edata;
186 init_mm.brk = (unsigned long) _end;
187
188 code_resource.start = __pa(_text);
189 code_resource.end = __pa(_etext)-1;
190 data_resource.start = __pa(_etext);
191 data_resource.end = __pa(_edata)-1;
192
193 parse_mem_cmdline(cmdline_p);
194
195 /*
196 * Find the lowest and highest page frame numbers we have available
197 */
198 first_pfn = PFN_DOWN(memory_start);
199 last_pfn = PFN_DOWN(memory_end);
200 pages = last_pfn - first_pfn;
201
202 /*
203 * Partially used pages are not usable - thus
204 * we are rounding upwards:
205 */
206 start_pfn = PFN_UP(__pa(_end));
207
208 /*
209 * Find a proper area for the bootmem bitmap. After this
210 * bootstrap step all allocations (until the page allocator
211 * is intact) must be done via bootmem_alloc().
212 */
213 bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn,
214 first_pfn,
215 last_pfn);
216 /*
217 * Round it up.
218 */
219 bootmap_size = PFN_PHYS(PFN_UP(bootmap_size));
220
221 /*
222 * Register fully available RAM pages with the bootmem allocator.
223 */
224 free_bootmem_node(NODE_DATA(0), PFN_PHYS(first_pfn), PFN_PHYS(pages));
225
226 /*
227 * Reserve all kernel sections + bootmem bitmap + a guard page.
228 */
229 reserve_bootmem_node(NODE_DATA(0), PFN_PHYS(first_pfn),
230 (PFN_PHYS(start_pfn) + bootmap_size + PAGE_SIZE) - PFN_PHYS(first_pfn));
231
232 /*
233 * Reserve platform dependent sections
234 */
235 platform_reserve();
236
237#ifdef CONFIG_BLK_DEV_INITRD
238 if (LOADER_TYPE && INITRD_START) {
239 if (INITRD_START + INITRD_SIZE <= (PFN_PHYS(last_pfn))) {
240 reserve_bootmem_node(NODE_DATA(0), INITRD_START + __MEMORY_START, INITRD_SIZE);
241
242 initrd_start = (long) INITRD_START + PAGE_OFFSET + __MEMORY_START;
243 initrd_end = initrd_start + INITRD_SIZE;
244 } else {
245 printk("initrd extends beyond end of memory "
246 "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
247 (long) INITRD_START + INITRD_SIZE,
248 PFN_PHYS(last_pfn));
249 initrd_start = 0;
250 }
251 }
252#endif
253
254 /*
255 * Claim all RAM, ROM, and I/O resources.
256 */
257
258 /* Kernel RAM */
259 request_resource(&iomem_resource, &code_resource);
260 request_resource(&iomem_resource, &data_resource);
261
262 /* Other KRAM space */
263 for (i = 0; i < STANDARD_KRAM_RESOURCES - 2; i++)
264 request_resource(&iomem_resource,
265 &platform_parms.kram_res_p[i]);
266
267 /* XRAM space */
268 for (i = 0; i < STANDARD_XRAM_RESOURCES; i++)
269 request_resource(&iomem_resource,
270 &platform_parms.xram_res_p[i]);
271
272 /* ROM space */
273 for (i = 0; i < STANDARD_ROM_RESOURCES; i++)
274 request_resource(&iomem_resource,
275 &platform_parms.rom_res_p[i]);
276
277 /* I/O space */
278 for (i = 0; i < STANDARD_IO_RESOURCES; i++)
279 request_resource(&ioport_resource,
280 &platform_parms.io_res_p[i]);
281
282
283#ifdef CONFIG_VT
284#if defined(CONFIG_VGA_CONSOLE)
285 conswitchp = &vga_con;
286#elif defined(CONFIG_DUMMY_CONSOLE)
287 conswitchp = &dummy_con;
288#endif
289#endif
290
291 printk("Hardware FPU: %s\n", fpu_in_use ? "enabled" : "disabled");
292
293 paging_init();
294}
295
296void __xchg_called_with_bad_pointer(void)
297{
298 printk(KERN_EMERG "xchg() called with bad pointer !\n");
299}
300
301static struct cpu cpu[1];
302
303static int __init topology_init(void)
304{
305 return register_cpu(cpu, 0);
306}
307
308subsys_initcall(topology_init);
309
310/*
311 * Get CPU information
312 */
313static const char *cpu_name[] = {
314 [CPU_SH5_101] = "SH5-101",
315 [CPU_SH5_103] = "SH5-103",
316 [CPU_SH_NONE] = "Unknown",
317};
318
319const char *get_cpu_subtype(void)
320{
321 return cpu_name[boot_cpu_data.type];
322}
323
324#ifdef CONFIG_PROC_FS
325static int show_cpuinfo(struct seq_file *m,void *v)
326{
327 unsigned int cpu = smp_processor_id();
328
329 if (!cpu)
330 seq_printf(m, "machine\t\t: %s\n", get_system_type());
331
332 seq_printf(m, "processor\t: %d\n", cpu);
333 seq_printf(m, "cpu family\t: SH-5\n");
334 seq_printf(m, "cpu type\t: %s\n", get_cpu_subtype());
335
336 seq_printf(m, "icache size\t: %dK-bytes\n",
337 (boot_cpu_data.icache.ways *
338 boot_cpu_data.icache.sets *
339 boot_cpu_data.icache.linesz) >> 10);
340 seq_printf(m, "dcache size\t: %dK-bytes\n",
341 (boot_cpu_data.dcache.ways *
342 boot_cpu_data.dcache.sets *
343 boot_cpu_data.dcache.linesz) >> 10);
344 seq_printf(m, "itlb entries\t: %d\n", boot_cpu_data.itlb.entries);
345 seq_printf(m, "dtlb entries\t: %d\n", boot_cpu_data.dtlb.entries);
346
347#define PRINT_CLOCK(name, value) \
348 seq_printf(m, name " clock\t: %d.%02dMHz\n", \
349 ((value) / 1000000), ((value) % 1000000)/10000)
350
351 PRINT_CLOCK("cpu", boot_cpu_data.cpu_clock);
352 PRINT_CLOCK("bus", boot_cpu_data.bus_clock);
353 PRINT_CLOCK("module", boot_cpu_data.module_clock);
354
355 seq_printf(m, "bogomips\t: %lu.%02lu\n\n",
356 (loops_per_jiffy*HZ+2500)/500000,
357 ((loops_per_jiffy*HZ+2500)/5000) % 100);
358
359 return 0;
360}
361
362static void *c_start(struct seq_file *m, loff_t *pos)
363{
364 return (void*)(*pos == 0);
365}
366static void *c_next(struct seq_file *m, void *v, loff_t *pos)
367{
368 return NULL;
369}
370static void c_stop(struct seq_file *m, void *v)
371{
372}
373struct seq_operations cpuinfo_op = {
374 .start = c_start,
375 .next = c_next,
376 .stop = c_stop,
377 .show = show_cpuinfo,
378};
379#endif /* CONFIG_PROC_FS */
diff --git a/arch/sh64/kernel/sys_sh64.c b/arch/sh64/kernel/sys_sh64.c
deleted file mode 100644
index de0a303ba26f..000000000000
--- a/arch/sh64/kernel/sys_sh64.c
+++ /dev/null
@@ -1,304 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * arch/sh64/kernel/sys_sh64.c
7 *
8 * Copyright (C) 2000, 2001 Paolo Alberelli
9 *
10 * This file contains various random system calls that
11 * have a non-standard calling sequence on the Linux/SH5
12 * platform.
13 *
14 * Mostly taken from i386 version.
15 *
16 */
17
18#include <linux/errno.h>
19#include <linux/rwsem.h>
20#include <linux/sched.h>
21#include <linux/mm.h>
22#include <linux/fs.h>
23#include <linux/smp.h>
24#include <linux/sem.h>
25#include <linux/msg.h>
26#include <linux/shm.h>
27#include <linux/stat.h>
28#include <linux/mman.h>
29#include <linux/file.h>
30#include <linux/utsname.h>
31#include <linux/syscalls.h>
32#include <linux/ipc.h>
33#include <asm/uaccess.h>
34#include <asm/ptrace.h>
35#include <asm/unistd.h>
36
37#define REG_3 3
38
39/*
40 * sys_pipe() is the normal C calling standard for creating
41 * a pipe. It's not the way Unix traditionally does this, though.
42 */
43#ifdef NEW_PIPE_IMPLEMENTATION
44asmlinkage int sys_pipe(unsigned long * fildes,
45 unsigned long dummy_r3,
46 unsigned long dummy_r4,
47 unsigned long dummy_r5,
48 unsigned long dummy_r6,
49 unsigned long dummy_r7,
50 struct pt_regs * regs) /* r8 = pt_regs forced by entry.S */
51{
52 int fd[2];
53 int ret;
54
55 ret = do_pipe(fd);
56 if (ret == 0)
57 /*
58 ***********************************************************************
59 * To avoid the copy_to_user we prefer to break the ABIs convention, *
60 * packing the valid pair of file IDs into a single register (r3); *
61 * while r2 is the return code as defined by the sh5-ABIs. *
62 * BE CAREFUL: pipe stub, into glibc, must be aware of this solution *
63 ***********************************************************************
64
65#ifdef __LITTLE_ENDIAN__
66 regs->regs[REG_3] = (((unsigned long long) fd[1]) << 32) | ((unsigned long long) fd[0]);
67#else
68 regs->regs[REG_3] = (((unsigned long long) fd[0]) << 32) | ((unsigned long long) fd[1]);
69#endif
70
71 */
72 /* although not very clever this is endianess independent */
73 regs->regs[REG_3] = (unsigned long long) *((unsigned long long *) fd);
74
75 return ret;
76}
77
78#else
79asmlinkage int sys_pipe(unsigned long * fildes)
80{
81 int fd[2];
82 int error;
83
84 error = do_pipe(fd);
85 if (!error) {
86 if (copy_to_user(fildes, fd, 2*sizeof(int)))
87 error = -EFAULT;
88 }
89 return error;
90}
91
92#endif
93
94/*
95 * To avoid cache alias, we map the shard page with same color.
96 */
97#define COLOUR_ALIGN(addr) (((addr)+SHMLBA-1)&~(SHMLBA-1))
98
99unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
100 unsigned long len, unsigned long pgoff, unsigned long flags)
101{
102 struct vm_area_struct *vma;
103
104 if (flags & MAP_FIXED) {
105 /* We do not accept a shared mapping if it would violate
106 * cache aliasing constraints.
107 */
108 if ((flags & MAP_SHARED) && (addr & (SHMLBA - 1)))
109 return -EINVAL;
110 return addr;
111 }
112
113 if (len > TASK_SIZE)
114 return -ENOMEM;
115 if (!addr)
116 addr = TASK_UNMAPPED_BASE;
117
118 if (flags & MAP_PRIVATE)
119 addr = PAGE_ALIGN(addr);
120 else
121 addr = COLOUR_ALIGN(addr);
122
123 for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
124 /* At this point: (!vma || addr < vma->vm_end). */
125 if (TASK_SIZE - len < addr)
126 return -ENOMEM;
127 if (!vma || addr + len <= vma->vm_start)
128 return addr;
129 addr = vma->vm_end;
130 if (!(flags & MAP_PRIVATE))
131 addr = COLOUR_ALIGN(addr);
132 }
133}
134
135/* common code for old and new mmaps */
136static inline long do_mmap2(
137 unsigned long addr, unsigned long len,
138 unsigned long prot, unsigned long flags,
139 unsigned long fd, unsigned long pgoff)
140{
141 int error = -EBADF;
142 struct file * file = NULL;
143
144 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
145 if (!(flags & MAP_ANONYMOUS)) {
146 file = fget(fd);
147 if (!file)
148 goto out;
149 }
150
151 down_write(&current->mm->mmap_sem);
152 error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
153 up_write(&current->mm->mmap_sem);
154
155 if (file)
156 fput(file);
157out:
158 return error;
159}
160
161asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
162 unsigned long prot, unsigned long flags,
163 unsigned long fd, unsigned long pgoff)
164{
165 return do_mmap2(addr, len, prot, flags, fd, pgoff);
166}
167
168asmlinkage int old_mmap(unsigned long addr, unsigned long len,
169 unsigned long prot, unsigned long flags,
170 int fd, unsigned long off)
171{
172 if (off & ~PAGE_MASK)
173 return -EINVAL;
174 return do_mmap2(addr, len, prot, flags, fd, off>>PAGE_SHIFT);
175}
176
177/*
178 * sys_ipc() is the de-multiplexer for the SysV IPC calls..
179 *
180 * This is really horribly ugly.
181 */
182asmlinkage int sys_ipc(uint call, int first, int second,
183 int third, void __user *ptr, long fifth)
184{
185 int version, ret;
186
187 version = call >> 16; /* hack for backward compatibility */
188 call &= 0xffff;
189
190 if (call <= SEMCTL)
191 switch (call) {
192 case SEMOP:
193 return sys_semtimedop(first, (struct sembuf __user *)ptr,
194 second, NULL);
195 case SEMTIMEDOP:
196 return sys_semtimedop(first, (struct sembuf __user *)ptr,
197 second,
198 (const struct timespec __user *)fifth);
199 case SEMGET:
200 return sys_semget (first, second, third);
201 case SEMCTL: {
202 union semun fourth;
203 if (!ptr)
204 return -EINVAL;
205 if (get_user(fourth.__pad, (void * __user *) ptr))
206 return -EFAULT;
207 return sys_semctl (first, second, third, fourth);
208 }
209 default:
210 return -EINVAL;
211 }
212
213 if (call <= MSGCTL)
214 switch (call) {
215 case MSGSND:
216 return sys_msgsnd (first, (struct msgbuf __user *) ptr,
217 second, third);
218 case MSGRCV:
219 switch (version) {
220 case 0: {
221 struct ipc_kludge tmp;
222 if (!ptr)
223 return -EINVAL;
224
225 if (copy_from_user(&tmp,
226 (struct ipc_kludge __user *) ptr,
227 sizeof (tmp)))
228 return -EFAULT;
229 return sys_msgrcv (first, tmp.msgp, second,
230 tmp.msgtyp, third);
231 }
232 default:
233 return sys_msgrcv (first,
234 (struct msgbuf __user *) ptr,
235 second, fifth, third);
236 }
237 case MSGGET:
238 return sys_msgget ((key_t) first, second);
239 case MSGCTL:
240 return sys_msgctl (first, second,
241 (struct msqid_ds __user *) ptr);
242 default:
243 return -EINVAL;
244 }
245 if (call <= SHMCTL)
246 switch (call) {
247 case SHMAT:
248 switch (version) {
249 default: {
250 ulong raddr;
251 ret = do_shmat (first, (char __user *) ptr,
252 second, &raddr);
253 if (ret)
254 return ret;
255 return put_user (raddr, (ulong __user *) third);
256 }
257 case 1: /* iBCS2 emulator entry point */
258 if (!segment_eq(get_fs(), get_ds()))
259 return -EINVAL;
260 return do_shmat (first, (char __user *) ptr,
261 second, (ulong *) third);
262 }
263 case SHMDT:
264 return sys_shmdt ((char __user *)ptr);
265 case SHMGET:
266 return sys_shmget (first, second, third);
267 case SHMCTL:
268 return sys_shmctl (first, second,
269 (struct shmid_ds __user *) ptr);
270 default:
271 return -EINVAL;
272 }
273
274 return -EINVAL;
275}
276
277asmlinkage int sys_uname(struct old_utsname * name)
278{
279 int err;
280 if (!name)
281 return -EFAULT;
282 down_read(&uts_sem);
283 err = copy_to_user(name, utsname(), sizeof (*name));
284 up_read(&uts_sem);
285 return err?-EFAULT:0;
286}
287
288/*
289 * Do a system call from kernel instead of calling sys_execve so we
290 * end up with proper pt_regs.
291 */
292int kernel_execve(const char *filename, char *const argv[], char *const envp[])
293{
294 register unsigned long __sc0 __asm__ ("r9") = ((0x13 << 16) | __NR_execve);
295 register unsigned long __sc2 __asm__ ("r2") = (unsigned long) filename;
296 register unsigned long __sc3 __asm__ ("r3") = (unsigned long) argv;
297 register unsigned long __sc4 __asm__ ("r4") = (unsigned long) envp;
298 __asm__ __volatile__ ("trapa %1 !\t\t\t execve(%2,%3,%4)"
299 : "=r" (__sc0)
300 : "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4) );
301 __asm__ __volatile__ ("!dummy %0 %1 %2 %3"
302 : : "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4) : "memory");
303 return __sc0;
304}
diff --git a/arch/sh64/kernel/vmlinux.lds.S b/arch/sh64/kernel/vmlinux.lds.S
deleted file mode 100644
index f533a064da5f..000000000000
--- a/arch/sh64/kernel/vmlinux.lds.S
+++ /dev/null
@@ -1,140 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * arch/sh5/vmlinux.lds.S
7 *
8 * ld script to make ST50 Linux kernel
9 *
10 * Copyright (C) 2000, 2001 Paolo Alberelli
11 *
12 * benedict.gaster@superh.com: 2nd May 2002
13 * Add definition of empty_zero_page to be the first page of kernel image.
14 *
15 * benedict.gaster@superh.com: 3rd May 2002
16 * Added support for ramdisk, removing statically linked romfs at the same time.
17 *
18 * lethal@linux-sh.org: 9th May 2003
19 * Kill off GLOBAL_NAME() usage and other CDC-isms.
20 *
21 * lethal@linux-sh.org: 19th May 2003
22 * Remove support for ancient toolchains.
23 */
24
25#include <asm/page.h>
26#include <asm/cache.h>
27#include <asm/processor.h>
28#include <asm/thread_info.h>
29
30#define LOAD_OFFSET CONFIG_CACHED_MEMORY_OFFSET
31#include <asm-generic/vmlinux.lds.h>
32
33OUTPUT_ARCH(sh:sh5)
34
35#define C_PHYS(x) AT (ADDR(x) - LOAD_OFFSET)
36
37ENTRY(__start)
38SECTIONS
39{
40 . = CONFIG_CACHED_MEMORY_OFFSET + CONFIG_MEMORY_START + PAGE_SIZE;
41 _text = .; /* Text and read-only data */
42 text = .; /* Text and read-only data */
43
44 .empty_zero_page : C_PHYS(.empty_zero_page) {
45 *(.empty_zero_page)
46 } = 0
47
48 .text : C_PHYS(.text) {
49 *(.text.head)
50 TEXT_TEXT
51 *(.text64)
52 *(.text..SHmedia32)
53 SCHED_TEXT
54 LOCK_TEXT
55 *(.fixup)
56 *(.gnu.warning)
57#ifdef CONFIG_LITTLE_ENDIAN
58 } = 0x6ff0fff0
59#else
60 } = 0xf0fff06f
61#endif
62
63 /* We likely want __ex_table to be Cache Line aligned */
64 . = ALIGN(L1_CACHE_BYTES); /* Exception table */
65 __start___ex_table = .;
66 __ex_table : C_PHYS(__ex_table) { *(__ex_table) }
67 __stop___ex_table = .;
68
69 _etext = .; /* End of text section */
70
71 NOTES
72
73 RODATA
74
75 .data : C_PHYS(.data) { /* Data */
76 DATA_DATA
77 CONSTRUCTORS
78 }
79
80 . = ALIGN(PAGE_SIZE);
81 .data.page_aligned : C_PHYS(.data.page_aligned) { *(.data.page_aligned) }
82
83 PERCPU(PAGE_SIZE)
84
85 . = ALIGN(L1_CACHE_BYTES);
86 .data.cacheline_aligned : C_PHYS(.data.cacheline_aligned) { *(.data.cacheline_aligned) }
87
88 _edata = .; /* End of data section */
89
90 . = ALIGN(THREAD_SIZE); /* init_task: structure size aligned */
91 .data.init_task : C_PHYS(.data.init_task) { *(.data.init_task) }
92
93 . = ALIGN(PAGE_SIZE); /* Init code and data */
94 __init_begin = .;
95 _sinittext = .;
96 .init.text : C_PHYS(.init.text) { *(.init.text) }
97 _einittext = .;
98 .init.data : C_PHYS(.init.data) { *(.init.data) }
99 . = ALIGN(L1_CACHE_BYTES); /* Better if Cache Line aligned */
100 __setup_start = .;
101 .init.setup : C_PHYS(.init.setup) { *(.init.setup) }
102 __setup_end = .;
103 __initcall_start = .;
104 .initcall.init : C_PHYS(.initcall.init) {
105 INITCALLS
106 }
107 __initcall_end = .;
108 __con_initcall_start = .;
109 .con_initcall.init : C_PHYS(.con_initcall.init) { *(.con_initcall.init) }
110 __con_initcall_end = .;
111 SECURITY_INIT
112
113#ifdef CONFIG_BLK_DEV_INITRD
114 __initramfs_start = .;
115 .init.ramfs : C_PHYS(.init.ramfs) { *(.init.ramfs) }
116 __initramfs_end = .;
117#endif
118
119 . = ALIGN(PAGE_SIZE);
120 __init_end = .;
121
122 /* Align to the biggest single data representation, head and tail */
123 . = ALIGN(8);
124 __bss_start = .; /* BSS */
125 .bss : C_PHYS(.bss) {
126 *(.bss)
127 }
128 . = ALIGN(8);
129 _end = . ;
130
131 /* Sections to be discarded */
132 /DISCARD/ : {
133 *(.exit.text)
134 *(.exit.data)
135 *(.exitcall.exit)
136 }
137
138 STABS_DEBUG
139 DWARF_DEBUG
140}
diff --git a/arch/sh64/lib/Makefile b/arch/sh64/lib/Makefile
deleted file mode 100644
index 6a4cc3f9c0b1..000000000000
--- a/arch/sh64/lib/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
1#
2# This file is subject to the terms and conditions of the GNU General Public
3# License. See the file "COPYING" in the main directory of this archive
4# for more details.
5#
6# Copyright (C) 2000, 2001 Paolo Alberelli
7# Coprygith (C) 2003 Paul Mundt
8#
9# Makefile for the SH-5 specific library files..
10#
11# Note! Dependencies are done automagically by 'make dep', which also
12# removes any old dependencies. DON'T put your own dependencies here
13# unless it's something special (ie not a .c file).
14#
15
16# Panic should really be compiled as PIC
17lib-y := udelay.o c-checksum.o dbg.o io.o panic.o memcpy.o copy_user_memcpy.o \
18 page_copy.o page_clear.o iomap.o
19
diff --git a/arch/sh64/lib/io.c b/arch/sh64/lib/io.c
deleted file mode 100644
index a3f3a2b8e25b..000000000000
--- a/arch/sh64/lib/io.c
+++ /dev/null
@@ -1,128 +0,0 @@
1/*
2 * Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
3 *
4 * May be copied or modified under the terms of the GNU General Public
5 * License. See linux/COPYING for more information.
6 *
7 * This file contains the I/O routines for use on the overdrive board
8 *
9 */
10
11#include <linux/kernel.h>
12#include <linux/types.h>
13#include <linux/delay.h>
14#include <linux/module.h>
15#include <asm/system.h>
16#include <asm/processor.h>
17#include <asm/io.h>
18
19/* Now for the string version of these functions */
20void outsb(unsigned long port, const void *addr, unsigned long count)
21{
22 int i;
23 unsigned char *p = (unsigned char *) addr;
24
25 for (i = 0; i < count; i++, p++) {
26 outb(*p, port);
27 }
28}
29EXPORT_SYMBOL(outsb);
30
31void insb(unsigned long port, void *addr, unsigned long count)
32{
33 int i;
34 unsigned char *p = (unsigned char *) addr;
35
36 for (i = 0; i < count; i++, p++) {
37 *p = inb(port);
38 }
39}
40EXPORT_SYMBOL(insb);
41
42/* For the 16 and 32 bit string functions, we have to worry about alignment.
43 * The SH does not do unaligned accesses, so we have to read as bytes and
44 * then write as a word or dword.
45 * This can be optimised a lot more, especially in the case where the data
46 * is aligned
47 */
48
49void outsw(unsigned long port, const void *addr, unsigned long count)
50{
51 int i;
52 unsigned short tmp;
53 unsigned char *p = (unsigned char *) addr;
54
55 for (i = 0; i < count; i++, p += 2) {
56 tmp = (*p) | ((*(p + 1)) << 8);
57 outw(tmp, port);
58 }
59}
60EXPORT_SYMBOL(outsw);
61
62void insw(unsigned long port, void *addr, unsigned long count)
63{
64 int i;
65 unsigned short tmp;
66 unsigned char *p = (unsigned char *) addr;
67
68 for (i = 0; i < count; i++, p += 2) {
69 tmp = inw(port);
70 p[0] = tmp & 0xff;
71 p[1] = (tmp >> 8) & 0xff;
72 }
73}
74EXPORT_SYMBOL(insw);
75
76void outsl(unsigned long port, const void *addr, unsigned long count)
77{
78 int i;
79 unsigned tmp;
80 unsigned char *p = (unsigned char *) addr;
81
82 for (i = 0; i < count; i++, p += 4) {
83 tmp = (*p) | ((*(p + 1)) << 8) | ((*(p + 2)) << 16) |
84 ((*(p + 3)) << 24);
85 outl(tmp, port);
86 }
87}
88EXPORT_SYMBOL(outsl);
89
90void insl(unsigned long port, void *addr, unsigned long count)
91{
92 int i;
93 unsigned tmp;
94 unsigned char *p = (unsigned char *) addr;
95
96 for (i = 0; i < count; i++, p += 4) {
97 tmp = inl(port);
98 p[0] = tmp & 0xff;
99 p[1] = (tmp >> 8) & 0xff;
100 p[2] = (tmp >> 16) & 0xff;
101 p[3] = (tmp >> 24) & 0xff;
102
103 }
104}
105EXPORT_SYMBOL(insl);
106
107void memcpy_toio(void __iomem *to, const void *from, long count)
108{
109 unsigned char *p = (unsigned char *) from;
110
111 while (count) {
112 count--;
113 writeb(*p++, to++);
114 }
115}
116EXPORT_SYMBOL(memcpy_toio);
117
118void memcpy_fromio(void *to, void __iomem *from, long count)
119{
120 int i;
121 unsigned char *p = (unsigned char *) to;
122
123 for (i = 0; i < count; i++) {
124 p[i] = readb(from);
125 from++;
126 }
127}
128EXPORT_SYMBOL(memcpy_fromio);
diff --git a/arch/sh64/lib/iomap.c b/arch/sh64/lib/iomap.c
deleted file mode 100644
index 253d1e351d49..000000000000
--- a/arch/sh64/lib/iomap.c
+++ /dev/null
@@ -1,54 +0,0 @@
1/*
2 * arch/sh64/lib/iomap.c
3 *
4 * Generic sh64 iomap interface
5 *
6 * Copyright (C) 2004 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/pci.h>
13#include <asm/io.h>
14
15void __iomem *__attribute__ ((weak))
16ioport_map(unsigned long port, unsigned int len)
17{
18 return (void __iomem *)port;
19}
20EXPORT_SYMBOL(ioport_map);
21
22void ioport_unmap(void __iomem *addr)
23{
24 /* Nothing .. */
25}
26EXPORT_SYMBOL(ioport_unmap);
27
28#ifdef CONFIG_PCI
29void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max)
30{
31 unsigned long start = pci_resource_start(dev, bar);
32 unsigned long len = pci_resource_len(dev, bar);
33 unsigned long flags = pci_resource_flags(dev, bar);
34
35 if (!len)
36 return NULL;
37 if (max && len > max)
38 len = max;
39 if (flags & IORESOURCE_IO)
40 return ioport_map(start + pciio_virt, len);
41 if (flags & IORESOURCE_MEM)
42 return (void __iomem *)start;
43
44 /* What? */
45 return NULL;
46}
47EXPORT_SYMBOL(pci_iomap);
48
49void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
50{
51 /* Nothing .. */
52}
53EXPORT_SYMBOL(pci_iounmap);
54#endif
diff --git a/arch/sh64/mach-cayman/Makefile b/arch/sh64/mach-cayman/Makefile
deleted file mode 100644
index 67a2258bf8c4..000000000000
--- a/arch/sh64/mach-cayman/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
1#
2# Makefile for the Hitachi Cayman specific parts of the kernel
3#
4# Note! Dependencies are done automagically by 'make dep', which also
5# removes any old dependencies. DON'T put your own dependencies here
6# unless it's something special (ie not a .c file).
7#
8
9obj-y := setup.o irq.o iomap.o
10obj-$(CONFIG_HEARTBEAT) += led.o
11
diff --git a/arch/sh64/mach-cayman/iomap.c b/arch/sh64/mach-cayman/iomap.c
deleted file mode 100644
index a5c645f02d57..000000000000
--- a/arch/sh64/mach-cayman/iomap.c
+++ /dev/null
@@ -1,22 +0,0 @@
1/*
2 * arch/sh64/mach-cayman/iomap.c
3 *
4 * Cayman iomap interface
5 *
6 * Copyright (C) 2004 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <asm/io.h>
13#include <asm/cayman.h>
14
15void __iomem *ioport_map(unsigned long port, unsigned int len)
16{
17 if (port < 0x400)
18 return (void __iomem *)((port << 2) | smsc_superio_virt);
19
20 return (void __iomem *)port;
21}
22
diff --git a/arch/sh64/mach-harp/Makefile b/arch/sh64/mach-harp/Makefile
deleted file mode 100644
index 2f2963fa2131..000000000000
--- a/arch/sh64/mach-harp/Makefile
+++ /dev/null
@@ -1 +0,0 @@
1obj-y := setup.o
diff --git a/arch/sh64/mach-harp/setup.c b/arch/sh64/mach-harp/setup.c
deleted file mode 100644
index 05011cb369bb..000000000000
--- a/arch/sh64/mach-harp/setup.c
+++ /dev/null
@@ -1,129 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * arch/sh64/mach-harp/setup.c
7 *
8 * SH-5 Simulator Platform Support
9 *
10 * This file handles the architecture-dependent parts of initialization
11 *
12 * Copyright (C) 2000, 2001 Paolo Alberelli
13 *
14 * benedict.gaster@superh.com: 3rd May 2002
15 * Added support for ramdisk, removing statically linked romfs at the same time. *
16 *
17 * lethal@linux-sh.org: 15th May 2003
18 * Use the generic procfs cpuinfo interface, just return a valid board name.
19 */
20#include <linux/init.h>
21#include <linux/kernel.h>
22#include <asm/platform.h>
23#include <asm/irq.h>
24
25/*
26 * Platform Dependent Interrupt Priorities.
27 */
28
29/* Using defaults defined in irq.h */
30#define RES NO_PRIORITY /* Disabled */
31#define IR0 IRL0_PRIORITY /* IRLs */
32#define IR1 IRL1_PRIORITY
33#define IR2 IRL2_PRIORITY
34#define IR3 IRL3_PRIORITY
35#define PCA INTA_PRIORITY /* PCI Ints */
36#define PCB INTB_PRIORITY
37#define PCC INTC_PRIORITY
38#define PCD INTD_PRIORITY
39#define SER TOP_PRIORITY
40#define ERR TOP_PRIORITY
41#define PW0 TOP_PRIORITY
42#define PW1 TOP_PRIORITY
43#define PW2 TOP_PRIORITY
44#define PW3 TOP_PRIORITY
45#define DM0 NO_PRIORITY /* DMA Ints */
46#define DM1 NO_PRIORITY
47#define DM2 NO_PRIORITY
48#define DM3 NO_PRIORITY
49#define DAE NO_PRIORITY
50#define TU0 TIMER_PRIORITY /* TMU Ints */
51#define TU1 NO_PRIORITY
52#define TU2 NO_PRIORITY
53#define TI2 NO_PRIORITY
54#define ATI NO_PRIORITY /* RTC Ints */
55#define PRI NO_PRIORITY
56#define CUI RTC_PRIORITY
57#define ERI SCIF_PRIORITY /* SCIF Ints */
58#define RXI SCIF_PRIORITY
59#define BRI SCIF_PRIORITY
60#define TXI SCIF_PRIORITY
61#define ITI TOP_PRIORITY /* WDT Ints */
62
63/*
64 * Platform dependent structures: maps and parms block.
65 */
66struct resource io_resources[] = {
67 /* To be updated with external devices */
68};
69
70struct resource kram_resources[] = {
71 /* These must be last in the array */
72 { .name = "Kernel code", .start = 0, .end = 0 },
73 /* These must be last in the array */
74 { .name = "Kernel data", .start = 0, .end = 0 }
75};
76
77struct resource xram_resources[] = {
78 /* To be updated with external devices */
79};
80
81struct resource rom_resources[] = {
82 /* To be updated with external devices */
83};
84
85struct sh64_platform platform_parms = {
86 .readonly_rootfs = 1,
87 .initial_root_dev = 0x0100,
88 .loader_type = 1,
89 .io_res_p = io_resources,
90 .io_res_count = ARRAY_SIZE(io_resources),
91 .kram_res_p = kram_resources,
92 .kram_res_count = ARRAY_SIZE(kram_resources),
93 .xram_res_p = xram_resources,
94 .xram_res_count = ARRAY_SIZE(xram_resources),
95 .rom_res_p = rom_resources,
96 .rom_res_count = ARRAY_SIZE(rom_resources),
97};
98
99int platform_int_priority[NR_INTC_IRQS] = {
100 IR0, IR1, IR2, IR3, PCA, PCB, PCC, PCD, /* IRQ 0- 7 */
101 RES, RES, RES, RES, SER, ERR, PW3, PW2, /* IRQ 8-15 */
102 PW1, PW0, DM0, DM1, DM2, DM3, DAE, RES, /* IRQ 16-23 */
103 RES, RES, RES, RES, RES, RES, RES, RES, /* IRQ 24-31 */
104 TU0, TU1, TU2, TI2, ATI, PRI, CUI, ERI, /* IRQ 32-39 */
105 RXI, BRI, TXI, RES, RES, RES, RES, RES, /* IRQ 40-47 */
106 RES, RES, RES, RES, RES, RES, RES, RES, /* IRQ 48-55 */
107 RES, RES, RES, RES, RES, RES, RES, ITI, /* IRQ 56-63 */
108};
109
110void __init platform_setup(void)
111{
112 /* Harp platform leaves the decision to head.S, for now */
113 platform_parms.fpu_flags = fpu_in_use;
114}
115
116void __init platform_monitor(void)
117{
118 /* Nothing yet .. */
119}
120
121void __init platform_reserve(void)
122{
123 /* Nothing yet .. */
124}
125
126const char *get_system_type(void)
127{
128 return "ST50 Harp";
129}
diff --git a/arch/sh64/mach-sim/Makefile b/arch/sh64/mach-sim/Makefile
deleted file mode 100644
index 2f2963fa2131..000000000000
--- a/arch/sh64/mach-sim/Makefile
+++ /dev/null
@@ -1 +0,0 @@
1obj-y := setup.o
diff --git a/arch/sh64/mach-sim/setup.c b/arch/sh64/mach-sim/setup.c
deleted file mode 100644
index e3386ec1ce1f..000000000000
--- a/arch/sh64/mach-sim/setup.c
+++ /dev/null
@@ -1,126 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * arch/sh64/mach-sim/setup.c
7 *
8 * ST50 Simulator Platform Support
9 *
10 * This file handles the architecture-dependent parts of initialization
11 *
12 * Copyright (C) 2000, 2001 Paolo Alberelli
13 *
14 * lethal@linux-sh.org: 15th May 2003
15 * Use the generic procfs cpuinfo interface, just return a valid board name.
16 */
17#include <linux/init.h>
18#include <linux/kernel.h>
19#include <asm/platform.h>
20#include <asm/irq.h>
21
22/*
23 * Platform Dependent Interrupt Priorities.
24 */
25
26/* Using defaults defined in irq.h */
27#define RES NO_PRIORITY /* Disabled */
28#define IR0 IRL0_PRIORITY /* IRLs */
29#define IR1 IRL1_PRIORITY
30#define IR2 IRL2_PRIORITY
31#define IR3 IRL3_PRIORITY
32#define PCA INTA_PRIORITY /* PCI Ints */
33#define PCB INTB_PRIORITY
34#define PCC INTC_PRIORITY
35#define PCD INTD_PRIORITY
36#define SER TOP_PRIORITY
37#define ERR TOP_PRIORITY
38#define PW0 TOP_PRIORITY
39#define PW1 TOP_PRIORITY
40#define PW2 TOP_PRIORITY
41#define PW3 TOP_PRIORITY
42#define DM0 NO_PRIORITY /* DMA Ints */
43#define DM1 NO_PRIORITY
44#define DM2 NO_PRIORITY
45#define DM3 NO_PRIORITY
46#define DAE NO_PRIORITY
47#define TU0 TIMER_PRIORITY /* TMU Ints */
48#define TU1 NO_PRIORITY
49#define TU2 NO_PRIORITY
50#define TI2 NO_PRIORITY
51#define ATI NO_PRIORITY /* RTC Ints */
52#define PRI NO_PRIORITY
53#define CUI RTC_PRIORITY
54#define ERI SCIF_PRIORITY /* SCIF Ints */
55#define RXI SCIF_PRIORITY
56#define BRI SCIF_PRIORITY
57#define TXI SCIF_PRIORITY
58#define ITI TOP_PRIORITY /* WDT Ints */
59
60/*
61 * Platform dependent structures: maps and parms block.
62 */
63struct resource io_resources[] = {
64 /* Nothing yet .. */
65};
66
67struct resource kram_resources[] = {
68 /* These must be last in the array */
69 { .name = "Kernel code", .start = 0, .end = 0 },
70 /* These must be last in the array */
71 { .name = "Kernel data", .start = 0, .end = 0 }
72};
73
74struct resource xram_resources[] = {
75 /* Nothing yet .. */
76};
77
78struct resource rom_resources[] = {
79 /* Nothing yet .. */
80};
81
82struct sh64_platform platform_parms = {
83 .readonly_rootfs = 1,
84 .initial_root_dev = 0x0100,
85 .loader_type = 1,
86 .io_res_p = io_resources,
87 .io_res_count = ARRAY_SIZE(io_resources),
88 .kram_res_p = kram_resources,
89 .kram_res_count = ARRAY_SIZE(kram_resources),
90 .xram_res_p = xram_resources,
91 .xram_res_count = ARRAY_SIZE(xram_resources),
92 .rom_res_p = rom_resources,
93 .rom_res_count = ARRAY_SIZE(rom_resources),
94};
95
96int platform_int_priority[NR_IRQS] = {
97 IR0, IR1, IR2, IR3, PCA, PCB, PCC, PCD, /* IRQ 0- 7 */
98 RES, RES, RES, RES, SER, ERR, PW3, PW2, /* IRQ 8-15 */
99 PW1, PW0, DM0, DM1, DM2, DM3, DAE, RES, /* IRQ 16-23 */
100 RES, RES, RES, RES, RES, RES, RES, RES, /* IRQ 24-31 */
101 TU0, TU1, TU2, TI2, ATI, PRI, CUI, ERI, /* IRQ 32-39 */
102 RXI, BRI, TXI, RES, RES, RES, RES, RES, /* IRQ 40-47 */
103 RES, RES, RES, RES, RES, RES, RES, RES, /* IRQ 48-55 */
104 RES, RES, RES, RES, RES, RES, RES, ITI, /* IRQ 56-63 */
105};
106
107void __init platform_setup(void)
108{
109 /* Simulator platform leaves the decision to head.S */
110 platform_parms.fpu_flags = fpu_in_use;
111}
112
113void __init platform_monitor(void)
114{
115 /* Nothing yet .. */
116}
117
118void __init platform_reserve(void)
119{
120 /* Nothing yet .. */
121}
122
123const char *get_system_type(void)
124{
125 return "SH-5 Simulator";
126}
diff --git a/arch/sh64/mm/consistent.c b/arch/sh64/mm/consistent.c
deleted file mode 100644
index c439620402cb..000000000000
--- a/arch/sh64/mm/consistent.c
+++ /dev/null
@@ -1,53 +0,0 @@
1/*
2 * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
3 * Copyright (C) 2003 Paul Mundt (lethal@linux-sh.org)
4 *
5 * May be copied or modified under the terms of the GNU General Public
6 * License. See linux/COPYING for more information.
7 *
8 * Dynamic DMA mapping support.
9 */
10#include <linux/types.h>
11#include <linux/mm.h>
12#include <linux/string.h>
13#include <linux/pci.h>
14#include <linux/dma-mapping.h>
15#include <linux/module.h>
16#include <asm/io.h>
17
18void *consistent_alloc(struct pci_dev *hwdev, size_t size,
19 dma_addr_t *dma_handle)
20{
21 void *ret;
22 int gfp = GFP_ATOMIC;
23 void *vp;
24
25 if (hwdev == NULL || hwdev->dma_mask != 0xffffffff)
26 gfp |= GFP_DMA;
27
28 ret = (void *)__get_free_pages(gfp, get_order(size));
29
30 /* now call our friend ioremap_nocache to give us an uncached area */
31 vp = ioremap_nocache(virt_to_phys(ret), size);
32
33 if (vp != NULL) {
34 memset(vp, 0, size);
35 *dma_handle = virt_to_phys(ret);
36 dma_cache_sync(NULL, ret, size, DMA_BIDIRECTIONAL);
37 }
38
39 return vp;
40}
41EXPORT_SYMBOL(consistent_alloc);
42
43void consistent_free(struct pci_dev *hwdev, size_t size,
44 void *vaddr, dma_addr_t dma_handle)
45{
46 void *alloc;
47
48 alloc = phys_to_virt((unsigned long)dma_handle);
49 free_pages((unsigned long)alloc, get_order(size));
50
51 iounmap(vaddr);
52}
53EXPORT_SYMBOL(consistent_free);
diff --git a/arch/sh64/mm/hugetlbpage.c b/arch/sh64/mm/hugetlbpage.c
deleted file mode 100644
index fa66daa2dfa9..000000000000
--- a/arch/sh64/mm/hugetlbpage.c
+++ /dev/null
@@ -1,105 +0,0 @@
1/*
2 * arch/sh64/mm/hugetlbpage.c
3 *
4 * SuperH HugeTLB page support.
5 *
6 * Cloned from sparc64 by Paul Mundt.
7 *
8 * Copyright (C) 2002, 2003 David S. Miller (davem@redhat.com)
9 */
10
11#include <linux/init.h>
12#include <linux/fs.h>
13#include <linux/mm.h>
14#include <linux/hugetlb.h>
15#include <linux/pagemap.h>
16#include <linux/slab.h>
17#include <linux/sysctl.h>
18
19#include <asm/mman.h>
20#include <asm/pgalloc.h>
21#include <asm/tlb.h>
22#include <asm/tlbflush.h>
23#include <asm/cacheflush.h>
24
25pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr)
26{
27 pgd_t *pgd;
28 pmd_t *pmd;
29 pte_t *pte = NULL;
30
31 pgd = pgd_offset(mm, addr);
32 if (pgd) {
33 pmd = pmd_alloc(mm, pgd, addr);
34 if (pmd)
35 pte = pte_alloc_map(mm, pmd, addr);
36 }
37 return pte;
38}
39
40pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
41{
42 pgd_t *pgd;
43 pmd_t *pmd;
44 pte_t *pte = NULL;
45
46 pgd = pgd_offset(mm, addr);
47 if (pgd) {
48 pmd = pmd_offset(pgd, addr);
49 if (pmd)
50 pte = pte_offset_map(pmd, addr);
51 }
52 return pte;
53}
54
55int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep)
56{
57 return 0;
58}
59
60void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
61 pte_t *ptep, pte_t entry)
62{
63 int i;
64
65 for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
66 set_pte_at(mm, addr, ptep, entry);
67 ptep++;
68 addr += PAGE_SIZE;
69 pte_val(entry) += PAGE_SIZE;
70 }
71}
72
73pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
74 pte_t *ptep)
75{
76 pte_t entry;
77 int i;
78
79 entry = *ptep;
80
81 for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
82 pte_clear(mm, addr, ptep);
83 addr += PAGE_SIZE;
84 ptep++;
85 }
86
87 return entry;
88}
89
90struct page *follow_huge_addr(struct mm_struct *mm,
91 unsigned long address, int write)
92{
93 return ERR_PTR(-EINVAL);
94}
95
96int pmd_huge(pmd_t pmd)
97{
98 return 0;
99}
100
101struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address,
102 pmd_t *pmd, int write)
103{
104 return NULL;
105}
diff --git a/arch/sh64/mm/init.c b/arch/sh64/mm/init.c
deleted file mode 100644
index 21cf42de23e2..000000000000
--- a/arch/sh64/mm/init.c
+++ /dev/null
@@ -1,189 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * arch/sh64/mm/init.c
7 *
8 * Copyright (C) 2000, 2001 Paolo Alberelli
9 * Copyright (C) 2003, 2004 Paul Mundt
10 *
11 */
12
13#include <linux/init.h>
14#include <linux/rwsem.h>
15#include <linux/mm.h>
16#include <linux/swap.h>
17#include <linux/bootmem.h>
18
19#include <asm/mmu_context.h>
20#include <asm/page.h>
21#include <asm/pgalloc.h>
22#include <asm/pgtable.h>
23#include <asm/tlb.h>
24
25DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
26
27/*
28 * Cache of MMU context last used.
29 */
30unsigned long mmu_context_cache;
31pgd_t * mmu_pdtp_cache;
32int after_bootmem = 0;
33
34/*
35 * BAD_PAGE is the page that is used for page faults when linux
36 * is out-of-memory. Older versions of linux just did a
37 * do_exit(), but using this instead means there is less risk
38 * for a process dying in kernel mode, possibly leaving an inode
39 * unused etc..
40 *
41 * BAD_PAGETABLE is the accompanying page-table: it is initialized
42 * to point to BAD_PAGE entries.
43 *
44 * ZERO_PAGE is a special page that is used for zero-initialized
45 * data and COW.
46 */
47
48extern unsigned char empty_zero_page[PAGE_SIZE];
49extern unsigned char empty_bad_page[PAGE_SIZE];
50extern pte_t empty_bad_pte_table[PTRS_PER_PTE];
51extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
52
53extern char _text, _etext, _edata, __bss_start, _end;
54extern char __init_begin, __init_end;
55
56/* It'd be good if these lines were in the standard header file. */
57#define START_PFN (NODE_DATA(0)->bdata->node_boot_start >> PAGE_SHIFT)
58#define MAX_LOW_PFN (NODE_DATA(0)->bdata->node_low_pfn)
59
60
61void show_mem(void)
62{
63 int i, total = 0, reserved = 0;
64 int shared = 0, cached = 0;
65
66 printk("Mem-info:\n");
67 show_free_areas();
68 printk("Free swap: %6ldkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
69 i = max_mapnr;
70 while (i-- > 0) {
71 total++;
72 if (PageReserved(mem_map+i))
73 reserved++;
74 else if (PageSwapCache(mem_map+i))
75 cached++;
76 else if (page_count(mem_map+i))
77 shared += page_count(mem_map+i) - 1;
78 }
79 printk("%d pages of RAM\n",total);
80 printk("%d reserved pages\n",reserved);
81 printk("%d pages shared\n",shared);
82 printk("%d pages swap cached\n",cached);
83 printk("%ld pages in page table cache\n", quicklist_total_size());
84}
85
86/*
87 * paging_init() sets up the page tables.
88 *
89 * head.S already did a lot to set up address translation for the kernel.
90 * Here we comes with:
91 * . MMU enabled
92 * . ASID set (SR)
93 * . some 512MB regions being mapped of which the most relevant here is:
94 * . CACHED segment (ASID 0 [irrelevant], shared AND NOT user)
95 * . possible variable length regions being mapped as:
96 * . UNCACHED segment (ASID 0 [irrelevant], shared AND NOT user)
97 * . All of the memory regions are placed, independently from the platform
98 * on high addresses, above 0x80000000.
99 * . swapper_pg_dir is already cleared out by the .space directive
100 * in any case swapper does not require a real page directory since
101 * it's all kernel contained.
102 *
103 * Those pesky NULL-reference errors in the kernel are then
104 * dealt with by not mapping address 0x00000000 at all.
105 *
106 */
107void __init paging_init(void)
108{
109 unsigned long zones_size[MAX_NR_ZONES] = {0, };
110
111 pgd_init((unsigned long)swapper_pg_dir);
112 pgd_init((unsigned long)swapper_pg_dir +
113 sizeof(pgd_t) * USER_PTRS_PER_PGD);
114
115 mmu_context_cache = MMU_CONTEXT_FIRST_VERSION;
116
117 zones_size[ZONE_NORMAL] = MAX_LOW_PFN - START_PFN;
118 NODE_DATA(0)->node_mem_map = NULL;
119 free_area_init_node(0, NODE_DATA(0), zones_size, __MEMORY_START >> PAGE_SHIFT, 0);
120}
121
122void __init mem_init(void)
123{
124 int codesize, reservedpages, datasize, initsize;
125 int tmp;
126
127 max_mapnr = num_physpages = MAX_LOW_PFN - START_PFN;
128 high_memory = (void *)__va(MAX_LOW_PFN * PAGE_SIZE);
129
130 /*
131 * Clear the zero-page.
132 * This is not required but we might want to re-use
133 * this very page to pass boot parameters, one day.
134 */
135 memset(empty_zero_page, 0, PAGE_SIZE);
136
137 /* this will put all low memory onto the freelists */
138 totalram_pages += free_all_bootmem_node(NODE_DATA(0));
139 reservedpages = 0;
140 for (tmp = 0; tmp < num_physpages; tmp++)
141 /*
142 * Only count reserved RAM pages
143 */
144 if (PageReserved(mem_map+tmp))
145 reservedpages++;
146
147 after_bootmem = 1;
148
149 codesize = (unsigned long) &_etext - (unsigned long) &_text;
150 datasize = (unsigned long) &_edata - (unsigned long) &_etext;
151 initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
152
153 printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init)\n",
154 (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
155 max_mapnr << (PAGE_SHIFT-10),
156 codesize >> 10,
157 reservedpages << (PAGE_SHIFT-10),
158 datasize >> 10,
159 initsize >> 10);
160}
161
162void free_initmem(void)
163{
164 unsigned long addr;
165
166 addr = (unsigned long)(&__init_begin);
167 for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
168 ClearPageReserved(virt_to_page(addr));
169 init_page_count(virt_to_page(addr));
170 free_page(addr);
171 totalram_pages++;
172 }
173 printk ("Freeing unused kernel memory: %ldk freed\n", (&__init_end - &__init_begin) >> 10);
174}
175
176#ifdef CONFIG_BLK_DEV_INITRD
177void free_initrd_mem(unsigned long start, unsigned long end)
178{
179 unsigned long p;
180 for (p = start; p < end; p += PAGE_SIZE) {
181 ClearPageReserved(virt_to_page(p));
182 init_page_count(virt_to_page(p));
183 free_page(p);
184 totalram_pages++;
185 }
186 printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
187}
188#endif
189
diff --git a/arch/sh64/oprofile/Makefile b/arch/sh64/oprofile/Makefile
deleted file mode 100644
index 11a451f6a9c3..000000000000
--- a/arch/sh64/oprofile/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
1obj-$(CONFIG_OPROFILE) += oprofile.o
2
3DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
4 oprof.o cpu_buffer.o buffer_sync.o \
5 event_buffer.o oprofile_files.o \
6 oprofilefs.o oprofile_stats.o \
7 timer_int.o )
8
9profdrvr-y := op_model_null.o
10
11oprofile-y := $(DRIVER_OBJS) $(profdrvr-y)
12
diff --git a/arch/sh64/oprofile/op_model_null.c b/arch/sh64/oprofile/op_model_null.c
deleted file mode 100644
index a750ea1fee98..000000000000
--- a/arch/sh64/oprofile/op_model_null.c
+++ /dev/null
@@ -1,23 +0,0 @@
1/*
2 * arch/sh64/oprofile/op_model_null.c
3 *
4 * Copyright (C) 2003 Paul Mundt
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/kernel.h>
11#include <linux/oprofile.h>
12#include <linux/init.h>
13#include <linux/errno.h>
14
15int __init oprofile_arch_init(struct oprofile_operations *ops)
16{
17 return -ENODEV;
18}
19
20void oprofile_arch_exit(void)
21{
22}
23
diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c
index f8228383895a..d07bc74773aa 100644
--- a/arch/sparc/kernel/setup.c
+++ b/arch/sparc/kernel/setup.c
@@ -379,7 +379,7 @@ static void c_stop(struct seq_file *m, void *v)
379{ 379{
380} 380}
381 381
382struct seq_operations cpuinfo_op = { 382const struct seq_operations cpuinfo_op = {
383 .start =c_start, 383 .start =c_start,
384 .next = c_next, 384 .next = c_next,
385 .stop = c_stop, 385 .stop = c_stop,
diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S
index a8b4200f9cc3..216147d6e61f 100644
--- a/arch/sparc/kernel/vmlinux.lds.S
+++ b/arch/sparc/kernel/vmlinux.lds.S
@@ -48,12 +48,12 @@ SECTIONS
48 __init_begin = .; 48 __init_begin = .;
49 .init.text : { 49 .init.text : {
50 _sinittext = .; 50 _sinittext = .;
51 *(.init.text) 51 INIT_TEXT
52 _einittext = .; 52 _einittext = .;
53 } 53 }
54 __init_text_end = .; 54 __init_text_end = .;
55 .init.data : { 55 .init.data : {
56 *(.init.data) 56 INIT_DATA
57 } 57 }
58 . = ALIGN(16); 58 . = ALIGN(16);
59 .init.setup : { 59 .init.setup : {
@@ -102,8 +102,8 @@ SECTIONS
102 _end = . ; 102 _end = . ;
103 PROVIDE (end = .); 103 PROVIDE (end = .);
104 /DISCARD/ : { 104 /DISCARD/ : {
105 *(.exit.text) 105 EXIT_TEXT
106 *(.exit.data) 106 EXIT_DATA
107 *(.exitcall.exit) 107 *(.exitcall.exit)
108 } 108 }
109 109
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index 10b212a1f9f5..26f5791baa33 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -66,6 +66,9 @@ config AUDIT_ARCH
66 bool 66 bool
67 default y 67 default y
68 68
69config ARCH_SETS_UP_PER_CPU_AREA
70 def_bool y
71
69config ARCH_NO_VIRT_TO_BUS 72config ARCH_NO_VIRT_TO_BUS
70 def_bool y 73 def_bool y
71 74
@@ -200,6 +203,11 @@ config US2E_FREQ
200 If in doubt, say N. 203 If in doubt, say N.
201 204
202# Global things across all Sun machines. 205# Global things across all Sun machines.
206config GENERIC_LOCKBREAK
207 bool
208 default y
209 depends on SMP && PREEMPT
210
203config RWSEM_GENERIC_SPINLOCK 211config RWSEM_GENERIC_SPINLOCK
204 bool 212 bool
205 213
diff --git a/arch/sparc64/kernel/pci_fire.c b/arch/sparc64/kernel/pci_fire.c
index fef3b37487bf..7571ed563147 100644
--- a/arch/sparc64/kernel/pci_fire.c
+++ b/arch/sparc64/kernel/pci_fire.c
@@ -30,7 +30,7 @@
30 "i" (ASI_PHYS_BYPASS_EC_E) \ 30 "i" (ASI_PHYS_BYPASS_EC_E) \
31 : "memory") 31 : "memory")
32 32
33static void pci_fire_scan_bus(struct pci_pbm_info *pbm) 33static void __init pci_fire_scan_bus(struct pci_pbm_info *pbm)
34{ 34{
35 pbm->pci_bus = pci_scan_one_pbm(pbm); 35 pbm->pci_bus = pci_scan_one_pbm(pbm);
36 36
@@ -434,8 +434,8 @@ static void pci_fire_hw_init(struct pci_pbm_info *pbm)
434 fire_write(pbm->pbm_regs + FIRE_PEC_IENAB, ~(u64)0); 434 fire_write(pbm->pbm_regs + FIRE_PEC_IENAB, ~(u64)0);
435} 435}
436 436
437static int pci_fire_pbm_init(struct pci_controller_info *p, 437static int __init pci_fire_pbm_init(struct pci_controller_info *p,
438 struct device_node *dp, u32 portid) 438 struct device_node *dp, u32 portid)
439{ 439{
440 const struct linux_prom64_registers *regs; 440 const struct linux_prom64_registers *regs;
441 struct pci_pbm_info *pbm; 441 struct pci_pbm_info *pbm;
@@ -488,7 +488,7 @@ static inline int portid_compare(u32 x, u32 y)
488 return 0; 488 return 0;
489} 489}
490 490
491void fire_pci_init(struct device_node *dp, const char *model_name) 491void __init fire_pci_init(struct device_node *dp, const char *model_name)
492{ 492{
493 struct pci_controller_info *p; 493 struct pci_controller_info *p;
494 u32 portid = of_getintprop_default(dp, "portid", 0xff); 494 u32 portid = of_getintprop_default(dp, "portid", 0xff);
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c
index d27ee5d528a2..0bad96e5d184 100644
--- a/arch/sparc64/kernel/pci_psycho.c
+++ b/arch/sparc64/kernel/pci_psycho.c
@@ -801,7 +801,7 @@ static void pbm_config_busmastering(struct pci_pbm_info *pbm)
801 pci_config_write8(addr, 64); 801 pci_config_write8(addr, 64);
802} 802}
803 803
804static void psycho_scan_bus(struct pci_pbm_info *pbm) 804static void __init psycho_scan_bus(struct pci_pbm_info *pbm)
805{ 805{
806 pbm_config_busmastering(pbm); 806 pbm_config_busmastering(pbm);
807 pbm->is_66mhz_capable = 0; 807 pbm->is_66mhz_capable = 0;
@@ -965,7 +965,7 @@ static void psycho_pbm_strbuf_init(struct pci_pbm_info *pbm,
965#define PSYCHO_MEMSPACE_B 0x180000000UL 965#define PSYCHO_MEMSPACE_B 0x180000000UL
966#define PSYCHO_MEMSPACE_SIZE 0x07fffffffUL 966#define PSYCHO_MEMSPACE_SIZE 0x07fffffffUL
967 967
968static void psycho_pbm_init(struct pci_controller_info *p, 968static void __init psycho_pbm_init(struct pci_controller_info *p,
969 struct device_node *dp, int is_pbm_a) 969 struct device_node *dp, int is_pbm_a)
970{ 970{
971 struct property *prop; 971 struct property *prop;
@@ -1012,7 +1012,7 @@ static void psycho_pbm_init(struct pci_controller_info *p,
1012 1012
1013#define PSYCHO_CONFIGSPACE 0x001000000UL 1013#define PSYCHO_CONFIGSPACE 0x001000000UL
1014 1014
1015void psycho_init(struct device_node *dp, char *model_name) 1015void __init psycho_init(struct device_node *dp, char *model_name)
1016{ 1016{
1017 struct linux_prom64_registers *pr_regs; 1017 struct linux_prom64_registers *pr_regs;
1018 struct pci_controller_info *p; 1018 struct pci_controller_info *p;
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c
index fba67c3d8809..1c5f5fa2339f 100644
--- a/arch/sparc64/kernel/pci_sabre.c
+++ b/arch/sparc64/kernel/pci_sabre.c
@@ -633,7 +633,7 @@ static void apb_init(struct pci_bus *sabre_bus)
633 } 633 }
634} 634}
635 635
636static void sabre_scan_bus(struct pci_pbm_info *pbm) 636static void __init sabre_scan_bus(struct pci_pbm_info *pbm)
637{ 637{
638 static int once; 638 static int once;
639 639
@@ -731,7 +731,8 @@ static int sabre_iommu_init(struct pci_pbm_info *pbm,
731 return 0; 731 return 0;
732} 732}
733 733
734static void sabre_pbm_init(struct pci_controller_info *p, struct pci_pbm_info *pbm, struct device_node *dp) 734static void __init sabre_pbm_init(struct pci_controller_info *p,
735 struct pci_pbm_info *pbm, struct device_node *dp)
735{ 736{
736 pbm->name = dp->full_name; 737 pbm->name = dp->full_name;
737 printk("%s: SABRE PCI Bus Module\n", pbm->name); 738 printk("%s: SABRE PCI Bus Module\n", pbm->name);
@@ -750,7 +751,7 @@ static void sabre_pbm_init(struct pci_controller_info *p, struct pci_pbm_info *p
750 pci_determine_mem_io_space(pbm); 751 pci_determine_mem_io_space(pbm);
751} 752}
752 753
753void sabre_init(struct device_node *dp, char *model_name) 754void __init sabre_init(struct device_node *dp, char *model_name)
754{ 755{
755 const struct linux_prom64_registers *pr_regs; 756 const struct linux_prom64_registers *pr_regs;
756 struct pci_controller_info *p; 757 struct pci_controller_info *p;
diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c
index e752e75cce83..e30609362322 100644
--- a/arch/sparc64/kernel/pci_schizo.c
+++ b/arch/sparc64/kernel/pci_schizo.c
@@ -1084,7 +1084,7 @@ static void pbm_config_busmastering(struct pci_pbm_info *pbm)
1084 pci_config_write8(addr, 64); 1084 pci_config_write8(addr, 64);
1085} 1085}
1086 1086
1087static void schizo_scan_bus(struct pci_pbm_info *pbm) 1087static void __init schizo_scan_bus(struct pci_pbm_info *pbm)
1088{ 1088{
1089 pbm_config_busmastering(pbm); 1089 pbm_config_busmastering(pbm);
1090 pbm->is_66mhz_capable = 1090 pbm->is_66mhz_capable =
@@ -1333,9 +1333,9 @@ static void schizo_pbm_hw_init(struct pci_pbm_info *pbm)
1333 } 1333 }
1334} 1334}
1335 1335
1336static int schizo_pbm_init(struct pci_controller_info *p, 1336static int __init schizo_pbm_init(struct pci_controller_info *p,
1337 struct device_node *dp, u32 portid, 1337 struct device_node *dp, u32 portid,
1338 int chip_type) 1338 int chip_type)
1339{ 1339{
1340 const struct linux_prom64_registers *regs; 1340 const struct linux_prom64_registers *regs;
1341 struct pci_pbm_info *pbm; 1341 struct pci_pbm_info *pbm;
@@ -1430,7 +1430,8 @@ static inline int portid_compare(u32 x, u32 y, int chip_type)
1430 return (x == y); 1430 return (x == y);
1431} 1431}
1432 1432
1433static void __schizo_init(struct device_node *dp, char *model_name, int chip_type) 1433static void __init __schizo_init(struct device_node *dp, char *model_name,
1434 int chip_type)
1434{ 1435{
1435 struct pci_controller_info *p; 1436 struct pci_controller_info *p;
1436 struct pci_pbm_info *pbm; 1437 struct pci_pbm_info *pbm;
@@ -1474,17 +1475,17 @@ fatal_memory_error:
1474 prom_halt(); 1475 prom_halt();
1475} 1476}
1476 1477
1477void schizo_init(struct device_node *dp, char *model_name) 1478void __init schizo_init(struct device_node *dp, char *model_name)
1478{ 1479{
1479 __schizo_init(dp, model_name, PBM_CHIP_TYPE_SCHIZO); 1480 __schizo_init(dp, model_name, PBM_CHIP_TYPE_SCHIZO);
1480} 1481}
1481 1482
1482void schizo_plus_init(struct device_node *dp, char *model_name) 1483void __init schizo_plus_init(struct device_node *dp, char *model_name)
1483{ 1484{
1484 __schizo_init(dp, model_name, PBM_CHIP_TYPE_SCHIZO_PLUS); 1485 __schizo_init(dp, model_name, PBM_CHIP_TYPE_SCHIZO_PLUS);
1485} 1486}
1486 1487
1487void tomatillo_init(struct device_node *dp, char *model_name) 1488void __init tomatillo_init(struct device_node *dp, char *model_name)
1488{ 1489{
1489 __schizo_init(dp, model_name, PBM_CHIP_TYPE_TOMATILLO); 1490 __schizo_init(dp, model_name, PBM_CHIP_TYPE_TOMATILLO);
1490} 1491}
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
index e587a372f3fe..1aa8e044b105 100644
--- a/arch/sparc64/kernel/pci_sun4v.c
+++ b/arch/sparc64/kernel/pci_sun4v.c
@@ -612,7 +612,7 @@ const struct dma_ops sun4v_dma_ops = {
612 .sync_sg_for_cpu = dma_4v_sync_sg_for_cpu, 612 .sync_sg_for_cpu = dma_4v_sync_sg_for_cpu,
613}; 613};
614 614
615static void pci_sun4v_scan_bus(struct pci_pbm_info *pbm) 615static void __init pci_sun4v_scan_bus(struct pci_pbm_info *pbm)
616{ 616{
617 struct property *prop; 617 struct property *prop;
618 struct device_node *dp; 618 struct device_node *dp;
@@ -960,7 +960,8 @@ static void pci_sun4v_msi_init(struct pci_pbm_info *pbm)
960} 960}
961#endif /* !(CONFIG_PCI_MSI) */ 961#endif /* !(CONFIG_PCI_MSI) */
962 962
963static void __init pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 devhandle) 963static void __init pci_sun4v_pbm_init(struct pci_controller_info *p,
964 struct device_node *dp, u32 devhandle)
964{ 965{
965 struct pci_pbm_info *pbm; 966 struct pci_pbm_info *pbm;
966 967
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index 0f5be828ee92..a813441b358f 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -421,7 +421,7 @@ static void c_stop(struct seq_file *m, void *v)
421{ 421{
422} 422}
423 423
424struct seq_operations cpuinfo_op = { 424const struct seq_operations cpuinfo_op = {
425 .start =c_start, 425 .start =c_start,
426 .next = c_next, 426 .next = c_next,
427 .stop = c_stop, 427 .stop = c_stop,
diff --git a/arch/sparc64/kernel/unaligned.c b/arch/sparc64/kernel/unaligned.c
index 953be816fa25..dc7bf1b6321c 100644
--- a/arch/sparc64/kernel/unaligned.c
+++ b/arch/sparc64/kernel/unaligned.c
@@ -175,7 +175,7 @@ unsigned long compute_effective_address(struct pt_regs *regs,
175} 175}
176 176
177/* This is just to make gcc think die_if_kernel does return... */ 177/* This is just to make gcc think die_if_kernel does return... */
178static void __attribute_used__ unaligned_panic(char *str, struct pt_regs *regs) 178static void __used unaligned_panic(char *str, struct pt_regs *regs)
179{ 179{
180 die_if_kernel(str, regs); 180 die_if_kernel(str, regs);
181} 181}
diff --git a/arch/sparc64/kernel/vio.c b/arch/sparc64/kernel/vio.c
index 0c1ee619d814..e78b3517940b 100644
--- a/arch/sparc64/kernel/vio.c
+++ b/arch/sparc64/kernel/vio.c
@@ -131,7 +131,7 @@ void vio_unregister_driver(struct vio_driver *viodrv)
131} 131}
132EXPORT_SYMBOL(vio_unregister_driver); 132EXPORT_SYMBOL(vio_unregister_driver);
133 133
134static void __devinit vio_dev_release(struct device *dev) 134static void vio_dev_release(struct device *dev)
135{ 135{
136 kfree(to_vio_dev(dev)); 136 kfree(to_vio_dev(dev));
137} 137}
diff --git a/arch/sparc64/kernel/vmlinux.lds.S b/arch/sparc64/kernel/vmlinux.lds.S
index 9fcd503bc04a..01f809617e5e 100644
--- a/arch/sparc64/kernel/vmlinux.lds.S
+++ b/arch/sparc64/kernel/vmlinux.lds.S
@@ -56,11 +56,11 @@ SECTIONS
56 .init.text : { 56 .init.text : {
57 __init_begin = .; 57 __init_begin = .;
58 _sinittext = .; 58 _sinittext = .;
59 *(.init.text) 59 INIT_TEXT
60 _einittext = .; 60 _einittext = .;
61 } 61 }
62 .init.data : { 62 .init.data : {
63 *(.init.data) 63 INIT_DATA
64 } 64 }
65 . = ALIGN(16); 65 . = ALIGN(16);
66 .init.setup : { 66 .init.setup : {
@@ -137,8 +137,8 @@ SECTIONS
137 PROVIDE (end = .); 137 PROVIDE (end = .);
138 138
139 /DISCARD/ : { 139 /DISCARD/ : {
140 *(.exit.text) 140 EXIT_TEXT
141 *(.exit.data) 141 EXIT_DATA
142 *(.exitcall.exit) 142 *(.exitcall.exit)
143 } 143 }
144 144
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index b1a77b11f089..99f9f9605e9c 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -475,17 +475,9 @@ static void do_ubd_request(struct request_queue * q);
475/* Only changed by ubd_init, which is an initcall. */ 475/* Only changed by ubd_init, which is an initcall. */
476int thread_fd = -1; 476int thread_fd = -1;
477 477
478static void ubd_end_request(struct request *req, int bytes, int uptodate) 478static void ubd_end_request(struct request *req, int bytes, int error)
479{ 479{
480 if (!end_that_request_first(req, uptodate, bytes >> 9)) { 480 blk_end_request(req, error, bytes);
481 struct ubd *dev = req->rq_disk->private_data;
482 unsigned long flags;
483
484 add_disk_randomness(req->rq_disk);
485 spin_lock_irqsave(&dev->lock, flags);
486 end_that_request_last(req, uptodate);
487 spin_unlock_irqrestore(&dev->lock, flags);
488 }
489} 481}
490 482
491/* Callable only from interrupt context - otherwise you need to do 483/* Callable only from interrupt context - otherwise you need to do
@@ -493,10 +485,10 @@ static void ubd_end_request(struct request *req, int bytes, int uptodate)
493static inline void ubd_finish(struct request *req, int bytes) 485static inline void ubd_finish(struct request *req, int bytes)
494{ 486{
495 if(bytes < 0){ 487 if(bytes < 0){
496 ubd_end_request(req, 0, 0); 488 ubd_end_request(req, 0, -EIO);
497 return; 489 return;
498 } 490 }
499 ubd_end_request(req, bytes, 1); 491 ubd_end_request(req, bytes, 0);
500} 492}
501 493
502static LIST_HEAD(restart); 494static LIST_HEAD(restart);
diff --git a/arch/um/include/init.h b/arch/um/include/init.h
index d4de7c0120ce..cebc6cae9190 100644
--- a/arch/um/include/init.h
+++ b/arch/um/include/init.h
@@ -42,15 +42,15 @@ typedef void (*exitcall_t)(void);
42 42
43/* These are for everybody (although not all archs will actually 43/* These are for everybody (although not all archs will actually
44 discard it in modules) */ 44 discard it in modules) */
45#define __init __attribute__ ((__section__ (".init.text"))) 45#define __init __section(.init.text)
46#define __initdata __attribute__ ((__section__ (".init.data"))) 46#define __initdata __section(.init.data)
47#define __exitdata __attribute__ ((__section__(".exit.data"))) 47#define __exitdata __section(.exit.data)
48#define __exit_call __attribute_used__ __attribute__ ((__section__ (".exitcall.exit"))) 48#define __exit_call __used __section(.exitcall.exit)
49 49
50#ifdef MODULE 50#ifdef MODULE
51#define __exit __attribute__ ((__section__(".exit.text"))) 51#define __exit __section(.exit.text)
52#else 52#else
53#define __exit __attribute_used__ __attribute__ ((__section__(".exit.text"))) 53#define __exit __used __section(.exit.text)
54#endif 54#endif
55 55
56#endif 56#endif
@@ -103,16 +103,16 @@ extern struct uml_param __uml_setup_start, __uml_setup_end;
103 * Mark functions and data as being only used at initialization 103 * Mark functions and data as being only used at initialization
104 * or exit time. 104 * or exit time.
105 */ 105 */
106#define __uml_init_setup __attribute_used__ __attribute__ ((__section__ (".uml.setup.init"))) 106#define __uml_init_setup __used __section(.uml.setup.init)
107#define __uml_setup_help __attribute_used__ __attribute__ ((__section__ (".uml.help.init"))) 107#define __uml_setup_help __used __section(.uml.help.init)
108#define __uml_init_call __attribute_used__ __attribute__ ((__section__ (".uml.initcall.init"))) 108#define __uml_init_call __used __section(.uml.initcall.init)
109#define __uml_postsetup_call __attribute_used__ __attribute__ ((__section__ (".uml.postsetup.init"))) 109#define __uml_postsetup_call __used __section(.uml.postsetup.init)
110#define __uml_exit_call __attribute_used__ __attribute__ ((__section__ (".uml.exitcall.exit"))) 110#define __uml_exit_call __used __section(.uml.exitcall.exit)
111 111
112#ifndef __KERNEL__ 112#ifndef __KERNEL__
113 113
114#define __define_initcall(level,fn) \ 114#define __define_initcall(level,fn) \
115 static initcall_t __initcall_##fn __attribute_used__ \ 115 static initcall_t __initcall_##fn __used \
116 __attribute__((__section__(".initcall" level ".init"))) = fn 116 __attribute__((__section__(".initcall" level ".init"))) = fn
117 117
118/* Userspace initcalls shouldn't depend on anything in the kernel, so we'll 118/* Userspace initcalls shouldn't depend on anything in the kernel, so we'll
@@ -122,7 +122,7 @@ extern struct uml_param __uml_setup_start, __uml_setup_end;
122 122
123#define __exitcall(fn) static exitcall_t __exitcall_##fn __exit_call = fn 123#define __exitcall(fn) static exitcall_t __exitcall_##fn __exit_call = fn
124 124
125#define __init_call __attribute_used__ __attribute__ ((__section__ (".initcall.init"))) 125#define __init_call __used __section(.initcall.init)
126 126
127#endif 127#endif
128 128
diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S
index 3866f4960f04..26090b7f323e 100644
--- a/arch/um/kernel/dyn.lds.S
+++ b/arch/um/kernel/dyn.lds.S
@@ -17,7 +17,7 @@ SECTIONS
17 __init_begin = .; 17 __init_begin = .;
18 .init.text : { 18 .init.text : {
19 _sinittext = .; 19 _sinittext = .;
20 *(.init.text) 20 INIT_TEXT
21 _einittext = .; 21 _einittext = .;
22 } 22 }
23 23
@@ -84,7 +84,7 @@ SECTIONS
84 84
85 #include "asm/common.lds.S" 85 #include "asm/common.lds.S"
86 86
87 init.data : { *(.init.data) } 87 init.data : { INIT_DATA }
88 88
89 /* Ensure the __preinit_array_start label is properly aligned. We 89 /* Ensure the __preinit_array_start label is properly aligned. We
90 could instead move the label definition inside the section, but 90 could instead move the label definition inside the section, but
diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c
index 1b388b41d95d..7c7142ba3bd7 100644
--- a/arch/um/kernel/ksyms.c
+++ b/arch/um/kernel/ksyms.c
@@ -71,10 +71,10 @@ EXPORT_SYMBOL(dump_thread);
71 71
72/* required for SMP */ 72/* required for SMP */
73 73
74extern void FASTCALL( __write_lock_failed(rwlock_t *rw)); 74extern void __write_lock_failed(rwlock_t *rw);
75EXPORT_SYMBOL(__write_lock_failed); 75EXPORT_SYMBOL(__write_lock_failed);
76 76
77extern void FASTCALL( __read_lock_failed(rwlock_t *rw)); 77extern void __read_lock_failed(rwlock_t *rw);
78EXPORT_SYMBOL(__read_lock_failed); 78EXPORT_SYMBOL(__read_lock_failed);
79 79
80#endif 80#endif
diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S
index 13df191e2b41..5828c1d54505 100644
--- a/arch/um/kernel/uml.lds.S
+++ b/arch/um/kernel/uml.lds.S
@@ -23,7 +23,7 @@ SECTIONS
23 __init_begin = .; 23 __init_begin = .;
24 .init.text : { 24 .init.text : {
25 _sinittext = .; 25 _sinittext = .;
26 *(.init.text) 26 INIT_TEXT
27 _einittext = .; 27 _einittext = .;
28 } 28 }
29 . = ALIGN(4096); 29 . = ALIGN(4096);
@@ -48,7 +48,7 @@ SECTIONS
48 48
49 #include "asm/common.lds.S" 49 #include "asm/common.lds.S"
50 50
51 init.data : { *(init.data) } 51 init.data : { INIT_DATA }
52 .data : 52 .data :
53 { 53 {
54 . = ALIGN(KERNEL_STACK_SIZE); /* init_task */ 54 . = ALIGN(KERNEL_STACK_SIZE); /* init_task */
diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c
index 0147227ce18d..19053d46cb60 100644
--- a/arch/um/sys-i386/signal.c
+++ b/arch/um/sys-i386/signal.c
@@ -3,10 +3,10 @@
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/ptrace.h" 6#include <linux/ptrace.h>
7#include "asm/unistd.h" 7#include <asm/unistd.h>
8#include "asm/uaccess.h" 8#include <asm/uaccess.h>
9#include "asm/ucontext.h" 9#include <asm/ucontext.h>
10#include "frame_kern.h" 10#include "frame_kern.h"
11#include "skas.h" 11#include "skas.h"
12 12
@@ -18,17 +18,17 @@ void copy_sc(struct uml_pt_regs *regs, void *from)
18 REGS_FS(regs->gp) = sc->fs; 18 REGS_FS(regs->gp) = sc->fs;
19 REGS_ES(regs->gp) = sc->es; 19 REGS_ES(regs->gp) = sc->es;
20 REGS_DS(regs->gp) = sc->ds; 20 REGS_DS(regs->gp) = sc->ds;
21 REGS_EDI(regs->gp) = sc->edi; 21 REGS_EDI(regs->gp) = sc->di;
22 REGS_ESI(regs->gp) = sc->esi; 22 REGS_ESI(regs->gp) = sc->si;
23 REGS_EBP(regs->gp) = sc->ebp; 23 REGS_EBP(regs->gp) = sc->bp;
24 REGS_SP(regs->gp) = sc->esp; 24 REGS_SP(regs->gp) = sc->sp;
25 REGS_EBX(regs->gp) = sc->ebx; 25 REGS_EBX(regs->gp) = sc->bx;
26 REGS_EDX(regs->gp) = sc->edx; 26 REGS_EDX(regs->gp) = sc->dx;
27 REGS_ECX(regs->gp) = sc->ecx; 27 REGS_ECX(regs->gp) = sc->cx;
28 REGS_EAX(regs->gp) = sc->eax; 28 REGS_EAX(regs->gp) = sc->ax;
29 REGS_IP(regs->gp) = sc->eip; 29 REGS_IP(regs->gp) = sc->ip;
30 REGS_CS(regs->gp) = sc->cs; 30 REGS_CS(regs->gp) = sc->cs;
31 REGS_EFLAGS(regs->gp) = sc->eflags; 31 REGS_EFLAGS(regs->gp) = sc->flags;
32 REGS_SS(regs->gp) = sc->ss; 32 REGS_SS(regs->gp) = sc->ss;
33} 33}
34 34
@@ -229,18 +229,18 @@ static int copy_sc_to_user(struct sigcontext __user *to,
229 sc.fs = REGS_FS(regs->regs.gp); 229 sc.fs = REGS_FS(regs->regs.gp);
230 sc.es = REGS_ES(regs->regs.gp); 230 sc.es = REGS_ES(regs->regs.gp);
231 sc.ds = REGS_DS(regs->regs.gp); 231 sc.ds = REGS_DS(regs->regs.gp);
232 sc.edi = REGS_EDI(regs->regs.gp); 232 sc.di = REGS_EDI(regs->regs.gp);
233 sc.esi = REGS_ESI(regs->regs.gp); 233 sc.si = REGS_ESI(regs->regs.gp);
234 sc.ebp = REGS_EBP(regs->regs.gp); 234 sc.bp = REGS_EBP(regs->regs.gp);
235 sc.esp = sp; 235 sc.sp = sp;
236 sc.ebx = REGS_EBX(regs->regs.gp); 236 sc.bx = REGS_EBX(regs->regs.gp);
237 sc.edx = REGS_EDX(regs->regs.gp); 237 sc.dx = REGS_EDX(regs->regs.gp);
238 sc.ecx = REGS_ECX(regs->regs.gp); 238 sc.cx = REGS_ECX(regs->regs.gp);
239 sc.eax = REGS_EAX(regs->regs.gp); 239 sc.ax = REGS_EAX(regs->regs.gp);
240 sc.eip = REGS_IP(regs->regs.gp); 240 sc.ip = REGS_IP(regs->regs.gp);
241 sc.cs = REGS_CS(regs->regs.gp); 241 sc.cs = REGS_CS(regs->regs.gp);
242 sc.eflags = REGS_EFLAGS(regs->regs.gp); 242 sc.flags = REGS_EFLAGS(regs->regs.gp);
243 sc.esp_at_signal = regs->regs.gp[UESP]; 243 sc.sp_at_signal = regs->regs.gp[UESP];
244 sc.ss = regs->regs.gp[SS]; 244 sc.ss = regs->regs.gp[SS];
245 sc.cr2 = fi->cr2; 245 sc.cr2 = fi->cr2;
246 sc.err = fi->error_code; 246 sc.err = fi->error_code;
diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c
index 1778d33808f4..7457436b433a 100644
--- a/arch/um/sys-x86_64/signal.c
+++ b/arch/um/sys-x86_64/signal.c
@@ -4,11 +4,11 @@
4 * Licensed under the GPL 4 * Licensed under the GPL
5 */ 5 */
6 6
7#include "linux/personality.h" 7#include <linux/personality.h>
8#include "linux/ptrace.h" 8#include <linux/ptrace.h>
9#include "asm/unistd.h" 9#include <asm/unistd.h>
10#include "asm/uaccess.h" 10#include <asm/uaccess.h>
11#include "asm/ucontext.h" 11#include <asm/ucontext.h>
12#include "frame_kern.h" 12#include "frame_kern.h"
13#include "skas.h" 13#include "skas.h"
14 14
@@ -27,16 +27,16 @@ void copy_sc(struct uml_pt_regs *regs, void *from)
27 GETREG(regs, R13, sc, r13); 27 GETREG(regs, R13, sc, r13);
28 GETREG(regs, R14, sc, r14); 28 GETREG(regs, R14, sc, r14);
29 GETREG(regs, R15, sc, r15); 29 GETREG(regs, R15, sc, r15);
30 GETREG(regs, RDI, sc, rdi); 30 GETREG(regs, RDI, sc, di);
31 GETREG(regs, RSI, sc, rsi); 31 GETREG(regs, RSI, sc, si);
32 GETREG(regs, RBP, sc, rbp); 32 GETREG(regs, RBP, sc, bp);
33 GETREG(regs, RBX, sc, rbx); 33 GETREG(regs, RBX, sc, bx);
34 GETREG(regs, RDX, sc, rdx); 34 GETREG(regs, RDX, sc, dx);
35 GETREG(regs, RAX, sc, rax); 35 GETREG(regs, RAX, sc, ax);
36 GETREG(regs, RCX, sc, rcx); 36 GETREG(regs, RCX, sc, cx);
37 GETREG(regs, RSP, sc, rsp); 37 GETREG(regs, RSP, sc, sp);
38 GETREG(regs, RIP, sc, rip); 38 GETREG(regs, RIP, sc, ip);
39 GETREG(regs, EFLAGS, sc, eflags); 39 GETREG(regs, EFLAGS, sc, flags);
40 GETREG(regs, CS, sc, cs); 40 GETREG(regs, CS, sc, cs);
41 41
42#undef GETREG 42#undef GETREG
@@ -61,16 +61,16 @@ static int copy_sc_from_user(struct pt_regs *regs,
61 err |= GETREG(regs, R13, from, r13); 61 err |= GETREG(regs, R13, from, r13);
62 err |= GETREG(regs, R14, from, r14); 62 err |= GETREG(regs, R14, from, r14);
63 err |= GETREG(regs, R15, from, r15); 63 err |= GETREG(regs, R15, from, r15);
64 err |= GETREG(regs, RDI, from, rdi); 64 err |= GETREG(regs, RDI, from, di);
65 err |= GETREG(regs, RSI, from, rsi); 65 err |= GETREG(regs, RSI, from, si);
66 err |= GETREG(regs, RBP, from, rbp); 66 err |= GETREG(regs, RBP, from, bp);
67 err |= GETREG(regs, RBX, from, rbx); 67 err |= GETREG(regs, RBX, from, bx);
68 err |= GETREG(regs, RDX, from, rdx); 68 err |= GETREG(regs, RDX, from, dx);
69 err |= GETREG(regs, RAX, from, rax); 69 err |= GETREG(regs, RAX, from, ax);
70 err |= GETREG(regs, RCX, from, rcx); 70 err |= GETREG(regs, RCX, from, cx);
71 err |= GETREG(regs, RSP, from, rsp); 71 err |= GETREG(regs, RSP, from, sp);
72 err |= GETREG(regs, RIP, from, rip); 72 err |= GETREG(regs, RIP, from, ip);
73 err |= GETREG(regs, EFLAGS, from, eflags); 73 err |= GETREG(regs, EFLAGS, from, flags);
74 err |= GETREG(regs, CS, from, cs); 74 err |= GETREG(regs, CS, from, cs);
75 if (err) 75 if (err)
76 return 1; 76 return 1;
@@ -108,19 +108,19 @@ static int copy_sc_to_user(struct sigcontext __user *to,
108 __put_user((regs)->regs.gp[(regno) / sizeof(unsigned long)], \ 108 __put_user((regs)->regs.gp[(regno) / sizeof(unsigned long)], \
109 &(sc)->regname) 109 &(sc)->regname)
110 110
111 err |= PUTREG(regs, RDI, to, rdi); 111 err |= PUTREG(regs, RDI, to, di);
112 err |= PUTREG(regs, RSI, to, rsi); 112 err |= PUTREG(regs, RSI, to, si);
113 err |= PUTREG(regs, RBP, to, rbp); 113 err |= PUTREG(regs, RBP, to, bp);
114 /* 114 /*
115 * Must use orignal RSP, which is passed in, rather than what's in 115 * Must use orignal RSP, which is passed in, rather than what's in
116 * the pt_regs, because that's already been updated to point at the 116 * the pt_regs, because that's already been updated to point at the
117 * signal frame. 117 * signal frame.
118 */ 118 */
119 err |= __put_user(sp, &to->rsp); 119 err |= __put_user(sp, &to->sp);
120 err |= PUTREG(regs, RBX, to, rbx); 120 err |= PUTREG(regs, RBX, to, bx);
121 err |= PUTREG(regs, RDX, to, rdx); 121 err |= PUTREG(regs, RDX, to, dx);
122 err |= PUTREG(regs, RCX, to, rcx); 122 err |= PUTREG(regs, RCX, to, cx);
123 err |= PUTREG(regs, RAX, to, rax); 123 err |= PUTREG(regs, RAX, to, ax);
124 err |= PUTREG(regs, R8, to, r8); 124 err |= PUTREG(regs, R8, to, r8);
125 err |= PUTREG(regs, R9, to, r9); 125 err |= PUTREG(regs, R9, to, r9);
126 err |= PUTREG(regs, R10, to, r10); 126 err |= PUTREG(regs, R10, to, r10);
@@ -135,8 +135,8 @@ static int copy_sc_to_user(struct sigcontext __user *to,
135 err |= __put_user(fi->error_code, &to->err); 135 err |= __put_user(fi->error_code, &to->err);
136 err |= __put_user(fi->trap_no, &to->trapno); 136 err |= __put_user(fi->trap_no, &to->trapno);
137 137
138 err |= PUTREG(regs, RIP, to, rip); 138 err |= PUTREG(regs, RIP, to, ip);
139 err |= PUTREG(regs, EFLAGS, to, eflags); 139 err |= PUTREG(regs, EFLAGS, to, flags);
140#undef PUTREG 140#undef PUTREG
141 141
142 err |= __put_user(mask, &to->oldmask); 142 err |= __put_user(mask, &to->oldmask);
diff --git a/arch/v850/kernel/vmlinux.lds.S b/arch/v850/kernel/vmlinux.lds.S
index 6172599b4ce2..d08cd1d27f27 100644
--- a/arch/v850/kernel/vmlinux.lds.S
+++ b/arch/v850/kernel/vmlinux.lds.S
@@ -114,7 +114,7 @@
114#define DATA_CONTENTS \ 114#define DATA_CONTENTS \
115 __sdata = . ; \ 115 __sdata = . ; \
116 DATA_DATA \ 116 DATA_DATA \
117 *(.exit.data) /* 2.5 convention */ \ 117 EXIT_DATA /* 2.5 convention */ \
118 *(.data.exit) /* 2.4 convention */ \ 118 *(.data.exit) /* 2.4 convention */ \
119 . = ALIGN (16) ; \ 119 . = ALIGN (16) ; \
120 *(.data.cacheline_aligned) \ 120 *(.data.cacheline_aligned) \
@@ -157,9 +157,9 @@
157 . = ALIGN (4096) ; \ 157 . = ALIGN (4096) ; \
158 __init_start = . ; \ 158 __init_start = . ; \
159 __sinittext = .; \ 159 __sinittext = .; \
160 *(.init.text) /* 2.5 convention */ \ 160 INIT_TEXT /* 2.5 convention */ \
161 __einittext = .; \ 161 __einittext = .; \
162 *(.init.data) \ 162 INIT_DATA \
163 *(.text.init) /* 2.4 convention */ \ 163 *(.text.init) /* 2.4 convention */ \
164 *(.data.init) \ 164 *(.data.init) \
165 INITCALL_CONTENTS \ 165 INITCALL_CONTENTS \
@@ -170,7 +170,7 @@
170#define ROMK_INIT_RAM_CONTENTS \ 170#define ROMK_INIT_RAM_CONTENTS \
171 . = ALIGN (4096) ; \ 171 . = ALIGN (4096) ; \
172 __init_start = . ; \ 172 __init_start = . ; \
173 *(.init.data) /* 2.5 convention */ \ 173 INIT_DATA /* 2.5 convention */ \
174 *(.data.init) /* 2.4 convention */ \ 174 *(.data.init) /* 2.4 convention */ \
175 __init_end = . ; \ 175 __init_end = . ; \
176 . = ALIGN (4096) ; 176 . = ALIGN (4096) ;
@@ -179,7 +179,7 @@
179 should go into ROM. */ 179 should go into ROM. */
180#define ROMK_INIT_ROM_CONTENTS \ 180#define ROMK_INIT_ROM_CONTENTS \
181 _sinittext = .; \ 181 _sinittext = .; \
182 *(.init.text) /* 2.5 convention */ \ 182 INIT_TEXT /* 2.5 convention */ \
183 _einittext = .; \ 183 _einittext = .; \
184 *(.text.init) /* 2.4 convention */ \ 184 *(.text.init) /* 2.4 convention */ \
185 INITCALL_CONTENTS \ 185 INITCALL_CONTENTS \
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 80b7ba4056db..65b449134cf7 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -17,81 +17,69 @@ config X86_64
17 17
18### Arch settings 18### Arch settings
19config X86 19config X86
20 bool 20 def_bool y
21 default y 21
22config GENERIC_LOCKBREAK
23 def_bool n
22 24
23config GENERIC_TIME 25config GENERIC_TIME
24 bool 26 def_bool y
25 default y
26 27
27config GENERIC_CMOS_UPDATE 28config GENERIC_CMOS_UPDATE
28 bool 29 def_bool y
29 default y
30 30
31config CLOCKSOURCE_WATCHDOG 31config CLOCKSOURCE_WATCHDOG
32 bool 32 def_bool y
33 default y
34 33
35config GENERIC_CLOCKEVENTS 34config GENERIC_CLOCKEVENTS
36 bool 35 def_bool y
37 default y
38 36
39config GENERIC_CLOCKEVENTS_BROADCAST 37config GENERIC_CLOCKEVENTS_BROADCAST
40 bool 38 def_bool y
41 default y
42 depends on X86_64 || (X86_32 && X86_LOCAL_APIC) 39 depends on X86_64 || (X86_32 && X86_LOCAL_APIC)
43 40
44config LOCKDEP_SUPPORT 41config LOCKDEP_SUPPORT
45 bool 42 def_bool y
46 default y
47 43
48config STACKTRACE_SUPPORT 44config STACKTRACE_SUPPORT
49 bool 45 def_bool y
50 default y
51 46
52config SEMAPHORE_SLEEPERS 47config SEMAPHORE_SLEEPERS
53 bool 48 def_bool y
54 default y
55 49
56config MMU 50config MMU
57 bool 51 def_bool y
58 default y
59 52
60config ZONE_DMA 53config ZONE_DMA
61 bool 54 def_bool y
62 default y
63 55
64config QUICKLIST 56config QUICKLIST
65 bool 57 def_bool X86_32
66 default X86_32
67 58
68config SBUS 59config SBUS
69 bool 60 bool
70 61
71config GENERIC_ISA_DMA 62config GENERIC_ISA_DMA
72 bool 63 def_bool y
73 default y
74 64
75config GENERIC_IOMAP 65config GENERIC_IOMAP
76 bool 66 def_bool y
77 default y
78 67
79config GENERIC_BUG 68config GENERIC_BUG
80 bool 69 def_bool y
81 default y
82 depends on BUG 70 depends on BUG
83 71
84config GENERIC_HWEIGHT 72config GENERIC_HWEIGHT
85 bool 73 def_bool y
86 default y 74
75config GENERIC_GPIO
76 def_bool n
87 77
88config ARCH_MAY_HAVE_PC_FDC 78config ARCH_MAY_HAVE_PC_FDC
89 bool 79 def_bool y
90 default y
91 80
92config DMI 81config DMI
93 bool 82 def_bool y
94 default y
95 83
96config RWSEM_GENERIC_SPINLOCK 84config RWSEM_GENERIC_SPINLOCK
97 def_bool !X86_XADD 85 def_bool !X86_XADD
@@ -112,10 +100,14 @@ config GENERIC_TIME_VSYSCALL
112 bool 100 bool
113 default X86_64 101 default X86_64
114 102
103config HAVE_SETUP_PER_CPU_AREA
104 def_bool X86_64
105
115config ARCH_SUPPORTS_OPROFILE 106config ARCH_SUPPORTS_OPROFILE
116 bool 107 bool
117 default y 108 default y
118 109
110select HAVE_KVM
119 111
120config ZONE_DMA32 112config ZONE_DMA32
121 bool 113 bool
@@ -144,9 +136,17 @@ config GENERIC_PENDING_IRQ
144 136
145config X86_SMP 137config X86_SMP
146 bool 138 bool
147 depends on X86_32 && SMP && !X86_VOYAGER 139 depends on SMP && ((X86_32 && !X86_VOYAGER) || X86_64)
148 default y 140 default y
149 141
142config X86_32_SMP
143 def_bool y
144 depends on X86_32 && SMP
145
146config X86_64_SMP
147 def_bool y
148 depends on X86_64 && SMP
149
150config X86_HT 150config X86_HT
151 bool 151 bool
152 depends on SMP 152 depends on SMP
@@ -292,6 +292,18 @@ config X86_ES7000
292 Only choose this option if you have such a system, otherwise you 292 Only choose this option if you have such a system, otherwise you
293 should say N here. 293 should say N here.
294 294
295config X86_RDC321X
296 bool "RDC R-321x SoC"
297 depends on X86_32
298 select M486
299 select X86_REBOOTFIXUPS
300 select GENERIC_GPIO
301 select LEDS_GPIO
302 help
303 This option is needed for RDC R-321x system-on-chip, also known
304 as R-8610-(G).
305 If you don't have one of these chips, you should say N here.
306
295config X86_VSMP 307config X86_VSMP
296 bool "Support for ScaleMP vSMP" 308 bool "Support for ScaleMP vSMP"
297 depends on X86_64 && PCI 309 depends on X86_64 && PCI
@@ -303,8 +315,8 @@ config X86_VSMP
303endchoice 315endchoice
304 316
305config SCHED_NO_NO_OMIT_FRAME_POINTER 317config SCHED_NO_NO_OMIT_FRAME_POINTER
306 bool "Single-depth WCHAN output" 318 def_bool y
307 default y 319 prompt "Single-depth WCHAN output"
308 depends on X86_32 320 depends on X86_32
309 help 321 help
310 Calculate simpler /proc/<PID>/wchan values. If this option 322 Calculate simpler /proc/<PID>/wchan values. If this option
@@ -314,18 +326,8 @@ config SCHED_NO_NO_OMIT_FRAME_POINTER
314 326
315 If in doubt, say "Y". 327 If in doubt, say "Y".
316 328
317config PARAVIRT
318 bool
319 depends on X86_32 && !(X86_VISWS || X86_VOYAGER)
320 help
321 This changes the kernel so it can modify itself when it is run
322 under a hypervisor, potentially improving performance significantly
323 over full virtualization. However, when run without a hypervisor
324 the kernel is theoretically slower and slightly larger.
325
326menuconfig PARAVIRT_GUEST 329menuconfig PARAVIRT_GUEST
327 bool "Paravirtualized guest support" 330 bool "Paravirtualized guest support"
328 depends on X86_32
329 help 331 help
330 Say Y here to get to see options related to running Linux under 332 Say Y here to get to see options related to running Linux under
331 various hypervisors. This option alone does not add any kernel code. 333 various hypervisors. This option alone does not add any kernel code.
@@ -339,6 +341,7 @@ source "arch/x86/xen/Kconfig"
339config VMI 341config VMI
340 bool "VMI Guest support" 342 bool "VMI Guest support"
341 select PARAVIRT 343 select PARAVIRT
344 depends on X86_32
342 depends on !(X86_VISWS || X86_VOYAGER) 345 depends on !(X86_VISWS || X86_VOYAGER)
343 help 346 help
344 VMI provides a paravirtualized interface to the VMware ESX server 347 VMI provides a paravirtualized interface to the VMware ESX server
@@ -348,40 +351,43 @@ config VMI
348 351
349source "arch/x86/lguest/Kconfig" 352source "arch/x86/lguest/Kconfig"
350 353
354config PARAVIRT
355 bool "Enable paravirtualization code"
356 depends on !(X86_VISWS || X86_VOYAGER)
357 help
358 This changes the kernel so it can modify itself when it is run
359 under a hypervisor, potentially improving performance significantly
360 over full virtualization. However, when run without a hypervisor
361 the kernel is theoretically slower and slightly larger.
362
351endif 363endif
352 364
353config ACPI_SRAT 365config ACPI_SRAT
354 bool 366 def_bool y
355 default y
356 depends on X86_32 && ACPI && NUMA && (X86_SUMMIT || X86_GENERICARCH) 367 depends on X86_32 && ACPI && NUMA && (X86_SUMMIT || X86_GENERICARCH)
357 select ACPI_NUMA 368 select ACPI_NUMA
358 369
359config HAVE_ARCH_PARSE_SRAT 370config HAVE_ARCH_PARSE_SRAT
360 bool 371 def_bool y
361 default y 372 depends on ACPI_SRAT
362 depends on ACPI_SRAT
363 373
364config X86_SUMMIT_NUMA 374config X86_SUMMIT_NUMA
365 bool 375 def_bool y
366 default y
367 depends on X86_32 && NUMA && (X86_SUMMIT || X86_GENERICARCH) 376 depends on X86_32 && NUMA && (X86_SUMMIT || X86_GENERICARCH)
368 377
369config X86_CYCLONE_TIMER 378config X86_CYCLONE_TIMER
370 bool 379 def_bool y
371 default y
372 depends on X86_32 && X86_SUMMIT || X86_GENERICARCH 380 depends on X86_32 && X86_SUMMIT || X86_GENERICARCH
373 381
374config ES7000_CLUSTERED_APIC 382config ES7000_CLUSTERED_APIC
375 bool 383 def_bool y
376 default y
377 depends on SMP && X86_ES7000 && MPENTIUMIII 384 depends on SMP && X86_ES7000 && MPENTIUMIII
378 385
379source "arch/x86/Kconfig.cpu" 386source "arch/x86/Kconfig.cpu"
380 387
381config HPET_TIMER 388config HPET_TIMER
382 bool 389 def_bool X86_64
383 prompt "HPET Timer Support" if X86_32 390 prompt "HPET Timer Support" if X86_32
384 default X86_64
385 help 391 help
386 Use the IA-PC HPET (High Precision Event Timer) to manage 392 Use the IA-PC HPET (High Precision Event Timer) to manage
387 time in preference to the PIT and RTC, if a HPET is 393 time in preference to the PIT and RTC, if a HPET is
@@ -399,9 +405,8 @@ config HPET_TIMER
399 Choose N to continue using the legacy 8254 timer. 405 Choose N to continue using the legacy 8254 timer.
400 406
401config HPET_EMULATE_RTC 407config HPET_EMULATE_RTC
402 bool 408 def_bool y
403 depends on HPET_TIMER && RTC=y 409 depends on HPET_TIMER && (RTC=y || RTC=m)
404 default y
405 410
406# Mark as embedded because too many people got it wrong. 411# Mark as embedded because too many people got it wrong.
407# The code disables itself when not needed. 412# The code disables itself when not needed.
@@ -441,8 +446,8 @@ config CALGARY_IOMMU
441 If unsure, say Y. 446 If unsure, say Y.
442 447
443config CALGARY_IOMMU_ENABLED_BY_DEFAULT 448config CALGARY_IOMMU_ENABLED_BY_DEFAULT
444 bool "Should Calgary be enabled by default?" 449 def_bool y
445 default y 450 prompt "Should Calgary be enabled by default?"
446 depends on CALGARY_IOMMU 451 depends on CALGARY_IOMMU
447 help 452 help
448 Should Calgary be enabled by default? if you choose 'y', Calgary 453 Should Calgary be enabled by default? if you choose 'y', Calgary
@@ -486,9 +491,9 @@ config SCHED_SMT
486 N here. 491 N here.
487 492
488config SCHED_MC 493config SCHED_MC
489 bool "Multi-core scheduler support" 494 def_bool y
495 prompt "Multi-core scheduler support"
490 depends on (X86_64 && SMP) || (X86_32 && X86_HT) 496 depends on (X86_64 && SMP) || (X86_32 && X86_HT)
491 default y
492 help 497 help
493 Multi-core scheduler support improves the CPU scheduler's decision 498 Multi-core scheduler support improves the CPU scheduler's decision
494 making when dealing with multi-core CPU chips at a cost of slightly 499 making when dealing with multi-core CPU chips at a cost of slightly
@@ -522,19 +527,16 @@ config X86_UP_IOAPIC
522 an IO-APIC, then the kernel will still run with no slowdown at all. 527 an IO-APIC, then the kernel will still run with no slowdown at all.
523 528
524config X86_LOCAL_APIC 529config X86_LOCAL_APIC
525 bool 530 def_bool y
526 depends on X86_64 || (X86_32 && (X86_UP_APIC || ((X86_VISWS || SMP) && !X86_VOYAGER) || X86_GENERICARCH)) 531 depends on X86_64 || (X86_32 && (X86_UP_APIC || ((X86_VISWS || SMP) && !X86_VOYAGER) || X86_GENERICARCH))
527 default y
528 532
529config X86_IO_APIC 533config X86_IO_APIC
530 bool 534 def_bool y
531 depends on X86_64 || (X86_32 && (X86_UP_IOAPIC || (SMP && !(X86_VISWS || X86_VOYAGER)) || X86_GENERICARCH)) 535 depends on X86_64 || (X86_32 && (X86_UP_IOAPIC || (SMP && !(X86_VISWS || X86_VOYAGER)) || X86_GENERICARCH))
532 default y
533 536
534config X86_VISWS_APIC 537config X86_VISWS_APIC
535 bool 538 def_bool y
536 depends on X86_32 && X86_VISWS 539 depends on X86_32 && X86_VISWS
537 default y
538 540
539config X86_MCE 541config X86_MCE
540 bool "Machine Check Exception" 542 bool "Machine Check Exception"
@@ -554,17 +556,17 @@ config X86_MCE
554 the 386 and 486, so nearly everyone can say Y here. 556 the 386 and 486, so nearly everyone can say Y here.
555 557
556config X86_MCE_INTEL 558config X86_MCE_INTEL
557 bool "Intel MCE features" 559 def_bool y
560 prompt "Intel MCE features"
558 depends on X86_64 && X86_MCE && X86_LOCAL_APIC 561 depends on X86_64 && X86_MCE && X86_LOCAL_APIC
559 default y
560 help 562 help
561 Additional support for intel specific MCE features such as 563 Additional support for intel specific MCE features such as
562 the thermal monitor. 564 the thermal monitor.
563 565
564config X86_MCE_AMD 566config X86_MCE_AMD
565 bool "AMD MCE features" 567 def_bool y
568 prompt "AMD MCE features"
566 depends on X86_64 && X86_MCE && X86_LOCAL_APIC 569 depends on X86_64 && X86_MCE && X86_LOCAL_APIC
567 default y
568 help 570 help
569 Additional support for AMD specific MCE features such as 571 Additional support for AMD specific MCE features such as
570 the DRAM Error Threshold. 572 the DRAM Error Threshold.
@@ -637,9 +639,9 @@ config I8K
637 Say N otherwise. 639 Say N otherwise.
638 640
639config X86_REBOOTFIXUPS 641config X86_REBOOTFIXUPS
640 bool "Enable X86 board specific fixups for reboot" 642 def_bool n
643 prompt "Enable X86 board specific fixups for reboot"
641 depends on X86_32 && X86 644 depends on X86_32 && X86
642 default n
643 ---help--- 645 ---help---
644 This enables chipset and/or board specific fixups to be done 646 This enables chipset and/or board specific fixups to be done
645 in order to get reboot to work correctly. This is only needed on 647 in order to get reboot to work correctly. This is only needed on
@@ -648,7 +650,7 @@ config X86_REBOOTFIXUPS
648 system. 650 system.
649 651
650 Currently, the only fixup is for the Geode machines using 652 Currently, the only fixup is for the Geode machines using
651 CS5530A and CS5536 chipsets. 653 CS5530A and CS5536 chipsets and the RDC R-321x SoC.
652 654
653 Say Y if you want to enable the fixup. Currently, it's safe to 655 Say Y if you want to enable the fixup. Currently, it's safe to
654 enable this option even if you don't need it. 656 enable this option even if you don't need it.
@@ -672,9 +674,8 @@ config MICROCODE
672 module will be called microcode. 674 module will be called microcode.
673 675
674config MICROCODE_OLD_INTERFACE 676config MICROCODE_OLD_INTERFACE
675 bool 677 def_bool y
676 depends on MICROCODE 678 depends on MICROCODE
677 default y
678 679
679config X86_MSR 680config X86_MSR
680 tristate "/dev/cpu/*/msr - Model-specific register support" 681 tristate "/dev/cpu/*/msr - Model-specific register support"
@@ -798,13 +799,12 @@ config PAGE_OFFSET
798 depends on X86_32 799 depends on X86_32
799 800
800config HIGHMEM 801config HIGHMEM
801 bool 802 def_bool y
802 depends on X86_32 && (HIGHMEM64G || HIGHMEM4G) 803 depends on X86_32 && (HIGHMEM64G || HIGHMEM4G)
803 default y
804 804
805config X86_PAE 805config X86_PAE
806 bool "PAE (Physical Address Extension) Support" 806 def_bool n
807 default n 807 prompt "PAE (Physical Address Extension) Support"
808 depends on X86_32 && !HIGHMEM4G 808 depends on X86_32 && !HIGHMEM4G
809 select RESOURCES_64BIT 809 select RESOURCES_64BIT
810 help 810 help
@@ -836,10 +836,10 @@ comment "NUMA (Summit) requires SMP, 64GB highmem support, ACPI"
836 depends on X86_32 && X86_SUMMIT && (!HIGHMEM64G || !ACPI) 836 depends on X86_32 && X86_SUMMIT && (!HIGHMEM64G || !ACPI)
837 837
838config K8_NUMA 838config K8_NUMA
839 bool "Old style AMD Opteron NUMA detection" 839 def_bool y
840 depends on X86_64 && NUMA && PCI 840 prompt "Old style AMD Opteron NUMA detection"
841 default y 841 depends on X86_64 && NUMA && PCI
842 help 842 help
843 Enable K8 NUMA node topology detection. You should say Y here if 843 Enable K8 NUMA node topology detection. You should say Y here if
844 you have a multi processor AMD K8 system. This uses an old 844 you have a multi processor AMD K8 system. This uses an old
845 method to read the NUMA configuration directly from the builtin 845 method to read the NUMA configuration directly from the builtin
@@ -847,10 +847,10 @@ config K8_NUMA
847 instead, which also takes priority if both are compiled in. 847 instead, which also takes priority if both are compiled in.
848 848
849config X86_64_ACPI_NUMA 849config X86_64_ACPI_NUMA
850 bool "ACPI NUMA detection" 850 def_bool y
851 prompt "ACPI NUMA detection"
851 depends on X86_64 && NUMA && ACPI && PCI 852 depends on X86_64 && NUMA && ACPI && PCI
852 select ACPI_NUMA 853 select ACPI_NUMA
853 default y
854 help 854 help
855 Enable ACPI SRAT based node topology detection. 855 Enable ACPI SRAT based node topology detection.
856 856
@@ -864,52 +864,53 @@ config NUMA_EMU
864 864
865config NODES_SHIFT 865config NODES_SHIFT
866 int 866 int
867 range 1 15 if X86_64
867 default "6" if X86_64 868 default "6" if X86_64
868 default "4" if X86_NUMAQ 869 default "4" if X86_NUMAQ
869 default "3" 870 default "3"
870 depends on NEED_MULTIPLE_NODES 871 depends on NEED_MULTIPLE_NODES
871 872
872config HAVE_ARCH_BOOTMEM_NODE 873config HAVE_ARCH_BOOTMEM_NODE
873 bool 874 def_bool y
874 depends on X86_32 && NUMA 875 depends on X86_32 && NUMA
875 default y
876 876
877config ARCH_HAVE_MEMORY_PRESENT 877config ARCH_HAVE_MEMORY_PRESENT
878 bool 878 def_bool y
879 depends on X86_32 && DISCONTIGMEM 879 depends on X86_32 && DISCONTIGMEM
880 default y
881 880
882config NEED_NODE_MEMMAP_SIZE 881config NEED_NODE_MEMMAP_SIZE
883 bool 882 def_bool y
884 depends on X86_32 && (DISCONTIGMEM || SPARSEMEM) 883 depends on X86_32 && (DISCONTIGMEM || SPARSEMEM)
885 default y
886 884
887config HAVE_ARCH_ALLOC_REMAP 885config HAVE_ARCH_ALLOC_REMAP
888 bool 886 def_bool y
889 depends on X86_32 && NUMA 887 depends on X86_32 && NUMA
890 default y
891 888
892config ARCH_FLATMEM_ENABLE 889config ARCH_FLATMEM_ENABLE
893 def_bool y 890 def_bool y
894 depends on (X86_32 && ARCH_SELECT_MEMORY_MODEL && X86_PC) || (X86_64 && !NUMA) 891 depends on X86_32 && ARCH_SELECT_MEMORY_MODEL && X86_PC && !NUMA
895 892
896config ARCH_DISCONTIGMEM_ENABLE 893config ARCH_DISCONTIGMEM_ENABLE
897 def_bool y 894 def_bool y
898 depends on NUMA 895 depends on NUMA && X86_32
899 896
900config ARCH_DISCONTIGMEM_DEFAULT 897config ARCH_DISCONTIGMEM_DEFAULT
901 def_bool y 898 def_bool y
902 depends on NUMA 899 depends on NUMA && X86_32
900
901config ARCH_SPARSEMEM_DEFAULT
902 def_bool y
903 depends on X86_64
903 904
904config ARCH_SPARSEMEM_ENABLE 905config ARCH_SPARSEMEM_ENABLE
905 def_bool y 906 def_bool y
906 depends on NUMA || (EXPERIMENTAL && (X86_PC || X86_64)) 907 depends on X86_64 || NUMA || (EXPERIMENTAL && X86_PC)
907 select SPARSEMEM_STATIC if X86_32 908 select SPARSEMEM_STATIC if X86_32
908 select SPARSEMEM_VMEMMAP_ENABLE if X86_64 909 select SPARSEMEM_VMEMMAP_ENABLE if X86_64
909 910
910config ARCH_SELECT_MEMORY_MODEL 911config ARCH_SELECT_MEMORY_MODEL
911 def_bool y 912 def_bool y
912 depends on X86_32 && ARCH_SPARSEMEM_ENABLE 913 depends on ARCH_SPARSEMEM_ENABLE
913 914
914config ARCH_MEMORY_PROBE 915config ARCH_MEMORY_PROBE
915 def_bool X86_64 916 def_bool X86_64
@@ -987,42 +988,32 @@ config MTRR
987 See <file:Documentation/mtrr.txt> for more information. 988 See <file:Documentation/mtrr.txt> for more information.
988 989
989config EFI 990config EFI
990 bool "Boot from EFI support" 991 def_bool n
991 depends on X86_32 && ACPI 992 prompt "EFI runtime service support"
992 default n 993 depends on ACPI
993 ---help--- 994 ---help---
994 This enables the kernel to boot on EFI platforms using 995 This enables the kernel to use EFI runtime services that are
995 system configuration information passed to it from the firmware.
996 This also enables the kernel to use any EFI runtime services that are
997 available (such as the EFI variable services). 996 available (such as the EFI variable services).
998 997
999 This option is only useful on systems that have EFI firmware 998 This option is only useful on systems that have EFI firmware.
1000 and will result in a kernel image that is ~8k larger. In addition, 999 In addition, you should use the latest ELILO loader available
1001 you must use the latest ELILO loader available at 1000 at <http://elilo.sourceforge.net> in order to take advantage
1002 <http://elilo.sourceforge.net> in order to take advantage of 1001 of EFI runtime services. However, even with this option, the
1003 kernel initialization using EFI information (neither GRUB nor LILO know 1002 resultant kernel should continue to boot on existing non-EFI
1004 anything about EFI). However, even with this option, the resultant 1003 platforms.
1005 kernel should continue to boot on existing non-EFI platforms.
1006 1004
1007config IRQBALANCE 1005config IRQBALANCE
1008 bool "Enable kernel irq balancing" 1006 def_bool y
1007 prompt "Enable kernel irq balancing"
1009 depends on X86_32 && SMP && X86_IO_APIC 1008 depends on X86_32 && SMP && X86_IO_APIC
1010 default y
1011 help 1009 help
1012 The default yes will allow the kernel to do irq load balancing. 1010 The default yes will allow the kernel to do irq load balancing.
1013 Saying no will keep the kernel from doing irq load balancing. 1011 Saying no will keep the kernel from doing irq load balancing.
1014 1012
1015# turning this on wastes a bunch of space.
1016# Summit needs it only when NUMA is on
1017config BOOT_IOREMAP
1018 bool
1019 depends on X86_32 && (((X86_SUMMIT || X86_GENERICARCH) && NUMA) || (X86 && EFI))
1020 default y
1021
1022config SECCOMP 1013config SECCOMP
1023 bool "Enable seccomp to safely compute untrusted bytecode" 1014 def_bool y
1015 prompt "Enable seccomp to safely compute untrusted bytecode"
1024 depends on PROC_FS 1016 depends on PROC_FS
1025 default y
1026 help 1017 help
1027 This kernel feature is useful for number crunching applications 1018 This kernel feature is useful for number crunching applications
1028 that may need to compute untrusted bytecode during their 1019 that may need to compute untrusted bytecode during their
@@ -1189,11 +1180,11 @@ config HOTPLUG_CPU
1189 suspend. 1180 suspend.
1190 1181
1191config COMPAT_VDSO 1182config COMPAT_VDSO
1192 bool "Compat VDSO support" 1183 def_bool y
1193 default y 1184 prompt "Compat VDSO support"
1194 depends on X86_32 1185 depends on X86_32 || IA32_EMULATION
1195 help 1186 help
1196 Map the VDSO to the predictable old-style address too. 1187 Map the 32-bit VDSO to the predictable old-style address too.
1197 ---help--- 1188 ---help---
1198 Say N here if you are running a sufficiently recent glibc 1189 Say N here if you are running a sufficiently recent glibc
1199 version (2.3.3 or later), to remove the high-mapped 1190 version (2.3.3 or later), to remove the high-mapped
@@ -1207,30 +1198,26 @@ config ARCH_ENABLE_MEMORY_HOTPLUG
1207 def_bool y 1198 def_bool y
1208 depends on X86_64 || (X86_32 && HIGHMEM) 1199 depends on X86_64 || (X86_32 && HIGHMEM)
1209 1200
1210config MEMORY_HOTPLUG_RESERVE
1211 def_bool X86_64
1212 depends on (MEMORY_HOTPLUG && DISCONTIGMEM)
1213
1214config HAVE_ARCH_EARLY_PFN_TO_NID 1201config HAVE_ARCH_EARLY_PFN_TO_NID
1215 def_bool X86_64 1202 def_bool X86_64
1216 depends on NUMA 1203 depends on NUMA
1217 1204
1218config OUT_OF_LINE_PFN_TO_PAGE
1219 def_bool X86_64
1220 depends on DISCONTIGMEM
1221
1222menu "Power management options" 1205menu "Power management options"
1223 depends on !X86_VOYAGER 1206 depends on !X86_VOYAGER
1224 1207
1225config ARCH_HIBERNATION_HEADER 1208config ARCH_HIBERNATION_HEADER
1226 bool 1209 def_bool y
1227 depends on X86_64 && HIBERNATION 1210 depends on X86_64 && HIBERNATION
1228 default y
1229 1211
1230source "kernel/power/Kconfig" 1212source "kernel/power/Kconfig"
1231 1213
1232source "drivers/acpi/Kconfig" 1214source "drivers/acpi/Kconfig"
1233 1215
1216config X86_APM_BOOT
1217 bool
1218 default y
1219 depends on APM || APM_MODULE
1220
1234menuconfig APM 1221menuconfig APM
1235 tristate "APM (Advanced Power Management) BIOS support" 1222 tristate "APM (Advanced Power Management) BIOS support"
1236 depends on X86_32 && PM_SLEEP && !X86_VISWS 1223 depends on X86_32 && PM_SLEEP && !X86_VISWS
@@ -1371,7 +1358,7 @@ menu "Bus options (PCI etc.)"
1371config PCI 1358config PCI
1372 bool "PCI support" if !X86_VISWS 1359 bool "PCI support" if !X86_VISWS
1373 depends on !X86_VOYAGER 1360 depends on !X86_VOYAGER
1374 default y if X86_VISWS 1361 default y
1375 select ARCH_SUPPORTS_MSI if (X86_LOCAL_APIC && X86_IO_APIC) 1362 select ARCH_SUPPORTS_MSI if (X86_LOCAL_APIC && X86_IO_APIC)
1376 help 1363 help
1377 Find out whether you have a PCI motherboard. PCI is the name of a 1364 Find out whether you have a PCI motherboard. PCI is the name of a
@@ -1418,25 +1405,21 @@ config PCI_GOANY
1418endchoice 1405endchoice
1419 1406
1420config PCI_BIOS 1407config PCI_BIOS
1421 bool 1408 def_bool y
1422 depends on X86_32 && !X86_VISWS && PCI && (PCI_GOBIOS || PCI_GOANY) 1409 depends on X86_32 && !X86_VISWS && PCI && (PCI_GOBIOS || PCI_GOANY)
1423 default y
1424 1410
1425# x86-64 doesn't support PCI BIOS access from long mode so always go direct. 1411# x86-64 doesn't support PCI BIOS access from long mode so always go direct.
1426config PCI_DIRECT 1412config PCI_DIRECT
1427 bool 1413 def_bool y
1428 depends on PCI && (X86_64 || (PCI_GODIRECT || PCI_GOANY) || X86_VISWS) 1414 depends on PCI && (X86_64 || (PCI_GODIRECT || PCI_GOANY) || X86_VISWS)
1429 default y
1430 1415
1431config PCI_MMCONFIG 1416config PCI_MMCONFIG
1432 bool 1417 def_bool y
1433 depends on X86_32 && PCI && ACPI && (PCI_GOMMCONFIG || PCI_GOANY) 1418 depends on X86_32 && PCI && ACPI && (PCI_GOMMCONFIG || PCI_GOANY)
1434 default y
1435 1419
1436config PCI_DOMAINS 1420config PCI_DOMAINS
1437 bool 1421 def_bool y
1438 depends on PCI 1422 depends on PCI
1439 default y
1440 1423
1441config PCI_MMCONFIG 1424config PCI_MMCONFIG
1442 bool "Support mmconfig PCI config space access" 1425 bool "Support mmconfig PCI config space access"
@@ -1453,9 +1436,9 @@ config DMAR
1453 remapping devices. 1436 remapping devices.
1454 1437
1455config DMAR_GFX_WA 1438config DMAR_GFX_WA
1456 bool "Support for Graphics workaround" 1439 def_bool y
1440 prompt "Support for Graphics workaround"
1457 depends on DMAR 1441 depends on DMAR
1458 default y
1459 help 1442 help
1460 Current Graphics drivers tend to use physical address 1443 Current Graphics drivers tend to use physical address
1461 for DMA and avoid using DMA APIs. Setting this config 1444 for DMA and avoid using DMA APIs. Setting this config
@@ -1464,9 +1447,8 @@ config DMAR_GFX_WA
1464 to use physical addresses for DMA. 1447 to use physical addresses for DMA.
1465 1448
1466config DMAR_FLOPPY_WA 1449config DMAR_FLOPPY_WA
1467 bool 1450 def_bool y
1468 depends on DMAR 1451 depends on DMAR
1469 default y
1470 help 1452 help
1471 Floppy disk drivers are know to bypass DMA API calls 1453 Floppy disk drivers are know to bypass DMA API calls
1472 thereby failing to work when IOMMU is enabled. This 1454 thereby failing to work when IOMMU is enabled. This
@@ -1479,8 +1461,7 @@ source "drivers/pci/Kconfig"
1479 1461
1480# x86_64 have no ISA slots, but do have ISA-style DMA. 1462# x86_64 have no ISA slots, but do have ISA-style DMA.
1481config ISA_DMA_API 1463config ISA_DMA_API
1482 bool 1464 def_bool y
1483 default y
1484 1465
1485if X86_32 1466if X86_32
1486 1467
@@ -1546,9 +1527,9 @@ config SCx200HR_TIMER
1546 other workaround is idle=poll boot option. 1527 other workaround is idle=poll boot option.
1547 1528
1548config GEODE_MFGPT_TIMER 1529config GEODE_MFGPT_TIMER
1549 bool "Geode Multi-Function General Purpose Timer (MFGPT) events" 1530 def_bool y
1531 prompt "Geode Multi-Function General Purpose Timer (MFGPT) events"
1550 depends on MGEODE_LX && GENERIC_TIME && GENERIC_CLOCKEVENTS 1532 depends on MGEODE_LX && GENERIC_TIME && GENERIC_CLOCKEVENTS
1551 default y
1552 help 1533 help
1553 This driver provides a clock event source based on the MFGPT 1534 This driver provides a clock event source based on the MFGPT
1554 timer(s) in the CS5535 and CS5536 companion chip for the geode. 1535 timer(s) in the CS5535 and CS5536 companion chip for the geode.
@@ -1575,6 +1556,7 @@ source "fs/Kconfig.binfmt"
1575config IA32_EMULATION 1556config IA32_EMULATION
1576 bool "IA32 Emulation" 1557 bool "IA32 Emulation"
1577 depends on X86_64 1558 depends on X86_64
1559 select COMPAT_BINFMT_ELF
1578 help 1560 help
1579 Include code to run 32-bit programs under a 64-bit kernel. You should 1561 Include code to run 32-bit programs under a 64-bit kernel. You should
1580 likely turn this on, unless you're 100% sure that you don't have any 1562 likely turn this on, unless you're 100% sure that you don't have any
@@ -1587,18 +1569,16 @@ config IA32_AOUT
1587 Support old a.out binaries in the 32bit emulation. 1569 Support old a.out binaries in the 32bit emulation.
1588 1570
1589config COMPAT 1571config COMPAT
1590 bool 1572 def_bool y
1591 depends on IA32_EMULATION 1573 depends on IA32_EMULATION
1592 default y
1593 1574
1594config COMPAT_FOR_U64_ALIGNMENT 1575config COMPAT_FOR_U64_ALIGNMENT
1595 def_bool COMPAT 1576 def_bool COMPAT
1596 depends on X86_64 1577 depends on X86_64
1597 1578
1598config SYSVIPC_COMPAT 1579config SYSVIPC_COMPAT
1599 bool 1580 def_bool y
1600 depends on X86_64 && COMPAT && SYSVIPC 1581 depends on X86_64 && COMPAT && SYSVIPC
1601 default y
1602 1582
1603endmenu 1583endmenu
1604 1584
@@ -1619,4 +1599,6 @@ source "security/Kconfig"
1619 1599
1620source "crypto/Kconfig" 1600source "crypto/Kconfig"
1621 1601
1602source "arch/x86/kvm/Kconfig"
1603
1622source "lib/Kconfig" 1604source "lib/Kconfig"
diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index c30162202dc4..e09a6b73a1aa 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -219,10 +219,10 @@ config MGEODEGX1
219 Select this for a Geode GX1 (Cyrix MediaGX) chip. 219 Select this for a Geode GX1 (Cyrix MediaGX) chip.
220 220
221config MGEODE_LX 221config MGEODE_LX
222 bool "Geode GX/LX" 222 bool "Geode GX/LX"
223 depends on X86_32 223 depends on X86_32
224 help 224 help
225 Select this for AMD Geode GX and LX processors. 225 Select this for AMD Geode GX and LX processors.
226 226
227config MCYRIXIII 227config MCYRIXIII
228 bool "CyrixIII/VIA-C3" 228 bool "CyrixIII/VIA-C3"
@@ -258,7 +258,7 @@ config MPSC
258 Optimize for Intel Pentium 4, Pentium D and older Nocona/Dempsey 258 Optimize for Intel Pentium 4, Pentium D and older Nocona/Dempsey
259 Xeon CPUs with Intel 64bit which is compatible with x86-64. 259 Xeon CPUs with Intel 64bit which is compatible with x86-64.
260 Note that the latest Xeons (Xeon 51xx and 53xx) are not based on the 260 Note that the latest Xeons (Xeon 51xx and 53xx) are not based on the
261 Netburst core and shouldn't use this option. You can distinguish them 261 Netburst core and shouldn't use this option. You can distinguish them
262 using the cpu family field 262 using the cpu family field
263 in /proc/cpuinfo. Family 15 is an older Xeon, Family 6 a newer one. 263 in /proc/cpuinfo. Family 15 is an older Xeon, Family 6 a newer one.
264 264
@@ -317,81 +317,75 @@ config X86_L1_CACHE_SHIFT
317 default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MVIAC7 317 default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MVIAC7
318 318
319config X86_XADD 319config X86_XADD
320 bool 320 def_bool y
321 depends on X86_32 && !M386 321 depends on X86_32 && !M386
322 default y
323 322
324config X86_PPRO_FENCE 323config X86_PPRO_FENCE
325 bool 324 bool "PentiumPro memory ordering errata workaround"
326 depends on M686 || M586MMX || M586TSC || M586 || M486 || M386 || MGEODEGX1 325 depends on M686 || M586MMX || M586TSC || M586 || M486 || M386 || MGEODEGX1
327 default y 326 help
327 Old PentiumPro multiprocessor systems had errata that could cause memory
328 operations to violate the x86 ordering standard in rare cases. Enabling this
329 option will attempt to work around some (but not all) occurances of
330 this problem, at the cost of much heavier spinlock and memory barrier
331 operations.
332
333 If unsure, say n here. Even distro kernels should think twice before enabling
334 this: there are few systems, and an unlikely bug.
328 335
329config X86_F00F_BUG 336config X86_F00F_BUG
330 bool 337 def_bool y
331 depends on M586MMX || M586TSC || M586 || M486 || M386 338 depends on M586MMX || M586TSC || M586 || M486 || M386
332 default y
333 339
334config X86_WP_WORKS_OK 340config X86_WP_WORKS_OK
335 bool 341 def_bool y
336 depends on X86_32 && !M386 342 depends on X86_32 && !M386
337 default y
338 343
339config X86_INVLPG 344config X86_INVLPG
340 bool 345 def_bool y
341 depends on X86_32 && !M386 346 depends on X86_32 && !M386
342 default y
343 347
344config X86_BSWAP 348config X86_BSWAP
345 bool 349 def_bool y
346 depends on X86_32 && !M386 350 depends on X86_32 && !M386
347 default y
348 351
349config X86_POPAD_OK 352config X86_POPAD_OK
350 bool 353 def_bool y
351 depends on X86_32 && !M386 354 depends on X86_32 && !M386
352 default y
353 355
354config X86_ALIGNMENT_16 356config X86_ALIGNMENT_16
355 bool 357 def_bool y
356 depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1 358 depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
357 default y
358 359
359config X86_GOOD_APIC 360config X86_GOOD_APIC
360 bool 361 def_bool y
361 depends on MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8 || MEFFICEON || MCORE2 || MVIAC7 || X86_64 362 depends on MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8 || MEFFICEON || MCORE2 || MVIAC7 || X86_64
362 default y
363 363
364config X86_INTEL_USERCOPY 364config X86_INTEL_USERCOPY
365 bool 365 def_bool y
366 depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON || MCORE2 366 depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON || MCORE2
367 default y
368 367
369config X86_USE_PPRO_CHECKSUM 368config X86_USE_PPRO_CHECKSUM
370 bool 369 def_bool y
371 depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON || MGEODE_LX || MCORE2 370 depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON || MGEODE_LX || MCORE2
372 default y
373 371
374config X86_USE_3DNOW 372config X86_USE_3DNOW
375 bool 373 def_bool y
376 depends on (MCYRIXIII || MK7 || MGEODE_LX) && !UML 374 depends on (MCYRIXIII || MK7 || MGEODE_LX) && !UML
377 default y
378 375
379config X86_OOSTORE 376config X86_OOSTORE
380 bool 377 def_bool y
381 depends on (MWINCHIP3D || MWINCHIP2 || MWINCHIPC6) && MTRR 378 depends on (MWINCHIP3D || MWINCHIP2 || MWINCHIPC6) && MTRR
382 default y
383 379
384config X86_TSC 380config X86_TSC
385 bool 381 def_bool y
386 depends on ((MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2) && !X86_NUMAQ) || X86_64 382 depends on ((MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2) && !X86_NUMAQ) || X86_64
387 default y
388 383
389# this should be set for all -march=.. options where the compiler 384# this should be set for all -march=.. options where the compiler
390# generates cmov. 385# generates cmov.
391config X86_CMOV 386config X86_CMOV
392 bool 387 def_bool y
393 depends on (MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7) 388 depends on (MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7)
394 default y
395 389
396config X86_MINIMUM_CPU_FAMILY 390config X86_MINIMUM_CPU_FAMILY
397 int 391 int
@@ -399,3 +393,6 @@ config X86_MINIMUM_CPU_FAMILY
399 default "4" if X86_32 && (X86_XADD || X86_CMPXCHG || X86_BSWAP || X86_WP_WORKS_OK) 393 default "4" if X86_32 && (X86_XADD || X86_CMPXCHG || X86_BSWAP || X86_WP_WORKS_OK)
400 default "3" 394 default "3"
401 395
396config X86_DEBUGCTLMSR
397 def_bool y
398 depends on !(M586MMX || M586TSC || M586 || M486 || M386)
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
index 761ca7b5f120..2e1e3af28c3a 100644
--- a/arch/x86/Kconfig.debug
+++ b/arch/x86/Kconfig.debug
@@ -6,7 +6,7 @@ config TRACE_IRQFLAGS_SUPPORT
6source "lib/Kconfig.debug" 6source "lib/Kconfig.debug"
7 7
8config EARLY_PRINTK 8config EARLY_PRINTK
9 bool "Early printk" if EMBEDDED && DEBUG_KERNEL && X86_32 9 bool "Early printk" if EMBEDDED
10 default y 10 default y
11 help 11 help
12 Write kernel log output directly into the VGA buffer or to a serial 12 Write kernel log output directly into the VGA buffer or to a serial
@@ -40,22 +40,49 @@ comment "Page alloc debug is incompatible with Software Suspend on i386"
40 40
41config DEBUG_PAGEALLOC 41config DEBUG_PAGEALLOC
42 bool "Debug page memory allocations" 42 bool "Debug page memory allocations"
43 depends on DEBUG_KERNEL && !HIBERNATION && !HUGETLBFS 43 depends on DEBUG_KERNEL && X86_32
44 depends on X86_32
45 help 44 help
46 Unmap pages from the kernel linear mapping after free_pages(). 45 Unmap pages from the kernel linear mapping after free_pages().
47 This results in a large slowdown, but helps to find certain types 46 This results in a large slowdown, but helps to find certain types
48 of memory corruptions. 47 of memory corruptions.
49 48
49config DEBUG_PER_CPU_MAPS
50 bool "Debug access to per_cpu maps"
51 depends on DEBUG_KERNEL
52 depends on X86_64_SMP
53 default n
54 help
55 Say Y to verify that the per_cpu map being accessed has
56 been setup. Adds a fair amount of code to kernel memory
57 and decreases performance.
58
59 Say N if unsure.
60
50config DEBUG_RODATA 61config DEBUG_RODATA
51 bool "Write protect kernel read-only data structures" 62 bool "Write protect kernel read-only data structures"
63 default y
52 depends on DEBUG_KERNEL 64 depends on DEBUG_KERNEL
53 help 65 help
54 Mark the kernel read-only data as write-protected in the pagetables, 66 Mark the kernel read-only data as write-protected in the pagetables,
55 in order to catch accidental (and incorrect) writes to such const 67 in order to catch accidental (and incorrect) writes to such const
56 data. This option may have a slight performance impact because a 68 data. This is recommended so that we can catch kernel bugs sooner.
57 portion of the kernel code won't be covered by a 2MB TLB anymore. 69 If in doubt, say "Y".
58 If in doubt, say "N". 70
71config DEBUG_RODATA_TEST
72 bool "Testcase for the DEBUG_RODATA feature"
73 depends on DEBUG_RODATA
74 help
75 This option enables a testcase for the DEBUG_RODATA
76 feature as well as for the change_page_attr() infrastructure.
77 If in doubt, say "N"
78
79config DEBUG_NX_TEST
80 tristate "Testcase for the NX non-executable stack feature"
81 depends on DEBUG_KERNEL && m
82 help
83 This option enables a testcase for the CPU NX capability
84 and the software setup of this feature.
85 If in doubt, say "N"
59 86
60config 4KSTACKS 87config 4KSTACKS
61 bool "Use 4Kb for kernel stacks instead of 8Kb" 88 bool "Use 4Kb for kernel stacks instead of 8Kb"
@@ -75,8 +102,7 @@ config X86_FIND_SMP_CONFIG
75 102
76config X86_MPPARSE 103config X86_MPPARSE
77 def_bool y 104 def_bool y
78 depends on X86_LOCAL_APIC && !X86_VISWS 105 depends on (X86_32 && (X86_LOCAL_APIC && !X86_VISWS)) || X86_64
79 depends on X86_32
80 106
81config DOUBLEFAULT 107config DOUBLEFAULT
82 default y 108 default y
@@ -112,4 +138,91 @@ config IOMMU_LEAK
112 Add a simple leak tracer to the IOMMU code. This is useful when you 138 Add a simple leak tracer to the IOMMU code. This is useful when you
113 are debugging a buggy device driver that leaks IOMMU mappings. 139 are debugging a buggy device driver that leaks IOMMU mappings.
114 140
141#
142# IO delay types:
143#
144
145config IO_DELAY_TYPE_0X80
146 int
147 default "0"
148
149config IO_DELAY_TYPE_0XED
150 int
151 default "1"
152
153config IO_DELAY_TYPE_UDELAY
154 int
155 default "2"
156
157config IO_DELAY_TYPE_NONE
158 int
159 default "3"
160
161choice
162 prompt "IO delay type"
163 default IO_DELAY_0XED
164
165config IO_DELAY_0X80
166 bool "port 0x80 based port-IO delay [recommended]"
167 help
168 This is the traditional Linux IO delay used for in/out_p.
169 It is the most tested hence safest selection here.
170
171config IO_DELAY_0XED
172 bool "port 0xed based port-IO delay"
173 help
174 Use port 0xed as the IO delay. This frees up port 0x80 which is
175 often used as a hardware-debug port.
176
177config IO_DELAY_UDELAY
178 bool "udelay based port-IO delay"
179 help
180 Use udelay(2) as the IO delay method. This provides the delay
181 while not having any side-effect on the IO port space.
182
183config IO_DELAY_NONE
184 bool "no port-IO delay"
185 help
186 No port-IO delay. Will break on old boxes that require port-IO
187 delay for certain operations. Should work on most new machines.
188
189endchoice
190
191if IO_DELAY_0X80
192config DEFAULT_IO_DELAY_TYPE
193 int
194 default IO_DELAY_TYPE_0X80
195endif
196
197if IO_DELAY_0XED
198config DEFAULT_IO_DELAY_TYPE
199 int
200 default IO_DELAY_TYPE_0XED
201endif
202
203if IO_DELAY_UDELAY
204config DEFAULT_IO_DELAY_TYPE
205 int
206 default IO_DELAY_TYPE_UDELAY
207endif
208
209if IO_DELAY_NONE
210config DEFAULT_IO_DELAY_TYPE
211 int
212 default IO_DELAY_TYPE_NONE
213endif
214
215config DEBUG_BOOT_PARAMS
216 bool "Debug boot parameters"
217 depends on DEBUG_KERNEL
218 depends on DEBUG_FS
219 help
220 This option will cause struct boot_params to be exported via debugfs.
221
222config CPA_DEBUG
223 bool "CPA self test code"
224 depends on DEBUG_KERNEL
225 help
226 Do change_page_attr self tests at boot.
227
115endmenu 228endmenu
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 7aa1dc6d67c8..da8f4129780b 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -7,13 +7,254 @@ else
7 KBUILD_DEFCONFIG := $(ARCH)_defconfig 7 KBUILD_DEFCONFIG := $(ARCH)_defconfig
8endif 8endif
9 9
10# No need to remake these files 10core-$(CONFIG_KVM) += arch/x86/kvm/
11$(srctree)/arch/x86/Makefile%: ; 11
12# BITS is used as extension for files which are available in a 32 bit
13# and a 64 bit version to simplify shared Makefiles.
14# e.g.: obj-y += foo_$(BITS).o
15export BITS
12 16
13ifeq ($(CONFIG_X86_32),y) 17ifeq ($(CONFIG_X86_32),y)
18 BITS := 32
14 UTS_MACHINE := i386 19 UTS_MACHINE := i386
15 include $(srctree)/arch/x86/Makefile_32 20 CHECKFLAGS += -D__i386__
21
22 biarch := $(call cc-option,-m32)
23 KBUILD_AFLAGS += $(biarch)
24 KBUILD_CFLAGS += $(biarch)
25
26 ifdef CONFIG_RELOCATABLE
27 LDFLAGS_vmlinux := --emit-relocs
28 endif
29
30 KBUILD_CFLAGS += -msoft-float -mregparm=3 -freg-struct-return
31
32 # prevent gcc from keeping the stack 16 byte aligned
33 KBUILD_CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2)
34
35 # Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use
36 # a lot more stack due to the lack of sharing of stacklots:
37 KBUILD_CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then \
38 echo $(call cc-option,-fno-unit-at-a-time); fi ;)
39
40 # CPU-specific tuning. Anything which can be shared with UML should go here.
41 include $(srctree)/arch/x86/Makefile_32.cpu
42 KBUILD_CFLAGS += $(cflags-y)
43
44 # temporary until string.h is fixed
45 KBUILD_CFLAGS += -ffreestanding
16else 46else
47 BITS := 64
17 UTS_MACHINE := x86_64 48 UTS_MACHINE := x86_64
18 include $(srctree)/arch/x86/Makefile_64 49 CHECKFLAGS += -D__x86_64__ -m64
50
51 KBUILD_AFLAGS += -m64
52 KBUILD_CFLAGS += -m64
53
54 # FIXME - should be integrated in Makefile.cpu (Makefile_32.cpu)
55 cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8)
56 cflags-$(CONFIG_MPSC) += $(call cc-option,-march=nocona)
57
58 cflags-$(CONFIG_MCORE2) += \
59 $(call cc-option,-march=core2,$(call cc-option,-mtune=generic))
60 cflags-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=generic)
61 KBUILD_CFLAGS += $(cflags-y)
62
63 KBUILD_CFLAGS += -mno-red-zone
64 KBUILD_CFLAGS += -mcmodel=kernel
65
66 # -funit-at-a-time shrinks the kernel .text considerably
67 # unfortunately it makes reading oopses harder.
68 KBUILD_CFLAGS += $(call cc-option,-funit-at-a-time)
69
70 # this works around some issues with generating unwind tables in older gccs
71 # newer gccs do it by default
72 KBUILD_CFLAGS += -maccumulate-outgoing-args
73
74 stackp := $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh
75 stackp-$(CONFIG_CC_STACKPROTECTOR) := $(shell $(stackp) \
76 "$(CC)" -fstack-protector )
77 stackp-$(CONFIG_CC_STACKPROTECTOR_ALL) += $(shell $(stackp) \
78 "$(CC)" -fstack-protector-all )
79
80 KBUILD_CFLAGS += $(stackp-y)
19endif 81endif
82
83# Stackpointer is addressed different for 32 bit and 64 bit x86
84sp-$(CONFIG_X86_32) := esp
85sp-$(CONFIG_X86_64) := rsp
86
87# do binutils support CFI?
88cfi := $(call as-instr,.cfi_startproc\n.cfi_rel_offset $(sp-y)$(comma)0\n.cfi_endproc,-DCONFIG_AS_CFI=1)
89# is .cfi_signal_frame supported too?
90cfi-sigframe := $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1)
91KBUILD_AFLAGS += $(cfi) $(cfi-sigframe)
92KBUILD_CFLAGS += $(cfi) $(cfi-sigframe)
93
94LDFLAGS := -m elf_$(UTS_MACHINE)
95OBJCOPYFLAGS := -O binary -R .note -R .comment -S
96
97# Speed up the build
98KBUILD_CFLAGS += -pipe
99# Workaround for a gcc prelease that unfortunately was shipped in a suse release
100KBUILD_CFLAGS += -Wno-sign-compare
101#
102KBUILD_CFLAGS += -fno-asynchronous-unwind-tables
103# prevent gcc from generating any FP code by mistake
104KBUILD_CFLAGS += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,)
105
106###
107# Sub architecture support
108# fcore-y is linked before mcore-y files.
109
110# Default subarch .c files
111mcore-y := arch/x86/mach-default/
112
113# Voyager subarch support
114mflags-$(CONFIG_X86_VOYAGER) := -Iinclude/asm-x86/mach-voyager
115mcore-$(CONFIG_X86_VOYAGER) := arch/x86/mach-voyager/
116
117# VISWS subarch support
118mflags-$(CONFIG_X86_VISWS) := -Iinclude/asm-x86/mach-visws
119mcore-$(CONFIG_X86_VISWS) := arch/x86/mach-visws/
120
121# NUMAQ subarch support
122mflags-$(CONFIG_X86_NUMAQ) := -Iinclude/asm-x86/mach-numaq
123mcore-$(CONFIG_X86_NUMAQ) := arch/x86/mach-default/
124
125# BIGSMP subarch support
126mflags-$(CONFIG_X86_BIGSMP) := -Iinclude/asm-x86/mach-bigsmp
127mcore-$(CONFIG_X86_BIGSMP) := arch/x86/mach-default/
128
129#Summit subarch support
130mflags-$(CONFIG_X86_SUMMIT) := -Iinclude/asm-x86/mach-summit
131mcore-$(CONFIG_X86_SUMMIT) := arch/x86/mach-default/
132
133# generic subarchitecture
134mflags-$(CONFIG_X86_GENERICARCH):= -Iinclude/asm-x86/mach-generic
135fcore-$(CONFIG_X86_GENERICARCH) += arch/x86/mach-generic/
136mcore-$(CONFIG_X86_GENERICARCH) := arch/x86/mach-default/
137
138
139# ES7000 subarch support
140mflags-$(CONFIG_X86_ES7000) := -Iinclude/asm-x86/mach-es7000
141fcore-$(CONFIG_X86_ES7000) := arch/x86/mach-es7000/
142mcore-$(CONFIG_X86_ES7000) := arch/x86/mach-default/
143
144# RDC R-321x subarch support
145mflags-$(CONFIG_X86_RDC321X) := -Iinclude/asm-x86/mach-rdc321x
146mcore-$(CONFIG_X86_RDC321X) := arch/x86/mach-default
147core-$(CONFIG_X86_RDC321X) += arch/x86/mach-rdc321x/
148
149# default subarch .h files
150mflags-y += -Iinclude/asm-x86/mach-default
151
152# 64 bit does not support subarch support - clear sub arch variables
153fcore-$(CONFIG_X86_64) :=
154mcore-$(CONFIG_X86_64) :=
155mflags-$(CONFIG_X86_64) :=
156
157KBUILD_CFLAGS += $(mflags-y)
158KBUILD_AFLAGS += $(mflags-y)
159
160###
161# Kernel objects
162
163head-y := arch/x86/kernel/head_$(BITS).o
164head-$(CONFIG_X86_64) += arch/x86/kernel/head64.o
165head-y += arch/x86/kernel/init_task.o
166
167libs-y += arch/x86/lib/
168
169# Sub architecture files that needs linking first
170core-y += $(fcore-y)
171
172# Xen paravirtualization support
173core-$(CONFIG_XEN) += arch/x86/xen/
174
175# lguest paravirtualization support
176core-$(CONFIG_LGUEST_GUEST) += arch/x86/lguest/
177
178core-y += arch/x86/kernel/
179core-y += arch/x86/mm/
180
181# Remaining sub architecture files
182core-y += $(mcore-y)
183
184core-y += arch/x86/crypto/
185core-y += arch/x86/vdso/
186core-$(CONFIG_IA32_EMULATION) += arch/x86/ia32/
187
188# drivers-y are linked after core-y
189drivers-$(CONFIG_MATH_EMULATION) += arch/x86/math-emu/
190drivers-$(CONFIG_PCI) += arch/x86/pci/
191
192# must be linked after kernel/
193drivers-$(CONFIG_OPROFILE) += arch/x86/oprofile/
194
195ifeq ($(CONFIG_X86_32),y)
196drivers-$(CONFIG_PM) += arch/x86/power/
197drivers-$(CONFIG_FB) += arch/x86/video/
198endif
199
200####
201# boot loader support. Several targets are kept for legacy purposes
202
203boot := arch/x86/boot
204
205PHONY += zImage bzImage compressed zlilo bzlilo \
206 zdisk bzdisk fdimage fdimage144 fdimage288 isoimage install
207
208# Default kernel to build
209all: bzImage
210
211# KBUILD_IMAGE specify target image being built
212 KBUILD_IMAGE := $(boot)/bzImage
213zImage zlilo zdisk: KBUILD_IMAGE := arch/x86/boot/zImage
214
215zImage bzImage: vmlinux
216 $(Q)$(MAKE) $(build)=$(boot) $(KBUILD_IMAGE)
217 $(Q)mkdir -p $(objtree)/arch/$(UTS_MACHINE)/boot
218 $(Q)ln -fsn ../../x86/boot/bzImage $(objtree)/arch/$(UTS_MACHINE)/boot/bzImage
219
220compressed: zImage
221
222zlilo bzlilo: vmlinux
223 $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) zlilo
224
225zdisk bzdisk: vmlinux
226 $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) zdisk
227
228fdimage fdimage144 fdimage288 isoimage: vmlinux
229 $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@
230
231install: vdso_install
232 $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install
233
234PHONY += vdso_install
235vdso_install:
236 $(Q)$(MAKE) $(build)=arch/x86/vdso $@
237
238archclean:
239 $(Q)rm -rf $(objtree)/arch/i386
240 $(Q)rm -rf $(objtree)/arch/x86_64
241 $(Q)$(MAKE) $(clean)=$(boot)
242
243define archhelp
244 echo '* bzImage - Compressed kernel image (arch/x86/boot/bzImage)'
245 echo ' install - Install kernel using'
246 echo ' (your) ~/bin/installkernel or'
247 echo ' (distribution) /sbin/installkernel or'
248 echo ' install to $$(INSTALL_PATH) and run lilo'
249 echo ' fdimage - Create 1.4MB boot floppy image (arch/x86/boot/fdimage)'
250 echo ' fdimage144 - Create 1.4MB boot floppy image (arch/x86/boot/fdimage)'
251 echo ' fdimage288 - Create 2.8MB boot floppy image (arch/x86/boot/fdimage)'
252 echo ' isoimage - Create a boot CD-ROM image (arch/x86/boot/image.iso)'
253 echo ' bzdisk/fdimage*/isoimage also accept:'
254 echo ' FDARGS="..." arguments for the booted kernel'
255 echo ' FDINITRD=file initrd for the booted kernel'
256endef
257
258CLEAN_FILES += arch/x86/boot/fdimage \
259 arch/x86/boot/image.iso \
260 arch/x86/boot/mtools.conf
diff --git a/arch/x86/Makefile_32 b/arch/x86/Makefile_32
deleted file mode 100644
index 50394da2f6c1..000000000000
--- a/arch/x86/Makefile_32
+++ /dev/null
@@ -1,175 +0,0 @@
1#
2# i386 Makefile
3#
4# This file is included by the global makefile so that you can add your own
5# architecture-specific flags and dependencies. Remember to do have actions
6# for "archclean" cleaning up for this architecture.
7#
8# This file is subject to the terms and conditions of the GNU General Public
9# License. See the file "COPYING" in the main directory of this archive
10# for more details.
11#
12# Copyright (C) 1994 by Linus Torvalds
13#
14# 19990713 Artur Skawina <skawina@geocities.com>
15# Added '-march' and '-mpreferred-stack-boundary' support
16#
17# 20050320 Kianusch Sayah Karadji <kianusch@sk-tech.net>
18# Added support for GEODE CPU
19
20# BITS is used as extension for files which are available in a 32 bit
21# and a 64 bit version to simplify shared Makefiles.
22# e.g.: obj-y += foo_$(BITS).o
23BITS := 32
24export BITS
25
26HAS_BIARCH := $(call cc-option-yn, -m32)
27ifeq ($(HAS_BIARCH),y)
28AS := $(AS) --32
29LD := $(LD) -m elf_i386
30CC := $(CC) -m32
31endif
32
33LDFLAGS := -m elf_i386
34OBJCOPYFLAGS := -O binary -R .note -R .comment -S
35ifdef CONFIG_RELOCATABLE
36LDFLAGS_vmlinux := --emit-relocs
37endif
38CHECKFLAGS += -D__i386__
39
40KBUILD_CFLAGS += -pipe -msoft-float -mregparm=3 -freg-struct-return
41
42# prevent gcc from keeping the stack 16 byte aligned
43KBUILD_CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2)
44
45# CPU-specific tuning. Anything which can be shared with UML should go here.
46include $(srctree)/arch/x86/Makefile_32.cpu
47
48# temporary until string.h is fixed
49cflags-y += -ffreestanding
50
51# this works around some issues with generating unwind tables in older gccs
52# newer gccs do it by default
53cflags-y += -maccumulate-outgoing-args
54
55# Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use
56# a lot more stack due to the lack of sharing of stacklots:
57KBUILD_CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then echo $(call cc-option,-fno-unit-at-a-time); fi ;)
58
59# do binutils support CFI?
60cflags-y += $(call as-instr,.cfi_startproc\n.cfi_rel_offset esp${comma}0\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
61KBUILD_AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_rel_offset esp${comma}0\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
62
63# is .cfi_signal_frame supported too?
64cflags-y += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
65KBUILD_AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
66
67KBUILD_CFLAGS += $(cflags-y)
68
69# Default subarch .c files
70mcore-y := arch/x86/mach-default
71
72# Voyager subarch support
73mflags-$(CONFIG_X86_VOYAGER) := -Iinclude/asm-x86/mach-voyager
74mcore-$(CONFIG_X86_VOYAGER) := arch/x86/mach-voyager
75
76# VISWS subarch support
77mflags-$(CONFIG_X86_VISWS) := -Iinclude/asm-x86/mach-visws
78mcore-$(CONFIG_X86_VISWS) := arch/x86/mach-visws
79
80# NUMAQ subarch support
81mflags-$(CONFIG_X86_NUMAQ) := -Iinclude/asm-x86/mach-numaq
82mcore-$(CONFIG_X86_NUMAQ) := arch/x86/mach-default
83
84# BIGSMP subarch support
85mflags-$(CONFIG_X86_BIGSMP) := -Iinclude/asm-x86/mach-bigsmp
86mcore-$(CONFIG_X86_BIGSMP) := arch/x86/mach-default
87
88#Summit subarch support
89mflags-$(CONFIG_X86_SUMMIT) := -Iinclude/asm-x86/mach-summit
90mcore-$(CONFIG_X86_SUMMIT) := arch/x86/mach-default
91
92# generic subarchitecture
93mflags-$(CONFIG_X86_GENERICARCH) := -Iinclude/asm-x86/mach-generic
94mcore-$(CONFIG_X86_GENERICARCH) := arch/x86/mach-default
95core-$(CONFIG_X86_GENERICARCH) += arch/x86/mach-generic/
96
97# ES7000 subarch support
98mflags-$(CONFIG_X86_ES7000) := -Iinclude/asm-x86/mach-es7000
99mcore-$(CONFIG_X86_ES7000) := arch/x86/mach-default
100core-$(CONFIG_X86_ES7000) := arch/x86/mach-es7000/
101
102# Xen paravirtualization support
103core-$(CONFIG_XEN) += arch/x86/xen/
104
105# lguest paravirtualization support
106core-$(CONFIG_LGUEST_GUEST) += arch/x86/lguest/
107
108# default subarch .h files
109mflags-y += -Iinclude/asm-x86/mach-default
110
111head-y := arch/x86/kernel/head_32.o arch/x86/kernel/init_task.o
112
113libs-y += arch/x86/lib/
114core-y += arch/x86/kernel/ \
115 arch/x86/mm/ \
116 $(mcore-y)/ \
117 arch/x86/crypto/
118drivers-$(CONFIG_MATH_EMULATION) += arch/x86/math-emu/
119drivers-$(CONFIG_PCI) += arch/x86/pci/
120# must be linked after kernel/
121drivers-$(CONFIG_OPROFILE) += arch/x86/oprofile/
122drivers-$(CONFIG_PM) += arch/x86/power/
123drivers-$(CONFIG_FB) += arch/x86/video/
124
125KBUILD_CFLAGS += $(mflags-y)
126KBUILD_AFLAGS += $(mflags-y)
127
128boot := arch/x86/boot
129
130PHONY += zImage bzImage compressed zlilo bzlilo \
131 zdisk bzdisk fdimage fdimage144 fdimage288 isoimage install
132
133all: bzImage
134
135# KBUILD_IMAGE specify target image being built
136 KBUILD_IMAGE := $(boot)/bzImage
137zImage zlilo zdisk: KBUILD_IMAGE := arch/x86/boot/zImage
138
139zImage bzImage: vmlinux
140 $(Q)$(MAKE) $(build)=$(boot) $(KBUILD_IMAGE)
141 $(Q)mkdir -p $(objtree)/arch/i386/boot
142 $(Q)ln -fsn ../../x86/boot/bzImage $(objtree)/arch/i386/boot/bzImage
143
144compressed: zImage
145
146zlilo bzlilo: vmlinux
147 $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) zlilo
148
149zdisk bzdisk: vmlinux
150 $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) zdisk
151
152fdimage fdimage144 fdimage288 isoimage: vmlinux
153 $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@
154
155install:
156 $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install
157
158archclean:
159 $(Q)rm -rf $(objtree)/arch/i386/boot
160 $(Q)$(MAKE) $(clean)=arch/x86/boot
161
162define archhelp
163 echo '* bzImage - Compressed kernel image (arch/x86/boot/bzImage)'
164 echo ' install - Install kernel using'
165 echo ' (your) ~/bin/installkernel or'
166 echo ' (distribution) /sbin/installkernel or'
167 echo ' install to $$(INSTALL_PATH) and run lilo'
168 echo ' bzdisk - Create a boot floppy in /dev/fd0'
169 echo ' fdimage - Create a boot floppy image'
170 echo ' isoimage - Create a boot CD-ROM image'
171endef
172
173CLEAN_FILES += arch/x86/boot/fdimage \
174 arch/x86/boot/image.iso \
175 arch/x86/boot/mtools.conf
diff --git a/arch/x86/Makefile_64 b/arch/x86/Makefile_64
deleted file mode 100644
index a804860022e6..000000000000
--- a/arch/x86/Makefile_64
+++ /dev/null
@@ -1,144 +0,0 @@
1#
2# x86_64 Makefile
3#
4# This file is included by the global makefile so that you can add your own
5# architecture-specific flags and dependencies. Remember to do have actions
6# for "archclean" and "archdep" for cleaning up and making dependencies for
7# this architecture
8#
9# This file is subject to the terms and conditions of the GNU General Public
10# License. See the file "COPYING" in the main directory of this archive
11# for more details.
12#
13# Copyright (C) 1994 by Linus Torvalds
14#
15# 19990713 Artur Skawina <skawina@geocities.com>
16# Added '-march' and '-mpreferred-stack-boundary' support
17# 20000913 Pavel Machek <pavel@suse.cz>
18# Converted for x86_64 architecture
19# 20010105 Andi Kleen, add IA32 compiler.
20# ....and later removed it again....
21#
22# $Id: Makefile,v 1.31 2002/03/22 15:56:07 ak Exp $
23
24# BITS is used as extension for files which are available in a 32 bit
25# and a 64 bit version to simplify shared Makefiles.
26# e.g.: obj-y += foo_$(BITS).o
27BITS := 64
28export BITS
29
30LDFLAGS := -m elf_x86_64
31OBJCOPYFLAGS := -O binary -R .note -R .comment -S
32LDFLAGS_vmlinux :=
33CHECKFLAGS += -D__x86_64__ -m64
34
35cflags-y :=
36cflags-kernel-y :=
37cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8)
38cflags-$(CONFIG_MPSC) += $(call cc-option,-march=nocona)
39# gcc doesn't support -march=core2 yet as of gcc 4.3, but I hope it
40# will eventually. Use -mtune=generic as fallback
41cflags-$(CONFIG_MCORE2) += \
42 $(call cc-option,-march=core2,$(call cc-option,-mtune=generic))
43cflags-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=generic)
44
45cflags-y += -m64
46cflags-y += -mno-red-zone
47cflags-y += -mcmodel=kernel
48cflags-y += -pipe
49cflags-y += -Wno-sign-compare
50cflags-y += -fno-asynchronous-unwind-tables
51ifneq ($(CONFIG_DEBUG_INFO),y)
52# -fweb shrinks the kernel a bit, but the difference is very small
53# it also messes up debugging, so don't use it for now.
54#cflags-y += $(call cc-option,-fweb)
55endif
56# -funit-at-a-time shrinks the kernel .text considerably
57# unfortunately it makes reading oopses harder.
58cflags-y += $(call cc-option,-funit-at-a-time)
59# prevent gcc from generating any FP code by mistake
60cflags-y += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,)
61# this works around some issues with generating unwind tables in older gccs
62# newer gccs do it by default
63cflags-y += -maccumulate-outgoing-args
64
65# do binutils support CFI?
66cflags-y += $(call as-instr,.cfi_startproc\n.cfi_rel_offset rsp${comma}0\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
67KBUILD_AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_rel_offset rsp${comma}0\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
68
69# is .cfi_signal_frame supported too?
70cflags-y += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
71KBUILD_AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
72
73cflags-$(CONFIG_CC_STACKPROTECTOR) += $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh "$(CC)" -fstack-protector )
74cflags-$(CONFIG_CC_STACKPROTECTOR_ALL) += $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh "$(CC)" -fstack-protector-all )
75
76KBUILD_CFLAGS += $(cflags-y)
77CFLAGS_KERNEL += $(cflags-kernel-y)
78KBUILD_AFLAGS += -m64
79
80head-y := arch/x86/kernel/head_64.o arch/x86/kernel/head64.o arch/x86/kernel/init_task.o
81
82libs-y += arch/x86/lib/
83core-y += arch/x86/kernel/ \
84 arch/x86/mm/ \
85 arch/x86/crypto/ \
86 arch/x86/vdso/
87core-$(CONFIG_IA32_EMULATION) += arch/x86/ia32/
88drivers-$(CONFIG_PCI) += arch/x86/pci/
89drivers-$(CONFIG_OPROFILE) += arch/x86/oprofile/
90
91boot := arch/x86/boot
92
93PHONY += bzImage bzlilo install archmrproper \
94 fdimage fdimage144 fdimage288 isoimage archclean
95
96#Default target when executing "make"
97all: bzImage
98
99BOOTIMAGE := arch/x86/boot/bzImage
100KBUILD_IMAGE := $(BOOTIMAGE)
101
102bzImage: vmlinux
103 $(Q)$(MAKE) $(build)=$(boot) $(BOOTIMAGE)
104 $(Q)mkdir -p $(objtree)/arch/x86_64/boot
105 $(Q)ln -fsn ../../x86/boot/bzImage $(objtree)/arch/x86_64/boot/bzImage
106
107bzlilo: vmlinux
108 $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) zlilo
109
110bzdisk: vmlinux
111 $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) zdisk
112
113fdimage fdimage144 fdimage288 isoimage: vmlinux
114 $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) $@
115
116install: vdso_install
117 $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) $@
118
119vdso_install:
120ifeq ($(CONFIG_IA32_EMULATION),y)
121 $(Q)$(MAKE) $(build)=arch/x86/ia32 $@
122endif
123 $(Q)$(MAKE) $(build)=arch/x86/vdso $@
124
125archclean:
126 $(Q)rm -rf $(objtree)/arch/x86_64/boot
127 $(Q)$(MAKE) $(clean)=$(boot)
128
129define archhelp
130 echo '* bzImage - Compressed kernel image (arch/x86/boot/bzImage)'
131 echo ' install - Install kernel using'
132 echo ' (your) ~/bin/installkernel or'
133 echo ' (distribution) /sbin/installkernel or'
134 echo ' install to $$(INSTALL_PATH) and run lilo'
135 echo ' bzdisk - Create a boot floppy in /dev/fd0'
136 echo ' fdimage - Create a boot floppy image'
137 echo ' isoimage - Create a boot CD-ROM image'
138endef
139
140CLEAN_FILES += arch/x86/boot/fdimage \
141 arch/x86/boot/image.iso \
142 arch/x86/boot/mtools.conf
143
144
diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile
index 7a3116ccf387..349b81a39c40 100644
--- a/arch/x86/boot/Makefile
+++ b/arch/x86/boot/Makefile
@@ -28,9 +28,11 @@ SVGA_MODE := -DSVGA_MODE=NORMAL_VGA
28targets := vmlinux.bin setup.bin setup.elf zImage bzImage 28targets := vmlinux.bin setup.bin setup.elf zImage bzImage
29subdir- := compressed 29subdir- := compressed
30 30
31setup-y += a20.o apm.o cmdline.o copy.o cpu.o cpucheck.o edd.o 31setup-y += a20.o cmdline.o copy.o cpu.o cpucheck.o edd.o
32setup-y += header.o main.o mca.o memory.o pm.o pmjump.o 32setup-y += header.o main.o mca.o memory.o pm.o pmjump.o
33setup-y += printf.o string.o tty.o video.o version.o voyager.o 33setup-y += printf.o string.o tty.o video.o version.o
34setup-$(CONFIG_X86_APM_BOOT) += apm.o
35setup-$(CONFIG_X86_VOYAGER) += voyager.o
34 36
35# The link order of the video-*.o modules can matter. In particular, 37# The link order of the video-*.o modules can matter. In particular,
36# video-vga.o *must* be listed first, followed by video-vesa.o. 38# video-vga.o *must* be listed first, followed by video-vesa.o.
@@ -49,10 +51,7 @@ HOSTCFLAGS_build.o := $(LINUXINCLUDE)
49 51
50# How to compile the 16-bit code. Note we always compile for -march=i386, 52# How to compile the 16-bit code. Note we always compile for -march=i386,
51# that way we can complain to the user if the CPU is insufficient. 53# that way we can complain to the user if the CPU is insufficient.
52cflags-$(CONFIG_X86_32) :=
53cflags-$(CONFIG_X86_64) := -m32
54KBUILD_CFLAGS := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \ 54KBUILD_CFLAGS := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
55 $(cflags-y) \
56 -Wall -Wstrict-prototypes \ 55 -Wall -Wstrict-prototypes \
57 -march=i386 -mregparm=3 \ 56 -march=i386 -mregparm=3 \
58 -include $(srctree)/$(src)/code16gcc.h \ 57 -include $(srctree)/$(src)/code16gcc.h \
@@ -62,6 +61,7 @@ KBUILD_CFLAGS := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
62 $(call cc-option, -fno-unit-at-a-time)) \ 61 $(call cc-option, -fno-unit-at-a-time)) \
63 $(call cc-option, -fno-stack-protector) \ 62 $(call cc-option, -fno-stack-protector) \
64 $(call cc-option, -mpreferred-stack-boundary=2) 63 $(call cc-option, -mpreferred-stack-boundary=2)
64KBUILD_CFLAGS += $(call cc-option,-m32)
65KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__ 65KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__
66 66
67$(obj)/zImage: IMAGE_OFFSET := 0x1000 67$(obj)/zImage: IMAGE_OFFSET := 0x1000
diff --git a/arch/x86/boot/apm.c b/arch/x86/boot/apm.c
index eab50c55a3a5..c117c7fb859c 100644
--- a/arch/x86/boot/apm.c
+++ b/arch/x86/boot/apm.c
@@ -19,8 +19,6 @@
19 19
20#include "boot.h" 20#include "boot.h"
21 21
22#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
23
24int query_apm_bios(void) 22int query_apm_bios(void)
25{ 23{
26 u16 ax, bx, cx, dx, di; 24 u16 ax, bx, cx, dx, di;
@@ -95,4 +93,3 @@ int query_apm_bios(void)
95 return 0; 93 return 0;
96} 94}
97 95
98#endif
diff --git a/arch/x86/boot/boot.h b/arch/x86/boot/boot.h
index d2b5adf46512..7822a4983da2 100644
--- a/arch/x86/boot/boot.h
+++ b/arch/x86/boot/boot.h
@@ -109,7 +109,7 @@ typedef unsigned int addr_t;
109static inline u8 rdfs8(addr_t addr) 109static inline u8 rdfs8(addr_t addr)
110{ 110{
111 u8 v; 111 u8 v;
112 asm volatile("movb %%fs:%1,%0" : "=r" (v) : "m" (*(u8 *)addr)); 112 asm volatile("movb %%fs:%1,%0" : "=q" (v) : "m" (*(u8 *)addr));
113 return v; 113 return v;
114} 114}
115static inline u16 rdfs16(addr_t addr) 115static inline u16 rdfs16(addr_t addr)
@@ -127,21 +127,21 @@ static inline u32 rdfs32(addr_t addr)
127 127
128static inline void wrfs8(u8 v, addr_t addr) 128static inline void wrfs8(u8 v, addr_t addr)
129{ 129{
130 asm volatile("movb %1,%%fs:%0" : "+m" (*(u8 *)addr) : "r" (v)); 130 asm volatile("movb %1,%%fs:%0" : "+m" (*(u8 *)addr) : "qi" (v));
131} 131}
132static inline void wrfs16(u16 v, addr_t addr) 132static inline void wrfs16(u16 v, addr_t addr)
133{ 133{
134 asm volatile("movw %1,%%fs:%0" : "+m" (*(u16 *)addr) : "r" (v)); 134 asm volatile("movw %1,%%fs:%0" : "+m" (*(u16 *)addr) : "ri" (v));
135} 135}
136static inline void wrfs32(u32 v, addr_t addr) 136static inline void wrfs32(u32 v, addr_t addr)
137{ 137{
138 asm volatile("movl %1,%%fs:%0" : "+m" (*(u32 *)addr) : "r" (v)); 138 asm volatile("movl %1,%%fs:%0" : "+m" (*(u32 *)addr) : "ri" (v));
139} 139}
140 140
141static inline u8 rdgs8(addr_t addr) 141static inline u8 rdgs8(addr_t addr)
142{ 142{
143 u8 v; 143 u8 v;
144 asm volatile("movb %%gs:%1,%0" : "=r" (v) : "m" (*(u8 *)addr)); 144 asm volatile("movb %%gs:%1,%0" : "=q" (v) : "m" (*(u8 *)addr));
145 return v; 145 return v;
146} 146}
147static inline u16 rdgs16(addr_t addr) 147static inline u16 rdgs16(addr_t addr)
@@ -159,15 +159,15 @@ static inline u32 rdgs32(addr_t addr)
159 159
160static inline void wrgs8(u8 v, addr_t addr) 160static inline void wrgs8(u8 v, addr_t addr)
161{ 161{
162 asm volatile("movb %1,%%gs:%0" : "+m" (*(u8 *)addr) : "r" (v)); 162 asm volatile("movb %1,%%gs:%0" : "+m" (*(u8 *)addr) : "qi" (v));
163} 163}
164static inline void wrgs16(u16 v, addr_t addr) 164static inline void wrgs16(u16 v, addr_t addr)
165{ 165{
166 asm volatile("movw %1,%%gs:%0" : "+m" (*(u16 *)addr) : "r" (v)); 166 asm volatile("movw %1,%%gs:%0" : "+m" (*(u16 *)addr) : "ri" (v));
167} 167}
168static inline void wrgs32(u32 v, addr_t addr) 168static inline void wrgs32(u32 v, addr_t addr)
169{ 169{
170 asm volatile("movl %1,%%gs:%0" : "+m" (*(u32 *)addr) : "r" (v)); 170 asm volatile("movl %1,%%gs:%0" : "+m" (*(u32 *)addr) : "ri" (v));
171} 171}
172 172
173/* Note: these only return true/false, not a signed return value! */ 173/* Note: these only return true/false, not a signed return value! */
@@ -241,6 +241,7 @@ int query_apm_bios(void);
241 241
242/* cmdline.c */ 242/* cmdline.c */
243int cmdline_find_option(const char *option, char *buffer, int bufsize); 243int cmdline_find_option(const char *option, char *buffer, int bufsize);
244int cmdline_find_option_bool(const char *option);
244 245
245/* cpu.c, cpucheck.c */ 246/* cpu.c, cpucheck.c */
246int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr); 247int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr);
diff --git a/arch/x86/boot/cmdline.c b/arch/x86/boot/cmdline.c
index 34bb778c4357..680408a0f463 100644
--- a/arch/x86/boot/cmdline.c
+++ b/arch/x86/boot/cmdline.c
@@ -95,3 +95,68 @@ int cmdline_find_option(const char *option, char *buffer, int bufsize)
95 95
96 return len; 96 return len;
97} 97}
98
99/*
100 * Find a boolean option (like quiet,noapic,nosmp....)
101 *
102 * Returns the position of that option (starts counting with 1)
103 * or 0 on not found
104 */
105int cmdline_find_option_bool(const char *option)
106{
107 u32 cmdline_ptr = boot_params.hdr.cmd_line_ptr;
108 addr_t cptr;
109 char c;
110 int pos = 0, wstart = 0;
111 const char *opptr = NULL;
112 enum {
113 st_wordstart, /* Start of word/after whitespace */
114 st_wordcmp, /* Comparing this word */
115 st_wordskip, /* Miscompare, skip */
116 } state = st_wordstart;
117
118 if (!cmdline_ptr || cmdline_ptr >= 0x100000)
119 return -1; /* No command line, or inaccessible */
120
121 cptr = cmdline_ptr & 0xf;
122 set_fs(cmdline_ptr >> 4);
123
124 while (cptr < 0x10000) {
125 c = rdfs8(cptr++);
126 pos++;
127
128 switch (state) {
129 case st_wordstart:
130 if (!c)
131 return 0;
132 else if (myisspace(c))
133 break;
134
135 state = st_wordcmp;
136 opptr = option;
137 wstart = pos;
138 /* fall through */
139
140 case st_wordcmp:
141 if (!*opptr)
142 if (!c || myisspace(c))
143 return wstart;
144 else
145 state = st_wordskip;
146 else if (!c)
147 return 0;
148 else if (c != *opptr++)
149 state = st_wordskip;
150 break;
151
152 case st_wordskip:
153 if (!c)
154 return 0;
155 else if (myisspace(c))
156 state = st_wordstart;
157 break;
158 }
159 }
160
161 return 0; /* Buffer overrun */
162}
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
index 52c1db854520..fe24ceabd909 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -1,5 +1,63 @@
1#
2# linux/arch/x86/boot/compressed/Makefile
3#
4# create a compressed vmlinux image from the original vmlinux
5#
6
7targets := vmlinux vmlinux.bin vmlinux.bin.gz head_$(BITS).o misc.o piggy.o
8
9KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2
10KBUILD_CFLAGS += -fno-strict-aliasing -fPIC
11cflags-$(CONFIG_X86_64) := -mcmodel=small
12KBUILD_CFLAGS += $(cflags-y)
13KBUILD_CFLAGS += $(call cc-option,-ffreestanding)
14KBUILD_CFLAGS += $(call cc-option,-fno-stack-protector)
15
16KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__
17
18LDFLAGS := -m elf_$(UTS_MACHINE)
19LDFLAGS_vmlinux := -T
20
21$(obj)/vmlinux: $(src)/vmlinux_$(BITS).lds $(obj)/head_$(BITS).o $(obj)/misc.o $(obj)/piggy.o FORCE
22 $(call if_changed,ld)
23 @:
24
25$(obj)/vmlinux.bin: vmlinux FORCE
26 $(call if_changed,objcopy)
27
28
1ifeq ($(CONFIG_X86_32),y) 29ifeq ($(CONFIG_X86_32),y)
2include ${srctree}/arch/x86/boot/compressed/Makefile_32 30targets += vmlinux.bin.all vmlinux.relocs
31hostprogs-y := relocs
32
33quiet_cmd_relocs = RELOCS $@
34 cmd_relocs = $(obj)/relocs $< > $@;$(obj)/relocs --abs-relocs $<
35$(obj)/vmlinux.relocs: vmlinux $(obj)/relocs FORCE
36 $(call if_changed,relocs)
37
38vmlinux.bin.all-y := $(obj)/vmlinux.bin
39vmlinux.bin.all-$(CONFIG_RELOCATABLE) += $(obj)/vmlinux.relocs
40quiet_cmd_relocbin = BUILD $@
41 cmd_relocbin = cat $(filter-out FORCE,$^) > $@
42$(obj)/vmlinux.bin.all: $(vmlinux.bin.all-y) FORCE
43 $(call if_changed,relocbin)
44
45ifdef CONFIG_RELOCATABLE
46$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin.all FORCE
47 $(call if_changed,gzip)
3else 48else
4include ${srctree}/arch/x86/boot/compressed/Makefile_64 49$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
50 $(call if_changed,gzip)
5endif 51endif
52LDFLAGS_piggy.o := -r --format binary --oformat elf32-i386 -T
53
54else
55$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
56 $(call if_changed,gzip)
57
58LDFLAGS_piggy.o := -r --format binary --oformat elf64-x86-64 -T
59endif
60
61
62$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE
63 $(call if_changed,ld)
diff --git a/arch/x86/boot/compressed/Makefile_32 b/arch/x86/boot/compressed/Makefile_32
deleted file mode 100644
index e43ff7c56e6e..000000000000
--- a/arch/x86/boot/compressed/Makefile_32
+++ /dev/null
@@ -1,50 +0,0 @@
1#
2# linux/arch/x86/boot/compressed/Makefile
3#
4# create a compressed vmlinux image from the original vmlinux
5#
6
7targets := vmlinux vmlinux.bin vmlinux.bin.gz head_32.o misc_32.o piggy.o \
8 vmlinux.bin.all vmlinux.relocs
9EXTRA_AFLAGS := -traditional
10
11LDFLAGS_vmlinux := -T
12hostprogs-y := relocs
13
14KBUILD_CFLAGS := -m32 -D__KERNEL__ $(LINUX_INCLUDE) -O2 \
15 -fno-strict-aliasing -fPIC \
16 $(call cc-option,-ffreestanding) \
17 $(call cc-option,-fno-stack-protector)
18LDFLAGS := -m elf_i386
19
20$(obj)/vmlinux: $(src)/vmlinux_32.lds $(obj)/head_32.o $(obj)/misc_32.o $(obj)/piggy.o FORCE
21 $(call if_changed,ld)
22 @:
23
24$(obj)/vmlinux.bin: vmlinux FORCE
25 $(call if_changed,objcopy)
26
27quiet_cmd_relocs = RELOCS $@
28 cmd_relocs = $(obj)/relocs $< > $@;$(obj)/relocs --abs-relocs $<
29$(obj)/vmlinux.relocs: vmlinux $(obj)/relocs FORCE
30 $(call if_changed,relocs)
31
32vmlinux.bin.all-y := $(obj)/vmlinux.bin
33vmlinux.bin.all-$(CONFIG_RELOCATABLE) += $(obj)/vmlinux.relocs
34quiet_cmd_relocbin = BUILD $@
35 cmd_relocbin = cat $(filter-out FORCE,$^) > $@
36$(obj)/vmlinux.bin.all: $(vmlinux.bin.all-y) FORCE
37 $(call if_changed,relocbin)
38
39ifdef CONFIG_RELOCATABLE
40$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin.all FORCE
41 $(call if_changed,gzip)
42else
43$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
44 $(call if_changed,gzip)
45endif
46
47LDFLAGS_piggy.o := -r --format binary --oformat elf32-i386 -T
48
49$(obj)/piggy.o: $(src)/vmlinux_32.scr $(obj)/vmlinux.bin.gz FORCE
50 $(call if_changed,ld)
diff --git a/arch/x86/boot/compressed/Makefile_64 b/arch/x86/boot/compressed/Makefile_64
deleted file mode 100644
index 7801e8dd90b2..000000000000
--- a/arch/x86/boot/compressed/Makefile_64
+++ /dev/null
@@ -1,30 +0,0 @@
1#
2# linux/arch/x86/boot/compressed/Makefile
3#
4# create a compressed vmlinux image from the original vmlinux
5#
6
7targets := vmlinux vmlinux.bin vmlinux.bin.gz head_64.o misc_64.o piggy.o
8
9KBUILD_CFLAGS := -m64 -D__KERNEL__ $(LINUXINCLUDE) -O2 \
10 -fno-strict-aliasing -fPIC -mcmodel=small \
11 $(call cc-option, -ffreestanding) \
12 $(call cc-option, -fno-stack-protector)
13KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__
14LDFLAGS := -m elf_x86_64
15
16LDFLAGS_vmlinux := -T
17$(obj)/vmlinux: $(src)/vmlinux_64.lds $(obj)/head_64.o $(obj)/misc_64.o $(obj)/piggy.o FORCE
18 $(call if_changed,ld)
19 @:
20
21$(obj)/vmlinux.bin: vmlinux FORCE
22 $(call if_changed,objcopy)
23
24$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
25 $(call if_changed,gzip)
26
27LDFLAGS_piggy.o := -r --format binary --oformat elf64-x86-64 -T
28
29$(obj)/piggy.o: $(obj)/vmlinux_64.scr $(obj)/vmlinux.bin.gz FORCE
30 $(call if_changed,ld)
diff --git a/arch/x86/boot/compressed/misc_32.c b/arch/x86/boot/compressed/misc.c
index b74d60d1b2fa..8182e32c1b42 100644
--- a/arch/x86/boot/compressed/misc_32.c
+++ b/arch/x86/boot/compressed/misc.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * misc.c 2 * misc.c
3 * 3 *
4 * This is a collection of several routines from gzip-1.0.3 4 * This is a collection of several routines from gzip-1.0.3
5 * adapted for Linux. 5 * adapted for Linux.
6 * 6 *
7 * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994 7 * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
@@ -9,9 +9,18 @@
9 * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996 9 * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
10 */ 10 */
11 11
12/*
13 * we have to be careful, because no indirections are allowed here, and
14 * paravirt_ops is a kind of one. As it will only run in baremetal anyway,
15 * we just keep it from happening
16 */
12#undef CONFIG_PARAVIRT 17#undef CONFIG_PARAVIRT
18#ifdef CONFIG_X86_64
19#define _LINUX_STRING_H_ 1
20#define __LINUX_BITMAP_H 1
21#endif
22
13#include <linux/linkage.h> 23#include <linux/linkage.h>
14#include <linux/vmalloc.h>
15#include <linux/screen_info.h> 24#include <linux/screen_info.h>
16#include <asm/io.h> 25#include <asm/io.h>
17#include <asm/page.h> 26#include <asm/page.h>
@@ -186,10 +195,20 @@ static void *memcpy(void *dest, const void *src, unsigned n);
186 195
187static void putstr(const char *); 196static void putstr(const char *);
188 197
189static unsigned long free_mem_ptr; 198#ifdef CONFIG_X86_64
190static unsigned long free_mem_end_ptr; 199#define memptr long
200#else
201#define memptr unsigned
202#endif
203
204static memptr free_mem_ptr;
205static memptr free_mem_end_ptr;
191 206
207#ifdef CONFIG_X86_64
208#define HEAP_SIZE 0x7000
209#else
192#define HEAP_SIZE 0x4000 210#define HEAP_SIZE 0x4000
211#endif
193 212
194static char *vidmem = (char *)0xb8000; 213static char *vidmem = (char *)0xb8000;
195static int vidport; 214static int vidport;
@@ -230,7 +249,7 @@ static void gzip_mark(void **ptr)
230 249
231static void gzip_release(void **ptr) 250static void gzip_release(void **ptr)
232{ 251{
233 free_mem_ptr = (unsigned long) *ptr; 252 free_mem_ptr = (memptr) *ptr;
234} 253}
235 254
236static void scroll(void) 255static void scroll(void)
@@ -247,8 +266,10 @@ static void putstr(const char *s)
247 int x,y,pos; 266 int x,y,pos;
248 char c; 267 char c;
249 268
269#ifdef CONFIG_X86_32
250 if (RM_SCREEN_INFO.orig_video_mode == 0 && lines == 0 && cols == 0) 270 if (RM_SCREEN_INFO.orig_video_mode == 0 && lines == 0 && cols == 0)
251 return; 271 return;
272#endif
252 273
253 x = RM_SCREEN_INFO.orig_x; 274 x = RM_SCREEN_INFO.orig_x;
254 y = RM_SCREEN_INFO.orig_y; 275 y = RM_SCREEN_INFO.orig_y;
@@ -261,7 +282,7 @@ static void putstr(const char *s)
261 y--; 282 y--;
262 } 283 }
263 } else { 284 } else {
264 vidmem [ ( x + cols * y ) * 2 ] = c; 285 vidmem [(x + cols * y) * 2] = c;
265 if ( ++x >= cols ) { 286 if ( ++x >= cols ) {
266 x = 0; 287 x = 0;
267 if ( ++y >= lines ) { 288 if ( ++y >= lines ) {
@@ -276,16 +297,16 @@ static void putstr(const char *s)
276 RM_SCREEN_INFO.orig_y = y; 297 RM_SCREEN_INFO.orig_y = y;
277 298
278 pos = (x + cols * y) * 2; /* Update cursor position */ 299 pos = (x + cols * y) * 2; /* Update cursor position */
279 outb_p(14, vidport); 300 outb(14, vidport);
280 outb_p(0xff & (pos >> 9), vidport+1); 301 outb(0xff & (pos >> 9), vidport+1);
281 outb_p(15, vidport); 302 outb(15, vidport);
282 outb_p(0xff & (pos >> 1), vidport+1); 303 outb(0xff & (pos >> 1), vidport+1);
283} 304}
284 305
285static void* memset(void* s, int c, unsigned n) 306static void* memset(void* s, int c, unsigned n)
286{ 307{
287 int i; 308 int i;
288 char *ss = (char*)s; 309 char *ss = s;
289 310
290 for (i=0;i<n;i++) ss[i] = c; 311 for (i=0;i<n;i++) ss[i] = c;
291 return s; 312 return s;
@@ -294,7 +315,8 @@ static void* memset(void* s, int c, unsigned n)
294static void* memcpy(void* dest, const void* src, unsigned n) 315static void* memcpy(void* dest, const void* src, unsigned n)
295{ 316{
296 int i; 317 int i;
297 char *d = (char *)dest, *s = (char *)src; 318 const char *s = src;
319 char *d = dest;
298 320
299 for (i=0;i<n;i++) d[i] = s[i]; 321 for (i=0;i<n;i++) d[i] = s[i];
300 return dest; 322 return dest;
@@ -339,11 +361,13 @@ static void error(char *x)
339 putstr(x); 361 putstr(x);
340 putstr("\n\n -- System halted"); 362 putstr("\n\n -- System halted");
341 363
342 while(1); /* Halt */ 364 while (1)
365 asm("hlt");
343} 366}
344 367
345asmlinkage void decompress_kernel(void *rmode, unsigned long end, 368asmlinkage void decompress_kernel(void *rmode, memptr heap,
346 uch *input_data, unsigned long input_len, uch *output) 369 uch *input_data, unsigned long input_len,
370 uch *output)
347{ 371{
348 real_mode = rmode; 372 real_mode = rmode;
349 373
@@ -358,25 +382,32 @@ asmlinkage void decompress_kernel(void *rmode, unsigned long end,
358 lines = RM_SCREEN_INFO.orig_video_lines; 382 lines = RM_SCREEN_INFO.orig_video_lines;
359 cols = RM_SCREEN_INFO.orig_video_cols; 383 cols = RM_SCREEN_INFO.orig_video_cols;
360 384
361 window = output; /* Output buffer (Normally at 1M) */ 385 window = output; /* Output buffer (Normally at 1M) */
362 free_mem_ptr = end; /* Heap */ 386 free_mem_ptr = heap; /* Heap */
363 free_mem_end_ptr = end + HEAP_SIZE; 387 free_mem_end_ptr = heap + HEAP_SIZE;
364 inbuf = input_data; /* Input buffer */ 388 inbuf = input_data; /* Input buffer */
365 insize = input_len; 389 insize = input_len;
366 inptr = 0; 390 inptr = 0;
367 391
392#ifdef CONFIG_X86_64
393 if ((ulg)output & (__KERNEL_ALIGN - 1))
394 error("Destination address not 2M aligned");
395 if ((ulg)output >= 0xffffffffffUL)
396 error("Destination address too large");
397#else
368 if ((u32)output & (CONFIG_PHYSICAL_ALIGN -1)) 398 if ((u32)output & (CONFIG_PHYSICAL_ALIGN -1))
369 error("Destination address not CONFIG_PHYSICAL_ALIGN aligned"); 399 error("Destination address not CONFIG_PHYSICAL_ALIGN aligned");
370 if (end > ((-__PAGE_OFFSET-(512 <<20)-1) & 0x7fffffff)) 400 if (heap > ((-__PAGE_OFFSET-(512<<20)-1) & 0x7fffffff))
371 error("Destination address too large"); 401 error("Destination address too large");
372#ifndef CONFIG_RELOCATABLE 402#ifndef CONFIG_RELOCATABLE
373 if ((u32)output != LOAD_PHYSICAL_ADDR) 403 if ((u32)output != LOAD_PHYSICAL_ADDR)
374 error("Wrong destination address"); 404 error("Wrong destination address");
375#endif 405#endif
406#endif
376 407
377 makecrc(); 408 makecrc();
378 putstr("Uncompressing Linux... "); 409 putstr("\nDecompressing Linux... ");
379 gunzip(); 410 gunzip();
380 putstr("Ok, booting the kernel.\n"); 411 putstr("done.\nBooting the kernel.\n");
381 return; 412 return;
382} 413}
diff --git a/arch/x86/boot/compressed/misc_64.c b/arch/x86/boot/compressed/misc_64.c
deleted file mode 100644
index 6ea015aa65e4..000000000000
--- a/arch/x86/boot/compressed/misc_64.c
+++ /dev/null
@@ -1,371 +0,0 @@
1/*
2 * misc.c
3 *
4 * This is a collection of several routines from gzip-1.0.3
5 * adapted for Linux.
6 *
7 * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
8 * puts by Nick Holloway 1993, better puts by Martin Mares 1995
9 * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
10 */
11
12#define _LINUX_STRING_H_ 1
13#define __LINUX_BITMAP_H 1
14
15#include <linux/linkage.h>
16#include <linux/screen_info.h>
17#include <asm/io.h>
18#include <asm/page.h>
19
20/* WARNING!!
21 * This code is compiled with -fPIC and it is relocated dynamically
22 * at run time, but no relocation processing is performed.
23 * This means that it is not safe to place pointers in static structures.
24 */
25
26/*
27 * Getting to provable safe in place decompression is hard.
28 * Worst case behaviours need to be analyzed.
29 * Background information:
30 *
31 * The file layout is:
32 * magic[2]
33 * method[1]
34 * flags[1]
35 * timestamp[4]
36 * extraflags[1]
37 * os[1]
38 * compressed data blocks[N]
39 * crc[4] orig_len[4]
40 *
41 * resulting in 18 bytes of non compressed data overhead.
42 *
43 * Files divided into blocks
44 * 1 bit (last block flag)
45 * 2 bits (block type)
46 *
47 * 1 block occurs every 32K -1 bytes or when there 50% compression has been achieved.
48 * The smallest block type encoding is always used.
49 *
50 * stored:
51 * 32 bits length in bytes.
52 *
53 * fixed:
54 * magic fixed tree.
55 * symbols.
56 *
57 * dynamic:
58 * dynamic tree encoding.
59 * symbols.
60 *
61 *
62 * The buffer for decompression in place is the length of the
63 * uncompressed data, plus a small amount extra to keep the algorithm safe.
64 * The compressed data is placed at the end of the buffer. The output
65 * pointer is placed at the start of the buffer and the input pointer
66 * is placed where the compressed data starts. Problems will occur
67 * when the output pointer overruns the input pointer.
68 *
69 * The output pointer can only overrun the input pointer if the input
70 * pointer is moving faster than the output pointer. A condition only
71 * triggered by data whose compressed form is larger than the uncompressed
72 * form.
73 *
74 * The worst case at the block level is a growth of the compressed data
75 * of 5 bytes per 32767 bytes.
76 *
77 * The worst case internal to a compressed block is very hard to figure.
78 * The worst case can at least be boundined by having one bit that represents
79 * 32764 bytes and then all of the rest of the bytes representing the very
80 * very last byte.
81 *
82 * All of which is enough to compute an amount of extra data that is required
83 * to be safe. To avoid problems at the block level allocating 5 extra bytes
84 * per 32767 bytes of data is sufficient. To avoind problems internal to a block
85 * adding an extra 32767 bytes (the worst case uncompressed block size) is
86 * sufficient, to ensure that in the worst case the decompressed data for
87 * block will stop the byte before the compressed data for a block begins.
88 * To avoid problems with the compressed data's meta information an extra 18
89 * bytes are needed. Leading to the formula:
90 *
91 * extra_bytes = (uncompressed_size >> 12) + 32768 + 18 + decompressor_size.
92 *
93 * Adding 8 bytes per 32K is a bit excessive but much easier to calculate.
94 * Adding 32768 instead of 32767 just makes for round numbers.
95 * Adding the decompressor_size is necessary as it musht live after all
96 * of the data as well. Last I measured the decompressor is about 14K.
97 * 10K of actual data and 4K of bss.
98 *
99 */
100
101/*
102 * gzip declarations
103 */
104
105#define OF(args) args
106#define STATIC static
107
108#undef memset
109#undef memcpy
110#define memzero(s, n) memset ((s), 0, (n))
111
112typedef unsigned char uch;
113typedef unsigned short ush;
114typedef unsigned long ulg;
115
116#define WSIZE 0x80000000 /* Window size must be at least 32k,
117 * and a power of two
118 * We don't actually have a window just
119 * a huge output buffer so I report
120 * a 2G windows size, as that should
121 * always be larger than our output buffer.
122 */
123
124static uch *inbuf; /* input buffer */
125static uch *window; /* Sliding window buffer, (and final output buffer) */
126
127static unsigned insize; /* valid bytes in inbuf */
128static unsigned inptr; /* index of next byte to be processed in inbuf */
129static unsigned outcnt; /* bytes in output buffer */
130
131/* gzip flag byte */
132#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */
133#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
134#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
135#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
136#define COMMENT 0x10 /* bit 4 set: file comment present */
137#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
138#define RESERVED 0xC0 /* bit 6,7: reserved */
139
140#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
141
142/* Diagnostic functions */
143#ifdef DEBUG
144# define Assert(cond,msg) {if(!(cond)) error(msg);}
145# define Trace(x) fprintf x
146# define Tracev(x) {if (verbose) fprintf x ;}
147# define Tracevv(x) {if (verbose>1) fprintf x ;}
148# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
149# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
150#else
151# define Assert(cond,msg)
152# define Trace(x)
153# define Tracev(x)
154# define Tracevv(x)
155# define Tracec(c,x)
156# define Tracecv(c,x)
157#endif
158
159static int fill_inbuf(void);
160static void flush_window(void);
161static void error(char *m);
162static void gzip_mark(void **);
163static void gzip_release(void **);
164
165/*
166 * This is set up by the setup-routine at boot-time
167 */
168static unsigned char *real_mode; /* Pointer to real-mode data */
169
170#define RM_EXT_MEM_K (*(unsigned short *)(real_mode + 0x2))
171#ifndef STANDARD_MEMORY_BIOS_CALL
172#define RM_ALT_MEM_K (*(unsigned long *)(real_mode + 0x1e0))
173#endif
174#define RM_SCREEN_INFO (*(struct screen_info *)(real_mode+0))
175
176extern unsigned char input_data[];
177extern int input_len;
178
179static long bytes_out = 0;
180
181static void *malloc(int size);
182static void free(void *where);
183
184static void *memset(void *s, int c, unsigned n);
185static void *memcpy(void *dest, const void *src, unsigned n);
186
187static void putstr(const char *);
188
189static long free_mem_ptr;
190static long free_mem_end_ptr;
191
192#define HEAP_SIZE 0x7000
193
194static char *vidmem = (char *)0xb8000;
195static int vidport;
196static int lines, cols;
197
198#include "../../../../lib/inflate.c"
199
200static void *malloc(int size)
201{
202 void *p;
203
204 if (size <0) error("Malloc error");
205 if (free_mem_ptr <= 0) error("Memory error");
206
207 free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
208
209 p = (void *)free_mem_ptr;
210 free_mem_ptr += size;
211
212 if (free_mem_ptr >= free_mem_end_ptr)
213 error("Out of memory");
214
215 return p;
216}
217
218static void free(void *where)
219{ /* Don't care */
220}
221
222static void gzip_mark(void **ptr)
223{
224 *ptr = (void *) free_mem_ptr;
225}
226
227static void gzip_release(void **ptr)
228{
229 free_mem_ptr = (long) *ptr;
230}
231
232static void scroll(void)
233{
234 int i;
235
236 memcpy ( vidmem, vidmem + cols * 2, ( lines - 1 ) * cols * 2 );
237 for ( i = ( lines - 1 ) * cols * 2; i < lines * cols * 2; i += 2 )
238 vidmem[i] = ' ';
239}
240
241static void putstr(const char *s)
242{
243 int x,y,pos;
244 char c;
245
246 x = RM_SCREEN_INFO.orig_x;
247 y = RM_SCREEN_INFO.orig_y;
248
249 while ( ( c = *s++ ) != '\0' ) {
250 if ( c == '\n' ) {
251 x = 0;
252 if ( ++y >= lines ) {
253 scroll();
254 y--;
255 }
256 } else {
257 vidmem [ ( x + cols * y ) * 2 ] = c;
258 if ( ++x >= cols ) {
259 x = 0;
260 if ( ++y >= lines ) {
261 scroll();
262 y--;
263 }
264 }
265 }
266 }
267
268 RM_SCREEN_INFO.orig_x = x;
269 RM_SCREEN_INFO.orig_y = y;
270
271 pos = (x + cols * y) * 2; /* Update cursor position */
272 outb_p(14, vidport);
273 outb_p(0xff & (pos >> 9), vidport+1);
274 outb_p(15, vidport);
275 outb_p(0xff & (pos >> 1), vidport+1);
276}
277
278static void* memset(void* s, int c, unsigned n)
279{
280 int i;
281 char *ss = (char*)s;
282
283 for (i=0;i<n;i++) ss[i] = c;
284 return s;
285}
286
287static void* memcpy(void* dest, const void* src, unsigned n)
288{
289 int i;
290 char *d = (char *)dest, *s = (char *)src;
291
292 for (i=0;i<n;i++) d[i] = s[i];
293 return dest;
294}
295
296/* ===========================================================================
297 * Fill the input buffer. This is called only when the buffer is empty
298 * and at least one byte is really needed.
299 */
300static int fill_inbuf(void)
301{
302 error("ran out of input data");
303 return 0;
304}
305
306/* ===========================================================================
307 * Write the output window window[0..outcnt-1] and update crc and bytes_out.
308 * (Used for the decompressed data only.)
309 */
310static void flush_window(void)
311{
312 /* With my window equal to my output buffer
313 * I only need to compute the crc here.
314 */
315 ulg c = crc; /* temporary variable */
316 unsigned n;
317 uch *in, ch;
318
319 in = window;
320 for (n = 0; n < outcnt; n++) {
321 ch = *in++;
322 c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
323 }
324 crc = c;
325 bytes_out += (ulg)outcnt;
326 outcnt = 0;
327}
328
329static void error(char *x)
330{
331 putstr("\n\n");
332 putstr(x);
333 putstr("\n\n -- System halted");
334
335 while(1); /* Halt */
336}
337
338asmlinkage void decompress_kernel(void *rmode, unsigned long heap,
339 uch *input_data, unsigned long input_len, uch *output)
340{
341 real_mode = rmode;
342
343 if (RM_SCREEN_INFO.orig_video_mode == 7) {
344 vidmem = (char *) 0xb0000;
345 vidport = 0x3b4;
346 } else {
347 vidmem = (char *) 0xb8000;
348 vidport = 0x3d4;
349 }
350
351 lines = RM_SCREEN_INFO.orig_video_lines;
352 cols = RM_SCREEN_INFO.orig_video_cols;
353
354 window = output; /* Output buffer (Normally at 1M) */
355 free_mem_ptr = heap; /* Heap */
356 free_mem_end_ptr = heap + HEAP_SIZE;
357 inbuf = input_data; /* Input buffer */
358 insize = input_len;
359 inptr = 0;
360
361 if ((ulg)output & (__KERNEL_ALIGN - 1))
362 error("Destination address not 2M aligned");
363 if ((ulg)output >= 0xffffffffffUL)
364 error("Destination address too large");
365
366 makecrc();
367 putstr(".\nDecompressing Linux...");
368 gunzip();
369 putstr("done.\nBooting the kernel.\n");
370 return;
371}
diff --git a/arch/x86/boot/compressed/relocs.c b/arch/x86/boot/compressed/relocs.c
index 7a0d00b2cf28..d01ea42187e6 100644
--- a/arch/x86/boot/compressed/relocs.c
+++ b/arch/x86/boot/compressed/relocs.c
@@ -27,11 +27,6 @@ static unsigned long *relocs;
27 * absolute relocations present w.r.t these symbols. 27 * absolute relocations present w.r.t these symbols.
28 */ 28 */
29static const char* safe_abs_relocs[] = { 29static const char* safe_abs_relocs[] = {
30 "__kernel_vsyscall",
31 "__kernel_rt_sigreturn",
32 "__kernel_sigreturn",
33 "SYSENTER_RETURN",
34 "VDSO_NOTE_MASK",
35 "xen_irq_disable_direct_reloc", 30 "xen_irq_disable_direct_reloc",
36 "xen_save_fl_direct_reloc", 31 "xen_save_fl_direct_reloc",
37}; 32};
@@ -45,6 +40,8 @@ static int is_safe_abs_reloc(const char* sym_name)
45 /* Match found */ 40 /* Match found */
46 return 1; 41 return 1;
47 } 42 }
43 if (strncmp(sym_name, "VDSO", 4) == 0)
44 return 1;
48 if (strncmp(sym_name, "__crc_", 6) == 0) 45 if (strncmp(sym_name, "__crc_", 6) == 0)
49 return 1; 46 return 1;
50 return 0; 47 return 0;
diff --git a/arch/x86/boot/compressed/vmlinux_64.scr b/arch/x86/boot/compressed/vmlinux.scr
index bd1429ce193e..f02382ae5c48 100644
--- a/arch/x86/boot/compressed/vmlinux_64.scr
+++ b/arch/x86/boot/compressed/vmlinux.scr
@@ -1,6 +1,6 @@
1SECTIONS 1SECTIONS
2{ 2{
3 .text.compressed : { 3 .rodata.compressed : {
4 input_len = .; 4 input_len = .;
5 LONG(input_data_end - input_data) input_data = .; 5 LONG(input_data_end - input_data) input_data = .;
6 *(.data) 6 *(.data)
diff --git a/arch/x86/boot/compressed/vmlinux_32.lds b/arch/x86/boot/compressed/vmlinux_32.lds
index cc4854f6c6c1..bb3c48379c40 100644
--- a/arch/x86/boot/compressed/vmlinux_32.lds
+++ b/arch/x86/boot/compressed/vmlinux_32.lds
@@ -3,17 +3,17 @@ OUTPUT_ARCH(i386)
3ENTRY(startup_32) 3ENTRY(startup_32)
4SECTIONS 4SECTIONS
5{ 5{
6 /* Be careful parts of head.S assume startup_32 is at 6 /* Be careful parts of head_32.S assume startup_32 is at
7 * address 0. 7 * address 0.
8 */ 8 */
9 . = 0 ; 9 . = 0;
10 .text.head : { 10 .text.head : {
11 _head = . ; 11 _head = . ;
12 *(.text.head) 12 *(.text.head)
13 _ehead = . ; 13 _ehead = . ;
14 } 14 }
15 .data.compressed : { 15 .rodata.compressed : {
16 *(.data.compressed) 16 *(.rodata.compressed)
17 } 17 }
18 .text : { 18 .text : {
19 _text = .; /* Text */ 19 _text = .; /* Text */
diff --git a/arch/x86/boot/compressed/vmlinux_32.scr b/arch/x86/boot/compressed/vmlinux_32.scr
deleted file mode 100644
index 707a88f7f29e..000000000000
--- a/arch/x86/boot/compressed/vmlinux_32.scr
+++ /dev/null
@@ -1,10 +0,0 @@
1SECTIONS
2{
3 .data.compressed : {
4 input_len = .;
5 LONG(input_data_end - input_data) input_data = .;
6 *(.data)
7 output_len = . - 4;
8 input_data_end = .;
9 }
10}
diff --git a/arch/x86/boot/compressed/vmlinux_64.lds b/arch/x86/boot/compressed/vmlinux_64.lds
index 94c13e557fb4..f6e5b445f457 100644
--- a/arch/x86/boot/compressed/vmlinux_64.lds
+++ b/arch/x86/boot/compressed/vmlinux_64.lds
@@ -3,15 +3,19 @@ OUTPUT_ARCH(i386:x86-64)
3ENTRY(startup_64) 3ENTRY(startup_64)
4SECTIONS 4SECTIONS
5{ 5{
6 /* Be careful parts of head.S assume startup_32 is at 6 /* Be careful parts of head_64.S assume startup_64 is at
7 * address 0. 7 * address 0.
8 */ 8 */
9 . = 0; 9 . = 0;
10 .text : { 10 .text.head : {
11 _head = . ; 11 _head = . ;
12 *(.text.head) 12 *(.text.head)
13 _ehead = . ; 13 _ehead = . ;
14 *(.text.compressed) 14 }
15 .rodata.compressed : {
16 *(.rodata.compressed)
17 }
18 .text : {
15 _text = .; /* Text */ 19 _text = .; /* Text */
16 *(.text) 20 *(.text)
17 *(.text.*) 21 *(.text.*)
diff --git a/arch/x86/boot/edd.c b/arch/x86/boot/edd.c
index bd138e442ec2..8721dc46a0b6 100644
--- a/arch/x86/boot/edd.c
+++ b/arch/x86/boot/edd.c
@@ -129,6 +129,7 @@ void query_edd(void)
129 char eddarg[8]; 129 char eddarg[8];
130 int do_mbr = 1; 130 int do_mbr = 1;
131 int do_edd = 1; 131 int do_edd = 1;
132 int be_quiet;
132 int devno; 133 int devno;
133 struct edd_info ei, *edp; 134 struct edd_info ei, *edp;
134 u32 *mbrptr; 135 u32 *mbrptr;
@@ -140,12 +141,21 @@ void query_edd(void)
140 do_edd = 0; 141 do_edd = 0;
141 } 142 }
142 143
144 be_quiet = cmdline_find_option_bool("quiet");
145
143 edp = boot_params.eddbuf; 146 edp = boot_params.eddbuf;
144 mbrptr = boot_params.edd_mbr_sig_buffer; 147 mbrptr = boot_params.edd_mbr_sig_buffer;
145 148
146 if (!do_edd) 149 if (!do_edd)
147 return; 150 return;
148 151
152 /* Bugs in OnBoard or AddOnCards Bios may hang the EDD probe,
153 * so give a hint if this happens.
154 */
155
156 if (!be_quiet)
157 printf("Probing EDD (edd=off to disable)... ");
158
149 for (devno = 0x80; devno < 0x80+EDD_MBR_SIG_MAX; devno++) { 159 for (devno = 0x80; devno < 0x80+EDD_MBR_SIG_MAX; devno++) {
150 /* 160 /*
151 * Scan the BIOS-supported hard disks and query EDD 161 * Scan the BIOS-supported hard disks and query EDD
@@ -162,6 +172,9 @@ void query_edd(void)
162 if (do_mbr && !read_mbr_sig(devno, &ei, mbrptr++)) 172 if (do_mbr && !read_mbr_sig(devno, &ei, mbrptr++))
163 boot_params.edd_mbr_sig_buf_entries = devno-0x80+1; 173 boot_params.edd_mbr_sig_buf_entries = devno-0x80+1;
164 } 174 }
175
176 if (!be_quiet)
177 printf("ok\n");
165} 178}
166 179
167#endif 180#endif
diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
index 4cc5b0411db5..64ad9016585a 100644
--- a/arch/x86/boot/header.S
+++ b/arch/x86/boot/header.S
@@ -195,10 +195,13 @@ cmd_line_ptr: .long 0 # (Header version 0x0202 or later)
195 # can be located anywhere in 195 # can be located anywhere in
196 # low memory 0x10000 or higher. 196 # low memory 0x10000 or higher.
197 197
198ramdisk_max: .long (-__PAGE_OFFSET-(512 << 20)-1) & 0x7fffffff 198ramdisk_max: .long 0x7fffffff
199 # (Header version 0x0203 or later) 199 # (Header version 0x0203 or later)
200 # The highest safe address for 200 # The highest safe address for
201 # the contents of an initrd 201 # the contents of an initrd
202 # The current kernel allows up to 4 GB,
203 # but leave it at 2 GB to avoid
204 # possible bootloader bugs.
202 205
203kernel_alignment: .long CONFIG_PHYSICAL_ALIGN #physical addr alignment 206kernel_alignment: .long CONFIG_PHYSICAL_ALIGN #physical addr alignment
204 #required for protected mode 207 #required for protected mode
diff --git a/arch/x86/boot/main.c b/arch/x86/boot/main.c
index 1f95750ede28..7828da5cfd07 100644
--- a/arch/x86/boot/main.c
+++ b/arch/x86/boot/main.c
@@ -100,20 +100,32 @@ static void set_bios_mode(void)
100#endif 100#endif
101} 101}
102 102
103void main(void) 103static void init_heap(void)
104{ 104{
105 /* First, copy the boot header into the "zeropage" */ 105 char *stack_end;
106 copy_boot_params();
107 106
108 /* End of heap check */
109 if (boot_params.hdr.loadflags & CAN_USE_HEAP) { 107 if (boot_params.hdr.loadflags & CAN_USE_HEAP) {
110 heap_end = (char *)(boot_params.hdr.heap_end_ptr 108 asm("leal %P1(%%esp),%0"
111 +0x200-STACK_SIZE); 109 : "=r" (stack_end) : "i" (-STACK_SIZE));
110
111 heap_end = (char *)
112 ((size_t)boot_params.hdr.heap_end_ptr + 0x200);
113 if (heap_end > stack_end)
114 heap_end = stack_end;
112 } else { 115 } else {
113 /* Boot protocol 2.00 only, no heap available */ 116 /* Boot protocol 2.00 only, no heap available */
114 puts("WARNING: Ancient bootloader, some functionality " 117 puts("WARNING: Ancient bootloader, some functionality "
115 "may be limited!\n"); 118 "may be limited!\n");
116 } 119 }
120}
121
122void main(void)
123{
124 /* First, copy the boot header into the "zeropage" */
125 copy_boot_params();
126
127 /* End of heap check */
128 init_heap();
117 129
118 /* Make sure we have all the proper CPU support */ 130 /* Make sure we have all the proper CPU support */
119 if (validate_cpu()) { 131 if (validate_cpu()) {
@@ -131,9 +143,6 @@ void main(void)
131 /* Set keyboard repeat rate (why?) */ 143 /* Set keyboard repeat rate (why?) */
132 keyboard_set_repeat(); 144 keyboard_set_repeat();
133 145
134 /* Set the video mode */
135 set_video();
136
137 /* Query MCA information */ 146 /* Query MCA information */
138 query_mca(); 147 query_mca();
139 148
@@ -154,6 +163,10 @@ void main(void)
154#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) 163#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
155 query_edd(); 164 query_edd();
156#endif 165#endif
166
167 /* Set the video mode */
168 set_video();
169
157 /* Do the last things and invoke protected mode */ 170 /* Do the last things and invoke protected mode */
158 go_to_protected_mode(); 171 go_to_protected_mode();
159} 172}
diff --git a/arch/x86/boot/pm.c b/arch/x86/boot/pm.c
index 09fb342cc62e..1a0f936c160b 100644
--- a/arch/x86/boot/pm.c
+++ b/arch/x86/boot/pm.c
@@ -104,7 +104,7 @@ static void reset_coprocessor(void)
104 (((u64)(base & 0xff000000) << 32) | \ 104 (((u64)(base & 0xff000000) << 32) | \
105 ((u64)flags << 40) | \ 105 ((u64)flags << 40) | \
106 ((u64)(limit & 0x00ff0000) << 32) | \ 106 ((u64)(limit & 0x00ff0000) << 32) | \
107 ((u64)(base & 0x00ffff00) << 16) | \ 107 ((u64)(base & 0x00ffffff) << 16) | \
108 ((u64)(limit & 0x0000ffff))) 108 ((u64)(limit & 0x0000ffff)))
109 109
110struct gdt_ptr { 110struct gdt_ptr {
@@ -121,6 +121,10 @@ static void setup_gdt(void)
121 [GDT_ENTRY_BOOT_CS] = GDT_ENTRY(0xc09b, 0, 0xfffff), 121 [GDT_ENTRY_BOOT_CS] = GDT_ENTRY(0xc09b, 0, 0xfffff),
122 /* DS: data, read/write, 4 GB, base 0 */ 122 /* DS: data, read/write, 4 GB, base 0 */
123 [GDT_ENTRY_BOOT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff), 123 [GDT_ENTRY_BOOT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff),
124 /* TSS: 32-bit tss, 104 bytes, base 4096 */
125 /* We only have a TSS here to keep Intel VT happy;
126 we don't actually use it for anything. */
127 [GDT_ENTRY_BOOT_TSS] = GDT_ENTRY(0x0089, 4096, 103),
124 }; 128 };
125 /* Xen HVM incorrectly stores a pointer to the gdt_ptr, instead 129 /* Xen HVM incorrectly stores a pointer to the gdt_ptr, instead
126 of the gdt_ptr contents. Thus, make it static so it will 130 of the gdt_ptr contents. Thus, make it static so it will
diff --git a/arch/x86/boot/pmjump.S b/arch/x86/boot/pmjump.S
index fa6bed1fac14..f5402d51f7c3 100644
--- a/arch/x86/boot/pmjump.S
+++ b/arch/x86/boot/pmjump.S
@@ -15,6 +15,7 @@
15 */ 15 */
16 16
17#include <asm/boot.h> 17#include <asm/boot.h>
18#include <asm/processor-flags.h>
18#include <asm/segment.h> 19#include <asm/segment.h>
19 20
20 .text 21 .text
@@ -29,28 +30,55 @@
29 */ 30 */
30protected_mode_jump: 31protected_mode_jump:
31 movl %edx, %esi # Pointer to boot_params table 32 movl %edx, %esi # Pointer to boot_params table
32 movl %eax, 2f # Patch ljmpl instruction 33
34 xorl %ebx, %ebx
35 movw %cs, %bx
36 shll $4, %ebx
37 addl %ebx, 2f
33 38
34 movw $__BOOT_DS, %cx 39 movw $__BOOT_DS, %cx
35 xorl %ebx, %ebx # Per the 32-bit boot protocol 40 movw $__BOOT_TSS, %di
36 xorl %ebp, %ebp # Per the 32-bit boot protocol
37 xorl %edi, %edi # Per the 32-bit boot protocol
38 41
39 movl %cr0, %edx 42 movl %cr0, %edx
40 orb $1, %dl # Protected mode (PE) bit 43 orb $X86_CR0_PE, %dl # Protected mode
41 movl %edx, %cr0 44 movl %edx, %cr0
42 jmp 1f # Short jump to serialize on 386/486 45 jmp 1f # Short jump to serialize on 386/486
431: 461:
44 47
45 movw %cx, %ds 48 # Transition to 32-bit mode
46 movw %cx, %es
47 movw %cx, %fs
48 movw %cx, %gs
49 movw %cx, %ss
50
51 # Jump to the 32-bit entrypoint
52 .byte 0x66, 0xea # ljmpl opcode 49 .byte 0x66, 0xea # ljmpl opcode
532: .long 0 # offset 502: .long in_pm32 # offset
54 .word __BOOT_CS # segment 51 .word __BOOT_CS # segment
55 52
56 .size protected_mode_jump, .-protected_mode_jump 53 .size protected_mode_jump, .-protected_mode_jump
54
55 .code32
56 .type in_pm32, @function
57in_pm32:
58 # Set up data segments for flat 32-bit mode
59 movl %ecx, %ds
60 movl %ecx, %es
61 movl %ecx, %fs
62 movl %ecx, %gs
63 movl %ecx, %ss
64 # The 32-bit code sets up its own stack, but this way we do have
65 # a valid stack if some debugging hack wants to use it.
66 addl %ebx, %esp
67
68 # Set up TR to make Intel VT happy
69 ltr %di
70
71 # Clear registers to allow for future extensions to the
72 # 32-bit boot protocol
73 xorl %ecx, %ecx
74 xorl %edx, %edx
75 xorl %ebx, %ebx
76 xorl %ebp, %ebp
77 xorl %edi, %edi
78
79 # Set up LDTR to make Intel VT happy
80 lldt %cx
81
82 jmpl *%eax # Jump to the 32-bit entrypoint
83
84 .size in_pm32, .-in_pm32
diff --git a/arch/x86/boot/video-bios.c b/arch/x86/boot/video-bios.c
index ed0672a81870..ff664a117096 100644
--- a/arch/x86/boot/video-bios.c
+++ b/arch/x86/boot/video-bios.c
@@ -104,6 +104,7 @@ static int bios_probe(void)
104 104
105 mi = GET_HEAP(struct mode_info, 1); 105 mi = GET_HEAP(struct mode_info, 1);
106 mi->mode = VIDEO_FIRST_BIOS+mode; 106 mi->mode = VIDEO_FIRST_BIOS+mode;
107 mi->depth = 0; /* text */
107 mi->x = rdfs16(0x44a); 108 mi->x = rdfs16(0x44a);
108 mi->y = rdfs8(0x484)+1; 109 mi->y = rdfs8(0x484)+1;
109 nmodes++; 110 nmodes++;
@@ -116,7 +117,7 @@ static int bios_probe(void)
116 117
117__videocard video_bios = 118__videocard video_bios =
118{ 119{
119 .card_name = "BIOS (scanned)", 120 .card_name = "BIOS",
120 .probe = bios_probe, 121 .probe = bios_probe,
121 .set_mode = bios_set_mode, 122 .set_mode = bios_set_mode,
122 .unsafe = 1, 123 .unsafe = 1,
diff --git a/arch/x86/boot/video-vesa.c b/arch/x86/boot/video-vesa.c
index 4716b9a96357..662dd2f13068 100644
--- a/arch/x86/boot/video-vesa.c
+++ b/arch/x86/boot/video-vesa.c
@@ -79,20 +79,28 @@ static int vesa_probe(void)
79 /* Text Mode, TTY BIOS supported, 79 /* Text Mode, TTY BIOS supported,
80 supported by hardware */ 80 supported by hardware */
81 mi = GET_HEAP(struct mode_info, 1); 81 mi = GET_HEAP(struct mode_info, 1);
82 mi->mode = mode + VIDEO_FIRST_VESA; 82 mi->mode = mode + VIDEO_FIRST_VESA;
83 mi->x = vminfo.h_res; 83 mi->depth = 0; /* text */
84 mi->y = vminfo.v_res; 84 mi->x = vminfo.h_res;
85 mi->y = vminfo.v_res;
85 nmodes++; 86 nmodes++;
86 } else if ((vminfo.mode_attr & 0x99) == 0x99) { 87 } else if ((vminfo.mode_attr & 0x99) == 0x99 &&
88 (vminfo.memory_layout == 4 ||
89 vminfo.memory_layout == 6) &&
90 vminfo.memory_planes == 1) {
87#ifdef CONFIG_FB 91#ifdef CONFIG_FB
88 /* Graphics mode, color, linear frame buffer 92 /* Graphics mode, color, linear frame buffer
89 supported -- register the mode but hide from 93 supported. Only register the mode if
90 the menu. Only do this if framebuffer is 94 if framebuffer is configured, however,
91 configured, however, otherwise the user will 95 otherwise the user will be left without a screen.
92 be left without a screen. */ 96 We don't require CONFIG_FB_VESA, however, since
97 some of the other framebuffer drivers can use
98 this mode-setting, too. */
93 mi = GET_HEAP(struct mode_info, 1); 99 mi = GET_HEAP(struct mode_info, 1);
94 mi->mode = mode + VIDEO_FIRST_VESA; 100 mi->mode = mode + VIDEO_FIRST_VESA;
95 mi->x = mi->y = 0; 101 mi->depth = vminfo.bpp;
102 mi->x = vminfo.h_res;
103 mi->y = vminfo.v_res;
96 nmodes++; 104 nmodes++;
97#endif 105#endif
98 } 106 }
diff --git a/arch/x86/boot/video-vga.c b/arch/x86/boot/video-vga.c
index aef02f9ec0c1..7259387b7d19 100644
--- a/arch/x86/boot/video-vga.c
+++ b/arch/x86/boot/video-vga.c
@@ -18,22 +18,22 @@
18#include "video.h" 18#include "video.h"
19 19
20static struct mode_info vga_modes[] = { 20static struct mode_info vga_modes[] = {
21 { VIDEO_80x25, 80, 25 }, 21 { VIDEO_80x25, 80, 25, 0 },
22 { VIDEO_8POINT, 80, 50 }, 22 { VIDEO_8POINT, 80, 50, 0 },
23 { VIDEO_80x43, 80, 43 }, 23 { VIDEO_80x43, 80, 43, 0 },
24 { VIDEO_80x28, 80, 28 }, 24 { VIDEO_80x28, 80, 28, 0 },
25 { VIDEO_80x30, 80, 30 }, 25 { VIDEO_80x30, 80, 30, 0 },
26 { VIDEO_80x34, 80, 34 }, 26 { VIDEO_80x34, 80, 34, 0 },
27 { VIDEO_80x60, 80, 60 }, 27 { VIDEO_80x60, 80, 60, 0 },
28}; 28};
29 29
30static struct mode_info ega_modes[] = { 30static struct mode_info ega_modes[] = {
31 { VIDEO_80x25, 80, 25 }, 31 { VIDEO_80x25, 80, 25, 0 },
32 { VIDEO_8POINT, 80, 43 }, 32 { VIDEO_8POINT, 80, 43, 0 },
33}; 33};
34 34
35static struct mode_info cga_modes[] = { 35static struct mode_info cga_modes[] = {
36 { VIDEO_80x25, 80, 25 }, 36 { VIDEO_80x25, 80, 25, 0 },
37}; 37};
38 38
39__videocard video_vga; 39__videocard video_vga;
diff --git a/arch/x86/boot/video.c b/arch/x86/boot/video.c
index ad9712f01739..696d08f3843c 100644
--- a/arch/x86/boot/video.c
+++ b/arch/x86/boot/video.c
@@ -293,13 +293,28 @@ static void display_menu(void)
293 struct mode_info *mi; 293 struct mode_info *mi;
294 char ch; 294 char ch;
295 int i; 295 int i;
296 int nmodes;
297 int modes_per_line;
298 int col;
296 299
297 puts("Mode: COLSxROWS:\n"); 300 nmodes = 0;
301 for (card = video_cards; card < video_cards_end; card++)
302 nmodes += card->nmodes;
298 303
304 modes_per_line = 1;
305 if (nmodes >= 20)
306 modes_per_line = 3;
307
308 for (col = 0; col < modes_per_line; col++)
309 puts("Mode: Resolution: Type: ");
310 putchar('\n');
311
312 col = 0;
299 ch = '0'; 313 ch = '0';
300 for (card = video_cards; card < video_cards_end; card++) { 314 for (card = video_cards; card < video_cards_end; card++) {
301 mi = card->modes; 315 mi = card->modes;
302 for (i = 0; i < card->nmodes; i++, mi++) { 316 for (i = 0; i < card->nmodes; i++, mi++) {
317 char resbuf[32];
303 int visible = mi->x && mi->y; 318 int visible = mi->x && mi->y;
304 u16 mode_id = mi->mode ? mi->mode : 319 u16 mode_id = mi->mode ? mi->mode :
305 (mi->y << 8)+mi->x; 320 (mi->y << 8)+mi->x;
@@ -307,8 +322,18 @@ static void display_menu(void)
307 if (!visible) 322 if (!visible)
308 continue; /* Hidden mode */ 323 continue; /* Hidden mode */
309 324
310 printf("%c %04X %3dx%-3d %s\n", 325 if (mi->depth)
311 ch, mode_id, mi->x, mi->y, card->card_name); 326 sprintf(resbuf, "%dx%d", mi->y, mi->depth);
327 else
328 sprintf(resbuf, "%d", mi->y);
329
330 printf("%c %03X %4dx%-7s %-6s",
331 ch, mode_id, mi->x, resbuf, card->card_name);
332 col++;
333 if (col >= modes_per_line) {
334 putchar('\n');
335 col = 0;
336 }
312 337
313 if (ch == '9') 338 if (ch == '9')
314 ch = 'a'; 339 ch = 'a';
@@ -318,6 +343,8 @@ static void display_menu(void)
318 ch++; 343 ch++;
319 } 344 }
320 } 345 }
346 if (col)
347 putchar('\n');
321} 348}
322 349
323#define H(x) ((x)-'a'+10) 350#define H(x) ((x)-'a'+10)
diff --git a/arch/x86/boot/video.h b/arch/x86/boot/video.h
index b92447d51213..d69347f79e8e 100644
--- a/arch/x86/boot/video.h
+++ b/arch/x86/boot/video.h
@@ -83,7 +83,8 @@ void store_screen(void);
83 83
84struct mode_info { 84struct mode_info {
85 u16 mode; /* Mode number (vga= style) */ 85 u16 mode; /* Mode number (vga= style) */
86 u8 x, y; /* Width, height */ 86 u16 x, y; /* Width, height */
87 u16 depth; /* Bits per pixel, 0 for text mode */
87}; 88};
88 89
89struct card_info { 90struct card_info {
diff --git a/arch/x86/boot/voyager.c b/arch/x86/boot/voyager.c
index 61c8fe0453be..6499e3239b41 100644
--- a/arch/x86/boot/voyager.c
+++ b/arch/x86/boot/voyager.c
@@ -16,8 +16,6 @@
16 16
17#include "boot.h" 17#include "boot.h"
18 18
19#ifdef CONFIG_X86_VOYAGER
20
21int query_voyager(void) 19int query_voyager(void)
22{ 20{
23 u8 err; 21 u8 err;
@@ -42,5 +40,3 @@ int query_voyager(void)
42 copy_from_fs(data_ptr, di, 7); /* Table is 7 bytes apparently */ 40 copy_from_fs(data_ptr, di, 7); /* Table is 7 bytes apparently */
43 return 0; 41 return 0;
44} 42}
45
46#endif /* CONFIG_X86_VOYAGER */
diff --git a/arch/x86/configs/i386_defconfig b/arch/x86/configs/i386_defconfig
index 54ee1764fdae..77562e7cdab6 100644
--- a/arch/x86/configs/i386_defconfig
+++ b/arch/x86/configs/i386_defconfig
@@ -99,9 +99,9 @@ CONFIG_IOSCHED_NOOP=y
99CONFIG_IOSCHED_AS=y 99CONFIG_IOSCHED_AS=y
100CONFIG_IOSCHED_DEADLINE=y 100CONFIG_IOSCHED_DEADLINE=y
101CONFIG_IOSCHED_CFQ=y 101CONFIG_IOSCHED_CFQ=y
102CONFIG_DEFAULT_AS=y 102# CONFIG_DEFAULT_AS is not set
103# CONFIG_DEFAULT_DEADLINE is not set 103# CONFIG_DEFAULT_DEADLINE is not set
104# CONFIG_DEFAULT_CFQ is not set 104CONFIG_DEFAULT_CFQ=y
105# CONFIG_DEFAULT_NOOP is not set 105# CONFIG_DEFAULT_NOOP is not set
106CONFIG_DEFAULT_IOSCHED="anticipatory" 106CONFIG_DEFAULT_IOSCHED="anticipatory"
107 107
diff --git a/arch/x86/configs/x86_64_defconfig b/arch/x86/configs/x86_64_defconfig
index 38a83f9c966f..9e2b0ef851de 100644
--- a/arch/x86/configs/x86_64_defconfig
+++ b/arch/x86/configs/x86_64_defconfig
@@ -145,15 +145,6 @@ CONFIG_K8_NUMA=y
145CONFIG_NODES_SHIFT=6 145CONFIG_NODES_SHIFT=6
146CONFIG_X86_64_ACPI_NUMA=y 146CONFIG_X86_64_ACPI_NUMA=y
147CONFIG_NUMA_EMU=y 147CONFIG_NUMA_EMU=y
148CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
149CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y
150CONFIG_ARCH_SPARSEMEM_ENABLE=y
151CONFIG_SELECT_MEMORY_MODEL=y
152# CONFIG_FLATMEM_MANUAL is not set
153CONFIG_DISCONTIGMEM_MANUAL=y
154# CONFIG_SPARSEMEM_MANUAL is not set
155CONFIG_DISCONTIGMEM=y
156CONFIG_FLAT_NODE_MEM_MAP=y
157CONFIG_NEED_MULTIPLE_NODES=y 148CONFIG_NEED_MULTIPLE_NODES=y
158# CONFIG_SPARSEMEM_STATIC is not set 149# CONFIG_SPARSEMEM_STATIC is not set
159CONFIG_SPLIT_PTLOCK_CPUS=4 150CONFIG_SPLIT_PTLOCK_CPUS=4
diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile
index 46bb609e2444..3874c2de5403 100644
--- a/arch/x86/crypto/Makefile
+++ b/arch/x86/crypto/Makefile
@@ -4,12 +4,16 @@
4 4
5obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o 5obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o
6obj-$(CONFIG_CRYPTO_TWOFISH_586) += twofish-i586.o 6obj-$(CONFIG_CRYPTO_TWOFISH_586) += twofish-i586.o
7obj-$(CONFIG_CRYPTO_SALSA20_586) += salsa20-i586.o
7 8
8obj-$(CONFIG_CRYPTO_AES_X86_64) += aes-x86_64.o 9obj-$(CONFIG_CRYPTO_AES_X86_64) += aes-x86_64.o
9obj-$(CONFIG_CRYPTO_TWOFISH_X86_64) += twofish-x86_64.o 10obj-$(CONFIG_CRYPTO_TWOFISH_X86_64) += twofish-x86_64.o
11obj-$(CONFIG_CRYPTO_SALSA20_X86_64) += salsa20-x86_64.o
10 12
11aes-i586-y := aes-i586-asm_32.o aes_32.o 13aes-i586-y := aes-i586-asm_32.o aes_glue.o
12twofish-i586-y := twofish-i586-asm_32.o twofish_32.o 14twofish-i586-y := twofish-i586-asm_32.o twofish_glue.o
15salsa20-i586-y := salsa20-i586-asm_32.o salsa20_glue.o
13 16
14aes-x86_64-y := aes-x86_64-asm_64.o aes_64.o 17aes-x86_64-y := aes-x86_64-asm_64.o aes_glue.o
15twofish-x86_64-y := twofish-x86_64-asm_64.o twofish_64.o 18twofish-x86_64-y := twofish-x86_64-asm_64.o twofish_glue.o
19salsa20-x86_64-y := salsa20-x86_64-asm_64.o salsa20_glue.o
diff --git a/arch/x86/crypto/aes-i586-asm_32.S b/arch/x86/crypto/aes-i586-asm_32.S
index f942f0c8f630..1093bede3e0a 100644
--- a/arch/x86/crypto/aes-i586-asm_32.S
+++ b/arch/x86/crypto/aes-i586-asm_32.S
@@ -46,9 +46,9 @@
46#define in_blk 16 46#define in_blk 16
47 47
48/* offsets in crypto_tfm structure */ 48/* offsets in crypto_tfm structure */
49#define ekey (crypto_tfm_ctx_offset + 0) 49#define klen (crypto_tfm_ctx_offset + 0)
50#define nrnd (crypto_tfm_ctx_offset + 256) 50#define ekey (crypto_tfm_ctx_offset + 4)
51#define dkey (crypto_tfm_ctx_offset + 260) 51#define dkey (crypto_tfm_ctx_offset + 244)
52 52
53// register mapping for encrypt and decrypt subroutines 53// register mapping for encrypt and decrypt subroutines
54 54
@@ -221,8 +221,8 @@
221 221
222.global aes_enc_blk 222.global aes_enc_blk
223 223
224.extern ft_tab 224.extern crypto_ft_tab
225.extern fl_tab 225.extern crypto_fl_tab
226 226
227.align 4 227.align 4
228 228
@@ -236,7 +236,7 @@ aes_enc_blk:
2361: push %ebx 2361: push %ebx
237 mov in_blk+4(%esp),%r2 237 mov in_blk+4(%esp),%r2
238 push %esi 238 push %esi
239 mov nrnd(%ebp),%r3 // number of rounds 239 mov klen(%ebp),%r3 // key size
240 push %edi 240 push %edi
241#if ekey != 0 241#if ekey != 0
242 lea ekey(%ebp),%ebp // key pointer 242 lea ekey(%ebp),%ebp // key pointer
@@ -255,26 +255,26 @@ aes_enc_blk:
255 255
256 sub $8,%esp // space for register saves on stack 256 sub $8,%esp // space for register saves on stack
257 add $16,%ebp // increment to next round key 257 add $16,%ebp // increment to next round key
258 cmp $12,%r3 258 cmp $24,%r3
259 jb 4f // 10 rounds for 128-bit key 259 jb 4f // 10 rounds for 128-bit key
260 lea 32(%ebp),%ebp 260 lea 32(%ebp),%ebp
261 je 3f // 12 rounds for 192-bit key 261 je 3f // 12 rounds for 192-bit key
262 lea 32(%ebp),%ebp 262 lea 32(%ebp),%ebp
263 263
2642: fwd_rnd1( -64(%ebp) ,ft_tab) // 14 rounds for 256-bit key 2642: fwd_rnd1( -64(%ebp), crypto_ft_tab) // 14 rounds for 256-bit key
265 fwd_rnd2( -48(%ebp) ,ft_tab) 265 fwd_rnd2( -48(%ebp), crypto_ft_tab)
2663: fwd_rnd1( -32(%ebp) ,ft_tab) // 12 rounds for 192-bit key 2663: fwd_rnd1( -32(%ebp), crypto_ft_tab) // 12 rounds for 192-bit key
267 fwd_rnd2( -16(%ebp) ,ft_tab) 267 fwd_rnd2( -16(%ebp), crypto_ft_tab)
2684: fwd_rnd1( (%ebp) ,ft_tab) // 10 rounds for 128-bit key 2684: fwd_rnd1( (%ebp), crypto_ft_tab) // 10 rounds for 128-bit key
269 fwd_rnd2( +16(%ebp) ,ft_tab) 269 fwd_rnd2( +16(%ebp), crypto_ft_tab)
270 fwd_rnd1( +32(%ebp) ,ft_tab) 270 fwd_rnd1( +32(%ebp), crypto_ft_tab)
271 fwd_rnd2( +48(%ebp) ,ft_tab) 271 fwd_rnd2( +48(%ebp), crypto_ft_tab)
272 fwd_rnd1( +64(%ebp) ,ft_tab) 272 fwd_rnd1( +64(%ebp), crypto_ft_tab)
273 fwd_rnd2( +80(%ebp) ,ft_tab) 273 fwd_rnd2( +80(%ebp), crypto_ft_tab)
274 fwd_rnd1( +96(%ebp) ,ft_tab) 274 fwd_rnd1( +96(%ebp), crypto_ft_tab)
275 fwd_rnd2(+112(%ebp) ,ft_tab) 275 fwd_rnd2(+112(%ebp), crypto_ft_tab)
276 fwd_rnd1(+128(%ebp) ,ft_tab) 276 fwd_rnd1(+128(%ebp), crypto_ft_tab)
277 fwd_rnd2(+144(%ebp) ,fl_tab) // last round uses a different table 277 fwd_rnd2(+144(%ebp), crypto_fl_tab) // last round uses a different table
278 278
279// move final values to the output array. CAUTION: the 279// move final values to the output array. CAUTION: the
280// order of these assigns rely on the register mappings 280// order of these assigns rely on the register mappings
@@ -297,8 +297,8 @@ aes_enc_blk:
297 297
298.global aes_dec_blk 298.global aes_dec_blk
299 299
300.extern it_tab 300.extern crypto_it_tab
301.extern il_tab 301.extern crypto_il_tab
302 302
303.align 4 303.align 4
304 304
@@ -312,14 +312,11 @@ aes_dec_blk:
3121: push %ebx 3121: push %ebx
313 mov in_blk+4(%esp),%r2 313 mov in_blk+4(%esp),%r2
314 push %esi 314 push %esi
315 mov nrnd(%ebp),%r3 // number of rounds 315 mov klen(%ebp),%r3 // key size
316 push %edi 316 push %edi
317#if dkey != 0 317#if dkey != 0
318 lea dkey(%ebp),%ebp // key pointer 318 lea dkey(%ebp),%ebp // key pointer
319#endif 319#endif
320 mov %r3,%r0
321 shl $4,%r0
322 add %r0,%ebp
323 320
324// input four columns and xor in first round key 321// input four columns and xor in first round key
325 322
@@ -333,27 +330,27 @@ aes_dec_blk:
333 xor 12(%ebp),%r5 330 xor 12(%ebp),%r5
334 331
335 sub $8,%esp // space for register saves on stack 332 sub $8,%esp // space for register saves on stack
336 sub $16,%ebp // increment to next round key 333 add $16,%ebp // increment to next round key
337 cmp $12,%r3 334 cmp $24,%r3
338 jb 4f // 10 rounds for 128-bit key 335 jb 4f // 10 rounds for 128-bit key
339 lea -32(%ebp),%ebp 336 lea 32(%ebp),%ebp
340 je 3f // 12 rounds for 192-bit key 337 je 3f // 12 rounds for 192-bit key
341 lea -32(%ebp),%ebp 338 lea 32(%ebp),%ebp
342 339
3432: inv_rnd1( +64(%ebp), it_tab) // 14 rounds for 256-bit key 3402: inv_rnd1( -64(%ebp), crypto_it_tab) // 14 rounds for 256-bit key
344 inv_rnd2( +48(%ebp), it_tab) 341 inv_rnd2( -48(%ebp), crypto_it_tab)
3453: inv_rnd1( +32(%ebp), it_tab) // 12 rounds for 192-bit key 3423: inv_rnd1( -32(%ebp), crypto_it_tab) // 12 rounds for 192-bit key
346 inv_rnd2( +16(%ebp), it_tab) 343 inv_rnd2( -16(%ebp), crypto_it_tab)
3474: inv_rnd1( (%ebp), it_tab) // 10 rounds for 128-bit key 3444: inv_rnd1( (%ebp), crypto_it_tab) // 10 rounds for 128-bit key
348 inv_rnd2( -16(%ebp), it_tab) 345 inv_rnd2( +16(%ebp), crypto_it_tab)
349 inv_rnd1( -32(%ebp), it_tab) 346 inv_rnd1( +32(%ebp), crypto_it_tab)
350 inv_rnd2( -48(%ebp), it_tab) 347 inv_rnd2( +48(%ebp), crypto_it_tab)
351 inv_rnd1( -64(%ebp), it_tab) 348 inv_rnd1( +64(%ebp), crypto_it_tab)
352 inv_rnd2( -80(%ebp), it_tab) 349 inv_rnd2( +80(%ebp), crypto_it_tab)
353 inv_rnd1( -96(%ebp), it_tab) 350 inv_rnd1( +96(%ebp), crypto_it_tab)
354 inv_rnd2(-112(%ebp), it_tab) 351 inv_rnd2(+112(%ebp), crypto_it_tab)
355 inv_rnd1(-128(%ebp), it_tab) 352 inv_rnd1(+128(%ebp), crypto_it_tab)
356 inv_rnd2(-144(%ebp), il_tab) // last round uses a different table 353 inv_rnd2(+144(%ebp), crypto_il_tab) // last round uses a different table
357 354
358// move final values to the output array. CAUTION: the 355// move final values to the output array. CAUTION: the
359// order of these assigns rely on the register mappings 356// order of these assigns rely on the register mappings
diff --git a/arch/x86/crypto/aes-x86_64-asm_64.S b/arch/x86/crypto/aes-x86_64-asm_64.S
index 26b40de4d0b0..a120f526c3df 100644
--- a/arch/x86/crypto/aes-x86_64-asm_64.S
+++ b/arch/x86/crypto/aes-x86_64-asm_64.S
@@ -8,10 +8,10 @@
8 * including this sentence is retained in full. 8 * including this sentence is retained in full.
9 */ 9 */
10 10
11.extern aes_ft_tab 11.extern crypto_ft_tab
12.extern aes_it_tab 12.extern crypto_it_tab
13.extern aes_fl_tab 13.extern crypto_fl_tab
14.extern aes_il_tab 14.extern crypto_il_tab
15 15
16.text 16.text
17 17
@@ -56,13 +56,13 @@
56 .align 8; \ 56 .align 8; \
57FUNC: movq r1,r2; \ 57FUNC: movq r1,r2; \
58 movq r3,r4; \ 58 movq r3,r4; \
59 leaq BASE+KEY+52(r8),r9; \ 59 leaq BASE+KEY+48+4(r8),r9; \
60 movq r10,r11; \ 60 movq r10,r11; \
61 movl (r7),r5 ## E; \ 61 movl (r7),r5 ## E; \
62 movl 4(r7),r1 ## E; \ 62 movl 4(r7),r1 ## E; \
63 movl 8(r7),r6 ## E; \ 63 movl 8(r7),r6 ## E; \
64 movl 12(r7),r7 ## E; \ 64 movl 12(r7),r7 ## E; \
65 movl BASE(r8),r10 ## E; \ 65 movl BASE+0(r8),r10 ## E; \
66 xorl -48(r9),r5 ## E; \ 66 xorl -48(r9),r5 ## E; \
67 xorl -44(r9),r1 ## E; \ 67 xorl -44(r9),r1 ## E; \
68 xorl -40(r9),r6 ## E; \ 68 xorl -40(r9),r6 ## E; \
@@ -154,37 +154,37 @@ FUNC: movq r1,r2; \
154/* void aes_enc_blk(stuct crypto_tfm *tfm, u8 *out, const u8 *in) */ 154/* void aes_enc_blk(stuct crypto_tfm *tfm, u8 *out, const u8 *in) */
155 155
156 entry(aes_enc_blk,0,enc128,enc192) 156 entry(aes_enc_blk,0,enc128,enc192)
157 encrypt_round(aes_ft_tab,-96) 157 encrypt_round(crypto_ft_tab,-96)
158 encrypt_round(aes_ft_tab,-80) 158 encrypt_round(crypto_ft_tab,-80)
159enc192: encrypt_round(aes_ft_tab,-64) 159enc192: encrypt_round(crypto_ft_tab,-64)
160 encrypt_round(aes_ft_tab,-48) 160 encrypt_round(crypto_ft_tab,-48)
161enc128: encrypt_round(aes_ft_tab,-32) 161enc128: encrypt_round(crypto_ft_tab,-32)
162 encrypt_round(aes_ft_tab,-16) 162 encrypt_round(crypto_ft_tab,-16)
163 encrypt_round(aes_ft_tab, 0) 163 encrypt_round(crypto_ft_tab, 0)
164 encrypt_round(aes_ft_tab, 16) 164 encrypt_round(crypto_ft_tab, 16)
165 encrypt_round(aes_ft_tab, 32) 165 encrypt_round(crypto_ft_tab, 32)
166 encrypt_round(aes_ft_tab, 48) 166 encrypt_round(crypto_ft_tab, 48)
167 encrypt_round(aes_ft_tab, 64) 167 encrypt_round(crypto_ft_tab, 64)
168 encrypt_round(aes_ft_tab, 80) 168 encrypt_round(crypto_ft_tab, 80)
169 encrypt_round(aes_ft_tab, 96) 169 encrypt_round(crypto_ft_tab, 96)
170 encrypt_final(aes_fl_tab,112) 170 encrypt_final(crypto_fl_tab,112)
171 return 171 return
172 172
173/* void aes_dec_blk(struct crypto_tfm *tfm, u8 *out, const u8 *in) */ 173/* void aes_dec_blk(struct crypto_tfm *tfm, u8 *out, const u8 *in) */
174 174
175 entry(aes_dec_blk,240,dec128,dec192) 175 entry(aes_dec_blk,240,dec128,dec192)
176 decrypt_round(aes_it_tab,-96) 176 decrypt_round(crypto_it_tab,-96)
177 decrypt_round(aes_it_tab,-80) 177 decrypt_round(crypto_it_tab,-80)
178dec192: decrypt_round(aes_it_tab,-64) 178dec192: decrypt_round(crypto_it_tab,-64)
179 decrypt_round(aes_it_tab,-48) 179 decrypt_round(crypto_it_tab,-48)
180dec128: decrypt_round(aes_it_tab,-32) 180dec128: decrypt_round(crypto_it_tab,-32)
181 decrypt_round(aes_it_tab,-16) 181 decrypt_round(crypto_it_tab,-16)
182 decrypt_round(aes_it_tab, 0) 182 decrypt_round(crypto_it_tab, 0)
183 decrypt_round(aes_it_tab, 16) 183 decrypt_round(crypto_it_tab, 16)
184 decrypt_round(aes_it_tab, 32) 184 decrypt_round(crypto_it_tab, 32)
185 decrypt_round(aes_it_tab, 48) 185 decrypt_round(crypto_it_tab, 48)
186 decrypt_round(aes_it_tab, 64) 186 decrypt_round(crypto_it_tab, 64)
187 decrypt_round(aes_it_tab, 80) 187 decrypt_round(crypto_it_tab, 80)
188 decrypt_round(aes_it_tab, 96) 188 decrypt_round(crypto_it_tab, 96)
189 decrypt_final(aes_il_tab,112) 189 decrypt_final(crypto_il_tab,112)
190 return 190 return
diff --git a/arch/x86/crypto/aes_32.c b/arch/x86/crypto/aes_32.c
deleted file mode 100644
index 49aad9397f10..000000000000
--- a/arch/x86/crypto/aes_32.c
+++ /dev/null
@@ -1,515 +0,0 @@
1/*
2 *
3 * Glue Code for optimized 586 assembler version of AES
4 *
5 * Copyright (c) 2002, Dr Brian Gladman <>, Worcester, UK.
6 * All rights reserved.
7 *
8 * LICENSE TERMS
9 *
10 * The free distribution and use of this software in both source and binary
11 * form is allowed (with or without changes) provided that:
12 *
13 * 1. distributions of this source code include the above copyright
14 * notice, this list of conditions and the following disclaimer;
15 *
16 * 2. distributions in binary form include the above copyright
17 * notice, this list of conditions and the following disclaimer
18 * in the documentation and/or other associated materials;
19 *
20 * 3. the copyright holder's name is not used to endorse products
21 * built using this software without specific written permission.
22 *
23 * ALTERNATIVELY, provided that this notice is retained in full, this product
24 * may be distributed under the terms of the GNU General Public License (GPL),
25 * in which case the provisions of the GPL apply INSTEAD OF those given above.
26 *
27 * DISCLAIMER
28 *
29 * This software is provided 'as is' with no explicit or implied warranties
30 * in respect of its properties, including, but not limited to, correctness
31 * and/or fitness for purpose.
32 *
33 * Copyright (c) 2003, Adam J. Richter <adam@yggdrasil.com> (conversion to
34 * 2.5 API).
35 * Copyright (c) 2003, 2004 Fruhwirth Clemens <clemens@endorphin.org>
36 * Copyright (c) 2004 Red Hat, Inc., James Morris <jmorris@redhat.com>
37 *
38 */
39
40#include <asm/byteorder.h>
41#include <linux/kernel.h>
42#include <linux/module.h>
43#include <linux/init.h>
44#include <linux/types.h>
45#include <linux/crypto.h>
46#include <linux/linkage.h>
47
48asmlinkage void aes_enc_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
49asmlinkage void aes_dec_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
50
51#define AES_MIN_KEY_SIZE 16
52#define AES_MAX_KEY_SIZE 32
53#define AES_BLOCK_SIZE 16
54#define AES_KS_LENGTH 4 * AES_BLOCK_SIZE
55#define RC_LENGTH 29
56
57struct aes_ctx {
58 u32 ekey[AES_KS_LENGTH];
59 u32 rounds;
60 u32 dkey[AES_KS_LENGTH];
61};
62
63#define WPOLY 0x011b
64#define bytes2word(b0, b1, b2, b3) \
65 (((u32)(b3) << 24) | ((u32)(b2) << 16) | ((u32)(b1) << 8) | (b0))
66
67/* define the finite field multiplies required for Rijndael */
68#define f2(x) ((x) ? pow[log[x] + 0x19] : 0)
69#define f3(x) ((x) ? pow[log[x] + 0x01] : 0)
70#define f9(x) ((x) ? pow[log[x] + 0xc7] : 0)
71#define fb(x) ((x) ? pow[log[x] + 0x68] : 0)
72#define fd(x) ((x) ? pow[log[x] + 0xee] : 0)
73#define fe(x) ((x) ? pow[log[x] + 0xdf] : 0)
74#define fi(x) ((x) ? pow[255 - log[x]]: 0)
75
76static inline u32 upr(u32 x, int n)
77{
78 return (x << 8 * n) | (x >> (32 - 8 * n));
79}
80
81static inline u8 bval(u32 x, int n)
82{
83 return x >> 8 * n;
84}
85
86/* The forward and inverse affine transformations used in the S-box */
87#define fwd_affine(x) \
88 (w = (u32)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(u8)(w^(w>>8)))
89
90#define inv_affine(x) \
91 (w = (u32)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(u8)(w^(w>>8)))
92
93static u32 rcon_tab[RC_LENGTH];
94
95u32 ft_tab[4][256];
96u32 fl_tab[4][256];
97static u32 im_tab[4][256];
98u32 il_tab[4][256];
99u32 it_tab[4][256];
100
101static void gen_tabs(void)
102{
103 u32 i, w;
104 u8 pow[512], log[256];
105
106 /*
107 * log and power tables for GF(2^8) finite field with
108 * WPOLY as modular polynomial - the simplest primitive
109 * root is 0x03, used here to generate the tables.
110 */
111 i = 0; w = 1;
112
113 do {
114 pow[i] = (u8)w;
115 pow[i + 255] = (u8)w;
116 log[w] = (u8)i++;
117 w ^= (w << 1) ^ (w & 0x80 ? WPOLY : 0);
118 } while (w != 1);
119
120 for(i = 0, w = 1; i < RC_LENGTH; ++i) {
121 rcon_tab[i] = bytes2word(w, 0, 0, 0);
122 w = f2(w);
123 }
124
125 for(i = 0; i < 256; ++i) {
126 u8 b;
127
128 b = fwd_affine(fi((u8)i));
129 w = bytes2word(f2(b), b, b, f3(b));
130
131 /* tables for a normal encryption round */
132 ft_tab[0][i] = w;
133 ft_tab[1][i] = upr(w, 1);
134 ft_tab[2][i] = upr(w, 2);
135 ft_tab[3][i] = upr(w, 3);
136 w = bytes2word(b, 0, 0, 0);
137
138 /*
139 * tables for last encryption round
140 * (may also be used in the key schedule)
141 */
142 fl_tab[0][i] = w;
143 fl_tab[1][i] = upr(w, 1);
144 fl_tab[2][i] = upr(w, 2);
145 fl_tab[3][i] = upr(w, 3);
146
147 b = fi(inv_affine((u8)i));
148 w = bytes2word(fe(b), f9(b), fd(b), fb(b));
149
150 /* tables for the inverse mix column operation */
151 im_tab[0][b] = w;
152 im_tab[1][b] = upr(w, 1);
153 im_tab[2][b] = upr(w, 2);
154 im_tab[3][b] = upr(w, 3);
155
156 /* tables for a normal decryption round */
157 it_tab[0][i] = w;
158 it_tab[1][i] = upr(w,1);
159 it_tab[2][i] = upr(w,2);
160 it_tab[3][i] = upr(w,3);
161
162 w = bytes2word(b, 0, 0, 0);
163
164 /* tables for last decryption round */
165 il_tab[0][i] = w;
166 il_tab[1][i] = upr(w,1);
167 il_tab[2][i] = upr(w,2);
168 il_tab[3][i] = upr(w,3);
169 }
170}
171
172#define four_tables(x,tab,vf,rf,c) \
173( tab[0][bval(vf(x,0,c),rf(0,c))] ^ \
174 tab[1][bval(vf(x,1,c),rf(1,c))] ^ \
175 tab[2][bval(vf(x,2,c),rf(2,c))] ^ \
176 tab[3][bval(vf(x,3,c),rf(3,c))] \
177)
178
179#define vf1(x,r,c) (x)
180#define rf1(r,c) (r)
181#define rf2(r,c) ((r-c)&3)
182
183#define inv_mcol(x) four_tables(x,im_tab,vf1,rf1,0)
184#define ls_box(x,c) four_tables(x,fl_tab,vf1,rf2,c)
185
186#define ff(x) inv_mcol(x)
187
188#define ke4(k,i) \
189{ \
190 k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; \
191 k[4*(i)+5] = ss[1] ^= ss[0]; \
192 k[4*(i)+6] = ss[2] ^= ss[1]; \
193 k[4*(i)+7] = ss[3] ^= ss[2]; \
194}
195
196#define kel4(k,i) \
197{ \
198 k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; \
199 k[4*(i)+5] = ss[1] ^= ss[0]; \
200 k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2]; \
201}
202
203#define ke6(k,i) \
204{ \
205 k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; \
206 k[6*(i)+ 7] = ss[1] ^= ss[0]; \
207 k[6*(i)+ 8] = ss[2] ^= ss[1]; \
208 k[6*(i)+ 9] = ss[3] ^= ss[2]; \
209 k[6*(i)+10] = ss[4] ^= ss[3]; \
210 k[6*(i)+11] = ss[5] ^= ss[4]; \
211}
212
213#define kel6(k,i) \
214{ \
215 k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; \
216 k[6*(i)+ 7] = ss[1] ^= ss[0]; \
217 k[6*(i)+ 8] = ss[2] ^= ss[1]; \
218 k[6*(i)+ 9] = ss[3] ^= ss[2]; \
219}
220
221#define ke8(k,i) \
222{ \
223 k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; \
224 k[8*(i)+ 9] = ss[1] ^= ss[0]; \
225 k[8*(i)+10] = ss[2] ^= ss[1]; \
226 k[8*(i)+11] = ss[3] ^= ss[2]; \
227 k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); \
228 k[8*(i)+13] = ss[5] ^= ss[4]; \
229 k[8*(i)+14] = ss[6] ^= ss[5]; \
230 k[8*(i)+15] = ss[7] ^= ss[6]; \
231}
232
233#define kel8(k,i) \
234{ \
235 k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; \
236 k[8*(i)+ 9] = ss[1] ^= ss[0]; \
237 k[8*(i)+10] = ss[2] ^= ss[1]; \
238 k[8*(i)+11] = ss[3] ^= ss[2]; \
239}
240
241#define kdf4(k,i) \
242{ \
243 ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; \
244 ss[1] = ss[1] ^ ss[3]; \
245 ss[2] = ss[2] ^ ss[3]; \
246 ss[3] = ss[3]; \
247 ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i]; \
248 ss[i % 4] ^= ss[4]; \
249 ss[4] ^= k[4*(i)]; \
250 k[4*(i)+4] = ff(ss[4]); \
251 ss[4] ^= k[4*(i)+1]; \
252 k[4*(i)+5] = ff(ss[4]); \
253 ss[4] ^= k[4*(i)+2]; \
254 k[4*(i)+6] = ff(ss[4]); \
255 ss[4] ^= k[4*(i)+3]; \
256 k[4*(i)+7] = ff(ss[4]); \
257}
258
259#define kd4(k,i) \
260{ \
261 ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i]; \
262 ss[i % 4] ^= ss[4]; \
263 ss[4] = ff(ss[4]); \
264 k[4*(i)+4] = ss[4] ^= k[4*(i)]; \
265 k[4*(i)+5] = ss[4] ^= k[4*(i)+1]; \
266 k[4*(i)+6] = ss[4] ^= k[4*(i)+2]; \
267 k[4*(i)+7] = ss[4] ^= k[4*(i)+3]; \
268}
269
270#define kdl4(k,i) \
271{ \
272 ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i]; \
273 ss[i % 4] ^= ss[4]; \
274 k[4*(i)+4] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; \
275 k[4*(i)+5] = ss[1] ^ ss[3]; \
276 k[4*(i)+6] = ss[0]; \
277 k[4*(i)+7] = ss[1]; \
278}
279
280#define kdf6(k,i) \
281{ \
282 ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; \
283 k[6*(i)+ 6] = ff(ss[0]); \
284 ss[1] ^= ss[0]; \
285 k[6*(i)+ 7] = ff(ss[1]); \
286 ss[2] ^= ss[1]; \
287 k[6*(i)+ 8] = ff(ss[2]); \
288 ss[3] ^= ss[2]; \
289 k[6*(i)+ 9] = ff(ss[3]); \
290 ss[4] ^= ss[3]; \
291 k[6*(i)+10] = ff(ss[4]); \
292 ss[5] ^= ss[4]; \
293 k[6*(i)+11] = ff(ss[5]); \
294}
295
296#define kd6(k,i) \
297{ \
298 ss[6] = ls_box(ss[5],3) ^ rcon_tab[i]; \
299 ss[0] ^= ss[6]; ss[6] = ff(ss[6]); \
300 k[6*(i)+ 6] = ss[6] ^= k[6*(i)]; \
301 ss[1] ^= ss[0]; \
302 k[6*(i)+ 7] = ss[6] ^= k[6*(i)+ 1]; \
303 ss[2] ^= ss[1]; \
304 k[6*(i)+ 8] = ss[6] ^= k[6*(i)+ 2]; \
305 ss[3] ^= ss[2]; \
306 k[6*(i)+ 9] = ss[6] ^= k[6*(i)+ 3]; \
307 ss[4] ^= ss[3]; \
308 k[6*(i)+10] = ss[6] ^= k[6*(i)+ 4]; \
309 ss[5] ^= ss[4]; \
310 k[6*(i)+11] = ss[6] ^= k[6*(i)+ 5]; \
311}
312
313#define kdl6(k,i) \
314{ \
315 ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; \
316 k[6*(i)+ 6] = ss[0]; \
317 ss[1] ^= ss[0]; \
318 k[6*(i)+ 7] = ss[1]; \
319 ss[2] ^= ss[1]; \
320 k[6*(i)+ 8] = ss[2]; \
321 ss[3] ^= ss[2]; \
322 k[6*(i)+ 9] = ss[3]; \
323}
324
325#define kdf8(k,i) \
326{ \
327 ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; \
328 k[8*(i)+ 8] = ff(ss[0]); \
329 ss[1] ^= ss[0]; \
330 k[8*(i)+ 9] = ff(ss[1]); \
331 ss[2] ^= ss[1]; \
332 k[8*(i)+10] = ff(ss[2]); \
333 ss[3] ^= ss[2]; \
334 k[8*(i)+11] = ff(ss[3]); \
335 ss[4] ^= ls_box(ss[3],0); \
336 k[8*(i)+12] = ff(ss[4]); \
337 ss[5] ^= ss[4]; \
338 k[8*(i)+13] = ff(ss[5]); \
339 ss[6] ^= ss[5]; \
340 k[8*(i)+14] = ff(ss[6]); \
341 ss[7] ^= ss[6]; \
342 k[8*(i)+15] = ff(ss[7]); \
343}
344
345#define kd8(k,i) \
346{ \
347 u32 __g = ls_box(ss[7],3) ^ rcon_tab[i]; \
348 ss[0] ^= __g; \
349 __g = ff(__g); \
350 k[8*(i)+ 8] = __g ^= k[8*(i)]; \
351 ss[1] ^= ss[0]; \
352 k[8*(i)+ 9] = __g ^= k[8*(i)+ 1]; \
353 ss[2] ^= ss[1]; \
354 k[8*(i)+10] = __g ^= k[8*(i)+ 2]; \
355 ss[3] ^= ss[2]; \
356 k[8*(i)+11] = __g ^= k[8*(i)+ 3]; \
357 __g = ls_box(ss[3],0); \
358 ss[4] ^= __g; \
359 __g = ff(__g); \
360 k[8*(i)+12] = __g ^= k[8*(i)+ 4]; \
361 ss[5] ^= ss[4]; \
362 k[8*(i)+13] = __g ^= k[8*(i)+ 5]; \
363 ss[6] ^= ss[5]; \
364 k[8*(i)+14] = __g ^= k[8*(i)+ 6]; \
365 ss[7] ^= ss[6]; \
366 k[8*(i)+15] = __g ^= k[8*(i)+ 7]; \
367}
368
369#define kdl8(k,i) \
370{ \
371 ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; \
372 k[8*(i)+ 8] = ss[0]; \
373 ss[1] ^= ss[0]; \
374 k[8*(i)+ 9] = ss[1]; \
375 ss[2] ^= ss[1]; \
376 k[8*(i)+10] = ss[2]; \
377 ss[3] ^= ss[2]; \
378 k[8*(i)+11] = ss[3]; \
379}
380
381static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
382 unsigned int key_len)
383{
384 int i;
385 u32 ss[8];
386 struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
387 const __le32 *key = (const __le32 *)in_key;
388 u32 *flags = &tfm->crt_flags;
389
390 /* encryption schedule */
391
392 ctx->ekey[0] = ss[0] = le32_to_cpu(key[0]);
393 ctx->ekey[1] = ss[1] = le32_to_cpu(key[1]);
394 ctx->ekey[2] = ss[2] = le32_to_cpu(key[2]);
395 ctx->ekey[3] = ss[3] = le32_to_cpu(key[3]);
396
397 switch(key_len) {
398 case 16:
399 for (i = 0; i < 9; i++)
400 ke4(ctx->ekey, i);
401 kel4(ctx->ekey, 9);
402 ctx->rounds = 10;
403 break;
404
405 case 24:
406 ctx->ekey[4] = ss[4] = le32_to_cpu(key[4]);
407 ctx->ekey[5] = ss[5] = le32_to_cpu(key[5]);
408 for (i = 0; i < 7; i++)
409 ke6(ctx->ekey, i);
410 kel6(ctx->ekey, 7);
411 ctx->rounds = 12;
412 break;
413
414 case 32:
415 ctx->ekey[4] = ss[4] = le32_to_cpu(key[4]);
416 ctx->ekey[5] = ss[5] = le32_to_cpu(key[5]);
417 ctx->ekey[6] = ss[6] = le32_to_cpu(key[6]);
418 ctx->ekey[7] = ss[7] = le32_to_cpu(key[7]);
419 for (i = 0; i < 6; i++)
420 ke8(ctx->ekey, i);
421 kel8(ctx->ekey, 6);
422 ctx->rounds = 14;
423 break;
424
425 default:
426 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
427 return -EINVAL;
428 }
429
430 /* decryption schedule */
431
432 ctx->dkey[0] = ss[0] = le32_to_cpu(key[0]);
433 ctx->dkey[1] = ss[1] = le32_to_cpu(key[1]);
434 ctx->dkey[2] = ss[2] = le32_to_cpu(key[2]);
435 ctx->dkey[3] = ss[3] = le32_to_cpu(key[3]);
436
437 switch (key_len) {
438 case 16:
439 kdf4(ctx->dkey, 0);
440 for (i = 1; i < 9; i++)
441 kd4(ctx->dkey, i);
442 kdl4(ctx->dkey, 9);
443 break;
444
445 case 24:
446 ctx->dkey[4] = ff(ss[4] = le32_to_cpu(key[4]));
447 ctx->dkey[5] = ff(ss[5] = le32_to_cpu(key[5]));
448 kdf6(ctx->dkey, 0);
449 for (i = 1; i < 7; i++)
450 kd6(ctx->dkey, i);
451 kdl6(ctx->dkey, 7);
452 break;
453
454 case 32:
455 ctx->dkey[4] = ff(ss[4] = le32_to_cpu(key[4]));
456 ctx->dkey[5] = ff(ss[5] = le32_to_cpu(key[5]));
457 ctx->dkey[6] = ff(ss[6] = le32_to_cpu(key[6]));
458 ctx->dkey[7] = ff(ss[7] = le32_to_cpu(key[7]));
459 kdf8(ctx->dkey, 0);
460 for (i = 1; i < 6; i++)
461 kd8(ctx->dkey, i);
462 kdl8(ctx->dkey, 6);
463 break;
464 }
465 return 0;
466}
467
468static void aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
469{
470 aes_enc_blk(tfm, dst, src);
471}
472
473static void aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
474{
475 aes_dec_blk(tfm, dst, src);
476}
477
478static struct crypto_alg aes_alg = {
479 .cra_name = "aes",
480 .cra_driver_name = "aes-i586",
481 .cra_priority = 200,
482 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
483 .cra_blocksize = AES_BLOCK_SIZE,
484 .cra_ctxsize = sizeof(struct aes_ctx),
485 .cra_module = THIS_MODULE,
486 .cra_list = LIST_HEAD_INIT(aes_alg.cra_list),
487 .cra_u = {
488 .cipher = {
489 .cia_min_keysize = AES_MIN_KEY_SIZE,
490 .cia_max_keysize = AES_MAX_KEY_SIZE,
491 .cia_setkey = aes_set_key,
492 .cia_encrypt = aes_encrypt,
493 .cia_decrypt = aes_decrypt
494 }
495 }
496};
497
498static int __init aes_init(void)
499{
500 gen_tabs();
501 return crypto_register_alg(&aes_alg);
502}
503
504static void __exit aes_fini(void)
505{
506 crypto_unregister_alg(&aes_alg);
507}
508
509module_init(aes_init);
510module_exit(aes_fini);
511
512MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm, i586 asm optimized");
513MODULE_LICENSE("Dual BSD/GPL");
514MODULE_AUTHOR("Fruhwirth Clemens, James Morris, Brian Gladman, Adam Richter");
515MODULE_ALIAS("aes");
diff --git a/arch/x86/crypto/aes_64.c b/arch/x86/crypto/aes_64.c
deleted file mode 100644
index 5cdb13ea5cc2..000000000000
--- a/arch/x86/crypto/aes_64.c
+++ /dev/null
@@ -1,336 +0,0 @@
1/*
2 * Cryptographic API.
3 *
4 * AES Cipher Algorithm.
5 *
6 * Based on Brian Gladman's code.
7 *
8 * Linux developers:
9 * Alexander Kjeldaas <astor@fast.no>
10 * Herbert Valerio Riedel <hvr@hvrlab.org>
11 * Kyle McMartin <kyle@debian.org>
12 * Adam J. Richter <adam@yggdrasil.com> (conversion to 2.5 API).
13 * Andreas Steinmetz <ast@domdv.de> (adapted to x86_64 assembler)
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * ---------------------------------------------------------------------------
21 * Copyright (c) 2002, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK.
22 * All rights reserved.
23 *
24 * LICENSE TERMS
25 *
26 * The free distribution and use of this software in both source and binary
27 * form is allowed (with or without changes) provided that:
28 *
29 * 1. distributions of this source code include the above copyright
30 * notice, this list of conditions and the following disclaimer;
31 *
32 * 2. distributions in binary form include the above copyright
33 * notice, this list of conditions and the following disclaimer
34 * in the documentation and/or other associated materials;
35 *
36 * 3. the copyright holder's name is not used to endorse products
37 * built using this software without specific written permission.
38 *
39 * ALTERNATIVELY, provided that this notice is retained in full, this product
40 * may be distributed under the terms of the GNU General Public License (GPL),
41 * in which case the provisions of the GPL apply INSTEAD OF those given above.
42 *
43 * DISCLAIMER
44 *
45 * This software is provided 'as is' with no explicit or implied warranties
46 * in respect of its properties, including, but not limited to, correctness
47 * and/or fitness for purpose.
48 * ---------------------------------------------------------------------------
49 */
50
51/* Some changes from the Gladman version:
52 s/RIJNDAEL(e_key)/E_KEY/g
53 s/RIJNDAEL(d_key)/D_KEY/g
54*/
55
56#include <asm/byteorder.h>
57#include <linux/bitops.h>
58#include <linux/crypto.h>
59#include <linux/errno.h>
60#include <linux/init.h>
61#include <linux/module.h>
62#include <linux/types.h>
63
64#define AES_MIN_KEY_SIZE 16
65#define AES_MAX_KEY_SIZE 32
66
67#define AES_BLOCK_SIZE 16
68
69/*
70 * #define byte(x, nr) ((unsigned char)((x) >> (nr*8)))
71 */
72static inline u8 byte(const u32 x, const unsigned n)
73{
74 return x >> (n << 3);
75}
76
77struct aes_ctx
78{
79 u32 key_length;
80 u32 buf[120];
81};
82
83#define E_KEY (&ctx->buf[0])
84#define D_KEY (&ctx->buf[60])
85
86static u8 pow_tab[256] __initdata;
87static u8 log_tab[256] __initdata;
88static u8 sbx_tab[256] __initdata;
89static u8 isb_tab[256] __initdata;
90static u32 rco_tab[10];
91u32 aes_ft_tab[4][256];
92u32 aes_it_tab[4][256];
93
94u32 aes_fl_tab[4][256];
95u32 aes_il_tab[4][256];
96
97static inline u8 f_mult(u8 a, u8 b)
98{
99 u8 aa = log_tab[a], cc = aa + log_tab[b];
100
101 return pow_tab[cc + (cc < aa ? 1 : 0)];
102}
103
104#define ff_mult(a, b) (a && b ? f_mult(a, b) : 0)
105
106#define ls_box(x) \
107 (aes_fl_tab[0][byte(x, 0)] ^ \
108 aes_fl_tab[1][byte(x, 1)] ^ \
109 aes_fl_tab[2][byte(x, 2)] ^ \
110 aes_fl_tab[3][byte(x, 3)])
111
112static void __init gen_tabs(void)
113{
114 u32 i, t;
115 u8 p, q;
116
117 /* log and power tables for GF(2**8) finite field with
118 0x011b as modular polynomial - the simplest primitive
119 root is 0x03, used here to generate the tables */
120
121 for (i = 0, p = 1; i < 256; ++i) {
122 pow_tab[i] = (u8)p;
123 log_tab[p] = (u8)i;
124
125 p ^= (p << 1) ^ (p & 0x80 ? 0x01b : 0);
126 }
127
128 log_tab[1] = 0;
129
130 for (i = 0, p = 1; i < 10; ++i) {
131 rco_tab[i] = p;
132
133 p = (p << 1) ^ (p & 0x80 ? 0x01b : 0);
134 }
135
136 for (i = 0; i < 256; ++i) {
137 p = (i ? pow_tab[255 - log_tab[i]] : 0);
138 q = ((p >> 7) | (p << 1)) ^ ((p >> 6) | (p << 2));
139 p ^= 0x63 ^ q ^ ((q >> 6) | (q << 2));
140 sbx_tab[i] = p;
141 isb_tab[p] = (u8)i;
142 }
143
144 for (i = 0; i < 256; ++i) {
145 p = sbx_tab[i];
146
147 t = p;
148 aes_fl_tab[0][i] = t;
149 aes_fl_tab[1][i] = rol32(t, 8);
150 aes_fl_tab[2][i] = rol32(t, 16);
151 aes_fl_tab[3][i] = rol32(t, 24);
152
153 t = ((u32)ff_mult(2, p)) |
154 ((u32)p << 8) |
155 ((u32)p << 16) | ((u32)ff_mult(3, p) << 24);
156
157 aes_ft_tab[0][i] = t;
158 aes_ft_tab[1][i] = rol32(t, 8);
159 aes_ft_tab[2][i] = rol32(t, 16);
160 aes_ft_tab[3][i] = rol32(t, 24);
161
162 p = isb_tab[i];
163
164 t = p;
165 aes_il_tab[0][i] = t;
166 aes_il_tab[1][i] = rol32(t, 8);
167 aes_il_tab[2][i] = rol32(t, 16);
168 aes_il_tab[3][i] = rol32(t, 24);
169
170 t = ((u32)ff_mult(14, p)) |
171 ((u32)ff_mult(9, p) << 8) |
172 ((u32)ff_mult(13, p) << 16) |
173 ((u32)ff_mult(11, p) << 24);
174
175 aes_it_tab[0][i] = t;
176 aes_it_tab[1][i] = rol32(t, 8);
177 aes_it_tab[2][i] = rol32(t, 16);
178 aes_it_tab[3][i] = rol32(t, 24);
179 }
180}
181
182#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b)
183
184#define imix_col(y, x) \
185 u = star_x(x); \
186 v = star_x(u); \
187 w = star_x(v); \
188 t = w ^ (x); \
189 (y) = u ^ v ^ w; \
190 (y) ^= ror32(u ^ t, 8) ^ \
191 ror32(v ^ t, 16) ^ \
192 ror32(t, 24)
193
194/* initialise the key schedule from the user supplied key */
195
196#define loop4(i) \
197{ \
198 t = ror32(t, 8); t = ls_box(t) ^ rco_tab[i]; \
199 t ^= E_KEY[4 * i]; E_KEY[4 * i + 4] = t; \
200 t ^= E_KEY[4 * i + 1]; E_KEY[4 * i + 5] = t; \
201 t ^= E_KEY[4 * i + 2]; E_KEY[4 * i + 6] = t; \
202 t ^= E_KEY[4 * i + 3]; E_KEY[4 * i + 7] = t; \
203}
204
205#define loop6(i) \
206{ \
207 t = ror32(t, 8); t = ls_box(t) ^ rco_tab[i]; \
208 t ^= E_KEY[6 * i]; E_KEY[6 * i + 6] = t; \
209 t ^= E_KEY[6 * i + 1]; E_KEY[6 * i + 7] = t; \
210 t ^= E_KEY[6 * i + 2]; E_KEY[6 * i + 8] = t; \
211 t ^= E_KEY[6 * i + 3]; E_KEY[6 * i + 9] = t; \
212 t ^= E_KEY[6 * i + 4]; E_KEY[6 * i + 10] = t; \
213 t ^= E_KEY[6 * i + 5]; E_KEY[6 * i + 11] = t; \
214}
215
216#define loop8(i) \
217{ \
218 t = ror32(t, 8); ; t = ls_box(t) ^ rco_tab[i]; \
219 t ^= E_KEY[8 * i]; E_KEY[8 * i + 8] = t; \
220 t ^= E_KEY[8 * i + 1]; E_KEY[8 * i + 9] = t; \
221 t ^= E_KEY[8 * i + 2]; E_KEY[8 * i + 10] = t; \
222 t ^= E_KEY[8 * i + 3]; E_KEY[8 * i + 11] = t; \
223 t = E_KEY[8 * i + 4] ^ ls_box(t); \
224 E_KEY[8 * i + 12] = t; \
225 t ^= E_KEY[8 * i + 5]; E_KEY[8 * i + 13] = t; \
226 t ^= E_KEY[8 * i + 6]; E_KEY[8 * i + 14] = t; \
227 t ^= E_KEY[8 * i + 7]; E_KEY[8 * i + 15] = t; \
228}
229
230static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
231 unsigned int key_len)
232{
233 struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
234 const __le32 *key = (const __le32 *)in_key;
235 u32 *flags = &tfm->crt_flags;
236 u32 i, j, t, u, v, w;
237
238 if (key_len % 8) {
239 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
240 return -EINVAL;
241 }
242
243 ctx->key_length = key_len;
244
245 D_KEY[key_len + 24] = E_KEY[0] = le32_to_cpu(key[0]);
246 D_KEY[key_len + 25] = E_KEY[1] = le32_to_cpu(key[1]);
247 D_KEY[key_len + 26] = E_KEY[2] = le32_to_cpu(key[2]);
248 D_KEY[key_len + 27] = E_KEY[3] = le32_to_cpu(key[3]);
249
250 switch (key_len) {
251 case 16:
252 t = E_KEY[3];
253 for (i = 0; i < 10; ++i)
254 loop4(i);
255 break;
256
257 case 24:
258 E_KEY[4] = le32_to_cpu(key[4]);
259 t = E_KEY[5] = le32_to_cpu(key[5]);
260 for (i = 0; i < 8; ++i)
261 loop6 (i);
262 break;
263
264 case 32:
265 E_KEY[4] = le32_to_cpu(key[4]);
266 E_KEY[5] = le32_to_cpu(key[5]);
267 E_KEY[6] = le32_to_cpu(key[6]);
268 t = E_KEY[7] = le32_to_cpu(key[7]);
269 for (i = 0; i < 7; ++i)
270 loop8(i);
271 break;
272 }
273
274 D_KEY[0] = E_KEY[key_len + 24];
275 D_KEY[1] = E_KEY[key_len + 25];
276 D_KEY[2] = E_KEY[key_len + 26];
277 D_KEY[3] = E_KEY[key_len + 27];
278
279 for (i = 4; i < key_len + 24; ++i) {
280 j = key_len + 24 - (i & ~3) + (i & 3);
281 imix_col(D_KEY[j], E_KEY[i]);
282 }
283
284 return 0;
285}
286
287asmlinkage void aes_enc_blk(struct crypto_tfm *tfm, u8 *out, const u8 *in);
288asmlinkage void aes_dec_blk(struct crypto_tfm *tfm, u8 *out, const u8 *in);
289
290static void aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
291{
292 aes_enc_blk(tfm, dst, src);
293}
294
295static void aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
296{
297 aes_dec_blk(tfm, dst, src);
298}
299
300static struct crypto_alg aes_alg = {
301 .cra_name = "aes",
302 .cra_driver_name = "aes-x86_64",
303 .cra_priority = 200,
304 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
305 .cra_blocksize = AES_BLOCK_SIZE,
306 .cra_ctxsize = sizeof(struct aes_ctx),
307 .cra_module = THIS_MODULE,
308 .cra_list = LIST_HEAD_INIT(aes_alg.cra_list),
309 .cra_u = {
310 .cipher = {
311 .cia_min_keysize = AES_MIN_KEY_SIZE,
312 .cia_max_keysize = AES_MAX_KEY_SIZE,
313 .cia_setkey = aes_set_key,
314 .cia_encrypt = aes_encrypt,
315 .cia_decrypt = aes_decrypt
316 }
317 }
318};
319
320static int __init aes_init(void)
321{
322 gen_tabs();
323 return crypto_register_alg(&aes_alg);
324}
325
326static void __exit aes_fini(void)
327{
328 crypto_unregister_alg(&aes_alg);
329}
330
331module_init(aes_init);
332module_exit(aes_fini);
333
334MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm");
335MODULE_LICENSE("GPL");
336MODULE_ALIAS("aes");
diff --git a/arch/x86/crypto/aes_glue.c b/arch/x86/crypto/aes_glue.c
new file mode 100644
index 000000000000..71f457827116
--- /dev/null
+++ b/arch/x86/crypto/aes_glue.c
@@ -0,0 +1,57 @@
1/*
2 * Glue Code for the asm optimized version of the AES Cipher Algorithm
3 *
4 */
5
6#include <crypto/aes.h>
7
8asmlinkage void aes_enc_blk(struct crypto_tfm *tfm, u8 *out, const u8 *in);
9asmlinkage void aes_dec_blk(struct crypto_tfm *tfm, u8 *out, const u8 *in);
10
11static void aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
12{
13 aes_enc_blk(tfm, dst, src);
14}
15
16static void aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
17{
18 aes_dec_blk(tfm, dst, src);
19}
20
21static struct crypto_alg aes_alg = {
22 .cra_name = "aes",
23 .cra_driver_name = "aes-asm",
24 .cra_priority = 200,
25 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
26 .cra_blocksize = AES_BLOCK_SIZE,
27 .cra_ctxsize = sizeof(struct crypto_aes_ctx),
28 .cra_module = THIS_MODULE,
29 .cra_list = LIST_HEAD_INIT(aes_alg.cra_list),
30 .cra_u = {
31 .cipher = {
32 .cia_min_keysize = AES_MIN_KEY_SIZE,
33 .cia_max_keysize = AES_MAX_KEY_SIZE,
34 .cia_setkey = crypto_aes_set_key,
35 .cia_encrypt = aes_encrypt,
36 .cia_decrypt = aes_decrypt
37 }
38 }
39};
40
41static int __init aes_init(void)
42{
43 return crypto_register_alg(&aes_alg);
44}
45
46static void __exit aes_fini(void)
47{
48 crypto_unregister_alg(&aes_alg);
49}
50
51module_init(aes_init);
52module_exit(aes_fini);
53
54MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm, asm optimized");
55MODULE_LICENSE("GPL");
56MODULE_ALIAS("aes");
57MODULE_ALIAS("aes-asm");
diff --git a/arch/x86/crypto/salsa20-i586-asm_32.S b/arch/x86/crypto/salsa20-i586-asm_32.S
new file mode 100644
index 000000000000..72eb306680b2
--- /dev/null
+++ b/arch/x86/crypto/salsa20-i586-asm_32.S
@@ -0,0 +1,1114 @@
1# salsa20_pm.s version 20051229
2# D. J. Bernstein
3# Public domain.
4
5# enter ECRYPT_encrypt_bytes
6.text
7.p2align 5
8.globl ECRYPT_encrypt_bytes
9ECRYPT_encrypt_bytes:
10 mov %esp,%eax
11 and $31,%eax
12 add $256,%eax
13 sub %eax,%esp
14 # eax_stack = eax
15 movl %eax,80(%esp)
16 # ebx_stack = ebx
17 movl %ebx,84(%esp)
18 # esi_stack = esi
19 movl %esi,88(%esp)
20 # edi_stack = edi
21 movl %edi,92(%esp)
22 # ebp_stack = ebp
23 movl %ebp,96(%esp)
24 # x = arg1
25 movl 4(%esp,%eax),%edx
26 # m = arg2
27 movl 8(%esp,%eax),%esi
28 # out = arg3
29 movl 12(%esp,%eax),%edi
30 # bytes = arg4
31 movl 16(%esp,%eax),%ebx
32 # bytes -= 0
33 sub $0,%ebx
34 # goto done if unsigned<=
35 jbe ._done
36._start:
37 # in0 = *(uint32 *) (x + 0)
38 movl 0(%edx),%eax
39 # in1 = *(uint32 *) (x + 4)
40 movl 4(%edx),%ecx
41 # in2 = *(uint32 *) (x + 8)
42 movl 8(%edx),%ebp
43 # j0 = in0
44 movl %eax,164(%esp)
45 # in3 = *(uint32 *) (x + 12)
46 movl 12(%edx),%eax
47 # j1 = in1
48 movl %ecx,168(%esp)
49 # in4 = *(uint32 *) (x + 16)
50 movl 16(%edx),%ecx
51 # j2 = in2
52 movl %ebp,172(%esp)
53 # in5 = *(uint32 *) (x + 20)
54 movl 20(%edx),%ebp
55 # j3 = in3
56 movl %eax,176(%esp)
57 # in6 = *(uint32 *) (x + 24)
58 movl 24(%edx),%eax
59 # j4 = in4
60 movl %ecx,180(%esp)
61 # in7 = *(uint32 *) (x + 28)
62 movl 28(%edx),%ecx
63 # j5 = in5
64 movl %ebp,184(%esp)
65 # in8 = *(uint32 *) (x + 32)
66 movl 32(%edx),%ebp
67 # j6 = in6
68 movl %eax,188(%esp)
69 # in9 = *(uint32 *) (x + 36)
70 movl 36(%edx),%eax
71 # j7 = in7
72 movl %ecx,192(%esp)
73 # in10 = *(uint32 *) (x + 40)
74 movl 40(%edx),%ecx
75 # j8 = in8
76 movl %ebp,196(%esp)
77 # in11 = *(uint32 *) (x + 44)
78 movl 44(%edx),%ebp
79 # j9 = in9
80 movl %eax,200(%esp)
81 # in12 = *(uint32 *) (x + 48)
82 movl 48(%edx),%eax
83 # j10 = in10
84 movl %ecx,204(%esp)
85 # in13 = *(uint32 *) (x + 52)
86 movl 52(%edx),%ecx
87 # j11 = in11
88 movl %ebp,208(%esp)
89 # in14 = *(uint32 *) (x + 56)
90 movl 56(%edx),%ebp
91 # j12 = in12
92 movl %eax,212(%esp)
93 # in15 = *(uint32 *) (x + 60)
94 movl 60(%edx),%eax
95 # j13 = in13
96 movl %ecx,216(%esp)
97 # j14 = in14
98 movl %ebp,220(%esp)
99 # j15 = in15
100 movl %eax,224(%esp)
101 # x_backup = x
102 movl %edx,64(%esp)
103._bytesatleast1:
104 # bytes - 64
105 cmp $64,%ebx
106 # goto nocopy if unsigned>=
107 jae ._nocopy
108 # ctarget = out
109 movl %edi,228(%esp)
110 # out = &tmp
111 leal 0(%esp),%edi
112 # i = bytes
113 mov %ebx,%ecx
114 # while (i) { *out++ = *m++; --i }
115 rep movsb
116 # out = &tmp
117 leal 0(%esp),%edi
118 # m = &tmp
119 leal 0(%esp),%esi
120._nocopy:
121 # out_backup = out
122 movl %edi,72(%esp)
123 # m_backup = m
124 movl %esi,68(%esp)
125 # bytes_backup = bytes
126 movl %ebx,76(%esp)
127 # in0 = j0
128 movl 164(%esp),%eax
129 # in1 = j1
130 movl 168(%esp),%ecx
131 # in2 = j2
132 movl 172(%esp),%edx
133 # in3 = j3
134 movl 176(%esp),%ebx
135 # x0 = in0
136 movl %eax,100(%esp)
137 # x1 = in1
138 movl %ecx,104(%esp)
139 # x2 = in2
140 movl %edx,108(%esp)
141 # x3 = in3
142 movl %ebx,112(%esp)
143 # in4 = j4
144 movl 180(%esp),%eax
145 # in5 = j5
146 movl 184(%esp),%ecx
147 # in6 = j6
148 movl 188(%esp),%edx
149 # in7 = j7
150 movl 192(%esp),%ebx
151 # x4 = in4
152 movl %eax,116(%esp)
153 # x5 = in5
154 movl %ecx,120(%esp)
155 # x6 = in6
156 movl %edx,124(%esp)
157 # x7 = in7
158 movl %ebx,128(%esp)
159 # in8 = j8
160 movl 196(%esp),%eax
161 # in9 = j9
162 movl 200(%esp),%ecx
163 # in10 = j10
164 movl 204(%esp),%edx
165 # in11 = j11
166 movl 208(%esp),%ebx
167 # x8 = in8
168 movl %eax,132(%esp)
169 # x9 = in9
170 movl %ecx,136(%esp)
171 # x10 = in10
172 movl %edx,140(%esp)
173 # x11 = in11
174 movl %ebx,144(%esp)
175 # in12 = j12
176 movl 212(%esp),%eax
177 # in13 = j13
178 movl 216(%esp),%ecx
179 # in14 = j14
180 movl 220(%esp),%edx
181 # in15 = j15
182 movl 224(%esp),%ebx
183 # x12 = in12
184 movl %eax,148(%esp)
185 # x13 = in13
186 movl %ecx,152(%esp)
187 # x14 = in14
188 movl %edx,156(%esp)
189 # x15 = in15
190 movl %ebx,160(%esp)
191 # i = 20
192 mov $20,%ebp
193 # p = x0
194 movl 100(%esp),%eax
195 # s = x5
196 movl 120(%esp),%ecx
197 # t = x10
198 movl 140(%esp),%edx
199 # w = x15
200 movl 160(%esp),%ebx
201._mainloop:
202 # x0 = p
203 movl %eax,100(%esp)
204 # x10 = t
205 movl %edx,140(%esp)
206 # p += x12
207 addl 148(%esp),%eax
208 # x5 = s
209 movl %ecx,120(%esp)
210 # t += x6
211 addl 124(%esp),%edx
212 # x15 = w
213 movl %ebx,160(%esp)
214 # r = x1
215 movl 104(%esp),%esi
216 # r += s
217 add %ecx,%esi
218 # v = x11
219 movl 144(%esp),%edi
220 # v += w
221 add %ebx,%edi
222 # p <<<= 7
223 rol $7,%eax
224 # p ^= x4
225 xorl 116(%esp),%eax
226 # t <<<= 7
227 rol $7,%edx
228 # t ^= x14
229 xorl 156(%esp),%edx
230 # r <<<= 7
231 rol $7,%esi
232 # r ^= x9
233 xorl 136(%esp),%esi
234 # v <<<= 7
235 rol $7,%edi
236 # v ^= x3
237 xorl 112(%esp),%edi
238 # x4 = p
239 movl %eax,116(%esp)
240 # x14 = t
241 movl %edx,156(%esp)
242 # p += x0
243 addl 100(%esp),%eax
244 # x9 = r
245 movl %esi,136(%esp)
246 # t += x10
247 addl 140(%esp),%edx
248 # x3 = v
249 movl %edi,112(%esp)
250 # p <<<= 9
251 rol $9,%eax
252 # p ^= x8
253 xorl 132(%esp),%eax
254 # t <<<= 9
255 rol $9,%edx
256 # t ^= x2
257 xorl 108(%esp),%edx
258 # s += r
259 add %esi,%ecx
260 # s <<<= 9
261 rol $9,%ecx
262 # s ^= x13
263 xorl 152(%esp),%ecx
264 # w += v
265 add %edi,%ebx
266 # w <<<= 9
267 rol $9,%ebx
268 # w ^= x7
269 xorl 128(%esp),%ebx
270 # x8 = p
271 movl %eax,132(%esp)
272 # x2 = t
273 movl %edx,108(%esp)
274 # p += x4
275 addl 116(%esp),%eax
276 # x13 = s
277 movl %ecx,152(%esp)
278 # t += x14
279 addl 156(%esp),%edx
280 # x7 = w
281 movl %ebx,128(%esp)
282 # p <<<= 13
283 rol $13,%eax
284 # p ^= x12
285 xorl 148(%esp),%eax
286 # t <<<= 13
287 rol $13,%edx
288 # t ^= x6
289 xorl 124(%esp),%edx
290 # r += s
291 add %ecx,%esi
292 # r <<<= 13
293 rol $13,%esi
294 # r ^= x1
295 xorl 104(%esp),%esi
296 # v += w
297 add %ebx,%edi
298 # v <<<= 13
299 rol $13,%edi
300 # v ^= x11
301 xorl 144(%esp),%edi
302 # x12 = p
303 movl %eax,148(%esp)
304 # x6 = t
305 movl %edx,124(%esp)
306 # p += x8
307 addl 132(%esp),%eax
308 # x1 = r
309 movl %esi,104(%esp)
310 # t += x2
311 addl 108(%esp),%edx
312 # x11 = v
313 movl %edi,144(%esp)
314 # p <<<= 18
315 rol $18,%eax
316 # p ^= x0
317 xorl 100(%esp),%eax
318 # t <<<= 18
319 rol $18,%edx
320 # t ^= x10
321 xorl 140(%esp),%edx
322 # s += r
323 add %esi,%ecx
324 # s <<<= 18
325 rol $18,%ecx
326 # s ^= x5
327 xorl 120(%esp),%ecx
328 # w += v
329 add %edi,%ebx
330 # w <<<= 18
331 rol $18,%ebx
332 # w ^= x15
333 xorl 160(%esp),%ebx
334 # x0 = p
335 movl %eax,100(%esp)
336 # x10 = t
337 movl %edx,140(%esp)
338 # p += x3
339 addl 112(%esp),%eax
340 # p <<<= 7
341 rol $7,%eax
342 # x5 = s
343 movl %ecx,120(%esp)
344 # t += x9
345 addl 136(%esp),%edx
346 # x15 = w
347 movl %ebx,160(%esp)
348 # r = x4
349 movl 116(%esp),%esi
350 # r += s
351 add %ecx,%esi
352 # v = x14
353 movl 156(%esp),%edi
354 # v += w
355 add %ebx,%edi
356 # p ^= x1
357 xorl 104(%esp),%eax
358 # t <<<= 7
359 rol $7,%edx
360 # t ^= x11
361 xorl 144(%esp),%edx
362 # r <<<= 7
363 rol $7,%esi
364 # r ^= x6
365 xorl 124(%esp),%esi
366 # v <<<= 7
367 rol $7,%edi
368 # v ^= x12
369 xorl 148(%esp),%edi
370 # x1 = p
371 movl %eax,104(%esp)
372 # x11 = t
373 movl %edx,144(%esp)
374 # p += x0
375 addl 100(%esp),%eax
376 # x6 = r
377 movl %esi,124(%esp)
378 # t += x10
379 addl 140(%esp),%edx
380 # x12 = v
381 movl %edi,148(%esp)
382 # p <<<= 9
383 rol $9,%eax
384 # p ^= x2
385 xorl 108(%esp),%eax
386 # t <<<= 9
387 rol $9,%edx
388 # t ^= x8
389 xorl 132(%esp),%edx
390 # s += r
391 add %esi,%ecx
392 # s <<<= 9
393 rol $9,%ecx
394 # s ^= x7
395 xorl 128(%esp),%ecx
396 # w += v
397 add %edi,%ebx
398 # w <<<= 9
399 rol $9,%ebx
400 # w ^= x13
401 xorl 152(%esp),%ebx
402 # x2 = p
403 movl %eax,108(%esp)
404 # x8 = t
405 movl %edx,132(%esp)
406 # p += x1
407 addl 104(%esp),%eax
408 # x7 = s
409 movl %ecx,128(%esp)
410 # t += x11
411 addl 144(%esp),%edx
412 # x13 = w
413 movl %ebx,152(%esp)
414 # p <<<= 13
415 rol $13,%eax
416 # p ^= x3
417 xorl 112(%esp),%eax
418 # t <<<= 13
419 rol $13,%edx
420 # t ^= x9
421 xorl 136(%esp),%edx
422 # r += s
423 add %ecx,%esi
424 # r <<<= 13
425 rol $13,%esi
426 # r ^= x4
427 xorl 116(%esp),%esi
428 # v += w
429 add %ebx,%edi
430 # v <<<= 13
431 rol $13,%edi
432 # v ^= x14
433 xorl 156(%esp),%edi
434 # x3 = p
435 movl %eax,112(%esp)
436 # x9 = t
437 movl %edx,136(%esp)
438 # p += x2
439 addl 108(%esp),%eax
440 # x4 = r
441 movl %esi,116(%esp)
442 # t += x8
443 addl 132(%esp),%edx
444 # x14 = v
445 movl %edi,156(%esp)
446 # p <<<= 18
447 rol $18,%eax
448 # p ^= x0
449 xorl 100(%esp),%eax
450 # t <<<= 18
451 rol $18,%edx
452 # t ^= x10
453 xorl 140(%esp),%edx
454 # s += r
455 add %esi,%ecx
456 # s <<<= 18
457 rol $18,%ecx
458 # s ^= x5
459 xorl 120(%esp),%ecx
460 # w += v
461 add %edi,%ebx
462 # w <<<= 18
463 rol $18,%ebx
464 # w ^= x15
465 xorl 160(%esp),%ebx
466 # x0 = p
467 movl %eax,100(%esp)
468 # x10 = t
469 movl %edx,140(%esp)
470 # p += x12
471 addl 148(%esp),%eax
472 # x5 = s
473 movl %ecx,120(%esp)
474 # t += x6
475 addl 124(%esp),%edx
476 # x15 = w
477 movl %ebx,160(%esp)
478 # r = x1
479 movl 104(%esp),%esi
480 # r += s
481 add %ecx,%esi
482 # v = x11
483 movl 144(%esp),%edi
484 # v += w
485 add %ebx,%edi
486 # p <<<= 7
487 rol $7,%eax
488 # p ^= x4
489 xorl 116(%esp),%eax
490 # t <<<= 7
491 rol $7,%edx
492 # t ^= x14
493 xorl 156(%esp),%edx
494 # r <<<= 7
495 rol $7,%esi
496 # r ^= x9
497 xorl 136(%esp),%esi
498 # v <<<= 7
499 rol $7,%edi
500 # v ^= x3
501 xorl 112(%esp),%edi
502 # x4 = p
503 movl %eax,116(%esp)
504 # x14 = t
505 movl %edx,156(%esp)
506 # p += x0
507 addl 100(%esp),%eax
508 # x9 = r
509 movl %esi,136(%esp)
510 # t += x10
511 addl 140(%esp),%edx
512 # x3 = v
513 movl %edi,112(%esp)
514 # p <<<= 9
515 rol $9,%eax
516 # p ^= x8
517 xorl 132(%esp),%eax
518 # t <<<= 9
519 rol $9,%edx
520 # t ^= x2
521 xorl 108(%esp),%edx
522 # s += r
523 add %esi,%ecx
524 # s <<<= 9
525 rol $9,%ecx
526 # s ^= x13
527 xorl 152(%esp),%ecx
528 # w += v
529 add %edi,%ebx
530 # w <<<= 9
531 rol $9,%ebx
532 # w ^= x7
533 xorl 128(%esp),%ebx
534 # x8 = p
535 movl %eax,132(%esp)
536 # x2 = t
537 movl %edx,108(%esp)
538 # p += x4
539 addl 116(%esp),%eax
540 # x13 = s
541 movl %ecx,152(%esp)
542 # t += x14
543 addl 156(%esp),%edx
544 # x7 = w
545 movl %ebx,128(%esp)
546 # p <<<= 13
547 rol $13,%eax
548 # p ^= x12
549 xorl 148(%esp),%eax
550 # t <<<= 13
551 rol $13,%edx
552 # t ^= x6
553 xorl 124(%esp),%edx
554 # r += s
555 add %ecx,%esi
556 # r <<<= 13
557 rol $13,%esi
558 # r ^= x1
559 xorl 104(%esp),%esi
560 # v += w
561 add %ebx,%edi
562 # v <<<= 13
563 rol $13,%edi
564 # v ^= x11
565 xorl 144(%esp),%edi
566 # x12 = p
567 movl %eax,148(%esp)
568 # x6 = t
569 movl %edx,124(%esp)
570 # p += x8
571 addl 132(%esp),%eax
572 # x1 = r
573 movl %esi,104(%esp)
574 # t += x2
575 addl 108(%esp),%edx
576 # x11 = v
577 movl %edi,144(%esp)
578 # p <<<= 18
579 rol $18,%eax
580 # p ^= x0
581 xorl 100(%esp),%eax
582 # t <<<= 18
583 rol $18,%edx
584 # t ^= x10
585 xorl 140(%esp),%edx
586 # s += r
587 add %esi,%ecx
588 # s <<<= 18
589 rol $18,%ecx
590 # s ^= x5
591 xorl 120(%esp),%ecx
592 # w += v
593 add %edi,%ebx
594 # w <<<= 18
595 rol $18,%ebx
596 # w ^= x15
597 xorl 160(%esp),%ebx
598 # x0 = p
599 movl %eax,100(%esp)
600 # x10 = t
601 movl %edx,140(%esp)
602 # p += x3
603 addl 112(%esp),%eax
604 # p <<<= 7
605 rol $7,%eax
606 # x5 = s
607 movl %ecx,120(%esp)
608 # t += x9
609 addl 136(%esp),%edx
610 # x15 = w
611 movl %ebx,160(%esp)
612 # r = x4
613 movl 116(%esp),%esi
614 # r += s
615 add %ecx,%esi
616 # v = x14
617 movl 156(%esp),%edi
618 # v += w
619 add %ebx,%edi
620 # p ^= x1
621 xorl 104(%esp),%eax
622 # t <<<= 7
623 rol $7,%edx
624 # t ^= x11
625 xorl 144(%esp),%edx
626 # r <<<= 7
627 rol $7,%esi
628 # r ^= x6
629 xorl 124(%esp),%esi
630 # v <<<= 7
631 rol $7,%edi
632 # v ^= x12
633 xorl 148(%esp),%edi
634 # x1 = p
635 movl %eax,104(%esp)
636 # x11 = t
637 movl %edx,144(%esp)
638 # p += x0
639 addl 100(%esp),%eax
640 # x6 = r
641 movl %esi,124(%esp)
642 # t += x10
643 addl 140(%esp),%edx
644 # x12 = v
645 movl %edi,148(%esp)
646 # p <<<= 9
647 rol $9,%eax
648 # p ^= x2
649 xorl 108(%esp),%eax
650 # t <<<= 9
651 rol $9,%edx
652 # t ^= x8
653 xorl 132(%esp),%edx
654 # s += r
655 add %esi,%ecx
656 # s <<<= 9
657 rol $9,%ecx
658 # s ^= x7
659 xorl 128(%esp),%ecx
660 # w += v
661 add %edi,%ebx
662 # w <<<= 9
663 rol $9,%ebx
664 # w ^= x13
665 xorl 152(%esp),%ebx
666 # x2 = p
667 movl %eax,108(%esp)
668 # x8 = t
669 movl %edx,132(%esp)
670 # p += x1
671 addl 104(%esp),%eax
672 # x7 = s
673 movl %ecx,128(%esp)
674 # t += x11
675 addl 144(%esp),%edx
676 # x13 = w
677 movl %ebx,152(%esp)
678 # p <<<= 13
679 rol $13,%eax
680 # p ^= x3
681 xorl 112(%esp),%eax
682 # t <<<= 13
683 rol $13,%edx
684 # t ^= x9
685 xorl 136(%esp),%edx
686 # r += s
687 add %ecx,%esi
688 # r <<<= 13
689 rol $13,%esi
690 # r ^= x4
691 xorl 116(%esp),%esi
692 # v += w
693 add %ebx,%edi
694 # v <<<= 13
695 rol $13,%edi
696 # v ^= x14
697 xorl 156(%esp),%edi
698 # x3 = p
699 movl %eax,112(%esp)
700 # x9 = t
701 movl %edx,136(%esp)
702 # p += x2
703 addl 108(%esp),%eax
704 # x4 = r
705 movl %esi,116(%esp)
706 # t += x8
707 addl 132(%esp),%edx
708 # x14 = v
709 movl %edi,156(%esp)
710 # p <<<= 18
711 rol $18,%eax
712 # p ^= x0
713 xorl 100(%esp),%eax
714 # t <<<= 18
715 rol $18,%edx
716 # t ^= x10
717 xorl 140(%esp),%edx
718 # s += r
719 add %esi,%ecx
720 # s <<<= 18
721 rol $18,%ecx
722 # s ^= x5
723 xorl 120(%esp),%ecx
724 # w += v
725 add %edi,%ebx
726 # w <<<= 18
727 rol $18,%ebx
728 # w ^= x15
729 xorl 160(%esp),%ebx
730 # i -= 4
731 sub $4,%ebp
732 # goto mainloop if unsigned >
733 ja ._mainloop
734 # x0 = p
735 movl %eax,100(%esp)
736 # x5 = s
737 movl %ecx,120(%esp)
738 # x10 = t
739 movl %edx,140(%esp)
740 # x15 = w
741 movl %ebx,160(%esp)
742 # out = out_backup
743 movl 72(%esp),%edi
744 # m = m_backup
745 movl 68(%esp),%esi
746 # in0 = x0
747 movl 100(%esp),%eax
748 # in1 = x1
749 movl 104(%esp),%ecx
750 # in0 += j0
751 addl 164(%esp),%eax
752 # in1 += j1
753 addl 168(%esp),%ecx
754 # in0 ^= *(uint32 *) (m + 0)
755 xorl 0(%esi),%eax
756 # in1 ^= *(uint32 *) (m + 4)
757 xorl 4(%esi),%ecx
758 # *(uint32 *) (out + 0) = in0
759 movl %eax,0(%edi)
760 # *(uint32 *) (out + 4) = in1
761 movl %ecx,4(%edi)
762 # in2 = x2
763 movl 108(%esp),%eax
764 # in3 = x3
765 movl 112(%esp),%ecx
766 # in2 += j2
767 addl 172(%esp),%eax
768 # in3 += j3
769 addl 176(%esp),%ecx
770 # in2 ^= *(uint32 *) (m + 8)
771 xorl 8(%esi),%eax
772 # in3 ^= *(uint32 *) (m + 12)
773 xorl 12(%esi),%ecx
774 # *(uint32 *) (out + 8) = in2
775 movl %eax,8(%edi)
776 # *(uint32 *) (out + 12) = in3
777 movl %ecx,12(%edi)
778 # in4 = x4
779 movl 116(%esp),%eax
780 # in5 = x5
781 movl 120(%esp),%ecx
782 # in4 += j4
783 addl 180(%esp),%eax
784 # in5 += j5
785 addl 184(%esp),%ecx
786 # in4 ^= *(uint32 *) (m + 16)
787 xorl 16(%esi),%eax
788 # in5 ^= *(uint32 *) (m + 20)
789 xorl 20(%esi),%ecx
790 # *(uint32 *) (out + 16) = in4
791 movl %eax,16(%edi)
792 # *(uint32 *) (out + 20) = in5
793 movl %ecx,20(%edi)
794 # in6 = x6
795 movl 124(%esp),%eax
796 # in7 = x7
797 movl 128(%esp),%ecx
798 # in6 += j6
799 addl 188(%esp),%eax
800 # in7 += j7
801 addl 192(%esp),%ecx
802 # in6 ^= *(uint32 *) (m + 24)
803 xorl 24(%esi),%eax
804 # in7 ^= *(uint32 *) (m + 28)
805 xorl 28(%esi),%ecx
806 # *(uint32 *) (out + 24) = in6
807 movl %eax,24(%edi)
808 # *(uint32 *) (out + 28) = in7
809 movl %ecx,28(%edi)
810 # in8 = x8
811 movl 132(%esp),%eax
812 # in9 = x9
813 movl 136(%esp),%ecx
814 # in8 += j8
815 addl 196(%esp),%eax
816 # in9 += j9
817 addl 200(%esp),%ecx
818 # in8 ^= *(uint32 *) (m + 32)
819 xorl 32(%esi),%eax
820 # in9 ^= *(uint32 *) (m + 36)
821 xorl 36(%esi),%ecx
822 # *(uint32 *) (out + 32) = in8
823 movl %eax,32(%edi)
824 # *(uint32 *) (out + 36) = in9
825 movl %ecx,36(%edi)
826 # in10 = x10
827 movl 140(%esp),%eax
828 # in11 = x11
829 movl 144(%esp),%ecx
830 # in10 += j10
831 addl 204(%esp),%eax
832 # in11 += j11
833 addl 208(%esp),%ecx
834 # in10 ^= *(uint32 *) (m + 40)
835 xorl 40(%esi),%eax
836 # in11 ^= *(uint32 *) (m + 44)
837 xorl 44(%esi),%ecx
838 # *(uint32 *) (out + 40) = in10
839 movl %eax,40(%edi)
840 # *(uint32 *) (out + 44) = in11
841 movl %ecx,44(%edi)
842 # in12 = x12
843 movl 148(%esp),%eax
844 # in13 = x13
845 movl 152(%esp),%ecx
846 # in12 += j12
847 addl 212(%esp),%eax
848 # in13 += j13
849 addl 216(%esp),%ecx
850 # in12 ^= *(uint32 *) (m + 48)
851 xorl 48(%esi),%eax
852 # in13 ^= *(uint32 *) (m + 52)
853 xorl 52(%esi),%ecx
854 # *(uint32 *) (out + 48) = in12
855 movl %eax,48(%edi)
856 # *(uint32 *) (out + 52) = in13
857 movl %ecx,52(%edi)
858 # in14 = x14
859 movl 156(%esp),%eax
860 # in15 = x15
861 movl 160(%esp),%ecx
862 # in14 += j14
863 addl 220(%esp),%eax
864 # in15 += j15
865 addl 224(%esp),%ecx
866 # in14 ^= *(uint32 *) (m + 56)
867 xorl 56(%esi),%eax
868 # in15 ^= *(uint32 *) (m + 60)
869 xorl 60(%esi),%ecx
870 # *(uint32 *) (out + 56) = in14
871 movl %eax,56(%edi)
872 # *(uint32 *) (out + 60) = in15
873 movl %ecx,60(%edi)
874 # bytes = bytes_backup
875 movl 76(%esp),%ebx
876 # in8 = j8
877 movl 196(%esp),%eax
878 # in9 = j9
879 movl 200(%esp),%ecx
880 # in8 += 1
881 add $1,%eax
882 # in9 += 0 + carry
883 adc $0,%ecx
884 # j8 = in8
885 movl %eax,196(%esp)
886 # j9 = in9
887 movl %ecx,200(%esp)
888 # bytes - 64
889 cmp $64,%ebx
890 # goto bytesatleast65 if unsigned>
891 ja ._bytesatleast65
892 # goto bytesatleast64 if unsigned>=
893 jae ._bytesatleast64
894 # m = out
895 mov %edi,%esi
896 # out = ctarget
897 movl 228(%esp),%edi
898 # i = bytes
899 mov %ebx,%ecx
900 # while (i) { *out++ = *m++; --i }
901 rep movsb
902._bytesatleast64:
903 # x = x_backup
904 movl 64(%esp),%eax
905 # in8 = j8
906 movl 196(%esp),%ecx
907 # in9 = j9
908 movl 200(%esp),%edx
909 # *(uint32 *) (x + 32) = in8
910 movl %ecx,32(%eax)
911 # *(uint32 *) (x + 36) = in9
912 movl %edx,36(%eax)
913._done:
914 # eax = eax_stack
915 movl 80(%esp),%eax
916 # ebx = ebx_stack
917 movl 84(%esp),%ebx
918 # esi = esi_stack
919 movl 88(%esp),%esi
920 # edi = edi_stack
921 movl 92(%esp),%edi
922 # ebp = ebp_stack
923 movl 96(%esp),%ebp
924 # leave
925 add %eax,%esp
926 ret
927._bytesatleast65:
928 # bytes -= 64
929 sub $64,%ebx
930 # out += 64
931 add $64,%edi
932 # m += 64
933 add $64,%esi
934 # goto bytesatleast1
935 jmp ._bytesatleast1
936# enter ECRYPT_keysetup
937.text
938.p2align 5
939.globl ECRYPT_keysetup
940ECRYPT_keysetup:
941 mov %esp,%eax
942 and $31,%eax
943 add $256,%eax
944 sub %eax,%esp
945 # eax_stack = eax
946 movl %eax,64(%esp)
947 # ebx_stack = ebx
948 movl %ebx,68(%esp)
949 # esi_stack = esi
950 movl %esi,72(%esp)
951 # edi_stack = edi
952 movl %edi,76(%esp)
953 # ebp_stack = ebp
954 movl %ebp,80(%esp)
955 # k = arg2
956 movl 8(%esp,%eax),%ecx
957 # kbits = arg3
958 movl 12(%esp,%eax),%edx
959 # x = arg1
960 movl 4(%esp,%eax),%eax
961 # in1 = *(uint32 *) (k + 0)
962 movl 0(%ecx),%ebx
963 # in2 = *(uint32 *) (k + 4)
964 movl 4(%ecx),%esi
965 # in3 = *(uint32 *) (k + 8)
966 movl 8(%ecx),%edi
967 # in4 = *(uint32 *) (k + 12)
968 movl 12(%ecx),%ebp
969 # *(uint32 *) (x + 4) = in1
970 movl %ebx,4(%eax)
971 # *(uint32 *) (x + 8) = in2
972 movl %esi,8(%eax)
973 # *(uint32 *) (x + 12) = in3
974 movl %edi,12(%eax)
975 # *(uint32 *) (x + 16) = in4
976 movl %ebp,16(%eax)
977 # kbits - 256
978 cmp $256,%edx
979 # goto kbits128 if unsigned<
980 jb ._kbits128
981._kbits256:
982 # in11 = *(uint32 *) (k + 16)
983 movl 16(%ecx),%edx
984 # in12 = *(uint32 *) (k + 20)
985 movl 20(%ecx),%ebx
986 # in13 = *(uint32 *) (k + 24)
987 movl 24(%ecx),%esi
988 # in14 = *(uint32 *) (k + 28)
989 movl 28(%ecx),%ecx
990 # *(uint32 *) (x + 44) = in11
991 movl %edx,44(%eax)
992 # *(uint32 *) (x + 48) = in12
993 movl %ebx,48(%eax)
994 # *(uint32 *) (x + 52) = in13
995 movl %esi,52(%eax)
996 # *(uint32 *) (x + 56) = in14
997 movl %ecx,56(%eax)
998 # in0 = 1634760805
999 mov $1634760805,%ecx
1000 # in5 = 857760878
1001 mov $857760878,%edx
1002 # in10 = 2036477234
1003 mov $2036477234,%ebx
1004 # in15 = 1797285236
1005 mov $1797285236,%esi
1006 # *(uint32 *) (x + 0) = in0
1007 movl %ecx,0(%eax)
1008 # *(uint32 *) (x + 20) = in5
1009 movl %edx,20(%eax)
1010 # *(uint32 *) (x + 40) = in10
1011 movl %ebx,40(%eax)
1012 # *(uint32 *) (x + 60) = in15
1013 movl %esi,60(%eax)
1014 # goto keysetupdone
1015 jmp ._keysetupdone
1016._kbits128:
1017 # in11 = *(uint32 *) (k + 0)
1018 movl 0(%ecx),%edx
1019 # in12 = *(uint32 *) (k + 4)
1020 movl 4(%ecx),%ebx
1021 # in13 = *(uint32 *) (k + 8)
1022 movl 8(%ecx),%esi
1023 # in14 = *(uint32 *) (k + 12)
1024 movl 12(%ecx),%ecx
1025 # *(uint32 *) (x + 44) = in11
1026 movl %edx,44(%eax)
1027 # *(uint32 *) (x + 48) = in12
1028 movl %ebx,48(%eax)
1029 # *(uint32 *) (x + 52) = in13
1030 movl %esi,52(%eax)
1031 # *(uint32 *) (x + 56) = in14
1032 movl %ecx,56(%eax)
1033 # in0 = 1634760805
1034 mov $1634760805,%ecx
1035 # in5 = 824206446
1036 mov $824206446,%edx
1037 # in10 = 2036477238
1038 mov $2036477238,%ebx
1039 # in15 = 1797285236
1040 mov $1797285236,%esi
1041 # *(uint32 *) (x + 0) = in0
1042 movl %ecx,0(%eax)
1043 # *(uint32 *) (x + 20) = in5
1044 movl %edx,20(%eax)
1045 # *(uint32 *) (x + 40) = in10
1046 movl %ebx,40(%eax)
1047 # *(uint32 *) (x + 60) = in15
1048 movl %esi,60(%eax)
1049._keysetupdone:
1050 # eax = eax_stack
1051 movl 64(%esp),%eax
1052 # ebx = ebx_stack
1053 movl 68(%esp),%ebx
1054 # esi = esi_stack
1055 movl 72(%esp),%esi
1056 # edi = edi_stack
1057 movl 76(%esp),%edi
1058 # ebp = ebp_stack
1059 movl 80(%esp),%ebp
1060 # leave
1061 add %eax,%esp
1062 ret
1063# enter ECRYPT_ivsetup
1064.text
1065.p2align 5
1066.globl ECRYPT_ivsetup
1067ECRYPT_ivsetup:
1068 mov %esp,%eax
1069 and $31,%eax
1070 add $256,%eax
1071 sub %eax,%esp
1072 # eax_stack = eax
1073 movl %eax,64(%esp)
1074 # ebx_stack = ebx
1075 movl %ebx,68(%esp)
1076 # esi_stack = esi
1077 movl %esi,72(%esp)
1078 # edi_stack = edi
1079 movl %edi,76(%esp)
1080 # ebp_stack = ebp
1081 movl %ebp,80(%esp)
1082 # iv = arg2
1083 movl 8(%esp,%eax),%ecx
1084 # x = arg1
1085 movl 4(%esp,%eax),%eax
1086 # in6 = *(uint32 *) (iv + 0)
1087 movl 0(%ecx),%edx
1088 # in7 = *(uint32 *) (iv + 4)
1089 movl 4(%ecx),%ecx
1090 # in8 = 0
1091 mov $0,%ebx
1092 # in9 = 0
1093 mov $0,%esi
1094 # *(uint32 *) (x + 24) = in6
1095 movl %edx,24(%eax)
1096 # *(uint32 *) (x + 28) = in7
1097 movl %ecx,28(%eax)
1098 # *(uint32 *) (x + 32) = in8
1099 movl %ebx,32(%eax)
1100 # *(uint32 *) (x + 36) = in9
1101 movl %esi,36(%eax)
1102 # eax = eax_stack
1103 movl 64(%esp),%eax
1104 # ebx = ebx_stack
1105 movl 68(%esp),%ebx
1106 # esi = esi_stack
1107 movl 72(%esp),%esi
1108 # edi = edi_stack
1109 movl 76(%esp),%edi
1110 # ebp = ebp_stack
1111 movl 80(%esp),%ebp
1112 # leave
1113 add %eax,%esp
1114 ret
diff --git a/arch/x86/crypto/salsa20-x86_64-asm_64.S b/arch/x86/crypto/salsa20-x86_64-asm_64.S
new file mode 100644
index 000000000000..6214a9b09706
--- /dev/null
+++ b/arch/x86/crypto/salsa20-x86_64-asm_64.S
@@ -0,0 +1,920 @@
1# enter ECRYPT_encrypt_bytes
2.text
3.p2align 5
4.globl ECRYPT_encrypt_bytes
5ECRYPT_encrypt_bytes:
6 mov %rsp,%r11
7 and $31,%r11
8 add $256,%r11
9 sub %r11,%rsp
10 # x = arg1
11 mov %rdi,%r8
12 # m = arg2
13 mov %rsi,%rsi
14 # out = arg3
15 mov %rdx,%rdi
16 # bytes = arg4
17 mov %rcx,%rdx
18 # unsigned>? bytes - 0
19 cmp $0,%rdx
20 # comment:fp stack unchanged by jump
21 # goto done if !unsigned>
22 jbe ._done
23 # comment:fp stack unchanged by fallthrough
24# start:
25._start:
26 # r11_stack = r11
27 movq %r11,0(%rsp)
28 # r12_stack = r12
29 movq %r12,8(%rsp)
30 # r13_stack = r13
31 movq %r13,16(%rsp)
32 # r14_stack = r14
33 movq %r14,24(%rsp)
34 # r15_stack = r15
35 movq %r15,32(%rsp)
36 # rbx_stack = rbx
37 movq %rbx,40(%rsp)
38 # rbp_stack = rbp
39 movq %rbp,48(%rsp)
40 # in0 = *(uint64 *) (x + 0)
41 movq 0(%r8),%rcx
42 # in2 = *(uint64 *) (x + 8)
43 movq 8(%r8),%r9
44 # in4 = *(uint64 *) (x + 16)
45 movq 16(%r8),%rax
46 # in6 = *(uint64 *) (x + 24)
47 movq 24(%r8),%r10
48 # in8 = *(uint64 *) (x + 32)
49 movq 32(%r8),%r11
50 # in10 = *(uint64 *) (x + 40)
51 movq 40(%r8),%r12
52 # in12 = *(uint64 *) (x + 48)
53 movq 48(%r8),%r13
54 # in14 = *(uint64 *) (x + 56)
55 movq 56(%r8),%r14
56 # j0 = in0
57 movq %rcx,56(%rsp)
58 # j2 = in2
59 movq %r9,64(%rsp)
60 # j4 = in4
61 movq %rax,72(%rsp)
62 # j6 = in6
63 movq %r10,80(%rsp)
64 # j8 = in8
65 movq %r11,88(%rsp)
66 # j10 = in10
67 movq %r12,96(%rsp)
68 # j12 = in12
69 movq %r13,104(%rsp)
70 # j14 = in14
71 movq %r14,112(%rsp)
72 # x_backup = x
73 movq %r8,120(%rsp)
74# bytesatleast1:
75._bytesatleast1:
76 # unsigned<? bytes - 64
77 cmp $64,%rdx
78 # comment:fp stack unchanged by jump
79 # goto nocopy if !unsigned<
80 jae ._nocopy
81 # ctarget = out
82 movq %rdi,128(%rsp)
83 # out = &tmp
84 leaq 192(%rsp),%rdi
85 # i = bytes
86 mov %rdx,%rcx
87 # while (i) { *out++ = *m++; --i }
88 rep movsb
89 # out = &tmp
90 leaq 192(%rsp),%rdi
91 # m = &tmp
92 leaq 192(%rsp),%rsi
93 # comment:fp stack unchanged by fallthrough
94# nocopy:
95._nocopy:
96 # out_backup = out
97 movq %rdi,136(%rsp)
98 # m_backup = m
99 movq %rsi,144(%rsp)
100 # bytes_backup = bytes
101 movq %rdx,152(%rsp)
102 # x1 = j0
103 movq 56(%rsp),%rdi
104 # x0 = x1
105 mov %rdi,%rdx
106 # (uint64) x1 >>= 32
107 shr $32,%rdi
108 # x3 = j2
109 movq 64(%rsp),%rsi
110 # x2 = x3
111 mov %rsi,%rcx
112 # (uint64) x3 >>= 32
113 shr $32,%rsi
114 # x5 = j4
115 movq 72(%rsp),%r8
116 # x4 = x5
117 mov %r8,%r9
118 # (uint64) x5 >>= 32
119 shr $32,%r8
120 # x5_stack = x5
121 movq %r8,160(%rsp)
122 # x7 = j6
123 movq 80(%rsp),%r8
124 # x6 = x7
125 mov %r8,%rax
126 # (uint64) x7 >>= 32
127 shr $32,%r8
128 # x9 = j8
129 movq 88(%rsp),%r10
130 # x8 = x9
131 mov %r10,%r11
132 # (uint64) x9 >>= 32
133 shr $32,%r10
134 # x11 = j10
135 movq 96(%rsp),%r12
136 # x10 = x11
137 mov %r12,%r13
138 # x10_stack = x10
139 movq %r13,168(%rsp)
140 # (uint64) x11 >>= 32
141 shr $32,%r12
142 # x13 = j12
143 movq 104(%rsp),%r13
144 # x12 = x13
145 mov %r13,%r14
146 # (uint64) x13 >>= 32
147 shr $32,%r13
148 # x15 = j14
149 movq 112(%rsp),%r15
150 # x14 = x15
151 mov %r15,%rbx
152 # (uint64) x15 >>= 32
153 shr $32,%r15
154 # x15_stack = x15
155 movq %r15,176(%rsp)
156 # i = 20
157 mov $20,%r15
158# mainloop:
159._mainloop:
160 # i_backup = i
161 movq %r15,184(%rsp)
162 # x5 = x5_stack
163 movq 160(%rsp),%r15
164 # a = x12 + x0
165 lea (%r14,%rdx),%rbp
166 # (uint32) a <<<= 7
167 rol $7,%ebp
168 # x4 ^= a
169 xor %rbp,%r9
170 # b = x1 + x5
171 lea (%rdi,%r15),%rbp
172 # (uint32) b <<<= 7
173 rol $7,%ebp
174 # x9 ^= b
175 xor %rbp,%r10
176 # a = x0 + x4
177 lea (%rdx,%r9),%rbp
178 # (uint32) a <<<= 9
179 rol $9,%ebp
180 # x8 ^= a
181 xor %rbp,%r11
182 # b = x5 + x9
183 lea (%r15,%r10),%rbp
184 # (uint32) b <<<= 9
185 rol $9,%ebp
186 # x13 ^= b
187 xor %rbp,%r13
188 # a = x4 + x8
189 lea (%r9,%r11),%rbp
190 # (uint32) a <<<= 13
191 rol $13,%ebp
192 # x12 ^= a
193 xor %rbp,%r14
194 # b = x9 + x13
195 lea (%r10,%r13),%rbp
196 # (uint32) b <<<= 13
197 rol $13,%ebp
198 # x1 ^= b
199 xor %rbp,%rdi
200 # a = x8 + x12
201 lea (%r11,%r14),%rbp
202 # (uint32) a <<<= 18
203 rol $18,%ebp
204 # x0 ^= a
205 xor %rbp,%rdx
206 # b = x13 + x1
207 lea (%r13,%rdi),%rbp
208 # (uint32) b <<<= 18
209 rol $18,%ebp
210 # x5 ^= b
211 xor %rbp,%r15
212 # x10 = x10_stack
213 movq 168(%rsp),%rbp
214 # x5_stack = x5
215 movq %r15,160(%rsp)
216 # c = x6 + x10
217 lea (%rax,%rbp),%r15
218 # (uint32) c <<<= 7
219 rol $7,%r15d
220 # x14 ^= c
221 xor %r15,%rbx
222 # c = x10 + x14
223 lea (%rbp,%rbx),%r15
224 # (uint32) c <<<= 9
225 rol $9,%r15d
226 # x2 ^= c
227 xor %r15,%rcx
228 # c = x14 + x2
229 lea (%rbx,%rcx),%r15
230 # (uint32) c <<<= 13
231 rol $13,%r15d
232 # x6 ^= c
233 xor %r15,%rax
234 # c = x2 + x6
235 lea (%rcx,%rax),%r15
236 # (uint32) c <<<= 18
237 rol $18,%r15d
238 # x10 ^= c
239 xor %r15,%rbp
240 # x15 = x15_stack
241 movq 176(%rsp),%r15
242 # x10_stack = x10
243 movq %rbp,168(%rsp)
244 # d = x11 + x15
245 lea (%r12,%r15),%rbp
246 # (uint32) d <<<= 7
247 rol $7,%ebp
248 # x3 ^= d
249 xor %rbp,%rsi
250 # d = x15 + x3
251 lea (%r15,%rsi),%rbp
252 # (uint32) d <<<= 9
253 rol $9,%ebp
254 # x7 ^= d
255 xor %rbp,%r8
256 # d = x3 + x7
257 lea (%rsi,%r8),%rbp
258 # (uint32) d <<<= 13
259 rol $13,%ebp
260 # x11 ^= d
261 xor %rbp,%r12
262 # d = x7 + x11
263 lea (%r8,%r12),%rbp
264 # (uint32) d <<<= 18
265 rol $18,%ebp
266 # x15 ^= d
267 xor %rbp,%r15
268 # x15_stack = x15
269 movq %r15,176(%rsp)
270 # x5 = x5_stack
271 movq 160(%rsp),%r15
272 # a = x3 + x0
273 lea (%rsi,%rdx),%rbp
274 # (uint32) a <<<= 7
275 rol $7,%ebp
276 # x1 ^= a
277 xor %rbp,%rdi
278 # b = x4 + x5
279 lea (%r9,%r15),%rbp
280 # (uint32) b <<<= 7
281 rol $7,%ebp
282 # x6 ^= b
283 xor %rbp,%rax
284 # a = x0 + x1
285 lea (%rdx,%rdi),%rbp
286 # (uint32) a <<<= 9
287 rol $9,%ebp
288 # x2 ^= a
289 xor %rbp,%rcx
290 # b = x5 + x6
291 lea (%r15,%rax),%rbp
292 # (uint32) b <<<= 9
293 rol $9,%ebp
294 # x7 ^= b
295 xor %rbp,%r8
296 # a = x1 + x2
297 lea (%rdi,%rcx),%rbp
298 # (uint32) a <<<= 13
299 rol $13,%ebp
300 # x3 ^= a
301 xor %rbp,%rsi
302 # b = x6 + x7
303 lea (%rax,%r8),%rbp
304 # (uint32) b <<<= 13
305 rol $13,%ebp
306 # x4 ^= b
307 xor %rbp,%r9
308 # a = x2 + x3
309 lea (%rcx,%rsi),%rbp
310 # (uint32) a <<<= 18
311 rol $18,%ebp
312 # x0 ^= a
313 xor %rbp,%rdx
314 # b = x7 + x4
315 lea (%r8,%r9),%rbp
316 # (uint32) b <<<= 18
317 rol $18,%ebp
318 # x5 ^= b
319 xor %rbp,%r15
320 # x10 = x10_stack
321 movq 168(%rsp),%rbp
322 # x5_stack = x5
323 movq %r15,160(%rsp)
324 # c = x9 + x10
325 lea (%r10,%rbp),%r15
326 # (uint32) c <<<= 7
327 rol $7,%r15d
328 # x11 ^= c
329 xor %r15,%r12
330 # c = x10 + x11
331 lea (%rbp,%r12),%r15
332 # (uint32) c <<<= 9
333 rol $9,%r15d
334 # x8 ^= c
335 xor %r15,%r11
336 # c = x11 + x8
337 lea (%r12,%r11),%r15
338 # (uint32) c <<<= 13
339 rol $13,%r15d
340 # x9 ^= c
341 xor %r15,%r10
342 # c = x8 + x9
343 lea (%r11,%r10),%r15
344 # (uint32) c <<<= 18
345 rol $18,%r15d
346 # x10 ^= c
347 xor %r15,%rbp
348 # x15 = x15_stack
349 movq 176(%rsp),%r15
350 # x10_stack = x10
351 movq %rbp,168(%rsp)
352 # d = x14 + x15
353 lea (%rbx,%r15),%rbp
354 # (uint32) d <<<= 7
355 rol $7,%ebp
356 # x12 ^= d
357 xor %rbp,%r14
358 # d = x15 + x12
359 lea (%r15,%r14),%rbp
360 # (uint32) d <<<= 9
361 rol $9,%ebp
362 # x13 ^= d
363 xor %rbp,%r13
364 # d = x12 + x13
365 lea (%r14,%r13),%rbp
366 # (uint32) d <<<= 13
367 rol $13,%ebp
368 # x14 ^= d
369 xor %rbp,%rbx
370 # d = x13 + x14
371 lea (%r13,%rbx),%rbp
372 # (uint32) d <<<= 18
373 rol $18,%ebp
374 # x15 ^= d
375 xor %rbp,%r15
376 # x15_stack = x15
377 movq %r15,176(%rsp)
378 # x5 = x5_stack
379 movq 160(%rsp),%r15
380 # a = x12 + x0
381 lea (%r14,%rdx),%rbp
382 # (uint32) a <<<= 7
383 rol $7,%ebp
384 # x4 ^= a
385 xor %rbp,%r9
386 # b = x1 + x5
387 lea (%rdi,%r15),%rbp
388 # (uint32) b <<<= 7
389 rol $7,%ebp
390 # x9 ^= b
391 xor %rbp,%r10
392 # a = x0 + x4
393 lea (%rdx,%r9),%rbp
394 # (uint32) a <<<= 9
395 rol $9,%ebp
396 # x8 ^= a
397 xor %rbp,%r11
398 # b = x5 + x9
399 lea (%r15,%r10),%rbp
400 # (uint32) b <<<= 9
401 rol $9,%ebp
402 # x13 ^= b
403 xor %rbp,%r13
404 # a = x4 + x8
405 lea (%r9,%r11),%rbp
406 # (uint32) a <<<= 13
407 rol $13,%ebp
408 # x12 ^= a
409 xor %rbp,%r14
410 # b = x9 + x13
411 lea (%r10,%r13),%rbp
412 # (uint32) b <<<= 13
413 rol $13,%ebp
414 # x1 ^= b
415 xor %rbp,%rdi
416 # a = x8 + x12
417 lea (%r11,%r14),%rbp
418 # (uint32) a <<<= 18
419 rol $18,%ebp
420 # x0 ^= a
421 xor %rbp,%rdx
422 # b = x13 + x1
423 lea (%r13,%rdi),%rbp
424 # (uint32) b <<<= 18
425 rol $18,%ebp
426 # x5 ^= b
427 xor %rbp,%r15
428 # x10 = x10_stack
429 movq 168(%rsp),%rbp
430 # x5_stack = x5
431 movq %r15,160(%rsp)
432 # c = x6 + x10
433 lea (%rax,%rbp),%r15
434 # (uint32) c <<<= 7
435 rol $7,%r15d
436 # x14 ^= c
437 xor %r15,%rbx
438 # c = x10 + x14
439 lea (%rbp,%rbx),%r15
440 # (uint32) c <<<= 9
441 rol $9,%r15d
442 # x2 ^= c
443 xor %r15,%rcx
444 # c = x14 + x2
445 lea (%rbx,%rcx),%r15
446 # (uint32) c <<<= 13
447 rol $13,%r15d
448 # x6 ^= c
449 xor %r15,%rax
450 # c = x2 + x6
451 lea (%rcx,%rax),%r15
452 # (uint32) c <<<= 18
453 rol $18,%r15d
454 # x10 ^= c
455 xor %r15,%rbp
456 # x15 = x15_stack
457 movq 176(%rsp),%r15
458 # x10_stack = x10
459 movq %rbp,168(%rsp)
460 # d = x11 + x15
461 lea (%r12,%r15),%rbp
462 # (uint32) d <<<= 7
463 rol $7,%ebp
464 # x3 ^= d
465 xor %rbp,%rsi
466 # d = x15 + x3
467 lea (%r15,%rsi),%rbp
468 # (uint32) d <<<= 9
469 rol $9,%ebp
470 # x7 ^= d
471 xor %rbp,%r8
472 # d = x3 + x7
473 lea (%rsi,%r8),%rbp
474 # (uint32) d <<<= 13
475 rol $13,%ebp
476 # x11 ^= d
477 xor %rbp,%r12
478 # d = x7 + x11
479 lea (%r8,%r12),%rbp
480 # (uint32) d <<<= 18
481 rol $18,%ebp
482 # x15 ^= d
483 xor %rbp,%r15
484 # x15_stack = x15
485 movq %r15,176(%rsp)
486 # x5 = x5_stack
487 movq 160(%rsp),%r15
488 # a = x3 + x0
489 lea (%rsi,%rdx),%rbp
490 # (uint32) a <<<= 7
491 rol $7,%ebp
492 # x1 ^= a
493 xor %rbp,%rdi
494 # b = x4 + x5
495 lea (%r9,%r15),%rbp
496 # (uint32) b <<<= 7
497 rol $7,%ebp
498 # x6 ^= b
499 xor %rbp,%rax
500 # a = x0 + x1
501 lea (%rdx,%rdi),%rbp
502 # (uint32) a <<<= 9
503 rol $9,%ebp
504 # x2 ^= a
505 xor %rbp,%rcx
506 # b = x5 + x6
507 lea (%r15,%rax),%rbp
508 # (uint32) b <<<= 9
509 rol $9,%ebp
510 # x7 ^= b
511 xor %rbp,%r8
512 # a = x1 + x2
513 lea (%rdi,%rcx),%rbp
514 # (uint32) a <<<= 13
515 rol $13,%ebp
516 # x3 ^= a
517 xor %rbp,%rsi
518 # b = x6 + x7
519 lea (%rax,%r8),%rbp
520 # (uint32) b <<<= 13
521 rol $13,%ebp
522 # x4 ^= b
523 xor %rbp,%r9
524 # a = x2 + x3
525 lea (%rcx,%rsi),%rbp
526 # (uint32) a <<<= 18
527 rol $18,%ebp
528 # x0 ^= a
529 xor %rbp,%rdx
530 # b = x7 + x4
531 lea (%r8,%r9),%rbp
532 # (uint32) b <<<= 18
533 rol $18,%ebp
534 # x5 ^= b
535 xor %rbp,%r15
536 # x10 = x10_stack
537 movq 168(%rsp),%rbp
538 # x5_stack = x5
539 movq %r15,160(%rsp)
540 # c = x9 + x10
541 lea (%r10,%rbp),%r15
542 # (uint32) c <<<= 7
543 rol $7,%r15d
544 # x11 ^= c
545 xor %r15,%r12
546 # c = x10 + x11
547 lea (%rbp,%r12),%r15
548 # (uint32) c <<<= 9
549 rol $9,%r15d
550 # x8 ^= c
551 xor %r15,%r11
552 # c = x11 + x8
553 lea (%r12,%r11),%r15
554 # (uint32) c <<<= 13
555 rol $13,%r15d
556 # x9 ^= c
557 xor %r15,%r10
558 # c = x8 + x9
559 lea (%r11,%r10),%r15
560 # (uint32) c <<<= 18
561 rol $18,%r15d
562 # x10 ^= c
563 xor %r15,%rbp
564 # x15 = x15_stack
565 movq 176(%rsp),%r15
566 # x10_stack = x10
567 movq %rbp,168(%rsp)
568 # d = x14 + x15
569 lea (%rbx,%r15),%rbp
570 # (uint32) d <<<= 7
571 rol $7,%ebp
572 # x12 ^= d
573 xor %rbp,%r14
574 # d = x15 + x12
575 lea (%r15,%r14),%rbp
576 # (uint32) d <<<= 9
577 rol $9,%ebp
578 # x13 ^= d
579 xor %rbp,%r13
580 # d = x12 + x13
581 lea (%r14,%r13),%rbp
582 # (uint32) d <<<= 13
583 rol $13,%ebp
584 # x14 ^= d
585 xor %rbp,%rbx
586 # d = x13 + x14
587 lea (%r13,%rbx),%rbp
588 # (uint32) d <<<= 18
589 rol $18,%ebp
590 # x15 ^= d
591 xor %rbp,%r15
592 # x15_stack = x15
593 movq %r15,176(%rsp)
594 # i = i_backup
595 movq 184(%rsp),%r15
596 # unsigned>? i -= 4
597 sub $4,%r15
598 # comment:fp stack unchanged by jump
599 # goto mainloop if unsigned>
600 ja ._mainloop
601 # (uint32) x2 += j2
602 addl 64(%rsp),%ecx
603 # x3 <<= 32
604 shl $32,%rsi
605 # x3 += j2
606 addq 64(%rsp),%rsi
607 # (uint64) x3 >>= 32
608 shr $32,%rsi
609 # x3 <<= 32
610 shl $32,%rsi
611 # x2 += x3
612 add %rsi,%rcx
613 # (uint32) x6 += j6
614 addl 80(%rsp),%eax
615 # x7 <<= 32
616 shl $32,%r8
617 # x7 += j6
618 addq 80(%rsp),%r8
619 # (uint64) x7 >>= 32
620 shr $32,%r8
621 # x7 <<= 32
622 shl $32,%r8
623 # x6 += x7
624 add %r8,%rax
625 # (uint32) x8 += j8
626 addl 88(%rsp),%r11d
627 # x9 <<= 32
628 shl $32,%r10
629 # x9 += j8
630 addq 88(%rsp),%r10
631 # (uint64) x9 >>= 32
632 shr $32,%r10
633 # x9 <<= 32
634 shl $32,%r10
635 # x8 += x9
636 add %r10,%r11
637 # (uint32) x12 += j12
638 addl 104(%rsp),%r14d
639 # x13 <<= 32
640 shl $32,%r13
641 # x13 += j12
642 addq 104(%rsp),%r13
643 # (uint64) x13 >>= 32
644 shr $32,%r13
645 # x13 <<= 32
646 shl $32,%r13
647 # x12 += x13
648 add %r13,%r14
649 # (uint32) x0 += j0
650 addl 56(%rsp),%edx
651 # x1 <<= 32
652 shl $32,%rdi
653 # x1 += j0
654 addq 56(%rsp),%rdi
655 # (uint64) x1 >>= 32
656 shr $32,%rdi
657 # x1 <<= 32
658 shl $32,%rdi
659 # x0 += x1
660 add %rdi,%rdx
661 # x5 = x5_stack
662 movq 160(%rsp),%rdi
663 # (uint32) x4 += j4
664 addl 72(%rsp),%r9d
665 # x5 <<= 32
666 shl $32,%rdi
667 # x5 += j4
668 addq 72(%rsp),%rdi
669 # (uint64) x5 >>= 32
670 shr $32,%rdi
671 # x5 <<= 32
672 shl $32,%rdi
673 # x4 += x5
674 add %rdi,%r9
675 # x10 = x10_stack
676 movq 168(%rsp),%r8
677 # (uint32) x10 += j10
678 addl 96(%rsp),%r8d
679 # x11 <<= 32
680 shl $32,%r12
681 # x11 += j10
682 addq 96(%rsp),%r12
683 # (uint64) x11 >>= 32
684 shr $32,%r12
685 # x11 <<= 32
686 shl $32,%r12
687 # x10 += x11
688 add %r12,%r8
689 # x15 = x15_stack
690 movq 176(%rsp),%rdi
691 # (uint32) x14 += j14
692 addl 112(%rsp),%ebx
693 # x15 <<= 32
694 shl $32,%rdi
695 # x15 += j14
696 addq 112(%rsp),%rdi
697 # (uint64) x15 >>= 32
698 shr $32,%rdi
699 # x15 <<= 32
700 shl $32,%rdi
701 # x14 += x15
702 add %rdi,%rbx
703 # out = out_backup
704 movq 136(%rsp),%rdi
705 # m = m_backup
706 movq 144(%rsp),%rsi
707 # x0 ^= *(uint64 *) (m + 0)
708 xorq 0(%rsi),%rdx
709 # *(uint64 *) (out + 0) = x0
710 movq %rdx,0(%rdi)
711 # x2 ^= *(uint64 *) (m + 8)
712 xorq 8(%rsi),%rcx
713 # *(uint64 *) (out + 8) = x2
714 movq %rcx,8(%rdi)
715 # x4 ^= *(uint64 *) (m + 16)
716 xorq 16(%rsi),%r9
717 # *(uint64 *) (out + 16) = x4
718 movq %r9,16(%rdi)
719 # x6 ^= *(uint64 *) (m + 24)
720 xorq 24(%rsi),%rax
721 # *(uint64 *) (out + 24) = x6
722 movq %rax,24(%rdi)
723 # x8 ^= *(uint64 *) (m + 32)
724 xorq 32(%rsi),%r11
725 # *(uint64 *) (out + 32) = x8
726 movq %r11,32(%rdi)
727 # x10 ^= *(uint64 *) (m + 40)
728 xorq 40(%rsi),%r8
729 # *(uint64 *) (out + 40) = x10
730 movq %r8,40(%rdi)
731 # x12 ^= *(uint64 *) (m + 48)
732 xorq 48(%rsi),%r14
733 # *(uint64 *) (out + 48) = x12
734 movq %r14,48(%rdi)
735 # x14 ^= *(uint64 *) (m + 56)
736 xorq 56(%rsi),%rbx
737 # *(uint64 *) (out + 56) = x14
738 movq %rbx,56(%rdi)
739 # bytes = bytes_backup
740 movq 152(%rsp),%rdx
741 # in8 = j8
742 movq 88(%rsp),%rcx
743 # in8 += 1
744 add $1,%rcx
745 # j8 = in8
746 movq %rcx,88(%rsp)
747 # unsigned>? unsigned<? bytes - 64
748 cmp $64,%rdx
749 # comment:fp stack unchanged by jump
750 # goto bytesatleast65 if unsigned>
751 ja ._bytesatleast65
752 # comment:fp stack unchanged by jump
753 # goto bytesatleast64 if !unsigned<
754 jae ._bytesatleast64
755 # m = out
756 mov %rdi,%rsi
757 # out = ctarget
758 movq 128(%rsp),%rdi
759 # i = bytes
760 mov %rdx,%rcx
761 # while (i) { *out++ = *m++; --i }
762 rep movsb
763 # comment:fp stack unchanged by fallthrough
764# bytesatleast64:
765._bytesatleast64:
766 # x = x_backup
767 movq 120(%rsp),%rdi
768 # in8 = j8
769 movq 88(%rsp),%rsi
770 # *(uint64 *) (x + 32) = in8
771 movq %rsi,32(%rdi)
772 # r11 = r11_stack
773 movq 0(%rsp),%r11
774 # r12 = r12_stack
775 movq 8(%rsp),%r12
776 # r13 = r13_stack
777 movq 16(%rsp),%r13
778 # r14 = r14_stack
779 movq 24(%rsp),%r14
780 # r15 = r15_stack
781 movq 32(%rsp),%r15
782 # rbx = rbx_stack
783 movq 40(%rsp),%rbx
784 # rbp = rbp_stack
785 movq 48(%rsp),%rbp
786 # comment:fp stack unchanged by fallthrough
787# done:
788._done:
789 # leave
790 add %r11,%rsp
791 mov %rdi,%rax
792 mov %rsi,%rdx
793 ret
794# bytesatleast65:
795._bytesatleast65:
796 # bytes -= 64
797 sub $64,%rdx
798 # out += 64
799 add $64,%rdi
800 # m += 64
801 add $64,%rsi
802 # comment:fp stack unchanged by jump
803 # goto bytesatleast1
804 jmp ._bytesatleast1
805# enter ECRYPT_keysetup
806.text
807.p2align 5
808.globl ECRYPT_keysetup
809ECRYPT_keysetup:
810 mov %rsp,%r11
811 and $31,%r11
812 add $256,%r11
813 sub %r11,%rsp
814 # k = arg2
815 mov %rsi,%rsi
816 # kbits = arg3
817 mov %rdx,%rdx
818 # x = arg1
819 mov %rdi,%rdi
820 # in0 = *(uint64 *) (k + 0)
821 movq 0(%rsi),%r8
822 # in2 = *(uint64 *) (k + 8)
823 movq 8(%rsi),%r9
824 # *(uint64 *) (x + 4) = in0
825 movq %r8,4(%rdi)
826 # *(uint64 *) (x + 12) = in2
827 movq %r9,12(%rdi)
828 # unsigned<? kbits - 256
829 cmp $256,%rdx
830 # comment:fp stack unchanged by jump
831 # goto kbits128 if unsigned<
832 jb ._kbits128
833# kbits256:
834._kbits256:
835 # in10 = *(uint64 *) (k + 16)
836 movq 16(%rsi),%rdx
837 # in12 = *(uint64 *) (k + 24)
838 movq 24(%rsi),%rsi
839 # *(uint64 *) (x + 44) = in10
840 movq %rdx,44(%rdi)
841 # *(uint64 *) (x + 52) = in12
842 movq %rsi,52(%rdi)
843 # in0 = 1634760805
844 mov $1634760805,%rsi
845 # in4 = 857760878
846 mov $857760878,%rdx
847 # in10 = 2036477234
848 mov $2036477234,%rcx
849 # in14 = 1797285236
850 mov $1797285236,%r8
851 # *(uint32 *) (x + 0) = in0
852 movl %esi,0(%rdi)
853 # *(uint32 *) (x + 20) = in4
854 movl %edx,20(%rdi)
855 # *(uint32 *) (x + 40) = in10
856 movl %ecx,40(%rdi)
857 # *(uint32 *) (x + 60) = in14
858 movl %r8d,60(%rdi)
859 # comment:fp stack unchanged by jump
860 # goto keysetupdone
861 jmp ._keysetupdone
862# kbits128:
863._kbits128:
864 # in10 = *(uint64 *) (k + 0)
865 movq 0(%rsi),%rdx
866 # in12 = *(uint64 *) (k + 8)
867 movq 8(%rsi),%rsi
868 # *(uint64 *) (x + 44) = in10
869 movq %rdx,44(%rdi)
870 # *(uint64 *) (x + 52) = in12
871 movq %rsi,52(%rdi)
872 # in0 = 1634760805
873 mov $1634760805,%rsi
874 # in4 = 824206446
875 mov $824206446,%rdx
876 # in10 = 2036477238
877 mov $2036477238,%rcx
878 # in14 = 1797285236
879 mov $1797285236,%r8
880 # *(uint32 *) (x + 0) = in0
881 movl %esi,0(%rdi)
882 # *(uint32 *) (x + 20) = in4
883 movl %edx,20(%rdi)
884 # *(uint32 *) (x + 40) = in10
885 movl %ecx,40(%rdi)
886 # *(uint32 *) (x + 60) = in14
887 movl %r8d,60(%rdi)
888# keysetupdone:
889._keysetupdone:
890 # leave
891 add %r11,%rsp
892 mov %rdi,%rax
893 mov %rsi,%rdx
894 ret
895# enter ECRYPT_ivsetup
896.text
897.p2align 5
898.globl ECRYPT_ivsetup
899ECRYPT_ivsetup:
900 mov %rsp,%r11
901 and $31,%r11
902 add $256,%r11
903 sub %r11,%rsp
904 # iv = arg2
905 mov %rsi,%rsi
906 # x = arg1
907 mov %rdi,%rdi
908 # in6 = *(uint64 *) (iv + 0)
909 movq 0(%rsi),%rsi
910 # in8 = 0
911 mov $0,%r8
912 # *(uint64 *) (x + 24) = in6
913 movq %rsi,24(%rdi)
914 # *(uint64 *) (x + 32) = in8
915 movq %r8,32(%rdi)
916 # leave
917 add %r11,%rsp
918 mov %rdi,%rax
919 mov %rsi,%rdx
920 ret
diff --git a/arch/x86/crypto/salsa20_glue.c b/arch/x86/crypto/salsa20_glue.c
new file mode 100644
index 000000000000..bccb76d80987
--- /dev/null
+++ b/arch/x86/crypto/salsa20_glue.c
@@ -0,0 +1,129 @@
1/*
2 * Glue code for optimized assembly version of Salsa20.
3 *
4 * Copyright (c) 2007 Tan Swee Heng <thesweeheng@gmail.com>
5 *
6 * The assembly codes are public domain assembly codes written by Daniel. J.
7 * Bernstein <djb@cr.yp.to>. The codes are modified to include indentation
8 * and to remove extraneous comments and functions that are not needed.
9 * - i586 version, renamed as salsa20-i586-asm_32.S
10 * available from <http://cr.yp.to/snuffle/salsa20/x86-pm/salsa20.s>
11 * - x86-64 version, renamed as salsa20-x86_64-asm_64.S
12 * available from <http://cr.yp.to/snuffle/salsa20/amd64-3/salsa20.s>
13 *
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the Free
16 * Software Foundation; either version 2 of the License, or (at your option)
17 * any later version.
18 *
19 */
20
21#include <crypto/algapi.h>
22#include <linux/module.h>
23#include <linux/crypto.h>
24
25#define SALSA20_IV_SIZE 8U
26#define SALSA20_MIN_KEY_SIZE 16U
27#define SALSA20_MAX_KEY_SIZE 32U
28
29// use the ECRYPT_* function names
30#define salsa20_keysetup ECRYPT_keysetup
31#define salsa20_ivsetup ECRYPT_ivsetup
32#define salsa20_encrypt_bytes ECRYPT_encrypt_bytes
33
34struct salsa20_ctx
35{
36 u32 input[16];
37};
38
39asmlinkage void salsa20_keysetup(struct salsa20_ctx *ctx, const u8 *k,
40 u32 keysize, u32 ivsize);
41asmlinkage void salsa20_ivsetup(struct salsa20_ctx *ctx, const u8 *iv);
42asmlinkage void salsa20_encrypt_bytes(struct salsa20_ctx *ctx,
43 const u8 *src, u8 *dst, u32 bytes);
44
45static int setkey(struct crypto_tfm *tfm, const u8 *key,
46 unsigned int keysize)
47{
48 struct salsa20_ctx *ctx = crypto_tfm_ctx(tfm);
49 salsa20_keysetup(ctx, key, keysize*8, SALSA20_IV_SIZE*8);
50 return 0;
51}
52
53static int encrypt(struct blkcipher_desc *desc,
54 struct scatterlist *dst, struct scatterlist *src,
55 unsigned int nbytes)
56{
57 struct blkcipher_walk walk;
58 struct crypto_blkcipher *tfm = desc->tfm;
59 struct salsa20_ctx *ctx = crypto_blkcipher_ctx(tfm);
60 int err;
61
62 blkcipher_walk_init(&walk, dst, src, nbytes);
63 err = blkcipher_walk_virt_block(desc, &walk, 64);
64
65 salsa20_ivsetup(ctx, walk.iv);
66
67 if (likely(walk.nbytes == nbytes))
68 {
69 salsa20_encrypt_bytes(ctx, walk.src.virt.addr,
70 walk.dst.virt.addr, nbytes);
71 return blkcipher_walk_done(desc, &walk, 0);
72 }
73
74 while (walk.nbytes >= 64) {
75 salsa20_encrypt_bytes(ctx, walk.src.virt.addr,
76 walk.dst.virt.addr,
77 walk.nbytes - (walk.nbytes % 64));
78 err = blkcipher_walk_done(desc, &walk, walk.nbytes % 64);
79 }
80
81 if (walk.nbytes) {
82 salsa20_encrypt_bytes(ctx, walk.src.virt.addr,
83 walk.dst.virt.addr, walk.nbytes);
84 err = blkcipher_walk_done(desc, &walk, 0);
85 }
86
87 return err;
88}
89
90static struct crypto_alg alg = {
91 .cra_name = "salsa20",
92 .cra_driver_name = "salsa20-asm",
93 .cra_priority = 200,
94 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
95 .cra_type = &crypto_blkcipher_type,
96 .cra_blocksize = 1,
97 .cra_ctxsize = sizeof(struct salsa20_ctx),
98 .cra_alignmask = 3,
99 .cra_module = THIS_MODULE,
100 .cra_list = LIST_HEAD_INIT(alg.cra_list),
101 .cra_u = {
102 .blkcipher = {
103 .setkey = setkey,
104 .encrypt = encrypt,
105 .decrypt = encrypt,
106 .min_keysize = SALSA20_MIN_KEY_SIZE,
107 .max_keysize = SALSA20_MAX_KEY_SIZE,
108 .ivsize = SALSA20_IV_SIZE,
109 }
110 }
111};
112
113static int __init init(void)
114{
115 return crypto_register_alg(&alg);
116}
117
118static void __exit fini(void)
119{
120 crypto_unregister_alg(&alg);
121}
122
123module_init(init);
124module_exit(fini);
125
126MODULE_LICENSE("GPL");
127MODULE_DESCRIPTION ("Salsa20 stream cipher algorithm (optimized assembly version)");
128MODULE_ALIAS("salsa20");
129MODULE_ALIAS("salsa20-asm");
diff --git a/arch/x86/crypto/twofish_64.c b/arch/x86/crypto/twofish_64.c
deleted file mode 100644
index 182d91d5cfb9..000000000000
--- a/arch/x86/crypto/twofish_64.c
+++ /dev/null
@@ -1,97 +0,0 @@
1/*
2 * Glue Code for optimized x86_64 assembler version of TWOFISH
3 *
4 * Originally Twofish for GPG
5 * By Matthew Skala <mskala@ansuz.sooke.bc.ca>, July 26, 1998
6 * 256-bit key length added March 20, 1999
7 * Some modifications to reduce the text size by Werner Koch, April, 1998
8 * Ported to the kerneli patch by Marc Mutz <Marc@Mutz.com>
9 * Ported to CryptoAPI by Colin Slater <hoho@tacomeat.net>
10 *
11 * The original author has disclaimed all copyright interest in this
12 * code and thus put it in the public domain. The subsequent authors
13 * have put this under the GNU General Public License.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
28 * USA
29 *
30 * This code is a "clean room" implementation, written from the paper
31 * _Twofish: A 128-Bit Block Cipher_ by Bruce Schneier, John Kelsey,
32 * Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson, available
33 * through http://www.counterpane.com/twofish.html
34 *
35 * For background information on multiplication in finite fields, used for
36 * the matrix operations in the key schedule, see the book _Contemporary
37 * Abstract Algebra_ by Joseph A. Gallian, especially chapter 22 in the
38 * Third Edition.
39 */
40
41#include <crypto/twofish.h>
42#include <linux/crypto.h>
43#include <linux/init.h>
44#include <linux/kernel.h>
45#include <linux/module.h>
46#include <linux/types.h>
47
48asmlinkage void twofish_enc_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
49asmlinkage void twofish_dec_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
50
51static void twofish_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
52{
53 twofish_enc_blk(tfm, dst, src);
54}
55
56static void twofish_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
57{
58 twofish_dec_blk(tfm, dst, src);
59}
60
61static struct crypto_alg alg = {
62 .cra_name = "twofish",
63 .cra_driver_name = "twofish-x86_64",
64 .cra_priority = 200,
65 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
66 .cra_blocksize = TF_BLOCK_SIZE,
67 .cra_ctxsize = sizeof(struct twofish_ctx),
68 .cra_alignmask = 3,
69 .cra_module = THIS_MODULE,
70 .cra_list = LIST_HEAD_INIT(alg.cra_list),
71 .cra_u = {
72 .cipher = {
73 .cia_min_keysize = TF_MIN_KEY_SIZE,
74 .cia_max_keysize = TF_MAX_KEY_SIZE,
75 .cia_setkey = twofish_setkey,
76 .cia_encrypt = twofish_encrypt,
77 .cia_decrypt = twofish_decrypt
78 }
79 }
80};
81
82static int __init init(void)
83{
84 return crypto_register_alg(&alg);
85}
86
87static void __exit fini(void)
88{
89 crypto_unregister_alg(&alg);
90}
91
92module_init(init);
93module_exit(fini);
94
95MODULE_LICENSE("GPL");
96MODULE_DESCRIPTION ("Twofish Cipher Algorithm, x86_64 asm optimized");
97MODULE_ALIAS("twofish");
diff --git a/arch/x86/crypto/twofish_32.c b/arch/x86/crypto/twofish_glue.c
index e3004dfe9c7a..cefaf8b9aa18 100644
--- a/arch/x86/crypto/twofish_32.c
+++ b/arch/x86/crypto/twofish_glue.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Glue Code for optimized 586 assembler version of TWOFISH 2 * Glue Code for assembler optimized version of TWOFISH
3 * 3 *
4 * Originally Twofish for GPG 4 * Originally Twofish for GPG
5 * By Matthew Skala <mskala@ansuz.sooke.bc.ca>, July 26, 1998 5 * By Matthew Skala <mskala@ansuz.sooke.bc.ca>, July 26, 1998
@@ -44,7 +44,6 @@
44#include <linux/module.h> 44#include <linux/module.h>
45#include <linux/types.h> 45#include <linux/types.h>
46 46
47
48asmlinkage void twofish_enc_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src); 47asmlinkage void twofish_enc_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
49asmlinkage void twofish_dec_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src); 48asmlinkage void twofish_dec_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
50 49
@@ -60,7 +59,7 @@ static void twofish_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
60 59
61static struct crypto_alg alg = { 60static struct crypto_alg alg = {
62 .cra_name = "twofish", 61 .cra_name = "twofish",
63 .cra_driver_name = "twofish-i586", 62 .cra_driver_name = "twofish-asm",
64 .cra_priority = 200, 63 .cra_priority = 200,
65 .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 64 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
66 .cra_blocksize = TF_BLOCK_SIZE, 65 .cra_blocksize = TF_BLOCK_SIZE,
@@ -93,5 +92,6 @@ module_init(init);
93module_exit(fini); 92module_exit(fini);
94 93
95MODULE_LICENSE("GPL"); 94MODULE_LICENSE("GPL");
96MODULE_DESCRIPTION ("Twofish Cipher Algorithm, i586 asm optimized"); 95MODULE_DESCRIPTION ("Twofish Cipher Algorithm, asm optimized");
97MODULE_ALIAS("twofish"); 96MODULE_ALIAS("twofish");
97MODULE_ALIAS("twofish-asm");
diff --git a/arch/x86/ia32/Makefile b/arch/x86/ia32/Makefile
index e2edda255a84..52d0ccfcf6ea 100644
--- a/arch/x86/ia32/Makefile
+++ b/arch/x86/ia32/Makefile
@@ -2,9 +2,7 @@
2# Makefile for the ia32 kernel emulation subsystem. 2# Makefile for the ia32 kernel emulation subsystem.
3# 3#
4 4
5obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_signal.o tls32.o \ 5obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_signal.o
6 ia32_binfmt.o fpu32.o ptrace32.o syscall32.o syscall32_syscall.o \
7 mmap32.o
8 6
9sysv-$(CONFIG_SYSVIPC) := ipc32.o 7sysv-$(CONFIG_SYSVIPC) := ipc32.o
10obj-$(CONFIG_IA32_EMULATION) += $(sysv-y) 8obj-$(CONFIG_IA32_EMULATION) += $(sysv-y)
@@ -13,40 +11,3 @@ obj-$(CONFIG_IA32_AOUT) += ia32_aout.o
13 11
14audit-class-$(CONFIG_AUDIT) := audit.o 12audit-class-$(CONFIG_AUDIT) := audit.o
15obj-$(CONFIG_IA32_EMULATION) += $(audit-class-y) 13obj-$(CONFIG_IA32_EMULATION) += $(audit-class-y)
16
17$(obj)/syscall32_syscall.o: \
18 $(foreach F,sysenter syscall,$(obj)/vsyscall-$F.so)
19
20# Teach kbuild about targets
21targets := $(foreach F,$(addprefix vsyscall-,sysenter syscall),\
22 $F.o $F.so $F.so.dbg)
23
24# The DSO images are built using a special linker script
25quiet_cmd_syscall = SYSCALL $@
26 cmd_syscall = $(CC) -m32 -nostdlib -shared \
27 $(call ld-option, -Wl$(comma)--hash-style=sysv) \
28 -Wl,-soname=linux-gate.so.1 -o $@ \
29 -Wl,-T,$(filter-out FORCE,$^)
30
31$(obj)/%.so: OBJCOPYFLAGS := -S
32$(obj)/%.so: $(obj)/%.so.dbg FORCE
33 $(call if_changed,objcopy)
34
35$(obj)/vsyscall-sysenter.so.dbg $(obj)/vsyscall-syscall.so.dbg: \
36$(obj)/vsyscall-%.so.dbg: $(src)/vsyscall.lds $(obj)/vsyscall-%.o FORCE
37 $(call if_changed,syscall)
38
39AFLAGS_vsyscall-sysenter.o = -m32 -Wa,-32
40AFLAGS_vsyscall-syscall.o = -m32 -Wa,-32
41
42vdsos := vdso32-sysenter.so vdso32-syscall.so
43
44quiet_cmd_vdso_install = INSTALL $@
45 cmd_vdso_install = cp $(@:vdso32-%.so=$(obj)/vsyscall-%.so.dbg) \
46 $(MODLIB)/vdso/$@
47
48$(vdsos):
49 @mkdir -p $(MODLIB)/vdso
50 $(call cmd,vdso_install)
51
52vdso_install: $(vdsos)
diff --git a/arch/x86/ia32/audit.c b/arch/x86/ia32/audit.c
index 91b7b5922dfa..5d7b381da692 100644
--- a/arch/x86/ia32/audit.c
+++ b/arch/x86/ia32/audit.c
@@ -27,7 +27,7 @@ unsigned ia32_signal_class[] = {
27 27
28int ia32_classify_syscall(unsigned syscall) 28int ia32_classify_syscall(unsigned syscall)
29{ 29{
30 switch(syscall) { 30 switch (syscall) {
31 case __NR_open: 31 case __NR_open:
32 return 2; 32 return 2;
33 case __NR_openat: 33 case __NR_openat:
diff --git a/arch/x86/ia32/fpu32.c b/arch/x86/ia32/fpu32.c
deleted file mode 100644
index 2c8209a3605a..000000000000
--- a/arch/x86/ia32/fpu32.c
+++ /dev/null
@@ -1,183 +0,0 @@
1/*
2 * Copyright 2002 Andi Kleen, SuSE Labs.
3 * FXSAVE<->i387 conversion support. Based on code by Gareth Hughes.
4 * This is used for ptrace, signals and coredumps in 32bit emulation.
5 */
6
7#include <linux/sched.h>
8#include <asm/sigcontext32.h>
9#include <asm/processor.h>
10#include <asm/uaccess.h>
11#include <asm/i387.h>
12
13static inline unsigned short twd_i387_to_fxsr(unsigned short twd)
14{
15 unsigned int tmp; /* to avoid 16 bit prefixes in the code */
16
17 /* Transform each pair of bits into 01 (valid) or 00 (empty) */
18 tmp = ~twd;
19 tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
20 /* and move the valid bits to the lower byte. */
21 tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
22 tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
23 tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
24 return tmp;
25}
26
27static inline unsigned long twd_fxsr_to_i387(struct i387_fxsave_struct *fxsave)
28{
29 struct _fpxreg *st = NULL;
30 unsigned long tos = (fxsave->swd >> 11) & 7;
31 unsigned long twd = (unsigned long) fxsave->twd;
32 unsigned long tag;
33 unsigned long ret = 0xffff0000;
34 int i;
35
36#define FPREG_ADDR(f, n) ((void *)&(f)->st_space + (n) * 16);
37
38 for (i = 0 ; i < 8 ; i++) {
39 if (twd & 0x1) {
40 st = FPREG_ADDR( fxsave, (i - tos) & 7 );
41
42 switch (st->exponent & 0x7fff) {
43 case 0x7fff:
44 tag = 2; /* Special */
45 break;
46 case 0x0000:
47 if ( !st->significand[0] &&
48 !st->significand[1] &&
49 !st->significand[2] &&
50 !st->significand[3] ) {
51 tag = 1; /* Zero */
52 } else {
53 tag = 2; /* Special */
54 }
55 break;
56 default:
57 if (st->significand[3] & 0x8000) {
58 tag = 0; /* Valid */
59 } else {
60 tag = 2; /* Special */
61 }
62 break;
63 }
64 } else {
65 tag = 3; /* Empty */
66 }
67 ret |= (tag << (2 * i));
68 twd = twd >> 1;
69 }
70 return ret;
71}
72
73
74static inline int convert_fxsr_from_user(struct i387_fxsave_struct *fxsave,
75 struct _fpstate_ia32 __user *buf)
76{
77 struct _fpxreg *to;
78 struct _fpreg __user *from;
79 int i;
80 u32 v;
81 int err = 0;
82
83#define G(num,val) err |= __get_user(val, num + (u32 __user *)buf)
84 G(0, fxsave->cwd);
85 G(1, fxsave->swd);
86 G(2, fxsave->twd);
87 fxsave->twd = twd_i387_to_fxsr(fxsave->twd);
88 G(3, fxsave->rip);
89 G(4, v);
90 fxsave->fop = v>>16; /* cs ignored */
91 G(5, fxsave->rdp);
92 /* 6: ds ignored */
93#undef G
94 if (err)
95 return -1;
96
97 to = (struct _fpxreg *)&fxsave->st_space[0];
98 from = &buf->_st[0];
99 for (i = 0 ; i < 8 ; i++, to++, from++) {
100 if (__copy_from_user(to, from, sizeof(*from)))
101 return -1;
102 }
103 return 0;
104}
105
106
107static inline int convert_fxsr_to_user(struct _fpstate_ia32 __user *buf,
108 struct i387_fxsave_struct *fxsave,
109 struct pt_regs *regs,
110 struct task_struct *tsk)
111{
112 struct _fpreg __user *to;
113 struct _fpxreg *from;
114 int i;
115 u16 cs,ds;
116 int err = 0;
117
118 if (tsk == current) {
119 /* should be actually ds/cs at fpu exception time,
120 but that information is not available in 64bit mode. */
121 asm("movw %%ds,%0 " : "=r" (ds));
122 asm("movw %%cs,%0 " : "=r" (cs));
123 } else { /* ptrace. task has stopped. */
124 ds = tsk->thread.ds;
125 cs = regs->cs;
126 }
127
128#define P(num,val) err |= __put_user(val, num + (u32 __user *)buf)
129 P(0, (u32)fxsave->cwd | 0xffff0000);
130 P(1, (u32)fxsave->swd | 0xffff0000);
131 P(2, twd_fxsr_to_i387(fxsave));
132 P(3, (u32)fxsave->rip);
133 P(4, cs | ((u32)fxsave->fop) << 16);
134 P(5, fxsave->rdp);
135 P(6, 0xffff0000 | ds);
136#undef P
137
138 if (err)
139 return -1;
140
141 to = &buf->_st[0];
142 from = (struct _fpxreg *) &fxsave->st_space[0];
143 for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
144 if (__copy_to_user(to, from, sizeof(*to)))
145 return -1;
146 }
147 return 0;
148}
149
150int restore_i387_ia32(struct task_struct *tsk, struct _fpstate_ia32 __user *buf, int fsave)
151{
152 clear_fpu(tsk);
153 if (!fsave) {
154 if (__copy_from_user(&tsk->thread.i387.fxsave,
155 &buf->_fxsr_env[0],
156 sizeof(struct i387_fxsave_struct)))
157 return -1;
158 tsk->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask;
159 set_stopped_child_used_math(tsk);
160 }
161 return convert_fxsr_from_user(&tsk->thread.i387.fxsave, buf);
162}
163
164int save_i387_ia32(struct task_struct *tsk,
165 struct _fpstate_ia32 __user *buf,
166 struct pt_regs *regs,
167 int fsave)
168{
169 int err = 0;
170
171 init_fpu(tsk);
172 if (convert_fxsr_to_user(buf, &tsk->thread.i387.fxsave, regs, tsk))
173 return -1;
174 if (fsave)
175 return 0;
176 err |= __put_user(tsk->thread.i387.fxsave.swd, &buf->status);
177 if (fsave)
178 return err ? -1 : 1;
179 err |= __put_user(X86_FXSR_MAGIC, &buf->magic);
180 err |= __copy_to_user(&buf->_fxsr_env[0], &tsk->thread.i387.fxsave,
181 sizeof(struct i387_fxsave_struct));
182 return err ? -1 : 1;
183}
diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c
index f82e1a94fcb7..e4c12079171b 100644
--- a/arch/x86/ia32/ia32_aout.c
+++ b/arch/x86/ia32/ia32_aout.c
@@ -25,6 +25,7 @@
25#include <linux/binfmts.h> 25#include <linux/binfmts.h>
26#include <linux/personality.h> 26#include <linux/personality.h>
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/jiffies.h>
28 29
29#include <asm/system.h> 30#include <asm/system.h>
30#include <asm/uaccess.h> 31#include <asm/uaccess.h>
@@ -36,61 +37,67 @@
36#undef WARN_OLD 37#undef WARN_OLD
37#undef CORE_DUMP /* probably broken */ 38#undef CORE_DUMP /* probably broken */
38 39
39static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs); 40static int load_aout_binary(struct linux_binprm *, struct pt_regs *regs);
40static int load_aout_library(struct file*); 41static int load_aout_library(struct file *);
41 42
42#ifdef CORE_DUMP 43#ifdef CORE_DUMP
43static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit); 44static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file,
45 unsigned long limit);
44 46
45/* 47/*
46 * fill in the user structure for a core dump.. 48 * fill in the user structure for a core dump..
47 */ 49 */
48static void dump_thread32(struct pt_regs * regs, struct user32 * dump) 50static void dump_thread32(struct pt_regs *regs, struct user32 *dump)
49{ 51{
50 u32 fs,gs; 52 u32 fs, gs;
51 53
52/* changed the size calculations - should hopefully work better. lbt */ 54/* changed the size calculations - should hopefully work better. lbt */
53 dump->magic = CMAGIC; 55 dump->magic = CMAGIC;
54 dump->start_code = 0; 56 dump->start_code = 0;
55 dump->start_stack = regs->rsp & ~(PAGE_SIZE - 1); 57 dump->start_stack = regs->sp & ~(PAGE_SIZE - 1);
56 dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT; 58 dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
57 dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> PAGE_SHIFT; 59 dump->u_dsize = ((unsigned long)
60 (current->mm->brk + (PAGE_SIZE-1))) >> PAGE_SHIFT;
58 dump->u_dsize -= dump->u_tsize; 61 dump->u_dsize -= dump->u_tsize;
59 dump->u_ssize = 0; 62 dump->u_ssize = 0;
60 dump->u_debugreg[0] = current->thread.debugreg0; 63 dump->u_debugreg[0] = current->thread.debugreg0;
61 dump->u_debugreg[1] = current->thread.debugreg1; 64 dump->u_debugreg[1] = current->thread.debugreg1;
62 dump->u_debugreg[2] = current->thread.debugreg2; 65 dump->u_debugreg[2] = current->thread.debugreg2;
63 dump->u_debugreg[3] = current->thread.debugreg3; 66 dump->u_debugreg[3] = current->thread.debugreg3;
64 dump->u_debugreg[4] = 0; 67 dump->u_debugreg[4] = 0;
65 dump->u_debugreg[5] = 0; 68 dump->u_debugreg[5] = 0;
66 dump->u_debugreg[6] = current->thread.debugreg6; 69 dump->u_debugreg[6] = current->thread.debugreg6;
67 dump->u_debugreg[7] = current->thread.debugreg7; 70 dump->u_debugreg[7] = current->thread.debugreg7;
68 71
69 if (dump->start_stack < 0xc0000000) 72 if (dump->start_stack < 0xc0000000) {
70 dump->u_ssize = ((unsigned long) (0xc0000000 - dump->start_stack)) >> PAGE_SHIFT; 73 unsigned long tmp;
71 74
72 dump->regs.ebx = regs->rbx; 75 tmp = (unsigned long) (0xc0000000 - dump->start_stack);
73 dump->regs.ecx = regs->rcx; 76 dump->u_ssize = tmp >> PAGE_SHIFT;
74 dump->regs.edx = regs->rdx; 77 }
75 dump->regs.esi = regs->rsi; 78
76 dump->regs.edi = regs->rdi; 79 dump->regs.bx = regs->bx;
77 dump->regs.ebp = regs->rbp; 80 dump->regs.cx = regs->cx;
78 dump->regs.eax = regs->rax; 81 dump->regs.dx = regs->dx;
82 dump->regs.si = regs->si;
83 dump->regs.di = regs->di;
84 dump->regs.bp = regs->bp;
85 dump->regs.ax = regs->ax;
79 dump->regs.ds = current->thread.ds; 86 dump->regs.ds = current->thread.ds;
80 dump->regs.es = current->thread.es; 87 dump->regs.es = current->thread.es;
81 asm("movl %%fs,%0" : "=r" (fs)); dump->regs.fs = fs; 88 asm("movl %%fs,%0" : "=r" (fs)); dump->regs.fs = fs;
82 asm("movl %%gs,%0" : "=r" (gs)); dump->regs.gs = gs; 89 asm("movl %%gs,%0" : "=r" (gs)); dump->regs.gs = gs;
83 dump->regs.orig_eax = regs->orig_rax; 90 dump->regs.orig_ax = regs->orig_ax;
84 dump->regs.eip = regs->rip; 91 dump->regs.ip = regs->ip;
85 dump->regs.cs = regs->cs; 92 dump->regs.cs = regs->cs;
86 dump->regs.eflags = regs->eflags; 93 dump->regs.flags = regs->flags;
87 dump->regs.esp = regs->rsp; 94 dump->regs.sp = regs->sp;
88 dump->regs.ss = regs->ss; 95 dump->regs.ss = regs->ss;
89 96
90#if 1 /* FIXME */ 97#if 1 /* FIXME */
91 dump->u_fpvalid = 0; 98 dump->u_fpvalid = 0;
92#else 99#else
93 dump->u_fpvalid = dump_fpu (regs, &dump->i387); 100 dump->u_fpvalid = dump_fpu(regs, &dump->i387);
94#endif 101#endif
95} 102}
96 103
@@ -128,15 +135,19 @@ static int dump_write(struct file *file, const void *addr, int nr)
128 return file->f_op->write(file, addr, nr, &file->f_pos) == nr; 135 return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
129} 136}
130 137
131#define DUMP_WRITE(addr, nr) \ 138#define DUMP_WRITE(addr, nr) \
132 if (!dump_write(file, (void *)(addr), (nr))) \ 139 if (!dump_write(file, (void *)(addr), (nr))) \
133 goto end_coredump; 140 goto end_coredump;
134 141
135#define DUMP_SEEK(offset) \ 142#define DUMP_SEEK(offset) \
136if (file->f_op->llseek) { \ 143 if (file->f_op->llseek) { \
137 if (file->f_op->llseek(file,(offset),0) != (offset)) \ 144 if (file->f_op->llseek(file, (offset), 0) != (offset)) \
138 goto end_coredump; \ 145 goto end_coredump; \
139} else file->f_pos = (offset) 146 } else \
147 file->f_pos = (offset)
148
149#define START_DATA() (u.u_tsize << PAGE_SHIFT)
150#define START_STACK(u) (u.start_stack)
140 151
141/* 152/*
142 * Routine writes a core dump image in the current directory. 153 * Routine writes a core dump image in the current directory.
@@ -148,62 +159,70 @@ if (file->f_op->llseek) { \
148 * dumping of the process results in another error.. 159 * dumping of the process results in another error..
149 */ 160 */
150 161
151static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit) 162static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file,
163 unsigned long limit)
152{ 164{
153 mm_segment_t fs; 165 mm_segment_t fs;
154 int has_dumped = 0; 166 int has_dumped = 0;
155 unsigned long dump_start, dump_size; 167 unsigned long dump_start, dump_size;
156 struct user32 dump; 168 struct user32 dump;
157# define START_DATA(u) (u.u_tsize << PAGE_SHIFT)
158# define START_STACK(u) (u.start_stack)
159 169
160 fs = get_fs(); 170 fs = get_fs();
161 set_fs(KERNEL_DS); 171 set_fs(KERNEL_DS);
162 has_dumped = 1; 172 has_dumped = 1;
163 current->flags |= PF_DUMPCORE; 173 current->flags |= PF_DUMPCORE;
164 strncpy(dump.u_comm, current->comm, sizeof(current->comm)); 174 strncpy(dump.u_comm, current->comm, sizeof(current->comm));
165 dump.u_ar0 = (u32)(((unsigned long)(&dump.regs)) - ((unsigned long)(&dump))); 175 dump.u_ar0 = (u32)(((unsigned long)(&dump.regs)) -
176 ((unsigned long)(&dump)));
166 dump.signal = signr; 177 dump.signal = signr;
167 dump_thread32(regs, &dump); 178 dump_thread32(regs, &dump);
168 179
169/* If the size of the dump file exceeds the rlimit, then see what would happen 180 /*
170 if we wrote the stack, but not the data area. */ 181 * If the size of the dump file exceeds the rlimit, then see
182 * what would happen if we wrote the stack, but not the data
183 * area.
184 */
171 if ((dump.u_dsize + dump.u_ssize + 1) * PAGE_SIZE > limit) 185 if ((dump.u_dsize + dump.u_ssize + 1) * PAGE_SIZE > limit)
172 dump.u_dsize = 0; 186 dump.u_dsize = 0;
173 187
174/* Make sure we have enough room to write the stack and data areas. */ 188 /* Make sure we have enough room to write the stack and data areas. */
175 if ((dump.u_ssize + 1) * PAGE_SIZE > limit) 189 if ((dump.u_ssize + 1) * PAGE_SIZE > limit)
176 dump.u_ssize = 0; 190 dump.u_ssize = 0;
177 191
178/* make sure we actually have a data and stack area to dump */ 192 /* make sure we actually have a data and stack area to dump */
179 set_fs(USER_DS); 193 set_fs(USER_DS);
180 if (!access_ok(VERIFY_READ, (void *) (unsigned long)START_DATA(dump), dump.u_dsize << PAGE_SHIFT)) 194 if (!access_ok(VERIFY_READ, (void *) (unsigned long)START_DATA(dump),
195 dump.u_dsize << PAGE_SHIFT))
181 dump.u_dsize = 0; 196 dump.u_dsize = 0;
182 if (!access_ok(VERIFY_READ, (void *) (unsigned long)START_STACK(dump), dump.u_ssize << PAGE_SHIFT)) 197 if (!access_ok(VERIFY_READ, (void *) (unsigned long)START_STACK(dump),
198 dump.u_ssize << PAGE_SHIFT))
183 dump.u_ssize = 0; 199 dump.u_ssize = 0;
184 200
185 set_fs(KERNEL_DS); 201 set_fs(KERNEL_DS);
186/* struct user */ 202 /* struct user */
187 DUMP_WRITE(&dump,sizeof(dump)); 203 DUMP_WRITE(&dump, sizeof(dump));
188/* Now dump all of the user data. Include malloced stuff as well */ 204 /* Now dump all of the user data. Include malloced stuff as well */
189 DUMP_SEEK(PAGE_SIZE); 205 DUMP_SEEK(PAGE_SIZE);
190/* now we start writing out the user space info */ 206 /* now we start writing out the user space info */
191 set_fs(USER_DS); 207 set_fs(USER_DS);
192/* Dump the data area */ 208 /* Dump the data area */
193 if (dump.u_dsize != 0) { 209 if (dump.u_dsize != 0) {
194 dump_start = START_DATA(dump); 210 dump_start = START_DATA(dump);
195 dump_size = dump.u_dsize << PAGE_SHIFT; 211 dump_size = dump.u_dsize << PAGE_SHIFT;
196 DUMP_WRITE(dump_start,dump_size); 212 DUMP_WRITE(dump_start, dump_size);
197 } 213 }
198/* Now prepare to dump the stack area */ 214 /* Now prepare to dump the stack area */
199 if (dump.u_ssize != 0) { 215 if (dump.u_ssize != 0) {
200 dump_start = START_STACK(dump); 216 dump_start = START_STACK(dump);
201 dump_size = dump.u_ssize << PAGE_SHIFT; 217 dump_size = dump.u_ssize << PAGE_SHIFT;
202 DUMP_WRITE(dump_start,dump_size); 218 DUMP_WRITE(dump_start, dump_size);
203 } 219 }
204/* Finally dump the task struct. Not be used by gdb, but could be useful */ 220 /*
221 * Finally dump the task struct. Not be used by gdb, but
222 * could be useful
223 */
205 set_fs(KERNEL_DS); 224 set_fs(KERNEL_DS);
206 DUMP_WRITE(current,sizeof(*current)); 225 DUMP_WRITE(current, sizeof(*current));
207end_coredump: 226end_coredump:
208 set_fs(fs); 227 set_fs(fs);
209 return has_dumped; 228 return has_dumped;
@@ -217,35 +236,34 @@ end_coredump:
217 */ 236 */
218static u32 __user *create_aout_tables(char __user *p, struct linux_binprm *bprm) 237static u32 __user *create_aout_tables(char __user *p, struct linux_binprm *bprm)
219{ 238{
220 u32 __user *argv; 239 u32 __user *argv, *envp, *sp;
221 u32 __user *envp; 240 int argc = bprm->argc, envc = bprm->envc;
222 u32 __user *sp;
223 int argc = bprm->argc;
224 int envc = bprm->envc;
225 241
226 sp = (u32 __user *) ((-(unsigned long)sizeof(u32)) & (unsigned long) p); 242 sp = (u32 __user *) ((-(unsigned long)sizeof(u32)) & (unsigned long) p);
227 sp -= envc+1; 243 sp -= envc+1;
228 envp = sp; 244 envp = sp;
229 sp -= argc+1; 245 sp -= argc+1;
230 argv = sp; 246 argv = sp;
231 put_user((unsigned long) envp,--sp); 247 put_user((unsigned long) envp, --sp);
232 put_user((unsigned long) argv,--sp); 248 put_user((unsigned long) argv, --sp);
233 put_user(argc,--sp); 249 put_user(argc, --sp);
234 current->mm->arg_start = (unsigned long) p; 250 current->mm->arg_start = (unsigned long) p;
235 while (argc-->0) { 251 while (argc-- > 0) {
236 char c; 252 char c;
237 put_user((u32)(unsigned long)p,argv++); 253
254 put_user((u32)(unsigned long)p, argv++);
238 do { 255 do {
239 get_user(c,p++); 256 get_user(c, p++);
240 } while (c); 257 } while (c);
241 } 258 }
242 put_user(0, argv); 259 put_user(0, argv);
243 current->mm->arg_end = current->mm->env_start = (unsigned long) p; 260 current->mm->arg_end = current->mm->env_start = (unsigned long) p;
244 while (envc-->0) { 261 while (envc-- > 0) {
245 char c; 262 char c;
246 put_user((u32)(unsigned long)p,envp++); 263
264 put_user((u32)(unsigned long)p, envp++);
247 do { 265 do {
248 get_user(c,p++); 266 get_user(c, p++);
249 } while (c); 267 } while (c);
250 } 268 }
251 put_user(0, envp); 269 put_user(0, envp);
@@ -257,20 +275,18 @@ static u32 __user *create_aout_tables(char __user *p, struct linux_binprm *bprm)
257 * These are the functions used to load a.out style executables and shared 275 * These are the functions used to load a.out style executables and shared
258 * libraries. There is no binary dependent code anywhere else. 276 * libraries. There is no binary dependent code anywhere else.
259 */ 277 */
260 278static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs)
261static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
262{ 279{
280 unsigned long error, fd_offset, rlim;
263 struct exec ex; 281 struct exec ex;
264 unsigned long error;
265 unsigned long fd_offset;
266 unsigned long rlim;
267 int retval; 282 int retval;
268 283
269 ex = *((struct exec *) bprm->buf); /* exec-header */ 284 ex = *((struct exec *) bprm->buf); /* exec-header */
270 if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC && 285 if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC &&
271 N_MAGIC(ex) != QMAGIC && N_MAGIC(ex) != NMAGIC) || 286 N_MAGIC(ex) != QMAGIC && N_MAGIC(ex) != NMAGIC) ||
272 N_TRSIZE(ex) || N_DRSIZE(ex) || 287 N_TRSIZE(ex) || N_DRSIZE(ex) ||
273 i_size_read(bprm->file->f_path.dentry->d_inode) < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) { 288 i_size_read(bprm->file->f_path.dentry->d_inode) <
289 ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) {
274 return -ENOEXEC; 290 return -ENOEXEC;
275 } 291 }
276 292
@@ -291,13 +307,13 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
291 if (retval) 307 if (retval)
292 return retval; 308 return retval;
293 309
294 regs->cs = __USER32_CS; 310 regs->cs = __USER32_CS;
295 regs->r8 = regs->r9 = regs->r10 = regs->r11 = regs->r12 = 311 regs->r8 = regs->r9 = regs->r10 = regs->r11 = regs->r12 =
296 regs->r13 = regs->r14 = regs->r15 = 0; 312 regs->r13 = regs->r14 = regs->r15 = 0;
297 313
298 /* OK, This is the point of no return */ 314 /* OK, This is the point of no return */
299 set_personality(PER_LINUX); 315 set_personality(PER_LINUX);
300 set_thread_flag(TIF_IA32); 316 set_thread_flag(TIF_IA32);
301 clear_thread_flag(TIF_ABI_PENDING); 317 clear_thread_flag(TIF_ABI_PENDING);
302 318
303 current->mm->end_code = ex.a_text + 319 current->mm->end_code = ex.a_text +
@@ -311,7 +327,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
311 327
312 current->mm->mmap = NULL; 328 current->mm->mmap = NULL;
313 compute_creds(bprm); 329 compute_creds(bprm);
314 current->flags &= ~PF_FORKNOEXEC; 330 current->flags &= ~PF_FORKNOEXEC;
315 331
316 if (N_MAGIC(ex) == OMAGIC) { 332 if (N_MAGIC(ex) == OMAGIC) {
317 unsigned long text_addr, map_size; 333 unsigned long text_addr, map_size;
@@ -338,30 +354,31 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
338 send_sig(SIGKILL, current, 0); 354 send_sig(SIGKILL, current, 0);
339 return error; 355 return error;
340 } 356 }
341 357
342 flush_icache_range(text_addr, text_addr+ex.a_text+ex.a_data); 358 flush_icache_range(text_addr, text_addr+ex.a_text+ex.a_data);
343 } else { 359 } else {
344#ifdef WARN_OLD 360#ifdef WARN_OLD
345 static unsigned long error_time, error_time2; 361 static unsigned long error_time, error_time2;
346 if ((ex.a_text & 0xfff || ex.a_data & 0xfff) && 362 if ((ex.a_text & 0xfff || ex.a_data & 0xfff) &&
347 (N_MAGIC(ex) != NMAGIC) && (jiffies-error_time2) > 5*HZ) 363 (N_MAGIC(ex) != NMAGIC) &&
348 { 364 time_after(jiffies, error_time2 + 5*HZ)) {
349 printk(KERN_NOTICE "executable not page aligned\n"); 365 printk(KERN_NOTICE "executable not page aligned\n");
350 error_time2 = jiffies; 366 error_time2 = jiffies;
351 } 367 }
352 368
353 if ((fd_offset & ~PAGE_MASK) != 0 && 369 if ((fd_offset & ~PAGE_MASK) != 0 &&
354 (jiffies-error_time) > 5*HZ) 370 time_after(jiffies, error_time + 5*HZ)) {
355 { 371 printk(KERN_WARNING
356 printk(KERN_WARNING 372 "fd_offset is not page aligned. Please convert "
357 "fd_offset is not page aligned. Please convert program: %s\n", 373 "program: %s\n",
358 bprm->file->f_path.dentry->d_name.name); 374 bprm->file->f_path.dentry->d_name.name);
359 error_time = jiffies; 375 error_time = jiffies;
360 } 376 }
361#endif 377#endif
362 378
363 if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) { 379 if (!bprm->file->f_op->mmap || (fd_offset & ~PAGE_MASK) != 0) {
364 loff_t pos = fd_offset; 380 loff_t pos = fd_offset;
381
365 down_write(&current->mm->mmap_sem); 382 down_write(&current->mm->mmap_sem);
366 do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); 383 do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
367 up_write(&current->mm->mmap_sem); 384 up_write(&current->mm->mmap_sem);
@@ -376,9 +393,10 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
376 393
377 down_write(&current->mm->mmap_sem); 394 down_write(&current->mm->mmap_sem);
378 error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text, 395 error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text,
379 PROT_READ | PROT_EXEC, 396 PROT_READ | PROT_EXEC,
380 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE | MAP_32BIT, 397 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE |
381 fd_offset); 398 MAP_EXECUTABLE | MAP_32BIT,
399 fd_offset);
382 up_write(&current->mm->mmap_sem); 400 up_write(&current->mm->mmap_sem);
383 401
384 if (error != N_TXTADDR(ex)) { 402 if (error != N_TXTADDR(ex)) {
@@ -387,9 +405,10 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
387 } 405 }
388 406
389 down_write(&current->mm->mmap_sem); 407 down_write(&current->mm->mmap_sem);
390 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data, 408 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
391 PROT_READ | PROT_WRITE | PROT_EXEC, 409 PROT_READ | PROT_WRITE | PROT_EXEC,
392 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE | MAP_32BIT, 410 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE |
411 MAP_EXECUTABLE | MAP_32BIT,
393 fd_offset + ex.a_text); 412 fd_offset + ex.a_text);
394 up_write(&current->mm->mmap_sem); 413 up_write(&current->mm->mmap_sem);
395 if (error != N_DATADDR(ex)) { 414 if (error != N_DATADDR(ex)) {
@@ -403,9 +422,9 @@ beyond_if:
403 set_brk(current->mm->start_brk, current->mm->brk); 422 set_brk(current->mm->start_brk, current->mm->brk);
404 423
405 retval = setup_arg_pages(bprm, IA32_STACK_TOP, EXSTACK_DEFAULT); 424 retval = setup_arg_pages(bprm, IA32_STACK_TOP, EXSTACK_DEFAULT);
406 if (retval < 0) { 425 if (retval < 0) {
407 /* Someone check-me: is this error path enough? */ 426 /* Someone check-me: is this error path enough? */
408 send_sig(SIGKILL, current, 0); 427 send_sig(SIGKILL, current, 0);
409 return retval; 428 return retval;
410 } 429 }
411 430
@@ -414,10 +433,10 @@ beyond_if:
414 /* start thread */ 433 /* start thread */
415 asm volatile("movl %0,%%fs" :: "r" (0)); \ 434 asm volatile("movl %0,%%fs" :: "r" (0)); \
416 asm volatile("movl %0,%%es; movl %0,%%ds": :"r" (__USER32_DS)); 435 asm volatile("movl %0,%%es; movl %0,%%ds": :"r" (__USER32_DS));
417 load_gs_index(0); 436 load_gs_index(0);
418 (regs)->rip = ex.a_entry; 437 (regs)->ip = ex.a_entry;
419 (regs)->rsp = current->mm->start_stack; 438 (regs)->sp = current->mm->start_stack;
420 (regs)->eflags = 0x200; 439 (regs)->flags = 0x200;
421 (regs)->cs = __USER32_CS; 440 (regs)->cs = __USER32_CS;
422 (regs)->ss = __USER32_DS; 441 (regs)->ss = __USER32_DS;
423 regs->r8 = regs->r9 = regs->r10 = regs->r11 = 442 regs->r8 = regs->r9 = regs->r10 = regs->r11 =
@@ -425,7 +444,7 @@ beyond_if:
425 set_fs(USER_DS); 444 set_fs(USER_DS);
426 if (unlikely(current->ptrace & PT_PTRACED)) { 445 if (unlikely(current->ptrace & PT_PTRACED)) {
427 if (current->ptrace & PT_TRACE_EXEC) 446 if (current->ptrace & PT_TRACE_EXEC)
428 ptrace_notify ((PTRACE_EVENT_EXEC << 8) | SIGTRAP); 447 ptrace_notify((PTRACE_EVENT_EXEC << 8) | SIGTRAP);
429 else 448 else
430 send_sig(SIGTRAP, current, 0); 449 send_sig(SIGTRAP, current, 0);
431 } 450 }
@@ -434,9 +453,8 @@ beyond_if:
434 453
435static int load_aout_library(struct file *file) 454static int load_aout_library(struct file *file)
436{ 455{
437 struct inode * inode; 456 struct inode *inode;
438 unsigned long bss, start_addr, len; 457 unsigned long bss, start_addr, len, error;
439 unsigned long error;
440 int retval; 458 int retval;
441 struct exec ex; 459 struct exec ex;
442 460
@@ -450,7 +468,8 @@ static int load_aout_library(struct file *file)
450 /* We come in here for the regular a.out style of shared libraries */ 468 /* We come in here for the regular a.out style of shared libraries */
451 if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != QMAGIC) || N_TRSIZE(ex) || 469 if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != QMAGIC) || N_TRSIZE(ex) ||
452 N_DRSIZE(ex) || ((ex.a_entry & 0xfff) && N_MAGIC(ex) == ZMAGIC) || 470 N_DRSIZE(ex) || ((ex.a_entry & 0xfff) && N_MAGIC(ex) == ZMAGIC) ||
453 i_size_read(inode) < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) { 471 i_size_read(inode) <
472 ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) {
454 goto out; 473 goto out;
455 } 474 }
456 475
@@ -467,10 +486,10 @@ static int load_aout_library(struct file *file)
467 486
468#ifdef WARN_OLD 487#ifdef WARN_OLD
469 static unsigned long error_time; 488 static unsigned long error_time;
470 if ((jiffies-error_time) > 5*HZ) 489 if (time_after(jiffies, error_time + 5*HZ)) {
471 { 490 printk(KERN_WARNING
472 printk(KERN_WARNING 491 "N_TXTOFF is not page aligned. Please convert "
473 "N_TXTOFF is not page aligned. Please convert library: %s\n", 492 "library: %s\n",
474 file->f_path.dentry->d_name.name); 493 file->f_path.dentry->d_name.name);
475 error_time = jiffies; 494 error_time = jiffies;
476 } 495 }
@@ -478,11 +497,12 @@ static int load_aout_library(struct file *file)
478 down_write(&current->mm->mmap_sem); 497 down_write(&current->mm->mmap_sem);
479 do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); 498 do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
480 up_write(&current->mm->mmap_sem); 499 up_write(&current->mm->mmap_sem);
481 500
482 file->f_op->read(file, (char __user *)start_addr, 501 file->f_op->read(file, (char __user *)start_addr,
483 ex.a_text + ex.a_data, &pos); 502 ex.a_text + ex.a_data, &pos);
484 flush_icache_range((unsigned long) start_addr, 503 flush_icache_range((unsigned long) start_addr,
485 (unsigned long) start_addr + ex.a_text + ex.a_data); 504 (unsigned long) start_addr + ex.a_text +
505 ex.a_data);
486 506
487 retval = 0; 507 retval = 0;
488 goto out; 508 goto out;
diff --git a/arch/x86/ia32/ia32_binfmt.c b/arch/x86/ia32/ia32_binfmt.c
deleted file mode 100644
index 55822d2cf053..000000000000
--- a/arch/x86/ia32/ia32_binfmt.c
+++ /dev/null
@@ -1,285 +0,0 @@
1/*
2 * Written 2000,2002 by Andi Kleen.
3 *
4 * Loosely based on the sparc64 and IA64 32bit emulation loaders.
5 * This tricks binfmt_elf.c into loading 32bit binaries using lots
6 * of ugly preprocessor tricks. Talk about very very poor man's inheritance.
7 */
8
9#include <linux/types.h>
10#include <linux/stddef.h>
11#include <linux/rwsem.h>
12#include <linux/sched.h>
13#include <linux/compat.h>
14#include <linux/string.h>
15#include <linux/binfmts.h>
16#include <linux/mm.h>
17#include <linux/security.h>
18#include <linux/elfcore-compat.h>
19
20#include <asm/segment.h>
21#include <asm/ptrace.h>
22#include <asm/processor.h>
23#include <asm/user32.h>
24#include <asm/sigcontext32.h>
25#include <asm/fpu32.h>
26#include <asm/i387.h>
27#include <asm/uaccess.h>
28#include <asm/ia32.h>
29#include <asm/vsyscall32.h>
30
31#undef ELF_ARCH
32#undef ELF_CLASS
33#define ELF_CLASS ELFCLASS32
34#define ELF_ARCH EM_386
35
36#undef elfhdr
37#undef elf_phdr
38#undef elf_note
39#undef elf_addr_t
40#define elfhdr elf32_hdr
41#define elf_phdr elf32_phdr
42#define elf_note elf32_note
43#define elf_addr_t Elf32_Off
44
45#define ELF_NAME "elf/i386"
46
47#define AT_SYSINFO 32
48#define AT_SYSINFO_EHDR 33
49
50int sysctl_vsyscall32 = 1;
51
52#undef ARCH_DLINFO
53#define ARCH_DLINFO do { \
54 if (sysctl_vsyscall32) { \
55 current->mm->context.vdso = (void *)VSYSCALL32_BASE; \
56 NEW_AUX_ENT(AT_SYSINFO, (u32)(u64)VSYSCALL32_VSYSCALL); \
57 NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL32_BASE); \
58 } \
59} while(0)
60
61struct file;
62
63#define IA32_EMULATOR 1
64
65#undef ELF_ET_DYN_BASE
66
67#define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
68
69#define jiffies_to_timeval(a,b) do { (b)->tv_usec = 0; (b)->tv_sec = (a)/HZ; }while(0)
70
71#define _GET_SEG(x) \
72 ({ __u32 seg; asm("movl %%" __stringify(x) ",%0" : "=r"(seg)); seg; })
73
74/* Assumes current==process to be dumped */
75#undef ELF_CORE_COPY_REGS
76#define ELF_CORE_COPY_REGS(pr_reg, regs) \
77 pr_reg[0] = regs->rbx; \
78 pr_reg[1] = regs->rcx; \
79 pr_reg[2] = regs->rdx; \
80 pr_reg[3] = regs->rsi; \
81 pr_reg[4] = regs->rdi; \
82 pr_reg[5] = regs->rbp; \
83 pr_reg[6] = regs->rax; \
84 pr_reg[7] = _GET_SEG(ds); \
85 pr_reg[8] = _GET_SEG(es); \
86 pr_reg[9] = _GET_SEG(fs); \
87 pr_reg[10] = _GET_SEG(gs); \
88 pr_reg[11] = regs->orig_rax; \
89 pr_reg[12] = regs->rip; \
90 pr_reg[13] = regs->cs; \
91 pr_reg[14] = regs->eflags; \
92 pr_reg[15] = regs->rsp; \
93 pr_reg[16] = regs->ss;
94
95
96#define elf_prstatus compat_elf_prstatus
97#define elf_prpsinfo compat_elf_prpsinfo
98#define elf_fpregset_t struct user_i387_ia32_struct
99#define elf_fpxregset_t struct user32_fxsr_struct
100#define user user32
101
102#undef elf_read_implies_exec
103#define elf_read_implies_exec(ex, executable_stack) (executable_stack != EXSTACK_DISABLE_X)
104
105#define elf_core_copy_regs elf32_core_copy_regs
106static inline void elf32_core_copy_regs(compat_elf_gregset_t *elfregs,
107 struct pt_regs *regs)
108{
109 ELF_CORE_COPY_REGS((&elfregs->ebx), regs)
110}
111
112#define elf_core_copy_task_regs elf32_core_copy_task_regs
113static inline int elf32_core_copy_task_regs(struct task_struct *t,
114 compat_elf_gregset_t* elfregs)
115{
116 struct pt_regs *pp = task_pt_regs(t);
117 ELF_CORE_COPY_REGS((&elfregs->ebx), pp);
118 /* fix wrong segments */
119 elfregs->ds = t->thread.ds;
120 elfregs->fs = t->thread.fsindex;
121 elfregs->gs = t->thread.gsindex;
122 elfregs->es = t->thread.es;
123 return 1;
124}
125
126#define elf_core_copy_task_fpregs elf32_core_copy_task_fpregs
127static inline int
128elf32_core_copy_task_fpregs(struct task_struct *tsk, struct pt_regs *regs,
129 elf_fpregset_t *fpu)
130{
131 struct _fpstate_ia32 *fpstate = (void*)fpu;
132 mm_segment_t oldfs = get_fs();
133
134 if (!tsk_used_math(tsk))
135 return 0;
136 if (!regs)
137 regs = task_pt_regs(tsk);
138 if (tsk == current)
139 unlazy_fpu(tsk);
140 set_fs(KERNEL_DS);
141 save_i387_ia32(tsk, fpstate, regs, 1);
142 /* Correct for i386 bug. It puts the fop into the upper 16bits of
143 the tag word (like FXSAVE), not into the fcs*/
144 fpstate->cssel |= fpstate->tag & 0xffff0000;
145 set_fs(oldfs);
146 return 1;
147}
148
149#define ELF_CORE_COPY_XFPREGS 1
150#define ELF_CORE_XFPREG_TYPE NT_PRXFPREG
151#define elf_core_copy_task_xfpregs elf32_core_copy_task_xfpregs
152static inline int
153elf32_core_copy_task_xfpregs(struct task_struct *t, elf_fpxregset_t *xfpu)
154{
155 struct pt_regs *regs = task_pt_regs(t);
156 if (!tsk_used_math(t))
157 return 0;
158 if (t == current)
159 unlazy_fpu(t);
160 memcpy(xfpu, &t->thread.i387.fxsave, sizeof(elf_fpxregset_t));
161 xfpu->fcs = regs->cs;
162 xfpu->fos = t->thread.ds; /* right? */
163 return 1;
164}
165
166#undef elf_check_arch
167#define elf_check_arch(x) \
168 ((x)->e_machine == EM_386)
169
170extern int force_personality32;
171
172#undef ELF_EXEC_PAGESIZE
173#undef ELF_HWCAP
174#undef ELF_PLATFORM
175#undef SET_PERSONALITY
176#define ELF_EXEC_PAGESIZE PAGE_SIZE
177#define ELF_HWCAP (boot_cpu_data.x86_capability[0])
178#define ELF_PLATFORM ("i686")
179#define SET_PERSONALITY(ex, ibcs2) \
180do { \
181 unsigned long new_flags = 0; \
182 if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
183 new_flags = _TIF_IA32; \
184 if ((current_thread_info()->flags & _TIF_IA32) \
185 != new_flags) \
186 set_thread_flag(TIF_ABI_PENDING); \
187 else \
188 clear_thread_flag(TIF_ABI_PENDING); \
189 /* XXX This overwrites the user set personality */ \
190 current->personality |= force_personality32; \
191} while (0)
192
193/* Override some function names */
194#define elf_format elf32_format
195
196#define init_elf_binfmt init_elf32_binfmt
197#define exit_elf_binfmt exit_elf32_binfmt
198
199#define load_elf_binary load_elf32_binary
200
201#undef ELF_PLAT_INIT
202#define ELF_PLAT_INIT(r, load_addr) elf32_init(r)
203
204#undef start_thread
205#define start_thread(regs,new_rip,new_rsp) do { \
206 asm volatile("movl %0,%%fs" :: "r" (0)); \
207 asm volatile("movl %0,%%es; movl %0,%%ds": :"r" (__USER32_DS)); \
208 load_gs_index(0); \
209 (regs)->rip = (new_rip); \
210 (regs)->rsp = (new_rsp); \
211 (regs)->eflags = 0x200; \
212 (regs)->cs = __USER32_CS; \
213 (regs)->ss = __USER32_DS; \
214 set_fs(USER_DS); \
215} while(0)
216
217
218#include <linux/module.h>
219
220MODULE_DESCRIPTION("Binary format loader for compatibility with IA32 ELF binaries.");
221MODULE_AUTHOR("Eric Youngdale, Andi Kleen");
222
223#undef MODULE_DESCRIPTION
224#undef MODULE_AUTHOR
225
226static void elf32_init(struct pt_regs *);
227
228#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
229#define arch_setup_additional_pages syscall32_setup_pages
230extern int syscall32_setup_pages(struct linux_binprm *, int exstack);
231
232#include "../../../fs/binfmt_elf.c"
233
234static void elf32_init(struct pt_regs *regs)
235{
236 struct task_struct *me = current;
237 regs->rdi = 0;
238 regs->rsi = 0;
239 regs->rdx = 0;
240 regs->rcx = 0;
241 regs->rax = 0;
242 regs->rbx = 0;
243 regs->rbp = 0;
244 regs->r8 = regs->r9 = regs->r10 = regs->r11 = regs->r12 =
245 regs->r13 = regs->r14 = regs->r15 = 0;
246 me->thread.fs = 0;
247 me->thread.gs = 0;
248 me->thread.fsindex = 0;
249 me->thread.gsindex = 0;
250 me->thread.ds = __USER_DS;
251 me->thread.es = __USER_DS;
252}
253
254#ifdef CONFIG_SYSCTL
255/* Register vsyscall32 into the ABI table */
256#include <linux/sysctl.h>
257
258static ctl_table abi_table2[] = {
259 {
260 .procname = "vsyscall32",
261 .data = &sysctl_vsyscall32,
262 .maxlen = sizeof(int),
263 .mode = 0644,
264 .proc_handler = proc_dointvec
265 },
266 {}
267};
268
269static ctl_table abi_root_table2[] = {
270 {
271 .ctl_name = CTL_ABI,
272 .procname = "abi",
273 .mode = 0555,
274 .child = abi_table2
275 },
276 {}
277};
278
279static __init int ia32_binfmt_init(void)
280{
281 register_sysctl_table(abi_root_table2);
282 return 0;
283}
284__initcall(ia32_binfmt_init);
285#endif
diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c
index 6ea19c25f90d..1c0503bdfb1a 100644
--- a/arch/x86/ia32/ia32_signal.c
+++ b/arch/x86/ia32/ia32_signal.c
@@ -29,9 +29,8 @@
29#include <asm/ia32_unistd.h> 29#include <asm/ia32_unistd.h>
30#include <asm/user32.h> 30#include <asm/user32.h>
31#include <asm/sigcontext32.h> 31#include <asm/sigcontext32.h>
32#include <asm/fpu32.h>
33#include <asm/proto.h> 32#include <asm/proto.h>
34#include <asm/vsyscall32.h> 33#include <asm/vdso.h>
35 34
36#define DEBUG_SIG 0 35#define DEBUG_SIG 0
37 36
@@ -43,7 +42,8 @@ void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
43int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) 42int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
44{ 43{
45 int err; 44 int err;
46 if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t))) 45
46 if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
47 return -EFAULT; 47 return -EFAULT;
48 48
49 /* If you change siginfo_t structure, please make sure that 49 /* If you change siginfo_t structure, please make sure that
@@ -53,16 +53,19 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
53 3 ints plus the relevant union member. */ 53 3 ints plus the relevant union member. */
54 err = __put_user(from->si_signo, &to->si_signo); 54 err = __put_user(from->si_signo, &to->si_signo);
55 err |= __put_user(from->si_errno, &to->si_errno); 55 err |= __put_user(from->si_errno, &to->si_errno);
56 err |= __put_user((short)from->si_code, &to->si_code); 56 err |= __put_user((short)from->si_code, &to->si_code);
57 57
58 if (from->si_code < 0) { 58 if (from->si_code < 0) {
59 err |= __put_user(from->si_pid, &to->si_pid); 59 err |= __put_user(from->si_pid, &to->si_pid);
60 err |= __put_user(from->si_uid, &to->si_uid); 60 err |= __put_user(from->si_uid, &to->si_uid);
61 err |= __put_user(ptr_to_compat(from->si_ptr), &to->si_ptr); 61 err |= __put_user(ptr_to_compat(from->si_ptr), &to->si_ptr);
62 } else { 62 } else {
63 /* First 32bits of unions are always present: 63 /*
64 * si_pid === si_band === si_tid === si_addr(LS half) */ 64 * First 32bits of unions are always present:
65 err |= __put_user(from->_sifields._pad[0], &to->_sifields._pad[0]); 65 * si_pid === si_band === si_tid === si_addr(LS half)
66 */
67 err |= __put_user(from->_sifields._pad[0],
68 &to->_sifields._pad[0]);
66 switch (from->si_code >> 16) { 69 switch (from->si_code >> 16) {
67 case __SI_FAULT >> 16: 70 case __SI_FAULT >> 16:
68 break; 71 break;
@@ -76,14 +79,15 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
76 err |= __put_user(from->si_uid, &to->si_uid); 79 err |= __put_user(from->si_uid, &to->si_uid);
77 break; 80 break;
78 case __SI_POLL >> 16: 81 case __SI_POLL >> 16:
79 err |= __put_user(from->si_fd, &to->si_fd); 82 err |= __put_user(from->si_fd, &to->si_fd);
80 break; 83 break;
81 case __SI_TIMER >> 16: 84 case __SI_TIMER >> 16:
82 err |= __put_user(from->si_overrun, &to->si_overrun); 85 err |= __put_user(from->si_overrun, &to->si_overrun);
83 err |= __put_user(ptr_to_compat(from->si_ptr), 86 err |= __put_user(ptr_to_compat(from->si_ptr),
84 &to->si_ptr); 87 &to->si_ptr);
85 break; 88 break;
86 case __SI_RT >> 16: /* This is not generated by the kernel as of now. */ 89 /* This is not generated by the kernel as of now. */
90 case __SI_RT >> 16:
87 case __SI_MESGQ >> 16: 91 case __SI_MESGQ >> 16:
88 err |= __put_user(from->si_uid, &to->si_uid); 92 err |= __put_user(from->si_uid, &to->si_uid);
89 err |= __put_user(from->si_int, &to->si_int); 93 err |= __put_user(from->si_int, &to->si_int);
@@ -97,7 +101,8 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
97{ 101{
98 int err; 102 int err;
99 u32 ptr32; 103 u32 ptr32;
100 if (!access_ok (VERIFY_READ, from, sizeof(compat_siginfo_t))) 104
105 if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
101 return -EFAULT; 106 return -EFAULT;
102 107
103 err = __get_user(to->si_signo, &from->si_signo); 108 err = __get_user(to->si_signo, &from->si_signo);
@@ -112,8 +117,7 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
112 return err; 117 return err;
113} 118}
114 119
115asmlinkage long 120asmlinkage long sys32_sigsuspend(int history0, int history1, old_sigset_t mask)
116sys32_sigsuspend(int history0, int history1, old_sigset_t mask)
117{ 121{
118 mask &= _BLOCKABLE; 122 mask &= _BLOCKABLE;
119 spin_lock_irq(&current->sighand->siglock); 123 spin_lock_irq(&current->sighand->siglock);
@@ -128,36 +132,37 @@ sys32_sigsuspend(int history0, int history1, old_sigset_t mask)
128 return -ERESTARTNOHAND; 132 return -ERESTARTNOHAND;
129} 133}
130 134
131asmlinkage long 135asmlinkage long sys32_sigaltstack(const stack_ia32_t __user *uss_ptr,
132sys32_sigaltstack(const stack_ia32_t __user *uss_ptr, 136 stack_ia32_t __user *uoss_ptr,
133 stack_ia32_t __user *uoss_ptr, 137 struct pt_regs *regs)
134 struct pt_regs *regs)
135{ 138{
136 stack_t uss,uoss; 139 stack_t uss, uoss;
137 int ret; 140 int ret;
138 mm_segment_t seg; 141 mm_segment_t seg;
139 if (uss_ptr) { 142
143 if (uss_ptr) {
140 u32 ptr; 144 u32 ptr;
141 memset(&uss,0,sizeof(stack_t)); 145
142 if (!access_ok(VERIFY_READ,uss_ptr,sizeof(stack_ia32_t)) || 146 memset(&uss, 0, sizeof(stack_t));
147 if (!access_ok(VERIFY_READ, uss_ptr, sizeof(stack_ia32_t)) ||
143 __get_user(ptr, &uss_ptr->ss_sp) || 148 __get_user(ptr, &uss_ptr->ss_sp) ||
144 __get_user(uss.ss_flags, &uss_ptr->ss_flags) || 149 __get_user(uss.ss_flags, &uss_ptr->ss_flags) ||
145 __get_user(uss.ss_size, &uss_ptr->ss_size)) 150 __get_user(uss.ss_size, &uss_ptr->ss_size))
146 return -EFAULT; 151 return -EFAULT;
147 uss.ss_sp = compat_ptr(ptr); 152 uss.ss_sp = compat_ptr(ptr);
148 } 153 }
149 seg = get_fs(); 154 seg = get_fs();
150 set_fs(KERNEL_DS); 155 set_fs(KERNEL_DS);
151 ret = do_sigaltstack(uss_ptr ? &uss : NULL, &uoss, regs->rsp); 156 ret = do_sigaltstack(uss_ptr ? &uss : NULL, &uoss, regs->sp);
152 set_fs(seg); 157 set_fs(seg);
153 if (ret >= 0 && uoss_ptr) { 158 if (ret >= 0 && uoss_ptr) {
154 if (!access_ok(VERIFY_WRITE,uoss_ptr,sizeof(stack_ia32_t)) || 159 if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(stack_ia32_t)) ||
155 __put_user(ptr_to_compat(uoss.ss_sp), &uoss_ptr->ss_sp) || 160 __put_user(ptr_to_compat(uoss.ss_sp), &uoss_ptr->ss_sp) ||
156 __put_user(uoss.ss_flags, &uoss_ptr->ss_flags) || 161 __put_user(uoss.ss_flags, &uoss_ptr->ss_flags) ||
157 __put_user(uoss.ss_size, &uoss_ptr->ss_size)) 162 __put_user(uoss.ss_size, &uoss_ptr->ss_size))
158 ret = -EFAULT; 163 ret = -EFAULT;
159 } 164 }
160 return ret; 165 return ret;
161} 166}
162 167
163/* 168/*
@@ -186,87 +191,85 @@ struct rt_sigframe
186 char retcode[8]; 191 char retcode[8];
187}; 192};
188 193
189static int 194#define COPY(x) { \
190ia32_restore_sigcontext(struct pt_regs *regs, struct sigcontext_ia32 __user *sc, unsigned int *peax) 195 unsigned int reg; \
196 err |= __get_user(reg, &sc->x); \
197 regs->x = reg; \
198}
199
200#define RELOAD_SEG(seg,mask) \
201 { unsigned int cur; \
202 unsigned short pre; \
203 err |= __get_user(pre, &sc->seg); \
204 asm volatile("movl %%" #seg ",%0" : "=r" (cur)); \
205 pre |= mask; \
206 if (pre != cur) loadsegment(seg, pre); }
207
208static int ia32_restore_sigcontext(struct pt_regs *regs,
209 struct sigcontext_ia32 __user *sc,
210 unsigned int *peax)
191{ 211{
192 unsigned int err = 0; 212 unsigned int tmpflags, gs, oldgs, err = 0;
193 213 struct _fpstate_ia32 __user *buf;
214 u32 tmp;
215
194 /* Always make any pending restarted system calls return -EINTR */ 216 /* Always make any pending restarted system calls return -EINTR */
195 current_thread_info()->restart_block.fn = do_no_restart_syscall; 217 current_thread_info()->restart_block.fn = do_no_restart_syscall;
196 218
197#if DEBUG_SIG 219#if DEBUG_SIG
198 printk("SIG restore_sigcontext: sc=%p err(%x) eip(%x) cs(%x) flg(%x)\n", 220 printk(KERN_DEBUG "SIG restore_sigcontext: "
199 sc, sc->err, sc->eip, sc->cs, sc->eflags); 221 "sc=%p err(%x) eip(%x) cs(%x) flg(%x)\n",
222 sc, sc->err, sc->ip, sc->cs, sc->flags);
200#endif 223#endif
201#define COPY(x) { \
202 unsigned int reg; \
203 err |= __get_user(reg, &sc->e ##x); \
204 regs->r ## x = reg; \
205}
206 224
207#define RELOAD_SEG(seg,mask) \ 225 /*
208 { unsigned int cur; \ 226 * Reload fs and gs if they have changed in the signal
209 unsigned short pre; \ 227 * handler. This does not handle long fs/gs base changes in
210 err |= __get_user(pre, &sc->seg); \ 228 * the handler, but does not clobber them at least in the
211 asm volatile("movl %%" #seg ",%0" : "=r" (cur)); \ 229 * normal case.
212 pre |= mask; \ 230 */
213 if (pre != cur) loadsegment(seg,pre); } 231 err |= __get_user(gs, &sc->gs);
214 232 gs |= 3;
215 /* Reload fs and gs if they have changed in the signal handler. 233 asm("movl %%gs,%0" : "=r" (oldgs));
216 This does not handle long fs/gs base changes in the handler, but 234 if (gs != oldgs)
217 does not clobber them at least in the normal case. */ 235 load_gs_index(gs);
218 236
219 { 237 RELOAD_SEG(fs, 3);
220 unsigned gs, oldgs; 238 RELOAD_SEG(ds, 3);
221 err |= __get_user(gs, &sc->gs); 239 RELOAD_SEG(es, 3);
222 gs |= 3;
223 asm("movl %%gs,%0" : "=r" (oldgs));
224 if (gs != oldgs)
225 load_gs_index(gs);
226 }
227 RELOAD_SEG(fs,3);
228 RELOAD_SEG(ds,3);
229 RELOAD_SEG(es,3);
230 240
231 COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx); 241 COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
232 COPY(dx); COPY(cx); COPY(ip); 242 COPY(dx); COPY(cx); COPY(ip);
233 /* Don't touch extended registers */ 243 /* Don't touch extended registers */
234 244
235 err |= __get_user(regs->cs, &sc->cs); 245 err |= __get_user(regs->cs, &sc->cs);
236 regs->cs |= 3; 246 regs->cs |= 3;
237 err |= __get_user(regs->ss, &sc->ss); 247 err |= __get_user(regs->ss, &sc->ss);
238 regs->ss |= 3; 248 regs->ss |= 3;
239 249
240 { 250 err |= __get_user(tmpflags, &sc->flags);
241 unsigned int tmpflags; 251 regs->flags = (regs->flags & ~0x40DD5) | (tmpflags & 0x40DD5);
242 err |= __get_user(tmpflags, &sc->eflags); 252 /* disable syscall checks */
243 regs->eflags = (regs->eflags & ~0x40DD5) | (tmpflags & 0x40DD5); 253 regs->orig_ax = -1;
244 regs->orig_rax = -1; /* disable syscall checks */ 254
245 } 255 err |= __get_user(tmp, &sc->fpstate);
256 buf = compat_ptr(tmp);
257 if (buf) {
258 if (!access_ok(VERIFY_READ, buf, sizeof(*buf)))
259 goto badframe;
260 err |= restore_i387_ia32(buf);
261 } else {
262 struct task_struct *me = current;
246 263
247 { 264 if (used_math()) {
248 u32 tmp; 265 clear_fpu(me);
249 struct _fpstate_ia32 __user * buf; 266 clear_used_math();
250 err |= __get_user(tmp, &sc->fpstate);
251 buf = compat_ptr(tmp);
252 if (buf) {
253 if (!access_ok(VERIFY_READ, buf, sizeof(*buf)))
254 goto badframe;
255 err |= restore_i387_ia32(current, buf, 0);
256 } else {
257 struct task_struct *me = current;
258 if (used_math()) {
259 clear_fpu(me);
260 clear_used_math();
261 }
262 } 267 }
263 } 268 }
264 269
265 { 270 err |= __get_user(tmp, &sc->ax);
266 u32 tmp; 271 *peax = tmp;
267 err |= __get_user(tmp, &sc->eax); 272
268 *peax = tmp;
269 }
270 return err; 273 return err;
271 274
272badframe: 275badframe:
@@ -275,15 +278,16 @@ badframe:
275 278
276asmlinkage long sys32_sigreturn(struct pt_regs *regs) 279asmlinkage long sys32_sigreturn(struct pt_regs *regs)
277{ 280{
278 struct sigframe __user *frame = (struct sigframe __user *)(regs->rsp-8); 281 struct sigframe __user *frame = (struct sigframe __user *)(regs->sp-8);
279 sigset_t set; 282 sigset_t set;
280 unsigned int eax; 283 unsigned int ax;
281 284
282 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 285 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
283 goto badframe; 286 goto badframe;
284 if (__get_user(set.sig[0], &frame->sc.oldmask) 287 if (__get_user(set.sig[0], &frame->sc.oldmask)
285 || (_COMPAT_NSIG_WORDS > 1 288 || (_COMPAT_NSIG_WORDS > 1
286 && __copy_from_user((((char *) &set.sig) + 4), &frame->extramask, 289 && __copy_from_user((((char *) &set.sig) + 4),
290 &frame->extramask,
287 sizeof(frame->extramask)))) 291 sizeof(frame->extramask))))
288 goto badframe; 292 goto badframe;
289 293
@@ -292,24 +296,24 @@ asmlinkage long sys32_sigreturn(struct pt_regs *regs)
292 current->blocked = set; 296 current->blocked = set;
293 recalc_sigpending(); 297 recalc_sigpending();
294 spin_unlock_irq(&current->sighand->siglock); 298 spin_unlock_irq(&current->sighand->siglock);
295 299
296 if (ia32_restore_sigcontext(regs, &frame->sc, &eax)) 300 if (ia32_restore_sigcontext(regs, &frame->sc, &ax))
297 goto badframe; 301 goto badframe;
298 return eax; 302 return ax;
299 303
300badframe: 304badframe:
301 signal_fault(regs, frame, "32bit sigreturn"); 305 signal_fault(regs, frame, "32bit sigreturn");
302 return 0; 306 return 0;
303} 307}
304 308
305asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs) 309asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
306{ 310{
307 struct rt_sigframe __user *frame; 311 struct rt_sigframe __user *frame;
308 sigset_t set; 312 sigset_t set;
309 unsigned int eax; 313 unsigned int ax;
310 struct pt_regs tregs; 314 struct pt_regs tregs;
311 315
312 frame = (struct rt_sigframe __user *)(regs->rsp - 4); 316 frame = (struct rt_sigframe __user *)(regs->sp - 4);
313 317
314 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 318 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
315 goto badframe; 319 goto badframe;
@@ -321,28 +325,28 @@ asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
321 current->blocked = set; 325 current->blocked = set;
322 recalc_sigpending(); 326 recalc_sigpending();
323 spin_unlock_irq(&current->sighand->siglock); 327 spin_unlock_irq(&current->sighand->siglock);
324 328
325 if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext, &eax)) 329 if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
326 goto badframe; 330 goto badframe;
327 331
328 tregs = *regs; 332 tregs = *regs;
329 if (sys32_sigaltstack(&frame->uc.uc_stack, NULL, &tregs) == -EFAULT) 333 if (sys32_sigaltstack(&frame->uc.uc_stack, NULL, &tregs) == -EFAULT)
330 goto badframe; 334 goto badframe;
331 335
332 return eax; 336 return ax;
333 337
334badframe: 338badframe:
335 signal_fault(regs,frame,"32bit rt sigreturn"); 339 signal_fault(regs, frame, "32bit rt sigreturn");
336 return 0; 340 return 0;
337} 341}
338 342
339/* 343/*
340 * Set up a signal frame. 344 * Set up a signal frame.
341 */ 345 */
342 346
343static int 347static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
344ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc, struct _fpstate_ia32 __user *fpstate, 348 struct _fpstate_ia32 __user *fpstate,
345 struct pt_regs *regs, unsigned int mask) 349 struct pt_regs *regs, unsigned int mask)
346{ 350{
347 int tmp, err = 0; 351 int tmp, err = 0;
348 352
@@ -356,26 +360,26 @@ ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc, struct _fpstate_ia32 __
356 __asm__("movl %%es,%0" : "=r"(tmp): "0"(tmp)); 360 __asm__("movl %%es,%0" : "=r"(tmp): "0"(tmp));
357 err |= __put_user(tmp, (unsigned int __user *)&sc->es); 361 err |= __put_user(tmp, (unsigned int __user *)&sc->es);
358 362
359 err |= __put_user((u32)regs->rdi, &sc->edi); 363 err |= __put_user((u32)regs->di, &sc->di);
360 err |= __put_user((u32)regs->rsi, &sc->esi); 364 err |= __put_user((u32)regs->si, &sc->si);
361 err |= __put_user((u32)regs->rbp, &sc->ebp); 365 err |= __put_user((u32)regs->bp, &sc->bp);
362 err |= __put_user((u32)regs->rsp, &sc->esp); 366 err |= __put_user((u32)regs->sp, &sc->sp);
363 err |= __put_user((u32)regs->rbx, &sc->ebx); 367 err |= __put_user((u32)regs->bx, &sc->bx);
364 err |= __put_user((u32)regs->rdx, &sc->edx); 368 err |= __put_user((u32)regs->dx, &sc->dx);
365 err |= __put_user((u32)regs->rcx, &sc->ecx); 369 err |= __put_user((u32)regs->cx, &sc->cx);
366 err |= __put_user((u32)regs->rax, &sc->eax); 370 err |= __put_user((u32)regs->ax, &sc->ax);
367 err |= __put_user((u32)regs->cs, &sc->cs); 371 err |= __put_user((u32)regs->cs, &sc->cs);
368 err |= __put_user((u32)regs->ss, &sc->ss); 372 err |= __put_user((u32)regs->ss, &sc->ss);
369 err |= __put_user(current->thread.trap_no, &sc->trapno); 373 err |= __put_user(current->thread.trap_no, &sc->trapno);
370 err |= __put_user(current->thread.error_code, &sc->err); 374 err |= __put_user(current->thread.error_code, &sc->err);
371 err |= __put_user((u32)regs->rip, &sc->eip); 375 err |= __put_user((u32)regs->ip, &sc->ip);
372 err |= __put_user((u32)regs->eflags, &sc->eflags); 376 err |= __put_user((u32)regs->flags, &sc->flags);
373 err |= __put_user((u32)regs->rsp, &sc->esp_at_signal); 377 err |= __put_user((u32)regs->sp, &sc->sp_at_signal);
374 378
375 tmp = save_i387_ia32(current, fpstate, regs, 0); 379 tmp = save_i387_ia32(fpstate);
376 if (tmp < 0) 380 if (tmp < 0)
377 err = -EFAULT; 381 err = -EFAULT;
378 else { 382 else {
379 clear_used_math(); 383 clear_used_math();
380 stts(); 384 stts();
381 err |= __put_user(ptr_to_compat(tmp ? fpstate : NULL), 385 err |= __put_user(ptr_to_compat(tmp ? fpstate : NULL),
@@ -392,40 +396,53 @@ ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc, struct _fpstate_ia32 __
392/* 396/*
393 * Determine which stack to use.. 397 * Determine which stack to use..
394 */ 398 */
395static void __user * 399static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
396get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) 400 size_t frame_size)
397{ 401{
398 unsigned long rsp; 402 unsigned long sp;
399 403
400 /* Default to using normal stack */ 404 /* Default to using normal stack */
401 rsp = regs->rsp; 405 sp = regs->sp;
402 406
403 /* This is the X/Open sanctioned signal stack switching. */ 407 /* This is the X/Open sanctioned signal stack switching. */
404 if (ka->sa.sa_flags & SA_ONSTACK) { 408 if (ka->sa.sa_flags & SA_ONSTACK) {
405 if (sas_ss_flags(rsp) == 0) 409 if (sas_ss_flags(sp) == 0)
406 rsp = current->sas_ss_sp + current->sas_ss_size; 410 sp = current->sas_ss_sp + current->sas_ss_size;
407 } 411 }
408 412
409 /* This is the legacy signal stack switching. */ 413 /* This is the legacy signal stack switching. */
410 else if ((regs->ss & 0xffff) != __USER_DS && 414 else if ((regs->ss & 0xffff) != __USER_DS &&
411 !(ka->sa.sa_flags & SA_RESTORER) && 415 !(ka->sa.sa_flags & SA_RESTORER) &&
412 ka->sa.sa_restorer) { 416 ka->sa.sa_restorer)
413 rsp = (unsigned long) ka->sa.sa_restorer; 417 sp = (unsigned long) ka->sa.sa_restorer;
414 }
415 418
416 rsp -= frame_size; 419 sp -= frame_size;
417 /* Align the stack pointer according to the i386 ABI, 420 /* Align the stack pointer according to the i386 ABI,
418 * i.e. so that on function entry ((sp + 4) & 15) == 0. */ 421 * i.e. so that on function entry ((sp + 4) & 15) == 0. */
419 rsp = ((rsp + 4) & -16ul) - 4; 422 sp = ((sp + 4) & -16ul) - 4;
420 return (void __user *) rsp; 423 return (void __user *) sp;
421} 424}
422 425
423int ia32_setup_frame(int sig, struct k_sigaction *ka, 426int ia32_setup_frame(int sig, struct k_sigaction *ka,
424 compat_sigset_t *set, struct pt_regs * regs) 427 compat_sigset_t *set, struct pt_regs *regs)
425{ 428{
426 struct sigframe __user *frame; 429 struct sigframe __user *frame;
430 void __user *restorer;
427 int err = 0; 431 int err = 0;
428 432
433 /* copy_to_user optimizes that into a single 8 byte store */
434 static const struct {
435 u16 poplmovl;
436 u32 val;
437 u16 int80;
438 u16 pad;
439 } __attribute__((packed)) code = {
440 0xb858, /* popl %eax ; movl $...,%eax */
441 __NR_ia32_sigreturn,
442 0x80cd, /* int $0x80 */
443 0,
444 };
445
429 frame = get_sigframe(ka, regs, sizeof(*frame)); 446 frame = get_sigframe(ka, regs, sizeof(*frame));
430 447
431 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 448 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
@@ -443,64 +460,53 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka,
443 if (_COMPAT_NSIG_WORDS > 1) { 460 if (_COMPAT_NSIG_WORDS > 1) {
444 err |= __copy_to_user(frame->extramask, &set->sig[1], 461 err |= __copy_to_user(frame->extramask, &set->sig[1],
445 sizeof(frame->extramask)); 462 sizeof(frame->extramask));
463 if (err)
464 goto give_sigsegv;
446 } 465 }
447 if (err)
448 goto give_sigsegv;
449 466
450 /* Return stub is in 32bit vsyscall page */ 467 if (ka->sa.sa_flags & SA_RESTORER) {
451 { 468 restorer = ka->sa.sa_restorer;
452 void __user *restorer; 469 } else {
470 /* Return stub is in 32bit vsyscall page */
453 if (current->binfmt->hasvdso) 471 if (current->binfmt->hasvdso)
454 restorer = VSYSCALL32_SIGRETURN; 472 restorer = VDSO32_SYMBOL(current->mm->context.vdso,
473 sigreturn);
455 else 474 else
456 restorer = (void *)&frame->retcode; 475 restorer = &frame->retcode;
457 if (ka->sa.sa_flags & SA_RESTORER)
458 restorer = ka->sa.sa_restorer;
459 err |= __put_user(ptr_to_compat(restorer), &frame->pretcode);
460 }
461 /* These are actually not used anymore, but left because some
462 gdb versions depend on them as a marker. */
463 {
464 /* copy_to_user optimizes that into a single 8 byte store */
465 static const struct {
466 u16 poplmovl;
467 u32 val;
468 u16 int80;
469 u16 pad;
470 } __attribute__((packed)) code = {
471 0xb858, /* popl %eax ; movl $...,%eax */
472 __NR_ia32_sigreturn,
473 0x80cd, /* int $0x80 */
474 0,
475 };
476 err |= __copy_to_user(frame->retcode, &code, 8);
477 } 476 }
477 err |= __put_user(ptr_to_compat(restorer), &frame->pretcode);
478
479 /*
480 * These are actually not used anymore, but left because some
481 * gdb versions depend on them as a marker.
482 */
483 err |= __copy_to_user(frame->retcode, &code, 8);
478 if (err) 484 if (err)
479 goto give_sigsegv; 485 goto give_sigsegv;
480 486
481 /* Set up registers for signal handler */ 487 /* Set up registers for signal handler */
482 regs->rsp = (unsigned long) frame; 488 regs->sp = (unsigned long) frame;
483 regs->rip = (unsigned long) ka->sa.sa_handler; 489 regs->ip = (unsigned long) ka->sa.sa_handler;
484 490
485 /* Make -mregparm=3 work */ 491 /* Make -mregparm=3 work */
486 regs->rax = sig; 492 regs->ax = sig;
487 regs->rdx = 0; 493 regs->dx = 0;
488 regs->rcx = 0; 494 regs->cx = 0;
489 495
490 asm volatile("movl %0,%%ds" :: "r" (__USER32_DS)); 496 asm volatile("movl %0,%%ds" :: "r" (__USER32_DS));
491 asm volatile("movl %0,%%es" :: "r" (__USER32_DS)); 497 asm volatile("movl %0,%%es" :: "r" (__USER32_DS));
492 498
493 regs->cs = __USER32_CS; 499 regs->cs = __USER32_CS;
494 regs->ss = __USER32_DS; 500 regs->ss = __USER32_DS;
495 501
496 set_fs(USER_DS); 502 set_fs(USER_DS);
497 regs->eflags &= ~TF_MASK; 503 regs->flags &= ~X86_EFLAGS_TF;
498 if (test_thread_flag(TIF_SINGLESTEP)) 504 if (test_thread_flag(TIF_SINGLESTEP))
499 ptrace_notify(SIGTRAP); 505 ptrace_notify(SIGTRAP);
500 506
501#if DEBUG_SIG 507#if DEBUG_SIG
502 printk("SIG deliver (%s:%d): sp=%p pc=%lx ra=%u\n", 508 printk(KERN_DEBUG "SIG deliver (%s:%d): sp=%p pc=%lx ra=%u\n",
503 current->comm, current->pid, frame, regs->rip, frame->pretcode); 509 current->comm, current->pid, frame, regs->ip, frame->pretcode);
504#endif 510#endif
505 511
506 return 0; 512 return 0;
@@ -511,25 +517,34 @@ give_sigsegv:
511} 517}
512 518
513int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 519int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
514 compat_sigset_t *set, struct pt_regs * regs) 520 compat_sigset_t *set, struct pt_regs *regs)
515{ 521{
516 struct rt_sigframe __user *frame; 522 struct rt_sigframe __user *frame;
523 struct exec_domain *ed = current_thread_info()->exec_domain;
524 void __user *restorer;
517 int err = 0; 525 int err = 0;
518 526
527 /* __copy_to_user optimizes that into a single 8 byte store */
528 static const struct {
529 u8 movl;
530 u32 val;
531 u16 int80;
532 u16 pad;
533 u8 pad2;
534 } __attribute__((packed)) code = {
535 0xb8,
536 __NR_ia32_rt_sigreturn,
537 0x80cd,
538 0,
539 };
540
519 frame = get_sigframe(ka, regs, sizeof(*frame)); 541 frame = get_sigframe(ka, regs, sizeof(*frame));
520 542
521 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 543 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
522 goto give_sigsegv; 544 goto give_sigsegv;
523 545
524 { 546 err |= __put_user((ed && ed->signal_invmap && sig < 32
525 struct exec_domain *ed = current_thread_info()->exec_domain; 547 ? ed->signal_invmap[sig] : sig), &frame->sig);
526 err |= __put_user((ed
527 && ed->signal_invmap
528 && sig < 32
529 ? ed->signal_invmap[sig]
530 : sig),
531 &frame->sig);
532 }
533 err |= __put_user(ptr_to_compat(&frame->info), &frame->pinfo); 548 err |= __put_user(ptr_to_compat(&frame->info), &frame->pinfo);
534 err |= __put_user(ptr_to_compat(&frame->uc), &frame->puc); 549 err |= __put_user(ptr_to_compat(&frame->uc), &frame->puc);
535 err |= copy_siginfo_to_user32(&frame->info, info); 550 err |= copy_siginfo_to_user32(&frame->info, info);
@@ -540,73 +555,58 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
540 err |= __put_user(0, &frame->uc.uc_flags); 555 err |= __put_user(0, &frame->uc.uc_flags);
541 err |= __put_user(0, &frame->uc.uc_link); 556 err |= __put_user(0, &frame->uc.uc_link);
542 err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); 557 err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
543 err |= __put_user(sas_ss_flags(regs->rsp), 558 err |= __put_user(sas_ss_flags(regs->sp),
544 &frame->uc.uc_stack.ss_flags); 559 &frame->uc.uc_stack.ss_flags);
545 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); 560 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
546 err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate, 561 err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate,
547 regs, set->sig[0]); 562 regs, set->sig[0]);
548 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 563 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
549 if (err) 564 if (err)
550 goto give_sigsegv; 565 goto give_sigsegv;
551 566
552 567 if (ka->sa.sa_flags & SA_RESTORER)
553 { 568 restorer = ka->sa.sa_restorer;
554 void __user *restorer = VSYSCALL32_RTSIGRETURN; 569 else
555 if (ka->sa.sa_flags & SA_RESTORER) 570 restorer = VDSO32_SYMBOL(current->mm->context.vdso,
556 restorer = ka->sa.sa_restorer; 571 rt_sigreturn);
557 err |= __put_user(ptr_to_compat(restorer), &frame->pretcode); 572 err |= __put_user(ptr_to_compat(restorer), &frame->pretcode);
558 } 573
559 574 /*
560 /* This is movl $,%eax ; int $0x80 */ 575 * Not actually used anymore, but left because some gdb
561 /* Not actually used anymore, but left because some gdb versions 576 * versions need it.
562 need it. */ 577 */
563 { 578 err |= __copy_to_user(frame->retcode, &code, 8);
564 /* __copy_to_user optimizes that into a single 8 byte store */
565 static const struct {
566 u8 movl;
567 u32 val;
568 u16 int80;
569 u16 pad;
570 u8 pad2;
571 } __attribute__((packed)) code = {
572 0xb8,
573 __NR_ia32_rt_sigreturn,
574 0x80cd,
575 0,
576 };
577 err |= __copy_to_user(frame->retcode, &code, 8);
578 }
579 if (err) 579 if (err)
580 goto give_sigsegv; 580 goto give_sigsegv;
581 581
582 /* Set up registers for signal handler */ 582 /* Set up registers for signal handler */
583 regs->rsp = (unsigned long) frame; 583 regs->sp = (unsigned long) frame;
584 regs->rip = (unsigned long) ka->sa.sa_handler; 584 regs->ip = (unsigned long) ka->sa.sa_handler;
585 585
586 /* Make -mregparm=3 work */ 586 /* Make -mregparm=3 work */
587 regs->rax = sig; 587 regs->ax = sig;
588 regs->rdx = (unsigned long) &frame->info; 588 regs->dx = (unsigned long) &frame->info;
589 regs->rcx = (unsigned long) &frame->uc; 589 regs->cx = (unsigned long) &frame->uc;
590 590
591 /* Make -mregparm=3 work */ 591 /* Make -mregparm=3 work */
592 regs->rax = sig; 592 regs->ax = sig;
593 regs->rdx = (unsigned long) &frame->info; 593 regs->dx = (unsigned long) &frame->info;
594 regs->rcx = (unsigned long) &frame->uc; 594 regs->cx = (unsigned long) &frame->uc;
595
596 asm volatile("movl %0,%%ds" :: "r" (__USER32_DS));
597 asm volatile("movl %0,%%es" :: "r" (__USER32_DS));
595 598
596 asm volatile("movl %0,%%ds" :: "r" (__USER32_DS)); 599 regs->cs = __USER32_CS;
597 asm volatile("movl %0,%%es" :: "r" (__USER32_DS)); 600 regs->ss = __USER32_DS;
598
599 regs->cs = __USER32_CS;
600 regs->ss = __USER32_DS;
601 601
602 set_fs(USER_DS); 602 set_fs(USER_DS);
603 regs->eflags &= ~TF_MASK; 603 regs->flags &= ~X86_EFLAGS_TF;
604 if (test_thread_flag(TIF_SINGLESTEP)) 604 if (test_thread_flag(TIF_SINGLESTEP))
605 ptrace_notify(SIGTRAP); 605 ptrace_notify(SIGTRAP);
606 606
607#if DEBUG_SIG 607#if DEBUG_SIG
608 printk("SIG deliver (%s:%d): sp=%p pc=%lx ra=%u\n", 608 printk(KERN_DEBUG "SIG deliver (%s:%d): sp=%p pc=%lx ra=%u\n",
609 current->comm, current->pid, frame, regs->rip, frame->pretcode); 609 current->comm, current->pid, frame, regs->ip, frame->pretcode);
610#endif 610#endif
611 611
612 return 0; 612 return 0;
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
index df588f0f76e1..0db0a6291bbd 100644
--- a/arch/x86/ia32/ia32entry.S
+++ b/arch/x86/ia32/ia32entry.S
@@ -12,7 +12,6 @@
12#include <asm/ia32_unistd.h> 12#include <asm/ia32_unistd.h>
13#include <asm/thread_info.h> 13#include <asm/thread_info.h>
14#include <asm/segment.h> 14#include <asm/segment.h>
15#include <asm/vsyscall32.h>
16#include <asm/irqflags.h> 15#include <asm/irqflags.h>
17#include <linux/linkage.h> 16#include <linux/linkage.h>
18 17
@@ -104,7 +103,7 @@ ENTRY(ia32_sysenter_target)
104 pushfq 103 pushfq
105 CFI_ADJUST_CFA_OFFSET 8 104 CFI_ADJUST_CFA_OFFSET 8
106 /*CFI_REL_OFFSET rflags,0*/ 105 /*CFI_REL_OFFSET rflags,0*/
107 movl $VSYSCALL32_SYSEXIT, %r10d 106 movl 8*3-THREAD_SIZE+threadinfo_sysenter_return(%rsp), %r10d
108 CFI_REGISTER rip,r10 107 CFI_REGISTER rip,r10
109 pushq $__USER32_CS 108 pushq $__USER32_CS
110 CFI_ADJUST_CFA_OFFSET 8 109 CFI_ADJUST_CFA_OFFSET 8
@@ -142,6 +141,8 @@ sysenter_do_call:
142 andl $~TS_COMPAT,threadinfo_status(%r10) 141 andl $~TS_COMPAT,threadinfo_status(%r10)
143 /* clear IF, that popfq doesn't enable interrupts early */ 142 /* clear IF, that popfq doesn't enable interrupts early */
144 andl $~0x200,EFLAGS-R11(%rsp) 143 andl $~0x200,EFLAGS-R11(%rsp)
144 movl RIP-R11(%rsp),%edx /* User %eip */
145 CFI_REGISTER rip,rdx
145 RESTORE_ARGS 1,24,1,1,1,1 146 RESTORE_ARGS 1,24,1,1,1,1
146 popfq 147 popfq
147 CFI_ADJUST_CFA_OFFSET -8 148 CFI_ADJUST_CFA_OFFSET -8
@@ -149,8 +150,6 @@ sysenter_do_call:
149 popq %rcx /* User %esp */ 150 popq %rcx /* User %esp */
150 CFI_ADJUST_CFA_OFFSET -8 151 CFI_ADJUST_CFA_OFFSET -8
151 CFI_REGISTER rsp,rcx 152 CFI_REGISTER rsp,rcx
152 movl $VSYSCALL32_SYSEXIT,%edx /* User %eip */
153 CFI_REGISTER rip,rdx
154 TRACE_IRQS_ON 153 TRACE_IRQS_ON
155 swapgs 154 swapgs
156 sti /* sti only takes effect after the next instruction */ 155 sti /* sti only takes effect after the next instruction */
@@ -644,8 +643,8 @@ ia32_sys_call_table:
644 .quad compat_sys_futex /* 240 */ 643 .quad compat_sys_futex /* 240 */
645 .quad compat_sys_sched_setaffinity 644 .quad compat_sys_sched_setaffinity
646 .quad compat_sys_sched_getaffinity 645 .quad compat_sys_sched_getaffinity
647 .quad sys32_set_thread_area 646 .quad sys_set_thread_area
648 .quad sys32_get_thread_area 647 .quad sys_get_thread_area
649 .quad compat_sys_io_setup /* 245 */ 648 .quad compat_sys_io_setup /* 245 */
650 .quad sys_io_destroy 649 .quad sys_io_destroy
651 .quad compat_sys_io_getevents 650 .quad compat_sys_io_getevents
diff --git a/arch/x86/ia32/ipc32.c b/arch/x86/ia32/ipc32.c
index 7b3342e5aab5..d21991ce606c 100644
--- a/arch/x86/ia32/ipc32.c
+++ b/arch/x86/ia32/ipc32.c
@@ -9,9 +9,8 @@
9#include <linux/ipc.h> 9#include <linux/ipc.h>
10#include <linux/compat.h> 10#include <linux/compat.h>
11 11
12asmlinkage long 12asmlinkage long sys32_ipc(u32 call, int first, int second, int third,
13sys32_ipc(u32 call, int first, int second, int third, 13 compat_uptr_t ptr, u32 fifth)
14 compat_uptr_t ptr, u32 fifth)
15{ 14{
16 int version; 15 int version;
17 16
@@ -19,36 +18,35 @@ sys32_ipc(u32 call, int first, int second, int third,
19 call &= 0xffff; 18 call &= 0xffff;
20 19
21 switch (call) { 20 switch (call) {
22 case SEMOP: 21 case SEMOP:
23 /* struct sembuf is the same on 32 and 64bit :)) */ 22 /* struct sembuf is the same on 32 and 64bit :)) */
24 return sys_semtimedop(first, compat_ptr(ptr), second, NULL); 23 return sys_semtimedop(first, compat_ptr(ptr), second, NULL);
25 case SEMTIMEDOP: 24 case SEMTIMEDOP:
26 return compat_sys_semtimedop(first, compat_ptr(ptr), second, 25 return compat_sys_semtimedop(first, compat_ptr(ptr), second,
27 compat_ptr(fifth)); 26 compat_ptr(fifth));
28 case SEMGET: 27 case SEMGET:
29 return sys_semget(first, second, third); 28 return sys_semget(first, second, third);
30 case SEMCTL: 29 case SEMCTL:
31 return compat_sys_semctl(first, second, third, compat_ptr(ptr)); 30 return compat_sys_semctl(first, second, third, compat_ptr(ptr));
32 31
33 case MSGSND: 32 case MSGSND:
34 return compat_sys_msgsnd(first, second, third, compat_ptr(ptr)); 33 return compat_sys_msgsnd(first, second, third, compat_ptr(ptr));
35 case MSGRCV: 34 case MSGRCV:
36 return compat_sys_msgrcv(first, second, fifth, third, 35 return compat_sys_msgrcv(first, second, fifth, third,
37 version, compat_ptr(ptr)); 36 version, compat_ptr(ptr));
38 case MSGGET: 37 case MSGGET:
39 return sys_msgget((key_t) first, second); 38 return sys_msgget((key_t) first, second);
40 case MSGCTL: 39 case MSGCTL:
41 return compat_sys_msgctl(first, second, compat_ptr(ptr)); 40 return compat_sys_msgctl(first, second, compat_ptr(ptr));
42 41
43 case SHMAT: 42 case SHMAT:
44 return compat_sys_shmat(first, second, third, version, 43 return compat_sys_shmat(first, second, third, version,
45 compat_ptr(ptr)); 44 compat_ptr(ptr));
46 break; 45 case SHMDT:
47 case SHMDT:
48 return sys_shmdt(compat_ptr(ptr)); 46 return sys_shmdt(compat_ptr(ptr));
49 case SHMGET: 47 case SHMGET:
50 return sys_shmget(first, (unsigned)second, third); 48 return sys_shmget(first, (unsigned)second, third);
51 case SHMCTL: 49 case SHMCTL:
52 return compat_sys_shmctl(first, second, compat_ptr(ptr)); 50 return compat_sys_shmctl(first, second, compat_ptr(ptr));
53 } 51 }
54 return -ENOSYS; 52 return -ENOSYS;
diff --git a/arch/x86/ia32/mmap32.c b/arch/x86/ia32/mmap32.c
deleted file mode 100644
index e4b84b4a417a..000000000000
--- a/arch/x86/ia32/mmap32.c
+++ /dev/null
@@ -1,79 +0,0 @@
1/*
2 * linux/arch/x86_64/ia32/mm/mmap.c
3 *
4 * flexible mmap layout support
5 *
6 * Based on the i386 version which was
7 *
8 * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
9 * All Rights Reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 *
26 * Started by Ingo Molnar <mingo@elte.hu>
27 */
28
29#include <linux/personality.h>
30#include <linux/mm.h>
31#include <linux/random.h>
32#include <linux/sched.h>
33
34/*
35 * Top of mmap area (just below the process stack).
36 *
37 * Leave an at least ~128 MB hole.
38 */
39#define MIN_GAP (128*1024*1024)
40#define MAX_GAP (TASK_SIZE/6*5)
41
42static inline unsigned long mmap_base(struct mm_struct *mm)
43{
44 unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
45 unsigned long random_factor = 0;
46
47 if (current->flags & PF_RANDOMIZE)
48 random_factor = get_random_int() % (1024*1024);
49
50 if (gap < MIN_GAP)
51 gap = MIN_GAP;
52 else if (gap > MAX_GAP)
53 gap = MAX_GAP;
54
55 return PAGE_ALIGN(TASK_SIZE - gap - random_factor);
56}
57
58/*
59 * This function, called very early during the creation of a new
60 * process VM image, sets up which VM layout function to use:
61 */
62void ia32_pick_mmap_layout(struct mm_struct *mm)
63{
64 /*
65 * Fall back to the standard layout if the personality
66 * bit is set, or if the expected stack growth is unlimited:
67 */
68 if (sysctl_legacy_va_layout ||
69 (current->personality & ADDR_COMPAT_LAYOUT) ||
70 current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
71 mm->mmap_base = TASK_UNMAPPED_BASE;
72 mm->get_unmapped_area = arch_get_unmapped_area;
73 mm->unmap_area = arch_unmap_area;
74 } else {
75 mm->mmap_base = mmap_base(mm);
76 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
77 mm->unmap_area = arch_unmap_area_topdown;
78 }
79}
diff --git a/arch/x86/ia32/ptrace32.c b/arch/x86/ia32/ptrace32.c
deleted file mode 100644
index 4a233ad6269c..000000000000
--- a/arch/x86/ia32/ptrace32.c
+++ /dev/null
@@ -1,404 +0,0 @@
1/*
2 * 32bit ptrace for x86-64.
3 *
4 * Copyright 2001,2002 Andi Kleen, SuSE Labs.
5 * Some parts copied from arch/i386/kernel/ptrace.c. See that file for earlier
6 * copyright.
7 *
8 * This allows to access 64bit processes too; but there is no way to see the extended
9 * register contents.
10 */
11
12#include <linux/kernel.h>
13#include <linux/stddef.h>
14#include <linux/sched.h>
15#include <linux/syscalls.h>
16#include <linux/unistd.h>
17#include <linux/mm.h>
18#include <linux/err.h>
19#include <linux/ptrace.h>
20#include <asm/ptrace.h>
21#include <asm/compat.h>
22#include <asm/uaccess.h>
23#include <asm/user32.h>
24#include <asm/user.h>
25#include <asm/errno.h>
26#include <asm/debugreg.h>
27#include <asm/i387.h>
28#include <asm/fpu32.h>
29#include <asm/ia32.h>
30
31/*
32 * Determines which flags the user has access to [1 = access, 0 = no access].
33 * Prohibits changing ID(21), VIP(20), VIF(19), VM(17), IOPL(12-13), IF(9).
34 * Also masks reserved bits (31-22, 15, 5, 3, 1).
35 */
36#define FLAG_MASK 0x54dd5UL
37
38#define R32(l,q) \
39 case offsetof(struct user32, regs.l): stack[offsetof(struct pt_regs, q)/8] = val; break
40
41static int putreg32(struct task_struct *child, unsigned regno, u32 val)
42{
43 int i;
44 __u64 *stack = (__u64 *)task_pt_regs(child);
45
46 switch (regno) {
47 case offsetof(struct user32, regs.fs):
48 if (val && (val & 3) != 3) return -EIO;
49 child->thread.fsindex = val & 0xffff;
50 break;
51 case offsetof(struct user32, regs.gs):
52 if (val && (val & 3) != 3) return -EIO;
53 child->thread.gsindex = val & 0xffff;
54 break;
55 case offsetof(struct user32, regs.ds):
56 if (val && (val & 3) != 3) return -EIO;
57 child->thread.ds = val & 0xffff;
58 break;
59 case offsetof(struct user32, regs.es):
60 child->thread.es = val & 0xffff;
61 break;
62 case offsetof(struct user32, regs.ss):
63 if ((val & 3) != 3) return -EIO;
64 stack[offsetof(struct pt_regs, ss)/8] = val & 0xffff;
65 break;
66 case offsetof(struct user32, regs.cs):
67 if ((val & 3) != 3) return -EIO;
68 stack[offsetof(struct pt_regs, cs)/8] = val & 0xffff;
69 break;
70
71 R32(ebx, rbx);
72 R32(ecx, rcx);
73 R32(edx, rdx);
74 R32(edi, rdi);
75 R32(esi, rsi);
76 R32(ebp, rbp);
77 R32(eax, rax);
78 R32(orig_eax, orig_rax);
79 R32(eip, rip);
80 R32(esp, rsp);
81
82 case offsetof(struct user32, regs.eflags): {
83 __u64 *flags = &stack[offsetof(struct pt_regs, eflags)/8];
84 val &= FLAG_MASK;
85 *flags = val | (*flags & ~FLAG_MASK);
86 break;
87 }
88
89 case offsetof(struct user32, u_debugreg[4]):
90 case offsetof(struct user32, u_debugreg[5]):
91 return -EIO;
92
93 case offsetof(struct user32, u_debugreg[0]):
94 child->thread.debugreg0 = val;
95 break;
96
97 case offsetof(struct user32, u_debugreg[1]):
98 child->thread.debugreg1 = val;
99 break;
100
101 case offsetof(struct user32, u_debugreg[2]):
102 child->thread.debugreg2 = val;
103 break;
104
105 case offsetof(struct user32, u_debugreg[3]):
106 child->thread.debugreg3 = val;
107 break;
108
109 case offsetof(struct user32, u_debugreg[6]):
110 child->thread.debugreg6 = val;
111 break;
112
113 case offsetof(struct user32, u_debugreg[7]):
114 val &= ~DR_CONTROL_RESERVED;
115 /* See arch/i386/kernel/ptrace.c for an explanation of
116 * this awkward check.*/
117 for(i=0; i<4; i++)
118 if ((0x5454 >> ((val >> (16 + 4*i)) & 0xf)) & 1)
119 return -EIO;
120 child->thread.debugreg7 = val;
121 if (val)
122 set_tsk_thread_flag(child, TIF_DEBUG);
123 else
124 clear_tsk_thread_flag(child, TIF_DEBUG);
125 break;
126
127 default:
128 if (regno > sizeof(struct user32) || (regno & 3))
129 return -EIO;
130
131 /* Other dummy fields in the virtual user structure are ignored */
132 break;
133 }
134 return 0;
135}
136
137#undef R32
138
139#define R32(l,q) \
140 case offsetof(struct user32, regs.l): *val = stack[offsetof(struct pt_regs, q)/8]; break
141
142static int getreg32(struct task_struct *child, unsigned regno, u32 *val)
143{
144 __u64 *stack = (__u64 *)task_pt_regs(child);
145
146 switch (regno) {
147 case offsetof(struct user32, regs.fs):
148 *val = child->thread.fsindex;
149 break;
150 case offsetof(struct user32, regs.gs):
151 *val = child->thread.gsindex;
152 break;
153 case offsetof(struct user32, regs.ds):
154 *val = child->thread.ds;
155 break;
156 case offsetof(struct user32, regs.es):
157 *val = child->thread.es;
158 break;
159
160 R32(cs, cs);
161 R32(ss, ss);
162 R32(ebx, rbx);
163 R32(ecx, rcx);
164 R32(edx, rdx);
165 R32(edi, rdi);
166 R32(esi, rsi);
167 R32(ebp, rbp);
168 R32(eax, rax);
169 R32(orig_eax, orig_rax);
170 R32(eip, rip);
171 R32(eflags, eflags);
172 R32(esp, rsp);
173
174 case offsetof(struct user32, u_debugreg[0]):
175 *val = child->thread.debugreg0;
176 break;
177 case offsetof(struct user32, u_debugreg[1]):
178 *val = child->thread.debugreg1;
179 break;
180 case offsetof(struct user32, u_debugreg[2]):
181 *val = child->thread.debugreg2;
182 break;
183 case offsetof(struct user32, u_debugreg[3]):
184 *val = child->thread.debugreg3;
185 break;
186 case offsetof(struct user32, u_debugreg[6]):
187 *val = child->thread.debugreg6;
188 break;
189 case offsetof(struct user32, u_debugreg[7]):
190 *val = child->thread.debugreg7;
191 break;
192
193 default:
194 if (regno > sizeof(struct user32) || (regno & 3))
195 return -EIO;
196
197 /* Other dummy fields in the virtual user structure are ignored */
198 *val = 0;
199 break;
200 }
201 return 0;
202}
203
204#undef R32
205
206static long ptrace32_siginfo(unsigned request, u32 pid, u32 addr, u32 data)
207{
208 int ret;
209 compat_siginfo_t __user *si32 = compat_ptr(data);
210 siginfo_t ssi;
211 siginfo_t __user *si = compat_alloc_user_space(sizeof(siginfo_t));
212 if (request == PTRACE_SETSIGINFO) {
213 memset(&ssi, 0, sizeof(siginfo_t));
214 ret = copy_siginfo_from_user32(&ssi, si32);
215 if (ret)
216 return ret;
217 if (copy_to_user(si, &ssi, sizeof(siginfo_t)))
218 return -EFAULT;
219 }
220 ret = sys_ptrace(request, pid, addr, (unsigned long)si);
221 if (ret)
222 return ret;
223 if (request == PTRACE_GETSIGINFO) {
224 if (copy_from_user(&ssi, si, sizeof(siginfo_t)))
225 return -EFAULT;
226 ret = copy_siginfo_to_user32(si32, &ssi);
227 }
228 return ret;
229}
230
231asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
232{
233 struct task_struct *child;
234 struct pt_regs *childregs;
235 void __user *datap = compat_ptr(data);
236 int ret;
237 __u32 val;
238
239 switch (request) {
240 case PTRACE_TRACEME:
241 case PTRACE_ATTACH:
242 case PTRACE_KILL:
243 case PTRACE_CONT:
244 case PTRACE_SINGLESTEP:
245 case PTRACE_DETACH:
246 case PTRACE_SYSCALL:
247 case PTRACE_OLDSETOPTIONS:
248 case PTRACE_SETOPTIONS:
249 case PTRACE_SET_THREAD_AREA:
250 case PTRACE_GET_THREAD_AREA:
251 return sys_ptrace(request, pid, addr, data);
252
253 default:
254 return -EINVAL;
255
256 case PTRACE_PEEKTEXT:
257 case PTRACE_PEEKDATA:
258 case PTRACE_POKEDATA:
259 case PTRACE_POKETEXT:
260 case PTRACE_POKEUSR:
261 case PTRACE_PEEKUSR:
262 case PTRACE_GETREGS:
263 case PTRACE_SETREGS:
264 case PTRACE_SETFPREGS:
265 case PTRACE_GETFPREGS:
266 case PTRACE_SETFPXREGS:
267 case PTRACE_GETFPXREGS:
268 case PTRACE_GETEVENTMSG:
269 break;
270
271 case PTRACE_SETSIGINFO:
272 case PTRACE_GETSIGINFO:
273 return ptrace32_siginfo(request, pid, addr, data);
274 }
275
276 child = ptrace_get_task_struct(pid);
277 if (IS_ERR(child))
278 return PTR_ERR(child);
279
280 ret = ptrace_check_attach(child, request == PTRACE_KILL);
281 if (ret < 0)
282 goto out;
283
284 childregs = task_pt_regs(child);
285
286 switch (request) {
287 case PTRACE_PEEKDATA:
288 case PTRACE_PEEKTEXT:
289 ret = 0;
290 if (access_process_vm(child, addr, &val, sizeof(u32), 0)!=sizeof(u32))
291 ret = -EIO;
292 else
293 ret = put_user(val, (unsigned int __user *)datap);
294 break;
295
296 case PTRACE_POKEDATA:
297 case PTRACE_POKETEXT:
298 ret = 0;
299 if (access_process_vm(child, addr, &data, sizeof(u32), 1)!=sizeof(u32))
300 ret = -EIO;
301 break;
302
303 case PTRACE_PEEKUSR:
304 ret = getreg32(child, addr, &val);
305 if (ret == 0)
306 ret = put_user(val, (__u32 __user *)datap);
307 break;
308
309 case PTRACE_POKEUSR:
310 ret = putreg32(child, addr, data);
311 break;
312
313 case PTRACE_GETREGS: { /* Get all gp regs from the child. */
314 int i;
315 if (!access_ok(VERIFY_WRITE, datap, 16*4)) {
316 ret = -EIO;
317 break;
318 }
319 ret = 0;
320 for ( i = 0; i <= 16*4 ; i += sizeof(__u32) ) {
321 getreg32(child, i, &val);
322 ret |= __put_user(val,(u32 __user *)datap);
323 datap += sizeof(u32);
324 }
325 break;
326 }
327
328 case PTRACE_SETREGS: { /* Set all gp regs in the child. */
329 unsigned long tmp;
330 int i;
331 if (!access_ok(VERIFY_READ, datap, 16*4)) {
332 ret = -EIO;
333 break;
334 }
335 ret = 0;
336 for ( i = 0; i <= 16*4; i += sizeof(u32) ) {
337 ret |= __get_user(tmp, (u32 __user *)datap);
338 putreg32(child, i, tmp);
339 datap += sizeof(u32);
340 }
341 break;
342 }
343
344 case PTRACE_GETFPREGS:
345 ret = -EIO;
346 if (!access_ok(VERIFY_READ, compat_ptr(data),
347 sizeof(struct user_i387_struct)))
348 break;
349 save_i387_ia32(child, datap, childregs, 1);
350 ret = 0;
351 break;
352
353 case PTRACE_SETFPREGS:
354 ret = -EIO;
355 if (!access_ok(VERIFY_WRITE, datap,
356 sizeof(struct user_i387_struct)))
357 break;
358 ret = 0;
359 /* don't check EFAULT to be bug-to-bug compatible to i386 */
360 restore_i387_ia32(child, datap, 1);
361 break;
362
363 case PTRACE_GETFPXREGS: {
364 struct user32_fxsr_struct __user *u = datap;
365 init_fpu(child);
366 ret = -EIO;
367 if (!access_ok(VERIFY_WRITE, u, sizeof(*u)))
368 break;
369 ret = -EFAULT;
370 if (__copy_to_user(u, &child->thread.i387.fxsave, sizeof(*u)))
371 break;
372 ret = __put_user(childregs->cs, &u->fcs);
373 ret |= __put_user(child->thread.ds, &u->fos);
374 break;
375 }
376 case PTRACE_SETFPXREGS: {
377 struct user32_fxsr_struct __user *u = datap;
378 unlazy_fpu(child);
379 ret = -EIO;
380 if (!access_ok(VERIFY_READ, u, sizeof(*u)))
381 break;
382 /* no checking to be bug-to-bug compatible with i386. */
383 /* but silence warning */
384 if (__copy_from_user(&child->thread.i387.fxsave, u, sizeof(*u)))
385 ;
386 set_stopped_child_used_math(child);
387 child->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask;
388 ret = 0;
389 break;
390 }
391
392 case PTRACE_GETEVENTMSG:
393 ret = put_user(child->ptrace_message,(unsigned int __user *)compat_ptr(data));
394 break;
395
396 default:
397 BUG();
398 }
399
400 out:
401 put_task_struct(child);
402 return ret;
403}
404
diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c
index bee96d614432..abf71d26fc2a 100644
--- a/arch/x86/ia32/sys_ia32.c
+++ b/arch/x86/ia32/sys_ia32.c
@@ -1,29 +1,29 @@
1/* 1/*
2 * sys_ia32.c: Conversion between 32bit and 64bit native syscalls. Based on 2 * sys_ia32.c: Conversion between 32bit and 64bit native syscalls. Based on
3 * sys_sparc32 3 * sys_sparc32
4 * 4 *
5 * Copyright (C) 2000 VA Linux Co 5 * Copyright (C) 2000 VA Linux Co
6 * Copyright (C) 2000 Don Dugger <n0ano@valinux.com> 6 * Copyright (C) 2000 Don Dugger <n0ano@valinux.com>
7 * Copyright (C) 1999 Arun Sharma <arun.sharma@intel.com> 7 * Copyright (C) 1999 Arun Sharma <arun.sharma@intel.com>
8 * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) 8 * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
9 * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) 9 * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
10 * Copyright (C) 2000 Hewlett-Packard Co. 10 * Copyright (C) 2000 Hewlett-Packard Co.
11 * Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com> 11 * Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com>
12 * Copyright (C) 2000,2001,2002 Andi Kleen, SuSE Labs (x86-64 port) 12 * Copyright (C) 2000,2001,2002 Andi Kleen, SuSE Labs (x86-64 port)
13 * 13 *
14 * These routines maintain argument size conversion between 32bit and 64bit 14 * These routines maintain argument size conversion between 32bit and 64bit
15 * environment. In 2.5 most of this should be moved to a generic directory. 15 * environment. In 2.5 most of this should be moved to a generic directory.
16 * 16 *
17 * This file assumes that there is a hole at the end of user address space. 17 * This file assumes that there is a hole at the end of user address space.
18 * 18 *
19 * Some of the functions are LE specific currently. These are hopefully all marked. 19 * Some of the functions are LE specific currently. These are
20 * This should be fixed. 20 * hopefully all marked. This should be fixed.
21 */ 21 */
22 22
23#include <linux/kernel.h> 23#include <linux/kernel.h>
24#include <linux/sched.h> 24#include <linux/sched.h>
25#include <linux/fs.h> 25#include <linux/fs.h>
26#include <linux/file.h> 26#include <linux/file.h>
27#include <linux/signal.h> 27#include <linux/signal.h>
28#include <linux/syscalls.h> 28#include <linux/syscalls.h>
29#include <linux/resource.h> 29#include <linux/resource.h>
@@ -90,43 +90,44 @@ int cp_compat_stat(struct kstat *kbuf, struct compat_stat __user *ubuf)
90 if (sizeof(ino) < sizeof(kbuf->ino) && ino != kbuf->ino) 90 if (sizeof(ino) < sizeof(kbuf->ino) && ino != kbuf->ino)
91 return -EOVERFLOW; 91 return -EOVERFLOW;
92 if (!access_ok(VERIFY_WRITE, ubuf, sizeof(struct compat_stat)) || 92 if (!access_ok(VERIFY_WRITE, ubuf, sizeof(struct compat_stat)) ||
93 __put_user (old_encode_dev(kbuf->dev), &ubuf->st_dev) || 93 __put_user(old_encode_dev(kbuf->dev), &ubuf->st_dev) ||
94 __put_user (ino, &ubuf->st_ino) || 94 __put_user(ino, &ubuf->st_ino) ||
95 __put_user (kbuf->mode, &ubuf->st_mode) || 95 __put_user(kbuf->mode, &ubuf->st_mode) ||
96 __put_user (kbuf->nlink, &ubuf->st_nlink) || 96 __put_user(kbuf->nlink, &ubuf->st_nlink) ||
97 __put_user (uid, &ubuf->st_uid) || 97 __put_user(uid, &ubuf->st_uid) ||
98 __put_user (gid, &ubuf->st_gid) || 98 __put_user(gid, &ubuf->st_gid) ||
99 __put_user (old_encode_dev(kbuf->rdev), &ubuf->st_rdev) || 99 __put_user(old_encode_dev(kbuf->rdev), &ubuf->st_rdev) ||
100 __put_user (kbuf->size, &ubuf->st_size) || 100 __put_user(kbuf->size, &ubuf->st_size) ||
101 __put_user (kbuf->atime.tv_sec, &ubuf->st_atime) || 101 __put_user(kbuf->atime.tv_sec, &ubuf->st_atime) ||
102 __put_user (kbuf->atime.tv_nsec, &ubuf->st_atime_nsec) || 102 __put_user(kbuf->atime.tv_nsec, &ubuf->st_atime_nsec) ||
103 __put_user (kbuf->mtime.tv_sec, &ubuf->st_mtime) || 103 __put_user(kbuf->mtime.tv_sec, &ubuf->st_mtime) ||
104 __put_user (kbuf->mtime.tv_nsec, &ubuf->st_mtime_nsec) || 104 __put_user(kbuf->mtime.tv_nsec, &ubuf->st_mtime_nsec) ||
105 __put_user (kbuf->ctime.tv_sec, &ubuf->st_ctime) || 105 __put_user(kbuf->ctime.tv_sec, &ubuf->st_ctime) ||
106 __put_user (kbuf->ctime.tv_nsec, &ubuf->st_ctime_nsec) || 106 __put_user(kbuf->ctime.tv_nsec, &ubuf->st_ctime_nsec) ||
107 __put_user (kbuf->blksize, &ubuf->st_blksize) || 107 __put_user(kbuf->blksize, &ubuf->st_blksize) ||
108 __put_user (kbuf->blocks, &ubuf->st_blocks)) 108 __put_user(kbuf->blocks, &ubuf->st_blocks))
109 return -EFAULT; 109 return -EFAULT;
110 return 0; 110 return 0;
111} 111}
112 112
113asmlinkage long 113asmlinkage long sys32_truncate64(char __user *filename,
114sys32_truncate64(char __user * filename, unsigned long offset_low, unsigned long offset_high) 114 unsigned long offset_low,
115 unsigned long offset_high)
115{ 116{
116 return sys_truncate(filename, ((loff_t) offset_high << 32) | offset_low); 117 return sys_truncate(filename, ((loff_t) offset_high << 32) | offset_low);
117} 118}
118 119
119asmlinkage long 120asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long offset_low,
120sys32_ftruncate64(unsigned int fd, unsigned long offset_low, unsigned long offset_high) 121 unsigned long offset_high)
121{ 122{
122 return sys_ftruncate(fd, ((loff_t) offset_high << 32) | offset_low); 123 return sys_ftruncate(fd, ((loff_t) offset_high << 32) | offset_low);
123} 124}
124 125
125/* Another set for IA32/LFS -- x86_64 struct stat is different due to 126/*
126 support for 64bit inode numbers. */ 127 * Another set for IA32/LFS -- x86_64 struct stat is different due to
127 128 * support for 64bit inode numbers.
128static int 129 */
129cp_stat64(struct stat64 __user *ubuf, struct kstat *stat) 130static int cp_stat64(struct stat64 __user *ubuf, struct kstat *stat)
130{ 131{
131 typeof(ubuf->st_uid) uid = 0; 132 typeof(ubuf->st_uid) uid = 0;
132 typeof(ubuf->st_gid) gid = 0; 133 typeof(ubuf->st_gid) gid = 0;
@@ -134,38 +135,39 @@ cp_stat64(struct stat64 __user *ubuf, struct kstat *stat)
134 SET_GID(gid, stat->gid); 135 SET_GID(gid, stat->gid);
135 if (!access_ok(VERIFY_WRITE, ubuf, sizeof(struct stat64)) || 136 if (!access_ok(VERIFY_WRITE, ubuf, sizeof(struct stat64)) ||
136 __put_user(huge_encode_dev(stat->dev), &ubuf->st_dev) || 137 __put_user(huge_encode_dev(stat->dev), &ubuf->st_dev) ||
137 __put_user (stat->ino, &ubuf->__st_ino) || 138 __put_user(stat->ino, &ubuf->__st_ino) ||
138 __put_user (stat->ino, &ubuf->st_ino) || 139 __put_user(stat->ino, &ubuf->st_ino) ||
139 __put_user (stat->mode, &ubuf->st_mode) || 140 __put_user(stat->mode, &ubuf->st_mode) ||
140 __put_user (stat->nlink, &ubuf->st_nlink) || 141 __put_user(stat->nlink, &ubuf->st_nlink) ||
141 __put_user (uid, &ubuf->st_uid) || 142 __put_user(uid, &ubuf->st_uid) ||
142 __put_user (gid, &ubuf->st_gid) || 143 __put_user(gid, &ubuf->st_gid) ||
143 __put_user (huge_encode_dev(stat->rdev), &ubuf->st_rdev) || 144 __put_user(huge_encode_dev(stat->rdev), &ubuf->st_rdev) ||
144 __put_user (stat->size, &ubuf->st_size) || 145 __put_user(stat->size, &ubuf->st_size) ||
145 __put_user (stat->atime.tv_sec, &ubuf->st_atime) || 146 __put_user(stat->atime.tv_sec, &ubuf->st_atime) ||
146 __put_user (stat->atime.tv_nsec, &ubuf->st_atime_nsec) || 147 __put_user(stat->atime.tv_nsec, &ubuf->st_atime_nsec) ||
147 __put_user (stat->mtime.tv_sec, &ubuf->st_mtime) || 148 __put_user(stat->mtime.tv_sec, &ubuf->st_mtime) ||
148 __put_user (stat->mtime.tv_nsec, &ubuf->st_mtime_nsec) || 149 __put_user(stat->mtime.tv_nsec, &ubuf->st_mtime_nsec) ||
149 __put_user (stat->ctime.tv_sec, &ubuf->st_ctime) || 150 __put_user(stat->ctime.tv_sec, &ubuf->st_ctime) ||
150 __put_user (stat->ctime.tv_nsec, &ubuf->st_ctime_nsec) || 151 __put_user(stat->ctime.tv_nsec, &ubuf->st_ctime_nsec) ||
151 __put_user (stat->blksize, &ubuf->st_blksize) || 152 __put_user(stat->blksize, &ubuf->st_blksize) ||
152 __put_user (stat->blocks, &ubuf->st_blocks)) 153 __put_user(stat->blocks, &ubuf->st_blocks))
153 return -EFAULT; 154 return -EFAULT;
154 return 0; 155 return 0;
155} 156}
156 157
157asmlinkage long 158asmlinkage long sys32_stat64(char __user *filename,
158sys32_stat64(char __user * filename, struct stat64 __user *statbuf) 159 struct stat64 __user *statbuf)
159{ 160{
160 struct kstat stat; 161 struct kstat stat;
161 int ret = vfs_stat(filename, &stat); 162 int ret = vfs_stat(filename, &stat);
163
162 if (!ret) 164 if (!ret)
163 ret = cp_stat64(statbuf, &stat); 165 ret = cp_stat64(statbuf, &stat);
164 return ret; 166 return ret;
165} 167}
166 168
167asmlinkage long 169asmlinkage long sys32_lstat64(char __user *filename,
168sys32_lstat64(char __user * filename, struct stat64 __user *statbuf) 170 struct stat64 __user *statbuf)
169{ 171{
170 struct kstat stat; 172 struct kstat stat;
171 int ret = vfs_lstat(filename, &stat); 173 int ret = vfs_lstat(filename, &stat);
@@ -174,8 +176,7 @@ sys32_lstat64(char __user * filename, struct stat64 __user *statbuf)
174 return ret; 176 return ret;
175} 177}
176 178
177asmlinkage long 179asmlinkage long sys32_fstat64(unsigned int fd, struct stat64 __user *statbuf)
178sys32_fstat64(unsigned int fd, struct stat64 __user *statbuf)
179{ 180{
180 struct kstat stat; 181 struct kstat stat;
181 int ret = vfs_fstat(fd, &stat); 182 int ret = vfs_fstat(fd, &stat);
@@ -184,9 +185,8 @@ sys32_fstat64(unsigned int fd, struct stat64 __user *statbuf)
184 return ret; 185 return ret;
185} 186}
186 187
187asmlinkage long 188asmlinkage long sys32_fstatat(unsigned int dfd, char __user *filename,
188sys32_fstatat(unsigned int dfd, char __user *filename, 189 struct stat64 __user *statbuf, int flag)
189 struct stat64 __user* statbuf, int flag)
190{ 190{
191 struct kstat stat; 191 struct kstat stat;
192 int error = -EINVAL; 192 int error = -EINVAL;
@@ -221,8 +221,7 @@ struct mmap_arg_struct {
221 unsigned int offset; 221 unsigned int offset;
222}; 222};
223 223
224asmlinkage long 224asmlinkage long sys32_mmap(struct mmap_arg_struct __user *arg)
225sys32_mmap(struct mmap_arg_struct __user *arg)
226{ 225{
227 struct mmap_arg_struct a; 226 struct mmap_arg_struct a;
228 struct file *file = NULL; 227 struct file *file = NULL;
@@ -233,33 +232,33 @@ sys32_mmap(struct mmap_arg_struct __user *arg)
233 return -EFAULT; 232 return -EFAULT;
234 233
235 if (a.offset & ~PAGE_MASK) 234 if (a.offset & ~PAGE_MASK)
236 return -EINVAL; 235 return -EINVAL;
237 236
238 if (!(a.flags & MAP_ANONYMOUS)) { 237 if (!(a.flags & MAP_ANONYMOUS)) {
239 file = fget(a.fd); 238 file = fget(a.fd);
240 if (!file) 239 if (!file)
241 return -EBADF; 240 return -EBADF;
242 } 241 }
243 242
244 mm = current->mm; 243 mm = current->mm;
245 down_write(&mm->mmap_sem); 244 down_write(&mm->mmap_sem);
246 retval = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, a.offset>>PAGE_SHIFT); 245 retval = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags,
246 a.offset>>PAGE_SHIFT);
247 if (file) 247 if (file)
248 fput(file); 248 fput(file);
249 249
250 up_write(&mm->mmap_sem); 250 up_write(&mm->mmap_sem);
251 251
252 return retval; 252 return retval;
253} 253}
254 254
255asmlinkage long 255asmlinkage long sys32_mprotect(unsigned long start, size_t len,
256sys32_mprotect(unsigned long start, size_t len, unsigned long prot) 256 unsigned long prot)
257{ 257{
258 return sys_mprotect(start,len,prot); 258 return sys_mprotect(start, len, prot);
259} 259}
260 260
261asmlinkage long 261asmlinkage long sys32_pipe(int __user *fd)
262sys32_pipe(int __user *fd)
263{ 262{
264 int retval; 263 int retval;
265 int fds[2]; 264 int fds[2];
@@ -269,13 +268,13 @@ sys32_pipe(int __user *fd)
269 goto out; 268 goto out;
270 if (copy_to_user(fd, fds, sizeof(fds))) 269 if (copy_to_user(fd, fds, sizeof(fds)))
271 retval = -EFAULT; 270 retval = -EFAULT;
272 out: 271out:
273 return retval; 272 return retval;
274} 273}
275 274
276asmlinkage long 275asmlinkage long sys32_rt_sigaction(int sig, struct sigaction32 __user *act,
277sys32_rt_sigaction(int sig, struct sigaction32 __user *act, 276 struct sigaction32 __user *oact,
278 struct sigaction32 __user *oact, unsigned int sigsetsize) 277 unsigned int sigsetsize)
279{ 278{
280 struct k_sigaction new_ka, old_ka; 279 struct k_sigaction new_ka, old_ka;
281 int ret; 280 int ret;
@@ -291,12 +290,17 @@ sys32_rt_sigaction(int sig, struct sigaction32 __user *act,
291 if (!access_ok(VERIFY_READ, act, sizeof(*act)) || 290 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
292 __get_user(handler, &act->sa_handler) || 291 __get_user(handler, &act->sa_handler) ||
293 __get_user(new_ka.sa.sa_flags, &act->sa_flags) || 292 __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
294 __get_user(restorer, &act->sa_restorer)|| 293 __get_user(restorer, &act->sa_restorer) ||
295 __copy_from_user(&set32, &act->sa_mask, sizeof(compat_sigset_t))) 294 __copy_from_user(&set32, &act->sa_mask,
295 sizeof(compat_sigset_t)))
296 return -EFAULT; 296 return -EFAULT;
297 new_ka.sa.sa_handler = compat_ptr(handler); 297 new_ka.sa.sa_handler = compat_ptr(handler);
298 new_ka.sa.sa_restorer = compat_ptr(restorer); 298 new_ka.sa.sa_restorer = compat_ptr(restorer);
299 /* FIXME: here we rely on _COMPAT_NSIG_WORS to be >= than _NSIG_WORDS << 1 */ 299
300 /*
301 * FIXME: here we rely on _COMPAT_NSIG_WORS to be >=
302 * than _NSIG_WORDS << 1
303 */
300 switch (_NSIG_WORDS) { 304 switch (_NSIG_WORDS) {
301 case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6] 305 case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6]
302 | (((long)set32.sig[7]) << 32); 306 | (((long)set32.sig[7]) << 32);
@@ -312,7 +316,10 @@ sys32_rt_sigaction(int sig, struct sigaction32 __user *act,
312 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); 316 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
313 317
314 if (!ret && oact) { 318 if (!ret && oact) {
315 /* FIXME: here we rely on _COMPAT_NSIG_WORS to be >= than _NSIG_WORDS << 1 */ 319 /*
320 * FIXME: here we rely on _COMPAT_NSIG_WORS to be >=
321 * than _NSIG_WORDS << 1
322 */
316 switch (_NSIG_WORDS) { 323 switch (_NSIG_WORDS) {
317 case 4: 324 case 4:
318 set32.sig[7] = (old_ka.sa.sa_mask.sig[3] >> 32); 325 set32.sig[7] = (old_ka.sa.sa_mask.sig[3] >> 32);
@@ -328,23 +335,26 @@ sys32_rt_sigaction(int sig, struct sigaction32 __user *act,
328 set32.sig[0] = old_ka.sa.sa_mask.sig[0]; 335 set32.sig[0] = old_ka.sa.sa_mask.sig[0];
329 } 336 }
330 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || 337 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
331 __put_user(ptr_to_compat(old_ka.sa.sa_handler), &oact->sa_handler) || 338 __put_user(ptr_to_compat(old_ka.sa.sa_handler),
332 __put_user(ptr_to_compat(old_ka.sa.sa_restorer), &oact->sa_restorer) || 339 &oact->sa_handler) ||
340 __put_user(ptr_to_compat(old_ka.sa.sa_restorer),
341 &oact->sa_restorer) ||
333 __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || 342 __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
334 __copy_to_user(&oact->sa_mask, &set32, sizeof(compat_sigset_t))) 343 __copy_to_user(&oact->sa_mask, &set32,
344 sizeof(compat_sigset_t)))
335 return -EFAULT; 345 return -EFAULT;
336 } 346 }
337 347
338 return ret; 348 return ret;
339} 349}
340 350
341asmlinkage long 351asmlinkage long sys32_sigaction(int sig, struct old_sigaction32 __user *act,
342sys32_sigaction (int sig, struct old_sigaction32 __user *act, struct old_sigaction32 __user *oact) 352 struct old_sigaction32 __user *oact)
343{ 353{
344 struct k_sigaction new_ka, old_ka; 354 struct k_sigaction new_ka, old_ka;
345 int ret; 355 int ret;
346 356
347 if (act) { 357 if (act) {
348 compat_old_sigset_t mask; 358 compat_old_sigset_t mask;
349 compat_uptr_t handler, restorer; 359 compat_uptr_t handler, restorer;
350 360
@@ -359,33 +369,35 @@ sys32_sigaction (int sig, struct old_sigaction32 __user *act, struct old_sigacti
359 new_ka.sa.sa_restorer = compat_ptr(restorer); 369 new_ka.sa.sa_restorer = compat_ptr(restorer);
360 370
361 siginitset(&new_ka.sa.sa_mask, mask); 371 siginitset(&new_ka.sa.sa_mask, mask);
362 } 372 }
363 373
364 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); 374 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
365 375
366 if (!ret && oact) { 376 if (!ret && oact) {
367 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || 377 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
368 __put_user(ptr_to_compat(old_ka.sa.sa_handler), &oact->sa_handler) || 378 __put_user(ptr_to_compat(old_ka.sa.sa_handler),
369 __put_user(ptr_to_compat(old_ka.sa.sa_restorer), &oact->sa_restorer) || 379 &oact->sa_handler) ||
380 __put_user(ptr_to_compat(old_ka.sa.sa_restorer),
381 &oact->sa_restorer) ||
370 __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || 382 __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
371 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) 383 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
372 return -EFAULT; 384 return -EFAULT;
373 } 385 }
374 386
375 return ret; 387 return ret;
376} 388}
377 389
378asmlinkage long 390asmlinkage long sys32_rt_sigprocmask(int how, compat_sigset_t __user *set,
379sys32_rt_sigprocmask(int how, compat_sigset_t __user *set, 391 compat_sigset_t __user *oset,
380 compat_sigset_t __user *oset, unsigned int sigsetsize) 392 unsigned int sigsetsize)
381{ 393{
382 sigset_t s; 394 sigset_t s;
383 compat_sigset_t s32; 395 compat_sigset_t s32;
384 int ret; 396 int ret;
385 mm_segment_t old_fs = get_fs(); 397 mm_segment_t old_fs = get_fs();
386 398
387 if (set) { 399 if (set) {
388 if (copy_from_user (&s32, set, sizeof(compat_sigset_t))) 400 if (copy_from_user(&s32, set, sizeof(compat_sigset_t)))
389 return -EFAULT; 401 return -EFAULT;
390 switch (_NSIG_WORDS) { 402 switch (_NSIG_WORDS) {
391 case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32); 403 case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
@@ -394,13 +406,14 @@ sys32_rt_sigprocmask(int how, compat_sigset_t __user *set,
394 case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32); 406 case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
395 } 407 }
396 } 408 }
397 set_fs (KERNEL_DS); 409 set_fs(KERNEL_DS);
398 ret = sys_rt_sigprocmask(how, 410 ret = sys_rt_sigprocmask(how,
399 set ? (sigset_t __user *)&s : NULL, 411 set ? (sigset_t __user *)&s : NULL,
400 oset ? (sigset_t __user *)&s : NULL, 412 oset ? (sigset_t __user *)&s : NULL,
401 sigsetsize); 413 sigsetsize);
402 set_fs (old_fs); 414 set_fs(old_fs);
403 if (ret) return ret; 415 if (ret)
416 return ret;
404 if (oset) { 417 if (oset) {
405 switch (_NSIG_WORDS) { 418 switch (_NSIG_WORDS) {
406 case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3]; 419 case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
@@ -408,52 +421,49 @@ sys32_rt_sigprocmask(int how, compat_sigset_t __user *set,
408 case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1]; 421 case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
409 case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0]; 422 case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
410 } 423 }
411 if (copy_to_user (oset, &s32, sizeof(compat_sigset_t))) 424 if (copy_to_user(oset, &s32, sizeof(compat_sigset_t)))
412 return -EFAULT; 425 return -EFAULT;
413 } 426 }
414 return 0; 427 return 0;
415} 428}
416 429
417static inline long 430static inline long get_tv32(struct timeval *o, struct compat_timeval __user *i)
418get_tv32(struct timeval *o, struct compat_timeval __user *i)
419{ 431{
420 int err = -EFAULT; 432 int err = -EFAULT;
421 if (access_ok(VERIFY_READ, i, sizeof(*i))) { 433
434 if (access_ok(VERIFY_READ, i, sizeof(*i))) {
422 err = __get_user(o->tv_sec, &i->tv_sec); 435 err = __get_user(o->tv_sec, &i->tv_sec);
423 err |= __get_user(o->tv_usec, &i->tv_usec); 436 err |= __get_user(o->tv_usec, &i->tv_usec);
424 } 437 }
425 return err; 438 return err;
426} 439}
427 440
428static inline long 441static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i)
429put_tv32(struct compat_timeval __user *o, struct timeval *i)
430{ 442{
431 int err = -EFAULT; 443 int err = -EFAULT;
432 if (access_ok(VERIFY_WRITE, o, sizeof(*o))) { 444
445 if (access_ok(VERIFY_WRITE, o, sizeof(*o))) {
433 err = __put_user(i->tv_sec, &o->tv_sec); 446 err = __put_user(i->tv_sec, &o->tv_sec);
434 err |= __put_user(i->tv_usec, &o->tv_usec); 447 err |= __put_user(i->tv_usec, &o->tv_usec);
435 } 448 }
436 return err; 449 return err;
437} 450}
438 451
439extern unsigned int alarm_setitimer(unsigned int seconds); 452asmlinkage long sys32_alarm(unsigned int seconds)
440
441asmlinkage long
442sys32_alarm(unsigned int seconds)
443{ 453{
444 return alarm_setitimer(seconds); 454 return alarm_setitimer(seconds);
445} 455}
446 456
447/* Translations due to time_t size differences. Which affects all 457/*
448 sorts of things, like timeval and itimerval. */ 458 * Translations due to time_t size differences. Which affects all
449 459 * sorts of things, like timeval and itimerval.
450extern struct timezone sys_tz; 460 */
451 461asmlinkage long sys32_gettimeofday(struct compat_timeval __user *tv,
452asmlinkage long 462 struct timezone __user *tz)
453sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
454{ 463{
455 if (tv) { 464 if (tv) {
456 struct timeval ktv; 465 struct timeval ktv;
466
457 do_gettimeofday(&ktv); 467 do_gettimeofday(&ktv);
458 if (put_tv32(tv, &ktv)) 468 if (put_tv32(tv, &ktv))
459 return -EFAULT; 469 return -EFAULT;
@@ -465,14 +475,14 @@ sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
465 return 0; 475 return 0;
466} 476}
467 477
468asmlinkage long 478asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv,
469sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) 479 struct timezone __user *tz)
470{ 480{
471 struct timeval ktv; 481 struct timeval ktv;
472 struct timespec kts; 482 struct timespec kts;
473 struct timezone ktz; 483 struct timezone ktz;
474 484
475 if (tv) { 485 if (tv) {
476 if (get_tv32(&ktv, tv)) 486 if (get_tv32(&ktv, tv))
477 return -EFAULT; 487 return -EFAULT;
478 kts.tv_sec = ktv.tv_sec; 488 kts.tv_sec = ktv.tv_sec;
@@ -494,8 +504,7 @@ struct sel_arg_struct {
494 unsigned int tvp; 504 unsigned int tvp;
495}; 505};
496 506
497asmlinkage long 507asmlinkage long sys32_old_select(struct sel_arg_struct __user *arg)
498sys32_old_select(struct sel_arg_struct __user *arg)
499{ 508{
500 struct sel_arg_struct a; 509 struct sel_arg_struct a;
501 510
@@ -505,50 +514,45 @@ sys32_old_select(struct sel_arg_struct __user *arg)
505 compat_ptr(a.exp), compat_ptr(a.tvp)); 514 compat_ptr(a.exp), compat_ptr(a.tvp));
506} 515}
507 516
508extern asmlinkage long 517asmlinkage long sys32_waitpid(compat_pid_t pid, unsigned int *stat_addr,
509compat_sys_wait4(compat_pid_t pid, compat_uint_t * stat_addr, int options, 518 int options)
510 struct compat_rusage *ru);
511
512asmlinkage long
513sys32_waitpid(compat_pid_t pid, unsigned int *stat_addr, int options)
514{ 519{
515 return compat_sys_wait4(pid, stat_addr, options, NULL); 520 return compat_sys_wait4(pid, stat_addr, options, NULL);
516} 521}
517 522
518/* 32-bit timeval and related flotsam. */ 523/* 32-bit timeval and related flotsam. */
519 524
520asmlinkage long 525asmlinkage long sys32_sysfs(int option, u32 arg1, u32 arg2)
521sys32_sysfs(int option, u32 arg1, u32 arg2)
522{ 526{
523 return sys_sysfs(option, arg1, arg2); 527 return sys_sysfs(option, arg1, arg2);
524} 528}
525 529
526asmlinkage long 530asmlinkage long sys32_sched_rr_get_interval(compat_pid_t pid,
527sys32_sched_rr_get_interval(compat_pid_t pid, struct compat_timespec __user *interval) 531 struct compat_timespec __user *interval)
528{ 532{
529 struct timespec t; 533 struct timespec t;
530 int ret; 534 int ret;
531 mm_segment_t old_fs = get_fs (); 535 mm_segment_t old_fs = get_fs();
532 536
533 set_fs (KERNEL_DS); 537 set_fs(KERNEL_DS);
534 ret = sys_sched_rr_get_interval(pid, (struct timespec __user *)&t); 538 ret = sys_sched_rr_get_interval(pid, (struct timespec __user *)&t);
535 set_fs (old_fs); 539 set_fs(old_fs);
536 if (put_compat_timespec(&t, interval)) 540 if (put_compat_timespec(&t, interval))
537 return -EFAULT; 541 return -EFAULT;
538 return ret; 542 return ret;
539} 543}
540 544
541asmlinkage long 545asmlinkage long sys32_rt_sigpending(compat_sigset_t __user *set,
542sys32_rt_sigpending(compat_sigset_t __user *set, compat_size_t sigsetsize) 546 compat_size_t sigsetsize)
543{ 547{
544 sigset_t s; 548 sigset_t s;
545 compat_sigset_t s32; 549 compat_sigset_t s32;
546 int ret; 550 int ret;
547 mm_segment_t old_fs = get_fs(); 551 mm_segment_t old_fs = get_fs();
548 552
549 set_fs (KERNEL_DS); 553 set_fs(KERNEL_DS);
550 ret = sys_rt_sigpending((sigset_t __user *)&s, sigsetsize); 554 ret = sys_rt_sigpending((sigset_t __user *)&s, sigsetsize);
551 set_fs (old_fs); 555 set_fs(old_fs);
552 if (!ret) { 556 if (!ret) {
553 switch (_NSIG_WORDS) { 557 switch (_NSIG_WORDS) {
554 case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3]; 558 case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
@@ -556,30 +560,29 @@ sys32_rt_sigpending(compat_sigset_t __user *set, compat_size_t sigsetsize)
556 case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1]; 560 case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
557 case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0]; 561 case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
558 } 562 }
559 if (copy_to_user (set, &s32, sizeof(compat_sigset_t))) 563 if (copy_to_user(set, &s32, sizeof(compat_sigset_t)))
560 return -EFAULT; 564 return -EFAULT;
561 } 565 }
562 return ret; 566 return ret;
563} 567}
564 568
565asmlinkage long 569asmlinkage long sys32_rt_sigqueueinfo(int pid, int sig,
566sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo) 570 compat_siginfo_t __user *uinfo)
567{ 571{
568 siginfo_t info; 572 siginfo_t info;
569 int ret; 573 int ret;
570 mm_segment_t old_fs = get_fs(); 574 mm_segment_t old_fs = get_fs();
571 575
572 if (copy_siginfo_from_user32(&info, uinfo)) 576 if (copy_siginfo_from_user32(&info, uinfo))
573 return -EFAULT; 577 return -EFAULT;
574 set_fs (KERNEL_DS); 578 set_fs(KERNEL_DS);
575 ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *)&info); 579 ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *)&info);
576 set_fs (old_fs); 580 set_fs(old_fs);
577 return ret; 581 return ret;
578} 582}
579 583
580/* These are here just in case some old ia32 binary calls it. */ 584/* These are here just in case some old ia32 binary calls it. */
581asmlinkage long 585asmlinkage long sys32_pause(void)
582sys32_pause(void)
583{ 586{
584 current->state = TASK_INTERRUPTIBLE; 587 current->state = TASK_INTERRUPTIBLE;
585 schedule(); 588 schedule();
@@ -599,25 +602,25 @@ struct sysctl_ia32 {
599}; 602};
600 603
601 604
602asmlinkage long 605asmlinkage long sys32_sysctl(struct sysctl_ia32 __user *args32)
603sys32_sysctl(struct sysctl_ia32 __user *args32)
604{ 606{
605 struct sysctl_ia32 a32; 607 struct sysctl_ia32 a32;
606 mm_segment_t old_fs = get_fs (); 608 mm_segment_t old_fs = get_fs();
607 void __user *oldvalp, *newvalp; 609 void __user *oldvalp, *newvalp;
608 size_t oldlen; 610 size_t oldlen;
609 int __user *namep; 611 int __user *namep;
610 long ret; 612 long ret;
611 613
612 if (copy_from_user(&a32, args32, sizeof (a32))) 614 if (copy_from_user(&a32, args32, sizeof(a32)))
613 return -EFAULT; 615 return -EFAULT;
614 616
615 /* 617 /*
616 * We need to pre-validate these because we have to disable address checking 618 * We need to pre-validate these because we have to disable
617 * before calling do_sysctl() because of OLDLEN but we can't run the risk of the 619 * address checking before calling do_sysctl() because of
618 * user specifying bad addresses here. Well, since we're dealing with 32 bit 620 * OLDLEN but we can't run the risk of the user specifying bad
619 * addresses, we KNOW that access_ok() will always succeed, so this is an 621 * addresses here. Well, since we're dealing with 32 bit
620 * expensive NOP, but so what... 622 * addresses, we KNOW that access_ok() will always succeed, so
623 * this is an expensive NOP, but so what...
621 */ 624 */
622 namep = compat_ptr(a32.name); 625 namep = compat_ptr(a32.name);
623 oldvalp = compat_ptr(a32.oldval); 626 oldvalp = compat_ptr(a32.oldval);
@@ -636,34 +639,34 @@ sys32_sysctl(struct sysctl_ia32 __user *args32)
636 unlock_kernel(); 639 unlock_kernel();
637 set_fs(old_fs); 640 set_fs(old_fs);
638 641
639 if (oldvalp && put_user (oldlen, (int __user *)compat_ptr(a32.oldlenp))) 642 if (oldvalp && put_user(oldlen, (int __user *)compat_ptr(a32.oldlenp)))
640 return -EFAULT; 643 return -EFAULT;
641 644
642 return ret; 645 return ret;
643} 646}
644#endif 647#endif
645 648
646/* warning: next two assume little endian */ 649/* warning: next two assume little endian */
647asmlinkage long 650asmlinkage long sys32_pread(unsigned int fd, char __user *ubuf, u32 count,
648sys32_pread(unsigned int fd, char __user *ubuf, u32 count, u32 poslo, u32 poshi) 651 u32 poslo, u32 poshi)
649{ 652{
650 return sys_pread64(fd, ubuf, count, 653 return sys_pread64(fd, ubuf, count,
651 ((loff_t)AA(poshi) << 32) | AA(poslo)); 654 ((loff_t)AA(poshi) << 32) | AA(poslo));
652} 655}
653 656
654asmlinkage long 657asmlinkage long sys32_pwrite(unsigned int fd, char __user *ubuf, u32 count,
655sys32_pwrite(unsigned int fd, char __user *ubuf, u32 count, u32 poslo, u32 poshi) 658 u32 poslo, u32 poshi)
656{ 659{
657 return sys_pwrite64(fd, ubuf, count, 660 return sys_pwrite64(fd, ubuf, count,
658 ((loff_t)AA(poshi) << 32) | AA(poslo)); 661 ((loff_t)AA(poshi) << 32) | AA(poslo));
659} 662}
660 663
661 664
662asmlinkage long 665asmlinkage long sys32_personality(unsigned long personality)
663sys32_personality(unsigned long personality)
664{ 666{
665 int ret; 667 int ret;
666 if (personality(current->personality) == PER_LINUX32 && 668
669 if (personality(current->personality) == PER_LINUX32 &&
667 personality == PER_LINUX) 670 personality == PER_LINUX)
668 personality = PER_LINUX32; 671 personality = PER_LINUX32;
669 ret = sys_personality(personality); 672 ret = sys_personality(personality);
@@ -672,34 +675,33 @@ sys32_personality(unsigned long personality)
672 return ret; 675 return ret;
673} 676}
674 677
675asmlinkage long 678asmlinkage long sys32_sendfile(int out_fd, int in_fd,
676sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset, s32 count) 679 compat_off_t __user *offset, s32 count)
677{ 680{
678 mm_segment_t old_fs = get_fs(); 681 mm_segment_t old_fs = get_fs();
679 int ret; 682 int ret;
680 off_t of; 683 off_t of;
681 684
682 if (offset && get_user(of, offset)) 685 if (offset && get_user(of, offset))
683 return -EFAULT; 686 return -EFAULT;
684 687
685 set_fs(KERNEL_DS); 688 set_fs(KERNEL_DS);
686 ret = sys_sendfile(out_fd, in_fd, offset ? (off_t __user *)&of : NULL, 689 ret = sys_sendfile(out_fd, in_fd, offset ? (off_t __user *)&of : NULL,
687 count); 690 count);
688 set_fs(old_fs); 691 set_fs(old_fs);
689 692
690 if (offset && put_user(of, offset)) 693 if (offset && put_user(of, offset))
691 return -EFAULT; 694 return -EFAULT;
692
693 return ret; 695 return ret;
694} 696}
695 697
696asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len, 698asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len,
697 unsigned long prot, unsigned long flags, 699 unsigned long prot, unsigned long flags,
698 unsigned long fd, unsigned long pgoff) 700 unsigned long fd, unsigned long pgoff)
699{ 701{
700 struct mm_struct *mm = current->mm; 702 struct mm_struct *mm = current->mm;
701 unsigned long error; 703 unsigned long error;
702 struct file * file = NULL; 704 struct file *file = NULL;
703 705
704 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); 706 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
705 if (!(flags & MAP_ANONYMOUS)) { 707 if (!(flags & MAP_ANONYMOUS)) {
@@ -717,36 +719,35 @@ asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len,
717 return error; 719 return error;
718} 720}
719 721
720asmlinkage long sys32_olduname(struct oldold_utsname __user * name) 722asmlinkage long sys32_olduname(struct oldold_utsname __user *name)
721{ 723{
724 char *arch = "x86_64";
722 int err; 725 int err;
723 726
724 if (!name) 727 if (!name)
725 return -EFAULT; 728 return -EFAULT;
726 if (!access_ok(VERIFY_WRITE, name, sizeof(struct oldold_utsname))) 729 if (!access_ok(VERIFY_WRITE, name, sizeof(struct oldold_utsname)))
727 return -EFAULT; 730 return -EFAULT;
728 731
729 down_read(&uts_sem); 732 down_read(&uts_sem);
730 733
731 err = __copy_to_user(&name->sysname,&utsname()->sysname, 734 err = __copy_to_user(&name->sysname, &utsname()->sysname,
732 __OLD_UTS_LEN); 735 __OLD_UTS_LEN);
733 err |= __put_user(0,name->sysname+__OLD_UTS_LEN); 736 err |= __put_user(0, name->sysname+__OLD_UTS_LEN);
734 err |= __copy_to_user(&name->nodename,&utsname()->nodename, 737 err |= __copy_to_user(&name->nodename, &utsname()->nodename,
735 __OLD_UTS_LEN); 738 __OLD_UTS_LEN);
736 err |= __put_user(0,name->nodename+__OLD_UTS_LEN); 739 err |= __put_user(0, name->nodename+__OLD_UTS_LEN);
737 err |= __copy_to_user(&name->release,&utsname()->release, 740 err |= __copy_to_user(&name->release, &utsname()->release,
738 __OLD_UTS_LEN); 741 __OLD_UTS_LEN);
739 err |= __put_user(0,name->release+__OLD_UTS_LEN); 742 err |= __put_user(0, name->release+__OLD_UTS_LEN);
740 err |= __copy_to_user(&name->version,&utsname()->version, 743 err |= __copy_to_user(&name->version, &utsname()->version,
741 __OLD_UTS_LEN); 744 __OLD_UTS_LEN);
742 err |= __put_user(0,name->version+__OLD_UTS_LEN); 745 err |= __put_user(0, name->version+__OLD_UTS_LEN);
743 { 746
744 char *arch = "x86_64"; 747 if (personality(current->personality) == PER_LINUX32)
745 if (personality(current->personality) == PER_LINUX32) 748 arch = "i686";
746 arch = "i686"; 749
747 750 err |= __copy_to_user(&name->machine, arch, strlen(arch) + 1);
748 err |= __copy_to_user(&name->machine, arch, strlen(arch)+1);
749 }
750 751
751 up_read(&uts_sem); 752 up_read(&uts_sem);
752 753
@@ -755,17 +756,19 @@ asmlinkage long sys32_olduname(struct oldold_utsname __user * name)
755 return err; 756 return err;
756} 757}
757 758
758long sys32_uname(struct old_utsname __user * name) 759long sys32_uname(struct old_utsname __user *name)
759{ 760{
760 int err; 761 int err;
762
761 if (!name) 763 if (!name)
762 return -EFAULT; 764 return -EFAULT;
763 down_read(&uts_sem); 765 down_read(&uts_sem);
764 err = copy_to_user(name, utsname(), sizeof (*name)); 766 err = copy_to_user(name, utsname(), sizeof(*name));
765 up_read(&uts_sem); 767 up_read(&uts_sem);
766 if (personality(current->personality) == PER_LINUX32) 768 if (personality(current->personality) == PER_LINUX32)
767 err |= copy_to_user(&name->machine, "i686", 5); 769 err |= copy_to_user(&name->machine, "i686", 5);
768 return err?-EFAULT:0; 770
771 return err ? -EFAULT : 0;
769} 772}
770 773
771long sys32_ustat(unsigned dev, struct ustat32 __user *u32p) 774long sys32_ustat(unsigned dev, struct ustat32 __user *u32p)
@@ -773,27 +776,28 @@ long sys32_ustat(unsigned dev, struct ustat32 __user *u32p)
773 struct ustat u; 776 struct ustat u;
774 mm_segment_t seg; 777 mm_segment_t seg;
775 int ret; 778 int ret;
776 779
777 seg = get_fs(); 780 seg = get_fs();
778 set_fs(KERNEL_DS); 781 set_fs(KERNEL_DS);
779 ret = sys_ustat(dev, (struct ustat __user *)&u); 782 ret = sys_ustat(dev, (struct ustat __user *)&u);
780 set_fs(seg); 783 set_fs(seg);
781 if (ret >= 0) { 784 if (ret < 0)
782 if (!access_ok(VERIFY_WRITE,u32p,sizeof(struct ustat32)) || 785 return ret;
783 __put_user((__u32) u.f_tfree, &u32p->f_tfree) || 786
784 __put_user((__u32) u.f_tinode, &u32p->f_tfree) || 787 if (!access_ok(VERIFY_WRITE, u32p, sizeof(struct ustat32)) ||
785 __copy_to_user(&u32p->f_fname, u.f_fname, sizeof(u.f_fname)) || 788 __put_user((__u32) u.f_tfree, &u32p->f_tfree) ||
786 __copy_to_user(&u32p->f_fpack, u.f_fpack, sizeof(u.f_fpack))) 789 __put_user((__u32) u.f_tinode, &u32p->f_tfree) ||
787 ret = -EFAULT; 790 __copy_to_user(&u32p->f_fname, u.f_fname, sizeof(u.f_fname)) ||
788 } 791 __copy_to_user(&u32p->f_fpack, u.f_fpack, sizeof(u.f_fpack)))
792 ret = -EFAULT;
789 return ret; 793 return ret;
790} 794}
791 795
792asmlinkage long sys32_execve(char __user *name, compat_uptr_t __user *argv, 796asmlinkage long sys32_execve(char __user *name, compat_uptr_t __user *argv,
793 compat_uptr_t __user *envp, struct pt_regs *regs) 797 compat_uptr_t __user *envp, struct pt_regs *regs)
794{ 798{
795 long error; 799 long error;
796 char * filename; 800 char *filename;
797 801
798 filename = getname(name); 802 filename = getname(name);
799 error = PTR_ERR(filename); 803 error = PTR_ERR(filename);
@@ -812,18 +816,19 @@ asmlinkage long sys32_execve(char __user *name, compat_uptr_t __user *argv,
812asmlinkage long sys32_clone(unsigned int clone_flags, unsigned int newsp, 816asmlinkage long sys32_clone(unsigned int clone_flags, unsigned int newsp,
813 struct pt_regs *regs) 817 struct pt_regs *regs)
814{ 818{
815 void __user *parent_tid = (void __user *)regs->rdx; 819 void __user *parent_tid = (void __user *)regs->dx;
816 void __user *child_tid = (void __user *)regs->rdi; 820 void __user *child_tid = (void __user *)regs->di;
821
817 if (!newsp) 822 if (!newsp)
818 newsp = regs->rsp; 823 newsp = regs->sp;
819 return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid); 824 return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid);
820} 825}
821 826
822/* 827/*
823 * Some system calls that need sign extended arguments. This could be done by a generic wrapper. 828 * Some system calls that need sign extended arguments. This could be
824 */ 829 * done by a generic wrapper.
825 830 */
826long sys32_lseek (unsigned int fd, int offset, unsigned int whence) 831long sys32_lseek(unsigned int fd, int offset, unsigned int whence)
827{ 832{
828 return sys_lseek(fd, offset, whence); 833 return sys_lseek(fd, offset, whence);
829} 834}
@@ -832,49 +837,52 @@ long sys32_kill(int pid, int sig)
832{ 837{
833 return sys_kill(pid, sig); 838 return sys_kill(pid, sig);
834} 839}
835 840
836long sys32_fadvise64_64(int fd, __u32 offset_low, __u32 offset_high, 841long sys32_fadvise64_64(int fd, __u32 offset_low, __u32 offset_high,
837 __u32 len_low, __u32 len_high, int advice) 842 __u32 len_low, __u32 len_high, int advice)
838{ 843{
839 return sys_fadvise64_64(fd, 844 return sys_fadvise64_64(fd,
840 (((u64)offset_high)<<32) | offset_low, 845 (((u64)offset_high)<<32) | offset_low,
841 (((u64)len_high)<<32) | len_low, 846 (((u64)len_high)<<32) | len_low,
842 advice); 847 advice);
843} 848}
844 849
845long sys32_vm86_warning(void) 850long sys32_vm86_warning(void)
846{ 851{
847 struct task_struct *me = current; 852 struct task_struct *me = current;
848 static char lastcomm[sizeof(me->comm)]; 853 static char lastcomm[sizeof(me->comm)];
854
849 if (strncmp(lastcomm, me->comm, sizeof(lastcomm))) { 855 if (strncmp(lastcomm, me->comm, sizeof(lastcomm))) {
850 compat_printk(KERN_INFO "%s: vm86 mode not supported on 64 bit kernel\n", 856 compat_printk(KERN_INFO
851 me->comm); 857 "%s: vm86 mode not supported on 64 bit kernel\n",
858 me->comm);
852 strncpy(lastcomm, me->comm, sizeof(lastcomm)); 859 strncpy(lastcomm, me->comm, sizeof(lastcomm));
853 } 860 }
854 return -ENOSYS; 861 return -ENOSYS;
855} 862}
856 863
857long sys32_lookup_dcookie(u32 addr_low, u32 addr_high, 864long sys32_lookup_dcookie(u32 addr_low, u32 addr_high,
858 char __user * buf, size_t len) 865 char __user *buf, size_t len)
859{ 866{
860 return sys_lookup_dcookie(((u64)addr_high << 32) | addr_low, buf, len); 867 return sys_lookup_dcookie(((u64)addr_high << 32) | addr_low, buf, len);
861} 868}
862 869
863asmlinkage ssize_t sys32_readahead(int fd, unsigned off_lo, unsigned off_hi, size_t count) 870asmlinkage ssize_t sys32_readahead(int fd, unsigned off_lo, unsigned off_hi,
871 size_t count)
864{ 872{
865 return sys_readahead(fd, ((u64)off_hi << 32) | off_lo, count); 873 return sys_readahead(fd, ((u64)off_hi << 32) | off_lo, count);
866} 874}
867 875
868asmlinkage long sys32_sync_file_range(int fd, unsigned off_low, unsigned off_hi, 876asmlinkage long sys32_sync_file_range(int fd, unsigned off_low, unsigned off_hi,
869 unsigned n_low, unsigned n_hi, int flags) 877 unsigned n_low, unsigned n_hi, int flags)
870{ 878{
871 return sys_sync_file_range(fd, 879 return sys_sync_file_range(fd,
872 ((u64)off_hi << 32) | off_low, 880 ((u64)off_hi << 32) | off_low,
873 ((u64)n_hi << 32) | n_low, flags); 881 ((u64)n_hi << 32) | n_low, flags);
874} 882}
875 883
876asmlinkage long sys32_fadvise64(int fd, unsigned offset_lo, unsigned offset_hi, size_t len, 884asmlinkage long sys32_fadvise64(int fd, unsigned offset_lo, unsigned offset_hi,
877 int advice) 885 size_t len, int advice)
878{ 886{
879 return sys_fadvise64_64(fd, ((u64)offset_hi << 32) | offset_lo, 887 return sys_fadvise64_64(fd, ((u64)offset_hi << 32) | offset_lo,
880 len, advice); 888 len, advice);
diff --git a/arch/x86/ia32/syscall32.c b/arch/x86/ia32/syscall32.c
deleted file mode 100644
index 15013bac181c..000000000000
--- a/arch/x86/ia32/syscall32.c
+++ /dev/null
@@ -1,83 +0,0 @@
1/* Copyright 2002,2003 Andi Kleen, SuSE Labs */
2
3/* vsyscall handling for 32bit processes. Map a stub page into it
4 on demand because 32bit cannot reach the kernel's fixmaps */
5
6#include <linux/mm.h>
7#include <linux/string.h>
8#include <linux/kernel.h>
9#include <linux/gfp.h>
10#include <linux/init.h>
11#include <linux/stringify.h>
12#include <linux/security.h>
13#include <asm/proto.h>
14#include <asm/tlbflush.h>
15#include <asm/ia32_unistd.h>
16#include <asm/vsyscall32.h>
17
18extern unsigned char syscall32_syscall[], syscall32_syscall_end[];
19extern unsigned char syscall32_sysenter[], syscall32_sysenter_end[];
20extern int sysctl_vsyscall32;
21
22static struct page *syscall32_pages[1];
23static int use_sysenter = -1;
24
25struct linux_binprm;
26
27/* Setup a VMA at program startup for the vsyscall page */
28int syscall32_setup_pages(struct linux_binprm *bprm, int exstack)
29{
30 struct mm_struct *mm = current->mm;
31 int ret;
32
33 down_write(&mm->mmap_sem);
34 /*
35 * MAYWRITE to allow gdb to COW and set breakpoints
36 *
37 * Make sure the vDSO gets into every core dump.
38 * Dumping its contents makes post-mortem fully interpretable later
39 * without matching up the same kernel and hardware config to see
40 * what PC values meant.
41 */
42 /* Could randomize here */
43 ret = install_special_mapping(mm, VSYSCALL32_BASE, PAGE_SIZE,
44 VM_READ|VM_EXEC|
45 VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
46 VM_ALWAYSDUMP,
47 syscall32_pages);
48 up_write(&mm->mmap_sem);
49 return ret;
50}
51
52static int __init init_syscall32(void)
53{
54 char *syscall32_page = (void *)get_zeroed_page(GFP_KERNEL);
55 if (!syscall32_page)
56 panic("Cannot allocate syscall32 page");
57 syscall32_pages[0] = virt_to_page(syscall32_page);
58 if (use_sysenter > 0) {
59 memcpy(syscall32_page, syscall32_sysenter,
60 syscall32_sysenter_end - syscall32_sysenter);
61 } else {
62 memcpy(syscall32_page, syscall32_syscall,
63 syscall32_syscall_end - syscall32_syscall);
64 }
65 return 0;
66}
67
68__initcall(init_syscall32);
69
70/* May not be __init: called during resume */
71void syscall32_cpu_init(void)
72{
73 if (use_sysenter < 0)
74 use_sysenter = (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL);
75
76 /* Load these always in case some future AMD CPU supports
77 SYSENTER from compat mode too. */
78 checking_wrmsrl(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS);
79 checking_wrmsrl(MSR_IA32_SYSENTER_ESP, 0ULL);
80 checking_wrmsrl(MSR_IA32_SYSENTER_EIP, (u64)ia32_sysenter_target);
81
82 wrmsrl(MSR_CSTAR, ia32_cstar_target);
83}
diff --git a/arch/x86/ia32/syscall32_syscall.S b/arch/x86/ia32/syscall32_syscall.S
deleted file mode 100644
index 933f0f08b1cf..000000000000
--- a/arch/x86/ia32/syscall32_syscall.S
+++ /dev/null
@@ -1,17 +0,0 @@
1/* 32bit VDSOs mapped into user space. */
2
3 .section ".init.data","aw"
4
5 .globl syscall32_syscall
6 .globl syscall32_syscall_end
7
8syscall32_syscall:
9 .incbin "arch/x86/ia32/vsyscall-syscall.so"
10syscall32_syscall_end:
11
12 .globl syscall32_sysenter
13 .globl syscall32_sysenter_end
14
15syscall32_sysenter:
16 .incbin "arch/x86/ia32/vsyscall-sysenter.so"
17syscall32_sysenter_end:
diff --git a/arch/x86/ia32/tls32.c b/arch/x86/ia32/tls32.c
deleted file mode 100644
index 1cc4340de3ca..000000000000
--- a/arch/x86/ia32/tls32.c
+++ /dev/null
@@ -1,163 +0,0 @@
1#include <linux/kernel.h>
2#include <linux/errno.h>
3#include <linux/sched.h>
4#include <linux/user.h>
5
6#include <asm/uaccess.h>
7#include <asm/desc.h>
8#include <asm/system.h>
9#include <asm/ldt.h>
10#include <asm/processor.h>
11#include <asm/proto.h>
12
13/*
14 * sys_alloc_thread_area: get a yet unused TLS descriptor index.
15 */
16static int get_free_idx(void)
17{
18 struct thread_struct *t = &current->thread;
19 int idx;
20
21 for (idx = 0; idx < GDT_ENTRY_TLS_ENTRIES; idx++)
22 if (desc_empty((struct n_desc_struct *)(t->tls_array) + idx))
23 return idx + GDT_ENTRY_TLS_MIN;
24 return -ESRCH;
25}
26
27/*
28 * Set a given TLS descriptor:
29 * When you want addresses > 32bit use arch_prctl()
30 */
31int do_set_thread_area(struct thread_struct *t, struct user_desc __user *u_info)
32{
33 struct user_desc info;
34 struct n_desc_struct *desc;
35 int cpu, idx;
36
37 if (copy_from_user(&info, u_info, sizeof(info)))
38 return -EFAULT;
39
40 idx = info.entry_number;
41
42 /*
43 * index -1 means the kernel should try to find and
44 * allocate an empty descriptor:
45 */
46 if (idx == -1) {
47 idx = get_free_idx();
48 if (idx < 0)
49 return idx;
50 if (put_user(idx, &u_info->entry_number))
51 return -EFAULT;
52 }
53
54 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
55 return -EINVAL;
56
57 desc = ((struct n_desc_struct *)t->tls_array) + idx - GDT_ENTRY_TLS_MIN;
58
59 /*
60 * We must not get preempted while modifying the TLS.
61 */
62 cpu = get_cpu();
63
64 if (LDT_empty(&info)) {
65 desc->a = 0;
66 desc->b = 0;
67 } else {
68 desc->a = LDT_entry_a(&info);
69 desc->b = LDT_entry_b(&info);
70 }
71 if (t == &current->thread)
72 load_TLS(t, cpu);
73
74 put_cpu();
75 return 0;
76}
77
78asmlinkage long sys32_set_thread_area(struct user_desc __user *u_info)
79{
80 return do_set_thread_area(&current->thread, u_info);
81}
82
83
84/*
85 * Get the current Thread-Local Storage area:
86 */
87
88#define GET_BASE(desc) ( \
89 (((desc)->a >> 16) & 0x0000ffff) | \
90 (((desc)->b << 16) & 0x00ff0000) | \
91 ( (desc)->b & 0xff000000) )
92
93#define GET_LIMIT(desc) ( \
94 ((desc)->a & 0x0ffff) | \
95 ((desc)->b & 0xf0000) )
96
97#define GET_32BIT(desc) (((desc)->b >> 22) & 1)
98#define GET_CONTENTS(desc) (((desc)->b >> 10) & 3)
99#define GET_WRITABLE(desc) (((desc)->b >> 9) & 1)
100#define GET_LIMIT_PAGES(desc) (((desc)->b >> 23) & 1)
101#define GET_PRESENT(desc) (((desc)->b >> 15) & 1)
102#define GET_USEABLE(desc) (((desc)->b >> 20) & 1)
103#define GET_LONGMODE(desc) (((desc)->b >> 21) & 1)
104
105int do_get_thread_area(struct thread_struct *t, struct user_desc __user *u_info)
106{
107 struct user_desc info;
108 struct n_desc_struct *desc;
109 int idx;
110
111 if (get_user(idx, &u_info->entry_number))
112 return -EFAULT;
113 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
114 return -EINVAL;
115
116 desc = ((struct n_desc_struct *)t->tls_array) + idx - GDT_ENTRY_TLS_MIN;
117
118 memset(&info, 0, sizeof(struct user_desc));
119 info.entry_number = idx;
120 info.base_addr = GET_BASE(desc);
121 info.limit = GET_LIMIT(desc);
122 info.seg_32bit = GET_32BIT(desc);
123 info.contents = GET_CONTENTS(desc);
124 info.read_exec_only = !GET_WRITABLE(desc);
125 info.limit_in_pages = GET_LIMIT_PAGES(desc);
126 info.seg_not_present = !GET_PRESENT(desc);
127 info.useable = GET_USEABLE(desc);
128 info.lm = GET_LONGMODE(desc);
129
130 if (copy_to_user(u_info, &info, sizeof(info)))
131 return -EFAULT;
132 return 0;
133}
134
135asmlinkage long sys32_get_thread_area(struct user_desc __user *u_info)
136{
137 return do_get_thread_area(&current->thread, u_info);
138}
139
140
141int ia32_child_tls(struct task_struct *p, struct pt_regs *childregs)
142{
143 struct n_desc_struct *desc;
144 struct user_desc info;
145 struct user_desc __user *cp;
146 int idx;
147
148 cp = (void __user *)childregs->rsi;
149 if (copy_from_user(&info, cp, sizeof(info)))
150 return -EFAULT;
151 if (LDT_empty(&info))
152 return -EINVAL;
153
154 idx = info.entry_number;
155 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
156 return -EINVAL;
157
158 desc = (struct n_desc_struct *)(p->thread.tls_array) + idx - GDT_ENTRY_TLS_MIN;
159 desc->a = LDT_entry_a(&info);
160 desc->b = LDT_entry_b(&info);
161
162 return 0;
163}
diff --git a/arch/x86/ia32/vsyscall-sigreturn.S b/arch/x86/ia32/vsyscall-sigreturn.S
deleted file mode 100644
index b383be00baec..000000000000
--- a/arch/x86/ia32/vsyscall-sigreturn.S
+++ /dev/null
@@ -1,143 +0,0 @@
1/*
2 * Common code for the sigreturn entry points on the vsyscall page.
3 * This code uses SYSCALL_ENTER_KERNEL (either syscall or int $0x80)
4 * to enter the kernel.
5 * This file is #include'd by vsyscall-*.S to define them after the
6 * vsyscall entry point. The addresses we get for these entry points
7 * by doing ".balign 32" must match in both versions of the page.
8 */
9
10 .code32
11 .section .text.sigreturn,"ax"
12 .balign 32
13 .globl __kernel_sigreturn
14 .type __kernel_sigreturn,@function
15__kernel_sigreturn:
16.LSTART_sigreturn:
17 popl %eax
18 movl $__NR_ia32_sigreturn, %eax
19 SYSCALL_ENTER_KERNEL
20.LEND_sigreturn:
21 .size __kernel_sigreturn,.-.LSTART_sigreturn
22
23 .section .text.rtsigreturn,"ax"
24 .balign 32
25 .globl __kernel_rt_sigreturn
26 .type __kernel_rt_sigreturn,@function
27__kernel_rt_sigreturn:
28.LSTART_rt_sigreturn:
29 movl $__NR_ia32_rt_sigreturn, %eax
30 SYSCALL_ENTER_KERNEL
31.LEND_rt_sigreturn:
32 .size __kernel_rt_sigreturn,.-.LSTART_rt_sigreturn
33
34 .section .eh_frame,"a",@progbits
35.LSTARTFRAMES:
36 .long .LENDCIES-.LSTARTCIES
37.LSTARTCIES:
38 .long 0 /* CIE ID */
39 .byte 1 /* Version number */
40 .string "zRS" /* NUL-terminated augmentation string */
41 .uleb128 1 /* Code alignment factor */
42 .sleb128 -4 /* Data alignment factor */
43 .byte 8 /* Return address register column */
44 .uleb128 1 /* Augmentation value length */
45 .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */
46 .byte 0x0c /* DW_CFA_def_cfa */
47 .uleb128 4
48 .uleb128 4
49 .byte 0x88 /* DW_CFA_offset, column 0x8 */
50 .uleb128 1
51 .align 4
52.LENDCIES:
53
54 .long .LENDFDE2-.LSTARTFDE2 /* Length FDE */
55.LSTARTFDE2:
56 .long .LSTARTFDE2-.LSTARTFRAMES /* CIE pointer */
57 /* HACK: The dwarf2 unwind routines will subtract 1 from the
58 return address to get an address in the middle of the
59 presumed call instruction. Since we didn't get here via
60 a call, we need to include the nop before the real start
61 to make up for it. */
62 .long .LSTART_sigreturn-1-. /* PC-relative start address */
63 .long .LEND_sigreturn-.LSTART_sigreturn+1
64 .uleb128 0 /* Augmentation length */
65 /* What follows are the instructions for the table generation.
66 We record the locations of each register saved. This is
67 complicated by the fact that the "CFA" is always assumed to
68 be the value of the stack pointer in the caller. This means
69 that we must define the CFA of this body of code to be the
70 saved value of the stack pointer in the sigcontext. Which
71 also means that there is no fixed relation to the other
72 saved registers, which means that we must use DW_CFA_expression
73 to compute their addresses. It also means that when we
74 adjust the stack with the popl, we have to do it all over again. */
75
76#define do_cfa_expr(offset) \
77 .byte 0x0f; /* DW_CFA_def_cfa_expression */ \
78 .uleb128 1f-0f; /* length */ \
790: .byte 0x74; /* DW_OP_breg4 */ \
80 .sleb128 offset; /* offset */ \
81 .byte 0x06; /* DW_OP_deref */ \
821:
83
84#define do_expr(regno, offset) \
85 .byte 0x10; /* DW_CFA_expression */ \
86 .uleb128 regno; /* regno */ \
87 .uleb128 1f-0f; /* length */ \
880: .byte 0x74; /* DW_OP_breg4 */ \
89 .sleb128 offset; /* offset */ \
901:
91
92 do_cfa_expr(IA32_SIGCONTEXT_esp+4)
93 do_expr(0, IA32_SIGCONTEXT_eax+4)
94 do_expr(1, IA32_SIGCONTEXT_ecx+4)
95 do_expr(2, IA32_SIGCONTEXT_edx+4)
96 do_expr(3, IA32_SIGCONTEXT_ebx+4)
97 do_expr(5, IA32_SIGCONTEXT_ebp+4)
98 do_expr(6, IA32_SIGCONTEXT_esi+4)
99 do_expr(7, IA32_SIGCONTEXT_edi+4)
100 do_expr(8, IA32_SIGCONTEXT_eip+4)
101
102 .byte 0x42 /* DW_CFA_advance_loc 2 -- nop; popl eax. */
103
104 do_cfa_expr(IA32_SIGCONTEXT_esp)
105 do_expr(0, IA32_SIGCONTEXT_eax)
106 do_expr(1, IA32_SIGCONTEXT_ecx)
107 do_expr(2, IA32_SIGCONTEXT_edx)
108 do_expr(3, IA32_SIGCONTEXT_ebx)
109 do_expr(5, IA32_SIGCONTEXT_ebp)
110 do_expr(6, IA32_SIGCONTEXT_esi)
111 do_expr(7, IA32_SIGCONTEXT_edi)
112 do_expr(8, IA32_SIGCONTEXT_eip)
113
114 .align 4
115.LENDFDE2:
116
117 .long .LENDFDE3-.LSTARTFDE3 /* Length FDE */
118.LSTARTFDE3:
119 .long .LSTARTFDE3-.LSTARTFRAMES /* CIE pointer */
120 /* HACK: See above wrt unwind library assumptions. */
121 .long .LSTART_rt_sigreturn-1-. /* PC-relative start address */
122 .long .LEND_rt_sigreturn-.LSTART_rt_sigreturn+1
123 .uleb128 0 /* Augmentation */
124 /* What follows are the instructions for the table generation.
125 We record the locations of each register saved. This is
126 slightly less complicated than the above, since we don't
127 modify the stack pointer in the process. */
128
129 do_cfa_expr(IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_esp)
130 do_expr(0, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_eax)
131 do_expr(1, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ecx)
132 do_expr(2, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_edx)
133 do_expr(3, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ebx)
134 do_expr(5, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ebp)
135 do_expr(6, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_esi)
136 do_expr(7, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_edi)
137 do_expr(8, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_eip)
138
139 .align 4
140.LENDFDE3:
141
142#include "../../x86/kernel/vsyscall-note_32.S"
143
diff --git a/arch/x86/ia32/vsyscall-sysenter.S b/arch/x86/ia32/vsyscall-sysenter.S
deleted file mode 100644
index ae056e553d13..000000000000
--- a/arch/x86/ia32/vsyscall-sysenter.S
+++ /dev/null
@@ -1,95 +0,0 @@
1/*
2 * Code for the vsyscall page. This version uses the sysenter instruction.
3 */
4
5#include <asm/ia32_unistd.h>
6#include <asm/asm-offsets.h>
7
8 .code32
9 .text
10 .section .text.vsyscall,"ax"
11 .globl __kernel_vsyscall
12 .type __kernel_vsyscall,@function
13__kernel_vsyscall:
14.LSTART_vsyscall:
15 push %ecx
16.Lpush_ecx:
17 push %edx
18.Lpush_edx:
19 push %ebp
20.Lenter_kernel:
21 movl %esp,%ebp
22 sysenter
23 .space 7,0x90
24 jmp .Lenter_kernel
25 /* 16: System call normal return point is here! */
26 pop %ebp
27.Lpop_ebp:
28 pop %edx
29.Lpop_edx:
30 pop %ecx
31.Lpop_ecx:
32 ret
33.LEND_vsyscall:
34 .size __kernel_vsyscall,.-.LSTART_vsyscall
35
36 .section .eh_frame,"a",@progbits
37.LSTARTFRAME:
38 .long .LENDCIE-.LSTARTCIE
39.LSTARTCIE:
40 .long 0 /* CIE ID */
41 .byte 1 /* Version number */
42 .string "zR" /* NUL-terminated augmentation string */
43 .uleb128 1 /* Code alignment factor */
44 .sleb128 -4 /* Data alignment factor */
45 .byte 8 /* Return address register column */
46 .uleb128 1 /* Augmentation value length */
47 .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */
48 .byte 0x0c /* DW_CFA_def_cfa */
49 .uleb128 4
50 .uleb128 4
51 .byte 0x88 /* DW_CFA_offset, column 0x8 */
52 .uleb128 1
53 .align 4
54.LENDCIE:
55
56 .long .LENDFDE1-.LSTARTFDE1 /* Length FDE */
57.LSTARTFDE1:
58 .long .LSTARTFDE1-.LSTARTFRAME /* CIE pointer */
59 .long .LSTART_vsyscall-. /* PC-relative start address */
60 .long .LEND_vsyscall-.LSTART_vsyscall
61 .uleb128 0 /* Augmentation length */
62 /* What follows are the instructions for the table generation.
63 We have to record all changes of the stack pointer. */
64 .byte 0x04 /* DW_CFA_advance_loc4 */
65 .long .Lpush_ecx-.LSTART_vsyscall
66 .byte 0x0e /* DW_CFA_def_cfa_offset */
67 .byte 0x08 /* RA at offset 8 now */
68 .byte 0x04 /* DW_CFA_advance_loc4 */
69 .long .Lpush_edx-.Lpush_ecx
70 .byte 0x0e /* DW_CFA_def_cfa_offset */
71 .byte 0x0c /* RA at offset 12 now */
72 .byte 0x04 /* DW_CFA_advance_loc4 */
73 .long .Lenter_kernel-.Lpush_edx
74 .byte 0x0e /* DW_CFA_def_cfa_offset */
75 .byte 0x10 /* RA at offset 16 now */
76 .byte 0x85, 0x04 /* DW_CFA_offset %ebp -16 */
77 /* Finally the epilogue. */
78 .byte 0x04 /* DW_CFA_advance_loc4 */
79 .long .Lpop_ebp-.Lenter_kernel
80 .byte 0x0e /* DW_CFA_def_cfa_offset */
81 .byte 0x12 /* RA at offset 12 now */
82 .byte 0xc5 /* DW_CFA_restore %ebp */
83 .byte 0x04 /* DW_CFA_advance_loc4 */
84 .long .Lpop_edx-.Lpop_ebp
85 .byte 0x0e /* DW_CFA_def_cfa_offset */
86 .byte 0x08 /* RA at offset 8 now */
87 .byte 0x04 /* DW_CFA_advance_loc4 */
88 .long .Lpop_ecx-.Lpop_edx
89 .byte 0x0e /* DW_CFA_def_cfa_offset */
90 .byte 0x04 /* RA at offset 4 now */
91 .align 4
92.LENDFDE1:
93
94#define SYSCALL_ENTER_KERNEL int $0x80
95#include "vsyscall-sigreturn.S"
diff --git a/arch/x86/ia32/vsyscall.lds b/arch/x86/ia32/vsyscall.lds
deleted file mode 100644
index 1dc86ff5bcb9..000000000000
--- a/arch/x86/ia32/vsyscall.lds
+++ /dev/null
@@ -1,80 +0,0 @@
1/*
2 * Linker script for vsyscall DSO. The vsyscall page is an ELF shared
3 * object prelinked to its virtual address. This script controls its layout.
4 */
5
6/* This must match <asm/fixmap.h>. */
7VSYSCALL_BASE = 0xffffe000;
8
9SECTIONS
10{
11 . = VSYSCALL_BASE + SIZEOF_HEADERS;
12
13 .hash : { *(.hash) } :text
14 .gnu.hash : { *(.gnu.hash) }
15 .dynsym : { *(.dynsym) }
16 .dynstr : { *(.dynstr) }
17 .gnu.version : { *(.gnu.version) }
18 .gnu.version_d : { *(.gnu.version_d) }
19 .gnu.version_r : { *(.gnu.version_r) }
20
21 /* This linker script is used both with -r and with -shared.
22 For the layouts to match, we need to skip more than enough
23 space for the dynamic symbol table et al. If this amount
24 is insufficient, ld -shared will barf. Just increase it here. */
25 . = VSYSCALL_BASE + 0x400;
26
27 .text.vsyscall : { *(.text.vsyscall) } :text =0x90909090
28
29 /* This is an 32bit object and we cannot easily get the offsets
30 into the 64bit kernel. Just hardcode them here. This assumes
31 that all the stubs don't need more than 0x100 bytes. */
32 . = VSYSCALL_BASE + 0x500;
33
34 .text.sigreturn : { *(.text.sigreturn) } :text =0x90909090
35
36 . = VSYSCALL_BASE + 0x600;
37
38 .text.rtsigreturn : { *(.text.rtsigreturn) } :text =0x90909090
39
40 .note : { *(.note.*) } :text :note
41 .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
42 .eh_frame : { KEEP (*(.eh_frame)) } :text
43 .dynamic : { *(.dynamic) } :text :dynamic
44 .useless : {
45 *(.got.plt) *(.got)
46 *(.data .data.* .gnu.linkonce.d.*)
47 *(.dynbss)
48 *(.bss .bss.* .gnu.linkonce.b.*)
49 } :text
50}
51
52/*
53 * We must supply the ELF program headers explicitly to get just one
54 * PT_LOAD segment, and set the flags explicitly to make segments read-only.
55 */
56PHDRS
57{
58 text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */
59 dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
60 note PT_NOTE FLAGS(4); /* PF_R */
61 eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */
62}
63
64/*
65 * This controls what symbols we export from the DSO.
66 */
67VERSION
68{
69 LINUX_2.5 {
70 global:
71 __kernel_vsyscall;
72 __kernel_sigreturn;
73 __kernel_rt_sigreturn;
74
75 local: *;
76 };
77}
78
79/* The ELF entry point can be used to set the AT_SYSINFO value. */
80ENTRY(__kernel_vsyscall);
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 38573340b143..6f813009d44b 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -1,9 +1,91 @@
1ifeq ($(CONFIG_X86_32),y) 1#
2include ${srctree}/arch/x86/kernel/Makefile_32 2# Makefile for the linux kernel.
3else 3#
4include ${srctree}/arch/x86/kernel/Makefile_64 4
5extra-y := head_$(BITS).o init_task.o vmlinux.lds
6extra-$(CONFIG_X86_64) += head64.o
7
8CPPFLAGS_vmlinux.lds += -U$(UTS_MACHINE)
9CFLAGS_vsyscall_64.o := $(PROFILING) -g0
10
11obj-y := process_$(BITS).o signal_$(BITS).o entry_$(BITS).o
12obj-y += traps_$(BITS).o irq_$(BITS).o
13obj-y += time_$(BITS).o ioport.o ldt.o
14obj-y += setup_$(BITS).o i8259_$(BITS).o
15obj-$(CONFIG_X86_32) += sys_i386_32.o i386_ksyms_32.o
16obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o
17obj-$(CONFIG_X86_64) += syscall_64.o vsyscall_64.o setup64.o
18obj-y += pci-dma_$(BITS).o bootflag.o e820_$(BITS).o
19obj-y += quirks.o i8237.o topology.o kdebugfs.o
20obj-y += alternative.o i8253.o
21obj-$(CONFIG_X86_64) += pci-nommu_64.o bugs_64.o
22obj-y += tsc_$(BITS).o io_delay.o rtc.o
23
24obj-y += i387.o
25obj-y += ptrace.o
26obj-y += ds.o
27obj-$(CONFIG_X86_32) += tls.o
28obj-$(CONFIG_IA32_EMULATION) += tls.o
29obj-y += step.o
30obj-$(CONFIG_STACKTRACE) += stacktrace.o
31obj-y += cpu/
32obj-y += acpi/
33obj-$(CONFIG_X86_BIOS_REBOOT) += reboot.o
34obj-$(CONFIG_X86_64) += reboot.o
35obj-$(CONFIG_MCA) += mca_32.o
36obj-$(CONFIG_X86_MSR) += msr.o
37obj-$(CONFIG_X86_CPUID) += cpuid.o
38obj-$(CONFIG_MICROCODE) += microcode.o
39obj-$(CONFIG_PCI) += early-quirks.o
40obj-$(CONFIG_APM) += apm_32.o
41obj-$(CONFIG_X86_SMP) += smp_$(BITS).o smpboot_$(BITS).o tsc_sync.o
42obj-$(CONFIG_X86_32_SMP) += smpcommon_32.o
43obj-$(CONFIG_X86_64_SMP) += smp_64.o smpboot_64.o tsc_sync.o
44obj-$(CONFIG_X86_TRAMPOLINE) += trampoline_$(BITS).o
45obj-$(CONFIG_X86_MPPARSE) += mpparse_$(BITS).o
46obj-$(CONFIG_X86_LOCAL_APIC) += apic_$(BITS).o nmi_$(BITS).o
47obj-$(CONFIG_X86_IO_APIC) += io_apic_$(BITS).o
48obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups_32.o
49obj-$(CONFIG_KEXEC) += machine_kexec_$(BITS).o
50obj-$(CONFIG_KEXEC) += relocate_kernel_$(BITS).o crash.o
51obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o
52obj-$(CONFIG_X86_NUMAQ) += numaq_32.o
53obj-$(CONFIG_X86_SUMMIT_NUMA) += summit_32.o
54obj-$(CONFIG_X86_VSMP) += vsmp_64.o
55obj-$(CONFIG_KPROBES) += kprobes.o
56obj-$(CONFIG_MODULES) += module_$(BITS).o
57obj-$(CONFIG_ACPI_SRAT) += srat_32.o
58obj-$(CONFIG_EFI) += efi.o efi_$(BITS).o efi_stub_$(BITS).o
59obj-$(CONFIG_DOUBLEFAULT) += doublefault_32.o
60obj-$(CONFIG_VM86) += vm86_32.o
61obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
62
63obj-$(CONFIG_HPET_TIMER) += hpet.o
64
65obj-$(CONFIG_K8_NB) += k8.o
66obj-$(CONFIG_MGEODE_LX) += geode_32.o mfgpt_32.o
67obj-$(CONFIG_DEBUG_RODATA_TEST) += test_rodata.o
68obj-$(CONFIG_DEBUG_NX_TEST) += test_nx.o
69
70obj-$(CONFIG_VMI) += vmi_32.o vmiclock_32.o
71obj-$(CONFIG_PARAVIRT) += paravirt.o paravirt_patch_$(BITS).o
72
73ifdef CONFIG_INPUT_PCSPKR
74obj-y += pcspeaker.o
5endif 75endif
6 76
7# Workaround to delete .lds files with make clean 77obj-$(CONFIG_SCx200) += scx200_32.o
8# The problem is that we do not enter Makefile_32 with make clean. 78
9clean-files := vsyscall*.lds vsyscall*.so 79###
80# 64 bit specific files
81ifeq ($(CONFIG_X86_64),y)
82 obj-y += genapic_64.o genapic_flat_64.o
83 obj-$(CONFIG_X86_PM_TIMER) += pmtimer_64.o
84 obj-$(CONFIG_AUDIT) += audit_64.o
85 obj-$(CONFIG_PM) += suspend_64.o
86 obj-$(CONFIG_HIBERNATION) += suspend_asm_64.o
87
88 obj-$(CONFIG_GART_IOMMU) += pci-gart_64.o aperture_64.o
89 obj-$(CONFIG_CALGARY_IOMMU) += pci-calgary_64.o tce_64.o
90 obj-$(CONFIG_SWIOTLB) += pci-swiotlb_64.o
91endif
diff --git a/arch/x86/kernel/Makefile_32 b/arch/x86/kernel/Makefile_32
deleted file mode 100644
index a7bc93c27662..000000000000
--- a/arch/x86/kernel/Makefile_32
+++ /dev/null
@@ -1,88 +0,0 @@
1#
2# Makefile for the linux kernel.
3#
4
5extra-y := head_32.o init_task.o vmlinux.lds
6CPPFLAGS_vmlinux.lds += -Ui386
7
8obj-y := process_32.o signal_32.o entry_32.o traps_32.o irq_32.o \
9 ptrace_32.o time_32.o ioport_32.o ldt_32.o setup_32.o i8259_32.o sys_i386_32.o \
10 pci-dma_32.o i386_ksyms_32.o i387_32.o bootflag.o e820_32.o\
11 quirks.o i8237.o topology.o alternative.o i8253.o tsc_32.o
12
13obj-$(CONFIG_STACKTRACE) += stacktrace.o
14obj-y += cpu/
15obj-y += acpi/
16obj-$(CONFIG_X86_BIOS_REBOOT) += reboot_32.o
17obj-$(CONFIG_MCA) += mca_32.o
18obj-$(CONFIG_X86_MSR) += msr.o
19obj-$(CONFIG_X86_CPUID) += cpuid.o
20obj-$(CONFIG_MICROCODE) += microcode.o
21obj-$(CONFIG_PCI) += early-quirks.o
22obj-$(CONFIG_APM) += apm_32.o
23obj-$(CONFIG_X86_SMP) += smp_32.o smpboot_32.o tsc_sync.o
24obj-$(CONFIG_SMP) += smpcommon_32.o
25obj-$(CONFIG_X86_TRAMPOLINE) += trampoline_32.o
26obj-$(CONFIG_X86_MPPARSE) += mpparse_32.o
27obj-$(CONFIG_X86_LOCAL_APIC) += apic_32.o nmi_32.o
28obj-$(CONFIG_X86_IO_APIC) += io_apic_32.o
29obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups_32.o
30obj-$(CONFIG_KEXEC) += machine_kexec_32.o relocate_kernel_32.o crash.o
31obj-$(CONFIG_CRASH_DUMP) += crash_dump_32.o
32obj-$(CONFIG_X86_NUMAQ) += numaq_32.o
33obj-$(CONFIG_X86_SUMMIT_NUMA) += summit_32.o
34obj-$(CONFIG_KPROBES) += kprobes_32.o
35obj-$(CONFIG_MODULES) += module_32.o
36obj-y += sysenter_32.o vsyscall_32.o
37obj-$(CONFIG_ACPI_SRAT) += srat_32.o
38obj-$(CONFIG_EFI) += efi_32.o efi_stub_32.o
39obj-$(CONFIG_DOUBLEFAULT) += doublefault_32.o
40obj-$(CONFIG_VM86) += vm86_32.o
41obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
42obj-$(CONFIG_HPET_TIMER) += hpet.o
43obj-$(CONFIG_K8_NB) += k8.o
44obj-$(CONFIG_MGEODE_LX) += geode_32.o mfgpt_32.o
45
46obj-$(CONFIG_VMI) += vmi_32.o vmiclock_32.o
47obj-$(CONFIG_PARAVIRT) += paravirt_32.o
48obj-y += pcspeaker.o
49
50obj-$(CONFIG_SCx200) += scx200_32.o
51
52# vsyscall_32.o contains the vsyscall DSO images as __initdata.
53# We must build both images before we can assemble it.
54# Note: kbuild does not track this dependency due to usage of .incbin
55$(obj)/vsyscall_32.o: $(obj)/vsyscall-int80_32.so $(obj)/vsyscall-sysenter_32.so
56targets += $(foreach F,int80 sysenter,vsyscall-$F_32.o vsyscall-$F_32.so)
57targets += vsyscall-note_32.o vsyscall_32.lds
58
59# The DSO images are built using a special linker script.
60quiet_cmd_syscall = SYSCALL $@
61 cmd_syscall = $(CC) -m elf_i386 -nostdlib $(SYSCFLAGS_$(@F)) \
62 -Wl,-T,$(filter-out FORCE,$^) -o $@
63
64export CPPFLAGS_vsyscall_32.lds += -P -C -Ui386
65
66vsyscall-flags = -shared -s -Wl,-soname=linux-gate.so.1 \
67 $(call ld-option, -Wl$(comma)--hash-style=sysv)
68SYSCFLAGS_vsyscall-sysenter_32.so = $(vsyscall-flags)
69SYSCFLAGS_vsyscall-int80_32.so = $(vsyscall-flags)
70
71$(obj)/vsyscall-int80_32.so $(obj)/vsyscall-sysenter_32.so: \
72$(obj)/vsyscall-%.so: $(src)/vsyscall_32.lds \
73 $(obj)/vsyscall-%.o $(obj)/vsyscall-note_32.o FORCE
74 $(call if_changed,syscall)
75
76# We also create a special relocatable object that should mirror the symbol
77# table and layout of the linked DSO. With ld -R we can then refer to
78# these symbols in the kernel code rather than hand-coded addresses.
79extra-y += vsyscall-syms.o
80$(obj)/built-in.o: $(obj)/vsyscall-syms.o
81$(obj)/built-in.o: ld_flags += -R $(obj)/vsyscall-syms.o
82
83SYSCFLAGS_vsyscall-syms.o = -r
84$(obj)/vsyscall-syms.o: $(src)/vsyscall_32.lds \
85 $(obj)/vsyscall-sysenter_32.o $(obj)/vsyscall-note_32.o FORCE
86 $(call if_changed,syscall)
87
88
diff --git a/arch/x86/kernel/Makefile_64 b/arch/x86/kernel/Makefile_64
deleted file mode 100644
index 5a88890d8ee9..000000000000
--- a/arch/x86/kernel/Makefile_64
+++ /dev/null
@@ -1,45 +0,0 @@
1#
2# Makefile for the linux kernel.
3#
4
5extra-y := head_64.o head64.o init_task.o vmlinux.lds
6CPPFLAGS_vmlinux.lds += -Ux86_64
7EXTRA_AFLAGS := -traditional
8
9obj-y := process_64.o signal_64.o entry_64.o traps_64.o irq_64.o \
10 ptrace_64.o time_64.o ioport_64.o ldt_64.o setup_64.o i8259_64.o sys_x86_64.o \
11 x8664_ksyms_64.o i387_64.o syscall_64.o vsyscall_64.o \
12 setup64.o bootflag.o e820_64.o reboot_64.o quirks.o i8237.o \
13 pci-dma_64.o pci-nommu_64.o alternative.o hpet.o tsc_64.o bugs_64.o \
14 i8253.o
15
16obj-$(CONFIG_STACKTRACE) += stacktrace.o
17obj-y += cpu/
18obj-y += acpi/
19obj-$(CONFIG_X86_MSR) += msr.o
20obj-$(CONFIG_MICROCODE) += microcode.o
21obj-$(CONFIG_X86_CPUID) += cpuid.o
22obj-$(CONFIG_SMP) += smp_64.o smpboot_64.o trampoline_64.o tsc_sync.o
23obj-y += apic_64.o nmi_64.o
24obj-y += io_apic_64.o mpparse_64.o genapic_64.o genapic_flat_64.o
25obj-$(CONFIG_KEXEC) += machine_kexec_64.o relocate_kernel_64.o crash.o
26obj-$(CONFIG_CRASH_DUMP) += crash_dump_64.o
27obj-$(CONFIG_PM) += suspend_64.o
28obj-$(CONFIG_HIBERNATION) += suspend_asm_64.o
29obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
30obj-$(CONFIG_GART_IOMMU) += pci-gart_64.o aperture_64.o
31obj-$(CONFIG_CALGARY_IOMMU) += pci-calgary_64.o tce_64.o
32obj-$(CONFIG_SWIOTLB) += pci-swiotlb_64.o
33obj-$(CONFIG_KPROBES) += kprobes_64.o
34obj-$(CONFIG_X86_PM_TIMER) += pmtimer_64.o
35obj-$(CONFIG_X86_VSMP) += vsmp_64.o
36obj-$(CONFIG_K8_NB) += k8.o
37obj-$(CONFIG_AUDIT) += audit_64.o
38
39obj-$(CONFIG_MODULES) += module_64.o
40obj-$(CONFIG_PCI) += early-quirks.o
41
42obj-y += topology.o
43obj-y += pcspeaker.o
44
45CFLAGS_vsyscall_64.o := $(PROFILING) -g0
diff --git a/arch/x86/kernel/acpi/Makefile b/arch/x86/kernel/acpi/Makefile
index 1351c3982ee4..19d3d6e9d09b 100644
--- a/arch/x86/kernel/acpi/Makefile
+++ b/arch/x86/kernel/acpi/Makefile
@@ -1,5 +1,5 @@
1obj-$(CONFIG_ACPI) += boot.o 1obj-$(CONFIG_ACPI) += boot.o
2obj-$(CONFIG_ACPI_SLEEP) += sleep_$(BITS).o wakeup_$(BITS).o 2obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup_$(BITS).o
3 3
4ifneq ($(CONFIG_ACPI_PROCESSOR),) 4ifneq ($(CONFIG_ACPI_PROCESSOR),)
5obj-y += cstate.o processor.o 5obj-y += cstate.o processor.o
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c
new file mode 100644
index 000000000000..6bc815cd8cb3
--- /dev/null
+++ b/arch/x86/kernel/acpi/sleep.c
@@ -0,0 +1,87 @@
1/*
2 * sleep.c - x86-specific ACPI sleep support.
3 *
4 * Copyright (C) 2001-2003 Patrick Mochel
5 * Copyright (C) 2001-2003 Pavel Machek <pavel@suse.cz>
6 */
7
8#include <linux/acpi.h>
9#include <linux/bootmem.h>
10#include <linux/dmi.h>
11#include <linux/cpumask.h>
12
13#include <asm/smp.h>
14
15/* address in low memory of the wakeup routine. */
16unsigned long acpi_wakeup_address = 0;
17unsigned long acpi_realmode_flags;
18extern char wakeup_start, wakeup_end;
19
20extern unsigned long acpi_copy_wakeup_routine(unsigned long);
21
22/**
23 * acpi_save_state_mem - save kernel state
24 *
25 * Create an identity mapped page table and copy the wakeup routine to
26 * low memory.
27 */
28int acpi_save_state_mem(void)
29{
30 if (!acpi_wakeup_address) {
31 printk(KERN_ERR "Could not allocate memory during boot, S3 disabled\n");
32 return -ENOMEM;
33 }
34 memcpy((void *)acpi_wakeup_address, &wakeup_start,
35 &wakeup_end - &wakeup_start);
36 acpi_copy_wakeup_routine(acpi_wakeup_address);
37
38 return 0;
39}
40
41/*
42 * acpi_restore_state - undo effects of acpi_save_state_mem
43 */
44void acpi_restore_state_mem(void)
45{
46}
47
48
49/**
50 * acpi_reserve_bootmem - do _very_ early ACPI initialisation
51 *
52 * We allocate a page from the first 1MB of memory for the wakeup
53 * routine for when we come back from a sleep state. The
54 * runtime allocator allows specification of <16MB pages, but not
55 * <1MB pages.
56 */
57void __init acpi_reserve_bootmem(void)
58{
59 if ((&wakeup_end - &wakeup_start) > PAGE_SIZE*2) {
60 printk(KERN_ERR
61 "ACPI: Wakeup code way too big, S3 disabled.\n");
62 return;
63 }
64
65 acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE*2);
66 if (!acpi_wakeup_address)
67 printk(KERN_ERR "ACPI: Cannot allocate lowmem, S3 disabled.\n");
68}
69
70
71static int __init acpi_sleep_setup(char *str)
72{
73 while ((str != NULL) && (*str != '\0')) {
74 if (strncmp(str, "s3_bios", 7) == 0)
75 acpi_realmode_flags |= 1;
76 if (strncmp(str, "s3_mode", 7) == 0)
77 acpi_realmode_flags |= 2;
78 if (strncmp(str, "s3_beep", 7) == 0)
79 acpi_realmode_flags |= 4;
80 str = strchr(str, ',');
81 if (str != NULL)
82 str += strspn(str, ", \t");
83 }
84 return 1;
85}
86
87__setup("acpi_sleep=", acpi_sleep_setup);
diff --git a/arch/x86/kernel/acpi/sleep_32.c b/arch/x86/kernel/acpi/sleep_32.c
index 10699489cfe7..63fe5525e026 100644
--- a/arch/x86/kernel/acpi/sleep_32.c
+++ b/arch/x86/kernel/acpi/sleep_32.c
@@ -12,76 +12,6 @@
12 12
13#include <asm/smp.h> 13#include <asm/smp.h>
14 14
15/* address in low memory of the wakeup routine. */
16unsigned long acpi_wakeup_address = 0;
17unsigned long acpi_realmode_flags;
18extern char wakeup_start, wakeup_end;
19
20extern unsigned long FASTCALL(acpi_copy_wakeup_routine(unsigned long));
21
22/**
23 * acpi_save_state_mem - save kernel state
24 *
25 * Create an identity mapped page table and copy the wakeup routine to
26 * low memory.
27 */
28int acpi_save_state_mem(void)
29{
30 if (!acpi_wakeup_address)
31 return 1;
32 memcpy((void *)acpi_wakeup_address, &wakeup_start,
33 &wakeup_end - &wakeup_start);
34 acpi_copy_wakeup_routine(acpi_wakeup_address);
35
36 return 0;
37}
38
39/*
40 * acpi_restore_state - undo effects of acpi_save_state_mem
41 */
42void acpi_restore_state_mem(void)
43{
44}
45
46/**
47 * acpi_reserve_bootmem - do _very_ early ACPI initialisation
48 *
49 * We allocate a page from the first 1MB of memory for the wakeup
50 * routine for when we come back from a sleep state. The
51 * runtime allocator allows specification of <16MB pages, but not
52 * <1MB pages.
53 */
54void __init acpi_reserve_bootmem(void)
55{
56 if ((&wakeup_end - &wakeup_start) > PAGE_SIZE) {
57 printk(KERN_ERR
58 "ACPI: Wakeup code way too big, S3 disabled.\n");
59 return;
60 }
61
62 acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE);
63 if (!acpi_wakeup_address)
64 printk(KERN_ERR "ACPI: Cannot allocate lowmem, S3 disabled.\n");
65}
66
67static int __init acpi_sleep_setup(char *str)
68{
69 while ((str != NULL) && (*str != '\0')) {
70 if (strncmp(str, "s3_bios", 7) == 0)
71 acpi_realmode_flags |= 1;
72 if (strncmp(str, "s3_mode", 7) == 0)
73 acpi_realmode_flags |= 2;
74 if (strncmp(str, "s3_beep", 7) == 0)
75 acpi_realmode_flags |= 4;
76 str = strchr(str, ',');
77 if (str != NULL)
78 str += strspn(str, ", \t");
79 }
80 return 1;
81}
82
83__setup("acpi_sleep=", acpi_sleep_setup);
84
85/* Ouch, we want to delete this. We already have better version in userspace, in 15/* Ouch, we want to delete this. We already have better version in userspace, in
86 s2ram from suspend.sf.net project */ 16 s2ram from suspend.sf.net project */
87static __init int reset_videomode_after_s3(const struct dmi_system_id *d) 17static __init int reset_videomode_after_s3(const struct dmi_system_id *d)
diff --git a/arch/x86/kernel/acpi/sleep_64.c b/arch/x86/kernel/acpi/sleep_64.c
deleted file mode 100644
index da42de261ba8..000000000000
--- a/arch/x86/kernel/acpi/sleep_64.c
+++ /dev/null
@@ -1,117 +0,0 @@
1/*
2 * acpi.c - Architecture-Specific Low-Level ACPI Support
3 *
4 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
5 * Copyright (C) 2001 Jun Nakajima <jun.nakajima@intel.com>
6 * Copyright (C) 2001 Patrick Mochel <mochel@osdl.org>
7 * Copyright (C) 2002 Andi Kleen, SuSE Labs (x86-64 port)
8 * Copyright (C) 2003 Pavel Machek, SuSE Labs
9 *
10 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 *
26 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
27 */
28
29#include <linux/kernel.h>
30#include <linux/init.h>
31#include <linux/types.h>
32#include <linux/stddef.h>
33#include <linux/slab.h>
34#include <linux/pci.h>
35#include <linux/bootmem.h>
36#include <linux/acpi.h>
37#include <linux/cpumask.h>
38
39#include <asm/mpspec.h>
40#include <asm/io.h>
41#include <asm/apic.h>
42#include <asm/apicdef.h>
43#include <asm/page.h>
44#include <asm/pgtable.h>
45#include <asm/pgalloc.h>
46#include <asm/io_apic.h>
47#include <asm/proto.h>
48#include <asm/tlbflush.h>
49
50/* --------------------------------------------------------------------------
51 Low-Level Sleep Support
52 -------------------------------------------------------------------------- */
53
54/* address in low memory of the wakeup routine. */
55unsigned long acpi_wakeup_address = 0;
56unsigned long acpi_realmode_flags;
57extern char wakeup_start, wakeup_end;
58
59extern unsigned long acpi_copy_wakeup_routine(unsigned long);
60
61/**
62 * acpi_save_state_mem - save kernel state
63 *
64 * Create an identity mapped page table and copy the wakeup routine to
65 * low memory.
66 */
67int acpi_save_state_mem(void)
68{
69 memcpy((void *)acpi_wakeup_address, &wakeup_start,
70 &wakeup_end - &wakeup_start);
71 acpi_copy_wakeup_routine(acpi_wakeup_address);
72
73 return 0;
74}
75
76/*
77 * acpi_restore_state
78 */
79void acpi_restore_state_mem(void)
80{
81}
82
83/**
84 * acpi_reserve_bootmem - do _very_ early ACPI initialisation
85 *
86 * We allocate a page in low memory for the wakeup
87 * routine for when we come back from a sleep state. The
88 * runtime allocator allows specification of <16M pages, but not
89 * <1M pages.
90 */
91void __init acpi_reserve_bootmem(void)
92{
93 acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE*2);
94 if ((&wakeup_end - &wakeup_start) > (PAGE_SIZE*2))
95 printk(KERN_CRIT
96 "ACPI: Wakeup code way too big, will crash on attempt"
97 " to suspend\n");
98}
99
100static int __init acpi_sleep_setup(char *str)
101{
102 while ((str != NULL) && (*str != '\0')) {
103 if (strncmp(str, "s3_bios", 7) == 0)
104 acpi_realmode_flags |= 1;
105 if (strncmp(str, "s3_mode", 7) == 0)
106 acpi_realmode_flags |= 2;
107 if (strncmp(str, "s3_beep", 7) == 0)
108 acpi_realmode_flags |= 4;
109 str = strchr(str, ',');
110 if (str != NULL)
111 str += strspn(str, ", \t");
112 }
113 return 1;
114}
115
116__setup("acpi_sleep=", acpi_sleep_setup);
117
diff --git a/arch/x86/kernel/acpi/wakeup_32.S b/arch/x86/kernel/acpi/wakeup_32.S
index 1e931aaf2ef6..f53e3277f8e5 100644
--- a/arch/x86/kernel/acpi/wakeup_32.S
+++ b/arch/x86/kernel/acpi/wakeup_32.S
@@ -1,4 +1,4 @@
1.text 1 .section .text.page_aligned
2#include <linux/linkage.h> 2#include <linux/linkage.h>
3#include <asm/segment.h> 3#include <asm/segment.h>
4#include <asm/page.h> 4#include <asm/page.h>
diff --git a/arch/x86/kernel/acpi/wakeup_64.S b/arch/x86/kernel/acpi/wakeup_64.S
index 5ed3bc5c61d7..2e1b9e0d0767 100644
--- a/arch/x86/kernel/acpi/wakeup_64.S
+++ b/arch/x86/kernel/acpi/wakeup_64.S
@@ -344,13 +344,13 @@ do_suspend_lowlevel:
344 call save_processor_state 344 call save_processor_state
345 345
346 movq $saved_context, %rax 346 movq $saved_context, %rax
347 movq %rsp, pt_regs_rsp(%rax) 347 movq %rsp, pt_regs_sp(%rax)
348 movq %rbp, pt_regs_rbp(%rax) 348 movq %rbp, pt_regs_bp(%rax)
349 movq %rsi, pt_regs_rsi(%rax) 349 movq %rsi, pt_regs_si(%rax)
350 movq %rdi, pt_regs_rdi(%rax) 350 movq %rdi, pt_regs_di(%rax)
351 movq %rbx, pt_regs_rbx(%rax) 351 movq %rbx, pt_regs_bx(%rax)
352 movq %rcx, pt_regs_rcx(%rax) 352 movq %rcx, pt_regs_cx(%rax)
353 movq %rdx, pt_regs_rdx(%rax) 353 movq %rdx, pt_regs_dx(%rax)
354 movq %r8, pt_regs_r8(%rax) 354 movq %r8, pt_regs_r8(%rax)
355 movq %r9, pt_regs_r9(%rax) 355 movq %r9, pt_regs_r9(%rax)
356 movq %r10, pt_regs_r10(%rax) 356 movq %r10, pt_regs_r10(%rax)
@@ -360,7 +360,7 @@ do_suspend_lowlevel:
360 movq %r14, pt_regs_r14(%rax) 360 movq %r14, pt_regs_r14(%rax)
361 movq %r15, pt_regs_r15(%rax) 361 movq %r15, pt_regs_r15(%rax)
362 pushfq 362 pushfq
363 popq pt_regs_eflags(%rax) 363 popq pt_regs_flags(%rax)
364 364
365 movq $.L97, saved_rip(%rip) 365 movq $.L97, saved_rip(%rip)
366 366
@@ -391,15 +391,15 @@ do_suspend_lowlevel:
391 movq %rbx, %cr2 391 movq %rbx, %cr2
392 movq saved_context_cr0(%rax), %rbx 392 movq saved_context_cr0(%rax), %rbx
393 movq %rbx, %cr0 393 movq %rbx, %cr0
394 pushq pt_regs_eflags(%rax) 394 pushq pt_regs_flags(%rax)
395 popfq 395 popfq
396 movq pt_regs_rsp(%rax), %rsp 396 movq pt_regs_sp(%rax), %rsp
397 movq pt_regs_rbp(%rax), %rbp 397 movq pt_regs_bp(%rax), %rbp
398 movq pt_regs_rsi(%rax), %rsi 398 movq pt_regs_si(%rax), %rsi
399 movq pt_regs_rdi(%rax), %rdi 399 movq pt_regs_di(%rax), %rdi
400 movq pt_regs_rbx(%rax), %rbx 400 movq pt_regs_bx(%rax), %rbx
401 movq pt_regs_rcx(%rax), %rcx 401 movq pt_regs_cx(%rax), %rcx
402 movq pt_regs_rdx(%rax), %rdx 402 movq pt_regs_dx(%rax), %rdx
403 movq pt_regs_r8(%rax), %r8 403 movq pt_regs_r8(%rax), %r8
404 movq pt_regs_r9(%rax), %r9 404 movq pt_regs_r9(%rax), %r9
405 movq pt_regs_r10(%rax), %r10 405 movq pt_regs_r10(%rax), %r10
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index d6405e0842b5..45d79ea890ae 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -273,6 +273,7 @@ struct smp_alt_module {
273}; 273};
274static LIST_HEAD(smp_alt_modules); 274static LIST_HEAD(smp_alt_modules);
275static DEFINE_SPINLOCK(smp_alt); 275static DEFINE_SPINLOCK(smp_alt);
276static int smp_mode = 1; /* protected by smp_alt */
276 277
277void alternatives_smp_module_add(struct module *mod, char *name, 278void alternatives_smp_module_add(struct module *mod, char *name,
278 void *locks, void *locks_end, 279 void *locks, void *locks_end,
@@ -341,12 +342,13 @@ void alternatives_smp_switch(int smp)
341 342
342#ifdef CONFIG_LOCKDEP 343#ifdef CONFIG_LOCKDEP
343 /* 344 /*
344 * A not yet fixed binutils section handling bug prevents 345 * Older binutils section handling bug prevented
345 * alternatives-replacement from working reliably, so turn 346 * alternatives-replacement from working reliably.
346 * it off: 347 *
348 * If this still occurs then you should see a hang
349 * or crash shortly after this line:
347 */ 350 */
348 printk("lockdep: not fixing up alternatives.\n"); 351 printk("lockdep: fixing up alternatives.\n");
349 return;
350#endif 352#endif
351 353
352 if (noreplace_smp || smp_alt_once) 354 if (noreplace_smp || smp_alt_once)
@@ -354,21 +356,29 @@ void alternatives_smp_switch(int smp)
354 BUG_ON(!smp && (num_online_cpus() > 1)); 356 BUG_ON(!smp && (num_online_cpus() > 1));
355 357
356 spin_lock_irqsave(&smp_alt, flags); 358 spin_lock_irqsave(&smp_alt, flags);
357 if (smp) { 359
360 /*
361 * Avoid unnecessary switches because it forces JIT based VMs to
362 * throw away all cached translations, which can be quite costly.
363 */
364 if (smp == smp_mode) {
365 /* nothing */
366 } else if (smp) {
358 printk(KERN_INFO "SMP alternatives: switching to SMP code\n"); 367 printk(KERN_INFO "SMP alternatives: switching to SMP code\n");
359 clear_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability); 368 clear_cpu_cap(&boot_cpu_data, X86_FEATURE_UP);
360 clear_bit(X86_FEATURE_UP, cpu_data(0).x86_capability); 369 clear_cpu_cap(&cpu_data(0), X86_FEATURE_UP);
361 list_for_each_entry(mod, &smp_alt_modules, next) 370 list_for_each_entry(mod, &smp_alt_modules, next)
362 alternatives_smp_lock(mod->locks, mod->locks_end, 371 alternatives_smp_lock(mod->locks, mod->locks_end,
363 mod->text, mod->text_end); 372 mod->text, mod->text_end);
364 } else { 373 } else {
365 printk(KERN_INFO "SMP alternatives: switching to UP code\n"); 374 printk(KERN_INFO "SMP alternatives: switching to UP code\n");
366 set_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability); 375 set_cpu_cap(&boot_cpu_data, X86_FEATURE_UP);
367 set_bit(X86_FEATURE_UP, cpu_data(0).x86_capability); 376 set_cpu_cap(&cpu_data(0), X86_FEATURE_UP);
368 list_for_each_entry(mod, &smp_alt_modules, next) 377 list_for_each_entry(mod, &smp_alt_modules, next)
369 alternatives_smp_unlock(mod->locks, mod->locks_end, 378 alternatives_smp_unlock(mod->locks, mod->locks_end,
370 mod->text, mod->text_end); 379 mod->text, mod->text_end);
371 } 380 }
381 smp_mode = smp;
372 spin_unlock_irqrestore(&smp_alt, flags); 382 spin_unlock_irqrestore(&smp_alt, flags);
373} 383}
374 384
@@ -431,8 +441,9 @@ void __init alternative_instructions(void)
431 if (smp_alt_once) { 441 if (smp_alt_once) {
432 if (1 == num_possible_cpus()) { 442 if (1 == num_possible_cpus()) {
433 printk(KERN_INFO "SMP alternatives: switching to UP code\n"); 443 printk(KERN_INFO "SMP alternatives: switching to UP code\n");
434 set_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability); 444 set_cpu_cap(&boot_cpu_data, X86_FEATURE_UP);
435 set_bit(X86_FEATURE_UP, cpu_data(0).x86_capability); 445 set_cpu_cap(&cpu_data(0), X86_FEATURE_UP);
446
436 alternatives_smp_unlock(__smp_locks, __smp_locks_end, 447 alternatives_smp_unlock(__smp_locks, __smp_locks_end,
437 _text, _etext); 448 _text, _etext);
438 } 449 }
@@ -440,7 +451,10 @@ void __init alternative_instructions(void)
440 alternatives_smp_module_add(NULL, "core kernel", 451 alternatives_smp_module_add(NULL, "core kernel",
441 __smp_locks, __smp_locks_end, 452 __smp_locks, __smp_locks_end,
442 _text, _etext); 453 _text, _etext);
443 alternatives_smp_switch(0); 454
455 /* Only switch to UP mode if we don't immediately boot others */
456 if (num_possible_cpus() == 1 || setup_max_cpus <= 1)
457 alternatives_smp_switch(0);
444 } 458 }
445#endif 459#endif
446 apply_paravirt(__parainstructions, __parainstructions_end); 460 apply_paravirt(__parainstructions, __parainstructions_end);
diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c
index 5b6992799c9d..608152a2a05e 100644
--- a/arch/x86/kernel/aperture_64.c
+++ b/arch/x86/kernel/aperture_64.c
@@ -1,12 +1,12 @@
1/* 1/*
2 * Firmware replacement code. 2 * Firmware replacement code.
3 * 3 *
4 * Work around broken BIOSes that don't set an aperture or only set the 4 * Work around broken BIOSes that don't set an aperture or only set the
5 * aperture in the AGP bridge. 5 * aperture in the AGP bridge.
6 * If all fails map the aperture over some low memory. This is cheaper than 6 * If all fails map the aperture over some low memory. This is cheaper than
7 * doing bounce buffering. The memory is lost. This is done at early boot 7 * doing bounce buffering. The memory is lost. This is done at early boot
8 * because only the bootmem allocator can allocate 32+MB. 8 * because only the bootmem allocator can allocate 32+MB.
9 * 9 *
10 * Copyright 2002 Andi Kleen, SuSE Labs. 10 * Copyright 2002 Andi Kleen, SuSE Labs.
11 */ 11 */
12#include <linux/kernel.h> 12#include <linux/kernel.h>
@@ -30,7 +30,7 @@ int gart_iommu_aperture_disabled __initdata = 0;
30int gart_iommu_aperture_allowed __initdata = 0; 30int gart_iommu_aperture_allowed __initdata = 0;
31 31
32int fallback_aper_order __initdata = 1; /* 64MB */ 32int fallback_aper_order __initdata = 1; /* 64MB */
33int fallback_aper_force __initdata = 0; 33int fallback_aper_force __initdata = 0;
34 34
35int fix_aperture __initdata = 1; 35int fix_aperture __initdata = 1;
36 36
@@ -49,167 +49,270 @@ static void __init insert_aperture_resource(u32 aper_base, u32 aper_size)
49/* This code runs before the PCI subsystem is initialized, so just 49/* This code runs before the PCI subsystem is initialized, so just
50 access the northbridge directly. */ 50 access the northbridge directly. */
51 51
52static u32 __init allocate_aperture(void) 52static u32 __init allocate_aperture(void)
53{ 53{
54 u32 aper_size; 54 u32 aper_size;
55 void *p; 55 void *p;
56 56
57 if (fallback_aper_order > 7) 57 if (fallback_aper_order > 7)
58 fallback_aper_order = 7; 58 fallback_aper_order = 7;
59 aper_size = (32 * 1024 * 1024) << fallback_aper_order; 59 aper_size = (32 * 1024 * 1024) << fallback_aper_order;
60 60
61 /* 61 /*
62 * Aperture has to be naturally aligned. This means an 2GB aperture won't 62 * Aperture has to be naturally aligned. This means a 2GB aperture
63 * have much chance of finding a place in the lower 4GB of memory. 63 * won't have much chance of finding a place in the lower 4GB of
64 * Unfortunately we cannot move it up because that would make the 64 * memory. Unfortunately we cannot move it up because that would
65 * IOMMU useless. 65 * make the IOMMU useless.
66 */ 66 */
67 p = __alloc_bootmem_nopanic(aper_size, aper_size, 0); 67 p = __alloc_bootmem_nopanic(aper_size, aper_size, 0);
68 if (!p || __pa(p)+aper_size > 0xffffffff) { 68 if (!p || __pa(p)+aper_size > 0xffffffff) {
69 printk("Cannot allocate aperture memory hole (%p,%uK)\n", 69 printk(KERN_ERR
70 p, aper_size>>10); 70 "Cannot allocate aperture memory hole (%p,%uK)\n",
71 p, aper_size>>10);
71 if (p) 72 if (p)
72 free_bootmem(__pa(p), aper_size); 73 free_bootmem(__pa(p), aper_size);
73 return 0; 74 return 0;
74 } 75 }
75 printk("Mapping aperture over %d KB of RAM @ %lx\n", 76 printk(KERN_INFO "Mapping aperture over %d KB of RAM @ %lx\n",
76 aper_size >> 10, __pa(p)); 77 aper_size >> 10, __pa(p));
77 insert_aperture_resource((u32)__pa(p), aper_size); 78 insert_aperture_resource((u32)__pa(p), aper_size);
78 return (u32)__pa(p); 79
80 return (u32)__pa(p);
79} 81}
80 82
81static int __init aperture_valid(u64 aper_base, u32 aper_size) 83static int __init aperture_valid(u64 aper_base, u32 aper_size)
82{ 84{
83 if (!aper_base) 85 if (!aper_base)
84 return 0;
85 if (aper_size < 64*1024*1024) {
86 printk("Aperture too small (%d MB)\n", aper_size>>20);
87 return 0; 86 return 0;
88 } 87
89 if (aper_base + aper_size > 0x100000000UL) { 88 if (aper_base + aper_size > 0x100000000UL) {
90 printk("Aperture beyond 4GB. Ignoring.\n"); 89 printk(KERN_ERR "Aperture beyond 4GB. Ignoring.\n");
91 return 0; 90 return 0;
92 } 91 }
93 if (e820_any_mapped(aper_base, aper_base + aper_size, E820_RAM)) { 92 if (e820_any_mapped(aper_base, aper_base + aper_size, E820_RAM)) {
94 printk("Aperture pointing to e820 RAM. Ignoring.\n"); 93 printk(KERN_ERR "Aperture pointing to e820 RAM. Ignoring.\n");
95 return 0; 94 return 0;
96 } 95 }
96 if (aper_size < 64*1024*1024) {
97 printk(KERN_ERR "Aperture too small (%d MB)\n", aper_size>>20);
98 return 0;
99 }
100
97 return 1; 101 return 1;
98} 102}
99 103
100/* Find a PCI capability */ 104/* Find a PCI capability */
101static __u32 __init find_cap(int num, int slot, int func, int cap) 105static __u32 __init find_cap(int num, int slot, int func, int cap)
102{ 106{
103 u8 pos;
104 int bytes; 107 int bytes;
105 if (!(read_pci_config_16(num,slot,func,PCI_STATUS) & PCI_STATUS_CAP_LIST)) 108 u8 pos;
109
110 if (!(read_pci_config_16(num, slot, func, PCI_STATUS) &
111 PCI_STATUS_CAP_LIST))
106 return 0; 112 return 0;
107 pos = read_pci_config_byte(num,slot,func,PCI_CAPABILITY_LIST); 113
108 for (bytes = 0; bytes < 48 && pos >= 0x40; bytes++) { 114 pos = read_pci_config_byte(num, slot, func, PCI_CAPABILITY_LIST);
115 for (bytes = 0; bytes < 48 && pos >= 0x40; bytes++) {
109 u8 id; 116 u8 id;
110 pos &= ~3; 117
111 id = read_pci_config_byte(num,slot,func,pos+PCI_CAP_LIST_ID); 118 pos &= ~3;
119 id = read_pci_config_byte(num, slot, func, pos+PCI_CAP_LIST_ID);
112 if (id == 0xff) 120 if (id == 0xff)
113 break; 121 break;
114 if (id == cap) 122 if (id == cap)
115 return pos; 123 return pos;
116 pos = read_pci_config_byte(num,slot,func,pos+PCI_CAP_LIST_NEXT); 124 pos = read_pci_config_byte(num, slot, func,
117 } 125 pos+PCI_CAP_LIST_NEXT);
126 }
118 return 0; 127 return 0;
119} 128}
120 129
121/* Read a standard AGPv3 bridge header */ 130/* Read a standard AGPv3 bridge header */
122static __u32 __init read_agp(int num, int slot, int func, int cap, u32 *order) 131static __u32 __init read_agp(int num, int slot, int func, int cap, u32 *order)
123{ 132{
124 u32 apsize; 133 u32 apsize;
125 u32 apsizereg; 134 u32 apsizereg;
126 int nbits; 135 int nbits;
127 u32 aper_low, aper_hi; 136 u32 aper_low, aper_hi;
128 u64 aper; 137 u64 aper;
129 138
130 printk("AGP bridge at %02x:%02x:%02x\n", num, slot, func); 139 printk(KERN_INFO "AGP bridge at %02x:%02x:%02x\n", num, slot, func);
131 apsizereg = read_pci_config_16(num,slot,func, cap + 0x14); 140 apsizereg = read_pci_config_16(num, slot, func, cap + 0x14);
132 if (apsizereg == 0xffffffff) { 141 if (apsizereg == 0xffffffff) {
133 printk("APSIZE in AGP bridge unreadable\n"); 142 printk(KERN_ERR "APSIZE in AGP bridge unreadable\n");
134 return 0; 143 return 0;
135 } 144 }
136 145
137 apsize = apsizereg & 0xfff; 146 apsize = apsizereg & 0xfff;
138 /* Some BIOS use weird encodings not in the AGPv3 table. */ 147 /* Some BIOS use weird encodings not in the AGPv3 table. */
139 if (apsize & 0xff) 148 if (apsize & 0xff)
140 apsize |= 0xf00; 149 apsize |= 0xf00;
141 nbits = hweight16(apsize); 150 nbits = hweight16(apsize);
142 *order = 7 - nbits; 151 *order = 7 - nbits;
143 if ((int)*order < 0) /* < 32MB */ 152 if ((int)*order < 0) /* < 32MB */
144 *order = 0; 153 *order = 0;
145 154
146 aper_low = read_pci_config(num,slot,func, 0x10); 155 aper_low = read_pci_config(num, slot, func, 0x10);
147 aper_hi = read_pci_config(num,slot,func,0x14); 156 aper_hi = read_pci_config(num, slot, func, 0x14);
148 aper = (aper_low & ~((1<<22)-1)) | ((u64)aper_hi << 32); 157 aper = (aper_low & ~((1<<22)-1)) | ((u64)aper_hi << 32);
149 158
150 printk("Aperture from AGP @ %Lx size %u MB (APSIZE %x)\n", 159 printk(KERN_INFO "Aperture from AGP @ %Lx size %u MB (APSIZE %x)\n",
151 aper, 32 << *order, apsizereg); 160 aper, 32 << *order, apsizereg);
152 161
153 if (!aperture_valid(aper, (32*1024*1024) << *order)) 162 if (!aperture_valid(aper, (32*1024*1024) << *order))
154 return 0; 163 return 0;
155 return (u32)aper; 164 return (u32)aper;
156} 165}
157
158/* Look for an AGP bridge. Windows only expects the aperture in the
159 AGP bridge and some BIOS forget to initialize the Northbridge too.
160 Work around this here.
161
162 Do an PCI bus scan by hand because we're running before the PCI
163 subsystem.
164 166
165 All K8 AGP bridges are AGPv3 compliant, so we can do this scan 167/*
166 generically. It's probably overkill to always scan all slots because 168 * Look for an AGP bridge. Windows only expects the aperture in the
167 the AGP bridges should be always an own bus on the HT hierarchy, 169 * AGP bridge and some BIOS forget to initialize the Northbridge too.
168 but do it here for future safety. */ 170 * Work around this here.
171 *
172 * Do an PCI bus scan by hand because we're running before the PCI
173 * subsystem.
174 *
175 * All K8 AGP bridges are AGPv3 compliant, so we can do this scan
176 * generically. It's probably overkill to always scan all slots because
177 * the AGP bridges should be always an own bus on the HT hierarchy,
178 * but do it here for future safety.
179 */
169static __u32 __init search_agp_bridge(u32 *order, int *valid_agp) 180static __u32 __init search_agp_bridge(u32 *order, int *valid_agp)
170{ 181{
171 int num, slot, func; 182 int num, slot, func;
172 183
173 /* Poor man's PCI discovery */ 184 /* Poor man's PCI discovery */
174 for (num = 0; num < 256; num++) { 185 for (num = 0; num < 256; num++) {
175 for (slot = 0; slot < 32; slot++) { 186 for (slot = 0; slot < 32; slot++) {
176 for (func = 0; func < 8; func++) { 187 for (func = 0; func < 8; func++) {
177 u32 class, cap; 188 u32 class, cap;
178 u8 type; 189 u8 type;
179 class = read_pci_config(num,slot,func, 190 class = read_pci_config(num, slot, func,
180 PCI_CLASS_REVISION); 191 PCI_CLASS_REVISION);
181 if (class == 0xffffffff) 192 if (class == 0xffffffff)
182 break; 193 break;
183 194
184 switch (class >> 16) { 195 switch (class >> 16) {
185 case PCI_CLASS_BRIDGE_HOST: 196 case PCI_CLASS_BRIDGE_HOST:
186 case PCI_CLASS_BRIDGE_OTHER: /* needed? */ 197 case PCI_CLASS_BRIDGE_OTHER: /* needed? */
187 /* AGP bridge? */ 198 /* AGP bridge? */
188 cap = find_cap(num,slot,func,PCI_CAP_ID_AGP); 199 cap = find_cap(num, slot, func,
200 PCI_CAP_ID_AGP);
189 if (!cap) 201 if (!cap)
190 break; 202 break;
191 *valid_agp = 1; 203 *valid_agp = 1;
192 return read_agp(num,slot,func,cap,order); 204 return read_agp(num, slot, func, cap,
193 } 205 order);
194 206 }
207
195 /* No multi-function device? */ 208 /* No multi-function device? */
196 type = read_pci_config_byte(num,slot,func, 209 type = read_pci_config_byte(num, slot, func,
197 PCI_HEADER_TYPE); 210 PCI_HEADER_TYPE);
198 if (!(type & 0x80)) 211 if (!(type & 0x80))
199 break; 212 break;
200 } 213 }
201 } 214 }
202 } 215 }
203 printk("No AGP bridge found\n"); 216 printk(KERN_INFO "No AGP bridge found\n");
217
204 return 0; 218 return 0;
205} 219}
206 220
221static int gart_fix_e820 __initdata = 1;
222
223static int __init parse_gart_mem(char *p)
224{
225 if (!p)
226 return -EINVAL;
227
228 if (!strncmp(p, "off", 3))
229 gart_fix_e820 = 0;
230 else if (!strncmp(p, "on", 2))
231 gart_fix_e820 = 1;
232
233 return 0;
234}
235early_param("gart_fix_e820", parse_gart_mem);
236
237void __init early_gart_iommu_check(void)
238{
239 /*
240 * in case it is enabled before, esp for kexec/kdump,
241 * previous kernel already enable that. memset called
242 * by allocate_aperture/__alloc_bootmem_nopanic cause restart.
243 * or second kernel have different position for GART hole. and new
244 * kernel could use hole as RAM that is still used by GART set by
245 * first kernel
246 * or BIOS forget to put that in reserved.
247 * try to update e820 to make that region as reserved.
248 */
249 int fix, num;
250 u32 ctl;
251 u32 aper_size = 0, aper_order = 0, last_aper_order = 0;
252 u64 aper_base = 0, last_aper_base = 0;
253 int aper_enabled = 0, last_aper_enabled = 0;
254
255 if (!early_pci_allowed())
256 return;
257
258 fix = 0;
259 for (num = 24; num < 32; num++) {
260 if (!early_is_k8_nb(read_pci_config(0, num, 3, 0x00)))
261 continue;
262
263 ctl = read_pci_config(0, num, 3, 0x90);
264 aper_enabled = ctl & 1;
265 aper_order = (ctl >> 1) & 7;
266 aper_size = (32 * 1024 * 1024) << aper_order;
267 aper_base = read_pci_config(0, num, 3, 0x94) & 0x7fff;
268 aper_base <<= 25;
269
270 if ((last_aper_order && aper_order != last_aper_order) ||
271 (last_aper_base && aper_base != last_aper_base) ||
272 (last_aper_enabled && aper_enabled != last_aper_enabled)) {
273 fix = 1;
274 break;
275 }
276 last_aper_order = aper_order;
277 last_aper_base = aper_base;
278 last_aper_enabled = aper_enabled;
279 }
280
281 if (!fix && !aper_enabled)
282 return;
283
284 if (!aper_base || !aper_size || aper_base + aper_size > 0x100000000UL)
285 fix = 1;
286
287 if (gart_fix_e820 && !fix && aper_enabled) {
288 if (e820_any_mapped(aper_base, aper_base + aper_size,
289 E820_RAM)) {
290 /* reserved it, so we can resuse it in second kernel */
291 printk(KERN_INFO "update e820 for GART\n");
292 add_memory_region(aper_base, aper_size, E820_RESERVED);
293 update_e820();
294 }
295 return;
296 }
297
298 /* different nodes have different setting, disable them all at first*/
299 for (num = 24; num < 32; num++) {
300 if (!early_is_k8_nb(read_pci_config(0, num, 3, 0x00)))
301 continue;
302
303 ctl = read_pci_config(0, num, 3, 0x90);
304 ctl &= ~1;
305 write_pci_config(0, num, 3, 0x90, ctl);
306 }
307
308}
309
207void __init gart_iommu_hole_init(void) 310void __init gart_iommu_hole_init(void)
208{ 311{
209 int fix, num;
210 u32 aper_size, aper_alloc = 0, aper_order = 0, last_aper_order = 0; 312 u32 aper_size, aper_alloc = 0, aper_order = 0, last_aper_order = 0;
211 u64 aper_base, last_aper_base = 0; 313 u64 aper_base, last_aper_base = 0;
212 int valid_agp = 0; 314 int fix, num, valid_agp = 0;
315 int node;
213 316
214 if (gart_iommu_aperture_disabled || !fix_aperture || 317 if (gart_iommu_aperture_disabled || !fix_aperture ||
215 !early_pci_allowed()) 318 !early_pci_allowed())
@@ -218,24 +321,26 @@ void __init gart_iommu_hole_init(void)
218 printk(KERN_INFO "Checking aperture...\n"); 321 printk(KERN_INFO "Checking aperture...\n");
219 322
220 fix = 0; 323 fix = 0;
221 for (num = 24; num < 32; num++) { 324 node = 0;
325 for (num = 24; num < 32; num++) {
222 if (!early_is_k8_nb(read_pci_config(0, num, 3, 0x00))) 326 if (!early_is_k8_nb(read_pci_config(0, num, 3, 0x00)))
223 continue; 327 continue;
224 328
225 iommu_detected = 1; 329 iommu_detected = 1;
226 gart_iommu_aperture = 1; 330 gart_iommu_aperture = 1;
227 331
228 aper_order = (read_pci_config(0, num, 3, 0x90) >> 1) & 7; 332 aper_order = (read_pci_config(0, num, 3, 0x90) >> 1) & 7;
229 aper_size = (32 * 1024 * 1024) << aper_order; 333 aper_size = (32 * 1024 * 1024) << aper_order;
230 aper_base = read_pci_config(0, num, 3, 0x94) & 0x7fff; 334 aper_base = read_pci_config(0, num, 3, 0x94) & 0x7fff;
231 aper_base <<= 25; 335 aper_base <<= 25;
336
337 printk(KERN_INFO "Node %d: aperture @ %Lx size %u MB\n",
338 node, aper_base, aper_size >> 20);
339 node++;
232 340
233 printk("CPU %d: aperture @ %Lx size %u MB\n", num-24,
234 aper_base, aper_size>>20);
235
236 if (!aperture_valid(aper_base, aper_size)) { 341 if (!aperture_valid(aper_base, aper_size)) {
237 fix = 1; 342 fix = 1;
238 break; 343 break;
239 } 344 }
240 345
241 if ((last_aper_order && aper_order != last_aper_order) || 346 if ((last_aper_order && aper_order != last_aper_order) ||
@@ -245,55 +350,64 @@ void __init gart_iommu_hole_init(void)
245 } 350 }
246 last_aper_order = aper_order; 351 last_aper_order = aper_order;
247 last_aper_base = aper_base; 352 last_aper_base = aper_base;
248 } 353 }
249 354
250 if (!fix && !fallback_aper_force) { 355 if (!fix && !fallback_aper_force) {
251 if (last_aper_base) { 356 if (last_aper_base) {
252 unsigned long n = (32 * 1024 * 1024) << last_aper_order; 357 unsigned long n = (32 * 1024 * 1024) << last_aper_order;
358
253 insert_aperture_resource((u32)last_aper_base, n); 359 insert_aperture_resource((u32)last_aper_base, n);
254 } 360 }
255 return; 361 return;
256 } 362 }
257 363
258 if (!fallback_aper_force) 364 if (!fallback_aper_force)
259 aper_alloc = search_agp_bridge(&aper_order, &valid_agp); 365 aper_alloc = search_agp_bridge(&aper_order, &valid_agp);
260 366
261 if (aper_alloc) { 367 if (aper_alloc) {
262 /* Got the aperture from the AGP bridge */ 368 /* Got the aperture from the AGP bridge */
263 } else if (swiotlb && !valid_agp) { 369 } else if (swiotlb && !valid_agp) {
264 /* Do nothing */ 370 /* Do nothing */
265 } else if ((!no_iommu && end_pfn > MAX_DMA32_PFN) || 371 } else if ((!no_iommu && end_pfn > MAX_DMA32_PFN) ||
266 force_iommu || 372 force_iommu ||
267 valid_agp || 373 valid_agp ||
268 fallback_aper_force) { 374 fallback_aper_force) {
269 printk("Your BIOS doesn't leave a aperture memory hole\n"); 375 printk(KERN_ERR
270 printk("Please enable the IOMMU option in the BIOS setup\n"); 376 "Your BIOS doesn't leave a aperture memory hole\n");
271 printk("This costs you %d MB of RAM\n", 377 printk(KERN_ERR
272 32 << fallback_aper_order); 378 "Please enable the IOMMU option in the BIOS setup\n");
379 printk(KERN_ERR
380 "This costs you %d MB of RAM\n",
381 32 << fallback_aper_order);
273 382
274 aper_order = fallback_aper_order; 383 aper_order = fallback_aper_order;
275 aper_alloc = allocate_aperture(); 384 aper_alloc = allocate_aperture();
276 if (!aper_alloc) { 385 if (!aper_alloc) {
277 /* Could disable AGP and IOMMU here, but it's probably 386 /*
278 not worth it. But the later users cannot deal with 387 * Could disable AGP and IOMMU here, but it's
279 bad apertures and turning on the aperture over memory 388 * probably not worth it. But the later users
280 causes very strange problems, so it's better to 389 * cannot deal with bad apertures and turning
281 panic early. */ 390 * on the aperture over memory causes very
391 * strange problems, so it's better to panic
392 * early.
393 */
282 panic("Not enough memory for aperture"); 394 panic("Not enough memory for aperture");
283 } 395 }
284 } else { 396 } else {
285 return; 397 return;
286 } 398 }
287 399
288 /* Fix up the north bridges */ 400 /* Fix up the north bridges */
289 for (num = 24; num < 32; num++) { 401 for (num = 24; num < 32; num++) {
290 if (!early_is_k8_nb(read_pci_config(0, num, 3, 0x00))) 402 if (!early_is_k8_nb(read_pci_config(0, num, 3, 0x00)))
291 continue; 403 continue;
292 404
293 /* Don't enable translation yet. That is done later. 405 /*
294 Assume this BIOS didn't initialise the GART so 406 * Don't enable translation yet. That is done later.
295 just overwrite all previous bits */ 407 * Assume this BIOS didn't initialise the GART so
296 write_pci_config(0, num, 3, 0x90, aper_order<<1); 408 * just overwrite all previous bits
297 write_pci_config(0, num, 3, 0x94, aper_alloc>>25); 409 */
298 } 410 write_pci_config(0, num, 3, 0x90, aper_order<<1);
299} 411 write_pci_config(0, num, 3, 0x94, aper_alloc>>25);
412 }
413}
diff --git a/arch/x86/kernel/apic_32.c b/arch/x86/kernel/apic_32.c
index edb5108e5d0e..35a568ea8400 100644
--- a/arch/x86/kernel/apic_32.c
+++ b/arch/x86/kernel/apic_32.c
@@ -43,12 +43,10 @@
43#include <mach_apicdef.h> 43#include <mach_apicdef.h>
44#include <mach_ipi.h> 44#include <mach_ipi.h>
45 45
46#include "io_ports.h"
47
48/* 46/*
49 * Sanity check 47 * Sanity check
50 */ 48 */
51#if (SPURIOUS_APIC_VECTOR & 0x0F) != 0x0F 49#if ((SPURIOUS_APIC_VECTOR & 0x0F) != 0x0F)
52# error SPURIOUS_APIC_VECTOR definition error 50# error SPURIOUS_APIC_VECTOR definition error
53#endif 51#endif
54 52
@@ -57,7 +55,7 @@
57 * 55 *
58 * -1=force-disable, +1=force-enable 56 * -1=force-disable, +1=force-enable
59 */ 57 */
60static int enable_local_apic __initdata = 0; 58static int enable_local_apic __initdata;
61 59
62/* Local APIC timer verification ok */ 60/* Local APIC timer verification ok */
63static int local_apic_timer_verify_ok; 61static int local_apic_timer_verify_ok;
@@ -101,6 +99,8 @@ static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
101/* Local APIC was disabled by the BIOS and enabled by the kernel */ 99/* Local APIC was disabled by the BIOS and enabled by the kernel */
102static int enabled_via_apicbase; 100static int enabled_via_apicbase;
103 101
102static unsigned long apic_phys;
103
104/* 104/*
105 * Get the LAPIC version 105 * Get the LAPIC version
106 */ 106 */
@@ -110,7 +110,7 @@ static inline int lapic_get_version(void)
110} 110}
111 111
112/* 112/*
113 * Check, if the APIC is integrated or a seperate chip 113 * Check, if the APIC is integrated or a separate chip
114 */ 114 */
115static inline int lapic_is_integrated(void) 115static inline int lapic_is_integrated(void)
116{ 116{
@@ -135,9 +135,9 @@ void apic_wait_icr_idle(void)
135 cpu_relax(); 135 cpu_relax();
136} 136}
137 137
138unsigned long safe_apic_wait_icr_idle(void) 138u32 safe_apic_wait_icr_idle(void)
139{ 139{
140 unsigned long send_status; 140 u32 send_status;
141 int timeout; 141 int timeout;
142 142
143 timeout = 0; 143 timeout = 0;
@@ -154,7 +154,7 @@ unsigned long safe_apic_wait_icr_idle(void)
154/** 154/**
155 * enable_NMI_through_LVT0 - enable NMI through local vector table 0 155 * enable_NMI_through_LVT0 - enable NMI through local vector table 0
156 */ 156 */
157void enable_NMI_through_LVT0 (void * dummy) 157void __cpuinit enable_NMI_through_LVT0(void)
158{ 158{
159 unsigned int v = APIC_DM_NMI; 159 unsigned int v = APIC_DM_NMI;
160 160
@@ -379,8 +379,10 @@ void __init setup_boot_APIC_clock(void)
379 */ 379 */
380 if (local_apic_timer_disabled) { 380 if (local_apic_timer_disabled) {
381 /* No broadcast on UP ! */ 381 /* No broadcast on UP ! */
382 if (num_possible_cpus() > 1) 382 if (num_possible_cpus() > 1) {
383 lapic_clockevent.mult = 1;
383 setup_APIC_timer(); 384 setup_APIC_timer();
385 }
384 return; 386 return;
385 } 387 }
386 388
@@ -434,7 +436,7 @@ void __init setup_boot_APIC_clock(void)
434 "with PM Timer: %ldms instead of 100ms\n", 436 "with PM Timer: %ldms instead of 100ms\n",
435 (long)res); 437 (long)res);
436 /* Correct the lapic counter value */ 438 /* Correct the lapic counter value */
437 res = (((u64) delta ) * pm_100ms); 439 res = (((u64) delta) * pm_100ms);
438 do_div(res, deltapm); 440 do_div(res, deltapm);
439 printk(KERN_INFO "APIC delta adjusted to PM-Timer: " 441 printk(KERN_INFO "APIC delta adjusted to PM-Timer: "
440 "%lu (%ld)\n", (unsigned long) res, delta); 442 "%lu (%ld)\n", (unsigned long) res, delta);
@@ -472,6 +474,19 @@ void __init setup_boot_APIC_clock(void)
472 474
473 local_apic_timer_verify_ok = 1; 475 local_apic_timer_verify_ok = 1;
474 476
477 /*
478 * Do a sanity check on the APIC calibration result
479 */
480 if (calibration_result < (1000000 / HZ)) {
481 local_irq_enable();
482 printk(KERN_WARNING
483 "APIC frequency too slow, disabling apic timer\n");
484 /* No broadcast on UP ! */
485 if (num_possible_cpus() > 1)
486 setup_APIC_timer();
487 return;
488 }
489
475 /* We trust the pm timer based calibration */ 490 /* We trust the pm timer based calibration */
476 if (!pm_referenced) { 491 if (!pm_referenced) {
477 apic_printk(APIC_VERBOSE, "... verify APIC timer\n"); 492 apic_printk(APIC_VERBOSE, "... verify APIC timer\n");
@@ -563,6 +578,9 @@ static void local_apic_timer_interrupt(void)
563 return; 578 return;
564 } 579 }
565 580
581 /*
582 * the NMI deadlock-detector uses this.
583 */
566 per_cpu(irq_stat, cpu).apic_timer_irqs++; 584 per_cpu(irq_stat, cpu).apic_timer_irqs++;
567 585
568 evt->event_handler(evt); 586 evt->event_handler(evt);
@@ -576,8 +594,7 @@ static void local_apic_timer_interrupt(void)
576 * [ if a single-CPU system runs an SMP kernel then we call the local 594 * [ if a single-CPU system runs an SMP kernel then we call the local
577 * interrupt as well. Thus we cannot inline the local irq ... ] 595 * interrupt as well. Thus we cannot inline the local irq ... ]
578 */ 596 */
579 597void smp_apic_timer_interrupt(struct pt_regs *regs)
580void fastcall smp_apic_timer_interrupt(struct pt_regs *regs)
581{ 598{
582 struct pt_regs *old_regs = set_irq_regs(regs); 599 struct pt_regs *old_regs = set_irq_regs(regs);
583 600
@@ -616,9 +633,14 @@ int setup_profiling_timer(unsigned int multiplier)
616 */ 633 */
617void clear_local_APIC(void) 634void clear_local_APIC(void)
618{ 635{
619 int maxlvt = lapic_get_maxlvt(); 636 int maxlvt;
620 unsigned long v; 637 u32 v;
638
639 /* APIC hasn't been mapped yet */
640 if (!apic_phys)
641 return;
621 642
643 maxlvt = lapic_get_maxlvt();
622 /* 644 /*
623 * Masking an LVT entry can trigger a local APIC error 645 * Masking an LVT entry can trigger a local APIC error
624 * if the vector is zero. Mask LVTERR first to prevent this. 646 * if the vector is zero. Mask LVTERR first to prevent this.
@@ -976,7 +998,8 @@ void __cpuinit setup_local_APIC(void)
976 value |= APIC_LVT_LEVEL_TRIGGER; 998 value |= APIC_LVT_LEVEL_TRIGGER;
977 apic_write_around(APIC_LVT1, value); 999 apic_write_around(APIC_LVT1, value);
978 1000
979 if (integrated && !esr_disable) { /* !82489DX */ 1001 if (integrated && !esr_disable) {
1002 /* !82489DX */
980 maxlvt = lapic_get_maxlvt(); 1003 maxlvt = lapic_get_maxlvt();
981 if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */ 1004 if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */
982 apic_write(APIC_ESR, 0); 1005 apic_write(APIC_ESR, 0);
@@ -1020,7 +1043,7 @@ void __cpuinit setup_local_APIC(void)
1020/* 1043/*
1021 * Detect and initialize APIC 1044 * Detect and initialize APIC
1022 */ 1045 */
1023static int __init detect_init_APIC (void) 1046static int __init detect_init_APIC(void)
1024{ 1047{
1025 u32 h, l, features; 1048 u32 h, l, features;
1026 1049
@@ -1077,7 +1100,7 @@ static int __init detect_init_APIC (void)
1077 printk(KERN_WARNING "Could not enable APIC!\n"); 1100 printk(KERN_WARNING "Could not enable APIC!\n");
1078 return -1; 1101 return -1;
1079 } 1102 }
1080 set_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); 1103 set_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC);
1081 mp_lapic_addr = APIC_DEFAULT_PHYS_BASE; 1104 mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
1082 1105
1083 /* The BIOS may have set up the APIC at some other address */ 1106 /* The BIOS may have set up the APIC at some other address */
@@ -1104,8 +1127,6 @@ no_apic:
1104 */ 1127 */
1105void __init init_apic_mappings(void) 1128void __init init_apic_mappings(void)
1106{ 1129{
1107 unsigned long apic_phys;
1108
1109 /* 1130 /*
1110 * If no local APIC can be found then set up a fake all 1131 * If no local APIC can be found then set up a fake all
1111 * zeroes page to simulate the local APIC and another 1132 * zeroes page to simulate the local APIC and another
@@ -1164,10 +1185,10 @@ fake_ioapic_page:
1164 * This initializes the IO-APIC and APIC hardware if this is 1185 * This initializes the IO-APIC and APIC hardware if this is
1165 * a UP kernel. 1186 * a UP kernel.
1166 */ 1187 */
1167int __init APIC_init_uniprocessor (void) 1188int __init APIC_init_uniprocessor(void)
1168{ 1189{
1169 if (enable_local_apic < 0) 1190 if (enable_local_apic < 0)
1170 clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); 1191 clear_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC);
1171 1192
1172 if (!smp_found_config && !cpu_has_apic) 1193 if (!smp_found_config && !cpu_has_apic)
1173 return -1; 1194 return -1;
@@ -1179,7 +1200,7 @@ int __init APIC_init_uniprocessor (void)
1179 APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) { 1200 APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) {
1180 printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n", 1201 printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
1181 boot_cpu_physical_apicid); 1202 boot_cpu_physical_apicid);
1182 clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); 1203 clear_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC);
1183 return -1; 1204 return -1;
1184 } 1205 }
1185 1206
@@ -1210,50 +1231,6 @@ int __init APIC_init_uniprocessor (void)
1210} 1231}
1211 1232
1212/* 1233/*
1213 * APIC command line parameters
1214 */
1215static int __init parse_lapic(char *arg)
1216{
1217 enable_local_apic = 1;
1218 return 0;
1219}
1220early_param("lapic", parse_lapic);
1221
1222static int __init parse_nolapic(char *arg)
1223{
1224 enable_local_apic = -1;
1225 clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
1226 return 0;
1227}
1228early_param("nolapic", parse_nolapic);
1229
1230static int __init parse_disable_lapic_timer(char *arg)
1231{
1232 local_apic_timer_disabled = 1;
1233 return 0;
1234}
1235early_param("nolapic_timer", parse_disable_lapic_timer);
1236
1237static int __init parse_lapic_timer_c2_ok(char *arg)
1238{
1239 local_apic_timer_c2_ok = 1;
1240 return 0;
1241}
1242early_param("lapic_timer_c2_ok", parse_lapic_timer_c2_ok);
1243
1244static int __init apic_set_verbosity(char *str)
1245{
1246 if (strcmp("debug", str) == 0)
1247 apic_verbosity = APIC_DEBUG;
1248 else if (strcmp("verbose", str) == 0)
1249 apic_verbosity = APIC_VERBOSE;
1250 return 1;
1251}
1252
1253__setup("apic=", apic_set_verbosity);
1254
1255
1256/*
1257 * Local APIC interrupts 1234 * Local APIC interrupts
1258 */ 1235 */
1259 1236
@@ -1306,7 +1283,7 @@ void smp_error_interrupt(struct pt_regs *regs)
1306 6: Received illegal vector 1283 6: Received illegal vector
1307 7: Illegal register address 1284 7: Illegal register address
1308 */ 1285 */
1309 printk (KERN_DEBUG "APIC error on CPU%d: %02lx(%02lx)\n", 1286 printk(KERN_DEBUG "APIC error on CPU%d: %02lx(%02lx)\n",
1310 smp_processor_id(), v , v1); 1287 smp_processor_id(), v , v1);
1311 irq_exit(); 1288 irq_exit();
1312} 1289}
@@ -1393,7 +1370,7 @@ void disconnect_bsp_APIC(int virt_wire_setup)
1393 value = apic_read(APIC_LVT0); 1370 value = apic_read(APIC_LVT0);
1394 value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING | 1371 value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING |
1395 APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR | 1372 APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR |
1396 APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED ); 1373 APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED);
1397 value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING; 1374 value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
1398 value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT); 1375 value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT);
1399 apic_write_around(APIC_LVT0, value); 1376 apic_write_around(APIC_LVT0, value);
@@ -1530,7 +1507,7 @@ static int lapic_resume(struct sys_device *dev)
1530 */ 1507 */
1531 1508
1532static struct sysdev_class lapic_sysclass = { 1509static struct sysdev_class lapic_sysclass = {
1533 set_kset_name("lapic"), 1510 .name = "lapic",
1534 .resume = lapic_resume, 1511 .resume = lapic_resume,
1535 .suspend = lapic_suspend, 1512 .suspend = lapic_suspend,
1536}; 1513};
@@ -1565,3 +1542,46 @@ device_initcall(init_lapic_sysfs);
1565static void apic_pm_activate(void) { } 1542static void apic_pm_activate(void) { }
1566 1543
1567#endif /* CONFIG_PM */ 1544#endif /* CONFIG_PM */
1545
1546/*
1547 * APIC command line parameters
1548 */
1549static int __init parse_lapic(char *arg)
1550{
1551 enable_local_apic = 1;
1552 return 0;
1553}
1554early_param("lapic", parse_lapic);
1555
1556static int __init parse_nolapic(char *arg)
1557{
1558 enable_local_apic = -1;
1559 clear_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC);
1560 return 0;
1561}
1562early_param("nolapic", parse_nolapic);
1563
1564static int __init parse_disable_lapic_timer(char *arg)
1565{
1566 local_apic_timer_disabled = 1;
1567 return 0;
1568}
1569early_param("nolapic_timer", parse_disable_lapic_timer);
1570
1571static int __init parse_lapic_timer_c2_ok(char *arg)
1572{
1573 local_apic_timer_c2_ok = 1;
1574 return 0;
1575}
1576early_param("lapic_timer_c2_ok", parse_lapic_timer_c2_ok);
1577
1578static int __init apic_set_verbosity(char *str)
1579{
1580 if (strcmp("debug", str) == 0)
1581 apic_verbosity = APIC_DEBUG;
1582 else if (strcmp("verbose", str) == 0)
1583 apic_verbosity = APIC_VERBOSE;
1584 return 1;
1585}
1586__setup("apic=", apic_set_verbosity);
1587
diff --git a/arch/x86/kernel/apic_64.c b/arch/x86/kernel/apic_64.c
index f28ccb588fba..d8d03e09dea2 100644
--- a/arch/x86/kernel/apic_64.c
+++ b/arch/x86/kernel/apic_64.c
@@ -23,32 +23,37 @@
23#include <linux/mc146818rtc.h> 23#include <linux/mc146818rtc.h>
24#include <linux/kernel_stat.h> 24#include <linux/kernel_stat.h>
25#include <linux/sysdev.h> 25#include <linux/sysdev.h>
26#include <linux/module.h>
27#include <linux/ioport.h> 26#include <linux/ioport.h>
28#include <linux/clockchips.h> 27#include <linux/clockchips.h>
28#include <linux/acpi_pmtmr.h>
29#include <linux/module.h>
29 30
30#include <asm/atomic.h> 31#include <asm/atomic.h>
31#include <asm/smp.h> 32#include <asm/smp.h>
32#include <asm/mtrr.h> 33#include <asm/mtrr.h>
33#include <asm/mpspec.h> 34#include <asm/mpspec.h>
35#include <asm/hpet.h>
34#include <asm/pgalloc.h> 36#include <asm/pgalloc.h>
35#include <asm/mach_apic.h> 37#include <asm/mach_apic.h>
36#include <asm/nmi.h> 38#include <asm/nmi.h>
37#include <asm/idle.h> 39#include <asm/idle.h>
38#include <asm/proto.h> 40#include <asm/proto.h>
39#include <asm/timex.h> 41#include <asm/timex.h>
40#include <asm/hpet.h>
41#include <asm/apic.h> 42#include <asm/apic.h>
42 43
43int apic_verbosity;
44int disable_apic_timer __cpuinitdata; 44int disable_apic_timer __cpuinitdata;
45static int apic_calibrate_pmtmr __initdata; 45static int apic_calibrate_pmtmr __initdata;
46int disable_apic;
46 47
47/* Local APIC timer works in C2? */ 48/* Local APIC timer works in C2 */
48int local_apic_timer_c2_ok; 49int local_apic_timer_c2_ok;
49EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok); 50EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok);
50 51
51static struct resource *ioapic_resources; 52/*
53 * Debug level, exported for io_apic.c
54 */
55int apic_verbosity;
56
52static struct resource lapic_resource = { 57static struct resource lapic_resource = {
53 .name = "Local APIC", 58 .name = "Local APIC",
54 .flags = IORESOURCE_MEM | IORESOURCE_BUSY, 59 .flags = IORESOURCE_MEM | IORESOURCE_BUSY,
@@ -60,10 +65,8 @@ static int lapic_next_event(unsigned long delta,
60 struct clock_event_device *evt); 65 struct clock_event_device *evt);
61static void lapic_timer_setup(enum clock_event_mode mode, 66static void lapic_timer_setup(enum clock_event_mode mode,
62 struct clock_event_device *evt); 67 struct clock_event_device *evt);
63
64static void lapic_timer_broadcast(cpumask_t mask); 68static void lapic_timer_broadcast(cpumask_t mask);
65 69static void apic_pm_activate(void);
66static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen);
67 70
68static struct clock_event_device lapic_clockevent = { 71static struct clock_event_device lapic_clockevent = {
69 .name = "lapic", 72 .name = "lapic",
@@ -78,6 +81,150 @@ static struct clock_event_device lapic_clockevent = {
78}; 81};
79static DEFINE_PER_CPU(struct clock_event_device, lapic_events); 82static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
80 83
84static unsigned long apic_phys;
85
86/*
87 * Get the LAPIC version
88 */
89static inline int lapic_get_version(void)
90{
91 return GET_APIC_VERSION(apic_read(APIC_LVR));
92}
93
94/*
95 * Check, if the APIC is integrated or a seperate chip
96 */
97static inline int lapic_is_integrated(void)
98{
99 return 1;
100}
101
102/*
103 * Check, whether this is a modern or a first generation APIC
104 */
105static int modern_apic(void)
106{
107 /* AMD systems use old APIC versions, so check the CPU */
108 if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
109 boot_cpu_data.x86 >= 0xf)
110 return 1;
111 return lapic_get_version() >= 0x14;
112}
113
114void apic_wait_icr_idle(void)
115{
116 while (apic_read(APIC_ICR) & APIC_ICR_BUSY)
117 cpu_relax();
118}
119
120u32 safe_apic_wait_icr_idle(void)
121{
122 u32 send_status;
123 int timeout;
124
125 timeout = 0;
126 do {
127 send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY;
128 if (!send_status)
129 break;
130 udelay(100);
131 } while (timeout++ < 1000);
132
133 return send_status;
134}
135
136/**
137 * enable_NMI_through_LVT0 - enable NMI through local vector table 0
138 */
139void __cpuinit enable_NMI_through_LVT0(void)
140{
141 unsigned int v;
142
143 /* unmask and set to NMI */
144 v = APIC_DM_NMI;
145 apic_write(APIC_LVT0, v);
146}
147
148/**
149 * lapic_get_maxlvt - get the maximum number of local vector table entries
150 */
151int lapic_get_maxlvt(void)
152{
153 unsigned int v, maxlvt;
154
155 v = apic_read(APIC_LVR);
156 maxlvt = GET_APIC_MAXLVT(v);
157 return maxlvt;
158}
159
160/*
161 * This function sets up the local APIC timer, with a timeout of
162 * 'clocks' APIC bus clock. During calibration we actually call
163 * this function twice on the boot CPU, once with a bogus timeout
164 * value, second time for real. The other (noncalibrating) CPUs
165 * call this function only once, with the real, calibrated value.
166 *
167 * We do reads before writes even if unnecessary, to get around the
168 * P5 APIC double write bug.
169 */
170
171static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen)
172{
173 unsigned int lvtt_value, tmp_value;
174
175 lvtt_value = LOCAL_TIMER_VECTOR;
176 if (!oneshot)
177 lvtt_value |= APIC_LVT_TIMER_PERIODIC;
178 if (!irqen)
179 lvtt_value |= APIC_LVT_MASKED;
180
181 apic_write(APIC_LVTT, lvtt_value);
182
183 /*
184 * Divide PICLK by 16
185 */
186 tmp_value = apic_read(APIC_TDCR);
187 apic_write(APIC_TDCR, (tmp_value
188 & ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE))
189 | APIC_TDR_DIV_16);
190
191 if (!oneshot)
192 apic_write(APIC_TMICT, clocks);
193}
194
195/*
196 * Setup extended LVT, AMD specific (K8, family 10h)
197 *
198 * Vector mappings are hard coded. On K8 only offset 0 (APIC500) and
199 * MCE interrupts are supported. Thus MCE offset must be set to 0.
200 */
201
202#define APIC_EILVT_LVTOFF_MCE 0
203#define APIC_EILVT_LVTOFF_IBS 1
204
205static void setup_APIC_eilvt(u8 lvt_off, u8 vector, u8 msg_type, u8 mask)
206{
207 unsigned long reg = (lvt_off << 4) + APIC_EILVT0;
208 unsigned int v = (mask << 16) | (msg_type << 8) | vector;
209
210 apic_write(reg, v);
211}
212
213u8 setup_APIC_eilvt_mce(u8 vector, u8 msg_type, u8 mask)
214{
215 setup_APIC_eilvt(APIC_EILVT_LVTOFF_MCE, vector, msg_type, mask);
216 return APIC_EILVT_LVTOFF_MCE;
217}
218
219u8 setup_APIC_eilvt_ibs(u8 vector, u8 msg_type, u8 mask)
220{
221 setup_APIC_eilvt(APIC_EILVT_LVTOFF_IBS, vector, msg_type, mask);
222 return APIC_EILVT_LVTOFF_IBS;
223}
224
225/*
226 * Program the next event, relative to now
227 */
81static int lapic_next_event(unsigned long delta, 228static int lapic_next_event(unsigned long delta,
82 struct clock_event_device *evt) 229 struct clock_event_device *evt)
83{ 230{
@@ -85,6 +232,9 @@ static int lapic_next_event(unsigned long delta,
85 return 0; 232 return 0;
86} 233}
87 234
235/*
236 * Setup the lapic timer in periodic or oneshot mode
237 */
88static void lapic_timer_setup(enum clock_event_mode mode, 238static void lapic_timer_setup(enum clock_event_mode mode,
89 struct clock_event_device *evt) 239 struct clock_event_device *evt)
90{ 240{
@@ -127,75 +277,261 @@ static void lapic_timer_broadcast(cpumask_t mask)
127#endif 277#endif
128} 278}
129 279
130static void apic_pm_activate(void); 280/*
281 * Setup the local APIC timer for this CPU. Copy the initilized values
282 * of the boot CPU and register the clock event in the framework.
283 */
284static void setup_APIC_timer(void)
285{
286 struct clock_event_device *levt = &__get_cpu_var(lapic_events);
131 287
132void apic_wait_icr_idle(void) 288 memcpy(levt, &lapic_clockevent, sizeof(*levt));
289 levt->cpumask = cpumask_of_cpu(smp_processor_id());
290
291 clockevents_register_device(levt);
292}
293
294/*
295 * In this function we calibrate APIC bus clocks to the external
296 * timer. Unfortunately we cannot use jiffies and the timer irq
297 * to calibrate, since some later bootup code depends on getting
298 * the first irq? Ugh.
299 *
300 * We want to do the calibration only once since we
301 * want to have local timer irqs syncron. CPUs connected
302 * by the same APIC bus have the very same bus frequency.
303 * And we want to have irqs off anyways, no accidental
304 * APIC irq that way.
305 */
306
307#define TICK_COUNT 100000000
308
309static void __init calibrate_APIC_clock(void)
133{ 310{
134 while (apic_read(APIC_ICR) & APIC_ICR_BUSY) 311 unsigned apic, apic_start;
135 cpu_relax(); 312 unsigned long tsc, tsc_start;
313 int result;
314
315 local_irq_disable();
316
317 /*
318 * Put whatever arbitrary (but long enough) timeout
319 * value into the APIC clock, we just want to get the
320 * counter running for calibration.
321 *
322 * No interrupt enable !
323 */
324 __setup_APIC_LVTT(250000000, 0, 0);
325
326 apic_start = apic_read(APIC_TMCCT);
327#ifdef CONFIG_X86_PM_TIMER
328 if (apic_calibrate_pmtmr && pmtmr_ioport) {
329 pmtimer_wait(5000); /* 5ms wait */
330 apic = apic_read(APIC_TMCCT);
331 result = (apic_start - apic) * 1000L / 5;
332 } else
333#endif
334 {
335 rdtscll(tsc_start);
336
337 do {
338 apic = apic_read(APIC_TMCCT);
339 rdtscll(tsc);
340 } while ((tsc - tsc_start) < TICK_COUNT &&
341 (apic_start - apic) < TICK_COUNT);
342
343 result = (apic_start - apic) * 1000L * tsc_khz /
344 (tsc - tsc_start);
345 }
346
347 local_irq_enable();
348
349 printk(KERN_DEBUG "APIC timer calibration result %d\n", result);
350
351 printk(KERN_INFO "Detected %d.%03d MHz APIC timer.\n",
352 result / 1000 / 1000, result / 1000 % 1000);
353
354 /* Calculate the scaled math multiplication factor */
355 lapic_clockevent.mult = div_sc(result, NSEC_PER_SEC, 32);
356 lapic_clockevent.max_delta_ns =
357 clockevent_delta2ns(0x7FFFFF, &lapic_clockevent);
358 lapic_clockevent.min_delta_ns =
359 clockevent_delta2ns(0xF, &lapic_clockevent);
360
361 calibration_result = result / HZ;
136} 362}
137 363
138unsigned int safe_apic_wait_icr_idle(void) 364/*
365 * Setup the boot APIC
366 *
367 * Calibrate and verify the result.
368 */
369void __init setup_boot_APIC_clock(void)
139{ 370{
140 unsigned int send_status; 371 /*
141 int timeout; 372 * The local apic timer can be disabled via the kernel commandline.
373 * Register the lapic timer as a dummy clock event source on SMP
374 * systems, so the broadcast mechanism is used. On UP systems simply
375 * ignore it.
376 */
377 if (disable_apic_timer) {
378 printk(KERN_INFO "Disabling APIC timer\n");
379 /* No broadcast on UP ! */
380 if (num_possible_cpus() > 1) {
381 lapic_clockevent.mult = 1;
382 setup_APIC_timer();
383 }
384 return;
385 }
142 386
143 timeout = 0; 387 printk(KERN_INFO "Using local APIC timer interrupts.\n");
144 do { 388 calibrate_APIC_clock();
145 send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY;
146 if (!send_status)
147 break;
148 udelay(100);
149 } while (timeout++ < 1000);
150 389
151 return send_status; 390 /*
391 * Do a sanity check on the APIC calibration result
392 */
393 if (calibration_result < (1000000 / HZ)) {
394 printk(KERN_WARNING
395 "APIC frequency too slow, disabling apic timer\n");
396 /* No broadcast on UP ! */
397 if (num_possible_cpus() > 1)
398 setup_APIC_timer();
399 return;
400 }
401
402 /*
403 * If nmi_watchdog is set to IO_APIC, we need the
404 * PIT/HPET going. Otherwise register lapic as a dummy
405 * device.
406 */
407 if (nmi_watchdog != NMI_IO_APIC)
408 lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY;
409 else
410 printk(KERN_WARNING "APIC timer registered as dummy,"
411 " due to nmi_watchdog=1!\n");
412
413 setup_APIC_timer();
152} 414}
153 415
154void enable_NMI_through_LVT0 (void * dummy) 416/*
417 * AMD C1E enabled CPUs have a real nasty problem: Some BIOSes set the
418 * C1E flag only in the secondary CPU, so when we detect the wreckage
419 * we already have enabled the boot CPU local apic timer. Check, if
420 * disable_apic_timer is set and the DUMMY flag is cleared. If yes,
421 * set the DUMMY flag again and force the broadcast mode in the
422 * clockevents layer.
423 */
424void __cpuinit check_boot_apic_timer_broadcast(void)
155{ 425{
156 unsigned int v; 426 if (!disable_apic_timer ||
427 (lapic_clockevent.features & CLOCK_EVT_FEAT_DUMMY))
428 return;
157 429
158 /* unmask and set to NMI */ 430 printk(KERN_INFO "AMD C1E detected late. Force timer broadcast.\n");
159 v = APIC_DM_NMI; 431 lapic_clockevent.features |= CLOCK_EVT_FEAT_DUMMY;
160 apic_write(APIC_LVT0, v); 432
433 local_irq_enable();
434 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_FORCE, &boot_cpu_id);
435 local_irq_disable();
161} 436}
162 437
163int get_maxlvt(void) 438void __cpuinit setup_secondary_APIC_clock(void)
164{ 439{
165 unsigned int v, maxlvt; 440 check_boot_apic_timer_broadcast();
441 setup_APIC_timer();
442}
166 443
167 v = apic_read(APIC_LVR); 444/*
168 maxlvt = GET_APIC_MAXLVT(v); 445 * The guts of the apic timer interrupt
169 return maxlvt; 446 */
447static void local_apic_timer_interrupt(void)
448{
449 int cpu = smp_processor_id();
450 struct clock_event_device *evt = &per_cpu(lapic_events, cpu);
451
452 /*
453 * Normally we should not be here till LAPIC has been initialized but
454 * in some cases like kdump, its possible that there is a pending LAPIC
455 * timer interrupt from previous kernel's context and is delivered in
456 * new kernel the moment interrupts are enabled.
457 *
458 * Interrupts are enabled early and LAPIC is setup much later, hence
459 * its possible that when we get here evt->event_handler is NULL.
460 * Check for event_handler being NULL and discard the interrupt as
461 * spurious.
462 */
463 if (!evt->event_handler) {
464 printk(KERN_WARNING
465 "Spurious LAPIC timer interrupt on cpu %d\n", cpu);
466 /* Switch it off */
467 lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, evt);
468 return;
469 }
470
471 /*
472 * the NMI deadlock-detector uses this.
473 */
474 add_pda(apic_timer_irqs, 1);
475
476 evt->event_handler(evt);
170} 477}
171 478
172/* 479/*
173 * 'what should we do if we get a hw irq event on an illegal vector'. 480 * Local APIC timer interrupt. This is the most natural way for doing
174 * each architecture has to answer this themselves. 481 * local interrupts, but local timer interrupts can be emulated by
482 * broadcast interrupts too. [in case the hw doesn't support APIC timers]
483 *
484 * [ if a single-CPU system runs an SMP kernel then we call the local
485 * interrupt as well. Thus we cannot inline the local irq ... ]
175 */ 486 */
176void ack_bad_irq(unsigned int irq) 487void smp_apic_timer_interrupt(struct pt_regs *regs)
177{ 488{
178 printk("unexpected IRQ trap at vector %02x\n", irq); 489 struct pt_regs *old_regs = set_irq_regs(regs);
490
179 /* 491 /*
180 * Currently unexpected vectors happen only on SMP and APIC. 492 * NOTE! We'd better ACK the irq immediately,
181 * We _must_ ack these because every local APIC has only N 493 * because timer handling can be slow.
182 * irq slots per priority level, and a 'hanging, unacked' IRQ
183 * holds up an irq slot - in excessive cases (when multiple
184 * unexpected vectors occur) that might lock up the APIC
185 * completely.
186 * But don't ack when the APIC is disabled. -AK
187 */ 494 */
188 if (!disable_apic) 495 ack_APIC_irq();
189 ack_APIC_irq(); 496 /*
497 * update_process_times() expects us to have done irq_enter().
498 * Besides, if we don't timer interrupts ignore the global
499 * interrupt lock, which is the WrongThing (tm) to do.
500 */
501 exit_idle();
502 irq_enter();
503 local_apic_timer_interrupt();
504 irq_exit();
505 set_irq_regs(old_regs);
506}
507
508int setup_profiling_timer(unsigned int multiplier)
509{
510 return -EINVAL;
190} 511}
191 512
513
514/*
515 * Local APIC start and shutdown
516 */
517
518/**
519 * clear_local_APIC - shutdown the local APIC
520 *
521 * This is called, when a CPU is disabled and before rebooting, so the state of
522 * the local APIC has no dangling leftovers. Also used to cleanout any BIOS
523 * leftovers during boot.
524 */
192void clear_local_APIC(void) 525void clear_local_APIC(void)
193{ 526{
194 int maxlvt; 527 int maxlvt = lapic_get_maxlvt();
195 unsigned int v; 528 u32 v;
196 529
197 maxlvt = get_maxlvt(); 530 /* APIC hasn't been mapped yet */
531 if (!apic_phys)
532 return;
198 533
534 maxlvt = lapic_get_maxlvt();
199 /* 535 /*
200 * Masking an LVT entry can trigger a local APIC error 536 * Masking an LVT entry can trigger a local APIC error
201 * if the vector is zero. Mask LVTERR first to prevent this. 537 * if the vector is zero. Mask LVTERR first to prevent this.
@@ -233,45 +569,9 @@ void clear_local_APIC(void)
233 apic_read(APIC_ESR); 569 apic_read(APIC_ESR);
234} 570}
235 571
236void disconnect_bsp_APIC(int virt_wire_setup) 572/**
237{ 573 * disable_local_APIC - clear and disable the local APIC
238 /* Go back to Virtual Wire compatibility mode */ 574 */
239 unsigned long value;
240
241 /* For the spurious interrupt use vector F, and enable it */
242 value = apic_read(APIC_SPIV);
243 value &= ~APIC_VECTOR_MASK;
244 value |= APIC_SPIV_APIC_ENABLED;
245 value |= 0xf;
246 apic_write(APIC_SPIV, value);
247
248 if (!virt_wire_setup) {
249 /*
250 * For LVT0 make it edge triggered, active high,
251 * external and enabled
252 */
253 value = apic_read(APIC_LVT0);
254 value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING |
255 APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR |
256 APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED );
257 value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
258 value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT);
259 apic_write(APIC_LVT0, value);
260 } else {
261 /* Disable LVT0 */
262 apic_write(APIC_LVT0, APIC_LVT_MASKED);
263 }
264
265 /* For LVT1 make it edge triggered, active high, nmi and enabled */
266 value = apic_read(APIC_LVT1);
267 value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING |
268 APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR |
269 APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED);
270 value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
271 value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI);
272 apic_write(APIC_LVT1, value);
273}
274
275void disable_local_APIC(void) 575void disable_local_APIC(void)
276{ 576{
277 unsigned int value; 577 unsigned int value;
@@ -333,7 +633,7 @@ int __init verify_local_APIC(void)
333 reg1 = GET_APIC_VERSION(reg0); 633 reg1 = GET_APIC_VERSION(reg0);
334 if (reg1 == 0x00 || reg1 == 0xff) 634 if (reg1 == 0x00 || reg1 == 0xff)
335 return 0; 635 return 0;
336 reg1 = get_maxlvt(); 636 reg1 = lapic_get_maxlvt();
337 if (reg1 < 0x02 || reg1 == 0xff) 637 if (reg1 < 0x02 || reg1 == 0xff)
338 return 0; 638 return 0;
339 639
@@ -355,18 +655,20 @@ int __init verify_local_APIC(void)
355 * compatibility mode, but most boxes are anymore. 655 * compatibility mode, but most boxes are anymore.
356 */ 656 */
357 reg0 = apic_read(APIC_LVT0); 657 reg0 = apic_read(APIC_LVT0);
358 apic_printk(APIC_DEBUG,"Getting LVT0: %x\n", reg0); 658 apic_printk(APIC_DEBUG, "Getting LVT0: %x\n", reg0);
359 reg1 = apic_read(APIC_LVT1); 659 reg1 = apic_read(APIC_LVT1);
360 apic_printk(APIC_DEBUG, "Getting LVT1: %x\n", reg1); 660 apic_printk(APIC_DEBUG, "Getting LVT1: %x\n", reg1);
361 661
362 return 1; 662 return 1;
363} 663}
364 664
665/**
666 * sync_Arb_IDs - synchronize APIC bus arbitration IDs
667 */
365void __init sync_Arb_IDs(void) 668void __init sync_Arb_IDs(void)
366{ 669{
367 /* Unsupported on P4 - see Intel Dev. Manual Vol. 3, Ch. 8.6.1 */ 670 /* Unsupported on P4 - see Intel Dev. Manual Vol. 3, Ch. 8.6.1 */
368 unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR)); 671 if (modern_apic())
369 if (ver >= 0x14) /* P4 or higher */
370 return; 672 return;
371 673
372 /* 674 /*
@@ -418,9 +720,12 @@ void __init init_bsp_APIC(void)
418 apic_write(APIC_LVT1, value); 720 apic_write(APIC_LVT1, value);
419} 721}
420 722
421void __cpuinit setup_local_APIC (void) 723/**
724 * setup_local_APIC - setup the local APIC
725 */
726void __cpuinit setup_local_APIC(void)
422{ 727{
423 unsigned int value, maxlvt; 728 unsigned int value;
424 int i, j; 729 int i, j;
425 730
426 value = apic_read(APIC_LVR); 731 value = apic_read(APIC_LVR);
@@ -516,30 +821,217 @@ void __cpuinit setup_local_APIC (void)
516 else 821 else
517 value = APIC_DM_NMI | APIC_LVT_MASKED; 822 value = APIC_DM_NMI | APIC_LVT_MASKED;
518 apic_write(APIC_LVT1, value); 823 apic_write(APIC_LVT1, value);
824}
519 825
520 { 826void __cpuinit lapic_setup_esr(void)
521 unsigned oldvalue; 827{
522 maxlvt = get_maxlvt(); 828 unsigned maxlvt = lapic_get_maxlvt();
523 oldvalue = apic_read(APIC_ESR); 829
524 value = ERROR_APIC_VECTOR; // enables sending errors 830 apic_write(APIC_LVTERR, ERROR_APIC_VECTOR);
525 apic_write(APIC_LVTERR, value); 831 /*
526 /* 832 * spec says clear errors after enabling vector.
527 * spec says clear errors after enabling vector. 833 */
528 */ 834 if (maxlvt > 3)
529 if (maxlvt > 3) 835 apic_write(APIC_ESR, 0);
530 apic_write(APIC_ESR, 0); 836}
531 value = apic_read(APIC_ESR);
532 if (value != oldvalue)
533 apic_printk(APIC_VERBOSE,
534 "ESR value after enabling vector: %08x, after %08x\n",
535 oldvalue, value);
536 }
537 837
838void __cpuinit end_local_APIC_setup(void)
839{
840 lapic_setup_esr();
538 nmi_watchdog_default(); 841 nmi_watchdog_default();
539 setup_apic_nmi_watchdog(NULL); 842 setup_apic_nmi_watchdog(NULL);
540 apic_pm_activate(); 843 apic_pm_activate();
541} 844}
542 845
846/*
847 * Detect and enable local APICs on non-SMP boards.
848 * Original code written by Keir Fraser.
849 * On AMD64 we trust the BIOS - if it says no APIC it is likely
850 * not correctly set up (usually the APIC timer won't work etc.)
851 */
852static int __init detect_init_APIC(void)
853{
854 if (!cpu_has_apic) {
855 printk(KERN_INFO "No local APIC present\n");
856 return -1;
857 }
858
859 mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
860 boot_cpu_id = 0;
861 return 0;
862}
863
864/**
865 * init_apic_mappings - initialize APIC mappings
866 */
867void __init init_apic_mappings(void)
868{
869 /*
870 * If no local APIC can be found then set up a fake all
871 * zeroes page to simulate the local APIC and another
872 * one for the IO-APIC.
873 */
874 if (!smp_found_config && detect_init_APIC()) {
875 apic_phys = (unsigned long) alloc_bootmem_pages(PAGE_SIZE);
876 apic_phys = __pa(apic_phys);
877 } else
878 apic_phys = mp_lapic_addr;
879
880 set_fixmap_nocache(FIX_APIC_BASE, apic_phys);
881 apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n",
882 APIC_BASE, apic_phys);
883
884 /* Put local APIC into the resource map. */
885 lapic_resource.start = apic_phys;
886 lapic_resource.end = lapic_resource.start + PAGE_SIZE - 1;
887 insert_resource(&iomem_resource, &lapic_resource);
888
889 /*
890 * Fetch the APIC ID of the BSP in case we have a
891 * default configuration (or the MP table is broken).
892 */
893 boot_cpu_id = GET_APIC_ID(apic_read(APIC_ID));
894}
895
896/*
897 * This initializes the IO-APIC and APIC hardware if this is
898 * a UP kernel.
899 */
900int __init APIC_init_uniprocessor(void)
901{
902 if (disable_apic) {
903 printk(KERN_INFO "Apic disabled\n");
904 return -1;
905 }
906 if (!cpu_has_apic) {
907 disable_apic = 1;
908 printk(KERN_INFO "Apic disabled by BIOS\n");
909 return -1;
910 }
911
912 verify_local_APIC();
913
914 phys_cpu_present_map = physid_mask_of_physid(boot_cpu_id);
915 apic_write(APIC_ID, SET_APIC_ID(boot_cpu_id));
916
917 setup_local_APIC();
918
919 /*
920 * Now enable IO-APICs, actually call clear_IO_APIC
921 * We need clear_IO_APIC before enabling vector on BP
922 */
923 if (!skip_ioapic_setup && nr_ioapics)
924 enable_IO_APIC();
925
926 end_local_APIC_setup();
927
928 if (smp_found_config && !skip_ioapic_setup && nr_ioapics)
929 setup_IO_APIC();
930 else
931 nr_ioapics = 0;
932 setup_boot_APIC_clock();
933 check_nmi_watchdog();
934 return 0;
935}
936
937/*
938 * Local APIC interrupts
939 */
940
941/*
942 * This interrupt should _never_ happen with our APIC/SMP architecture
943 */
944asmlinkage void smp_spurious_interrupt(void)
945{
946 unsigned int v;
947 exit_idle();
948 irq_enter();
949 /*
950 * Check if this really is a spurious interrupt and ACK it
951 * if it is a vectored one. Just in case...
952 * Spurious interrupts should not be ACKed.
953 */
954 v = apic_read(APIC_ISR + ((SPURIOUS_APIC_VECTOR & ~0x1f) >> 1));
955 if (v & (1 << (SPURIOUS_APIC_VECTOR & 0x1f)))
956 ack_APIC_irq();
957
958 add_pda(irq_spurious_count, 1);
959 irq_exit();
960}
961
962/*
963 * This interrupt should never happen with our APIC/SMP architecture
964 */
965asmlinkage void smp_error_interrupt(void)
966{
967 unsigned int v, v1;
968
969 exit_idle();
970 irq_enter();
971 /* First tickle the hardware, only then report what went on. -- REW */
972 v = apic_read(APIC_ESR);
973 apic_write(APIC_ESR, 0);
974 v1 = apic_read(APIC_ESR);
975 ack_APIC_irq();
976 atomic_inc(&irq_err_count);
977
978 /* Here is what the APIC error bits mean:
979 0: Send CS error
980 1: Receive CS error
981 2: Send accept error
982 3: Receive accept error
983 4: Reserved
984 5: Send illegal vector
985 6: Received illegal vector
986 7: Illegal register address
987 */
988 printk(KERN_DEBUG "APIC error on CPU%d: %02x(%02x)\n",
989 smp_processor_id(), v , v1);
990 irq_exit();
991}
992
993void disconnect_bsp_APIC(int virt_wire_setup)
994{
995 /* Go back to Virtual Wire compatibility mode */
996 unsigned long value;
997
998 /* For the spurious interrupt use vector F, and enable it */
999 value = apic_read(APIC_SPIV);
1000 value &= ~APIC_VECTOR_MASK;
1001 value |= APIC_SPIV_APIC_ENABLED;
1002 value |= 0xf;
1003 apic_write(APIC_SPIV, value);
1004
1005 if (!virt_wire_setup) {
1006 /*
1007 * For LVT0 make it edge triggered, active high,
1008 * external and enabled
1009 */
1010 value = apic_read(APIC_LVT0);
1011 value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING |
1012 APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR |
1013 APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED);
1014 value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
1015 value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT);
1016 apic_write(APIC_LVT0, value);
1017 } else {
1018 /* Disable LVT0 */
1019 apic_write(APIC_LVT0, APIC_LVT_MASKED);
1020 }
1021
1022 /* For LVT1 make it edge triggered, active high, nmi and enabled */
1023 value = apic_read(APIC_LVT1);
1024 value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING |
1025 APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR |
1026 APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED);
1027 value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
1028 value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI);
1029 apic_write(APIC_LVT1, value);
1030}
1031
1032/*
1033 * Power management
1034 */
543#ifdef CONFIG_PM 1035#ifdef CONFIG_PM
544 1036
545static struct { 1037static struct {
@@ -571,7 +1063,7 @@ static int lapic_suspend(struct sys_device *dev, pm_message_t state)
571 if (!apic_pm_state.active) 1063 if (!apic_pm_state.active)
572 return 0; 1064 return 0;
573 1065
574 maxlvt = get_maxlvt(); 1066 maxlvt = lapic_get_maxlvt();
575 1067
576 apic_pm_state.apic_id = apic_read(APIC_ID); 1068 apic_pm_state.apic_id = apic_read(APIC_ID);
577 apic_pm_state.apic_taskpri = apic_read(APIC_TASKPRI); 1069 apic_pm_state.apic_taskpri = apic_read(APIC_TASKPRI);
@@ -605,7 +1097,7 @@ static int lapic_resume(struct sys_device *dev)
605 if (!apic_pm_state.active) 1097 if (!apic_pm_state.active)
606 return 0; 1098 return 0;
607 1099
608 maxlvt = get_maxlvt(); 1100 maxlvt = lapic_get_maxlvt();
609 1101
610 local_irq_save(flags); 1102 local_irq_save(flags);
611 rdmsr(MSR_IA32_APICBASE, l, h); 1103 rdmsr(MSR_IA32_APICBASE, l, h);
@@ -639,14 +1131,14 @@ static int lapic_resume(struct sys_device *dev)
639} 1131}
640 1132
641static struct sysdev_class lapic_sysclass = { 1133static struct sysdev_class lapic_sysclass = {
642 set_kset_name("lapic"), 1134 .name = "lapic",
643 .resume = lapic_resume, 1135 .resume = lapic_resume,
644 .suspend = lapic_suspend, 1136 .suspend = lapic_suspend,
645}; 1137};
646 1138
647static struct sys_device device_lapic = { 1139static struct sys_device device_lapic = {
648 .id = 0, 1140 .id = 0,
649 .cls = &lapic_sysclass, 1141 .cls = &lapic_sysclass,
650}; 1142};
651 1143
652static void __cpuinit apic_pm_activate(void) 1144static void __cpuinit apic_pm_activate(void)
@@ -657,9 +1149,11 @@ static void __cpuinit apic_pm_activate(void)
657static int __init init_lapic_sysfs(void) 1149static int __init init_lapic_sysfs(void)
658{ 1150{
659 int error; 1151 int error;
1152
660 if (!cpu_has_apic) 1153 if (!cpu_has_apic)
661 return 0; 1154 return 0;
662 /* XXX: remove suspend/resume procs if !apic_pm_state.active? */ 1155 /* XXX: remove suspend/resume procs if !apic_pm_state.active? */
1156
663 error = sysdev_class_register(&lapic_sysclass); 1157 error = sysdev_class_register(&lapic_sysclass);
664 if (!error) 1158 if (!error)
665 error = sysdev_register(&device_lapic); 1159 error = sysdev_register(&device_lapic);
@@ -673,423 +1167,6 @@ static void apic_pm_activate(void) { }
673 1167
674#endif /* CONFIG_PM */ 1168#endif /* CONFIG_PM */
675 1169
676static int __init apic_set_verbosity(char *str)
677{
678 if (str == NULL) {
679 skip_ioapic_setup = 0;
680 ioapic_force = 1;
681 return 0;
682 }
683 if (strcmp("debug", str) == 0)
684 apic_verbosity = APIC_DEBUG;
685 else if (strcmp("verbose", str) == 0)
686 apic_verbosity = APIC_VERBOSE;
687 else {
688 printk(KERN_WARNING "APIC Verbosity level %s not recognised"
689 " use apic=verbose or apic=debug\n", str);
690 return -EINVAL;
691 }
692
693 return 0;
694}
695early_param("apic", apic_set_verbosity);
696
697/*
698 * Detect and enable local APICs on non-SMP boards.
699 * Original code written by Keir Fraser.
700 * On AMD64 we trust the BIOS - if it says no APIC it is likely
701 * not correctly set up (usually the APIC timer won't work etc.)
702 */
703
704static int __init detect_init_APIC (void)
705{
706 if (!cpu_has_apic) {
707 printk(KERN_INFO "No local APIC present\n");
708 return -1;
709 }
710
711 mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
712 boot_cpu_id = 0;
713 return 0;
714}
715
716#ifdef CONFIG_X86_IO_APIC
717static struct resource * __init ioapic_setup_resources(void)
718{
719#define IOAPIC_RESOURCE_NAME_SIZE 11
720 unsigned long n;
721 struct resource *res;
722 char *mem;
723 int i;
724
725 if (nr_ioapics <= 0)
726 return NULL;
727
728 n = IOAPIC_RESOURCE_NAME_SIZE + sizeof(struct resource);
729 n *= nr_ioapics;
730
731 mem = alloc_bootmem(n);
732 res = (void *)mem;
733
734 if (mem != NULL) {
735 memset(mem, 0, n);
736 mem += sizeof(struct resource) * nr_ioapics;
737
738 for (i = 0; i < nr_ioapics; i++) {
739 res[i].name = mem;
740 res[i].flags = IORESOURCE_MEM | IORESOURCE_BUSY;
741 sprintf(mem, "IOAPIC %u", i);
742 mem += IOAPIC_RESOURCE_NAME_SIZE;
743 }
744 }
745
746 ioapic_resources = res;
747
748 return res;
749}
750
751static int __init ioapic_insert_resources(void)
752{
753 int i;
754 struct resource *r = ioapic_resources;
755
756 if (!r) {
757 printk("IO APIC resources could be not be allocated.\n");
758 return -1;
759 }
760
761 for (i = 0; i < nr_ioapics; i++) {
762 insert_resource(&iomem_resource, r);
763 r++;
764 }
765
766 return 0;
767}
768
769/* Insert the IO APIC resources after PCI initialization has occured to handle
770 * IO APICS that are mapped in on a BAR in PCI space. */
771late_initcall(ioapic_insert_resources);
772#endif
773
774void __init init_apic_mappings(void)
775{
776 unsigned long apic_phys;
777
778 /*
779 * If no local APIC can be found then set up a fake all
780 * zeroes page to simulate the local APIC and another
781 * one for the IO-APIC.
782 */
783 if (!smp_found_config && detect_init_APIC()) {
784 apic_phys = (unsigned long) alloc_bootmem_pages(PAGE_SIZE);
785 apic_phys = __pa(apic_phys);
786 } else
787 apic_phys = mp_lapic_addr;
788
789 set_fixmap_nocache(FIX_APIC_BASE, apic_phys);
790 apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n",
791 APIC_BASE, apic_phys);
792
793 /* Put local APIC into the resource map. */
794 lapic_resource.start = apic_phys;
795 lapic_resource.end = lapic_resource.start + PAGE_SIZE - 1;
796 insert_resource(&iomem_resource, &lapic_resource);
797
798 /*
799 * Fetch the APIC ID of the BSP in case we have a
800 * default configuration (or the MP table is broken).
801 */
802 boot_cpu_id = GET_APIC_ID(apic_read(APIC_ID));
803
804 {
805 unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0;
806 int i;
807 struct resource *ioapic_res;
808
809 ioapic_res = ioapic_setup_resources();
810 for (i = 0; i < nr_ioapics; i++) {
811 if (smp_found_config) {
812 ioapic_phys = mp_ioapics[i].mpc_apicaddr;
813 } else {
814 ioapic_phys = (unsigned long)
815 alloc_bootmem_pages(PAGE_SIZE);
816 ioapic_phys = __pa(ioapic_phys);
817 }
818 set_fixmap_nocache(idx, ioapic_phys);
819 apic_printk(APIC_VERBOSE,
820 "mapped IOAPIC to %016lx (%016lx)\n",
821 __fix_to_virt(idx), ioapic_phys);
822 idx++;
823
824 if (ioapic_res != NULL) {
825 ioapic_res->start = ioapic_phys;
826 ioapic_res->end = ioapic_phys + (4 * 1024) - 1;
827 ioapic_res++;
828 }
829 }
830 }
831}
832
833/*
834 * This function sets up the local APIC timer, with a timeout of
835 * 'clocks' APIC bus clock. During calibration we actually call
836 * this function twice on the boot CPU, once with a bogus timeout
837 * value, second time for real. The other (noncalibrating) CPUs
838 * call this function only once, with the real, calibrated value.
839 *
840 * We do reads before writes even if unnecessary, to get around the
841 * P5 APIC double write bug.
842 */
843
844static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen)
845{
846 unsigned int lvtt_value, tmp_value;
847
848 lvtt_value = LOCAL_TIMER_VECTOR;
849 if (!oneshot)
850 lvtt_value |= APIC_LVT_TIMER_PERIODIC;
851 if (!irqen)
852 lvtt_value |= APIC_LVT_MASKED;
853
854 apic_write(APIC_LVTT, lvtt_value);
855
856 /*
857 * Divide PICLK by 16
858 */
859 tmp_value = apic_read(APIC_TDCR);
860 apic_write(APIC_TDCR, (tmp_value
861 & ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE))
862 | APIC_TDR_DIV_16);
863
864 if (!oneshot)
865 apic_write(APIC_TMICT, clocks);
866}
867
868static void setup_APIC_timer(void)
869{
870 struct clock_event_device *levt = &__get_cpu_var(lapic_events);
871
872 memcpy(levt, &lapic_clockevent, sizeof(*levt));
873 levt->cpumask = cpumask_of_cpu(smp_processor_id());
874
875 clockevents_register_device(levt);
876}
877
878/*
879 * In this function we calibrate APIC bus clocks to the external
880 * timer. Unfortunately we cannot use jiffies and the timer irq
881 * to calibrate, since some later bootup code depends on getting
882 * the first irq? Ugh.
883 *
884 * We want to do the calibration only once since we
885 * want to have local timer irqs syncron. CPUs connected
886 * by the same APIC bus have the very same bus frequency.
887 * And we want to have irqs off anyways, no accidental
888 * APIC irq that way.
889 */
890
891#define TICK_COUNT 100000000
892
893static void __init calibrate_APIC_clock(void)
894{
895 unsigned apic, apic_start;
896 unsigned long tsc, tsc_start;
897 int result;
898
899 local_irq_disable();
900
901 /*
902 * Put whatever arbitrary (but long enough) timeout
903 * value into the APIC clock, we just want to get the
904 * counter running for calibration.
905 *
906 * No interrupt enable !
907 */
908 __setup_APIC_LVTT(250000000, 0, 0);
909
910 apic_start = apic_read(APIC_TMCCT);
911#ifdef CONFIG_X86_PM_TIMER
912 if (apic_calibrate_pmtmr && pmtmr_ioport) {
913 pmtimer_wait(5000); /* 5ms wait */
914 apic = apic_read(APIC_TMCCT);
915 result = (apic_start - apic) * 1000L / 5;
916 } else
917#endif
918 {
919 rdtscll(tsc_start);
920
921 do {
922 apic = apic_read(APIC_TMCCT);
923 rdtscll(tsc);
924 } while ((tsc - tsc_start) < TICK_COUNT &&
925 (apic_start - apic) < TICK_COUNT);
926
927 result = (apic_start - apic) * 1000L * tsc_khz /
928 (tsc - tsc_start);
929 }
930
931 local_irq_enable();
932
933 printk(KERN_DEBUG "APIC timer calibration result %d\n", result);
934
935 printk(KERN_INFO "Detected %d.%03d MHz APIC timer.\n",
936 result / 1000 / 1000, result / 1000 % 1000);
937
938 /* Calculate the scaled math multiplication factor */
939 lapic_clockevent.mult = div_sc(result, NSEC_PER_SEC, 32);
940 lapic_clockevent.max_delta_ns =
941 clockevent_delta2ns(0x7FFFFF, &lapic_clockevent);
942 lapic_clockevent.min_delta_ns =
943 clockevent_delta2ns(0xF, &lapic_clockevent);
944
945 calibration_result = result / HZ;
946}
947
948void __init setup_boot_APIC_clock (void)
949{
950 /*
951 * The local apic timer can be disabled via the kernel commandline.
952 * Register the lapic timer as a dummy clock event source on SMP
953 * systems, so the broadcast mechanism is used. On UP systems simply
954 * ignore it.
955 */
956 if (disable_apic_timer) {
957 printk(KERN_INFO "Disabling APIC timer\n");
958 /* No broadcast on UP ! */
959 if (num_possible_cpus() > 1)
960 setup_APIC_timer();
961 return;
962 }
963
964 printk(KERN_INFO "Using local APIC timer interrupts.\n");
965 calibrate_APIC_clock();
966
967 /*
968 * If nmi_watchdog is set to IO_APIC, we need the
969 * PIT/HPET going. Otherwise register lapic as a dummy
970 * device.
971 */
972 if (nmi_watchdog != NMI_IO_APIC)
973 lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY;
974 else
975 printk(KERN_WARNING "APIC timer registered as dummy,"
976 " due to nmi_watchdog=1!\n");
977
978 setup_APIC_timer();
979}
980
981/*
982 * AMD C1E enabled CPUs have a real nasty problem: Some BIOSes set the
983 * C1E flag only in the secondary CPU, so when we detect the wreckage
984 * we already have enabled the boot CPU local apic timer. Check, if
985 * disable_apic_timer is set and the DUMMY flag is cleared. If yes,
986 * set the DUMMY flag again and force the broadcast mode in the
987 * clockevents layer.
988 */
989void __cpuinit check_boot_apic_timer_broadcast(void)
990{
991 if (!disable_apic_timer ||
992 (lapic_clockevent.features & CLOCK_EVT_FEAT_DUMMY))
993 return;
994
995 printk(KERN_INFO "AMD C1E detected late. Force timer broadcast.\n");
996 lapic_clockevent.features |= CLOCK_EVT_FEAT_DUMMY;
997
998 local_irq_enable();
999 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_FORCE, &boot_cpu_id);
1000 local_irq_disable();
1001}
1002
1003void __cpuinit setup_secondary_APIC_clock(void)
1004{
1005 check_boot_apic_timer_broadcast();
1006 setup_APIC_timer();
1007}
1008
1009int setup_profiling_timer(unsigned int multiplier)
1010{
1011 return -EINVAL;
1012}
1013
1014void setup_APIC_extended_lvt(unsigned char lvt_off, unsigned char vector,
1015 unsigned char msg_type, unsigned char mask)
1016{
1017 unsigned long reg = (lvt_off << 4) + K8_APIC_EXT_LVT_BASE;
1018 unsigned int v = (mask << 16) | (msg_type << 8) | vector;
1019 apic_write(reg, v);
1020}
1021
1022/*
1023 * Local timer interrupt handler. It does both profiling and
1024 * process statistics/rescheduling.
1025 *
1026 * We do profiling in every local tick, statistics/rescheduling
1027 * happen only every 'profiling multiplier' ticks. The default
1028 * multiplier is 1 and it can be changed by writing the new multiplier
1029 * value into /proc/profile.
1030 */
1031
1032void smp_local_timer_interrupt(void)
1033{
1034 int cpu = smp_processor_id();
1035 struct clock_event_device *evt = &per_cpu(lapic_events, cpu);
1036
1037 /*
1038 * Normally we should not be here till LAPIC has been initialized but
1039 * in some cases like kdump, its possible that there is a pending LAPIC
1040 * timer interrupt from previous kernel's context and is delivered in
1041 * new kernel the moment interrupts are enabled.
1042 *
1043 * Interrupts are enabled early and LAPIC is setup much later, hence
1044 * its possible that when we get here evt->event_handler is NULL.
1045 * Check for event_handler being NULL and discard the interrupt as
1046 * spurious.
1047 */
1048 if (!evt->event_handler) {
1049 printk(KERN_WARNING
1050 "Spurious LAPIC timer interrupt on cpu %d\n", cpu);
1051 /* Switch it off */
1052 lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, evt);
1053 return;
1054 }
1055
1056 /*
1057 * the NMI deadlock-detector uses this.
1058 */
1059 add_pda(apic_timer_irqs, 1);
1060
1061 evt->event_handler(evt);
1062}
1063
1064/*
1065 * Local APIC timer interrupt. This is the most natural way for doing
1066 * local interrupts, but local timer interrupts can be emulated by
1067 * broadcast interrupts too. [in case the hw doesn't support APIC timers]
1068 *
1069 * [ if a single-CPU system runs an SMP kernel then we call the local
1070 * interrupt as well. Thus we cannot inline the local irq ... ]
1071 */
1072void smp_apic_timer_interrupt(struct pt_regs *regs)
1073{
1074 struct pt_regs *old_regs = set_irq_regs(regs);
1075
1076 /*
1077 * NOTE! We'd better ACK the irq immediately,
1078 * because timer handling can be slow.
1079 */
1080 ack_APIC_irq();
1081 /*
1082 * update_process_times() expects us to have done irq_enter().
1083 * Besides, if we don't timer interrupts ignore the global
1084 * interrupt lock, which is the WrongThing (tm) to do.
1085 */
1086 exit_idle();
1087 irq_enter();
1088 smp_local_timer_interrupt();
1089 irq_exit();
1090 set_irq_regs(old_regs);
1091}
1092
1093/* 1170/*
1094 * apic_is_clustered_box() -- Check if we can expect good TSC 1171 * apic_is_clustered_box() -- Check if we can expect good TSC
1095 * 1172 *
@@ -1103,21 +1180,34 @@ __cpuinit int apic_is_clustered_box(void)
1103{ 1180{
1104 int i, clusters, zeros; 1181 int i, clusters, zeros;
1105 unsigned id; 1182 unsigned id;
1183 u16 *bios_cpu_apicid = x86_bios_cpu_apicid_early_ptr;
1106 DECLARE_BITMAP(clustermap, NUM_APIC_CLUSTERS); 1184 DECLARE_BITMAP(clustermap, NUM_APIC_CLUSTERS);
1107 1185
1108 bitmap_zero(clustermap, NUM_APIC_CLUSTERS); 1186 bitmap_zero(clustermap, NUM_APIC_CLUSTERS);
1109 1187
1110 for (i = 0; i < NR_CPUS; i++) { 1188 for (i = 0; i < NR_CPUS; i++) {
1111 id = bios_cpu_apicid[i]; 1189 /* are we being called early in kernel startup? */
1190 if (bios_cpu_apicid) {
1191 id = bios_cpu_apicid[i];
1192 }
1193 else if (i < nr_cpu_ids) {
1194 if (cpu_present(i))
1195 id = per_cpu(x86_bios_cpu_apicid, i);
1196 else
1197 continue;
1198 }
1199 else
1200 break;
1201
1112 if (id != BAD_APICID) 1202 if (id != BAD_APICID)
1113 __set_bit(APIC_CLUSTERID(id), clustermap); 1203 __set_bit(APIC_CLUSTERID(id), clustermap);
1114 } 1204 }
1115 1205
1116 /* Problem: Partially populated chassis may not have CPUs in some of 1206 /* Problem: Partially populated chassis may not have CPUs in some of
1117 * the APIC clusters they have been allocated. Only present CPUs have 1207 * the APIC clusters they have been allocated. Only present CPUs have
1118 * bios_cpu_apicid entries, thus causing zeroes in the bitmap. Since 1208 * x86_bios_cpu_apicid entries, thus causing zeroes in the bitmap.
1119 * clusters are allocated sequentially, count zeros only if they are 1209 * Since clusters are allocated sequentially, count zeros only if
1120 * bounded by ones. 1210 * they are bounded by ones.
1121 */ 1211 */
1122 clusters = 0; 1212 clusters = 0;
1123 zeros = 0; 1213 zeros = 0;
@@ -1138,96 +1228,33 @@ __cpuinit int apic_is_clustered_box(void)
1138} 1228}
1139 1229
1140/* 1230/*
1141 * This interrupt should _never_ happen with our APIC/SMP architecture 1231 * APIC command line parameters
1142 */
1143asmlinkage void smp_spurious_interrupt(void)
1144{
1145 unsigned int v;
1146 exit_idle();
1147 irq_enter();
1148 /*
1149 * Check if this really is a spurious interrupt and ACK it
1150 * if it is a vectored one. Just in case...
1151 * Spurious interrupts should not be ACKed.
1152 */
1153 v = apic_read(APIC_ISR + ((SPURIOUS_APIC_VECTOR & ~0x1f) >> 1));
1154 if (v & (1 << (SPURIOUS_APIC_VECTOR & 0x1f)))
1155 ack_APIC_irq();
1156
1157 add_pda(irq_spurious_count, 1);
1158 irq_exit();
1159}
1160
1161/*
1162 * This interrupt should never happen with our APIC/SMP architecture
1163 */ 1232 */
1164 1233static int __init apic_set_verbosity(char *str)
1165asmlinkage void smp_error_interrupt(void)
1166{
1167 unsigned int v, v1;
1168
1169 exit_idle();
1170 irq_enter();
1171 /* First tickle the hardware, only then report what went on. -- REW */
1172 v = apic_read(APIC_ESR);
1173 apic_write(APIC_ESR, 0);
1174 v1 = apic_read(APIC_ESR);
1175 ack_APIC_irq();
1176 atomic_inc(&irq_err_count);
1177
1178 /* Here is what the APIC error bits mean:
1179 0: Send CS error
1180 1: Receive CS error
1181 2: Send accept error
1182 3: Receive accept error
1183 4: Reserved
1184 5: Send illegal vector
1185 6: Received illegal vector
1186 7: Illegal register address
1187 */
1188 printk (KERN_DEBUG "APIC error on CPU%d: %02x(%02x)\n",
1189 smp_processor_id(), v , v1);
1190 irq_exit();
1191}
1192
1193int disable_apic;
1194
1195/*
1196 * This initializes the IO-APIC and APIC hardware if this is
1197 * a UP kernel.
1198 */
1199int __init APIC_init_uniprocessor (void)
1200{ 1234{
1201 if (disable_apic) { 1235 if (str == NULL) {
1202 printk(KERN_INFO "Apic disabled\n"); 1236 skip_ioapic_setup = 0;
1203 return -1; 1237 ioapic_force = 1;
1238 return 0;
1204 } 1239 }
1205 if (!cpu_has_apic) { 1240 if (strcmp("debug", str) == 0)
1206 disable_apic = 1; 1241 apic_verbosity = APIC_DEBUG;
1207 printk(KERN_INFO "Apic disabled by BIOS\n"); 1242 else if (strcmp("verbose", str) == 0)
1208 return -1; 1243 apic_verbosity = APIC_VERBOSE;
1244 else {
1245 printk(KERN_WARNING "APIC Verbosity level %s not recognised"
1246 " use apic=verbose or apic=debug\n", str);
1247 return -EINVAL;
1209 } 1248 }
1210 1249
1211 verify_local_APIC();
1212
1213 phys_cpu_present_map = physid_mask_of_physid(boot_cpu_id);
1214 apic_write(APIC_ID, SET_APIC_ID(boot_cpu_id));
1215
1216 setup_local_APIC();
1217
1218 if (smp_found_config && !skip_ioapic_setup && nr_ioapics)
1219 setup_IO_APIC();
1220 else
1221 nr_ioapics = 0;
1222 setup_boot_APIC_clock();
1223 check_nmi_watchdog();
1224 return 0; 1250 return 0;
1225} 1251}
1252early_param("apic", apic_set_verbosity);
1226 1253
1227static __init int setup_disableapic(char *str) 1254static __init int setup_disableapic(char *str)
1228{ 1255{
1229 disable_apic = 1; 1256 disable_apic = 1;
1230 clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); 1257 clear_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC);
1231 return 0; 1258 return 0;
1232} 1259}
1233early_param("disableapic", setup_disableapic); 1260early_param("disableapic", setup_disableapic);
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
index af045ca0f653..d4438ef296d8 100644
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -227,6 +227,7 @@
227#include <linux/dmi.h> 227#include <linux/dmi.h>
228#include <linux/suspend.h> 228#include <linux/suspend.h>
229#include <linux/kthread.h> 229#include <linux/kthread.h>
230#include <linux/jiffies.h>
230 231
231#include <asm/system.h> 232#include <asm/system.h>
232#include <asm/uaccess.h> 233#include <asm/uaccess.h>
@@ -235,8 +236,6 @@
235#include <asm/paravirt.h> 236#include <asm/paravirt.h>
236#include <asm/reboot.h> 237#include <asm/reboot.h>
237 238
238#include "io_ports.h"
239
240#if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT) 239#if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
241extern int (*console_blank_hook)(int); 240extern int (*console_blank_hook)(int);
242#endif 241#endif
@@ -324,7 +323,7 @@ extern int (*console_blank_hook)(int);
324/* 323/*
325 * Ignore suspend events for this amount of time after a resume 324 * Ignore suspend events for this amount of time after a resume
326 */ 325 */
327#define DEFAULT_BOUNCE_INTERVAL (3 * HZ) 326#define DEFAULT_BOUNCE_INTERVAL (3 * HZ)
328 327
329/* 328/*
330 * Maximum number of events stored 329 * Maximum number of events stored
@@ -336,7 +335,7 @@ extern int (*console_blank_hook)(int);
336 */ 335 */
337struct apm_user { 336struct apm_user {
338 int magic; 337 int magic;
339 struct apm_user * next; 338 struct apm_user *next;
340 unsigned int suser: 1; 339 unsigned int suser: 1;
341 unsigned int writer: 1; 340 unsigned int writer: 1;
342 unsigned int reader: 1; 341 unsigned int reader: 1;
@@ -372,44 +371,44 @@ struct apm_user {
372static struct { 371static struct {
373 unsigned long offset; 372 unsigned long offset;
374 unsigned short segment; 373 unsigned short segment;
375} apm_bios_entry; 374} apm_bios_entry;
376static int clock_slowed; 375static int clock_slowed;
377static int idle_threshold __read_mostly = DEFAULT_IDLE_THRESHOLD; 376static int idle_threshold __read_mostly = DEFAULT_IDLE_THRESHOLD;
378static int idle_period __read_mostly = DEFAULT_IDLE_PERIOD; 377static int idle_period __read_mostly = DEFAULT_IDLE_PERIOD;
379static int set_pm_idle; 378static int set_pm_idle;
380static int suspends_pending; 379static int suspends_pending;
381static int standbys_pending; 380static int standbys_pending;
382static int ignore_sys_suspend; 381static int ignore_sys_suspend;
383static int ignore_normal_resume; 382static int ignore_normal_resume;
384static int bounce_interval __read_mostly = DEFAULT_BOUNCE_INTERVAL; 383static int bounce_interval __read_mostly = DEFAULT_BOUNCE_INTERVAL;
385 384
386static int debug __read_mostly; 385static int debug __read_mostly;
387static int smp __read_mostly; 386static int smp __read_mostly;
388static int apm_disabled = -1; 387static int apm_disabled = -1;
389#ifdef CONFIG_SMP 388#ifdef CONFIG_SMP
390static int power_off; 389static int power_off;
391#else 390#else
392static int power_off = 1; 391static int power_off = 1;
393#endif 392#endif
394#ifdef CONFIG_APM_REAL_MODE_POWER_OFF 393#ifdef CONFIG_APM_REAL_MODE_POWER_OFF
395static int realmode_power_off = 1; 394static int realmode_power_off = 1;
396#else 395#else
397static int realmode_power_off; 396static int realmode_power_off;
398#endif 397#endif
399#ifdef CONFIG_APM_ALLOW_INTS 398#ifdef CONFIG_APM_ALLOW_INTS
400static int allow_ints = 1; 399static int allow_ints = 1;
401#else 400#else
402static int allow_ints; 401static int allow_ints;
403#endif 402#endif
404static int broken_psr; 403static int broken_psr;
405 404
406static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue); 405static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue);
407static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); 406static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
408static struct apm_user * user_list; 407static struct apm_user *user_list;
409static DEFINE_SPINLOCK(user_list_lock); 408static DEFINE_SPINLOCK(user_list_lock);
410static const struct desc_struct bad_bios_desc = { 0, 0x00409200 }; 409static const struct desc_struct bad_bios_desc = { { { 0, 0x00409200 } } };
411 410
412static const char driver_version[] = "1.16ac"; /* no spaces */ 411static const char driver_version[] = "1.16ac"; /* no spaces */
413 412
414static struct task_struct *kapmd_task; 413static struct task_struct *kapmd_task;
415 414
@@ -417,7 +416,7 @@ static struct task_struct *kapmd_task;
417 * APM event names taken from the APM 1.2 specification. These are 416 * APM event names taken from the APM 1.2 specification. These are
418 * the message codes that the BIOS uses to tell us about events 417 * the message codes that the BIOS uses to tell us about events
419 */ 418 */
420static const char * const apm_event_name[] = { 419static const char * const apm_event_name[] = {
421 "system standby", 420 "system standby",
422 "system suspend", 421 "system suspend",
423 "normal resume", 422 "normal resume",
@@ -435,14 +434,14 @@ static const char * const apm_event_name[] = {
435 434
436typedef struct lookup_t { 435typedef struct lookup_t {
437 int key; 436 int key;
438 char * msg; 437 char *msg;
439} lookup_t; 438} lookup_t;
440 439
441/* 440/*
442 * The BIOS returns a set of standard error codes in AX when the 441 * The BIOS returns a set of standard error codes in AX when the
443 * carry flag is set. 442 * carry flag is set.
444 */ 443 */
445 444
446static const lookup_t error_table[] = { 445static const lookup_t error_table[] = {
447/* N/A { APM_SUCCESS, "Operation succeeded" }, */ 446/* N/A { APM_SUCCESS, "Operation succeeded" }, */
448 { APM_DISABLED, "Power management disabled" }, 447 { APM_DISABLED, "Power management disabled" },
@@ -472,24 +471,25 @@ static const lookup_t error_table[] = {
472 * Write a meaningful log entry to the kernel log in the event of 471 * Write a meaningful log entry to the kernel log in the event of
473 * an APM error. 472 * an APM error.
474 */ 473 */
475 474
476static void apm_error(char *str, int err) 475static void apm_error(char *str, int err)
477{ 476{
478 int i; 477 int i;
479 478
480 for (i = 0; i < ERROR_COUNT; i++) 479 for (i = 0; i < ERROR_COUNT; i++)
481 if (error_table[i].key == err) break; 480 if (error_table[i].key == err)
481 break;
482 if (i < ERROR_COUNT) 482 if (i < ERROR_COUNT)
483 printk(KERN_NOTICE "apm: %s: %s\n", str, error_table[i].msg); 483 printk(KERN_NOTICE "apm: %s: %s\n", str, error_table[i].msg);
484 else 484 else
485 printk(KERN_NOTICE "apm: %s: unknown error code %#2.2x\n", 485 printk(KERN_NOTICE "apm: %s: unknown error code %#2.2x\n",
486 str, err); 486 str, err);
487} 487}
488 488
489/* 489/*
490 * Lock APM functionality to physical CPU 0 490 * Lock APM functionality to physical CPU 0
491 */ 491 */
492 492
493#ifdef CONFIG_SMP 493#ifdef CONFIG_SMP
494 494
495static cpumask_t apm_save_cpus(void) 495static cpumask_t apm_save_cpus(void)
@@ -511,7 +511,7 @@ static inline void apm_restore_cpus(cpumask_t mask)
511/* 511/*
512 * No CPU lockdown needed on a uniprocessor 512 * No CPU lockdown needed on a uniprocessor
513 */ 513 */
514 514
515#define apm_save_cpus() (current->cpus_allowed) 515#define apm_save_cpus() (current->cpus_allowed)
516#define apm_restore_cpus(x) (void)(x) 516#define apm_restore_cpus(x) (void)(x)
517 517
@@ -590,7 +590,7 @@ static inline void apm_irq_restore(unsigned long flags)
590 * code is returned in AH (bits 8-15 of eax) and this function 590 * code is returned in AH (bits 8-15 of eax) and this function
591 * returns non-zero. 591 * returns non-zero.
592 */ 592 */
593 593
594static u8 apm_bios_call(u32 func, u32 ebx_in, u32 ecx_in, 594static u8 apm_bios_call(u32 func, u32 ebx_in, u32 ecx_in,
595 u32 *eax, u32 *ebx, u32 *ecx, u32 *edx, u32 *esi) 595 u32 *eax, u32 *ebx, u32 *ecx, u32 *edx, u32 *esi)
596{ 596{
@@ -602,7 +602,7 @@ static u8 apm_bios_call(u32 func, u32 ebx_in, u32 ecx_in,
602 struct desc_struct *gdt; 602 struct desc_struct *gdt;
603 603
604 cpus = apm_save_cpus(); 604 cpus = apm_save_cpus();
605 605
606 cpu = get_cpu(); 606 cpu = get_cpu();
607 gdt = get_cpu_gdt_table(cpu); 607 gdt = get_cpu_gdt_table(cpu);
608 save_desc_40 = gdt[0x40 / 8]; 608 save_desc_40 = gdt[0x40 / 8];
@@ -616,7 +616,7 @@ static u8 apm_bios_call(u32 func, u32 ebx_in, u32 ecx_in,
616 gdt[0x40 / 8] = save_desc_40; 616 gdt[0x40 / 8] = save_desc_40;
617 put_cpu(); 617 put_cpu();
618 apm_restore_cpus(cpus); 618 apm_restore_cpus(cpus);
619 619
620 return *eax & 0xff; 620 return *eax & 0xff;
621} 621}
622 622
@@ -645,7 +645,7 @@ static u8 apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax)
645 struct desc_struct *gdt; 645 struct desc_struct *gdt;
646 646
647 cpus = apm_save_cpus(); 647 cpus = apm_save_cpus();
648 648
649 cpu = get_cpu(); 649 cpu = get_cpu();
650 gdt = get_cpu_gdt_table(cpu); 650 gdt = get_cpu_gdt_table(cpu);
651 save_desc_40 = gdt[0x40 / 8]; 651 save_desc_40 = gdt[0x40 / 8];
@@ -680,7 +680,7 @@ static u8 apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax)
680 680
681static int apm_driver_version(u_short *val) 681static int apm_driver_version(u_short *val)
682{ 682{
683 u32 eax; 683 u32 eax;
684 684
685 if (apm_bios_call_simple(APM_FUNC_VERSION, 0, *val, &eax)) 685 if (apm_bios_call_simple(APM_FUNC_VERSION, 0, *val, &eax))
686 return (eax >> 8) & 0xff; 686 return (eax >> 8) & 0xff;
@@ -704,16 +704,16 @@ static int apm_driver_version(u_short *val)
704 * that APM 1.2 is in use. If no messges are pending the value 0x80 704 * that APM 1.2 is in use. If no messges are pending the value 0x80
705 * is returned (No power management events pending). 705 * is returned (No power management events pending).
706 */ 706 */
707 707
708static int apm_get_event(apm_event_t *event, apm_eventinfo_t *info) 708static int apm_get_event(apm_event_t *event, apm_eventinfo_t *info)
709{ 709{
710 u32 eax; 710 u32 eax;
711 u32 ebx; 711 u32 ebx;
712 u32 ecx; 712 u32 ecx;
713 u32 dummy; 713 u32 dummy;
714 714
715 if (apm_bios_call(APM_FUNC_GET_EVENT, 0, 0, &eax, &ebx, &ecx, 715 if (apm_bios_call(APM_FUNC_GET_EVENT, 0, 0, &eax, &ebx, &ecx,
716 &dummy, &dummy)) 716 &dummy, &dummy))
717 return (eax >> 8) & 0xff; 717 return (eax >> 8) & 0xff;
718 *event = ebx; 718 *event = ebx;
719 if (apm_info.connection_version < 0x0102) 719 if (apm_info.connection_version < 0x0102)
@@ -736,10 +736,10 @@ static int apm_get_event(apm_event_t *event, apm_eventinfo_t *info)
736 * The state holds the state to transition to, which may in fact 736 * The state holds the state to transition to, which may in fact
737 * be an acceptance of a BIOS requested state change. 737 * be an acceptance of a BIOS requested state change.
738 */ 738 */
739 739
740static int set_power_state(u_short what, u_short state) 740static int set_power_state(u_short what, u_short state)
741{ 741{
742 u32 eax; 742 u32 eax;
743 743
744 if (apm_bios_call_simple(APM_FUNC_SET_STATE, what, state, &eax)) 744 if (apm_bios_call_simple(APM_FUNC_SET_STATE, what, state, &eax))
745 return (eax >> 8) & 0xff; 745 return (eax >> 8) & 0xff;
@@ -752,7 +752,7 @@ static int set_power_state(u_short what, u_short state)
752 * 752 *
753 * Transition the entire system into a new APM power state. 753 * Transition the entire system into a new APM power state.
754 */ 754 */
755 755
756static int set_system_power_state(u_short state) 756static int set_system_power_state(u_short state)
757{ 757{
758 return set_power_state(APM_DEVICE_ALL, state); 758 return set_power_state(APM_DEVICE_ALL, state);
@@ -766,13 +766,13 @@ static int set_system_power_state(u_short state)
766 * to handle the idle request. On a success the function returns 1 766 * to handle the idle request. On a success the function returns 1
767 * if the BIOS did clock slowing or 0 otherwise. 767 * if the BIOS did clock slowing or 0 otherwise.
768 */ 768 */
769 769
770static int apm_do_idle(void) 770static int apm_do_idle(void)
771{ 771{
772 u32 eax; 772 u32 eax;
773 u8 ret = 0; 773 u8 ret = 0;
774 int idled = 0; 774 int idled = 0;
775 int polling; 775 int polling;
776 776
777 polling = !!(current_thread_info()->status & TS_POLLING); 777 polling = !!(current_thread_info()->status & TS_POLLING);
778 if (polling) { 778 if (polling) {
@@ -799,10 +799,9 @@ static int apm_do_idle(void)
799 /* This always fails on some SMP boards running UP kernels. 799 /* This always fails on some SMP boards running UP kernels.
800 * Only report the failure the first 5 times. 800 * Only report the failure the first 5 times.
801 */ 801 */
802 if (++t < 5) 802 if (++t < 5) {
803 {
804 printk(KERN_DEBUG "apm_do_idle failed (%d)\n", 803 printk(KERN_DEBUG "apm_do_idle failed (%d)\n",
805 (eax >> 8) & 0xff); 804 (eax >> 8) & 0xff);
806 t = jiffies; 805 t = jiffies;
807 } 806 }
808 return -1; 807 return -1;
@@ -814,15 +813,15 @@ static int apm_do_idle(void)
814/** 813/**
815 * apm_do_busy - inform the BIOS the CPU is busy 814 * apm_do_busy - inform the BIOS the CPU is busy
816 * 815 *
817 * Request that the BIOS brings the CPU back to full performance. 816 * Request that the BIOS brings the CPU back to full performance.
818 */ 817 */
819 818
820static void apm_do_busy(void) 819static void apm_do_busy(void)
821{ 820{
822 u32 dummy; 821 u32 dummy;
823 822
824 if (clock_slowed || ALWAYS_CALL_BUSY) { 823 if (clock_slowed || ALWAYS_CALL_BUSY) {
825 (void) apm_bios_call_simple(APM_FUNC_BUSY, 0, 0, &dummy); 824 (void)apm_bios_call_simple(APM_FUNC_BUSY, 0, 0, &dummy);
826 clock_slowed = 0; 825 clock_slowed = 0;
827 } 826 }
828} 827}
@@ -833,15 +832,15 @@ static void apm_do_busy(void)
833 * power management - we probably want 832 * power management - we probably want
834 * to conserve power. 833 * to conserve power.
835 */ 834 */
836#define IDLE_CALC_LIMIT (HZ * 100) 835#define IDLE_CALC_LIMIT (HZ * 100)
837#define IDLE_LEAKY_MAX 16 836#define IDLE_LEAKY_MAX 16
838 837
839static void (*original_pm_idle)(void) __read_mostly; 838static void (*original_pm_idle)(void) __read_mostly;
840 839
841/** 840/**
842 * apm_cpu_idle - cpu idling for APM capable Linux 841 * apm_cpu_idle - cpu idling for APM capable Linux
843 * 842 *
844 * This is the idling function the kernel executes when APM is available. It 843 * This is the idling function the kernel executes when APM is available. It
845 * tries to do BIOS powermanagement based on the average system idle time. 844 * tries to do BIOS powermanagement based on the average system idle time.
846 * Furthermore it calls the system default idle routine. 845 * Furthermore it calls the system default idle routine.
847 */ 846 */
@@ -882,7 +881,8 @@ recalc:
882 881
883 t = jiffies; 882 t = jiffies;
884 switch (apm_do_idle()) { 883 switch (apm_do_idle()) {
885 case 0: apm_idle_done = 1; 884 case 0:
885 apm_idle_done = 1;
886 if (t != jiffies) { 886 if (t != jiffies) {
887 if (bucket) { 887 if (bucket) {
888 bucket = IDLE_LEAKY_MAX; 888 bucket = IDLE_LEAKY_MAX;
@@ -893,7 +893,8 @@ recalc:
893 continue; 893 continue;
894 } 894 }
895 break; 895 break;
896 case 1: apm_idle_done = 1; 896 case 1:
897 apm_idle_done = 1;
897 break; 898 break;
898 default: /* BIOS refused */ 899 default: /* BIOS refused */
899 break; 900 break;
@@ -921,10 +922,10 @@ recalc:
921 * the SMP call on CPU0 as some systems will only honour this call 922 * the SMP call on CPU0 as some systems will only honour this call
922 * on their first cpu. 923 * on their first cpu.
923 */ 924 */
924 925
925static void apm_power_off(void) 926static void apm_power_off(void)
926{ 927{
927 unsigned char po_bios_call[] = { 928 unsigned char po_bios_call[] = {
928 0xb8, 0x00, 0x10, /* movw $0x1000,ax */ 929 0xb8, 0x00, 0x10, /* movw $0x1000,ax */
929 0x8e, 0xd0, /* movw ax,ss */ 930 0x8e, 0xd0, /* movw ax,ss */
930 0xbc, 0x00, 0xf0, /* movw $0xf000,sp */ 931 0xbc, 0x00, 0xf0, /* movw $0xf000,sp */
@@ -935,13 +936,12 @@ static void apm_power_off(void)
935 }; 936 };
936 937
937 /* Some bioses don't like being called from CPU != 0 */ 938 /* Some bioses don't like being called from CPU != 0 */
938 if (apm_info.realmode_power_off) 939 if (apm_info.realmode_power_off) {
939 {
940 (void)apm_save_cpus(); 940 (void)apm_save_cpus();
941 machine_real_restart(po_bios_call, sizeof(po_bios_call)); 941 machine_real_restart(po_bios_call, sizeof(po_bios_call));
942 } else {
943 (void)set_system_power_state(APM_STATE_OFF);
942 } 944 }
943 else
944 (void) set_system_power_state(APM_STATE_OFF);
945} 945}
946 946
947#ifdef CONFIG_APM_DO_ENABLE 947#ifdef CONFIG_APM_DO_ENABLE
@@ -950,17 +950,17 @@ static void apm_power_off(void)
950 * apm_enable_power_management - enable BIOS APM power management 950 * apm_enable_power_management - enable BIOS APM power management
951 * @enable: enable yes/no 951 * @enable: enable yes/no
952 * 952 *
953 * Enable or disable the APM BIOS power services. 953 * Enable or disable the APM BIOS power services.
954 */ 954 */
955 955
956static int apm_enable_power_management(int enable) 956static int apm_enable_power_management(int enable)
957{ 957{
958 u32 eax; 958 u32 eax;
959 959
960 if ((enable == 0) && (apm_info.bios.flags & APM_BIOS_DISENGAGED)) 960 if ((enable == 0) && (apm_info.bios.flags & APM_BIOS_DISENGAGED))
961 return APM_NOT_ENGAGED; 961 return APM_NOT_ENGAGED;
962 if (apm_bios_call_simple(APM_FUNC_ENABLE_PM, APM_DEVICE_BALL, 962 if (apm_bios_call_simple(APM_FUNC_ENABLE_PM, APM_DEVICE_BALL,
963 enable, &eax)) 963 enable, &eax))
964 return (eax >> 8) & 0xff; 964 return (eax >> 8) & 0xff;
965 if (enable) 965 if (enable)
966 apm_info.bios.flags &= ~APM_BIOS_DISABLED; 966 apm_info.bios.flags &= ~APM_BIOS_DISABLED;
@@ -983,19 +983,19 @@ static int apm_enable_power_management(int enable)
983 * if reported is a lifetime in secodnds/minutes at current powwer 983 * if reported is a lifetime in secodnds/minutes at current powwer
984 * consumption. 984 * consumption.
985 */ 985 */
986 986
987static int apm_get_power_status(u_short *status, u_short *bat, u_short *life) 987static int apm_get_power_status(u_short *status, u_short *bat, u_short *life)
988{ 988{
989 u32 eax; 989 u32 eax;
990 u32 ebx; 990 u32 ebx;
991 u32 ecx; 991 u32 ecx;
992 u32 edx; 992 u32 edx;
993 u32 dummy; 993 u32 dummy;
994 994
995 if (apm_info.get_power_status_broken) 995 if (apm_info.get_power_status_broken)
996 return APM_32_UNSUPPORTED; 996 return APM_32_UNSUPPORTED;
997 if (apm_bios_call(APM_FUNC_GET_STATUS, APM_DEVICE_ALL, 0, 997 if (apm_bios_call(APM_FUNC_GET_STATUS, APM_DEVICE_ALL, 0,
998 &eax, &ebx, &ecx, &edx, &dummy)) 998 &eax, &ebx, &ecx, &edx, &dummy))
999 return (eax >> 8) & 0xff; 999 return (eax >> 8) & 0xff;
1000 *status = ebx; 1000 *status = ebx;
1001 *bat = ecx; 1001 *bat = ecx;
@@ -1011,11 +1011,11 @@ static int apm_get_power_status(u_short *status, u_short *bat, u_short *life)
1011static int apm_get_battery_status(u_short which, u_short *status, 1011static int apm_get_battery_status(u_short which, u_short *status,
1012 u_short *bat, u_short *life, u_short *nbat) 1012 u_short *bat, u_short *life, u_short *nbat)
1013{ 1013{
1014 u32 eax; 1014 u32 eax;
1015 u32 ebx; 1015 u32 ebx;
1016 u32 ecx; 1016 u32 ecx;
1017 u32 edx; 1017 u32 edx;
1018 u32 esi; 1018 u32 esi;
1019 1019
1020 if (apm_info.connection_version < 0x0102) { 1020 if (apm_info.connection_version < 0x0102) {
1021 /* pretend we only have one battery. */ 1021 /* pretend we only have one battery. */
@@ -1026,7 +1026,7 @@ static int apm_get_battery_status(u_short which, u_short *status,
1026 } 1026 }
1027 1027
1028 if (apm_bios_call(APM_FUNC_GET_STATUS, (0x8000 | (which)), 0, &eax, 1028 if (apm_bios_call(APM_FUNC_GET_STATUS, (0x8000 | (which)), 0, &eax,
1029 &ebx, &ecx, &edx, &esi)) 1029 &ebx, &ecx, &edx, &esi))
1030 return (eax >> 8) & 0xff; 1030 return (eax >> 8) & 0xff;
1031 *status = ebx; 1031 *status = ebx;
1032 *bat = ecx; 1032 *bat = ecx;
@@ -1044,10 +1044,10 @@ static int apm_get_battery_status(u_short which, u_short *status,
1044 * Activate or deactive power management on either a specific device 1044 * Activate or deactive power management on either a specific device
1045 * or the entire system (%APM_DEVICE_ALL). 1045 * or the entire system (%APM_DEVICE_ALL).
1046 */ 1046 */
1047 1047
1048static int apm_engage_power_management(u_short device, int enable) 1048static int apm_engage_power_management(u_short device, int enable)
1049{ 1049{
1050 u32 eax; 1050 u32 eax;
1051 1051
1052 if ((enable == 0) && (device == APM_DEVICE_ALL) 1052 if ((enable == 0) && (device == APM_DEVICE_ALL)
1053 && (apm_info.bios.flags & APM_BIOS_DISABLED)) 1053 && (apm_info.bios.flags & APM_BIOS_DISABLED))
@@ -1074,7 +1074,7 @@ static int apm_engage_power_management(u_short device, int enable)
1074 * all video devices. Typically the BIOS will do laptop backlight and 1074 * all video devices. Typically the BIOS will do laptop backlight and
1075 * monitor powerdown for us. 1075 * monitor powerdown for us.
1076 */ 1076 */
1077 1077
1078static int apm_console_blank(int blank) 1078static int apm_console_blank(int blank)
1079{ 1079{
1080 int error = APM_NOT_ENGAGED; /* silence gcc */ 1080 int error = APM_NOT_ENGAGED; /* silence gcc */
@@ -1126,7 +1126,7 @@ static apm_event_t get_queued_event(struct apm_user *as)
1126 1126
1127static void queue_event(apm_event_t event, struct apm_user *sender) 1127static void queue_event(apm_event_t event, struct apm_user *sender)
1128{ 1128{
1129 struct apm_user * as; 1129 struct apm_user *as;
1130 1130
1131 spin_lock(&user_list_lock); 1131 spin_lock(&user_list_lock);
1132 if (user_list == NULL) 1132 if (user_list == NULL)
@@ -1174,11 +1174,11 @@ static void reinit_timer(void)
1174 1174
1175 spin_lock_irqsave(&i8253_lock, flags); 1175 spin_lock_irqsave(&i8253_lock, flags);
1176 /* set the clock to HZ */ 1176 /* set the clock to HZ */
1177 outb_p(0x34, PIT_MODE); /* binary, mode 2, LSB/MSB, ch 0 */ 1177 outb_pit(0x34, PIT_MODE); /* binary, mode 2, LSB/MSB, ch 0 */
1178 udelay(10); 1178 udelay(10);
1179 outb_p(LATCH & 0xff, PIT_CH0); /* LSB */ 1179 outb_pit(LATCH & 0xff, PIT_CH0); /* LSB */
1180 udelay(10); 1180 udelay(10);
1181 outb(LATCH >> 8, PIT_CH0); /* MSB */ 1181 outb_pit(LATCH >> 8, PIT_CH0); /* MSB */
1182 udelay(10); 1182 udelay(10);
1183 spin_unlock_irqrestore(&i8253_lock, flags); 1183 spin_unlock_irqrestore(&i8253_lock, flags);
1184#endif 1184#endif
@@ -1186,7 +1186,7 @@ static void reinit_timer(void)
1186 1186
1187static int suspend(int vetoable) 1187static int suspend(int vetoable)
1188{ 1188{
1189 int err; 1189 int err;
1190 struct apm_user *as; 1190 struct apm_user *as;
1191 1191
1192 if (pm_send_all(PM_SUSPEND, (void *)3)) { 1192 if (pm_send_all(PM_SUSPEND, (void *)3)) {
@@ -1239,7 +1239,7 @@ static int suspend(int vetoable)
1239 1239
1240static void standby(void) 1240static void standby(void)
1241{ 1241{
1242 int err; 1242 int err;
1243 1243
1244 local_irq_disable(); 1244 local_irq_disable();
1245 device_power_down(PMSG_SUSPEND); 1245 device_power_down(PMSG_SUSPEND);
@@ -1256,8 +1256,8 @@ static void standby(void)
1256 1256
1257static apm_event_t get_event(void) 1257static apm_event_t get_event(void)
1258{ 1258{
1259 int error; 1259 int error;
1260 apm_event_t event = APM_NO_EVENTS; /* silence gcc */ 1260 apm_event_t event = APM_NO_EVENTS; /* silence gcc */
1261 apm_eventinfo_t info; 1261 apm_eventinfo_t info;
1262 1262
1263 static int notified; 1263 static int notified;
@@ -1275,9 +1275,9 @@ static apm_event_t get_event(void)
1275 1275
1276static void check_events(void) 1276static void check_events(void)
1277{ 1277{
1278 apm_event_t event; 1278 apm_event_t event;
1279 static unsigned long last_resume; 1279 static unsigned long last_resume;
1280 static int ignore_bounce; 1280 static int ignore_bounce;
1281 1281
1282 while ((event = get_event()) != 0) { 1282 while ((event = get_event()) != 0) {
1283 if (debug) { 1283 if (debug) {
@@ -1289,7 +1289,7 @@ static void check_events(void)
1289 "event 0x%02x\n", event); 1289 "event 0x%02x\n", event);
1290 } 1290 }
1291 if (ignore_bounce 1291 if (ignore_bounce
1292 && ((jiffies - last_resume) > bounce_interval)) 1292 && (time_after(jiffies, last_resume + bounce_interval)))
1293 ignore_bounce = 0; 1293 ignore_bounce = 0;
1294 1294
1295 switch (event) { 1295 switch (event) {
@@ -1357,7 +1357,7 @@ static void check_events(void)
1357 /* 1357 /*
1358 * We are not allowed to reject a critical suspend. 1358 * We are not allowed to reject a critical suspend.
1359 */ 1359 */
1360 (void) suspend(0); 1360 (void)suspend(0);
1361 break; 1361 break;
1362 } 1362 }
1363 } 1363 }
@@ -1365,12 +1365,12 @@ static void check_events(void)
1365 1365
1366static void apm_event_handler(void) 1366static void apm_event_handler(void)
1367{ 1367{
1368 static int pending_count = 4; 1368 static int pending_count = 4;
1369 int err; 1369 int err;
1370 1370
1371 if ((standbys_pending > 0) || (suspends_pending > 0)) { 1371 if ((standbys_pending > 0) || (suspends_pending > 0)) {
1372 if ((apm_info.connection_version > 0x100) && 1372 if ((apm_info.connection_version > 0x100) &&
1373 (pending_count-- <= 0)) { 1373 (pending_count-- <= 0)) {
1374 pending_count = 4; 1374 pending_count = 4;
1375 if (debug) 1375 if (debug)
1376 printk(KERN_DEBUG "apm: setting state busy\n"); 1376 printk(KERN_DEBUG "apm: setting state busy\n");
@@ -1418,9 +1418,9 @@ static int check_apm_user(struct apm_user *as, const char *func)
1418 1418
1419static ssize_t do_read(struct file *fp, char __user *buf, size_t count, loff_t *ppos) 1419static ssize_t do_read(struct file *fp, char __user *buf, size_t count, loff_t *ppos)
1420{ 1420{
1421 struct apm_user * as; 1421 struct apm_user *as;
1422 int i; 1422 int i;
1423 apm_event_t event; 1423 apm_event_t event;
1424 1424
1425 as = fp->private_data; 1425 as = fp->private_data;
1426 if (check_apm_user(as, "read")) 1426 if (check_apm_user(as, "read"))
@@ -1459,9 +1459,9 @@ static ssize_t do_read(struct file *fp, char __user *buf, size_t count, loff_t *
1459 return 0; 1459 return 0;
1460} 1460}
1461 1461
1462static unsigned int do_poll(struct file *fp, poll_table * wait) 1462static unsigned int do_poll(struct file *fp, poll_table *wait)
1463{ 1463{
1464 struct apm_user * as; 1464 struct apm_user *as;
1465 1465
1466 as = fp->private_data; 1466 as = fp->private_data;
1467 if (check_apm_user(as, "poll")) 1467 if (check_apm_user(as, "poll"))
@@ -1472,10 +1472,10 @@ static unsigned int do_poll(struct file *fp, poll_table * wait)
1472 return 0; 1472 return 0;
1473} 1473}
1474 1474
1475static int do_ioctl(struct inode * inode, struct file *filp, 1475static int do_ioctl(struct inode *inode, struct file *filp,
1476 u_int cmd, u_long arg) 1476 u_int cmd, u_long arg)
1477{ 1477{
1478 struct apm_user * as; 1478 struct apm_user *as;
1479 1479
1480 as = filp->private_data; 1480 as = filp->private_data;
1481 if (check_apm_user(as, "ioctl")) 1481 if (check_apm_user(as, "ioctl"))
@@ -1515,9 +1515,9 @@ static int do_ioctl(struct inode * inode, struct file *filp,
1515 return 0; 1515 return 0;
1516} 1516}
1517 1517
1518static int do_release(struct inode * inode, struct file * filp) 1518static int do_release(struct inode *inode, struct file *filp)
1519{ 1519{
1520 struct apm_user * as; 1520 struct apm_user *as;
1521 1521
1522 as = filp->private_data; 1522 as = filp->private_data;
1523 if (check_apm_user(as, "release")) 1523 if (check_apm_user(as, "release"))
@@ -1533,11 +1533,11 @@ static int do_release(struct inode * inode, struct file * filp)
1533 if (suspends_pending <= 0) 1533 if (suspends_pending <= 0)
1534 (void) suspend(1); 1534 (void) suspend(1);
1535 } 1535 }
1536 spin_lock(&user_list_lock); 1536 spin_lock(&user_list_lock);
1537 if (user_list == as) 1537 if (user_list == as)
1538 user_list = as->next; 1538 user_list = as->next;
1539 else { 1539 else {
1540 struct apm_user * as1; 1540 struct apm_user *as1;
1541 1541
1542 for (as1 = user_list; 1542 for (as1 = user_list;
1543 (as1 != NULL) && (as1->next != as); 1543 (as1 != NULL) && (as1->next != as);
@@ -1553,9 +1553,9 @@ static int do_release(struct inode * inode, struct file * filp)
1553 return 0; 1553 return 0;
1554} 1554}
1555 1555
1556static int do_open(struct inode * inode, struct file * filp) 1556static int do_open(struct inode *inode, struct file *filp)
1557{ 1557{
1558 struct apm_user * as; 1558 struct apm_user *as;
1559 1559
1560 as = kmalloc(sizeof(*as), GFP_KERNEL); 1560 as = kmalloc(sizeof(*as), GFP_KERNEL);
1561 if (as == NULL) { 1561 if (as == NULL) {
@@ -1569,7 +1569,7 @@ static int do_open(struct inode * inode, struct file * filp)
1569 as->suspends_read = as->standbys_read = 0; 1569 as->suspends_read = as->standbys_read = 0;
1570 /* 1570 /*
1571 * XXX - this is a tiny bit broken, when we consider BSD 1571 * XXX - this is a tiny bit broken, when we consider BSD
1572 * process accounting. If the device is opened by root, we 1572 * process accounting. If the device is opened by root, we
1573 * instantly flag that we used superuser privs. Who knows, 1573 * instantly flag that we used superuser privs. Who knows,
1574 * we might close the device immediately without doing a 1574 * we might close the device immediately without doing a
1575 * privileged operation -- cevans 1575 * privileged operation -- cevans
@@ -1652,16 +1652,16 @@ static int proc_apm_show(struct seq_file *m, void *v)
1652 8) min = minutes; sec = seconds */ 1652 8) min = minutes; sec = seconds */
1653 1653
1654 seq_printf(m, "%s %d.%d 0x%02x 0x%02x 0x%02x 0x%02x %d%% %d %s\n", 1654 seq_printf(m, "%s %d.%d 0x%02x 0x%02x 0x%02x 0x%02x %d%% %d %s\n",
1655 driver_version, 1655 driver_version,
1656 (apm_info.bios.version >> 8) & 0xff, 1656 (apm_info.bios.version >> 8) & 0xff,
1657 apm_info.bios.version & 0xff, 1657 apm_info.bios.version & 0xff,
1658 apm_info.bios.flags, 1658 apm_info.bios.flags,
1659 ac_line_status, 1659 ac_line_status,
1660 battery_status, 1660 battery_status,
1661 battery_flag, 1661 battery_flag,
1662 percentage, 1662 percentage,
1663 time_units, 1663 time_units,
1664 units); 1664 units);
1665 return 0; 1665 return 0;
1666} 1666}
1667 1667
@@ -1684,8 +1684,8 @@ static int apm(void *unused)
1684 unsigned short cx; 1684 unsigned short cx;
1685 unsigned short dx; 1685 unsigned short dx;
1686 int error; 1686 int error;
1687 char * power_stat; 1687 char *power_stat;
1688 char * bat_stat; 1688 char *bat_stat;
1689 1689
1690#ifdef CONFIG_SMP 1690#ifdef CONFIG_SMP
1691 /* 2002/08/01 - WT 1691 /* 2002/08/01 - WT
@@ -1744,23 +1744,41 @@ static int apm(void *unused)
1744 } 1744 }
1745 } 1745 }
1746 1746
1747 if (debug && (num_online_cpus() == 1 || smp )) { 1747 if (debug && (num_online_cpus() == 1 || smp)) {
1748 error = apm_get_power_status(&bx, &cx, &dx); 1748 error = apm_get_power_status(&bx, &cx, &dx);
1749 if (error) 1749 if (error)
1750 printk(KERN_INFO "apm: power status not available\n"); 1750 printk(KERN_INFO "apm: power status not available\n");
1751 else { 1751 else {
1752 switch ((bx >> 8) & 0xff) { 1752 switch ((bx >> 8) & 0xff) {
1753 case 0: power_stat = "off line"; break; 1753 case 0:
1754 case 1: power_stat = "on line"; break; 1754 power_stat = "off line";
1755 case 2: power_stat = "on backup power"; break; 1755 break;
1756 default: power_stat = "unknown"; break; 1756 case 1:
1757 power_stat = "on line";
1758 break;
1759 case 2:
1760 power_stat = "on backup power";
1761 break;
1762 default:
1763 power_stat = "unknown";
1764 break;
1757 } 1765 }
1758 switch (bx & 0xff) { 1766 switch (bx & 0xff) {
1759 case 0: bat_stat = "high"; break; 1767 case 0:
1760 case 1: bat_stat = "low"; break; 1768 bat_stat = "high";
1761 case 2: bat_stat = "critical"; break; 1769 break;
1762 case 3: bat_stat = "charging"; break; 1770 case 1:
1763 default: bat_stat = "unknown"; break; 1771 bat_stat = "low";
1772 break;
1773 case 2:
1774 bat_stat = "critical";
1775 break;
1776 case 3:
1777 bat_stat = "charging";
1778 break;
1779 default:
1780 bat_stat = "unknown";
1781 break;
1764 } 1782 }
1765 printk(KERN_INFO 1783 printk(KERN_INFO
1766 "apm: AC %s, battery status %s, battery life ", 1784 "apm: AC %s, battery status %s, battery life ",
@@ -1777,8 +1795,8 @@ static int apm(void *unused)
1777 printk("unknown\n"); 1795 printk("unknown\n");
1778 else 1796 else
1779 printk("%d %s\n", dx & 0x7fff, 1797 printk("%d %s\n", dx & 0x7fff,
1780 (dx & 0x8000) ? 1798 (dx & 0x8000) ?
1781 "minutes" : "seconds"); 1799 "minutes" : "seconds");
1782 } 1800 }
1783 } 1801 }
1784 } 1802 }
@@ -1803,7 +1821,7 @@ static int apm(void *unused)
1803#ifndef MODULE 1821#ifndef MODULE
1804static int __init apm_setup(char *str) 1822static int __init apm_setup(char *str)
1805{ 1823{
1806 int invert; 1824 int invert;
1807 1825
1808 while ((str != NULL) && (*str != '\0')) { 1826 while ((str != NULL) && (*str != '\0')) {
1809 if (strncmp(str, "off", 3) == 0) 1827 if (strncmp(str, "off", 3) == 0)
@@ -1828,14 +1846,13 @@ static int __init apm_setup(char *str)
1828 if ((strncmp(str, "power-off", 9) == 0) || 1846 if ((strncmp(str, "power-off", 9) == 0) ||
1829 (strncmp(str, "power_off", 9) == 0)) 1847 (strncmp(str, "power_off", 9) == 0))
1830 power_off = !invert; 1848 power_off = !invert;
1831 if (strncmp(str, "smp", 3) == 0) 1849 if (strncmp(str, "smp", 3) == 0) {
1832 {
1833 smp = !invert; 1850 smp = !invert;
1834 idle_threshold = 100; 1851 idle_threshold = 100;
1835 } 1852 }
1836 if ((strncmp(str, "allow-ints", 10) == 0) || 1853 if ((strncmp(str, "allow-ints", 10) == 0) ||
1837 (strncmp(str, "allow_ints", 10) == 0)) 1854 (strncmp(str, "allow_ints", 10) == 0))
1838 apm_info.allow_ints = !invert; 1855 apm_info.allow_ints = !invert;
1839 if ((strncmp(str, "broken-psr", 10) == 0) || 1856 if ((strncmp(str, "broken-psr", 10) == 0) ||
1840 (strncmp(str, "broken_psr", 10) == 0)) 1857 (strncmp(str, "broken_psr", 10) == 0))
1841 apm_info.get_power_status_broken = !invert; 1858 apm_info.get_power_status_broken = !invert;
@@ -1881,7 +1898,8 @@ static int __init print_if_true(const struct dmi_system_id *d)
1881 */ 1898 */
1882static int __init broken_ps2_resume(const struct dmi_system_id *d) 1899static int __init broken_ps2_resume(const struct dmi_system_id *d)
1883{ 1900{
1884 printk(KERN_INFO "%s machine detected. Mousepad Resume Bug workaround hopefully not needed.\n", d->ident); 1901 printk(KERN_INFO "%s machine detected. Mousepad Resume Bug "
1902 "workaround hopefully not needed.\n", d->ident);
1885 return 0; 1903 return 0;
1886} 1904}
1887 1905
@@ -1890,7 +1908,8 @@ static int __init set_realmode_power_off(const struct dmi_system_id *d)
1890{ 1908{
1891 if (apm_info.realmode_power_off == 0) { 1909 if (apm_info.realmode_power_off == 0) {
1892 apm_info.realmode_power_off = 1; 1910 apm_info.realmode_power_off = 1;
1893 printk(KERN_INFO "%s bios detected. Using realmode poweroff only.\n", d->ident); 1911 printk(KERN_INFO "%s bios detected. "
1912 "Using realmode poweroff only.\n", d->ident);
1894 } 1913 }
1895 return 0; 1914 return 0;
1896} 1915}
@@ -1900,7 +1919,8 @@ static int __init set_apm_ints(const struct dmi_system_id *d)
1900{ 1919{
1901 if (apm_info.allow_ints == 0) { 1920 if (apm_info.allow_ints == 0) {
1902 apm_info.allow_ints = 1; 1921 apm_info.allow_ints = 1;
1903 printk(KERN_INFO "%s machine detected. Enabling interrupts during APM calls.\n", d->ident); 1922 printk(KERN_INFO "%s machine detected. "
1923 "Enabling interrupts during APM calls.\n", d->ident);
1904 } 1924 }
1905 return 0; 1925 return 0;
1906} 1926}
@@ -1910,7 +1930,8 @@ static int __init apm_is_horked(const struct dmi_system_id *d)
1910{ 1930{
1911 if (apm_info.disabled == 0) { 1931 if (apm_info.disabled == 0) {
1912 apm_info.disabled = 1; 1932 apm_info.disabled = 1;
1913 printk(KERN_INFO "%s machine detected. Disabling APM.\n", d->ident); 1933 printk(KERN_INFO "%s machine detected. "
1934 "Disabling APM.\n", d->ident);
1914 } 1935 }
1915 return 0; 1936 return 0;
1916} 1937}
@@ -1919,7 +1940,8 @@ static int __init apm_is_horked_d850md(const struct dmi_system_id *d)
1919{ 1940{
1920 if (apm_info.disabled == 0) { 1941 if (apm_info.disabled == 0) {
1921 apm_info.disabled = 1; 1942 apm_info.disabled = 1;
1922 printk(KERN_INFO "%s machine detected. Disabling APM.\n", d->ident); 1943 printk(KERN_INFO "%s machine detected. "
1944 "Disabling APM.\n", d->ident);
1923 printk(KERN_INFO "This bug is fixed in bios P15 which is available for \n"); 1945 printk(KERN_INFO "This bug is fixed in bios P15 which is available for \n");
1924 printk(KERN_INFO "download from support.intel.com \n"); 1946 printk(KERN_INFO "download from support.intel.com \n");
1925 } 1947 }
@@ -1931,7 +1953,8 @@ static int __init apm_likes_to_melt(const struct dmi_system_id *d)
1931{ 1953{
1932 if (apm_info.forbid_idle == 0) { 1954 if (apm_info.forbid_idle == 0) {
1933 apm_info.forbid_idle = 1; 1955 apm_info.forbid_idle = 1;
1934 printk(KERN_INFO "%s machine detected. Disabling APM idle calls.\n", d->ident); 1956 printk(KERN_INFO "%s machine detected. "
1957 "Disabling APM idle calls.\n", d->ident);
1935 } 1958 }
1936 return 0; 1959 return 0;
1937} 1960}
@@ -1954,7 +1977,8 @@ static int __init apm_likes_to_melt(const struct dmi_system_id *d)
1954static int __init broken_apm_power(const struct dmi_system_id *d) 1977static int __init broken_apm_power(const struct dmi_system_id *d)
1955{ 1978{
1956 apm_info.get_power_status_broken = 1; 1979 apm_info.get_power_status_broken = 1;
1957 printk(KERN_WARNING "BIOS strings suggest APM bugs, disabling power status reporting.\n"); 1980 printk(KERN_WARNING "BIOS strings suggest APM bugs, "
1981 "disabling power status reporting.\n");
1958 return 0; 1982 return 0;
1959} 1983}
1960 1984
@@ -1965,7 +1989,8 @@ static int __init broken_apm_power(const struct dmi_system_id *d)
1965static int __init swab_apm_power_in_minutes(const struct dmi_system_id *d) 1989static int __init swab_apm_power_in_minutes(const struct dmi_system_id *d)
1966{ 1990{
1967 apm_info.get_power_status_swabinminutes = 1; 1991 apm_info.get_power_status_swabinminutes = 1;
1968 printk(KERN_WARNING "BIOS strings suggest APM reports battery life in minutes and wrong byte order.\n"); 1992 printk(KERN_WARNING "BIOS strings suggest APM reports battery life "
1993 "in minutes and wrong byte order.\n");
1969 return 0; 1994 return 0;
1970} 1995}
1971 1996
@@ -1990,8 +2015,8 @@ static struct dmi_system_id __initdata apm_dmi_table[] = {
1990 apm_is_horked, "Dell Inspiron 2500", 2015 apm_is_horked, "Dell Inspiron 2500",
1991 { DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), 2016 { DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
1992 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 2500"), 2017 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 2500"),
1993 DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"), 2018 DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
1994 DMI_MATCH(DMI_BIOS_VERSION,"A11"), }, 2019 DMI_MATCH(DMI_BIOS_VERSION, "A11"), },
1995 }, 2020 },
1996 { /* Allow interrupts during suspend on Dell Inspiron laptops*/ 2021 { /* Allow interrupts during suspend on Dell Inspiron laptops*/
1997 set_apm_ints, "Dell Inspiron", { 2022 set_apm_ints, "Dell Inspiron", {
@@ -2014,15 +2039,15 @@ static struct dmi_system_id __initdata apm_dmi_table[] = {
2014 apm_is_horked, "Dell Dimension 4100", 2039 apm_is_horked, "Dell Dimension 4100",
2015 { DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), 2040 { DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
2016 DMI_MATCH(DMI_PRODUCT_NAME, "XPS-Z"), 2041 DMI_MATCH(DMI_PRODUCT_NAME, "XPS-Z"),
2017 DMI_MATCH(DMI_BIOS_VENDOR,"Intel Corp."), 2042 DMI_MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
2018 DMI_MATCH(DMI_BIOS_VERSION,"A11"), }, 2043 DMI_MATCH(DMI_BIOS_VERSION, "A11"), },
2019 }, 2044 },
2020 { /* Allow interrupts during suspend on Compaq Laptops*/ 2045 { /* Allow interrupts during suspend on Compaq Laptops*/
2021 set_apm_ints, "Compaq 12XL125", 2046 set_apm_ints, "Compaq 12XL125",
2022 { DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), 2047 { DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
2023 DMI_MATCH(DMI_PRODUCT_NAME, "Compaq PC"), 2048 DMI_MATCH(DMI_PRODUCT_NAME, "Compaq PC"),
2024 DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), 2049 DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
2025 DMI_MATCH(DMI_BIOS_VERSION,"4.06"), }, 2050 DMI_MATCH(DMI_BIOS_VERSION, "4.06"), },
2026 }, 2051 },
2027 { /* Allow interrupts during APM or the clock goes slow */ 2052 { /* Allow interrupts during APM or the clock goes slow */
2028 set_apm_ints, "ASUSTeK", 2053 set_apm_ints, "ASUSTeK",
@@ -2064,15 +2089,15 @@ static struct dmi_system_id __initdata apm_dmi_table[] = {
2064 apm_is_horked, "Sharp PC-PJ/AX", 2089 apm_is_horked, "Sharp PC-PJ/AX",
2065 { DMI_MATCH(DMI_SYS_VENDOR, "SHARP"), 2090 { DMI_MATCH(DMI_SYS_VENDOR, "SHARP"),
2066 DMI_MATCH(DMI_PRODUCT_NAME, "PC-PJ/AX"), 2091 DMI_MATCH(DMI_PRODUCT_NAME, "PC-PJ/AX"),
2067 DMI_MATCH(DMI_BIOS_VENDOR,"SystemSoft"), 2092 DMI_MATCH(DMI_BIOS_VENDOR, "SystemSoft"),
2068 DMI_MATCH(DMI_BIOS_VERSION,"Version R2.08"), }, 2093 DMI_MATCH(DMI_BIOS_VERSION, "Version R2.08"), },
2069 }, 2094 },
2070 { /* APM crashes */ 2095 { /* APM crashes */
2071 apm_is_horked, "Dell Inspiron 2500", 2096 apm_is_horked, "Dell Inspiron 2500",
2072 { DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), 2097 { DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
2073 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 2500"), 2098 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 2500"),
2074 DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"), 2099 DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
2075 DMI_MATCH(DMI_BIOS_VERSION,"A11"), }, 2100 DMI_MATCH(DMI_BIOS_VERSION, "A11"), },
2076 }, 2101 },
2077 { /* APM idle hangs */ 2102 { /* APM idle hangs */
2078 apm_likes_to_melt, "Jabil AMD", 2103 apm_likes_to_melt, "Jabil AMD",
@@ -2203,11 +2228,11 @@ static int __init apm_init(void)
2203 return -ENODEV; 2228 return -ENODEV;
2204 } 2229 }
2205 printk(KERN_INFO 2230 printk(KERN_INFO
2206 "apm: BIOS version %d.%d Flags 0x%02x (Driver version %s)\n", 2231 "apm: BIOS version %d.%d Flags 0x%02x (Driver version %s)\n",
2207 ((apm_info.bios.version >> 8) & 0xff), 2232 ((apm_info.bios.version >> 8) & 0xff),
2208 (apm_info.bios.version & 0xff), 2233 (apm_info.bios.version & 0xff),
2209 apm_info.bios.flags, 2234 apm_info.bios.flags,
2210 driver_version); 2235 driver_version);
2211 if ((apm_info.bios.flags & APM_32_BIT_SUPPORT) == 0) { 2236 if ((apm_info.bios.flags & APM_32_BIT_SUPPORT) == 0) {
2212 printk(KERN_INFO "apm: no 32 bit BIOS support\n"); 2237 printk(KERN_INFO "apm: no 32 bit BIOS support\n");
2213 return -ENODEV; 2238 return -ENODEV;
@@ -2312,9 +2337,9 @@ static int __init apm_init(void)
2312 } 2337 }
2313 wake_up_process(kapmd_task); 2338 wake_up_process(kapmd_task);
2314 2339
2315 if (num_online_cpus() > 1 && !smp ) { 2340 if (num_online_cpus() > 1 && !smp) {
2316 printk(KERN_NOTICE 2341 printk(KERN_NOTICE
2317 "apm: disabled - APM is not SMP safe (power off active).\n"); 2342 "apm: disabled - APM is not SMP safe (power off active).\n");
2318 return 0; 2343 return 0;
2319 } 2344 }
2320 2345
@@ -2339,7 +2364,7 @@ static int __init apm_init(void)
2339 2364
2340static void __exit apm_exit(void) 2365static void __exit apm_exit(void)
2341{ 2366{
2342 int error; 2367 int error;
2343 2368
2344 if (set_pm_idle) { 2369 if (set_pm_idle) {
2345 pm_idle = original_pm_idle; 2370 pm_idle = original_pm_idle;
diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c
index 0e45981b2dd7..afd84463b712 100644
--- a/arch/x86/kernel/asm-offsets_32.c
+++ b/arch/x86/kernel/asm-offsets_32.c
@@ -38,15 +38,15 @@ void foo(void);
38 38
39void foo(void) 39void foo(void)
40{ 40{
41 OFFSET(SIGCONTEXT_eax, sigcontext, eax); 41 OFFSET(IA32_SIGCONTEXT_ax, sigcontext, ax);
42 OFFSET(SIGCONTEXT_ebx, sigcontext, ebx); 42 OFFSET(IA32_SIGCONTEXT_bx, sigcontext, bx);
43 OFFSET(SIGCONTEXT_ecx, sigcontext, ecx); 43 OFFSET(IA32_SIGCONTEXT_cx, sigcontext, cx);
44 OFFSET(SIGCONTEXT_edx, sigcontext, edx); 44 OFFSET(IA32_SIGCONTEXT_dx, sigcontext, dx);
45 OFFSET(SIGCONTEXT_esi, sigcontext, esi); 45 OFFSET(IA32_SIGCONTEXT_si, sigcontext, si);
46 OFFSET(SIGCONTEXT_edi, sigcontext, edi); 46 OFFSET(IA32_SIGCONTEXT_di, sigcontext, di);
47 OFFSET(SIGCONTEXT_ebp, sigcontext, ebp); 47 OFFSET(IA32_SIGCONTEXT_bp, sigcontext, bp);
48 OFFSET(SIGCONTEXT_esp, sigcontext, esp); 48 OFFSET(IA32_SIGCONTEXT_sp, sigcontext, sp);
49 OFFSET(SIGCONTEXT_eip, sigcontext, eip); 49 OFFSET(IA32_SIGCONTEXT_ip, sigcontext, ip);
50 BLANK(); 50 BLANK();
51 51
52 OFFSET(CPUINFO_x86, cpuinfo_x86, x86); 52 OFFSET(CPUINFO_x86, cpuinfo_x86, x86);
@@ -70,39 +70,38 @@ void foo(void)
70 OFFSET(TI_cpu, thread_info, cpu); 70 OFFSET(TI_cpu, thread_info, cpu);
71 BLANK(); 71 BLANK();
72 72
73 OFFSET(GDS_size, Xgt_desc_struct, size); 73 OFFSET(GDS_size, desc_ptr, size);
74 OFFSET(GDS_address, Xgt_desc_struct, address); 74 OFFSET(GDS_address, desc_ptr, address);
75 OFFSET(GDS_pad, Xgt_desc_struct, pad);
76 BLANK(); 75 BLANK();
77 76
78 OFFSET(PT_EBX, pt_regs, ebx); 77 OFFSET(PT_EBX, pt_regs, bx);
79 OFFSET(PT_ECX, pt_regs, ecx); 78 OFFSET(PT_ECX, pt_regs, cx);
80 OFFSET(PT_EDX, pt_regs, edx); 79 OFFSET(PT_EDX, pt_regs, dx);
81 OFFSET(PT_ESI, pt_regs, esi); 80 OFFSET(PT_ESI, pt_regs, si);
82 OFFSET(PT_EDI, pt_regs, edi); 81 OFFSET(PT_EDI, pt_regs, di);
83 OFFSET(PT_EBP, pt_regs, ebp); 82 OFFSET(PT_EBP, pt_regs, bp);
84 OFFSET(PT_EAX, pt_regs, eax); 83 OFFSET(PT_EAX, pt_regs, ax);
85 OFFSET(PT_DS, pt_regs, xds); 84 OFFSET(PT_DS, pt_regs, ds);
86 OFFSET(PT_ES, pt_regs, xes); 85 OFFSET(PT_ES, pt_regs, es);
87 OFFSET(PT_FS, pt_regs, xfs); 86 OFFSET(PT_FS, pt_regs, fs);
88 OFFSET(PT_ORIG_EAX, pt_regs, orig_eax); 87 OFFSET(PT_ORIG_EAX, pt_regs, orig_ax);
89 OFFSET(PT_EIP, pt_regs, eip); 88 OFFSET(PT_EIP, pt_regs, ip);
90 OFFSET(PT_CS, pt_regs, xcs); 89 OFFSET(PT_CS, pt_regs, cs);
91 OFFSET(PT_EFLAGS, pt_regs, eflags); 90 OFFSET(PT_EFLAGS, pt_regs, flags);
92 OFFSET(PT_OLDESP, pt_regs, esp); 91 OFFSET(PT_OLDESP, pt_regs, sp);
93 OFFSET(PT_OLDSS, pt_regs, xss); 92 OFFSET(PT_OLDSS, pt_regs, ss);
94 BLANK(); 93 BLANK();
95 94
96 OFFSET(EXEC_DOMAIN_handler, exec_domain, handler); 95 OFFSET(EXEC_DOMAIN_handler, exec_domain, handler);
97 OFFSET(RT_SIGFRAME_sigcontext, rt_sigframe, uc.uc_mcontext); 96 OFFSET(IA32_RT_SIGFRAME_sigcontext, rt_sigframe, uc.uc_mcontext);
98 BLANK(); 97 BLANK();
99 98
100 OFFSET(pbe_address, pbe, address); 99 OFFSET(pbe_address, pbe, address);
101 OFFSET(pbe_orig_address, pbe, orig_address); 100 OFFSET(pbe_orig_address, pbe, orig_address);
102 OFFSET(pbe_next, pbe, next); 101 OFFSET(pbe_next, pbe, next);
103 102
104 /* Offset from the sysenter stack to tss.esp0 */ 103 /* Offset from the sysenter stack to tss.sp0 */
105 DEFINE(TSS_sysenter_esp0, offsetof(struct tss_struct, x86_tss.esp0) - 104 DEFINE(TSS_sysenter_sp0, offsetof(struct tss_struct, x86_tss.sp0) -
106 sizeof(struct tss_struct)); 105 sizeof(struct tss_struct));
107 106
108 DEFINE(PAGE_SIZE_asm, PAGE_SIZE); 107 DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
@@ -111,8 +110,6 @@ void foo(void)
111 DEFINE(PTRS_PER_PMD, PTRS_PER_PMD); 110 DEFINE(PTRS_PER_PMD, PTRS_PER_PMD);
112 DEFINE(PTRS_PER_PGD, PTRS_PER_PGD); 111 DEFINE(PTRS_PER_PGD, PTRS_PER_PGD);
113 112
114 DEFINE(VDSO_PRELINK_asm, VDSO_PRELINK);
115
116 OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx); 113 OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx);
117 114
118#ifdef CONFIG_PARAVIRT 115#ifdef CONFIG_PARAVIRT
@@ -123,7 +120,7 @@ void foo(void)
123 OFFSET(PV_IRQ_irq_disable, pv_irq_ops, irq_disable); 120 OFFSET(PV_IRQ_irq_disable, pv_irq_ops, irq_disable);
124 OFFSET(PV_IRQ_irq_enable, pv_irq_ops, irq_enable); 121 OFFSET(PV_IRQ_irq_enable, pv_irq_ops, irq_enable);
125 OFFSET(PV_CPU_iret, pv_cpu_ops, iret); 122 OFFSET(PV_CPU_iret, pv_cpu_ops, iret);
126 OFFSET(PV_CPU_irq_enable_sysexit, pv_cpu_ops, irq_enable_sysexit); 123 OFFSET(PV_CPU_irq_enable_syscall_ret, pv_cpu_ops, irq_enable_syscall_ret);
127 OFFSET(PV_CPU_read_cr0, pv_cpu_ops, read_cr0); 124 OFFSET(PV_CPU_read_cr0, pv_cpu_ops, read_cr0);
128#endif 125#endif
129 126
diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c
index d1b6ed98774e..494e1e096ee6 100644
--- a/arch/x86/kernel/asm-offsets_64.c
+++ b/arch/x86/kernel/asm-offsets_64.c
@@ -38,7 +38,6 @@ int main(void)
38#define ENTRY(entry) DEFINE(tsk_ ## entry, offsetof(struct task_struct, entry)) 38#define ENTRY(entry) DEFINE(tsk_ ## entry, offsetof(struct task_struct, entry))
39 ENTRY(state); 39 ENTRY(state);
40 ENTRY(flags); 40 ENTRY(flags);
41 ENTRY(thread);
42 ENTRY(pid); 41 ENTRY(pid);
43 BLANK(); 42 BLANK();
44#undef ENTRY 43#undef ENTRY
@@ -47,6 +46,9 @@ int main(void)
47 ENTRY(addr_limit); 46 ENTRY(addr_limit);
48 ENTRY(preempt_count); 47 ENTRY(preempt_count);
49 ENTRY(status); 48 ENTRY(status);
49#ifdef CONFIG_IA32_EMULATION
50 ENTRY(sysenter_return);
51#endif
50 BLANK(); 52 BLANK();
51#undef ENTRY 53#undef ENTRY
52#define ENTRY(entry) DEFINE(pda_ ## entry, offsetof(struct x8664_pda, entry)) 54#define ENTRY(entry) DEFINE(pda_ ## entry, offsetof(struct x8664_pda, entry))
@@ -59,17 +61,31 @@ int main(void)
59 ENTRY(data_offset); 61 ENTRY(data_offset);
60 BLANK(); 62 BLANK();
61#undef ENTRY 63#undef ENTRY
64#ifdef CONFIG_PARAVIRT
65 BLANK();
66 OFFSET(PARAVIRT_enabled, pv_info, paravirt_enabled);
67 OFFSET(PARAVIRT_PATCH_pv_cpu_ops, paravirt_patch_template, pv_cpu_ops);
68 OFFSET(PARAVIRT_PATCH_pv_irq_ops, paravirt_patch_template, pv_irq_ops);
69 OFFSET(PV_IRQ_irq_disable, pv_irq_ops, irq_disable);
70 OFFSET(PV_IRQ_irq_enable, pv_irq_ops, irq_enable);
71 OFFSET(PV_CPU_iret, pv_cpu_ops, iret);
72 OFFSET(PV_CPU_irq_enable_syscall_ret, pv_cpu_ops, irq_enable_syscall_ret);
73 OFFSET(PV_CPU_swapgs, pv_cpu_ops, swapgs);
74 OFFSET(PV_MMU_read_cr2, pv_mmu_ops, read_cr2);
75#endif
76
77
62#ifdef CONFIG_IA32_EMULATION 78#ifdef CONFIG_IA32_EMULATION
63#define ENTRY(entry) DEFINE(IA32_SIGCONTEXT_ ## entry, offsetof(struct sigcontext_ia32, entry)) 79#define ENTRY(entry) DEFINE(IA32_SIGCONTEXT_ ## entry, offsetof(struct sigcontext_ia32, entry))
64 ENTRY(eax); 80 ENTRY(ax);
65 ENTRY(ebx); 81 ENTRY(bx);
66 ENTRY(ecx); 82 ENTRY(cx);
67 ENTRY(edx); 83 ENTRY(dx);
68 ENTRY(esi); 84 ENTRY(si);
69 ENTRY(edi); 85 ENTRY(di);
70 ENTRY(ebp); 86 ENTRY(bp);
71 ENTRY(esp); 87 ENTRY(sp);
72 ENTRY(eip); 88 ENTRY(ip);
73 BLANK(); 89 BLANK();
74#undef ENTRY 90#undef ENTRY
75 DEFINE(IA32_RT_SIGFRAME_sigcontext, 91 DEFINE(IA32_RT_SIGFRAME_sigcontext,
@@ -81,14 +97,14 @@ int main(void)
81 DEFINE(pbe_next, offsetof(struct pbe, next)); 97 DEFINE(pbe_next, offsetof(struct pbe, next));
82 BLANK(); 98 BLANK();
83#define ENTRY(entry) DEFINE(pt_regs_ ## entry, offsetof(struct pt_regs, entry)) 99#define ENTRY(entry) DEFINE(pt_regs_ ## entry, offsetof(struct pt_regs, entry))
84 ENTRY(rbx); 100 ENTRY(bx);
85 ENTRY(rbx); 101 ENTRY(bx);
86 ENTRY(rcx); 102 ENTRY(cx);
87 ENTRY(rdx); 103 ENTRY(dx);
88 ENTRY(rsp); 104 ENTRY(sp);
89 ENTRY(rbp); 105 ENTRY(bp);
90 ENTRY(rsi); 106 ENTRY(si);
91 ENTRY(rdi); 107 ENTRY(di);
92 ENTRY(r8); 108 ENTRY(r8);
93 ENTRY(r9); 109 ENTRY(r9);
94 ENTRY(r10); 110 ENTRY(r10);
@@ -97,7 +113,7 @@ int main(void)
97 ENTRY(r13); 113 ENTRY(r13);
98 ENTRY(r14); 114 ENTRY(r14);
99 ENTRY(r15); 115 ENTRY(r15);
100 ENTRY(eflags); 116 ENTRY(flags);
101 BLANK(); 117 BLANK();
102#undef ENTRY 118#undef ENTRY
103#define ENTRY(entry) DEFINE(saved_context_ ## entry, offsetof(struct saved_context, entry)) 119#define ENTRY(entry) DEFINE(saved_context_ ## entry, offsetof(struct saved_context, entry))
@@ -108,7 +124,7 @@ int main(void)
108 ENTRY(cr8); 124 ENTRY(cr8);
109 BLANK(); 125 BLANK();
110#undef ENTRY 126#undef ENTRY
111 DEFINE(TSS_ist, offsetof(struct tss_struct, ist)); 127 DEFINE(TSS_ist, offsetof(struct tss_struct, x86_tss.ist));
112 BLANK(); 128 BLANK();
113 DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx)); 129 DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
114 BLANK(); 130 BLANK();
diff --git a/arch/x86/kernel/bootflag.c b/arch/x86/kernel/bootflag.c
index 0b9860530a6b..30f25a75fe28 100644
--- a/arch/x86/kernel/bootflag.c
+++ b/arch/x86/kernel/bootflag.c
@@ -1,8 +1,6 @@
1/* 1/*
2 * Implement 'Simple Boot Flag Specification 2.0' 2 * Implement 'Simple Boot Flag Specification 2.0'
3 */ 3 */
4
5
6#include <linux/types.h> 4#include <linux/types.h>
7#include <linux/kernel.h> 5#include <linux/kernel.h>
8#include <linux/init.h> 6#include <linux/init.h>
@@ -14,40 +12,38 @@
14 12
15#include <linux/mc146818rtc.h> 13#include <linux/mc146818rtc.h>
16 14
17
18#define SBF_RESERVED (0x78) 15#define SBF_RESERVED (0x78)
19#define SBF_PNPOS (1<<0) 16#define SBF_PNPOS (1<<0)
20#define SBF_BOOTING (1<<1) 17#define SBF_BOOTING (1<<1)
21#define SBF_DIAG (1<<2) 18#define SBF_DIAG (1<<2)
22#define SBF_PARITY (1<<7) 19#define SBF_PARITY (1<<7)
23 20
24
25int sbf_port __initdata = -1; /* set via acpi_boot_init() */ 21int sbf_port __initdata = -1; /* set via acpi_boot_init() */
26 22
27
28static int __init parity(u8 v) 23static int __init parity(u8 v)
29{ 24{
30 int x = 0; 25 int x = 0;
31 int i; 26 int i;
32 27
33 for(i=0;i<8;i++) 28 for (i = 0; i < 8; i++) {
34 { 29 x ^= (v & 1);
35 x^=(v&1); 30 v >>= 1;
36 v>>=1;
37 } 31 }
32
38 return x; 33 return x;
39} 34}
40 35
41static void __init sbf_write(u8 v) 36static void __init sbf_write(u8 v)
42{ 37{
43 unsigned long flags; 38 unsigned long flags;
44 if(sbf_port != -1) 39
45 { 40 if (sbf_port != -1) {
46 v &= ~SBF_PARITY; 41 v &= ~SBF_PARITY;
47 if(!parity(v)) 42 if (!parity(v))
48 v|=SBF_PARITY; 43 v |= SBF_PARITY;
49 44
50 printk(KERN_INFO "Simple Boot Flag at 0x%x set to 0x%x\n", sbf_port, v); 45 printk(KERN_INFO "Simple Boot Flag at 0x%x set to 0x%x\n",
46 sbf_port, v);
51 47
52 spin_lock_irqsave(&rtc_lock, flags); 48 spin_lock_irqsave(&rtc_lock, flags);
53 CMOS_WRITE(v, sbf_port); 49 CMOS_WRITE(v, sbf_port);
@@ -57,33 +53,41 @@ static void __init sbf_write(u8 v)
57 53
58static u8 __init sbf_read(void) 54static u8 __init sbf_read(void)
59{ 55{
60 u8 v;
61 unsigned long flags; 56 unsigned long flags;
62 if(sbf_port == -1) 57 u8 v;
58
59 if (sbf_port == -1)
63 return 0; 60 return 0;
61
64 spin_lock_irqsave(&rtc_lock, flags); 62 spin_lock_irqsave(&rtc_lock, flags);
65 v = CMOS_READ(sbf_port); 63 v = CMOS_READ(sbf_port);
66 spin_unlock_irqrestore(&rtc_lock, flags); 64 spin_unlock_irqrestore(&rtc_lock, flags);
65
67 return v; 66 return v;
68} 67}
69 68
70static int __init sbf_value_valid(u8 v) 69static int __init sbf_value_valid(u8 v)
71{ 70{
72 if(v&SBF_RESERVED) /* Reserved bits */ 71 if (v & SBF_RESERVED) /* Reserved bits */
73 return 0; 72 return 0;
74 if(!parity(v)) 73 if (!parity(v))
75 return 0; 74 return 0;
75
76 return 1; 76 return 1;
77} 77}
78 78
79static int __init sbf_init(void) 79static int __init sbf_init(void)
80{ 80{
81 u8 v; 81 u8 v;
82 if(sbf_port == -1) 82
83 if (sbf_port == -1)
83 return 0; 84 return 0;
85
84 v = sbf_read(); 86 v = sbf_read();
85 if(!sbf_value_valid(v)) 87 if (!sbf_value_valid(v)) {
86 printk(KERN_WARNING "Simple Boot Flag value 0x%x read from CMOS RAM was invalid\n",v); 88 printk(KERN_WARNING "Simple Boot Flag value 0x%x read from "
89 "CMOS RAM was invalid\n", v);
90 }
87 91
88 v &= ~SBF_RESERVED; 92 v &= ~SBF_RESERVED;
89 v &= ~SBF_BOOTING; 93 v &= ~SBF_BOOTING;
@@ -92,7 +96,7 @@ static int __init sbf_init(void)
92 v |= SBF_PNPOS; 96 v |= SBF_PNPOS;
93#endif 97#endif
94 sbf_write(v); 98 sbf_write(v);
99
95 return 0; 100 return 0;
96} 101}
97
98module_init(sbf_init); 102module_init(sbf_init);
diff --git a/arch/x86/kernel/bugs_64.c b/arch/x86/kernel/bugs_64.c
index 9a189cef6404..8f520f93ffd4 100644
--- a/arch/x86/kernel/bugs_64.c
+++ b/arch/x86/kernel/bugs_64.c
@@ -13,7 +13,6 @@
13void __init check_bugs(void) 13void __init check_bugs(void)
14{ 14{
15 identify_cpu(&boot_cpu_data); 15 identify_cpu(&boot_cpu_data);
16 mtrr_bp_init();
17#if !defined(CONFIG_SMP) 16#if !defined(CONFIG_SMP)
18 printk("CPU: "); 17 printk("CPU: ");
19 print_cpu_info(&boot_cpu_data); 18 print_cpu_info(&boot_cpu_data);
diff --git a/arch/x86/kernel/cpu/addon_cpuid_features.c b/arch/x86/kernel/cpu/addon_cpuid_features.c
index 3e91d3ee26ec..238468ae1993 100644
--- a/arch/x86/kernel/cpu/addon_cpuid_features.c
+++ b/arch/x86/kernel/cpu/addon_cpuid_features.c
@@ -45,6 +45,6 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c)
45 &regs[CR_ECX], &regs[CR_EDX]); 45 &regs[CR_ECX], &regs[CR_EDX]);
46 46
47 if (regs[cb->reg] & (1 << cb->bit)) 47 if (regs[cb->reg] & (1 << cb->bit))
48 set_bit(cb->feature, c->x86_capability); 48 set_cpu_cap(c, cb->feature);
49 } 49 }
50} 50}
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index 1ff88c7f45cf..06fa159232fd 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -63,6 +63,15 @@ static __cpuinit int amd_apic_timer_broken(void)
63 63
64int force_mwait __cpuinitdata; 64int force_mwait __cpuinitdata;
65 65
66void __cpuinit early_init_amd(struct cpuinfo_x86 *c)
67{
68 if (cpuid_eax(0x80000000) >= 0x80000007) {
69 c->x86_power = cpuid_edx(0x80000007);
70 if (c->x86_power & (1<<8))
71 set_bit(X86_FEATURE_CONSTANT_TSC, c->x86_capability);
72 }
73}
74
66static void __cpuinit init_amd(struct cpuinfo_x86 *c) 75static void __cpuinit init_amd(struct cpuinfo_x86 *c)
67{ 76{
68 u32 l, h; 77 u32 l, h;
@@ -85,6 +94,8 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
85 } 94 }
86#endif 95#endif
87 96
97 early_init_amd(c);
98
88 /* 99 /*
89 * FIXME: We should handle the K5 here. Set up the write 100 * FIXME: We should handle the K5 here. Set up the write
90 * range and also turn on MSR 83 bits 4 and 31 (write alloc, 101 * range and also turn on MSR 83 bits 4 and 31 (write alloc,
@@ -257,12 +268,6 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
257 c->x86_max_cores = (cpuid_ecx(0x80000008) & 0xff) + 1; 268 c->x86_max_cores = (cpuid_ecx(0x80000008) & 0xff) + 1;
258 } 269 }
259 270
260 if (cpuid_eax(0x80000000) >= 0x80000007) {
261 c->x86_power = cpuid_edx(0x80000007);
262 if (c->x86_power & (1<<8))
263 set_bit(X86_FEATURE_CONSTANT_TSC, c->x86_capability);
264 }
265
266#ifdef CONFIG_X86_HT 271#ifdef CONFIG_X86_HT
267 /* 272 /*
268 * On a AMD multi core setup the lower bits of the APIC id 273 * On a AMD multi core setup the lower bits of the APIC id
@@ -295,12 +300,12 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
295 local_apic_timer_disabled = 1; 300 local_apic_timer_disabled = 1;
296#endif 301#endif
297 302
298 if (c->x86 == 0x10 && !force_mwait)
299 clear_bit(X86_FEATURE_MWAIT, c->x86_capability);
300
301 /* K6s reports MCEs but don't actually have all the MSRs */ 303 /* K6s reports MCEs but don't actually have all the MSRs */
302 if (c->x86 < 6) 304 if (c->x86 < 6)
303 clear_bit(X86_FEATURE_MCE, c->x86_capability); 305 clear_bit(X86_FEATURE_MCE, c->x86_capability);
306
307 if (cpu_has_xmm)
308 set_bit(X86_FEATURE_MFENCE_RDTSC, c->x86_capability);
304} 309}
305 310
306static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 * c, unsigned int size) 311static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 * c, unsigned int size)
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index 205fd5ba57f7..9b95edcfc6ae 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -11,6 +11,7 @@
11#include <linux/utsname.h> 11#include <linux/utsname.h>
12#include <asm/bugs.h> 12#include <asm/bugs.h>
13#include <asm/processor.h> 13#include <asm/processor.h>
14#include <asm/processor-flags.h>
14#include <asm/i387.h> 15#include <asm/i387.h>
15#include <asm/msr.h> 16#include <asm/msr.h>
16#include <asm/paravirt.h> 17#include <asm/paravirt.h>
@@ -35,7 +36,7 @@ __setup("mca-pentium", mca_pentium);
35static int __init no_387(char *s) 36static int __init no_387(char *s)
36{ 37{
37 boot_cpu_data.hard_math = 0; 38 boot_cpu_data.hard_math = 0;
38 write_cr0(0xE | read_cr0()); 39 write_cr0(X86_CR0_TS | X86_CR0_EM | X86_CR0_MP | read_cr0());
39 return 1; 40 return 1;
40} 41}
41 42
@@ -153,7 +154,7 @@ static void __init check_config(void)
153 * If we configured ourselves for a TSC, we'd better have one! 154 * If we configured ourselves for a TSC, we'd better have one!
154 */ 155 */
155#ifdef CONFIG_X86_TSC 156#ifdef CONFIG_X86_TSC
156 if (!cpu_has_tsc && !tsc_disable) 157 if (!cpu_has_tsc)
157 panic("Kernel compiled for Pentium+, requires TSC feature!"); 158 panic("Kernel compiled for Pentium+, requires TSC feature!");
158#endif 159#endif
159 160
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index e2fcf2051bdb..db28aa9e2f69 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -22,43 +22,48 @@
22#include "cpu.h" 22#include "cpu.h"
23 23
24DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = { 24DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = {
25 [GDT_ENTRY_KERNEL_CS] = { 0x0000ffff, 0x00cf9a00 }, 25 [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } },
26 [GDT_ENTRY_KERNEL_DS] = { 0x0000ffff, 0x00cf9200 }, 26 [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9200 } } },
27 [GDT_ENTRY_DEFAULT_USER_CS] = { 0x0000ffff, 0x00cffa00 }, 27 [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00cffa00 } } },
28 [GDT_ENTRY_DEFAULT_USER_DS] = { 0x0000ffff, 0x00cff200 }, 28 [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff200 } } },
29 /* 29 /*
30 * Segments used for calling PnP BIOS have byte granularity. 30 * Segments used for calling PnP BIOS have byte granularity.
31 * They code segments and data segments have fixed 64k limits, 31 * They code segments and data segments have fixed 64k limits,
32 * the transfer segment sizes are set at run time. 32 * the transfer segment sizes are set at run time.
33 */ 33 */
34 [GDT_ENTRY_PNPBIOS_CS32] = { 0x0000ffff, 0x00409a00 },/* 32-bit code */ 34 /* 32-bit code */
35 [GDT_ENTRY_PNPBIOS_CS16] = { 0x0000ffff, 0x00009a00 },/* 16-bit code */ 35 [GDT_ENTRY_PNPBIOS_CS32] = { { { 0x0000ffff, 0x00409a00 } } },
36 [GDT_ENTRY_PNPBIOS_DS] = { 0x0000ffff, 0x00009200 }, /* 16-bit data */ 36 /* 16-bit code */
37 [GDT_ENTRY_PNPBIOS_TS1] = { 0x00000000, 0x00009200 },/* 16-bit data */ 37 [GDT_ENTRY_PNPBIOS_CS16] = { { { 0x0000ffff, 0x00009a00 } } },
38 [GDT_ENTRY_PNPBIOS_TS2] = { 0x00000000, 0x00009200 },/* 16-bit data */ 38 /* 16-bit data */
39 [GDT_ENTRY_PNPBIOS_DS] = { { { 0x0000ffff, 0x00009200 } } },
40 /* 16-bit data */
41 [GDT_ENTRY_PNPBIOS_TS1] = { { { 0x00000000, 0x00009200 } } },
42 /* 16-bit data */
43 [GDT_ENTRY_PNPBIOS_TS2] = { { { 0x00000000, 0x00009200 } } },
39 /* 44 /*
40 * The APM segments have byte granularity and their bases 45 * The APM segments have byte granularity and their bases
41 * are set at run time. All have 64k limits. 46 * are set at run time. All have 64k limits.
42 */ 47 */
43 [GDT_ENTRY_APMBIOS_BASE] = { 0x0000ffff, 0x00409a00 },/* 32-bit code */ 48 /* 32-bit code */
49 [GDT_ENTRY_APMBIOS_BASE] = { { { 0x0000ffff, 0x00409a00 } } },
44 /* 16-bit code */ 50 /* 16-bit code */
45 [GDT_ENTRY_APMBIOS_BASE+1] = { 0x0000ffff, 0x00009a00 }, 51 [GDT_ENTRY_APMBIOS_BASE+1] = { { { 0x0000ffff, 0x00009a00 } } },
46 [GDT_ENTRY_APMBIOS_BASE+2] = { 0x0000ffff, 0x00409200 }, /* data */ 52 /* data */
53 [GDT_ENTRY_APMBIOS_BASE+2] = { { { 0x0000ffff, 0x00409200 } } },
47 54
48 [GDT_ENTRY_ESPFIX_SS] = { 0x00000000, 0x00c09200 }, 55 [GDT_ENTRY_ESPFIX_SS] = { { { 0x00000000, 0x00c09200 } } },
49 [GDT_ENTRY_PERCPU] = { 0x00000000, 0x00000000 }, 56 [GDT_ENTRY_PERCPU] = { { { 0x00000000, 0x00000000 } } },
50} }; 57} };
51EXPORT_PER_CPU_SYMBOL_GPL(gdt_page); 58EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
52 59
60__u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata;
61
53static int cachesize_override __cpuinitdata = -1; 62static int cachesize_override __cpuinitdata = -1;
54static int disable_x86_fxsr __cpuinitdata;
55static int disable_x86_serial_nr __cpuinitdata = 1; 63static int disable_x86_serial_nr __cpuinitdata = 1;
56static int disable_x86_sep __cpuinitdata;
57 64
58struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {}; 65struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {};
59 66
60extern int disable_pse;
61
62static void __cpuinit default_init(struct cpuinfo_x86 * c) 67static void __cpuinit default_init(struct cpuinfo_x86 * c)
63{ 68{
64 /* Not much we can do here... */ 69 /* Not much we can do here... */
@@ -207,16 +212,8 @@ static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c, int early)
207 212
208static int __init x86_fxsr_setup(char * s) 213static int __init x86_fxsr_setup(char * s)
209{ 214{
210 /* Tell all the other CPUs to not use it... */ 215 setup_clear_cpu_cap(X86_FEATURE_FXSR);
211 disable_x86_fxsr = 1; 216 setup_clear_cpu_cap(X86_FEATURE_XMM);
212
213 /*
214 * ... and clear the bits early in the boot_cpu_data
215 * so that the bootup process doesn't try to do this
216 * either.
217 */
218 clear_bit(X86_FEATURE_FXSR, boot_cpu_data.x86_capability);
219 clear_bit(X86_FEATURE_XMM, boot_cpu_data.x86_capability);
220 return 1; 217 return 1;
221} 218}
222__setup("nofxsr", x86_fxsr_setup); 219__setup("nofxsr", x86_fxsr_setup);
@@ -224,7 +221,7 @@ __setup("nofxsr", x86_fxsr_setup);
224 221
225static int __init x86_sep_setup(char * s) 222static int __init x86_sep_setup(char * s)
226{ 223{
227 disable_x86_sep = 1; 224 setup_clear_cpu_cap(X86_FEATURE_SEP);
228 return 1; 225 return 1;
229} 226}
230__setup("nosep", x86_sep_setup); 227__setup("nosep", x86_sep_setup);
@@ -281,6 +278,33 @@ void __init cpu_detect(struct cpuinfo_x86 *c)
281 c->x86_cache_alignment = ((misc >> 8) & 0xff) * 8; 278 c->x86_cache_alignment = ((misc >> 8) & 0xff) * 8;
282 } 279 }
283} 280}
281static void __cpuinit early_get_cap(struct cpuinfo_x86 *c)
282{
283 u32 tfms, xlvl;
284 int ebx;
285
286 memset(&c->x86_capability, 0, sizeof c->x86_capability);
287 if (have_cpuid_p()) {
288 /* Intel-defined flags: level 0x00000001 */
289 if (c->cpuid_level >= 0x00000001) {
290 u32 capability, excap;
291 cpuid(0x00000001, &tfms, &ebx, &excap, &capability);
292 c->x86_capability[0] = capability;
293 c->x86_capability[4] = excap;
294 }
295
296 /* AMD-defined flags: level 0x80000001 */
297 xlvl = cpuid_eax(0x80000000);
298 if ((xlvl & 0xffff0000) == 0x80000000) {
299 if (xlvl >= 0x80000001) {
300 c->x86_capability[1] = cpuid_edx(0x80000001);
301 c->x86_capability[6] = cpuid_ecx(0x80000001);
302 }
303 }
304
305 }
306
307}
284 308
285/* Do minimum CPU detection early. 309/* Do minimum CPU detection early.
286 Fields really needed: vendor, cpuid_level, family, model, mask, cache alignment. 310 Fields really needed: vendor, cpuid_level, family, model, mask, cache alignment.
@@ -300,6 +324,17 @@ static void __init early_cpu_detect(void)
300 cpu_detect(c); 324 cpu_detect(c);
301 325
302 get_cpu_vendor(c, 1); 326 get_cpu_vendor(c, 1);
327
328 switch (c->x86_vendor) {
329 case X86_VENDOR_AMD:
330 early_init_amd(c);
331 break;
332 case X86_VENDOR_INTEL:
333 early_init_intel(c);
334 break;
335 }
336
337 early_get_cap(c);
303} 338}
304 339
305static void __cpuinit generic_identify(struct cpuinfo_x86 * c) 340static void __cpuinit generic_identify(struct cpuinfo_x86 * c)
@@ -357,8 +392,6 @@ static void __cpuinit generic_identify(struct cpuinfo_x86 * c)
357 init_scattered_cpuid_features(c); 392 init_scattered_cpuid_features(c);
358 } 393 }
359 394
360 early_intel_workaround(c);
361
362#ifdef CONFIG_X86_HT 395#ifdef CONFIG_X86_HT
363 c->phys_proc_id = (cpuid_ebx(1) >> 24) & 0xff; 396 c->phys_proc_id = (cpuid_ebx(1) >> 24) & 0xff;
364#endif 397#endif
@@ -392,7 +425,7 @@ __setup("serialnumber", x86_serial_nr_setup);
392/* 425/*
393 * This does the hard work of actually picking apart the CPU stuff... 426 * This does the hard work of actually picking apart the CPU stuff...
394 */ 427 */
395static void __cpuinit identify_cpu(struct cpuinfo_x86 *c) 428void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
396{ 429{
397 int i; 430 int i;
398 431
@@ -418,20 +451,9 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
418 451
419 generic_identify(c); 452 generic_identify(c);
420 453
421 printk(KERN_DEBUG "CPU: After generic identify, caps:"); 454 if (this_cpu->c_identify)
422 for (i = 0; i < NCAPINTS; i++)
423 printk(" %08lx", c->x86_capability[i]);
424 printk("\n");
425
426 if (this_cpu->c_identify) {
427 this_cpu->c_identify(c); 455 this_cpu->c_identify(c);
428 456
429 printk(KERN_DEBUG "CPU: After vendor identify, caps:");
430 for (i = 0; i < NCAPINTS; i++)
431 printk(" %08lx", c->x86_capability[i]);
432 printk("\n");
433 }
434
435 /* 457 /*
436 * Vendor-specific initialization. In this section we 458 * Vendor-specific initialization. In this section we
437 * canonicalize the feature flags, meaning if there are 459 * canonicalize the feature flags, meaning if there are
@@ -453,23 +475,6 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
453 * we do "generic changes." 475 * we do "generic changes."
454 */ 476 */
455 477
456 /* TSC disabled? */
457 if ( tsc_disable )
458 clear_bit(X86_FEATURE_TSC, c->x86_capability);
459
460 /* FXSR disabled? */
461 if (disable_x86_fxsr) {
462 clear_bit(X86_FEATURE_FXSR, c->x86_capability);
463 clear_bit(X86_FEATURE_XMM, c->x86_capability);
464 }
465
466 /* SEP disabled? */
467 if (disable_x86_sep)
468 clear_bit(X86_FEATURE_SEP, c->x86_capability);
469
470 if (disable_pse)
471 clear_bit(X86_FEATURE_PSE, c->x86_capability);
472
473 /* If the model name is still unset, do table lookup. */ 478 /* If the model name is still unset, do table lookup. */
474 if ( !c->x86_model_id[0] ) { 479 if ( !c->x86_model_id[0] ) {
475 char *p; 480 char *p;
@@ -482,13 +487,6 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
482 c->x86, c->x86_model); 487 c->x86, c->x86_model);
483 } 488 }
484 489
485 /* Now the feature flags better reflect actual CPU features! */
486
487 printk(KERN_DEBUG "CPU: After all inits, caps:");
488 for (i = 0; i < NCAPINTS; i++)
489 printk(" %08lx", c->x86_capability[i]);
490 printk("\n");
491
492 /* 490 /*
493 * On SMP, boot_cpu_data holds the common feature set between 491 * On SMP, boot_cpu_data holds the common feature set between
494 * all CPUs; so make sure that we indicate which features are 492 * all CPUs; so make sure that we indicate which features are
@@ -501,8 +499,14 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
501 boot_cpu_data.x86_capability[i] &= c->x86_capability[i]; 499 boot_cpu_data.x86_capability[i] &= c->x86_capability[i];
502 } 500 }
503 501
502 /* Clear all flags overriden by options */
503 for (i = 0; i < NCAPINTS; i++)
504 c->x86_capability[i] ^= cleared_cpu_caps[i];
505
504 /* Init Machine Check Exception if available. */ 506 /* Init Machine Check Exception if available. */
505 mcheck_init(c); 507 mcheck_init(c);
508
509 select_idle_routine(c);
506} 510}
507 511
508void __init identify_boot_cpu(void) 512void __init identify_boot_cpu(void)
@@ -510,7 +514,6 @@ void __init identify_boot_cpu(void)
510 identify_cpu(&boot_cpu_data); 514 identify_cpu(&boot_cpu_data);
511 sysenter_setup(); 515 sysenter_setup();
512 enable_sep_cpu(); 516 enable_sep_cpu();
513 mtrr_bp_init();
514} 517}
515 518
516void __cpuinit identify_secondary_cpu(struct cpuinfo_x86 *c) 519void __cpuinit identify_secondary_cpu(struct cpuinfo_x86 *c)
@@ -567,6 +570,13 @@ void __cpuinit detect_ht(struct cpuinfo_x86 *c)
567} 570}
568#endif 571#endif
569 572
573static __init int setup_noclflush(char *arg)
574{
575 setup_clear_cpu_cap(X86_FEATURE_CLFLSH);
576 return 1;
577}
578__setup("noclflush", setup_noclflush);
579
570void __cpuinit print_cpu_info(struct cpuinfo_x86 *c) 580void __cpuinit print_cpu_info(struct cpuinfo_x86 *c)
571{ 581{
572 char *vendor = NULL; 582 char *vendor = NULL;
@@ -590,6 +600,17 @@ void __cpuinit print_cpu_info(struct cpuinfo_x86 *c)
590 printk("\n"); 600 printk("\n");
591} 601}
592 602
603static __init int setup_disablecpuid(char *arg)
604{
605 int bit;
606 if (get_option(&arg, &bit) && bit < NCAPINTS*32)
607 setup_clear_cpu_cap(bit);
608 else
609 return 0;
610 return 1;
611}
612__setup("clearcpuid=", setup_disablecpuid);
613
593cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE; 614cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE;
594 615
595/* This is hacky. :) 616/* This is hacky. :)
@@ -620,21 +641,13 @@ void __init early_cpu_init(void)
620 nexgen_init_cpu(); 641 nexgen_init_cpu();
621 umc_init_cpu(); 642 umc_init_cpu();
622 early_cpu_detect(); 643 early_cpu_detect();
623
624#ifdef CONFIG_DEBUG_PAGEALLOC
625 /* pse is not compatible with on-the-fly unmapping,
626 * disable it even if the cpus claim to support it.
627 */
628 clear_bit(X86_FEATURE_PSE, boot_cpu_data.x86_capability);
629 disable_pse = 1;
630#endif
631} 644}
632 645
633/* Make sure %fs is initialized properly in idle threads */ 646/* Make sure %fs is initialized properly in idle threads */
634struct pt_regs * __devinit idle_regs(struct pt_regs *regs) 647struct pt_regs * __devinit idle_regs(struct pt_regs *regs)
635{ 648{
636 memset(regs, 0, sizeof(struct pt_regs)); 649 memset(regs, 0, sizeof(struct pt_regs));
637 regs->xfs = __KERNEL_PERCPU; 650 regs->fs = __KERNEL_PERCPU;
638 return regs; 651 return regs;
639} 652}
640 653
@@ -642,7 +655,7 @@ struct pt_regs * __devinit idle_regs(struct pt_regs *regs)
642 * it's on the real one. */ 655 * it's on the real one. */
643void switch_to_new_gdt(void) 656void switch_to_new_gdt(void)
644{ 657{
645 struct Xgt_desc_struct gdt_descr; 658 struct desc_ptr gdt_descr;
646 659
647 gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id()); 660 gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id());
648 gdt_descr.size = GDT_SIZE - 1; 661 gdt_descr.size = GDT_SIZE - 1;
@@ -672,12 +685,6 @@ void __cpuinit cpu_init(void)
672 685
673 if (cpu_has_vme || cpu_has_tsc || cpu_has_de) 686 if (cpu_has_vme || cpu_has_tsc || cpu_has_de)
674 clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE); 687 clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
675 if (tsc_disable && cpu_has_tsc) {
676 printk(KERN_NOTICE "Disabling TSC...\n");
677 /**** FIX-HPA: DOES THIS REALLY BELONG HERE? ****/
678 clear_bit(X86_FEATURE_TSC, boot_cpu_data.x86_capability);
679 set_in_cr4(X86_CR4_TSD);
680 }
681 688
682 load_idt(&idt_descr); 689 load_idt(&idt_descr);
683 switch_to_new_gdt(); 690 switch_to_new_gdt();
@@ -691,7 +698,7 @@ void __cpuinit cpu_init(void)
691 BUG(); 698 BUG();
692 enter_lazy_tlb(&init_mm, curr); 699 enter_lazy_tlb(&init_mm, curr);
693 700
694 load_esp0(t, thread); 701 load_sp0(t, thread);
695 set_tss_desc(cpu,t); 702 set_tss_desc(cpu,t);
696 load_TR_desc(); 703 load_TR_desc();
697 load_LDT(&init_mm.context); 704 load_LDT(&init_mm.context);
diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h
index 2f6432cef6ff..ad6527a5beb1 100644
--- a/arch/x86/kernel/cpu/cpu.h
+++ b/arch/x86/kernel/cpu/cpu.h
@@ -24,5 +24,6 @@ extern struct cpu_dev * cpu_devs [X86_VENDOR_NUM];
24extern int get_model_name(struct cpuinfo_x86 *c); 24extern int get_model_name(struct cpuinfo_x86 *c);
25extern void display_cacheinfo(struct cpuinfo_x86 *c); 25extern void display_cacheinfo(struct cpuinfo_x86 *c);
26 26
27extern void early_intel_workaround(struct cpuinfo_x86 *c); 27extern void early_init_intel(struct cpuinfo_x86 *c);
28extern void early_init_amd(struct cpuinfo_x86 *c);
28 29
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
index fea0af0476b9..a962dcb9c408 100644
--- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -67,7 +67,8 @@ struct acpi_cpufreq_data {
67 unsigned int cpu_feature; 67 unsigned int cpu_feature;
68}; 68};
69 69
70static struct acpi_cpufreq_data *drv_data[NR_CPUS]; 70static DEFINE_PER_CPU(struct acpi_cpufreq_data *, drv_data);
71
71/* acpi_perf_data is a pointer to percpu data. */ 72/* acpi_perf_data is a pointer to percpu data. */
72static struct acpi_processor_performance *acpi_perf_data; 73static struct acpi_processor_performance *acpi_perf_data;
73 74
@@ -218,14 +219,14 @@ static u32 get_cur_val(cpumask_t mask)
218 if (unlikely(cpus_empty(mask))) 219 if (unlikely(cpus_empty(mask)))
219 return 0; 220 return 0;
220 221
221 switch (drv_data[first_cpu(mask)]->cpu_feature) { 222 switch (per_cpu(drv_data, first_cpu(mask))->cpu_feature) {
222 case SYSTEM_INTEL_MSR_CAPABLE: 223 case SYSTEM_INTEL_MSR_CAPABLE:
223 cmd.type = SYSTEM_INTEL_MSR_CAPABLE; 224 cmd.type = SYSTEM_INTEL_MSR_CAPABLE;
224 cmd.addr.msr.reg = MSR_IA32_PERF_STATUS; 225 cmd.addr.msr.reg = MSR_IA32_PERF_STATUS;
225 break; 226 break;
226 case SYSTEM_IO_CAPABLE: 227 case SYSTEM_IO_CAPABLE:
227 cmd.type = SYSTEM_IO_CAPABLE; 228 cmd.type = SYSTEM_IO_CAPABLE;
228 perf = drv_data[first_cpu(mask)]->acpi_data; 229 perf = per_cpu(drv_data, first_cpu(mask))->acpi_data;
229 cmd.addr.io.port = perf->control_register.address; 230 cmd.addr.io.port = perf->control_register.address;
230 cmd.addr.io.bit_width = perf->control_register.bit_width; 231 cmd.addr.io.bit_width = perf->control_register.bit_width;
231 break; 232 break;
@@ -325,7 +326,7 @@ static unsigned int get_measured_perf(unsigned int cpu)
325 326
326#endif 327#endif
327 328
328 retval = drv_data[cpu]->max_freq * perf_percent / 100; 329 retval = per_cpu(drv_data, cpu)->max_freq * perf_percent / 100;
329 330
330 put_cpu(); 331 put_cpu();
331 set_cpus_allowed(current, saved_mask); 332 set_cpus_allowed(current, saved_mask);
@@ -336,7 +337,7 @@ static unsigned int get_measured_perf(unsigned int cpu)
336 337
337static unsigned int get_cur_freq_on_cpu(unsigned int cpu) 338static unsigned int get_cur_freq_on_cpu(unsigned int cpu)
338{ 339{
339 struct acpi_cpufreq_data *data = drv_data[cpu]; 340 struct acpi_cpufreq_data *data = per_cpu(drv_data, cpu);
340 unsigned int freq; 341 unsigned int freq;
341 342
342 dprintk("get_cur_freq_on_cpu (%d)\n", cpu); 343 dprintk("get_cur_freq_on_cpu (%d)\n", cpu);
@@ -370,7 +371,7 @@ static unsigned int check_freqs(cpumask_t mask, unsigned int freq,
370static int acpi_cpufreq_target(struct cpufreq_policy *policy, 371static int acpi_cpufreq_target(struct cpufreq_policy *policy,
371 unsigned int target_freq, unsigned int relation) 372 unsigned int target_freq, unsigned int relation)
372{ 373{
373 struct acpi_cpufreq_data *data = drv_data[policy->cpu]; 374 struct acpi_cpufreq_data *data = per_cpu(drv_data, policy->cpu);
374 struct acpi_processor_performance *perf; 375 struct acpi_processor_performance *perf;
375 struct cpufreq_freqs freqs; 376 struct cpufreq_freqs freqs;
376 cpumask_t online_policy_cpus; 377 cpumask_t online_policy_cpus;
@@ -466,7 +467,7 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy,
466 467
467static int acpi_cpufreq_verify(struct cpufreq_policy *policy) 468static int acpi_cpufreq_verify(struct cpufreq_policy *policy)
468{ 469{
469 struct acpi_cpufreq_data *data = drv_data[policy->cpu]; 470 struct acpi_cpufreq_data *data = per_cpu(drv_data, policy->cpu);
470 471
471 dprintk("acpi_cpufreq_verify\n"); 472 dprintk("acpi_cpufreq_verify\n");
472 473
@@ -570,7 +571,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
570 return -ENOMEM; 571 return -ENOMEM;
571 572
572 data->acpi_data = percpu_ptr(acpi_perf_data, cpu); 573 data->acpi_data = percpu_ptr(acpi_perf_data, cpu);
573 drv_data[cpu] = data; 574 per_cpu(drv_data, cpu) = data;
574 575
575 if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) 576 if (cpu_has(c, X86_FEATURE_CONSTANT_TSC))
576 acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS; 577 acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS;
@@ -714,20 +715,20 @@ err_unreg:
714 acpi_processor_unregister_performance(perf, cpu); 715 acpi_processor_unregister_performance(perf, cpu);
715err_free: 716err_free:
716 kfree(data); 717 kfree(data);
717 drv_data[cpu] = NULL; 718 per_cpu(drv_data, cpu) = NULL;
718 719
719 return result; 720 return result;
720} 721}
721 722
722static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy) 723static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy)
723{ 724{
724 struct acpi_cpufreq_data *data = drv_data[policy->cpu]; 725 struct acpi_cpufreq_data *data = per_cpu(drv_data, policy->cpu);
725 726
726 dprintk("acpi_cpufreq_cpu_exit\n"); 727 dprintk("acpi_cpufreq_cpu_exit\n");
727 728
728 if (data) { 729 if (data) {
729 cpufreq_frequency_table_put_attr(policy->cpu); 730 cpufreq_frequency_table_put_attr(policy->cpu);
730 drv_data[policy->cpu] = NULL; 731 per_cpu(drv_data, policy->cpu) = NULL;
731 acpi_processor_unregister_performance(data->acpi_data, 732 acpi_processor_unregister_performance(data->acpi_data,
732 policy->cpu); 733 policy->cpu);
733 kfree(data); 734 kfree(data);
@@ -738,7 +739,7 @@ static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy)
738 739
739static int acpi_cpufreq_resume(struct cpufreq_policy *policy) 740static int acpi_cpufreq_resume(struct cpufreq_policy *policy)
740{ 741{
741 struct acpi_cpufreq_data *data = drv_data[policy->cpu]; 742 struct acpi_cpufreq_data *data = per_cpu(drv_data, policy->cpu);
742 743
743 dprintk("acpi_cpufreq_resume\n"); 744 dprintk("acpi_cpufreq_resume\n");
744 745
diff --git a/arch/x86/kernel/cpu/cpufreq/longhaul.c b/arch/x86/kernel/cpu/cpufreq/longhaul.c
index 749d00cb2ebd..06fcce516d51 100644
--- a/arch/x86/kernel/cpu/cpufreq/longhaul.c
+++ b/arch/x86/kernel/cpu/cpufreq/longhaul.c
@@ -694,7 +694,7 @@ static acpi_status longhaul_walk_callback(acpi_handle obj_handle,
694 if ( acpi_bus_get_device(obj_handle, &d) ) { 694 if ( acpi_bus_get_device(obj_handle, &d) ) {
695 return 0; 695 return 0;
696 } 696 }
697 *return_value = (void *)acpi_driver_data(d); 697 *return_value = acpi_driver_data(d);
698 return 1; 698 return 1;
699} 699}
700 700
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
index 99e1ef9939be..a0522735dd9d 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
@@ -52,7 +52,7 @@
52/* serialize freq changes */ 52/* serialize freq changes */
53static DEFINE_MUTEX(fidvid_mutex); 53static DEFINE_MUTEX(fidvid_mutex);
54 54
55static struct powernow_k8_data *powernow_data[NR_CPUS]; 55static DEFINE_PER_CPU(struct powernow_k8_data *, powernow_data);
56 56
57static int cpu_family = CPU_OPTERON; 57static int cpu_family = CPU_OPTERON;
58 58
@@ -1018,7 +1018,7 @@ static int transition_frequency_pstate(struct powernow_k8_data *data, unsigned i
1018static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsigned relation) 1018static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsigned relation)
1019{ 1019{
1020 cpumask_t oldmask = CPU_MASK_ALL; 1020 cpumask_t oldmask = CPU_MASK_ALL;
1021 struct powernow_k8_data *data = powernow_data[pol->cpu]; 1021 struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu);
1022 u32 checkfid; 1022 u32 checkfid;
1023 u32 checkvid; 1023 u32 checkvid;
1024 unsigned int newstate; 1024 unsigned int newstate;
@@ -1094,7 +1094,7 @@ err_out:
1094/* Driver entry point to verify the policy and range of frequencies */ 1094/* Driver entry point to verify the policy and range of frequencies */
1095static int powernowk8_verify(struct cpufreq_policy *pol) 1095static int powernowk8_verify(struct cpufreq_policy *pol)
1096{ 1096{
1097 struct powernow_k8_data *data = powernow_data[pol->cpu]; 1097 struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu);
1098 1098
1099 if (!data) 1099 if (!data)
1100 return -EINVAL; 1100 return -EINVAL;
@@ -1202,7 +1202,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
1202 dprintk("cpu_init done, current fid 0x%x, vid 0x%x\n", 1202 dprintk("cpu_init done, current fid 0x%x, vid 0x%x\n",
1203 data->currfid, data->currvid); 1203 data->currfid, data->currvid);
1204 1204
1205 powernow_data[pol->cpu] = data; 1205 per_cpu(powernow_data, pol->cpu) = data;
1206 1206
1207 return 0; 1207 return 0;
1208 1208
@@ -1216,7 +1216,7 @@ err_out:
1216 1216
1217static int __devexit powernowk8_cpu_exit (struct cpufreq_policy *pol) 1217static int __devexit powernowk8_cpu_exit (struct cpufreq_policy *pol)
1218{ 1218{
1219 struct powernow_k8_data *data = powernow_data[pol->cpu]; 1219 struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu);
1220 1220
1221 if (!data) 1221 if (!data)
1222 return -EINVAL; 1222 return -EINVAL;
@@ -1237,7 +1237,7 @@ static unsigned int powernowk8_get (unsigned int cpu)
1237 cpumask_t oldmask = current->cpus_allowed; 1237 cpumask_t oldmask = current->cpus_allowed;
1238 unsigned int khz = 0; 1238 unsigned int khz = 0;
1239 1239
1240 data = powernow_data[first_cpu(per_cpu(cpu_core_map, cpu))]; 1240 data = per_cpu(powernow_data, first_cpu(per_cpu(cpu_core_map, cpu)));
1241 1241
1242 if (!data) 1242 if (!data)
1243 return -EINVAL; 1243 return -EINVAL;
diff --git a/arch/x86/kernel/cpu/cyrix.c b/arch/x86/kernel/cpu/cyrix.c
index 88d66fb8411d..404a6a2d4016 100644
--- a/arch/x86/kernel/cpu/cyrix.c
+++ b/arch/x86/kernel/cpu/cyrix.c
@@ -5,6 +5,7 @@
5#include <asm/dma.h> 5#include <asm/dma.h>
6#include <asm/io.h> 6#include <asm/io.h>
7#include <asm/processor-cyrix.h> 7#include <asm/processor-cyrix.h>
8#include <asm/processor-flags.h>
8#include <asm/timer.h> 9#include <asm/timer.h>
9#include <asm/pci-direct.h> 10#include <asm/pci-direct.h>
10#include <asm/tsc.h> 11#include <asm/tsc.h>
@@ -126,15 +127,12 @@ static void __cpuinit set_cx86_reorder(void)
126 127
127static void __cpuinit set_cx86_memwb(void) 128static void __cpuinit set_cx86_memwb(void)
128{ 129{
129 u32 cr0;
130
131 printk(KERN_INFO "Enable Memory-Write-back mode on Cyrix/NSC processor.\n"); 130 printk(KERN_INFO "Enable Memory-Write-back mode on Cyrix/NSC processor.\n");
132 131
133 /* CCR2 bit 2: unlock NW bit */ 132 /* CCR2 bit 2: unlock NW bit */
134 setCx86(CX86_CCR2, getCx86(CX86_CCR2) & ~0x04); 133 setCx86(CX86_CCR2, getCx86(CX86_CCR2) & ~0x04);
135 /* set 'Not Write-through' */ 134 /* set 'Not Write-through' */
136 cr0 = 0x20000000; 135 write_cr0(read_cr0() | X86_CR0_NW);
137 write_cr0(read_cr0() | cr0);
138 /* CCR2 bit 2: lock NW bit and set WT1 */ 136 /* CCR2 bit 2: lock NW bit and set WT1 */
139 setCx86(CX86_CCR2, getCx86(CX86_CCR2) | 0x14 ); 137 setCx86(CX86_CCR2, getCx86(CX86_CCR2) | 0x14 );
140} 138}
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index cc8c501b9f39..d1c372b018db 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -11,6 +11,8 @@
11#include <asm/pgtable.h> 11#include <asm/pgtable.h>
12#include <asm/msr.h> 12#include <asm/msr.h>
13#include <asm/uaccess.h> 13#include <asm/uaccess.h>
14#include <asm/ptrace.h>
15#include <asm/ds.h>
14 16
15#include "cpu.h" 17#include "cpu.h"
16 18
@@ -27,13 +29,14 @@
27struct movsl_mask movsl_mask __read_mostly; 29struct movsl_mask movsl_mask __read_mostly;
28#endif 30#endif
29 31
30void __cpuinit early_intel_workaround(struct cpuinfo_x86 *c) 32void __cpuinit early_init_intel(struct cpuinfo_x86 *c)
31{ 33{
32 if (c->x86_vendor != X86_VENDOR_INTEL)
33 return;
34 /* Netburst reports 64 bytes clflush size, but does IO in 128 bytes */ 34 /* Netburst reports 64 bytes clflush size, but does IO in 128 bytes */
35 if (c->x86 == 15 && c->x86_cache_alignment == 64) 35 if (c->x86 == 15 && c->x86_cache_alignment == 64)
36 c->x86_cache_alignment = 128; 36 c->x86_cache_alignment = 128;
37 if ((c->x86 == 0xf && c->x86_model >= 0x03) ||
38 (c->x86 == 0x6 && c->x86_model >= 0x0e))
39 set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
37} 40}
38 41
39/* 42/*
@@ -113,6 +116,8 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
113 unsigned int l2 = 0; 116 unsigned int l2 = 0;
114 char *p = NULL; 117 char *p = NULL;
115 118
119 early_init_intel(c);
120
116#ifdef CONFIG_X86_F00F_BUG 121#ifdef CONFIG_X86_F00F_BUG
117 /* 122 /*
118 * All current models of Pentium and Pentium with MMX technology CPUs 123 * All current models of Pentium and Pentium with MMX technology CPUs
@@ -132,7 +137,6 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
132 } 137 }
133#endif 138#endif
134 139
135 select_idle_routine(c);
136 l2 = init_intel_cacheinfo(c); 140 l2 = init_intel_cacheinfo(c);
137 if (c->cpuid_level > 9 ) { 141 if (c->cpuid_level > 9 ) {
138 unsigned eax = cpuid_eax(10); 142 unsigned eax = cpuid_eax(10);
@@ -201,16 +205,13 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
201 } 205 }
202#endif 206#endif
203 207
208 if (cpu_has_xmm2)
209 set_bit(X86_FEATURE_LFENCE_RDTSC, c->x86_capability);
204 if (c->x86 == 15) { 210 if (c->x86 == 15) {
205 set_bit(X86_FEATURE_P4, c->x86_capability); 211 set_bit(X86_FEATURE_P4, c->x86_capability);
206 set_bit(X86_FEATURE_SYNC_RDTSC, c->x86_capability);
207 } 212 }
208 if (c->x86 == 6) 213 if (c->x86 == 6)
209 set_bit(X86_FEATURE_P3, c->x86_capability); 214 set_bit(X86_FEATURE_P3, c->x86_capability);
210 if ((c->x86 == 0xf && c->x86_model >= 0x03) ||
211 (c->x86 == 0x6 && c->x86_model >= 0x0e))
212 set_bit(X86_FEATURE_CONSTANT_TSC, c->x86_capability);
213
214 if (cpu_has_ds) { 215 if (cpu_has_ds) {
215 unsigned int l1; 216 unsigned int l1;
216 rdmsr(MSR_IA32_MISC_ENABLE, l1, l2); 217 rdmsr(MSR_IA32_MISC_ENABLE, l1, l2);
@@ -219,6 +220,9 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
219 if (!(l1 & (1<<12))) 220 if (!(l1 & (1<<12)))
220 set_bit(X86_FEATURE_PEBS, c->x86_capability); 221 set_bit(X86_FEATURE_PEBS, c->x86_capability);
221 } 222 }
223
224 if (cpu_has_bts)
225 ds_init_intel(c);
222} 226}
223 227
224static unsigned int __cpuinit intel_size_cache(struct cpuinfo_x86 * c, unsigned int size) 228static unsigned int __cpuinit intel_size_cache(struct cpuinfo_x86 * c, unsigned int size)
@@ -342,5 +346,22 @@ unsigned long cmpxchg_386_u32(volatile void *ptr, u32 old, u32 new)
342EXPORT_SYMBOL(cmpxchg_386_u32); 346EXPORT_SYMBOL(cmpxchg_386_u32);
343#endif 347#endif
344 348
349#ifndef CONFIG_X86_CMPXCHG64
350unsigned long long cmpxchg_486_u64(volatile void *ptr, u64 old, u64 new)
351{
352 u64 prev;
353 unsigned long flags;
354
355 /* Poor man's cmpxchg8b for 386 and 486. Unsuitable for SMP */
356 local_irq_save(flags);
357 prev = *(u64 *)ptr;
358 if (prev == old)
359 *(u64 *)ptr = new;
360 local_irq_restore(flags);
361 return prev;
362}
363EXPORT_SYMBOL(cmpxchg_486_u64);
364#endif
365
345// arch_initcall(intel_cpu_init); 366// arch_initcall(intel_cpu_init);
346 367
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c
index 9f530ff43c21..8b4507b8469b 100644
--- a/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ b/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -733,10 +733,8 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
733 if (unlikely(retval < 0)) 733 if (unlikely(retval < 0))
734 return retval; 734 return retval;
735 735
736 cache_kobject[cpu]->parent = &sys_dev->kobj; 736 retval = kobject_init_and_add(cache_kobject[cpu], &ktype_percpu_entry,
737 kobject_set_name(cache_kobject[cpu], "%s", "cache"); 737 &sys_dev->kobj, "%s", "cache");
738 cache_kobject[cpu]->ktype = &ktype_percpu_entry;
739 retval = kobject_register(cache_kobject[cpu]);
740 if (retval < 0) { 738 if (retval < 0) {
741 cpuid4_cache_sysfs_exit(cpu); 739 cpuid4_cache_sysfs_exit(cpu);
742 return retval; 740 return retval;
@@ -746,23 +744,23 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
746 this_object = INDEX_KOBJECT_PTR(cpu,i); 744 this_object = INDEX_KOBJECT_PTR(cpu,i);
747 this_object->cpu = cpu; 745 this_object->cpu = cpu;
748 this_object->index = i; 746 this_object->index = i;
749 this_object->kobj.parent = cache_kobject[cpu]; 747 retval = kobject_init_and_add(&(this_object->kobj),
750 kobject_set_name(&(this_object->kobj), "index%1lu", i); 748 &ktype_cache, cache_kobject[cpu],
751 this_object->kobj.ktype = &ktype_cache; 749 "index%1lu", i);
752 retval = kobject_register(&(this_object->kobj));
753 if (unlikely(retval)) { 750 if (unlikely(retval)) {
754 for (j = 0; j < i; j++) { 751 for (j = 0; j < i; j++) {
755 kobject_unregister( 752 kobject_put(&(INDEX_KOBJECT_PTR(cpu,j)->kobj));
756 &(INDEX_KOBJECT_PTR(cpu,j)->kobj));
757 } 753 }
758 kobject_unregister(cache_kobject[cpu]); 754 kobject_put(cache_kobject[cpu]);
759 cpuid4_cache_sysfs_exit(cpu); 755 cpuid4_cache_sysfs_exit(cpu);
760 break; 756 break;
761 } 757 }
758 kobject_uevent(&(this_object->kobj), KOBJ_ADD);
762 } 759 }
763 if (!retval) 760 if (!retval)
764 cpu_set(cpu, cache_dev_map); 761 cpu_set(cpu, cache_dev_map);
765 762
763 kobject_uevent(cache_kobject[cpu], KOBJ_ADD);
766 return retval; 764 return retval;
767} 765}
768 766
@@ -778,8 +776,8 @@ static void __cpuinit cache_remove_dev(struct sys_device * sys_dev)
778 cpu_clear(cpu, cache_dev_map); 776 cpu_clear(cpu, cache_dev_map);
779 777
780 for (i = 0; i < num_cache_leaves; i++) 778 for (i = 0; i < num_cache_leaves; i++)
781 kobject_unregister(&(INDEX_KOBJECT_PTR(cpu,i)->kobj)); 779 kobject_put(&(INDEX_KOBJECT_PTR(cpu,i)->kobj));
782 kobject_unregister(cache_kobject[cpu]); 780 kobject_put(cache_kobject[cpu]);
783 cpuid4_cache_sysfs_exit(cpu); 781 cpuid4_cache_sysfs_exit(cpu);
784} 782}
785 783
diff --git a/arch/x86/kernel/cpu/mcheck/k7.c b/arch/x86/kernel/cpu/mcheck/k7.c
index eef63e3630c2..e633c9c2b764 100644
--- a/arch/x86/kernel/cpu/mcheck/k7.c
+++ b/arch/x86/kernel/cpu/mcheck/k7.c
@@ -16,7 +16,7 @@
16#include "mce.h" 16#include "mce.h"
17 17
18/* Machine Check Handler For AMD Athlon/Duron */ 18/* Machine Check Handler For AMD Athlon/Duron */
19static fastcall void k7_machine_check(struct pt_regs * regs, long error_code) 19static void k7_machine_check(struct pt_regs * regs, long error_code)
20{ 20{
21 int recover=1; 21 int recover=1;
22 u32 alow, ahigh, high, low; 22 u32 alow, ahigh, high, low;
@@ -27,29 +27,32 @@ static fastcall void k7_machine_check(struct pt_regs * regs, long error_code)
27 if (mcgstl & (1<<0)) /* Recoverable ? */ 27 if (mcgstl & (1<<0)) /* Recoverable ? */
28 recover=0; 28 recover=0;
29 29
30 printk (KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n", 30 printk(KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n",
31 smp_processor_id(), mcgsth, mcgstl); 31 smp_processor_id(), mcgsth, mcgstl);
32 32
33 for (i=1; i<nr_mce_banks; i++) { 33 for (i = 1; i < nr_mce_banks; i++) {
34 rdmsr (MSR_IA32_MC0_STATUS+i*4,low, high); 34 rdmsr(MSR_IA32_MC0_STATUS+i*4, low, high);
35 if (high&(1<<31)) { 35 if (high&(1<<31)) {
36 char misc[20];
37 char addr[24];
38 misc[0] = addr[0] = '\0';
36 if (high & (1<<29)) 39 if (high & (1<<29))
37 recover |= 1; 40 recover |= 1;
38 if (high & (1<<25)) 41 if (high & (1<<25))
39 recover |= 2; 42 recover |= 2;
40 printk (KERN_EMERG "Bank %d: %08x%08x", i, high, low);
41 high &= ~(1<<31); 43 high &= ~(1<<31);
42 if (high & (1<<27)) { 44 if (high & (1<<27)) {
43 rdmsr (MSR_IA32_MC0_MISC+i*4, alow, ahigh); 45 rdmsr(MSR_IA32_MC0_MISC+i*4, alow, ahigh);
44 printk ("[%08x%08x]", ahigh, alow); 46 snprintf(misc, 20, "[%08x%08x]", ahigh, alow);
45 } 47 }
46 if (high & (1<<26)) { 48 if (high & (1<<26)) {
47 rdmsr (MSR_IA32_MC0_ADDR+i*4, alow, ahigh); 49 rdmsr(MSR_IA32_MC0_ADDR+i*4, alow, ahigh);
48 printk (" at %08x%08x", ahigh, alow); 50 snprintf(addr, 24, " at %08x%08x", ahigh, alow);
49 } 51 }
50 printk ("\n"); 52 printk(KERN_EMERG "CPU %d: Bank %d: %08x%08x%s%s\n",
53 smp_processor_id(), i, high, low, misc, addr);
51 /* Clear it */ 54 /* Clear it */
52 wrmsr (MSR_IA32_MC0_STATUS+i*4, 0UL, 0UL); 55 wrmsr(MSR_IA32_MC0_STATUS+i*4, 0UL, 0UL);
53 /* Serialize */ 56 /* Serialize */
54 wmb(); 57 wmb();
55 add_taint(TAINT_MACHINE_CHECK); 58 add_taint(TAINT_MACHINE_CHECK);
diff --git a/arch/x86/kernel/cpu/mcheck/mce.h b/arch/x86/kernel/cpu/mcheck/mce.h
index 81fb6e2d35f3..ae9f628838f1 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.h
+++ b/arch/x86/kernel/cpu/mcheck/mce.h
@@ -8,7 +8,7 @@ void intel_p6_mcheck_init(struct cpuinfo_x86 *c);
8void winchip_mcheck_init(struct cpuinfo_x86 *c); 8void winchip_mcheck_init(struct cpuinfo_x86 *c);
9 9
10/* Call the installed machine check handler for this CPU setup. */ 10/* Call the installed machine check handler for this CPU setup. */
11extern fastcall void (*machine_check_vector)(struct pt_regs *, long error_code); 11extern void (*machine_check_vector)(struct pt_regs *, long error_code);
12 12
13extern int nr_mce_banks; 13extern int nr_mce_banks;
14 14
diff --git a/arch/x86/kernel/cpu/mcheck/mce_32.c b/arch/x86/kernel/cpu/mcheck/mce_32.c
index 34c781eddee4..a5182dcd94ae 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_32.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_32.c
@@ -22,13 +22,13 @@ int nr_mce_banks;
22EXPORT_SYMBOL_GPL(nr_mce_banks); /* non-fatal.o */ 22EXPORT_SYMBOL_GPL(nr_mce_banks); /* non-fatal.o */
23 23
24/* Handle unconfigured int18 (should never happen) */ 24/* Handle unconfigured int18 (should never happen) */
25static fastcall void unexpected_machine_check(struct pt_regs * regs, long error_code) 25static void unexpected_machine_check(struct pt_regs * regs, long error_code)
26{ 26{
27 printk(KERN_ERR "CPU#%d: Unexpected int18 (Machine Check).\n", smp_processor_id()); 27 printk(KERN_ERR "CPU#%d: Unexpected int18 (Machine Check).\n", smp_processor_id());
28} 28}
29 29
30/* Call the installed machine check handler for this CPU setup. */ 30/* Call the installed machine check handler for this CPU setup. */
31void fastcall (*machine_check_vector)(struct pt_regs *, long error_code) = unexpected_machine_check; 31void (*machine_check_vector)(struct pt_regs *, long error_code) = unexpected_machine_check;
32 32
33/* This has to be run for each processor */ 33/* This has to be run for each processor */
34void mcheck_init(struct cpuinfo_x86 *c) 34void mcheck_init(struct cpuinfo_x86 *c)
diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c
index 4b21d29fb5aa..9a699ed03598 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_64.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_64.c
@@ -63,7 +63,7 @@ static DECLARE_WAIT_QUEUE_HEAD(mce_wait);
63 * separate MCEs from kernel messages to avoid bogus bug reports. 63 * separate MCEs from kernel messages to avoid bogus bug reports.
64 */ 64 */
65 65
66struct mce_log mcelog = { 66static struct mce_log mcelog = {
67 MCE_LOG_SIGNATURE, 67 MCE_LOG_SIGNATURE,
68 MCE_LOG_LEN, 68 MCE_LOG_LEN,
69}; 69};
@@ -80,7 +80,7 @@ void mce_log(struct mce *mce)
80 /* When the buffer fills up discard new entries. Assume 80 /* When the buffer fills up discard new entries. Assume
81 that the earlier errors are the more interesting. */ 81 that the earlier errors are the more interesting. */
82 if (entry >= MCE_LOG_LEN) { 82 if (entry >= MCE_LOG_LEN) {
83 set_bit(MCE_OVERFLOW, &mcelog.flags); 83 set_bit(MCE_OVERFLOW, (unsigned long *)&mcelog.flags);
84 return; 84 return;
85 } 85 }
86 /* Old left over entry. Skip. */ 86 /* Old left over entry. Skip. */
@@ -110,12 +110,12 @@ static void print_mce(struct mce *m)
110 KERN_EMERG 110 KERN_EMERG
111 "CPU %d: Machine Check Exception: %16Lx Bank %d: %016Lx\n", 111 "CPU %d: Machine Check Exception: %16Lx Bank %d: %016Lx\n",
112 m->cpu, m->mcgstatus, m->bank, m->status); 112 m->cpu, m->mcgstatus, m->bank, m->status);
113 if (m->rip) { 113 if (m->ip) {
114 printk(KERN_EMERG "RIP%s %02x:<%016Lx> ", 114 printk(KERN_EMERG "RIP%s %02x:<%016Lx> ",
115 !(m->mcgstatus & MCG_STATUS_EIPV) ? " !INEXACT!" : "", 115 !(m->mcgstatus & MCG_STATUS_EIPV) ? " !INEXACT!" : "",
116 m->cs, m->rip); 116 m->cs, m->ip);
117 if (m->cs == __KERNEL_CS) 117 if (m->cs == __KERNEL_CS)
118 print_symbol("{%s}", m->rip); 118 print_symbol("{%s}", m->ip);
119 printk("\n"); 119 printk("\n");
120 } 120 }
121 printk(KERN_EMERG "TSC %Lx ", m->tsc); 121 printk(KERN_EMERG "TSC %Lx ", m->tsc);
@@ -156,16 +156,16 @@ static int mce_available(struct cpuinfo_x86 *c)
156static inline void mce_get_rip(struct mce *m, struct pt_regs *regs) 156static inline void mce_get_rip(struct mce *m, struct pt_regs *regs)
157{ 157{
158 if (regs && (m->mcgstatus & MCG_STATUS_RIPV)) { 158 if (regs && (m->mcgstatus & MCG_STATUS_RIPV)) {
159 m->rip = regs->rip; 159 m->ip = regs->ip;
160 m->cs = regs->cs; 160 m->cs = regs->cs;
161 } else { 161 } else {
162 m->rip = 0; 162 m->ip = 0;
163 m->cs = 0; 163 m->cs = 0;
164 } 164 }
165 if (rip_msr) { 165 if (rip_msr) {
166 /* Assume the RIP in the MSR is exact. Is this true? */ 166 /* Assume the RIP in the MSR is exact. Is this true? */
167 m->mcgstatus |= MCG_STATUS_EIPV; 167 m->mcgstatus |= MCG_STATUS_EIPV;
168 rdmsrl(rip_msr, m->rip); 168 rdmsrl(rip_msr, m->ip);
169 m->cs = 0; 169 m->cs = 0;
170 } 170 }
171} 171}
@@ -192,10 +192,10 @@ void do_machine_check(struct pt_regs * regs, long error_code)
192 192
193 atomic_inc(&mce_entry); 193 atomic_inc(&mce_entry);
194 194
195 if (regs) 195 if ((regs
196 notify_die(DIE_NMI, "machine check", regs, error_code, 18, 196 && notify_die(DIE_NMI, "machine check", regs, error_code,
197 SIGKILL); 197 18, SIGKILL) == NOTIFY_STOP)
198 if (!banks) 198 || !banks)
199 goto out2; 199 goto out2;
200 200
201 memset(&m, 0, sizeof(struct mce)); 201 memset(&m, 0, sizeof(struct mce));
@@ -288,7 +288,7 @@ void do_machine_check(struct pt_regs * regs, long error_code)
288 * instruction which caused the MCE. 288 * instruction which caused the MCE.
289 */ 289 */
290 if (m.mcgstatus & MCG_STATUS_EIPV) 290 if (m.mcgstatus & MCG_STATUS_EIPV)
291 user_space = panicm.rip && (panicm.cs & 3); 291 user_space = panicm.ip && (panicm.cs & 3);
292 292
293 /* 293 /*
294 * If we know that the error was in user space, send a 294 * If we know that the error was in user space, send a
@@ -564,7 +564,7 @@ static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize,
564 loff_t *off) 564 loff_t *off)
565{ 565{
566 unsigned long *cpu_tsc; 566 unsigned long *cpu_tsc;
567 static DECLARE_MUTEX(mce_read_sem); 567 static DEFINE_MUTEX(mce_read_mutex);
568 unsigned next; 568 unsigned next;
569 char __user *buf = ubuf; 569 char __user *buf = ubuf;
570 int i, err; 570 int i, err;
@@ -573,12 +573,12 @@ static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize,
573 if (!cpu_tsc) 573 if (!cpu_tsc)
574 return -ENOMEM; 574 return -ENOMEM;
575 575
576 down(&mce_read_sem); 576 mutex_lock(&mce_read_mutex);
577 next = rcu_dereference(mcelog.next); 577 next = rcu_dereference(mcelog.next);
578 578
579 /* Only supports full reads right now */ 579 /* Only supports full reads right now */
580 if (*off != 0 || usize < MCE_LOG_LEN*sizeof(struct mce)) { 580 if (*off != 0 || usize < MCE_LOG_LEN*sizeof(struct mce)) {
581 up(&mce_read_sem); 581 mutex_unlock(&mce_read_mutex);
582 kfree(cpu_tsc); 582 kfree(cpu_tsc);
583 return -EINVAL; 583 return -EINVAL;
584 } 584 }
@@ -621,7 +621,7 @@ static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize,
621 memset(&mcelog.entry[i], 0, sizeof(struct mce)); 621 memset(&mcelog.entry[i], 0, sizeof(struct mce));
622 } 622 }
623 } 623 }
624 up(&mce_read_sem); 624 mutex_unlock(&mce_read_mutex);
625 kfree(cpu_tsc); 625 kfree(cpu_tsc);
626 return err ? -EFAULT : buf - ubuf; 626 return err ? -EFAULT : buf - ubuf;
627} 627}
@@ -634,8 +634,7 @@ static unsigned int mce_poll(struct file *file, poll_table *wait)
634 return 0; 634 return 0;
635} 635}
636 636
637static int mce_ioctl(struct inode *i, struct file *f,unsigned int cmd, 637static long mce_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
638 unsigned long arg)
639{ 638{
640 int __user *p = (int __user *)arg; 639 int __user *p = (int __user *)arg;
641 640
@@ -664,7 +663,7 @@ static const struct file_operations mce_chrdev_ops = {
664 .release = mce_release, 663 .release = mce_release,
665 .read = mce_read, 664 .read = mce_read,
666 .poll = mce_poll, 665 .poll = mce_poll,
667 .ioctl = mce_ioctl, 666 .unlocked_ioctl = mce_ioctl,
668}; 667};
669 668
670static struct miscdevice mce_log_device = { 669static struct miscdevice mce_log_device = {
@@ -745,7 +744,7 @@ static void mce_restart(void)
745 744
746static struct sysdev_class mce_sysclass = { 745static struct sysdev_class mce_sysclass = {
747 .resume = mce_resume, 746 .resume = mce_resume,
748 set_kset_name("machinecheck"), 747 .name = "machinecheck",
749}; 748};
750 749
751DEFINE_PER_CPU(struct sys_device, device_mce); 750DEFINE_PER_CPU(struct sys_device, device_mce);
@@ -855,8 +854,8 @@ static void mce_remove_device(unsigned int cpu)
855} 854}
856 855
857/* Get notified when a cpu comes on/off. Be hotplug friendly. */ 856/* Get notified when a cpu comes on/off. Be hotplug friendly. */
858static int 857static int __cpuinit mce_cpu_callback(struct notifier_block *nfb,
859mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) 858 unsigned long action, void *hcpu)
860{ 859{
861 unsigned int cpu = (unsigned long)hcpu; 860 unsigned int cpu = (unsigned long)hcpu;
862 861
@@ -873,7 +872,7 @@ mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
873 return NOTIFY_OK; 872 return NOTIFY_OK;
874} 873}
875 874
876static struct notifier_block mce_cpu_notifier = { 875static struct notifier_block mce_cpu_notifier __cpuinitdata = {
877 .notifier_call = mce_cpu_callback, 876 .notifier_call = mce_cpu_callback,
878}; 877};
879 878
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c
index 752fb16a817d..32671da8184e 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c
@@ -65,7 +65,7 @@ static struct threshold_block threshold_defaults = {
65}; 65};
66 66
67struct threshold_bank { 67struct threshold_bank {
68 struct kobject kobj; 68 struct kobject *kobj;
69 struct threshold_block *blocks; 69 struct threshold_block *blocks;
70 cpumask_t cpus; 70 cpumask_t cpus;
71}; 71};
@@ -118,6 +118,7 @@ void __cpuinit mce_amd_feature_init(struct cpuinfo_x86 *c)
118{ 118{
119 unsigned int bank, block; 119 unsigned int bank, block;
120 unsigned int cpu = smp_processor_id(); 120 unsigned int cpu = smp_processor_id();
121 u8 lvt_off;
121 u32 low = 0, high = 0, address = 0; 122 u32 low = 0, high = 0, address = 0;
122 123
123 for (bank = 0; bank < NR_BANKS; ++bank) { 124 for (bank = 0; bank < NR_BANKS; ++bank) {
@@ -153,14 +154,13 @@ void __cpuinit mce_amd_feature_init(struct cpuinfo_x86 *c)
153 if (shared_bank[bank] && c->cpu_core_id) 154 if (shared_bank[bank] && c->cpu_core_id)
154 break; 155 break;
155#endif 156#endif
157 lvt_off = setup_APIC_eilvt_mce(THRESHOLD_APIC_VECTOR,
158 APIC_EILVT_MSG_FIX, 0);
159
156 high &= ~MASK_LVTOFF_HI; 160 high &= ~MASK_LVTOFF_HI;
157 high |= K8_APIC_EXT_LVT_ENTRY_THRESHOLD << 20; 161 high |= lvt_off << 20;
158 wrmsr(address, low, high); 162 wrmsr(address, low, high);
159 163
160 setup_APIC_extended_lvt(K8_APIC_EXT_LVT_ENTRY_THRESHOLD,
161 THRESHOLD_APIC_VECTOR,
162 K8_APIC_EXT_INT_MSG_FIX, 0);
163
164 threshold_defaults.address = address; 164 threshold_defaults.address = address;
165 threshold_restart_bank(&threshold_defaults, 0, 0); 165 threshold_restart_bank(&threshold_defaults, 0, 0);
166 } 166 }
@@ -432,10 +432,9 @@ static __cpuinit int allocate_threshold_blocks(unsigned int cpu,
432 else 432 else
433 per_cpu(threshold_banks, cpu)[bank]->blocks = b; 433 per_cpu(threshold_banks, cpu)[bank]->blocks = b;
434 434
435 kobject_set_name(&b->kobj, "misc%i", block); 435 err = kobject_init_and_add(&b->kobj, &threshold_ktype,
436 b->kobj.parent = &per_cpu(threshold_banks, cpu)[bank]->kobj; 436 per_cpu(threshold_banks, cpu)[bank]->kobj,
437 b->kobj.ktype = &threshold_ktype; 437 "misc%i", block);
438 err = kobject_register(&b->kobj);
439 if (err) 438 if (err)
440 goto out_free; 439 goto out_free;
441recurse: 440recurse:
@@ -451,11 +450,14 @@ recurse:
451 if (err) 450 if (err)
452 goto out_free; 451 goto out_free;
453 452
453 if (b)
454 kobject_uevent(&b->kobj, KOBJ_ADD);
455
454 return err; 456 return err;
455 457
456out_free: 458out_free:
457 if (b) { 459 if (b) {
458 kobject_unregister(&b->kobj); 460 kobject_put(&b->kobj);
459 kfree(b); 461 kfree(b);
460 } 462 }
461 return err; 463 return err;
@@ -489,7 +491,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
489 goto out; 491 goto out;
490 492
491 err = sysfs_create_link(&per_cpu(device_mce, cpu).kobj, 493 err = sysfs_create_link(&per_cpu(device_mce, cpu).kobj,
492 &b->kobj, name); 494 b->kobj, name);
493 if (err) 495 if (err)
494 goto out; 496 goto out;
495 497
@@ -505,16 +507,15 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
505 goto out; 507 goto out;
506 } 508 }
507 509
508 kobject_set_name(&b->kobj, "threshold_bank%i", bank); 510 b->kobj = kobject_create_and_add(name, &per_cpu(device_mce, cpu).kobj);
509 b->kobj.parent = &per_cpu(device_mce, cpu).kobj; 511 if (!b->kobj)
512 goto out_free;
513
510#ifndef CONFIG_SMP 514#ifndef CONFIG_SMP
511 b->cpus = CPU_MASK_ALL; 515 b->cpus = CPU_MASK_ALL;
512#else 516#else
513 b->cpus = per_cpu(cpu_core_map, cpu); 517 b->cpus = per_cpu(cpu_core_map, cpu);
514#endif 518#endif
515 err = kobject_register(&b->kobj);
516 if (err)
517 goto out_free;
518 519
519 per_cpu(threshold_banks, cpu)[bank] = b; 520 per_cpu(threshold_banks, cpu)[bank] = b;
520 521
@@ -531,7 +532,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
531 continue; 532 continue;
532 533
533 err = sysfs_create_link(&per_cpu(device_mce, i).kobj, 534 err = sysfs_create_link(&per_cpu(device_mce, i).kobj,
534 &b->kobj, name); 535 b->kobj, name);
535 if (err) 536 if (err)
536 goto out; 537 goto out;
537 538
@@ -554,7 +555,7 @@ static __cpuinit int threshold_create_device(unsigned int cpu)
554 int err = 0; 555 int err = 0;
555 556
556 for (bank = 0; bank < NR_BANKS; ++bank) { 557 for (bank = 0; bank < NR_BANKS; ++bank) {
557 if (!(per_cpu(bank_map, cpu) & 1 << bank)) 558 if (!(per_cpu(bank_map, cpu) & (1 << bank)))
558 continue; 559 continue;
559 err = threshold_create_bank(cpu, bank); 560 err = threshold_create_bank(cpu, bank);
560 if (err) 561 if (err)
@@ -581,7 +582,7 @@ static void deallocate_threshold_block(unsigned int cpu,
581 return; 582 return;
582 583
583 list_for_each_entry_safe(pos, tmp, &head->blocks->miscj, miscj) { 584 list_for_each_entry_safe(pos, tmp, &head->blocks->miscj, miscj) {
584 kobject_unregister(&pos->kobj); 585 kobject_put(&pos->kobj);
585 list_del(&pos->miscj); 586 list_del(&pos->miscj);
586 kfree(pos); 587 kfree(pos);
587 } 588 }
@@ -627,7 +628,7 @@ static void threshold_remove_bank(unsigned int cpu, int bank)
627 deallocate_threshold_block(cpu, bank); 628 deallocate_threshold_block(cpu, bank);
628 629
629free_out: 630free_out:
630 kobject_unregister(&b->kobj); 631 kobject_put(b->kobj);
631 kfree(b); 632 kfree(b);
632 per_cpu(threshold_banks, cpu)[bank] = NULL; 633 per_cpu(threshold_banks, cpu)[bank] = NULL;
633} 634}
@@ -637,14 +638,14 @@ static void threshold_remove_device(unsigned int cpu)
637 unsigned int bank; 638 unsigned int bank;
638 639
639 for (bank = 0; bank < NR_BANKS; ++bank) { 640 for (bank = 0; bank < NR_BANKS; ++bank) {
640 if (!(per_cpu(bank_map, cpu) & 1 << bank)) 641 if (!(per_cpu(bank_map, cpu) & (1 << bank)))
641 continue; 642 continue;
642 threshold_remove_bank(cpu, bank); 643 threshold_remove_bank(cpu, bank);
643 } 644 }
644} 645}
645 646
646/* get notified when a cpu comes on/off */ 647/* get notified when a cpu comes on/off */
647static int threshold_cpu_callback(struct notifier_block *nfb, 648static int __cpuinit threshold_cpu_callback(struct notifier_block *nfb,
648 unsigned long action, void *hcpu) 649 unsigned long action, void *hcpu)
649{ 650{
650 /* cpu was unsigned int to begin with */ 651 /* cpu was unsigned int to begin with */
@@ -669,7 +670,7 @@ static int threshold_cpu_callback(struct notifier_block *nfb,
669 return NOTIFY_OK; 670 return NOTIFY_OK;
670} 671}
671 672
672static struct notifier_block threshold_cpu_notifier = { 673static struct notifier_block threshold_cpu_notifier __cpuinitdata = {
673 .notifier_call = threshold_cpu_callback, 674 .notifier_call = threshold_cpu_callback,
674}; 675};
675 676
diff --git a/arch/x86/kernel/cpu/mcheck/p4.c b/arch/x86/kernel/cpu/mcheck/p4.c
index be4dabfee1f5..cb03345554a5 100644
--- a/arch/x86/kernel/cpu/mcheck/p4.c
+++ b/arch/x86/kernel/cpu/mcheck/p4.c
@@ -57,7 +57,7 @@ static void intel_thermal_interrupt(struct pt_regs *regs)
57/* Thermal interrupt handler for this CPU setup */ 57/* Thermal interrupt handler for this CPU setup */
58static void (*vendor_thermal_interrupt)(struct pt_regs *regs) = unexpected_thermal_interrupt; 58static void (*vendor_thermal_interrupt)(struct pt_regs *regs) = unexpected_thermal_interrupt;
59 59
60fastcall void smp_thermal_interrupt(struct pt_regs *regs) 60void smp_thermal_interrupt(struct pt_regs *regs)
61{ 61{
62 irq_enter(); 62 irq_enter();
63 vendor_thermal_interrupt(regs); 63 vendor_thermal_interrupt(regs);
@@ -141,7 +141,7 @@ static inline void intel_get_extended_msrs(struct intel_mce_extended_msrs *r)
141 rdmsr (MSR_IA32_MCG_EIP, r->eip, h); 141 rdmsr (MSR_IA32_MCG_EIP, r->eip, h);
142} 142}
143 143
144static fastcall void intel_machine_check(struct pt_regs * regs, long error_code) 144static void intel_machine_check(struct pt_regs * regs, long error_code)
145{ 145{
146 int recover=1; 146 int recover=1;
147 u32 alow, ahigh, high, low; 147 u32 alow, ahigh, high, low;
@@ -152,38 +152,41 @@ static fastcall void intel_machine_check(struct pt_regs * regs, long error_code)
152 if (mcgstl & (1<<0)) /* Recoverable ? */ 152 if (mcgstl & (1<<0)) /* Recoverable ? */
153 recover=0; 153 recover=0;
154 154
155 printk (KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n", 155 printk(KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n",
156 smp_processor_id(), mcgsth, mcgstl); 156 smp_processor_id(), mcgsth, mcgstl);
157 157
158 if (mce_num_extended_msrs > 0) { 158 if (mce_num_extended_msrs > 0) {
159 struct intel_mce_extended_msrs dbg; 159 struct intel_mce_extended_msrs dbg;
160 intel_get_extended_msrs(&dbg); 160 intel_get_extended_msrs(&dbg);
161 printk (KERN_DEBUG "CPU %d: EIP: %08x EFLAGS: %08x\n", 161 printk(KERN_DEBUG "CPU %d: EIP: %08x EFLAGS: %08x\n"
162 smp_processor_id(), dbg.eip, dbg.eflags); 162 "\teax: %08x ebx: %08x ecx: %08x edx: %08x\n"
163 printk (KERN_DEBUG "\teax: %08x ebx: %08x ecx: %08x edx: %08x\n", 163 "\tesi: %08x edi: %08x ebp: %08x esp: %08x\n",
164 dbg.eax, dbg.ebx, dbg.ecx, dbg.edx); 164 smp_processor_id(), dbg.eip, dbg.eflags,
165 printk (KERN_DEBUG "\tesi: %08x edi: %08x ebp: %08x esp: %08x\n", 165 dbg.eax, dbg.ebx, dbg.ecx, dbg.edx,
166 dbg.esi, dbg.edi, dbg.ebp, dbg.esp); 166 dbg.esi, dbg.edi, dbg.ebp, dbg.esp);
167 } 167 }
168 168
169 for (i=0; i<nr_mce_banks; i++) { 169 for (i = 0; i < nr_mce_banks; i++) {
170 rdmsr (MSR_IA32_MC0_STATUS+i*4,low, high); 170 rdmsr(MSR_IA32_MC0_STATUS+i*4, low, high);
171 if (high & (1<<31)) { 171 if (high & (1<<31)) {
172 char misc[20];
173 char addr[24];
174 misc[0] = addr[0] = '\0';
172 if (high & (1<<29)) 175 if (high & (1<<29))
173 recover |= 1; 176 recover |= 1;
174 if (high & (1<<25)) 177 if (high & (1<<25))
175 recover |= 2; 178 recover |= 2;
176 printk (KERN_EMERG "Bank %d: %08x%08x", i, high, low);
177 high &= ~(1<<31); 179 high &= ~(1<<31);
178 if (high & (1<<27)) { 180 if (high & (1<<27)) {
179 rdmsr (MSR_IA32_MC0_MISC+i*4, alow, ahigh); 181 rdmsr(MSR_IA32_MC0_MISC+i*4, alow, ahigh);
180 printk ("[%08x%08x]", ahigh, alow); 182 snprintf(misc, 20, "[%08x%08x]", ahigh, alow);
181 } 183 }
182 if (high & (1<<26)) { 184 if (high & (1<<26)) {
183 rdmsr (MSR_IA32_MC0_ADDR+i*4, alow, ahigh); 185 rdmsr(MSR_IA32_MC0_ADDR+i*4, alow, ahigh);
184 printk (" at %08x%08x", ahigh, alow); 186 snprintf(addr, 24, " at %08x%08x", ahigh, alow);
185 } 187 }
186 printk ("\n"); 188 printk(KERN_EMERG "CPU %d: Bank %d: %08x%08x%s%s\n",
189 smp_processor_id(), i, high, low, misc, addr);
187 } 190 }
188 } 191 }
189 192
diff --git a/arch/x86/kernel/cpu/mcheck/p5.c b/arch/x86/kernel/cpu/mcheck/p5.c
index 94bc43d950cf..a18310aaae0c 100644
--- a/arch/x86/kernel/cpu/mcheck/p5.c
+++ b/arch/x86/kernel/cpu/mcheck/p5.c
@@ -16,7 +16,7 @@
16#include "mce.h" 16#include "mce.h"
17 17
18/* Machine check handler for Pentium class Intel */ 18/* Machine check handler for Pentium class Intel */
19static fastcall void pentium_machine_check(struct pt_regs * regs, long error_code) 19static void pentium_machine_check(struct pt_regs * regs, long error_code)
20{ 20{
21 u32 loaddr, hi, lotype; 21 u32 loaddr, hi, lotype;
22 rdmsr(MSR_IA32_P5_MC_ADDR, loaddr, hi); 22 rdmsr(MSR_IA32_P5_MC_ADDR, loaddr, hi);
diff --git a/arch/x86/kernel/cpu/mcheck/p6.c b/arch/x86/kernel/cpu/mcheck/p6.c
index deeae42ce199..74342604d30e 100644
--- a/arch/x86/kernel/cpu/mcheck/p6.c
+++ b/arch/x86/kernel/cpu/mcheck/p6.c
@@ -16,7 +16,7 @@
16#include "mce.h" 16#include "mce.h"
17 17
18/* Machine Check Handler For PII/PIII */ 18/* Machine Check Handler For PII/PIII */
19static fastcall void intel_machine_check(struct pt_regs * regs, long error_code) 19static void intel_machine_check(struct pt_regs * regs, long error_code)
20{ 20{
21 int recover=1; 21 int recover=1;
22 u32 alow, ahigh, high, low; 22 u32 alow, ahigh, high, low;
@@ -27,27 +27,30 @@ static fastcall void intel_machine_check(struct pt_regs * regs, long error_code)
27 if (mcgstl & (1<<0)) /* Recoverable ? */ 27 if (mcgstl & (1<<0)) /* Recoverable ? */
28 recover=0; 28 recover=0;
29 29
30 printk (KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n", 30 printk(KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n",
31 smp_processor_id(), mcgsth, mcgstl); 31 smp_processor_id(), mcgsth, mcgstl);
32 32
33 for (i=0; i<nr_mce_banks; i++) { 33 for (i = 0; i < nr_mce_banks; i++) {
34 rdmsr (MSR_IA32_MC0_STATUS+i*4,low, high); 34 rdmsr(MSR_IA32_MC0_STATUS+i*4, low, high);
35 if (high & (1<<31)) { 35 if (high & (1<<31)) {
36 char misc[20];
37 char addr[24];
38 misc[0] = addr[0] = '\0';
36 if (high & (1<<29)) 39 if (high & (1<<29))
37 recover |= 1; 40 recover |= 1;
38 if (high & (1<<25)) 41 if (high & (1<<25))
39 recover |= 2; 42 recover |= 2;
40 printk (KERN_EMERG "Bank %d: %08x%08x", i, high, low);
41 high &= ~(1<<31); 43 high &= ~(1<<31);
42 if (high & (1<<27)) { 44 if (high & (1<<27)) {
43 rdmsr (MSR_IA32_MC0_MISC+i*4, alow, ahigh); 45 rdmsr(MSR_IA32_MC0_MISC+i*4, alow, ahigh);
44 printk ("[%08x%08x]", ahigh, alow); 46 snprintf(misc, 20, "[%08x%08x]", ahigh, alow);
45 } 47 }
46 if (high & (1<<26)) { 48 if (high & (1<<26)) {
47 rdmsr (MSR_IA32_MC0_ADDR+i*4, alow, ahigh); 49 rdmsr(MSR_IA32_MC0_ADDR+i*4, alow, ahigh);
48 printk (" at %08x%08x", ahigh, alow); 50 snprintf(addr, 24, " at %08x%08x", ahigh, alow);
49 } 51 }
50 printk ("\n"); 52 printk(KERN_EMERG "CPU %d: Bank %d: %08x%08x%s%s\n",
53 smp_processor_id(), i, high, low, misc, addr);
51 } 54 }
52 } 55 }
53 56
diff --git a/arch/x86/kernel/cpu/mcheck/winchip.c b/arch/x86/kernel/cpu/mcheck/winchip.c
index 9e424b6c293d..3d428d5afc52 100644
--- a/arch/x86/kernel/cpu/mcheck/winchip.c
+++ b/arch/x86/kernel/cpu/mcheck/winchip.c
@@ -15,7 +15,7 @@
15#include "mce.h" 15#include "mce.h"
16 16
17/* Machine check handler for WinChip C6 */ 17/* Machine check handler for WinChip C6 */
18static fastcall void winchip_machine_check(struct pt_regs * regs, long error_code) 18static void winchip_machine_check(struct pt_regs * regs, long error_code)
19{ 19{
20 printk(KERN_EMERG "CPU0: Machine Check Exception.\n"); 20 printk(KERN_EMERG "CPU0: Machine Check Exception.\n");
21 add_taint(TAINT_MACHINE_CHECK); 21 add_taint(TAINT_MACHINE_CHECK);
diff --git a/arch/x86/kernel/cpu/mtrr/amd.c b/arch/x86/kernel/cpu/mtrr/amd.c
index 0949cdbf848a..ee2331b0e58f 100644
--- a/arch/x86/kernel/cpu/mtrr/amd.c
+++ b/arch/x86/kernel/cpu/mtrr/amd.c
@@ -53,8 +53,6 @@ static void amd_set_mtrr(unsigned int reg, unsigned long base,
53 <base> The base address of the region. 53 <base> The base address of the region.
54 <size> The size of the region. If this is 0 the region is disabled. 54 <size> The size of the region. If this is 0 the region is disabled.
55 <type> The type of the region. 55 <type> The type of the region.
56 <do_safe> If TRUE, do the change safely. If FALSE, safety measures should
57 be done externally.
58 [RETURNS] Nothing. 56 [RETURNS] Nothing.
59*/ 57*/
60{ 58{
diff --git a/arch/x86/kernel/cpu/mtrr/cyrix.c b/arch/x86/kernel/cpu/mtrr/cyrix.c
index 9964be3de2b7..8e139c70f888 100644
--- a/arch/x86/kernel/cpu/mtrr/cyrix.c
+++ b/arch/x86/kernel/cpu/mtrr/cyrix.c
@@ -4,6 +4,7 @@
4#include <asm/msr.h> 4#include <asm/msr.h>
5#include <asm/io.h> 5#include <asm/io.h>
6#include <asm/processor-cyrix.h> 6#include <asm/processor-cyrix.h>
7#include <asm/processor-flags.h>
7#include "mtrr.h" 8#include "mtrr.h"
8 9
9int arr3_protected; 10int arr3_protected;
@@ -142,7 +143,7 @@ static void prepare_set(void)
142 143
143 /* Disable and flush caches. Note that wbinvd flushes the TLBs as 144 /* Disable and flush caches. Note that wbinvd flushes the TLBs as
144 a side-effect */ 145 a side-effect */
145 cr0 = read_cr0() | 0x40000000; 146 cr0 = read_cr0() | X86_CR0_CD;
146 wbinvd(); 147 wbinvd();
147 write_cr0(cr0); 148 write_cr0(cr0);
148 wbinvd(); 149 wbinvd();
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c
index 992f08dfbb6c..103d61a59b19 100644
--- a/arch/x86/kernel/cpu/mtrr/generic.c
+++ b/arch/x86/kernel/cpu/mtrr/generic.c
@@ -9,11 +9,12 @@
9#include <asm/msr.h> 9#include <asm/msr.h>
10#include <asm/system.h> 10#include <asm/system.h>
11#include <asm/cpufeature.h> 11#include <asm/cpufeature.h>
12#include <asm/processor-flags.h>
12#include <asm/tlbflush.h> 13#include <asm/tlbflush.h>
13#include "mtrr.h" 14#include "mtrr.h"
14 15
15struct mtrr_state { 16struct mtrr_state {
16 struct mtrr_var_range *var_ranges; 17 struct mtrr_var_range var_ranges[MAX_VAR_RANGES];
17 mtrr_type fixed_ranges[NUM_FIXED_RANGES]; 18 mtrr_type fixed_ranges[NUM_FIXED_RANGES];
18 unsigned char enabled; 19 unsigned char enabled;
19 unsigned char have_fixed; 20 unsigned char have_fixed;
@@ -85,12 +86,6 @@ void __init get_mtrr_state(void)
85 struct mtrr_var_range *vrs; 86 struct mtrr_var_range *vrs;
86 unsigned lo, dummy; 87 unsigned lo, dummy;
87 88
88 if (!mtrr_state.var_ranges) {
89 mtrr_state.var_ranges = kmalloc(num_var_ranges * sizeof (struct mtrr_var_range),
90 GFP_KERNEL);
91 if (!mtrr_state.var_ranges)
92 return;
93 }
94 vrs = mtrr_state.var_ranges; 89 vrs = mtrr_state.var_ranges;
95 90
96 rdmsr(MTRRcap_MSR, lo, dummy); 91 rdmsr(MTRRcap_MSR, lo, dummy);
@@ -188,7 +183,7 @@ static inline void k8_enable_fixed_iorrs(void)
188 * \param changed pointer which indicates whether the MTRR needed to be changed 183 * \param changed pointer which indicates whether the MTRR needed to be changed
189 * \param msrwords pointer to the MSR values which the MSR should have 184 * \param msrwords pointer to the MSR values which the MSR should have
190 */ 185 */
191static void set_fixed_range(int msr, int * changed, unsigned int * msrwords) 186static void set_fixed_range(int msr, bool *changed, unsigned int *msrwords)
192{ 187{
193 unsigned lo, hi; 188 unsigned lo, hi;
194 189
@@ -200,7 +195,7 @@ static void set_fixed_range(int msr, int * changed, unsigned int * msrwords)
200 ((msrwords[0] | msrwords[1]) & K8_MTRR_RDMEM_WRMEM_MASK)) 195 ((msrwords[0] | msrwords[1]) & K8_MTRR_RDMEM_WRMEM_MASK))
201 k8_enable_fixed_iorrs(); 196 k8_enable_fixed_iorrs();
202 mtrr_wrmsr(msr, msrwords[0], msrwords[1]); 197 mtrr_wrmsr(msr, msrwords[0], msrwords[1]);
203 *changed = TRUE; 198 *changed = true;
204 } 199 }
205} 200}
206 201
@@ -260,7 +255,7 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base,
260static int set_fixed_ranges(mtrr_type * frs) 255static int set_fixed_ranges(mtrr_type * frs)
261{ 256{
262 unsigned long long *saved = (unsigned long long *) frs; 257 unsigned long long *saved = (unsigned long long *) frs;
263 int changed = FALSE; 258 bool changed = false;
264 int block=-1, range; 259 int block=-1, range;
265 260
266 while (fixed_range_blocks[++block].ranges) 261 while (fixed_range_blocks[++block].ranges)
@@ -273,17 +268,17 @@ static int set_fixed_ranges(mtrr_type * frs)
273 268
274/* Set the MSR pair relating to a var range. Returns TRUE if 269/* Set the MSR pair relating to a var range. Returns TRUE if
275 changes are made */ 270 changes are made */
276static int set_mtrr_var_ranges(unsigned int index, struct mtrr_var_range *vr) 271static bool set_mtrr_var_ranges(unsigned int index, struct mtrr_var_range *vr)
277{ 272{
278 unsigned int lo, hi; 273 unsigned int lo, hi;
279 int changed = FALSE; 274 bool changed = false;
280 275
281 rdmsr(MTRRphysBase_MSR(index), lo, hi); 276 rdmsr(MTRRphysBase_MSR(index), lo, hi);
282 if ((vr->base_lo & 0xfffff0ffUL) != (lo & 0xfffff0ffUL) 277 if ((vr->base_lo & 0xfffff0ffUL) != (lo & 0xfffff0ffUL)
283 || (vr->base_hi & (size_and_mask >> (32 - PAGE_SHIFT))) != 278 || (vr->base_hi & (size_and_mask >> (32 - PAGE_SHIFT))) !=
284 (hi & (size_and_mask >> (32 - PAGE_SHIFT)))) { 279 (hi & (size_and_mask >> (32 - PAGE_SHIFT)))) {
285 mtrr_wrmsr(MTRRphysBase_MSR(index), vr->base_lo, vr->base_hi); 280 mtrr_wrmsr(MTRRphysBase_MSR(index), vr->base_lo, vr->base_hi);
286 changed = TRUE; 281 changed = true;
287 } 282 }
288 283
289 rdmsr(MTRRphysMask_MSR(index), lo, hi); 284 rdmsr(MTRRphysMask_MSR(index), lo, hi);
@@ -292,7 +287,7 @@ static int set_mtrr_var_ranges(unsigned int index, struct mtrr_var_range *vr)
292 || (vr->mask_hi & (size_and_mask >> (32 - PAGE_SHIFT))) != 287 || (vr->mask_hi & (size_and_mask >> (32 - PAGE_SHIFT))) !=
293 (hi & (size_and_mask >> (32 - PAGE_SHIFT)))) { 288 (hi & (size_and_mask >> (32 - PAGE_SHIFT)))) {
294 mtrr_wrmsr(MTRRphysMask_MSR(index), vr->mask_lo, vr->mask_hi); 289 mtrr_wrmsr(MTRRphysMask_MSR(index), vr->mask_lo, vr->mask_hi);
295 changed = TRUE; 290 changed = true;
296 } 291 }
297 return changed; 292 return changed;
298} 293}
@@ -350,7 +345,7 @@ static void prepare_set(void) __acquires(set_atomicity_lock)
350 spin_lock(&set_atomicity_lock); 345 spin_lock(&set_atomicity_lock);
351 346
352 /* Enter the no-fill (CD=1, NW=0) cache mode and flush caches. */ 347 /* Enter the no-fill (CD=1, NW=0) cache mode and flush caches. */
353 cr0 = read_cr0() | 0x40000000; /* set CD flag */ 348 cr0 = read_cr0() | X86_CR0_CD;
354 write_cr0(cr0); 349 write_cr0(cr0);
355 wbinvd(); 350 wbinvd();
356 351
@@ -417,8 +412,6 @@ static void generic_set_mtrr(unsigned int reg, unsigned long base,
417 <base> The base address of the region. 412 <base> The base address of the region.
418 <size> The size of the region. If this is 0 the region is disabled. 413 <size> The size of the region. If this is 0 the region is disabled.
419 <type> The type of the region. 414 <type> The type of the region.
420 <do_safe> If TRUE, do the change safely. If FALSE, safety measures should
421 be done externally.
422 [RETURNS] Nothing. 415 [RETURNS] Nothing.
423*/ 416*/
424{ 417{
diff --git a/arch/x86/kernel/cpu/mtrr/if.c b/arch/x86/kernel/cpu/mtrr/if.c
index c7d8f1756745..91e150acb46c 100644
--- a/arch/x86/kernel/cpu/mtrr/if.c
+++ b/arch/x86/kernel/cpu/mtrr/if.c
@@ -11,10 +11,6 @@
11#include <asm/mtrr.h> 11#include <asm/mtrr.h>
12#include "mtrr.h" 12#include "mtrr.h"
13 13
14/* RED-PEN: this is accessed without any locking */
15extern unsigned int *usage_table;
16
17
18#define FILE_FCOUNT(f) (((struct seq_file *)((f)->private_data))->private) 14#define FILE_FCOUNT(f) (((struct seq_file *)((f)->private_data))->private)
19 15
20static const char *const mtrr_strings[MTRR_NUM_TYPES] = 16static const char *const mtrr_strings[MTRR_NUM_TYPES] =
@@ -37,7 +33,7 @@ const char *mtrr_attrib_to_str(int x)
37 33
38static int 34static int
39mtrr_file_add(unsigned long base, unsigned long size, 35mtrr_file_add(unsigned long base, unsigned long size,
40 unsigned int type, char increment, struct file *file, int page) 36 unsigned int type, bool increment, struct file *file, int page)
41{ 37{
42 int reg, max; 38 int reg, max;
43 unsigned int *fcount = FILE_FCOUNT(file); 39 unsigned int *fcount = FILE_FCOUNT(file);
@@ -55,7 +51,7 @@ mtrr_file_add(unsigned long base, unsigned long size,
55 base >>= PAGE_SHIFT; 51 base >>= PAGE_SHIFT;
56 size >>= PAGE_SHIFT; 52 size >>= PAGE_SHIFT;
57 } 53 }
58 reg = mtrr_add_page(base, size, type, 1); 54 reg = mtrr_add_page(base, size, type, true);
59 if (reg >= 0) 55 if (reg >= 0)
60 ++fcount[reg]; 56 ++fcount[reg];
61 return reg; 57 return reg;
@@ -141,7 +137,7 @@ mtrr_write(struct file *file, const char __user *buf, size_t len, loff_t * ppos)
141 size >>= PAGE_SHIFT; 137 size >>= PAGE_SHIFT;
142 err = 138 err =
143 mtrr_add_page((unsigned long) base, (unsigned long) size, i, 139 mtrr_add_page((unsigned long) base, (unsigned long) size, i,
144 1); 140 true);
145 if (err < 0) 141 if (err < 0)
146 return err; 142 return err;
147 return len; 143 return len;
@@ -217,7 +213,7 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)
217 if (!capable(CAP_SYS_ADMIN)) 213 if (!capable(CAP_SYS_ADMIN))
218 return -EPERM; 214 return -EPERM;
219 err = 215 err =
220 mtrr_file_add(sentry.base, sentry.size, sentry.type, 1, 216 mtrr_file_add(sentry.base, sentry.size, sentry.type, true,
221 file, 0); 217 file, 0);
222 break; 218 break;
223 case MTRRIOC_SET_ENTRY: 219 case MTRRIOC_SET_ENTRY:
@@ -226,7 +222,7 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)
226#endif 222#endif
227 if (!capable(CAP_SYS_ADMIN)) 223 if (!capable(CAP_SYS_ADMIN))
228 return -EPERM; 224 return -EPERM;
229 err = mtrr_add(sentry.base, sentry.size, sentry.type, 0); 225 err = mtrr_add(sentry.base, sentry.size, sentry.type, false);
230 break; 226 break;
231 case MTRRIOC_DEL_ENTRY: 227 case MTRRIOC_DEL_ENTRY:
232#ifdef CONFIG_COMPAT 228#ifdef CONFIG_COMPAT
@@ -270,7 +266,7 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)
270 if (!capable(CAP_SYS_ADMIN)) 266 if (!capable(CAP_SYS_ADMIN))
271 return -EPERM; 267 return -EPERM;
272 err = 268 err =
273 mtrr_file_add(sentry.base, sentry.size, sentry.type, 1, 269 mtrr_file_add(sentry.base, sentry.size, sentry.type, true,
274 file, 1); 270 file, 1);
275 break; 271 break;
276 case MTRRIOC_SET_PAGE_ENTRY: 272 case MTRRIOC_SET_PAGE_ENTRY:
@@ -279,7 +275,8 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)
279#endif 275#endif
280 if (!capable(CAP_SYS_ADMIN)) 276 if (!capable(CAP_SYS_ADMIN))
281 return -EPERM; 277 return -EPERM;
282 err = mtrr_add_page(sentry.base, sentry.size, sentry.type, 0); 278 err =
279 mtrr_add_page(sentry.base, sentry.size, sentry.type, false);
283 break; 280 break;
284 case MTRRIOC_DEL_PAGE_ENTRY: 281 case MTRRIOC_DEL_PAGE_ENTRY:
285#ifdef CONFIG_COMPAT 282#ifdef CONFIG_COMPAT
@@ -396,7 +393,7 @@ static int mtrr_seq_show(struct seq_file *seq, void *offset)
396 for (i = 0; i < max; i++) { 393 for (i = 0; i < max; i++) {
397 mtrr_if->get(i, &base, &size, &type); 394 mtrr_if->get(i, &base, &size, &type);
398 if (size == 0) 395 if (size == 0)
399 usage_table[i] = 0; 396 mtrr_usage_table[i] = 0;
400 else { 397 else {
401 if (size < (0x100000 >> PAGE_SHIFT)) { 398 if (size < (0x100000 >> PAGE_SHIFT)) {
402 /* less than 1MB */ 399 /* less than 1MB */
@@ -410,7 +407,7 @@ static int mtrr_seq_show(struct seq_file *seq, void *offset)
410 len += seq_printf(seq, 407 len += seq_printf(seq,
411 "reg%02i: base=0x%05lx000 (%4luMB), size=%4lu%cB: %s, count=%d\n", 408 "reg%02i: base=0x%05lx000 (%4luMB), size=%4lu%cB: %s, count=%d\n",
412 i, base, base >> (20 - PAGE_SHIFT), size, factor, 409 i, base, base >> (20 - PAGE_SHIFT), size, factor,
413 mtrr_attrib_to_str(type), usage_table[i]); 410 mtrr_attrib_to_str(type), mtrr_usage_table[i]);
414 } 411 }
415 } 412 }
416 return 0; 413 return 0;
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
index 3b20613325dc..715919582657 100644
--- a/arch/x86/kernel/cpu/mtrr/main.c
+++ b/arch/x86/kernel/cpu/mtrr/main.c
@@ -38,8 +38,8 @@
38#include <linux/cpu.h> 38#include <linux/cpu.h>
39#include <linux/mutex.h> 39#include <linux/mutex.h>
40 40
41#include <asm/e820.h>
41#include <asm/mtrr.h> 42#include <asm/mtrr.h>
42
43#include <asm/uaccess.h> 43#include <asm/uaccess.h>
44#include <asm/processor.h> 44#include <asm/processor.h>
45#include <asm/msr.h> 45#include <asm/msr.h>
@@ -47,7 +47,7 @@
47 47
48u32 num_var_ranges = 0; 48u32 num_var_ranges = 0;
49 49
50unsigned int *usage_table; 50unsigned int mtrr_usage_table[MAX_VAR_RANGES];
51static DEFINE_MUTEX(mtrr_mutex); 51static DEFINE_MUTEX(mtrr_mutex);
52 52
53u64 size_or_mask, size_and_mask; 53u64 size_or_mask, size_and_mask;
@@ -121,13 +121,8 @@ static void __init init_table(void)
121 int i, max; 121 int i, max;
122 122
123 max = num_var_ranges; 123 max = num_var_ranges;
124 if ((usage_table = kmalloc(max * sizeof *usage_table, GFP_KERNEL))
125 == NULL) {
126 printk(KERN_ERR "mtrr: could not allocate\n");
127 return;
128 }
129 for (i = 0; i < max; i++) 124 for (i = 0; i < max; i++)
130 usage_table[i] = 1; 125 mtrr_usage_table[i] = 1;
131} 126}
132 127
133struct set_mtrr_data { 128struct set_mtrr_data {
@@ -311,7 +306,7 @@ static void set_mtrr(unsigned int reg, unsigned long base,
311 */ 306 */
312 307
313int mtrr_add_page(unsigned long base, unsigned long size, 308int mtrr_add_page(unsigned long base, unsigned long size,
314 unsigned int type, char increment) 309 unsigned int type, bool increment)
315{ 310{
316 int i, replace, error; 311 int i, replace, error;
317 mtrr_type ltype; 312 mtrr_type ltype;
@@ -349,7 +344,7 @@ int mtrr_add_page(unsigned long base, unsigned long size,
349 replace = -1; 344 replace = -1;
350 345
351 /* No CPU hotplug when we change MTRR entries */ 346 /* No CPU hotplug when we change MTRR entries */
352 lock_cpu_hotplug(); 347 get_online_cpus();
353 /* Search for existing MTRR */ 348 /* Search for existing MTRR */
354 mutex_lock(&mtrr_mutex); 349 mutex_lock(&mtrr_mutex);
355 for (i = 0; i < num_var_ranges; ++i) { 350 for (i = 0; i < num_var_ranges; ++i) {
@@ -383,7 +378,7 @@ int mtrr_add_page(unsigned long base, unsigned long size,
383 goto out; 378 goto out;
384 } 379 }
385 if (increment) 380 if (increment)
386 ++usage_table[i]; 381 ++mtrr_usage_table[i];
387 error = i; 382 error = i;
388 goto out; 383 goto out;
389 } 384 }
@@ -391,13 +386,15 @@ int mtrr_add_page(unsigned long base, unsigned long size,
391 i = mtrr_if->get_free_region(base, size, replace); 386 i = mtrr_if->get_free_region(base, size, replace);
392 if (i >= 0) { 387 if (i >= 0) {
393 set_mtrr(i, base, size, type); 388 set_mtrr(i, base, size, type);
394 if (likely(replace < 0)) 389 if (likely(replace < 0)) {
395 usage_table[i] = 1; 390 mtrr_usage_table[i] = 1;
396 else { 391 } else {
397 usage_table[i] = usage_table[replace] + !!increment; 392 mtrr_usage_table[i] = mtrr_usage_table[replace];
393 if (increment)
394 mtrr_usage_table[i]++;
398 if (unlikely(replace != i)) { 395 if (unlikely(replace != i)) {
399 set_mtrr(replace, 0, 0, 0); 396 set_mtrr(replace, 0, 0, 0);
400 usage_table[replace] = 0; 397 mtrr_usage_table[replace] = 0;
401 } 398 }
402 } 399 }
403 } else 400 } else
@@ -405,7 +402,7 @@ int mtrr_add_page(unsigned long base, unsigned long size,
405 error = i; 402 error = i;
406 out: 403 out:
407 mutex_unlock(&mtrr_mutex); 404 mutex_unlock(&mtrr_mutex);
408 unlock_cpu_hotplug(); 405 put_online_cpus();
409 return error; 406 return error;
410} 407}
411 408
@@ -460,7 +457,7 @@ static int mtrr_check(unsigned long base, unsigned long size)
460 457
461int 458int
462mtrr_add(unsigned long base, unsigned long size, unsigned int type, 459mtrr_add(unsigned long base, unsigned long size, unsigned int type,
463 char increment) 460 bool increment)
464{ 461{
465 if (mtrr_check(base, size)) 462 if (mtrr_check(base, size))
466 return -EINVAL; 463 return -EINVAL;
@@ -495,7 +492,7 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size)
495 492
496 max = num_var_ranges; 493 max = num_var_ranges;
497 /* No CPU hotplug when we change MTRR entries */ 494 /* No CPU hotplug when we change MTRR entries */
498 lock_cpu_hotplug(); 495 get_online_cpus();
499 mutex_lock(&mtrr_mutex); 496 mutex_lock(&mtrr_mutex);
500 if (reg < 0) { 497 if (reg < 0) {
501 /* Search for existing MTRR */ 498 /* Search for existing MTRR */
@@ -527,16 +524,16 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size)
527 printk(KERN_WARNING "mtrr: MTRR %d not used\n", reg); 524 printk(KERN_WARNING "mtrr: MTRR %d not used\n", reg);
528 goto out; 525 goto out;
529 } 526 }
530 if (usage_table[reg] < 1) { 527 if (mtrr_usage_table[reg] < 1) {
531 printk(KERN_WARNING "mtrr: reg: %d has count=0\n", reg); 528 printk(KERN_WARNING "mtrr: reg: %d has count=0\n", reg);
532 goto out; 529 goto out;
533 } 530 }
534 if (--usage_table[reg] < 1) 531 if (--mtrr_usage_table[reg] < 1)
535 set_mtrr(reg, 0, 0, 0); 532 set_mtrr(reg, 0, 0, 0);
536 error = reg; 533 error = reg;
537 out: 534 out:
538 mutex_unlock(&mtrr_mutex); 535 mutex_unlock(&mtrr_mutex);
539 unlock_cpu_hotplug(); 536 put_online_cpus();
540 return error; 537 return error;
541} 538}
542/** 539/**
@@ -591,16 +588,11 @@ struct mtrr_value {
591 unsigned long lsize; 588 unsigned long lsize;
592}; 589};
593 590
594static struct mtrr_value * mtrr_state; 591static struct mtrr_value mtrr_state[MAX_VAR_RANGES];
595 592
596static int mtrr_save(struct sys_device * sysdev, pm_message_t state) 593static int mtrr_save(struct sys_device * sysdev, pm_message_t state)
597{ 594{
598 int i; 595 int i;
599 int size = num_var_ranges * sizeof(struct mtrr_value);
600
601 mtrr_state = kzalloc(size,GFP_ATOMIC);
602 if (!mtrr_state)
603 return -ENOMEM;
604 596
605 for (i = 0; i < num_var_ranges; i++) { 597 for (i = 0; i < num_var_ranges; i++) {
606 mtrr_if->get(i, 598 mtrr_if->get(i,
@@ -622,7 +614,6 @@ static int mtrr_restore(struct sys_device * sysdev)
622 mtrr_state[i].lsize, 614 mtrr_state[i].lsize,
623 mtrr_state[i].ltype); 615 mtrr_state[i].ltype);
624 } 616 }
625 kfree(mtrr_state);
626 return 0; 617 return 0;
627} 618}
628 619
@@ -633,6 +624,112 @@ static struct sysdev_driver mtrr_sysdev_driver = {
633 .resume = mtrr_restore, 624 .resume = mtrr_restore,
634}; 625};
635 626
627static int disable_mtrr_trim;
628
629static int __init disable_mtrr_trim_setup(char *str)
630{
631 disable_mtrr_trim = 1;
632 return 0;
633}
634early_param("disable_mtrr_trim", disable_mtrr_trim_setup);
635
636/*
637 * Newer AMD K8s and later CPUs have a special magic MSR way to force WB
638 * for memory >4GB. Check for that here.
639 * Note this won't check if the MTRRs < 4GB where the magic bit doesn't
640 * apply to are wrong, but so far we don't know of any such case in the wild.
641 */
642#define Tom2Enabled (1U << 21)
643#define Tom2ForceMemTypeWB (1U << 22)
644
645static __init int amd_special_default_mtrr(void)
646{
647 u32 l, h;
648
649 if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
650 return 0;
651 if (boot_cpu_data.x86 < 0xf || boot_cpu_data.x86 > 0x11)
652 return 0;
653 /* In case some hypervisor doesn't pass SYSCFG through */
654 if (rdmsr_safe(MSR_K8_SYSCFG, &l, &h) < 0)
655 return 0;
656 /*
657 * Memory between 4GB and top of mem is forced WB by this magic bit.
658 * Reserved before K8RevF, but should be zero there.
659 */
660 if ((l & (Tom2Enabled | Tom2ForceMemTypeWB)) ==
661 (Tom2Enabled | Tom2ForceMemTypeWB))
662 return 1;
663 return 0;
664}
665
666/**
667 * mtrr_trim_uncached_memory - trim RAM not covered by MTRRs
668 *
669 * Some buggy BIOSes don't setup the MTRRs properly for systems with certain
670 * memory configurations. This routine checks that the highest MTRR matches
671 * the end of memory, to make sure the MTRRs having a write back type cover
672 * all of the memory the kernel is intending to use. If not, it'll trim any
673 * memory off the end by adjusting end_pfn, removing it from the kernel's
674 * allocation pools, warning the user with an obnoxious message.
675 */
676int __init mtrr_trim_uncached_memory(unsigned long end_pfn)
677{
678 unsigned long i, base, size, highest_addr = 0, def, dummy;
679 mtrr_type type;
680 u64 trim_start, trim_size;
681
682 /*
683 * Make sure we only trim uncachable memory on machines that
684 * support the Intel MTRR architecture:
685 */
686 if (!is_cpu(INTEL) || disable_mtrr_trim)
687 return 0;
688 rdmsr(MTRRdefType_MSR, def, dummy);
689 def &= 0xff;
690 if (def != MTRR_TYPE_UNCACHABLE)
691 return 0;
692
693 if (amd_special_default_mtrr())
694 return 0;
695
696 /* Find highest cached pfn */
697 for (i = 0; i < num_var_ranges; i++) {
698 mtrr_if->get(i, &base, &size, &type);
699 if (type != MTRR_TYPE_WRBACK)
700 continue;
701 base <<= PAGE_SHIFT;
702 size <<= PAGE_SHIFT;
703 if (highest_addr < base + size)
704 highest_addr = base + size;
705 }
706
707 /* kvm/qemu doesn't have mtrr set right, don't trim them all */
708 if (!highest_addr) {
709 printk(KERN_WARNING "WARNING: strange, CPU MTRRs all blank?\n");
710 WARN_ON(1);
711 return 0;
712 }
713
714 if ((highest_addr >> PAGE_SHIFT) < end_pfn) {
715 printk(KERN_WARNING "WARNING: BIOS bug: CPU MTRRs don't cover"
716 " all of memory, losing %LdMB of RAM.\n",
717 (((u64)end_pfn << PAGE_SHIFT) - highest_addr) >> 20);
718
719 WARN_ON(1);
720
721 printk(KERN_INFO "update e820 for mtrr\n");
722 trim_start = highest_addr;
723 trim_size = end_pfn;
724 trim_size <<= PAGE_SHIFT;
725 trim_size -= trim_start;
726 add_memory_region(trim_start, trim_size, E820_RESERVED);
727 update_e820();
728 return 1;
729 }
730
731 return 0;
732}
636 733
637/** 734/**
638 * mtrr_bp_init - initialize mtrrs on the boot CPU 735 * mtrr_bp_init - initialize mtrrs on the boot CPU
diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.h b/arch/x86/kernel/cpu/mtrr/mtrr.h
index 289dfe6030e3..fb74a2c20814 100644
--- a/arch/x86/kernel/cpu/mtrr/mtrr.h
+++ b/arch/x86/kernel/cpu/mtrr/mtrr.h
@@ -2,10 +2,8 @@
2 * local mtrr defines. 2 * local mtrr defines.
3 */ 3 */
4 4
5#ifndef TRUE 5#include <linux/types.h>
6#define TRUE 1 6#include <linux/stddef.h>
7#define FALSE 0
8#endif
9 7
10#define MTRRcap_MSR 0x0fe 8#define MTRRcap_MSR 0x0fe
11#define MTRRdefType_MSR 0x2ff 9#define MTRRdefType_MSR 0x2ff
@@ -14,6 +12,7 @@
14#define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1) 12#define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1)
15 13
16#define NUM_FIXED_RANGES 88 14#define NUM_FIXED_RANGES 88
15#define MAX_VAR_RANGES 256
17#define MTRRfix64K_00000_MSR 0x250 16#define MTRRfix64K_00000_MSR 0x250
18#define MTRRfix16K_80000_MSR 0x258 17#define MTRRfix16K_80000_MSR 0x258
19#define MTRRfix16K_A0000_MSR 0x259 18#define MTRRfix16K_A0000_MSR 0x259
@@ -34,6 +33,8 @@
34 an 8 bit field: */ 33 an 8 bit field: */
35typedef u8 mtrr_type; 34typedef u8 mtrr_type;
36 35
36extern unsigned int mtrr_usage_table[MAX_VAR_RANGES];
37
37struct mtrr_ops { 38struct mtrr_ops {
38 u32 vendor; 39 u32 vendor;
39 u32 use_intel_if; 40 u32 use_intel_if;
diff --git a/arch/x86/kernel/cpu/mtrr/state.c b/arch/x86/kernel/cpu/mtrr/state.c
index 49e20c2afcdf..9f8ba923d1c9 100644
--- a/arch/x86/kernel/cpu/mtrr/state.c
+++ b/arch/x86/kernel/cpu/mtrr/state.c
@@ -4,6 +4,7 @@
4#include <asm/mtrr.h> 4#include <asm/mtrr.h>
5#include <asm/msr.h> 5#include <asm/msr.h>
6#include <asm/processor-cyrix.h> 6#include <asm/processor-cyrix.h>
7#include <asm/processor-flags.h>
7#include "mtrr.h" 8#include "mtrr.h"
8 9
9 10
@@ -25,7 +26,7 @@ void set_mtrr_prepare_save(struct set_mtrr_context *ctxt)
25 26
26 /* Disable and flush caches. Note that wbinvd flushes the TLBs as 27 /* Disable and flush caches. Note that wbinvd flushes the TLBs as
27 a side-effect */ 28 a side-effect */
28 cr0 = read_cr0() | 0x40000000; 29 cr0 = read_cr0() | X86_CR0_CD;
29 wbinvd(); 30 wbinvd();
30 write_cr0(cr0); 31 write_cr0(cr0);
31 wbinvd(); 32 wbinvd();
diff --git a/arch/x86/kernel/cpu/perfctr-watchdog.c b/arch/x86/kernel/cpu/perfctr-watchdog.c
index c02541e6e653..9b838324b818 100644
--- a/arch/x86/kernel/cpu/perfctr-watchdog.c
+++ b/arch/x86/kernel/cpu/perfctr-watchdog.c
@@ -167,7 +167,6 @@ void release_evntsel_nmi(unsigned int msr)
167 clear_bit(counter, evntsel_nmi_owner); 167 clear_bit(counter, evntsel_nmi_owner);
168} 168}
169 169
170EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi);
171EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi_bit); 170EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi_bit);
172EXPORT_SYMBOL(reserve_perfctr_nmi); 171EXPORT_SYMBOL(reserve_perfctr_nmi);
173EXPORT_SYMBOL(release_perfctr_nmi); 172EXPORT_SYMBOL(release_perfctr_nmi);
diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c
index 3900e46d66db..028213260148 100644
--- a/arch/x86/kernel/cpu/proc.c
+++ b/arch/x86/kernel/cpu/proc.c
@@ -188,7 +188,7 @@ static void *c_next(struct seq_file *m, void *v, loff_t *pos)
188static void c_stop(struct seq_file *m, void *v) 188static void c_stop(struct seq_file *m, void *v)
189{ 189{
190} 190}
191struct seq_operations cpuinfo_op = { 191const struct seq_operations cpuinfo_op = {
192 .start = c_start, 192 .start = c_start,
193 .next = c_next, 193 .next = c_next,
194 .stop = c_stop, 194 .stop = c_stop,
diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c
index 05c9936a16cc..dec66e452810 100644
--- a/arch/x86/kernel/cpuid.c
+++ b/arch/x86/kernel/cpuid.c
@@ -50,7 +50,7 @@ struct cpuid_command {
50 50
51static void cpuid_smp_cpuid(void *cmd_block) 51static void cpuid_smp_cpuid(void *cmd_block)
52{ 52{
53 struct cpuid_command *cmd = (struct cpuid_command *)cmd_block; 53 struct cpuid_command *cmd = cmd_block;
54 54
55 cpuid(cmd->reg, &cmd->data[0], &cmd->data[1], &cmd->data[2], 55 cpuid(cmd->reg, &cmd->data[0], &cmd->data[1], &cmd->data[2],
56 &cmd->data[3]); 56 &cmd->data[3]);
@@ -157,15 +157,15 @@ static int __cpuinit cpuid_class_cpu_callback(struct notifier_block *nfb,
157 157
158 switch (action) { 158 switch (action) {
159 case CPU_UP_PREPARE: 159 case CPU_UP_PREPARE:
160 case CPU_UP_PREPARE_FROZEN:
161 err = cpuid_device_create(cpu); 160 err = cpuid_device_create(cpu);
162 break; 161 break;
163 case CPU_UP_CANCELED: 162 case CPU_UP_CANCELED:
164 case CPU_UP_CANCELED_FROZEN:
165 case CPU_DEAD: 163 case CPU_DEAD:
166 case CPU_DEAD_FROZEN:
167 cpuid_device_destroy(cpu); 164 cpuid_device_destroy(cpu);
168 break; 165 break;
166 case CPU_UP_CANCELED_FROZEN:
167 destroy_suspended_device(cpuid_class, MKDEV(CPUID_MAJOR, cpu));
168 break;
169 } 169 }
170 return err ? NOTIFY_BAD : NOTIFY_OK; 170 return err ? NOTIFY_BAD : NOTIFY_OK;
171} 171}
diff --git a/arch/x86/kernel/doublefault_32.c b/arch/x86/kernel/doublefault_32.c
index 40978af630e7..a47798b59f07 100644
--- a/arch/x86/kernel/doublefault_32.c
+++ b/arch/x86/kernel/doublefault_32.c
@@ -17,7 +17,7 @@ static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
17 17
18static void doublefault_fn(void) 18static void doublefault_fn(void)
19{ 19{
20 struct Xgt_desc_struct gdt_desc = {0, 0}; 20 struct desc_ptr gdt_desc = {0, 0};
21 unsigned long gdt, tss; 21 unsigned long gdt, tss;
22 22
23 store_gdt(&gdt_desc); 23 store_gdt(&gdt_desc);
@@ -33,14 +33,15 @@ static void doublefault_fn(void)
33 printk(KERN_EMERG "double fault, tss at %08lx\n", tss); 33 printk(KERN_EMERG "double fault, tss at %08lx\n", tss);
34 34
35 if (ptr_ok(tss)) { 35 if (ptr_ok(tss)) {
36 struct i386_hw_tss *t = (struct i386_hw_tss *)tss; 36 struct x86_hw_tss *t = (struct x86_hw_tss *)tss;
37 37
38 printk(KERN_EMERG "eip = %08lx, esp = %08lx\n", t->eip, t->esp); 38 printk(KERN_EMERG "eip = %08lx, esp = %08lx\n",
39 t->ip, t->sp);
39 40
40 printk(KERN_EMERG "eax = %08lx, ebx = %08lx, ecx = %08lx, edx = %08lx\n", 41 printk(KERN_EMERG "eax = %08lx, ebx = %08lx, ecx = %08lx, edx = %08lx\n",
41 t->eax, t->ebx, t->ecx, t->edx); 42 t->ax, t->bx, t->cx, t->dx);
42 printk(KERN_EMERG "esi = %08lx, edi = %08lx\n", 43 printk(KERN_EMERG "esi = %08lx, edi = %08lx\n",
43 t->esi, t->edi); 44 t->si, t->di);
44 } 45 }
45 } 46 }
46 47
@@ -50,15 +51,15 @@ static void doublefault_fn(void)
50 51
51struct tss_struct doublefault_tss __cacheline_aligned = { 52struct tss_struct doublefault_tss __cacheline_aligned = {
52 .x86_tss = { 53 .x86_tss = {
53 .esp0 = STACK_START, 54 .sp0 = STACK_START,
54 .ss0 = __KERNEL_DS, 55 .ss0 = __KERNEL_DS,
55 .ldt = 0, 56 .ldt = 0,
56 .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, 57 .io_bitmap_base = INVALID_IO_BITMAP_OFFSET,
57 58
58 .eip = (unsigned long) doublefault_fn, 59 .ip = (unsigned long) doublefault_fn,
59 /* 0x2 bit is always set */ 60 /* 0x2 bit is always set */
60 .eflags = X86_EFLAGS_SF | 0x2, 61 .flags = X86_EFLAGS_SF | 0x2,
61 .esp = STACK_START, 62 .sp = STACK_START,
62 .es = __USER_DS, 63 .es = __USER_DS,
63 .cs = __KERNEL_CS, 64 .cs = __KERNEL_CS,
64 .ss = __KERNEL_DS, 65 .ss = __KERNEL_DS,
diff --git a/arch/x86/kernel/ds.c b/arch/x86/kernel/ds.c
new file mode 100644
index 000000000000..1c5ca4d18787
--- /dev/null
+++ b/arch/x86/kernel/ds.c
@@ -0,0 +1,464 @@
1/*
2 * Debug Store support
3 *
4 * This provides a low-level interface to the hardware's Debug Store
5 * feature that is used for last branch recording (LBR) and
6 * precise-event based sampling (PEBS).
7 *
8 * Different architectures use a different DS layout/pointer size.
9 * The below functions therefore work on a void*.
10 *
11 *
12 * Since there is no user for PEBS, yet, only LBR (or branch
13 * trace store, BTS) is supported.
14 *
15 *
16 * Copyright (C) 2007 Intel Corporation.
17 * Markus Metzger <markus.t.metzger@intel.com>, Dec 2007
18 */
19
20#include <asm/ds.h>
21
22#include <linux/errno.h>
23#include <linux/string.h>
24#include <linux/slab.h>
25
26
27/*
28 * Debug Store (DS) save area configuration (see Intel64 and IA32
29 * Architectures Software Developer's Manual, section 18.5)
30 *
31 * The DS configuration consists of the following fields; different
32 * architetures vary in the size of those fields.
33 * - double-word aligned base linear address of the BTS buffer
34 * - write pointer into the BTS buffer
35 * - end linear address of the BTS buffer (one byte beyond the end of
36 * the buffer)
37 * - interrupt pointer into BTS buffer
38 * (interrupt occurs when write pointer passes interrupt pointer)
39 * - double-word aligned base linear address of the PEBS buffer
40 * - write pointer into the PEBS buffer
41 * - end linear address of the PEBS buffer (one byte beyond the end of
42 * the buffer)
43 * - interrupt pointer into PEBS buffer
44 * (interrupt occurs when write pointer passes interrupt pointer)
45 * - value to which counter is reset following counter overflow
46 *
47 * On later architectures, the last branch recording hardware uses
48 * 64bit pointers even in 32bit mode.
49 *
50 *
51 * Branch Trace Store (BTS) records store information about control
52 * flow changes. They at least provide the following information:
53 * - source linear address
54 * - destination linear address
55 *
56 * Netburst supported a predicated bit that had been dropped in later
57 * architectures. We do not suppor it.
58 *
59 *
60 * In order to abstract from the actual DS and BTS layout, we describe
61 * the access to the relevant fields.
62 * Thanks to Andi Kleen for proposing this design.
63 *
64 * The implementation, however, is not as general as it might seem. In
65 * order to stay somewhat simple and efficient, we assume an
66 * underlying unsigned type (mostly a pointer type) and we expect the
67 * field to be at least as big as that type.
68 */
69
70/*
71 * A special from_ip address to indicate that the BTS record is an
72 * info record that needs to be interpreted or skipped.
73 */
74#define BTS_ESCAPE_ADDRESS (-1)
75
76/*
77 * A field access descriptor
78 */
79struct access_desc {
80 unsigned char offset;
81 unsigned char size;
82};
83
84/*
85 * The configuration for a particular DS/BTS hardware implementation.
86 */
87struct ds_configuration {
88 /* the DS configuration */
89 unsigned char sizeof_ds;
90 struct access_desc bts_buffer_base;
91 struct access_desc bts_index;
92 struct access_desc bts_absolute_maximum;
93 struct access_desc bts_interrupt_threshold;
94 /* the BTS configuration */
95 unsigned char sizeof_bts;
96 struct access_desc from_ip;
97 struct access_desc to_ip;
98 /* BTS variants used to store additional information like
99 timestamps */
100 struct access_desc info_type;
101 struct access_desc info_data;
102 unsigned long debugctl_mask;
103};
104
105/*
106 * The global configuration used by the below accessor functions
107 */
108static struct ds_configuration ds_cfg;
109
110/*
111 * Accessor functions for some DS and BTS fields using the above
112 * global ptrace_bts_cfg.
113 */
114static inline unsigned long get_bts_buffer_base(char *base)
115{
116 return *(unsigned long *)(base + ds_cfg.bts_buffer_base.offset);
117}
118static inline void set_bts_buffer_base(char *base, unsigned long value)
119{
120 (*(unsigned long *)(base + ds_cfg.bts_buffer_base.offset)) = value;
121}
122static inline unsigned long get_bts_index(char *base)
123{
124 return *(unsigned long *)(base + ds_cfg.bts_index.offset);
125}
126static inline void set_bts_index(char *base, unsigned long value)
127{
128 (*(unsigned long *)(base + ds_cfg.bts_index.offset)) = value;
129}
130static inline unsigned long get_bts_absolute_maximum(char *base)
131{
132 return *(unsigned long *)(base + ds_cfg.bts_absolute_maximum.offset);
133}
134static inline void set_bts_absolute_maximum(char *base, unsigned long value)
135{
136 (*(unsigned long *)(base + ds_cfg.bts_absolute_maximum.offset)) = value;
137}
138static inline unsigned long get_bts_interrupt_threshold(char *base)
139{
140 return *(unsigned long *)(base + ds_cfg.bts_interrupt_threshold.offset);
141}
142static inline void set_bts_interrupt_threshold(char *base, unsigned long value)
143{
144 (*(unsigned long *)(base + ds_cfg.bts_interrupt_threshold.offset)) = value;
145}
146static inline unsigned long get_from_ip(char *base)
147{
148 return *(unsigned long *)(base + ds_cfg.from_ip.offset);
149}
150static inline void set_from_ip(char *base, unsigned long value)
151{
152 (*(unsigned long *)(base + ds_cfg.from_ip.offset)) = value;
153}
154static inline unsigned long get_to_ip(char *base)
155{
156 return *(unsigned long *)(base + ds_cfg.to_ip.offset);
157}
158static inline void set_to_ip(char *base, unsigned long value)
159{
160 (*(unsigned long *)(base + ds_cfg.to_ip.offset)) = value;
161}
162static inline unsigned char get_info_type(char *base)
163{
164 return *(unsigned char *)(base + ds_cfg.info_type.offset);
165}
166static inline void set_info_type(char *base, unsigned char value)
167{
168 (*(unsigned char *)(base + ds_cfg.info_type.offset)) = value;
169}
170static inline unsigned long get_info_data(char *base)
171{
172 return *(unsigned long *)(base + ds_cfg.info_data.offset);
173}
174static inline void set_info_data(char *base, unsigned long value)
175{
176 (*(unsigned long *)(base + ds_cfg.info_data.offset)) = value;
177}
178
179
180int ds_allocate(void **dsp, size_t bts_size_in_bytes)
181{
182 size_t bts_size_in_records;
183 unsigned long bts;
184 void *ds;
185
186 if (!ds_cfg.sizeof_ds || !ds_cfg.sizeof_bts)
187 return -EOPNOTSUPP;
188
189 if (bts_size_in_bytes < 0)
190 return -EINVAL;
191
192 bts_size_in_records =
193 bts_size_in_bytes / ds_cfg.sizeof_bts;
194 bts_size_in_bytes =
195 bts_size_in_records * ds_cfg.sizeof_bts;
196
197 if (bts_size_in_bytes <= 0)
198 return -EINVAL;
199
200 bts = (unsigned long)kzalloc(bts_size_in_bytes, GFP_KERNEL);
201
202 if (!bts)
203 return -ENOMEM;
204
205 ds = kzalloc(ds_cfg.sizeof_ds, GFP_KERNEL);
206
207 if (!ds) {
208 kfree((void *)bts);
209 return -ENOMEM;
210 }
211
212 set_bts_buffer_base(ds, bts);
213 set_bts_index(ds, bts);
214 set_bts_absolute_maximum(ds, bts + bts_size_in_bytes);
215 set_bts_interrupt_threshold(ds, bts + bts_size_in_bytes + 1);
216
217 *dsp = ds;
218 return 0;
219}
220
221int ds_free(void **dsp)
222{
223 if (*dsp)
224 kfree((void *)get_bts_buffer_base(*dsp));
225 kfree(*dsp);
226 *dsp = 0;
227
228 return 0;
229}
230
231int ds_get_bts_size(void *ds)
232{
233 int size_in_bytes;
234
235 if (!ds_cfg.sizeof_ds || !ds_cfg.sizeof_bts)
236 return -EOPNOTSUPP;
237
238 if (!ds)
239 return 0;
240
241 size_in_bytes =
242 get_bts_absolute_maximum(ds) -
243 get_bts_buffer_base(ds);
244 return size_in_bytes;
245}
246
247int ds_get_bts_end(void *ds)
248{
249 int size_in_bytes = ds_get_bts_size(ds);
250
251 if (size_in_bytes <= 0)
252 return size_in_bytes;
253
254 return size_in_bytes / ds_cfg.sizeof_bts;
255}
256
257int ds_get_bts_index(void *ds)
258{
259 int index_offset_in_bytes;
260
261 if (!ds_cfg.sizeof_ds || !ds_cfg.sizeof_bts)
262 return -EOPNOTSUPP;
263
264 index_offset_in_bytes =
265 get_bts_index(ds) -
266 get_bts_buffer_base(ds);
267
268 return index_offset_in_bytes / ds_cfg.sizeof_bts;
269}
270
271int ds_set_overflow(void *ds, int method)
272{
273 switch (method) {
274 case DS_O_SIGNAL:
275 return -EOPNOTSUPP;
276 case DS_O_WRAP:
277 return 0;
278 default:
279 return -EINVAL;
280 }
281}
282
283int ds_get_overflow(void *ds)
284{
285 return DS_O_WRAP;
286}
287
288int ds_clear(void *ds)
289{
290 int bts_size = ds_get_bts_size(ds);
291 unsigned long bts_base;
292
293 if (bts_size <= 0)
294 return bts_size;
295
296 bts_base = get_bts_buffer_base(ds);
297 memset((void *)bts_base, 0, bts_size);
298
299 set_bts_index(ds, bts_base);
300 return 0;
301}
302
303int ds_read_bts(void *ds, int index, struct bts_struct *out)
304{
305 void *bts;
306
307 if (!ds_cfg.sizeof_ds || !ds_cfg.sizeof_bts)
308 return -EOPNOTSUPP;
309
310 if (index < 0)
311 return -EINVAL;
312
313 if (index >= ds_get_bts_size(ds))
314 return -EINVAL;
315
316 bts = (void *)(get_bts_buffer_base(ds) + (index * ds_cfg.sizeof_bts));
317
318 memset(out, 0, sizeof(*out));
319 if (get_from_ip(bts) == BTS_ESCAPE_ADDRESS) {
320 out->qualifier = get_info_type(bts);
321 out->variant.jiffies = get_info_data(bts);
322 } else {
323 out->qualifier = BTS_BRANCH;
324 out->variant.lbr.from_ip = get_from_ip(bts);
325 out->variant.lbr.to_ip = get_to_ip(bts);
326 }
327
328 return sizeof(*out);;
329}
330
331int ds_write_bts(void *ds, const struct bts_struct *in)
332{
333 unsigned long bts;
334
335 if (!ds_cfg.sizeof_ds || !ds_cfg.sizeof_bts)
336 return -EOPNOTSUPP;
337
338 if (ds_get_bts_size(ds) <= 0)
339 return -ENXIO;
340
341 bts = get_bts_index(ds);
342
343 memset((void *)bts, 0, ds_cfg.sizeof_bts);
344 switch (in->qualifier) {
345 case BTS_INVALID:
346 break;
347
348 case BTS_BRANCH:
349 set_from_ip((void *)bts, in->variant.lbr.from_ip);
350 set_to_ip((void *)bts, in->variant.lbr.to_ip);
351 break;
352
353 case BTS_TASK_ARRIVES:
354 case BTS_TASK_DEPARTS:
355 set_from_ip((void *)bts, BTS_ESCAPE_ADDRESS);
356 set_info_type((void *)bts, in->qualifier);
357 set_info_data((void *)bts, in->variant.jiffies);
358 break;
359
360 default:
361 return -EINVAL;
362 }
363
364 bts = bts + ds_cfg.sizeof_bts;
365 if (bts >= get_bts_absolute_maximum(ds))
366 bts = get_bts_buffer_base(ds);
367 set_bts_index(ds, bts);
368
369 return ds_cfg.sizeof_bts;
370}
371
372unsigned long ds_debugctl_mask(void)
373{
374 return ds_cfg.debugctl_mask;
375}
376
377#ifdef __i386__
378static const struct ds_configuration ds_cfg_netburst = {
379 .sizeof_ds = 9 * 4,
380 .bts_buffer_base = { 0, 4 },
381 .bts_index = { 4, 4 },
382 .bts_absolute_maximum = { 8, 4 },
383 .bts_interrupt_threshold = { 12, 4 },
384 .sizeof_bts = 3 * 4,
385 .from_ip = { 0, 4 },
386 .to_ip = { 4, 4 },
387 .info_type = { 4, 1 },
388 .info_data = { 8, 4 },
389 .debugctl_mask = (1<<2)|(1<<3)
390};
391
392static const struct ds_configuration ds_cfg_pentium_m = {
393 .sizeof_ds = 9 * 4,
394 .bts_buffer_base = { 0, 4 },
395 .bts_index = { 4, 4 },
396 .bts_absolute_maximum = { 8, 4 },
397 .bts_interrupt_threshold = { 12, 4 },
398 .sizeof_bts = 3 * 4,
399 .from_ip = { 0, 4 },
400 .to_ip = { 4, 4 },
401 .info_type = { 4, 1 },
402 .info_data = { 8, 4 },
403 .debugctl_mask = (1<<6)|(1<<7)
404};
405#endif /* _i386_ */
406
407static const struct ds_configuration ds_cfg_core2 = {
408 .sizeof_ds = 9 * 8,
409 .bts_buffer_base = { 0, 8 },
410 .bts_index = { 8, 8 },
411 .bts_absolute_maximum = { 16, 8 },
412 .bts_interrupt_threshold = { 24, 8 },
413 .sizeof_bts = 3 * 8,
414 .from_ip = { 0, 8 },
415 .to_ip = { 8, 8 },
416 .info_type = { 8, 1 },
417 .info_data = { 16, 8 },
418 .debugctl_mask = (1<<6)|(1<<7)|(1<<9)
419};
420
421static inline void
422ds_configure(const struct ds_configuration *cfg)
423{
424 ds_cfg = *cfg;
425}
426
427void __cpuinit ds_init_intel(struct cpuinfo_x86 *c)
428{
429 switch (c->x86) {
430 case 0x6:
431 switch (c->x86_model) {
432#ifdef __i386__
433 case 0xD:
434 case 0xE: /* Pentium M */
435 ds_configure(&ds_cfg_pentium_m);
436 break;
437#endif /* _i386_ */
438 case 0xF: /* Core2 */
439 ds_configure(&ds_cfg_core2);
440 break;
441 default:
442 /* sorry, don't know about them */
443 break;
444 }
445 break;
446 case 0xF:
447 switch (c->x86_model) {
448#ifdef __i386__
449 case 0x0:
450 case 0x1:
451 case 0x2: /* Netburst */
452 ds_configure(&ds_cfg_netburst);
453 break;
454#endif /* _i386_ */
455 default:
456 /* sorry, don't know about them */
457 break;
458 }
459 break;
460 default:
461 /* sorry, don't know about them */
462 break;
463 }
464}
diff --git a/arch/x86/kernel/e820_32.c b/arch/x86/kernel/e820_32.c
index 18f500d185a2..4e16ef4a2659 100644
--- a/arch/x86/kernel/e820_32.c
+++ b/arch/x86/kernel/e820_32.c
@@ -7,7 +7,6 @@
7#include <linux/kexec.h> 7#include <linux/kexec.h>
8#include <linux/module.h> 8#include <linux/module.h>
9#include <linux/mm.h> 9#include <linux/mm.h>
10#include <linux/efi.h>
11#include <linux/pfn.h> 10#include <linux/pfn.h>
12#include <linux/uaccess.h> 11#include <linux/uaccess.h>
13#include <linux/suspend.h> 12#include <linux/suspend.h>
@@ -17,11 +16,6 @@
17#include <asm/e820.h> 16#include <asm/e820.h>
18#include <asm/setup.h> 17#include <asm/setup.h>
19 18
20#ifdef CONFIG_EFI
21int efi_enabled = 0;
22EXPORT_SYMBOL(efi_enabled);
23#endif
24
25struct e820map e820; 19struct e820map e820;
26struct change_member { 20struct change_member {
27 struct e820entry *pbios; /* pointer to original bios entry */ 21 struct e820entry *pbios; /* pointer to original bios entry */
@@ -37,26 +31,6 @@ unsigned long pci_mem_start = 0x10000000;
37EXPORT_SYMBOL(pci_mem_start); 31EXPORT_SYMBOL(pci_mem_start);
38#endif 32#endif
39extern int user_defined_memmap; 33extern int user_defined_memmap;
40struct resource data_resource = {
41 .name = "Kernel data",
42 .start = 0,
43 .end = 0,
44 .flags = IORESOURCE_BUSY | IORESOURCE_MEM
45};
46
47struct resource code_resource = {
48 .name = "Kernel code",
49 .start = 0,
50 .end = 0,
51 .flags = IORESOURCE_BUSY | IORESOURCE_MEM
52};
53
54struct resource bss_resource = {
55 .name = "Kernel bss",
56 .start = 0,
57 .end = 0,
58 .flags = IORESOURCE_BUSY | IORESOURCE_MEM
59};
60 34
61static struct resource system_rom_resource = { 35static struct resource system_rom_resource = {
62 .name = "System ROM", 36 .name = "System ROM",
@@ -111,60 +85,6 @@ static struct resource video_rom_resource = {
111 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM 85 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
112}; 86};
113 87
114static struct resource video_ram_resource = {
115 .name = "Video RAM area",
116 .start = 0xa0000,
117 .end = 0xbffff,
118 .flags = IORESOURCE_BUSY | IORESOURCE_MEM
119};
120
121static struct resource standard_io_resources[] = { {
122 .name = "dma1",
123 .start = 0x0000,
124 .end = 0x001f,
125 .flags = IORESOURCE_BUSY | IORESOURCE_IO
126}, {
127 .name = "pic1",
128 .start = 0x0020,
129 .end = 0x0021,
130 .flags = IORESOURCE_BUSY | IORESOURCE_IO
131}, {
132 .name = "timer0",
133 .start = 0x0040,
134 .end = 0x0043,
135 .flags = IORESOURCE_BUSY | IORESOURCE_IO
136}, {
137 .name = "timer1",
138 .start = 0x0050,
139 .end = 0x0053,
140 .flags = IORESOURCE_BUSY | IORESOURCE_IO
141}, {
142 .name = "keyboard",
143 .start = 0x0060,
144 .end = 0x006f,
145 .flags = IORESOURCE_BUSY | IORESOURCE_IO
146}, {
147 .name = "dma page reg",
148 .start = 0x0080,
149 .end = 0x008f,
150 .flags = IORESOURCE_BUSY | IORESOURCE_IO
151}, {
152 .name = "pic2",
153 .start = 0x00a0,
154 .end = 0x00a1,
155 .flags = IORESOURCE_BUSY | IORESOURCE_IO
156}, {
157 .name = "dma2",
158 .start = 0x00c0,
159 .end = 0x00df,
160 .flags = IORESOURCE_BUSY | IORESOURCE_IO
161}, {
162 .name = "fpu",
163 .start = 0x00f0,
164 .end = 0x00ff,
165 .flags = IORESOURCE_BUSY | IORESOURCE_IO
166} };
167
168#define ROMSIGNATURE 0xaa55 88#define ROMSIGNATURE 0xaa55
169 89
170static int __init romsignature(const unsigned char *rom) 90static int __init romsignature(const unsigned char *rom)
@@ -260,10 +180,9 @@ static void __init probe_roms(void)
260 * Request address space for all standard RAM and ROM resources 180 * Request address space for all standard RAM and ROM resources
261 * and also for regions reported as reserved by the e820. 181 * and also for regions reported as reserved by the e820.
262 */ 182 */
263static void __init 183void __init init_iomem_resources(struct resource *code_resource,
264legacy_init_iomem_resources(struct resource *code_resource, 184 struct resource *data_resource,
265 struct resource *data_resource, 185 struct resource *bss_resource)
266 struct resource *bss_resource)
267{ 186{
268 int i; 187 int i;
269 188
@@ -305,35 +224,6 @@ legacy_init_iomem_resources(struct resource *code_resource,
305 } 224 }
306} 225}
307 226
308/*
309 * Request address space for all standard resources
310 *
311 * This is called just before pcibios_init(), which is also a
312 * subsys_initcall, but is linked in later (in arch/i386/pci/common.c).
313 */
314static int __init request_standard_resources(void)
315{
316 int i;
317
318 printk("Setting up standard PCI resources\n");
319 if (efi_enabled)
320 efi_initialize_iomem_resources(&code_resource,
321 &data_resource, &bss_resource);
322 else
323 legacy_init_iomem_resources(&code_resource,
324 &data_resource, &bss_resource);
325
326 /* EFI systems may still have VGA */
327 request_resource(&iomem_resource, &video_ram_resource);
328
329 /* request I/O space for devices used on all i[345]86 PCs */
330 for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++)
331 request_resource(&ioport_resource, &standard_io_resources[i]);
332 return 0;
333}
334
335subsys_initcall(request_standard_resources);
336
337#if defined(CONFIG_PM) && defined(CONFIG_HIBERNATION) 227#if defined(CONFIG_PM) && defined(CONFIG_HIBERNATION)
338/** 228/**
339 * e820_mark_nosave_regions - Find the ranges of physical addresses that do not 229 * e820_mark_nosave_regions - Find the ranges of physical addresses that do not
@@ -370,19 +260,17 @@ void __init add_memory_region(unsigned long long start,
370{ 260{
371 int x; 261 int x;
372 262
373 if (!efi_enabled) { 263 x = e820.nr_map;
374 x = e820.nr_map;
375
376 if (x == E820MAX) {
377 printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
378 return;
379 }
380 264
381 e820.map[x].addr = start; 265 if (x == E820MAX) {
382 e820.map[x].size = size; 266 printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
383 e820.map[x].type = type; 267 return;
384 e820.nr_map++;
385 } 268 }
269
270 e820.map[x].addr = start;
271 e820.map[x].size = size;
272 e820.map[x].type = type;
273 e820.nr_map++;
386} /* add_memory_region */ 274} /* add_memory_region */
387 275
388/* 276/*
@@ -598,29 +486,6 @@ int __init copy_e820_map(struct e820entry * biosmap, int nr_map)
598} 486}
599 487
600/* 488/*
601 * Callback for efi_memory_walk.
602 */
603static int __init
604efi_find_max_pfn(unsigned long start, unsigned long end, void *arg)
605{
606 unsigned long *max_pfn = arg, pfn;
607
608 if (start < end) {
609 pfn = PFN_UP(end -1);
610 if (pfn > *max_pfn)
611 *max_pfn = pfn;
612 }
613 return 0;
614}
615
616static int __init
617efi_memory_present_wrapper(unsigned long start, unsigned long end, void *arg)
618{
619 memory_present(0, PFN_UP(start), PFN_DOWN(end));
620 return 0;
621}
622
623/*
624 * Find the highest page frame number we have available 489 * Find the highest page frame number we have available
625 */ 490 */
626void __init find_max_pfn(void) 491void __init find_max_pfn(void)
@@ -628,11 +493,6 @@ void __init find_max_pfn(void)
628 int i; 493 int i;
629 494
630 max_pfn = 0; 495 max_pfn = 0;
631 if (efi_enabled) {
632 efi_memmap_walk(efi_find_max_pfn, &max_pfn);
633 efi_memmap_walk(efi_memory_present_wrapper, NULL);
634 return;
635 }
636 496
637 for (i = 0; i < e820.nr_map; i++) { 497 for (i = 0; i < e820.nr_map; i++) {
638 unsigned long start, end; 498 unsigned long start, end;
@@ -650,34 +510,12 @@ void __init find_max_pfn(void)
650} 510}
651 511
652/* 512/*
653 * Free all available memory for boot time allocation. Used
654 * as a callback function by efi_memory_walk()
655 */
656
657static int __init
658free_available_memory(unsigned long start, unsigned long end, void *arg)
659{
660 /* check max_low_pfn */
661 if (start >= (max_low_pfn << PAGE_SHIFT))
662 return 0;
663 if (end >= (max_low_pfn << PAGE_SHIFT))
664 end = max_low_pfn << PAGE_SHIFT;
665 if (start < end)
666 free_bootmem(start, end - start);
667
668 return 0;
669}
670/*
671 * Register fully available low RAM pages with the bootmem allocator. 513 * Register fully available low RAM pages with the bootmem allocator.
672 */ 514 */
673void __init register_bootmem_low_pages(unsigned long max_low_pfn) 515void __init register_bootmem_low_pages(unsigned long max_low_pfn)
674{ 516{
675 int i; 517 int i;
676 518
677 if (efi_enabled) {
678 efi_memmap_walk(free_available_memory, NULL);
679 return;
680 }
681 for (i = 0; i < e820.nr_map; i++) { 519 for (i = 0; i < e820.nr_map; i++) {
682 unsigned long curr_pfn, last_pfn, size; 520 unsigned long curr_pfn, last_pfn, size;
683 /* 521 /*
@@ -785,56 +623,12 @@ void __init print_memory_map(char *who)
785 } 623 }
786} 624}
787 625
788static __init __always_inline void efi_limit_regions(unsigned long long size)
789{
790 unsigned long long current_addr = 0;
791 efi_memory_desc_t *md, *next_md;
792 void *p, *p1;
793 int i, j;
794
795 j = 0;
796 p1 = memmap.map;
797 for (p = p1, i = 0; p < memmap.map_end; p += memmap.desc_size, i++) {
798 md = p;
799 next_md = p1;
800 current_addr = md->phys_addr +
801 PFN_PHYS(md->num_pages);
802 if (is_available_memory(md)) {
803 if (md->phys_addr >= size) continue;
804 memcpy(next_md, md, memmap.desc_size);
805 if (current_addr >= size) {
806 next_md->num_pages -=
807 PFN_UP(current_addr-size);
808 }
809 p1 += memmap.desc_size;
810 next_md = p1;
811 j++;
812 } else if ((md->attribute & EFI_MEMORY_RUNTIME) ==
813 EFI_MEMORY_RUNTIME) {
814 /* In order to make runtime services
815 * available we have to include runtime
816 * memory regions in memory map */
817 memcpy(next_md, md, memmap.desc_size);
818 p1 += memmap.desc_size;
819 next_md = p1;
820 j++;
821 }
822 }
823 memmap.nr_map = j;
824 memmap.map_end = memmap.map +
825 (memmap.nr_map * memmap.desc_size);
826}
827
828void __init limit_regions(unsigned long long size) 626void __init limit_regions(unsigned long long size)
829{ 627{
830 unsigned long long current_addr; 628 unsigned long long current_addr;
831 int i; 629 int i;
832 630
833 print_memory_map("limit_regions start"); 631 print_memory_map("limit_regions start");
834 if (efi_enabled) {
835 efi_limit_regions(size);
836 return;
837 }
838 for (i = 0; i < e820.nr_map; i++) { 632 for (i = 0; i < e820.nr_map; i++) {
839 current_addr = e820.map[i].addr + e820.map[i].size; 633 current_addr = e820.map[i].addr + e820.map[i].size;
840 if (current_addr < size) 634 if (current_addr < size)
@@ -955,3 +749,14 @@ static int __init parse_memmap(char *arg)
955 return 0; 749 return 0;
956} 750}
957early_param("memmap", parse_memmap); 751early_param("memmap", parse_memmap);
752void __init update_e820(void)
753{
754 u8 nr_map;
755
756 nr_map = e820.nr_map;
757 if (sanitize_e820_map(e820.map, &nr_map))
758 return;
759 e820.nr_map = nr_map;
760 printk(KERN_INFO "modified physical RAM map:\n");
761 print_memory_map("modified");
762}
diff --git a/arch/x86/kernel/e820_64.c b/arch/x86/kernel/e820_64.c
index 04698e0b056c..c617174e8963 100644
--- a/arch/x86/kernel/e820_64.c
+++ b/arch/x86/kernel/e820_64.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * Handle the memory map. 2 * Handle the memory map.
3 * The functions here do the job until bootmem takes over. 3 * The functions here do the job until bootmem takes over.
4 * 4 *
@@ -26,80 +26,87 @@
26#include <asm/proto.h> 26#include <asm/proto.h>
27#include <asm/setup.h> 27#include <asm/setup.h>
28#include <asm/sections.h> 28#include <asm/sections.h>
29#include <asm/kdebug.h>
29 30
30struct e820map e820; 31struct e820map e820;
31 32
32/* 33/*
33 * PFN of last memory page. 34 * PFN of last memory page.
34 */ 35 */
35unsigned long end_pfn; 36unsigned long end_pfn;
36EXPORT_SYMBOL(end_pfn);
37 37
38/* 38/*
39 * end_pfn only includes RAM, while end_pfn_map includes all e820 entries. 39 * end_pfn only includes RAM, while end_pfn_map includes all e820 entries.
40 * The direct mapping extends to end_pfn_map, so that we can directly access 40 * The direct mapping extends to end_pfn_map, so that we can directly access
41 * apertures, ACPI and other tables without having to play with fixmaps. 41 * apertures, ACPI and other tables without having to play with fixmaps.
42 */ 42 */
43unsigned long end_pfn_map; 43unsigned long end_pfn_map;
44 44
45/* 45/*
46 * Last pfn which the user wants to use. 46 * Last pfn which the user wants to use.
47 */ 47 */
48static unsigned long __initdata end_user_pfn = MAXMEM>>PAGE_SHIFT; 48static unsigned long __initdata end_user_pfn = MAXMEM>>PAGE_SHIFT;
49 49
50extern struct resource code_resource, data_resource, bss_resource; 50/*
51 51 * Early reserved memory areas.
52/* Check for some hardcoded bad areas that early boot is not allowed to touch */ 52 */
53static inline int bad_addr(unsigned long *addrp, unsigned long size) 53#define MAX_EARLY_RES 20
54{ 54
55 unsigned long addr = *addrp, last = addr + size; 55struct early_res {
56 56 unsigned long start, end;
57 /* various gunk below that needed for SMP startup */ 57};
58 if (addr < 0x8000) { 58static struct early_res early_res[MAX_EARLY_RES] __initdata = {
59 *addrp = PAGE_ALIGN(0x8000); 59 { 0, PAGE_SIZE }, /* BIOS data page */
60 return 1; 60#ifdef CONFIG_SMP
61 } 61 { SMP_TRAMPOLINE_BASE, SMP_TRAMPOLINE_BASE + 2*PAGE_SIZE },
62
63 /* direct mapping tables of the kernel */
64 if (last >= table_start<<PAGE_SHIFT && addr < table_end<<PAGE_SHIFT) {
65 *addrp = PAGE_ALIGN(table_end << PAGE_SHIFT);
66 return 1;
67 }
68
69 /* initrd */
70#ifdef CONFIG_BLK_DEV_INITRD
71 if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) {
72 unsigned long ramdisk_image = boot_params.hdr.ramdisk_image;
73 unsigned long ramdisk_size = boot_params.hdr.ramdisk_size;
74 unsigned long ramdisk_end = ramdisk_image+ramdisk_size;
75
76 if (last >= ramdisk_image && addr < ramdisk_end) {
77 *addrp = PAGE_ALIGN(ramdisk_end);
78 return 1;
79 }
80 }
81#endif 62#endif
82 /* kernel code */ 63 {}
83 if (last >= __pa_symbol(&_text) && addr < __pa_symbol(&_end)) { 64};
84 *addrp = PAGE_ALIGN(__pa_symbol(&_end)); 65
85 return 1; 66void __init reserve_early(unsigned long start, unsigned long end)
67{
68 int i;
69 struct early_res *r;
70 for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) {
71 r = &early_res[i];
72 if (end > r->start && start < r->end)
73 panic("Overlapping early reservations %lx-%lx to %lx-%lx\n",
74 start, end, r->start, r->end);
86 } 75 }
76 if (i >= MAX_EARLY_RES)
77 panic("Too many early reservations");
78 r = &early_res[i];
79 r->start = start;
80 r->end = end;
81}
87 82
88 if (last >= ebda_addr && addr < ebda_addr + ebda_size) { 83void __init early_res_to_bootmem(void)
89 *addrp = PAGE_ALIGN(ebda_addr + ebda_size); 84{
90 return 1; 85 int i;
86 for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) {
87 struct early_res *r = &early_res[i];
88 reserve_bootmem_generic(r->start, r->end - r->start);
91 } 89 }
90}
92 91
93#ifdef CONFIG_NUMA 92/* Check for already reserved areas */
94 /* NUMA memory to node map */ 93static inline int bad_addr(unsigned long *addrp, unsigned long size)
95 if (last >= nodemap_addr && addr < nodemap_addr + nodemap_size) { 94{
96 *addrp = nodemap_addr + nodemap_size; 95 int i;
97 return 1; 96 unsigned long addr = *addrp, last;
97 int changed = 0;
98again:
99 last = addr + size;
100 for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) {
101 struct early_res *r = &early_res[i];
102 if (last >= r->start && addr < r->end) {
103 *addrp = addr = r->end;
104 changed = 1;
105 goto again;
106 }
98 } 107 }
99#endif 108 return changed;
100 /* XXX ramdisk image here? */ 109}
101 return 0;
102}
103 110
104/* 111/*
105 * This function checks if any part of the range <start,end> is mapped 112 * This function checks if any part of the range <start,end> is mapped
@@ -107,16 +114,18 @@ static inline int bad_addr(unsigned long *addrp, unsigned long size)
107 */ 114 */
108int 115int
109e820_any_mapped(unsigned long start, unsigned long end, unsigned type) 116e820_any_mapped(unsigned long start, unsigned long end, unsigned type)
110{ 117{
111 int i; 118 int i;
112 for (i = 0; i < e820.nr_map; i++) { 119
113 struct e820entry *ei = &e820.map[i]; 120 for (i = 0; i < e820.nr_map; i++) {
114 if (type && ei->type != type) 121 struct e820entry *ei = &e820.map[i];
122
123 if (type && ei->type != type)
115 continue; 124 continue;
116 if (ei->addr >= end || ei->addr + ei->size <= start) 125 if (ei->addr >= end || ei->addr + ei->size <= start)
117 continue; 126 continue;
118 return 1; 127 return 1;
119 } 128 }
120 return 0; 129 return 0;
121} 130}
122EXPORT_SYMBOL_GPL(e820_any_mapped); 131EXPORT_SYMBOL_GPL(e820_any_mapped);
@@ -127,11 +136,14 @@ EXPORT_SYMBOL_GPL(e820_any_mapped);
127 * Note: this function only works correct if the e820 table is sorted and 136 * Note: this function only works correct if the e820 table is sorted and
128 * not-overlapping, which is the case 137 * not-overlapping, which is the case
129 */ 138 */
130int __init e820_all_mapped(unsigned long start, unsigned long end, unsigned type) 139int __init e820_all_mapped(unsigned long start, unsigned long end,
140 unsigned type)
131{ 141{
132 int i; 142 int i;
143
133 for (i = 0; i < e820.nr_map; i++) { 144 for (i = 0; i < e820.nr_map; i++) {
134 struct e820entry *ei = &e820.map[i]; 145 struct e820entry *ei = &e820.map[i];
146
135 if (type && ei->type != type) 147 if (type && ei->type != type)
136 continue; 148 continue;
137 /* is the region (part) in overlap with the current region ?*/ 149 /* is the region (part) in overlap with the current region ?*/
@@ -143,65 +155,73 @@ int __init e820_all_mapped(unsigned long start, unsigned long end, unsigned type
143 */ 155 */
144 if (ei->addr <= start) 156 if (ei->addr <= start)
145 start = ei->addr + ei->size; 157 start = ei->addr + ei->size;
146 /* if start is now at or beyond end, we're done, full coverage */ 158 /*
159 * if start is now at or beyond end, we're done, full
160 * coverage
161 */
147 if (start >= end) 162 if (start >= end)
148 return 1; /* we're done */ 163 return 1;
149 } 164 }
150 return 0; 165 return 0;
151} 166}
152 167
153/* 168/*
154 * Find a free area in a specific range. 169 * Find a free area in a specific range.
155 */ 170 */
156unsigned long __init find_e820_area(unsigned long start, unsigned long end, unsigned size) 171unsigned long __init find_e820_area(unsigned long start, unsigned long end,
157{ 172 unsigned size)
158 int i; 173{
159 for (i = 0; i < e820.nr_map; i++) { 174 int i;
160 struct e820entry *ei = &e820.map[i]; 175
161 unsigned long addr = ei->addr, last; 176 for (i = 0; i < e820.nr_map; i++) {
162 if (ei->type != E820_RAM) 177 struct e820entry *ei = &e820.map[i];
163 continue; 178 unsigned long addr = ei->addr, last;
164 if (addr < start) 179
180 if (ei->type != E820_RAM)
181 continue;
182 if (addr < start)
165 addr = start; 183 addr = start;
166 if (addr > ei->addr + ei->size) 184 if (addr > ei->addr + ei->size)
167 continue; 185 continue;
168 while (bad_addr(&addr, size) && addr+size <= ei->addr+ei->size) 186 while (bad_addr(&addr, size) && addr+size <= ei->addr+ei->size)
169 ; 187 ;
170 last = PAGE_ALIGN(addr) + size; 188 last = PAGE_ALIGN(addr) + size;
171 if (last > ei->addr + ei->size) 189 if (last > ei->addr + ei->size)
172 continue; 190 continue;
173 if (last > end) 191 if (last > end)
174 continue; 192 continue;
175 return addr; 193 return addr;
176 } 194 }
177 return -1UL; 195 return -1UL;
178} 196}
179 197
180/* 198/*
181 * Find the highest page frame number we have available 199 * Find the highest page frame number we have available
182 */ 200 */
183unsigned long __init e820_end_of_ram(void) 201unsigned long __init e820_end_of_ram(void)
184{ 202{
185 unsigned long end_pfn = 0; 203 unsigned long end_pfn;
204
186 end_pfn = find_max_pfn_with_active_regions(); 205 end_pfn = find_max_pfn_with_active_regions();
187 206
188 if (end_pfn > end_pfn_map) 207 if (end_pfn > end_pfn_map)
189 end_pfn_map = end_pfn; 208 end_pfn_map = end_pfn;
190 if (end_pfn_map > MAXMEM>>PAGE_SHIFT) 209 if (end_pfn_map > MAXMEM>>PAGE_SHIFT)
191 end_pfn_map = MAXMEM>>PAGE_SHIFT; 210 end_pfn_map = MAXMEM>>PAGE_SHIFT;
192 if (end_pfn > end_user_pfn) 211 if (end_pfn > end_user_pfn)
193 end_pfn = end_user_pfn; 212 end_pfn = end_user_pfn;
194 if (end_pfn > end_pfn_map) 213 if (end_pfn > end_pfn_map)
195 end_pfn = end_pfn_map; 214 end_pfn = end_pfn_map;
196 215
197 printk("end_pfn_map = %lu\n", end_pfn_map); 216 printk(KERN_INFO "end_pfn_map = %lu\n", end_pfn_map);
198 return end_pfn; 217 return end_pfn;
199} 218}
200 219
201/* 220/*
202 * Mark e820 reserved areas as busy for the resource manager. 221 * Mark e820 reserved areas as busy for the resource manager.
203 */ 222 */
204void __init e820_reserve_resources(void) 223void __init e820_reserve_resources(struct resource *code_resource,
224 struct resource *data_resource, struct resource *bss_resource)
205{ 225{
206 int i; 226 int i;
207 for (i = 0; i < e820.nr_map; i++) { 227 for (i = 0; i < e820.nr_map; i++) {
@@ -219,13 +239,13 @@ void __init e820_reserve_resources(void)
219 request_resource(&iomem_resource, res); 239 request_resource(&iomem_resource, res);
220 if (e820.map[i].type == E820_RAM) { 240 if (e820.map[i].type == E820_RAM) {
221 /* 241 /*
222 * We don't know which RAM region contains kernel data, 242 * We don't know which RAM region contains kernel data,
223 * so we try it repeatedly and let the resource manager 243 * so we try it repeatedly and let the resource manager
224 * test it. 244 * test it.
225 */ 245 */
226 request_resource(res, &code_resource); 246 request_resource(res, code_resource);
227 request_resource(res, &data_resource); 247 request_resource(res, data_resource);
228 request_resource(res, &bss_resource); 248 request_resource(res, bss_resource);
229#ifdef CONFIG_KEXEC 249#ifdef CONFIG_KEXEC
230 if (crashk_res.start != crashk_res.end) 250 if (crashk_res.start != crashk_res.end)
231 request_resource(res, &crashk_res); 251 request_resource(res, &crashk_res);
@@ -322,9 +342,9 @@ e820_register_active_regions(int nid, unsigned long start_pfn,
322 add_active_range(nid, ei_startpfn, ei_endpfn); 342 add_active_range(nid, ei_startpfn, ei_endpfn);
323} 343}
324 344
325/* 345/*
326 * Add a memory region to the kernel e820 map. 346 * Add a memory region to the kernel e820 map.
327 */ 347 */
328void __init add_memory_region(unsigned long start, unsigned long size, int type) 348void __init add_memory_region(unsigned long start, unsigned long size, int type)
329{ 349{
330 int x = e820.nr_map; 350 int x = e820.nr_map;
@@ -349,9 +369,7 @@ unsigned long __init e820_hole_size(unsigned long start, unsigned long end)
349{ 369{
350 unsigned long start_pfn = start >> PAGE_SHIFT; 370 unsigned long start_pfn = start >> PAGE_SHIFT;
351 unsigned long end_pfn = end >> PAGE_SHIFT; 371 unsigned long end_pfn = end >> PAGE_SHIFT;
352 unsigned long ei_startpfn; 372 unsigned long ei_startpfn, ei_endpfn, ram = 0;
353 unsigned long ei_endpfn;
354 unsigned long ram = 0;
355 int i; 373 int i;
356 374
357 for (i = 0; i < e820.nr_map; i++) { 375 for (i = 0; i < e820.nr_map; i++) {
@@ -363,28 +381,31 @@ unsigned long __init e820_hole_size(unsigned long start, unsigned long end)
363 return end - start - (ram << PAGE_SHIFT); 381 return end - start - (ram << PAGE_SHIFT);
364} 382}
365 383
366void __init e820_print_map(char *who) 384static void __init e820_print_map(char *who)
367{ 385{
368 int i; 386 int i;
369 387
370 for (i = 0; i < e820.nr_map; i++) { 388 for (i = 0; i < e820.nr_map; i++) {
371 printk(KERN_INFO " %s: %016Lx - %016Lx ", who, 389 printk(KERN_INFO " %s: %016Lx - %016Lx ", who,
372 (unsigned long long) e820.map[i].addr, 390 (unsigned long long) e820.map[i].addr,
373 (unsigned long long) (e820.map[i].addr + e820.map[i].size)); 391 (unsigned long long)
392 (e820.map[i].addr + e820.map[i].size));
374 switch (e820.map[i].type) { 393 switch (e820.map[i].type) {
375 case E820_RAM: printk("(usable)\n"); 394 case E820_RAM:
376 break; 395 printk(KERN_CONT "(usable)\n");
396 break;
377 case E820_RESERVED: 397 case E820_RESERVED:
378 printk("(reserved)\n"); 398 printk(KERN_CONT "(reserved)\n");
379 break; 399 break;
380 case E820_ACPI: 400 case E820_ACPI:
381 printk("(ACPI data)\n"); 401 printk(KERN_CONT "(ACPI data)\n");
382 break; 402 break;
383 case E820_NVS: 403 case E820_NVS:
384 printk("(ACPI NVS)\n"); 404 printk(KERN_CONT "(ACPI NVS)\n");
385 break; 405 break;
386 default: printk("type %u\n", e820.map[i].type); 406 default:
387 break; 407 printk(KERN_CONT "type %u\n", e820.map[i].type);
408 break;
388 } 409 }
389 } 410 }
390} 411}
@@ -392,11 +413,11 @@ void __init e820_print_map(char *who)
392/* 413/*
393 * Sanitize the BIOS e820 map. 414 * Sanitize the BIOS e820 map.
394 * 415 *
395 * Some e820 responses include overlapping entries. The following 416 * Some e820 responses include overlapping entries. The following
396 * replaces the original e820 map with a new one, removing overlaps. 417 * replaces the original e820 map with a new one, removing overlaps.
397 * 418 *
398 */ 419 */
399static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map) 420static int __init sanitize_e820_map(struct e820entry *biosmap, char *pnr_map)
400{ 421{
401 struct change_member { 422 struct change_member {
402 struct e820entry *pbios; /* pointer to original bios entry */ 423 struct e820entry *pbios; /* pointer to original bios entry */
@@ -416,7 +437,8 @@ static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map)
416 int i; 437 int i;
417 438
418 /* 439 /*
419 Visually we're performing the following (1,2,3,4 = memory types)... 440 Visually we're performing the following
441 (1,2,3,4 = memory types)...
420 442
421 Sample memory map (w/overlaps): 443 Sample memory map (w/overlaps):
422 ____22__________________ 444 ____22__________________
@@ -458,22 +480,23 @@ static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map)
458 old_nr = *pnr_map; 480 old_nr = *pnr_map;
459 481
460 /* bail out if we find any unreasonable addresses in bios map */ 482 /* bail out if we find any unreasonable addresses in bios map */
461 for (i=0; i<old_nr; i++) 483 for (i = 0; i < old_nr; i++)
462 if (biosmap[i].addr + biosmap[i].size < biosmap[i].addr) 484 if (biosmap[i].addr + biosmap[i].size < biosmap[i].addr)
463 return -1; 485 return -1;
464 486
465 /* create pointers for initial change-point information (for sorting) */ 487 /* create pointers for initial change-point information (for sorting) */
466 for (i=0; i < 2*old_nr; i++) 488 for (i = 0; i < 2 * old_nr; i++)
467 change_point[i] = &change_point_list[i]; 489 change_point[i] = &change_point_list[i];
468 490
469 /* record all known change-points (starting and ending addresses), 491 /* record all known change-points (starting and ending addresses),
470 omitting those that are for empty memory regions */ 492 omitting those that are for empty memory regions */
471 chgidx = 0; 493 chgidx = 0;
472 for (i=0; i < old_nr; i++) { 494 for (i = 0; i < old_nr; i++) {
473 if (biosmap[i].size != 0) { 495 if (biosmap[i].size != 0) {
474 change_point[chgidx]->addr = biosmap[i].addr; 496 change_point[chgidx]->addr = biosmap[i].addr;
475 change_point[chgidx++]->pbios = &biosmap[i]; 497 change_point[chgidx++]->pbios = &biosmap[i];
476 change_point[chgidx]->addr = biosmap[i].addr + biosmap[i].size; 498 change_point[chgidx]->addr = biosmap[i].addr +
499 biosmap[i].size;
477 change_point[chgidx++]->pbios = &biosmap[i]; 500 change_point[chgidx++]->pbios = &biosmap[i];
478 } 501 }
479 } 502 }
@@ -483,75 +506,106 @@ static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map)
483 still_changing = 1; 506 still_changing = 1;
484 while (still_changing) { 507 while (still_changing) {
485 still_changing = 0; 508 still_changing = 0;
486 for (i=1; i < chg_nr; i++) { 509 for (i = 1; i < chg_nr; i++) {
487 /* if <current_addr> > <last_addr>, swap */ 510 unsigned long long curaddr, lastaddr;
488 /* or, if current=<start_addr> & last=<end_addr>, swap */ 511 unsigned long long curpbaddr, lastpbaddr;
489 if ((change_point[i]->addr < change_point[i-1]->addr) || 512
490 ((change_point[i]->addr == change_point[i-1]->addr) && 513 curaddr = change_point[i]->addr;
491 (change_point[i]->addr == change_point[i]->pbios->addr) && 514 lastaddr = change_point[i - 1]->addr;
492 (change_point[i-1]->addr != change_point[i-1]->pbios->addr)) 515 curpbaddr = change_point[i]->pbios->addr;
493 ) 516 lastpbaddr = change_point[i - 1]->pbios->addr;
494 { 517
518 /*
519 * swap entries, when:
520 *
521 * curaddr > lastaddr or
522 * curaddr == lastaddr and curaddr == curpbaddr and
523 * lastaddr != lastpbaddr
524 */
525 if (curaddr < lastaddr ||
526 (curaddr == lastaddr && curaddr == curpbaddr &&
527 lastaddr != lastpbaddr)) {
495 change_tmp = change_point[i]; 528 change_tmp = change_point[i];
496 change_point[i] = change_point[i-1]; 529 change_point[i] = change_point[i-1];
497 change_point[i-1] = change_tmp; 530 change_point[i-1] = change_tmp;
498 still_changing=1; 531 still_changing = 1;
499 } 532 }
500 } 533 }
501 } 534 }
502 535
503 /* create a new bios memory map, removing overlaps */ 536 /* create a new bios memory map, removing overlaps */
504 overlap_entries=0; /* number of entries in the overlap table */ 537 overlap_entries = 0; /* number of entries in the overlap table */
505 new_bios_entry=0; /* index for creating new bios map entries */ 538 new_bios_entry = 0; /* index for creating new bios map entries */
506 last_type = 0; /* start with undefined memory type */ 539 last_type = 0; /* start with undefined memory type */
507 last_addr = 0; /* start with 0 as last starting address */ 540 last_addr = 0; /* start with 0 as last starting address */
541
508 /* loop through change-points, determining affect on the new bios map */ 542 /* loop through change-points, determining affect on the new bios map */
509 for (chgidx=0; chgidx < chg_nr; chgidx++) 543 for (chgidx = 0; chgidx < chg_nr; chgidx++) {
510 {
511 /* keep track of all overlapping bios entries */ 544 /* keep track of all overlapping bios entries */
512 if (change_point[chgidx]->addr == change_point[chgidx]->pbios->addr) 545 if (change_point[chgidx]->addr ==
513 { 546 change_point[chgidx]->pbios->addr) {
514 /* add map entry to overlap list (> 1 entry implies an overlap) */ 547 /*
515 overlap_list[overlap_entries++]=change_point[chgidx]->pbios; 548 * add map entry to overlap list (> 1 entry
516 } 549 * implies an overlap)
517 else 550 */
518 { 551 overlap_list[overlap_entries++] =
519 /* remove entry from list (order independent, so swap with last) */ 552 change_point[chgidx]->pbios;
520 for (i=0; i<overlap_entries; i++) 553 } else {
521 { 554 /*
522 if (overlap_list[i] == change_point[chgidx]->pbios) 555 * remove entry from list (order independent,
523 overlap_list[i] = overlap_list[overlap_entries-1]; 556 * so swap with last)
557 */
558 for (i = 0; i < overlap_entries; i++) {
559 if (overlap_list[i] ==
560 change_point[chgidx]->pbios)
561 overlap_list[i] =
562 overlap_list[overlap_entries-1];
524 } 563 }
525 overlap_entries--; 564 overlap_entries--;
526 } 565 }
527 /* if there are overlapping entries, decide which "type" to use */ 566 /*
528 /* (larger value takes precedence -- 1=usable, 2,3,4,4+=unusable) */ 567 * if there are overlapping entries, decide which
568 * "type" to use (larger value takes precedence --
569 * 1=usable, 2,3,4,4+=unusable)
570 */
529 current_type = 0; 571 current_type = 0;
530 for (i=0; i<overlap_entries; i++) 572 for (i = 0; i < overlap_entries; i++)
531 if (overlap_list[i]->type > current_type) 573 if (overlap_list[i]->type > current_type)
532 current_type = overlap_list[i]->type; 574 current_type = overlap_list[i]->type;
533 /* continue building up new bios map based on this information */ 575 /*
576 * continue building up new bios map based on this
577 * information
578 */
534 if (current_type != last_type) { 579 if (current_type != last_type) {
535 if (last_type != 0) { 580 if (last_type != 0) {
536 new_bios[new_bios_entry].size = 581 new_bios[new_bios_entry].size =
537 change_point[chgidx]->addr - last_addr; 582 change_point[chgidx]->addr - last_addr;
538 /* move forward only if the new size was non-zero */ 583 /*
584 * move forward only if the new size
585 * was non-zero
586 */
539 if (new_bios[new_bios_entry].size != 0) 587 if (new_bios[new_bios_entry].size != 0)
588 /*
589 * no more space left for new
590 * bios entries ?
591 */
540 if (++new_bios_entry >= E820MAX) 592 if (++new_bios_entry >= E820MAX)
541 break; /* no more space left for new bios entries */ 593 break;
542 } 594 }
543 if (current_type != 0) { 595 if (current_type != 0) {
544 new_bios[new_bios_entry].addr = change_point[chgidx]->addr; 596 new_bios[new_bios_entry].addr =
597 change_point[chgidx]->addr;
545 new_bios[new_bios_entry].type = current_type; 598 new_bios[new_bios_entry].type = current_type;
546 last_addr=change_point[chgidx]->addr; 599 last_addr = change_point[chgidx]->addr;
547 } 600 }
548 last_type = current_type; 601 last_type = current_type;
549 } 602 }
550 } 603 }
551 new_nr = new_bios_entry; /* retain count for new bios entries */ 604 /* retain count for new bios entries */
605 new_nr = new_bios_entry;
552 606
553 /* copy new bios mapping into original location */ 607 /* copy new bios mapping into original location */
554 memcpy(biosmap, new_bios, new_nr*sizeof(struct e820entry)); 608 memcpy(biosmap, new_bios, new_nr * sizeof(struct e820entry));
555 *pnr_map = new_nr; 609 *pnr_map = new_nr;
556 610
557 return 0; 611 return 0;
@@ -566,7 +620,7 @@ static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map)
566 * will have given us a memory map that we can use to properly 620 * will have given us a memory map that we can use to properly
567 * set up memory. If we aren't, we'll fake a memory map. 621 * set up memory. If we aren't, we'll fake a memory map.
568 */ 622 */
569static int __init copy_e820_map(struct e820entry * biosmap, int nr_map) 623static int __init copy_e820_map(struct e820entry *biosmap, int nr_map)
570{ 624{
571 /* Only one memory region (or negative)? Ignore it */ 625 /* Only one memory region (or negative)? Ignore it */
572 if (nr_map < 2) 626 if (nr_map < 2)
@@ -583,18 +637,20 @@ static int __init copy_e820_map(struct e820entry * biosmap, int nr_map)
583 return -1; 637 return -1;
584 638
585 add_memory_region(start, size, type); 639 add_memory_region(start, size, type);
586 } while (biosmap++,--nr_map); 640 } while (biosmap++, --nr_map);
587 return 0; 641 return 0;
588} 642}
589 643
590void early_panic(char *msg) 644static void early_panic(char *msg)
591{ 645{
592 early_printk(msg); 646 early_printk(msg);
593 panic(msg); 647 panic(msg);
594} 648}
595 649
596void __init setup_memory_region(void) 650/* We're not void only for x86 32-bit compat */
651char * __init machine_specific_memory_setup(void)
597{ 652{
653 char *who = "BIOS-e820";
598 /* 654 /*
599 * Try to copy the BIOS-supplied E820-map. 655 * Try to copy the BIOS-supplied E820-map.
600 * 656 *
@@ -605,7 +661,10 @@ void __init setup_memory_region(void)
605 if (copy_e820_map(boot_params.e820_map, boot_params.e820_entries) < 0) 661 if (copy_e820_map(boot_params.e820_map, boot_params.e820_entries) < 0)
606 early_panic("Cannot find a valid memory map"); 662 early_panic("Cannot find a valid memory map");
607 printk(KERN_INFO "BIOS-provided physical RAM map:\n"); 663 printk(KERN_INFO "BIOS-provided physical RAM map:\n");
608 e820_print_map("BIOS-e820"); 664 e820_print_map(who);
665
666 /* In case someone cares... */
667 return who;
609} 668}
610 669
611static int __init parse_memopt(char *p) 670static int __init parse_memopt(char *p)
@@ -613,9 +672,9 @@ static int __init parse_memopt(char *p)
613 if (!p) 672 if (!p)
614 return -EINVAL; 673 return -EINVAL;
615 end_user_pfn = memparse(p, &p); 674 end_user_pfn = memparse(p, &p);
616 end_user_pfn >>= PAGE_SHIFT; 675 end_user_pfn >>= PAGE_SHIFT;
617 return 0; 676 return 0;
618} 677}
619early_param("mem", parse_memopt); 678early_param("mem", parse_memopt);
620 679
621static int userdef __initdata; 680static int userdef __initdata;
@@ -627,9 +686,9 @@ static int __init parse_memmap_opt(char *p)
627 686
628 if (!strcmp(p, "exactmap")) { 687 if (!strcmp(p, "exactmap")) {
629#ifdef CONFIG_CRASH_DUMP 688#ifdef CONFIG_CRASH_DUMP
630 /* If we are doing a crash dump, we 689 /*
631 * still need to know the real mem 690 * If we are doing a crash dump, we still need to know
632 * size before original memory map is 691 * the real mem size before original memory map is
633 * reset. 692 * reset.
634 */ 693 */
635 e820_register_active_regions(0, 0, -1UL); 694 e820_register_active_regions(0, 0, -1UL);
@@ -646,6 +705,8 @@ static int __init parse_memmap_opt(char *p)
646 mem_size = memparse(p, &p); 705 mem_size = memparse(p, &p);
647 if (p == oldp) 706 if (p == oldp)
648 return -EINVAL; 707 return -EINVAL;
708
709 userdef = 1;
649 if (*p == '@') { 710 if (*p == '@') {
650 start_at = memparse(p+1, &p); 711 start_at = memparse(p+1, &p);
651 add_memory_region(start_at, mem_size, E820_RAM); 712 add_memory_region(start_at, mem_size, E820_RAM);
@@ -665,11 +726,29 @@ early_param("memmap", parse_memmap_opt);
665void __init finish_e820_parsing(void) 726void __init finish_e820_parsing(void)
666{ 727{
667 if (userdef) { 728 if (userdef) {
729 char nr = e820.nr_map;
730
731 if (sanitize_e820_map(e820.map, &nr) < 0)
732 early_panic("Invalid user supplied memory map");
733 e820.nr_map = nr;
734
668 printk(KERN_INFO "user-defined physical RAM map:\n"); 735 printk(KERN_INFO "user-defined physical RAM map:\n");
669 e820_print_map("user"); 736 e820_print_map("user");
670 } 737 }
671} 738}
672 739
740void __init update_e820(void)
741{
742 u8 nr_map;
743
744 nr_map = e820.nr_map;
745 if (sanitize_e820_map(e820.map, &nr_map))
746 return;
747 e820.nr_map = nr_map;
748 printk(KERN_INFO "modified physical RAM map:\n");
749 e820_print_map("modified");
750}
751
673unsigned long pci_mem_start = 0xaeedbabe; 752unsigned long pci_mem_start = 0xaeedbabe;
674EXPORT_SYMBOL(pci_mem_start); 753EXPORT_SYMBOL(pci_mem_start);
675 754
@@ -713,8 +792,10 @@ __init void e820_setup_gap(void)
713 792
714 if (!found) { 793 if (!found) {
715 gapstart = (end_pfn << PAGE_SHIFT) + 1024*1024; 794 gapstart = (end_pfn << PAGE_SHIFT) + 1024*1024;
716 printk(KERN_ERR "PCI: Warning: Cannot find a gap in the 32bit address range\n" 795 printk(KERN_ERR "PCI: Warning: Cannot find a gap in the 32bit "
717 KERN_ERR "PCI: Unassigned devices with 32bit resource registers may break!\n"); 796 "address range\n"
797 KERN_ERR "PCI: Unassigned devices with 32bit resource "
798 "registers may break!\n");
718 } 799 }
719 800
720 /* 801 /*
@@ -727,8 +808,9 @@ __init void e820_setup_gap(void)
727 /* Fun with two's complement */ 808 /* Fun with two's complement */
728 pci_mem_start = (gapstart + round) & -round; 809 pci_mem_start = (gapstart + round) & -round;
729 810
730 printk(KERN_INFO "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n", 811 printk(KERN_INFO
731 pci_mem_start, gapstart, gapsize); 812 "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n",
813 pci_mem_start, gapstart, gapsize);
732} 814}
733 815
734int __init arch_get_ram_range(int slot, u64 *addr, u64 *size) 816int __init arch_get_ram_range(int slot, u64 *addr, u64 *size)
diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c
index 88bb83ec895f..9f51e1ea9e82 100644
--- a/arch/x86/kernel/early-quirks.c
+++ b/arch/x86/kernel/early-quirks.c
@@ -21,7 +21,33 @@
21#include <asm/gart.h> 21#include <asm/gart.h>
22#endif 22#endif
23 23
24static void __init via_bugs(void) 24static void __init fix_hypertransport_config(int num, int slot, int func)
25{
26 u32 htcfg;
27 /*
28 * we found a hypertransport bus
29 * make sure that we are broadcasting
30 * interrupts to all cpus on the ht bus
31 * if we're using extended apic ids
32 */
33 htcfg = read_pci_config(num, slot, func, 0x68);
34 if (htcfg & (1 << 18)) {
35 printk(KERN_INFO "Detected use of extended apic ids "
36 "on hypertransport bus\n");
37 if ((htcfg & (1 << 17)) == 0) {
38 printk(KERN_INFO "Enabling hypertransport extended "
39 "apic interrupt broadcast\n");
40 printk(KERN_INFO "Note this is a bios bug, "
41 "please contact your hw vendor\n");
42 htcfg |= (1 << 17);
43 write_pci_config(num, slot, func, 0x68, htcfg);
44 }
45 }
46
47
48}
49
50static void __init via_bugs(int num, int slot, int func)
25{ 51{
26#ifdef CONFIG_GART_IOMMU 52#ifdef CONFIG_GART_IOMMU
27 if ((end_pfn > MAX_DMA32_PFN || force_iommu) && 53 if ((end_pfn > MAX_DMA32_PFN || force_iommu) &&
@@ -44,7 +70,7 @@ static int __init nvidia_hpet_check(struct acpi_table_header *header)
44#endif /* CONFIG_X86_IO_APIC */ 70#endif /* CONFIG_X86_IO_APIC */
45#endif /* CONFIG_ACPI */ 71#endif /* CONFIG_ACPI */
46 72
47static void __init nvidia_bugs(void) 73static void __init nvidia_bugs(int num, int slot, int func)
48{ 74{
49#ifdef CONFIG_ACPI 75#ifdef CONFIG_ACPI
50#ifdef CONFIG_X86_IO_APIC 76#ifdef CONFIG_X86_IO_APIC
@@ -72,7 +98,7 @@ static void __init nvidia_bugs(void)
72 98
73} 99}
74 100
75static void __init ati_bugs(void) 101static void __init ati_bugs(int num, int slot, int func)
76{ 102{
77#ifdef CONFIG_X86_IO_APIC 103#ifdef CONFIG_X86_IO_APIC
78 if (timer_over_8254 == 1) { 104 if (timer_over_8254 == 1) {
@@ -83,18 +109,67 @@ static void __init ati_bugs(void)
83#endif 109#endif
84} 110}
85 111
112#define QFLAG_APPLY_ONCE 0x1
113#define QFLAG_APPLIED 0x2
114#define QFLAG_DONE (QFLAG_APPLY_ONCE|QFLAG_APPLIED)
86struct chipset { 115struct chipset {
87 u16 vendor; 116 u32 vendor;
88 void (*f)(void); 117 u32 device;
118 u32 class;
119 u32 class_mask;
120 u32 flags;
121 void (*f)(int num, int slot, int func);
89}; 122};
90 123
91static struct chipset early_qrk[] __initdata = { 124static struct chipset early_qrk[] __initdata = {
92 { PCI_VENDOR_ID_NVIDIA, nvidia_bugs }, 125 { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
93 { PCI_VENDOR_ID_VIA, via_bugs }, 126 PCI_CLASS_BRIDGE_PCI, PCI_ANY_ID, QFLAG_APPLY_ONCE, nvidia_bugs },
94 { PCI_VENDOR_ID_ATI, ati_bugs }, 127 { PCI_VENDOR_ID_VIA, PCI_ANY_ID,
128 PCI_CLASS_BRIDGE_PCI, PCI_ANY_ID, QFLAG_APPLY_ONCE, via_bugs },
129 { PCI_VENDOR_ID_ATI, PCI_ANY_ID,
130 PCI_CLASS_BRIDGE_PCI, PCI_ANY_ID, QFLAG_APPLY_ONCE, ati_bugs },
131 { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB,
132 PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, fix_hypertransport_config },
95 {} 133 {}
96}; 134};
97 135
136static void __init check_dev_quirk(int num, int slot, int func)
137{
138 u16 class;
139 u16 vendor;
140 u16 device;
141 u8 type;
142 int i;
143
144 class = read_pci_config_16(num, slot, func, PCI_CLASS_DEVICE);
145
146 if (class == 0xffff)
147 return;
148
149 vendor = read_pci_config_16(num, slot, func, PCI_VENDOR_ID);
150
151 device = read_pci_config_16(num, slot, func, PCI_DEVICE_ID);
152
153 for (i = 0; early_qrk[i].f != NULL; i++) {
154 if (((early_qrk[i].vendor == PCI_ANY_ID) ||
155 (early_qrk[i].vendor == vendor)) &&
156 ((early_qrk[i].device == PCI_ANY_ID) ||
157 (early_qrk[i].device == device)) &&
158 (!((early_qrk[i].class ^ class) &
159 early_qrk[i].class_mask))) {
160 if ((early_qrk[i].flags &
161 QFLAG_DONE) != QFLAG_DONE)
162 early_qrk[i].f(num, slot, func);
163 early_qrk[i].flags |= QFLAG_APPLIED;
164 }
165 }
166
167 type = read_pci_config_byte(num, slot, func,
168 PCI_HEADER_TYPE);
169 if (!(type & 0x80))
170 return;
171}
172
98void __init early_quirks(void) 173void __init early_quirks(void)
99{ 174{
100 int num, slot, func; 175 int num, slot, func;
@@ -103,36 +178,8 @@ void __init early_quirks(void)
103 return; 178 return;
104 179
105 /* Poor man's PCI discovery */ 180 /* Poor man's PCI discovery */
106 for (num = 0; num < 32; num++) { 181 for (num = 0; num < 32; num++)
107 for (slot = 0; slot < 32; slot++) { 182 for (slot = 0; slot < 32; slot++)
108 for (func = 0; func < 8; func++) { 183 for (func = 0; func < 8; func++)
109 u32 class; 184 check_dev_quirk(num, slot, func);
110 u32 vendor;
111 u8 type;
112 int i;
113 class = read_pci_config(num,slot,func,
114 PCI_CLASS_REVISION);
115 if (class == 0xffffffff)
116 break;
117
118 if ((class >> 16) != PCI_CLASS_BRIDGE_PCI)
119 continue;
120
121 vendor = read_pci_config(num, slot, func,
122 PCI_VENDOR_ID);
123 vendor &= 0xffff;
124
125 for (i = 0; early_qrk[i].f; i++)
126 if (early_qrk[i].vendor == vendor) {
127 early_qrk[i].f();
128 return;
129 }
130
131 type = read_pci_config_byte(num, slot, func,
132 PCI_HEADER_TYPE);
133 if (!(type & 0x80))
134 break;
135 }
136 }
137 }
138} 185}
diff --git a/arch/x86/kernel/efi.c b/arch/x86/kernel/efi.c
new file mode 100644
index 000000000000..1411324a625c
--- /dev/null
+++ b/arch/x86/kernel/efi.c
@@ -0,0 +1,512 @@
1/*
2 * Common EFI (Extensible Firmware Interface) support functions
3 * Based on Extensible Firmware Interface Specification version 1.0
4 *
5 * Copyright (C) 1999 VA Linux Systems
6 * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
7 * Copyright (C) 1999-2002 Hewlett-Packard Co.
8 * David Mosberger-Tang <davidm@hpl.hp.com>
9 * Stephane Eranian <eranian@hpl.hp.com>
10 * Copyright (C) 2005-2008 Intel Co.
11 * Fenghua Yu <fenghua.yu@intel.com>
12 * Bibo Mao <bibo.mao@intel.com>
13 * Chandramouli Narayanan <mouli@linux.intel.com>
14 * Huang Ying <ying.huang@intel.com>
15 *
16 * Copied from efi_32.c to eliminate the duplicated code between EFI
17 * 32/64 support code. --ying 2007-10-26
18 *
19 * All EFI Runtime Services are not implemented yet as EFI only
20 * supports physical mode addressing on SoftSDV. This is to be fixed
21 * in a future version. --drummond 1999-07-20
22 *
23 * Implemented EFI runtime services and virtual mode calls. --davidm
24 *
25 * Goutham Rao: <goutham.rao@intel.com>
26 * Skip non-WB memory and ignore empty memory ranges.
27 */
28
29#include <linux/kernel.h>
30#include <linux/init.h>
31#include <linux/efi.h>
32#include <linux/bootmem.h>
33#include <linux/spinlock.h>
34#include <linux/uaccess.h>
35#include <linux/time.h>
36#include <linux/io.h>
37#include <linux/reboot.h>
38#include <linux/bcd.h>
39
40#include <asm/setup.h>
41#include <asm/efi.h>
42#include <asm/time.h>
43#include <asm/cacheflush.h>
44#include <asm/tlbflush.h>
45
46#define EFI_DEBUG 1
47#define PFX "EFI: "
48
49int efi_enabled;
50EXPORT_SYMBOL(efi_enabled);
51
52struct efi efi;
53EXPORT_SYMBOL(efi);
54
55struct efi_memory_map memmap;
56
57struct efi efi_phys __initdata;
58static efi_system_table_t efi_systab __initdata;
59
60static int __init setup_noefi(char *arg)
61{
62 efi_enabled = 0;
63 return 0;
64}
65early_param("noefi", setup_noefi);
66
67static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
68{
69 return efi_call_virt2(get_time, tm, tc);
70}
71
72static efi_status_t virt_efi_set_time(efi_time_t *tm)
73{
74 return efi_call_virt1(set_time, tm);
75}
76
77static efi_status_t virt_efi_get_wakeup_time(efi_bool_t *enabled,
78 efi_bool_t *pending,
79 efi_time_t *tm)
80{
81 return efi_call_virt3(get_wakeup_time,
82 enabled, pending, tm);
83}
84
85static efi_status_t virt_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
86{
87 return efi_call_virt2(set_wakeup_time,
88 enabled, tm);
89}
90
91static efi_status_t virt_efi_get_variable(efi_char16_t *name,
92 efi_guid_t *vendor,
93 u32 *attr,
94 unsigned long *data_size,
95 void *data)
96{
97 return efi_call_virt5(get_variable,
98 name, vendor, attr,
99 data_size, data);
100}
101
102static efi_status_t virt_efi_get_next_variable(unsigned long *name_size,
103 efi_char16_t *name,
104 efi_guid_t *vendor)
105{
106 return efi_call_virt3(get_next_variable,
107 name_size, name, vendor);
108}
109
110static efi_status_t virt_efi_set_variable(efi_char16_t *name,
111 efi_guid_t *vendor,
112 unsigned long attr,
113 unsigned long data_size,
114 void *data)
115{
116 return efi_call_virt5(set_variable,
117 name, vendor, attr,
118 data_size, data);
119}
120
121static efi_status_t virt_efi_get_next_high_mono_count(u32 *count)
122{
123 return efi_call_virt1(get_next_high_mono_count, count);
124}
125
126static void virt_efi_reset_system(int reset_type,
127 efi_status_t status,
128 unsigned long data_size,
129 efi_char16_t *data)
130{
131 efi_call_virt4(reset_system, reset_type, status,
132 data_size, data);
133}
134
135static efi_status_t virt_efi_set_virtual_address_map(
136 unsigned long memory_map_size,
137 unsigned long descriptor_size,
138 u32 descriptor_version,
139 efi_memory_desc_t *virtual_map)
140{
141 return efi_call_virt4(set_virtual_address_map,
142 memory_map_size, descriptor_size,
143 descriptor_version, virtual_map);
144}
145
146static efi_status_t __init phys_efi_set_virtual_address_map(
147 unsigned long memory_map_size,
148 unsigned long descriptor_size,
149 u32 descriptor_version,
150 efi_memory_desc_t *virtual_map)
151{
152 efi_status_t status;
153
154 efi_call_phys_prelog();
155 status = efi_call_phys4(efi_phys.set_virtual_address_map,
156 memory_map_size, descriptor_size,
157 descriptor_version, virtual_map);
158 efi_call_phys_epilog();
159 return status;
160}
161
162static efi_status_t __init phys_efi_get_time(efi_time_t *tm,
163 efi_time_cap_t *tc)
164{
165 efi_status_t status;
166
167 efi_call_phys_prelog();
168 status = efi_call_phys2(efi_phys.get_time, tm, tc);
169 efi_call_phys_epilog();
170 return status;
171}
172
173int efi_set_rtc_mmss(unsigned long nowtime)
174{
175 int real_seconds, real_minutes;
176 efi_status_t status;
177 efi_time_t eft;
178 efi_time_cap_t cap;
179
180 status = efi.get_time(&eft, &cap);
181 if (status != EFI_SUCCESS) {
182 printk(KERN_ERR "Oops: efitime: can't read time!\n");
183 return -1;
184 }
185
186 real_seconds = nowtime % 60;
187 real_minutes = nowtime / 60;
188 if (((abs(real_minutes - eft.minute) + 15)/30) & 1)
189 real_minutes += 30;
190 real_minutes %= 60;
191 eft.minute = real_minutes;
192 eft.second = real_seconds;
193
194 status = efi.set_time(&eft);
195 if (status != EFI_SUCCESS) {
196 printk(KERN_ERR "Oops: efitime: can't write time!\n");
197 return -1;
198 }
199 return 0;
200}
201
202unsigned long efi_get_time(void)
203{
204 efi_status_t status;
205 efi_time_t eft;
206 efi_time_cap_t cap;
207
208 status = efi.get_time(&eft, &cap);
209 if (status != EFI_SUCCESS)
210 printk(KERN_ERR "Oops: efitime: can't read time!\n");
211
212 return mktime(eft.year, eft.month, eft.day, eft.hour,
213 eft.minute, eft.second);
214}
215
216#if EFI_DEBUG
217static void __init print_efi_memmap(void)
218{
219 efi_memory_desc_t *md;
220 void *p;
221 int i;
222
223 for (p = memmap.map, i = 0;
224 p < memmap.map_end;
225 p += memmap.desc_size, i++) {
226 md = p;
227 printk(KERN_INFO PFX "mem%02u: type=%u, attr=0x%llx, "
228 "range=[0x%016llx-0x%016llx) (%lluMB)\n",
229 i, md->type, md->attribute, md->phys_addr,
230 md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
231 (md->num_pages >> (20 - EFI_PAGE_SHIFT)));
232 }
233}
234#endif /* EFI_DEBUG */
235
236void __init efi_init(void)
237{
238 efi_config_table_t *config_tables;
239 efi_runtime_services_t *runtime;
240 efi_char16_t *c16;
241 char vendor[100] = "unknown";
242 int i = 0;
243 void *tmp;
244
245#ifdef CONFIG_X86_32
246 efi_phys.systab = (efi_system_table_t *)boot_params.efi_info.efi_systab;
247 memmap.phys_map = (void *)boot_params.efi_info.efi_memmap;
248#else
249 efi_phys.systab = (efi_system_table_t *)
250 (boot_params.efi_info.efi_systab |
251 ((__u64)boot_params.efi_info.efi_systab_hi<<32));
252 memmap.phys_map = (void *)
253 (boot_params.efi_info.efi_memmap |
254 ((__u64)boot_params.efi_info.efi_memmap_hi<<32));
255#endif
256 memmap.nr_map = boot_params.efi_info.efi_memmap_size /
257 boot_params.efi_info.efi_memdesc_size;
258 memmap.desc_version = boot_params.efi_info.efi_memdesc_version;
259 memmap.desc_size = boot_params.efi_info.efi_memdesc_size;
260
261 efi.systab = early_ioremap((unsigned long)efi_phys.systab,
262 sizeof(efi_system_table_t));
263 if (efi.systab == NULL)
264 printk(KERN_ERR "Couldn't map the EFI system table!\n");
265 memcpy(&efi_systab, efi.systab, sizeof(efi_system_table_t));
266 early_iounmap(efi.systab, sizeof(efi_system_table_t));
267 efi.systab = &efi_systab;
268
269 /*
270 * Verify the EFI Table
271 */
272 if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
273 printk(KERN_ERR "EFI system table signature incorrect!\n");
274 if ((efi.systab->hdr.revision >> 16) == 0)
275 printk(KERN_ERR "Warning: EFI system table version "
276 "%d.%02d, expected 1.00 or greater!\n",
277 efi.systab->hdr.revision >> 16,
278 efi.systab->hdr.revision & 0xffff);
279
280 /*
281 * Show what we know for posterity
282 */
283 c16 = tmp = early_ioremap(efi.systab->fw_vendor, 2);
284 if (c16) {
285 for (i = 0; i < sizeof(vendor) && *c16; ++i)
286 vendor[i] = *c16++;
287 vendor[i] = '\0';
288 } else
289 printk(KERN_ERR PFX "Could not map the firmware vendor!\n");
290 early_iounmap(tmp, 2);
291
292 printk(KERN_INFO "EFI v%u.%.02u by %s \n",
293 efi.systab->hdr.revision >> 16,
294 efi.systab->hdr.revision & 0xffff, vendor);
295
296 /*
297 * Let's see what config tables the firmware passed to us.
298 */
299 config_tables = early_ioremap(
300 efi.systab->tables,
301 efi.systab->nr_tables * sizeof(efi_config_table_t));
302 if (config_tables == NULL)
303 printk(KERN_ERR "Could not map EFI Configuration Table!\n");
304
305 printk(KERN_INFO);
306 for (i = 0; i < efi.systab->nr_tables; i++) {
307 if (!efi_guidcmp(config_tables[i].guid, MPS_TABLE_GUID)) {
308 efi.mps = config_tables[i].table;
309 printk(" MPS=0x%lx ", config_tables[i].table);
310 } else if (!efi_guidcmp(config_tables[i].guid,
311 ACPI_20_TABLE_GUID)) {
312 efi.acpi20 = config_tables[i].table;
313 printk(" ACPI 2.0=0x%lx ", config_tables[i].table);
314 } else if (!efi_guidcmp(config_tables[i].guid,
315 ACPI_TABLE_GUID)) {
316 efi.acpi = config_tables[i].table;
317 printk(" ACPI=0x%lx ", config_tables[i].table);
318 } else if (!efi_guidcmp(config_tables[i].guid,
319 SMBIOS_TABLE_GUID)) {
320 efi.smbios = config_tables[i].table;
321 printk(" SMBIOS=0x%lx ", config_tables[i].table);
322 } else if (!efi_guidcmp(config_tables[i].guid,
323 HCDP_TABLE_GUID)) {
324 efi.hcdp = config_tables[i].table;
325 printk(" HCDP=0x%lx ", config_tables[i].table);
326 } else if (!efi_guidcmp(config_tables[i].guid,
327 UGA_IO_PROTOCOL_GUID)) {
328 efi.uga = config_tables[i].table;
329 printk(" UGA=0x%lx ", config_tables[i].table);
330 }
331 }
332 printk("\n");
333 early_iounmap(config_tables,
334 efi.systab->nr_tables * sizeof(efi_config_table_t));
335
336 /*
337 * Check out the runtime services table. We need to map
338 * the runtime services table so that we can grab the physical
339 * address of several of the EFI runtime functions, needed to
340 * set the firmware into virtual mode.
341 */
342 runtime = early_ioremap((unsigned long)efi.systab->runtime,
343 sizeof(efi_runtime_services_t));
344 if (runtime != NULL) {
345 /*
346 * We will only need *early* access to the following
347 * two EFI runtime services before set_virtual_address_map
348 * is invoked.
349 */
350 efi_phys.get_time = (efi_get_time_t *)runtime->get_time;
351 efi_phys.set_virtual_address_map =
352 (efi_set_virtual_address_map_t *)
353 runtime->set_virtual_address_map;
354 /*
355 * Make efi_get_time can be called before entering
356 * virtual mode.
357 */
358 efi.get_time = phys_efi_get_time;
359 } else
360 printk(KERN_ERR "Could not map the EFI runtime service "
361 "table!\n");
362 early_iounmap(runtime, sizeof(efi_runtime_services_t));
363
364 /* Map the EFI memory map */
365 memmap.map = early_ioremap((unsigned long)memmap.phys_map,
366 memmap.nr_map * memmap.desc_size);
367 if (memmap.map == NULL)
368 printk(KERN_ERR "Could not map the EFI memory map!\n");
369 memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size);
370 if (memmap.desc_size != sizeof(efi_memory_desc_t))
371 printk(KERN_WARNING "Kernel-defined memdesc"
372 "doesn't match the one from EFI!\n");
373
374 /* Setup for EFI runtime service */
375 reboot_type = BOOT_EFI;
376
377#if EFI_DEBUG
378 print_efi_memmap();
379#endif
380}
381
382#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
383static void __init runtime_code_page_mkexec(void)
384{
385 efi_memory_desc_t *md;
386 unsigned long end;
387 void *p;
388
389 if (!(__supported_pte_mask & _PAGE_NX))
390 return;
391
392 /* Make EFI runtime service code area executable */
393 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
394 md = p;
395 end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
396 if (md->type == EFI_RUNTIME_SERVICES_CODE &&
397 (end >> PAGE_SHIFT) <= max_pfn_mapped) {
398 set_memory_x(md->virt_addr, md->num_pages);
399 set_memory_uc(md->virt_addr, md->num_pages);
400 }
401 }
402 __flush_tlb_all();
403}
404#else
405static inline void __init runtime_code_page_mkexec(void) { }
406#endif
407
408/*
409 * This function will switch the EFI runtime services to virtual mode.
410 * Essentially, look through the EFI memmap and map every region that
411 * has the runtime attribute bit set in its memory descriptor and update
412 * that memory descriptor with the virtual address obtained from ioremap().
413 * This enables the runtime services to be called without having to
414 * thunk back into physical mode for every invocation.
415 */
416void __init efi_enter_virtual_mode(void)
417{
418 efi_memory_desc_t *md;
419 efi_status_t status;
420 unsigned long end;
421 void *p;
422
423 efi.systab = NULL;
424 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
425 md = p;
426 if (!(md->attribute & EFI_MEMORY_RUNTIME))
427 continue;
428 end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
429 if ((md->attribute & EFI_MEMORY_WB) &&
430 ((end >> PAGE_SHIFT) <= max_pfn_mapped))
431 md->virt_addr = (unsigned long)__va(md->phys_addr);
432 else
433 md->virt_addr = (unsigned long)
434 efi_ioremap(md->phys_addr,
435 md->num_pages << EFI_PAGE_SHIFT);
436 if (!md->virt_addr)
437 printk(KERN_ERR PFX "ioremap of 0x%llX failed!\n",
438 (unsigned long long)md->phys_addr);
439 if ((md->phys_addr <= (unsigned long)efi_phys.systab) &&
440 ((unsigned long)efi_phys.systab < end))
441 efi.systab = (efi_system_table_t *)(unsigned long)
442 (md->virt_addr - md->phys_addr +
443 (unsigned long)efi_phys.systab);
444 }
445
446 BUG_ON(!efi.systab);
447
448 status = phys_efi_set_virtual_address_map(
449 memmap.desc_size * memmap.nr_map,
450 memmap.desc_size,
451 memmap.desc_version,
452 memmap.phys_map);
453
454 if (status != EFI_SUCCESS) {
455 printk(KERN_ALERT "Unable to switch EFI into virtual mode "
456 "(status=%lx)!\n", status);
457 panic("EFI call to SetVirtualAddressMap() failed!");
458 }
459
460 /*
461 * Now that EFI is in virtual mode, update the function
462 * pointers in the runtime service table to the new virtual addresses.
463 *
464 * Call EFI services through wrapper functions.
465 */
466 efi.get_time = virt_efi_get_time;
467 efi.set_time = virt_efi_set_time;
468 efi.get_wakeup_time = virt_efi_get_wakeup_time;
469 efi.set_wakeup_time = virt_efi_set_wakeup_time;
470 efi.get_variable = virt_efi_get_variable;
471 efi.get_next_variable = virt_efi_get_next_variable;
472 efi.set_variable = virt_efi_set_variable;
473 efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count;
474 efi.reset_system = virt_efi_reset_system;
475 efi.set_virtual_address_map = virt_efi_set_virtual_address_map;
476 runtime_code_page_mkexec();
477 early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size);
478 memmap.map = NULL;
479}
480
481/*
482 * Convenience functions to obtain memory types and attributes
483 */
484u32 efi_mem_type(unsigned long phys_addr)
485{
486 efi_memory_desc_t *md;
487 void *p;
488
489 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
490 md = p;
491 if ((md->phys_addr <= phys_addr) &&
492 (phys_addr < (md->phys_addr +
493 (md->num_pages << EFI_PAGE_SHIFT))))
494 return md->type;
495 }
496 return 0;
497}
498
499u64 efi_mem_attributes(unsigned long phys_addr)
500{
501 efi_memory_desc_t *md;
502 void *p;
503
504 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
505 md = p;
506 if ((md->phys_addr <= phys_addr) &&
507 (phys_addr < (md->phys_addr +
508 (md->num_pages << EFI_PAGE_SHIFT))))
509 return md->attribute;
510 }
511 return 0;
512}
diff --git a/arch/x86/kernel/efi_32.c b/arch/x86/kernel/efi_32.c
index e2be78f49399..cb91f985b4a1 100644
--- a/arch/x86/kernel/efi_32.c
+++ b/arch/x86/kernel/efi_32.c
@@ -20,40 +20,15 @@
20 */ 20 */
21 21
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/init.h>
24#include <linux/mm.h>
25#include <linux/types.h> 23#include <linux/types.h>
26#include <linux/time.h>
27#include <linux/spinlock.h>
28#include <linux/bootmem.h>
29#include <linux/ioport.h> 24#include <linux/ioport.h>
30#include <linux/module.h>
31#include <linux/efi.h> 25#include <linux/efi.h>
32#include <linux/kexec.h>
33 26
34#include <asm/setup.h>
35#include <asm/io.h> 27#include <asm/io.h>
36#include <asm/page.h> 28#include <asm/page.h>
37#include <asm/pgtable.h> 29#include <asm/pgtable.h>
38#include <asm/processor.h>
39#include <asm/desc.h>
40#include <asm/tlbflush.h> 30#include <asm/tlbflush.h>
41 31
42#define EFI_DEBUG 0
43#define PFX "EFI: "
44
45extern efi_status_t asmlinkage efi_call_phys(void *, ...);
46
47struct efi efi;
48EXPORT_SYMBOL(efi);
49static struct efi efi_phys;
50struct efi_memory_map memmap;
51
52/*
53 * We require an early boot_ioremap mapping mechanism initially
54 */
55extern void * boot_ioremap(unsigned long, unsigned long);
56
57/* 32/*
58 * To make EFI call EFI runtime service in physical addressing mode we need 33 * To make EFI call EFI runtime service in physical addressing mode we need
59 * prelog/epilog before/after the invocation to disable interrupt, to 34 * prelog/epilog before/after the invocation to disable interrupt, to
@@ -62,16 +37,14 @@ extern void * boot_ioremap(unsigned long, unsigned long);
62 */ 37 */
63 38
64static unsigned long efi_rt_eflags; 39static unsigned long efi_rt_eflags;
65static DEFINE_SPINLOCK(efi_rt_lock);
66static pgd_t efi_bak_pg_dir_pointer[2]; 40static pgd_t efi_bak_pg_dir_pointer[2];
67 41
68static void efi_call_phys_prelog(void) __acquires(efi_rt_lock) 42void efi_call_phys_prelog(void)
69{ 43{
70 unsigned long cr4; 44 unsigned long cr4;
71 unsigned long temp; 45 unsigned long temp;
72 struct Xgt_desc_struct gdt_descr; 46 struct desc_ptr gdt_descr;
73 47
74 spin_lock(&efi_rt_lock);
75 local_irq_save(efi_rt_eflags); 48 local_irq_save(efi_rt_eflags);
76 49
77 /* 50 /*
@@ -101,17 +74,17 @@ static void efi_call_phys_prelog(void) __acquires(efi_rt_lock)
101 /* 74 /*
102 * After the lock is released, the original page table is restored. 75 * After the lock is released, the original page table is restored.
103 */ 76 */
104 local_flush_tlb(); 77 __flush_tlb_all();
105 78
106 gdt_descr.address = __pa(get_cpu_gdt_table(0)); 79 gdt_descr.address = __pa(get_cpu_gdt_table(0));
107 gdt_descr.size = GDT_SIZE - 1; 80 gdt_descr.size = GDT_SIZE - 1;
108 load_gdt(&gdt_descr); 81 load_gdt(&gdt_descr);
109} 82}
110 83
111static void efi_call_phys_epilog(void) __releases(efi_rt_lock) 84void efi_call_phys_epilog(void)
112{ 85{
113 unsigned long cr4; 86 unsigned long cr4;
114 struct Xgt_desc_struct gdt_descr; 87 struct desc_ptr gdt_descr;
115 88
116 gdt_descr.address = (unsigned long)get_cpu_gdt_table(0); 89 gdt_descr.address = (unsigned long)get_cpu_gdt_table(0);
117 gdt_descr.size = GDT_SIZE - 1; 90 gdt_descr.size = GDT_SIZE - 1;
@@ -132,586 +105,7 @@ static void efi_call_phys_epilog(void) __releases(efi_rt_lock)
132 /* 105 /*
133 * After the lock is released, the original page table is restored. 106 * After the lock is released, the original page table is restored.
134 */ 107 */
135 local_flush_tlb(); 108 __flush_tlb_all();
136 109
137 local_irq_restore(efi_rt_eflags); 110 local_irq_restore(efi_rt_eflags);
138 spin_unlock(&efi_rt_lock);
139}
140
141static efi_status_t
142phys_efi_set_virtual_address_map(unsigned long memory_map_size,
143 unsigned long descriptor_size,
144 u32 descriptor_version,
145 efi_memory_desc_t *virtual_map)
146{
147 efi_status_t status;
148
149 efi_call_phys_prelog();
150 status = efi_call_phys(efi_phys.set_virtual_address_map,
151 memory_map_size, descriptor_size,
152 descriptor_version, virtual_map);
153 efi_call_phys_epilog();
154 return status;
155}
156
157static efi_status_t
158phys_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
159{
160 efi_status_t status;
161
162 efi_call_phys_prelog();
163 status = efi_call_phys(efi_phys.get_time, tm, tc);
164 efi_call_phys_epilog();
165 return status;
166}
167
168inline int efi_set_rtc_mmss(unsigned long nowtime)
169{
170 int real_seconds, real_minutes;
171 efi_status_t status;
172 efi_time_t eft;
173 efi_time_cap_t cap;
174
175 spin_lock(&efi_rt_lock);
176 status = efi.get_time(&eft, &cap);
177 spin_unlock(&efi_rt_lock);
178 if (status != EFI_SUCCESS)
179 panic("Ooops, efitime: can't read time!\n");
180 real_seconds = nowtime % 60;
181 real_minutes = nowtime / 60;
182
183 if (((abs(real_minutes - eft.minute) + 15)/30) & 1)
184 real_minutes += 30;
185 real_minutes %= 60;
186
187 eft.minute = real_minutes;
188 eft.second = real_seconds;
189
190 if (status != EFI_SUCCESS) {
191 printk("Ooops: efitime: can't read time!\n");
192 return -1;
193 }
194 return 0;
195}
196/*
197 * This is used during kernel init before runtime
198 * services have been remapped and also during suspend, therefore,
199 * we'll need to call both in physical and virtual modes.
200 */
201inline unsigned long efi_get_time(void)
202{
203 efi_status_t status;
204 efi_time_t eft;
205 efi_time_cap_t cap;
206
207 if (efi.get_time) {
208 /* if we are in virtual mode use remapped function */
209 status = efi.get_time(&eft, &cap);
210 } else {
211 /* we are in physical mode */
212 status = phys_efi_get_time(&eft, &cap);
213 }
214
215 if (status != EFI_SUCCESS)
216 printk("Oops: efitime: can't read time status: 0x%lx\n",status);
217
218 return mktime(eft.year, eft.month, eft.day, eft.hour,
219 eft.minute, eft.second);
220}
221
222int is_available_memory(efi_memory_desc_t * md)
223{
224 if (!(md->attribute & EFI_MEMORY_WB))
225 return 0;
226
227 switch (md->type) {
228 case EFI_LOADER_CODE:
229 case EFI_LOADER_DATA:
230 case EFI_BOOT_SERVICES_CODE:
231 case EFI_BOOT_SERVICES_DATA:
232 case EFI_CONVENTIONAL_MEMORY:
233 return 1;
234 }
235 return 0;
236}
237
238/*
239 * We need to map the EFI memory map again after paging_init().
240 */
241void __init efi_map_memmap(void)
242{
243 memmap.map = NULL;
244
245 memmap.map = bt_ioremap((unsigned long) memmap.phys_map,
246 (memmap.nr_map * memmap.desc_size));
247 if (memmap.map == NULL)
248 printk(KERN_ERR PFX "Could not remap the EFI memmap!\n");
249
250 memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size);
251}
252
253#if EFI_DEBUG
254static void __init print_efi_memmap(void)
255{
256 efi_memory_desc_t *md;
257 void *p;
258 int i;
259
260 for (p = memmap.map, i = 0; p < memmap.map_end; p += memmap.desc_size, i++) {
261 md = p;
262 printk(KERN_INFO "mem%02u: type=%u, attr=0x%llx, "
263 "range=[0x%016llx-0x%016llx) (%lluMB)\n",
264 i, md->type, md->attribute, md->phys_addr,
265 md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
266 (md->num_pages >> (20 - EFI_PAGE_SHIFT)));
267 }
268}
269#endif /* EFI_DEBUG */
270
271/*
272 * Walks the EFI memory map and calls CALLBACK once for each EFI
273 * memory descriptor that has memory that is available for kernel use.
274 */
275void efi_memmap_walk(efi_freemem_callback_t callback, void *arg)
276{
277 int prev_valid = 0;
278 struct range {
279 unsigned long start;
280 unsigned long end;
281 } uninitialized_var(prev), curr;
282 efi_memory_desc_t *md;
283 unsigned long start, end;
284 void *p;
285
286 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
287 md = p;
288
289 if ((md->num_pages == 0) || (!is_available_memory(md)))
290 continue;
291
292 curr.start = md->phys_addr;
293 curr.end = curr.start + (md->num_pages << EFI_PAGE_SHIFT);
294
295 if (!prev_valid) {
296 prev = curr;
297 prev_valid = 1;
298 } else {
299 if (curr.start < prev.start)
300 printk(KERN_INFO PFX "Unordered memory map\n");
301 if (prev.end == curr.start)
302 prev.end = curr.end;
303 else {
304 start =
305 (unsigned long) (PAGE_ALIGN(prev.start));
306 end = (unsigned long) (prev.end & PAGE_MASK);
307 if ((end > start)
308 && (*callback) (start, end, arg) < 0)
309 return;
310 prev = curr;
311 }
312 }
313 }
314 if (prev_valid) {
315 start = (unsigned long) PAGE_ALIGN(prev.start);
316 end = (unsigned long) (prev.end & PAGE_MASK);
317 if (end > start)
318 (*callback) (start, end, arg);
319 }
320}
321
322void __init efi_init(void)
323{
324 efi_config_table_t *config_tables;
325 efi_runtime_services_t *runtime;
326 efi_char16_t *c16;
327 char vendor[100] = "unknown";
328 unsigned long num_config_tables;
329 int i = 0;
330
331 memset(&efi, 0, sizeof(efi) );
332 memset(&efi_phys, 0, sizeof(efi_phys));
333
334 efi_phys.systab =
335 (efi_system_table_t *)boot_params.efi_info.efi_systab;
336 memmap.phys_map = (void *)boot_params.efi_info.efi_memmap;
337 memmap.nr_map = boot_params.efi_info.efi_memmap_size/
338 boot_params.efi_info.efi_memdesc_size;
339 memmap.desc_version = boot_params.efi_info.efi_memdesc_version;
340 memmap.desc_size = boot_params.efi_info.efi_memdesc_size;
341
342 efi.systab = (efi_system_table_t *)
343 boot_ioremap((unsigned long) efi_phys.systab,
344 sizeof(efi_system_table_t));
345 /*
346 * Verify the EFI Table
347 */
348 if (efi.systab == NULL)
349 printk(KERN_ERR PFX "Woah! Couldn't map the EFI system table.\n");
350 if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
351 printk(KERN_ERR PFX "Woah! EFI system table signature incorrect\n");
352 if ((efi.systab->hdr.revision >> 16) == 0)
353 printk(KERN_ERR PFX "Warning: EFI system table version "
354 "%d.%02d, expected 1.00 or greater\n",
355 efi.systab->hdr.revision >> 16,
356 efi.systab->hdr.revision & 0xffff);
357
358 /*
359 * Grab some details from the system table
360 */
361 num_config_tables = efi.systab->nr_tables;
362 config_tables = (efi_config_table_t *)efi.systab->tables;
363 runtime = efi.systab->runtime;
364
365 /*
366 * Show what we know for posterity
367 */
368 c16 = (efi_char16_t *) boot_ioremap(efi.systab->fw_vendor, 2);
369 if (c16) {
370 for (i = 0; i < (sizeof(vendor) - 1) && *c16; ++i)
371 vendor[i] = *c16++;
372 vendor[i] = '\0';
373 } else
374 printk(KERN_ERR PFX "Could not map the firmware vendor!\n");
375
376 printk(KERN_INFO PFX "EFI v%u.%.02u by %s \n",
377 efi.systab->hdr.revision >> 16,
378 efi.systab->hdr.revision & 0xffff, vendor);
379
380 /*
381 * Let's see what config tables the firmware passed to us.
382 */
383 config_tables = (efi_config_table_t *)
384 boot_ioremap((unsigned long) config_tables,
385 num_config_tables * sizeof(efi_config_table_t));
386
387 if (config_tables == NULL)
388 printk(KERN_ERR PFX "Could not map EFI Configuration Table!\n");
389
390 efi.mps = EFI_INVALID_TABLE_ADDR;
391 efi.acpi = EFI_INVALID_TABLE_ADDR;
392 efi.acpi20 = EFI_INVALID_TABLE_ADDR;
393 efi.smbios = EFI_INVALID_TABLE_ADDR;
394 efi.sal_systab = EFI_INVALID_TABLE_ADDR;
395 efi.boot_info = EFI_INVALID_TABLE_ADDR;
396 efi.hcdp = EFI_INVALID_TABLE_ADDR;
397 efi.uga = EFI_INVALID_TABLE_ADDR;
398
399 for (i = 0; i < num_config_tables; i++) {
400 if (efi_guidcmp(config_tables[i].guid, MPS_TABLE_GUID) == 0) {
401 efi.mps = config_tables[i].table;
402 printk(KERN_INFO " MPS=0x%lx ", config_tables[i].table);
403 } else
404 if (efi_guidcmp(config_tables[i].guid, ACPI_20_TABLE_GUID) == 0) {
405 efi.acpi20 = config_tables[i].table;
406 printk(KERN_INFO " ACPI 2.0=0x%lx ", config_tables[i].table);
407 } else
408 if (efi_guidcmp(config_tables[i].guid, ACPI_TABLE_GUID) == 0) {
409 efi.acpi = config_tables[i].table;
410 printk(KERN_INFO " ACPI=0x%lx ", config_tables[i].table);
411 } else
412 if (efi_guidcmp(config_tables[i].guid, SMBIOS_TABLE_GUID) == 0) {
413 efi.smbios = config_tables[i].table;
414 printk(KERN_INFO " SMBIOS=0x%lx ", config_tables[i].table);
415 } else
416 if (efi_guidcmp(config_tables[i].guid, HCDP_TABLE_GUID) == 0) {
417 efi.hcdp = config_tables[i].table;
418 printk(KERN_INFO " HCDP=0x%lx ", config_tables[i].table);
419 } else
420 if (efi_guidcmp(config_tables[i].guid, UGA_IO_PROTOCOL_GUID) == 0) {
421 efi.uga = config_tables[i].table;
422 printk(KERN_INFO " UGA=0x%lx ", config_tables[i].table);
423 }
424 }
425 printk("\n");
426
427 /*
428 * Check out the runtime services table. We need to map
429 * the runtime services table so that we can grab the physical
430 * address of several of the EFI runtime functions, needed to
431 * set the firmware into virtual mode.
432 */
433
434 runtime = (efi_runtime_services_t *) boot_ioremap((unsigned long)
435 runtime,
436 sizeof(efi_runtime_services_t));
437 if (runtime != NULL) {
438 /*
439 * We will only need *early* access to the following
440 * two EFI runtime services before set_virtual_address_map
441 * is invoked.
442 */
443 efi_phys.get_time = (efi_get_time_t *) runtime->get_time;
444 efi_phys.set_virtual_address_map =
445 (efi_set_virtual_address_map_t *)
446 runtime->set_virtual_address_map;
447 } else
448 printk(KERN_ERR PFX "Could not map the runtime service table!\n");
449
450 /* Map the EFI memory map for use until paging_init() */
451 memmap.map = boot_ioremap(boot_params.efi_info.efi_memmap,
452 boot_params.efi_info.efi_memmap_size);
453 if (memmap.map == NULL)
454 printk(KERN_ERR PFX "Could not map the EFI memory map!\n");
455
456 memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size);
457
458#if EFI_DEBUG
459 print_efi_memmap();
460#endif
461}
462
463static inline void __init check_range_for_systab(efi_memory_desc_t *md)
464{
465 if (((unsigned long)md->phys_addr <= (unsigned long)efi_phys.systab) &&
466 ((unsigned long)efi_phys.systab < md->phys_addr +
467 ((unsigned long)md->num_pages << EFI_PAGE_SHIFT))) {
468 unsigned long addr;
469
470 addr = md->virt_addr - md->phys_addr +
471 (unsigned long)efi_phys.systab;
472 efi.systab = (efi_system_table_t *)addr;
473 }
474}
475
476/*
477 * Wrap all the virtual calls in a way that forces the parameters on the stack.
478 */
479
480#define efi_call_virt(f, args...) \
481 ((efi_##f##_t __attribute__((regparm(0)))*)efi.systab->runtime->f)(args)
482
483static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
484{
485 return efi_call_virt(get_time, tm, tc);
486}
487
488static efi_status_t virt_efi_set_time (efi_time_t *tm)
489{
490 return efi_call_virt(set_time, tm);
491}
492
493static efi_status_t virt_efi_get_wakeup_time (efi_bool_t *enabled,
494 efi_bool_t *pending,
495 efi_time_t *tm)
496{
497 return efi_call_virt(get_wakeup_time, enabled, pending, tm);
498}
499
500static efi_status_t virt_efi_set_wakeup_time (efi_bool_t enabled,
501 efi_time_t *tm)
502{
503 return efi_call_virt(set_wakeup_time, enabled, tm);
504}
505
506static efi_status_t virt_efi_get_variable (efi_char16_t *name,
507 efi_guid_t *vendor, u32 *attr,
508 unsigned long *data_size, void *data)
509{
510 return efi_call_virt(get_variable, name, vendor, attr, data_size, data);
511}
512
513static efi_status_t virt_efi_get_next_variable (unsigned long *name_size,
514 efi_char16_t *name,
515 efi_guid_t *vendor)
516{
517 return efi_call_virt(get_next_variable, name_size, name, vendor);
518}
519
520static efi_status_t virt_efi_set_variable (efi_char16_t *name,
521 efi_guid_t *vendor,
522 unsigned long attr,
523 unsigned long data_size, void *data)
524{
525 return efi_call_virt(set_variable, name, vendor, attr, data_size, data);
526}
527
528static efi_status_t virt_efi_get_next_high_mono_count (u32 *count)
529{
530 return efi_call_virt(get_next_high_mono_count, count);
531}
532
533static void virt_efi_reset_system (int reset_type, efi_status_t status,
534 unsigned long data_size,
535 efi_char16_t *data)
536{
537 efi_call_virt(reset_system, reset_type, status, data_size, data);
538}
539
540/*
541 * This function will switch the EFI runtime services to virtual mode.
542 * Essentially, look through the EFI memmap and map every region that
543 * has the runtime attribute bit set in its memory descriptor and update
544 * that memory descriptor with the virtual address obtained from ioremap().
545 * This enables the runtime services to be called without having to
546 * thunk back into physical mode for every invocation.
547 */
548
549void __init efi_enter_virtual_mode(void)
550{
551 efi_memory_desc_t *md;
552 efi_status_t status;
553 void *p;
554
555 efi.systab = NULL;
556
557 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
558 md = p;
559
560 if (!(md->attribute & EFI_MEMORY_RUNTIME))
561 continue;
562
563 md->virt_addr = (unsigned long)ioremap(md->phys_addr,
564 md->num_pages << EFI_PAGE_SHIFT);
565 if (!(unsigned long)md->virt_addr) {
566 printk(KERN_ERR PFX "ioremap of 0x%lX failed\n",
567 (unsigned long)md->phys_addr);
568 }
569 /* update the virtual address of the EFI system table */
570 check_range_for_systab(md);
571 }
572
573 BUG_ON(!efi.systab);
574
575 status = phys_efi_set_virtual_address_map(
576 memmap.desc_size * memmap.nr_map,
577 memmap.desc_size,
578 memmap.desc_version,
579 memmap.phys_map);
580
581 if (status != EFI_SUCCESS) {
582 printk (KERN_ALERT "You are screwed! "
583 "Unable to switch EFI into virtual mode "
584 "(status=%lx)\n", status);
585 panic("EFI call to SetVirtualAddressMap() failed!");
586 }
587
588 /*
589 * Now that EFI is in virtual mode, update the function
590 * pointers in the runtime service table to the new virtual addresses.
591 */
592
593 efi.get_time = virt_efi_get_time;
594 efi.set_time = virt_efi_set_time;
595 efi.get_wakeup_time = virt_efi_get_wakeup_time;
596 efi.set_wakeup_time = virt_efi_set_wakeup_time;
597 efi.get_variable = virt_efi_get_variable;
598 efi.get_next_variable = virt_efi_get_next_variable;
599 efi.set_variable = virt_efi_set_variable;
600 efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count;
601 efi.reset_system = virt_efi_reset_system;
602}
603
604void __init
605efi_initialize_iomem_resources(struct resource *code_resource,
606 struct resource *data_resource,
607 struct resource *bss_resource)
608{
609 struct resource *res;
610 efi_memory_desc_t *md;
611 void *p;
612
613 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
614 md = p;
615
616 if ((md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) >
617 0x100000000ULL)
618 continue;
619 res = kzalloc(sizeof(struct resource), GFP_ATOMIC);
620 switch (md->type) {
621 case EFI_RESERVED_TYPE:
622 res->name = "Reserved Memory";
623 break;
624 case EFI_LOADER_CODE:
625 res->name = "Loader Code";
626 break;
627 case EFI_LOADER_DATA:
628 res->name = "Loader Data";
629 break;
630 case EFI_BOOT_SERVICES_DATA:
631 res->name = "BootServices Data";
632 break;
633 case EFI_BOOT_SERVICES_CODE:
634 res->name = "BootServices Code";
635 break;
636 case EFI_RUNTIME_SERVICES_CODE:
637 res->name = "Runtime Service Code";
638 break;
639 case EFI_RUNTIME_SERVICES_DATA:
640 res->name = "Runtime Service Data";
641 break;
642 case EFI_CONVENTIONAL_MEMORY:
643 res->name = "Conventional Memory";
644 break;
645 case EFI_UNUSABLE_MEMORY:
646 res->name = "Unusable Memory";
647 break;
648 case EFI_ACPI_RECLAIM_MEMORY:
649 res->name = "ACPI Reclaim";
650 break;
651 case EFI_ACPI_MEMORY_NVS:
652 res->name = "ACPI NVS";
653 break;
654 case EFI_MEMORY_MAPPED_IO:
655 res->name = "Memory Mapped IO";
656 break;
657 case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
658 res->name = "Memory Mapped IO Port Space";
659 break;
660 default:
661 res->name = "Reserved";
662 break;
663 }
664 res->start = md->phys_addr;
665 res->end = res->start + ((md->num_pages << EFI_PAGE_SHIFT) - 1);
666 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
667 if (request_resource(&iomem_resource, res) < 0)
668 printk(KERN_ERR PFX "Failed to allocate res %s : "
669 "0x%llx-0x%llx\n", res->name,
670 (unsigned long long)res->start,
671 (unsigned long long)res->end);
672 /*
673 * We don't know which region contains kernel data so we try
674 * it repeatedly and let the resource manager test it.
675 */
676 if (md->type == EFI_CONVENTIONAL_MEMORY) {
677 request_resource(res, code_resource);
678 request_resource(res, data_resource);
679 request_resource(res, bss_resource);
680#ifdef CONFIG_KEXEC
681 request_resource(res, &crashk_res);
682#endif
683 }
684 }
685}
686
687/*
688 * Convenience functions to obtain memory types and attributes
689 */
690
691u32 efi_mem_type(unsigned long phys_addr)
692{
693 efi_memory_desc_t *md;
694 void *p;
695
696 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
697 md = p;
698 if ((md->phys_addr <= phys_addr) && (phys_addr <
699 (md->phys_addr + (md-> num_pages << EFI_PAGE_SHIFT)) ))
700 return md->type;
701 }
702 return 0;
703}
704
705u64 efi_mem_attributes(unsigned long phys_addr)
706{
707 efi_memory_desc_t *md;
708 void *p;
709
710 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
711 md = p;
712 if ((md->phys_addr <= phys_addr) && (phys_addr <
713 (md->phys_addr + (md-> num_pages << EFI_PAGE_SHIFT)) ))
714 return md->attribute;
715 }
716 return 0;
717} 111}
diff --git a/arch/x86/kernel/efi_64.c b/arch/x86/kernel/efi_64.c
new file mode 100644
index 000000000000..4b73992c1e11
--- /dev/null
+++ b/arch/x86/kernel/efi_64.c
@@ -0,0 +1,134 @@
1/*
2 * x86_64 specific EFI support functions
3 * Based on Extensible Firmware Interface Specification version 1.0
4 *
5 * Copyright (C) 2005-2008 Intel Co.
6 * Fenghua Yu <fenghua.yu@intel.com>
7 * Bibo Mao <bibo.mao@intel.com>
8 * Chandramouli Narayanan <mouli@linux.intel.com>
9 * Huang Ying <ying.huang@intel.com>
10 *
11 * Code to convert EFI to E820 map has been implemented in elilo bootloader
12 * based on a EFI patch by Edgar Hucek. Based on the E820 map, the page table
13 * is setup appropriately for EFI runtime code.
14 * - mouli 06/14/2007.
15 *
16 */
17
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/mm.h>
21#include <linux/types.h>
22#include <linux/spinlock.h>
23#include <linux/bootmem.h>
24#include <linux/ioport.h>
25#include <linux/module.h>
26#include <linux/efi.h>
27#include <linux/uaccess.h>
28#include <linux/io.h>
29#include <linux/reboot.h>
30
31#include <asm/setup.h>
32#include <asm/page.h>
33#include <asm/e820.h>
34#include <asm/pgtable.h>
35#include <asm/tlbflush.h>
36#include <asm/proto.h>
37#include <asm/efi.h>
38
39static pgd_t save_pgd __initdata;
40static unsigned long efi_flags __initdata;
41
42static void __init early_mapping_set_exec(unsigned long start,
43 unsigned long end,
44 int executable)
45{
46 pte_t *kpte;
47 int level;
48
49 while (start < end) {
50 kpte = lookup_address((unsigned long)__va(start), &level);
51 BUG_ON(!kpte);
52 if (executable)
53 set_pte(kpte, pte_mkexec(*kpte));
54 else
55 set_pte(kpte, __pte((pte_val(*kpte) | _PAGE_NX) & \
56 __supported_pte_mask));
57 if (level == 4)
58 start = (start + PMD_SIZE) & PMD_MASK;
59 else
60 start = (start + PAGE_SIZE) & PAGE_MASK;
61 }
62}
63
64static void __init early_runtime_code_mapping_set_exec(int executable)
65{
66 efi_memory_desc_t *md;
67 void *p;
68
69 if (!(__supported_pte_mask & _PAGE_NX))
70 return;
71
72 /* Make EFI runtime service code area executable */
73 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
74 md = p;
75 if (md->type == EFI_RUNTIME_SERVICES_CODE) {
76 unsigned long end;
77 end = md->phys_addr + (md->num_pages << PAGE_SHIFT);
78 early_mapping_set_exec(md->phys_addr, end, executable);
79 }
80 }
81}
82
83void __init efi_call_phys_prelog(void)
84{
85 unsigned long vaddress;
86
87 local_irq_save(efi_flags);
88 early_runtime_code_mapping_set_exec(1);
89 vaddress = (unsigned long)__va(0x0UL);
90 save_pgd = *pgd_offset_k(0x0UL);
91 set_pgd(pgd_offset_k(0x0UL), *pgd_offset_k(vaddress));
92 __flush_tlb_all();
93}
94
95void __init efi_call_phys_epilog(void)
96{
97 /*
98 * After the lock is released, the original page table is restored.
99 */
100 set_pgd(pgd_offset_k(0x0UL), save_pgd);
101 early_runtime_code_mapping_set_exec(0);
102 __flush_tlb_all();
103 local_irq_restore(efi_flags);
104}
105
106void __init efi_reserve_bootmem(void)
107{
108 reserve_bootmem_generic((unsigned long)memmap.phys_map,
109 memmap.nr_map * memmap.desc_size);
110}
111
112void __iomem * __init efi_ioremap(unsigned long offset,
113 unsigned long size)
114{
115 static unsigned pages_mapped;
116 unsigned long last_addr;
117 unsigned i, pages;
118
119 last_addr = offset + size - 1;
120 offset &= PAGE_MASK;
121 pages = (PAGE_ALIGN(last_addr) - offset) >> PAGE_SHIFT;
122 if (pages_mapped + pages > MAX_EFI_IO_PAGES)
123 return NULL;
124
125 for (i = 0; i < pages; i++) {
126 __set_fixmap(FIX_EFI_IO_MAP_FIRST_PAGE - pages_mapped,
127 offset, PAGE_KERNEL_EXEC_NOCACHE);
128 offset += PAGE_SIZE;
129 pages_mapped++;
130 }
131
132 return (void __iomem *)__fix_to_virt(FIX_EFI_IO_MAP_FIRST_PAGE - \
133 (pages_mapped - pages));
134}
diff --git a/arch/x86/kernel/efi_stub_64.S b/arch/x86/kernel/efi_stub_64.S
new file mode 100644
index 000000000000..99b47d48c9f4
--- /dev/null
+++ b/arch/x86/kernel/efi_stub_64.S
@@ -0,0 +1,109 @@
1/*
2 * Function calling ABI conversion from Linux to EFI for x86_64
3 *
4 * Copyright (C) 2007 Intel Corp
5 * Bibo Mao <bibo.mao@intel.com>
6 * Huang Ying <ying.huang@intel.com>
7 */
8
9#include <linux/linkage.h>
10
11#define SAVE_XMM \
12 mov %rsp, %rax; \
13 subq $0x70, %rsp; \
14 and $~0xf, %rsp; \
15 mov %rax, (%rsp); \
16 mov %cr0, %rax; \
17 clts; \
18 mov %rax, 0x8(%rsp); \
19 movaps %xmm0, 0x60(%rsp); \
20 movaps %xmm1, 0x50(%rsp); \
21 movaps %xmm2, 0x40(%rsp); \
22 movaps %xmm3, 0x30(%rsp); \
23 movaps %xmm4, 0x20(%rsp); \
24 movaps %xmm5, 0x10(%rsp)
25
26#define RESTORE_XMM \
27 movaps 0x60(%rsp), %xmm0; \
28 movaps 0x50(%rsp), %xmm1; \
29 movaps 0x40(%rsp), %xmm2; \
30 movaps 0x30(%rsp), %xmm3; \
31 movaps 0x20(%rsp), %xmm4; \
32 movaps 0x10(%rsp), %xmm5; \
33 mov 0x8(%rsp), %rsi; \
34 mov %rsi, %cr0; \
35 mov (%rsp), %rsp
36
37ENTRY(efi_call0)
38 SAVE_XMM
39 subq $32, %rsp
40 call *%rdi
41 addq $32, %rsp
42 RESTORE_XMM
43 ret
44
45ENTRY(efi_call1)
46 SAVE_XMM
47 subq $32, %rsp
48 mov %rsi, %rcx
49 call *%rdi
50 addq $32, %rsp
51 RESTORE_XMM
52 ret
53
54ENTRY(efi_call2)
55 SAVE_XMM
56 subq $32, %rsp
57 mov %rsi, %rcx
58 call *%rdi
59 addq $32, %rsp
60 RESTORE_XMM
61 ret
62
63ENTRY(efi_call3)
64 SAVE_XMM
65 subq $32, %rsp
66 mov %rcx, %r8
67 mov %rsi, %rcx
68 call *%rdi
69 addq $32, %rsp
70 RESTORE_XMM
71 ret
72
73ENTRY(efi_call4)
74 SAVE_XMM
75 subq $32, %rsp
76 mov %r8, %r9
77 mov %rcx, %r8
78 mov %rsi, %rcx
79 call *%rdi
80 addq $32, %rsp
81 RESTORE_XMM
82 ret
83
84ENTRY(efi_call5)
85 SAVE_XMM
86 subq $48, %rsp
87 mov %r9, 32(%rsp)
88 mov %r8, %r9
89 mov %rcx, %r8
90 mov %rsi, %rcx
91 call *%rdi
92 addq $48, %rsp
93 RESTORE_XMM
94 ret
95
96ENTRY(efi_call6)
97 SAVE_XMM
98 mov (%rsp), %rax
99 mov 8(%rax), %rax
100 subq $48, %rsp
101 mov %r9, 32(%rsp)
102 mov %rax, 40(%rsp)
103 mov %r8, %r9
104 mov %rcx, %r8
105 mov %rsi, %rcx
106 call *%rdi
107 addq $48, %rsp
108 RESTORE_XMM
109 ret
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index dc7f938e5015..be5c31d04884 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -58,7 +58,7 @@
58 * for paravirtualization. The following will never clobber any registers: 58 * for paravirtualization. The following will never clobber any registers:
59 * INTERRUPT_RETURN (aka. "iret") 59 * INTERRUPT_RETURN (aka. "iret")
60 * GET_CR0_INTO_EAX (aka. "movl %cr0, %eax") 60 * GET_CR0_INTO_EAX (aka. "movl %cr0, %eax")
61 * ENABLE_INTERRUPTS_SYSEXIT (aka "sti; sysexit"). 61 * ENABLE_INTERRUPTS_SYSCALL_RET (aka "sti; sysexit").
62 * 62 *
63 * For DISABLE_INTERRUPTS/ENABLE_INTERRUPTS (aka "cli"/"sti"), you must 63 * For DISABLE_INTERRUPTS/ENABLE_INTERRUPTS (aka "cli"/"sti"), you must
64 * specify what registers can be overwritten (CLBR_NONE, CLBR_EAX/EDX/ECX/ANY). 64 * specify what registers can be overwritten (CLBR_NONE, CLBR_EAX/EDX/ECX/ANY).
@@ -283,12 +283,12 @@ END(resume_kernel)
283 the vsyscall page. See vsyscall-sysentry.S, which defines the symbol. */ 283 the vsyscall page. See vsyscall-sysentry.S, which defines the symbol. */
284 284
285 # sysenter call handler stub 285 # sysenter call handler stub
286ENTRY(sysenter_entry) 286ENTRY(ia32_sysenter_target)
287 CFI_STARTPROC simple 287 CFI_STARTPROC simple
288 CFI_SIGNAL_FRAME 288 CFI_SIGNAL_FRAME
289 CFI_DEF_CFA esp, 0 289 CFI_DEF_CFA esp, 0
290 CFI_REGISTER esp, ebp 290 CFI_REGISTER esp, ebp
291 movl TSS_sysenter_esp0(%esp),%esp 291 movl TSS_sysenter_sp0(%esp),%esp
292sysenter_past_esp: 292sysenter_past_esp:
293 /* 293 /*
294 * No need to follow this irqs on/off section: the syscall 294 * No need to follow this irqs on/off section: the syscall
@@ -351,7 +351,7 @@ sysenter_past_esp:
351 xorl %ebp,%ebp 351 xorl %ebp,%ebp
352 TRACE_IRQS_ON 352 TRACE_IRQS_ON
3531: mov PT_FS(%esp), %fs 3531: mov PT_FS(%esp), %fs
354 ENABLE_INTERRUPTS_SYSEXIT 354 ENABLE_INTERRUPTS_SYSCALL_RET
355 CFI_ENDPROC 355 CFI_ENDPROC
356.pushsection .fixup,"ax" 356.pushsection .fixup,"ax"
3572: movl $0,PT_FS(%esp) 3572: movl $0,PT_FS(%esp)
@@ -360,7 +360,7 @@ sysenter_past_esp:
360 .align 4 360 .align 4
361 .long 1b,2b 361 .long 1b,2b
362.popsection 362.popsection
363ENDPROC(sysenter_entry) 363ENDPROC(ia32_sysenter_target)
364 364
365 # system call handler stub 365 # system call handler stub
366ENTRY(system_call) 366ENTRY(system_call)
@@ -583,7 +583,7 @@ END(syscall_badsys)
583 * Build the entry stubs and pointer table with 583 * Build the entry stubs and pointer table with
584 * some assembler magic. 584 * some assembler magic.
585 */ 585 */
586.data 586.section .rodata,"a"
587ENTRY(interrupt) 587ENTRY(interrupt)
588.text 588.text
589 589
@@ -743,7 +743,7 @@ END(device_not_available)
743 * that sets up the real kernel stack. Check here, since we can't 743 * that sets up the real kernel stack. Check here, since we can't
744 * allow the wrong stack to be used. 744 * allow the wrong stack to be used.
745 * 745 *
746 * "TSS_sysenter_esp0+12" is because the NMI/debug handler will have 746 * "TSS_sysenter_sp0+12" is because the NMI/debug handler will have
747 * already pushed 3 words if it hits on the sysenter instruction: 747 * already pushed 3 words if it hits on the sysenter instruction:
748 * eflags, cs and eip. 748 * eflags, cs and eip.
749 * 749 *
@@ -755,7 +755,7 @@ END(device_not_available)
755 cmpw $__KERNEL_CS,4(%esp); \ 755 cmpw $__KERNEL_CS,4(%esp); \
756 jne ok; \ 756 jne ok; \
757label: \ 757label: \
758 movl TSS_sysenter_esp0+offset(%esp),%esp; \ 758 movl TSS_sysenter_sp0+offset(%esp),%esp; \
759 CFI_DEF_CFA esp, 0; \ 759 CFI_DEF_CFA esp, 0; \
760 CFI_UNDEFINED eip; \ 760 CFI_UNDEFINED eip; \
761 pushfl; \ 761 pushfl; \
@@ -768,7 +768,7 @@ label: \
768 768
769KPROBE_ENTRY(debug) 769KPROBE_ENTRY(debug)
770 RING0_INT_FRAME 770 RING0_INT_FRAME
771 cmpl $sysenter_entry,(%esp) 771 cmpl $ia32_sysenter_target,(%esp)
772 jne debug_stack_correct 772 jne debug_stack_correct
773 FIX_STACK(12, debug_stack_correct, debug_esp_fix_insn) 773 FIX_STACK(12, debug_stack_correct, debug_esp_fix_insn)
774debug_stack_correct: 774debug_stack_correct:
@@ -799,7 +799,7 @@ KPROBE_ENTRY(nmi)
799 popl %eax 799 popl %eax
800 CFI_ADJUST_CFA_OFFSET -4 800 CFI_ADJUST_CFA_OFFSET -4
801 je nmi_espfix_stack 801 je nmi_espfix_stack
802 cmpl $sysenter_entry,(%esp) 802 cmpl $ia32_sysenter_target,(%esp)
803 je nmi_stack_fixup 803 je nmi_stack_fixup
804 pushl %eax 804 pushl %eax
805 CFI_ADJUST_CFA_OFFSET 4 805 CFI_ADJUST_CFA_OFFSET 4
@@ -812,7 +812,7 @@ KPROBE_ENTRY(nmi)
812 popl %eax 812 popl %eax
813 CFI_ADJUST_CFA_OFFSET -4 813 CFI_ADJUST_CFA_OFFSET -4
814 jae nmi_stack_correct 814 jae nmi_stack_correct
815 cmpl $sysenter_entry,12(%esp) 815 cmpl $ia32_sysenter_target,12(%esp)
816 je nmi_debug_stack_check 816 je nmi_debug_stack_check
817nmi_stack_correct: 817nmi_stack_correct:
818 /* We have a RING0_INT_FRAME here */ 818 /* We have a RING0_INT_FRAME here */
@@ -882,10 +882,10 @@ ENTRY(native_iret)
882.previous 882.previous
883END(native_iret) 883END(native_iret)
884 884
885ENTRY(native_irq_enable_sysexit) 885ENTRY(native_irq_enable_syscall_ret)
886 sti 886 sti
887 sysexit 887 sysexit
888END(native_irq_enable_sysexit) 888END(native_irq_enable_syscall_ret)
889#endif 889#endif
890 890
891KPROBE_ENTRY(int3) 891KPROBE_ENTRY(int3)
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index 3a058bb16409..bea8474744ff 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -50,6 +50,7 @@
50#include <asm/hw_irq.h> 50#include <asm/hw_irq.h>
51#include <asm/page.h> 51#include <asm/page.h>
52#include <asm/irqflags.h> 52#include <asm/irqflags.h>
53#include <asm/paravirt.h>
53 54
54 .code64 55 .code64
55 56
@@ -57,6 +58,13 @@
57#define retint_kernel retint_restore_args 58#define retint_kernel retint_restore_args
58#endif 59#endif
59 60
61#ifdef CONFIG_PARAVIRT
62ENTRY(native_irq_enable_syscall_ret)
63 movq %gs:pda_oldrsp,%rsp
64 swapgs
65 sysretq
66#endif /* CONFIG_PARAVIRT */
67
60 68
61.macro TRACE_IRQS_IRETQ offset=ARGOFFSET 69.macro TRACE_IRQS_IRETQ offset=ARGOFFSET
62#ifdef CONFIG_TRACE_IRQFLAGS 70#ifdef CONFIG_TRACE_IRQFLAGS
@@ -216,14 +224,21 @@ ENTRY(system_call)
216 CFI_DEF_CFA rsp,PDA_STACKOFFSET 224 CFI_DEF_CFA rsp,PDA_STACKOFFSET
217 CFI_REGISTER rip,rcx 225 CFI_REGISTER rip,rcx
218 /*CFI_REGISTER rflags,r11*/ 226 /*CFI_REGISTER rflags,r11*/
219 swapgs 227 SWAPGS_UNSAFE_STACK
228 /*
229 * A hypervisor implementation might want to use a label
230 * after the swapgs, so that it can do the swapgs
231 * for the guest and jump here on syscall.
232 */
233ENTRY(system_call_after_swapgs)
234
220 movq %rsp,%gs:pda_oldrsp 235 movq %rsp,%gs:pda_oldrsp
221 movq %gs:pda_kernelstack,%rsp 236 movq %gs:pda_kernelstack,%rsp
222 /* 237 /*
223 * No need to follow this irqs off/on section - it's straight 238 * No need to follow this irqs off/on section - it's straight
224 * and short: 239 * and short:
225 */ 240 */
226 sti 241 ENABLE_INTERRUPTS(CLBR_NONE)
227 SAVE_ARGS 8,1 242 SAVE_ARGS 8,1
228 movq %rax,ORIG_RAX-ARGOFFSET(%rsp) 243 movq %rax,ORIG_RAX-ARGOFFSET(%rsp)
229 movq %rcx,RIP-ARGOFFSET(%rsp) 244 movq %rcx,RIP-ARGOFFSET(%rsp)
@@ -246,7 +261,7 @@ ret_from_sys_call:
246sysret_check: 261sysret_check:
247 LOCKDEP_SYS_EXIT 262 LOCKDEP_SYS_EXIT
248 GET_THREAD_INFO(%rcx) 263 GET_THREAD_INFO(%rcx)
249 cli 264 DISABLE_INTERRUPTS(CLBR_NONE)
250 TRACE_IRQS_OFF 265 TRACE_IRQS_OFF
251 movl threadinfo_flags(%rcx),%edx 266 movl threadinfo_flags(%rcx),%edx
252 andl %edi,%edx 267 andl %edi,%edx
@@ -260,9 +275,7 @@ sysret_check:
260 CFI_REGISTER rip,rcx 275 CFI_REGISTER rip,rcx
261 RESTORE_ARGS 0,-ARG_SKIP,1 276 RESTORE_ARGS 0,-ARG_SKIP,1
262 /*CFI_REGISTER rflags,r11*/ 277 /*CFI_REGISTER rflags,r11*/
263 movq %gs:pda_oldrsp,%rsp 278 ENABLE_INTERRUPTS_SYSCALL_RET
264 swapgs
265 sysretq
266 279
267 CFI_RESTORE_STATE 280 CFI_RESTORE_STATE
268 /* Handle reschedules */ 281 /* Handle reschedules */
@@ -271,7 +284,7 @@ sysret_careful:
271 bt $TIF_NEED_RESCHED,%edx 284 bt $TIF_NEED_RESCHED,%edx
272 jnc sysret_signal 285 jnc sysret_signal
273 TRACE_IRQS_ON 286 TRACE_IRQS_ON
274 sti 287 ENABLE_INTERRUPTS(CLBR_NONE)
275 pushq %rdi 288 pushq %rdi
276 CFI_ADJUST_CFA_OFFSET 8 289 CFI_ADJUST_CFA_OFFSET 8
277 call schedule 290 call schedule
@@ -282,8 +295,8 @@ sysret_careful:
282 /* Handle a signal */ 295 /* Handle a signal */
283sysret_signal: 296sysret_signal:
284 TRACE_IRQS_ON 297 TRACE_IRQS_ON
285 sti 298 ENABLE_INTERRUPTS(CLBR_NONE)
286 testl $(_TIF_SIGPENDING|_TIF_SINGLESTEP|_TIF_MCE_NOTIFY),%edx 299 testl $_TIF_DO_NOTIFY_MASK,%edx
287 jz 1f 300 jz 1f
288 301
289 /* Really a signal */ 302 /* Really a signal */
@@ -295,7 +308,7 @@ sysret_signal:
2951: movl $_TIF_NEED_RESCHED,%edi 3081: movl $_TIF_NEED_RESCHED,%edi
296 /* Use IRET because user could have changed frame. This 309 /* Use IRET because user could have changed frame. This
297 works because ptregscall_common has called FIXUP_TOP_OF_STACK. */ 310 works because ptregscall_common has called FIXUP_TOP_OF_STACK. */
298 cli 311 DISABLE_INTERRUPTS(CLBR_NONE)
299 TRACE_IRQS_OFF 312 TRACE_IRQS_OFF
300 jmp int_with_check 313 jmp int_with_check
301 314
@@ -327,7 +340,7 @@ tracesys:
327 */ 340 */
328 .globl int_ret_from_sys_call 341 .globl int_ret_from_sys_call
329int_ret_from_sys_call: 342int_ret_from_sys_call:
330 cli 343 DISABLE_INTERRUPTS(CLBR_NONE)
331 TRACE_IRQS_OFF 344 TRACE_IRQS_OFF
332 testl $3,CS-ARGOFFSET(%rsp) 345 testl $3,CS-ARGOFFSET(%rsp)
333 je retint_restore_args 346 je retint_restore_args
@@ -349,20 +362,20 @@ int_careful:
349 bt $TIF_NEED_RESCHED,%edx 362 bt $TIF_NEED_RESCHED,%edx
350 jnc int_very_careful 363 jnc int_very_careful
351 TRACE_IRQS_ON 364 TRACE_IRQS_ON
352 sti 365 ENABLE_INTERRUPTS(CLBR_NONE)
353 pushq %rdi 366 pushq %rdi
354 CFI_ADJUST_CFA_OFFSET 8 367 CFI_ADJUST_CFA_OFFSET 8
355 call schedule 368 call schedule
356 popq %rdi 369 popq %rdi
357 CFI_ADJUST_CFA_OFFSET -8 370 CFI_ADJUST_CFA_OFFSET -8
358 cli 371 DISABLE_INTERRUPTS(CLBR_NONE)
359 TRACE_IRQS_OFF 372 TRACE_IRQS_OFF
360 jmp int_with_check 373 jmp int_with_check
361 374
362 /* handle signals and tracing -- both require a full stack frame */ 375 /* handle signals and tracing -- both require a full stack frame */
363int_very_careful: 376int_very_careful:
364 TRACE_IRQS_ON 377 TRACE_IRQS_ON
365 sti 378 ENABLE_INTERRUPTS(CLBR_NONE)
366 SAVE_REST 379 SAVE_REST
367 /* Check for syscall exit trace */ 380 /* Check for syscall exit trace */
368 testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP),%edx 381 testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP),%edx
@@ -377,7 +390,7 @@ int_very_careful:
377 jmp int_restore_rest 390 jmp int_restore_rest
378 391
379int_signal: 392int_signal:
380 testl $(_TIF_SIGPENDING|_TIF_SINGLESTEP|_TIF_MCE_NOTIFY),%edx 393 testl $_TIF_DO_NOTIFY_MASK,%edx
381 jz 1f 394 jz 1f
382 movq %rsp,%rdi # &ptregs -> arg1 395 movq %rsp,%rdi # &ptregs -> arg1
383 xorl %esi,%esi # oldset -> arg2 396 xorl %esi,%esi # oldset -> arg2
@@ -385,7 +398,7 @@ int_signal:
3851: movl $_TIF_NEED_RESCHED,%edi 3981: movl $_TIF_NEED_RESCHED,%edi
386int_restore_rest: 399int_restore_rest:
387 RESTORE_REST 400 RESTORE_REST
388 cli 401 DISABLE_INTERRUPTS(CLBR_NONE)
389 TRACE_IRQS_OFF 402 TRACE_IRQS_OFF
390 jmp int_with_check 403 jmp int_with_check
391 CFI_ENDPROC 404 CFI_ENDPROC
@@ -506,7 +519,7 @@ END(stub_rt_sigreturn)
506 CFI_DEF_CFA_REGISTER rbp 519 CFI_DEF_CFA_REGISTER rbp
507 testl $3,CS(%rdi) 520 testl $3,CS(%rdi)
508 je 1f 521 je 1f
509 swapgs 522 SWAPGS
510 /* irqcount is used to check if a CPU is already on an interrupt 523 /* irqcount is used to check if a CPU is already on an interrupt
511 stack or not. While this is essentially redundant with preempt_count 524 stack or not. While this is essentially redundant with preempt_count
512 it is a little cheaper to use a separate counter in the PDA 525 it is a little cheaper to use a separate counter in the PDA
@@ -527,7 +540,7 @@ ENTRY(common_interrupt)
527 interrupt do_IRQ 540 interrupt do_IRQ
528 /* 0(%rsp): oldrsp-ARGOFFSET */ 541 /* 0(%rsp): oldrsp-ARGOFFSET */
529ret_from_intr: 542ret_from_intr:
530 cli 543 DISABLE_INTERRUPTS(CLBR_NONE)
531 TRACE_IRQS_OFF 544 TRACE_IRQS_OFF
532 decl %gs:pda_irqcount 545 decl %gs:pda_irqcount
533 leaveq 546 leaveq
@@ -556,13 +569,13 @@ retint_swapgs: /* return to user-space */
556 /* 569 /*
557 * The iretq could re-enable interrupts: 570 * The iretq could re-enable interrupts:
558 */ 571 */
559 cli 572 DISABLE_INTERRUPTS(CLBR_ANY)
560 TRACE_IRQS_IRETQ 573 TRACE_IRQS_IRETQ
561 swapgs 574 SWAPGS
562 jmp restore_args 575 jmp restore_args
563 576
564retint_restore_args: /* return to kernel space */ 577retint_restore_args: /* return to kernel space */
565 cli 578 DISABLE_INTERRUPTS(CLBR_ANY)
566 /* 579 /*
567 * The iretq could re-enable interrupts: 580 * The iretq could re-enable interrupts:
568 */ 581 */
@@ -570,10 +583,14 @@ retint_restore_args: /* return to kernel space */
570restore_args: 583restore_args:
571 RESTORE_ARGS 0,8,0 584 RESTORE_ARGS 0,8,0
572iret_label: 585iret_label:
586#ifdef CONFIG_PARAVIRT
587 INTERRUPT_RETURN
588#endif
589ENTRY(native_iret)
573 iretq 590 iretq
574 591
575 .section __ex_table,"a" 592 .section __ex_table,"a"
576 .quad iret_label,bad_iret 593 .quad native_iret, bad_iret
577 .previous 594 .previous
578 .section .fixup,"ax" 595 .section .fixup,"ax"
579 /* force a signal here? this matches i386 behaviour */ 596 /* force a signal here? this matches i386 behaviour */
@@ -581,39 +598,39 @@ iret_label:
581bad_iret: 598bad_iret:
582 movq $11,%rdi /* SIGSEGV */ 599 movq $11,%rdi /* SIGSEGV */
583 TRACE_IRQS_ON 600 TRACE_IRQS_ON
584 sti 601 ENABLE_INTERRUPTS(CLBR_ANY | ~(CLBR_RDI))
585 jmp do_exit 602 jmp do_exit
586 .previous 603 .previous
587 604
588 /* edi: workmask, edx: work */ 605 /* edi: workmask, edx: work */
589retint_careful: 606retint_careful:
590 CFI_RESTORE_STATE 607 CFI_RESTORE_STATE
591 bt $TIF_NEED_RESCHED,%edx 608 bt $TIF_NEED_RESCHED,%edx
592 jnc retint_signal 609 jnc retint_signal
593 TRACE_IRQS_ON 610 TRACE_IRQS_ON
594 sti 611 ENABLE_INTERRUPTS(CLBR_NONE)
595 pushq %rdi 612 pushq %rdi
596 CFI_ADJUST_CFA_OFFSET 8 613 CFI_ADJUST_CFA_OFFSET 8
597 call schedule 614 call schedule
598 popq %rdi 615 popq %rdi
599 CFI_ADJUST_CFA_OFFSET -8 616 CFI_ADJUST_CFA_OFFSET -8
600 GET_THREAD_INFO(%rcx) 617 GET_THREAD_INFO(%rcx)
601 cli 618 DISABLE_INTERRUPTS(CLBR_NONE)
602 TRACE_IRQS_OFF 619 TRACE_IRQS_OFF
603 jmp retint_check 620 jmp retint_check
604 621
605retint_signal: 622retint_signal:
606 testl $(_TIF_SIGPENDING|_TIF_SINGLESTEP|_TIF_MCE_NOTIFY),%edx 623 testl $_TIF_DO_NOTIFY_MASK,%edx
607 jz retint_swapgs 624 jz retint_swapgs
608 TRACE_IRQS_ON 625 TRACE_IRQS_ON
609 sti 626 ENABLE_INTERRUPTS(CLBR_NONE)
610 SAVE_REST 627 SAVE_REST
611 movq $-1,ORIG_RAX(%rsp) 628 movq $-1,ORIG_RAX(%rsp)
612 xorl %esi,%esi # oldset 629 xorl %esi,%esi # oldset
613 movq %rsp,%rdi # &pt_regs 630 movq %rsp,%rdi # &pt_regs
614 call do_notify_resume 631 call do_notify_resume
615 RESTORE_REST 632 RESTORE_REST
616 cli 633 DISABLE_INTERRUPTS(CLBR_NONE)
617 TRACE_IRQS_OFF 634 TRACE_IRQS_OFF
618 movl $_TIF_NEED_RESCHED,%edi 635 movl $_TIF_NEED_RESCHED,%edi
619 GET_THREAD_INFO(%rcx) 636 GET_THREAD_INFO(%rcx)
@@ -731,7 +748,7 @@ END(spurious_interrupt)
731 rdmsr 748 rdmsr
732 testl %edx,%edx 749 testl %edx,%edx
733 js 1f 750 js 1f
734 swapgs 751 SWAPGS
735 xorl %ebx,%ebx 752 xorl %ebx,%ebx
7361: 7531:
737 .if \ist 754 .if \ist
@@ -747,7 +764,7 @@ END(spurious_interrupt)
747 .if \ist 764 .if \ist
748 addq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp) 765 addq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
749 .endif 766 .endif
750 cli 767 DISABLE_INTERRUPTS(CLBR_NONE)
751 .if \irqtrace 768 .if \irqtrace
752 TRACE_IRQS_OFF 769 TRACE_IRQS_OFF
753 .endif 770 .endif
@@ -776,10 +793,10 @@ paranoid_swapgs\trace:
776 .if \trace 793 .if \trace
777 TRACE_IRQS_IRETQ 0 794 TRACE_IRQS_IRETQ 0
778 .endif 795 .endif
779 swapgs 796 SWAPGS_UNSAFE_STACK
780paranoid_restore\trace: 797paranoid_restore\trace:
781 RESTORE_ALL 8 798 RESTORE_ALL 8
782 iretq 799 INTERRUPT_RETURN
783paranoid_userspace\trace: 800paranoid_userspace\trace:
784 GET_THREAD_INFO(%rcx) 801 GET_THREAD_INFO(%rcx)
785 movl threadinfo_flags(%rcx),%ebx 802 movl threadinfo_flags(%rcx),%ebx
@@ -794,11 +811,11 @@ paranoid_userspace\trace:
794 .if \trace 811 .if \trace
795 TRACE_IRQS_ON 812 TRACE_IRQS_ON
796 .endif 813 .endif
797 sti 814 ENABLE_INTERRUPTS(CLBR_NONE)
798 xorl %esi,%esi /* arg2: oldset */ 815 xorl %esi,%esi /* arg2: oldset */
799 movq %rsp,%rdi /* arg1: &pt_regs */ 816 movq %rsp,%rdi /* arg1: &pt_regs */
800 call do_notify_resume 817 call do_notify_resume
801 cli 818 DISABLE_INTERRUPTS(CLBR_NONE)
802 .if \trace 819 .if \trace
803 TRACE_IRQS_OFF 820 TRACE_IRQS_OFF
804 .endif 821 .endif
@@ -807,9 +824,9 @@ paranoid_schedule\trace:
807 .if \trace 824 .if \trace
808 TRACE_IRQS_ON 825 TRACE_IRQS_ON
809 .endif 826 .endif
810 sti 827 ENABLE_INTERRUPTS(CLBR_ANY)
811 call schedule 828 call schedule
812 cli 829 DISABLE_INTERRUPTS(CLBR_ANY)
813 .if \trace 830 .if \trace
814 TRACE_IRQS_OFF 831 TRACE_IRQS_OFF
815 .endif 832 .endif
@@ -862,7 +879,7 @@ KPROBE_ENTRY(error_entry)
862 testl $3,CS(%rsp) 879 testl $3,CS(%rsp)
863 je error_kernelspace 880 je error_kernelspace
864error_swapgs: 881error_swapgs:
865 swapgs 882 SWAPGS
866error_sti: 883error_sti:
867 movq %rdi,RDI(%rsp) 884 movq %rdi,RDI(%rsp)
868 CFI_REL_OFFSET rdi,RDI 885 CFI_REL_OFFSET rdi,RDI
@@ -874,7 +891,7 @@ error_sti:
874error_exit: 891error_exit:
875 movl %ebx,%eax 892 movl %ebx,%eax
876 RESTORE_REST 893 RESTORE_REST
877 cli 894 DISABLE_INTERRUPTS(CLBR_NONE)
878 TRACE_IRQS_OFF 895 TRACE_IRQS_OFF
879 GET_THREAD_INFO(%rcx) 896 GET_THREAD_INFO(%rcx)
880 testl %eax,%eax 897 testl %eax,%eax
@@ -911,12 +928,12 @@ ENTRY(load_gs_index)
911 CFI_STARTPROC 928 CFI_STARTPROC
912 pushf 929 pushf
913 CFI_ADJUST_CFA_OFFSET 8 930 CFI_ADJUST_CFA_OFFSET 8
914 cli 931 DISABLE_INTERRUPTS(CLBR_ANY | ~(CLBR_RDI))
915 swapgs 932 SWAPGS
916gs_change: 933gs_change:
917 movl %edi,%gs 934 movl %edi,%gs
9182: mfence /* workaround */ 9352: mfence /* workaround */
919 swapgs 936 SWAPGS
920 popf 937 popf
921 CFI_ADJUST_CFA_OFFSET -8 938 CFI_ADJUST_CFA_OFFSET -8
922 ret 939 ret
@@ -930,7 +947,7 @@ ENDPROC(load_gs_index)
930 .section .fixup,"ax" 947 .section .fixup,"ax"
931 /* running with kernelgs */ 948 /* running with kernelgs */
932bad_gs: 949bad_gs:
933 swapgs /* switch back to user gs */ 950 SWAPGS /* switch back to user gs */
934 xorl %eax,%eax 951 xorl %eax,%eax
935 movl %eax,%gs 952 movl %eax,%gs
936 jmp 2b 953 jmp 2b
diff --git a/arch/x86/kernel/genapic_64.c b/arch/x86/kernel/genapic_64.c
index ce703e21c912..4ae7b6440260 100644
--- a/arch/x86/kernel/genapic_64.c
+++ b/arch/x86/kernel/genapic_64.c
@@ -24,18 +24,11 @@
24#include <acpi/acpi_bus.h> 24#include <acpi/acpi_bus.h>
25#endif 25#endif
26 26
27/* 27/* which logical CPU number maps to which CPU (physical APIC ID) */
28 * which logical CPU number maps to which CPU (physical APIC ID) 28u16 x86_cpu_to_apicid_init[NR_CPUS] __initdata
29 *
30 * The following static array is used during kernel startup
31 * and the x86_cpu_to_apicid_ptr contains the address of the
32 * array during this time. Is it zeroed when the per_cpu
33 * data area is removed.
34 */
35u8 x86_cpu_to_apicid_init[NR_CPUS] __initdata
36 = { [0 ... NR_CPUS-1] = BAD_APICID }; 29 = { [0 ... NR_CPUS-1] = BAD_APICID };
37void *x86_cpu_to_apicid_ptr; 30void *x86_cpu_to_apicid_early_ptr;
38DEFINE_PER_CPU(u8, x86_cpu_to_apicid) = BAD_APICID; 31DEFINE_PER_CPU(u16, x86_cpu_to_apicid) = BAD_APICID;
39EXPORT_PER_CPU_SYMBOL(x86_cpu_to_apicid); 32EXPORT_PER_CPU_SYMBOL(x86_cpu_to_apicid);
40 33
41struct genapic __read_mostly *genapic = &apic_flat; 34struct genapic __read_mostly *genapic = &apic_flat;
diff --git a/arch/x86/kernel/geode_32.c b/arch/x86/kernel/geode_32.c
index f12d8c5d9809..9c7f7d395968 100644
--- a/arch/x86/kernel/geode_32.c
+++ b/arch/x86/kernel/geode_32.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * AMD Geode southbridge support code 2 * AMD Geode southbridge support code
3 * Copyright (C) 2006, Advanced Micro Devices, Inc. 3 * Copyright (C) 2006, Advanced Micro Devices, Inc.
4 * Copyright (C) 2007, Andres Salomon <dilinger@debian.org>
4 * 5 *
5 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of version 2 of the GNU General Public License 7 * modify it under the terms of version 2 of the GNU General Public License
@@ -51,45 +52,62 @@ EXPORT_SYMBOL_GPL(geode_get_dev_base);
51 52
52/* === GPIO API === */ 53/* === GPIO API === */
53 54
54void geode_gpio_set(unsigned int gpio, unsigned int reg) 55void geode_gpio_set(u32 gpio, unsigned int reg)
55{ 56{
56 u32 base = geode_get_dev_base(GEODE_DEV_GPIO); 57 u32 base = geode_get_dev_base(GEODE_DEV_GPIO);
57 58
58 if (!base) 59 if (!base)
59 return; 60 return;
60 61
61 if (gpio < 16) 62 /* low bank register */
62 outl(1 << gpio, base + reg); 63 if (gpio & 0xFFFF)
63 else 64 outl(gpio & 0xFFFF, base + reg);
64 outl(1 << (gpio - 16), base + 0x80 + reg); 65 /* high bank register */
66 gpio >>= 16;
67 if (gpio)
68 outl(gpio, base + 0x80 + reg);
65} 69}
66EXPORT_SYMBOL_GPL(geode_gpio_set); 70EXPORT_SYMBOL_GPL(geode_gpio_set);
67 71
68void geode_gpio_clear(unsigned int gpio, unsigned int reg) 72void geode_gpio_clear(u32 gpio, unsigned int reg)
69{ 73{
70 u32 base = geode_get_dev_base(GEODE_DEV_GPIO); 74 u32 base = geode_get_dev_base(GEODE_DEV_GPIO);
71 75
72 if (!base) 76 if (!base)
73 return; 77 return;
74 78
75 if (gpio < 16) 79 /* low bank register */
76 outl(1 << (gpio + 16), base + reg); 80 if (gpio & 0xFFFF)
77 else 81 outl((gpio & 0xFFFF) << 16, base + reg);
78 outl(1 << gpio, base + 0x80 + reg); 82 /* high bank register */
83 gpio &= (0xFFFF << 16);
84 if (gpio)
85 outl(gpio, base + 0x80 + reg);
79} 86}
80EXPORT_SYMBOL_GPL(geode_gpio_clear); 87EXPORT_SYMBOL_GPL(geode_gpio_clear);
81 88
82int geode_gpio_isset(unsigned int gpio, unsigned int reg) 89int geode_gpio_isset(u32 gpio, unsigned int reg)
83{ 90{
84 u32 base = geode_get_dev_base(GEODE_DEV_GPIO); 91 u32 base = geode_get_dev_base(GEODE_DEV_GPIO);
92 u32 val;
85 93
86 if (!base) 94 if (!base)
87 return 0; 95 return 0;
88 96
89 if (gpio < 16) 97 /* low bank register */
90 return (inl(base + reg) & (1 << gpio)) ? 1 : 0; 98 if (gpio & 0xFFFF) {
91 else 99 val = inl(base + reg) & (gpio & 0xFFFF);
92 return (inl(base + 0x80 + reg) & (1 << (gpio - 16))) ? 1 : 0; 100 if ((gpio & 0xFFFF) == val)
101 return 1;
102 }
103 /* high bank register */
104 gpio >>= 16;
105 if (gpio) {
106 val = inl(base + 0x80 + reg) & gpio;
107 if (gpio == val)
108 return 1;
109 }
110 return 0;
93} 111}
94EXPORT_SYMBOL_GPL(geode_gpio_isset); 112EXPORT_SYMBOL_GPL(geode_gpio_isset);
95 113
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index 6b3469311e42..a317336cdeaa 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -10,6 +10,7 @@
10#include <linux/kernel.h> 10#include <linux/kernel.h>
11#include <linux/string.h> 11#include <linux/string.h>
12#include <linux/percpu.h> 12#include <linux/percpu.h>
13#include <linux/start_kernel.h>
13 14
14#include <asm/processor.h> 15#include <asm/processor.h>
15#include <asm/proto.h> 16#include <asm/proto.h>
@@ -19,12 +20,14 @@
19#include <asm/pgtable.h> 20#include <asm/pgtable.h>
20#include <asm/tlbflush.h> 21#include <asm/tlbflush.h>
21#include <asm/sections.h> 22#include <asm/sections.h>
23#include <asm/kdebug.h>
24#include <asm/e820.h>
22 25
23static void __init zap_identity_mappings(void) 26static void __init zap_identity_mappings(void)
24{ 27{
25 pgd_t *pgd = pgd_offset_k(0UL); 28 pgd_t *pgd = pgd_offset_k(0UL);
26 pgd_clear(pgd); 29 pgd_clear(pgd);
27 __flush_tlb(); 30 __flush_tlb_all();
28} 31}
29 32
30/* Don't add a printk in there. printk relies on the PDA which is not initialized 33/* Don't add a printk in there. printk relies on the PDA which is not initialized
@@ -46,6 +49,35 @@ static void __init copy_bootdata(char *real_mode_data)
46 } 49 }
47} 50}
48 51
52#define EBDA_ADDR_POINTER 0x40E
53
54static __init void reserve_ebda(void)
55{
56 unsigned ebda_addr, ebda_size;
57
58 /*
59 * there is a real-mode segmented pointer pointing to the
60 * 4K EBDA area at 0x40E
61 */
62 ebda_addr = *(unsigned short *)__va(EBDA_ADDR_POINTER);
63 ebda_addr <<= 4;
64
65 if (!ebda_addr)
66 return;
67
68 ebda_size = *(unsigned short *)__va(ebda_addr);
69
70 /* Round EBDA up to pages */
71 if (ebda_size == 0)
72 ebda_size = 1;
73 ebda_size <<= 10;
74 ebda_size = round_up(ebda_size + (ebda_addr & ~PAGE_MASK), PAGE_SIZE);
75 if (ebda_size > 64*1024)
76 ebda_size = 64*1024;
77
78 reserve_early(ebda_addr, ebda_addr + ebda_size);
79}
80
49void __init x86_64_start_kernel(char * real_mode_data) 81void __init x86_64_start_kernel(char * real_mode_data)
50{ 82{
51 int i; 83 int i;
@@ -56,8 +88,13 @@ void __init x86_64_start_kernel(char * real_mode_data)
56 /* Make NULL pointers segfault */ 88 /* Make NULL pointers segfault */
57 zap_identity_mappings(); 89 zap_identity_mappings();
58 90
59 for (i = 0; i < IDT_ENTRIES; i++) 91 for (i = 0; i < IDT_ENTRIES; i++) {
92#ifdef CONFIG_EARLY_PRINTK
93 set_intr_gate(i, &early_idt_handlers[i]);
94#else
60 set_intr_gate(i, early_idt_handler); 95 set_intr_gate(i, early_idt_handler);
96#endif
97 }
61 load_idt((const struct desc_ptr *)&idt_descr); 98 load_idt((const struct desc_ptr *)&idt_descr);
62 99
63 early_printk("Kernel alive\n"); 100 early_printk("Kernel alive\n");
@@ -67,8 +104,24 @@ void __init x86_64_start_kernel(char * real_mode_data)
67 104
68 pda_init(0); 105 pda_init(0);
69 copy_bootdata(__va(real_mode_data)); 106 copy_bootdata(__va(real_mode_data));
70#ifdef CONFIG_SMP 107
71 cpu_set(0, cpu_online_map); 108 reserve_early(__pa_symbol(&_text), __pa_symbol(&_end));
72#endif 109
110 /* Reserve INITRD */
111 if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) {
112 unsigned long ramdisk_image = boot_params.hdr.ramdisk_image;
113 unsigned long ramdisk_size = boot_params.hdr.ramdisk_size;
114 unsigned long ramdisk_end = ramdisk_image + ramdisk_size;
115 reserve_early(ramdisk_image, ramdisk_end);
116 }
117
118 reserve_ebda();
119
120 /*
121 * At this point everything still needed from the boot loader
122 * or BIOS or kernel text should be early reserved or marked not
123 * RAM in e820. All other memory is free game.
124 */
125
73 start_kernel(); 126 start_kernel();
74} 127}
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
index fbad51fce672..5d8c5730686b 100644
--- a/arch/x86/kernel/head_32.S
+++ b/arch/x86/kernel/head_32.S
@@ -9,6 +9,7 @@
9 9
10.text 10.text
11#include <linux/threads.h> 11#include <linux/threads.h>
12#include <linux/init.h>
12#include <linux/linkage.h> 13#include <linux/linkage.h>
13#include <asm/segment.h> 14#include <asm/segment.h>
14#include <asm/page.h> 15#include <asm/page.h>
@@ -151,7 +152,9 @@ WEAK(xen_entry)
151 /* Unknown implementation; there's really 152 /* Unknown implementation; there's really
152 nothing we can do at this point. */ 153 nothing we can do at this point. */
153 ud2a 154 ud2a
154.data 155
156 __INITDATA
157
155subarch_entries: 158subarch_entries:
156 .long default_entry /* normal x86/PC */ 159 .long default_entry /* normal x86/PC */
157 .long lguest_entry /* lguest hypervisor */ 160 .long lguest_entry /* lguest hypervisor */
@@ -199,7 +202,6 @@ default_entry:
199 addl $0x67, %eax /* 0x67 == _PAGE_TABLE */ 202 addl $0x67, %eax /* 0x67 == _PAGE_TABLE */
200 movl %eax, 4092(%edx) 203 movl %eax, 4092(%edx)
201 204
202 xorl %ebx,%ebx /* This is the boot CPU (BSP) */
203 jmp 3f 205 jmp 3f
204/* 206/*
205 * Non-boot CPU entry point; entered from trampoline.S 207 * Non-boot CPU entry point; entered from trampoline.S
@@ -222,6 +224,8 @@ ENTRY(startup_32_smp)
222 movl %eax,%es 224 movl %eax,%es
223 movl %eax,%fs 225 movl %eax,%fs
224 movl %eax,%gs 226 movl %eax,%gs
227#endif /* CONFIG_SMP */
2283:
225 229
226/* 230/*
227 * New page tables may be in 4Mbyte page mode and may 231 * New page tables may be in 4Mbyte page mode and may
@@ -268,12 +272,6 @@ ENTRY(startup_32_smp)
268 wrmsr 272 wrmsr
269 273
2706: 2746:
271 /* This is a secondary processor (AP) */
272 xorl %ebx,%ebx
273 incl %ebx
274
275#endif /* CONFIG_SMP */
2763:
277 275
278/* 276/*
279 * Enable paging 277 * Enable paging
@@ -297,7 +295,7 @@ ENTRY(startup_32_smp)
297 popfl 295 popfl
298 296
299#ifdef CONFIG_SMP 297#ifdef CONFIG_SMP
300 andl %ebx,%ebx 298 cmpb $0, ready
301 jz 1f /* Initial CPU cleans BSS */ 299 jz 1f /* Initial CPU cleans BSS */
302 jmp checkCPUtype 300 jmp checkCPUtype
3031: 3011:
@@ -502,6 +500,7 @@ early_fault:
502 call printk 500 call printk
503#endif 501#endif
504#endif 502#endif
503 call dump_stack
505hlt_loop: 504hlt_loop:
506 hlt 505 hlt
507 jmp hlt_loop 506 jmp hlt_loop
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
index b6167fe3330e..1d5a7a361200 100644
--- a/arch/x86/kernel/head_64.S
+++ b/arch/x86/kernel/head_64.S
@@ -19,6 +19,13 @@
19#include <asm/msr.h> 19#include <asm/msr.h>
20#include <asm/cache.h> 20#include <asm/cache.h>
21 21
22#ifdef CONFIG_PARAVIRT
23#include <asm/asm-offsets.h>
24#include <asm/paravirt.h>
25#else
26#define GET_CR2_INTO_RCX movq %cr2, %rcx
27#endif
28
22/* we are not able to switch in one step to the final KERNEL ADRESS SPACE 29/* we are not able to switch in one step to the final KERNEL ADRESS SPACE
23 * because we need identity-mapped pages. 30 * because we need identity-mapped pages.
24 * 31 *
@@ -260,14 +267,43 @@ init_rsp:
260bad_address: 267bad_address:
261 jmp bad_address 268 jmp bad_address
262 269
270#ifdef CONFIG_EARLY_PRINTK
271.macro early_idt_tramp first, last
272 .ifgt \last-\first
273 early_idt_tramp \first, \last-1
274 .endif
275 movl $\last,%esi
276 jmp early_idt_handler
277.endm
278
279 .globl early_idt_handlers
280early_idt_handlers:
281 early_idt_tramp 0, 63
282 early_idt_tramp 64, 127
283 early_idt_tramp 128, 191
284 early_idt_tramp 192, 255
285#endif
286
263ENTRY(early_idt_handler) 287ENTRY(early_idt_handler)
288#ifdef CONFIG_EARLY_PRINTK
264 cmpl $2,early_recursion_flag(%rip) 289 cmpl $2,early_recursion_flag(%rip)
265 jz 1f 290 jz 1f
266 incl early_recursion_flag(%rip) 291 incl early_recursion_flag(%rip)
292 GET_CR2_INTO_RCX
293 movq %rcx,%r9
294 xorl %r8d,%r8d # zero for error code
295 movl %esi,%ecx # get vector number
296 # Test %ecx against mask of vectors that push error code.
297 cmpl $31,%ecx
298 ja 0f
299 movl $1,%eax
300 salq %cl,%rax
301 testl $0x27d00,%eax
302 je 0f
303 popq %r8 # get error code
3040: movq 0(%rsp),%rcx # get ip
305 movq 8(%rsp),%rdx # get cs
267 xorl %eax,%eax 306 xorl %eax,%eax
268 movq 8(%rsp),%rsi # get rip
269 movq (%rsp),%rdx
270 movq %cr2,%rcx
271 leaq early_idt_msg(%rip),%rdi 307 leaq early_idt_msg(%rip),%rdi
272 call early_printk 308 call early_printk
273 cmpl $2,early_recursion_flag(%rip) 309 cmpl $2,early_recursion_flag(%rip)
@@ -278,15 +314,19 @@ ENTRY(early_idt_handler)
278 movq 8(%rsp),%rsi # get rip again 314 movq 8(%rsp),%rsi # get rip again
279 call __print_symbol 315 call __print_symbol
280#endif 316#endif
317#endif /* EARLY_PRINTK */
2811: hlt 3181: hlt
282 jmp 1b 319 jmp 1b
320
321#ifdef CONFIG_EARLY_PRINTK
283early_recursion_flag: 322early_recursion_flag:
284 .long 0 323 .long 0
285 324
286early_idt_msg: 325early_idt_msg:
287 .asciz "PANIC: early exception rip %lx error %lx cr2 %lx\n" 326 .asciz "PANIC: early exception %02lx rip %lx:%lx error %lx cr2 %lx\n"
288early_idt_ripmsg: 327early_idt_ripmsg:
289 .asciz "RIP %s\n" 328 .asciz "RIP %s\n"
329#endif /* CONFIG_EARLY_PRINTK */
290 330
291.balign PAGE_SIZE 331.balign PAGE_SIZE
292 332
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index 2f99ee206b95..429d084e014d 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -6,7 +6,6 @@
6#include <linux/init.h> 6#include <linux/init.h>
7#include <linux/sysdev.h> 7#include <linux/sysdev.h>
8#include <linux/pm.h> 8#include <linux/pm.h>
9#include <linux/delay.h>
10 9
11#include <asm/fixmap.h> 10#include <asm/fixmap.h>
12#include <asm/hpet.h> 11#include <asm/hpet.h>
@@ -16,7 +15,8 @@
16#define HPET_MASK CLOCKSOURCE_MASK(32) 15#define HPET_MASK CLOCKSOURCE_MASK(32)
17#define HPET_SHIFT 22 16#define HPET_SHIFT 22
18 17
19/* FSEC = 10^-15 NSEC = 10^-9 */ 18/* FSEC = 10^-15
19 NSEC = 10^-9 */
20#define FSEC_PER_NSEC 1000000 20#define FSEC_PER_NSEC 1000000
21 21
22/* 22/*
@@ -107,6 +107,7 @@ int is_hpet_enabled(void)
107{ 107{
108 return is_hpet_capable() && hpet_legacy_int_enabled; 108 return is_hpet_capable() && hpet_legacy_int_enabled;
109} 109}
110EXPORT_SYMBOL_GPL(is_hpet_enabled);
110 111
111/* 112/*
112 * When the hpet driver (/dev/hpet) is enabled, we need to reserve 113 * When the hpet driver (/dev/hpet) is enabled, we need to reserve
@@ -132,16 +133,13 @@ static void hpet_reserve_platform_timers(unsigned long id)
132#ifdef CONFIG_HPET_EMULATE_RTC 133#ifdef CONFIG_HPET_EMULATE_RTC
133 hpet_reserve_timer(&hd, 1); 134 hpet_reserve_timer(&hd, 1);
134#endif 135#endif
135
136 hd.hd_irq[0] = HPET_LEGACY_8254; 136 hd.hd_irq[0] = HPET_LEGACY_8254;
137 hd.hd_irq[1] = HPET_LEGACY_RTC; 137 hd.hd_irq[1] = HPET_LEGACY_RTC;
138 138
139 for (i = 2; i < nrtimers; timer++, i++) 139 for (i = 2; i < nrtimers; timer++, i++)
140 hd.hd_irq[i] = (timer->hpet_config & Tn_INT_ROUTE_CNF_MASK) >> 140 hd.hd_irq[i] = (timer->hpet_config & Tn_INT_ROUTE_CNF_MASK) >>
141 Tn_INT_ROUTE_CNF_SHIFT; 141 Tn_INT_ROUTE_CNF_SHIFT;
142
143 hpet_alloc(&hd); 142 hpet_alloc(&hd);
144
145} 143}
146#else 144#else
147static void hpet_reserve_platform_timers(unsigned long id) { } 145static void hpet_reserve_platform_timers(unsigned long id) { }
@@ -478,6 +476,7 @@ void hpet_disable(void)
478 */ 476 */
479#include <linux/mc146818rtc.h> 477#include <linux/mc146818rtc.h>
480#include <linux/rtc.h> 478#include <linux/rtc.h>
479#include <asm/rtc.h>
481 480
482#define DEFAULT_RTC_INT_FREQ 64 481#define DEFAULT_RTC_INT_FREQ 64
483#define DEFAULT_RTC_SHIFT 6 482#define DEFAULT_RTC_SHIFT 6
@@ -492,6 +491,38 @@ static unsigned long hpet_default_delta;
492static unsigned long hpet_pie_delta; 491static unsigned long hpet_pie_delta;
493static unsigned long hpet_pie_limit; 492static unsigned long hpet_pie_limit;
494 493
494static rtc_irq_handler irq_handler;
495
496/*
497 * Registers a IRQ handler.
498 */
499int hpet_register_irq_handler(rtc_irq_handler handler)
500{
501 if (!is_hpet_enabled())
502 return -ENODEV;
503 if (irq_handler)
504 return -EBUSY;
505
506 irq_handler = handler;
507
508 return 0;
509}
510EXPORT_SYMBOL_GPL(hpet_register_irq_handler);
511
512/*
513 * Deregisters the IRQ handler registered with hpet_register_irq_handler()
514 * and does cleanup.
515 */
516void hpet_unregister_irq_handler(rtc_irq_handler handler)
517{
518 if (!is_hpet_enabled())
519 return;
520
521 irq_handler = NULL;
522 hpet_rtc_flags = 0;
523}
524EXPORT_SYMBOL_GPL(hpet_unregister_irq_handler);
525
495/* 526/*
496 * Timer 1 for RTC emulation. We use one shot mode, as periodic mode 527 * Timer 1 for RTC emulation. We use one shot mode, as periodic mode
497 * is not supported by all HPET implementations for timer 1. 528 * is not supported by all HPET implementations for timer 1.
@@ -533,6 +564,7 @@ int hpet_rtc_timer_init(void)
533 564
534 return 1; 565 return 1;
535} 566}
567EXPORT_SYMBOL_GPL(hpet_rtc_timer_init);
536 568
537/* 569/*
538 * The functions below are called from rtc driver. 570 * The functions below are called from rtc driver.
@@ -547,6 +579,7 @@ int hpet_mask_rtc_irq_bit(unsigned long bit_mask)
547 hpet_rtc_flags &= ~bit_mask; 579 hpet_rtc_flags &= ~bit_mask;
548 return 1; 580 return 1;
549} 581}
582EXPORT_SYMBOL_GPL(hpet_mask_rtc_irq_bit);
550 583
551int hpet_set_rtc_irq_bit(unsigned long bit_mask) 584int hpet_set_rtc_irq_bit(unsigned long bit_mask)
552{ 585{
@@ -562,6 +595,7 @@ int hpet_set_rtc_irq_bit(unsigned long bit_mask)
562 595
563 return 1; 596 return 1;
564} 597}
598EXPORT_SYMBOL_GPL(hpet_set_rtc_irq_bit);
565 599
566int hpet_set_alarm_time(unsigned char hrs, unsigned char min, 600int hpet_set_alarm_time(unsigned char hrs, unsigned char min,
567 unsigned char sec) 601 unsigned char sec)
@@ -575,6 +609,7 @@ int hpet_set_alarm_time(unsigned char hrs, unsigned char min,
575 609
576 return 1; 610 return 1;
577} 611}
612EXPORT_SYMBOL_GPL(hpet_set_alarm_time);
578 613
579int hpet_set_periodic_freq(unsigned long freq) 614int hpet_set_periodic_freq(unsigned long freq)
580{ 615{
@@ -593,11 +628,13 @@ int hpet_set_periodic_freq(unsigned long freq)
593 } 628 }
594 return 1; 629 return 1;
595} 630}
631EXPORT_SYMBOL_GPL(hpet_set_periodic_freq);
596 632
597int hpet_rtc_dropped_irq(void) 633int hpet_rtc_dropped_irq(void)
598{ 634{
599 return is_hpet_enabled(); 635 return is_hpet_enabled();
600} 636}
637EXPORT_SYMBOL_GPL(hpet_rtc_dropped_irq);
601 638
602static void hpet_rtc_timer_reinit(void) 639static void hpet_rtc_timer_reinit(void)
603{ 640{
@@ -641,9 +678,10 @@ irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id)
641 unsigned long rtc_int_flag = 0; 678 unsigned long rtc_int_flag = 0;
642 679
643 hpet_rtc_timer_reinit(); 680 hpet_rtc_timer_reinit();
681 memset(&curr_time, 0, sizeof(struct rtc_time));
644 682
645 if (hpet_rtc_flags & (RTC_UIE | RTC_AIE)) 683 if (hpet_rtc_flags & (RTC_UIE | RTC_AIE))
646 rtc_get_rtc_time(&curr_time); 684 get_rtc_time(&curr_time);
647 685
648 if (hpet_rtc_flags & RTC_UIE && 686 if (hpet_rtc_flags & RTC_UIE &&
649 curr_time.tm_sec != hpet_prev_update_sec) { 687 curr_time.tm_sec != hpet_prev_update_sec) {
@@ -665,8 +703,10 @@ irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id)
665 703
666 if (rtc_int_flag) { 704 if (rtc_int_flag) {
667 rtc_int_flag |= (RTC_IRQF | (RTC_NUM_INTS << 8)); 705 rtc_int_flag |= (RTC_IRQF | (RTC_NUM_INTS << 8));
668 rtc_interrupt(rtc_int_flag, dev_id); 706 if (irq_handler)
707 irq_handler(rtc_int_flag, dev_id);
669 } 708 }
670 return IRQ_HANDLED; 709 return IRQ_HANDLED;
671} 710}
711EXPORT_SYMBOL_GPL(hpet_rtc_interrupt);
672#endif 712#endif
diff --git a/arch/x86/kernel/i386_ksyms_32.c b/arch/x86/kernel/i386_ksyms_32.c
index 02112fcc0de7..061627806a2d 100644
--- a/arch/x86/kernel/i386_ksyms_32.c
+++ b/arch/x86/kernel/i386_ksyms_32.c
@@ -22,12 +22,5 @@ EXPORT_SYMBOL(__put_user_8);
22 22
23EXPORT_SYMBOL(strstr); 23EXPORT_SYMBOL(strstr);
24 24
25#ifdef CONFIG_SMP
26extern void FASTCALL( __write_lock_failed(rwlock_t *rw));
27extern void FASTCALL( __read_lock_failed(rwlock_t *rw));
28EXPORT_SYMBOL(__write_lock_failed);
29EXPORT_SYMBOL(__read_lock_failed);
30#endif
31
32EXPORT_SYMBOL(csum_partial); 25EXPORT_SYMBOL(csum_partial);
33EXPORT_SYMBOL(empty_zero_page); 26EXPORT_SYMBOL(empty_zero_page);
diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c
new file mode 100644
index 000000000000..26719bd2c77c
--- /dev/null
+++ b/arch/x86/kernel/i387.c
@@ -0,0 +1,479 @@
1/*
2 * Copyright (C) 1994 Linus Torvalds
3 *
4 * Pentium III FXSR, SSE support
5 * General FPU state handling cleanups
6 * Gareth Hughes <gareth@valinux.com>, May 2000
7 */
8
9#include <linux/sched.h>
10#include <linux/module.h>
11#include <linux/regset.h>
12#include <asm/processor.h>
13#include <asm/i387.h>
14#include <asm/math_emu.h>
15#include <asm/sigcontext.h>
16#include <asm/user.h>
17#include <asm/ptrace.h>
18#include <asm/uaccess.h>
19
20#ifdef CONFIG_X86_64
21
22#include <asm/sigcontext32.h>
23#include <asm/user32.h>
24
25#else
26
27#define save_i387_ia32 save_i387
28#define restore_i387_ia32 restore_i387
29
30#define _fpstate_ia32 _fpstate
31#define user_i387_ia32_struct user_i387_struct
32#define user32_fxsr_struct user_fxsr_struct
33
34#endif
35
36#ifdef CONFIG_MATH_EMULATION
37#define HAVE_HWFP (boot_cpu_data.hard_math)
38#else
39#define HAVE_HWFP 1
40#endif
41
42unsigned int mxcsr_feature_mask __read_mostly = 0xffffffffu;
43
44void mxcsr_feature_mask_init(void)
45{
46 unsigned long mask = 0;
47 clts();
48 if (cpu_has_fxsr) {
49 memset(&current->thread.i387.fxsave, 0,
50 sizeof(struct i387_fxsave_struct));
51 asm volatile("fxsave %0" : : "m" (current->thread.i387.fxsave));
52 mask = current->thread.i387.fxsave.mxcsr_mask;
53 if (mask == 0)
54 mask = 0x0000ffbf;
55 }
56 mxcsr_feature_mask &= mask;
57 stts();
58}
59
60#ifdef CONFIG_X86_64
61/*
62 * Called at bootup to set up the initial FPU state that is later cloned
63 * into all processes.
64 */
65void __cpuinit fpu_init(void)
66{
67 unsigned long oldcr0 = read_cr0();
68 extern void __bad_fxsave_alignment(void);
69
70 if (offsetof(struct task_struct, thread.i387.fxsave) & 15)
71 __bad_fxsave_alignment();
72 set_in_cr4(X86_CR4_OSFXSR);
73 set_in_cr4(X86_CR4_OSXMMEXCPT);
74
75 write_cr0(oldcr0 & ~((1UL<<3)|(1UL<<2))); /* clear TS and EM */
76
77 mxcsr_feature_mask_init();
78 /* clean state in init */
79 current_thread_info()->status = 0;
80 clear_used_math();
81}
82#endif /* CONFIG_X86_64 */
83
84/*
85 * The _current_ task is using the FPU for the first time
86 * so initialize it and set the mxcsr to its default
87 * value at reset if we support XMM instructions and then
88 * remeber the current task has used the FPU.
89 */
90void init_fpu(struct task_struct *tsk)
91{
92 if (tsk_used_math(tsk)) {
93 if (tsk == current)
94 unlazy_fpu(tsk);
95 return;
96 }
97
98 if (cpu_has_fxsr) {
99 memset(&tsk->thread.i387.fxsave, 0,
100 sizeof(struct i387_fxsave_struct));
101 tsk->thread.i387.fxsave.cwd = 0x37f;
102 if (cpu_has_xmm)
103 tsk->thread.i387.fxsave.mxcsr = MXCSR_DEFAULT;
104 } else {
105 memset(&tsk->thread.i387.fsave, 0,
106 sizeof(struct i387_fsave_struct));
107 tsk->thread.i387.fsave.cwd = 0xffff037fu;
108 tsk->thread.i387.fsave.swd = 0xffff0000u;
109 tsk->thread.i387.fsave.twd = 0xffffffffu;
110 tsk->thread.i387.fsave.fos = 0xffff0000u;
111 }
112 /*
113 * Only the device not available exception or ptrace can call init_fpu.
114 */
115 set_stopped_child_used_math(tsk);
116}
117
118int fpregs_active(struct task_struct *target, const struct user_regset *regset)
119{
120 return tsk_used_math(target) ? regset->n : 0;
121}
122
123int xfpregs_active(struct task_struct *target, const struct user_regset *regset)
124{
125 return (cpu_has_fxsr && tsk_used_math(target)) ? regset->n : 0;
126}
127
128int xfpregs_get(struct task_struct *target, const struct user_regset *regset,
129 unsigned int pos, unsigned int count,
130 void *kbuf, void __user *ubuf)
131{
132 if (!cpu_has_fxsr)
133 return -ENODEV;
134
135 unlazy_fpu(target);
136
137 return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
138 &target->thread.i387.fxsave, 0, -1);
139}
140
141int xfpregs_set(struct task_struct *target, const struct user_regset *regset,
142 unsigned int pos, unsigned int count,
143 const void *kbuf, const void __user *ubuf)
144{
145 int ret;
146
147 if (!cpu_has_fxsr)
148 return -ENODEV;
149
150 unlazy_fpu(target);
151 set_stopped_child_used_math(target);
152
153 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
154 &target->thread.i387.fxsave, 0, -1);
155
156 /*
157 * mxcsr reserved bits must be masked to zero for security reasons.
158 */
159 target->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask;
160
161 return ret;
162}
163
164#if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION
165
166/*
167 * FPU tag word conversions.
168 */
169
170static inline unsigned short twd_i387_to_fxsr(unsigned short twd)
171{
172 unsigned int tmp; /* to avoid 16 bit prefixes in the code */
173
174 /* Transform each pair of bits into 01 (valid) or 00 (empty) */
175 tmp = ~twd;
176 tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
177 /* and move the valid bits to the lower byte. */
178 tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
179 tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
180 tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
181 return tmp;
182}
183
184#define FPREG_ADDR(f, n) ((void *)&(f)->st_space + (n) * 16);
185#define FP_EXP_TAG_VALID 0
186#define FP_EXP_TAG_ZERO 1
187#define FP_EXP_TAG_SPECIAL 2
188#define FP_EXP_TAG_EMPTY 3
189
190static inline u32 twd_fxsr_to_i387(struct i387_fxsave_struct *fxsave)
191{
192 struct _fpxreg *st;
193 u32 tos = (fxsave->swd >> 11) & 7;
194 u32 twd = (unsigned long) fxsave->twd;
195 u32 tag;
196 u32 ret = 0xffff0000u;
197 int i;
198
199 for (i = 0; i < 8; i++, twd >>= 1) {
200 if (twd & 0x1) {
201 st = FPREG_ADDR(fxsave, (i - tos) & 7);
202
203 switch (st->exponent & 0x7fff) {
204 case 0x7fff:
205 tag = FP_EXP_TAG_SPECIAL;
206 break;
207 case 0x0000:
208 if (!st->significand[0] &&
209 !st->significand[1] &&
210 !st->significand[2] &&
211 !st->significand[3])
212 tag = FP_EXP_TAG_ZERO;
213 else
214 tag = FP_EXP_TAG_SPECIAL;
215 break;
216 default:
217 if (st->significand[3] & 0x8000)
218 tag = FP_EXP_TAG_VALID;
219 else
220 tag = FP_EXP_TAG_SPECIAL;
221 break;
222 }
223 } else {
224 tag = FP_EXP_TAG_EMPTY;
225 }
226 ret |= tag << (2 * i);
227 }
228 return ret;
229}
230
231/*
232 * FXSR floating point environment conversions.
233 */
234
235static void convert_from_fxsr(struct user_i387_ia32_struct *env,
236 struct task_struct *tsk)
237{
238 struct i387_fxsave_struct *fxsave = &tsk->thread.i387.fxsave;
239 struct _fpreg *to = (struct _fpreg *) &env->st_space[0];
240 struct _fpxreg *from = (struct _fpxreg *) &fxsave->st_space[0];
241 int i;
242
243 env->cwd = fxsave->cwd | 0xffff0000u;
244 env->swd = fxsave->swd | 0xffff0000u;
245 env->twd = twd_fxsr_to_i387(fxsave);
246
247#ifdef CONFIG_X86_64
248 env->fip = fxsave->rip;
249 env->foo = fxsave->rdp;
250 if (tsk == current) {
251 /*
252 * should be actually ds/cs at fpu exception time, but
253 * that information is not available in 64bit mode.
254 */
255 asm("mov %%ds,%0" : "=r" (env->fos));
256 asm("mov %%cs,%0" : "=r" (env->fcs));
257 } else {
258 struct pt_regs *regs = task_pt_regs(tsk);
259 env->fos = 0xffff0000 | tsk->thread.ds;
260 env->fcs = regs->cs;
261 }
262#else
263 env->fip = fxsave->fip;
264 env->fcs = fxsave->fcs;
265 env->foo = fxsave->foo;
266 env->fos = fxsave->fos;
267#endif
268
269 for (i = 0; i < 8; ++i)
270 memcpy(&to[i], &from[i], sizeof(to[0]));
271}
272
273static void convert_to_fxsr(struct task_struct *tsk,
274 const struct user_i387_ia32_struct *env)
275
276{
277 struct i387_fxsave_struct *fxsave = &tsk->thread.i387.fxsave;
278 struct _fpreg *from = (struct _fpreg *) &env->st_space[0];
279 struct _fpxreg *to = (struct _fpxreg *) &fxsave->st_space[0];
280 int i;
281
282 fxsave->cwd = env->cwd;
283 fxsave->swd = env->swd;
284 fxsave->twd = twd_i387_to_fxsr(env->twd);
285 fxsave->fop = (u16) ((u32) env->fcs >> 16);
286#ifdef CONFIG_X86_64
287 fxsave->rip = env->fip;
288 fxsave->rdp = env->foo;
289 /* cs and ds ignored */
290#else
291 fxsave->fip = env->fip;
292 fxsave->fcs = (env->fcs & 0xffff);
293 fxsave->foo = env->foo;
294 fxsave->fos = env->fos;
295#endif
296
297 for (i = 0; i < 8; ++i)
298 memcpy(&to[i], &from[i], sizeof(from[0]));
299}
300
301int fpregs_get(struct task_struct *target, const struct user_regset *regset,
302 unsigned int pos, unsigned int count,
303 void *kbuf, void __user *ubuf)
304{
305 struct user_i387_ia32_struct env;
306
307 if (!HAVE_HWFP)
308 return fpregs_soft_get(target, regset, pos, count, kbuf, ubuf);
309
310 unlazy_fpu(target);
311
312 if (!cpu_has_fxsr)
313 return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
314 &target->thread.i387.fsave, 0, -1);
315
316 if (kbuf && pos == 0 && count == sizeof(env)) {
317 convert_from_fxsr(kbuf, target);
318 return 0;
319 }
320
321 convert_from_fxsr(&env, target);
322 return user_regset_copyout(&pos, &count, &kbuf, &ubuf, &env, 0, -1);
323}
324
325int fpregs_set(struct task_struct *target, const struct user_regset *regset,
326 unsigned int pos, unsigned int count,
327 const void *kbuf, const void __user *ubuf)
328{
329 struct user_i387_ia32_struct env;
330 int ret;
331
332 if (!HAVE_HWFP)
333 return fpregs_soft_set(target, regset, pos, count, kbuf, ubuf);
334
335 unlazy_fpu(target);
336 set_stopped_child_used_math(target);
337
338 if (!cpu_has_fxsr)
339 return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
340 &target->thread.i387.fsave, 0, -1);
341
342 if (pos > 0 || count < sizeof(env))
343 convert_from_fxsr(&env, target);
344
345 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &env, 0, -1);
346 if (!ret)
347 convert_to_fxsr(target, &env);
348
349 return ret;
350}
351
352/*
353 * Signal frame handlers.
354 */
355
356static inline int save_i387_fsave(struct _fpstate_ia32 __user *buf)
357{
358 struct task_struct *tsk = current;
359
360 unlazy_fpu(tsk);
361 tsk->thread.i387.fsave.status = tsk->thread.i387.fsave.swd;
362 if (__copy_to_user(buf, &tsk->thread.i387.fsave,
363 sizeof(struct i387_fsave_struct)))
364 return -1;
365 return 1;
366}
367
368static int save_i387_fxsave(struct _fpstate_ia32 __user *buf)
369{
370 struct task_struct *tsk = current;
371 struct user_i387_ia32_struct env;
372 int err = 0;
373
374 unlazy_fpu(tsk);
375
376 convert_from_fxsr(&env, tsk);
377 if (__copy_to_user(buf, &env, sizeof(env)))
378 return -1;
379
380 err |= __put_user(tsk->thread.i387.fxsave.swd, &buf->status);
381 err |= __put_user(X86_FXSR_MAGIC, &buf->magic);
382 if (err)
383 return -1;
384
385 if (__copy_to_user(&buf->_fxsr_env[0], &tsk->thread.i387.fxsave,
386 sizeof(struct i387_fxsave_struct)))
387 return -1;
388 return 1;
389}
390
391int save_i387_ia32(struct _fpstate_ia32 __user *buf)
392{
393 if (!used_math())
394 return 0;
395
396 /* This will cause a "finit" to be triggered by the next
397 * attempted FPU operation by the 'current' process.
398 */
399 clear_used_math();
400
401 if (HAVE_HWFP) {
402 if (cpu_has_fxsr) {
403 return save_i387_fxsave(buf);
404 } else {
405 return save_i387_fsave(buf);
406 }
407 } else {
408 return fpregs_soft_get(current, NULL,
409 0, sizeof(struct user_i387_ia32_struct),
410 NULL, buf) ? -1 : 1;
411 }
412}
413
414static inline int restore_i387_fsave(struct _fpstate_ia32 __user *buf)
415{
416 struct task_struct *tsk = current;
417 clear_fpu(tsk);
418 return __copy_from_user(&tsk->thread.i387.fsave, buf,
419 sizeof(struct i387_fsave_struct));
420}
421
422static int restore_i387_fxsave(struct _fpstate_ia32 __user *buf)
423{
424 int err;
425 struct task_struct *tsk = current;
426 struct user_i387_ia32_struct env;
427 clear_fpu(tsk);
428 err = __copy_from_user(&tsk->thread.i387.fxsave, &buf->_fxsr_env[0],
429 sizeof(struct i387_fxsave_struct));
430 /* mxcsr reserved bits must be masked to zero for security reasons */
431 tsk->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask;
432 if (err || __copy_from_user(&env, buf, sizeof(env)))
433 return 1;
434 convert_to_fxsr(tsk, &env);
435 return 0;
436}
437
438int restore_i387_ia32(struct _fpstate_ia32 __user *buf)
439{
440 int err;
441
442 if (HAVE_HWFP) {
443 if (cpu_has_fxsr) {
444 err = restore_i387_fxsave(buf);
445 } else {
446 err = restore_i387_fsave(buf);
447 }
448 } else {
449 err = fpregs_soft_set(current, NULL,
450 0, sizeof(struct user_i387_ia32_struct),
451 NULL, buf) != 0;
452 }
453 set_used_math();
454 return err;
455}
456
457/*
458 * FPU state for core dumps.
459 * This is only used for a.out dumps now.
460 * It is declared generically using elf_fpregset_t (which is
461 * struct user_i387_struct) but is in fact only used for 32-bit
462 * dumps, so on 64-bit it is really struct user_i387_ia32_struct.
463 */
464int dump_fpu(struct pt_regs *regs, struct user_i387_struct *fpu)
465{
466 int fpvalid;
467 struct task_struct *tsk = current;
468
469 fpvalid = !!used_math();
470 if (fpvalid)
471 fpvalid = !fpregs_get(tsk, NULL,
472 0, sizeof(struct user_i387_ia32_struct),
473 fpu, NULL);
474
475 return fpvalid;
476}
477EXPORT_SYMBOL(dump_fpu);
478
479#endif /* CONFIG_X86_32 || CONFIG_IA32_EMULATION */
diff --git a/arch/x86/kernel/i387_32.c b/arch/x86/kernel/i387_32.c
deleted file mode 100644
index 7d2e12f6c78b..000000000000
--- a/arch/x86/kernel/i387_32.c
+++ /dev/null
@@ -1,544 +0,0 @@
1/*
2 * Copyright (C) 1994 Linus Torvalds
3 *
4 * Pentium III FXSR, SSE support
5 * General FPU state handling cleanups
6 * Gareth Hughes <gareth@valinux.com>, May 2000
7 */
8
9#include <linux/sched.h>
10#include <linux/module.h>
11#include <asm/processor.h>
12#include <asm/i387.h>
13#include <asm/math_emu.h>
14#include <asm/sigcontext.h>
15#include <asm/user.h>
16#include <asm/ptrace.h>
17#include <asm/uaccess.h>
18
19#ifdef CONFIG_MATH_EMULATION
20#define HAVE_HWFP (boot_cpu_data.hard_math)
21#else
22#define HAVE_HWFP 1
23#endif
24
25static unsigned long mxcsr_feature_mask __read_mostly = 0xffffffff;
26
27void mxcsr_feature_mask_init(void)
28{
29 unsigned long mask = 0;
30 clts();
31 if (cpu_has_fxsr) {
32 memset(&current->thread.i387.fxsave, 0, sizeof(struct i387_fxsave_struct));
33 asm volatile("fxsave %0" : : "m" (current->thread.i387.fxsave));
34 mask = current->thread.i387.fxsave.mxcsr_mask;
35 if (mask == 0) mask = 0x0000ffbf;
36 }
37 mxcsr_feature_mask &= mask;
38 stts();
39}
40
41/*
42 * The _current_ task is using the FPU for the first time
43 * so initialize it and set the mxcsr to its default
44 * value at reset if we support XMM instructions and then
45 * remeber the current task has used the FPU.
46 */
47void init_fpu(struct task_struct *tsk)
48{
49 if (cpu_has_fxsr) {
50 memset(&tsk->thread.i387.fxsave, 0, sizeof(struct i387_fxsave_struct));
51 tsk->thread.i387.fxsave.cwd = 0x37f;
52 if (cpu_has_xmm)
53 tsk->thread.i387.fxsave.mxcsr = 0x1f80;
54 } else {
55 memset(&tsk->thread.i387.fsave, 0, sizeof(struct i387_fsave_struct));
56 tsk->thread.i387.fsave.cwd = 0xffff037fu;
57 tsk->thread.i387.fsave.swd = 0xffff0000u;
58 tsk->thread.i387.fsave.twd = 0xffffffffu;
59 tsk->thread.i387.fsave.fos = 0xffff0000u;
60 }
61 /* only the device not available exception or ptrace can call init_fpu */
62 set_stopped_child_used_math(tsk);
63}
64
65/*
66 * FPU lazy state save handling.
67 */
68
69void kernel_fpu_begin(void)
70{
71 struct thread_info *thread = current_thread_info();
72
73 preempt_disable();
74 if (thread->status & TS_USEDFPU) {
75 __save_init_fpu(thread->task);
76 return;
77 }
78 clts();
79}
80EXPORT_SYMBOL_GPL(kernel_fpu_begin);
81
82/*
83 * FPU tag word conversions.
84 */
85
86static inline unsigned short twd_i387_to_fxsr( unsigned short twd )
87{
88 unsigned int tmp; /* to avoid 16 bit prefixes in the code */
89
90 /* Transform each pair of bits into 01 (valid) or 00 (empty) */
91 tmp = ~twd;
92 tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
93 /* and move the valid bits to the lower byte. */
94 tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
95 tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
96 tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
97 return tmp;
98}
99
100static inline unsigned long twd_fxsr_to_i387( struct i387_fxsave_struct *fxsave )
101{
102 struct _fpxreg *st = NULL;
103 unsigned long tos = (fxsave->swd >> 11) & 7;
104 unsigned long twd = (unsigned long) fxsave->twd;
105 unsigned long tag;
106 unsigned long ret = 0xffff0000u;
107 int i;
108
109#define FPREG_ADDR(f, n) ((void *)&(f)->st_space + (n) * 16);
110
111 for ( i = 0 ; i < 8 ; i++ ) {
112 if ( twd & 0x1 ) {
113 st = FPREG_ADDR( fxsave, (i - tos) & 7 );
114
115 switch ( st->exponent & 0x7fff ) {
116 case 0x7fff:
117 tag = 2; /* Special */
118 break;
119 case 0x0000:
120 if ( !st->significand[0] &&
121 !st->significand[1] &&
122 !st->significand[2] &&
123 !st->significand[3] ) {
124 tag = 1; /* Zero */
125 } else {
126 tag = 2; /* Special */
127 }
128 break;
129 default:
130 if ( st->significand[3] & 0x8000 ) {
131 tag = 0; /* Valid */
132 } else {
133 tag = 2; /* Special */
134 }
135 break;
136 }
137 } else {
138 tag = 3; /* Empty */
139 }
140 ret |= (tag << (2 * i));
141 twd = twd >> 1;
142 }
143 return ret;
144}
145
146/*
147 * FPU state interaction.
148 */
149
150unsigned short get_fpu_cwd( struct task_struct *tsk )
151{
152 if ( cpu_has_fxsr ) {
153 return tsk->thread.i387.fxsave.cwd;
154 } else {
155 return (unsigned short)tsk->thread.i387.fsave.cwd;
156 }
157}
158
159unsigned short get_fpu_swd( struct task_struct *tsk )
160{
161 if ( cpu_has_fxsr ) {
162 return tsk->thread.i387.fxsave.swd;
163 } else {
164 return (unsigned short)tsk->thread.i387.fsave.swd;
165 }
166}
167
168#if 0
169unsigned short get_fpu_twd( struct task_struct *tsk )
170{
171 if ( cpu_has_fxsr ) {
172 return tsk->thread.i387.fxsave.twd;
173 } else {
174 return (unsigned short)tsk->thread.i387.fsave.twd;
175 }
176}
177#endif /* 0 */
178
179unsigned short get_fpu_mxcsr( struct task_struct *tsk )
180{
181 if ( cpu_has_xmm ) {
182 return tsk->thread.i387.fxsave.mxcsr;
183 } else {
184 return 0x1f80;
185 }
186}
187
188#if 0
189
190void set_fpu_cwd( struct task_struct *tsk, unsigned short cwd )
191{
192 if ( cpu_has_fxsr ) {
193 tsk->thread.i387.fxsave.cwd = cwd;
194 } else {
195 tsk->thread.i387.fsave.cwd = ((long)cwd | 0xffff0000u);
196 }
197}
198
199void set_fpu_swd( struct task_struct *tsk, unsigned short swd )
200{
201 if ( cpu_has_fxsr ) {
202 tsk->thread.i387.fxsave.swd = swd;
203 } else {
204 tsk->thread.i387.fsave.swd = ((long)swd | 0xffff0000u);
205 }
206}
207
208void set_fpu_twd( struct task_struct *tsk, unsigned short twd )
209{
210 if ( cpu_has_fxsr ) {
211 tsk->thread.i387.fxsave.twd = twd_i387_to_fxsr(twd);
212 } else {
213 tsk->thread.i387.fsave.twd = ((long)twd | 0xffff0000u);
214 }
215}
216
217#endif /* 0 */
218
219/*
220 * FXSR floating point environment conversions.
221 */
222
223static int convert_fxsr_to_user( struct _fpstate __user *buf,
224 struct i387_fxsave_struct *fxsave )
225{
226 unsigned long env[7];
227 struct _fpreg __user *to;
228 struct _fpxreg *from;
229 int i;
230
231 env[0] = (unsigned long)fxsave->cwd | 0xffff0000ul;
232 env[1] = (unsigned long)fxsave->swd | 0xffff0000ul;
233 env[2] = twd_fxsr_to_i387(fxsave);
234 env[3] = fxsave->fip;
235 env[4] = fxsave->fcs | ((unsigned long)fxsave->fop << 16);
236 env[5] = fxsave->foo;
237 env[6] = fxsave->fos;
238
239 if ( __copy_to_user( buf, env, 7 * sizeof(unsigned long) ) )
240 return 1;
241
242 to = &buf->_st[0];
243 from = (struct _fpxreg *) &fxsave->st_space[0];
244 for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
245 unsigned long __user *t = (unsigned long __user *)to;
246 unsigned long *f = (unsigned long *)from;
247
248 if (__put_user(*f, t) ||
249 __put_user(*(f + 1), t + 1) ||
250 __put_user(from->exponent, &to->exponent))
251 return 1;
252 }
253 return 0;
254}
255
256static int convert_fxsr_from_user( struct i387_fxsave_struct *fxsave,
257 struct _fpstate __user *buf )
258{
259 unsigned long env[7];
260 struct _fpxreg *to;
261 struct _fpreg __user *from;
262 int i;
263
264 if ( __copy_from_user( env, buf, 7 * sizeof(long) ) )
265 return 1;
266
267 fxsave->cwd = (unsigned short)(env[0] & 0xffff);
268 fxsave->swd = (unsigned short)(env[1] & 0xffff);
269 fxsave->twd = twd_i387_to_fxsr((unsigned short)(env[2] & 0xffff));
270 fxsave->fip = env[3];
271 fxsave->fop = (unsigned short)((env[4] & 0xffff0000ul) >> 16);
272 fxsave->fcs = (env[4] & 0xffff);
273 fxsave->foo = env[5];
274 fxsave->fos = env[6];
275
276 to = (struct _fpxreg *) &fxsave->st_space[0];
277 from = &buf->_st[0];
278 for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
279 unsigned long *t = (unsigned long *)to;
280 unsigned long __user *f = (unsigned long __user *)from;
281
282 if (__get_user(*t, f) ||
283 __get_user(*(t + 1), f + 1) ||
284 __get_user(to->exponent, &from->exponent))
285 return 1;
286 }
287 return 0;
288}
289
290/*
291 * Signal frame handlers.
292 */
293
294static inline int save_i387_fsave( struct _fpstate __user *buf )
295{
296 struct task_struct *tsk = current;
297
298 unlazy_fpu( tsk );
299 tsk->thread.i387.fsave.status = tsk->thread.i387.fsave.swd;
300 if ( __copy_to_user( buf, &tsk->thread.i387.fsave,
301 sizeof(struct i387_fsave_struct) ) )
302 return -1;
303 return 1;
304}
305
306static int save_i387_fxsave( struct _fpstate __user *buf )
307{
308 struct task_struct *tsk = current;
309 int err = 0;
310
311 unlazy_fpu( tsk );
312
313 if ( convert_fxsr_to_user( buf, &tsk->thread.i387.fxsave ) )
314 return -1;
315
316 err |= __put_user( tsk->thread.i387.fxsave.swd, &buf->status );
317 err |= __put_user( X86_FXSR_MAGIC, &buf->magic );
318 if ( err )
319 return -1;
320
321 if ( __copy_to_user( &buf->_fxsr_env[0], &tsk->thread.i387.fxsave,
322 sizeof(struct i387_fxsave_struct) ) )
323 return -1;
324 return 1;
325}
326
327int save_i387( struct _fpstate __user *buf )
328{
329 if ( !used_math() )
330 return 0;
331
332 /* This will cause a "finit" to be triggered by the next
333 * attempted FPU operation by the 'current' process.
334 */
335 clear_used_math();
336
337 if ( HAVE_HWFP ) {
338 if ( cpu_has_fxsr ) {
339 return save_i387_fxsave( buf );
340 } else {
341 return save_i387_fsave( buf );
342 }
343 } else {
344 return save_i387_soft( &current->thread.i387.soft, buf );
345 }
346}
347
348static inline int restore_i387_fsave( struct _fpstate __user *buf )
349{
350 struct task_struct *tsk = current;
351 clear_fpu( tsk );
352 return __copy_from_user( &tsk->thread.i387.fsave, buf,
353 sizeof(struct i387_fsave_struct) );
354}
355
356static int restore_i387_fxsave( struct _fpstate __user *buf )
357{
358 int err;
359 struct task_struct *tsk = current;
360 clear_fpu( tsk );
361 err = __copy_from_user( &tsk->thread.i387.fxsave, &buf->_fxsr_env[0],
362 sizeof(struct i387_fxsave_struct) );
363 /* mxcsr reserved bits must be masked to zero for security reasons */
364 tsk->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask;
365 return err ? 1 : convert_fxsr_from_user( &tsk->thread.i387.fxsave, buf );
366}
367
368int restore_i387( struct _fpstate __user *buf )
369{
370 int err;
371
372 if ( HAVE_HWFP ) {
373 if ( cpu_has_fxsr ) {
374 err = restore_i387_fxsave( buf );
375 } else {
376 err = restore_i387_fsave( buf );
377 }
378 } else {
379 err = restore_i387_soft( &current->thread.i387.soft, buf );
380 }
381 set_used_math();
382 return err;
383}
384
385/*
386 * ptrace request handlers.
387 */
388
389static inline int get_fpregs_fsave( struct user_i387_struct __user *buf,
390 struct task_struct *tsk )
391{
392 return __copy_to_user( buf, &tsk->thread.i387.fsave,
393 sizeof(struct user_i387_struct) );
394}
395
396static inline int get_fpregs_fxsave( struct user_i387_struct __user *buf,
397 struct task_struct *tsk )
398{
399 return convert_fxsr_to_user( (struct _fpstate __user *)buf,
400 &tsk->thread.i387.fxsave );
401}
402
403int get_fpregs( struct user_i387_struct __user *buf, struct task_struct *tsk )
404{
405 if ( HAVE_HWFP ) {
406 if ( cpu_has_fxsr ) {
407 return get_fpregs_fxsave( buf, tsk );
408 } else {
409 return get_fpregs_fsave( buf, tsk );
410 }
411 } else {
412 return save_i387_soft( &tsk->thread.i387.soft,
413 (struct _fpstate __user *)buf );
414 }
415}
416
417static inline int set_fpregs_fsave( struct task_struct *tsk,
418 struct user_i387_struct __user *buf )
419{
420 return __copy_from_user( &tsk->thread.i387.fsave, buf,
421 sizeof(struct user_i387_struct) );
422}
423
424static inline int set_fpregs_fxsave( struct task_struct *tsk,
425 struct user_i387_struct __user *buf )
426{
427 return convert_fxsr_from_user( &tsk->thread.i387.fxsave,
428 (struct _fpstate __user *)buf );
429}
430
431int set_fpregs( struct task_struct *tsk, struct user_i387_struct __user *buf )
432{
433 if ( HAVE_HWFP ) {
434 if ( cpu_has_fxsr ) {
435 return set_fpregs_fxsave( tsk, buf );
436 } else {
437 return set_fpregs_fsave( tsk, buf );
438 }
439 } else {
440 return restore_i387_soft( &tsk->thread.i387.soft,
441 (struct _fpstate __user *)buf );
442 }
443}
444
445int get_fpxregs( struct user_fxsr_struct __user *buf, struct task_struct *tsk )
446{
447 if ( cpu_has_fxsr ) {
448 if (__copy_to_user( buf, &tsk->thread.i387.fxsave,
449 sizeof(struct user_fxsr_struct) ))
450 return -EFAULT;
451 return 0;
452 } else {
453 return -EIO;
454 }
455}
456
457int set_fpxregs( struct task_struct *tsk, struct user_fxsr_struct __user *buf )
458{
459 int ret = 0;
460
461 if ( cpu_has_fxsr ) {
462 if (__copy_from_user( &tsk->thread.i387.fxsave, buf,
463 sizeof(struct user_fxsr_struct) ))
464 ret = -EFAULT;
465 /* mxcsr reserved bits must be masked to zero for security reasons */
466 tsk->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask;
467 } else {
468 ret = -EIO;
469 }
470 return ret;
471}
472
473/*
474 * FPU state for core dumps.
475 */
476
477static inline void copy_fpu_fsave( struct task_struct *tsk,
478 struct user_i387_struct *fpu )
479{
480 memcpy( fpu, &tsk->thread.i387.fsave,
481 sizeof(struct user_i387_struct) );
482}
483
484static inline void copy_fpu_fxsave( struct task_struct *tsk,
485 struct user_i387_struct *fpu )
486{
487 unsigned short *to;
488 unsigned short *from;
489 int i;
490
491 memcpy( fpu, &tsk->thread.i387.fxsave, 7 * sizeof(long) );
492
493 to = (unsigned short *)&fpu->st_space[0];
494 from = (unsigned short *)&tsk->thread.i387.fxsave.st_space[0];
495 for ( i = 0 ; i < 8 ; i++, to += 5, from += 8 ) {
496 memcpy( to, from, 5 * sizeof(unsigned short) );
497 }
498}
499
500int dump_fpu( struct pt_regs *regs, struct user_i387_struct *fpu )
501{
502 int fpvalid;
503 struct task_struct *tsk = current;
504
505 fpvalid = !!used_math();
506 if ( fpvalid ) {
507 unlazy_fpu( tsk );
508 if ( cpu_has_fxsr ) {
509 copy_fpu_fxsave( tsk, fpu );
510 } else {
511 copy_fpu_fsave( tsk, fpu );
512 }
513 }
514
515 return fpvalid;
516}
517EXPORT_SYMBOL(dump_fpu);
518
519int dump_task_fpu(struct task_struct *tsk, struct user_i387_struct *fpu)
520{
521 int fpvalid = !!tsk_used_math(tsk);
522
523 if (fpvalid) {
524 if (tsk == current)
525 unlazy_fpu(tsk);
526 if (cpu_has_fxsr)
527 copy_fpu_fxsave(tsk, fpu);
528 else
529 copy_fpu_fsave(tsk, fpu);
530 }
531 return fpvalid;
532}
533
534int dump_task_extended_fpu(struct task_struct *tsk, struct user_fxsr_struct *fpu)
535{
536 int fpvalid = tsk_used_math(tsk) && cpu_has_fxsr;
537
538 if (fpvalid) {
539 if (tsk == current)
540 unlazy_fpu(tsk);
541 memcpy(fpu, &tsk->thread.i387.fxsave, sizeof(*fpu));
542 }
543 return fpvalid;
544}
diff --git a/arch/x86/kernel/i387_64.c b/arch/x86/kernel/i387_64.c
deleted file mode 100644
index bfaff28fb134..000000000000
--- a/arch/x86/kernel/i387_64.c
+++ /dev/null
@@ -1,150 +0,0 @@
1/*
2 * Copyright (C) 1994 Linus Torvalds
3 * Copyright (C) 2002 Andi Kleen, SuSE Labs
4 *
5 * Pentium III FXSR, SSE support
6 * General FPU state handling cleanups
7 * Gareth Hughes <gareth@valinux.com>, May 2000
8 *
9 * x86-64 rework 2002 Andi Kleen.
10 * Does direct fxsave in and out of user space now for signal handlers.
11 * All the FSAVE<->FXSAVE conversion code has been moved to the 32bit emulation,
12 * the 64bit user space sees a FXSAVE frame directly.
13 */
14
15#include <linux/sched.h>
16#include <linux/init.h>
17#include <asm/processor.h>
18#include <asm/i387.h>
19#include <asm/sigcontext.h>
20#include <asm/user.h>
21#include <asm/ptrace.h>
22#include <asm/uaccess.h>
23
24unsigned int mxcsr_feature_mask __read_mostly = 0xffffffff;
25
26void mxcsr_feature_mask_init(void)
27{
28 unsigned int mask;
29 clts();
30 memset(&current->thread.i387.fxsave, 0, sizeof(struct i387_fxsave_struct));
31 asm volatile("fxsave %0" : : "m" (current->thread.i387.fxsave));
32 mask = current->thread.i387.fxsave.mxcsr_mask;
33 if (mask == 0) mask = 0x0000ffbf;
34 mxcsr_feature_mask &= mask;
35 stts();
36}
37
38/*
39 * Called at bootup to set up the initial FPU state that is later cloned
40 * into all processes.
41 */
42void __cpuinit fpu_init(void)
43{
44 unsigned long oldcr0 = read_cr0();
45 extern void __bad_fxsave_alignment(void);
46
47 if (offsetof(struct task_struct, thread.i387.fxsave) & 15)
48 __bad_fxsave_alignment();
49 set_in_cr4(X86_CR4_OSFXSR);
50 set_in_cr4(X86_CR4_OSXMMEXCPT);
51
52 write_cr0(oldcr0 & ~((1UL<<3)|(1UL<<2))); /* clear TS and EM */
53
54 mxcsr_feature_mask_init();
55 /* clean state in init */
56 current_thread_info()->status = 0;
57 clear_used_math();
58}
59
60void init_fpu(struct task_struct *child)
61{
62 if (tsk_used_math(child)) {
63 if (child == current)
64 unlazy_fpu(child);
65 return;
66 }
67 memset(&child->thread.i387.fxsave, 0, sizeof(struct i387_fxsave_struct));
68 child->thread.i387.fxsave.cwd = 0x37f;
69 child->thread.i387.fxsave.mxcsr = 0x1f80;
70 /* only the device not available exception or ptrace can call init_fpu */
71 set_stopped_child_used_math(child);
72}
73
74/*
75 * Signal frame handlers.
76 */
77
78int save_i387(struct _fpstate __user *buf)
79{
80 struct task_struct *tsk = current;
81 int err = 0;
82
83 BUILD_BUG_ON(sizeof(struct user_i387_struct) !=
84 sizeof(tsk->thread.i387.fxsave));
85
86 if ((unsigned long)buf % 16)
87 printk("save_i387: bad fpstate %p\n",buf);
88
89 if (!used_math())
90 return 0;
91 clear_used_math(); /* trigger finit */
92 if (task_thread_info(tsk)->status & TS_USEDFPU) {
93 err = save_i387_checking((struct i387_fxsave_struct __user *)buf);
94 if (err) return err;
95 task_thread_info(tsk)->status &= ~TS_USEDFPU;
96 stts();
97 } else {
98 if (__copy_to_user(buf, &tsk->thread.i387.fxsave,
99 sizeof(struct i387_fxsave_struct)))
100 return -1;
101 }
102 return 1;
103}
104
105/*
106 * ptrace request handlers.
107 */
108
109int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *tsk)
110{
111 init_fpu(tsk);
112 return __copy_to_user(buf, &tsk->thread.i387.fxsave,
113 sizeof(struct user_i387_struct)) ? -EFAULT : 0;
114}
115
116int set_fpregs(struct task_struct *tsk, struct user_i387_struct __user *buf)
117{
118 if (__copy_from_user(&tsk->thread.i387.fxsave, buf,
119 sizeof(struct user_i387_struct)))
120 return -EFAULT;
121 return 0;
122}
123
124/*
125 * FPU state for core dumps.
126 */
127
128int dump_fpu( struct pt_regs *regs, struct user_i387_struct *fpu )
129{
130 struct task_struct *tsk = current;
131
132 if (!used_math())
133 return 0;
134
135 unlazy_fpu(tsk);
136 memcpy(fpu, &tsk->thread.i387.fxsave, sizeof(struct user_i387_struct));
137 return 1;
138}
139
140int dump_task_fpu(struct task_struct *tsk, struct user_i387_struct *fpu)
141{
142 int fpvalid = !!tsk_used_math(tsk);
143
144 if (fpvalid) {
145 if (tsk == current)
146 unlazy_fpu(tsk);
147 memcpy(fpu, &tsk->thread.i387.fxsave, sizeof(struct user_i387_struct));
148}
149 return fpvalid;
150}
diff --git a/arch/x86/kernel/i8237.c b/arch/x86/kernel/i8237.c
index 29313832df0c..dbd6c1d1b638 100644
--- a/arch/x86/kernel/i8237.c
+++ b/arch/x86/kernel/i8237.c
@@ -51,7 +51,7 @@ static int i8237A_suspend(struct sys_device *dev, pm_message_t state)
51} 51}
52 52
53static struct sysdev_class i8237_sysdev_class = { 53static struct sysdev_class i8237_sysdev_class = {
54 set_kset_name("i8237"), 54 .name = "i8237",
55 .suspend = i8237A_suspend, 55 .suspend = i8237A_suspend,
56 .resume = i8237A_resume, 56 .resume = i8237A_resume,
57}; 57};
diff --git a/arch/x86/kernel/i8253.c b/arch/x86/kernel/i8253.c
index a42c80745325..ef62b07b2b48 100644
--- a/arch/x86/kernel/i8253.c
+++ b/arch/x86/kernel/i8253.c
@@ -13,10 +13,17 @@
13#include <asm/delay.h> 13#include <asm/delay.h>
14#include <asm/i8253.h> 14#include <asm/i8253.h>
15#include <asm/io.h> 15#include <asm/io.h>
16#include <asm/hpet.h>
16 17
17DEFINE_SPINLOCK(i8253_lock); 18DEFINE_SPINLOCK(i8253_lock);
18EXPORT_SYMBOL(i8253_lock); 19EXPORT_SYMBOL(i8253_lock);
19 20
21#ifdef CONFIG_X86_32
22static void pit_disable_clocksource(void);
23#else
24static inline void pit_disable_clocksource(void) { }
25#endif
26
20/* 27/*
21 * HPET replaces the PIT, when enabled. So we need to know, which of 28 * HPET replaces the PIT, when enabled. So we need to know, which of
22 * the two timers is used 29 * the two timers is used
@@ -31,38 +38,38 @@ struct clock_event_device *global_clock_event;
31static void init_pit_timer(enum clock_event_mode mode, 38static void init_pit_timer(enum clock_event_mode mode,
32 struct clock_event_device *evt) 39 struct clock_event_device *evt)
33{ 40{
34 unsigned long flags; 41 spin_lock(&i8253_lock);
35
36 spin_lock_irqsave(&i8253_lock, flags);
37 42
38 switch(mode) { 43 switch(mode) {
39 case CLOCK_EVT_MODE_PERIODIC: 44 case CLOCK_EVT_MODE_PERIODIC:
40 /* binary, mode 2, LSB/MSB, ch 0 */ 45 /* binary, mode 2, LSB/MSB, ch 0 */
41 outb_p(0x34, PIT_MODE); 46 outb_pit(0x34, PIT_MODE);
42 outb_p(LATCH & 0xff , PIT_CH0); /* LSB */ 47 outb_pit(LATCH & 0xff , PIT_CH0); /* LSB */
43 outb(LATCH >> 8 , PIT_CH0); /* MSB */ 48 outb_pit(LATCH >> 8 , PIT_CH0); /* MSB */
44 break; 49 break;
45 50
46 case CLOCK_EVT_MODE_SHUTDOWN: 51 case CLOCK_EVT_MODE_SHUTDOWN:
47 case CLOCK_EVT_MODE_UNUSED: 52 case CLOCK_EVT_MODE_UNUSED:
48 if (evt->mode == CLOCK_EVT_MODE_PERIODIC || 53 if (evt->mode == CLOCK_EVT_MODE_PERIODIC ||
49 evt->mode == CLOCK_EVT_MODE_ONESHOT) { 54 evt->mode == CLOCK_EVT_MODE_ONESHOT) {
50 outb_p(0x30, PIT_MODE); 55 outb_pit(0x30, PIT_MODE);
51 outb_p(0, PIT_CH0); 56 outb_pit(0, PIT_CH0);
52 outb_p(0, PIT_CH0); 57 outb_pit(0, PIT_CH0);
53 } 58 }
59 pit_disable_clocksource();
54 break; 60 break;
55 61
56 case CLOCK_EVT_MODE_ONESHOT: 62 case CLOCK_EVT_MODE_ONESHOT:
57 /* One shot setup */ 63 /* One shot setup */
58 outb_p(0x38, PIT_MODE); 64 pit_disable_clocksource();
65 outb_pit(0x38, PIT_MODE);
59 break; 66 break;
60 67
61 case CLOCK_EVT_MODE_RESUME: 68 case CLOCK_EVT_MODE_RESUME:
62 /* Nothing to do here */ 69 /* Nothing to do here */
63 break; 70 break;
64 } 71 }
65 spin_unlock_irqrestore(&i8253_lock, flags); 72 spin_unlock(&i8253_lock);
66} 73}
67 74
68/* 75/*
@@ -72,12 +79,10 @@ static void init_pit_timer(enum clock_event_mode mode,
72 */ 79 */
73static int pit_next_event(unsigned long delta, struct clock_event_device *evt) 80static int pit_next_event(unsigned long delta, struct clock_event_device *evt)
74{ 81{
75 unsigned long flags; 82 spin_lock(&i8253_lock);
76 83 outb_pit(delta & 0xff , PIT_CH0); /* LSB */
77 spin_lock_irqsave(&i8253_lock, flags); 84 outb_pit(delta >> 8 , PIT_CH0); /* MSB */
78 outb_p(delta & 0xff , PIT_CH0); /* LSB */ 85 spin_unlock(&i8253_lock);
79 outb(delta >> 8 , PIT_CH0); /* MSB */
80 spin_unlock_irqrestore(&i8253_lock, flags);
81 86
82 return 0; 87 return 0;
83} 88}
@@ -148,15 +153,15 @@ static cycle_t pit_read(void)
148 * count), it cannot be newer. 153 * count), it cannot be newer.
149 */ 154 */
150 jifs = jiffies; 155 jifs = jiffies;
151 outb_p(0x00, PIT_MODE); /* latch the count ASAP */ 156 outb_pit(0x00, PIT_MODE); /* latch the count ASAP */
152 count = inb_p(PIT_CH0); /* read the latched count */ 157 count = inb_pit(PIT_CH0); /* read the latched count */
153 count |= inb_p(PIT_CH0) << 8; 158 count |= inb_pit(PIT_CH0) << 8;
154 159
155 /* VIA686a test code... reset the latch if count > max + 1 */ 160 /* VIA686a test code... reset the latch if count > max + 1 */
156 if (count > LATCH) { 161 if (count > LATCH) {
157 outb_p(0x34, PIT_MODE); 162 outb_pit(0x34, PIT_MODE);
158 outb_p(LATCH & 0xff, PIT_CH0); 163 outb_pit(LATCH & 0xff, PIT_CH0);
159 outb(LATCH >> 8, PIT_CH0); 164 outb_pit(LATCH >> 8, PIT_CH0);
160 count = LATCH - 1; 165 count = LATCH - 1;
161 } 166 }
162 167
@@ -195,9 +200,28 @@ static struct clocksource clocksource_pit = {
195 .shift = 20, 200 .shift = 20,
196}; 201};
197 202
203static void pit_disable_clocksource(void)
204{
205 /*
206 * Use mult to check whether it is registered or not
207 */
208 if (clocksource_pit.mult) {
209 clocksource_unregister(&clocksource_pit);
210 clocksource_pit.mult = 0;
211 }
212}
213
198static int __init init_pit_clocksource(void) 214static int __init init_pit_clocksource(void)
199{ 215{
200 if (num_possible_cpus() > 1) /* PIT does not scale! */ 216 /*
217 * Several reasons not to register PIT as a clocksource:
218 *
219 * - On SMP PIT does not scale due to i8253_lock
220 * - when HPET is enabled
221 * - when local APIC timer is active (PIT is switched off)
222 */
223 if (num_possible_cpus() > 1 || is_hpet_enabled() ||
224 pit_clockevent.mode != CLOCK_EVT_MODE_PERIODIC)
201 return 0; 225 return 0;
202 226
203 clocksource_pit.mult = clocksource_hz2mult(CLOCK_TICK_RATE, 20); 227 clocksource_pit.mult = clocksource_hz2mult(CLOCK_TICK_RATE, 20);
diff --git a/arch/x86/kernel/i8259_32.c b/arch/x86/kernel/i8259_32.c
index f634fc715c99..2d25b77102fe 100644
--- a/arch/x86/kernel/i8259_32.c
+++ b/arch/x86/kernel/i8259_32.c
@@ -21,8 +21,6 @@
21#include <asm/arch_hooks.h> 21#include <asm/arch_hooks.h>
22#include <asm/i8259.h> 22#include <asm/i8259.h>
23 23
24#include <io_ports.h>
25
26/* 24/*
27 * This is the 'legacy' 8259A Programmable Interrupt Controller, 25 * This is the 'legacy' 8259A Programmable Interrupt Controller,
28 * present in the majority of PC/AT boxes. 26 * present in the majority of PC/AT boxes.
@@ -258,7 +256,7 @@ static int i8259A_shutdown(struct sys_device *dev)
258} 256}
259 257
260static struct sysdev_class i8259_sysdev_class = { 258static struct sysdev_class i8259_sysdev_class = {
261 set_kset_name("i8259"), 259 .name = "i8259",
262 .suspend = i8259A_suspend, 260 .suspend = i8259A_suspend,
263 .resume = i8259A_resume, 261 .resume = i8259A_resume,
264 .shutdown = i8259A_shutdown, 262 .shutdown = i8259A_shutdown,
@@ -291,20 +289,20 @@ void init_8259A(int auto_eoi)
291 outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-2 */ 289 outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-2 */
292 290
293 /* 291 /*
294 * outb_p - this has to work on a wide range of PC hardware. 292 * outb_pic - this has to work on a wide range of PC hardware.
295 */ 293 */
296 outb_p(0x11, PIC_MASTER_CMD); /* ICW1: select 8259A-1 init */ 294 outb_pic(0x11, PIC_MASTER_CMD); /* ICW1: select 8259A-1 init */
297 outb_p(0x20 + 0, PIC_MASTER_IMR); /* ICW2: 8259A-1 IR0-7 mapped to 0x20-0x27 */ 295 outb_pic(0x20 + 0, PIC_MASTER_IMR); /* ICW2: 8259A-1 IR0-7 mapped to 0x20-0x27 */
298 outb_p(1U << PIC_CASCADE_IR, PIC_MASTER_IMR); /* 8259A-1 (the master) has a slave on IR2 */ 296 outb_pic(1U << PIC_CASCADE_IR, PIC_MASTER_IMR); /* 8259A-1 (the master) has a slave on IR2 */
299 if (auto_eoi) /* master does Auto EOI */ 297 if (auto_eoi) /* master does Auto EOI */
300 outb_p(MASTER_ICW4_DEFAULT | PIC_ICW4_AEOI, PIC_MASTER_IMR); 298 outb_pic(MASTER_ICW4_DEFAULT | PIC_ICW4_AEOI, PIC_MASTER_IMR);
301 else /* master expects normal EOI */ 299 else /* master expects normal EOI */
302 outb_p(MASTER_ICW4_DEFAULT, PIC_MASTER_IMR); 300 outb_pic(MASTER_ICW4_DEFAULT, PIC_MASTER_IMR);
303 301
304 outb_p(0x11, PIC_SLAVE_CMD); /* ICW1: select 8259A-2 init */ 302 outb_pic(0x11, PIC_SLAVE_CMD); /* ICW1: select 8259A-2 init */
305 outb_p(0x20 + 8, PIC_SLAVE_IMR); /* ICW2: 8259A-2 IR0-7 mapped to 0x28-0x2f */ 303 outb_pic(0x20 + 8, PIC_SLAVE_IMR); /* ICW2: 8259A-2 IR0-7 mapped to 0x28-0x2f */
306 outb_p(PIC_CASCADE_IR, PIC_SLAVE_IMR); /* 8259A-2 is a slave on master's IR2 */ 304 outb_pic(PIC_CASCADE_IR, PIC_SLAVE_IMR); /* 8259A-2 is a slave on master's IR2 */
307 outb_p(SLAVE_ICW4_DEFAULT, PIC_SLAVE_IMR); /* (slave's support for AEOI in flat mode is to be investigated) */ 305 outb_pic(SLAVE_ICW4_DEFAULT, PIC_SLAVE_IMR); /* (slave's support for AEOI in flat mode is to be investigated) */
308 if (auto_eoi) 306 if (auto_eoi)
309 /* 307 /*
310 * In AEOI mode we just have to mask the interrupt 308 * In AEOI mode we just have to mask the interrupt
@@ -341,7 +339,7 @@ static irqreturn_t math_error_irq(int cpl, void *dev_id)
341 outb(0,0xF0); 339 outb(0,0xF0);
342 if (ignore_fpu_irq || !boot_cpu_data.hard_math) 340 if (ignore_fpu_irq || !boot_cpu_data.hard_math)
343 return IRQ_NONE; 341 return IRQ_NONE;
344 math_error((void __user *)get_irq_regs()->eip); 342 math_error((void __user *)get_irq_regs()->ip);
345 return IRQ_HANDLED; 343 return IRQ_HANDLED;
346} 344}
347 345
diff --git a/arch/x86/kernel/i8259_64.c b/arch/x86/kernel/i8259_64.c
index 3f27ea0b9816..fa57a1568508 100644
--- a/arch/x86/kernel/i8259_64.c
+++ b/arch/x86/kernel/i8259_64.c
@@ -21,6 +21,7 @@
21#include <asm/delay.h> 21#include <asm/delay.h>
22#include <asm/desc.h> 22#include <asm/desc.h>
23#include <asm/apic.h> 23#include <asm/apic.h>
24#include <asm/i8259.h>
24 25
25/* 26/*
26 * Common place to define all x86 IRQ vectors 27 * Common place to define all x86 IRQ vectors
@@ -48,7 +49,7 @@
48 */ 49 */
49 50
50/* 51/*
51 * The IO-APIC gives us many more interrupt sources. Most of these 52 * The IO-APIC gives us many more interrupt sources. Most of these
52 * are unused but an SMP system is supposed to have enough memory ... 53 * are unused but an SMP system is supposed to have enough memory ...
53 * sometimes (mostly wrt. hw bugs) we get corrupted vectors all 54 * sometimes (mostly wrt. hw bugs) we get corrupted vectors all
54 * across the spectrum, so we really want to be prepared to get all 55 * across the spectrum, so we really want to be prepared to get all
@@ -76,7 +77,7 @@ BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd) BUILD_16_IRQS(0xe) BUILD_16_IRQS(0xf)
76 IRQ(x,c), IRQ(x,d), IRQ(x,e), IRQ(x,f) 77 IRQ(x,c), IRQ(x,d), IRQ(x,e), IRQ(x,f)
77 78
78/* for the irq vectors */ 79/* for the irq vectors */
79static void (*interrupt[NR_VECTORS - FIRST_EXTERNAL_VECTOR])(void) = { 80static void (*__initdata interrupt[NR_VECTORS - FIRST_EXTERNAL_VECTOR])(void) = {
80 IRQLIST_16(0x2), IRQLIST_16(0x3), 81 IRQLIST_16(0x2), IRQLIST_16(0x3),
81 IRQLIST_16(0x4), IRQLIST_16(0x5), IRQLIST_16(0x6), IRQLIST_16(0x7), 82 IRQLIST_16(0x4), IRQLIST_16(0x5), IRQLIST_16(0x6), IRQLIST_16(0x7),
82 IRQLIST_16(0x8), IRQLIST_16(0x9), IRQLIST_16(0xa), IRQLIST_16(0xb), 83 IRQLIST_16(0x8), IRQLIST_16(0x9), IRQLIST_16(0xa), IRQLIST_16(0xb),
@@ -114,11 +115,7 @@ static struct irq_chip i8259A_chip = {
114/* 115/*
115 * This contains the irq mask for both 8259A irq controllers, 116 * This contains the irq mask for both 8259A irq controllers,
116 */ 117 */
117static unsigned int cached_irq_mask = 0xffff; 118unsigned int cached_irq_mask = 0xffff;
118
119#define __byte(x,y) (((unsigned char *)&(y))[x])
120#define cached_21 (__byte(0,cached_irq_mask))
121#define cached_A1 (__byte(1,cached_irq_mask))
122 119
123/* 120/*
124 * Not all IRQs can be routed through the IO-APIC, eg. on certain (older) 121 * Not all IRQs can be routed through the IO-APIC, eg. on certain (older)
@@ -139,9 +136,9 @@ void disable_8259A_irq(unsigned int irq)
139 spin_lock_irqsave(&i8259A_lock, flags); 136 spin_lock_irqsave(&i8259A_lock, flags);
140 cached_irq_mask |= mask; 137 cached_irq_mask |= mask;
141 if (irq & 8) 138 if (irq & 8)
142 outb(cached_A1,0xA1); 139 outb(cached_slave_mask, PIC_SLAVE_IMR);
143 else 140 else
144 outb(cached_21,0x21); 141 outb(cached_master_mask, PIC_MASTER_IMR);
145 spin_unlock_irqrestore(&i8259A_lock, flags); 142 spin_unlock_irqrestore(&i8259A_lock, flags);
146} 143}
147 144
@@ -153,9 +150,9 @@ void enable_8259A_irq(unsigned int irq)
153 spin_lock_irqsave(&i8259A_lock, flags); 150 spin_lock_irqsave(&i8259A_lock, flags);
154 cached_irq_mask &= mask; 151 cached_irq_mask &= mask;
155 if (irq & 8) 152 if (irq & 8)
156 outb(cached_A1,0xA1); 153 outb(cached_slave_mask, PIC_SLAVE_IMR);
157 else 154 else
158 outb(cached_21,0x21); 155 outb(cached_master_mask, PIC_MASTER_IMR);
159 spin_unlock_irqrestore(&i8259A_lock, flags); 156 spin_unlock_irqrestore(&i8259A_lock, flags);
160} 157}
161 158
@@ -167,9 +164,9 @@ int i8259A_irq_pending(unsigned int irq)
167 164
168 spin_lock_irqsave(&i8259A_lock, flags); 165 spin_lock_irqsave(&i8259A_lock, flags);
169 if (irq < 8) 166 if (irq < 8)
170 ret = inb(0x20) & mask; 167 ret = inb(PIC_MASTER_CMD) & mask;
171 else 168 else
172 ret = inb(0xA0) & (mask >> 8); 169 ret = inb(PIC_SLAVE_CMD) & (mask >> 8);
173 spin_unlock_irqrestore(&i8259A_lock, flags); 170 spin_unlock_irqrestore(&i8259A_lock, flags);
174 171
175 return ret; 172 return ret;
@@ -196,14 +193,14 @@ static inline int i8259A_irq_real(unsigned int irq)
196 int irqmask = 1<<irq; 193 int irqmask = 1<<irq;
197 194
198 if (irq < 8) { 195 if (irq < 8) {
199 outb(0x0B,0x20); /* ISR register */ 196 outb(0x0B,PIC_MASTER_CMD); /* ISR register */
200 value = inb(0x20) & irqmask; 197 value = inb(PIC_MASTER_CMD) & irqmask;
201 outb(0x0A,0x20); /* back to the IRR register */ 198 outb(0x0A,PIC_MASTER_CMD); /* back to the IRR register */
202 return value; 199 return value;
203 } 200 }
204 outb(0x0B,0xA0); /* ISR register */ 201 outb(0x0B,PIC_SLAVE_CMD); /* ISR register */
205 value = inb(0xA0) & (irqmask >> 8); 202 value = inb(PIC_SLAVE_CMD) & (irqmask >> 8);
206 outb(0x0A,0xA0); /* back to the IRR register */ 203 outb(0x0A,PIC_SLAVE_CMD); /* back to the IRR register */
207 return value; 204 return value;
208} 205}
209 206
@@ -240,14 +237,17 @@ static void mask_and_ack_8259A(unsigned int irq)
240 237
241handle_real_irq: 238handle_real_irq:
242 if (irq & 8) { 239 if (irq & 8) {
243 inb(0xA1); /* DUMMY - (do we need this?) */ 240 inb(PIC_SLAVE_IMR); /* DUMMY - (do we need this?) */
244 outb(cached_A1,0xA1); 241 outb(cached_slave_mask, PIC_SLAVE_IMR);
245 outb(0x60+(irq&7),0xA0);/* 'Specific EOI' to slave */ 242 /* 'Specific EOI' to slave */
246 outb(0x62,0x20); /* 'Specific EOI' to master-IRQ2 */ 243 outb(0x60+(irq&7),PIC_SLAVE_CMD);
244 /* 'Specific EOI' to master-IRQ2 */
245 outb(0x60+PIC_CASCADE_IR,PIC_MASTER_CMD);
247 } else { 246 } else {
248 inb(0x21); /* DUMMY - (do we need this?) */ 247 inb(PIC_MASTER_IMR); /* DUMMY - (do we need this?) */
249 outb(cached_21,0x21); 248 outb(cached_master_mask, PIC_MASTER_IMR);
250 outb(0x60+irq,0x20); /* 'Specific EOI' to master */ 249 /* 'Specific EOI' to master */
250 outb(0x60+irq,PIC_MASTER_CMD);
251 } 251 }
252 spin_unlock_irqrestore(&i8259A_lock, flags); 252 spin_unlock_irqrestore(&i8259A_lock, flags);
253 return; 253 return;
@@ -270,7 +270,8 @@ spurious_8259A_irq:
270 * lets ACK and report it. [once per IRQ] 270 * lets ACK and report it. [once per IRQ]
271 */ 271 */
272 if (!(spurious_irq_mask & irqmask)) { 272 if (!(spurious_irq_mask & irqmask)) {
273 printk(KERN_DEBUG "spurious 8259A interrupt: IRQ%d.\n", irq); 273 printk(KERN_DEBUG
274 "spurious 8259A interrupt: IRQ%d.\n", irq);
274 spurious_irq_mask |= irqmask; 275 spurious_irq_mask |= irqmask;
275 } 276 }
276 atomic_inc(&irq_err_count); 277 atomic_inc(&irq_err_count);
@@ -283,51 +284,6 @@ spurious_8259A_irq:
283 } 284 }
284} 285}
285 286
286void init_8259A(int auto_eoi)
287{
288 unsigned long flags;
289
290 i8259A_auto_eoi = auto_eoi;
291
292 spin_lock_irqsave(&i8259A_lock, flags);
293
294 outb(0xff, 0x21); /* mask all of 8259A-1 */
295 outb(0xff, 0xA1); /* mask all of 8259A-2 */
296
297 /*
298 * outb_p - this has to work on a wide range of PC hardware.
299 */
300 outb_p(0x11, 0x20); /* ICW1: select 8259A-1 init */
301 outb_p(IRQ0_VECTOR, 0x21); /* ICW2: 8259A-1 IR0-7 mapped to 0x30-0x37 */
302 outb_p(0x04, 0x21); /* 8259A-1 (the master) has a slave on IR2 */
303 if (auto_eoi)
304 outb_p(0x03, 0x21); /* master does Auto EOI */
305 else
306 outb_p(0x01, 0x21); /* master expects normal EOI */
307
308 outb_p(0x11, 0xA0); /* ICW1: select 8259A-2 init */
309 outb_p(IRQ8_VECTOR, 0xA1); /* ICW2: 8259A-2 IR0-7 mapped to 0x38-0x3f */
310 outb_p(0x02, 0xA1); /* 8259A-2 is a slave on master's IR2 */
311 outb_p(0x01, 0xA1); /* (slave's support for AEOI in flat mode
312 is to be investigated) */
313
314 if (auto_eoi)
315 /*
316 * in AEOI mode we just have to mask the interrupt
317 * when acking.
318 */
319 i8259A_chip.mask_ack = disable_8259A_irq;
320 else
321 i8259A_chip.mask_ack = mask_and_ack_8259A;
322
323 udelay(100); /* wait for 8259A to initialize */
324
325 outb(cached_21, 0x21); /* restore master IRQ mask */
326 outb(cached_A1, 0xA1); /* restore slave IRQ mask */
327
328 spin_unlock_irqrestore(&i8259A_lock, flags);
329}
330
331static char irq_trigger[2]; 287static char irq_trigger[2];
332/** 288/**
333 * ELCR registers (0x4d0, 0x4d1) control edge/level of IRQ 289 * ELCR registers (0x4d0, 0x4d1) control edge/level of IRQ
@@ -364,13 +320,13 @@ static int i8259A_shutdown(struct sys_device *dev)
364 * the kernel initialization code can get it 320 * the kernel initialization code can get it
365 * out of. 321 * out of.
366 */ 322 */
367 outb(0xff, 0x21); /* mask all of 8259A-1 */ 323 outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */
368 outb(0xff, 0xA1); /* mask all of 8259A-1 */ 324 outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-1 */
369 return 0; 325 return 0;
370} 326}
371 327
372static struct sysdev_class i8259_sysdev_class = { 328static struct sysdev_class i8259_sysdev_class = {
373 set_kset_name("i8259"), 329 .name = "i8259",
374 .suspend = i8259A_suspend, 330 .suspend = i8259A_suspend,
375 .resume = i8259A_resume, 331 .resume = i8259A_resume,
376 .shutdown = i8259A_shutdown, 332 .shutdown = i8259A_shutdown,
@@ -391,6 +347,58 @@ static int __init i8259A_init_sysfs(void)
391 347
392device_initcall(i8259A_init_sysfs); 348device_initcall(i8259A_init_sysfs);
393 349
350void init_8259A(int auto_eoi)
351{
352 unsigned long flags;
353
354 i8259A_auto_eoi = auto_eoi;
355
356 spin_lock_irqsave(&i8259A_lock, flags);
357
358 outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */
359 outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-2 */
360
361 /*
362 * outb_pic - this has to work on a wide range of PC hardware.
363 */
364 outb_pic(0x11, PIC_MASTER_CMD); /* ICW1: select 8259A-1 init */
365 /* ICW2: 8259A-1 IR0-7 mapped to 0x30-0x37 */
366 outb_pic(IRQ0_VECTOR, PIC_MASTER_IMR);
367 /* 8259A-1 (the master) has a slave on IR2 */
368 outb_pic(0x04, PIC_MASTER_IMR);
369 if (auto_eoi) /* master does Auto EOI */
370 outb_pic(MASTER_ICW4_DEFAULT | PIC_ICW4_AEOI, PIC_MASTER_IMR);
371 else /* master expects normal EOI */
372 outb_pic(MASTER_ICW4_DEFAULT, PIC_MASTER_IMR);
373
374 outb_pic(0x11, PIC_SLAVE_CMD); /* ICW1: select 8259A-2 init */
375 /* ICW2: 8259A-2 IR0-7 mapped to 0x38-0x3f */
376 outb_pic(IRQ8_VECTOR, PIC_SLAVE_IMR);
377 /* 8259A-2 is a slave on master's IR2 */
378 outb_pic(PIC_CASCADE_IR, PIC_SLAVE_IMR);
379 /* (slave's support for AEOI in flat mode is to be investigated) */
380 outb_pic(SLAVE_ICW4_DEFAULT, PIC_SLAVE_IMR);
381
382 if (auto_eoi)
383 /*
384 * In AEOI mode we just have to mask the interrupt
385 * when acking.
386 */
387 i8259A_chip.mask_ack = disable_8259A_irq;
388 else
389 i8259A_chip.mask_ack = mask_and_ack_8259A;
390
391 udelay(100); /* wait for 8259A to initialize */
392
393 outb(cached_master_mask, PIC_MASTER_IMR); /* restore master IRQ mask */
394 outb(cached_slave_mask, PIC_SLAVE_IMR); /* restore slave IRQ mask */
395
396 spin_unlock_irqrestore(&i8259A_lock, flags);
397}
398
399
400
401
394/* 402/*
395 * IRQ2 is cascade interrupt to second interrupt controller 403 * IRQ2 is cascade interrupt to second interrupt controller
396 */ 404 */
@@ -448,7 +456,9 @@ void __init init_ISA_irqs (void)
448 } 456 }
449} 457}
450 458
451void __init init_IRQ(void) 459void init_IRQ(void) __attribute__((weak, alias("native_init_IRQ")));
460
461void __init native_init_IRQ(void)
452{ 462{
453 int i; 463 int i;
454 464
diff --git a/arch/x86/kernel/init_task.c b/arch/x86/kernel/init_task.c
index 468c9c437842..5b3ce7934363 100644
--- a/arch/x86/kernel/init_task.c
+++ b/arch/x86/kernel/init_task.c
@@ -15,7 +15,6 @@ static struct files_struct init_files = INIT_FILES;
15static struct signal_struct init_signals = INIT_SIGNALS(init_signals); 15static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
16static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); 16static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
17struct mm_struct init_mm = INIT_MM(init_mm); 17struct mm_struct init_mm = INIT_MM(init_mm);
18EXPORT_SYMBOL(init_mm);
19 18
20/* 19/*
21 * Initial thread structure. 20 * Initial thread structure.
diff --git a/arch/x86/kernel/io_apic_32.c b/arch/x86/kernel/io_apic_32.c
index a6b1490e00c4..4ca548632c8d 100644
--- a/arch/x86/kernel/io_apic_32.c
+++ b/arch/x86/kernel/io_apic_32.c
@@ -35,6 +35,7 @@
35#include <linux/htirq.h> 35#include <linux/htirq.h>
36#include <linux/freezer.h> 36#include <linux/freezer.h>
37#include <linux/kthread.h> 37#include <linux/kthread.h>
38#include <linux/jiffies.h> /* time_after() */
38 39
39#include <asm/io.h> 40#include <asm/io.h>
40#include <asm/smp.h> 41#include <asm/smp.h>
@@ -48,8 +49,6 @@
48#include <mach_apic.h> 49#include <mach_apic.h>
49#include <mach_apicdef.h> 50#include <mach_apicdef.h>
50 51
51#include "io_ports.h"
52
53int (*ioapic_renumber_irq)(int ioapic, int irq); 52int (*ioapic_renumber_irq)(int ioapic, int irq);
54atomic_t irq_mis_count; 53atomic_t irq_mis_count;
55 54
@@ -351,7 +350,7 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask)
351# include <asm/processor.h> /* kernel_thread() */ 350# include <asm/processor.h> /* kernel_thread() */
352# include <linux/kernel_stat.h> /* kstat */ 351# include <linux/kernel_stat.h> /* kstat */
353# include <linux/slab.h> /* kmalloc() */ 352# include <linux/slab.h> /* kmalloc() */
354# include <linux/timer.h> /* time_after() */ 353# include <linux/timer.h>
355 354
356#define IRQBALANCE_CHECK_ARCH -999 355#define IRQBALANCE_CHECK_ARCH -999
357#define MAX_BALANCED_IRQ_INTERVAL (5*HZ) 356#define MAX_BALANCED_IRQ_INTERVAL (5*HZ)
@@ -727,7 +726,7 @@ late_initcall(balanced_irq_init);
727#endif /* CONFIG_SMP */ 726#endif /* CONFIG_SMP */
728 727
729#ifndef CONFIG_SMP 728#ifndef CONFIG_SMP
730void fastcall send_IPI_self(int vector) 729void send_IPI_self(int vector)
731{ 730{
732 unsigned int cfg; 731 unsigned int cfg;
733 732
@@ -1900,7 +1899,7 @@ static int __init timer_irq_works(void)
1900 * might have cached one ExtINT interrupt. Finally, at 1899 * might have cached one ExtINT interrupt. Finally, at
1901 * least one tick may be lost due to delays. 1900 * least one tick may be lost due to delays.
1902 */ 1901 */
1903 if (jiffies - t1 > 4) 1902 if (time_after(jiffies, t1 + 4))
1904 return 1; 1903 return 1;
1905 1904
1906 return 0; 1905 return 0;
@@ -2080,7 +2079,7 @@ static struct irq_chip lapic_chip __read_mostly = {
2080 .eoi = ack_apic, 2079 .eoi = ack_apic,
2081}; 2080};
2082 2081
2083static void setup_nmi (void) 2082static void __init setup_nmi(void)
2084{ 2083{
2085 /* 2084 /*
2086 * Dirty trick to enable the NMI watchdog ... 2085 * Dirty trick to enable the NMI watchdog ...
@@ -2093,7 +2092,7 @@ static void setup_nmi (void)
2093 */ 2092 */
2094 apic_printk(APIC_VERBOSE, KERN_INFO "activating NMI Watchdog ..."); 2093 apic_printk(APIC_VERBOSE, KERN_INFO "activating NMI Watchdog ...");
2095 2094
2096 on_each_cpu(enable_NMI_through_LVT0, NULL, 1, 1); 2095 enable_NMI_through_LVT0();
2097 2096
2098 apic_printk(APIC_VERBOSE, " done.\n"); 2097 apic_printk(APIC_VERBOSE, " done.\n");
2099} 2098}
@@ -2401,7 +2400,7 @@ static int ioapic_resume(struct sys_device *dev)
2401} 2400}
2402 2401
2403static struct sysdev_class ioapic_sysdev_class = { 2402static struct sysdev_class ioapic_sysdev_class = {
2404 set_kset_name("ioapic"), 2403 .name = "ioapic",
2405 .suspend = ioapic_suspend, 2404 .suspend = ioapic_suspend,
2406 .resume = ioapic_resume, 2405 .resume = ioapic_resume,
2407}; 2406};
diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c
index cbac1670c7c3..1627c0d53e0b 100644
--- a/arch/x86/kernel/io_apic_64.c
+++ b/arch/x86/kernel/io_apic_64.c
@@ -32,9 +32,11 @@
32#include <linux/msi.h> 32#include <linux/msi.h>
33#include <linux/htirq.h> 33#include <linux/htirq.h>
34#include <linux/dmar.h> 34#include <linux/dmar.h>
35#include <linux/jiffies.h>
35#ifdef CONFIG_ACPI 36#ifdef CONFIG_ACPI
36#include <acpi/acpi_bus.h> 37#include <acpi/acpi_bus.h>
37#endif 38#endif
39#include <linux/bootmem.h>
38 40
39#include <asm/idle.h> 41#include <asm/idle.h>
40#include <asm/io.h> 42#include <asm/io.h>
@@ -1069,7 +1071,7 @@ void __apicdebuginit print_local_APIC(void * dummy)
1069 v = apic_read(APIC_LVR); 1071 v = apic_read(APIC_LVR);
1070 printk(KERN_INFO "... APIC VERSION: %08x\n", v); 1072 printk(KERN_INFO "... APIC VERSION: %08x\n", v);
1071 ver = GET_APIC_VERSION(v); 1073 ver = GET_APIC_VERSION(v);
1072 maxlvt = get_maxlvt(); 1074 maxlvt = lapic_get_maxlvt();
1073 1075
1074 v = apic_read(APIC_TASKPRI); 1076 v = apic_read(APIC_TASKPRI);
1075 printk(KERN_DEBUG "... APIC TASKPRI: %08x (%02x)\n", v, v & APIC_TPRI_MASK); 1077 printk(KERN_DEBUG "... APIC TASKPRI: %08x (%02x)\n", v, v & APIC_TPRI_MASK);
@@ -1171,7 +1173,7 @@ void __apicdebuginit print_PIC(void)
1171 1173
1172#endif /* 0 */ 1174#endif /* 0 */
1173 1175
1174static void __init enable_IO_APIC(void) 1176void __init enable_IO_APIC(void)
1175{ 1177{
1176 union IO_APIC_reg_01 reg_01; 1178 union IO_APIC_reg_01 reg_01;
1177 int i8259_apic, i8259_pin; 1179 int i8259_apic, i8259_pin;
@@ -1298,7 +1300,7 @@ static int __init timer_irq_works(void)
1298 */ 1300 */
1299 1301
1300 /* jiffies wrap? */ 1302 /* jiffies wrap? */
1301 if (jiffies - t1 > 4) 1303 if (time_after(jiffies, t1 + 4))
1302 return 1; 1304 return 1;
1303 return 0; 1305 return 0;
1304} 1306}
@@ -1411,7 +1413,7 @@ static void irq_complete_move(unsigned int irq)
1411 if (likely(!cfg->move_in_progress)) 1413 if (likely(!cfg->move_in_progress))
1412 return; 1414 return;
1413 1415
1414 vector = ~get_irq_regs()->orig_rax; 1416 vector = ~get_irq_regs()->orig_ax;
1415 me = smp_processor_id(); 1417 me = smp_processor_id();
1416 if ((vector == cfg->vector) && cpu_isset(me, cfg->domain)) { 1418 if ((vector == cfg->vector) && cpu_isset(me, cfg->domain)) {
1417 cpumask_t cleanup_mask; 1419 cpumask_t cleanup_mask;
@@ -1438,7 +1440,7 @@ static void ack_apic_level(unsigned int irq)
1438 int do_unmask_irq = 0; 1440 int do_unmask_irq = 0;
1439 1441
1440 irq_complete_move(irq); 1442 irq_complete_move(irq);
1441#if defined(CONFIG_GENERIC_PENDING_IRQ) || defined(CONFIG_IRQBALANCE) 1443#ifdef CONFIG_GENERIC_PENDING_IRQ
1442 /* If we are moving the irq we need to mask it */ 1444 /* If we are moving the irq we need to mask it */
1443 if (unlikely(irq_desc[irq].status & IRQ_MOVE_PENDING)) { 1445 if (unlikely(irq_desc[irq].status & IRQ_MOVE_PENDING)) {
1444 do_unmask_irq = 1; 1446 do_unmask_irq = 1;
@@ -1565,7 +1567,7 @@ static struct hw_interrupt_type lapic_irq_type __read_mostly = {
1565 .end = end_lapic_irq, 1567 .end = end_lapic_irq,
1566}; 1568};
1567 1569
1568static void setup_nmi (void) 1570static void __init setup_nmi(void)
1569{ 1571{
1570 /* 1572 /*
1571 * Dirty trick to enable the NMI watchdog ... 1573 * Dirty trick to enable the NMI watchdog ...
@@ -1578,7 +1580,7 @@ static void setup_nmi (void)
1578 */ 1580 */
1579 printk(KERN_INFO "activating NMI Watchdog ..."); 1581 printk(KERN_INFO "activating NMI Watchdog ...");
1580 1582
1581 enable_NMI_through_LVT0(NULL); 1583 enable_NMI_through_LVT0();
1582 1584
1583 printk(" done.\n"); 1585 printk(" done.\n");
1584} 1586}
@@ -1654,7 +1656,7 @@ static inline void unlock_ExtINT_logic(void)
1654 * 1656 *
1655 * FIXME: really need to revamp this for modern platforms only. 1657 * FIXME: really need to revamp this for modern platforms only.
1656 */ 1658 */
1657static inline void check_timer(void) 1659static inline void __init check_timer(void)
1658{ 1660{
1659 struct irq_cfg *cfg = irq_cfg + 0; 1661 struct irq_cfg *cfg = irq_cfg + 0;
1660 int apic1, pin1, apic2, pin2; 1662 int apic1, pin1, apic2, pin2;
@@ -1788,7 +1790,10 @@ __setup("no_timer_check", notimercheck);
1788 1790
1789void __init setup_IO_APIC(void) 1791void __init setup_IO_APIC(void)
1790{ 1792{
1791 enable_IO_APIC(); 1793
1794 /*
1795 * calling enable_IO_APIC() is moved to setup_local_APIC for BP
1796 */
1792 1797
1793 if (acpi_ioapic) 1798 if (acpi_ioapic)
1794 io_apic_irqs = ~0; /* all IRQs go through IOAPIC */ 1799 io_apic_irqs = ~0; /* all IRQs go through IOAPIC */
@@ -1850,7 +1855,7 @@ static int ioapic_resume(struct sys_device *dev)
1850} 1855}
1851 1856
1852static struct sysdev_class ioapic_sysdev_class = { 1857static struct sysdev_class ioapic_sysdev_class = {
1853 set_kset_name("ioapic"), 1858 .name = "ioapic",
1854 .suspend = ioapic_suspend, 1859 .suspend = ioapic_suspend,
1855 .resume = ioapic_resume, 1860 .resume = ioapic_resume,
1856}; 1861};
@@ -2288,3 +2293,92 @@ void __init setup_ioapic_dest(void)
2288} 2293}
2289#endif 2294#endif
2290 2295
2296#define IOAPIC_RESOURCE_NAME_SIZE 11
2297
2298static struct resource *ioapic_resources;
2299
2300static struct resource * __init ioapic_setup_resources(void)
2301{
2302 unsigned long n;
2303 struct resource *res;
2304 char *mem;
2305 int i;
2306
2307 if (nr_ioapics <= 0)
2308 return NULL;
2309
2310 n = IOAPIC_RESOURCE_NAME_SIZE + sizeof(struct resource);
2311 n *= nr_ioapics;
2312
2313 mem = alloc_bootmem(n);
2314 res = (void *)mem;
2315
2316 if (mem != NULL) {
2317 memset(mem, 0, n);
2318 mem += sizeof(struct resource) * nr_ioapics;
2319
2320 for (i = 0; i < nr_ioapics; i++) {
2321 res[i].name = mem;
2322 res[i].flags = IORESOURCE_MEM | IORESOURCE_BUSY;
2323 sprintf(mem, "IOAPIC %u", i);
2324 mem += IOAPIC_RESOURCE_NAME_SIZE;
2325 }
2326 }
2327
2328 ioapic_resources = res;
2329
2330 return res;
2331}
2332
2333void __init ioapic_init_mappings(void)
2334{
2335 unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0;
2336 struct resource *ioapic_res;
2337 int i;
2338
2339 ioapic_res = ioapic_setup_resources();
2340 for (i = 0; i < nr_ioapics; i++) {
2341 if (smp_found_config) {
2342 ioapic_phys = mp_ioapics[i].mpc_apicaddr;
2343 } else {
2344 ioapic_phys = (unsigned long)
2345 alloc_bootmem_pages(PAGE_SIZE);
2346 ioapic_phys = __pa(ioapic_phys);
2347 }
2348 set_fixmap_nocache(idx, ioapic_phys);
2349 apic_printk(APIC_VERBOSE,
2350 "mapped IOAPIC to %016lx (%016lx)\n",
2351 __fix_to_virt(idx), ioapic_phys);
2352 idx++;
2353
2354 if (ioapic_res != NULL) {
2355 ioapic_res->start = ioapic_phys;
2356 ioapic_res->end = ioapic_phys + (4 * 1024) - 1;
2357 ioapic_res++;
2358 }
2359 }
2360}
2361
2362static int __init ioapic_insert_resources(void)
2363{
2364 int i;
2365 struct resource *r = ioapic_resources;
2366
2367 if (!r) {
2368 printk(KERN_ERR
2369 "IO APIC resources could be not be allocated.\n");
2370 return -1;
2371 }
2372
2373 for (i = 0; i < nr_ioapics; i++) {
2374 insert_resource(&iomem_resource, r);
2375 r++;
2376 }
2377
2378 return 0;
2379}
2380
2381/* Insert the IO APIC resources after PCI initialization has occured to handle
2382 * IO APICS that are mapped in on a BAR in PCI space. */
2383late_initcall(ioapic_insert_resources);
2384
diff --git a/arch/x86/kernel/io_delay.c b/arch/x86/kernel/io_delay.c
new file mode 100644
index 000000000000..bd49321034db
--- /dev/null
+++ b/arch/x86/kernel/io_delay.c
@@ -0,0 +1,114 @@
1/*
2 * I/O delay strategies for inb_p/outb_p
3 *
4 * Allow for a DMI based override of port 0x80, needed for certain HP laptops
5 * and possibly other systems. Also allow for the gradual elimination of
6 * outb_p/inb_p API uses.
7 */
8#include <linux/kernel.h>
9#include <linux/module.h>
10#include <linux/init.h>
11#include <linux/delay.h>
12#include <linux/dmi.h>
13#include <asm/io.h>
14
15int io_delay_type __read_mostly = CONFIG_DEFAULT_IO_DELAY_TYPE;
16EXPORT_SYMBOL_GPL(io_delay_type);
17
18static int __initdata io_delay_override;
19
20/*
21 * Paravirt wants native_io_delay to be a constant.
22 */
23void native_io_delay(void)
24{
25 switch (io_delay_type) {
26 default:
27 case CONFIG_IO_DELAY_TYPE_0X80:
28 asm volatile ("outb %al, $0x80");
29 break;
30 case CONFIG_IO_DELAY_TYPE_0XED:
31 asm volatile ("outb %al, $0xed");
32 break;
33 case CONFIG_IO_DELAY_TYPE_UDELAY:
34 /*
35 * 2 usecs is an upper-bound for the outb delay but
36 * note that udelay doesn't have the bus-level
37 * side-effects that outb does, nor does udelay() have
38 * precise timings during very early bootup (the delays
39 * are shorter until calibrated):
40 */
41 udelay(2);
42 case CONFIG_IO_DELAY_TYPE_NONE:
43 break;
44 }
45}
46EXPORT_SYMBOL(native_io_delay);
47
48static int __init dmi_io_delay_0xed_port(const struct dmi_system_id *id)
49{
50 if (io_delay_type == CONFIG_IO_DELAY_TYPE_0X80) {
51 printk(KERN_NOTICE "%s: using 0xed I/O delay port\n",
52 id->ident);
53 io_delay_type = CONFIG_IO_DELAY_TYPE_0XED;
54 }
55
56 return 0;
57}
58
59/*
60 * Quirk table for systems that misbehave (lock up, etc.) if port
61 * 0x80 is used:
62 */
63static struct dmi_system_id __initdata io_delay_0xed_port_dmi_table[] = {
64 {
65 .callback = dmi_io_delay_0xed_port,
66 .ident = "Compaq Presario V6000",
67 .matches = {
68 DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
69 DMI_MATCH(DMI_BOARD_NAME, "30B7")
70 }
71 },
72 {
73 .callback = dmi_io_delay_0xed_port,
74 .ident = "HP Pavilion dv9000z",
75 .matches = {
76 DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
77 DMI_MATCH(DMI_BOARD_NAME, "30B9")
78 }
79 },
80 {
81 .callback = dmi_io_delay_0xed_port,
82 .ident = "HP Pavilion tx1000",
83 .matches = {
84 DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
85 DMI_MATCH(DMI_BOARD_NAME, "30BF")
86 }
87 },
88 { }
89};
90
91void __init io_delay_init(void)
92{
93 if (!io_delay_override)
94 dmi_check_system(io_delay_0xed_port_dmi_table);
95}
96
97static int __init io_delay_param(char *s)
98{
99 if (!strcmp(s, "0x80"))
100 io_delay_type = CONFIG_IO_DELAY_TYPE_0X80;
101 else if (!strcmp(s, "0xed"))
102 io_delay_type = CONFIG_IO_DELAY_TYPE_0XED;
103 else if (!strcmp(s, "udelay"))
104 io_delay_type = CONFIG_IO_DELAY_TYPE_UDELAY;
105 else if (!strcmp(s, "none"))
106 io_delay_type = CONFIG_IO_DELAY_TYPE_NONE;
107 else
108 return -EINVAL;
109
110 io_delay_override = 1;
111 return 0;
112}
113
114early_param("io_delay", io_delay_param);
diff --git a/arch/x86/kernel/ioport_32.c b/arch/x86/kernel/ioport.c
index 4ed48dc8df1e..50e5e4a31c85 100644
--- a/arch/x86/kernel/ioport_32.c
+++ b/arch/x86/kernel/ioport.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * This contains the io-permission bitmap code - written by obz, with changes 2 * This contains the io-permission bitmap code - written by obz, with changes
3 * by Linus. 3 * by Linus. 32/64 bits code unification by Miguel Botón.
4 */ 4 */
5 5
6#include <linux/sched.h> 6#include <linux/sched.h>
@@ -16,49 +16,27 @@
16#include <linux/syscalls.h> 16#include <linux/syscalls.h>
17 17
18/* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */ 18/* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
19static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value) 19static void set_bitmap(unsigned long *bitmap, unsigned int base,
20 unsigned int extent, int new_value)
20{ 21{
21 unsigned long mask; 22 unsigned int i;
22 unsigned long *bitmap_base = bitmap + (base / BITS_PER_LONG);
23 unsigned int low_index = base & (BITS_PER_LONG-1);
24 int length = low_index + extent;
25
26 if (low_index != 0) {
27 mask = (~0UL << low_index);
28 if (length < BITS_PER_LONG)
29 mask &= ~(~0UL << length);
30 if (new_value)
31 *bitmap_base++ |= mask;
32 else
33 *bitmap_base++ &= ~mask;
34 length -= BITS_PER_LONG;
35 }
36
37 mask = (new_value ? ~0UL : 0UL);
38 while (length >= BITS_PER_LONG) {
39 *bitmap_base++ = mask;
40 length -= BITS_PER_LONG;
41 }
42 23
43 if (length > 0) { 24 for (i = base; i < base + extent; i++) {
44 mask = ~(~0UL << length);
45 if (new_value) 25 if (new_value)
46 *bitmap_base++ |= mask; 26 __set_bit(i, bitmap);
47 else 27 else
48 *bitmap_base++ &= ~mask; 28 __clear_bit(i, bitmap);
49 } 29 }
50} 30}
51 31
52
53/* 32/*
54 * this changes the io permissions bitmap in the current task. 33 * this changes the io permissions bitmap in the current task.
55 */ 34 */
56asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on) 35asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
57{ 36{
58 unsigned long i, max_long, bytes, bytes_updated;
59 struct thread_struct * t = &current->thread; 37 struct thread_struct * t = &current->thread;
60 struct tss_struct * tss; 38 struct tss_struct * tss;
61 unsigned long *bitmap; 39 unsigned int i, max_long, bytes, bytes_updated;
62 40
63 if ((from + num <= from) || (from + num > IO_BITMAP_BITS)) 41 if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
64 return -EINVAL; 42 return -EINVAL;
@@ -71,7 +49,8 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
71 * this is why we delay this operation until now: 49 * this is why we delay this operation until now:
72 */ 50 */
73 if (!t->io_bitmap_ptr) { 51 if (!t->io_bitmap_ptr) {
74 bitmap = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL); 52 unsigned long *bitmap = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
53
75 if (!bitmap) 54 if (!bitmap)
76 return -ENOMEM; 55 return -ENOMEM;
77 56
@@ -100,11 +79,12 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
100 if (t->io_bitmap_ptr[i] != ~0UL) 79 if (t->io_bitmap_ptr[i] != ~0UL)
101 max_long = i; 80 max_long = i;
102 81
103 bytes = (max_long + 1) * sizeof(long); 82 bytes = (max_long + 1) * sizeof(unsigned long);
104 bytes_updated = max(bytes, t->io_bitmap_max); 83 bytes_updated = max(bytes, t->io_bitmap_max);
105 84
106 t->io_bitmap_max = bytes; 85 t->io_bitmap_max = bytes;
107 86
87#ifdef CONFIG_X86_32
108 /* 88 /*
109 * Sets the lazy trigger so that the next I/O operation will 89 * Sets the lazy trigger so that the next I/O operation will
110 * reload the correct bitmap. 90 * reload the correct bitmap.
@@ -113,6 +93,10 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
113 */ 93 */
114 tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET_LAZY; 94 tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET_LAZY;
115 tss->io_bitmap_owner = NULL; 95 tss->io_bitmap_owner = NULL;
96#else
97 /* Update the TSS: */
98 memcpy(tss->io_bitmap, t->io_bitmap_ptr, bytes_updated);
99#endif
116 100
117 put_cpu(); 101 put_cpu();
118 102
@@ -124,18 +108,14 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
124 * beyond the 0x3ff range: to get the full 65536 ports bitmapped 108 * beyond the 0x3ff range: to get the full 65536 ports bitmapped
125 * you'd need 8kB of bitmaps/process, which is a bit excessive. 109 * you'd need 8kB of bitmaps/process, which is a bit excessive.
126 * 110 *
127 * Here we just change the eflags value on the stack: we allow 111 * Here we just change the flags value on the stack: we allow
128 * only the super-user to do it. This depends on the stack-layout 112 * only the super-user to do it. This depends on the stack-layout
129 * on system-call entry - see also fork() and the signal handling 113 * on system-call entry - see also fork() and the signal handling
130 * code. 114 * code.
131 */ 115 */
132 116static int do_iopl(unsigned int level, struct pt_regs *regs)
133asmlinkage long sys_iopl(unsigned long unused)
134{ 117{
135 volatile struct pt_regs * regs = (struct pt_regs *) &unused; 118 unsigned int old = (regs->flags >> 12) & 3;
136 unsigned int level = regs->ebx;
137 unsigned int old = (regs->eflags >> 12) & 3;
138 struct thread_struct *t = &current->thread;
139 119
140 if (level > 3) 120 if (level > 3)
141 return -EINVAL; 121 return -EINVAL;
@@ -144,8 +124,31 @@ asmlinkage long sys_iopl(unsigned long unused)
144 if (!capable(CAP_SYS_RAWIO)) 124 if (!capable(CAP_SYS_RAWIO))
145 return -EPERM; 125 return -EPERM;
146 } 126 }
127 regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12);
128
129 return 0;
130}
131
132#ifdef CONFIG_X86_32
133asmlinkage long sys_iopl(unsigned long regsp)
134{
135 struct pt_regs *regs = (struct pt_regs *)&regsp;
136 unsigned int level = regs->bx;
137 struct thread_struct *t = &current->thread;
138 int rc;
139
140 rc = do_iopl(level, regs);
141 if (rc < 0)
142 goto out;
143
147 t->iopl = level << 12; 144 t->iopl = level << 12;
148 regs->eflags = (regs->eflags & ~X86_EFLAGS_IOPL) | t->iopl;
149 set_iopl_mask(t->iopl); 145 set_iopl_mask(t->iopl);
150 return 0; 146out:
147 return rc;
148}
149#else
150asmlinkage long sys_iopl(unsigned int level, struct pt_regs *regs)
151{
152 return do_iopl(level, regs);
151} 153}
154#endif
diff --git a/arch/x86/kernel/ioport_64.c b/arch/x86/kernel/ioport_64.c
deleted file mode 100644
index 5f62fad64dab..000000000000
--- a/arch/x86/kernel/ioport_64.c
+++ /dev/null
@@ -1,117 +0,0 @@
1/*
2 * This contains the io-permission bitmap code - written by obz, with changes
3 * by Linus.
4 */
5
6#include <linux/sched.h>
7#include <linux/kernel.h>
8#include <linux/capability.h>
9#include <linux/errno.h>
10#include <linux/types.h>
11#include <linux/ioport.h>
12#include <linux/smp.h>
13#include <linux/stddef.h>
14#include <linux/slab.h>
15#include <linux/thread_info.h>
16#include <linux/syscalls.h>
17
18/* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
19static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value)
20{
21 int i;
22 if (new_value)
23 for (i = base; i < base + extent; i++)
24 __set_bit(i, bitmap);
25 else
26 for (i = base; i < base + extent; i++)
27 clear_bit(i, bitmap);
28}
29
30/*
31 * this changes the io permissions bitmap in the current task.
32 */
33asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
34{
35 unsigned int i, max_long, bytes, bytes_updated;
36 struct thread_struct * t = &current->thread;
37 struct tss_struct * tss;
38 unsigned long *bitmap;
39
40 if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
41 return -EINVAL;
42 if (turn_on && !capable(CAP_SYS_RAWIO))
43 return -EPERM;
44
45 /*
46 * If it's the first ioperm() call in this thread's lifetime, set the
47 * IO bitmap up. ioperm() is much less timing critical than clone(),
48 * this is why we delay this operation until now:
49 */
50 if (!t->io_bitmap_ptr) {
51 bitmap = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
52 if (!bitmap)
53 return -ENOMEM;
54
55 memset(bitmap, 0xff, IO_BITMAP_BYTES);
56 t->io_bitmap_ptr = bitmap;
57 set_thread_flag(TIF_IO_BITMAP);
58 }
59
60 /*
61 * do it in the per-thread copy and in the TSS ...
62 *
63 * Disable preemption via get_cpu() - we must not switch away
64 * because the ->io_bitmap_max value must match the bitmap
65 * contents:
66 */
67 tss = &per_cpu(init_tss, get_cpu());
68
69 set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
70
71 /*
72 * Search for a (possibly new) maximum. This is simple and stupid,
73 * to keep it obviously correct:
74 */
75 max_long = 0;
76 for (i = 0; i < IO_BITMAP_LONGS; i++)
77 if (t->io_bitmap_ptr[i] != ~0UL)
78 max_long = i;
79
80 bytes = (max_long + 1) * sizeof(long);
81 bytes_updated = max(bytes, t->io_bitmap_max);
82
83 t->io_bitmap_max = bytes;
84
85 /* Update the TSS: */
86 memcpy(tss->io_bitmap, t->io_bitmap_ptr, bytes_updated);
87
88 put_cpu();
89
90 return 0;
91}
92
93/*
94 * sys_iopl has to be used when you want to access the IO ports
95 * beyond the 0x3ff range: to get the full 65536 ports bitmapped
96 * you'd need 8kB of bitmaps/process, which is a bit excessive.
97 *
98 * Here we just change the eflags value on the stack: we allow
99 * only the super-user to do it. This depends on the stack-layout
100 * on system-call entry - see also fork() and the signal handling
101 * code.
102 */
103
104asmlinkage long sys_iopl(unsigned int level, struct pt_regs *regs)
105{
106 unsigned int old = (regs->eflags >> 12) & 3;
107
108 if (level > 3)
109 return -EINVAL;
110 /* Trying to gain more privileges? */
111 if (level > old) {
112 if (!capable(CAP_SYS_RAWIO))
113 return -EPERM;
114 }
115 regs->eflags = (regs->eflags &~ X86_EFLAGS_IOPL) | (level << 12);
116 return 0;
117}
diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c
index d3fde94f7345..cef054b09d27 100644
--- a/arch/x86/kernel/irq_32.c
+++ b/arch/x86/kernel/irq_32.c
@@ -66,11 +66,11 @@ static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly;
66 * SMP cross-CPU interrupts have their own specific 66 * SMP cross-CPU interrupts have their own specific
67 * handlers). 67 * handlers).
68 */ 68 */
69fastcall unsigned int do_IRQ(struct pt_regs *regs) 69unsigned int do_IRQ(struct pt_regs *regs)
70{ 70{
71 struct pt_regs *old_regs; 71 struct pt_regs *old_regs;
72 /* high bit used in ret_from_ code */ 72 /* high bit used in ret_from_ code */
73 int irq = ~regs->orig_eax; 73 int irq = ~regs->orig_ax;
74 struct irq_desc *desc = irq_desc + irq; 74 struct irq_desc *desc = irq_desc + irq;
75#ifdef CONFIG_4KSTACKS 75#ifdef CONFIG_4KSTACKS
76 union irq_ctx *curctx, *irqctx; 76 union irq_ctx *curctx, *irqctx;
@@ -88,13 +88,13 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs)
88#ifdef CONFIG_DEBUG_STACKOVERFLOW 88#ifdef CONFIG_DEBUG_STACKOVERFLOW
89 /* Debugging check for stack overflow: is there less than 1KB free? */ 89 /* Debugging check for stack overflow: is there less than 1KB free? */
90 { 90 {
91 long esp; 91 long sp;
92 92
93 __asm__ __volatile__("andl %%esp,%0" : 93 __asm__ __volatile__("andl %%esp,%0" :
94 "=r" (esp) : "0" (THREAD_SIZE - 1)); 94 "=r" (sp) : "0" (THREAD_SIZE - 1));
95 if (unlikely(esp < (sizeof(struct thread_info) + STACK_WARN))) { 95 if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) {
96 printk("do_IRQ: stack overflow: %ld\n", 96 printk("do_IRQ: stack overflow: %ld\n",
97 esp - sizeof(struct thread_info)); 97 sp - sizeof(struct thread_info));
98 dump_stack(); 98 dump_stack();
99 } 99 }
100 } 100 }
@@ -112,7 +112,7 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs)
112 * current stack (which is the irq stack already after all) 112 * current stack (which is the irq stack already after all)
113 */ 113 */
114 if (curctx != irqctx) { 114 if (curctx != irqctx) {
115 int arg1, arg2, ebx; 115 int arg1, arg2, bx;
116 116
117 /* build the stack frame on the IRQ stack */ 117 /* build the stack frame on the IRQ stack */
118 isp = (u32*) ((char*)irqctx + sizeof(*irqctx)); 118 isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
@@ -128,10 +128,10 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs)
128 (curctx->tinfo.preempt_count & SOFTIRQ_MASK); 128 (curctx->tinfo.preempt_count & SOFTIRQ_MASK);
129 129
130 asm volatile( 130 asm volatile(
131 " xchgl %%ebx,%%esp \n" 131 " xchgl %%ebx,%%esp \n"
132 " call *%%edi \n" 132 " call *%%edi \n"
133 " movl %%ebx,%%esp \n" 133 " movl %%ebx,%%esp \n"
134 : "=a" (arg1), "=d" (arg2), "=b" (ebx) 134 : "=a" (arg1), "=d" (arg2), "=b" (bx)
135 : "0" (irq), "1" (desc), "2" (isp), 135 : "0" (irq), "1" (desc), "2" (isp),
136 "D" (desc->handle_irq) 136 "D" (desc->handle_irq)
137 : "memory", "cc" 137 : "memory", "cc"
diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c
index 6b5c730d67b9..3aac15466a91 100644
--- a/arch/x86/kernel/irq_64.c
+++ b/arch/x86/kernel/irq_64.c
@@ -20,6 +20,26 @@
20 20
21atomic_t irq_err_count; 21atomic_t irq_err_count;
22 22
23/*
24 * 'what should we do if we get a hw irq event on an illegal vector'.
25 * each architecture has to answer this themselves.
26 */
27void ack_bad_irq(unsigned int irq)
28{
29 printk(KERN_WARNING "unexpected IRQ trap at vector %02x\n", irq);
30 /*
31 * Currently unexpected vectors happen only on SMP and APIC.
32 * We _must_ ack these because every local APIC has only N
33 * irq slots per priority level, and a 'hanging, unacked' IRQ
34 * holds up an irq slot - in excessive cases (when multiple
35 * unexpected vectors occur) that might lock up the APIC
36 * completely.
37 * But don't ack when the APIC is disabled. -AK
38 */
39 if (!disable_apic)
40 ack_APIC_irq();
41}
42
23#ifdef CONFIG_DEBUG_STACKOVERFLOW 43#ifdef CONFIG_DEBUG_STACKOVERFLOW
24/* 44/*
25 * Probabilistic stack overflow check: 45 * Probabilistic stack overflow check:
@@ -33,11 +53,11 @@ static inline void stack_overflow_check(struct pt_regs *regs)
33 u64 curbase = (u64)task_stack_page(current); 53 u64 curbase = (u64)task_stack_page(current);
34 static unsigned long warned = -60*HZ; 54 static unsigned long warned = -60*HZ;
35 55
36 if (regs->rsp >= curbase && regs->rsp <= curbase + THREAD_SIZE && 56 if (regs->sp >= curbase && regs->sp <= curbase + THREAD_SIZE &&
37 regs->rsp < curbase + sizeof(struct thread_info) + 128 && 57 regs->sp < curbase + sizeof(struct thread_info) + 128 &&
38 time_after(jiffies, warned + 60*HZ)) { 58 time_after(jiffies, warned + 60*HZ)) {
39 printk("do_IRQ: %s near stack overflow (cur:%Lx,rsp:%lx)\n", 59 printk("do_IRQ: %s near stack overflow (cur:%Lx,sp:%lx)\n",
40 current->comm, curbase, regs->rsp); 60 current->comm, curbase, regs->sp);
41 show_stack(NULL,NULL); 61 show_stack(NULL,NULL);
42 warned = jiffies; 62 warned = jiffies;
43 } 63 }
@@ -142,7 +162,7 @@ asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
142 struct pt_regs *old_regs = set_irq_regs(regs); 162 struct pt_regs *old_regs = set_irq_regs(regs);
143 163
144 /* high bit used in ret_from_ code */ 164 /* high bit used in ret_from_ code */
145 unsigned vector = ~regs->orig_rax; 165 unsigned vector = ~regs->orig_ax;
146 unsigned irq; 166 unsigned irq;
147 167
148 exit_idle(); 168 exit_idle();
diff --git a/arch/x86/kernel/kdebugfs.c b/arch/x86/kernel/kdebugfs.c
new file mode 100644
index 000000000000..73354302fda7
--- /dev/null
+++ b/arch/x86/kernel/kdebugfs.c
@@ -0,0 +1,65 @@
1/*
2 * Architecture specific debugfs files
3 *
4 * Copyright (C) 2007, Intel Corp.
5 * Huang Ying <ying.huang@intel.com>
6 *
7 * This file is released under the GPLv2.
8 */
9
10#include <linux/debugfs.h>
11#include <linux/stat.h>
12#include <linux/init.h>
13
14#include <asm/setup.h>
15
16#ifdef CONFIG_DEBUG_BOOT_PARAMS
17static struct debugfs_blob_wrapper boot_params_blob = {
18 .data = &boot_params,
19 .size = sizeof(boot_params),
20};
21
22static int __init boot_params_kdebugfs_init(void)
23{
24 int error;
25 struct dentry *dbp, *version, *data;
26
27 dbp = debugfs_create_dir("boot_params", NULL);
28 if (!dbp) {
29 error = -ENOMEM;
30 goto err_return;
31 }
32 version = debugfs_create_x16("version", S_IRUGO, dbp,
33 &boot_params.hdr.version);
34 if (!version) {
35 error = -ENOMEM;
36 goto err_dir;
37 }
38 data = debugfs_create_blob("data", S_IRUGO, dbp,
39 &boot_params_blob);
40 if (!data) {
41 error = -ENOMEM;
42 goto err_version;
43 }
44 return 0;
45err_version:
46 debugfs_remove(version);
47err_dir:
48 debugfs_remove(dbp);
49err_return:
50 return error;
51}
52#endif
53
54static int __init arch_kdebugfs_init(void)
55{
56 int error = 0;
57
58#ifdef CONFIG_DEBUG_BOOT_PARAMS
59 error = boot_params_kdebugfs_init();
60#endif
61
62 return error;
63}
64
65arch_initcall(arch_kdebugfs_init);
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c
new file mode 100644
index 000000000000..a99e764fd66a
--- /dev/null
+++ b/arch/x86/kernel/kprobes.c
@@ -0,0 +1,1066 @@
1/*
2 * Kernel Probes (KProbes)
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 * Copyright (C) IBM Corporation, 2002, 2004
19 *
20 * 2002-Oct Created by Vamsi Krishna S <vamsi_krishna@in.ibm.com> Kernel
21 * Probes initial implementation ( includes contributions from
22 * Rusty Russell).
23 * 2004-July Suparna Bhattacharya <suparna@in.ibm.com> added jumper probes
24 * interface to access function arguments.
25 * 2004-Oct Jim Keniston <jkenisto@us.ibm.com> and Prasanna S Panchamukhi
26 * <prasanna@in.ibm.com> adapted for x86_64 from i386.
27 * 2005-Mar Roland McGrath <roland@redhat.com>
28 * Fixed to handle %rip-relative addressing mode correctly.
29 * 2005-May Hien Nguyen <hien@us.ibm.com>, Jim Keniston
30 * <jkenisto@us.ibm.com> and Prasanna S Panchamukhi
31 * <prasanna@in.ibm.com> added function-return probes.
32 * 2005-May Rusty Lynch <rusty.lynch@intel.com>
33 * Added function return probes functionality
34 * 2006-Feb Masami Hiramatsu <hiramatu@sdl.hitachi.co.jp> added
35 * kprobe-booster and kretprobe-booster for i386.
36 * 2007-Dec Masami Hiramatsu <mhiramat@redhat.com> added kprobe-booster
37 * and kretprobe-booster for x86-64
38 * 2007-Dec Masami Hiramatsu <mhiramat@redhat.com>, Arjan van de Ven
39 * <arjan@infradead.org> and Jim Keniston <jkenisto@us.ibm.com>
40 * unified x86 kprobes code.
41 */
42
43#include <linux/kprobes.h>
44#include <linux/ptrace.h>
45#include <linux/string.h>
46#include <linux/slab.h>
47#include <linux/hardirq.h>
48#include <linux/preempt.h>
49#include <linux/module.h>
50#include <linux/kdebug.h>
51
52#include <asm/cacheflush.h>
53#include <asm/desc.h>
54#include <asm/pgtable.h>
55#include <asm/uaccess.h>
56#include <asm/alternative.h>
57
58void jprobe_return_end(void);
59
60DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
61DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
62
63#ifdef CONFIG_X86_64
64#define stack_addr(regs) ((unsigned long *)regs->sp)
65#else
66/*
67 * "&regs->sp" looks wrong, but it's correct for x86_32. x86_32 CPUs
68 * don't save the ss and esp registers if the CPU is already in kernel
69 * mode when it traps. So for kprobes, regs->sp and regs->ss are not
70 * the [nonexistent] saved stack pointer and ss register, but rather
71 * the top 8 bytes of the pre-int3 stack. So &regs->sp happens to
72 * point to the top of the pre-int3 stack.
73 */
74#define stack_addr(regs) ((unsigned long *)&regs->sp)
75#endif
76
77#define W(row, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf)\
78 (((b0##UL << 0x0)|(b1##UL << 0x1)|(b2##UL << 0x2)|(b3##UL << 0x3) | \
79 (b4##UL << 0x4)|(b5##UL << 0x5)|(b6##UL << 0x6)|(b7##UL << 0x7) | \
80 (b8##UL << 0x8)|(b9##UL << 0x9)|(ba##UL << 0xa)|(bb##UL << 0xb) | \
81 (bc##UL << 0xc)|(bd##UL << 0xd)|(be##UL << 0xe)|(bf##UL << 0xf)) \
82 << (row % 32))
83 /*
84 * Undefined/reserved opcodes, conditional jump, Opcode Extension
85 * Groups, and some special opcodes can not boost.
86 */
87static const u32 twobyte_is_boostable[256 / 32] = {
88 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
89 /* ---------------------------------------------- */
90 W(0x00, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0) | /* 00 */
91 W(0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) , /* 10 */
92 W(0x20, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | /* 20 */
93 W(0x30, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) , /* 30 */
94 W(0x40, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 40 */
95 W(0x50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) , /* 50 */
96 W(0x60, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1) | /* 60 */
97 W(0x70, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1) , /* 70 */
98 W(0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | /* 80 */
99 W(0x90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 90 */
100 W(0xa0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1) | /* a0 */
101 W(0xb0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1) , /* b0 */
102 W(0xc0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1) | /* c0 */
103 W(0xd0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1) , /* d0 */
104 W(0xe0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1) | /* e0 */
105 W(0xf0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0) /* f0 */
106 /* ----------------------------------------------- */
107 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
108};
109static const u32 onebyte_has_modrm[256 / 32] = {
110 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
111 /* ----------------------------------------------- */
112 W(0x00, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) | /* 00 */
113 W(0x10, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) , /* 10 */
114 W(0x20, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) | /* 20 */
115 W(0x30, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) , /* 30 */
116 W(0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | /* 40 */
117 W(0x50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) , /* 50 */
118 W(0x60, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0) | /* 60 */
119 W(0x70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) , /* 70 */
120 W(0x80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 80 */
121 W(0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) , /* 90 */
122 W(0xa0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | /* a0 */
123 W(0xb0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) , /* b0 */
124 W(0xc0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0) | /* c0 */
125 W(0xd0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1) , /* d0 */
126 W(0xe0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | /* e0 */
127 W(0xf0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1) /* f0 */
128 /* ----------------------------------------------- */
129 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
130};
131static const u32 twobyte_has_modrm[256 / 32] = {
132 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
133 /* ----------------------------------------------- */
134 W(0x00, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1) | /* 0f */
135 W(0x10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0) , /* 1f */
136 W(0x20, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1) | /* 2f */
137 W(0x30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) , /* 3f */
138 W(0x40, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 4f */
139 W(0x50, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 5f */
140 W(0x60, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 6f */
141 W(0x70, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1) , /* 7f */
142 W(0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | /* 8f */
143 W(0x90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 9f */
144 W(0xa0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1) | /* af */
145 W(0xb0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1) , /* bf */
146 W(0xc0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0) | /* cf */
147 W(0xd0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* df */
148 W(0xe0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* ef */
149 W(0xf0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0) /* ff */
150 /* ----------------------------------------------- */
151 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
152};
153#undef W
154
155struct kretprobe_blackpoint kretprobe_blacklist[] = {
156 {"__switch_to", }, /* This function switches only current task, but
157 doesn't switch kernel stack.*/
158 {NULL, NULL} /* Terminator */
159};
160const int kretprobe_blacklist_size = ARRAY_SIZE(kretprobe_blacklist);
161
162/* Insert a jump instruction at address 'from', which jumps to address 'to'.*/
163static void __kprobes set_jmp_op(void *from, void *to)
164{
165 struct __arch_jmp_op {
166 char op;
167 s32 raddr;
168 } __attribute__((packed)) * jop;
169 jop = (struct __arch_jmp_op *)from;
170 jop->raddr = (s32)((long)(to) - ((long)(from) + 5));
171 jop->op = RELATIVEJUMP_INSTRUCTION;
172}
173
174/*
175 * Check for the REX prefix which can only exist on X86_64
176 * X86_32 always returns 0
177 */
178static int __kprobes is_REX_prefix(kprobe_opcode_t *insn)
179{
180#ifdef CONFIG_X86_64
181 if ((*insn & 0xf0) == 0x40)
182 return 1;
183#endif
184 return 0;
185}
186
187/*
188 * Returns non-zero if opcode is boostable.
189 * RIP relative instructions are adjusted at copying time in 64 bits mode
190 */
191static int __kprobes can_boost(kprobe_opcode_t *opcodes)
192{
193 kprobe_opcode_t opcode;
194 kprobe_opcode_t *orig_opcodes = opcodes;
195
196retry:
197 if (opcodes - orig_opcodes > MAX_INSN_SIZE - 1)
198 return 0;
199 opcode = *(opcodes++);
200
201 /* 2nd-byte opcode */
202 if (opcode == 0x0f) {
203 if (opcodes - orig_opcodes > MAX_INSN_SIZE - 1)
204 return 0;
205 return test_bit(*opcodes,
206 (unsigned long *)twobyte_is_boostable);
207 }
208
209 switch (opcode & 0xf0) {
210#ifdef CONFIG_X86_64
211 case 0x40:
212 goto retry; /* REX prefix is boostable */
213#endif
214 case 0x60:
215 if (0x63 < opcode && opcode < 0x67)
216 goto retry; /* prefixes */
217 /* can't boost Address-size override and bound */
218 return (opcode != 0x62 && opcode != 0x67);
219 case 0x70:
220 return 0; /* can't boost conditional jump */
221 case 0xc0:
222 /* can't boost software-interruptions */
223 return (0xc1 < opcode && opcode < 0xcc) || opcode == 0xcf;
224 case 0xd0:
225 /* can boost AA* and XLAT */
226 return (opcode == 0xd4 || opcode == 0xd5 || opcode == 0xd7);
227 case 0xe0:
228 /* can boost in/out and absolute jmps */
229 return ((opcode & 0x04) || opcode == 0xea);
230 case 0xf0:
231 if ((opcode & 0x0c) == 0 && opcode != 0xf1)
232 goto retry; /* lock/rep(ne) prefix */
233 /* clear and set flags are boostable */
234 return (opcode == 0xf5 || (0xf7 < opcode && opcode < 0xfe));
235 default:
236 /* segment override prefixes are boostable */
237 if (opcode == 0x26 || opcode == 0x36 || opcode == 0x3e)
238 goto retry; /* prefixes */
239 /* CS override prefix and call are not boostable */
240 return (opcode != 0x2e && opcode != 0x9a);
241 }
242}
243
244/*
245 * Returns non-zero if opcode modifies the interrupt flag.
246 */
247static int __kprobes is_IF_modifier(kprobe_opcode_t *insn)
248{
249 switch (*insn) {
250 case 0xfa: /* cli */
251 case 0xfb: /* sti */
252 case 0xcf: /* iret/iretd */
253 case 0x9d: /* popf/popfd */
254 return 1;
255 }
256
257 /*
258 * on X86_64, 0x40-0x4f are REX prefixes so we need to look
259 * at the next byte instead.. but of course not recurse infinitely
260 */
261 if (is_REX_prefix(insn))
262 return is_IF_modifier(++insn);
263
264 return 0;
265}
266
267/*
268 * Adjust the displacement if the instruction uses the %rip-relative
269 * addressing mode.
270 * If it does, Return the address of the 32-bit displacement word.
271 * If not, return null.
272 * Only applicable to 64-bit x86.
273 */
274static void __kprobes fix_riprel(struct kprobe *p)
275{
276#ifdef CONFIG_X86_64
277 u8 *insn = p->ainsn.insn;
278 s64 disp;
279 int need_modrm;
280
281 /* Skip legacy instruction prefixes. */
282 while (1) {
283 switch (*insn) {
284 case 0x66:
285 case 0x67:
286 case 0x2e:
287 case 0x3e:
288 case 0x26:
289 case 0x64:
290 case 0x65:
291 case 0x36:
292 case 0xf0:
293 case 0xf3:
294 case 0xf2:
295 ++insn;
296 continue;
297 }
298 break;
299 }
300
301 /* Skip REX instruction prefix. */
302 if (is_REX_prefix(insn))
303 ++insn;
304
305 if (*insn == 0x0f) {
306 /* Two-byte opcode. */
307 ++insn;
308 need_modrm = test_bit(*insn,
309 (unsigned long *)twobyte_has_modrm);
310 } else
311 /* One-byte opcode. */
312 need_modrm = test_bit(*insn,
313 (unsigned long *)onebyte_has_modrm);
314
315 if (need_modrm) {
316 u8 modrm = *++insn;
317 if ((modrm & 0xc7) == 0x05) {
318 /* %rip+disp32 addressing mode */
319 /* Displacement follows ModRM byte. */
320 ++insn;
321 /*
322 * The copied instruction uses the %rip-relative
323 * addressing mode. Adjust the displacement for the
324 * difference between the original location of this
325 * instruction and the location of the copy that will
326 * actually be run. The tricky bit here is making sure
327 * that the sign extension happens correctly in this
328 * calculation, since we need a signed 32-bit result to
329 * be sign-extended to 64 bits when it's added to the
330 * %rip value and yield the same 64-bit result that the
331 * sign-extension of the original signed 32-bit
332 * displacement would have given.
333 */
334 disp = (u8 *) p->addr + *((s32 *) insn) -
335 (u8 *) p->ainsn.insn;
336 BUG_ON((s64) (s32) disp != disp); /* Sanity check. */
337 *(s32 *)insn = (s32) disp;
338 }
339 }
340#endif
341}
342
343static void __kprobes arch_copy_kprobe(struct kprobe *p)
344{
345 memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
346
347 fix_riprel(p);
348
349 if (can_boost(p->addr))
350 p->ainsn.boostable = 0;
351 else
352 p->ainsn.boostable = -1;
353
354 p->opcode = *p->addr;
355}
356
357int __kprobes arch_prepare_kprobe(struct kprobe *p)
358{
359 /* insn: must be on special executable page on x86. */
360 p->ainsn.insn = get_insn_slot();
361 if (!p->ainsn.insn)
362 return -ENOMEM;
363 arch_copy_kprobe(p);
364 return 0;
365}
366
367void __kprobes arch_arm_kprobe(struct kprobe *p)
368{
369 text_poke(p->addr, ((unsigned char []){BREAKPOINT_INSTRUCTION}), 1);
370}
371
372void __kprobes arch_disarm_kprobe(struct kprobe *p)
373{
374 text_poke(p->addr, &p->opcode, 1);
375}
376
377void __kprobes arch_remove_kprobe(struct kprobe *p)
378{
379 mutex_lock(&kprobe_mutex);
380 free_insn_slot(p->ainsn.insn, (p->ainsn.boostable == 1));
381 mutex_unlock(&kprobe_mutex);
382}
383
384static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
385{
386 kcb->prev_kprobe.kp = kprobe_running();
387 kcb->prev_kprobe.status = kcb->kprobe_status;
388 kcb->prev_kprobe.old_flags = kcb->kprobe_old_flags;
389 kcb->prev_kprobe.saved_flags = kcb->kprobe_saved_flags;
390}
391
392static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
393{
394 __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
395 kcb->kprobe_status = kcb->prev_kprobe.status;
396 kcb->kprobe_old_flags = kcb->prev_kprobe.old_flags;
397 kcb->kprobe_saved_flags = kcb->prev_kprobe.saved_flags;
398}
399
400static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
401 struct kprobe_ctlblk *kcb)
402{
403 __get_cpu_var(current_kprobe) = p;
404 kcb->kprobe_saved_flags = kcb->kprobe_old_flags
405 = (regs->flags & (X86_EFLAGS_TF | X86_EFLAGS_IF));
406 if (is_IF_modifier(p->ainsn.insn))
407 kcb->kprobe_saved_flags &= ~X86_EFLAGS_IF;
408}
409
410static void __kprobes clear_btf(void)
411{
412 if (test_thread_flag(TIF_DEBUGCTLMSR))
413 wrmsrl(MSR_IA32_DEBUGCTLMSR, 0);
414}
415
416static void __kprobes restore_btf(void)
417{
418 if (test_thread_flag(TIF_DEBUGCTLMSR))
419 wrmsrl(MSR_IA32_DEBUGCTLMSR, current->thread.debugctlmsr);
420}
421
422static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
423{
424 clear_btf();
425 regs->flags |= X86_EFLAGS_TF;
426 regs->flags &= ~X86_EFLAGS_IF;
427 /* single step inline if the instruction is an int3 */
428 if (p->opcode == BREAKPOINT_INSTRUCTION)
429 regs->ip = (unsigned long)p->addr;
430 else
431 regs->ip = (unsigned long)p->ainsn.insn;
432}
433
434/* Called with kretprobe_lock held */
435void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
436 struct pt_regs *regs)
437{
438 unsigned long *sara = stack_addr(regs);
439
440 ri->ret_addr = (kprobe_opcode_t *) *sara;
441
442 /* Replace the return addr with trampoline addr */
443 *sara = (unsigned long) &kretprobe_trampoline;
444}
445
446static void __kprobes setup_singlestep(struct kprobe *p, struct pt_regs *regs,
447 struct kprobe_ctlblk *kcb)
448{
449#if !defined(CONFIG_PREEMPT) || defined(CONFIG_PM)
450 if (p->ainsn.boostable == 1 && !p->post_handler) {
451 /* Boost up -- we can execute copied instructions directly */
452 reset_current_kprobe();
453 regs->ip = (unsigned long)p->ainsn.insn;
454 preempt_enable_no_resched();
455 return;
456 }
457#endif
458 prepare_singlestep(p, regs);
459 kcb->kprobe_status = KPROBE_HIT_SS;
460}
461
462/*
463 * We have reentered the kprobe_handler(), since another probe was hit while
464 * within the handler. We save the original kprobes variables and just single
465 * step on the instruction of the new probe without calling any user handlers.
466 */
467static int __kprobes reenter_kprobe(struct kprobe *p, struct pt_regs *regs,
468 struct kprobe_ctlblk *kcb)
469{
470 switch (kcb->kprobe_status) {
471 case KPROBE_HIT_SSDONE:
472#ifdef CONFIG_X86_64
473 /* TODO: Provide re-entrancy from post_kprobes_handler() and
474 * avoid exception stack corruption while single-stepping on
475 * the instruction of the new probe.
476 */
477 arch_disarm_kprobe(p);
478 regs->ip = (unsigned long)p->addr;
479 reset_current_kprobe();
480 preempt_enable_no_resched();
481 break;
482#endif
483 case KPROBE_HIT_ACTIVE:
484 save_previous_kprobe(kcb);
485 set_current_kprobe(p, regs, kcb);
486 kprobes_inc_nmissed_count(p);
487 prepare_singlestep(p, regs);
488 kcb->kprobe_status = KPROBE_REENTER;
489 break;
490 case KPROBE_HIT_SS:
491 if (p == kprobe_running()) {
492 regs->flags &= ~TF_MASK;
493 regs->flags |= kcb->kprobe_saved_flags;
494 return 0;
495 } else {
496 /* A probe has been hit in the codepath leading up
497 * to, or just after, single-stepping of a probed
498 * instruction. This entire codepath should strictly
499 * reside in .kprobes.text section. Raise a warning
500 * to highlight this peculiar case.
501 */
502 }
503 default:
504 /* impossible cases */
505 WARN_ON(1);
506 return 0;
507 }
508
509 return 1;
510}
511
512/*
513 * Interrupts are disabled on entry as trap3 is an interrupt gate and they
514 * remain disabled thorough out this function.
515 */
516static int __kprobes kprobe_handler(struct pt_regs *regs)
517{
518 kprobe_opcode_t *addr;
519 struct kprobe *p;
520 struct kprobe_ctlblk *kcb;
521
522 addr = (kprobe_opcode_t *)(regs->ip - sizeof(kprobe_opcode_t));
523 if (*addr != BREAKPOINT_INSTRUCTION) {
524 /*
525 * The breakpoint instruction was removed right
526 * after we hit it. Another cpu has removed
527 * either a probepoint or a debugger breakpoint
528 * at this address. In either case, no further
529 * handling of this interrupt is appropriate.
530 * Back up over the (now missing) int3 and run
531 * the original instruction.
532 */
533 regs->ip = (unsigned long)addr;
534 return 1;
535 }
536
537 /*
538 * We don't want to be preempted for the entire
539 * duration of kprobe processing. We conditionally
540 * re-enable preemption at the end of this function,
541 * and also in reenter_kprobe() and setup_singlestep().
542 */
543 preempt_disable();
544
545 kcb = get_kprobe_ctlblk();
546 p = get_kprobe(addr);
547
548 if (p) {
549 if (kprobe_running()) {
550 if (reenter_kprobe(p, regs, kcb))
551 return 1;
552 } else {
553 set_current_kprobe(p, regs, kcb);
554 kcb->kprobe_status = KPROBE_HIT_ACTIVE;
555
556 /*
557 * If we have no pre-handler or it returned 0, we
558 * continue with normal processing. If we have a
559 * pre-handler and it returned non-zero, it prepped
560 * for calling the break_handler below on re-entry
561 * for jprobe processing, so get out doing nothing
562 * more here.
563 */
564 if (!p->pre_handler || !p->pre_handler(p, regs))
565 setup_singlestep(p, regs, kcb);
566 return 1;
567 }
568 } else if (kprobe_running()) {
569 p = __get_cpu_var(current_kprobe);
570 if (p->break_handler && p->break_handler(p, regs)) {
571 setup_singlestep(p, regs, kcb);
572 return 1;
573 }
574 } /* else: not a kprobe fault; let the kernel handle it */
575
576 preempt_enable_no_resched();
577 return 0;
578}
579
580/*
581 * When a retprobed function returns, this code saves registers and
582 * calls trampoline_handler() runs, which calls the kretprobe's handler.
583 */
584void __kprobes kretprobe_trampoline_holder(void)
585{
586 asm volatile (
587 ".global kretprobe_trampoline\n"
588 "kretprobe_trampoline: \n"
589#ifdef CONFIG_X86_64
590 /* We don't bother saving the ss register */
591 " pushq %rsp\n"
592 " pushfq\n"
593 /*
594 * Skip cs, ip, orig_ax.
595 * trampoline_handler() will plug in these values
596 */
597 " subq $24, %rsp\n"
598 " pushq %rdi\n"
599 " pushq %rsi\n"
600 " pushq %rdx\n"
601 " pushq %rcx\n"
602 " pushq %rax\n"
603 " pushq %r8\n"
604 " pushq %r9\n"
605 " pushq %r10\n"
606 " pushq %r11\n"
607 " pushq %rbx\n"
608 " pushq %rbp\n"
609 " pushq %r12\n"
610 " pushq %r13\n"
611 " pushq %r14\n"
612 " pushq %r15\n"
613 " movq %rsp, %rdi\n"
614 " call trampoline_handler\n"
615 /* Replace saved sp with true return address. */
616 " movq %rax, 152(%rsp)\n"
617 " popq %r15\n"
618 " popq %r14\n"
619 " popq %r13\n"
620 " popq %r12\n"
621 " popq %rbp\n"
622 " popq %rbx\n"
623 " popq %r11\n"
624 " popq %r10\n"
625 " popq %r9\n"
626 " popq %r8\n"
627 " popq %rax\n"
628 " popq %rcx\n"
629 " popq %rdx\n"
630 " popq %rsi\n"
631 " popq %rdi\n"
632 /* Skip orig_ax, ip, cs */
633 " addq $24, %rsp\n"
634 " popfq\n"
635#else
636 " pushf\n"
637 /*
638 * Skip cs, ip, orig_ax.
639 * trampoline_handler() will plug in these values
640 */
641 " subl $12, %esp\n"
642 " pushl %fs\n"
643 " pushl %ds\n"
644 " pushl %es\n"
645 " pushl %eax\n"
646 " pushl %ebp\n"
647 " pushl %edi\n"
648 " pushl %esi\n"
649 " pushl %edx\n"
650 " pushl %ecx\n"
651 " pushl %ebx\n"
652 " movl %esp, %eax\n"
653 " call trampoline_handler\n"
654 /* Move flags to cs */
655 " movl 52(%esp), %edx\n"
656 " movl %edx, 48(%esp)\n"
657 /* Replace saved flags with true return address. */
658 " movl %eax, 52(%esp)\n"
659 " popl %ebx\n"
660 " popl %ecx\n"
661 " popl %edx\n"
662 " popl %esi\n"
663 " popl %edi\n"
664 " popl %ebp\n"
665 " popl %eax\n"
666 /* Skip ip, orig_ax, es, ds, fs */
667 " addl $20, %esp\n"
668 " popf\n"
669#endif
670 " ret\n");
671}
672
673/*
674 * Called from kretprobe_trampoline
675 */
676void * __kprobes trampoline_handler(struct pt_regs *regs)
677{
678 struct kretprobe_instance *ri = NULL;
679 struct hlist_head *head, empty_rp;
680 struct hlist_node *node, *tmp;
681 unsigned long flags, orig_ret_address = 0;
682 unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline;
683
684 INIT_HLIST_HEAD(&empty_rp);
685 spin_lock_irqsave(&kretprobe_lock, flags);
686 head = kretprobe_inst_table_head(current);
687 /* fixup registers */
688#ifdef CONFIG_X86_64
689 regs->cs = __KERNEL_CS;
690#else
691 regs->cs = __KERNEL_CS | get_kernel_rpl();
692#endif
693 regs->ip = trampoline_address;
694 regs->orig_ax = ~0UL;
695
696 /*
697 * It is possible to have multiple instances associated with a given
698 * task either because multiple functions in the call path have
699 * return probes installed on them, and/or more then one
700 * return probe was registered for a target function.
701 *
702 * We can handle this because:
703 * - instances are always pushed into the head of the list
704 * - when multiple return probes are registered for the same
705 * function, the (chronologically) first instance's ret_addr
706 * will be the real return address, and all the rest will
707 * point to kretprobe_trampoline.
708 */
709 hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
710 if (ri->task != current)
711 /* another task is sharing our hash bucket */
712 continue;
713
714 if (ri->rp && ri->rp->handler) {
715 __get_cpu_var(current_kprobe) = &ri->rp->kp;
716 get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
717 ri->rp->handler(ri, regs);
718 __get_cpu_var(current_kprobe) = NULL;
719 }
720
721 orig_ret_address = (unsigned long)ri->ret_addr;
722 recycle_rp_inst(ri, &empty_rp);
723
724 if (orig_ret_address != trampoline_address)
725 /*
726 * This is the real return address. Any other
727 * instances associated with this task are for
728 * other calls deeper on the call stack
729 */
730 break;
731 }
732
733 kretprobe_assert(ri, orig_ret_address, trampoline_address);
734
735 spin_unlock_irqrestore(&kretprobe_lock, flags);
736
737 hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
738 hlist_del(&ri->hlist);
739 kfree(ri);
740 }
741 return (void *)orig_ret_address;
742}
743
744/*
745 * Called after single-stepping. p->addr is the address of the
746 * instruction whose first byte has been replaced by the "int 3"
747 * instruction. To avoid the SMP problems that can occur when we
748 * temporarily put back the original opcode to single-step, we
749 * single-stepped a copy of the instruction. The address of this
750 * copy is p->ainsn.insn.
751 *
752 * This function prepares to return from the post-single-step
753 * interrupt. We have to fix up the stack as follows:
754 *
755 * 0) Except in the case of absolute or indirect jump or call instructions,
756 * the new ip is relative to the copied instruction. We need to make
757 * it relative to the original instruction.
758 *
759 * 1) If the single-stepped instruction was pushfl, then the TF and IF
760 * flags are set in the just-pushed flags, and may need to be cleared.
761 *
762 * 2) If the single-stepped instruction was a call, the return address
763 * that is atop the stack is the address following the copied instruction.
764 * We need to make it the address following the original instruction.
765 *
766 * If this is the first time we've single-stepped the instruction at
767 * this probepoint, and the instruction is boostable, boost it: add a
768 * jump instruction after the copied instruction, that jumps to the next
769 * instruction after the probepoint.
770 */
771static void __kprobes resume_execution(struct kprobe *p,
772 struct pt_regs *regs, struct kprobe_ctlblk *kcb)
773{
774 unsigned long *tos = stack_addr(regs);
775 unsigned long copy_ip = (unsigned long)p->ainsn.insn;
776 unsigned long orig_ip = (unsigned long)p->addr;
777 kprobe_opcode_t *insn = p->ainsn.insn;
778
779 /*skip the REX prefix*/
780 if (is_REX_prefix(insn))
781 insn++;
782
783 regs->flags &= ~X86_EFLAGS_TF;
784 switch (*insn) {
785 case 0x9c: /* pushfl */
786 *tos &= ~(X86_EFLAGS_TF | X86_EFLAGS_IF);
787 *tos |= kcb->kprobe_old_flags;
788 break;
789 case 0xc2: /* iret/ret/lret */
790 case 0xc3:
791 case 0xca:
792 case 0xcb:
793 case 0xcf:
794 case 0xea: /* jmp absolute -- ip is correct */
795 /* ip is already adjusted, no more changes required */
796 p->ainsn.boostable = 1;
797 goto no_change;
798 case 0xe8: /* call relative - Fix return addr */
799 *tos = orig_ip + (*tos - copy_ip);
800 break;
801#ifdef CONFIG_X86_32
802 case 0x9a: /* call absolute -- same as call absolute, indirect */
803 *tos = orig_ip + (*tos - copy_ip);
804 goto no_change;
805#endif
806 case 0xff:
807 if ((insn[1] & 0x30) == 0x10) {
808 /*
809 * call absolute, indirect
810 * Fix return addr; ip is correct.
811 * But this is not boostable
812 */
813 *tos = orig_ip + (*tos - copy_ip);
814 goto no_change;
815 } else if (((insn[1] & 0x31) == 0x20) ||
816 ((insn[1] & 0x31) == 0x21)) {
817 /*
818 * jmp near and far, absolute indirect
819 * ip is correct. And this is boostable
820 */
821 p->ainsn.boostable = 1;
822 goto no_change;
823 }
824 default:
825 break;
826 }
827
828 if (p->ainsn.boostable == 0) {
829 if ((regs->ip > copy_ip) &&
830 (regs->ip - copy_ip) + 5 < MAX_INSN_SIZE) {
831 /*
832 * These instructions can be executed directly if it
833 * jumps back to correct address.
834 */
835 set_jmp_op((void *)regs->ip,
836 (void *)orig_ip + (regs->ip - copy_ip));
837 p->ainsn.boostable = 1;
838 } else {
839 p->ainsn.boostable = -1;
840 }
841 }
842
843 regs->ip += orig_ip - copy_ip;
844
845no_change:
846 restore_btf();
847}
848
849/*
850 * Interrupts are disabled on entry as trap1 is an interrupt gate and they
851 * remain disabled thoroughout this function.
852 */
853static int __kprobes post_kprobe_handler(struct pt_regs *regs)
854{
855 struct kprobe *cur = kprobe_running();
856 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
857
858 if (!cur)
859 return 0;
860
861 if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
862 kcb->kprobe_status = KPROBE_HIT_SSDONE;
863 cur->post_handler(cur, regs, 0);
864 }
865
866 resume_execution(cur, regs, kcb);
867 regs->flags |= kcb->kprobe_saved_flags;
868 trace_hardirqs_fixup_flags(regs->flags);
869
870 /* Restore back the original saved kprobes variables and continue. */
871 if (kcb->kprobe_status == KPROBE_REENTER) {
872 restore_previous_kprobe(kcb);
873 goto out;
874 }
875 reset_current_kprobe();
876out:
877 preempt_enable_no_resched();
878
879 /*
880 * if somebody else is singlestepping across a probe point, flags
881 * will have TF set, in which case, continue the remaining processing
882 * of do_debug, as if this is not a probe hit.
883 */
884 if (regs->flags & X86_EFLAGS_TF)
885 return 0;
886
887 return 1;
888}
889
890int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
891{
892 struct kprobe *cur = kprobe_running();
893 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
894
895 switch (kcb->kprobe_status) {
896 case KPROBE_HIT_SS:
897 case KPROBE_REENTER:
898 /*
899 * We are here because the instruction being single
900 * stepped caused a page fault. We reset the current
901 * kprobe and the ip points back to the probe address
902 * and allow the page fault handler to continue as a
903 * normal page fault.
904 */
905 regs->ip = (unsigned long)cur->addr;
906 regs->flags |= kcb->kprobe_old_flags;
907 if (kcb->kprobe_status == KPROBE_REENTER)
908 restore_previous_kprobe(kcb);
909 else
910 reset_current_kprobe();
911 preempt_enable_no_resched();
912 break;
913 case KPROBE_HIT_ACTIVE:
914 case KPROBE_HIT_SSDONE:
915 /*
916 * We increment the nmissed count for accounting,
917 * we can also use npre/npostfault count for accounting
918 * these specific fault cases.
919 */
920 kprobes_inc_nmissed_count(cur);
921
922 /*
923 * We come here because instructions in the pre/post
924 * handler caused the page_fault, this could happen
925 * if handler tries to access user space by
926 * copy_from_user(), get_user() etc. Let the
927 * user-specified handler try to fix it first.
928 */
929 if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
930 return 1;
931
932 /*
933 * In case the user-specified fault handler returned
934 * zero, try to fix up.
935 */
936 if (fixup_exception(regs))
937 return 1;
938
939 /*
940 * fixup routine could not handle it,
941 * Let do_page_fault() fix it.
942 */
943 break;
944 default:
945 break;
946 }
947 return 0;
948}
949
950/*
951 * Wrapper routine for handling exceptions.
952 */
953int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
954 unsigned long val, void *data)
955{
956 struct die_args *args = data;
957 int ret = NOTIFY_DONE;
958
959 if (args->regs && user_mode_vm(args->regs))
960 return ret;
961
962 switch (val) {
963 case DIE_INT3:
964 if (kprobe_handler(args->regs))
965 ret = NOTIFY_STOP;
966 break;
967 case DIE_DEBUG:
968 if (post_kprobe_handler(args->regs))
969 ret = NOTIFY_STOP;
970 break;
971 case DIE_GPF:
972 /*
973 * To be potentially processing a kprobe fault and to
974 * trust the result from kprobe_running(), we have
975 * be non-preemptible.
976 */
977 if (!preemptible() && kprobe_running() &&
978 kprobe_fault_handler(args->regs, args->trapnr))
979 ret = NOTIFY_STOP;
980 break;
981 default:
982 break;
983 }
984 return ret;
985}
986
987int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
988{
989 struct jprobe *jp = container_of(p, struct jprobe, kp);
990 unsigned long addr;
991 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
992
993 kcb->jprobe_saved_regs = *regs;
994 kcb->jprobe_saved_sp = stack_addr(regs);
995 addr = (unsigned long)(kcb->jprobe_saved_sp);
996
997 /*
998 * As Linus pointed out, gcc assumes that the callee
999 * owns the argument space and could overwrite it, e.g.
1000 * tailcall optimization. So, to be absolutely safe
1001 * we also save and restore enough stack bytes to cover
1002 * the argument area.
1003 */
1004 memcpy(kcb->jprobes_stack, (kprobe_opcode_t *)addr,
1005 MIN_STACK_SIZE(addr));
1006 regs->flags &= ~X86_EFLAGS_IF;
1007 trace_hardirqs_off();
1008 regs->ip = (unsigned long)(jp->entry);
1009 return 1;
1010}
1011
1012void __kprobes jprobe_return(void)
1013{
1014 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
1015
1016 asm volatile (
1017#ifdef CONFIG_X86_64
1018 " xchg %%rbx,%%rsp \n"
1019#else
1020 " xchgl %%ebx,%%esp \n"
1021#endif
1022 " int3 \n"
1023 " .globl jprobe_return_end\n"
1024 " jprobe_return_end: \n"
1025 " nop \n"::"b"
1026 (kcb->jprobe_saved_sp):"memory");
1027}
1028
1029int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
1030{
1031 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
1032 u8 *addr = (u8 *) (regs->ip - 1);
1033 struct jprobe *jp = container_of(p, struct jprobe, kp);
1034
1035 if ((addr > (u8 *) jprobe_return) &&
1036 (addr < (u8 *) jprobe_return_end)) {
1037 if (stack_addr(regs) != kcb->jprobe_saved_sp) {
1038 struct pt_regs *saved_regs = &kcb->jprobe_saved_regs;
1039 printk(KERN_ERR
1040 "current sp %p does not match saved sp %p\n",
1041 stack_addr(regs), kcb->jprobe_saved_sp);
1042 printk(KERN_ERR "Saved registers for jprobe %p\n", jp);
1043 show_registers(saved_regs);
1044 printk(KERN_ERR "Current registers\n");
1045 show_registers(regs);
1046 BUG();
1047 }
1048 *regs = kcb->jprobe_saved_regs;
1049 memcpy((kprobe_opcode_t *)(kcb->jprobe_saved_sp),
1050 kcb->jprobes_stack,
1051 MIN_STACK_SIZE(kcb->jprobe_saved_sp));
1052 preempt_enable_no_resched();
1053 return 1;
1054 }
1055 return 0;
1056}
1057
1058int __init arch_init_kprobes(void)
1059{
1060 return 0;
1061}
1062
1063int __kprobes arch_trampoline_kprobe(struct kprobe *p)
1064{
1065 return 0;
1066}
diff --git a/arch/x86/kernel/kprobes_32.c b/arch/x86/kernel/kprobes_32.c
deleted file mode 100644
index 3a020f79f82b..000000000000
--- a/arch/x86/kernel/kprobes_32.c
+++ /dev/null
@@ -1,756 +0,0 @@
1/*
2 * Kernel Probes (KProbes)
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 * Copyright (C) IBM Corporation, 2002, 2004
19 *
20 * 2002-Oct Created by Vamsi Krishna S <vamsi_krishna@in.ibm.com> Kernel
21 * Probes initial implementation ( includes contributions from
22 * Rusty Russell).
23 * 2004-July Suparna Bhattacharya <suparna@in.ibm.com> added jumper probes
24 * interface to access function arguments.
25 * 2005-May Hien Nguyen <hien@us.ibm.com>, Jim Keniston
26 * <jkenisto@us.ibm.com> and Prasanna S Panchamukhi
27 * <prasanna@in.ibm.com> added function-return probes.
28 */
29
30#include <linux/kprobes.h>
31#include <linux/ptrace.h>
32#include <linux/preempt.h>
33#include <linux/kdebug.h>
34#include <asm/cacheflush.h>
35#include <asm/desc.h>
36#include <asm/uaccess.h>
37#include <asm/alternative.h>
38
39void jprobe_return_end(void);
40
41DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
42DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
43
44struct kretprobe_blackpoint kretprobe_blacklist[] = {
45 {"__switch_to", }, /* This function switches only current task, but
46 doesn't switch kernel stack.*/
47 {NULL, NULL} /* Terminator */
48};
49const int kretprobe_blacklist_size = ARRAY_SIZE(kretprobe_blacklist);
50
51/* insert a jmp code */
52static __always_inline void set_jmp_op(void *from, void *to)
53{
54 struct __arch_jmp_op {
55 char op;
56 long raddr;
57 } __attribute__((packed)) *jop;
58 jop = (struct __arch_jmp_op *)from;
59 jop->raddr = (long)(to) - ((long)(from) + 5);
60 jop->op = RELATIVEJUMP_INSTRUCTION;
61}
62
63/*
64 * returns non-zero if opcodes can be boosted.
65 */
66static __always_inline int can_boost(kprobe_opcode_t *opcodes)
67{
68#define W(row,b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,ba,bb,bc,bd,be,bf) \
69 (((b0##UL << 0x0)|(b1##UL << 0x1)|(b2##UL << 0x2)|(b3##UL << 0x3) | \
70 (b4##UL << 0x4)|(b5##UL << 0x5)|(b6##UL << 0x6)|(b7##UL << 0x7) | \
71 (b8##UL << 0x8)|(b9##UL << 0x9)|(ba##UL << 0xa)|(bb##UL << 0xb) | \
72 (bc##UL << 0xc)|(bd##UL << 0xd)|(be##UL << 0xe)|(bf##UL << 0xf)) \
73 << (row % 32))
74 /*
75 * Undefined/reserved opcodes, conditional jump, Opcode Extension
76 * Groups, and some special opcodes can not be boost.
77 */
78 static const unsigned long twobyte_is_boostable[256 / 32] = {
79 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
80 /* ------------------------------- */
81 W(0x00, 0,0,1,1,0,0,1,0,1,1,0,0,0,0,0,0)| /* 00 */
82 W(0x10, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), /* 10 */
83 W(0x20, 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0)| /* 20 */
84 W(0x30, 0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0), /* 30 */
85 W(0x40, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 40 */
86 W(0x50, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), /* 50 */
87 W(0x60, 1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1)| /* 60 */
88 W(0x70, 0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1), /* 70 */
89 W(0x80, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)| /* 80 */
90 W(0x90, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1), /* 90 */
91 W(0xa0, 1,1,0,1,1,1,0,0,1,1,0,1,1,1,0,1)| /* a0 */
92 W(0xb0, 1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1), /* b0 */
93 W(0xc0, 1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1)| /* c0 */
94 W(0xd0, 0,1,1,1,0,1,0,0,1,1,0,1,1,1,0,1), /* d0 */
95 W(0xe0, 0,1,1,0,0,1,0,0,1,1,0,1,1,1,0,1)| /* e0 */
96 W(0xf0, 0,1,1,1,0,1,0,0,1,1,1,0,1,1,1,0) /* f0 */
97 /* ------------------------------- */
98 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
99 };
100#undef W
101 kprobe_opcode_t opcode;
102 kprobe_opcode_t *orig_opcodes = opcodes;
103retry:
104 if (opcodes - orig_opcodes > MAX_INSN_SIZE - 1)
105 return 0;
106 opcode = *(opcodes++);
107
108 /* 2nd-byte opcode */
109 if (opcode == 0x0f) {
110 if (opcodes - orig_opcodes > MAX_INSN_SIZE - 1)
111 return 0;
112 return test_bit(*opcodes, twobyte_is_boostable);
113 }
114
115 switch (opcode & 0xf0) {
116 case 0x60:
117 if (0x63 < opcode && opcode < 0x67)
118 goto retry; /* prefixes */
119 /* can't boost Address-size override and bound */
120 return (opcode != 0x62 && opcode != 0x67);
121 case 0x70:
122 return 0; /* can't boost conditional jump */
123 case 0xc0:
124 /* can't boost software-interruptions */
125 return (0xc1 < opcode && opcode < 0xcc) || opcode == 0xcf;
126 case 0xd0:
127 /* can boost AA* and XLAT */
128 return (opcode == 0xd4 || opcode == 0xd5 || opcode == 0xd7);
129 case 0xe0:
130 /* can boost in/out and absolute jmps */
131 return ((opcode & 0x04) || opcode == 0xea);
132 case 0xf0:
133 if ((opcode & 0x0c) == 0 && opcode != 0xf1)
134 goto retry; /* lock/rep(ne) prefix */
135 /* clear and set flags can be boost */
136 return (opcode == 0xf5 || (0xf7 < opcode && opcode < 0xfe));
137 default:
138 if (opcode == 0x26 || opcode == 0x36 || opcode == 0x3e)
139 goto retry; /* prefixes */
140 /* can't boost CS override and call */
141 return (opcode != 0x2e && opcode != 0x9a);
142 }
143}
144
145/*
146 * returns non-zero if opcode modifies the interrupt flag.
147 */
148static int __kprobes is_IF_modifier(kprobe_opcode_t opcode)
149{
150 switch (opcode) {
151 case 0xfa: /* cli */
152 case 0xfb: /* sti */
153 case 0xcf: /* iret/iretd */
154 case 0x9d: /* popf/popfd */
155 return 1;
156 }
157 return 0;
158}
159
160int __kprobes arch_prepare_kprobe(struct kprobe *p)
161{
162 /* insn: must be on special executable page on i386. */
163 p->ainsn.insn = get_insn_slot();
164 if (!p->ainsn.insn)
165 return -ENOMEM;
166
167 memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
168 p->opcode = *p->addr;
169 if (can_boost(p->addr)) {
170 p->ainsn.boostable = 0;
171 } else {
172 p->ainsn.boostable = -1;
173 }
174 return 0;
175}
176
177void __kprobes arch_arm_kprobe(struct kprobe *p)
178{
179 text_poke(p->addr, ((unsigned char []){BREAKPOINT_INSTRUCTION}), 1);
180}
181
182void __kprobes arch_disarm_kprobe(struct kprobe *p)
183{
184 text_poke(p->addr, &p->opcode, 1);
185}
186
187void __kprobes arch_remove_kprobe(struct kprobe *p)
188{
189 mutex_lock(&kprobe_mutex);
190 free_insn_slot(p->ainsn.insn, (p->ainsn.boostable == 1));
191 mutex_unlock(&kprobe_mutex);
192}
193
194static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
195{
196 kcb->prev_kprobe.kp = kprobe_running();
197 kcb->prev_kprobe.status = kcb->kprobe_status;
198 kcb->prev_kprobe.old_eflags = kcb->kprobe_old_eflags;
199 kcb->prev_kprobe.saved_eflags = kcb->kprobe_saved_eflags;
200}
201
202static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
203{
204 __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
205 kcb->kprobe_status = kcb->prev_kprobe.status;
206 kcb->kprobe_old_eflags = kcb->prev_kprobe.old_eflags;
207 kcb->kprobe_saved_eflags = kcb->prev_kprobe.saved_eflags;
208}
209
210static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
211 struct kprobe_ctlblk *kcb)
212{
213 __get_cpu_var(current_kprobe) = p;
214 kcb->kprobe_saved_eflags = kcb->kprobe_old_eflags
215 = (regs->eflags & (TF_MASK | IF_MASK));
216 if (is_IF_modifier(p->opcode))
217 kcb->kprobe_saved_eflags &= ~IF_MASK;
218}
219
220static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
221{
222 regs->eflags |= TF_MASK;
223 regs->eflags &= ~IF_MASK;
224 /*single step inline if the instruction is an int3*/
225 if (p->opcode == BREAKPOINT_INSTRUCTION)
226 regs->eip = (unsigned long)p->addr;
227 else
228 regs->eip = (unsigned long)p->ainsn.insn;
229}
230
231/* Called with kretprobe_lock held */
232void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
233 struct pt_regs *regs)
234{
235 unsigned long *sara = (unsigned long *)&regs->esp;
236
237 ri->ret_addr = (kprobe_opcode_t *) *sara;
238
239 /* Replace the return addr with trampoline addr */
240 *sara = (unsigned long) &kretprobe_trampoline;
241}
242
243/*
244 * Interrupts are disabled on entry as trap3 is an interrupt gate and they
245 * remain disabled thorough out this function.
246 */
247static int __kprobes kprobe_handler(struct pt_regs *regs)
248{
249 struct kprobe *p;
250 int ret = 0;
251 kprobe_opcode_t *addr;
252 struct kprobe_ctlblk *kcb;
253
254 addr = (kprobe_opcode_t *)(regs->eip - sizeof(kprobe_opcode_t));
255
256 /*
257 * We don't want to be preempted for the entire
258 * duration of kprobe processing
259 */
260 preempt_disable();
261 kcb = get_kprobe_ctlblk();
262
263 /* Check we're not actually recursing */
264 if (kprobe_running()) {
265 p = get_kprobe(addr);
266 if (p) {
267 if (kcb->kprobe_status == KPROBE_HIT_SS &&
268 *p->ainsn.insn == BREAKPOINT_INSTRUCTION) {
269 regs->eflags &= ~TF_MASK;
270 regs->eflags |= kcb->kprobe_saved_eflags;
271 goto no_kprobe;
272 }
273 /* We have reentered the kprobe_handler(), since
274 * another probe was hit while within the handler.
275 * We here save the original kprobes variables and
276 * just single step on the instruction of the new probe
277 * without calling any user handlers.
278 */
279 save_previous_kprobe(kcb);
280 set_current_kprobe(p, regs, kcb);
281 kprobes_inc_nmissed_count(p);
282 prepare_singlestep(p, regs);
283 kcb->kprobe_status = KPROBE_REENTER;
284 return 1;
285 } else {
286 if (*addr != BREAKPOINT_INSTRUCTION) {
287 /* The breakpoint instruction was removed by
288 * another cpu right after we hit, no further
289 * handling of this interrupt is appropriate
290 */
291 regs->eip -= sizeof(kprobe_opcode_t);
292 ret = 1;
293 goto no_kprobe;
294 }
295 p = __get_cpu_var(current_kprobe);
296 if (p->break_handler && p->break_handler(p, regs)) {
297 goto ss_probe;
298 }
299 }
300 goto no_kprobe;
301 }
302
303 p = get_kprobe(addr);
304 if (!p) {
305 if (*addr != BREAKPOINT_INSTRUCTION) {
306 /*
307 * The breakpoint instruction was removed right
308 * after we hit it. Another cpu has removed
309 * either a probepoint or a debugger breakpoint
310 * at this address. In either case, no further
311 * handling of this interrupt is appropriate.
312 * Back up over the (now missing) int3 and run
313 * the original instruction.
314 */
315 regs->eip -= sizeof(kprobe_opcode_t);
316 ret = 1;
317 }
318 /* Not one of ours: let kernel handle it */
319 goto no_kprobe;
320 }
321
322 set_current_kprobe(p, regs, kcb);
323 kcb->kprobe_status = KPROBE_HIT_ACTIVE;
324
325 if (p->pre_handler && p->pre_handler(p, regs))
326 /* handler has already set things up, so skip ss setup */
327 return 1;
328
329ss_probe:
330#if !defined(CONFIG_PREEMPT) || defined(CONFIG_PM)
331 if (p->ainsn.boostable == 1 && !p->post_handler){
332 /* Boost up -- we can execute copied instructions directly */
333 reset_current_kprobe();
334 regs->eip = (unsigned long)p->ainsn.insn;
335 preempt_enable_no_resched();
336 return 1;
337 }
338#endif
339 prepare_singlestep(p, regs);
340 kcb->kprobe_status = KPROBE_HIT_SS;
341 return 1;
342
343no_kprobe:
344 preempt_enable_no_resched();
345 return ret;
346}
347
348/*
349 * For function-return probes, init_kprobes() establishes a probepoint
350 * here. When a retprobed function returns, this probe is hit and
351 * trampoline_probe_handler() runs, calling the kretprobe's handler.
352 */
353 void __kprobes kretprobe_trampoline_holder(void)
354 {
355 asm volatile ( ".global kretprobe_trampoline\n"
356 "kretprobe_trampoline: \n"
357 " pushf\n"
358 /* skip cs, eip, orig_eax */
359 " subl $12, %esp\n"
360 " pushl %fs\n"
361 " pushl %ds\n"
362 " pushl %es\n"
363 " pushl %eax\n"
364 " pushl %ebp\n"
365 " pushl %edi\n"
366 " pushl %esi\n"
367 " pushl %edx\n"
368 " pushl %ecx\n"
369 " pushl %ebx\n"
370 " movl %esp, %eax\n"
371 " call trampoline_handler\n"
372 /* move eflags to cs */
373 " movl 52(%esp), %edx\n"
374 " movl %edx, 48(%esp)\n"
375 /* save true return address on eflags */
376 " movl %eax, 52(%esp)\n"
377 " popl %ebx\n"
378 " popl %ecx\n"
379 " popl %edx\n"
380 " popl %esi\n"
381 " popl %edi\n"
382 " popl %ebp\n"
383 " popl %eax\n"
384 /* skip eip, orig_eax, es, ds, fs */
385 " addl $20, %esp\n"
386 " popf\n"
387 " ret\n");
388}
389
390/*
391 * Called from kretprobe_trampoline
392 */
393fastcall void *__kprobes trampoline_handler(struct pt_regs *regs)
394{
395 struct kretprobe_instance *ri = NULL;
396 struct hlist_head *head, empty_rp;
397 struct hlist_node *node, *tmp;
398 unsigned long flags, orig_ret_address = 0;
399 unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline;
400
401 INIT_HLIST_HEAD(&empty_rp);
402 spin_lock_irqsave(&kretprobe_lock, flags);
403 head = kretprobe_inst_table_head(current);
404 /* fixup registers */
405 regs->xcs = __KERNEL_CS | get_kernel_rpl();
406 regs->eip = trampoline_address;
407 regs->orig_eax = 0xffffffff;
408
409 /*
410 * It is possible to have multiple instances associated with a given
411 * task either because an multiple functions in the call path
412 * have a return probe installed on them, and/or more then one return
413 * return probe was registered for a target function.
414 *
415 * We can handle this because:
416 * - instances are always inserted at the head of the list
417 * - when multiple return probes are registered for the same
418 * function, the first instance's ret_addr will point to the
419 * real return address, and all the rest will point to
420 * kretprobe_trampoline
421 */
422 hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
423 if (ri->task != current)
424 /* another task is sharing our hash bucket */
425 continue;
426
427 if (ri->rp && ri->rp->handler){
428 __get_cpu_var(current_kprobe) = &ri->rp->kp;
429 get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
430 ri->rp->handler(ri, regs);
431 __get_cpu_var(current_kprobe) = NULL;
432 }
433
434 orig_ret_address = (unsigned long)ri->ret_addr;
435 recycle_rp_inst(ri, &empty_rp);
436
437 if (orig_ret_address != trampoline_address)
438 /*
439 * This is the real return address. Any other
440 * instances associated with this task are for
441 * other calls deeper on the call stack
442 */
443 break;
444 }
445
446 kretprobe_assert(ri, orig_ret_address, trampoline_address);
447 spin_unlock_irqrestore(&kretprobe_lock, flags);
448
449 hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
450 hlist_del(&ri->hlist);
451 kfree(ri);
452 }
453 return (void*)orig_ret_address;
454}
455
456/*
457 * Called after single-stepping. p->addr is the address of the
458 * instruction whose first byte has been replaced by the "int 3"
459 * instruction. To avoid the SMP problems that can occur when we
460 * temporarily put back the original opcode to single-step, we
461 * single-stepped a copy of the instruction. The address of this
462 * copy is p->ainsn.insn.
463 *
464 * This function prepares to return from the post-single-step
465 * interrupt. We have to fix up the stack as follows:
466 *
467 * 0) Except in the case of absolute or indirect jump or call instructions,
468 * the new eip is relative to the copied instruction. We need to make
469 * it relative to the original instruction.
470 *
471 * 1) If the single-stepped instruction was pushfl, then the TF and IF
472 * flags are set in the just-pushed eflags, and may need to be cleared.
473 *
474 * 2) If the single-stepped instruction was a call, the return address
475 * that is atop the stack is the address following the copied instruction.
476 * We need to make it the address following the original instruction.
477 *
478 * This function also checks instruction size for preparing direct execution.
479 */
480static void __kprobes resume_execution(struct kprobe *p,
481 struct pt_regs *regs, struct kprobe_ctlblk *kcb)
482{
483 unsigned long *tos = (unsigned long *)&regs->esp;
484 unsigned long copy_eip = (unsigned long)p->ainsn.insn;
485 unsigned long orig_eip = (unsigned long)p->addr;
486
487 regs->eflags &= ~TF_MASK;
488 switch (p->ainsn.insn[0]) {
489 case 0x9c: /* pushfl */
490 *tos &= ~(TF_MASK | IF_MASK);
491 *tos |= kcb->kprobe_old_eflags;
492 break;
493 case 0xc2: /* iret/ret/lret */
494 case 0xc3:
495 case 0xca:
496 case 0xcb:
497 case 0xcf:
498 case 0xea: /* jmp absolute -- eip is correct */
499 /* eip is already adjusted, no more changes required */
500 p->ainsn.boostable = 1;
501 goto no_change;
502 case 0xe8: /* call relative - Fix return addr */
503 *tos = orig_eip + (*tos - copy_eip);
504 break;
505 case 0x9a: /* call absolute -- same as call absolute, indirect */
506 *tos = orig_eip + (*tos - copy_eip);
507 goto no_change;
508 case 0xff:
509 if ((p->ainsn.insn[1] & 0x30) == 0x10) {
510 /*
511 * call absolute, indirect
512 * Fix return addr; eip is correct.
513 * But this is not boostable
514 */
515 *tos = orig_eip + (*tos - copy_eip);
516 goto no_change;
517 } else if (((p->ainsn.insn[1] & 0x31) == 0x20) || /* jmp near, absolute indirect */
518 ((p->ainsn.insn[1] & 0x31) == 0x21)) { /* jmp far, absolute indirect */
519 /* eip is correct. And this is boostable */
520 p->ainsn.boostable = 1;
521 goto no_change;
522 }
523 default:
524 break;
525 }
526
527 if (p->ainsn.boostable == 0) {
528 if ((regs->eip > copy_eip) &&
529 (regs->eip - copy_eip) + 5 < MAX_INSN_SIZE) {
530 /*
531 * These instructions can be executed directly if it
532 * jumps back to correct address.
533 */
534 set_jmp_op((void *)regs->eip,
535 (void *)orig_eip + (regs->eip - copy_eip));
536 p->ainsn.boostable = 1;
537 } else {
538 p->ainsn.boostable = -1;
539 }
540 }
541
542 regs->eip = orig_eip + (regs->eip - copy_eip);
543
544no_change:
545 return;
546}
547
548/*
549 * Interrupts are disabled on entry as trap1 is an interrupt gate and they
550 * remain disabled thoroughout this function.
551 */
552static int __kprobes post_kprobe_handler(struct pt_regs *regs)
553{
554 struct kprobe *cur = kprobe_running();
555 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
556
557 if (!cur)
558 return 0;
559
560 if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
561 kcb->kprobe_status = KPROBE_HIT_SSDONE;
562 cur->post_handler(cur, regs, 0);
563 }
564
565 resume_execution(cur, regs, kcb);
566 regs->eflags |= kcb->kprobe_saved_eflags;
567 trace_hardirqs_fixup_flags(regs->eflags);
568
569 /*Restore back the original saved kprobes variables and continue. */
570 if (kcb->kprobe_status == KPROBE_REENTER) {
571 restore_previous_kprobe(kcb);
572 goto out;
573 }
574 reset_current_kprobe();
575out:
576 preempt_enable_no_resched();
577
578 /*
579 * if somebody else is singlestepping across a probe point, eflags
580 * will have TF set, in which case, continue the remaining processing
581 * of do_debug, as if this is not a probe hit.
582 */
583 if (regs->eflags & TF_MASK)
584 return 0;
585
586 return 1;
587}
588
589int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
590{
591 struct kprobe *cur = kprobe_running();
592 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
593
594 switch(kcb->kprobe_status) {
595 case KPROBE_HIT_SS:
596 case KPROBE_REENTER:
597 /*
598 * We are here because the instruction being single
599 * stepped caused a page fault. We reset the current
600 * kprobe and the eip points back to the probe address
601 * and allow the page fault handler to continue as a
602 * normal page fault.
603 */
604 regs->eip = (unsigned long)cur->addr;
605 regs->eflags |= kcb->kprobe_old_eflags;
606 if (kcb->kprobe_status == KPROBE_REENTER)
607 restore_previous_kprobe(kcb);
608 else
609 reset_current_kprobe();
610 preempt_enable_no_resched();
611 break;
612 case KPROBE_HIT_ACTIVE:
613 case KPROBE_HIT_SSDONE:
614 /*
615 * We increment the nmissed count for accounting,
616 * we can also use npre/npostfault count for accouting
617 * these specific fault cases.
618 */
619 kprobes_inc_nmissed_count(cur);
620
621 /*
622 * We come here because instructions in the pre/post
623 * handler caused the page_fault, this could happen
624 * if handler tries to access user space by
625 * copy_from_user(), get_user() etc. Let the
626 * user-specified handler try to fix it first.
627 */
628 if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
629 return 1;
630
631 /*
632 * In case the user-specified fault handler returned
633 * zero, try to fix up.
634 */
635 if (fixup_exception(regs))
636 return 1;
637
638 /*
639 * fixup_exception() could not handle it,
640 * Let do_page_fault() fix it.
641 */
642 break;
643 default:
644 break;
645 }
646 return 0;
647}
648
649/*
650 * Wrapper routine to for handling exceptions.
651 */
652int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
653 unsigned long val, void *data)
654{
655 struct die_args *args = (struct die_args *)data;
656 int ret = NOTIFY_DONE;
657
658 if (args->regs && user_mode_vm(args->regs))
659 return ret;
660
661 switch (val) {
662 case DIE_INT3:
663 if (kprobe_handler(args->regs))
664 ret = NOTIFY_STOP;
665 break;
666 case DIE_DEBUG:
667 if (post_kprobe_handler(args->regs))
668 ret = NOTIFY_STOP;
669 break;
670 case DIE_GPF:
671 /* kprobe_running() needs smp_processor_id() */
672 preempt_disable();
673 if (kprobe_running() &&
674 kprobe_fault_handler(args->regs, args->trapnr))
675 ret = NOTIFY_STOP;
676 preempt_enable();
677 break;
678 default:
679 break;
680 }
681 return ret;
682}
683
684int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
685{
686 struct jprobe *jp = container_of(p, struct jprobe, kp);
687 unsigned long addr;
688 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
689
690 kcb->jprobe_saved_regs = *regs;
691 kcb->jprobe_saved_esp = &regs->esp;
692 addr = (unsigned long)(kcb->jprobe_saved_esp);
693
694 /*
695 * TBD: As Linus pointed out, gcc assumes that the callee
696 * owns the argument space and could overwrite it, e.g.
697 * tailcall optimization. So, to be absolutely safe
698 * we also save and restore enough stack bytes to cover
699 * the argument area.
700 */
701 memcpy(kcb->jprobes_stack, (kprobe_opcode_t *)addr,
702 MIN_STACK_SIZE(addr));
703 regs->eflags &= ~IF_MASK;
704 trace_hardirqs_off();
705 regs->eip = (unsigned long)(jp->entry);
706 return 1;
707}
708
709void __kprobes jprobe_return(void)
710{
711 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
712
713 asm volatile (" xchgl %%ebx,%%esp \n"
714 " int3 \n"
715 " .globl jprobe_return_end \n"
716 " jprobe_return_end: \n"
717 " nop \n"::"b"
718 (kcb->jprobe_saved_esp):"memory");
719}
720
721int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
722{
723 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
724 u8 *addr = (u8 *) (regs->eip - 1);
725 unsigned long stack_addr = (unsigned long)(kcb->jprobe_saved_esp);
726 struct jprobe *jp = container_of(p, struct jprobe, kp);
727
728 if ((addr > (u8 *) jprobe_return) && (addr < (u8 *) jprobe_return_end)) {
729 if (&regs->esp != kcb->jprobe_saved_esp) {
730 struct pt_regs *saved_regs = &kcb->jprobe_saved_regs;
731 printk("current esp %p does not match saved esp %p\n",
732 &regs->esp, kcb->jprobe_saved_esp);
733 printk("Saved registers for jprobe %p\n", jp);
734 show_registers(saved_regs);
735 printk("Current registers\n");
736 show_registers(regs);
737 BUG();
738 }
739 *regs = kcb->jprobe_saved_regs;
740 memcpy((kprobe_opcode_t *) stack_addr, kcb->jprobes_stack,
741 MIN_STACK_SIZE(stack_addr));
742 preempt_enable_no_resched();
743 return 1;
744 }
745 return 0;
746}
747
748int __kprobes arch_trampoline_kprobe(struct kprobe *p)
749{
750 return 0;
751}
752
753int __init arch_init_kprobes(void)
754{
755 return 0;
756}
diff --git a/arch/x86/kernel/kprobes_64.c b/arch/x86/kernel/kprobes_64.c
deleted file mode 100644
index 5df19a9f9239..000000000000
--- a/arch/x86/kernel/kprobes_64.c
+++ /dev/null
@@ -1,749 +0,0 @@
1/*
2 * Kernel Probes (KProbes)
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 * Copyright (C) IBM Corporation, 2002, 2004
19 *
20 * 2002-Oct Created by Vamsi Krishna S <vamsi_krishna@in.ibm.com> Kernel
21 * Probes initial implementation ( includes contributions from
22 * Rusty Russell).
23 * 2004-July Suparna Bhattacharya <suparna@in.ibm.com> added jumper probes
24 * interface to access function arguments.
25 * 2004-Oct Jim Keniston <kenistoj@us.ibm.com> and Prasanna S Panchamukhi
26 * <prasanna@in.ibm.com> adapted for x86_64
27 * 2005-Mar Roland McGrath <roland@redhat.com>
28 * Fixed to handle %rip-relative addressing mode correctly.
29 * 2005-May Rusty Lynch <rusty.lynch@intel.com>
30 * Added function return probes functionality
31 */
32
33#include <linux/kprobes.h>
34#include <linux/ptrace.h>
35#include <linux/string.h>
36#include <linux/slab.h>
37#include <linux/preempt.h>
38#include <linux/module.h>
39#include <linux/kdebug.h>
40
41#include <asm/pgtable.h>
42#include <asm/uaccess.h>
43#include <asm/alternative.h>
44
45void jprobe_return_end(void);
46static void __kprobes arch_copy_kprobe(struct kprobe *p);
47
48DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
49DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
50
51struct kretprobe_blackpoint kretprobe_blacklist[] = {
52 {"__switch_to", }, /* This function switches only current task, but
53 doesn't switch kernel stack.*/
54 {NULL, NULL} /* Terminator */
55};
56const int kretprobe_blacklist_size = ARRAY_SIZE(kretprobe_blacklist);
57
58/*
59 * returns non-zero if opcode modifies the interrupt flag.
60 */
61static int __kprobes is_IF_modifier(kprobe_opcode_t *insn)
62{
63 switch (*insn) {
64 case 0xfa: /* cli */
65 case 0xfb: /* sti */
66 case 0xcf: /* iret/iretd */
67 case 0x9d: /* popf/popfd */
68 return 1;
69 }
70
71 if (*insn >= 0x40 && *insn <= 0x4f && *++insn == 0xcf)
72 return 1;
73 return 0;
74}
75
76int __kprobes arch_prepare_kprobe(struct kprobe *p)
77{
78 /* insn: must be on special executable page on x86_64. */
79 p->ainsn.insn = get_insn_slot();
80 if (!p->ainsn.insn) {
81 return -ENOMEM;
82 }
83 arch_copy_kprobe(p);
84 return 0;
85}
86
87/*
88 * Determine if the instruction uses the %rip-relative addressing mode.
89 * If it does, return the address of the 32-bit displacement word.
90 * If not, return null.
91 */
92static s32 __kprobes *is_riprel(u8 *insn)
93{
94#define W(row,b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,ba,bb,bc,bd,be,bf) \
95 (((b0##UL << 0x0)|(b1##UL << 0x1)|(b2##UL << 0x2)|(b3##UL << 0x3) | \
96 (b4##UL << 0x4)|(b5##UL << 0x5)|(b6##UL << 0x6)|(b7##UL << 0x7) | \
97 (b8##UL << 0x8)|(b9##UL << 0x9)|(ba##UL << 0xa)|(bb##UL << 0xb) | \
98 (bc##UL << 0xc)|(bd##UL << 0xd)|(be##UL << 0xe)|(bf##UL << 0xf)) \
99 << (row % 64))
100 static const u64 onebyte_has_modrm[256 / 64] = {
101 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
102 /* ------------------------------- */
103 W(0x00, 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0)| /* 00 */
104 W(0x10, 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0)| /* 10 */
105 W(0x20, 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0)| /* 20 */
106 W(0x30, 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0), /* 30 */
107 W(0x40, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)| /* 40 */
108 W(0x50, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)| /* 50 */
109 W(0x60, 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0)| /* 60 */
110 W(0x70, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), /* 70 */
111 W(0x80, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 80 */
112 W(0x90, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)| /* 90 */
113 W(0xa0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)| /* a0 */
114 W(0xb0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), /* b0 */
115 W(0xc0, 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0)| /* c0 */
116 W(0xd0, 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1)| /* d0 */
117 W(0xe0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)| /* e0 */
118 W(0xf0, 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1) /* f0 */
119 /* ------------------------------- */
120 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
121 };
122 static const u64 twobyte_has_modrm[256 / 64] = {
123 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
124 /* ------------------------------- */
125 W(0x00, 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1)| /* 0f */
126 W(0x10, 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0)| /* 1f */
127 W(0x20, 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1)| /* 2f */
128 W(0x30, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), /* 3f */
129 W(0x40, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 4f */
130 W(0x50, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 5f */
131 W(0x60, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 6f */
132 W(0x70, 1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1), /* 7f */
133 W(0x80, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)| /* 8f */
134 W(0x90, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 9f */
135 W(0xa0, 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1)| /* af */
136 W(0xb0, 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1), /* bf */
137 W(0xc0, 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0)| /* cf */
138 W(0xd0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* df */
139 W(0xe0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* ef */
140 W(0xf0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0) /* ff */
141 /* ------------------------------- */
142 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
143 };
144#undef W
145 int need_modrm;
146
147 /* Skip legacy instruction prefixes. */
148 while (1) {
149 switch (*insn) {
150 case 0x66:
151 case 0x67:
152 case 0x2e:
153 case 0x3e:
154 case 0x26:
155 case 0x64:
156 case 0x65:
157 case 0x36:
158 case 0xf0:
159 case 0xf3:
160 case 0xf2:
161 ++insn;
162 continue;
163 }
164 break;
165 }
166
167 /* Skip REX instruction prefix. */
168 if ((*insn & 0xf0) == 0x40)
169 ++insn;
170
171 if (*insn == 0x0f) { /* Two-byte opcode. */
172 ++insn;
173 need_modrm = test_bit(*insn, twobyte_has_modrm);
174 } else { /* One-byte opcode. */
175 need_modrm = test_bit(*insn, onebyte_has_modrm);
176 }
177
178 if (need_modrm) {
179 u8 modrm = *++insn;
180 if ((modrm & 0xc7) == 0x05) { /* %rip+disp32 addressing mode */
181 /* Displacement follows ModRM byte. */
182 return (s32 *) ++insn;
183 }
184 }
185
186 /* No %rip-relative addressing mode here. */
187 return NULL;
188}
189
190static void __kprobes arch_copy_kprobe(struct kprobe *p)
191{
192 s32 *ripdisp;
193 memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE);
194 ripdisp = is_riprel(p->ainsn.insn);
195 if (ripdisp) {
196 /*
197 * The copied instruction uses the %rip-relative
198 * addressing mode. Adjust the displacement for the
199 * difference between the original location of this
200 * instruction and the location of the copy that will
201 * actually be run. The tricky bit here is making sure
202 * that the sign extension happens correctly in this
203 * calculation, since we need a signed 32-bit result to
204 * be sign-extended to 64 bits when it's added to the
205 * %rip value and yield the same 64-bit result that the
206 * sign-extension of the original signed 32-bit
207 * displacement would have given.
208 */
209 s64 disp = (u8 *) p->addr + *ripdisp - (u8 *) p->ainsn.insn;
210 BUG_ON((s64) (s32) disp != disp); /* Sanity check. */
211 *ripdisp = disp;
212 }
213 p->opcode = *p->addr;
214}
215
216void __kprobes arch_arm_kprobe(struct kprobe *p)
217{
218 text_poke(p->addr, ((unsigned char []){BREAKPOINT_INSTRUCTION}), 1);
219}
220
221void __kprobes arch_disarm_kprobe(struct kprobe *p)
222{
223 text_poke(p->addr, &p->opcode, 1);
224}
225
226void __kprobes arch_remove_kprobe(struct kprobe *p)
227{
228 mutex_lock(&kprobe_mutex);
229 free_insn_slot(p->ainsn.insn, 0);
230 mutex_unlock(&kprobe_mutex);
231}
232
233static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
234{
235 kcb->prev_kprobe.kp = kprobe_running();
236 kcb->prev_kprobe.status = kcb->kprobe_status;
237 kcb->prev_kprobe.old_rflags = kcb->kprobe_old_rflags;
238 kcb->prev_kprobe.saved_rflags = kcb->kprobe_saved_rflags;
239}
240
241static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
242{
243 __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
244 kcb->kprobe_status = kcb->prev_kprobe.status;
245 kcb->kprobe_old_rflags = kcb->prev_kprobe.old_rflags;
246 kcb->kprobe_saved_rflags = kcb->prev_kprobe.saved_rflags;
247}
248
249static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
250 struct kprobe_ctlblk *kcb)
251{
252 __get_cpu_var(current_kprobe) = p;
253 kcb->kprobe_saved_rflags = kcb->kprobe_old_rflags
254 = (regs->eflags & (TF_MASK | IF_MASK));
255 if (is_IF_modifier(p->ainsn.insn))
256 kcb->kprobe_saved_rflags &= ~IF_MASK;
257}
258
259static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
260{
261 regs->eflags |= TF_MASK;
262 regs->eflags &= ~IF_MASK;
263 /*single step inline if the instruction is an int3*/
264 if (p->opcode == BREAKPOINT_INSTRUCTION)
265 regs->rip = (unsigned long)p->addr;
266 else
267 regs->rip = (unsigned long)p->ainsn.insn;
268}
269
270/* Called with kretprobe_lock held */
271void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
272 struct pt_regs *regs)
273{
274 unsigned long *sara = (unsigned long *)regs->rsp;
275
276 ri->ret_addr = (kprobe_opcode_t *) *sara;
277 /* Replace the return addr with trampoline addr */
278 *sara = (unsigned long) &kretprobe_trampoline;
279}
280
281int __kprobes kprobe_handler(struct pt_regs *regs)
282{
283 struct kprobe *p;
284 int ret = 0;
285 kprobe_opcode_t *addr = (kprobe_opcode_t *)(regs->rip - sizeof(kprobe_opcode_t));
286 struct kprobe_ctlblk *kcb;
287
288 /*
289 * We don't want to be preempted for the entire
290 * duration of kprobe processing
291 */
292 preempt_disable();
293 kcb = get_kprobe_ctlblk();
294
295 /* Check we're not actually recursing */
296 if (kprobe_running()) {
297 p = get_kprobe(addr);
298 if (p) {
299 if (kcb->kprobe_status == KPROBE_HIT_SS &&
300 *p->ainsn.insn == BREAKPOINT_INSTRUCTION) {
301 regs->eflags &= ~TF_MASK;
302 regs->eflags |= kcb->kprobe_saved_rflags;
303 goto no_kprobe;
304 } else if (kcb->kprobe_status == KPROBE_HIT_SSDONE) {
305 /* TODO: Provide re-entrancy from
306 * post_kprobes_handler() and avoid exception
307 * stack corruption while single-stepping on
308 * the instruction of the new probe.
309 */
310 arch_disarm_kprobe(p);
311 regs->rip = (unsigned long)p->addr;
312 reset_current_kprobe();
313 ret = 1;
314 } else {
315 /* We have reentered the kprobe_handler(), since
316 * another probe was hit while within the
317 * handler. We here save the original kprobe
318 * variables and just single step on instruction
319 * of the new probe without calling any user
320 * handlers.
321 */
322 save_previous_kprobe(kcb);
323 set_current_kprobe(p, regs, kcb);
324 kprobes_inc_nmissed_count(p);
325 prepare_singlestep(p, regs);
326 kcb->kprobe_status = KPROBE_REENTER;
327 return 1;
328 }
329 } else {
330 if (*addr != BREAKPOINT_INSTRUCTION) {
331 /* The breakpoint instruction was removed by
332 * another cpu right after we hit, no further
333 * handling of this interrupt is appropriate
334 */
335 regs->rip = (unsigned long)addr;
336 ret = 1;
337 goto no_kprobe;
338 }
339 p = __get_cpu_var(current_kprobe);
340 if (p->break_handler && p->break_handler(p, regs)) {
341 goto ss_probe;
342 }
343 }
344 goto no_kprobe;
345 }
346
347 p = get_kprobe(addr);
348 if (!p) {
349 if (*addr != BREAKPOINT_INSTRUCTION) {
350 /*
351 * The breakpoint instruction was removed right
352 * after we hit it. Another cpu has removed
353 * either a probepoint or a debugger breakpoint
354 * at this address. In either case, no further
355 * handling of this interrupt is appropriate.
356 * Back up over the (now missing) int3 and run
357 * the original instruction.
358 */
359 regs->rip = (unsigned long)addr;
360 ret = 1;
361 }
362 /* Not one of ours: let kernel handle it */
363 goto no_kprobe;
364 }
365
366 set_current_kprobe(p, regs, kcb);
367 kcb->kprobe_status = KPROBE_HIT_ACTIVE;
368
369 if (p->pre_handler && p->pre_handler(p, regs))
370 /* handler has already set things up, so skip ss setup */
371 return 1;
372
373ss_probe:
374 prepare_singlestep(p, regs);
375 kcb->kprobe_status = KPROBE_HIT_SS;
376 return 1;
377
378no_kprobe:
379 preempt_enable_no_resched();
380 return ret;
381}
382
383/*
384 * For function-return probes, init_kprobes() establishes a probepoint
385 * here. When a retprobed function returns, this probe is hit and
386 * trampoline_probe_handler() runs, calling the kretprobe's handler.
387 */
388 void kretprobe_trampoline_holder(void)
389 {
390 asm volatile ( ".global kretprobe_trampoline\n"
391 "kretprobe_trampoline: \n"
392 "nop\n");
393 }
394
395/*
396 * Called when we hit the probe point at kretprobe_trampoline
397 */
398int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
399{
400 struct kretprobe_instance *ri = NULL;
401 struct hlist_head *head, empty_rp;
402 struct hlist_node *node, *tmp;
403 unsigned long flags, orig_ret_address = 0;
404 unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline;
405
406 INIT_HLIST_HEAD(&empty_rp);
407 spin_lock_irqsave(&kretprobe_lock, flags);
408 head = kretprobe_inst_table_head(current);
409
410 /*
411 * It is possible to have multiple instances associated with a given
412 * task either because an multiple functions in the call path
413 * have a return probe installed on them, and/or more then one return
414 * return probe was registered for a target function.
415 *
416 * We can handle this because:
417 * - instances are always inserted at the head of the list
418 * - when multiple return probes are registered for the same
419 * function, the first instance's ret_addr will point to the
420 * real return address, and all the rest will point to
421 * kretprobe_trampoline
422 */
423 hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
424 if (ri->task != current)
425 /* another task is sharing our hash bucket */
426 continue;
427
428 if (ri->rp && ri->rp->handler)
429 ri->rp->handler(ri, regs);
430
431 orig_ret_address = (unsigned long)ri->ret_addr;
432 recycle_rp_inst(ri, &empty_rp);
433
434 if (orig_ret_address != trampoline_address)
435 /*
436 * This is the real return address. Any other
437 * instances associated with this task are for
438 * other calls deeper on the call stack
439 */
440 break;
441 }
442
443 kretprobe_assert(ri, orig_ret_address, trampoline_address);
444 regs->rip = orig_ret_address;
445
446 reset_current_kprobe();
447 spin_unlock_irqrestore(&kretprobe_lock, flags);
448 preempt_enable_no_resched();
449
450 hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
451 hlist_del(&ri->hlist);
452 kfree(ri);
453 }
454 /*
455 * By returning a non-zero value, we are telling
456 * kprobe_handler() that we don't want the post_handler
457 * to run (and have re-enabled preemption)
458 */
459 return 1;
460}
461
462/*
463 * Called after single-stepping. p->addr is the address of the
464 * instruction whose first byte has been replaced by the "int 3"
465 * instruction. To avoid the SMP problems that can occur when we
466 * temporarily put back the original opcode to single-step, we
467 * single-stepped a copy of the instruction. The address of this
468 * copy is p->ainsn.insn.
469 *
470 * This function prepares to return from the post-single-step
471 * interrupt. We have to fix up the stack as follows:
472 *
473 * 0) Except in the case of absolute or indirect jump or call instructions,
474 * the new rip is relative to the copied instruction. We need to make
475 * it relative to the original instruction.
476 *
477 * 1) If the single-stepped instruction was pushfl, then the TF and IF
478 * flags are set in the just-pushed eflags, and may need to be cleared.
479 *
480 * 2) If the single-stepped instruction was a call, the return address
481 * that is atop the stack is the address following the copied instruction.
482 * We need to make it the address following the original instruction.
483 */
484static void __kprobes resume_execution(struct kprobe *p,
485 struct pt_regs *regs, struct kprobe_ctlblk *kcb)
486{
487 unsigned long *tos = (unsigned long *)regs->rsp;
488 unsigned long copy_rip = (unsigned long)p->ainsn.insn;
489 unsigned long orig_rip = (unsigned long)p->addr;
490 kprobe_opcode_t *insn = p->ainsn.insn;
491
492 /*skip the REX prefix*/
493 if (*insn >= 0x40 && *insn <= 0x4f)
494 insn++;
495
496 regs->eflags &= ~TF_MASK;
497 switch (*insn) {
498 case 0x9c: /* pushfl */
499 *tos &= ~(TF_MASK | IF_MASK);
500 *tos |= kcb->kprobe_old_rflags;
501 break;
502 case 0xc2: /* iret/ret/lret */
503 case 0xc3:
504 case 0xca:
505 case 0xcb:
506 case 0xcf:
507 case 0xea: /* jmp absolute -- ip is correct */
508 /* ip is already adjusted, no more changes required */
509 goto no_change;
510 case 0xe8: /* call relative - Fix return addr */
511 *tos = orig_rip + (*tos - copy_rip);
512 break;
513 case 0xff:
514 if ((insn[1] & 0x30) == 0x10) {
515 /* call absolute, indirect */
516 /* Fix return addr; ip is correct. */
517 *tos = orig_rip + (*tos - copy_rip);
518 goto no_change;
519 } else if (((insn[1] & 0x31) == 0x20) || /* jmp near, absolute indirect */
520 ((insn[1] & 0x31) == 0x21)) { /* jmp far, absolute indirect */
521 /* ip is correct. */
522 goto no_change;
523 }
524 default:
525 break;
526 }
527
528 regs->rip = orig_rip + (regs->rip - copy_rip);
529no_change:
530
531 return;
532}
533
534int __kprobes post_kprobe_handler(struct pt_regs *regs)
535{
536 struct kprobe *cur = kprobe_running();
537 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
538
539 if (!cur)
540 return 0;
541
542 if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
543 kcb->kprobe_status = KPROBE_HIT_SSDONE;
544 cur->post_handler(cur, regs, 0);
545 }
546
547 resume_execution(cur, regs, kcb);
548 regs->eflags |= kcb->kprobe_saved_rflags;
549 trace_hardirqs_fixup_flags(regs->eflags);
550
551 /* Restore the original saved kprobes variables and continue. */
552 if (kcb->kprobe_status == KPROBE_REENTER) {
553 restore_previous_kprobe(kcb);
554 goto out;
555 }
556 reset_current_kprobe();
557out:
558 preempt_enable_no_resched();
559
560 /*
561 * if somebody else is singlestepping across a probe point, eflags
562 * will have TF set, in which case, continue the remaining processing
563 * of do_debug, as if this is not a probe hit.
564 */
565 if (regs->eflags & TF_MASK)
566 return 0;
567
568 return 1;
569}
570
571int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
572{
573 struct kprobe *cur = kprobe_running();
574 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
575 const struct exception_table_entry *fixup;
576
577 switch(kcb->kprobe_status) {
578 case KPROBE_HIT_SS:
579 case KPROBE_REENTER:
580 /*
581 * We are here because the instruction being single
582 * stepped caused a page fault. We reset the current
583 * kprobe and the rip points back to the probe address
584 * and allow the page fault handler to continue as a
585 * normal page fault.
586 */
587 regs->rip = (unsigned long)cur->addr;
588 regs->eflags |= kcb->kprobe_old_rflags;
589 if (kcb->kprobe_status == KPROBE_REENTER)
590 restore_previous_kprobe(kcb);
591 else
592 reset_current_kprobe();
593 preempt_enable_no_resched();
594 break;
595 case KPROBE_HIT_ACTIVE:
596 case KPROBE_HIT_SSDONE:
597 /*
598 * We increment the nmissed count for accounting,
599 * we can also use npre/npostfault count for accouting
600 * these specific fault cases.
601 */
602 kprobes_inc_nmissed_count(cur);
603
604 /*
605 * We come here because instructions in the pre/post
606 * handler caused the page_fault, this could happen
607 * if handler tries to access user space by
608 * copy_from_user(), get_user() etc. Let the
609 * user-specified handler try to fix it first.
610 */
611 if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
612 return 1;
613
614 /*
615 * In case the user-specified fault handler returned
616 * zero, try to fix up.
617 */
618 fixup = search_exception_tables(regs->rip);
619 if (fixup) {
620 regs->rip = fixup->fixup;
621 return 1;
622 }
623
624 /*
625 * fixup() could not handle it,
626 * Let do_page_fault() fix it.
627 */
628 break;
629 default:
630 break;
631 }
632 return 0;
633}
634
635/*
636 * Wrapper routine for handling exceptions.
637 */
638int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
639 unsigned long val, void *data)
640{
641 struct die_args *args = (struct die_args *)data;
642 int ret = NOTIFY_DONE;
643
644 if (args->regs && user_mode(args->regs))
645 return ret;
646
647 switch (val) {
648 case DIE_INT3:
649 if (kprobe_handler(args->regs))
650 ret = NOTIFY_STOP;
651 break;
652 case DIE_DEBUG:
653 if (post_kprobe_handler(args->regs))
654 ret = NOTIFY_STOP;
655 break;
656 case DIE_GPF:
657 /* kprobe_running() needs smp_processor_id() */
658 preempt_disable();
659 if (kprobe_running() &&
660 kprobe_fault_handler(args->regs, args->trapnr))
661 ret = NOTIFY_STOP;
662 preempt_enable();
663 break;
664 default:
665 break;
666 }
667 return ret;
668}
669
670int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
671{
672 struct jprobe *jp = container_of(p, struct jprobe, kp);
673 unsigned long addr;
674 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
675
676 kcb->jprobe_saved_regs = *regs;
677 kcb->jprobe_saved_rsp = (long *) regs->rsp;
678 addr = (unsigned long)(kcb->jprobe_saved_rsp);
679 /*
680 * As Linus pointed out, gcc assumes that the callee
681 * owns the argument space and could overwrite it, e.g.
682 * tailcall optimization. So, to be absolutely safe
683 * we also save and restore enough stack bytes to cover
684 * the argument area.
685 */
686 memcpy(kcb->jprobes_stack, (kprobe_opcode_t *)addr,
687 MIN_STACK_SIZE(addr));
688 regs->eflags &= ~IF_MASK;
689 trace_hardirqs_off();
690 regs->rip = (unsigned long)(jp->entry);
691 return 1;
692}
693
694void __kprobes jprobe_return(void)
695{
696 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
697
698 asm volatile (" xchg %%rbx,%%rsp \n"
699 " int3 \n"
700 " .globl jprobe_return_end \n"
701 " jprobe_return_end: \n"
702 " nop \n"::"b"
703 (kcb->jprobe_saved_rsp):"memory");
704}
705
706int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
707{
708 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
709 u8 *addr = (u8 *) (regs->rip - 1);
710 unsigned long stack_addr = (unsigned long)(kcb->jprobe_saved_rsp);
711 struct jprobe *jp = container_of(p, struct jprobe, kp);
712
713 if ((addr > (u8 *) jprobe_return) && (addr < (u8 *) jprobe_return_end)) {
714 if ((unsigned long *)regs->rsp != kcb->jprobe_saved_rsp) {
715 struct pt_regs *saved_regs = &kcb->jprobe_saved_regs;
716 printk("current rsp %p does not match saved rsp %p\n",
717 (long *)regs->rsp, kcb->jprobe_saved_rsp);
718 printk("Saved registers for jprobe %p\n", jp);
719 show_registers(saved_regs);
720 printk("Current registers\n");
721 show_registers(regs);
722 BUG();
723 }
724 *regs = kcb->jprobe_saved_regs;
725 memcpy((kprobe_opcode_t *) stack_addr, kcb->jprobes_stack,
726 MIN_STACK_SIZE(stack_addr));
727 preempt_enable_no_resched();
728 return 1;
729 }
730 return 0;
731}
732
733static struct kprobe trampoline_p = {
734 .addr = (kprobe_opcode_t *) &kretprobe_trampoline,
735 .pre_handler = trampoline_probe_handler
736};
737
738int __init arch_init_kprobes(void)
739{
740 return register_kprobe(&trampoline_p);
741}
742
743int __kprobes arch_trampoline_kprobe(struct kprobe *p)
744{
745 if (p->addr == (kprobe_opcode_t *)&kretprobe_trampoline)
746 return 1;
747
748 return 0;
749}
diff --git a/arch/x86/kernel/ldt_32.c b/arch/x86/kernel/ldt.c
index 9ff90a27c45f..8a7660c8394a 100644
--- a/arch/x86/kernel/ldt_32.c
+++ b/arch/x86/kernel/ldt.c
@@ -1,6 +1,9 @@
1/* 1/*
2 * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds 2 * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds
3 * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com> 3 * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
4 * Copyright (C) 2002 Andi Kleen
5 *
6 * This handles calls from both 32bit and 64bit mode.
4 */ 7 */
5 8
6#include <linux/errno.h> 9#include <linux/errno.h>
@@ -9,7 +12,6 @@
9#include <linux/mm.h> 12#include <linux/mm.h>
10#include <linux/smp.h> 13#include <linux/smp.h>
11#include <linux/vmalloc.h> 14#include <linux/vmalloc.h>
12#include <linux/slab.h>
13 15
14#include <asm/uaccess.h> 16#include <asm/uaccess.h>
15#include <asm/system.h> 17#include <asm/system.h>
@@ -17,7 +19,7 @@
17#include <asm/desc.h> 19#include <asm/desc.h>
18#include <asm/mmu_context.h> 20#include <asm/mmu_context.h>
19 21
20#ifdef CONFIG_SMP /* avoids "defined but not used" warnig */ 22#ifdef CONFIG_SMP
21static void flush_ldt(void *null) 23static void flush_ldt(void *null)
22{ 24{
23 if (current->active_mm) 25 if (current->active_mm)
@@ -27,26 +29,31 @@ static void flush_ldt(void *null)
27 29
28static int alloc_ldt(mm_context_t *pc, int mincount, int reload) 30static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
29{ 31{
30 void *oldldt; 32 void *oldldt, *newldt;
31 void *newldt;
32 int oldsize; 33 int oldsize;
33 34
34 if (mincount <= pc->size) 35 if (mincount <= pc->size)
35 return 0; 36 return 0;
36 oldsize = pc->size; 37 oldsize = pc->size;
37 mincount = (mincount+511)&(~511); 38 mincount = (mincount + 511) & (~511);
38 if (mincount*LDT_ENTRY_SIZE > PAGE_SIZE) 39 if (mincount * LDT_ENTRY_SIZE > PAGE_SIZE)
39 newldt = vmalloc(mincount*LDT_ENTRY_SIZE); 40 newldt = vmalloc(mincount * LDT_ENTRY_SIZE);
40 else 41 else
41 newldt = kmalloc(mincount*LDT_ENTRY_SIZE, GFP_KERNEL); 42 newldt = (void *)__get_free_page(GFP_KERNEL);
42 43
43 if (!newldt) 44 if (!newldt)
44 return -ENOMEM; 45 return -ENOMEM;
45 46
46 if (oldsize) 47 if (oldsize)
47 memcpy(newldt, pc->ldt, oldsize*LDT_ENTRY_SIZE); 48 memcpy(newldt, pc->ldt, oldsize * LDT_ENTRY_SIZE);
48 oldldt = pc->ldt; 49 oldldt = pc->ldt;
49 memset(newldt+oldsize*LDT_ENTRY_SIZE, 0, (mincount-oldsize)*LDT_ENTRY_SIZE); 50 memset(newldt + oldsize * LDT_ENTRY_SIZE, 0,
51 (mincount - oldsize) * LDT_ENTRY_SIZE);
52
53#ifdef CONFIG_X86_64
54 /* CHECKME: Do we really need this ? */
55 wmb();
56#endif
50 pc->ldt = newldt; 57 pc->ldt = newldt;
51 wmb(); 58 wmb();
52 pc->size = mincount; 59 pc->size = mincount;
@@ -55,6 +62,7 @@ static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
55 if (reload) { 62 if (reload) {
56#ifdef CONFIG_SMP 63#ifdef CONFIG_SMP
57 cpumask_t mask; 64 cpumask_t mask;
65
58 preempt_disable(); 66 preempt_disable();
59 load_LDT(pc); 67 load_LDT(pc);
60 mask = cpumask_of_cpu(smp_processor_id()); 68 mask = cpumask_of_cpu(smp_processor_id());
@@ -66,10 +74,10 @@ static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
66#endif 74#endif
67 } 75 }
68 if (oldsize) { 76 if (oldsize) {
69 if (oldsize*LDT_ENTRY_SIZE > PAGE_SIZE) 77 if (oldsize * LDT_ENTRY_SIZE > PAGE_SIZE)
70 vfree(oldldt); 78 vfree(oldldt);
71 else 79 else
72 kfree(oldldt); 80 put_page(virt_to_page(oldldt));
73 } 81 }
74 return 0; 82 return 0;
75} 83}
@@ -77,9 +85,10 @@ static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
77static inline int copy_ldt(mm_context_t *new, mm_context_t *old) 85static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
78{ 86{
79 int err = alloc_ldt(new, old->size, 0); 87 int err = alloc_ldt(new, old->size, 0);
88
80 if (err < 0) 89 if (err < 0)
81 return err; 90 return err;
82 memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE); 91 memcpy(new->ldt, old->ldt, old->size * LDT_ENTRY_SIZE);
83 return 0; 92 return 0;
84} 93}
85 94
@@ -89,7 +98,7 @@ static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
89 */ 98 */
90int init_new_context(struct task_struct *tsk, struct mm_struct *mm) 99int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
91{ 100{
92 struct mm_struct * old_mm; 101 struct mm_struct *old_mm;
93 int retval = 0; 102 int retval = 0;
94 103
95 mutex_init(&mm->context.lock); 104 mutex_init(&mm->context.lock);
@@ -105,33 +114,38 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
105 114
106/* 115/*
107 * No need to lock the MM as we are the last user 116 * No need to lock the MM as we are the last user
117 *
118 * 64bit: Don't touch the LDT register - we're already in the next thread.
108 */ 119 */
109void destroy_context(struct mm_struct *mm) 120void destroy_context(struct mm_struct *mm)
110{ 121{
111 if (mm->context.size) { 122 if (mm->context.size) {
123#ifdef CONFIG_X86_32
124 /* CHECKME: Can this ever happen ? */
112 if (mm == current->active_mm) 125 if (mm == current->active_mm)
113 clear_LDT(); 126 clear_LDT();
114 if (mm->context.size*LDT_ENTRY_SIZE > PAGE_SIZE) 127#endif
128 if (mm->context.size * LDT_ENTRY_SIZE > PAGE_SIZE)
115 vfree(mm->context.ldt); 129 vfree(mm->context.ldt);
116 else 130 else
117 kfree(mm->context.ldt); 131 put_page(virt_to_page(mm->context.ldt));
118 mm->context.size = 0; 132 mm->context.size = 0;
119 } 133 }
120} 134}
121 135
122static int read_ldt(void __user * ptr, unsigned long bytecount) 136static int read_ldt(void __user *ptr, unsigned long bytecount)
123{ 137{
124 int err; 138 int err;
125 unsigned long size; 139 unsigned long size;
126 struct mm_struct * mm = current->mm; 140 struct mm_struct *mm = current->mm;
127 141
128 if (!mm->context.size) 142 if (!mm->context.size)
129 return 0; 143 return 0;
130 if (bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES) 144 if (bytecount > LDT_ENTRY_SIZE * LDT_ENTRIES)
131 bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES; 145 bytecount = LDT_ENTRY_SIZE * LDT_ENTRIES;
132 146
133 mutex_lock(&mm->context.lock); 147 mutex_lock(&mm->context.lock);
134 size = mm->context.size*LDT_ENTRY_SIZE; 148 size = mm->context.size * LDT_ENTRY_SIZE;
135 if (size > bytecount) 149 if (size > bytecount)
136 size = bytecount; 150 size = bytecount;
137 151
@@ -143,7 +157,7 @@ static int read_ldt(void __user * ptr, unsigned long bytecount)
143 goto error_return; 157 goto error_return;
144 if (size != bytecount) { 158 if (size != bytecount) {
145 /* zero-fill the rest */ 159 /* zero-fill the rest */
146 if (clear_user(ptr+size, bytecount-size) != 0) { 160 if (clear_user(ptr + size, bytecount - size) != 0) {
147 err = -EFAULT; 161 err = -EFAULT;
148 goto error_return; 162 goto error_return;
149 } 163 }
@@ -153,34 +167,32 @@ error_return:
153 return err; 167 return err;
154} 168}
155 169
156static int read_default_ldt(void __user * ptr, unsigned long bytecount) 170static int read_default_ldt(void __user *ptr, unsigned long bytecount)
157{ 171{
158 int err; 172 /* CHECKME: Can we use _one_ random number ? */
159 unsigned long size; 173#ifdef CONFIG_X86_32
160 174 unsigned long size = 5 * sizeof(struct desc_struct);
161 err = 0; 175#else
162 size = 5*sizeof(struct desc_struct); 176 unsigned long size = 128;
163 if (size > bytecount) 177#endif
164 size = bytecount; 178 if (bytecount > size)
165 179 bytecount = size;
166 err = size; 180 if (clear_user(ptr, bytecount))
167 if (clear_user(ptr, size)) 181 return -EFAULT;
168 err = -EFAULT; 182 return bytecount;
169
170 return err;
171} 183}
172 184
173static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode) 185static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode)
174{ 186{
175 struct mm_struct * mm = current->mm; 187 struct mm_struct *mm = current->mm;
176 __u32 entry_1, entry_2; 188 struct desc_struct ldt;
177 int error; 189 int error;
178 struct user_desc ldt_info; 190 struct user_desc ldt_info;
179 191
180 error = -EINVAL; 192 error = -EINVAL;
181 if (bytecount != sizeof(ldt_info)) 193 if (bytecount != sizeof(ldt_info))
182 goto out; 194 goto out;
183 error = -EFAULT; 195 error = -EFAULT;
184 if (copy_from_user(&ldt_info, ptr, sizeof(ldt_info))) 196 if (copy_from_user(&ldt_info, ptr, sizeof(ldt_info)))
185 goto out; 197 goto out;
186 198
@@ -196,28 +208,27 @@ static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
196 208
197 mutex_lock(&mm->context.lock); 209 mutex_lock(&mm->context.lock);
198 if (ldt_info.entry_number >= mm->context.size) { 210 if (ldt_info.entry_number >= mm->context.size) {
199 error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1); 211 error = alloc_ldt(&current->mm->context,
212 ldt_info.entry_number + 1, 1);
200 if (error < 0) 213 if (error < 0)
201 goto out_unlock; 214 goto out_unlock;
202 } 215 }
203 216
204 /* Allow LDTs to be cleared by the user. */ 217 /* Allow LDTs to be cleared by the user. */
205 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) { 218 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
206 if (oldmode || LDT_empty(&ldt_info)) { 219 if (oldmode || LDT_empty(&ldt_info)) {
207 entry_1 = 0; 220 memset(&ldt, 0, sizeof(ldt));
208 entry_2 = 0;
209 goto install; 221 goto install;
210 } 222 }
211 } 223 }
212 224
213 entry_1 = LDT_entry_a(&ldt_info); 225 fill_ldt(&ldt, &ldt_info);
214 entry_2 = LDT_entry_b(&ldt_info);
215 if (oldmode) 226 if (oldmode)
216 entry_2 &= ~(1 << 20); 227 ldt.avl = 0;
217 228
218 /* Install the new entry ... */ 229 /* Install the new entry ... */
219install: 230install:
220 write_ldt_entry(mm->context.ldt, ldt_info.entry_number, entry_1, entry_2); 231 write_ldt_entry(mm->context.ldt, ldt_info.entry_number, &ldt);
221 error = 0; 232 error = 0;
222 233
223out_unlock: 234out_unlock:
@@ -226,7 +237,8 @@ out:
226 return error; 237 return error;
227} 238}
228 239
229asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount) 240asmlinkage int sys_modify_ldt(int func, void __user *ptr,
241 unsigned long bytecount)
230{ 242{
231 int ret = -ENOSYS; 243 int ret = -ENOSYS;
232 244
diff --git a/arch/x86/kernel/ldt_64.c b/arch/x86/kernel/ldt_64.c
deleted file mode 100644
index 60e57abb8e90..000000000000
--- a/arch/x86/kernel/ldt_64.c
+++ /dev/null
@@ -1,250 +0,0 @@
1/*
2 * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds
3 * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
4 * Copyright (C) 2002 Andi Kleen
5 *
6 * This handles calls from both 32bit and 64bit mode.
7 */
8
9#include <linux/errno.h>
10#include <linux/sched.h>
11#include <linux/string.h>
12#include <linux/mm.h>
13#include <linux/smp.h>
14#include <linux/vmalloc.h>
15#include <linux/slab.h>
16
17#include <asm/uaccess.h>
18#include <asm/system.h>
19#include <asm/ldt.h>
20#include <asm/desc.h>
21#include <asm/proto.h>
22
23#ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
24static void flush_ldt(void *null)
25{
26 if (current->active_mm)
27 load_LDT(&current->active_mm->context);
28}
29#endif
30
31static int alloc_ldt(mm_context_t *pc, unsigned mincount, int reload)
32{
33 void *oldldt;
34 void *newldt;
35 unsigned oldsize;
36
37 if (mincount <= (unsigned)pc->size)
38 return 0;
39 oldsize = pc->size;
40 mincount = (mincount+511)&(~511);
41 if (mincount*LDT_ENTRY_SIZE > PAGE_SIZE)
42 newldt = vmalloc(mincount*LDT_ENTRY_SIZE);
43 else
44 newldt = kmalloc(mincount*LDT_ENTRY_SIZE, GFP_KERNEL);
45
46 if (!newldt)
47 return -ENOMEM;
48
49 if (oldsize)
50 memcpy(newldt, pc->ldt, oldsize*LDT_ENTRY_SIZE);
51 oldldt = pc->ldt;
52 memset(newldt+oldsize*LDT_ENTRY_SIZE, 0, (mincount-oldsize)*LDT_ENTRY_SIZE);
53 wmb();
54 pc->ldt = newldt;
55 wmb();
56 pc->size = mincount;
57 wmb();
58 if (reload) {
59#ifdef CONFIG_SMP
60 cpumask_t mask;
61
62 preempt_disable();
63 mask = cpumask_of_cpu(smp_processor_id());
64 load_LDT(pc);
65 if (!cpus_equal(current->mm->cpu_vm_mask, mask))
66 smp_call_function(flush_ldt, NULL, 1, 1);
67 preempt_enable();
68#else
69 load_LDT(pc);
70#endif
71 }
72 if (oldsize) {
73 if (oldsize*LDT_ENTRY_SIZE > PAGE_SIZE)
74 vfree(oldldt);
75 else
76 kfree(oldldt);
77 }
78 return 0;
79}
80
81static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
82{
83 int err = alloc_ldt(new, old->size, 0);
84 if (err < 0)
85 return err;
86 memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
87 return 0;
88}
89
90/*
91 * we do not have to muck with descriptors here, that is
92 * done in switch_mm() as needed.
93 */
94int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
95{
96 struct mm_struct * old_mm;
97 int retval = 0;
98
99 mutex_init(&mm->context.lock);
100 mm->context.size = 0;
101 old_mm = current->mm;
102 if (old_mm && old_mm->context.size > 0) {
103 mutex_lock(&old_mm->context.lock);
104 retval = copy_ldt(&mm->context, &old_mm->context);
105 mutex_unlock(&old_mm->context.lock);
106 }
107 return retval;
108}
109
110/*
111 *
112 * Don't touch the LDT register - we're already in the next thread.
113 */
114void destroy_context(struct mm_struct *mm)
115{
116 if (mm->context.size) {
117 if ((unsigned)mm->context.size*LDT_ENTRY_SIZE > PAGE_SIZE)
118 vfree(mm->context.ldt);
119 else
120 kfree(mm->context.ldt);
121 mm->context.size = 0;
122 }
123}
124
125static int read_ldt(void __user * ptr, unsigned long bytecount)
126{
127 int err;
128 unsigned long size;
129 struct mm_struct * mm = current->mm;
130
131 if (!mm->context.size)
132 return 0;
133 if (bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES)
134 bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES;
135
136 mutex_lock(&mm->context.lock);
137 size = mm->context.size*LDT_ENTRY_SIZE;
138 if (size > bytecount)
139 size = bytecount;
140
141 err = 0;
142 if (copy_to_user(ptr, mm->context.ldt, size))
143 err = -EFAULT;
144 mutex_unlock(&mm->context.lock);
145 if (err < 0)
146 goto error_return;
147 if (size != bytecount) {
148 /* zero-fill the rest */
149 if (clear_user(ptr+size, bytecount-size) != 0) {
150 err = -EFAULT;
151 goto error_return;
152 }
153 }
154 return bytecount;
155error_return:
156 return err;
157}
158
159static int read_default_ldt(void __user * ptr, unsigned long bytecount)
160{
161 /* Arbitrary number */
162 /* x86-64 default LDT is all zeros */
163 if (bytecount > 128)
164 bytecount = 128;
165 if (clear_user(ptr, bytecount))
166 return -EFAULT;
167 return bytecount;
168}
169
170static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
171{
172 struct task_struct *me = current;
173 struct mm_struct * mm = me->mm;
174 __u32 entry_1, entry_2, *lp;
175 int error;
176 struct user_desc ldt_info;
177
178 error = -EINVAL;
179
180 if (bytecount != sizeof(ldt_info))
181 goto out;
182 error = -EFAULT;
183 if (copy_from_user(&ldt_info, ptr, bytecount))
184 goto out;
185
186 error = -EINVAL;
187 if (ldt_info.entry_number >= LDT_ENTRIES)
188 goto out;
189 if (ldt_info.contents == 3) {
190 if (oldmode)
191 goto out;
192 if (ldt_info.seg_not_present == 0)
193 goto out;
194 }
195
196 mutex_lock(&mm->context.lock);
197 if (ldt_info.entry_number >= (unsigned)mm->context.size) {
198 error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
199 if (error < 0)
200 goto out_unlock;
201 }
202
203 lp = (__u32 *) ((ldt_info.entry_number << 3) + (char *) mm->context.ldt);
204
205 /* Allow LDTs to be cleared by the user. */
206 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
207 if (oldmode || LDT_empty(&ldt_info)) {
208 entry_1 = 0;
209 entry_2 = 0;
210 goto install;
211 }
212 }
213
214 entry_1 = LDT_entry_a(&ldt_info);
215 entry_2 = LDT_entry_b(&ldt_info);
216 if (oldmode)
217 entry_2 &= ~(1 << 20);
218
219 /* Install the new entry ... */
220install:
221 *lp = entry_1;
222 *(lp+1) = entry_2;
223 error = 0;
224
225out_unlock:
226 mutex_unlock(&mm->context.lock);
227out:
228 return error;
229}
230
231asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
232{
233 int ret = -ENOSYS;
234
235 switch (func) {
236 case 0:
237 ret = read_ldt(ptr, bytecount);
238 break;
239 case 1:
240 ret = write_ldt(ptr, bytecount, 1);
241 break;
242 case 2:
243 ret = read_default_ldt(ptr, bytecount);
244 break;
245 case 0x11:
246 ret = write_ldt(ptr, bytecount, 0);
247 break;
248 }
249 return ret;
250}
diff --git a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c
index 11b935f4f886..c1cfd60639d4 100644
--- a/arch/x86/kernel/machine_kexec_32.c
+++ b/arch/x86/kernel/machine_kexec_32.c
@@ -32,7 +32,7 @@ static u32 kexec_pte1[1024] PAGE_ALIGNED;
32 32
33static void set_idt(void *newidt, __u16 limit) 33static void set_idt(void *newidt, __u16 limit)
34{ 34{
35 struct Xgt_desc_struct curidt; 35 struct desc_ptr curidt;
36 36
37 /* ia32 supports unaliged loads & stores */ 37 /* ia32 supports unaliged loads & stores */
38 curidt.size = limit; 38 curidt.size = limit;
@@ -44,7 +44,7 @@ static void set_idt(void *newidt, __u16 limit)
44 44
45static void set_gdt(void *newgdt, __u16 limit) 45static void set_gdt(void *newgdt, __u16 limit)
46{ 46{
47 struct Xgt_desc_struct curgdt; 47 struct desc_ptr curgdt;
48 48
49 /* ia32 supports unaligned loads & stores */ 49 /* ia32 supports unaligned loads & stores */
50 curgdt.size = limit; 50 curgdt.size = limit;
diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c
index aa3d2c8f7737..a1fef42f8cdb 100644
--- a/arch/x86/kernel/machine_kexec_64.c
+++ b/arch/x86/kernel/machine_kexec_64.c
@@ -234,10 +234,5 @@ NORET_TYPE void machine_kexec(struct kimage *image)
234void arch_crash_save_vmcoreinfo(void) 234void arch_crash_save_vmcoreinfo(void)
235{ 235{
236 VMCOREINFO_SYMBOL(init_level4_pgt); 236 VMCOREINFO_SYMBOL(init_level4_pgt);
237
238#ifdef CONFIG_ARCH_DISCONTIGMEM_ENABLE
239 VMCOREINFO_SYMBOL(node_data);
240 VMCOREINFO_LENGTH(node_data, MAX_NUMNODES);
241#endif
242} 237}
243 238
diff --git a/arch/x86/kernel/mfgpt_32.c b/arch/x86/kernel/mfgpt_32.c
index 3960ab7e1497..219f86eb6123 100644
--- a/arch/x86/kernel/mfgpt_32.c
+++ b/arch/x86/kernel/mfgpt_32.c
@@ -63,6 +63,21 @@ static int __init mfgpt_disable(char *s)
63} 63}
64__setup("nomfgpt", mfgpt_disable); 64__setup("nomfgpt", mfgpt_disable);
65 65
66/* Reset the MFGPT timers. This is required by some broken BIOSes which already
67 * do the same and leave the system in an unstable state. TinyBIOS 0.98 is
68 * affected at least (0.99 is OK with MFGPT workaround left to off).
69 */
70static int __init mfgpt_fix(char *s)
71{
72 u32 val, dummy;
73
74 /* The following udocumented bit resets the MFGPT timers */
75 val = 0xFF; dummy = 0;
76 wrmsr(0x5140002B, val, dummy);
77 return 1;
78}
79__setup("mfgptfix", mfgpt_fix);
80
66/* 81/*
67 * Check whether any MFGPTs are available for the kernel to use. In most 82 * Check whether any MFGPTs are available for the kernel to use. In most
68 * cases, firmware that uses AMD's VSA code will claim all timers during 83 * cases, firmware that uses AMD's VSA code will claim all timers during
diff --git a/arch/x86/kernel/microcode.c b/arch/x86/kernel/microcode.c
index 09c315214a5e..6ff447f9fda7 100644
--- a/arch/x86/kernel/microcode.c
+++ b/arch/x86/kernel/microcode.c
@@ -244,8 +244,8 @@ static int microcode_sanity_check(void *mc)
244 return 0; 244 return 0;
245 /* check extended signature checksum */ 245 /* check extended signature checksum */
246 for (i = 0; i < ext_sigcount; i++) { 246 for (i = 0; i < ext_sigcount; i++) {
247 ext_sig = (struct extended_signature *)((void *)ext_header 247 ext_sig = (void *)ext_header + EXT_HEADER_SIZE +
248 + EXT_HEADER_SIZE + EXT_SIGNATURE_SIZE * i); 248 EXT_SIGNATURE_SIZE * i;
249 sum = orig_sum 249 sum = orig_sum
250 - (mc_header->sig + mc_header->pf + mc_header->cksum) 250 - (mc_header->sig + mc_header->pf + mc_header->cksum)
251 + (ext_sig->sig + ext_sig->pf + ext_sig->cksum); 251 + (ext_sig->sig + ext_sig->pf + ext_sig->cksum);
@@ -279,11 +279,9 @@ static int get_maching_microcode(void *mc, int cpu)
279 if (total_size <= get_datasize(mc_header) + MC_HEADER_SIZE) 279 if (total_size <= get_datasize(mc_header) + MC_HEADER_SIZE)
280 return 0; 280 return 0;
281 281
282 ext_header = (struct extended_sigtable *)(mc + 282 ext_header = mc + get_datasize(mc_header) + MC_HEADER_SIZE;
283 get_datasize(mc_header) + MC_HEADER_SIZE);
284 ext_sigcount = ext_header->count; 283 ext_sigcount = ext_header->count;
285 ext_sig = (struct extended_signature *)((void *)ext_header 284 ext_sig = (void *)ext_header + EXT_HEADER_SIZE;
286 + EXT_HEADER_SIZE);
287 for (i = 0; i < ext_sigcount; i++) { 285 for (i = 0; i < ext_sigcount; i++) {
288 if (microcode_update_match(cpu, mc_header, 286 if (microcode_update_match(cpu, mc_header,
289 ext_sig->sig, ext_sig->pf)) 287 ext_sig->sig, ext_sig->pf))
@@ -436,7 +434,7 @@ static ssize_t microcode_write (struct file *file, const char __user *buf, size_
436 return -EINVAL; 434 return -EINVAL;
437 } 435 }
438 436
439 lock_cpu_hotplug(); 437 get_online_cpus();
440 mutex_lock(&microcode_mutex); 438 mutex_lock(&microcode_mutex);
441 439
442 user_buffer = (void __user *) buf; 440 user_buffer = (void __user *) buf;
@@ -447,7 +445,7 @@ static ssize_t microcode_write (struct file *file, const char __user *buf, size_
447 ret = (ssize_t)len; 445 ret = (ssize_t)len;
448 446
449 mutex_unlock(&microcode_mutex); 447 mutex_unlock(&microcode_mutex);
450 unlock_cpu_hotplug(); 448 put_online_cpus();
451 449
452 return ret; 450 return ret;
453} 451}
@@ -539,7 +537,7 @@ static int cpu_request_microcode(int cpu)
539 pr_debug("ucode data file %s load failed\n", name); 537 pr_debug("ucode data file %s load failed\n", name);
540 return error; 538 return error;
541 } 539 }
542 buf = (void *)firmware->data; 540 buf = firmware->data;
543 size = firmware->size; 541 size = firmware->size;
544 while ((offset = get_next_ucode_from_buffer(&mc, buf, size, offset)) 542 while ((offset = get_next_ucode_from_buffer(&mc, buf, size, offset))
545 > 0) { 543 > 0) {
@@ -658,14 +656,14 @@ static ssize_t reload_store(struct sys_device *dev, const char *buf, size_t sz)
658 656
659 old = current->cpus_allowed; 657 old = current->cpus_allowed;
660 658
661 lock_cpu_hotplug(); 659 get_online_cpus();
662 set_cpus_allowed(current, cpumask_of_cpu(cpu)); 660 set_cpus_allowed(current, cpumask_of_cpu(cpu));
663 661
664 mutex_lock(&microcode_mutex); 662 mutex_lock(&microcode_mutex);
665 if (uci->valid) 663 if (uci->valid)
666 err = cpu_request_microcode(cpu); 664 err = cpu_request_microcode(cpu);
667 mutex_unlock(&microcode_mutex); 665 mutex_unlock(&microcode_mutex);
668 unlock_cpu_hotplug(); 666 put_online_cpus();
669 set_cpus_allowed(current, old); 667 set_cpus_allowed(current, old);
670 } 668 }
671 if (err) 669 if (err)
@@ -817,9 +815,9 @@ static int __init microcode_init (void)
817 return PTR_ERR(microcode_pdev); 815 return PTR_ERR(microcode_pdev);
818 } 816 }
819 817
820 lock_cpu_hotplug(); 818 get_online_cpus();
821 error = sysdev_driver_register(&cpu_sysdev_class, &mc_sysdev_driver); 819 error = sysdev_driver_register(&cpu_sysdev_class, &mc_sysdev_driver);
822 unlock_cpu_hotplug(); 820 put_online_cpus();
823 if (error) { 821 if (error) {
824 microcode_dev_exit(); 822 microcode_dev_exit();
825 platform_device_unregister(microcode_pdev); 823 platform_device_unregister(microcode_pdev);
@@ -839,9 +837,9 @@ static void __exit microcode_exit (void)
839 837
840 unregister_hotcpu_notifier(&mc_cpu_notifier); 838 unregister_hotcpu_notifier(&mc_cpu_notifier);
841 839
842 lock_cpu_hotplug(); 840 get_online_cpus();
843 sysdev_driver_unregister(&cpu_sysdev_class, &mc_sysdev_driver); 841 sysdev_driver_unregister(&cpu_sysdev_class, &mc_sysdev_driver);
844 unlock_cpu_hotplug(); 842 put_online_cpus();
845 843
846 platform_device_unregister(microcode_pdev); 844 platform_device_unregister(microcode_pdev);
847} 845}
diff --git a/arch/x86/kernel/mpparse_32.c b/arch/x86/kernel/mpparse_32.c
index 7a05a7f6099a..67009cdd5eca 100644
--- a/arch/x86/kernel/mpparse_32.c
+++ b/arch/x86/kernel/mpparse_32.c
@@ -68,7 +68,7 @@ unsigned int def_to_bigsmp = 0;
68/* Processor that is doing the boot up */ 68/* Processor that is doing the boot up */
69unsigned int boot_cpu_physical_apicid = -1U; 69unsigned int boot_cpu_physical_apicid = -1U;
70/* Internal processor count */ 70/* Internal processor count */
71unsigned int __cpuinitdata num_processors; 71unsigned int num_processors;
72 72
73/* Bitmask of physically existing CPUs */ 73/* Bitmask of physically existing CPUs */
74physid_mask_t phys_cpu_present_map; 74physid_mask_t phys_cpu_present_map;
@@ -258,7 +258,7 @@ static void __init MP_ioapic_info (struct mpc_config_ioapic *m)
258 if (!(m->mpc_flags & MPC_APIC_USABLE)) 258 if (!(m->mpc_flags & MPC_APIC_USABLE))
259 return; 259 return;
260 260
261 printk(KERN_INFO "I/O APIC #%d Version %d at 0x%lX.\n", 261 printk(KERN_INFO "I/O APIC #%d Version %d at 0x%X.\n",
262 m->mpc_apicid, m->mpc_apicver, m->mpc_apicaddr); 262 m->mpc_apicid, m->mpc_apicver, m->mpc_apicaddr);
263 if (nr_ioapics >= MAX_IO_APICS) { 263 if (nr_ioapics >= MAX_IO_APICS) {
264 printk(KERN_CRIT "Max # of I/O APICs (%d) exceeded (found %d).\n", 264 printk(KERN_CRIT "Max # of I/O APICs (%d) exceeded (found %d).\n",
@@ -405,9 +405,9 @@ static int __init smp_read_mpc(struct mp_config_table *mpc)
405 405
406 mps_oem_check(mpc, oem, str); 406 mps_oem_check(mpc, oem, str);
407 407
408 printk("APIC at: 0x%lX\n",mpc->mpc_lapic); 408 printk("APIC at: 0x%X\n", mpc->mpc_lapic);
409 409
410 /* 410 /*
411 * Save the local APIC address (it might be non-default) -- but only 411 * Save the local APIC address (it might be non-default) -- but only
412 * if we're not using ACPI. 412 * if we're not using ACPI.
413 */ 413 */
@@ -721,7 +721,7 @@ static int __init smp_scan_config (unsigned long base, unsigned long length)
721 unsigned long *bp = phys_to_virt(base); 721 unsigned long *bp = phys_to_virt(base);
722 struct intel_mp_floating *mpf; 722 struct intel_mp_floating *mpf;
723 723
724 Dprintk("Scan SMP from %p for %ld bytes.\n", bp,length); 724 printk(KERN_INFO "Scan SMP from %p for %ld bytes.\n", bp,length);
725 if (sizeof(*mpf) != 16) 725 if (sizeof(*mpf) != 16)
726 printk("Error: MPF size\n"); 726 printk("Error: MPF size\n");
727 727
@@ -734,8 +734,8 @@ static int __init smp_scan_config (unsigned long base, unsigned long length)
734 || (mpf->mpf_specification == 4)) ) { 734 || (mpf->mpf_specification == 4)) ) {
735 735
736 smp_found_config = 1; 736 smp_found_config = 1;
737 printk(KERN_INFO "found SMP MP-table at %08lx\n", 737 printk(KERN_INFO "found SMP MP-table at [%p] %08lx\n",
738 virt_to_phys(mpf)); 738 mpf, virt_to_phys(mpf));
739 reserve_bootmem(virt_to_phys(mpf), PAGE_SIZE); 739 reserve_bootmem(virt_to_phys(mpf), PAGE_SIZE);
740 if (mpf->mpf_physptr) { 740 if (mpf->mpf_physptr) {
741 /* 741 /*
@@ -918,14 +918,14 @@ void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base)
918 */ 918 */
919 mp_ioapic_routing[idx].apic_id = mp_ioapics[idx].mpc_apicid; 919 mp_ioapic_routing[idx].apic_id = mp_ioapics[idx].mpc_apicid;
920 mp_ioapic_routing[idx].gsi_base = gsi_base; 920 mp_ioapic_routing[idx].gsi_base = gsi_base;
921 mp_ioapic_routing[idx].gsi_end = gsi_base + 921 mp_ioapic_routing[idx].gsi_end = gsi_base +
922 io_apic_get_redir_entries(idx); 922 io_apic_get_redir_entries(idx);
923 923
924 printk("IOAPIC[%d]: apic_id %d, version %d, address 0x%lx, " 924 printk("IOAPIC[%d]: apic_id %d, version %d, address 0x%x, "
925 "GSI %d-%d\n", idx, mp_ioapics[idx].mpc_apicid, 925 "GSI %d-%d\n", idx, mp_ioapics[idx].mpc_apicid,
926 mp_ioapics[idx].mpc_apicver, mp_ioapics[idx].mpc_apicaddr, 926 mp_ioapics[idx].mpc_apicver, mp_ioapics[idx].mpc_apicaddr,
927 mp_ioapic_routing[idx].gsi_base, 927 mp_ioapic_routing[idx].gsi_base,
928 mp_ioapic_routing[idx].gsi_end); 928 mp_ioapic_routing[idx].gsi_end);
929} 929}
930 930
931void __init 931void __init
@@ -1041,15 +1041,16 @@ void __init mp_config_acpi_legacy_irqs (void)
1041} 1041}
1042 1042
1043#define MAX_GSI_NUM 4096 1043#define MAX_GSI_NUM 4096
1044#define IRQ_COMPRESSION_START 64
1044 1045
1045int mp_register_gsi(u32 gsi, int triggering, int polarity) 1046int mp_register_gsi(u32 gsi, int triggering, int polarity)
1046{ 1047{
1047 int ioapic = -1; 1048 int ioapic = -1;
1048 int ioapic_pin = 0; 1049 int ioapic_pin = 0;
1049 int idx, bit = 0; 1050 int idx, bit = 0;
1050 static int pci_irq = 16; 1051 static int pci_irq = IRQ_COMPRESSION_START;
1051 /* 1052 /*
1052 * Mapping between Global System Interrups, which 1053 * Mapping between Global System Interrupts, which
1053 * represent all possible interrupts, and IRQs 1054 * represent all possible interrupts, and IRQs
1054 * assigned to actual devices. 1055 * assigned to actual devices.
1055 */ 1056 */
@@ -1086,12 +1087,16 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity)
1086 if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) { 1087 if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
1087 Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n", 1088 Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
1088 mp_ioapic_routing[ioapic].apic_id, ioapic_pin); 1089 mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
1089 return gsi_to_irq[gsi]; 1090 return (gsi < IRQ_COMPRESSION_START ? gsi : gsi_to_irq[gsi]);
1090 } 1091 }
1091 1092
1092 mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit); 1093 mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
1093 1094
1094 if (triggering == ACPI_LEVEL_SENSITIVE) { 1095 /*
1096 * For GSI >= 64, use IRQ compression
1097 */
1098 if ((gsi >= IRQ_COMPRESSION_START)
1099 && (triggering == ACPI_LEVEL_SENSITIVE)) {
1095 /* 1100 /*
1096 * For PCI devices assign IRQs in order, avoiding gaps 1101 * For PCI devices assign IRQs in order, avoiding gaps
1097 * due to unused I/O APIC pins. 1102 * due to unused I/O APIC pins.
diff --git a/arch/x86/kernel/mpparse_64.c b/arch/x86/kernel/mpparse_64.c
index ef4aab123581..72ab1403fed7 100644
--- a/arch/x86/kernel/mpparse_64.c
+++ b/arch/x86/kernel/mpparse_64.c
@@ -60,14 +60,18 @@ unsigned int boot_cpu_id = -1U;
60EXPORT_SYMBOL(boot_cpu_id); 60EXPORT_SYMBOL(boot_cpu_id);
61 61
62/* Internal processor count */ 62/* Internal processor count */
63unsigned int num_processors __cpuinitdata = 0; 63unsigned int num_processors;
64 64
65unsigned disabled_cpus __cpuinitdata; 65unsigned disabled_cpus __cpuinitdata;
66 66
67/* Bitmask of physically existing CPUs */ 67/* Bitmask of physically existing CPUs */
68physid_mask_t phys_cpu_present_map = PHYSID_MASK_NONE; 68physid_mask_t phys_cpu_present_map = PHYSID_MASK_NONE;
69 69
70u8 bios_cpu_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID }; 70u16 x86_bios_cpu_apicid_init[NR_CPUS] __initdata
71 = { [0 ... NR_CPUS-1] = BAD_APICID };
72void *x86_bios_cpu_apicid_early_ptr;
73DEFINE_PER_CPU(u16, x86_bios_cpu_apicid) = BAD_APICID;
74EXPORT_PER_CPU_SYMBOL(x86_bios_cpu_apicid);
71 75
72 76
73/* 77/*
@@ -118,24 +122,22 @@ static void __cpuinit MP_processor_info(struct mpc_config_processor *m)
118 physid_set(m->mpc_apicid, phys_cpu_present_map); 122 physid_set(m->mpc_apicid, phys_cpu_present_map);
119 if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) { 123 if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
120 /* 124 /*
121 * bios_cpu_apicid is required to have processors listed 125 * x86_bios_cpu_apicid is required to have processors listed
122 * in same order as logical cpu numbers. Hence the first 126 * in same order as logical cpu numbers. Hence the first
123 * entry is BSP, and so on. 127 * entry is BSP, and so on.
124 */ 128 */
125 cpu = 0; 129 cpu = 0;
126 } 130 }
127 bios_cpu_apicid[cpu] = m->mpc_apicid; 131 /* are we being called early in kernel startup? */
128 /* 132 if (x86_cpu_to_apicid_early_ptr) {
129 * We get called early in the the start_kernel initialization 133 u16 *cpu_to_apicid = x86_cpu_to_apicid_early_ptr;
130 * process when the per_cpu data area is not yet setup, so we 134 u16 *bios_cpu_apicid = x86_bios_cpu_apicid_early_ptr;
131 * use a static array that is removed after the per_cpu data 135
132 * area is created. 136 cpu_to_apicid[cpu] = m->mpc_apicid;
133 */ 137 bios_cpu_apicid[cpu] = m->mpc_apicid;
134 if (x86_cpu_to_apicid_ptr) {
135 u8 *x86_cpu_to_apicid = (u8 *)x86_cpu_to_apicid_ptr;
136 x86_cpu_to_apicid[cpu] = m->mpc_apicid;
137 } else { 138 } else {
138 per_cpu(x86_cpu_to_apicid, cpu) = m->mpc_apicid; 139 per_cpu(x86_cpu_to_apicid, cpu) = m->mpc_apicid;
140 per_cpu(x86_bios_cpu_apicid, cpu) = m->mpc_apicid;
139 } 141 }
140 142
141 cpu_set(cpu, cpu_possible_map); 143 cpu_set(cpu, cpu_possible_map);
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c
index ee6eba4ecfea..21f6e3c0be18 100644
--- a/arch/x86/kernel/msr.c
+++ b/arch/x86/kernel/msr.c
@@ -155,15 +155,15 @@ static int __cpuinit msr_class_cpu_callback(struct notifier_block *nfb,
155 155
156 switch (action) { 156 switch (action) {
157 case CPU_UP_PREPARE: 157 case CPU_UP_PREPARE:
158 case CPU_UP_PREPARE_FROZEN:
159 err = msr_device_create(cpu); 158 err = msr_device_create(cpu);
160 break; 159 break;
161 case CPU_UP_CANCELED: 160 case CPU_UP_CANCELED:
162 case CPU_UP_CANCELED_FROZEN:
163 case CPU_DEAD: 161 case CPU_DEAD:
164 case CPU_DEAD_FROZEN:
165 msr_device_destroy(cpu); 162 msr_device_destroy(cpu);
166 break; 163 break;
164 case CPU_UP_CANCELED_FROZEN:
165 destroy_suspended_device(msr_class, MKDEV(MSR_MAJOR, cpu));
166 break;
167 } 167 }
168 return err ? NOTIFY_BAD : NOTIFY_OK; 168 return err ? NOTIFY_BAD : NOTIFY_OK;
169} 169}
diff --git a/arch/x86/kernel/nmi_32.c b/arch/x86/kernel/nmi_32.c
index 852db2906921..edd413650b3b 100644
--- a/arch/x86/kernel/nmi_32.c
+++ b/arch/x86/kernel/nmi_32.c
@@ -51,13 +51,13 @@ static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu);
51 51
52static int endflag __initdata = 0; 52static int endflag __initdata = 0;
53 53
54#ifdef CONFIG_SMP
54/* The performance counters used by NMI_LOCAL_APIC don't trigger when 55/* The performance counters used by NMI_LOCAL_APIC don't trigger when
55 * the CPU is idle. To make sure the NMI watchdog really ticks on all 56 * the CPU is idle. To make sure the NMI watchdog really ticks on all
56 * CPUs during the test make them busy. 57 * CPUs during the test make them busy.
57 */ 58 */
58static __init void nmi_cpu_busy(void *data) 59static __init void nmi_cpu_busy(void *data)
59{ 60{
60#ifdef CONFIG_SMP
61 local_irq_enable_in_hardirq(); 61 local_irq_enable_in_hardirq();
62 /* Intentionally don't use cpu_relax here. This is 62 /* Intentionally don't use cpu_relax here. This is
63 to make sure that the performance counter really ticks, 63 to make sure that the performance counter really ticks,
@@ -67,8 +67,8 @@ static __init void nmi_cpu_busy(void *data)
67 care if they get somewhat less cycles. */ 67 care if they get somewhat less cycles. */
68 while (endflag == 0) 68 while (endflag == 0)
69 mb(); 69 mb();
70#endif
71} 70}
71#endif
72 72
73static int __init check_nmi_watchdog(void) 73static int __init check_nmi_watchdog(void)
74{ 74{
@@ -87,11 +87,13 @@ static int __init check_nmi_watchdog(void)
87 87
88 printk(KERN_INFO "Testing NMI watchdog ... "); 88 printk(KERN_INFO "Testing NMI watchdog ... ");
89 89
90#ifdef CONFIG_SMP
90 if (nmi_watchdog == NMI_LOCAL_APIC) 91 if (nmi_watchdog == NMI_LOCAL_APIC)
91 smp_call_function(nmi_cpu_busy, (void *)&endflag, 0, 0); 92 smp_call_function(nmi_cpu_busy, (void *)&endflag, 0, 0);
93#endif
92 94
93 for_each_possible_cpu(cpu) 95 for_each_possible_cpu(cpu)
94 prev_nmi_count[cpu] = per_cpu(irq_stat, cpu).__nmi_count; 96 prev_nmi_count[cpu] = nmi_count(cpu);
95 local_irq_enable(); 97 local_irq_enable();
96 mdelay((20*1000)/nmi_hz); // wait 20 ticks 98 mdelay((20*1000)/nmi_hz); // wait 20 ticks
97 99
@@ -176,7 +178,7 @@ static int lapic_nmi_resume(struct sys_device *dev)
176 178
177 179
178static struct sysdev_class nmi_sysclass = { 180static struct sysdev_class nmi_sysclass = {
179 set_kset_name("lapic_nmi"), 181 .name = "lapic_nmi",
180 .resume = lapic_nmi_resume, 182 .resume = lapic_nmi_resume,
181 .suspend = lapic_nmi_suspend, 183 .suspend = lapic_nmi_suspend,
182}; 184};
@@ -237,10 +239,10 @@ void acpi_nmi_disable(void)
237 on_each_cpu(__acpi_nmi_disable, NULL, 0, 1); 239 on_each_cpu(__acpi_nmi_disable, NULL, 0, 1);
238} 240}
239 241
240void setup_apic_nmi_watchdog (void *unused) 242void setup_apic_nmi_watchdog(void *unused)
241{ 243{
242 if (__get_cpu_var(wd_enabled)) 244 if (__get_cpu_var(wd_enabled))
243 return; 245 return;
244 246
245 /* cheap hack to support suspend/resume */ 247 /* cheap hack to support suspend/resume */
246 /* if cpu0 is not active neither should the other cpus */ 248 /* if cpu0 is not active neither should the other cpus */
@@ -329,7 +331,7 @@ __kprobes int nmi_watchdog_tick(struct pt_regs * regs, unsigned reason)
329 unsigned int sum; 331 unsigned int sum;
330 int touched = 0; 332 int touched = 0;
331 int cpu = smp_processor_id(); 333 int cpu = smp_processor_id();
332 int rc=0; 334 int rc = 0;
333 335
334 /* check for other users first */ 336 /* check for other users first */
335 if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) 337 if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT)
diff --git a/arch/x86/kernel/nmi_64.c b/arch/x86/kernel/nmi_64.c
index 4253c4e8849c..fb99484d21cf 100644
--- a/arch/x86/kernel/nmi_64.c
+++ b/arch/x86/kernel/nmi_64.c
@@ -39,7 +39,7 @@ static cpumask_t backtrace_mask = CPU_MASK_NONE;
39 * 0: the lapic NMI watchdog is disabled, but can be enabled 39 * 0: the lapic NMI watchdog is disabled, but can be enabled
40 */ 40 */
41atomic_t nmi_active = ATOMIC_INIT(0); /* oprofile uses this */ 41atomic_t nmi_active = ATOMIC_INIT(0); /* oprofile uses this */
42int panic_on_timeout; 42static int panic_on_timeout;
43 43
44unsigned int nmi_watchdog = NMI_DEFAULT; 44unsigned int nmi_watchdog = NMI_DEFAULT;
45static unsigned int nmi_hz = HZ; 45static unsigned int nmi_hz = HZ;
@@ -78,22 +78,22 @@ static __init void nmi_cpu_busy(void *data)
78} 78}
79#endif 79#endif
80 80
81int __init check_nmi_watchdog (void) 81int __init check_nmi_watchdog(void)
82{ 82{
83 int *counts; 83 int *prev_nmi_count;
84 int cpu; 84 int cpu;
85 85
86 if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DISABLED)) 86 if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DISABLED))
87 return 0; 87 return 0;
88 88
89 if (!atomic_read(&nmi_active)) 89 if (!atomic_read(&nmi_active))
90 return 0; 90 return 0;
91 91
92 counts = kmalloc(NR_CPUS * sizeof(int), GFP_KERNEL); 92 prev_nmi_count = kmalloc(NR_CPUS * sizeof(int), GFP_KERNEL);
93 if (!counts) 93 if (!prev_nmi_count)
94 return -1; 94 return -1;
95 95
96 printk(KERN_INFO "testing NMI watchdog ... "); 96 printk(KERN_INFO "Testing NMI watchdog ... ");
97 97
98#ifdef CONFIG_SMP 98#ifdef CONFIG_SMP
99 if (nmi_watchdog == NMI_LOCAL_APIC) 99 if (nmi_watchdog == NMI_LOCAL_APIC)
@@ -101,30 +101,29 @@ int __init check_nmi_watchdog (void)
101#endif 101#endif
102 102
103 for (cpu = 0; cpu < NR_CPUS; cpu++) 103 for (cpu = 0; cpu < NR_CPUS; cpu++)
104 counts[cpu] = cpu_pda(cpu)->__nmi_count; 104 prev_nmi_count[cpu] = cpu_pda(cpu)->__nmi_count;
105 local_irq_enable(); 105 local_irq_enable();
106 mdelay((20*1000)/nmi_hz); // wait 20 ticks 106 mdelay((20*1000)/nmi_hz); // wait 20 ticks
107 107
108 for_each_online_cpu(cpu) { 108 for_each_online_cpu(cpu) {
109 if (!per_cpu(wd_enabled, cpu)) 109 if (!per_cpu(wd_enabled, cpu))
110 continue; 110 continue;
111 if (cpu_pda(cpu)->__nmi_count - counts[cpu] <= 5) { 111 if (cpu_pda(cpu)->__nmi_count - prev_nmi_count[cpu] <= 5) {
112 printk(KERN_WARNING "WARNING: CPU#%d: NMI " 112 printk(KERN_WARNING "WARNING: CPU#%d: NMI "
113 "appears to be stuck (%d->%d)!\n", 113 "appears to be stuck (%d->%d)!\n",
114 cpu, 114 cpu,
115 counts[cpu], 115 prev_nmi_count[cpu],
116 cpu_pda(cpu)->__nmi_count); 116 cpu_pda(cpu)->__nmi_count);
117 per_cpu(wd_enabled, cpu) = 0; 117 per_cpu(wd_enabled, cpu) = 0;
118 atomic_dec(&nmi_active); 118 atomic_dec(&nmi_active);
119 } 119 }
120 } 120 }
121 endflag = 1;
121 if (!atomic_read(&nmi_active)) { 122 if (!atomic_read(&nmi_active)) {
122 kfree(counts); 123 kfree(prev_nmi_count);
123 atomic_set(&nmi_active, -1); 124 atomic_set(&nmi_active, -1);
124 endflag = 1;
125 return -1; 125 return -1;
126 } 126 }
127 endflag = 1;
128 printk("OK.\n"); 127 printk("OK.\n");
129 128
130 /* now that we know it works we can reduce NMI frequency to 129 /* now that we know it works we can reduce NMI frequency to
@@ -132,11 +131,11 @@ int __init check_nmi_watchdog (void)
132 if (nmi_watchdog == NMI_LOCAL_APIC) 131 if (nmi_watchdog == NMI_LOCAL_APIC)
133 nmi_hz = lapic_adjust_nmi_hz(1); 132 nmi_hz = lapic_adjust_nmi_hz(1);
134 133
135 kfree(counts); 134 kfree(prev_nmi_count);
136 return 0; 135 return 0;
137} 136}
138 137
139int __init setup_nmi_watchdog(char *str) 138static int __init setup_nmi_watchdog(char *str)
140{ 139{
141 int nmi; 140 int nmi;
142 141
@@ -159,34 +158,6 @@ int __init setup_nmi_watchdog(char *str)
159 158
160__setup("nmi_watchdog=", setup_nmi_watchdog); 159__setup("nmi_watchdog=", setup_nmi_watchdog);
161 160
162
163static void __acpi_nmi_disable(void *__unused)
164{
165 apic_write(APIC_LVT0, APIC_DM_NMI | APIC_LVT_MASKED);
166}
167
168/*
169 * Disable timer based NMIs on all CPUs:
170 */
171void acpi_nmi_disable(void)
172{
173 if (atomic_read(&nmi_active) && nmi_watchdog == NMI_IO_APIC)
174 on_each_cpu(__acpi_nmi_disable, NULL, 0, 1);
175}
176
177static void __acpi_nmi_enable(void *__unused)
178{
179 apic_write(APIC_LVT0, APIC_DM_NMI);
180}
181
182/*
183 * Enable timer based NMIs on all CPUs:
184 */
185void acpi_nmi_enable(void)
186{
187 if (atomic_read(&nmi_active) && nmi_watchdog == NMI_IO_APIC)
188 on_each_cpu(__acpi_nmi_enable, NULL, 0, 1);
189}
190#ifdef CONFIG_PM 161#ifdef CONFIG_PM
191 162
192static int nmi_pm_active; /* nmi_active before suspend */ 163static int nmi_pm_active; /* nmi_active before suspend */
@@ -211,13 +182,13 @@ static int lapic_nmi_resume(struct sys_device *dev)
211} 182}
212 183
213static struct sysdev_class nmi_sysclass = { 184static struct sysdev_class nmi_sysclass = {
214 set_kset_name("lapic_nmi"), 185 .name = "lapic_nmi",
215 .resume = lapic_nmi_resume, 186 .resume = lapic_nmi_resume,
216 .suspend = lapic_nmi_suspend, 187 .suspend = lapic_nmi_suspend,
217}; 188};
218 189
219static struct sys_device device_lapic_nmi = { 190static struct sys_device device_lapic_nmi = {
220 .id = 0, 191 .id = 0,
221 .cls = &nmi_sysclass, 192 .cls = &nmi_sysclass,
222}; 193};
223 194
@@ -231,7 +202,7 @@ static int __init init_lapic_nmi_sysfs(void)
231 if (nmi_watchdog != NMI_LOCAL_APIC) 202 if (nmi_watchdog != NMI_LOCAL_APIC)
232 return 0; 203 return 0;
233 204
234 if ( atomic_read(&nmi_active) < 0 ) 205 if (atomic_read(&nmi_active) < 0)
235 return 0; 206 return 0;
236 207
237 error = sysdev_class_register(&nmi_sysclass); 208 error = sysdev_class_register(&nmi_sysclass);
@@ -244,9 +215,37 @@ late_initcall(init_lapic_nmi_sysfs);
244 215
245#endif /* CONFIG_PM */ 216#endif /* CONFIG_PM */
246 217
218static void __acpi_nmi_enable(void *__unused)
219{
220 apic_write(APIC_LVT0, APIC_DM_NMI);
221}
222
223/*
224 * Enable timer based NMIs on all CPUs:
225 */
226void acpi_nmi_enable(void)
227{
228 if (atomic_read(&nmi_active) && nmi_watchdog == NMI_IO_APIC)
229 on_each_cpu(__acpi_nmi_enable, NULL, 0, 1);
230}
231
232static void __acpi_nmi_disable(void *__unused)
233{
234 apic_write(APIC_LVT0, APIC_DM_NMI | APIC_LVT_MASKED);
235}
236
237/*
238 * Disable timer based NMIs on all CPUs:
239 */
240void acpi_nmi_disable(void)
241{
242 if (atomic_read(&nmi_active) && nmi_watchdog == NMI_IO_APIC)
243 on_each_cpu(__acpi_nmi_disable, NULL, 0, 1);
244}
245
247void setup_apic_nmi_watchdog(void *unused) 246void setup_apic_nmi_watchdog(void *unused)
248{ 247{
249 if (__get_cpu_var(wd_enabled) == 1) 248 if (__get_cpu_var(wd_enabled))
250 return; 249 return;
251 250
252 /* cheap hack to support suspend/resume */ 251 /* cheap hack to support suspend/resume */
@@ -311,8 +310,9 @@ void touch_nmi_watchdog(void)
311 } 310 }
312 } 311 }
313 312
314 touch_softlockup_watchdog(); 313 touch_softlockup_watchdog();
315} 314}
315EXPORT_SYMBOL(touch_nmi_watchdog);
316 316
317int __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) 317int __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason)
318{ 318{
@@ -479,4 +479,3 @@ void __trigger_all_cpu_backtrace(void)
479 479
480EXPORT_SYMBOL(nmi_active); 480EXPORT_SYMBOL(nmi_active);
481EXPORT_SYMBOL(nmi_watchdog); 481EXPORT_SYMBOL(nmi_watchdog);
482EXPORT_SYMBOL(touch_nmi_watchdog);
diff --git a/arch/x86/kernel/numaq_32.c b/arch/x86/kernel/numaq_32.c
index 9000d82c6dc0..e65281b1634b 100644
--- a/arch/x86/kernel/numaq_32.c
+++ b/arch/x86/kernel/numaq_32.c
@@ -82,7 +82,7 @@ static int __init numaq_tsc_disable(void)
82{ 82{
83 if (num_online_nodes() > 1) { 83 if (num_online_nodes() > 1) {
84 printk(KERN_DEBUG "NUMAQ: disabling TSC\n"); 84 printk(KERN_DEBUG "NUMAQ: disabling TSC\n");
85 tsc_disable = 1; 85 setup_clear_cpu_cap(X86_FEATURE_TSC);
86 } 86 }
87 return 0; 87 return 0;
88} 88}
diff --git a/arch/x86/kernel/paravirt_32.c b/arch/x86/kernel/paravirt.c
index f5000799f8ef..075962cc75ab 100644
--- a/arch/x86/kernel/paravirt_32.c
+++ b/arch/x86/kernel/paravirt.c
@@ -14,7 +14,10 @@
14 You should have received a copy of the GNU General Public License 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 15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
18 2007 - x86_64 support added by Glauber de Oliveira Costa, Red Hat Inc
17*/ 19*/
20
18#include <linux/errno.h> 21#include <linux/errno.h>
19#include <linux/module.h> 22#include <linux/module.h>
20#include <linux/efi.h> 23#include <linux/efi.h>
@@ -55,59 +58,9 @@ char *memory_setup(void)
55 extern const char start_##ops##_##name[], end_##ops##_##name[]; \ 58 extern const char start_##ops##_##name[], end_##ops##_##name[]; \
56 asm("start_" #ops "_" #name ": " code "; end_" #ops "_" #name ":") 59 asm("start_" #ops "_" #name ": " code "; end_" #ops "_" #name ":")
57 60
58DEF_NATIVE(pv_irq_ops, irq_disable, "cli");
59DEF_NATIVE(pv_irq_ops, irq_enable, "sti");
60DEF_NATIVE(pv_irq_ops, restore_fl, "push %eax; popf");
61DEF_NATIVE(pv_irq_ops, save_fl, "pushf; pop %eax");
62DEF_NATIVE(pv_cpu_ops, iret, "iret");
63DEF_NATIVE(pv_cpu_ops, irq_enable_sysexit, "sti; sysexit");
64DEF_NATIVE(pv_mmu_ops, read_cr2, "mov %cr2, %eax");
65DEF_NATIVE(pv_mmu_ops, write_cr3, "mov %eax, %cr3");
66DEF_NATIVE(pv_mmu_ops, read_cr3, "mov %cr3, %eax");
67DEF_NATIVE(pv_cpu_ops, clts, "clts");
68DEF_NATIVE(pv_cpu_ops, read_tsc, "rdtsc");
69
70/* Undefined instruction for dealing with missing ops pointers. */ 61/* Undefined instruction for dealing with missing ops pointers. */
71static const unsigned char ud2a[] = { 0x0f, 0x0b }; 62static const unsigned char ud2a[] = { 0x0f, 0x0b };
72 63
73static unsigned native_patch(u8 type, u16 clobbers, void *ibuf,
74 unsigned long addr, unsigned len)
75{
76 const unsigned char *start, *end;
77 unsigned ret;
78
79 switch(type) {
80#define SITE(ops, x) \
81 case PARAVIRT_PATCH(ops.x): \
82 start = start_##ops##_##x; \
83 end = end_##ops##_##x; \
84 goto patch_site
85
86 SITE(pv_irq_ops, irq_disable);
87 SITE(pv_irq_ops, irq_enable);
88 SITE(pv_irq_ops, restore_fl);
89 SITE(pv_irq_ops, save_fl);
90 SITE(pv_cpu_ops, iret);
91 SITE(pv_cpu_ops, irq_enable_sysexit);
92 SITE(pv_mmu_ops, read_cr2);
93 SITE(pv_mmu_ops, read_cr3);
94 SITE(pv_mmu_ops, write_cr3);
95 SITE(pv_cpu_ops, clts);
96 SITE(pv_cpu_ops, read_tsc);
97#undef SITE
98
99 patch_site:
100 ret = paravirt_patch_insns(ibuf, len, start, end);
101 break;
102
103 default:
104 ret = paravirt_patch_default(type, clobbers, ibuf, addr, len);
105 break;
106 }
107
108 return ret;
109}
110
111unsigned paravirt_patch_nop(void) 64unsigned paravirt_patch_nop(void)
112{ 65{
113 return 0; 66 return 0;
@@ -186,7 +139,7 @@ unsigned paravirt_patch_default(u8 type, u16 clobbers, void *insnbuf,
186 /* If the operation is a nop, then nop the callsite */ 139 /* If the operation is a nop, then nop the callsite */
187 ret = paravirt_patch_nop(); 140 ret = paravirt_patch_nop();
188 else if (type == PARAVIRT_PATCH(pv_cpu_ops.iret) || 141 else if (type == PARAVIRT_PATCH(pv_cpu_ops.iret) ||
189 type == PARAVIRT_PATCH(pv_cpu_ops.irq_enable_sysexit)) 142 type == PARAVIRT_PATCH(pv_cpu_ops.irq_enable_syscall_ret))
190 /* If operation requires a jmp, then jmp */ 143 /* If operation requires a jmp, then jmp */
191 ret = paravirt_patch_jmp(insnbuf, opfunc, addr, len); 144 ret = paravirt_patch_jmp(insnbuf, opfunc, addr, len);
192 else 145 else
@@ -237,7 +190,7 @@ static void native_flush_tlb_single(unsigned long addr)
237 190
238/* These are in entry.S */ 191/* These are in entry.S */
239extern void native_iret(void); 192extern void native_iret(void);
240extern void native_irq_enable_sysexit(void); 193extern void native_irq_enable_syscall_ret(void);
241 194
242static int __init print_banner(void) 195static int __init print_banner(void)
243{ 196{
@@ -285,18 +238,18 @@ static DEFINE_PER_CPU(enum paravirt_lazy_mode, paravirt_lazy_mode) = PARAVIRT_LA
285 238
286static inline void enter_lazy(enum paravirt_lazy_mode mode) 239static inline void enter_lazy(enum paravirt_lazy_mode mode)
287{ 240{
288 BUG_ON(x86_read_percpu(paravirt_lazy_mode) != PARAVIRT_LAZY_NONE); 241 BUG_ON(__get_cpu_var(paravirt_lazy_mode) != PARAVIRT_LAZY_NONE);
289 BUG_ON(preemptible()); 242 BUG_ON(preemptible());
290 243
291 x86_write_percpu(paravirt_lazy_mode, mode); 244 __get_cpu_var(paravirt_lazy_mode) = mode;
292} 245}
293 246
294void paravirt_leave_lazy(enum paravirt_lazy_mode mode) 247void paravirt_leave_lazy(enum paravirt_lazy_mode mode)
295{ 248{
296 BUG_ON(x86_read_percpu(paravirt_lazy_mode) != mode); 249 BUG_ON(__get_cpu_var(paravirt_lazy_mode) != mode);
297 BUG_ON(preemptible()); 250 BUG_ON(preemptible());
298 251
299 x86_write_percpu(paravirt_lazy_mode, PARAVIRT_LAZY_NONE); 252 __get_cpu_var(paravirt_lazy_mode) = PARAVIRT_LAZY_NONE;
300} 253}
301 254
302void paravirt_enter_lazy_mmu(void) 255void paravirt_enter_lazy_mmu(void)
@@ -321,7 +274,7 @@ void paravirt_leave_lazy_cpu(void)
321 274
322enum paravirt_lazy_mode paravirt_get_lazy_mode(void) 275enum paravirt_lazy_mode paravirt_get_lazy_mode(void)
323{ 276{
324 return x86_read_percpu(paravirt_lazy_mode); 277 return __get_cpu_var(paravirt_lazy_mode);
325} 278}
326 279
327struct pv_info pv_info = { 280struct pv_info pv_info = {
@@ -366,11 +319,16 @@ struct pv_cpu_ops pv_cpu_ops = {
366 .read_cr4 = native_read_cr4, 319 .read_cr4 = native_read_cr4,
367 .read_cr4_safe = native_read_cr4_safe, 320 .read_cr4_safe = native_read_cr4_safe,
368 .write_cr4 = native_write_cr4, 321 .write_cr4 = native_write_cr4,
322#ifdef CONFIG_X86_64
323 .read_cr8 = native_read_cr8,
324 .write_cr8 = native_write_cr8,
325#endif
369 .wbinvd = native_wbinvd, 326 .wbinvd = native_wbinvd,
370 .read_msr = native_read_msr_safe, 327 .read_msr = native_read_msr_safe,
371 .write_msr = native_write_msr_safe, 328 .write_msr = native_write_msr_safe,
372 .read_tsc = native_read_tsc, 329 .read_tsc = native_read_tsc,
373 .read_pmc = native_read_pmc, 330 .read_pmc = native_read_pmc,
331 .read_tscp = native_read_tscp,
374 .load_tr_desc = native_load_tr_desc, 332 .load_tr_desc = native_load_tr_desc,
375 .set_ldt = native_set_ldt, 333 .set_ldt = native_set_ldt,
376 .load_gdt = native_load_gdt, 334 .load_gdt = native_load_gdt,
@@ -379,13 +337,14 @@ struct pv_cpu_ops pv_cpu_ops = {
379 .store_idt = native_store_idt, 337 .store_idt = native_store_idt,
380 .store_tr = native_store_tr, 338 .store_tr = native_store_tr,
381 .load_tls = native_load_tls, 339 .load_tls = native_load_tls,
382 .write_ldt_entry = write_dt_entry, 340 .write_ldt_entry = native_write_ldt_entry,
383 .write_gdt_entry = write_dt_entry, 341 .write_gdt_entry = native_write_gdt_entry,
384 .write_idt_entry = write_dt_entry, 342 .write_idt_entry = native_write_idt_entry,
385 .load_esp0 = native_load_esp0, 343 .load_sp0 = native_load_sp0,
386 344
387 .irq_enable_sysexit = native_irq_enable_sysexit, 345 .irq_enable_syscall_ret = native_irq_enable_syscall_ret,
388 .iret = native_iret, 346 .iret = native_iret,
347 .swapgs = native_swapgs,
389 348
390 .set_iopl_mask = native_set_iopl_mask, 349 .set_iopl_mask = native_set_iopl_mask,
391 .io_delay = native_io_delay, 350 .io_delay = native_io_delay,
@@ -408,8 +367,10 @@ struct pv_apic_ops pv_apic_ops = {
408}; 367};
409 368
410struct pv_mmu_ops pv_mmu_ops = { 369struct pv_mmu_ops pv_mmu_ops = {
370#ifndef CONFIG_X86_64
411 .pagetable_setup_start = native_pagetable_setup_start, 371 .pagetable_setup_start = native_pagetable_setup_start,
412 .pagetable_setup_done = native_pagetable_setup_done, 372 .pagetable_setup_done = native_pagetable_setup_done,
373#endif
413 374
414 .read_cr2 = native_read_cr2, 375 .read_cr2 = native_read_cr2,
415 .write_cr2 = native_write_cr2, 376 .write_cr2 = native_write_cr2,
@@ -437,16 +398,23 @@ struct pv_mmu_ops pv_mmu_ops = {
437 .kmap_atomic_pte = kmap_atomic, 398 .kmap_atomic_pte = kmap_atomic,
438#endif 399#endif
439 400
401#if PAGETABLE_LEVELS >= 3
440#ifdef CONFIG_X86_PAE 402#ifdef CONFIG_X86_PAE
441 .set_pte_atomic = native_set_pte_atomic, 403 .set_pte_atomic = native_set_pte_atomic,
442 .set_pte_present = native_set_pte_present, 404 .set_pte_present = native_set_pte_present,
443 .set_pud = native_set_pud,
444 .pte_clear = native_pte_clear, 405 .pte_clear = native_pte_clear,
445 .pmd_clear = native_pmd_clear, 406 .pmd_clear = native_pmd_clear,
446 407#endif
408 .set_pud = native_set_pud,
447 .pmd_val = native_pmd_val, 409 .pmd_val = native_pmd_val,
448 .make_pmd = native_make_pmd, 410 .make_pmd = native_make_pmd,
411
412#if PAGETABLE_LEVELS == 4
413 .pud_val = native_pud_val,
414 .make_pud = native_make_pud,
415 .set_pgd = native_set_pgd,
449#endif 416#endif
417#endif /* PAGETABLE_LEVELS >= 3 */
450 418
451 .pte_val = native_pte_val, 419 .pte_val = native_pte_val,
452 .pgd_val = native_pgd_val, 420 .pgd_val = native_pgd_val,
diff --git a/arch/x86/kernel/paravirt_patch_32.c b/arch/x86/kernel/paravirt_patch_32.c
new file mode 100644
index 000000000000..82fc5fcab4f4
--- /dev/null
+++ b/arch/x86/kernel/paravirt_patch_32.c
@@ -0,0 +1,49 @@
1#include <asm/paravirt.h>
2
3DEF_NATIVE(pv_irq_ops, irq_disable, "cli");
4DEF_NATIVE(pv_irq_ops, irq_enable, "sti");
5DEF_NATIVE(pv_irq_ops, restore_fl, "push %eax; popf");
6DEF_NATIVE(pv_irq_ops, save_fl, "pushf; pop %eax");
7DEF_NATIVE(pv_cpu_ops, iret, "iret");
8DEF_NATIVE(pv_cpu_ops, irq_enable_syscall_ret, "sti; sysexit");
9DEF_NATIVE(pv_mmu_ops, read_cr2, "mov %cr2, %eax");
10DEF_NATIVE(pv_mmu_ops, write_cr3, "mov %eax, %cr3");
11DEF_NATIVE(pv_mmu_ops, read_cr3, "mov %cr3, %eax");
12DEF_NATIVE(pv_cpu_ops, clts, "clts");
13DEF_NATIVE(pv_cpu_ops, read_tsc, "rdtsc");
14
15unsigned native_patch(u8 type, u16 clobbers, void *ibuf,
16 unsigned long addr, unsigned len)
17{
18 const unsigned char *start, *end;
19 unsigned ret;
20
21#define PATCH_SITE(ops, x) \
22 case PARAVIRT_PATCH(ops.x): \
23 start = start_##ops##_##x; \
24 end = end_##ops##_##x; \
25 goto patch_site
26 switch(type) {
27 PATCH_SITE(pv_irq_ops, irq_disable);
28 PATCH_SITE(pv_irq_ops, irq_enable);
29 PATCH_SITE(pv_irq_ops, restore_fl);
30 PATCH_SITE(pv_irq_ops, save_fl);
31 PATCH_SITE(pv_cpu_ops, iret);
32 PATCH_SITE(pv_cpu_ops, irq_enable_syscall_ret);
33 PATCH_SITE(pv_mmu_ops, read_cr2);
34 PATCH_SITE(pv_mmu_ops, read_cr3);
35 PATCH_SITE(pv_mmu_ops, write_cr3);
36 PATCH_SITE(pv_cpu_ops, clts);
37 PATCH_SITE(pv_cpu_ops, read_tsc);
38
39 patch_site:
40 ret = paravirt_patch_insns(ibuf, len, start, end);
41 break;
42
43 default:
44 ret = paravirt_patch_default(type, clobbers, ibuf, addr, len);
45 break;
46 }
47#undef PATCH_SITE
48 return ret;
49}
diff --git a/arch/x86/kernel/paravirt_patch_64.c b/arch/x86/kernel/paravirt_patch_64.c
new file mode 100644
index 000000000000..7d904e138d7e
--- /dev/null
+++ b/arch/x86/kernel/paravirt_patch_64.c
@@ -0,0 +1,57 @@
1#include <asm/paravirt.h>
2#include <asm/asm-offsets.h>
3#include <linux/stringify.h>
4
5DEF_NATIVE(pv_irq_ops, irq_disable, "cli");
6DEF_NATIVE(pv_irq_ops, irq_enable, "sti");
7DEF_NATIVE(pv_irq_ops, restore_fl, "pushq %rdi; popfq");
8DEF_NATIVE(pv_irq_ops, save_fl, "pushfq; popq %rax");
9DEF_NATIVE(pv_cpu_ops, iret, "iretq");
10DEF_NATIVE(pv_mmu_ops, read_cr2, "movq %cr2, %rax");
11DEF_NATIVE(pv_mmu_ops, read_cr3, "movq %cr3, %rax");
12DEF_NATIVE(pv_mmu_ops, write_cr3, "movq %rdi, %cr3");
13DEF_NATIVE(pv_mmu_ops, flush_tlb_single, "invlpg (%rdi)");
14DEF_NATIVE(pv_cpu_ops, clts, "clts");
15DEF_NATIVE(pv_cpu_ops, wbinvd, "wbinvd");
16
17/* the three commands give us more control to how to return from a syscall */
18DEF_NATIVE(pv_cpu_ops, irq_enable_syscall_ret, "movq %gs:" __stringify(pda_oldrsp) ", %rsp; swapgs; sysretq;");
19DEF_NATIVE(pv_cpu_ops, swapgs, "swapgs");
20
21unsigned native_patch(u8 type, u16 clobbers, void *ibuf,
22 unsigned long addr, unsigned len)
23{
24 const unsigned char *start, *end;
25 unsigned ret;
26
27#define PATCH_SITE(ops, x) \
28 case PARAVIRT_PATCH(ops.x): \
29 start = start_##ops##_##x; \
30 end = end_##ops##_##x; \
31 goto patch_site
32 switch(type) {
33 PATCH_SITE(pv_irq_ops, restore_fl);
34 PATCH_SITE(pv_irq_ops, save_fl);
35 PATCH_SITE(pv_irq_ops, irq_enable);
36 PATCH_SITE(pv_irq_ops, irq_disable);
37 PATCH_SITE(pv_cpu_ops, iret);
38 PATCH_SITE(pv_cpu_ops, irq_enable_syscall_ret);
39 PATCH_SITE(pv_cpu_ops, swapgs);
40 PATCH_SITE(pv_mmu_ops, read_cr2);
41 PATCH_SITE(pv_mmu_ops, read_cr3);
42 PATCH_SITE(pv_mmu_ops, write_cr3);
43 PATCH_SITE(pv_cpu_ops, clts);
44 PATCH_SITE(pv_mmu_ops, flush_tlb_single);
45 PATCH_SITE(pv_cpu_ops, wbinvd);
46
47 patch_site:
48 ret = paravirt_patch_insns(ibuf, len, start, end);
49 break;
50
51 default:
52 ret = paravirt_patch_default(type, clobbers, ibuf, addr, len);
53 break;
54 }
55#undef PATCH_SITE
56 return ret;
57}
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
index 6bf1f716909d..21f34db2c03c 100644
--- a/arch/x86/kernel/pci-calgary_64.c
+++ b/arch/x86/kernel/pci-calgary_64.c
@@ -30,7 +30,6 @@
30#include <linux/spinlock.h> 30#include <linux/spinlock.h>
31#include <linux/string.h> 31#include <linux/string.h>
32#include <linux/dma-mapping.h> 32#include <linux/dma-mapping.h>
33#include <linux/init.h>
34#include <linux/bitops.h> 33#include <linux/bitops.h>
35#include <linux/pci_ids.h> 34#include <linux/pci_ids.h>
36#include <linux/pci.h> 35#include <linux/pci.h>
@@ -183,7 +182,7 @@ static struct calgary_bus_info bus_info[MAX_PHB_BUS_NUM] = { { NULL, 0, 0 }, };
183 182
184/* enable this to stress test the chip's TCE cache */ 183/* enable this to stress test the chip's TCE cache */
185#ifdef CONFIG_IOMMU_DEBUG 184#ifdef CONFIG_IOMMU_DEBUG
186int debugging __read_mostly = 1; 185static int debugging = 1;
187 186
188static inline unsigned long verify_bit_range(unsigned long* bitmap, 187static inline unsigned long verify_bit_range(unsigned long* bitmap,
189 int expected, unsigned long start, unsigned long end) 188 int expected, unsigned long start, unsigned long end)
@@ -202,7 +201,7 @@ static inline unsigned long verify_bit_range(unsigned long* bitmap,
202 return ~0UL; 201 return ~0UL;
203} 202}
204#else /* debugging is disabled */ 203#else /* debugging is disabled */
205int debugging __read_mostly = 0; 204static int debugging;
206 205
207static inline unsigned long verify_bit_range(unsigned long* bitmap, 206static inline unsigned long verify_bit_range(unsigned long* bitmap,
208 int expected, unsigned long start, unsigned long end) 207 int expected, unsigned long start, unsigned long end)
diff --git a/arch/x86/kernel/pci-dma_64.c b/arch/x86/kernel/pci-dma_64.c
index 5552d23d23c2..a82473d192a3 100644
--- a/arch/x86/kernel/pci-dma_64.c
+++ b/arch/x86/kernel/pci-dma_64.c
@@ -13,7 +13,6 @@
13#include <asm/calgary.h> 13#include <asm/calgary.h>
14 14
15int iommu_merge __read_mostly = 0; 15int iommu_merge __read_mostly = 0;
16EXPORT_SYMBOL(iommu_merge);
17 16
18dma_addr_t bad_dma_address __read_mostly; 17dma_addr_t bad_dma_address __read_mostly;
19EXPORT_SYMBOL(bad_dma_address); 18EXPORT_SYMBOL(bad_dma_address);
@@ -230,7 +229,7 @@ EXPORT_SYMBOL(dma_set_mask);
230 * See <Documentation/x86_64/boot-options.txt> for the iommu kernel parameter 229 * See <Documentation/x86_64/boot-options.txt> for the iommu kernel parameter
231 * documentation. 230 * documentation.
232 */ 231 */
233__init int iommu_setup(char *p) 232static __init int iommu_setup(char *p)
234{ 233{
235 iommu_merge = 1; 234 iommu_merge = 1;
236 235
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
index 06bcba536045..4d5cc7181982 100644
--- a/arch/x86/kernel/pci-gart_64.c
+++ b/arch/x86/kernel/pci-gart_64.c
@@ -1,12 +1,12 @@
1/* 1/*
2 * Dynamic DMA mapping support for AMD Hammer. 2 * Dynamic DMA mapping support for AMD Hammer.
3 * 3 *
4 * Use the integrated AGP GART in the Hammer northbridge as an IOMMU for PCI. 4 * Use the integrated AGP GART in the Hammer northbridge as an IOMMU for PCI.
5 * This allows to use PCI devices that only support 32bit addresses on systems 5 * This allows to use PCI devices that only support 32bit addresses on systems
6 * with more than 4GB. 6 * with more than 4GB.
7 * 7 *
8 * See Documentation/DMA-mapping.txt for the interface specification. 8 * See Documentation/DMA-mapping.txt for the interface specification.
9 * 9 *
10 * Copyright 2002 Andi Kleen, SuSE Labs. 10 * Copyright 2002 Andi Kleen, SuSE Labs.
11 * Subject to the GNU General Public License v2 only. 11 * Subject to the GNU General Public License v2 only.
12 */ 12 */
@@ -37,23 +37,26 @@
37#include <asm/k8.h> 37#include <asm/k8.h>
38 38
39static unsigned long iommu_bus_base; /* GART remapping area (physical) */ 39static unsigned long iommu_bus_base; /* GART remapping area (physical) */
40static unsigned long iommu_size; /* size of remapping area bytes */ 40static unsigned long iommu_size; /* size of remapping area bytes */
41static unsigned long iommu_pages; /* .. and in pages */ 41static unsigned long iommu_pages; /* .. and in pages */
42 42
43static u32 *iommu_gatt_base; /* Remapping table */ 43static u32 *iommu_gatt_base; /* Remapping table */
44 44
45/* If this is disabled the IOMMU will use an optimized flushing strategy 45/*
46 of only flushing when an mapping is reused. With it true the GART is flushed 46 * If this is disabled the IOMMU will use an optimized flushing strategy
47 for every mapping. Problem is that doing the lazy flush seems to trigger 47 * of only flushing when an mapping is reused. With it true the GART is
48 bugs with some popular PCI cards, in particular 3ware (but has been also 48 * flushed for every mapping. Problem is that doing the lazy flush seems
49 also seen with Qlogic at least). */ 49 * to trigger bugs with some popular PCI cards, in particular 3ware (but
50 * has been also also seen with Qlogic at least).
51 */
50int iommu_fullflush = 1; 52int iommu_fullflush = 1;
51 53
52/* Allocation bitmap for the remapping area */ 54/* Allocation bitmap for the remapping area: */
53static DEFINE_SPINLOCK(iommu_bitmap_lock); 55static DEFINE_SPINLOCK(iommu_bitmap_lock);
54static unsigned long *iommu_gart_bitmap; /* guarded by iommu_bitmap_lock */ 56/* Guarded by iommu_bitmap_lock: */
57static unsigned long *iommu_gart_bitmap;
55 58
56static u32 gart_unmapped_entry; 59static u32 gart_unmapped_entry;
57 60
58#define GPTE_VALID 1 61#define GPTE_VALID 1
59#define GPTE_COHERENT 2 62#define GPTE_COHERENT 2
@@ -61,10 +64,10 @@ static u32 gart_unmapped_entry;
61 (((x) & 0xfffff000) | (((x) >> 32) << 4) | GPTE_VALID | GPTE_COHERENT) 64 (((x) & 0xfffff000) | (((x) >> 32) << 4) | GPTE_VALID | GPTE_COHERENT)
62#define GPTE_DECODE(x) (((x) & 0xfffff000) | (((u64)(x) & 0xff0) << 28)) 65#define GPTE_DECODE(x) (((x) & 0xfffff000) | (((u64)(x) & 0xff0) << 28))
63 66
64#define to_pages(addr,size) \ 67#define to_pages(addr, size) \
65 (round_up(((addr) & ~PAGE_MASK) + (size), PAGE_SIZE) >> PAGE_SHIFT) 68 (round_up(((addr) & ~PAGE_MASK) + (size), PAGE_SIZE) >> PAGE_SHIFT)
66 69
67#define EMERGENCY_PAGES 32 /* = 128KB */ 70#define EMERGENCY_PAGES 32 /* = 128KB */
68 71
69#ifdef CONFIG_AGP 72#ifdef CONFIG_AGP
70#define AGPEXTERN extern 73#define AGPEXTERN extern
@@ -77,130 +80,152 @@ AGPEXTERN int agp_memory_reserved;
77AGPEXTERN __u32 *agp_gatt_table; 80AGPEXTERN __u32 *agp_gatt_table;
78 81
79static unsigned long next_bit; /* protected by iommu_bitmap_lock */ 82static unsigned long next_bit; /* protected by iommu_bitmap_lock */
80static int need_flush; /* global flush state. set for each gart wrap */ 83static int need_flush; /* global flush state. set for each gart wrap */
81 84
82static unsigned long alloc_iommu(int size) 85static unsigned long alloc_iommu(int size)
83{ 86{
84 unsigned long offset, flags; 87 unsigned long offset, flags;
85 88
86 spin_lock_irqsave(&iommu_bitmap_lock, flags); 89 spin_lock_irqsave(&iommu_bitmap_lock, flags);
87 offset = find_next_zero_string(iommu_gart_bitmap,next_bit,iommu_pages,size); 90 offset = find_next_zero_string(iommu_gart_bitmap, next_bit,
91 iommu_pages, size);
88 if (offset == -1) { 92 if (offset == -1) {
89 need_flush = 1; 93 need_flush = 1;
90 offset = find_next_zero_string(iommu_gart_bitmap,0,iommu_pages,size); 94 offset = find_next_zero_string(iommu_gart_bitmap, 0,
95 iommu_pages, size);
91 } 96 }
92 if (offset != -1) { 97 if (offset != -1) {
93 set_bit_string(iommu_gart_bitmap, offset, size); 98 set_bit_string(iommu_gart_bitmap, offset, size);
94 next_bit = offset+size; 99 next_bit = offset+size;
95 if (next_bit >= iommu_pages) { 100 if (next_bit >= iommu_pages) {
96 next_bit = 0; 101 next_bit = 0;
97 need_flush = 1; 102 need_flush = 1;
98 } 103 }
99 } 104 }
100 if (iommu_fullflush) 105 if (iommu_fullflush)
101 need_flush = 1; 106 need_flush = 1;
102 spin_unlock_irqrestore(&iommu_bitmap_lock, flags); 107 spin_unlock_irqrestore(&iommu_bitmap_lock, flags);
108
103 return offset; 109 return offset;
104} 110}
105 111
106static void free_iommu(unsigned long offset, int size) 112static void free_iommu(unsigned long offset, int size)
107{ 113{
108 unsigned long flags; 114 unsigned long flags;
115
109 spin_lock_irqsave(&iommu_bitmap_lock, flags); 116 spin_lock_irqsave(&iommu_bitmap_lock, flags);
110 __clear_bit_string(iommu_gart_bitmap, offset, size); 117 __clear_bit_string(iommu_gart_bitmap, offset, size);
111 spin_unlock_irqrestore(&iommu_bitmap_lock, flags); 118 spin_unlock_irqrestore(&iommu_bitmap_lock, flags);
112} 119}
113 120
114/* 121/*
115 * Use global flush state to avoid races with multiple flushers. 122 * Use global flush state to avoid races with multiple flushers.
116 */ 123 */
117static void flush_gart(void) 124static void flush_gart(void)
118{ 125{
119 unsigned long flags; 126 unsigned long flags;
127
120 spin_lock_irqsave(&iommu_bitmap_lock, flags); 128 spin_lock_irqsave(&iommu_bitmap_lock, flags);
121 if (need_flush) { 129 if (need_flush) {
122 k8_flush_garts(); 130 k8_flush_garts();
123 need_flush = 0; 131 need_flush = 0;
124 } 132 }
125 spin_unlock_irqrestore(&iommu_bitmap_lock, flags); 133 spin_unlock_irqrestore(&iommu_bitmap_lock, flags);
126} 134}
127 135
128#ifdef CONFIG_IOMMU_LEAK 136#ifdef CONFIG_IOMMU_LEAK
129 137
130#define SET_LEAK(x) if (iommu_leak_tab) \ 138#define SET_LEAK(x) \
131 iommu_leak_tab[x] = __builtin_return_address(0); 139 do { \
132#define CLEAR_LEAK(x) if (iommu_leak_tab) \ 140 if (iommu_leak_tab) \
133 iommu_leak_tab[x] = NULL; 141 iommu_leak_tab[x] = __builtin_return_address(0);\
142 } while (0)
143
144#define CLEAR_LEAK(x) \
145 do { \
146 if (iommu_leak_tab) \
147 iommu_leak_tab[x] = NULL; \
148 } while (0)
134 149
135/* Debugging aid for drivers that don't free their IOMMU tables */ 150/* Debugging aid for drivers that don't free their IOMMU tables */
136static void **iommu_leak_tab; 151static void **iommu_leak_tab;
137static int leak_trace; 152static int leak_trace;
138static int iommu_leak_pages = 20; 153static int iommu_leak_pages = 20;
154
139static void dump_leak(void) 155static void dump_leak(void)
140{ 156{
141 int i; 157 int i;
142 static int dump; 158 static int dump;
143 if (dump || !iommu_leak_tab) return; 159
160 if (dump || !iommu_leak_tab)
161 return;
144 dump = 1; 162 dump = 1;
145 show_stack(NULL,NULL); 163 show_stack(NULL, NULL);
146 /* Very crude. dump some from the end of the table too */ 164
147 printk("Dumping %d pages from end of IOMMU:\n", iommu_leak_pages); 165 /* Very crude. dump some from the end of the table too */
148 for (i = 0; i < iommu_leak_pages; i+=2) { 166 printk(KERN_DEBUG "Dumping %d pages from end of IOMMU:\n",
149 printk("%lu: ", iommu_pages-i); 167 iommu_leak_pages);
150 printk_address((unsigned long) iommu_leak_tab[iommu_pages-i]); 168 for (i = 0; i < iommu_leak_pages; i += 2) {
151 printk("%c", (i+1)%2 == 0 ? '\n' : ' '); 169 printk(KERN_DEBUG "%lu: ", iommu_pages-i);
152 } 170 printk_address((unsigned long) iommu_leak_tab[iommu_pages-i], 0);
153 printk("\n"); 171 printk(KERN_CONT "%c", (i+1)%2 == 0 ? '\n' : ' ');
172 }
173 printk(KERN_DEBUG "\n");
154} 174}
155#else 175#else
156#define SET_LEAK(x) 176# define SET_LEAK(x)
157#define CLEAR_LEAK(x) 177# define CLEAR_LEAK(x)
158#endif 178#endif
159 179
160static void iommu_full(struct device *dev, size_t size, int dir) 180static void iommu_full(struct device *dev, size_t size, int dir)
161{ 181{
162 /* 182 /*
163 * Ran out of IOMMU space for this operation. This is very bad. 183 * Ran out of IOMMU space for this operation. This is very bad.
164 * Unfortunately the drivers cannot handle this operation properly. 184 * Unfortunately the drivers cannot handle this operation properly.
165 * Return some non mapped prereserved space in the aperture and 185 * Return some non mapped prereserved space in the aperture and
166 * let the Northbridge deal with it. This will result in garbage 186 * let the Northbridge deal with it. This will result in garbage
167 * in the IO operation. When the size exceeds the prereserved space 187 * in the IO operation. When the size exceeds the prereserved space
168 * memory corruption will occur or random memory will be DMAed 188 * memory corruption will occur or random memory will be DMAed
169 * out. Hopefully no network devices use single mappings that big. 189 * out. Hopefully no network devices use single mappings that big.
170 */ 190 */
171 191
172 printk(KERN_ERR 192 printk(KERN_ERR
173 "PCI-DMA: Out of IOMMU space for %lu bytes at device %s\n", 193 "PCI-DMA: Out of IOMMU space for %lu bytes at device %s\n",
174 size, dev->bus_id); 194 size, dev->bus_id);
175 195
176 if (size > PAGE_SIZE*EMERGENCY_PAGES) { 196 if (size > PAGE_SIZE*EMERGENCY_PAGES) {
177 if (dir == PCI_DMA_FROMDEVICE || dir == PCI_DMA_BIDIRECTIONAL) 197 if (dir == PCI_DMA_FROMDEVICE || dir == PCI_DMA_BIDIRECTIONAL)
178 panic("PCI-DMA: Memory would be corrupted\n"); 198 panic("PCI-DMA: Memory would be corrupted\n");
179 if (dir == PCI_DMA_TODEVICE || dir == PCI_DMA_BIDIRECTIONAL) 199 if (dir == PCI_DMA_TODEVICE || dir == PCI_DMA_BIDIRECTIONAL)
180 panic(KERN_ERR "PCI-DMA: Random memory would be DMAed\n"); 200 panic(KERN_ERR
181 } 201 "PCI-DMA: Random memory would be DMAed\n");
182 202 }
183#ifdef CONFIG_IOMMU_LEAK 203#ifdef CONFIG_IOMMU_LEAK
184 dump_leak(); 204 dump_leak();
185#endif 205#endif
186} 206}
187 207
188static inline int need_iommu(struct device *dev, unsigned long addr, size_t size) 208static inline int
189{ 209need_iommu(struct device *dev, unsigned long addr, size_t size)
210{
190 u64 mask = *dev->dma_mask; 211 u64 mask = *dev->dma_mask;
191 int high = addr + size > mask; 212 int high = addr + size > mask;
192 int mmu = high; 213 int mmu = high;
193 if (force_iommu) 214
194 mmu = 1; 215 if (force_iommu)
195 return mmu; 216 mmu = 1;
217
218 return mmu;
196} 219}
197 220
198static inline int nonforced_iommu(struct device *dev, unsigned long addr, size_t size) 221static inline int
199{ 222nonforced_iommu(struct device *dev, unsigned long addr, size_t size)
223{
200 u64 mask = *dev->dma_mask; 224 u64 mask = *dev->dma_mask;
201 int high = addr + size > mask; 225 int high = addr + size > mask;
202 int mmu = high; 226 int mmu = high;
203 return mmu; 227
228 return mmu;
204} 229}
205 230
206/* Map a single continuous physical area into the IOMMU. 231/* Map a single continuous physical area into the IOMMU.
@@ -208,13 +233,14 @@ static inline int nonforced_iommu(struct device *dev, unsigned long addr, size_t
208 */ 233 */
209static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem, 234static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem,
210 size_t size, int dir) 235 size_t size, int dir)
211{ 236{
212 unsigned long npages = to_pages(phys_mem, size); 237 unsigned long npages = to_pages(phys_mem, size);
213 unsigned long iommu_page = alloc_iommu(npages); 238 unsigned long iommu_page = alloc_iommu(npages);
214 int i; 239 int i;
240
215 if (iommu_page == -1) { 241 if (iommu_page == -1) {
216 if (!nonforced_iommu(dev, phys_mem, size)) 242 if (!nonforced_iommu(dev, phys_mem, size))
217 return phys_mem; 243 return phys_mem;
218 if (panic_on_overflow) 244 if (panic_on_overflow)
219 panic("dma_map_area overflow %lu bytes\n", size); 245 panic("dma_map_area overflow %lu bytes\n", size);
220 iommu_full(dev, size, dir); 246 iommu_full(dev, size, dir);
@@ -229,35 +255,39 @@ static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem,
229 return iommu_bus_base + iommu_page*PAGE_SIZE + (phys_mem & ~PAGE_MASK); 255 return iommu_bus_base + iommu_page*PAGE_SIZE + (phys_mem & ~PAGE_MASK);
230} 256}
231 257
232static dma_addr_t gart_map_simple(struct device *dev, char *buf, 258static dma_addr_t
233 size_t size, int dir) 259gart_map_simple(struct device *dev, char *buf, size_t size, int dir)
234{ 260{
235 dma_addr_t map = dma_map_area(dev, virt_to_bus(buf), size, dir); 261 dma_addr_t map = dma_map_area(dev, virt_to_bus(buf), size, dir);
262
236 flush_gart(); 263 flush_gart();
264
237 return map; 265 return map;
238} 266}
239 267
240/* Map a single area into the IOMMU */ 268/* Map a single area into the IOMMU */
241static dma_addr_t gart_map_single(struct device *dev, void *addr, size_t size, int dir) 269static dma_addr_t
270gart_map_single(struct device *dev, void *addr, size_t size, int dir)
242{ 271{
243 unsigned long phys_mem, bus; 272 unsigned long phys_mem, bus;
244 273
245 if (!dev) 274 if (!dev)
246 dev = &fallback_dev; 275 dev = &fallback_dev;
247 276
248 phys_mem = virt_to_phys(addr); 277 phys_mem = virt_to_phys(addr);
249 if (!need_iommu(dev, phys_mem, size)) 278 if (!need_iommu(dev, phys_mem, size))
250 return phys_mem; 279 return phys_mem;
251 280
252 bus = gart_map_simple(dev, addr, size, dir); 281 bus = gart_map_simple(dev, addr, size, dir);
253 return bus; 282
283 return bus;
254} 284}
255 285
256/* 286/*
257 * Free a DMA mapping. 287 * Free a DMA mapping.
258 */ 288 */
259static void gart_unmap_single(struct device *dev, dma_addr_t dma_addr, 289static void gart_unmap_single(struct device *dev, dma_addr_t dma_addr,
260 size_t size, int direction) 290 size_t size, int direction)
261{ 291{
262 unsigned long iommu_page; 292 unsigned long iommu_page;
263 int npages; 293 int npages;
@@ -266,6 +296,7 @@ static void gart_unmap_single(struct device *dev, dma_addr_t dma_addr,
266 if (dma_addr < iommu_bus_base + EMERGENCY_PAGES*PAGE_SIZE || 296 if (dma_addr < iommu_bus_base + EMERGENCY_PAGES*PAGE_SIZE ||
267 dma_addr >= iommu_bus_base + iommu_size) 297 dma_addr >= iommu_bus_base + iommu_size)
268 return; 298 return;
299
269 iommu_page = (dma_addr - iommu_bus_base)>>PAGE_SHIFT; 300 iommu_page = (dma_addr - iommu_bus_base)>>PAGE_SHIFT;
270 npages = to_pages(dma_addr, size); 301 npages = to_pages(dma_addr, size);
271 for (i = 0; i < npages; i++) { 302 for (i = 0; i < npages; i++) {
@@ -278,7 +309,8 @@ static void gart_unmap_single(struct device *dev, dma_addr_t dma_addr,
278/* 309/*
279 * Wrapper for pci_unmap_single working with scatterlists. 310 * Wrapper for pci_unmap_single working with scatterlists.
280 */ 311 */
281static void gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) 312static void
313gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
282{ 314{
283 struct scatterlist *s; 315 struct scatterlist *s;
284 int i; 316 int i;
@@ -303,12 +335,13 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg,
303 335
304 for_each_sg(sg, s, nents, i) { 336 for_each_sg(sg, s, nents, i) {
305 unsigned long addr = sg_phys(s); 337 unsigned long addr = sg_phys(s);
306 if (nonforced_iommu(dev, addr, s->length)) { 338
339 if (nonforced_iommu(dev, addr, s->length)) {
307 addr = dma_map_area(dev, addr, s->length, dir); 340 addr = dma_map_area(dev, addr, s->length, dir);
308 if (addr == bad_dma_address) { 341 if (addr == bad_dma_address) {
309 if (i > 0) 342 if (i > 0)
310 gart_unmap_sg(dev, sg, i, dir); 343 gart_unmap_sg(dev, sg, i, dir);
311 nents = 0; 344 nents = 0;
312 sg[0].dma_length = 0; 345 sg[0].dma_length = 0;
313 break; 346 break;
314 } 347 }
@@ -317,15 +350,16 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg,
317 s->dma_length = s->length; 350 s->dma_length = s->length;
318 } 351 }
319 flush_gart(); 352 flush_gart();
353
320 return nents; 354 return nents;
321} 355}
322 356
323/* Map multiple scatterlist entries continuous into the first. */ 357/* Map multiple scatterlist entries continuous into the first. */
324static int __dma_map_cont(struct scatterlist *start, int nelems, 358static int __dma_map_cont(struct scatterlist *start, int nelems,
325 struct scatterlist *sout, unsigned long pages) 359 struct scatterlist *sout, unsigned long pages)
326{ 360{
327 unsigned long iommu_start = alloc_iommu(pages); 361 unsigned long iommu_start = alloc_iommu(pages);
328 unsigned long iommu_page = iommu_start; 362 unsigned long iommu_page = iommu_start;
329 struct scatterlist *s; 363 struct scatterlist *s;
330 int i; 364 int i;
331 365
@@ -335,32 +369,33 @@ static int __dma_map_cont(struct scatterlist *start, int nelems,
335 for_each_sg(start, s, nelems, i) { 369 for_each_sg(start, s, nelems, i) {
336 unsigned long pages, addr; 370 unsigned long pages, addr;
337 unsigned long phys_addr = s->dma_address; 371 unsigned long phys_addr = s->dma_address;
338 372
339 BUG_ON(s != start && s->offset); 373 BUG_ON(s != start && s->offset);
340 if (s == start) { 374 if (s == start) {
341 sout->dma_address = iommu_bus_base; 375 sout->dma_address = iommu_bus_base;
342 sout->dma_address += iommu_page*PAGE_SIZE + s->offset; 376 sout->dma_address += iommu_page*PAGE_SIZE + s->offset;
343 sout->dma_length = s->length; 377 sout->dma_length = s->length;
344 } else { 378 } else {
345 sout->dma_length += s->length; 379 sout->dma_length += s->length;
346 } 380 }
347 381
348 addr = phys_addr; 382 addr = phys_addr;
349 pages = to_pages(s->offset, s->length); 383 pages = to_pages(s->offset, s->length);
350 while (pages--) { 384 while (pages--) {
351 iommu_gatt_base[iommu_page] = GPTE_ENCODE(addr); 385 iommu_gatt_base[iommu_page] = GPTE_ENCODE(addr);
352 SET_LEAK(iommu_page); 386 SET_LEAK(iommu_page);
353 addr += PAGE_SIZE; 387 addr += PAGE_SIZE;
354 iommu_page++; 388 iommu_page++;
355 } 389 }
356 } 390 }
357 BUG_ON(iommu_page - iommu_start != pages); 391 BUG_ON(iommu_page - iommu_start != pages);
392
358 return 0; 393 return 0;
359} 394}
360 395
361static inline int dma_map_cont(struct scatterlist *start, int nelems, 396static inline int
362 struct scatterlist *sout, 397dma_map_cont(struct scatterlist *start, int nelems, struct scatterlist *sout,
363 unsigned long pages, int need) 398 unsigned long pages, int need)
364{ 399{
365 if (!need) { 400 if (!need) {
366 BUG_ON(nelems != 1); 401 BUG_ON(nelems != 1);
@@ -370,22 +405,19 @@ static inline int dma_map_cont(struct scatterlist *start, int nelems,
370 } 405 }
371 return __dma_map_cont(start, nelems, sout, pages); 406 return __dma_map_cont(start, nelems, sout, pages);
372} 407}
373 408
374/* 409/*
375 * DMA map all entries in a scatterlist. 410 * DMA map all entries in a scatterlist.
376 * Merge chunks that have page aligned sizes into a continuous mapping. 411 * Merge chunks that have page aligned sizes into a continuous mapping.
377 */ 412 */
378static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, 413static int
379 int dir) 414gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
380{ 415{
381 int i;
382 int out;
383 int start;
384 unsigned long pages = 0;
385 int need = 0, nextneed;
386 struct scatterlist *s, *ps, *start_sg, *sgmap; 416 struct scatterlist *s, *ps, *start_sg, *sgmap;
417 int need = 0, nextneed, i, out, start;
418 unsigned long pages = 0;
387 419
388 if (nents == 0) 420 if (nents == 0)
389 return 0; 421 return 0;
390 422
391 if (!dev) 423 if (!dev)
@@ -397,15 +429,19 @@ static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents,
397 ps = NULL; /* shut up gcc */ 429 ps = NULL; /* shut up gcc */
398 for_each_sg(sg, s, nents, i) { 430 for_each_sg(sg, s, nents, i) {
399 dma_addr_t addr = sg_phys(s); 431 dma_addr_t addr = sg_phys(s);
432
400 s->dma_address = addr; 433 s->dma_address = addr;
401 BUG_ON(s->length == 0); 434 BUG_ON(s->length == 0);
402 435
403 nextneed = need_iommu(dev, addr, s->length); 436 nextneed = need_iommu(dev, addr, s->length);
404 437
405 /* Handle the previous not yet processed entries */ 438 /* Handle the previous not yet processed entries */
406 if (i > start) { 439 if (i > start) {
407 /* Can only merge when the last chunk ends on a page 440 /*
408 boundary and the new one doesn't have an offset. */ 441 * Can only merge when the last chunk ends on a
442 * page boundary and the new one doesn't have an
443 * offset.
444 */
409 if (!iommu_merge || !nextneed || !need || s->offset || 445 if (!iommu_merge || !nextneed || !need || s->offset ||
410 (ps->offset + ps->length) % PAGE_SIZE) { 446 (ps->offset + ps->length) % PAGE_SIZE) {
411 if (dma_map_cont(start_sg, i - start, sgmap, 447 if (dma_map_cont(start_sg, i - start, sgmap,
@@ -436,6 +472,7 @@ static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents,
436error: 472error:
437 flush_gart(); 473 flush_gart();
438 gart_unmap_sg(dev, sg, out, dir); 474 gart_unmap_sg(dev, sg, out, dir);
475
439 /* When it was forced or merged try again in a dumb way */ 476 /* When it was forced or merged try again in a dumb way */
440 if (force_iommu || iommu_merge) { 477 if (force_iommu || iommu_merge) {
441 out = dma_map_sg_nonforce(dev, sg, nents, dir); 478 out = dma_map_sg_nonforce(dev, sg, nents, dir);
@@ -444,64 +481,68 @@ error:
444 } 481 }
445 if (panic_on_overflow) 482 if (panic_on_overflow)
446 panic("dma_map_sg: overflow on %lu pages\n", pages); 483 panic("dma_map_sg: overflow on %lu pages\n", pages);
484
447 iommu_full(dev, pages << PAGE_SHIFT, dir); 485 iommu_full(dev, pages << PAGE_SHIFT, dir);
448 for_each_sg(sg, s, nents, i) 486 for_each_sg(sg, s, nents, i)
449 s->dma_address = bad_dma_address; 487 s->dma_address = bad_dma_address;
450 return 0; 488 return 0;
451} 489}
452 490
453static int no_agp; 491static int no_agp;
454 492
455static __init unsigned long check_iommu_size(unsigned long aper, u64 aper_size) 493static __init unsigned long check_iommu_size(unsigned long aper, u64 aper_size)
456{ 494{
457 unsigned long a; 495 unsigned long a;
458 if (!iommu_size) { 496
459 iommu_size = aper_size; 497 if (!iommu_size) {
460 if (!no_agp) 498 iommu_size = aper_size;
461 iommu_size /= 2; 499 if (!no_agp)
462 } 500 iommu_size /= 2;
463 501 }
464 a = aper + iommu_size; 502
503 a = aper + iommu_size;
465 iommu_size -= round_up(a, LARGE_PAGE_SIZE) - a; 504 iommu_size -= round_up(a, LARGE_PAGE_SIZE) - a;
466 505
467 if (iommu_size < 64*1024*1024) 506 if (iommu_size < 64*1024*1024) {
468 printk(KERN_WARNING 507 printk(KERN_WARNING
469 "PCI-DMA: Warning: Small IOMMU %luMB. Consider increasing the AGP aperture in BIOS\n",iommu_size>>20); 508 "PCI-DMA: Warning: Small IOMMU %luMB."
470 509 " Consider increasing the AGP aperture in BIOS\n",
510 iommu_size >> 20);
511 }
512
471 return iommu_size; 513 return iommu_size;
472} 514}
473 515
474static __init unsigned read_aperture(struct pci_dev *dev, u32 *size) 516static __init unsigned read_aperture(struct pci_dev *dev, u32 *size)
475{ 517{
476 unsigned aper_size = 0, aper_base_32; 518 unsigned aper_size = 0, aper_base_32, aper_order;
477 u64 aper_base; 519 u64 aper_base;
478 unsigned aper_order;
479 520
480 pci_read_config_dword(dev, 0x94, &aper_base_32); 521 pci_read_config_dword(dev, 0x94, &aper_base_32);
481 pci_read_config_dword(dev, 0x90, &aper_order); 522 pci_read_config_dword(dev, 0x90, &aper_order);
482 aper_order = (aper_order >> 1) & 7; 523 aper_order = (aper_order >> 1) & 7;
483 524
484 aper_base = aper_base_32 & 0x7fff; 525 aper_base = aper_base_32 & 0x7fff;
485 aper_base <<= 25; 526 aper_base <<= 25;
486 527
487 aper_size = (32 * 1024 * 1024) << aper_order; 528 aper_size = (32 * 1024 * 1024) << aper_order;
488 if (aper_base + aper_size > 0x100000000UL || !aper_size) 529 if (aper_base + aper_size > 0x100000000UL || !aper_size)
489 aper_base = 0; 530 aper_base = 0;
490 531
491 *size = aper_size; 532 *size = aper_size;
492 return aper_base; 533 return aper_base;
493} 534}
494 535
495/* 536/*
496 * Private Northbridge GATT initialization in case we cannot use the 537 * Private Northbridge GATT initialization in case we cannot use the
497 * AGP driver for some reason. 538 * AGP driver for some reason.
498 */ 539 */
499static __init int init_k8_gatt(struct agp_kern_info *info) 540static __init int init_k8_gatt(struct agp_kern_info *info)
500{ 541{
542 unsigned aper_size, gatt_size, new_aper_size;
543 unsigned aper_base, new_aper_base;
501 struct pci_dev *dev; 544 struct pci_dev *dev;
502 void *gatt; 545 void *gatt;
503 unsigned aper_base, new_aper_base;
504 unsigned aper_size, gatt_size, new_aper_size;
505 int i; 546 int i;
506 547
507 printk(KERN_INFO "PCI-DMA: Disabling AGP.\n"); 548 printk(KERN_INFO "PCI-DMA: Disabling AGP.\n");
@@ -509,75 +550,75 @@ static __init int init_k8_gatt(struct agp_kern_info *info)
509 dev = NULL; 550 dev = NULL;
510 for (i = 0; i < num_k8_northbridges; i++) { 551 for (i = 0; i < num_k8_northbridges; i++) {
511 dev = k8_northbridges[i]; 552 dev = k8_northbridges[i];
512 new_aper_base = read_aperture(dev, &new_aper_size); 553 new_aper_base = read_aperture(dev, &new_aper_size);
513 if (!new_aper_base) 554 if (!new_aper_base)
514 goto nommu; 555 goto nommu;
515 556
516 if (!aper_base) { 557 if (!aper_base) {
517 aper_size = new_aper_size; 558 aper_size = new_aper_size;
518 aper_base = new_aper_base; 559 aper_base = new_aper_base;
519 } 560 }
520 if (aper_size != new_aper_size || aper_base != new_aper_base) 561 if (aper_size != new_aper_size || aper_base != new_aper_base)
521 goto nommu; 562 goto nommu;
522 } 563 }
523 if (!aper_base) 564 if (!aper_base)
524 goto nommu; 565 goto nommu;
525 info->aper_base = aper_base; 566 info->aper_base = aper_base;
526 info->aper_size = aper_size>>20; 567 info->aper_size = aper_size >> 20;
527 568
528 gatt_size = (aper_size >> PAGE_SHIFT) * sizeof(u32); 569 gatt_size = (aper_size >> PAGE_SHIFT) * sizeof(u32);
529 gatt = (void *)__get_free_pages(GFP_KERNEL, get_order(gatt_size)); 570 gatt = (void *)__get_free_pages(GFP_KERNEL, get_order(gatt_size));
530 if (!gatt) 571 if (!gatt)
531 panic("Cannot allocate GATT table"); 572 panic("Cannot allocate GATT table");
532 if (change_page_attr_addr((unsigned long)gatt, gatt_size >> PAGE_SHIFT, PAGE_KERNEL_NOCACHE)) 573 if (set_memory_uc((unsigned long)gatt, gatt_size >> PAGE_SHIFT))
533 panic("Could not set GART PTEs to uncacheable pages"); 574 panic("Could not set GART PTEs to uncacheable pages");
534 global_flush_tlb();
535 575
536 memset(gatt, 0, gatt_size); 576 memset(gatt, 0, gatt_size);
537 agp_gatt_table = gatt; 577 agp_gatt_table = gatt;
538 578
539 for (i = 0; i < num_k8_northbridges; i++) { 579 for (i = 0; i < num_k8_northbridges; i++) {
540 u32 ctl; 580 u32 gatt_reg;
541 u32 gatt_reg; 581 u32 ctl;
542 582
543 dev = k8_northbridges[i]; 583 dev = k8_northbridges[i];
544 gatt_reg = __pa(gatt) >> 12; 584 gatt_reg = __pa(gatt) >> 12;
545 gatt_reg <<= 4; 585 gatt_reg <<= 4;
546 pci_write_config_dword(dev, 0x98, gatt_reg); 586 pci_write_config_dword(dev, 0x98, gatt_reg);
547 pci_read_config_dword(dev, 0x90, &ctl); 587 pci_read_config_dword(dev, 0x90, &ctl);
548 588
549 ctl |= 1; 589 ctl |= 1;
550 ctl &= ~((1<<4) | (1<<5)); 590 ctl &= ~((1<<4) | (1<<5));
551 591
552 pci_write_config_dword(dev, 0x90, ctl); 592 pci_write_config_dword(dev, 0x90, ctl);
553 } 593 }
554 flush_gart(); 594 flush_gart();
555 595
556 printk("PCI-DMA: aperture base @ %x size %u KB\n",aper_base, aper_size>>10); 596 printk(KERN_INFO "PCI-DMA: aperture base @ %x size %u KB\n",
597 aper_base, aper_size>>10);
557 return 0; 598 return 0;
558 599
559 nommu: 600 nommu:
560 /* Should not happen anymore */ 601 /* Should not happen anymore */
561 printk(KERN_ERR "PCI-DMA: More than 4GB of RAM and no IOMMU\n" 602 printk(KERN_ERR "PCI-DMA: More than 4GB of RAM and no IOMMU\n"
562 KERN_ERR "PCI-DMA: 32bit PCI IO may malfunction.\n"); 603 KERN_ERR "PCI-DMA: 32bit PCI IO may malfunction.\n");
563 return -1; 604 return -1;
564} 605}
565 606
566extern int agp_amd64_init(void); 607extern int agp_amd64_init(void);
567 608
568static const struct dma_mapping_ops gart_dma_ops = { 609static const struct dma_mapping_ops gart_dma_ops = {
569 .mapping_error = NULL, 610 .mapping_error = NULL,
570 .map_single = gart_map_single, 611 .map_single = gart_map_single,
571 .map_simple = gart_map_simple, 612 .map_simple = gart_map_simple,
572 .unmap_single = gart_unmap_single, 613 .unmap_single = gart_unmap_single,
573 .sync_single_for_cpu = NULL, 614 .sync_single_for_cpu = NULL,
574 .sync_single_for_device = NULL, 615 .sync_single_for_device = NULL,
575 .sync_single_range_for_cpu = NULL, 616 .sync_single_range_for_cpu = NULL,
576 .sync_single_range_for_device = NULL, 617 .sync_single_range_for_device = NULL,
577 .sync_sg_for_cpu = NULL, 618 .sync_sg_for_cpu = NULL,
578 .sync_sg_for_device = NULL, 619 .sync_sg_for_device = NULL,
579 .map_sg = gart_map_sg, 620 .map_sg = gart_map_sg,
580 .unmap_sg = gart_unmap_sg, 621 .unmap_sg = gart_unmap_sg,
581}; 622};
582 623
583void gart_iommu_shutdown(void) 624void gart_iommu_shutdown(void)
@@ -588,23 +629,23 @@ void gart_iommu_shutdown(void)
588 if (no_agp && (dma_ops != &gart_dma_ops)) 629 if (no_agp && (dma_ops != &gart_dma_ops))
589 return; 630 return;
590 631
591 for (i = 0; i < num_k8_northbridges; i++) { 632 for (i = 0; i < num_k8_northbridges; i++) {
592 u32 ctl; 633 u32 ctl;
593 634
594 dev = k8_northbridges[i]; 635 dev = k8_northbridges[i];
595 pci_read_config_dword(dev, 0x90, &ctl); 636 pci_read_config_dword(dev, 0x90, &ctl);
596 637
597 ctl &= ~1; 638 ctl &= ~1;
598 639
599 pci_write_config_dword(dev, 0x90, ctl); 640 pci_write_config_dword(dev, 0x90, ctl);
600 } 641 }
601} 642}
602 643
603void __init gart_iommu_init(void) 644void __init gart_iommu_init(void)
604{ 645{
605 struct agp_kern_info info; 646 struct agp_kern_info info;
606 unsigned long aper_size;
607 unsigned long iommu_start; 647 unsigned long iommu_start;
648 unsigned long aper_size;
608 unsigned long scratch; 649 unsigned long scratch;
609 long i; 650 long i;
610 651
@@ -614,14 +655,14 @@ void __init gart_iommu_init(void)
614 } 655 }
615 656
616#ifndef CONFIG_AGP_AMD64 657#ifndef CONFIG_AGP_AMD64
617 no_agp = 1; 658 no_agp = 1;
618#else 659#else
619 /* Makefile puts PCI initialization via subsys_initcall first. */ 660 /* Makefile puts PCI initialization via subsys_initcall first. */
620 /* Add other K8 AGP bridge drivers here */ 661 /* Add other K8 AGP bridge drivers here */
621 no_agp = no_agp || 662 no_agp = no_agp ||
622 (agp_amd64_init() < 0) || 663 (agp_amd64_init() < 0) ||
623 (agp_copy_info(agp_bridge, &info) < 0); 664 (agp_copy_info(agp_bridge, &info) < 0);
624#endif 665#endif
625 666
626 if (swiotlb) 667 if (swiotlb)
627 return; 668 return;
@@ -643,77 +684,78 @@ void __init gart_iommu_init(void)
643 } 684 }
644 685
645 printk(KERN_INFO "PCI-DMA: using GART IOMMU.\n"); 686 printk(KERN_INFO "PCI-DMA: using GART IOMMU.\n");
646 aper_size = info.aper_size * 1024 * 1024; 687 aper_size = info.aper_size * 1024 * 1024;
647 iommu_size = check_iommu_size(info.aper_base, aper_size); 688 iommu_size = check_iommu_size(info.aper_base, aper_size);
648 iommu_pages = iommu_size >> PAGE_SHIFT; 689 iommu_pages = iommu_size >> PAGE_SHIFT;
649 690
650 iommu_gart_bitmap = (void*)__get_free_pages(GFP_KERNEL, 691 iommu_gart_bitmap = (void *) __get_free_pages(GFP_KERNEL,
651 get_order(iommu_pages/8)); 692 get_order(iommu_pages/8));
652 if (!iommu_gart_bitmap) 693 if (!iommu_gart_bitmap)
653 panic("Cannot allocate iommu bitmap\n"); 694 panic("Cannot allocate iommu bitmap\n");
654 memset(iommu_gart_bitmap, 0, iommu_pages/8); 695 memset(iommu_gart_bitmap, 0, iommu_pages/8);
655 696
656#ifdef CONFIG_IOMMU_LEAK 697#ifdef CONFIG_IOMMU_LEAK
657 if (leak_trace) { 698 if (leak_trace) {
658 iommu_leak_tab = (void *)__get_free_pages(GFP_KERNEL, 699 iommu_leak_tab = (void *)__get_free_pages(GFP_KERNEL,
659 get_order(iommu_pages*sizeof(void *))); 700 get_order(iommu_pages*sizeof(void *)));
660 if (iommu_leak_tab) 701 if (iommu_leak_tab)
661 memset(iommu_leak_tab, 0, iommu_pages * 8); 702 memset(iommu_leak_tab, 0, iommu_pages * 8);
662 else 703 else
663 printk("PCI-DMA: Cannot allocate leak trace area\n"); 704 printk(KERN_DEBUG
664 } 705 "PCI-DMA: Cannot allocate leak trace area\n");
706 }
665#endif 707#endif
666 708
667 /* 709 /*
668 * Out of IOMMU space handling. 710 * Out of IOMMU space handling.
669 * Reserve some invalid pages at the beginning of the GART. 711 * Reserve some invalid pages at the beginning of the GART.
670 */ 712 */
671 set_bit_string(iommu_gart_bitmap, 0, EMERGENCY_PAGES); 713 set_bit_string(iommu_gart_bitmap, 0, EMERGENCY_PAGES);
672 714
673 agp_memory_reserved = iommu_size; 715 agp_memory_reserved = iommu_size;
674 printk(KERN_INFO 716 printk(KERN_INFO
675 "PCI-DMA: Reserving %luMB of IOMMU area in the AGP aperture\n", 717 "PCI-DMA: Reserving %luMB of IOMMU area in the AGP aperture\n",
676 iommu_size>>20); 718 iommu_size >> 20);
677 719
678 iommu_start = aper_size - iommu_size; 720 iommu_start = aper_size - iommu_size;
679 iommu_bus_base = info.aper_base + iommu_start; 721 iommu_bus_base = info.aper_base + iommu_start;
680 bad_dma_address = iommu_bus_base; 722 bad_dma_address = iommu_bus_base;
681 iommu_gatt_base = agp_gatt_table + (iommu_start>>PAGE_SHIFT); 723 iommu_gatt_base = agp_gatt_table + (iommu_start>>PAGE_SHIFT);
682 724
683 /* 725 /*
684 * Unmap the IOMMU part of the GART. The alias of the page is 726 * Unmap the IOMMU part of the GART. The alias of the page is
685 * always mapped with cache enabled and there is no full cache 727 * always mapped with cache enabled and there is no full cache
686 * coherency across the GART remapping. The unmapping avoids 728 * coherency across the GART remapping. The unmapping avoids
687 * automatic prefetches from the CPU allocating cache lines in 729 * automatic prefetches from the CPU allocating cache lines in
688 * there. All CPU accesses are done via the direct mapping to 730 * there. All CPU accesses are done via the direct mapping to
689 * the backing memory. The GART address is only used by PCI 731 * the backing memory. The GART address is only used by PCI
690 * devices. 732 * devices.
691 */ 733 */
692 clear_kernel_mapping((unsigned long)__va(iommu_bus_base), iommu_size); 734 clear_kernel_mapping((unsigned long)__va(iommu_bus_base), iommu_size);
693 735
694 /* 736 /*
695 * Try to workaround a bug (thanks to BenH) 737 * Try to workaround a bug (thanks to BenH)
696 * Set unmapped entries to a scratch page instead of 0. 738 * Set unmapped entries to a scratch page instead of 0.
697 * Any prefetches that hit unmapped entries won't get an bus abort 739 * Any prefetches that hit unmapped entries won't get an bus abort
698 * then. 740 * then.
699 */ 741 */
700 scratch = get_zeroed_page(GFP_KERNEL); 742 scratch = get_zeroed_page(GFP_KERNEL);
701 if (!scratch) 743 if (!scratch)
702 panic("Cannot allocate iommu scratch page"); 744 panic("Cannot allocate iommu scratch page");
703 gart_unmapped_entry = GPTE_ENCODE(__pa(scratch)); 745 gart_unmapped_entry = GPTE_ENCODE(__pa(scratch));
704 for (i = EMERGENCY_PAGES; i < iommu_pages; i++) 746 for (i = EMERGENCY_PAGES; i < iommu_pages; i++)
705 iommu_gatt_base[i] = gart_unmapped_entry; 747 iommu_gatt_base[i] = gart_unmapped_entry;
706 748
707 flush_gart(); 749 flush_gart();
708 dma_ops = &gart_dma_ops; 750 dma_ops = &gart_dma_ops;
709} 751}
710 752
711void __init gart_parse_options(char *p) 753void __init gart_parse_options(char *p)
712{ 754{
713 int arg; 755 int arg;
714 756
715#ifdef CONFIG_IOMMU_LEAK 757#ifdef CONFIG_IOMMU_LEAK
716 if (!strncmp(p,"leak",4)) { 758 if (!strncmp(p, "leak", 4)) {
717 leak_trace = 1; 759 leak_trace = 1;
718 p += 4; 760 p += 4;
719 if (*p == '=') ++p; 761 if (*p == '=') ++p;
@@ -723,18 +765,18 @@ void __init gart_parse_options(char *p)
723#endif 765#endif
724 if (isdigit(*p) && get_option(&p, &arg)) 766 if (isdigit(*p) && get_option(&p, &arg))
725 iommu_size = arg; 767 iommu_size = arg;
726 if (!strncmp(p, "fullflush",8)) 768 if (!strncmp(p, "fullflush", 8))
727 iommu_fullflush = 1; 769 iommu_fullflush = 1;
728 if (!strncmp(p, "nofullflush",11)) 770 if (!strncmp(p, "nofullflush", 11))
729 iommu_fullflush = 0; 771 iommu_fullflush = 0;
730 if (!strncmp(p,"noagp",5)) 772 if (!strncmp(p, "noagp", 5))
731 no_agp = 1; 773 no_agp = 1;
732 if (!strncmp(p, "noaperture",10)) 774 if (!strncmp(p, "noaperture", 10))
733 fix_aperture = 0; 775 fix_aperture = 0;
734 /* duplicated from pci-dma.c */ 776 /* duplicated from pci-dma.c */
735 if (!strncmp(p,"force",5)) 777 if (!strncmp(p, "force", 5))
736 gart_iommu_aperture_allowed = 1; 778 gart_iommu_aperture_allowed = 1;
737 if (!strncmp(p,"allowed",7)) 779 if (!strncmp(p, "allowed", 7))
738 gart_iommu_aperture_allowed = 1; 780 gart_iommu_aperture_allowed = 1;
739 if (!strncmp(p, "memaper", 7)) { 781 if (!strncmp(p, "memaper", 7)) {
740 fallback_aper_force = 1; 782 fallback_aper_force = 1;
diff --git a/arch/x86/kernel/pci-swiotlb_64.c b/arch/x86/kernel/pci-swiotlb_64.c
index 102866d729a5..82a0a674a003 100644
--- a/arch/x86/kernel/pci-swiotlb_64.c
+++ b/arch/x86/kernel/pci-swiotlb_64.c
@@ -10,7 +10,6 @@
10#include <asm/dma.h> 10#include <asm/dma.h>
11 11
12int swiotlb __read_mostly; 12int swiotlb __read_mostly;
13EXPORT_SYMBOL(swiotlb);
14 13
15const struct dma_mapping_ops swiotlb_dma_ops = { 14const struct dma_mapping_ops swiotlb_dma_ops = {
16 .mapping_error = swiotlb_dma_mapping_error, 15 .mapping_error = swiotlb_dma_mapping_error,
diff --git a/arch/x86/kernel/pmtimer_64.c b/arch/x86/kernel/pmtimer_64.c
index ae8f91214f15..b112406f1996 100644
--- a/arch/x86/kernel/pmtimer_64.c
+++ b/arch/x86/kernel/pmtimer_64.c
@@ -19,13 +19,13 @@
19#include <linux/time.h> 19#include <linux/time.h>
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/cpumask.h> 21#include <linux/cpumask.h>
22#include <linux/acpi_pmtmr.h>
23
22#include <asm/io.h> 24#include <asm/io.h>
23#include <asm/proto.h> 25#include <asm/proto.h>
24#include <asm/msr.h> 26#include <asm/msr.h>
25#include <asm/vsyscall.h> 27#include <asm/vsyscall.h>
26 28
27#define ACPI_PM_MASK 0xFFFFFF /* limit it to 24 bits */
28
29static inline u32 cyc2us(u32 cycles) 29static inline u32 cyc2us(u32 cycles)
30{ 30{
31 /* The Power Management Timer ticks at 3.579545 ticks per microsecond. 31 /* The Power Management Timer ticks at 3.579545 ticks per microsecond.
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 46d391d49de8..968371ab223a 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -55,6 +55,7 @@
55 55
56#include <asm/tlbflush.h> 56#include <asm/tlbflush.h>
57#include <asm/cpu.h> 57#include <asm/cpu.h>
58#include <asm/kdebug.h>
58 59
59asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); 60asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
60 61
@@ -74,7 +75,7 @@ EXPORT_PER_CPU_SYMBOL(cpu_number);
74 */ 75 */
75unsigned long thread_saved_pc(struct task_struct *tsk) 76unsigned long thread_saved_pc(struct task_struct *tsk)
76{ 77{
77 return ((unsigned long *)tsk->thread.esp)[3]; 78 return ((unsigned long *)tsk->thread.sp)[3];
78} 79}
79 80
80/* 81/*
@@ -113,10 +114,19 @@ void default_idle(void)
113 smp_mb(); 114 smp_mb();
114 115
115 local_irq_disable(); 116 local_irq_disable();
116 if (!need_resched()) 117 if (!need_resched()) {
118 ktime_t t0, t1;
119 u64 t0n, t1n;
120
121 t0 = ktime_get();
122 t0n = ktime_to_ns(t0);
117 safe_halt(); /* enables interrupts racelessly */ 123 safe_halt(); /* enables interrupts racelessly */
118 else 124 local_irq_disable();
119 local_irq_enable(); 125 t1 = ktime_get();
126 t1n = ktime_to_ns(t1);
127 sched_clock_idle_wakeup_event(t1n - t0n);
128 }
129 local_irq_enable();
120 current_thread_info()->status |= TS_POLLING; 130 current_thread_info()->status |= TS_POLLING;
121 } else { 131 } else {
122 /* loop is done by the caller */ 132 /* loop is done by the caller */
@@ -132,7 +142,7 @@ EXPORT_SYMBOL(default_idle);
132 * to poll the ->work.need_resched flag instead of waiting for the 142 * to poll the ->work.need_resched flag instead of waiting for the
133 * cross-CPU IPI to arrive. Use this option with caution. 143 * cross-CPU IPI to arrive. Use this option with caution.
134 */ 144 */
135static void poll_idle (void) 145static void poll_idle(void)
136{ 146{
137 cpu_relax(); 147 cpu_relax();
138} 148}
@@ -188,6 +198,9 @@ void cpu_idle(void)
188 rmb(); 198 rmb();
189 idle = pm_idle; 199 idle = pm_idle;
190 200
201 if (rcu_pending(cpu))
202 rcu_check_callbacks(cpu, 0);
203
191 if (!idle) 204 if (!idle)
192 idle = default_idle; 205 idle = default_idle;
193 206
@@ -255,13 +268,13 @@ EXPORT_SYMBOL_GPL(cpu_idle_wait);
255 * New with Core Duo processors, MWAIT can take some hints based on CPU 268 * New with Core Duo processors, MWAIT can take some hints based on CPU
256 * capability. 269 * capability.
257 */ 270 */
258void mwait_idle_with_hints(unsigned long eax, unsigned long ecx) 271void mwait_idle_with_hints(unsigned long ax, unsigned long cx)
259{ 272{
260 if (!need_resched()) { 273 if (!need_resched()) {
261 __monitor((void *)&current_thread_info()->flags, 0, 0); 274 __monitor((void *)&current_thread_info()->flags, 0, 0);
262 smp_mb(); 275 smp_mb();
263 if (!need_resched()) 276 if (!need_resched())
264 __mwait(eax, ecx); 277 __mwait(ax, cx);
265 } 278 }
266} 279}
267 280
@@ -272,19 +285,37 @@ static void mwait_idle(void)
272 mwait_idle_with_hints(0, 0); 285 mwait_idle_with_hints(0, 0);
273} 286}
274 287
288static int __cpuinit mwait_usable(const struct cpuinfo_x86 *c)
289{
290 if (force_mwait)
291 return 1;
292 /* Any C1 states supported? */
293 return c->cpuid_level >= 5 && ((cpuid_edx(5) >> 4) & 0xf) > 0;
294}
295
275void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) 296void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)
276{ 297{
277 if (cpu_has(c, X86_FEATURE_MWAIT)) { 298 static int selected;
278 printk("monitor/mwait feature present.\n"); 299
300 if (selected)
301 return;
302#ifdef CONFIG_X86_SMP
303 if (pm_idle == poll_idle && smp_num_siblings > 1) {
304 printk(KERN_WARNING "WARNING: polling idle and HT enabled,"
305 " performance may degrade.\n");
306 }
307#endif
308 if (cpu_has(c, X86_FEATURE_MWAIT) && mwait_usable(c)) {
279 /* 309 /*
280 * Skip, if setup has overridden idle. 310 * Skip, if setup has overridden idle.
281 * One CPU supports mwait => All CPUs supports mwait 311 * One CPU supports mwait => All CPUs supports mwait
282 */ 312 */
283 if (!pm_idle) { 313 if (!pm_idle) {
284 printk("using mwait in idle threads.\n"); 314 printk(KERN_INFO "using mwait in idle threads.\n");
285 pm_idle = mwait_idle; 315 pm_idle = mwait_idle;
286 } 316 }
287 } 317 }
318 selected = 1;
288} 319}
289 320
290static int __init idle_setup(char *str) 321static int __init idle_setup(char *str)
@@ -292,10 +323,6 @@ static int __init idle_setup(char *str)
292 if (!strcmp(str, "poll")) { 323 if (!strcmp(str, "poll")) {
293 printk("using polling idle threads.\n"); 324 printk("using polling idle threads.\n");
294 pm_idle = poll_idle; 325 pm_idle = poll_idle;
295#ifdef CONFIG_X86_SMP
296 if (smp_num_siblings > 1)
297 printk("WARNING: polling idle and HT enabled, performance may degrade.\n");
298#endif
299 } else if (!strcmp(str, "mwait")) 326 } else if (!strcmp(str, "mwait"))
300 force_mwait = 1; 327 force_mwait = 1;
301 else 328 else
@@ -310,15 +337,15 @@ void __show_registers(struct pt_regs *regs, int all)
310{ 337{
311 unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L; 338 unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
312 unsigned long d0, d1, d2, d3, d6, d7; 339 unsigned long d0, d1, d2, d3, d6, d7;
313 unsigned long esp; 340 unsigned long sp;
314 unsigned short ss, gs; 341 unsigned short ss, gs;
315 342
316 if (user_mode_vm(regs)) { 343 if (user_mode_vm(regs)) {
317 esp = regs->esp; 344 sp = regs->sp;
318 ss = regs->xss & 0xffff; 345 ss = regs->ss & 0xffff;
319 savesegment(gs, gs); 346 savesegment(gs, gs);
320 } else { 347 } else {
321 esp = (unsigned long) (&regs->esp); 348 sp = (unsigned long) (&regs->sp);
322 savesegment(ss, ss); 349 savesegment(ss, ss);
323 savesegment(gs, gs); 350 savesegment(gs, gs);
324 } 351 }
@@ -331,17 +358,17 @@ void __show_registers(struct pt_regs *regs, int all)
331 init_utsname()->version); 358 init_utsname()->version);
332 359
333 printk("EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n", 360 printk("EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n",
334 0xffff & regs->xcs, regs->eip, regs->eflags, 361 0xffff & regs->cs, regs->ip, regs->flags,
335 smp_processor_id()); 362 smp_processor_id());
336 print_symbol("EIP is at %s\n", regs->eip); 363 print_symbol("EIP is at %s\n", regs->ip);
337 364
338 printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n", 365 printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
339 regs->eax, regs->ebx, regs->ecx, regs->edx); 366 regs->ax, regs->bx, regs->cx, regs->dx);
340 printk("ESI: %08lx EDI: %08lx EBP: %08lx ESP: %08lx\n", 367 printk("ESI: %08lx EDI: %08lx EBP: %08lx ESP: %08lx\n",
341 regs->esi, regs->edi, regs->ebp, esp); 368 regs->si, regs->di, regs->bp, sp);
342 printk(" DS: %04x ES: %04x FS: %04x GS: %04x SS: %04x\n", 369 printk(" DS: %04x ES: %04x FS: %04x GS: %04x SS: %04x\n",
343 regs->xds & 0xffff, regs->xes & 0xffff, 370 regs->ds & 0xffff, regs->es & 0xffff,
344 regs->xfs & 0xffff, gs, ss); 371 regs->fs & 0xffff, gs, ss);
345 372
346 if (!all) 373 if (!all)
347 return; 374 return;
@@ -369,12 +396,12 @@ void __show_registers(struct pt_regs *regs, int all)
369void show_regs(struct pt_regs *regs) 396void show_regs(struct pt_regs *regs)
370{ 397{
371 __show_registers(regs, 1); 398 __show_registers(regs, 1);
372 show_trace(NULL, regs, &regs->esp); 399 show_trace(NULL, regs, &regs->sp, regs->bp);
373} 400}
374 401
375/* 402/*
376 * This gets run with %ebx containing the 403 * This gets run with %bx containing the
377 * function to call, and %edx containing 404 * function to call, and %dx containing
378 * the "args". 405 * the "args".
379 */ 406 */
380extern void kernel_thread_helper(void); 407extern void kernel_thread_helper(void);
@@ -388,16 +415,16 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
388 415
389 memset(&regs, 0, sizeof(regs)); 416 memset(&regs, 0, sizeof(regs));
390 417
391 regs.ebx = (unsigned long) fn; 418 regs.bx = (unsigned long) fn;
392 regs.edx = (unsigned long) arg; 419 regs.dx = (unsigned long) arg;
393 420
394 regs.xds = __USER_DS; 421 regs.ds = __USER_DS;
395 regs.xes = __USER_DS; 422 regs.es = __USER_DS;
396 regs.xfs = __KERNEL_PERCPU; 423 regs.fs = __KERNEL_PERCPU;
397 regs.orig_eax = -1; 424 regs.orig_ax = -1;
398 regs.eip = (unsigned long) kernel_thread_helper; 425 regs.ip = (unsigned long) kernel_thread_helper;
399 regs.xcs = __KERNEL_CS | get_kernel_rpl(); 426 regs.cs = __KERNEL_CS | get_kernel_rpl();
400 regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2; 427 regs.flags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2;
401 428
402 /* Ok, create the new process.. */ 429 /* Ok, create the new process.. */
403 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL); 430 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
@@ -435,7 +462,12 @@ void flush_thread(void)
435{ 462{
436 struct task_struct *tsk = current; 463 struct task_struct *tsk = current;
437 464
438 memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8); 465 tsk->thread.debugreg0 = 0;
466 tsk->thread.debugreg1 = 0;
467 tsk->thread.debugreg2 = 0;
468 tsk->thread.debugreg3 = 0;
469 tsk->thread.debugreg6 = 0;
470 tsk->thread.debugreg7 = 0;
439 memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array)); 471 memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
440 clear_tsk_thread_flag(tsk, TIF_DEBUG); 472 clear_tsk_thread_flag(tsk, TIF_DEBUG);
441 /* 473 /*
@@ -460,7 +492,7 @@ void prepare_to_copy(struct task_struct *tsk)
460 unlazy_fpu(tsk); 492 unlazy_fpu(tsk);
461} 493}
462 494
463int copy_thread(int nr, unsigned long clone_flags, unsigned long esp, 495int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
464 unsigned long unused, 496 unsigned long unused,
465 struct task_struct * p, struct pt_regs * regs) 497 struct task_struct * p, struct pt_regs * regs)
466{ 498{
@@ -470,15 +502,15 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
470 502
471 childregs = task_pt_regs(p); 503 childregs = task_pt_regs(p);
472 *childregs = *regs; 504 *childregs = *regs;
473 childregs->eax = 0; 505 childregs->ax = 0;
474 childregs->esp = esp; 506 childregs->sp = sp;
475 507
476 p->thread.esp = (unsigned long) childregs; 508 p->thread.sp = (unsigned long) childregs;
477 p->thread.esp0 = (unsigned long) (childregs+1); 509 p->thread.sp0 = (unsigned long) (childregs+1);
478 510
479 p->thread.eip = (unsigned long) ret_from_fork; 511 p->thread.ip = (unsigned long) ret_from_fork;
480 512
481 savesegment(gs,p->thread.gs); 513 savesegment(gs, p->thread.gs);
482 514
483 tsk = current; 515 tsk = current;
484 if (unlikely(test_tsk_thread_flag(tsk, TIF_IO_BITMAP))) { 516 if (unlikely(test_tsk_thread_flag(tsk, TIF_IO_BITMAP))) {
@@ -491,32 +523,15 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
491 set_tsk_thread_flag(p, TIF_IO_BITMAP); 523 set_tsk_thread_flag(p, TIF_IO_BITMAP);
492 } 524 }
493 525
526 err = 0;
527
494 /* 528 /*
495 * Set a new TLS for the child thread? 529 * Set a new TLS for the child thread?
496 */ 530 */
497 if (clone_flags & CLONE_SETTLS) { 531 if (clone_flags & CLONE_SETTLS)
498 struct desc_struct *desc; 532 err = do_set_thread_area(p, -1,
499 struct user_desc info; 533 (struct user_desc __user *)childregs->si, 0);
500 int idx;
501
502 err = -EFAULT;
503 if (copy_from_user(&info, (void __user *)childregs->esi, sizeof(info)))
504 goto out;
505 err = -EINVAL;
506 if (LDT_empty(&info))
507 goto out;
508
509 idx = info.entry_number;
510 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
511 goto out;
512
513 desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
514 desc->a = LDT_entry_a(&info);
515 desc->b = LDT_entry_b(&info);
516 }
517 534
518 err = 0;
519 out:
520 if (err && p->thread.io_bitmap_ptr) { 535 if (err && p->thread.io_bitmap_ptr) {
521 kfree(p->thread.io_bitmap_ptr); 536 kfree(p->thread.io_bitmap_ptr);
522 p->thread.io_bitmap_max = 0; 537 p->thread.io_bitmap_max = 0;
@@ -529,62 +544,52 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
529 */ 544 */
530void dump_thread(struct pt_regs * regs, struct user * dump) 545void dump_thread(struct pt_regs * regs, struct user * dump)
531{ 546{
532 int i; 547 u16 gs;
533 548
534/* changed the size calculations - should hopefully work better. lbt */ 549/* changed the size calculations - should hopefully work better. lbt */
535 dump->magic = CMAGIC; 550 dump->magic = CMAGIC;
536 dump->start_code = 0; 551 dump->start_code = 0;
537 dump->start_stack = regs->esp & ~(PAGE_SIZE - 1); 552 dump->start_stack = regs->sp & ~(PAGE_SIZE - 1);
538 dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT; 553 dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
539 dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> PAGE_SHIFT; 554 dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> PAGE_SHIFT;
540 dump->u_dsize -= dump->u_tsize; 555 dump->u_dsize -= dump->u_tsize;
541 dump->u_ssize = 0; 556 dump->u_ssize = 0;
542 for (i = 0; i < 8; i++) 557 dump->u_debugreg[0] = current->thread.debugreg0;
543 dump->u_debugreg[i] = current->thread.debugreg[i]; 558 dump->u_debugreg[1] = current->thread.debugreg1;
559 dump->u_debugreg[2] = current->thread.debugreg2;
560 dump->u_debugreg[3] = current->thread.debugreg3;
561 dump->u_debugreg[4] = 0;
562 dump->u_debugreg[5] = 0;
563 dump->u_debugreg[6] = current->thread.debugreg6;
564 dump->u_debugreg[7] = current->thread.debugreg7;
544 565
545 if (dump->start_stack < TASK_SIZE) 566 if (dump->start_stack < TASK_SIZE)
546 dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT; 567 dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
547 568
548 dump->regs.ebx = regs->ebx; 569 dump->regs.bx = regs->bx;
549 dump->regs.ecx = regs->ecx; 570 dump->regs.cx = regs->cx;
550 dump->regs.edx = regs->edx; 571 dump->regs.dx = regs->dx;
551 dump->regs.esi = regs->esi; 572 dump->regs.si = regs->si;
552 dump->regs.edi = regs->edi; 573 dump->regs.di = regs->di;
553 dump->regs.ebp = regs->ebp; 574 dump->regs.bp = regs->bp;
554 dump->regs.eax = regs->eax; 575 dump->regs.ax = regs->ax;
555 dump->regs.ds = regs->xds; 576 dump->regs.ds = (u16)regs->ds;
556 dump->regs.es = regs->xes; 577 dump->regs.es = (u16)regs->es;
557 dump->regs.fs = regs->xfs; 578 dump->regs.fs = (u16)regs->fs;
558 savesegment(gs,dump->regs.gs); 579 savesegment(gs,gs);
559 dump->regs.orig_eax = regs->orig_eax; 580 dump->regs.orig_ax = regs->orig_ax;
560 dump->regs.eip = regs->eip; 581 dump->regs.ip = regs->ip;
561 dump->regs.cs = regs->xcs; 582 dump->regs.cs = (u16)regs->cs;
562 dump->regs.eflags = regs->eflags; 583 dump->regs.flags = regs->flags;
563 dump->regs.esp = regs->esp; 584 dump->regs.sp = regs->sp;
564 dump->regs.ss = regs->xss; 585 dump->regs.ss = (u16)regs->ss;
565 586
566 dump->u_fpvalid = dump_fpu (regs, &dump->i387); 587 dump->u_fpvalid = dump_fpu (regs, &dump->i387);
567} 588}
568EXPORT_SYMBOL(dump_thread); 589EXPORT_SYMBOL(dump_thread);
569 590
570/*
571 * Capture the user space registers if the task is not running (in user space)
572 */
573int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
574{
575 struct pt_regs ptregs = *task_pt_regs(tsk);
576 ptregs.xcs &= 0xffff;
577 ptregs.xds &= 0xffff;
578 ptregs.xes &= 0xffff;
579 ptregs.xss &= 0xffff;
580
581 elf_core_copy_regs(regs, &ptregs);
582
583 return 1;
584}
585
586#ifdef CONFIG_SECCOMP 591#ifdef CONFIG_SECCOMP
587void hard_disable_TSC(void) 592static void hard_disable_TSC(void)
588{ 593{
589 write_cr4(read_cr4() | X86_CR4_TSD); 594 write_cr4(read_cr4() | X86_CR4_TSD);
590} 595}
@@ -599,7 +604,7 @@ void disable_TSC(void)
599 hard_disable_TSC(); 604 hard_disable_TSC();
600 preempt_enable(); 605 preempt_enable();
601} 606}
602void hard_enable_TSC(void) 607static void hard_enable_TSC(void)
603{ 608{
604 write_cr4(read_cr4() & ~X86_CR4_TSD); 609 write_cr4(read_cr4() & ~X86_CR4_TSD);
605} 610}
@@ -609,18 +614,32 @@ static noinline void
609__switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, 614__switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
610 struct tss_struct *tss) 615 struct tss_struct *tss)
611{ 616{
612 struct thread_struct *next; 617 struct thread_struct *prev, *next;
618 unsigned long debugctl;
613 619
620 prev = &prev_p->thread;
614 next = &next_p->thread; 621 next = &next_p->thread;
615 622
623 debugctl = prev->debugctlmsr;
624 if (next->ds_area_msr != prev->ds_area_msr) {
625 /* we clear debugctl to make sure DS
626 * is not in use when we change it */
627 debugctl = 0;
628 wrmsrl(MSR_IA32_DEBUGCTLMSR, 0);
629 wrmsr(MSR_IA32_DS_AREA, next->ds_area_msr, 0);
630 }
631
632 if (next->debugctlmsr != debugctl)
633 wrmsr(MSR_IA32_DEBUGCTLMSR, next->debugctlmsr, 0);
634
616 if (test_tsk_thread_flag(next_p, TIF_DEBUG)) { 635 if (test_tsk_thread_flag(next_p, TIF_DEBUG)) {
617 set_debugreg(next->debugreg[0], 0); 636 set_debugreg(next->debugreg0, 0);
618 set_debugreg(next->debugreg[1], 1); 637 set_debugreg(next->debugreg1, 1);
619 set_debugreg(next->debugreg[2], 2); 638 set_debugreg(next->debugreg2, 2);
620 set_debugreg(next->debugreg[3], 3); 639 set_debugreg(next->debugreg3, 3);
621 /* no 4 and 5 */ 640 /* no 4 and 5 */
622 set_debugreg(next->debugreg[6], 6); 641 set_debugreg(next->debugreg6, 6);
623 set_debugreg(next->debugreg[7], 7); 642 set_debugreg(next->debugreg7, 7);
624 } 643 }
625 644
626#ifdef CONFIG_SECCOMP 645#ifdef CONFIG_SECCOMP
@@ -634,6 +653,13 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
634 } 653 }
635#endif 654#endif
636 655
656 if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS))
657 ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS);
658
659 if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS))
660 ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES);
661
662
637 if (!test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) { 663 if (!test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) {
638 /* 664 /*
639 * Disable the bitmap via an invalid offset. We still cache 665 * Disable the bitmap via an invalid offset. We still cache
@@ -687,11 +713,11 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
687 * More important, however, is the fact that this allows us much 713 * More important, however, is the fact that this allows us much
688 * more flexibility. 714 * more flexibility.
689 * 715 *
690 * The return value (in %eax) will be the "prev" task after 716 * The return value (in %ax) will be the "prev" task after
691 * the task-switch, and shows up in ret_from_fork in entry.S, 717 * the task-switch, and shows up in ret_from_fork in entry.S,
692 * for example. 718 * for example.
693 */ 719 */
694struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct task_struct *next_p) 720struct task_struct * __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
695{ 721{
696 struct thread_struct *prev = &prev_p->thread, 722 struct thread_struct *prev = &prev_p->thread,
697 *next = &next_p->thread; 723 *next = &next_p->thread;
@@ -710,7 +736,7 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas
710 /* 736 /*
711 * Reload esp0. 737 * Reload esp0.
712 */ 738 */
713 load_esp0(tss, next); 739 load_sp0(tss, next);
714 740
715 /* 741 /*
716 * Save away %gs. No need to save %fs, as it was saved on the 742 * Save away %gs. No need to save %fs, as it was saved on the
@@ -774,7 +800,7 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas
774 800
775asmlinkage int sys_fork(struct pt_regs regs) 801asmlinkage int sys_fork(struct pt_regs regs)
776{ 802{
777 return do_fork(SIGCHLD, regs.esp, &regs, 0, NULL, NULL); 803 return do_fork(SIGCHLD, regs.sp, &regs, 0, NULL, NULL);
778} 804}
779 805
780asmlinkage int sys_clone(struct pt_regs regs) 806asmlinkage int sys_clone(struct pt_regs regs)
@@ -783,12 +809,12 @@ asmlinkage int sys_clone(struct pt_regs regs)
783 unsigned long newsp; 809 unsigned long newsp;
784 int __user *parent_tidptr, *child_tidptr; 810 int __user *parent_tidptr, *child_tidptr;
785 811
786 clone_flags = regs.ebx; 812 clone_flags = regs.bx;
787 newsp = regs.ecx; 813 newsp = regs.cx;
788 parent_tidptr = (int __user *)regs.edx; 814 parent_tidptr = (int __user *)regs.dx;
789 child_tidptr = (int __user *)regs.edi; 815 child_tidptr = (int __user *)regs.di;
790 if (!newsp) 816 if (!newsp)
791 newsp = regs.esp; 817 newsp = regs.sp;
792 return do_fork(clone_flags, newsp, &regs, 0, parent_tidptr, child_tidptr); 818 return do_fork(clone_flags, newsp, &regs, 0, parent_tidptr, child_tidptr);
793} 819}
794 820
@@ -804,7 +830,7 @@ asmlinkage int sys_clone(struct pt_regs regs)
804 */ 830 */
805asmlinkage int sys_vfork(struct pt_regs regs) 831asmlinkage int sys_vfork(struct pt_regs regs)
806{ 832{
807 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, &regs, 0, NULL, NULL); 833 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.sp, &regs, 0, NULL, NULL);
808} 834}
809 835
810/* 836/*
@@ -815,18 +841,15 @@ asmlinkage int sys_execve(struct pt_regs regs)
815 int error; 841 int error;
816 char * filename; 842 char * filename;
817 843
818 filename = getname((char __user *) regs.ebx); 844 filename = getname((char __user *) regs.bx);
819 error = PTR_ERR(filename); 845 error = PTR_ERR(filename);
820 if (IS_ERR(filename)) 846 if (IS_ERR(filename))
821 goto out; 847 goto out;
822 error = do_execve(filename, 848 error = do_execve(filename,
823 (char __user * __user *) regs.ecx, 849 (char __user * __user *) regs.cx,
824 (char __user * __user *) regs.edx, 850 (char __user * __user *) regs.dx,
825 &regs); 851 &regs);
826 if (error == 0) { 852 if (error == 0) {
827 task_lock(current);
828 current->ptrace &= ~PT_DTRACE;
829 task_unlock(current);
830 /* Make sure we don't return using sysenter.. */ 853 /* Make sure we don't return using sysenter.. */
831 set_thread_flag(TIF_IRET); 854 set_thread_flag(TIF_IRET);
832 } 855 }
@@ -840,145 +863,37 @@ out:
840 863
841unsigned long get_wchan(struct task_struct *p) 864unsigned long get_wchan(struct task_struct *p)
842{ 865{
843 unsigned long ebp, esp, eip; 866 unsigned long bp, sp, ip;
844 unsigned long stack_page; 867 unsigned long stack_page;
845 int count = 0; 868 int count = 0;
846 if (!p || p == current || p->state == TASK_RUNNING) 869 if (!p || p == current || p->state == TASK_RUNNING)
847 return 0; 870 return 0;
848 stack_page = (unsigned long)task_stack_page(p); 871 stack_page = (unsigned long)task_stack_page(p);
849 esp = p->thread.esp; 872 sp = p->thread.sp;
850 if (!stack_page || esp < stack_page || esp > top_esp+stack_page) 873 if (!stack_page || sp < stack_page || sp > top_esp+stack_page)
851 return 0; 874 return 0;
852 /* include/asm-i386/system.h:switch_to() pushes ebp last. */ 875 /* include/asm-i386/system.h:switch_to() pushes bp last. */
853 ebp = *(unsigned long *) esp; 876 bp = *(unsigned long *) sp;
854 do { 877 do {
855 if (ebp < stack_page || ebp > top_ebp+stack_page) 878 if (bp < stack_page || bp > top_ebp+stack_page)
856 return 0; 879 return 0;
857 eip = *(unsigned long *) (ebp+4); 880 ip = *(unsigned long *) (bp+4);
858 if (!in_sched_functions(eip)) 881 if (!in_sched_functions(ip))
859 return eip; 882 return ip;
860 ebp = *(unsigned long *) ebp; 883 bp = *(unsigned long *) bp;
861 } while (count++ < 16); 884 } while (count++ < 16);
862 return 0; 885 return 0;
863} 886}
864 887
865/*
866 * sys_alloc_thread_area: get a yet unused TLS descriptor index.
867 */
868static int get_free_idx(void)
869{
870 struct thread_struct *t = &current->thread;
871 int idx;
872
873 for (idx = 0; idx < GDT_ENTRY_TLS_ENTRIES; idx++)
874 if (desc_empty(t->tls_array + idx))
875 return idx + GDT_ENTRY_TLS_MIN;
876 return -ESRCH;
877}
878
879/*
880 * Set a given TLS descriptor:
881 */
882asmlinkage int sys_set_thread_area(struct user_desc __user *u_info)
883{
884 struct thread_struct *t = &current->thread;
885 struct user_desc info;
886 struct desc_struct *desc;
887 int cpu, idx;
888
889 if (copy_from_user(&info, u_info, sizeof(info)))
890 return -EFAULT;
891 idx = info.entry_number;
892
893 /*
894 * index -1 means the kernel should try to find and
895 * allocate an empty descriptor:
896 */
897 if (idx == -1) {
898 idx = get_free_idx();
899 if (idx < 0)
900 return idx;
901 if (put_user(idx, &u_info->entry_number))
902 return -EFAULT;
903 }
904
905 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
906 return -EINVAL;
907
908 desc = t->tls_array + idx - GDT_ENTRY_TLS_MIN;
909
910 /*
911 * We must not get preempted while modifying the TLS.
912 */
913 cpu = get_cpu();
914
915 if (LDT_empty(&info)) {
916 desc->a = 0;
917 desc->b = 0;
918 } else {
919 desc->a = LDT_entry_a(&info);
920 desc->b = LDT_entry_b(&info);
921 }
922 load_TLS(t, cpu);
923
924 put_cpu();
925
926 return 0;
927}
928
929/*
930 * Get the current Thread-Local Storage area:
931 */
932
933#define GET_BASE(desc) ( \
934 (((desc)->a >> 16) & 0x0000ffff) | \
935 (((desc)->b << 16) & 0x00ff0000) | \
936 ( (desc)->b & 0xff000000) )
937
938#define GET_LIMIT(desc) ( \
939 ((desc)->a & 0x0ffff) | \
940 ((desc)->b & 0xf0000) )
941
942#define GET_32BIT(desc) (((desc)->b >> 22) & 1)
943#define GET_CONTENTS(desc) (((desc)->b >> 10) & 3)
944#define GET_WRITABLE(desc) (((desc)->b >> 9) & 1)
945#define GET_LIMIT_PAGES(desc) (((desc)->b >> 23) & 1)
946#define GET_PRESENT(desc) (((desc)->b >> 15) & 1)
947#define GET_USEABLE(desc) (((desc)->b >> 20) & 1)
948
949asmlinkage int sys_get_thread_area(struct user_desc __user *u_info)
950{
951 struct user_desc info;
952 struct desc_struct *desc;
953 int idx;
954
955 if (get_user(idx, &u_info->entry_number))
956 return -EFAULT;
957 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
958 return -EINVAL;
959
960 memset(&info, 0, sizeof(info));
961
962 desc = current->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
963
964 info.entry_number = idx;
965 info.base_addr = GET_BASE(desc);
966 info.limit = GET_LIMIT(desc);
967 info.seg_32bit = GET_32BIT(desc);
968 info.contents = GET_CONTENTS(desc);
969 info.read_exec_only = !GET_WRITABLE(desc);
970 info.limit_in_pages = GET_LIMIT_PAGES(desc);
971 info.seg_not_present = !GET_PRESENT(desc);
972 info.useable = GET_USEABLE(desc);
973
974 if (copy_to_user(u_info, &info, sizeof(info)))
975 return -EFAULT;
976 return 0;
977}
978
979unsigned long arch_align_stack(unsigned long sp) 888unsigned long arch_align_stack(unsigned long sp)
980{ 889{
981 if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) 890 if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
982 sp -= get_random_int() % 8192; 891 sp -= get_random_int() % 8192;
983 return sp & ~0xf; 892 return sp & ~0xf;
984} 893}
894
895unsigned long arch_randomize_brk(struct mm_struct *mm)
896{
897 unsigned long range_end = mm->brk + 0x02000000;
898 return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
899}
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index ab79e1dfa023..137a86171c39 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Pentium III FXSR, SSE support 4 * Pentium III FXSR, SSE support
5 * Gareth Hughes <gareth@valinux.com>, May 2000 5 * Gareth Hughes <gareth@valinux.com>, May 2000
6 * 6 *
7 * X86-64 port 7 * X86-64 port
8 * Andi Kleen. 8 * Andi Kleen.
9 * 9 *
@@ -19,19 +19,19 @@
19#include <linux/cpu.h> 19#include <linux/cpu.h>
20#include <linux/errno.h> 20#include <linux/errno.h>
21#include <linux/sched.h> 21#include <linux/sched.h>
22#include <linux/fs.h>
22#include <linux/kernel.h> 23#include <linux/kernel.h>
23#include <linux/mm.h> 24#include <linux/mm.h>
24#include <linux/fs.h>
25#include <linux/elfcore.h> 25#include <linux/elfcore.h>
26#include <linux/smp.h> 26#include <linux/smp.h>
27#include <linux/slab.h> 27#include <linux/slab.h>
28#include <linux/user.h> 28#include <linux/user.h>
29#include <linux/module.h>
30#include <linux/a.out.h> 29#include <linux/a.out.h>
31#include <linux/interrupt.h> 30#include <linux/interrupt.h>
31#include <linux/utsname.h>
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/module.h>
33#include <linux/ptrace.h> 34#include <linux/ptrace.h>
34#include <linux/utsname.h>
35#include <linux/random.h> 35#include <linux/random.h>
36#include <linux/notifier.h> 36#include <linux/notifier.h>
37#include <linux/kprobes.h> 37#include <linux/kprobes.h>
@@ -72,13 +72,6 @@ void idle_notifier_register(struct notifier_block *n)
72{ 72{
73 atomic_notifier_chain_register(&idle_notifier, n); 73 atomic_notifier_chain_register(&idle_notifier, n);
74} 74}
75EXPORT_SYMBOL_GPL(idle_notifier_register);
76
77void idle_notifier_unregister(struct notifier_block *n)
78{
79 atomic_notifier_chain_unregister(&idle_notifier, n);
80}
81EXPORT_SYMBOL(idle_notifier_unregister);
82 75
83void enter_idle(void) 76void enter_idle(void)
84{ 77{
@@ -106,7 +99,7 @@ void exit_idle(void)
106 * We use this if we don't have any better 99 * We use this if we don't have any better
107 * idle routine.. 100 * idle routine..
108 */ 101 */
109static void default_idle(void) 102void default_idle(void)
110{ 103{
111 current_thread_info()->status &= ~TS_POLLING; 104 current_thread_info()->status &= ~TS_POLLING;
112 /* 105 /*
@@ -116,11 +109,18 @@ static void default_idle(void)
116 smp_mb(); 109 smp_mb();
117 local_irq_disable(); 110 local_irq_disable();
118 if (!need_resched()) { 111 if (!need_resched()) {
119 /* Enables interrupts one instruction before HLT. 112 ktime_t t0, t1;
120 x86 special cases this so there is no race. */ 113 u64 t0n, t1n;
121 safe_halt(); 114
122 } else 115 t0 = ktime_get();
123 local_irq_enable(); 116 t0n = ktime_to_ns(t0);
117 safe_halt(); /* enables interrupts racelessly */
118 local_irq_disable();
119 t1 = ktime_get();
120 t1n = ktime_to_ns(t1);
121 sched_clock_idle_wakeup_event(t1n - t0n);
122 }
123 local_irq_enable();
124 current_thread_info()->status |= TS_POLLING; 124 current_thread_info()->status |= TS_POLLING;
125} 125}
126 126
@@ -129,54 +129,12 @@ static void default_idle(void)
129 * to poll the ->need_resched flag instead of waiting for the 129 * to poll the ->need_resched flag instead of waiting for the
130 * cross-CPU IPI to arrive. Use this option with caution. 130 * cross-CPU IPI to arrive. Use this option with caution.
131 */ 131 */
132static void poll_idle (void) 132static void poll_idle(void)
133{ 133{
134 local_irq_enable(); 134 local_irq_enable();
135 cpu_relax(); 135 cpu_relax();
136} 136}
137 137
138static void do_nothing(void *unused)
139{
140}
141
142void cpu_idle_wait(void)
143{
144 unsigned int cpu, this_cpu = get_cpu();
145 cpumask_t map, tmp = current->cpus_allowed;
146
147 set_cpus_allowed(current, cpumask_of_cpu(this_cpu));
148 put_cpu();
149
150 cpus_clear(map);
151 for_each_online_cpu(cpu) {
152 per_cpu(cpu_idle_state, cpu) = 1;
153 cpu_set(cpu, map);
154 }
155
156 __get_cpu_var(cpu_idle_state) = 0;
157
158 wmb();
159 do {
160 ssleep(1);
161 for_each_online_cpu(cpu) {
162 if (cpu_isset(cpu, map) &&
163 !per_cpu(cpu_idle_state, cpu))
164 cpu_clear(cpu, map);
165 }
166 cpus_and(map, map, cpu_online_map);
167 /*
168 * We waited 1 sec, if a CPU still did not call idle
169 * it may be because it is in idle and not waking up
170 * because it has nothing to do.
171 * Give all the remaining CPUS a kick.
172 */
173 smp_call_function_mask(map, do_nothing, 0, 0);
174 } while (!cpus_empty(map));
175
176 set_cpus_allowed(current, tmp);
177}
178EXPORT_SYMBOL_GPL(cpu_idle_wait);
179
180#ifdef CONFIG_HOTPLUG_CPU 138#ifdef CONFIG_HOTPLUG_CPU
181DECLARE_PER_CPU(int, cpu_state); 139DECLARE_PER_CPU(int, cpu_state);
182 140
@@ -207,19 +165,18 @@ static inline void play_dead(void)
207 * low exit latency (ie sit in a loop waiting for 165 * low exit latency (ie sit in a loop waiting for
208 * somebody to say that they'd like to reschedule) 166 * somebody to say that they'd like to reschedule)
209 */ 167 */
210void cpu_idle (void) 168void cpu_idle(void)
211{ 169{
212 current_thread_info()->status |= TS_POLLING; 170 current_thread_info()->status |= TS_POLLING;
213 /* endless idle loop with no priority at all */ 171 /* endless idle loop with no priority at all */
214 while (1) { 172 while (1) {
173 tick_nohz_stop_sched_tick();
215 while (!need_resched()) { 174 while (!need_resched()) {
216 void (*idle)(void); 175 void (*idle)(void);
217 176
218 if (__get_cpu_var(cpu_idle_state)) 177 if (__get_cpu_var(cpu_idle_state))
219 __get_cpu_var(cpu_idle_state) = 0; 178 __get_cpu_var(cpu_idle_state) = 0;
220 179
221 tick_nohz_stop_sched_tick();
222
223 rmb(); 180 rmb();
224 idle = pm_idle; 181 idle = pm_idle;
225 if (!idle) 182 if (!idle)
@@ -247,6 +204,47 @@ void cpu_idle (void)
247 } 204 }
248} 205}
249 206
207static void do_nothing(void *unused)
208{
209}
210
211void cpu_idle_wait(void)
212{
213 unsigned int cpu, this_cpu = get_cpu();
214 cpumask_t map, tmp = current->cpus_allowed;
215
216 set_cpus_allowed(current, cpumask_of_cpu(this_cpu));
217 put_cpu();
218
219 cpus_clear(map);
220 for_each_online_cpu(cpu) {
221 per_cpu(cpu_idle_state, cpu) = 1;
222 cpu_set(cpu, map);
223 }
224
225 __get_cpu_var(cpu_idle_state) = 0;
226
227 wmb();
228 do {
229 ssleep(1);
230 for_each_online_cpu(cpu) {
231 if (cpu_isset(cpu, map) && !per_cpu(cpu_idle_state, cpu))
232 cpu_clear(cpu, map);
233 }
234 cpus_and(map, map, cpu_online_map);
235 /*
236 * We waited 1 sec, if a CPU still did not call idle
237 * it may be because it is in idle and not waking up
238 * because it has nothing to do.
239 * Give all the remaining CPUS a kick.
240 */
241 smp_call_function_mask(map, do_nothing, 0, 0);
242 } while (!cpus_empty(map));
243
244 set_cpus_allowed(current, tmp);
245}
246EXPORT_SYMBOL_GPL(cpu_idle_wait);
247
250/* 248/*
251 * This uses new MONITOR/MWAIT instructions on P4 processors with PNI, 249 * This uses new MONITOR/MWAIT instructions on P4 processors with PNI,
252 * which can obviate IPI to trigger checking of need_resched. 250 * which can obviate IPI to trigger checking of need_resched.
@@ -257,13 +255,13 @@ void cpu_idle (void)
257 * New with Core Duo processors, MWAIT can take some hints based on CPU 255 * New with Core Duo processors, MWAIT can take some hints based on CPU
258 * capability. 256 * capability.
259 */ 257 */
260void mwait_idle_with_hints(unsigned long eax, unsigned long ecx) 258void mwait_idle_with_hints(unsigned long ax, unsigned long cx)
261{ 259{
262 if (!need_resched()) { 260 if (!need_resched()) {
263 __monitor((void *)&current_thread_info()->flags, 0, 0); 261 __monitor((void *)&current_thread_info()->flags, 0, 0);
264 smp_mb(); 262 smp_mb();
265 if (!need_resched()) 263 if (!need_resched())
266 __mwait(eax, ecx); 264 __mwait(ax, cx);
267 } 265 }
268} 266}
269 267
@@ -282,25 +280,41 @@ static void mwait_idle(void)
282 } 280 }
283} 281}
284 282
283
284static int __cpuinit mwait_usable(const struct cpuinfo_x86 *c)
285{
286 if (force_mwait)
287 return 1;
288 /* Any C1 states supported? */
289 return c->cpuid_level >= 5 && ((cpuid_edx(5) >> 4) & 0xf) > 0;
290}
291
285void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) 292void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)
286{ 293{
287 static int printed; 294 static int selected;
288 if (cpu_has(c, X86_FEATURE_MWAIT)) { 295
296 if (selected)
297 return;
298#ifdef CONFIG_X86_SMP
299 if (pm_idle == poll_idle && smp_num_siblings > 1) {
300 printk(KERN_WARNING "WARNING: polling idle and HT enabled,"
301 " performance may degrade.\n");
302 }
303#endif
304 if (cpu_has(c, X86_FEATURE_MWAIT) && mwait_usable(c)) {
289 /* 305 /*
290 * Skip, if setup has overridden idle. 306 * Skip, if setup has overridden idle.
291 * One CPU supports mwait => All CPUs supports mwait 307 * One CPU supports mwait => All CPUs supports mwait
292 */ 308 */
293 if (!pm_idle) { 309 if (!pm_idle) {
294 if (!printed) { 310 printk(KERN_INFO "using mwait in idle threads.\n");
295 printk(KERN_INFO "using mwait in idle threads.\n");
296 printed = 1;
297 }
298 pm_idle = mwait_idle; 311 pm_idle = mwait_idle;
299 } 312 }
300 } 313 }
314 selected = 1;
301} 315}
302 316
303static int __init idle_setup (char *str) 317static int __init idle_setup(char *str)
304{ 318{
305 if (!strcmp(str, "poll")) { 319 if (!strcmp(str, "poll")) {
306 printk("using polling idle threads.\n"); 320 printk("using polling idle threads.\n");
@@ -315,13 +329,13 @@ static int __init idle_setup (char *str)
315} 329}
316early_param("idle", idle_setup); 330early_param("idle", idle_setup);
317 331
318/* Prints also some state that isn't saved in the pt_regs */ 332/* Prints also some state that isn't saved in the pt_regs */
319void __show_regs(struct pt_regs * regs) 333void __show_regs(struct pt_regs * regs)
320{ 334{
321 unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L, fs, gs, shadowgs; 335 unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L, fs, gs, shadowgs;
322 unsigned long d0, d1, d2, d3, d6, d7; 336 unsigned long d0, d1, d2, d3, d6, d7;
323 unsigned int fsindex,gsindex; 337 unsigned int fsindex, gsindex;
324 unsigned int ds,cs,es; 338 unsigned int ds, cs, es;
325 339
326 printk("\n"); 340 printk("\n");
327 print_modules(); 341 print_modules();
@@ -330,16 +344,16 @@ void __show_regs(struct pt_regs * regs)
330 init_utsname()->release, 344 init_utsname()->release,
331 (int)strcspn(init_utsname()->version, " "), 345 (int)strcspn(init_utsname()->version, " "),
332 init_utsname()->version); 346 init_utsname()->version);
333 printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->rip); 347 printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->ip);
334 printk_address(regs->rip); 348 printk_address(regs->ip, 1);
335 printk("RSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, regs->rsp, 349 printk("RSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, regs->sp,
336 regs->eflags); 350 regs->flags);
337 printk("RAX: %016lx RBX: %016lx RCX: %016lx\n", 351 printk("RAX: %016lx RBX: %016lx RCX: %016lx\n",
338 regs->rax, regs->rbx, regs->rcx); 352 regs->ax, regs->bx, regs->cx);
339 printk("RDX: %016lx RSI: %016lx RDI: %016lx\n", 353 printk("RDX: %016lx RSI: %016lx RDI: %016lx\n",
340 regs->rdx, regs->rsi, regs->rdi); 354 regs->dx, regs->si, regs->di);
341 printk("RBP: %016lx R08: %016lx R09: %016lx\n", 355 printk("RBP: %016lx R08: %016lx R09: %016lx\n",
342 regs->rbp, regs->r8, regs->r9); 356 regs->bp, regs->r8, regs->r9);
343 printk("R10: %016lx R11: %016lx R12: %016lx\n", 357 printk("R10: %016lx R11: %016lx R12: %016lx\n",
344 regs->r10, regs->r11, regs->r12); 358 regs->r10, regs->r11, regs->r12);
345 printk("R13: %016lx R14: %016lx R15: %016lx\n", 359 printk("R13: %016lx R14: %016lx R15: %016lx\n",
@@ -379,7 +393,7 @@ void show_regs(struct pt_regs *regs)
379{ 393{
380 printk("CPU %d:", smp_processor_id()); 394 printk("CPU %d:", smp_processor_id());
381 __show_regs(regs); 395 __show_regs(regs);
382 show_trace(NULL, regs, (void *)(regs + 1)); 396 show_trace(NULL, regs, (void *)(regs + 1), regs->bp);
383} 397}
384 398
385/* 399/*
@@ -390,7 +404,7 @@ void exit_thread(void)
390 struct task_struct *me = current; 404 struct task_struct *me = current;
391 struct thread_struct *t = &me->thread; 405 struct thread_struct *t = &me->thread;
392 406
393 if (me->thread.io_bitmap_ptr) { 407 if (me->thread.io_bitmap_ptr) {
394 struct tss_struct *tss = &per_cpu(init_tss, get_cpu()); 408 struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
395 409
396 kfree(t->io_bitmap_ptr); 410 kfree(t->io_bitmap_ptr);
@@ -426,7 +440,7 @@ void flush_thread(void)
426 tsk->thread.debugreg3 = 0; 440 tsk->thread.debugreg3 = 0;
427 tsk->thread.debugreg6 = 0; 441 tsk->thread.debugreg6 = 0;
428 tsk->thread.debugreg7 = 0; 442 tsk->thread.debugreg7 = 0;
429 memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array)); 443 memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
430 /* 444 /*
431 * Forget coprocessor state.. 445 * Forget coprocessor state..
432 */ 446 */
@@ -449,26 +463,21 @@ void release_thread(struct task_struct *dead_task)
449 463
450static inline void set_32bit_tls(struct task_struct *t, int tls, u32 addr) 464static inline void set_32bit_tls(struct task_struct *t, int tls, u32 addr)
451{ 465{
452 struct user_desc ud = { 466 struct user_desc ud = {
453 .base_addr = addr, 467 .base_addr = addr,
454 .limit = 0xfffff, 468 .limit = 0xfffff,
455 .seg_32bit = 1, 469 .seg_32bit = 1,
456 .limit_in_pages = 1, 470 .limit_in_pages = 1,
457 .useable = 1, 471 .useable = 1,
458 }; 472 };
459 struct n_desc_struct *desc = (void *)t->thread.tls_array; 473 struct desc_struct *desc = t->thread.tls_array;
460 desc += tls; 474 desc += tls;
461 desc->a = LDT_entry_a(&ud); 475 fill_ldt(desc, &ud);
462 desc->b = LDT_entry_b(&ud);
463} 476}
464 477
465static inline u32 read_32bit_tls(struct task_struct *t, int tls) 478static inline u32 read_32bit_tls(struct task_struct *t, int tls)
466{ 479{
467 struct desc_struct *desc = (void *)t->thread.tls_array; 480 return get_desc_base(&t->thread.tls_array[tls]);
468 desc += tls;
469 return desc->base0 |
470 (((u32)desc->base1) << 16) |
471 (((u32)desc->base2) << 24);
472} 481}
473 482
474/* 483/*
@@ -480,7 +489,7 @@ void prepare_to_copy(struct task_struct *tsk)
480 unlazy_fpu(tsk); 489 unlazy_fpu(tsk);
481} 490}
482 491
483int copy_thread(int nr, unsigned long clone_flags, unsigned long rsp, 492int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
484 unsigned long unused, 493 unsigned long unused,
485 struct task_struct * p, struct pt_regs * regs) 494 struct task_struct * p, struct pt_regs * regs)
486{ 495{
@@ -492,14 +501,14 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long rsp,
492 (THREAD_SIZE + task_stack_page(p))) - 1; 501 (THREAD_SIZE + task_stack_page(p))) - 1;
493 *childregs = *regs; 502 *childregs = *regs;
494 503
495 childregs->rax = 0; 504 childregs->ax = 0;
496 childregs->rsp = rsp; 505 childregs->sp = sp;
497 if (rsp == ~0UL) 506 if (sp == ~0UL)
498 childregs->rsp = (unsigned long)childregs; 507 childregs->sp = (unsigned long)childregs;
499 508
500 p->thread.rsp = (unsigned long) childregs; 509 p->thread.sp = (unsigned long) childregs;
501 p->thread.rsp0 = (unsigned long) (childregs+1); 510 p->thread.sp0 = (unsigned long) (childregs+1);
502 p->thread.userrsp = me->thread.userrsp; 511 p->thread.usersp = me->thread.usersp;
503 512
504 set_tsk_thread_flag(p, TIF_FORK); 513 set_tsk_thread_flag(p, TIF_FORK);
505 514
@@ -520,7 +529,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long rsp,
520 memcpy(p->thread.io_bitmap_ptr, me->thread.io_bitmap_ptr, 529 memcpy(p->thread.io_bitmap_ptr, me->thread.io_bitmap_ptr,
521 IO_BITMAP_BYTES); 530 IO_BITMAP_BYTES);
522 set_tsk_thread_flag(p, TIF_IO_BITMAP); 531 set_tsk_thread_flag(p, TIF_IO_BITMAP);
523 } 532 }
524 533
525 /* 534 /*
526 * Set a new TLS for the child thread? 535 * Set a new TLS for the child thread?
@@ -528,7 +537,8 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long rsp,
528 if (clone_flags & CLONE_SETTLS) { 537 if (clone_flags & CLONE_SETTLS) {
529#ifdef CONFIG_IA32_EMULATION 538#ifdef CONFIG_IA32_EMULATION
530 if (test_thread_flag(TIF_IA32)) 539 if (test_thread_flag(TIF_IA32))
531 err = ia32_child_tls(p, childregs); 540 err = do_set_thread_area(p, -1,
541 (struct user_desc __user *)childregs->si, 0);
532 else 542 else
533#endif 543#endif
534 err = do_arch_prctl(p, ARCH_SET_FS, childregs->r8); 544 err = do_arch_prctl(p, ARCH_SET_FS, childregs->r8);
@@ -547,17 +557,30 @@ out:
547/* 557/*
548 * This special macro can be used to load a debugging register 558 * This special macro can be used to load a debugging register
549 */ 559 */
550#define loaddebug(thread,r) set_debugreg(thread->debugreg ## r, r) 560#define loaddebug(thread, r) set_debugreg(thread->debugreg ## r, r)
551 561
552static inline void __switch_to_xtra(struct task_struct *prev_p, 562static inline void __switch_to_xtra(struct task_struct *prev_p,
553 struct task_struct *next_p, 563 struct task_struct *next_p,
554 struct tss_struct *tss) 564 struct tss_struct *tss)
555{ 565{
556 struct thread_struct *prev, *next; 566 struct thread_struct *prev, *next;
567 unsigned long debugctl;
557 568
558 prev = &prev_p->thread, 569 prev = &prev_p->thread,
559 next = &next_p->thread; 570 next = &next_p->thread;
560 571
572 debugctl = prev->debugctlmsr;
573 if (next->ds_area_msr != prev->ds_area_msr) {
574 /* we clear debugctl to make sure DS
575 * is not in use when we change it */
576 debugctl = 0;
577 wrmsrl(MSR_IA32_DEBUGCTLMSR, 0);
578 wrmsrl(MSR_IA32_DS_AREA, next->ds_area_msr);
579 }
580
581 if (next->debugctlmsr != debugctl)
582 wrmsrl(MSR_IA32_DEBUGCTLMSR, next->debugctlmsr);
583
561 if (test_tsk_thread_flag(next_p, TIF_DEBUG)) { 584 if (test_tsk_thread_flag(next_p, TIF_DEBUG)) {
562 loaddebug(next, 0); 585 loaddebug(next, 0);
563 loaddebug(next, 1); 586 loaddebug(next, 1);
@@ -581,12 +604,18 @@ static inline void __switch_to_xtra(struct task_struct *prev_p,
581 */ 604 */
582 memset(tss->io_bitmap, 0xff, prev->io_bitmap_max); 605 memset(tss->io_bitmap, 0xff, prev->io_bitmap_max);
583 } 606 }
607
608 if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS))
609 ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS);
610
611 if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS))
612 ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES);
584} 613}
585 614
586/* 615/*
587 * switch_to(x,y) should switch tasks from x to y. 616 * switch_to(x,y) should switch tasks from x to y.
588 * 617 *
589 * This could still be optimized: 618 * This could still be optimized:
590 * - fold all the options into a flag word and test it with a single test. 619 * - fold all the options into a flag word and test it with a single test.
591 * - could test fs/gs bitsliced 620 * - could test fs/gs bitsliced
592 * 621 *
@@ -597,7 +626,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
597{ 626{
598 struct thread_struct *prev = &prev_p->thread, 627 struct thread_struct *prev = &prev_p->thread,
599 *next = &next_p->thread; 628 *next = &next_p->thread;
600 int cpu = smp_processor_id(); 629 int cpu = smp_processor_id();
601 struct tss_struct *tss = &per_cpu(init_tss, cpu); 630 struct tss_struct *tss = &per_cpu(init_tss, cpu);
602 631
603 /* we're going to use this soon, after a few expensive things */ 632 /* we're going to use this soon, after a few expensive things */
@@ -607,7 +636,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
607 /* 636 /*
608 * Reload esp0, LDT and the page table pointer: 637 * Reload esp0, LDT and the page table pointer:
609 */ 638 */
610 tss->rsp0 = next->rsp0; 639 load_sp0(tss, next);
611 640
612 /* 641 /*
613 * Switch DS and ES. 642 * Switch DS and ES.
@@ -666,8 +695,8 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
666 /* 695 /*
667 * Switch the PDA and FPU contexts. 696 * Switch the PDA and FPU contexts.
668 */ 697 */
669 prev->userrsp = read_pda(oldrsp); 698 prev->usersp = read_pda(oldrsp);
670 write_pda(oldrsp, next->userrsp); 699 write_pda(oldrsp, next->usersp);
671 write_pda(pcurrent, next_p); 700 write_pda(pcurrent, next_p);
672 701
673 write_pda(kernelstack, 702 write_pda(kernelstack,
@@ -684,8 +713,8 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
684 /* 713 /*
685 * Now maybe reload the debug registers and handle I/O bitmaps 714 * Now maybe reload the debug registers and handle I/O bitmaps
686 */ 715 */
687 if (unlikely((task_thread_info(next_p)->flags & _TIF_WORK_CTXSW)) 716 if (unlikely(task_thread_info(next_p)->flags & _TIF_WORK_CTXSW_NEXT ||
688 || test_tsk_thread_flag(prev_p, TIF_IO_BITMAP)) 717 task_thread_info(prev_p)->flags & _TIF_WORK_CTXSW_PREV))
689 __switch_to_xtra(prev_p, next_p, tss); 718 __switch_to_xtra(prev_p, next_p, tss);
690 719
691 /* If the task has used fpu the last 5 timeslices, just do a full 720 /* If the task has used fpu the last 5 timeslices, just do a full
@@ -700,7 +729,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
700/* 729/*
701 * sys_execve() executes a new program. 730 * sys_execve() executes a new program.
702 */ 731 */
703asmlinkage 732asmlinkage
704long sys_execve(char __user *name, char __user * __user *argv, 733long sys_execve(char __user *name, char __user * __user *argv,
705 char __user * __user *envp, struct pt_regs regs) 734 char __user * __user *envp, struct pt_regs regs)
706{ 735{
@@ -712,11 +741,6 @@ long sys_execve(char __user *name, char __user * __user *argv,
712 if (IS_ERR(filename)) 741 if (IS_ERR(filename))
713 return error; 742 return error;
714 error = do_execve(filename, argv, envp, &regs); 743 error = do_execve(filename, argv, envp, &regs);
715 if (error == 0) {
716 task_lock(current);
717 current->ptrace &= ~PT_DTRACE;
718 task_unlock(current);
719 }
720 putname(filename); 744 putname(filename);
721 return error; 745 return error;
722} 746}
@@ -726,18 +750,18 @@ void set_personality_64bit(void)
726 /* inherit personality from parent */ 750 /* inherit personality from parent */
727 751
728 /* Make sure to be in 64bit mode */ 752 /* Make sure to be in 64bit mode */
729 clear_thread_flag(TIF_IA32); 753 clear_thread_flag(TIF_IA32);
730 754
731 /* TBD: overwrites user setup. Should have two bits. 755 /* TBD: overwrites user setup. Should have two bits.
732 But 64bit processes have always behaved this way, 756 But 64bit processes have always behaved this way,
733 so it's not too bad. The main problem is just that 757 so it's not too bad. The main problem is just that
734 32bit childs are affected again. */ 758 32bit childs are affected again. */
735 current->personality &= ~READ_IMPLIES_EXEC; 759 current->personality &= ~READ_IMPLIES_EXEC;
736} 760}
737 761
738asmlinkage long sys_fork(struct pt_regs *regs) 762asmlinkage long sys_fork(struct pt_regs *regs)
739{ 763{
740 return do_fork(SIGCHLD, regs->rsp, regs, 0, NULL, NULL); 764 return do_fork(SIGCHLD, regs->sp, regs, 0, NULL, NULL);
741} 765}
742 766
743asmlinkage long 767asmlinkage long
@@ -745,7 +769,7 @@ sys_clone(unsigned long clone_flags, unsigned long newsp,
745 void __user *parent_tid, void __user *child_tid, struct pt_regs *regs) 769 void __user *parent_tid, void __user *child_tid, struct pt_regs *regs)
746{ 770{
747 if (!newsp) 771 if (!newsp)
748 newsp = regs->rsp; 772 newsp = regs->sp;
749 return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid); 773 return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid);
750} 774}
751 775
@@ -761,29 +785,29 @@ sys_clone(unsigned long clone_flags, unsigned long newsp,
761 */ 785 */
762asmlinkage long sys_vfork(struct pt_regs *regs) 786asmlinkage long sys_vfork(struct pt_regs *regs)
763{ 787{
764 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->rsp, regs, 0, 788 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->sp, regs, 0,
765 NULL, NULL); 789 NULL, NULL);
766} 790}
767 791
768unsigned long get_wchan(struct task_struct *p) 792unsigned long get_wchan(struct task_struct *p)
769{ 793{
770 unsigned long stack; 794 unsigned long stack;
771 u64 fp,rip; 795 u64 fp,ip;
772 int count = 0; 796 int count = 0;
773 797
774 if (!p || p == current || p->state==TASK_RUNNING) 798 if (!p || p == current || p->state==TASK_RUNNING)
775 return 0; 799 return 0;
776 stack = (unsigned long)task_stack_page(p); 800 stack = (unsigned long)task_stack_page(p);
777 if (p->thread.rsp < stack || p->thread.rsp > stack+THREAD_SIZE) 801 if (p->thread.sp < stack || p->thread.sp > stack+THREAD_SIZE)
778 return 0; 802 return 0;
779 fp = *(u64 *)(p->thread.rsp); 803 fp = *(u64 *)(p->thread.sp);
780 do { 804 do {
781 if (fp < (unsigned long)stack || 805 if (fp < (unsigned long)stack ||
782 fp > (unsigned long)stack+THREAD_SIZE) 806 fp > (unsigned long)stack+THREAD_SIZE)
783 return 0; 807 return 0;
784 rip = *(u64 *)(fp+8); 808 ip = *(u64 *)(fp+8);
785 if (!in_sched_functions(rip)) 809 if (!in_sched_functions(ip))
786 return rip; 810 return ip;
787 fp = *(u64 *)fp; 811 fp = *(u64 *)fp;
788 } while (count++ < 16); 812 } while (count++ < 16);
789 return 0; 813 return 0;
@@ -824,19 +848,19 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
824 /* Not strictly needed for fs, but do it for symmetry 848 /* Not strictly needed for fs, but do it for symmetry
825 with gs */ 849 with gs */
826 if (addr >= TASK_SIZE_OF(task)) 850 if (addr >= TASK_SIZE_OF(task))
827 return -EPERM; 851 return -EPERM;
828 cpu = get_cpu(); 852 cpu = get_cpu();
829 /* handle small bases via the GDT because that's faster to 853 /* handle small bases via the GDT because that's faster to
830 switch. */ 854 switch. */
831 if (addr <= 0xffffffff) { 855 if (addr <= 0xffffffff) {
832 set_32bit_tls(task, FS_TLS, addr); 856 set_32bit_tls(task, FS_TLS, addr);
833 if (doit) { 857 if (doit) {
834 load_TLS(&task->thread, cpu); 858 load_TLS(&task->thread, cpu);
835 asm volatile("movl %0,%%fs" :: "r"(FS_TLS_SEL)); 859 asm volatile("movl %0,%%fs" :: "r"(FS_TLS_SEL));
836 } 860 }
837 task->thread.fsindex = FS_TLS_SEL; 861 task->thread.fsindex = FS_TLS_SEL;
838 task->thread.fs = 0; 862 task->thread.fs = 0;
839 } else { 863 } else {
840 task->thread.fsindex = 0; 864 task->thread.fsindex = 0;
841 task->thread.fs = addr; 865 task->thread.fs = addr;
842 if (doit) { 866 if (doit) {
@@ -848,24 +872,24 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
848 } 872 }
849 put_cpu(); 873 put_cpu();
850 break; 874 break;
851 case ARCH_GET_FS: { 875 case ARCH_GET_FS: {
852 unsigned long base; 876 unsigned long base;
853 if (task->thread.fsindex == FS_TLS_SEL) 877 if (task->thread.fsindex == FS_TLS_SEL)
854 base = read_32bit_tls(task, FS_TLS); 878 base = read_32bit_tls(task, FS_TLS);
855 else if (doit) 879 else if (doit)
856 rdmsrl(MSR_FS_BASE, base); 880 rdmsrl(MSR_FS_BASE, base);
857 else 881 else
858 base = task->thread.fs; 882 base = task->thread.fs;
859 ret = put_user(base, (unsigned long __user *)addr); 883 ret = put_user(base, (unsigned long __user *)addr);
860 break; 884 break;
861 } 885 }
862 case ARCH_GET_GS: { 886 case ARCH_GET_GS: {
863 unsigned long base; 887 unsigned long base;
864 unsigned gsindex; 888 unsigned gsindex;
865 if (task->thread.gsindex == GS_TLS_SEL) 889 if (task->thread.gsindex == GS_TLS_SEL)
866 base = read_32bit_tls(task, GS_TLS); 890 base = read_32bit_tls(task, GS_TLS);
867 else if (doit) { 891 else if (doit) {
868 asm("movl %%gs,%0" : "=r" (gsindex)); 892 asm("movl %%gs,%0" : "=r" (gsindex));
869 if (gsindex) 893 if (gsindex)
870 rdmsrl(MSR_KERNEL_GS_BASE, base); 894 rdmsrl(MSR_KERNEL_GS_BASE, base);
871 else 895 else
@@ -873,39 +897,21 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
873 } 897 }
874 else 898 else
875 base = task->thread.gs; 899 base = task->thread.gs;
876 ret = put_user(base, (unsigned long __user *)addr); 900 ret = put_user(base, (unsigned long __user *)addr);
877 break; 901 break;
878 } 902 }
879 903
880 default: 904 default:
881 ret = -EINVAL; 905 ret = -EINVAL;
882 break; 906 break;
883 } 907 }
884 908
885 return ret; 909 return ret;
886} 910}
887 911
888long sys_arch_prctl(int code, unsigned long addr) 912long sys_arch_prctl(int code, unsigned long addr)
889{ 913{
890 return do_arch_prctl(current, code, addr); 914 return do_arch_prctl(current, code, addr);
891}
892
893/*
894 * Capture the user space registers if the task is not running (in user space)
895 */
896int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
897{
898 struct pt_regs *pp, ptregs;
899
900 pp = task_pt_regs(tsk);
901
902 ptregs = *pp;
903 ptregs.cs &= 0xffff;
904 ptregs.ss &= 0xffff;
905
906 elf_core_copy_regs(regs, &ptregs);
907
908 return 1;
909} 915}
910 916
911unsigned long arch_align_stack(unsigned long sp) 917unsigned long arch_align_stack(unsigned long sp)
@@ -914,3 +920,9 @@ unsigned long arch_align_stack(unsigned long sp)
914 sp -= get_random_int() % 8192; 920 sp -= get_random_int() % 8192;
915 return sp & ~0xf; 921 return sp & ~0xf;
916} 922}
923
924unsigned long arch_randomize_brk(struct mm_struct *mm)
925{
926 unsigned long range_end = mm->brk + 0x02000000;
927 return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
928}
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
new file mode 100644
index 000000000000..96286df1bb81
--- /dev/null
+++ b/arch/x86/kernel/ptrace.c
@@ -0,0 +1,1545 @@
1/* By Ross Biro 1/23/92 */
2/*
3 * Pentium III FXSR, SSE support
4 * Gareth Hughes <gareth@valinux.com>, May 2000
5 *
6 * BTS tracing
7 * Markus Metzger <markus.t.metzger@intel.com>, Dec 2007
8 */
9
10#include <linux/kernel.h>
11#include <linux/sched.h>
12#include <linux/mm.h>
13#include <linux/smp.h>
14#include <linux/errno.h>
15#include <linux/ptrace.h>
16#include <linux/regset.h>
17#include <linux/user.h>
18#include <linux/elf.h>
19#include <linux/security.h>
20#include <linux/audit.h>
21#include <linux/seccomp.h>
22#include <linux/signal.h>
23
24#include <asm/uaccess.h>
25#include <asm/pgtable.h>
26#include <asm/system.h>
27#include <asm/processor.h>
28#include <asm/i387.h>
29#include <asm/debugreg.h>
30#include <asm/ldt.h>
31#include <asm/desc.h>
32#include <asm/prctl.h>
33#include <asm/proto.h>
34#include <asm/ds.h>
35
36#include "tls.h"
37
38enum x86_regset {
39 REGSET_GENERAL,
40 REGSET_FP,
41 REGSET_XFP,
42 REGSET_TLS,
43};
44
45/*
46 * does not yet catch signals sent when the child dies.
47 * in exit.c or in signal.c.
48 */
49
50/*
51 * Determines which flags the user has access to [1 = access, 0 = no access].
52 */
53#define FLAG_MASK_32 ((unsigned long) \
54 (X86_EFLAGS_CF | X86_EFLAGS_PF | \
55 X86_EFLAGS_AF | X86_EFLAGS_ZF | \
56 X86_EFLAGS_SF | X86_EFLAGS_TF | \
57 X86_EFLAGS_DF | X86_EFLAGS_OF | \
58 X86_EFLAGS_RF | X86_EFLAGS_AC))
59
60/*
61 * Determines whether a value may be installed in a segment register.
62 */
63static inline bool invalid_selector(u16 value)
64{
65 return unlikely(value != 0 && (value & SEGMENT_RPL_MASK) != USER_RPL);
66}
67
68#ifdef CONFIG_X86_32
69
70#define FLAG_MASK FLAG_MASK_32
71
72static long *pt_regs_access(struct pt_regs *regs, unsigned long regno)
73{
74 BUILD_BUG_ON(offsetof(struct pt_regs, bx) != 0);
75 regno >>= 2;
76 if (regno > FS)
77 --regno;
78 return &regs->bx + regno;
79}
80
81static u16 get_segment_reg(struct task_struct *task, unsigned long offset)
82{
83 /*
84 * Returning the value truncates it to 16 bits.
85 */
86 unsigned int retval;
87 if (offset != offsetof(struct user_regs_struct, gs))
88 retval = *pt_regs_access(task_pt_regs(task), offset);
89 else {
90 retval = task->thread.gs;
91 if (task == current)
92 savesegment(gs, retval);
93 }
94 return retval;
95}
96
97static int set_segment_reg(struct task_struct *task,
98 unsigned long offset, u16 value)
99{
100 /*
101 * The value argument was already truncated to 16 bits.
102 */
103 if (invalid_selector(value))
104 return -EIO;
105
106 if (offset != offsetof(struct user_regs_struct, gs))
107 *pt_regs_access(task_pt_regs(task), offset) = value;
108 else {
109 task->thread.gs = value;
110 if (task == current)
111 /*
112 * The user-mode %gs is not affected by
113 * kernel entry, so we must update the CPU.
114 */
115 loadsegment(gs, value);
116 }
117
118 return 0;
119}
120
121static unsigned long debugreg_addr_limit(struct task_struct *task)
122{
123 return TASK_SIZE - 3;
124}
125
126#else /* CONFIG_X86_64 */
127
128#define FLAG_MASK (FLAG_MASK_32 | X86_EFLAGS_NT)
129
130static unsigned long *pt_regs_access(struct pt_regs *regs, unsigned long offset)
131{
132 BUILD_BUG_ON(offsetof(struct pt_regs, r15) != 0);
133 return &regs->r15 + (offset / sizeof(regs->r15));
134}
135
136static u16 get_segment_reg(struct task_struct *task, unsigned long offset)
137{
138 /*
139 * Returning the value truncates it to 16 bits.
140 */
141 unsigned int seg;
142
143 switch (offset) {
144 case offsetof(struct user_regs_struct, fs):
145 if (task == current) {
146 /* Older gas can't assemble movq %?s,%r?? */
147 asm("movl %%fs,%0" : "=r" (seg));
148 return seg;
149 }
150 return task->thread.fsindex;
151 case offsetof(struct user_regs_struct, gs):
152 if (task == current) {
153 asm("movl %%gs,%0" : "=r" (seg));
154 return seg;
155 }
156 return task->thread.gsindex;
157 case offsetof(struct user_regs_struct, ds):
158 if (task == current) {
159 asm("movl %%ds,%0" : "=r" (seg));
160 return seg;
161 }
162 return task->thread.ds;
163 case offsetof(struct user_regs_struct, es):
164 if (task == current) {
165 asm("movl %%es,%0" : "=r" (seg));
166 return seg;
167 }
168 return task->thread.es;
169
170 case offsetof(struct user_regs_struct, cs):
171 case offsetof(struct user_regs_struct, ss):
172 break;
173 }
174 return *pt_regs_access(task_pt_regs(task), offset);
175}
176
177static int set_segment_reg(struct task_struct *task,
178 unsigned long offset, u16 value)
179{
180 /*
181 * The value argument was already truncated to 16 bits.
182 */
183 if (invalid_selector(value))
184 return -EIO;
185
186 switch (offset) {
187 case offsetof(struct user_regs_struct,fs):
188 /*
189 * If this is setting fs as for normal 64-bit use but
190 * setting fs_base has implicitly changed it, leave it.
191 */
192 if ((value == FS_TLS_SEL && task->thread.fsindex == 0 &&
193 task->thread.fs != 0) ||
194 (value == 0 && task->thread.fsindex == FS_TLS_SEL &&
195 task->thread.fs == 0))
196 break;
197 task->thread.fsindex = value;
198 if (task == current)
199 loadsegment(fs, task->thread.fsindex);
200 break;
201 case offsetof(struct user_regs_struct,gs):
202 /*
203 * If this is setting gs as for normal 64-bit use but
204 * setting gs_base has implicitly changed it, leave it.
205 */
206 if ((value == GS_TLS_SEL && task->thread.gsindex == 0 &&
207 task->thread.gs != 0) ||
208 (value == 0 && task->thread.gsindex == GS_TLS_SEL &&
209 task->thread.gs == 0))
210 break;
211 task->thread.gsindex = value;
212 if (task == current)
213 load_gs_index(task->thread.gsindex);
214 break;
215 case offsetof(struct user_regs_struct,ds):
216 task->thread.ds = value;
217 if (task == current)
218 loadsegment(ds, task->thread.ds);
219 break;
220 case offsetof(struct user_regs_struct,es):
221 task->thread.es = value;
222 if (task == current)
223 loadsegment(es, task->thread.es);
224 break;
225
226 /*
227 * Can't actually change these in 64-bit mode.
228 */
229 case offsetof(struct user_regs_struct,cs):
230#ifdef CONFIG_IA32_EMULATION
231 if (test_tsk_thread_flag(task, TIF_IA32))
232 task_pt_regs(task)->cs = value;
233#endif
234 break;
235 case offsetof(struct user_regs_struct,ss):
236#ifdef CONFIG_IA32_EMULATION
237 if (test_tsk_thread_flag(task, TIF_IA32))
238 task_pt_regs(task)->ss = value;
239#endif
240 break;
241 }
242
243 return 0;
244}
245
246static unsigned long debugreg_addr_limit(struct task_struct *task)
247{
248#ifdef CONFIG_IA32_EMULATION
249 if (test_tsk_thread_flag(task, TIF_IA32))
250 return IA32_PAGE_OFFSET - 3;
251#endif
252 return TASK_SIZE64 - 7;
253}
254
255#endif /* CONFIG_X86_32 */
256
257static unsigned long get_flags(struct task_struct *task)
258{
259 unsigned long retval = task_pt_regs(task)->flags;
260
261 /*
262 * If the debugger set TF, hide it from the readout.
263 */
264 if (test_tsk_thread_flag(task, TIF_FORCED_TF))
265 retval &= ~X86_EFLAGS_TF;
266
267 return retval;
268}
269
270static int set_flags(struct task_struct *task, unsigned long value)
271{
272 struct pt_regs *regs = task_pt_regs(task);
273
274 /*
275 * If the user value contains TF, mark that
276 * it was not "us" (the debugger) that set it.
277 * If not, make sure it stays set if we had.
278 */
279 if (value & X86_EFLAGS_TF)
280 clear_tsk_thread_flag(task, TIF_FORCED_TF);
281 else if (test_tsk_thread_flag(task, TIF_FORCED_TF))
282 value |= X86_EFLAGS_TF;
283
284 regs->flags = (regs->flags & ~FLAG_MASK) | (value & FLAG_MASK);
285
286 return 0;
287}
288
289static int putreg(struct task_struct *child,
290 unsigned long offset, unsigned long value)
291{
292 switch (offset) {
293 case offsetof(struct user_regs_struct, cs):
294 case offsetof(struct user_regs_struct, ds):
295 case offsetof(struct user_regs_struct, es):
296 case offsetof(struct user_regs_struct, fs):
297 case offsetof(struct user_regs_struct, gs):
298 case offsetof(struct user_regs_struct, ss):
299 return set_segment_reg(child, offset, value);
300
301 case offsetof(struct user_regs_struct, flags):
302 return set_flags(child, value);
303
304#ifdef CONFIG_X86_64
305 case offsetof(struct user_regs_struct,fs_base):
306 if (value >= TASK_SIZE_OF(child))
307 return -EIO;
308 /*
309 * When changing the segment base, use do_arch_prctl
310 * to set either thread.fs or thread.fsindex and the
311 * corresponding GDT slot.
312 */
313 if (child->thread.fs != value)
314 return do_arch_prctl(child, ARCH_SET_FS, value);
315 return 0;
316 case offsetof(struct user_regs_struct,gs_base):
317 /*
318 * Exactly the same here as the %fs handling above.
319 */
320 if (value >= TASK_SIZE_OF(child))
321 return -EIO;
322 if (child->thread.gs != value)
323 return do_arch_prctl(child, ARCH_SET_GS, value);
324 return 0;
325#endif
326 }
327
328 *pt_regs_access(task_pt_regs(child), offset) = value;
329 return 0;
330}
331
332static unsigned long getreg(struct task_struct *task, unsigned long offset)
333{
334 switch (offset) {
335 case offsetof(struct user_regs_struct, cs):
336 case offsetof(struct user_regs_struct, ds):
337 case offsetof(struct user_regs_struct, es):
338 case offsetof(struct user_regs_struct, fs):
339 case offsetof(struct user_regs_struct, gs):
340 case offsetof(struct user_regs_struct, ss):
341 return get_segment_reg(task, offset);
342
343 case offsetof(struct user_regs_struct, flags):
344 return get_flags(task);
345
346#ifdef CONFIG_X86_64
347 case offsetof(struct user_regs_struct, fs_base): {
348 /*
349 * do_arch_prctl may have used a GDT slot instead of
350 * the MSR. To userland, it appears the same either
351 * way, except the %fs segment selector might not be 0.
352 */
353 unsigned int seg = task->thread.fsindex;
354 if (task->thread.fs != 0)
355 return task->thread.fs;
356 if (task == current)
357 asm("movl %%fs,%0" : "=r" (seg));
358 if (seg != FS_TLS_SEL)
359 return 0;
360 return get_desc_base(&task->thread.tls_array[FS_TLS]);
361 }
362 case offsetof(struct user_regs_struct, gs_base): {
363 /*
364 * Exactly the same here as the %fs handling above.
365 */
366 unsigned int seg = task->thread.gsindex;
367 if (task->thread.gs != 0)
368 return task->thread.gs;
369 if (task == current)
370 asm("movl %%gs,%0" : "=r" (seg));
371 if (seg != GS_TLS_SEL)
372 return 0;
373 return get_desc_base(&task->thread.tls_array[GS_TLS]);
374 }
375#endif
376 }
377
378 return *pt_regs_access(task_pt_regs(task), offset);
379}
380
381static int genregs_get(struct task_struct *target,
382 const struct user_regset *regset,
383 unsigned int pos, unsigned int count,
384 void *kbuf, void __user *ubuf)
385{
386 if (kbuf) {
387 unsigned long *k = kbuf;
388 while (count > 0) {
389 *k++ = getreg(target, pos);
390 count -= sizeof(*k);
391 pos += sizeof(*k);
392 }
393 } else {
394 unsigned long __user *u = ubuf;
395 while (count > 0) {
396 if (__put_user(getreg(target, pos), u++))
397 return -EFAULT;
398 count -= sizeof(*u);
399 pos += sizeof(*u);
400 }
401 }
402
403 return 0;
404}
405
406static int genregs_set(struct task_struct *target,
407 const struct user_regset *regset,
408 unsigned int pos, unsigned int count,
409 const void *kbuf, const void __user *ubuf)
410{
411 int ret = 0;
412 if (kbuf) {
413 const unsigned long *k = kbuf;
414 while (count > 0 && !ret) {
415 ret = putreg(target, pos, *k++);
416 count -= sizeof(*k);
417 pos += sizeof(*k);
418 }
419 } else {
420 const unsigned long __user *u = ubuf;
421 while (count > 0 && !ret) {
422 unsigned long word;
423 ret = __get_user(word, u++);
424 if (ret)
425 break;
426 ret = putreg(target, pos, word);
427 count -= sizeof(*u);
428 pos += sizeof(*u);
429 }
430 }
431 return ret;
432}
433
434/*
435 * This function is trivial and will be inlined by the compiler.
436 * Having it separates the implementation details of debug
437 * registers from the interface details of ptrace.
438 */
439static unsigned long ptrace_get_debugreg(struct task_struct *child, int n)
440{
441 switch (n) {
442 case 0: return child->thread.debugreg0;
443 case 1: return child->thread.debugreg1;
444 case 2: return child->thread.debugreg2;
445 case 3: return child->thread.debugreg3;
446 case 6: return child->thread.debugreg6;
447 case 7: return child->thread.debugreg7;
448 }
449 return 0;
450}
451
452static int ptrace_set_debugreg(struct task_struct *child,
453 int n, unsigned long data)
454{
455 int i;
456
457 if (unlikely(n == 4 || n == 5))
458 return -EIO;
459
460 if (n < 4 && unlikely(data >= debugreg_addr_limit(child)))
461 return -EIO;
462
463 switch (n) {
464 case 0: child->thread.debugreg0 = data; break;
465 case 1: child->thread.debugreg1 = data; break;
466 case 2: child->thread.debugreg2 = data; break;
467 case 3: child->thread.debugreg3 = data; break;
468
469 case 6:
470 if ((data & ~0xffffffffUL) != 0)
471 return -EIO;
472 child->thread.debugreg6 = data;
473 break;
474
475 case 7:
476 /*
477 * Sanity-check data. Take one half-byte at once with
478 * check = (val >> (16 + 4*i)) & 0xf. It contains the
479 * R/Wi and LENi bits; bits 0 and 1 are R/Wi, and bits
480 * 2 and 3 are LENi. Given a list of invalid values,
481 * we do mask |= 1 << invalid_value, so that
482 * (mask >> check) & 1 is a correct test for invalid
483 * values.
484 *
485 * R/Wi contains the type of the breakpoint /
486 * watchpoint, LENi contains the length of the watched
487 * data in the watchpoint case.
488 *
489 * The invalid values are:
490 * - LENi == 0x10 (undefined), so mask |= 0x0f00. [32-bit]
491 * - R/Wi == 0x10 (break on I/O reads or writes), so
492 * mask |= 0x4444.
493 * - R/Wi == 0x00 && LENi != 0x00, so we have mask |=
494 * 0x1110.
495 *
496 * Finally, mask = 0x0f00 | 0x4444 | 0x1110 == 0x5f54.
497 *
498 * See the Intel Manual "System Programming Guide",
499 * 15.2.4
500 *
501 * Note that LENi == 0x10 is defined on x86_64 in long
502 * mode (i.e. even for 32-bit userspace software, but
503 * 64-bit kernel), so the x86_64 mask value is 0x5454.
504 * See the AMD manual no. 24593 (AMD64 System Programming)
505 */
506#ifdef CONFIG_X86_32
507#define DR7_MASK 0x5f54
508#else
509#define DR7_MASK 0x5554
510#endif
511 data &= ~DR_CONTROL_RESERVED;
512 for (i = 0; i < 4; i++)
513 if ((DR7_MASK >> ((data >> (16 + 4*i)) & 0xf)) & 1)
514 return -EIO;
515 child->thread.debugreg7 = data;
516 if (data)
517 set_tsk_thread_flag(child, TIF_DEBUG);
518 else
519 clear_tsk_thread_flag(child, TIF_DEBUG);
520 break;
521 }
522
523 return 0;
524}
525
526static int ptrace_bts_get_size(struct task_struct *child)
527{
528 if (!child->thread.ds_area_msr)
529 return -ENXIO;
530
531 return ds_get_bts_index((void *)child->thread.ds_area_msr);
532}
533
534static int ptrace_bts_read_record(struct task_struct *child,
535 long index,
536 struct bts_struct __user *out)
537{
538 struct bts_struct ret;
539 int retval;
540 int bts_end;
541 int bts_index;
542
543 if (!child->thread.ds_area_msr)
544 return -ENXIO;
545
546 if (index < 0)
547 return -EINVAL;
548
549 bts_end = ds_get_bts_end((void *)child->thread.ds_area_msr);
550 if (bts_end <= index)
551 return -EINVAL;
552
553 /* translate the ptrace bts index into the ds bts index */
554 bts_index = ds_get_bts_index((void *)child->thread.ds_area_msr);
555 bts_index -= (index + 1);
556 if (bts_index < 0)
557 bts_index += bts_end;
558
559 retval = ds_read_bts((void *)child->thread.ds_area_msr,
560 bts_index, &ret);
561 if (retval < 0)
562 return retval;
563
564 if (copy_to_user(out, &ret, sizeof(ret)))
565 return -EFAULT;
566
567 return sizeof(ret);
568}
569
570static int ptrace_bts_write_record(struct task_struct *child,
571 const struct bts_struct *in)
572{
573 int retval;
574
575 if (!child->thread.ds_area_msr)
576 return -ENXIO;
577
578 retval = ds_write_bts((void *)child->thread.ds_area_msr, in);
579 if (retval)
580 return retval;
581
582 return sizeof(*in);
583}
584
585static int ptrace_bts_clear(struct task_struct *child)
586{
587 if (!child->thread.ds_area_msr)
588 return -ENXIO;
589
590 return ds_clear((void *)child->thread.ds_area_msr);
591}
592
593static int ptrace_bts_drain(struct task_struct *child,
594 long size,
595 struct bts_struct __user *out)
596{
597 int end, i;
598 void *ds = (void *)child->thread.ds_area_msr;
599
600 if (!ds)
601 return -ENXIO;
602
603 end = ds_get_bts_index(ds);
604 if (end <= 0)
605 return end;
606
607 if (size < (end * sizeof(struct bts_struct)))
608 return -EIO;
609
610 for (i = 0; i < end; i++, out++) {
611 struct bts_struct ret;
612 int retval;
613
614 retval = ds_read_bts(ds, i, &ret);
615 if (retval < 0)
616 return retval;
617
618 if (copy_to_user(out, &ret, sizeof(ret)))
619 return -EFAULT;
620 }
621
622 ds_clear(ds);
623
624 return end;
625}
626
627static int ptrace_bts_realloc(struct task_struct *child,
628 int size, int reduce_size)
629{
630 unsigned long rlim, vm;
631 int ret, old_size;
632
633 if (size < 0)
634 return -EINVAL;
635
636 old_size = ds_get_bts_size((void *)child->thread.ds_area_msr);
637 if (old_size < 0)
638 return old_size;
639
640 ret = ds_free((void **)&child->thread.ds_area_msr);
641 if (ret < 0)
642 goto out;
643
644 size >>= PAGE_SHIFT;
645 old_size >>= PAGE_SHIFT;
646
647 current->mm->total_vm -= old_size;
648 current->mm->locked_vm -= old_size;
649
650 if (size == 0)
651 goto out;
652
653 rlim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
654 vm = current->mm->total_vm + size;
655 if (rlim < vm) {
656 ret = -ENOMEM;
657
658 if (!reduce_size)
659 goto out;
660
661 size = rlim - current->mm->total_vm;
662 if (size <= 0)
663 goto out;
664 }
665
666 rlim = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
667 vm = current->mm->locked_vm + size;
668 if (rlim < vm) {
669 ret = -ENOMEM;
670
671 if (!reduce_size)
672 goto out;
673
674 size = rlim - current->mm->locked_vm;
675 if (size <= 0)
676 goto out;
677 }
678
679 ret = ds_allocate((void **)&child->thread.ds_area_msr,
680 size << PAGE_SHIFT);
681 if (ret < 0)
682 goto out;
683
684 current->mm->total_vm += size;
685 current->mm->locked_vm += size;
686
687out:
688 if (child->thread.ds_area_msr)
689 set_tsk_thread_flag(child, TIF_DS_AREA_MSR);
690 else
691 clear_tsk_thread_flag(child, TIF_DS_AREA_MSR);
692
693 return ret;
694}
695
696static int ptrace_bts_config(struct task_struct *child,
697 long cfg_size,
698 const struct ptrace_bts_config __user *ucfg)
699{
700 struct ptrace_bts_config cfg;
701 int bts_size, ret = 0;
702 void *ds;
703
704 if (cfg_size < sizeof(cfg))
705 return -EIO;
706
707 if (copy_from_user(&cfg, ucfg, sizeof(cfg)))
708 return -EFAULT;
709
710 if ((int)cfg.size < 0)
711 return -EINVAL;
712
713 bts_size = 0;
714 ds = (void *)child->thread.ds_area_msr;
715 if (ds) {
716 bts_size = ds_get_bts_size(ds);
717 if (bts_size < 0)
718 return bts_size;
719 }
720 cfg.size = PAGE_ALIGN(cfg.size);
721
722 if (bts_size != cfg.size) {
723 ret = ptrace_bts_realloc(child, cfg.size,
724 cfg.flags & PTRACE_BTS_O_CUT_SIZE);
725 if (ret < 0)
726 goto errout;
727
728 ds = (void *)child->thread.ds_area_msr;
729 }
730
731 if (cfg.flags & PTRACE_BTS_O_SIGNAL)
732 ret = ds_set_overflow(ds, DS_O_SIGNAL);
733 else
734 ret = ds_set_overflow(ds, DS_O_WRAP);
735 if (ret < 0)
736 goto errout;
737
738 if (cfg.flags & PTRACE_BTS_O_TRACE)
739 child->thread.debugctlmsr |= ds_debugctl_mask();
740 else
741 child->thread.debugctlmsr &= ~ds_debugctl_mask();
742
743 if (cfg.flags & PTRACE_BTS_O_SCHED)
744 set_tsk_thread_flag(child, TIF_BTS_TRACE_TS);
745 else
746 clear_tsk_thread_flag(child, TIF_BTS_TRACE_TS);
747
748 ret = sizeof(cfg);
749
750out:
751 if (child->thread.debugctlmsr)
752 set_tsk_thread_flag(child, TIF_DEBUGCTLMSR);
753 else
754 clear_tsk_thread_flag(child, TIF_DEBUGCTLMSR);
755
756 return ret;
757
758errout:
759 child->thread.debugctlmsr &= ~ds_debugctl_mask();
760 clear_tsk_thread_flag(child, TIF_BTS_TRACE_TS);
761 goto out;
762}
763
764static int ptrace_bts_status(struct task_struct *child,
765 long cfg_size,
766 struct ptrace_bts_config __user *ucfg)
767{
768 void *ds = (void *)child->thread.ds_area_msr;
769 struct ptrace_bts_config cfg;
770
771 if (cfg_size < sizeof(cfg))
772 return -EIO;
773
774 memset(&cfg, 0, sizeof(cfg));
775
776 if (ds) {
777 cfg.size = ds_get_bts_size(ds);
778
779 if (ds_get_overflow(ds) == DS_O_SIGNAL)
780 cfg.flags |= PTRACE_BTS_O_SIGNAL;
781
782 if (test_tsk_thread_flag(child, TIF_DEBUGCTLMSR) &&
783 child->thread.debugctlmsr & ds_debugctl_mask())
784 cfg.flags |= PTRACE_BTS_O_TRACE;
785
786 if (test_tsk_thread_flag(child, TIF_BTS_TRACE_TS))
787 cfg.flags |= PTRACE_BTS_O_SCHED;
788 }
789
790 cfg.bts_size = sizeof(struct bts_struct);
791
792 if (copy_to_user(ucfg, &cfg, sizeof(cfg)))
793 return -EFAULT;
794
795 return sizeof(cfg);
796}
797
798void ptrace_bts_take_timestamp(struct task_struct *tsk,
799 enum bts_qualifier qualifier)
800{
801 struct bts_struct rec = {
802 .qualifier = qualifier,
803 .variant.jiffies = jiffies_64
804 };
805
806 ptrace_bts_write_record(tsk, &rec);
807}
808
809/*
810 * Called by kernel/ptrace.c when detaching..
811 *
812 * Make sure the single step bit is not set.
813 */
814void ptrace_disable(struct task_struct *child)
815{
816 user_disable_single_step(child);
817#ifdef TIF_SYSCALL_EMU
818 clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
819#endif
820 if (child->thread.ds_area_msr) {
821 ptrace_bts_realloc(child, 0, 0);
822 child->thread.debugctlmsr &= ~ds_debugctl_mask();
823 if (!child->thread.debugctlmsr)
824 clear_tsk_thread_flag(child, TIF_DEBUGCTLMSR);
825 clear_tsk_thread_flag(child, TIF_BTS_TRACE_TS);
826 }
827}
828
829#if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION
830static const struct user_regset_view user_x86_32_view; /* Initialized below. */
831#endif
832
833long arch_ptrace(struct task_struct *child, long request, long addr, long data)
834{
835 int ret;
836 unsigned long __user *datap = (unsigned long __user *)data;
837
838 switch (request) {
839 /* read the word at location addr in the USER area. */
840 case PTRACE_PEEKUSR: {
841 unsigned long tmp;
842
843 ret = -EIO;
844 if ((addr & (sizeof(data) - 1)) || addr < 0 ||
845 addr >= sizeof(struct user))
846 break;
847
848 tmp = 0; /* Default return condition */
849 if (addr < sizeof(struct user_regs_struct))
850 tmp = getreg(child, addr);
851 else if (addr >= offsetof(struct user, u_debugreg[0]) &&
852 addr <= offsetof(struct user, u_debugreg[7])) {
853 addr -= offsetof(struct user, u_debugreg[0]);
854 tmp = ptrace_get_debugreg(child, addr / sizeof(data));
855 }
856 ret = put_user(tmp, datap);
857 break;
858 }
859
860 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
861 ret = -EIO;
862 if ((addr & (sizeof(data) - 1)) || addr < 0 ||
863 addr >= sizeof(struct user))
864 break;
865
866 if (addr < sizeof(struct user_regs_struct))
867 ret = putreg(child, addr, data);
868 else if (addr >= offsetof(struct user, u_debugreg[0]) &&
869 addr <= offsetof(struct user, u_debugreg[7])) {
870 addr -= offsetof(struct user, u_debugreg[0]);
871 ret = ptrace_set_debugreg(child,
872 addr / sizeof(data), data);
873 }
874 break;
875
876 case PTRACE_GETREGS: /* Get all gp regs from the child. */
877 return copy_regset_to_user(child,
878 task_user_regset_view(current),
879 REGSET_GENERAL,
880 0, sizeof(struct user_regs_struct),
881 datap);
882
883 case PTRACE_SETREGS: /* Set all gp regs in the child. */
884 return copy_regset_from_user(child,
885 task_user_regset_view(current),
886 REGSET_GENERAL,
887 0, sizeof(struct user_regs_struct),
888 datap);
889
890 case PTRACE_GETFPREGS: /* Get the child FPU state. */
891 return copy_regset_to_user(child,
892 task_user_regset_view(current),
893 REGSET_FP,
894 0, sizeof(struct user_i387_struct),
895 datap);
896
897 case PTRACE_SETFPREGS: /* Set the child FPU state. */
898 return copy_regset_from_user(child,
899 task_user_regset_view(current),
900 REGSET_FP,
901 0, sizeof(struct user_i387_struct),
902 datap);
903
904#ifdef CONFIG_X86_32
905 case PTRACE_GETFPXREGS: /* Get the child extended FPU state. */
906 return copy_regset_to_user(child, &user_x86_32_view,
907 REGSET_XFP,
908 0, sizeof(struct user_fxsr_struct),
909 datap);
910
911 case PTRACE_SETFPXREGS: /* Set the child extended FPU state. */
912 return copy_regset_from_user(child, &user_x86_32_view,
913 REGSET_XFP,
914 0, sizeof(struct user_fxsr_struct),
915 datap);
916#endif
917
918#if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION
919 case PTRACE_GET_THREAD_AREA:
920 if (addr < 0)
921 return -EIO;
922 ret = do_get_thread_area(child, addr,
923 (struct user_desc __user *) data);
924 break;
925
926 case PTRACE_SET_THREAD_AREA:
927 if (addr < 0)
928 return -EIO;
929 ret = do_set_thread_area(child, addr,
930 (struct user_desc __user *) data, 0);
931 break;
932#endif
933
934#ifdef CONFIG_X86_64
935 /* normal 64bit interface to access TLS data.
936 Works just like arch_prctl, except that the arguments
937 are reversed. */
938 case PTRACE_ARCH_PRCTL:
939 ret = do_arch_prctl(child, data, addr);
940 break;
941#endif
942
943 case PTRACE_BTS_CONFIG:
944 ret = ptrace_bts_config
945 (child, data, (struct ptrace_bts_config __user *)addr);
946 break;
947
948 case PTRACE_BTS_STATUS:
949 ret = ptrace_bts_status
950 (child, data, (struct ptrace_bts_config __user *)addr);
951 break;
952
953 case PTRACE_BTS_SIZE:
954 ret = ptrace_bts_get_size(child);
955 break;
956
957 case PTRACE_BTS_GET:
958 ret = ptrace_bts_read_record
959 (child, data, (struct bts_struct __user *) addr);
960 break;
961
962 case PTRACE_BTS_CLEAR:
963 ret = ptrace_bts_clear(child);
964 break;
965
966 case PTRACE_BTS_DRAIN:
967 ret = ptrace_bts_drain
968 (child, data, (struct bts_struct __user *) addr);
969 break;
970
971 default:
972 ret = ptrace_request(child, request, addr, data);
973 break;
974 }
975
976 return ret;
977}
978
979#ifdef CONFIG_IA32_EMULATION
980
981#include <linux/compat.h>
982#include <linux/syscalls.h>
983#include <asm/ia32.h>
984#include <asm/user32.h>
985
986#define R32(l,q) \
987 case offsetof(struct user32, regs.l): \
988 regs->q = value; break
989
990#define SEG32(rs) \
991 case offsetof(struct user32, regs.rs): \
992 return set_segment_reg(child, \
993 offsetof(struct user_regs_struct, rs), \
994 value); \
995 break
996
997static int putreg32(struct task_struct *child, unsigned regno, u32 value)
998{
999 struct pt_regs *regs = task_pt_regs(child);
1000
1001 switch (regno) {
1002
1003 SEG32(cs);
1004 SEG32(ds);
1005 SEG32(es);
1006 SEG32(fs);
1007 SEG32(gs);
1008 SEG32(ss);
1009
1010 R32(ebx, bx);
1011 R32(ecx, cx);
1012 R32(edx, dx);
1013 R32(edi, di);
1014 R32(esi, si);
1015 R32(ebp, bp);
1016 R32(eax, ax);
1017 R32(orig_eax, orig_ax);
1018 R32(eip, ip);
1019 R32(esp, sp);
1020
1021 case offsetof(struct user32, regs.eflags):
1022 return set_flags(child, value);
1023
1024 case offsetof(struct user32, u_debugreg[0]) ...
1025 offsetof(struct user32, u_debugreg[7]):
1026 regno -= offsetof(struct user32, u_debugreg[0]);
1027 return ptrace_set_debugreg(child, regno / 4, value);
1028
1029 default:
1030 if (regno > sizeof(struct user32) || (regno & 3))
1031 return -EIO;
1032
1033 /*
1034 * Other dummy fields in the virtual user structure
1035 * are ignored
1036 */
1037 break;
1038 }
1039 return 0;
1040}
1041
1042#undef R32
1043#undef SEG32
1044
1045#define R32(l,q) \
1046 case offsetof(struct user32, regs.l): \
1047 *val = regs->q; break
1048
1049#define SEG32(rs) \
1050 case offsetof(struct user32, regs.rs): \
1051 *val = get_segment_reg(child, \
1052 offsetof(struct user_regs_struct, rs)); \
1053 break
1054
1055static int getreg32(struct task_struct *child, unsigned regno, u32 *val)
1056{
1057 struct pt_regs *regs = task_pt_regs(child);
1058
1059 switch (regno) {
1060
1061 SEG32(ds);
1062 SEG32(es);
1063 SEG32(fs);
1064 SEG32(gs);
1065
1066 R32(cs, cs);
1067 R32(ss, ss);
1068 R32(ebx, bx);
1069 R32(ecx, cx);
1070 R32(edx, dx);
1071 R32(edi, di);
1072 R32(esi, si);
1073 R32(ebp, bp);
1074 R32(eax, ax);
1075 R32(orig_eax, orig_ax);
1076 R32(eip, ip);
1077 R32(esp, sp);
1078
1079 case offsetof(struct user32, regs.eflags):
1080 *val = get_flags(child);
1081 break;
1082
1083 case offsetof(struct user32, u_debugreg[0]) ...
1084 offsetof(struct user32, u_debugreg[7]):
1085 regno -= offsetof(struct user32, u_debugreg[0]);
1086 *val = ptrace_get_debugreg(child, regno / 4);
1087 break;
1088
1089 default:
1090 if (regno > sizeof(struct user32) || (regno & 3))
1091 return -EIO;
1092
1093 /*
1094 * Other dummy fields in the virtual user structure
1095 * are ignored
1096 */
1097 *val = 0;
1098 break;
1099 }
1100 return 0;
1101}
1102
1103#undef R32
1104#undef SEG32
1105
1106static int genregs32_get(struct task_struct *target,
1107 const struct user_regset *regset,
1108 unsigned int pos, unsigned int count,
1109 void *kbuf, void __user *ubuf)
1110{
1111 if (kbuf) {
1112 compat_ulong_t *k = kbuf;
1113 while (count > 0) {
1114 getreg32(target, pos, k++);
1115 count -= sizeof(*k);
1116 pos += sizeof(*k);
1117 }
1118 } else {
1119 compat_ulong_t __user *u = ubuf;
1120 while (count > 0) {
1121 compat_ulong_t word;
1122 getreg32(target, pos, &word);
1123 if (__put_user(word, u++))
1124 return -EFAULT;
1125 count -= sizeof(*u);
1126 pos += sizeof(*u);
1127 }
1128 }
1129
1130 return 0;
1131}
1132
1133static int genregs32_set(struct task_struct *target,
1134 const struct user_regset *regset,
1135 unsigned int pos, unsigned int count,
1136 const void *kbuf, const void __user *ubuf)
1137{
1138 int ret = 0;
1139 if (kbuf) {
1140 const compat_ulong_t *k = kbuf;
1141 while (count > 0 && !ret) {
1142 ret = putreg(target, pos, *k++);
1143 count -= sizeof(*k);
1144 pos += sizeof(*k);
1145 }
1146 } else {
1147 const compat_ulong_t __user *u = ubuf;
1148 while (count > 0 && !ret) {
1149 compat_ulong_t word;
1150 ret = __get_user(word, u++);
1151 if (ret)
1152 break;
1153 ret = putreg(target, pos, word);
1154 count -= sizeof(*u);
1155 pos += sizeof(*u);
1156 }
1157 }
1158 return ret;
1159}
1160
1161static long ptrace32_siginfo(unsigned request, u32 pid, u32 addr, u32 data)
1162{
1163 siginfo_t __user *si = compat_alloc_user_space(sizeof(siginfo_t));
1164 compat_siginfo_t __user *si32 = compat_ptr(data);
1165 siginfo_t ssi;
1166 int ret;
1167
1168 if (request == PTRACE_SETSIGINFO) {
1169 memset(&ssi, 0, sizeof(siginfo_t));
1170 ret = copy_siginfo_from_user32(&ssi, si32);
1171 if (ret)
1172 return ret;
1173 if (copy_to_user(si, &ssi, sizeof(siginfo_t)))
1174 return -EFAULT;
1175 }
1176 ret = sys_ptrace(request, pid, addr, (unsigned long)si);
1177 if (ret)
1178 return ret;
1179 if (request == PTRACE_GETSIGINFO) {
1180 if (copy_from_user(&ssi, si, sizeof(siginfo_t)))
1181 return -EFAULT;
1182 ret = copy_siginfo_to_user32(si32, &ssi);
1183 }
1184 return ret;
1185}
1186
1187asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
1188{
1189 struct task_struct *child;
1190 struct pt_regs *childregs;
1191 void __user *datap = compat_ptr(data);
1192 int ret;
1193 __u32 val;
1194
1195 switch (request) {
1196 case PTRACE_TRACEME:
1197 case PTRACE_ATTACH:
1198 case PTRACE_KILL:
1199 case PTRACE_CONT:
1200 case PTRACE_SINGLESTEP:
1201 case PTRACE_SINGLEBLOCK:
1202 case PTRACE_DETACH:
1203 case PTRACE_SYSCALL:
1204 case PTRACE_OLDSETOPTIONS:
1205 case PTRACE_SETOPTIONS:
1206 case PTRACE_SET_THREAD_AREA:
1207 case PTRACE_GET_THREAD_AREA:
1208 case PTRACE_BTS_CONFIG:
1209 case PTRACE_BTS_STATUS:
1210 case PTRACE_BTS_SIZE:
1211 case PTRACE_BTS_GET:
1212 case PTRACE_BTS_CLEAR:
1213 case PTRACE_BTS_DRAIN:
1214 return sys_ptrace(request, pid, addr, data);
1215
1216 default:
1217 return -EINVAL;
1218
1219 case PTRACE_PEEKTEXT:
1220 case PTRACE_PEEKDATA:
1221 case PTRACE_POKEDATA:
1222 case PTRACE_POKETEXT:
1223 case PTRACE_POKEUSR:
1224 case PTRACE_PEEKUSR:
1225 case PTRACE_GETREGS:
1226 case PTRACE_SETREGS:
1227 case PTRACE_SETFPREGS:
1228 case PTRACE_GETFPREGS:
1229 case PTRACE_SETFPXREGS:
1230 case PTRACE_GETFPXREGS:
1231 case PTRACE_GETEVENTMSG:
1232 break;
1233
1234 case PTRACE_SETSIGINFO:
1235 case PTRACE_GETSIGINFO:
1236 return ptrace32_siginfo(request, pid, addr, data);
1237 }
1238
1239 child = ptrace_get_task_struct(pid);
1240 if (IS_ERR(child))
1241 return PTR_ERR(child);
1242
1243 ret = ptrace_check_attach(child, request == PTRACE_KILL);
1244 if (ret < 0)
1245 goto out;
1246
1247 childregs = task_pt_regs(child);
1248
1249 switch (request) {
1250 case PTRACE_PEEKUSR:
1251 ret = getreg32(child, addr, &val);
1252 if (ret == 0)
1253 ret = put_user(val, (__u32 __user *)datap);
1254 break;
1255
1256 case PTRACE_POKEUSR:
1257 ret = putreg32(child, addr, data);
1258 break;
1259
1260 case PTRACE_GETREGS: /* Get all gp regs from the child. */
1261 return copy_regset_to_user(child, &user_x86_32_view,
1262 REGSET_GENERAL,
1263 0, sizeof(struct user_regs_struct32),
1264 datap);
1265
1266 case PTRACE_SETREGS: /* Set all gp regs in the child. */
1267 return copy_regset_from_user(child, &user_x86_32_view,
1268 REGSET_GENERAL, 0,
1269 sizeof(struct user_regs_struct32),
1270 datap);
1271
1272 case PTRACE_GETFPREGS: /* Get the child FPU state. */
1273 return copy_regset_to_user(child, &user_x86_32_view,
1274 REGSET_FP, 0,
1275 sizeof(struct user_i387_ia32_struct),
1276 datap);
1277
1278 case PTRACE_SETFPREGS: /* Set the child FPU state. */
1279 return copy_regset_from_user(
1280 child, &user_x86_32_view, REGSET_FP,
1281 0, sizeof(struct user_i387_ia32_struct), datap);
1282
1283 case PTRACE_GETFPXREGS: /* Get the child extended FPU state. */
1284 return copy_regset_to_user(child, &user_x86_32_view,
1285 REGSET_XFP, 0,
1286 sizeof(struct user32_fxsr_struct),
1287 datap);
1288
1289 case PTRACE_SETFPXREGS: /* Set the child extended FPU state. */
1290 return copy_regset_from_user(child, &user_x86_32_view,
1291 REGSET_XFP, 0,
1292 sizeof(struct user32_fxsr_struct),
1293 datap);
1294
1295 default:
1296 return compat_ptrace_request(child, request, addr, data);
1297 }
1298
1299 out:
1300 put_task_struct(child);
1301 return ret;
1302}
1303
1304#endif /* CONFIG_IA32_EMULATION */
1305
1306#ifdef CONFIG_X86_64
1307
1308static const struct user_regset x86_64_regsets[] = {
1309 [REGSET_GENERAL] = {
1310 .core_note_type = NT_PRSTATUS,
1311 .n = sizeof(struct user_regs_struct) / sizeof(long),
1312 .size = sizeof(long), .align = sizeof(long),
1313 .get = genregs_get, .set = genregs_set
1314 },
1315 [REGSET_FP] = {
1316 .core_note_type = NT_PRFPREG,
1317 .n = sizeof(struct user_i387_struct) / sizeof(long),
1318 .size = sizeof(long), .align = sizeof(long),
1319 .active = xfpregs_active, .get = xfpregs_get, .set = xfpregs_set
1320 },
1321};
1322
1323static const struct user_regset_view user_x86_64_view = {
1324 .name = "x86_64", .e_machine = EM_X86_64,
1325 .regsets = x86_64_regsets, .n = ARRAY_SIZE(x86_64_regsets)
1326};
1327
1328#else /* CONFIG_X86_32 */
1329
1330#define user_regs_struct32 user_regs_struct
1331#define genregs32_get genregs_get
1332#define genregs32_set genregs_set
1333
1334#endif /* CONFIG_X86_64 */
1335
1336#if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION
1337static const struct user_regset x86_32_regsets[] = {
1338 [REGSET_GENERAL] = {
1339 .core_note_type = NT_PRSTATUS,
1340 .n = sizeof(struct user_regs_struct32) / sizeof(u32),
1341 .size = sizeof(u32), .align = sizeof(u32),
1342 .get = genregs32_get, .set = genregs32_set
1343 },
1344 [REGSET_FP] = {
1345 .core_note_type = NT_PRFPREG,
1346 .n = sizeof(struct user_i387_struct) / sizeof(u32),
1347 .size = sizeof(u32), .align = sizeof(u32),
1348 .active = fpregs_active, .get = fpregs_get, .set = fpregs_set
1349 },
1350 [REGSET_XFP] = {
1351 .core_note_type = NT_PRXFPREG,
1352 .n = sizeof(struct user_i387_struct) / sizeof(u32),
1353 .size = sizeof(u32), .align = sizeof(u32),
1354 .active = xfpregs_active, .get = xfpregs_get, .set = xfpregs_set
1355 },
1356 [REGSET_TLS] = {
1357 .core_note_type = NT_386_TLS,
1358 .n = GDT_ENTRY_TLS_ENTRIES, .bias = GDT_ENTRY_TLS_MIN,
1359 .size = sizeof(struct user_desc),
1360 .align = sizeof(struct user_desc),
1361 .active = regset_tls_active,
1362 .get = regset_tls_get, .set = regset_tls_set
1363 },
1364};
1365
1366static const struct user_regset_view user_x86_32_view = {
1367 .name = "i386", .e_machine = EM_386,
1368 .regsets = x86_32_regsets, .n = ARRAY_SIZE(x86_32_regsets)
1369};
1370#endif
1371
1372const struct user_regset_view *task_user_regset_view(struct task_struct *task)
1373{
1374#ifdef CONFIG_IA32_EMULATION
1375 if (test_tsk_thread_flag(task, TIF_IA32))
1376#endif
1377#if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION
1378 return &user_x86_32_view;
1379#endif
1380#ifdef CONFIG_X86_64
1381 return &user_x86_64_view;
1382#endif
1383}
1384
1385#ifdef CONFIG_X86_32
1386
1387void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
1388{
1389 struct siginfo info;
1390
1391 tsk->thread.trap_no = 1;
1392 tsk->thread.error_code = error_code;
1393
1394 memset(&info, 0, sizeof(info));
1395 info.si_signo = SIGTRAP;
1396 info.si_code = TRAP_BRKPT;
1397
1398 /* User-mode ip? */
1399 info.si_addr = user_mode_vm(regs) ? (void __user *) regs->ip : NULL;
1400
1401 /* Send us the fake SIGTRAP */
1402 force_sig_info(SIGTRAP, &info, tsk);
1403}
1404
1405/* notification of system call entry/exit
1406 * - triggered by current->work.syscall_trace
1407 */
1408__attribute__((regparm(3)))
1409int do_syscall_trace(struct pt_regs *regs, int entryexit)
1410{
1411 int is_sysemu = test_thread_flag(TIF_SYSCALL_EMU);
1412 /*
1413 * With TIF_SYSCALL_EMU set we want to ignore TIF_SINGLESTEP for syscall
1414 * interception
1415 */
1416 int is_singlestep = !is_sysemu && test_thread_flag(TIF_SINGLESTEP);
1417 int ret = 0;
1418
1419 /* do the secure computing check first */
1420 if (!entryexit)
1421 secure_computing(regs->orig_ax);
1422
1423 if (unlikely(current->audit_context)) {
1424 if (entryexit)
1425 audit_syscall_exit(AUDITSC_RESULT(regs->ax),
1426 regs->ax);
1427 /* Debug traps, when using PTRACE_SINGLESTEP, must be sent only
1428 * on the syscall exit path. Normally, when TIF_SYSCALL_AUDIT is
1429 * not used, entry.S will call us only on syscall exit, not
1430 * entry; so when TIF_SYSCALL_AUDIT is used we must avoid
1431 * calling send_sigtrap() on syscall entry.
1432 *
1433 * Note that when PTRACE_SYSEMU_SINGLESTEP is used,
1434 * is_singlestep is false, despite his name, so we will still do
1435 * the correct thing.
1436 */
1437 else if (is_singlestep)
1438 goto out;
1439 }
1440
1441 if (!(current->ptrace & PT_PTRACED))
1442 goto out;
1443
1444 /* If a process stops on the 1st tracepoint with SYSCALL_TRACE
1445 * and then is resumed with SYSEMU_SINGLESTEP, it will come in
1446 * here. We have to check this and return */
1447 if (is_sysemu && entryexit)
1448 return 0;
1449
1450 /* Fake a debug trap */
1451 if (is_singlestep)
1452 send_sigtrap(current, regs, 0);
1453
1454 if (!test_thread_flag(TIF_SYSCALL_TRACE) && !is_sysemu)
1455 goto out;
1456
1457 /* the 0x80 provides a way for the tracing parent to distinguish
1458 between a syscall stop and SIGTRAP delivery */
1459 /* Note that the debugger could change the result of test_thread_flag!*/
1460 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ? 0x80:0));
1461
1462 /*
1463 * this isn't the same as continuing with a signal, but it will do
1464 * for normal use. strace only continues with a signal if the
1465 * stopping signal is not SIGTRAP. -brl
1466 */
1467 if (current->exit_code) {
1468 send_sig(current->exit_code, current, 1);
1469 current->exit_code = 0;
1470 }
1471 ret = is_sysemu;
1472out:
1473 if (unlikely(current->audit_context) && !entryexit)
1474 audit_syscall_entry(AUDIT_ARCH_I386, regs->orig_ax,
1475 regs->bx, regs->cx, regs->dx, regs->si);
1476 if (ret == 0)
1477 return 0;
1478
1479 regs->orig_ax = -1; /* force skip of syscall restarting */
1480 if (unlikely(current->audit_context))
1481 audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax);
1482 return 1;
1483}
1484
1485#else /* CONFIG_X86_64 */
1486
1487static void syscall_trace(struct pt_regs *regs)
1488{
1489
1490#if 0
1491 printk("trace %s ip %lx sp %lx ax %d origrax %d caller %lx tiflags %x ptrace %x\n",
1492 current->comm,
1493 regs->ip, regs->sp, regs->ax, regs->orig_ax, __builtin_return_address(0),
1494 current_thread_info()->flags, current->ptrace);
1495#endif
1496
1497 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
1498 ? 0x80 : 0));
1499 /*
1500 * this isn't the same as continuing with a signal, but it will do
1501 * for normal use. strace only continues with a signal if the
1502 * stopping signal is not SIGTRAP. -brl
1503 */
1504 if (current->exit_code) {
1505 send_sig(current->exit_code, current, 1);
1506 current->exit_code = 0;
1507 }
1508}
1509
1510asmlinkage void syscall_trace_enter(struct pt_regs *regs)
1511{
1512 /* do the secure computing check first */
1513 secure_computing(regs->orig_ax);
1514
1515 if (test_thread_flag(TIF_SYSCALL_TRACE)
1516 && (current->ptrace & PT_PTRACED))
1517 syscall_trace(regs);
1518
1519 if (unlikely(current->audit_context)) {
1520 if (test_thread_flag(TIF_IA32)) {
1521 audit_syscall_entry(AUDIT_ARCH_I386,
1522 regs->orig_ax,
1523 regs->bx, regs->cx,
1524 regs->dx, regs->si);
1525 } else {
1526 audit_syscall_entry(AUDIT_ARCH_X86_64,
1527 regs->orig_ax,
1528 regs->di, regs->si,
1529 regs->dx, regs->r10);
1530 }
1531 }
1532}
1533
1534asmlinkage void syscall_trace_leave(struct pt_regs *regs)
1535{
1536 if (unlikely(current->audit_context))
1537 audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax);
1538
1539 if ((test_thread_flag(TIF_SYSCALL_TRACE)
1540 || test_thread_flag(TIF_SINGLESTEP))
1541 && (current->ptrace & PT_PTRACED))
1542 syscall_trace(regs);
1543}
1544
1545#endif /* CONFIG_X86_32 */
diff --git a/arch/x86/kernel/ptrace_32.c b/arch/x86/kernel/ptrace_32.c
deleted file mode 100644
index ff5431cc03ee..000000000000
--- a/arch/x86/kernel/ptrace_32.c
+++ /dev/null
@@ -1,717 +0,0 @@
1/* By Ross Biro 1/23/92 */
2/*
3 * Pentium III FXSR, SSE support
4 * Gareth Hughes <gareth@valinux.com>, May 2000
5 */
6
7#include <linux/kernel.h>
8#include <linux/sched.h>
9#include <linux/mm.h>
10#include <linux/smp.h>
11#include <linux/errno.h>
12#include <linux/ptrace.h>
13#include <linux/user.h>
14#include <linux/security.h>
15#include <linux/audit.h>
16#include <linux/seccomp.h>
17#include <linux/signal.h>
18
19#include <asm/uaccess.h>
20#include <asm/pgtable.h>
21#include <asm/system.h>
22#include <asm/processor.h>
23#include <asm/i387.h>
24#include <asm/debugreg.h>
25#include <asm/ldt.h>
26#include <asm/desc.h>
27
28/*
29 * does not yet catch signals sent when the child dies.
30 * in exit.c or in signal.c.
31 */
32
33/*
34 * Determines which flags the user has access to [1 = access, 0 = no access].
35 * Prohibits changing ID(21), VIP(20), VIF(19), VM(17), NT(14), IOPL(12-13), IF(9).
36 * Also masks reserved bits (31-22, 15, 5, 3, 1).
37 */
38#define FLAG_MASK 0x00050dd5
39
40/* set's the trap flag. */
41#define TRAP_FLAG 0x100
42
43/*
44 * Offset of eflags on child stack..
45 */
46#define EFL_OFFSET offsetof(struct pt_regs, eflags)
47
48static inline struct pt_regs *get_child_regs(struct task_struct *task)
49{
50 void *stack_top = (void *)task->thread.esp0;
51 return stack_top - sizeof(struct pt_regs);
52}
53
54/*
55 * This routine will get a word off of the processes privileged stack.
56 * the offset is bytes into the pt_regs structure on the stack.
57 * This routine assumes that all the privileged stacks are in our
58 * data space.
59 */
60static inline int get_stack_long(struct task_struct *task, int offset)
61{
62 unsigned char *stack;
63
64 stack = (unsigned char *)task->thread.esp0 - sizeof(struct pt_regs);
65 stack += offset;
66 return (*((int *)stack));
67}
68
69/*
70 * This routine will put a word on the processes privileged stack.
71 * the offset is bytes into the pt_regs structure on the stack.
72 * This routine assumes that all the privileged stacks are in our
73 * data space.
74 */
75static inline int put_stack_long(struct task_struct *task, int offset,
76 unsigned long data)
77{
78 unsigned char * stack;
79
80 stack = (unsigned char *)task->thread.esp0 - sizeof(struct pt_regs);
81 stack += offset;
82 *(unsigned long *) stack = data;
83 return 0;
84}
85
86static int putreg(struct task_struct *child,
87 unsigned long regno, unsigned long value)
88{
89 switch (regno >> 2) {
90 case GS:
91 if (value && (value & 3) != 3)
92 return -EIO;
93 child->thread.gs = value;
94 return 0;
95 case DS:
96 case ES:
97 case FS:
98 if (value && (value & 3) != 3)
99 return -EIO;
100 value &= 0xffff;
101 break;
102 case SS:
103 case CS:
104 if ((value & 3) != 3)
105 return -EIO;
106 value &= 0xffff;
107 break;
108 case EFL:
109 value &= FLAG_MASK;
110 value |= get_stack_long(child, EFL_OFFSET) & ~FLAG_MASK;
111 break;
112 }
113 if (regno > FS*4)
114 regno -= 1*4;
115 put_stack_long(child, regno, value);
116 return 0;
117}
118
119static unsigned long getreg(struct task_struct *child,
120 unsigned long regno)
121{
122 unsigned long retval = ~0UL;
123
124 switch (regno >> 2) {
125 case GS:
126 retval = child->thread.gs;
127 break;
128 case DS:
129 case ES:
130 case FS:
131 case SS:
132 case CS:
133 retval = 0xffff;
134 /* fall through */
135 default:
136 if (regno > FS*4)
137 regno -= 1*4;
138 retval &= get_stack_long(child, regno);
139 }
140 return retval;
141}
142
143#define LDT_SEGMENT 4
144
145static unsigned long convert_eip_to_linear(struct task_struct *child, struct pt_regs *regs)
146{
147 unsigned long addr, seg;
148
149 addr = regs->eip;
150 seg = regs->xcs & 0xffff;
151 if (regs->eflags & VM_MASK) {
152 addr = (addr & 0xffff) + (seg << 4);
153 return addr;
154 }
155
156 /*
157 * We'll assume that the code segments in the GDT
158 * are all zero-based. That is largely true: the
159 * TLS segments are used for data, and the PNPBIOS
160 * and APM bios ones we just ignore here.
161 */
162 if (seg & LDT_SEGMENT) {
163 u32 *desc;
164 unsigned long base;
165
166 seg &= ~7UL;
167
168 mutex_lock(&child->mm->context.lock);
169 if (unlikely((seg >> 3) >= child->mm->context.size))
170 addr = -1L; /* bogus selector, access would fault */
171 else {
172 desc = child->mm->context.ldt + seg;
173 base = ((desc[0] >> 16) |
174 ((desc[1] & 0xff) << 16) |
175 (desc[1] & 0xff000000));
176
177 /* 16-bit code segment? */
178 if (!((desc[1] >> 22) & 1))
179 addr &= 0xffff;
180 addr += base;
181 }
182 mutex_unlock(&child->mm->context.lock);
183 }
184 return addr;
185}
186
187static inline int is_setting_trap_flag(struct task_struct *child, struct pt_regs *regs)
188{
189 int i, copied;
190 unsigned char opcode[15];
191 unsigned long addr = convert_eip_to_linear(child, regs);
192
193 copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
194 for (i = 0; i < copied; i++) {
195 switch (opcode[i]) {
196 /* popf and iret */
197 case 0x9d: case 0xcf:
198 return 1;
199 /* opcode and address size prefixes */
200 case 0x66: case 0x67:
201 continue;
202 /* irrelevant prefixes (segment overrides and repeats) */
203 case 0x26: case 0x2e:
204 case 0x36: case 0x3e:
205 case 0x64: case 0x65:
206 case 0xf0: case 0xf2: case 0xf3:
207 continue;
208
209 /*
210 * pushf: NOTE! We should probably not let
211 * the user see the TF bit being set. But
212 * it's more pain than it's worth to avoid
213 * it, and a debugger could emulate this
214 * all in user space if it _really_ cares.
215 */
216 case 0x9c:
217 default:
218 return 0;
219 }
220 }
221 return 0;
222}
223
224static void set_singlestep(struct task_struct *child)
225{
226 struct pt_regs *regs = get_child_regs(child);
227
228 /*
229 * Always set TIF_SINGLESTEP - this guarantees that
230 * we single-step system calls etc.. This will also
231 * cause us to set TF when returning to user mode.
232 */
233 set_tsk_thread_flag(child, TIF_SINGLESTEP);
234
235 /*
236 * If TF was already set, don't do anything else
237 */
238 if (regs->eflags & TRAP_FLAG)
239 return;
240
241 /* Set TF on the kernel stack.. */
242 regs->eflags |= TRAP_FLAG;
243
244 /*
245 * ..but if TF is changed by the instruction we will trace,
246 * don't mark it as being "us" that set it, so that we
247 * won't clear it by hand later.
248 */
249 if (is_setting_trap_flag(child, regs))
250 return;
251
252 child->ptrace |= PT_DTRACE;
253}
254
255static void clear_singlestep(struct task_struct *child)
256{
257 /* Always clear TIF_SINGLESTEP... */
258 clear_tsk_thread_flag(child, TIF_SINGLESTEP);
259
260 /* But touch TF only if it was set by us.. */
261 if (child->ptrace & PT_DTRACE) {
262 struct pt_regs *regs = get_child_regs(child);
263 regs->eflags &= ~TRAP_FLAG;
264 child->ptrace &= ~PT_DTRACE;
265 }
266}
267
268/*
269 * Called by kernel/ptrace.c when detaching..
270 *
271 * Make sure the single step bit is not set.
272 */
273void ptrace_disable(struct task_struct *child)
274{
275 clear_singlestep(child);
276 clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
277}
278
279/*
280 * Perform get_thread_area on behalf of the traced child.
281 */
282static int
283ptrace_get_thread_area(struct task_struct *child,
284 int idx, struct user_desc __user *user_desc)
285{
286 struct user_desc info;
287 struct desc_struct *desc;
288
289/*
290 * Get the current Thread-Local Storage area:
291 */
292
293#define GET_BASE(desc) ( \
294 (((desc)->a >> 16) & 0x0000ffff) | \
295 (((desc)->b << 16) & 0x00ff0000) | \
296 ( (desc)->b & 0xff000000) )
297
298#define GET_LIMIT(desc) ( \
299 ((desc)->a & 0x0ffff) | \
300 ((desc)->b & 0xf0000) )
301
302#define GET_32BIT(desc) (((desc)->b >> 22) & 1)
303#define GET_CONTENTS(desc) (((desc)->b >> 10) & 3)
304#define GET_WRITABLE(desc) (((desc)->b >> 9) & 1)
305#define GET_LIMIT_PAGES(desc) (((desc)->b >> 23) & 1)
306#define GET_PRESENT(desc) (((desc)->b >> 15) & 1)
307#define GET_USEABLE(desc) (((desc)->b >> 20) & 1)
308
309 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
310 return -EINVAL;
311
312 desc = child->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
313
314 info.entry_number = idx;
315 info.base_addr = GET_BASE(desc);
316 info.limit = GET_LIMIT(desc);
317 info.seg_32bit = GET_32BIT(desc);
318 info.contents = GET_CONTENTS(desc);
319 info.read_exec_only = !GET_WRITABLE(desc);
320 info.limit_in_pages = GET_LIMIT_PAGES(desc);
321 info.seg_not_present = !GET_PRESENT(desc);
322 info.useable = GET_USEABLE(desc);
323
324 if (copy_to_user(user_desc, &info, sizeof(info)))
325 return -EFAULT;
326
327 return 0;
328}
329
330/*
331 * Perform set_thread_area on behalf of the traced child.
332 */
333static int
334ptrace_set_thread_area(struct task_struct *child,
335 int idx, struct user_desc __user *user_desc)
336{
337 struct user_desc info;
338 struct desc_struct *desc;
339
340 if (copy_from_user(&info, user_desc, sizeof(info)))
341 return -EFAULT;
342
343 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
344 return -EINVAL;
345
346 desc = child->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
347 if (LDT_empty(&info)) {
348 desc->a = 0;
349 desc->b = 0;
350 } else {
351 desc->a = LDT_entry_a(&info);
352 desc->b = LDT_entry_b(&info);
353 }
354
355 return 0;
356}
357
358long arch_ptrace(struct task_struct *child, long request, long addr, long data)
359{
360 struct user * dummy = NULL;
361 int i, ret;
362 unsigned long __user *datap = (unsigned long __user *)data;
363
364 switch (request) {
365 /* when I and D space are separate, these will need to be fixed. */
366 case PTRACE_PEEKTEXT: /* read word at location addr. */
367 case PTRACE_PEEKDATA:
368 ret = generic_ptrace_peekdata(child, addr, data);
369 break;
370
371 /* read the word at location addr in the USER area. */
372 case PTRACE_PEEKUSR: {
373 unsigned long tmp;
374
375 ret = -EIO;
376 if ((addr & 3) || addr < 0 ||
377 addr > sizeof(struct user) - 3)
378 break;
379
380 tmp = 0; /* Default return condition */
381 if(addr < FRAME_SIZE*sizeof(long))
382 tmp = getreg(child, addr);
383 if(addr >= (long) &dummy->u_debugreg[0] &&
384 addr <= (long) &dummy->u_debugreg[7]){
385 addr -= (long) &dummy->u_debugreg[0];
386 addr = addr >> 2;
387 tmp = child->thread.debugreg[addr];
388 }
389 ret = put_user(tmp, datap);
390 break;
391 }
392
393 /* when I and D space are separate, this will have to be fixed. */
394 case PTRACE_POKETEXT: /* write the word at location addr. */
395 case PTRACE_POKEDATA:
396 ret = generic_ptrace_pokedata(child, addr, data);
397 break;
398
399 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
400 ret = -EIO;
401 if ((addr & 3) || addr < 0 ||
402 addr > sizeof(struct user) - 3)
403 break;
404
405 if (addr < FRAME_SIZE*sizeof(long)) {
406 ret = putreg(child, addr, data);
407 break;
408 }
409 /* We need to be very careful here. We implicitly
410 want to modify a portion of the task_struct, and we
411 have to be selective about what portions we allow someone
412 to modify. */
413
414 ret = -EIO;
415 if(addr >= (long) &dummy->u_debugreg[0] &&
416 addr <= (long) &dummy->u_debugreg[7]){
417
418 if(addr == (long) &dummy->u_debugreg[4]) break;
419 if(addr == (long) &dummy->u_debugreg[5]) break;
420 if(addr < (long) &dummy->u_debugreg[4] &&
421 ((unsigned long) data) >= TASK_SIZE-3) break;
422
423 /* Sanity-check data. Take one half-byte at once with
424 * check = (val >> (16 + 4*i)) & 0xf. It contains the
425 * R/Wi and LENi bits; bits 0 and 1 are R/Wi, and bits
426 * 2 and 3 are LENi. Given a list of invalid values,
427 * we do mask |= 1 << invalid_value, so that
428 * (mask >> check) & 1 is a correct test for invalid
429 * values.
430 *
431 * R/Wi contains the type of the breakpoint /
432 * watchpoint, LENi contains the length of the watched
433 * data in the watchpoint case.
434 *
435 * The invalid values are:
436 * - LENi == 0x10 (undefined), so mask |= 0x0f00.
437 * - R/Wi == 0x10 (break on I/O reads or writes), so
438 * mask |= 0x4444.
439 * - R/Wi == 0x00 && LENi != 0x00, so we have mask |=
440 * 0x1110.
441 *
442 * Finally, mask = 0x0f00 | 0x4444 | 0x1110 == 0x5f54.
443 *
444 * See the Intel Manual "System Programming Guide",
445 * 15.2.4
446 *
447 * Note that LENi == 0x10 is defined on x86_64 in long
448 * mode (i.e. even for 32-bit userspace software, but
449 * 64-bit kernel), so the x86_64 mask value is 0x5454.
450 * See the AMD manual no. 24593 (AMD64 System
451 * Programming)*/
452
453 if(addr == (long) &dummy->u_debugreg[7]) {
454 data &= ~DR_CONTROL_RESERVED;
455 for(i=0; i<4; i++)
456 if ((0x5f54 >> ((data >> (16 + 4*i)) & 0xf)) & 1)
457 goto out_tsk;
458 if (data)
459 set_tsk_thread_flag(child, TIF_DEBUG);
460 else
461 clear_tsk_thread_flag(child, TIF_DEBUG);
462 }
463 addr -= (long) &dummy->u_debugreg;
464 addr = addr >> 2;
465 child->thread.debugreg[addr] = data;
466 ret = 0;
467 }
468 break;
469
470 case PTRACE_SYSEMU: /* continue and stop at next syscall, which will not be executed */
471 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
472 case PTRACE_CONT: /* restart after signal. */
473 ret = -EIO;
474 if (!valid_signal(data))
475 break;
476 if (request == PTRACE_SYSEMU) {
477 set_tsk_thread_flag(child, TIF_SYSCALL_EMU);
478 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
479 } else if (request == PTRACE_SYSCALL) {
480 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
481 clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
482 } else {
483 clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
484 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
485 }
486 child->exit_code = data;
487 /* make sure the single step bit is not set. */
488 clear_singlestep(child);
489 wake_up_process(child);
490 ret = 0;
491 break;
492
493/*
494 * make the child exit. Best I can do is send it a sigkill.
495 * perhaps it should be put in the status that it wants to
496 * exit.
497 */
498 case PTRACE_KILL:
499 ret = 0;
500 if (child->exit_state == EXIT_ZOMBIE) /* already dead */
501 break;
502 child->exit_code = SIGKILL;
503 /* make sure the single step bit is not set. */
504 clear_singlestep(child);
505 wake_up_process(child);
506 break;
507
508 case PTRACE_SYSEMU_SINGLESTEP: /* Same as SYSEMU, but singlestep if not syscall */
509 case PTRACE_SINGLESTEP: /* set the trap flag. */
510 ret = -EIO;
511 if (!valid_signal(data))
512 break;
513
514 if (request == PTRACE_SYSEMU_SINGLESTEP)
515 set_tsk_thread_flag(child, TIF_SYSCALL_EMU);
516 else
517 clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
518
519 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
520 set_singlestep(child);
521 child->exit_code = data;
522 /* give it a chance to run. */
523 wake_up_process(child);
524 ret = 0;
525 break;
526
527 case PTRACE_GETREGS: { /* Get all gp regs from the child. */
528 if (!access_ok(VERIFY_WRITE, datap, FRAME_SIZE*sizeof(long))) {
529 ret = -EIO;
530 break;
531 }
532 for ( i = 0; i < FRAME_SIZE*sizeof(long); i += sizeof(long) ) {
533 __put_user(getreg(child, i), datap);
534 datap++;
535 }
536 ret = 0;
537 break;
538 }
539
540 case PTRACE_SETREGS: { /* Set all gp regs in the child. */
541 unsigned long tmp;
542 if (!access_ok(VERIFY_READ, datap, FRAME_SIZE*sizeof(long))) {
543 ret = -EIO;
544 break;
545 }
546 for ( i = 0; i < FRAME_SIZE*sizeof(long); i += sizeof(long) ) {
547 __get_user(tmp, datap);
548 putreg(child, i, tmp);
549 datap++;
550 }
551 ret = 0;
552 break;
553 }
554
555 case PTRACE_GETFPREGS: { /* Get the child FPU state. */
556 if (!access_ok(VERIFY_WRITE, datap,
557 sizeof(struct user_i387_struct))) {
558 ret = -EIO;
559 break;
560 }
561 ret = 0;
562 if (!tsk_used_math(child))
563 init_fpu(child);
564 get_fpregs((struct user_i387_struct __user *)data, child);
565 break;
566 }
567
568 case PTRACE_SETFPREGS: { /* Set the child FPU state. */
569 if (!access_ok(VERIFY_READ, datap,
570 sizeof(struct user_i387_struct))) {
571 ret = -EIO;
572 break;
573 }
574 set_stopped_child_used_math(child);
575 set_fpregs(child, (struct user_i387_struct __user *)data);
576 ret = 0;
577 break;
578 }
579
580 case PTRACE_GETFPXREGS: { /* Get the child extended FPU state. */
581 if (!access_ok(VERIFY_WRITE, datap,
582 sizeof(struct user_fxsr_struct))) {
583 ret = -EIO;
584 break;
585 }
586 if (!tsk_used_math(child))
587 init_fpu(child);
588 ret = get_fpxregs((struct user_fxsr_struct __user *)data, child);
589 break;
590 }
591
592 case PTRACE_SETFPXREGS: { /* Set the child extended FPU state. */
593 if (!access_ok(VERIFY_READ, datap,
594 sizeof(struct user_fxsr_struct))) {
595 ret = -EIO;
596 break;
597 }
598 set_stopped_child_used_math(child);
599 ret = set_fpxregs(child, (struct user_fxsr_struct __user *)data);
600 break;
601 }
602
603 case PTRACE_GET_THREAD_AREA:
604 ret = ptrace_get_thread_area(child, addr,
605 (struct user_desc __user *) data);
606 break;
607
608 case PTRACE_SET_THREAD_AREA:
609 ret = ptrace_set_thread_area(child, addr,
610 (struct user_desc __user *) data);
611 break;
612
613 default:
614 ret = ptrace_request(child, request, addr, data);
615 break;
616 }
617 out_tsk:
618 return ret;
619}
620
621void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
622{
623 struct siginfo info;
624
625 tsk->thread.trap_no = 1;
626 tsk->thread.error_code = error_code;
627
628 memset(&info, 0, sizeof(info));
629 info.si_signo = SIGTRAP;
630 info.si_code = TRAP_BRKPT;
631
632 /* User-mode eip? */
633 info.si_addr = user_mode_vm(regs) ? (void __user *) regs->eip : NULL;
634
635 /* Send us the fake SIGTRAP */
636 force_sig_info(SIGTRAP, &info, tsk);
637}
638
639/* notification of system call entry/exit
640 * - triggered by current->work.syscall_trace
641 */
642__attribute__((regparm(3)))
643int do_syscall_trace(struct pt_regs *regs, int entryexit)
644{
645 int is_sysemu = test_thread_flag(TIF_SYSCALL_EMU);
646 /*
647 * With TIF_SYSCALL_EMU set we want to ignore TIF_SINGLESTEP for syscall
648 * interception
649 */
650 int is_singlestep = !is_sysemu && test_thread_flag(TIF_SINGLESTEP);
651 int ret = 0;
652
653 /* do the secure computing check first */
654 if (!entryexit)
655 secure_computing(regs->orig_eax);
656
657 if (unlikely(current->audit_context)) {
658 if (entryexit)
659 audit_syscall_exit(AUDITSC_RESULT(regs->eax),
660 regs->eax);
661 /* Debug traps, when using PTRACE_SINGLESTEP, must be sent only
662 * on the syscall exit path. Normally, when TIF_SYSCALL_AUDIT is
663 * not used, entry.S will call us only on syscall exit, not
664 * entry; so when TIF_SYSCALL_AUDIT is used we must avoid
665 * calling send_sigtrap() on syscall entry.
666 *
667 * Note that when PTRACE_SYSEMU_SINGLESTEP is used,
668 * is_singlestep is false, despite his name, so we will still do
669 * the correct thing.
670 */
671 else if (is_singlestep)
672 goto out;
673 }
674
675 if (!(current->ptrace & PT_PTRACED))
676 goto out;
677
678 /* If a process stops on the 1st tracepoint with SYSCALL_TRACE
679 * and then is resumed with SYSEMU_SINGLESTEP, it will come in
680 * here. We have to check this and return */
681 if (is_sysemu && entryexit)
682 return 0;
683
684 /* Fake a debug trap */
685 if (is_singlestep)
686 send_sigtrap(current, regs, 0);
687
688 if (!test_thread_flag(TIF_SYSCALL_TRACE) && !is_sysemu)
689 goto out;
690
691 /* the 0x80 provides a way for the tracing parent to distinguish
692 between a syscall stop and SIGTRAP delivery */
693 /* Note that the debugger could change the result of test_thread_flag!*/
694 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ? 0x80:0));
695
696 /*
697 * this isn't the same as continuing with a signal, but it will do
698 * for normal use. strace only continues with a signal if the
699 * stopping signal is not SIGTRAP. -brl
700 */
701 if (current->exit_code) {
702 send_sig(current->exit_code, current, 1);
703 current->exit_code = 0;
704 }
705 ret = is_sysemu;
706out:
707 if (unlikely(current->audit_context) && !entryexit)
708 audit_syscall_entry(AUDIT_ARCH_I386, regs->orig_eax,
709 regs->ebx, regs->ecx, regs->edx, regs->esi);
710 if (ret == 0)
711 return 0;
712
713 regs->orig_eax = -1; /* force skip of syscall restarting */
714 if (unlikely(current->audit_context))
715 audit_syscall_exit(AUDITSC_RESULT(regs->eax), regs->eax);
716 return 1;
717}
diff --git a/arch/x86/kernel/ptrace_64.c b/arch/x86/kernel/ptrace_64.c
deleted file mode 100644
index 607085f3f08a..000000000000
--- a/arch/x86/kernel/ptrace_64.c
+++ /dev/null
@@ -1,621 +0,0 @@
1/* By Ross Biro 1/23/92 */
2/*
3 * Pentium III FXSR, SSE support
4 * Gareth Hughes <gareth@valinux.com>, May 2000
5 *
6 * x86-64 port 2000-2002 Andi Kleen
7 */
8
9#include <linux/kernel.h>
10#include <linux/sched.h>
11#include <linux/mm.h>
12#include <linux/smp.h>
13#include <linux/errno.h>
14#include <linux/ptrace.h>
15#include <linux/user.h>
16#include <linux/security.h>
17#include <linux/audit.h>
18#include <linux/seccomp.h>
19#include <linux/signal.h>
20
21#include <asm/uaccess.h>
22#include <asm/pgtable.h>
23#include <asm/system.h>
24#include <asm/processor.h>
25#include <asm/i387.h>
26#include <asm/debugreg.h>
27#include <asm/ldt.h>
28#include <asm/desc.h>
29#include <asm/proto.h>
30#include <asm/ia32.h>
31
32/*
33 * does not yet catch signals sent when the child dies.
34 * in exit.c or in signal.c.
35 */
36
37/*
38 * Determines which flags the user has access to [1 = access, 0 = no access].
39 * Prohibits changing ID(21), VIP(20), VIF(19), VM(17), IOPL(12-13), IF(9).
40 * Also masks reserved bits (63-22, 15, 5, 3, 1).
41 */
42#define FLAG_MASK 0x54dd5UL
43
44/* set's the trap flag. */
45#define TRAP_FLAG 0x100UL
46
47/*
48 * eflags and offset of eflags on child stack..
49 */
50#define EFLAGS offsetof(struct pt_regs, eflags)
51#define EFL_OFFSET ((int)(EFLAGS-sizeof(struct pt_regs)))
52
53/*
54 * this routine will get a word off of the processes privileged stack.
55 * the offset is how far from the base addr as stored in the TSS.
56 * this routine assumes that all the privileged stacks are in our
57 * data space.
58 */
59static inline unsigned long get_stack_long(struct task_struct *task, int offset)
60{
61 unsigned char *stack;
62
63 stack = (unsigned char *)task->thread.rsp0;
64 stack += offset;
65 return (*((unsigned long *)stack));
66}
67
68/*
69 * this routine will put a word on the processes privileged stack.
70 * the offset is how far from the base addr as stored in the TSS.
71 * this routine assumes that all the privileged stacks are in our
72 * data space.
73 */
74static inline long put_stack_long(struct task_struct *task, int offset,
75 unsigned long data)
76{
77 unsigned char * stack;
78
79 stack = (unsigned char *) task->thread.rsp0;
80 stack += offset;
81 *(unsigned long *) stack = data;
82 return 0;
83}
84
85#define LDT_SEGMENT 4
86
87unsigned long convert_rip_to_linear(struct task_struct *child, struct pt_regs *regs)
88{
89 unsigned long addr, seg;
90
91 addr = regs->rip;
92 seg = regs->cs & 0xffff;
93
94 /*
95 * We'll assume that the code segments in the GDT
96 * are all zero-based. That is largely true: the
97 * TLS segments are used for data, and the PNPBIOS
98 * and APM bios ones we just ignore here.
99 */
100 if (seg & LDT_SEGMENT) {
101 u32 *desc;
102 unsigned long base;
103
104 seg &= ~7UL;
105
106 mutex_lock(&child->mm->context.lock);
107 if (unlikely((seg >> 3) >= child->mm->context.size))
108 addr = -1L; /* bogus selector, access would fault */
109 else {
110 desc = child->mm->context.ldt + seg;
111 base = ((desc[0] >> 16) |
112 ((desc[1] & 0xff) << 16) |
113 (desc[1] & 0xff000000));
114
115 /* 16-bit code segment? */
116 if (!((desc[1] >> 22) & 1))
117 addr &= 0xffff;
118 addr += base;
119 }
120 mutex_unlock(&child->mm->context.lock);
121 }
122
123 return addr;
124}
125
126static int is_setting_trap_flag(struct task_struct *child, struct pt_regs *regs)
127{
128 int i, copied;
129 unsigned char opcode[15];
130 unsigned long addr = convert_rip_to_linear(child, regs);
131
132 copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
133 for (i = 0; i < copied; i++) {
134 switch (opcode[i]) {
135 /* popf and iret */
136 case 0x9d: case 0xcf:
137 return 1;
138
139 /* CHECKME: 64 65 */
140
141 /* opcode and address size prefixes */
142 case 0x66: case 0x67:
143 continue;
144 /* irrelevant prefixes (segment overrides and repeats) */
145 case 0x26: case 0x2e:
146 case 0x36: case 0x3e:
147 case 0x64: case 0x65:
148 case 0xf2: case 0xf3:
149 continue;
150
151 case 0x40 ... 0x4f:
152 if (regs->cs != __USER_CS)
153 /* 32-bit mode: register increment */
154 return 0;
155 /* 64-bit mode: REX prefix */
156 continue;
157
158 /* CHECKME: f2, f3 */
159
160 /*
161 * pushf: NOTE! We should probably not let
162 * the user see the TF bit being set. But
163 * it's more pain than it's worth to avoid
164 * it, and a debugger could emulate this
165 * all in user space if it _really_ cares.
166 */
167 case 0x9c:
168 default:
169 return 0;
170 }
171 }
172 return 0;
173}
174
175static void set_singlestep(struct task_struct *child)
176{
177 struct pt_regs *regs = task_pt_regs(child);
178
179 /*
180 * Always set TIF_SINGLESTEP - this guarantees that
181 * we single-step system calls etc.. This will also
182 * cause us to set TF when returning to user mode.
183 */
184 set_tsk_thread_flag(child, TIF_SINGLESTEP);
185
186 /*
187 * If TF was already set, don't do anything else
188 */
189 if (regs->eflags & TRAP_FLAG)
190 return;
191
192 /* Set TF on the kernel stack.. */
193 regs->eflags |= TRAP_FLAG;
194
195 /*
196 * ..but if TF is changed by the instruction we will trace,
197 * don't mark it as being "us" that set it, so that we
198 * won't clear it by hand later.
199 */
200 if (is_setting_trap_flag(child, regs))
201 return;
202
203 child->ptrace |= PT_DTRACE;
204}
205
206static void clear_singlestep(struct task_struct *child)
207{
208 /* Always clear TIF_SINGLESTEP... */
209 clear_tsk_thread_flag(child, TIF_SINGLESTEP);
210
211 /* But touch TF only if it was set by us.. */
212 if (child->ptrace & PT_DTRACE) {
213 struct pt_regs *regs = task_pt_regs(child);
214 regs->eflags &= ~TRAP_FLAG;
215 child->ptrace &= ~PT_DTRACE;
216 }
217}
218
219/*
220 * Called by kernel/ptrace.c when detaching..
221 *
222 * Make sure the single step bit is not set.
223 */
224void ptrace_disable(struct task_struct *child)
225{
226 clear_singlestep(child);
227}
228
229static int putreg(struct task_struct *child,
230 unsigned long regno, unsigned long value)
231{
232 unsigned long tmp;
233
234 switch (regno) {
235 case offsetof(struct user_regs_struct,fs):
236 if (value && (value & 3) != 3)
237 return -EIO;
238 child->thread.fsindex = value & 0xffff;
239 return 0;
240 case offsetof(struct user_regs_struct,gs):
241 if (value && (value & 3) != 3)
242 return -EIO;
243 child->thread.gsindex = value & 0xffff;
244 return 0;
245 case offsetof(struct user_regs_struct,ds):
246 if (value && (value & 3) != 3)
247 return -EIO;
248 child->thread.ds = value & 0xffff;
249 return 0;
250 case offsetof(struct user_regs_struct,es):
251 if (value && (value & 3) != 3)
252 return -EIO;
253 child->thread.es = value & 0xffff;
254 return 0;
255 case offsetof(struct user_regs_struct,ss):
256 if ((value & 3) != 3)
257 return -EIO;
258 value &= 0xffff;
259 return 0;
260 case offsetof(struct user_regs_struct,fs_base):
261 if (value >= TASK_SIZE_OF(child))
262 return -EIO;
263 child->thread.fs = value;
264 return 0;
265 case offsetof(struct user_regs_struct,gs_base):
266 if (value >= TASK_SIZE_OF(child))
267 return -EIO;
268 child->thread.gs = value;
269 return 0;
270 case offsetof(struct user_regs_struct, eflags):
271 value &= FLAG_MASK;
272 tmp = get_stack_long(child, EFL_OFFSET);
273 tmp &= ~FLAG_MASK;
274 value |= tmp;
275 break;
276 case offsetof(struct user_regs_struct,cs):
277 if ((value & 3) != 3)
278 return -EIO;
279 value &= 0xffff;
280 break;
281 }
282 put_stack_long(child, regno - sizeof(struct pt_regs), value);
283 return 0;
284}
285
286static unsigned long getreg(struct task_struct *child, unsigned long regno)
287{
288 unsigned long val;
289 switch (regno) {
290 case offsetof(struct user_regs_struct, fs):
291 return child->thread.fsindex;
292 case offsetof(struct user_regs_struct, gs):
293 return child->thread.gsindex;
294 case offsetof(struct user_regs_struct, ds):
295 return child->thread.ds;
296 case offsetof(struct user_regs_struct, es):
297 return child->thread.es;
298 case offsetof(struct user_regs_struct, fs_base):
299 return child->thread.fs;
300 case offsetof(struct user_regs_struct, gs_base):
301 return child->thread.gs;
302 default:
303 regno = regno - sizeof(struct pt_regs);
304 val = get_stack_long(child, regno);
305 if (test_tsk_thread_flag(child, TIF_IA32))
306 val &= 0xffffffff;
307 return val;
308 }
309
310}
311
312long arch_ptrace(struct task_struct *child, long request, long addr, long data)
313{
314 long i, ret;
315 unsigned ui;
316
317 switch (request) {
318 /* when I and D space are separate, these will need to be fixed. */
319 case PTRACE_PEEKTEXT: /* read word at location addr. */
320 case PTRACE_PEEKDATA:
321 ret = generic_ptrace_peekdata(child, addr, data);
322 break;
323
324 /* read the word at location addr in the USER area. */
325 case PTRACE_PEEKUSR: {
326 unsigned long tmp;
327
328 ret = -EIO;
329 if ((addr & 7) ||
330 addr > sizeof(struct user) - 7)
331 break;
332
333 switch (addr) {
334 case 0 ... sizeof(struct user_regs_struct) - sizeof(long):
335 tmp = getreg(child, addr);
336 break;
337 case offsetof(struct user, u_debugreg[0]):
338 tmp = child->thread.debugreg0;
339 break;
340 case offsetof(struct user, u_debugreg[1]):
341 tmp = child->thread.debugreg1;
342 break;
343 case offsetof(struct user, u_debugreg[2]):
344 tmp = child->thread.debugreg2;
345 break;
346 case offsetof(struct user, u_debugreg[3]):
347 tmp = child->thread.debugreg3;
348 break;
349 case offsetof(struct user, u_debugreg[6]):
350 tmp = child->thread.debugreg6;
351 break;
352 case offsetof(struct user, u_debugreg[7]):
353 tmp = child->thread.debugreg7;
354 break;
355 default:
356 tmp = 0;
357 break;
358 }
359 ret = put_user(tmp,(unsigned long __user *) data);
360 break;
361 }
362
363 /* when I and D space are separate, this will have to be fixed. */
364 case PTRACE_POKETEXT: /* write the word at location addr. */
365 case PTRACE_POKEDATA:
366 ret = generic_ptrace_pokedata(child, addr, data);
367 break;
368
369 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
370 {
371 int dsize = test_tsk_thread_flag(child, TIF_IA32) ? 3 : 7;
372 ret = -EIO;
373 if ((addr & 7) ||
374 addr > sizeof(struct user) - 7)
375 break;
376
377 switch (addr) {
378 case 0 ... sizeof(struct user_regs_struct) - sizeof(long):
379 ret = putreg(child, addr, data);
380 break;
381 /* Disallows to set a breakpoint into the vsyscall */
382 case offsetof(struct user, u_debugreg[0]):
383 if (data >= TASK_SIZE_OF(child) - dsize) break;
384 child->thread.debugreg0 = data;
385 ret = 0;
386 break;
387 case offsetof(struct user, u_debugreg[1]):
388 if (data >= TASK_SIZE_OF(child) - dsize) break;
389 child->thread.debugreg1 = data;
390 ret = 0;
391 break;
392 case offsetof(struct user, u_debugreg[2]):
393 if (data >= TASK_SIZE_OF(child) - dsize) break;
394 child->thread.debugreg2 = data;
395 ret = 0;
396 break;
397 case offsetof(struct user, u_debugreg[3]):
398 if (data >= TASK_SIZE_OF(child) - dsize) break;
399 child->thread.debugreg3 = data;
400 ret = 0;
401 break;
402 case offsetof(struct user, u_debugreg[6]):
403 if (data >> 32)
404 break;
405 child->thread.debugreg6 = data;
406 ret = 0;
407 break;
408 case offsetof(struct user, u_debugreg[7]):
409 /* See arch/i386/kernel/ptrace.c for an explanation of
410 * this awkward check.*/
411 data &= ~DR_CONTROL_RESERVED;
412 for(i=0; i<4; i++)
413 if ((0x5554 >> ((data >> (16 + 4*i)) & 0xf)) & 1)
414 break;
415 if (i == 4) {
416 child->thread.debugreg7 = data;
417 if (data)
418 set_tsk_thread_flag(child, TIF_DEBUG);
419 else
420 clear_tsk_thread_flag(child, TIF_DEBUG);
421 ret = 0;
422 }
423 break;
424 }
425 break;
426 }
427 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
428 case PTRACE_CONT: /* restart after signal. */
429
430 ret = -EIO;
431 if (!valid_signal(data))
432 break;
433 if (request == PTRACE_SYSCALL)
434 set_tsk_thread_flag(child,TIF_SYSCALL_TRACE);
435 else
436 clear_tsk_thread_flag(child,TIF_SYSCALL_TRACE);
437 clear_tsk_thread_flag(child, TIF_SINGLESTEP);
438 child->exit_code = data;
439 /* make sure the single step bit is not set. */
440 clear_singlestep(child);
441 wake_up_process(child);
442 ret = 0;
443 break;
444
445#ifdef CONFIG_IA32_EMULATION
446 /* This makes only sense with 32bit programs. Allow a
447 64bit debugger to fully examine them too. Better
448 don't use it against 64bit processes, use
449 PTRACE_ARCH_PRCTL instead. */
450 case PTRACE_SET_THREAD_AREA: {
451 struct user_desc __user *p;
452 int old;
453 p = (struct user_desc __user *)data;
454 get_user(old, &p->entry_number);
455 put_user(addr, &p->entry_number);
456 ret = do_set_thread_area(&child->thread, p);
457 put_user(old, &p->entry_number);
458 break;
459 case PTRACE_GET_THREAD_AREA:
460 p = (struct user_desc __user *)data;
461 get_user(old, &p->entry_number);
462 put_user(addr, &p->entry_number);
463 ret = do_get_thread_area(&child->thread, p);
464 put_user(old, &p->entry_number);
465 break;
466 }
467#endif
468 /* normal 64bit interface to access TLS data.
469 Works just like arch_prctl, except that the arguments
470 are reversed. */
471 case PTRACE_ARCH_PRCTL:
472 ret = do_arch_prctl(child, data, addr);
473 break;
474
475/*
476 * make the child exit. Best I can do is send it a sigkill.
477 * perhaps it should be put in the status that it wants to
478 * exit.
479 */
480 case PTRACE_KILL:
481 ret = 0;
482 if (child->exit_state == EXIT_ZOMBIE) /* already dead */
483 break;
484 clear_tsk_thread_flag(child, TIF_SINGLESTEP);
485 child->exit_code = SIGKILL;
486 /* make sure the single step bit is not set. */
487 clear_singlestep(child);
488 wake_up_process(child);
489 break;
490
491 case PTRACE_SINGLESTEP: /* set the trap flag. */
492 ret = -EIO;
493 if (!valid_signal(data))
494 break;
495 clear_tsk_thread_flag(child,TIF_SYSCALL_TRACE);
496 set_singlestep(child);
497 child->exit_code = data;
498 /* give it a chance to run. */
499 wake_up_process(child);
500 ret = 0;
501 break;
502
503 case PTRACE_GETREGS: { /* Get all gp regs from the child. */
504 if (!access_ok(VERIFY_WRITE, (unsigned __user *)data,
505 sizeof(struct user_regs_struct))) {
506 ret = -EIO;
507 break;
508 }
509 ret = 0;
510 for (ui = 0; ui < sizeof(struct user_regs_struct); ui += sizeof(long)) {
511 ret |= __put_user(getreg(child, ui),(unsigned long __user *) data);
512 data += sizeof(long);
513 }
514 break;
515 }
516
517 case PTRACE_SETREGS: { /* Set all gp regs in the child. */
518 unsigned long tmp;
519 if (!access_ok(VERIFY_READ, (unsigned __user *)data,
520 sizeof(struct user_regs_struct))) {
521 ret = -EIO;
522 break;
523 }
524 ret = 0;
525 for (ui = 0; ui < sizeof(struct user_regs_struct); ui += sizeof(long)) {
526 ret = __get_user(tmp, (unsigned long __user *) data);
527 if (ret)
528 break;
529 ret = putreg(child, ui, tmp);
530 if (ret)
531 break;
532 data += sizeof(long);
533 }
534 break;
535 }
536
537 case PTRACE_GETFPREGS: { /* Get the child extended FPU state. */
538 if (!access_ok(VERIFY_WRITE, (unsigned __user *)data,
539 sizeof(struct user_i387_struct))) {
540 ret = -EIO;
541 break;
542 }
543 ret = get_fpregs((struct user_i387_struct __user *)data, child);
544 break;
545 }
546
547 case PTRACE_SETFPREGS: { /* Set the child extended FPU state. */
548 if (!access_ok(VERIFY_READ, (unsigned __user *)data,
549 sizeof(struct user_i387_struct))) {
550 ret = -EIO;
551 break;
552 }
553 set_stopped_child_used_math(child);
554 ret = set_fpregs(child, (struct user_i387_struct __user *)data);
555 break;
556 }
557
558 default:
559 ret = ptrace_request(child, request, addr, data);
560 break;
561 }
562 return ret;
563}
564
565static void syscall_trace(struct pt_regs *regs)
566{
567
568#if 0
569 printk("trace %s rip %lx rsp %lx rax %d origrax %d caller %lx tiflags %x ptrace %x\n",
570 current->comm,
571 regs->rip, regs->rsp, regs->rax, regs->orig_rax, __builtin_return_address(0),
572 current_thread_info()->flags, current->ptrace);
573#endif
574
575 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
576 ? 0x80 : 0));
577 /*
578 * this isn't the same as continuing with a signal, but it will do
579 * for normal use. strace only continues with a signal if the
580 * stopping signal is not SIGTRAP. -brl
581 */
582 if (current->exit_code) {
583 send_sig(current->exit_code, current, 1);
584 current->exit_code = 0;
585 }
586}
587
588asmlinkage void syscall_trace_enter(struct pt_regs *regs)
589{
590 /* do the secure computing check first */
591 secure_computing(regs->orig_rax);
592
593 if (test_thread_flag(TIF_SYSCALL_TRACE)
594 && (current->ptrace & PT_PTRACED))
595 syscall_trace(regs);
596
597 if (unlikely(current->audit_context)) {
598 if (test_thread_flag(TIF_IA32)) {
599 audit_syscall_entry(AUDIT_ARCH_I386,
600 regs->orig_rax,
601 regs->rbx, regs->rcx,
602 regs->rdx, regs->rsi);
603 } else {
604 audit_syscall_entry(AUDIT_ARCH_X86_64,
605 regs->orig_rax,
606 regs->rdi, regs->rsi,
607 regs->rdx, regs->r10);
608 }
609 }
610}
611
612asmlinkage void syscall_trace_leave(struct pt_regs *regs)
613{
614 if (unlikely(current->audit_context))
615 audit_syscall_exit(AUDITSC_RESULT(regs->rax), regs->rax);
616
617 if ((test_thread_flag(TIF_SYSCALL_TRACE)
618 || test_thread_flag(TIF_SINGLESTEP))
619 && (current->ptrace & PT_PTRACED))
620 syscall_trace(regs);
621}
diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c
index fab30e134836..150ba29a0d33 100644
--- a/arch/x86/kernel/quirks.c
+++ b/arch/x86/kernel/quirks.c
@@ -162,6 +162,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31,
162 ich_force_enable_hpet); 162 ich_force_enable_hpet);
163DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_1, 163DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_1,
164 ich_force_enable_hpet); 164 ich_force_enable_hpet);
165DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_7,
166 ich_force_enable_hpet);
165 167
166 168
167static struct pci_dev *cached_dev; 169static struct pci_dev *cached_dev;
diff --git a/arch/x86/kernel/reboot_32.c b/arch/x86/kernel/reboot.c
index bb1a0f889c5e..5818dc28167d 100644
--- a/arch/x86/kernel/reboot_32.c
+++ b/arch/x86/kernel/reboot.c
@@ -1,64 +1,94 @@
1#include <linux/mm.h>
2#include <linux/module.h> 1#include <linux/module.h>
3#include <linux/delay.h>
4#include <linux/init.h> 2#include <linux/init.h>
5#include <linux/interrupt.h>
6#include <linux/mc146818rtc.h>
7#include <linux/efi.h>
8#include <linux/dmi.h>
9#include <linux/ctype.h>
10#include <linux/pm.h>
11#include <linux/reboot.h> 3#include <linux/reboot.h>
12#include <asm/uaccess.h> 4#include <linux/init.h>
5#include <linux/pm.h>
6#include <linux/efi.h>
7#include <acpi/reboot.h>
8#include <asm/io.h>
13#include <asm/apic.h> 9#include <asm/apic.h>
14#include <asm/hpet.h>
15#include <asm/desc.h> 10#include <asm/desc.h>
16#include "mach_reboot.h" 11#include <asm/hpet.h>
17#include <asm/reboot_fixups.h> 12#include <asm/reboot_fixups.h>
18#include <asm/reboot.h> 13#include <asm/reboot.h>
19 14
15#ifdef CONFIG_X86_32
16# include <linux/dmi.h>
17# include <linux/ctype.h>
18# include <linux/mc146818rtc.h>
19# include <asm/pgtable.h>
20#else
21# include <asm/iommu.h>
22#endif
23
20/* 24/*
21 * Power off function, if any 25 * Power off function, if any
22 */ 26 */
23void (*pm_power_off)(void); 27void (*pm_power_off)(void);
24EXPORT_SYMBOL(pm_power_off); 28EXPORT_SYMBOL(pm_power_off);
25 29
30static long no_idt[3];
26static int reboot_mode; 31static int reboot_mode;
27static int reboot_thru_bios; 32enum reboot_type reboot_type = BOOT_KBD;
33int reboot_force;
28 34
29#ifdef CONFIG_SMP 35#if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
30static int reboot_cpu = -1; 36static int reboot_cpu = -1;
31#endif 37#endif
38
39/* reboot=b[ios] | s[mp] | t[riple] | k[bd] | e[fi] [, [w]arm | [c]old]
40 warm Don't set the cold reboot flag
41 cold Set the cold reboot flag
42 bios Reboot by jumping through the BIOS (only for X86_32)
43 smp Reboot by executing reset on BSP or other CPU (only for X86_32)
44 triple Force a triple fault (init)
45 kbd Use the keyboard controller. cold reset (default)
46 acpi Use the RESET_REG in the FADT
47 efi Use efi reset_system runtime service
48 force Avoid anything that could hang.
49 */
32static int __init reboot_setup(char *str) 50static int __init reboot_setup(char *str)
33{ 51{
34 while(1) { 52 for (;;) {
35 switch (*str) { 53 switch (*str) {
36 case 'w': /* "warm" reboot (no memory testing etc) */ 54 case 'w':
37 reboot_mode = 0x1234; 55 reboot_mode = 0x1234;
38 break; 56 break;
39 case 'c': /* "cold" reboot (with memory testing etc) */ 57
40 reboot_mode = 0x0; 58 case 'c':
41 break; 59 reboot_mode = 0;
42 case 'b': /* "bios" reboot by jumping through the BIOS */
43 reboot_thru_bios = 1;
44 break;
45 case 'h': /* "hard" reboot by toggling RESET and/or crashing the CPU */
46 reboot_thru_bios = 0;
47 break; 60 break;
61
62#ifdef CONFIG_X86_32
48#ifdef CONFIG_SMP 63#ifdef CONFIG_SMP
49 case 's': /* "smp" reboot by executing reset on BSP or other CPU*/ 64 case 's':
50 if (isdigit(*(str+1))) { 65 if (isdigit(*(str+1))) {
51 reboot_cpu = (int) (*(str+1) - '0'); 66 reboot_cpu = (int) (*(str+1) - '0');
52 if (isdigit(*(str+2))) 67 if (isdigit(*(str+2)))
53 reboot_cpu = reboot_cpu*10 + (int)(*(str+2) - '0'); 68 reboot_cpu = reboot_cpu*10 + (int)(*(str+2) - '0');
54 } 69 }
55 /* we will leave sorting out the final value 70 /* we will leave sorting out the final value
56 when we are ready to reboot, since we might not 71 when we are ready to reboot, since we might not
57 have set up boot_cpu_id or smp_num_cpu */ 72 have set up boot_cpu_id or smp_num_cpu */
58 break; 73 break;
74#endif /* CONFIG_SMP */
75
76 case 'b':
59#endif 77#endif
78 case 'a':
79 case 'k':
80 case 't':
81 case 'e':
82 reboot_type = *str;
83 break;
84
85 case 'f':
86 reboot_force = 1;
87 break;
60 } 88 }
61 if((str = strchr(str,',')) != NULL) 89
90 str = strchr(str, ',');
91 if (str)
62 str++; 92 str++;
63 else 93 else
64 break; 94 break;
@@ -68,18 +98,21 @@ static int __init reboot_setup(char *str)
68 98
69__setup("reboot=", reboot_setup); 99__setup("reboot=", reboot_setup);
70 100
101
102#ifdef CONFIG_X86_32
71/* 103/*
72 * Reboot options and system auto-detection code provided by 104 * Reboot options and system auto-detection code provided by
73 * Dell Inc. so their systems "just work". :-) 105 * Dell Inc. so their systems "just work". :-)
74 */ 106 */
75 107
76/* 108/*
77 * Some machines require the "reboot=b" commandline option, this quirk makes that automatic. 109 * Some machines require the "reboot=b" commandline option,
110 * this quirk makes that automatic.
78 */ 111 */
79static int __init set_bios_reboot(const struct dmi_system_id *d) 112static int __init set_bios_reboot(const struct dmi_system_id *d)
80{ 113{
81 if (!reboot_thru_bios) { 114 if (reboot_type != BOOT_BIOS) {
82 reboot_thru_bios = 1; 115 reboot_type = BOOT_BIOS;
83 printk(KERN_INFO "%s series board detected. Selecting BIOS-method for reboots.\n", d->ident); 116 printk(KERN_INFO "%s series board detected. Selecting BIOS-method for reboots.\n", d->ident);
84 } 117 }
85 return 0; 118 return 0;
@@ -143,7 +176,6 @@ static int __init reboot_init(void)
143 dmi_check_system(reboot_dmi_table); 176 dmi_check_system(reboot_dmi_table);
144 return 0; 177 return 0;
145} 178}
146
147core_initcall(reboot_init); 179core_initcall(reboot_init);
148 180
149/* The following code and data reboots the machine by switching to real 181/* The following code and data reboots the machine by switching to real
@@ -152,7 +184,6 @@ core_initcall(reboot_init);
152 controller to pulse the CPU reset line, which is more thorough, but 184 controller to pulse the CPU reset line, which is more thorough, but
153 doesn't work with at least one type of 486 motherboard. It is easy 185 doesn't work with at least one type of 486 motherboard. It is easy
154 to stop this code working; hence the copious comments. */ 186 to stop this code working; hence the copious comments. */
155
156static unsigned long long 187static unsigned long long
157real_mode_gdt_entries [3] = 188real_mode_gdt_entries [3] =
158{ 189{
@@ -161,11 +192,9 @@ real_mode_gdt_entries [3] =
161 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */ 192 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
162}; 193};
163 194
164static struct Xgt_desc_struct 195static struct desc_ptr
165real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (long)real_mode_gdt_entries }, 196real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (long)real_mode_gdt_entries },
166real_mode_idt = { 0x3ff, 0 }, 197real_mode_idt = { 0x3ff, 0 };
167no_idt = { 0, 0 };
168
169 198
170/* This is 16-bit protected mode code to disable paging and the cache, 199/* This is 16-bit protected mode code to disable paging and the cache,
171 switch to real mode and jump to the BIOS reset code. 200 switch to real mode and jump to the BIOS reset code.
@@ -185,7 +214,6 @@ no_idt = { 0, 0 };
185 214
186 More could be done here to set up the registers as if a CPU reset had 215 More could be done here to set up the registers as if a CPU reset had
187 occurred; hopefully real BIOSs don't assume much. */ 216 occurred; hopefully real BIOSs don't assume much. */
188
189static unsigned char real_mode_switch [] = 217static unsigned char real_mode_switch [] =
190{ 218{
191 0x66, 0x0f, 0x20, 0xc0, /* movl %cr0,%eax */ 219 0x66, 0x0f, 0x20, 0xc0, /* movl %cr0,%eax */
@@ -223,7 +251,6 @@ void machine_real_restart(unsigned char *code, int length)
223 `outb_p' is needed instead of just `outb'. Use it to be on the 251 `outb_p' is needed instead of just `outb'. Use it to be on the
224 safe side. (Yes, CMOS_WRITE does outb_p's. - Paul G.) 252 safe side. (Yes, CMOS_WRITE does outb_p's. - Paul G.)
225 */ 253 */
226
227 spin_lock(&rtc_lock); 254 spin_lock(&rtc_lock);
228 CMOS_WRITE(0x00, 0x8f); 255 CMOS_WRITE(0x00, 0x8f);
229 spin_unlock(&rtc_lock); 256 spin_unlock(&rtc_lock);
@@ -231,9 +258,8 @@ void machine_real_restart(unsigned char *code, int length)
231 /* Remap the kernel at virtual address zero, as well as offset zero 258 /* Remap the kernel at virtual address zero, as well as offset zero
232 from the kernel segment. This assumes the kernel segment starts at 259 from the kernel segment. This assumes the kernel segment starts at
233 virtual address PAGE_OFFSET. */ 260 virtual address PAGE_OFFSET. */
234 261 memcpy(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
235 memcpy (swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS, 262 sizeof(swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
236 sizeof (swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
237 263
238 /* 264 /*
239 * Use `swapper_pg_dir' as our page directory. 265 * Use `swapper_pg_dir' as our page directory.
@@ -245,7 +271,6 @@ void machine_real_restart(unsigned char *code, int length)
245 boot)". This seems like a fairly standard thing that gets set by 271 boot)". This seems like a fairly standard thing that gets set by
246 REBOOT.COM programs, and the previous reset routine did this 272 REBOOT.COM programs, and the previous reset routine did this
247 too. */ 273 too. */
248
249 *((unsigned short *)0x472) = reboot_mode; 274 *((unsigned short *)0x472) = reboot_mode;
250 275
251 /* For the switch to real mode, copy some code to low memory. It has 276 /* For the switch to real mode, copy some code to low memory. It has
@@ -253,19 +278,16 @@ void machine_real_restart(unsigned char *code, int length)
253 has to have the same physical and virtual address, because it turns 278 has to have the same physical and virtual address, because it turns
254 off paging. Copy it near the end of the first page, out of the way 279 off paging. Copy it near the end of the first page, out of the way
255 of BIOS variables. */ 280 of BIOS variables. */
256 281 memcpy((void *)(0x1000 - sizeof(real_mode_switch) - 100),
257 memcpy ((void *) (0x1000 - sizeof (real_mode_switch) - 100),
258 real_mode_switch, sizeof (real_mode_switch)); 282 real_mode_switch, sizeof (real_mode_switch));
259 memcpy ((void *) (0x1000 - 100), code, length); 283 memcpy((void *)(0x1000 - 100), code, length);
260 284
261 /* Set up the IDT for real mode. */ 285 /* Set up the IDT for real mode. */
262
263 load_idt(&real_mode_idt); 286 load_idt(&real_mode_idt);
264 287
265 /* Set up a GDT from which we can load segment descriptors for real 288 /* Set up a GDT from which we can load segment descriptors for real
266 mode. The GDT is not used in real mode; it is just needed here to 289 mode. The GDT is not used in real mode; it is just needed here to
267 prepare the descriptors. */ 290 prepare the descriptors. */
268
269 load_gdt(&real_mode_gdt); 291 load_gdt(&real_mode_gdt);
270 292
271 /* Load the data segment registers, and thus the descriptors ready for 293 /* Load the data segment registers, and thus the descriptors ready for
@@ -273,7 +295,6 @@ void machine_real_restart(unsigned char *code, int length)
273 selector value being loaded here. This is so that the segment 295 selector value being loaded here. This is so that the segment
274 registers don't have to be reloaded after switching to real mode: 296 registers don't have to be reloaded after switching to real mode:
275 the values are consistent for real mode operation already. */ 297 the values are consistent for real mode operation already. */
276
277 __asm__ __volatile__ ("movl $0x0010,%%eax\n" 298 __asm__ __volatile__ ("movl $0x0010,%%eax\n"
278 "\tmovl %%eax,%%ds\n" 299 "\tmovl %%eax,%%ds\n"
279 "\tmovl %%eax,%%es\n" 300 "\tmovl %%eax,%%es\n"
@@ -284,130 +305,147 @@ void machine_real_restart(unsigned char *code, int length)
284 /* Jump to the 16-bit code that we copied earlier. It disables paging 305 /* Jump to the 16-bit code that we copied earlier. It disables paging
285 and the cache, switches to real mode, and jumps to the BIOS reset 306 and the cache, switches to real mode, and jumps to the BIOS reset
286 entry point. */ 307 entry point. */
287
288 __asm__ __volatile__ ("ljmp $0x0008,%0" 308 __asm__ __volatile__ ("ljmp $0x0008,%0"
289 : 309 :
290 : "i" ((void *) (0x1000 - sizeof (real_mode_switch) - 100))); 310 : "i" ((void *)(0x1000 - sizeof (real_mode_switch) - 100)));
291} 311}
292#ifdef CONFIG_APM_MODULE 312#ifdef CONFIG_APM_MODULE
293EXPORT_SYMBOL(machine_real_restart); 313EXPORT_SYMBOL(machine_real_restart);
294#endif 314#endif
295 315
296static void native_machine_shutdown(void) 316#endif /* CONFIG_X86_32 */
317
318static inline void kb_wait(void)
319{
320 int i;
321
322 for (i = 0; i < 0x10000; i++) {
323 if ((inb(0x64) & 0x02) == 0)
324 break;
325 udelay(2);
326 }
327}
328
329void machine_emergency_restart(void)
330{
331 int i;
332
333 /* Tell the BIOS if we want cold or warm reboot */
334 *((unsigned short *)__va(0x472)) = reboot_mode;
335
336 for (;;) {
337 /* Could also try the reset bit in the Hammer NB */
338 switch (reboot_type) {
339 case BOOT_KBD:
340 for (i = 0; i < 10; i++) {
341 kb_wait();
342 udelay(50);
343 outb(0xfe, 0x64); /* pulse reset low */
344 udelay(50);
345 }
346
347 case BOOT_TRIPLE:
348 load_idt((const struct desc_ptr *)&no_idt);
349 __asm__ __volatile__("int3");
350
351 reboot_type = BOOT_KBD;
352 break;
353
354#ifdef CONFIG_X86_32
355 case BOOT_BIOS:
356 machine_real_restart(jump_to_bios, sizeof(jump_to_bios));
357
358 reboot_type = BOOT_KBD;
359 break;
360#endif
361
362 case BOOT_ACPI:
363 acpi_reboot();
364 reboot_type = BOOT_KBD;
365 break;
366
367
368 case BOOT_EFI:
369 if (efi_enabled)
370 efi.reset_system(reboot_mode ? EFI_RESET_WARM : EFI_RESET_COLD,
371 EFI_SUCCESS, 0, NULL);
372
373 reboot_type = BOOT_KBD;
374 break;
375 }
376 }
377}
378
379void machine_shutdown(void)
297{ 380{
381 /* Stop the cpus and apics */
298#ifdef CONFIG_SMP 382#ifdef CONFIG_SMP
299 int reboot_cpu_id; 383 int reboot_cpu_id;
300 384
301 /* The boot cpu is always logical cpu 0 */ 385 /* The boot cpu is always logical cpu 0 */
302 reboot_cpu_id = 0; 386 reboot_cpu_id = 0;
303 387
388#ifdef CONFIG_X86_32
304 /* See if there has been given a command line override */ 389 /* See if there has been given a command line override */
305 if ((reboot_cpu != -1) && (reboot_cpu < NR_CPUS) && 390 if ((reboot_cpu != -1) && (reboot_cpu < NR_CPUS) &&
306 cpu_isset(reboot_cpu, cpu_online_map)) { 391 cpu_isset(reboot_cpu, cpu_online_map))
307 reboot_cpu_id = reboot_cpu; 392 reboot_cpu_id = reboot_cpu;
308 } 393#endif
309 394
310 /* Make certain the cpu I'm rebooting on is online */ 395 /* Make certain the cpu I'm about to reboot on is online */
311 if (!cpu_isset(reboot_cpu_id, cpu_online_map)) { 396 if (!cpu_isset(reboot_cpu_id, cpu_online_map))
312 reboot_cpu_id = smp_processor_id(); 397 reboot_cpu_id = smp_processor_id();
313 }
314 398
315 /* Make certain I only run on the appropriate processor */ 399 /* Make certain I only run on the appropriate processor */
316 set_cpus_allowed(current, cpumask_of_cpu(reboot_cpu_id)); 400 set_cpus_allowed(current, cpumask_of_cpu(reboot_cpu_id));
317 401
318 /* O.K. Now that I'm on the appropriate processor, stop 402 /* O.K Now that I'm on the appropriate processor,
319 * all of the others, and disable their local APICs. 403 * stop all of the others.
320 */ 404 */
321
322 smp_send_stop(); 405 smp_send_stop();
323#endif /* CONFIG_SMP */ 406#endif
324 407
325 lapic_shutdown(); 408 lapic_shutdown();
326 409
327#ifdef CONFIG_X86_IO_APIC 410#ifdef CONFIG_X86_IO_APIC
328 disable_IO_APIC(); 411 disable_IO_APIC();
329#endif 412#endif
413
330#ifdef CONFIG_HPET_TIMER 414#ifdef CONFIG_HPET_TIMER
331 hpet_disable(); 415 hpet_disable();
332#endif 416#endif
333}
334 417
335void __attribute__((weak)) mach_reboot_fixups(void) 418#ifdef CONFIG_X86_64
336{ 419 pci_iommu_shutdown();
420#endif
337} 421}
338 422
339static void native_machine_emergency_restart(void) 423void machine_restart(char *__unused)
340{ 424{
341 if (!reboot_thru_bios) { 425 printk("machine restart\n");
342 if (efi_enabled) {
343 efi.reset_system(EFI_RESET_COLD, EFI_SUCCESS, 0, NULL);
344 load_idt(&no_idt);
345 __asm__ __volatile__("int3");
346 }
347 /* rebooting needs to touch the page at absolute addr 0 */
348 *((unsigned short *)__va(0x472)) = reboot_mode;
349 for (;;) {
350 mach_reboot_fixups(); /* for board specific fixups */
351 mach_reboot();
352 /* That didn't work - force a triple fault.. */
353 load_idt(&no_idt);
354 __asm__ __volatile__("int3");
355 }
356 }
357 if (efi_enabled)
358 efi.reset_system(EFI_RESET_WARM, EFI_SUCCESS, 0, NULL);
359 426
360 machine_real_restart(jump_to_bios, sizeof(jump_to_bios)); 427 if (!reboot_force)
361} 428 machine_shutdown();
362
363static void native_machine_restart(char * __unused)
364{
365 machine_shutdown();
366 machine_emergency_restart(); 429 machine_emergency_restart();
367} 430}
368 431
369static void native_machine_halt(void) 432void machine_halt(void)
370{ 433{
371} 434}
372 435
373static void native_machine_power_off(void) 436void machine_power_off(void)
374{ 437{
375 if (pm_power_off) { 438 if (pm_power_off) {
376 machine_shutdown(); 439 if (!reboot_force)
440 machine_shutdown();
377 pm_power_off(); 441 pm_power_off();
378 } 442 }
379} 443}
380 444
381
382struct machine_ops machine_ops = { 445struct machine_ops machine_ops = {
383 .power_off = native_machine_power_off, 446 .power_off = machine_power_off,
384 .shutdown = native_machine_shutdown, 447 .shutdown = machine_shutdown,
385 .emergency_restart = native_machine_emergency_restart, 448 .emergency_restart = machine_emergency_restart,
386 .restart = native_machine_restart, 449 .restart = machine_restart,
387 .halt = native_machine_halt, 450 .halt = machine_halt
388}; 451};
389
390void machine_power_off(void)
391{
392 machine_ops.power_off();
393}
394
395void machine_shutdown(void)
396{
397 machine_ops.shutdown();
398}
399
400void machine_emergency_restart(void)
401{
402 machine_ops.emergency_restart();
403}
404
405void machine_restart(char *cmd)
406{
407 machine_ops.restart(cmd);
408}
409
410void machine_halt(void)
411{
412 machine_ops.halt();
413}
diff --git a/arch/x86/kernel/reboot_64.c b/arch/x86/kernel/reboot_64.c
deleted file mode 100644
index 53620a92a8fd..000000000000
--- a/arch/x86/kernel/reboot_64.c
+++ /dev/null
@@ -1,176 +0,0 @@
1/* Various gunk just to reboot the machine. */
2#include <linux/module.h>
3#include <linux/reboot.h>
4#include <linux/init.h>
5#include <linux/smp.h>
6#include <linux/kernel.h>
7#include <linux/ctype.h>
8#include <linux/string.h>
9#include <linux/pm.h>
10#include <linux/kdebug.h>
11#include <linux/sched.h>
12#include <asm/io.h>
13#include <asm/delay.h>
14#include <asm/desc.h>
15#include <asm/hw_irq.h>
16#include <asm/system.h>
17#include <asm/pgtable.h>
18#include <asm/tlbflush.h>
19#include <asm/apic.h>
20#include <asm/hpet.h>
21#include <asm/gart.h>
22
23/*
24 * Power off function, if any
25 */
26void (*pm_power_off)(void);
27EXPORT_SYMBOL(pm_power_off);
28
29static long no_idt[3];
30static enum {
31 BOOT_TRIPLE = 't',
32 BOOT_KBD = 'k'
33} reboot_type = BOOT_KBD;
34static int reboot_mode = 0;
35int reboot_force;
36
37/* reboot=t[riple] | k[bd] [, [w]arm | [c]old]
38 warm Don't set the cold reboot flag
39 cold Set the cold reboot flag
40 triple Force a triple fault (init)
41 kbd Use the keyboard controller. cold reset (default)
42 force Avoid anything that could hang.
43 */
44static int __init reboot_setup(char *str)
45{
46 for (;;) {
47 switch (*str) {
48 case 'w':
49 reboot_mode = 0x1234;
50 break;
51
52 case 'c':
53 reboot_mode = 0;
54 break;
55
56 case 't':
57 case 'b':
58 case 'k':
59 reboot_type = *str;
60 break;
61 case 'f':
62 reboot_force = 1;
63 break;
64 }
65 if((str = strchr(str,',')) != NULL)
66 str++;
67 else
68 break;
69 }
70 return 1;
71}
72
73__setup("reboot=", reboot_setup);
74
75static inline void kb_wait(void)
76{
77 int i;
78
79 for (i=0; i<0x10000; i++)
80 if ((inb_p(0x64) & 0x02) == 0)
81 break;
82}
83
84void machine_shutdown(void)
85{
86 unsigned long flags;
87
88 /* Stop the cpus and apics */
89#ifdef CONFIG_SMP
90 int reboot_cpu_id;
91
92 /* The boot cpu is always logical cpu 0 */
93 reboot_cpu_id = 0;
94
95 /* Make certain the cpu I'm about to reboot on is online */
96 if (!cpu_isset(reboot_cpu_id, cpu_online_map)) {
97 reboot_cpu_id = smp_processor_id();
98 }
99
100 /* Make certain I only run on the appropriate processor */
101 set_cpus_allowed(current, cpumask_of_cpu(reboot_cpu_id));
102
103 /* O.K Now that I'm on the appropriate processor,
104 * stop all of the others.
105 */
106 smp_send_stop();
107#endif
108
109 local_irq_save(flags);
110
111#ifndef CONFIG_SMP
112 disable_local_APIC();
113#endif
114
115 disable_IO_APIC();
116
117#ifdef CONFIG_HPET_TIMER
118 hpet_disable();
119#endif
120 local_irq_restore(flags);
121
122 pci_iommu_shutdown();
123}
124
125void machine_emergency_restart(void)
126{
127 int i;
128
129 /* Tell the BIOS if we want cold or warm reboot */
130 *((unsigned short *)__va(0x472)) = reboot_mode;
131
132 for (;;) {
133 /* Could also try the reset bit in the Hammer NB */
134 switch (reboot_type) {
135 case BOOT_KBD:
136 for (i=0; i<10; i++) {
137 kb_wait();
138 udelay(50);
139 outb(0xfe,0x64); /* pulse reset low */
140 udelay(50);
141 }
142
143 case BOOT_TRIPLE:
144 load_idt((const struct desc_ptr *)&no_idt);
145 __asm__ __volatile__("int3");
146
147 reboot_type = BOOT_KBD;
148 break;
149 }
150 }
151}
152
153void machine_restart(char * __unused)
154{
155 printk("machine restart\n");
156
157 if (!reboot_force) {
158 machine_shutdown();
159 }
160 machine_emergency_restart();
161}
162
163void machine_halt(void)
164{
165}
166
167void machine_power_off(void)
168{
169 if (pm_power_off) {
170 if (!reboot_force) {
171 machine_shutdown();
172 }
173 pm_power_off();
174 }
175}
176
diff --git a/arch/x86/kernel/reboot_fixups_32.c b/arch/x86/kernel/reboot_fixups_32.c
index f452726c0fe2..dec0b5ec25c2 100644
--- a/arch/x86/kernel/reboot_fixups_32.c
+++ b/arch/x86/kernel/reboot_fixups_32.c
@@ -30,6 +30,19 @@ static void cs5536_warm_reset(struct pci_dev *dev)
30 udelay(50); /* shouldn't get here but be safe and spin a while */ 30 udelay(50); /* shouldn't get here but be safe and spin a while */
31} 31}
32 32
33static void rdc321x_reset(struct pci_dev *dev)
34{
35 unsigned i;
36 /* Voluntary reset the watchdog timer */
37 outl(0x80003840, 0xCF8);
38 /* Generate a CPU reset on next tick */
39 i = inl(0xCFC);
40 /* Use the minimum timer resolution */
41 i |= 0x1600;
42 outl(i, 0xCFC);
43 outb(1, 0x92);
44}
45
33struct device_fixup { 46struct device_fixup {
34 unsigned int vendor; 47 unsigned int vendor;
35 unsigned int device; 48 unsigned int device;
@@ -40,6 +53,7 @@ static struct device_fixup fixups_table[] = {
40{ PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, cs5530a_warm_reset }, 53{ PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, cs5530a_warm_reset },
41{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, cs5536_warm_reset }, 54{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, cs5536_warm_reset },
42{ PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE, cs5530a_warm_reset }, 55{ PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE, cs5530a_warm_reset },
56{ PCI_VENDOR_ID_RDC, PCI_DEVICE_ID_RDC_R6030, rdc321x_reset },
43}; 57};
44 58
45/* 59/*
diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c
new file mode 100644
index 000000000000..eb9b1a198f5e
--- /dev/null
+++ b/arch/x86/kernel/rtc.c
@@ -0,0 +1,204 @@
1/*
2 * RTC related functions
3 */
4#include <linux/acpi.h>
5#include <linux/bcd.h>
6#include <linux/mc146818rtc.h>
7
8#include <asm/time.h>
9#include <asm/vsyscall.h>
10
11#ifdef CONFIG_X86_32
12# define CMOS_YEARS_OFFS 1900
13/*
14 * This is a special lock that is owned by the CPU and holds the index
15 * register we are working with. It is required for NMI access to the
16 * CMOS/RTC registers. See include/asm-i386/mc146818rtc.h for details.
17 */
18volatile unsigned long cmos_lock = 0;
19EXPORT_SYMBOL(cmos_lock);
20#else
21/*
22 * x86-64 systems only exists since 2002.
23 * This will work up to Dec 31, 2100
24 */
25# define CMOS_YEARS_OFFS 2000
26#endif
27
28DEFINE_SPINLOCK(rtc_lock);
29EXPORT_SYMBOL(rtc_lock);
30
31/*
32 * In order to set the CMOS clock precisely, set_rtc_mmss has to be
33 * called 500 ms after the second nowtime has started, because when
34 * nowtime is written into the registers of the CMOS clock, it will
35 * jump to the next second precisely 500 ms later. Check the Motorola
36 * MC146818A or Dallas DS12887 data sheet for details.
37 *
38 * BUG: This routine does not handle hour overflow properly; it just
39 * sets the minutes. Usually you'll only notice that after reboot!
40 */
41int mach_set_rtc_mmss(unsigned long nowtime)
42{
43 int retval = 0;
44 int real_seconds, real_minutes, cmos_minutes;
45 unsigned char save_control, save_freq_select;
46
47 /* tell the clock it's being set */
48 save_control = CMOS_READ(RTC_CONTROL);
49 CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
50
51 /* stop and reset prescaler */
52 save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
53 CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
54
55 cmos_minutes = CMOS_READ(RTC_MINUTES);
56 if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
57 BCD_TO_BIN(cmos_minutes);
58
59 /*
60 * since we're only adjusting minutes and seconds,
61 * don't interfere with hour overflow. This avoids
62 * messing with unknown time zones but requires your
63 * RTC not to be off by more than 15 minutes
64 */
65 real_seconds = nowtime % 60;
66 real_minutes = nowtime / 60;
67 /* correct for half hour time zone */
68 if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
69 real_minutes += 30;
70 real_minutes %= 60;
71
72 if (abs(real_minutes - cmos_minutes) < 30) {
73 if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
74 BIN_TO_BCD(real_seconds);
75 BIN_TO_BCD(real_minutes);
76 }
77 CMOS_WRITE(real_seconds,RTC_SECONDS);
78 CMOS_WRITE(real_minutes,RTC_MINUTES);
79 } else {
80 printk(KERN_WARNING
81 "set_rtc_mmss: can't update from %d to %d\n",
82 cmos_minutes, real_minutes);
83 retval = -1;
84 }
85
86 /* The following flags have to be released exactly in this order,
87 * otherwise the DS12887 (popular MC146818A clone with integrated
88 * battery and quartz) will not reset the oscillator and will not
89 * update precisely 500 ms later. You won't find this mentioned in
90 * the Dallas Semiconductor data sheets, but who believes data
91 * sheets anyway ... -- Markus Kuhn
92 */
93 CMOS_WRITE(save_control, RTC_CONTROL);
94 CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
95
96 return retval;
97}
98
99unsigned long mach_get_cmos_time(void)
100{
101 unsigned int year, mon, day, hour, min, sec, century = 0;
102
103 /*
104 * If UIP is clear, then we have >= 244 microseconds before
105 * RTC registers will be updated. Spec sheet says that this
106 * is the reliable way to read RTC - registers. If UIP is set
107 * then the register access might be invalid.
108 */
109 while ((CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
110 cpu_relax();
111
112 sec = CMOS_READ(RTC_SECONDS);
113 min = CMOS_READ(RTC_MINUTES);
114 hour = CMOS_READ(RTC_HOURS);
115 day = CMOS_READ(RTC_DAY_OF_MONTH);
116 mon = CMOS_READ(RTC_MONTH);
117 year = CMOS_READ(RTC_YEAR);
118
119#if defined(CONFIG_ACPI) && defined(CONFIG_X86_64)
120 /* CHECKME: Is this really 64bit only ??? */
121 if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID &&
122 acpi_gbl_FADT.century)
123 century = CMOS_READ(acpi_gbl_FADT.century);
124#endif
125
126 if (RTC_ALWAYS_BCD || !(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY)) {
127 BCD_TO_BIN(sec);
128 BCD_TO_BIN(min);
129 BCD_TO_BIN(hour);
130 BCD_TO_BIN(day);
131 BCD_TO_BIN(mon);
132 BCD_TO_BIN(year);
133 }
134
135 if (century) {
136 BCD_TO_BIN(century);
137 year += century * 100;
138 printk(KERN_INFO "Extended CMOS year: %d\n", century * 100);
139 } else {
140 year += CMOS_YEARS_OFFS;
141 if (year < 1970)
142 year += 100;
143 }
144
145 return mktime(year, mon, day, hour, min, sec);
146}
147
148/* Routines for accessing the CMOS RAM/RTC. */
149unsigned char rtc_cmos_read(unsigned char addr)
150{
151 unsigned char val;
152
153 lock_cmos_prefix(addr);
154 outb_p(addr, RTC_PORT(0));
155 val = inb_p(RTC_PORT(1));
156 lock_cmos_suffix(addr);
157 return val;
158}
159EXPORT_SYMBOL(rtc_cmos_read);
160
161void rtc_cmos_write(unsigned char val, unsigned char addr)
162{
163 lock_cmos_prefix(addr);
164 outb_p(addr, RTC_PORT(0));
165 outb_p(val, RTC_PORT(1));
166 lock_cmos_suffix(addr);
167}
168EXPORT_SYMBOL(rtc_cmos_write);
169
170static int set_rtc_mmss(unsigned long nowtime)
171{
172 int retval;
173 unsigned long flags;
174
175 spin_lock_irqsave(&rtc_lock, flags);
176 retval = set_wallclock(nowtime);
177 spin_unlock_irqrestore(&rtc_lock, flags);
178
179 return retval;
180}
181
182/* not static: needed by APM */
183unsigned long read_persistent_clock(void)
184{
185 unsigned long retval, flags;
186
187 spin_lock_irqsave(&rtc_lock, flags);
188 retval = get_wallclock();
189 spin_unlock_irqrestore(&rtc_lock, flags);
190
191 return retval;
192}
193
194int update_persistent_clock(struct timespec now)
195{
196 return set_rtc_mmss(now.tv_sec);
197}
198
199unsigned long long native_read_tsc(void)
200{
201 return __native_read_tsc();
202}
203EXPORT_SYMBOL(native_read_tsc);
204
diff --git a/arch/x86/kernel/setup64.c b/arch/x86/kernel/setup64.c
index 3558ac78c926..309366f8f603 100644
--- a/arch/x86/kernel/setup64.c
+++ b/arch/x86/kernel/setup64.c
@@ -24,7 +24,11 @@
24#include <asm/sections.h> 24#include <asm/sections.h>
25#include <asm/setup.h> 25#include <asm/setup.h>
26 26
27#ifndef CONFIG_DEBUG_BOOT_PARAMS
27struct boot_params __initdata boot_params; 28struct boot_params __initdata boot_params;
29#else
30struct boot_params boot_params;
31#endif
28 32
29cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE; 33cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE;
30 34
@@ -37,6 +41,8 @@ struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table };
37char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned"))); 41char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned")));
38 42
39unsigned long __supported_pte_mask __read_mostly = ~0UL; 43unsigned long __supported_pte_mask __read_mostly = ~0UL;
44EXPORT_SYMBOL_GPL(__supported_pte_mask);
45
40static int do_not_nx __cpuinitdata = 0; 46static int do_not_nx __cpuinitdata = 0;
41 47
42/* noexec=on|off 48/* noexec=on|off
@@ -80,6 +86,43 @@ static int __init nonx32_setup(char *str)
80__setup("noexec32=", nonx32_setup); 86__setup("noexec32=", nonx32_setup);
81 87
82/* 88/*
89 * Copy data used in early init routines from the initial arrays to the
90 * per cpu data areas. These arrays then become expendable and the
91 * *_early_ptr's are zeroed indicating that the static arrays are gone.
92 */
93static void __init setup_per_cpu_maps(void)
94{
95 int cpu;
96
97 for_each_possible_cpu(cpu) {
98#ifdef CONFIG_SMP
99 if (per_cpu_offset(cpu)) {
100#endif
101 per_cpu(x86_cpu_to_apicid, cpu) =
102 x86_cpu_to_apicid_init[cpu];
103 per_cpu(x86_bios_cpu_apicid, cpu) =
104 x86_bios_cpu_apicid_init[cpu];
105#ifdef CONFIG_NUMA
106 per_cpu(x86_cpu_to_node_map, cpu) =
107 x86_cpu_to_node_map_init[cpu];
108#endif
109#ifdef CONFIG_SMP
110 }
111 else
112 printk(KERN_NOTICE "per_cpu_offset zero for cpu %d\n",
113 cpu);
114#endif
115 }
116
117 /* indicate the early static arrays will soon be gone */
118 x86_cpu_to_apicid_early_ptr = NULL;
119 x86_bios_cpu_apicid_early_ptr = NULL;
120#ifdef CONFIG_NUMA
121 x86_cpu_to_node_map_early_ptr = NULL;
122#endif
123}
124
125/*
83 * Great future plan: 126 * Great future plan:
84 * Declare PDA itself and support (irqstack,tss,pgd) as per cpu data. 127 * Declare PDA itself and support (irqstack,tss,pgd) as per cpu data.
85 * Always point %gs to its beginning 128 * Always point %gs to its beginning
@@ -100,18 +143,21 @@ void __init setup_per_cpu_areas(void)
100 for_each_cpu_mask (i, cpu_possible_map) { 143 for_each_cpu_mask (i, cpu_possible_map) {
101 char *ptr; 144 char *ptr;
102 145
103 if (!NODE_DATA(cpu_to_node(i))) { 146 if (!NODE_DATA(early_cpu_to_node(i))) {
104 printk("cpu with no node %d, num_online_nodes %d\n", 147 printk("cpu with no node %d, num_online_nodes %d\n",
105 i, num_online_nodes()); 148 i, num_online_nodes());
106 ptr = alloc_bootmem_pages(size); 149 ptr = alloc_bootmem_pages(size);
107 } else { 150 } else {
108 ptr = alloc_bootmem_pages_node(NODE_DATA(cpu_to_node(i)), size); 151 ptr = alloc_bootmem_pages_node(NODE_DATA(early_cpu_to_node(i)), size);
109 } 152 }
110 if (!ptr) 153 if (!ptr)
111 panic("Cannot allocate cpu data for CPU %d\n", i); 154 panic("Cannot allocate cpu data for CPU %d\n", i);
112 cpu_pda(i)->data_offset = ptr - __per_cpu_start; 155 cpu_pda(i)->data_offset = ptr - __per_cpu_start;
113 memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start); 156 memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
114 } 157 }
158
159 /* setup percpu data maps early */
160 setup_per_cpu_maps();
115} 161}
116 162
117void pda_init(int cpu) 163void pda_init(int cpu)
@@ -169,7 +215,8 @@ void syscall_init(void)
169#endif 215#endif
170 216
171 /* Flags to clear on syscall */ 217 /* Flags to clear on syscall */
172 wrmsrl(MSR_SYSCALL_MASK, EF_TF|EF_DF|EF_IE|0x3000); 218 wrmsrl(MSR_SYSCALL_MASK,
219 X86_EFLAGS_TF|X86_EFLAGS_DF|X86_EFLAGS_IF|X86_EFLAGS_IOPL);
173} 220}
174 221
175void __cpuinit check_efer(void) 222void __cpuinit check_efer(void)
@@ -227,7 +274,7 @@ void __cpuinit cpu_init (void)
227 * and set up the GDT descriptor: 274 * and set up the GDT descriptor:
228 */ 275 */
229 if (cpu) 276 if (cpu)
230 memcpy(cpu_gdt(cpu), cpu_gdt_table, GDT_SIZE); 277 memcpy(get_cpu_gdt_table(cpu), cpu_gdt_table, GDT_SIZE);
231 278
232 cpu_gdt_descr[cpu].size = GDT_SIZE; 279 cpu_gdt_descr[cpu].size = GDT_SIZE;
233 load_gdt((const struct desc_ptr *)&cpu_gdt_descr[cpu]); 280 load_gdt((const struct desc_ptr *)&cpu_gdt_descr[cpu]);
@@ -257,10 +304,10 @@ void __cpuinit cpu_init (void)
257 v, cpu); 304 v, cpu);
258 } 305 }
259 estacks += PAGE_SIZE << order[v]; 306 estacks += PAGE_SIZE << order[v];
260 orig_ist->ist[v] = t->ist[v] = (unsigned long)estacks; 307 orig_ist->ist[v] = t->x86_tss.ist[v] = (unsigned long)estacks;
261 } 308 }
262 309
263 t->io_bitmap_base = offsetof(struct tss_struct, io_bitmap); 310 t->x86_tss.io_bitmap_base = offsetof(struct tss_struct, io_bitmap);
264 /* 311 /*
265 * <= is required because the CPU will access up to 312 * <= is required because the CPU will access up to
266 * 8 bits beyond the end of the IO permission bitmap. 313 * 8 bits beyond the end of the IO permission bitmap.
diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c
index 9c24b45b513c..62adc5f20be5 100644
--- a/arch/x86/kernel/setup_32.c
+++ b/arch/x86/kernel/setup_32.c
@@ -44,9 +44,12 @@
44#include <linux/crash_dump.h> 44#include <linux/crash_dump.h>
45#include <linux/dmi.h> 45#include <linux/dmi.h>
46#include <linux/pfn.h> 46#include <linux/pfn.h>
47#include <linux/pci.h>
48#include <linux/init_ohci1394_dma.h>
47 49
48#include <video/edid.h> 50#include <video/edid.h>
49 51
52#include <asm/mtrr.h>
50#include <asm/apic.h> 53#include <asm/apic.h>
51#include <asm/e820.h> 54#include <asm/e820.h>
52#include <asm/mpspec.h> 55#include <asm/mpspec.h>
@@ -67,14 +70,83 @@
67 address, and must not be in the .bss segment! */ 70 address, and must not be in the .bss segment! */
68unsigned long init_pg_tables_end __initdata = ~0UL; 71unsigned long init_pg_tables_end __initdata = ~0UL;
69 72
70int disable_pse __cpuinitdata = 0;
71
72/* 73/*
73 * Machine setup.. 74 * Machine setup..
74 */ 75 */
75extern struct resource code_resource; 76static struct resource data_resource = {
76extern struct resource data_resource; 77 .name = "Kernel data",
77extern struct resource bss_resource; 78 .start = 0,
79 .end = 0,
80 .flags = IORESOURCE_BUSY | IORESOURCE_MEM
81};
82
83static struct resource code_resource = {
84 .name = "Kernel code",
85 .start = 0,
86 .end = 0,
87 .flags = IORESOURCE_BUSY | IORESOURCE_MEM
88};
89
90static struct resource bss_resource = {
91 .name = "Kernel bss",
92 .start = 0,
93 .end = 0,
94 .flags = IORESOURCE_BUSY | IORESOURCE_MEM
95};
96
97static struct resource video_ram_resource = {
98 .name = "Video RAM area",
99 .start = 0xa0000,
100 .end = 0xbffff,
101 .flags = IORESOURCE_BUSY | IORESOURCE_MEM
102};
103
104static struct resource standard_io_resources[] = { {
105 .name = "dma1",
106 .start = 0x0000,
107 .end = 0x001f,
108 .flags = IORESOURCE_BUSY | IORESOURCE_IO
109}, {
110 .name = "pic1",
111 .start = 0x0020,
112 .end = 0x0021,
113 .flags = IORESOURCE_BUSY | IORESOURCE_IO
114}, {
115 .name = "timer0",
116 .start = 0x0040,
117 .end = 0x0043,
118 .flags = IORESOURCE_BUSY | IORESOURCE_IO
119}, {
120 .name = "timer1",
121 .start = 0x0050,
122 .end = 0x0053,
123 .flags = IORESOURCE_BUSY | IORESOURCE_IO
124}, {
125 .name = "keyboard",
126 .start = 0x0060,
127 .end = 0x006f,
128 .flags = IORESOURCE_BUSY | IORESOURCE_IO
129}, {
130 .name = "dma page reg",
131 .start = 0x0080,
132 .end = 0x008f,
133 .flags = IORESOURCE_BUSY | IORESOURCE_IO
134}, {
135 .name = "pic2",
136 .start = 0x00a0,
137 .end = 0x00a1,
138 .flags = IORESOURCE_BUSY | IORESOURCE_IO
139}, {
140 .name = "dma2",
141 .start = 0x00c0,
142 .end = 0x00df,
143 .flags = IORESOURCE_BUSY | IORESOURCE_IO
144}, {
145 .name = "fpu",
146 .start = 0x00f0,
147 .end = 0x00ff,
148 .flags = IORESOURCE_BUSY | IORESOURCE_IO
149} };
78 150
79/* cpu data as detected by the assembly code in head.S */ 151/* cpu data as detected by the assembly code in head.S */
80struct cpuinfo_x86 new_cpu_data __cpuinitdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 }; 152struct cpuinfo_x86 new_cpu_data __cpuinitdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
@@ -116,13 +188,17 @@ extern int root_mountflags;
116 188
117unsigned long saved_videomode; 189unsigned long saved_videomode;
118 190
119#define RAMDISK_IMAGE_START_MASK 0x07FF 191#define RAMDISK_IMAGE_START_MASK 0x07FF
120#define RAMDISK_PROMPT_FLAG 0x8000 192#define RAMDISK_PROMPT_FLAG 0x8000
121#define RAMDISK_LOAD_FLAG 0x4000 193#define RAMDISK_LOAD_FLAG 0x4000
122 194
123static char __initdata command_line[COMMAND_LINE_SIZE]; 195static char __initdata command_line[COMMAND_LINE_SIZE];
124 196
197#ifndef CONFIG_DEBUG_BOOT_PARAMS
125struct boot_params __initdata boot_params; 198struct boot_params __initdata boot_params;
199#else
200struct boot_params boot_params;
201#endif
126 202
127#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) 203#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
128struct edd edd; 204struct edd edd;
@@ -166,8 +242,7 @@ static int __init parse_mem(char *arg)
166 return -EINVAL; 242 return -EINVAL;
167 243
168 if (strcmp(arg, "nopentium") == 0) { 244 if (strcmp(arg, "nopentium") == 0) {
169 clear_bit(X86_FEATURE_PSE, boot_cpu_data.x86_capability); 245 setup_clear_cpu_cap(X86_FEATURE_PSE);
170 disable_pse = 1;
171 } else { 246 } else {
172 /* If the user specifies memory size, we 247 /* If the user specifies memory size, we
173 * limit the BIOS-provided memory map to 248 * limit the BIOS-provided memory map to
@@ -176,7 +251,7 @@ static int __init parse_mem(char *arg)
176 * trim the existing memory map. 251 * trim the existing memory map.
177 */ 252 */
178 unsigned long long mem_size; 253 unsigned long long mem_size;
179 254
180 mem_size = memparse(arg, &arg); 255 mem_size = memparse(arg, &arg);
181 limit_regions(mem_size); 256 limit_regions(mem_size);
182 user_defined_memmap = 1; 257 user_defined_memmap = 1;
@@ -315,7 +390,7 @@ static void __init reserve_ebda_region(void)
315 unsigned int addr; 390 unsigned int addr;
316 addr = get_bios_ebda(); 391 addr = get_bios_ebda();
317 if (addr) 392 if (addr)
318 reserve_bootmem(addr, PAGE_SIZE); 393 reserve_bootmem(addr, PAGE_SIZE);
319} 394}
320 395
321#ifndef CONFIG_NEED_MULTIPLE_NODES 396#ifndef CONFIG_NEED_MULTIPLE_NODES
@@ -420,6 +495,100 @@ static inline void __init reserve_crashkernel(void)
420{} 495{}
421#endif 496#endif
422 497
498#ifdef CONFIG_BLK_DEV_INITRD
499
500static bool do_relocate_initrd = false;
501
502static void __init reserve_initrd(void)
503{
504 unsigned long ramdisk_image = boot_params.hdr.ramdisk_image;
505 unsigned long ramdisk_size = boot_params.hdr.ramdisk_size;
506 unsigned long ramdisk_end = ramdisk_image + ramdisk_size;
507 unsigned long end_of_lowmem = max_low_pfn << PAGE_SHIFT;
508 unsigned long ramdisk_here;
509
510 initrd_start = 0;
511
512 if (!boot_params.hdr.type_of_loader ||
513 !ramdisk_image || !ramdisk_size)
514 return; /* No initrd provided by bootloader */
515
516 if (ramdisk_end < ramdisk_image) {
517 printk(KERN_ERR "initrd wraps around end of memory, "
518 "disabling initrd\n");
519 return;
520 }
521 if (ramdisk_size >= end_of_lowmem/2) {
522 printk(KERN_ERR "initrd too large to handle, "
523 "disabling initrd\n");
524 return;
525 }
526 if (ramdisk_end <= end_of_lowmem) {
527 /* All in lowmem, easy case */
528 reserve_bootmem(ramdisk_image, ramdisk_size);
529 initrd_start = ramdisk_image + PAGE_OFFSET;
530 initrd_end = initrd_start+ramdisk_size;
531 return;
532 }
533
534 /* We need to move the initrd down into lowmem */
535 ramdisk_here = (end_of_lowmem - ramdisk_size) & PAGE_MASK;
536
537 /* Note: this includes all the lowmem currently occupied by
538 the initrd, we rely on that fact to keep the data intact. */
539 reserve_bootmem(ramdisk_here, ramdisk_size);
540 initrd_start = ramdisk_here + PAGE_OFFSET;
541 initrd_end = initrd_start + ramdisk_size;
542
543 do_relocate_initrd = true;
544}
545
546#define MAX_MAP_CHUNK (NR_FIX_BTMAPS << PAGE_SHIFT)
547
548static void __init relocate_initrd(void)
549{
550 unsigned long ramdisk_image = boot_params.hdr.ramdisk_image;
551 unsigned long ramdisk_size = boot_params.hdr.ramdisk_size;
552 unsigned long end_of_lowmem = max_low_pfn << PAGE_SHIFT;
553 unsigned long ramdisk_here;
554 unsigned long slop, clen, mapaddr;
555 char *p, *q;
556
557 if (!do_relocate_initrd)
558 return;
559
560 ramdisk_here = initrd_start - PAGE_OFFSET;
561
562 q = (char *)initrd_start;
563
564 /* Copy any lowmem portion of the initrd */
565 if (ramdisk_image < end_of_lowmem) {
566 clen = end_of_lowmem - ramdisk_image;
567 p = (char *)__va(ramdisk_image);
568 memcpy(q, p, clen);
569 q += clen;
570 ramdisk_image += clen;
571 ramdisk_size -= clen;
572 }
573
574 /* Copy the highmem portion of the initrd */
575 while (ramdisk_size) {
576 slop = ramdisk_image & ~PAGE_MASK;
577 clen = ramdisk_size;
578 if (clen > MAX_MAP_CHUNK-slop)
579 clen = MAX_MAP_CHUNK-slop;
580 mapaddr = ramdisk_image & PAGE_MASK;
581 p = early_ioremap(mapaddr, clen+slop);
582 memcpy(q, p+slop, clen);
583 early_iounmap(p, clen+slop);
584 q += clen;
585 ramdisk_image += clen;
586 ramdisk_size -= clen;
587 }
588}
589
590#endif /* CONFIG_BLK_DEV_INITRD */
591
423void __init setup_bootmem_allocator(void) 592void __init setup_bootmem_allocator(void)
424{ 593{
425 unsigned long bootmap_size; 594 unsigned long bootmap_size;
@@ -475,26 +644,10 @@ void __init setup_bootmem_allocator(void)
475 */ 644 */
476 find_smp_config(); 645 find_smp_config();
477#endif 646#endif
478 numa_kva_reserve();
479#ifdef CONFIG_BLK_DEV_INITRD 647#ifdef CONFIG_BLK_DEV_INITRD
480 if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) { 648 reserve_initrd();
481 unsigned long ramdisk_image = boot_params.hdr.ramdisk_image;
482 unsigned long ramdisk_size = boot_params.hdr.ramdisk_size;
483 unsigned long ramdisk_end = ramdisk_image + ramdisk_size;
484 unsigned long end_of_lowmem = max_low_pfn << PAGE_SHIFT;
485
486 if (ramdisk_end <= end_of_lowmem) {
487 reserve_bootmem(ramdisk_image, ramdisk_size);
488 initrd_start = ramdisk_image + PAGE_OFFSET;
489 initrd_end = initrd_start+ramdisk_size;
490 } else {
491 printk(KERN_ERR "initrd extends beyond end of memory "
492 "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
493 ramdisk_end, end_of_lowmem);
494 initrd_start = 0;
495 }
496 }
497#endif 649#endif
650 numa_kva_reserve();
498 reserve_crashkernel(); 651 reserve_crashkernel();
499} 652}
500 653
@@ -545,17 +698,11 @@ void __init setup_arch(char **cmdline_p)
545 memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); 698 memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
546 pre_setup_arch_hook(); 699 pre_setup_arch_hook();
547 early_cpu_init(); 700 early_cpu_init();
701 early_ioremap_init();
548 702
549 /*
550 * FIXME: This isn't an official loader_type right
551 * now but does currently work with elilo.
552 * If we were configured as an EFI kernel, check to make
553 * sure that we were loaded correctly from elilo and that
554 * the system table is valid. If not, then initialize normally.
555 */
556#ifdef CONFIG_EFI 703#ifdef CONFIG_EFI
557 if ((boot_params.hdr.type_of_loader == 0x50) && 704 if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature,
558 boot_params.efi_info.efi_systab) 705 "EL32", 4))
559 efi_enabled = 1; 706 efi_enabled = 1;
560#endif 707#endif
561 708
@@ -579,12 +726,9 @@ void __init setup_arch(char **cmdline_p)
579 rd_doload = ((boot_params.hdr.ram_size & RAMDISK_LOAD_FLAG) != 0); 726 rd_doload = ((boot_params.hdr.ram_size & RAMDISK_LOAD_FLAG) != 0);
580#endif 727#endif
581 ARCH_SETUP 728 ARCH_SETUP
582 if (efi_enabled) 729
583 efi_init(); 730 printk(KERN_INFO "BIOS-provided physical RAM map:\n");
584 else { 731 print_memory_map(memory_setup());
585 printk(KERN_INFO "BIOS-provided physical RAM map:\n");
586 print_memory_map(memory_setup());
587 }
588 732
589 copy_edd(); 733 copy_edd();
590 734
@@ -612,8 +756,16 @@ void __init setup_arch(char **cmdline_p)
612 strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); 756 strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
613 *cmdline_p = command_line; 757 *cmdline_p = command_line;
614 758
759 if (efi_enabled)
760 efi_init();
761
615 max_low_pfn = setup_memory(); 762 max_low_pfn = setup_memory();
616 763
764 /* update e820 for memory not covered by WB MTRRs */
765 mtrr_bp_init();
766 if (mtrr_trim_uncached_memory(max_pfn))
767 max_low_pfn = setup_memory();
768
617#ifdef CONFIG_VMI 769#ifdef CONFIG_VMI
618 /* 770 /*
619 * Must be after max_low_pfn is determined, and before kernel 771 * Must be after max_low_pfn is determined, and before kernel
@@ -636,6 +788,16 @@ void __init setup_arch(char **cmdline_p)
636 smp_alloc_memory(); /* AP processor realmode stacks in low memory*/ 788 smp_alloc_memory(); /* AP processor realmode stacks in low memory*/
637#endif 789#endif
638 paging_init(); 790 paging_init();
791
792 /*
793 * NOTE: On x86-32, only from this point on, fixmaps are ready for use.
794 */
795
796#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
797 if (init_ohci1394_dma_early)
798 init_ohci1394_dma_on_all_controllers();
799#endif
800
639 remapped_pgdat_init(); 801 remapped_pgdat_init();
640 sparse_init(); 802 sparse_init();
641 zone_sizes_init(); 803 zone_sizes_init();
@@ -644,15 +806,19 @@ void __init setup_arch(char **cmdline_p)
644 * NOTE: at this point the bootmem allocator is fully available. 806 * NOTE: at this point the bootmem allocator is fully available.
645 */ 807 */
646 808
809#ifdef CONFIG_BLK_DEV_INITRD
810 relocate_initrd();
811#endif
812
647 paravirt_post_allocator_init(); 813 paravirt_post_allocator_init();
648 814
649 dmi_scan_machine(); 815 dmi_scan_machine();
650 816
817 io_delay_init();
818
651#ifdef CONFIG_X86_GENERICARCH 819#ifdef CONFIG_X86_GENERICARCH
652 generic_apic_probe(); 820 generic_apic_probe();
653#endif 821#endif
654 if (efi_enabled)
655 efi_map_memmap();
656 822
657#ifdef CONFIG_ACPI 823#ifdef CONFIG_ACPI
658 /* 824 /*
@@ -661,9 +827,7 @@ void __init setup_arch(char **cmdline_p)
661 acpi_boot_table_init(); 827 acpi_boot_table_init();
662#endif 828#endif
663 829
664#ifdef CONFIG_PCI
665 early_quirks(); 830 early_quirks();
666#endif
667 831
668#ifdef CONFIG_ACPI 832#ifdef CONFIG_ACPI
669 acpi_boot_init(); 833 acpi_boot_init();
@@ -692,3 +856,26 @@ void __init setup_arch(char **cmdline_p)
692#endif 856#endif
693#endif 857#endif
694} 858}
859
860/*
861 * Request address space for all standard resources
862 *
863 * This is called just before pcibios_init(), which is also a
864 * subsys_initcall, but is linked in later (in arch/i386/pci/common.c).
865 */
866static int __init request_standard_resources(void)
867{
868 int i;
869
870 printk(KERN_INFO "Setting up standard PCI resources\n");
871 init_iomem_resources(&code_resource, &data_resource, &bss_resource);
872
873 request_resource(&iomem_resource, &video_ram_resource);
874
875 /* request I/O space for devices used on all i[345]86 PCs */
876 for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++)
877 request_resource(&ioport_resource, &standard_io_resources[i]);
878 return 0;
879}
880
881subsys_initcall(request_standard_resources);
diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c
index 30d94d1d5f5f..77fb87bf6e5a 100644
--- a/arch/x86/kernel/setup_64.c
+++ b/arch/x86/kernel/setup_64.c
@@ -30,6 +30,7 @@
30#include <linux/crash_dump.h> 30#include <linux/crash_dump.h>
31#include <linux/root_dev.h> 31#include <linux/root_dev.h>
32#include <linux/pci.h> 32#include <linux/pci.h>
33#include <linux/efi.h>
33#include <linux/acpi.h> 34#include <linux/acpi.h>
34#include <linux/kallsyms.h> 35#include <linux/kallsyms.h>
35#include <linux/edd.h> 36#include <linux/edd.h>
@@ -39,10 +40,13 @@
39#include <linux/dmi.h> 40#include <linux/dmi.h>
40#include <linux/dma-mapping.h> 41#include <linux/dma-mapping.h>
41#include <linux/ctype.h> 42#include <linux/ctype.h>
43#include <linux/uaccess.h>
44#include <linux/init_ohci1394_dma.h>
42 45
43#include <asm/mtrr.h> 46#include <asm/mtrr.h>
44#include <asm/uaccess.h> 47#include <asm/uaccess.h>
45#include <asm/system.h> 48#include <asm/system.h>
49#include <asm/vsyscall.h>
46#include <asm/io.h> 50#include <asm/io.h>
47#include <asm/smp.h> 51#include <asm/smp.h>
48#include <asm/msr.h> 52#include <asm/msr.h>
@@ -50,6 +54,7 @@
50#include <video/edid.h> 54#include <video/edid.h>
51#include <asm/e820.h> 55#include <asm/e820.h>
52#include <asm/dma.h> 56#include <asm/dma.h>
57#include <asm/gart.h>
53#include <asm/mpspec.h> 58#include <asm/mpspec.h>
54#include <asm/mmu_context.h> 59#include <asm/mmu_context.h>
55#include <asm/proto.h> 60#include <asm/proto.h>
@@ -59,6 +64,15 @@
59#include <asm/sections.h> 64#include <asm/sections.h>
60#include <asm/dmi.h> 65#include <asm/dmi.h>
61#include <asm/cacheflush.h> 66#include <asm/cacheflush.h>
67#include <asm/mce.h>
68#include <asm/ds.h>
69#include <asm/topology.h>
70
71#ifdef CONFIG_PARAVIRT
72#include <asm/paravirt.h>
73#else
74#define ARCH_SETUP
75#endif
62 76
63/* 77/*
64 * Machine setup.. 78 * Machine setup..
@@ -67,6 +81,8 @@
67struct cpuinfo_x86 boot_cpu_data __read_mostly; 81struct cpuinfo_x86 boot_cpu_data __read_mostly;
68EXPORT_SYMBOL(boot_cpu_data); 82EXPORT_SYMBOL(boot_cpu_data);
69 83
84__u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata;
85
70unsigned long mmu_cr4_features; 86unsigned long mmu_cr4_features;
71 87
72/* Boot loader ID as an integer, for the benefit of proc_dointvec */ 88/* Boot loader ID as an integer, for the benefit of proc_dointvec */
@@ -76,7 +92,7 @@ unsigned long saved_video_mode;
76 92
77int force_mwait __cpuinitdata; 93int force_mwait __cpuinitdata;
78 94
79/* 95/*
80 * Early DMI memory 96 * Early DMI memory
81 */ 97 */
82int dmi_alloc_index; 98int dmi_alloc_index;
@@ -122,25 +138,27 @@ struct resource standard_io_resources[] = {
122 138
123#define IORESOURCE_RAM (IORESOURCE_BUSY | IORESOURCE_MEM) 139#define IORESOURCE_RAM (IORESOURCE_BUSY | IORESOURCE_MEM)
124 140
125struct resource data_resource = { 141static struct resource data_resource = {
126 .name = "Kernel data", 142 .name = "Kernel data",
127 .start = 0, 143 .start = 0,
128 .end = 0, 144 .end = 0,
129 .flags = IORESOURCE_RAM, 145 .flags = IORESOURCE_RAM,
130}; 146};
131struct resource code_resource = { 147static struct resource code_resource = {
132 .name = "Kernel code", 148 .name = "Kernel code",
133 .start = 0, 149 .start = 0,
134 .end = 0, 150 .end = 0,
135 .flags = IORESOURCE_RAM, 151 .flags = IORESOURCE_RAM,
136}; 152};
137struct resource bss_resource = { 153static struct resource bss_resource = {
138 .name = "Kernel bss", 154 .name = "Kernel bss",
139 .start = 0, 155 .start = 0,
140 .end = 0, 156 .end = 0,
141 .flags = IORESOURCE_RAM, 157 .flags = IORESOURCE_RAM,
142}; 158};
143 159
160static void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c);
161
144#ifdef CONFIG_PROC_VMCORE 162#ifdef CONFIG_PROC_VMCORE
145/* elfcorehdr= specifies the location of elf core header 163/* elfcorehdr= specifies the location of elf core header
146 * stored by the crashed kernel. This option will be passed 164 * stored by the crashed kernel. This option will be passed
@@ -166,12 +184,12 @@ contig_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
166 bootmap_size = bootmem_bootmap_pages(end_pfn)<<PAGE_SHIFT; 184 bootmap_size = bootmem_bootmap_pages(end_pfn)<<PAGE_SHIFT;
167 bootmap = find_e820_area(0, end_pfn<<PAGE_SHIFT, bootmap_size); 185 bootmap = find_e820_area(0, end_pfn<<PAGE_SHIFT, bootmap_size);
168 if (bootmap == -1L) 186 if (bootmap == -1L)
169 panic("Cannot find bootmem map of size %ld\n",bootmap_size); 187 panic("Cannot find bootmem map of size %ld\n", bootmap_size);
170 bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn); 188 bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn);
171 e820_register_active_regions(0, start_pfn, end_pfn); 189 e820_register_active_regions(0, start_pfn, end_pfn);
172 free_bootmem_with_active_regions(0, end_pfn); 190 free_bootmem_with_active_regions(0, end_pfn);
173 reserve_bootmem(bootmap, bootmap_size); 191 reserve_bootmem(bootmap, bootmap_size);
174} 192}
175#endif 193#endif
176 194
177#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) 195#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
@@ -205,7 +223,8 @@ static void __init reserve_crashkernel(void)
205 unsigned long long crash_size, crash_base; 223 unsigned long long crash_size, crash_base;
206 int ret; 224 int ret;
207 225
208 free_mem = ((unsigned long long)max_low_pfn - min_low_pfn) << PAGE_SHIFT; 226 free_mem =
227 ((unsigned long long)max_low_pfn - min_low_pfn) << PAGE_SHIFT;
209 228
210 ret = parse_crashkernel(boot_command_line, free_mem, 229 ret = parse_crashkernel(boot_command_line, free_mem,
211 &crash_size, &crash_base); 230 &crash_size, &crash_base);
@@ -229,33 +248,21 @@ static inline void __init reserve_crashkernel(void)
229{} 248{}
230#endif 249#endif
231 250
232#define EBDA_ADDR_POINTER 0x40E 251/* Overridden in paravirt.c if CONFIG_PARAVIRT */
233 252void __attribute__((weak)) __init memory_setup(void)
234unsigned __initdata ebda_addr;
235unsigned __initdata ebda_size;
236
237static void discover_ebda(void)
238{ 253{
239 /* 254 machine_specific_memory_setup();
240 * there is a real-mode segmented pointer pointing to the
241 * 4K EBDA area at 0x40E
242 */
243 ebda_addr = *(unsigned short *)__va(EBDA_ADDR_POINTER);
244 ebda_addr <<= 4;
245
246 ebda_size = *(unsigned short *)__va(ebda_addr);
247
248 /* Round EBDA up to pages */
249 if (ebda_size == 0)
250 ebda_size = 1;
251 ebda_size <<= 10;
252 ebda_size = round_up(ebda_size + (ebda_addr & ~PAGE_MASK), PAGE_SIZE);
253 if (ebda_size > 64*1024)
254 ebda_size = 64*1024;
255} 255}
256 256
257/*
258 * setup_arch - architecture-specific boot-time initializations
259 *
260 * Note: On x86_64, fixmaps are ready for use even before this is called.
261 */
257void __init setup_arch(char **cmdline_p) 262void __init setup_arch(char **cmdline_p)
258{ 263{
264 unsigned i;
265
259 printk(KERN_INFO "Command line: %s\n", boot_command_line); 266 printk(KERN_INFO "Command line: %s\n", boot_command_line);
260 267
261 ROOT_DEV = old_decode_dev(boot_params.hdr.root_dev); 268 ROOT_DEV = old_decode_dev(boot_params.hdr.root_dev);
@@ -269,7 +276,15 @@ void __init setup_arch(char **cmdline_p)
269 rd_prompt = ((boot_params.hdr.ram_size & RAMDISK_PROMPT_FLAG) != 0); 276 rd_prompt = ((boot_params.hdr.ram_size & RAMDISK_PROMPT_FLAG) != 0);
270 rd_doload = ((boot_params.hdr.ram_size & RAMDISK_LOAD_FLAG) != 0); 277 rd_doload = ((boot_params.hdr.ram_size & RAMDISK_LOAD_FLAG) != 0);
271#endif 278#endif
272 setup_memory_region(); 279#ifdef CONFIG_EFI
280 if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature,
281 "EL64", 4))
282 efi_enabled = 1;
283#endif
284
285 ARCH_SETUP
286
287 memory_setup();
273 copy_edd(); 288 copy_edd();
274 289
275 if (!boot_params.hdr.root_flags) 290 if (!boot_params.hdr.root_flags)
@@ -293,27 +308,47 @@ void __init setup_arch(char **cmdline_p)
293 308
294 parse_early_param(); 309 parse_early_param();
295 310
311#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
312 if (init_ohci1394_dma_early)
313 init_ohci1394_dma_on_all_controllers();
314#endif
315
296 finish_e820_parsing(); 316 finish_e820_parsing();
297 317
318 early_gart_iommu_check();
319
298 e820_register_active_regions(0, 0, -1UL); 320 e820_register_active_regions(0, 0, -1UL);
299 /* 321 /*
300 * partially used pages are not usable - thus 322 * partially used pages are not usable - thus
301 * we are rounding upwards: 323 * we are rounding upwards:
302 */ 324 */
303 end_pfn = e820_end_of_ram(); 325 end_pfn = e820_end_of_ram();
326 /* update e820 for memory not covered by WB MTRRs */
327 mtrr_bp_init();
328 if (mtrr_trim_uncached_memory(end_pfn)) {
329 e820_register_active_regions(0, 0, -1UL);
330 end_pfn = e820_end_of_ram();
331 }
332
304 num_physpages = end_pfn; 333 num_physpages = end_pfn;
305 334
306 check_efer(); 335 check_efer();
307 336
308 discover_ebda();
309
310 init_memory_mapping(0, (end_pfn_map << PAGE_SHIFT)); 337 init_memory_mapping(0, (end_pfn_map << PAGE_SHIFT));
338 if (efi_enabled)
339 efi_init();
311 340
312 dmi_scan_machine(); 341 dmi_scan_machine();
313 342
343 io_delay_init();
344
314#ifdef CONFIG_SMP 345#ifdef CONFIG_SMP
315 /* setup to use the static apicid table during kernel startup */ 346 /* setup to use the early static init tables during kernel startup */
316 x86_cpu_to_apicid_ptr = (void *)&x86_cpu_to_apicid_init; 347 x86_cpu_to_apicid_early_ptr = (void *)x86_cpu_to_apicid_init;
348 x86_bios_cpu_apicid_early_ptr = (void *)x86_bios_cpu_apicid_init;
349#ifdef CONFIG_NUMA
350 x86_cpu_to_node_map_early_ptr = (void *)x86_cpu_to_node_map_init;
351#endif
317#endif 352#endif
318 353
319#ifdef CONFIG_ACPI 354#ifdef CONFIG_ACPI
@@ -340,48 +375,26 @@ void __init setup_arch(char **cmdline_p)
340#endif 375#endif
341 376
342#ifdef CONFIG_NUMA 377#ifdef CONFIG_NUMA
343 numa_initmem_init(0, end_pfn); 378 numa_initmem_init(0, end_pfn);
344#else 379#else
345 contig_initmem_init(0, end_pfn); 380 contig_initmem_init(0, end_pfn);
346#endif 381#endif
347 382
348 /* Reserve direct mapping */ 383 early_res_to_bootmem();
349 reserve_bootmem_generic(table_start << PAGE_SHIFT,
350 (table_end - table_start) << PAGE_SHIFT);
351
352 /* reserve kernel */
353 reserve_bootmem_generic(__pa_symbol(&_text),
354 __pa_symbol(&_end) - __pa_symbol(&_text));
355 384
385#ifdef CONFIG_ACPI_SLEEP
356 /* 386 /*
357 * reserve physical page 0 - it's a special BIOS page on many boxes, 387 * Reserve low memory region for sleep support.
358 * enabling clean reboots, SMP operation, laptop functions.
359 */ 388 */
360 reserve_bootmem_generic(0, PAGE_SIZE); 389 acpi_reserve_bootmem();
361
362 /* reserve ebda region */
363 if (ebda_addr)
364 reserve_bootmem_generic(ebda_addr, ebda_size);
365#ifdef CONFIG_NUMA
366 /* reserve nodemap region */
367 if (nodemap_addr)
368 reserve_bootmem_generic(nodemap_addr, nodemap_size);
369#endif 390#endif
370 391
371#ifdef CONFIG_SMP 392 if (efi_enabled)
372 /* Reserve SMP trampoline */ 393 efi_reserve_bootmem();
373 reserve_bootmem_generic(SMP_TRAMPOLINE_BASE, 2*PAGE_SIZE);
374#endif
375 394
376#ifdef CONFIG_ACPI_SLEEP
377 /* 395 /*
378 * Reserve low memory region for sleep support. 396 * Find and reserve possible boot-time SMP configuration:
379 */ 397 */
380 acpi_reserve_bootmem();
381#endif
382 /*
383 * Find and reserve possible boot-time SMP configuration:
384 */
385 find_smp_config(); 398 find_smp_config();
386#ifdef CONFIG_BLK_DEV_INITRD 399#ifdef CONFIG_BLK_DEV_INITRD
387 if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) { 400 if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) {
@@ -395,6 +408,8 @@ void __init setup_arch(char **cmdline_p)
395 initrd_start = ramdisk_image + PAGE_OFFSET; 408 initrd_start = ramdisk_image + PAGE_OFFSET;
396 initrd_end = initrd_start+ramdisk_size; 409 initrd_end = initrd_start+ramdisk_size;
397 } else { 410 } else {
411 /* Assumes everything on node 0 */
412 free_bootmem(ramdisk_image, ramdisk_size);
398 printk(KERN_ERR "initrd extends beyond end of memory " 413 printk(KERN_ERR "initrd extends beyond end of memory "
399 "(0x%08lx > 0x%08lx)\ndisabling initrd\n", 414 "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
400 ramdisk_end, end_of_mem); 415 ramdisk_end, end_of_mem);
@@ -404,17 +419,10 @@ void __init setup_arch(char **cmdline_p)
404#endif 419#endif
405 reserve_crashkernel(); 420 reserve_crashkernel();
406 paging_init(); 421 paging_init();
422 map_vsyscall();
407 423
408#ifdef CONFIG_PCI
409 early_quirks(); 424 early_quirks();
410#endif
411 425
412 /*
413 * set this early, so we dont allocate cpu0
414 * if MADT list doesnt list BSP first
415 * mpparse.c/MP_processor_info() allocates logical cpu numbers.
416 */
417 cpu_set(0, cpu_present_map);
418#ifdef CONFIG_ACPI 426#ifdef CONFIG_ACPI
419 /* 427 /*
420 * Read APIC and some other early information from ACPI tables. 428 * Read APIC and some other early information from ACPI tables.
@@ -430,25 +438,24 @@ void __init setup_arch(char **cmdline_p)
430 if (smp_found_config) 438 if (smp_found_config)
431 get_smp_config(); 439 get_smp_config();
432 init_apic_mappings(); 440 init_apic_mappings();
441 ioapic_init_mappings();
433 442
434 /* 443 /*
435 * We trust e820 completely. No explicit ROM probing in memory. 444 * We trust e820 completely. No explicit ROM probing in memory.
436 */ 445 */
437 e820_reserve_resources(); 446 e820_reserve_resources(&code_resource, &data_resource, &bss_resource);
438 e820_mark_nosave_regions(); 447 e820_mark_nosave_regions();
439 448
440 {
441 unsigned i;
442 /* request I/O space for devices used on all i[345]86 PCs */ 449 /* request I/O space for devices used on all i[345]86 PCs */
443 for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++) 450 for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++)
444 request_resource(&ioport_resource, &standard_io_resources[i]); 451 request_resource(&ioport_resource, &standard_io_resources[i]);
445 }
446 452
447 e820_setup_gap(); 453 e820_setup_gap();
448 454
449#ifdef CONFIG_VT 455#ifdef CONFIG_VT
450#if defined(CONFIG_VGA_CONSOLE) 456#if defined(CONFIG_VGA_CONSOLE)
451 conswitchp = &vga_con; 457 if (!efi_enabled || (efi_mem_type(0xa0000) != EFI_CONVENTIONAL_MEMORY))
458 conswitchp = &vga_con;
452#elif defined(CONFIG_DUMMY_CONSOLE) 459#elif defined(CONFIG_DUMMY_CONSOLE)
453 conswitchp = &dummy_con; 460 conswitchp = &dummy_con;
454#endif 461#endif
@@ -479,9 +486,10 @@ static void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c)
479 486
480 if (n >= 0x80000005) { 487 if (n >= 0x80000005) {
481 cpuid(0x80000005, &dummy, &ebx, &ecx, &edx); 488 cpuid(0x80000005, &dummy, &ebx, &ecx, &edx);
482 printk(KERN_INFO "CPU: L1 I Cache: %dK (%d bytes/line), D cache %dK (%d bytes/line)\n", 489 printk(KERN_INFO "CPU: L1 I Cache: %dK (%d bytes/line), "
483 edx>>24, edx&0xFF, ecx>>24, ecx&0xFF); 490 "D cache %dK (%d bytes/line)\n",
484 c->x86_cache_size=(ecx>>24)+(edx>>24); 491 edx>>24, edx&0xFF, ecx>>24, ecx&0xFF);
492 c->x86_cache_size = (ecx>>24) + (edx>>24);
485 /* On K8 L1 TLB is inclusive, so don't count it */ 493 /* On K8 L1 TLB is inclusive, so don't count it */
486 c->x86_tlbsize = 0; 494 c->x86_tlbsize = 0;
487 } 495 }
@@ -495,11 +503,8 @@ static void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c)
495 printk(KERN_INFO "CPU: L2 Cache: %dK (%d bytes/line)\n", 503 printk(KERN_INFO "CPU: L2 Cache: %dK (%d bytes/line)\n",
496 c->x86_cache_size, ecx & 0xFF); 504 c->x86_cache_size, ecx & 0xFF);
497 } 505 }
498
499 if (n >= 0x80000007)
500 cpuid(0x80000007, &dummy, &dummy, &dummy, &c->x86_power);
501 if (n >= 0x80000008) { 506 if (n >= 0x80000008) {
502 cpuid(0x80000008, &eax, &dummy, &dummy, &dummy); 507 cpuid(0x80000008, &eax, &dummy, &dummy, &dummy);
503 c->x86_virt_bits = (eax >> 8) & 0xff; 508 c->x86_virt_bits = (eax >> 8) & 0xff;
504 c->x86_phys_bits = eax & 0xff; 509 c->x86_phys_bits = eax & 0xff;
505 } 510 }
@@ -508,14 +513,15 @@ static void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c)
508#ifdef CONFIG_NUMA 513#ifdef CONFIG_NUMA
509static int nearby_node(int apicid) 514static int nearby_node(int apicid)
510{ 515{
511 int i; 516 int i, node;
517
512 for (i = apicid - 1; i >= 0; i--) { 518 for (i = apicid - 1; i >= 0; i--) {
513 int node = apicid_to_node[i]; 519 node = apicid_to_node[i];
514 if (node != NUMA_NO_NODE && node_online(node)) 520 if (node != NUMA_NO_NODE && node_online(node))
515 return node; 521 return node;
516 } 522 }
517 for (i = apicid + 1; i < MAX_LOCAL_APIC; i++) { 523 for (i = apicid + 1; i < MAX_LOCAL_APIC; i++) {
518 int node = apicid_to_node[i]; 524 node = apicid_to_node[i];
519 if (node != NUMA_NO_NODE && node_online(node)) 525 if (node != NUMA_NO_NODE && node_online(node))
520 return node; 526 return node;
521 } 527 }
@@ -527,7 +533,7 @@ static int nearby_node(int apicid)
527 * On a AMD dual core setup the lower bits of the APIC id distingush the cores. 533 * On a AMD dual core setup the lower bits of the APIC id distingush the cores.
528 * Assumes number of cores is a power of two. 534 * Assumes number of cores is a power of two.
529 */ 535 */
530static void __init amd_detect_cmp(struct cpuinfo_x86 *c) 536static void __cpuinit amd_detect_cmp(struct cpuinfo_x86 *c)
531{ 537{
532#ifdef CONFIG_SMP 538#ifdef CONFIG_SMP
533 unsigned bits; 539 unsigned bits;
@@ -536,7 +542,54 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
536 int node = 0; 542 int node = 0;
537 unsigned apicid = hard_smp_processor_id(); 543 unsigned apicid = hard_smp_processor_id();
538#endif 544#endif
539 unsigned ecx = cpuid_ecx(0x80000008); 545 bits = c->x86_coreid_bits;
546
547 /* Low order bits define the core id (index of core in socket) */
548 c->cpu_core_id = c->phys_proc_id & ((1 << bits)-1);
549 /* Convert the APIC ID into the socket ID */
550 c->phys_proc_id = phys_pkg_id(bits);
551
552#ifdef CONFIG_NUMA
553 node = c->phys_proc_id;
554 if (apicid_to_node[apicid] != NUMA_NO_NODE)
555 node = apicid_to_node[apicid];
556 if (!node_online(node)) {
557 /* Two possibilities here:
558 - The CPU is missing memory and no node was created.
559 In that case try picking one from a nearby CPU
560 - The APIC IDs differ from the HyperTransport node IDs
561 which the K8 northbridge parsing fills in.
562 Assume they are all increased by a constant offset,
563 but in the same order as the HT nodeids.
564 If that doesn't result in a usable node fall back to the
565 path for the previous case. */
566
567 int ht_nodeid = apicid - (cpu_data(0).phys_proc_id << bits);
568
569 if (ht_nodeid >= 0 &&
570 apicid_to_node[ht_nodeid] != NUMA_NO_NODE)
571 node = apicid_to_node[ht_nodeid];
572 /* Pick a nearby node */
573 if (!node_online(node))
574 node = nearby_node(apicid);
575 }
576 numa_set_node(cpu, node);
577
578 printk(KERN_INFO "CPU %d/%x -> Node %d\n", cpu, apicid, node);
579#endif
580#endif
581}
582
583static void __cpuinit early_init_amd_mc(struct cpuinfo_x86 *c)
584{
585#ifdef CONFIG_SMP
586 unsigned bits, ecx;
587
588 /* Multi core CPU? */
589 if (c->extended_cpuid_level < 0x80000008)
590 return;
591
592 ecx = cpuid_ecx(0x80000008);
540 593
541 c->x86_max_cores = (ecx & 0xff) + 1; 594 c->x86_max_cores = (ecx & 0xff) + 1;
542 595
@@ -549,37 +602,8 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
549 bits++; 602 bits++;
550 } 603 }
551 604
552 /* Low order bits define the core id (index of core in socket) */ 605 c->x86_coreid_bits = bits;
553 c->cpu_core_id = c->phys_proc_id & ((1 << bits)-1);
554 /* Convert the APIC ID into the socket ID */
555 c->phys_proc_id = phys_pkg_id(bits);
556
557#ifdef CONFIG_NUMA
558 node = c->phys_proc_id;
559 if (apicid_to_node[apicid] != NUMA_NO_NODE)
560 node = apicid_to_node[apicid];
561 if (!node_online(node)) {
562 /* Two possibilities here:
563 - The CPU is missing memory and no node was created.
564 In that case try picking one from a nearby CPU
565 - The APIC IDs differ from the HyperTransport node IDs
566 which the K8 northbridge parsing fills in.
567 Assume they are all increased by a constant offset,
568 but in the same order as the HT nodeids.
569 If that doesn't result in a usable node fall back to the
570 path for the previous case. */
571 int ht_nodeid = apicid - (cpu_data(0).phys_proc_id << bits);
572 if (ht_nodeid >= 0 &&
573 apicid_to_node[ht_nodeid] != NUMA_NO_NODE)
574 node = apicid_to_node[ht_nodeid];
575 /* Pick a nearby node */
576 if (!node_online(node))
577 node = nearby_node(apicid);
578 }
579 numa_set_node(cpu, node);
580 606
581 printk(KERN_INFO "CPU %d/%x -> Node %d\n", cpu, apicid, node);
582#endif
583#endif 607#endif
584} 608}
585 609
@@ -595,8 +619,8 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
595/* AMD systems with C1E don't have a working lAPIC timer. Check for that. */ 619/* AMD systems with C1E don't have a working lAPIC timer. Check for that. */
596static __cpuinit int amd_apic_timer_broken(void) 620static __cpuinit int amd_apic_timer_broken(void)
597{ 621{
598 u32 lo, hi; 622 u32 lo, hi, eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
599 u32 eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE); 623
600 switch (eax & CPUID_XFAM) { 624 switch (eax & CPUID_XFAM) {
601 case CPUID_XFAM_K8: 625 case CPUID_XFAM_K8:
602 if ((eax & CPUID_XMOD) < CPUID_XMOD_REV_F) 626 if ((eax & CPUID_XMOD) < CPUID_XMOD_REV_F)
@@ -614,6 +638,15 @@ static __cpuinit int amd_apic_timer_broken(void)
614 return 0; 638 return 0;
615} 639}
616 640
641static void __cpuinit early_init_amd(struct cpuinfo_x86 *c)
642{
643 early_init_amd_mc(c);
644
645 /* c->x86_power is 8000_0007 edx. Bit 8 is constant TSC */
646 if (c->x86_power & (1<<8))
647 set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
648}
649
617static void __cpuinit init_amd(struct cpuinfo_x86 *c) 650static void __cpuinit init_amd(struct cpuinfo_x86 *c)
618{ 651{
619 unsigned level; 652 unsigned level;
@@ -624,7 +657,7 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
624 /* 657 /*
625 * Disable TLB flush filter by setting HWCR.FFDIS on K8 658 * Disable TLB flush filter by setting HWCR.FFDIS on K8
626 * bit 6 of msr C001_0015 659 * bit 6 of msr C001_0015
627 * 660 *
628 * Errata 63 for SH-B3 steppings 661 * Errata 63 for SH-B3 steppings
629 * Errata 122 for all steppings (F+ have it disabled by default) 662 * Errata 122 for all steppings (F+ have it disabled by default)
630 */ 663 */
@@ -637,35 +670,32 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
637 670
638 /* Bit 31 in normal CPUID used for nonstandard 3DNow ID; 671 /* Bit 31 in normal CPUID used for nonstandard 3DNow ID;
639 3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */ 672 3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */
640 clear_bit(0*32+31, &c->x86_capability); 673 clear_bit(0*32+31, (unsigned long *)&c->x86_capability);
641 674
642 /* On C+ stepping K8 rep microcode works well for copy/memset */ 675 /* On C+ stepping K8 rep microcode works well for copy/memset */
643 level = cpuid_eax(1); 676 level = cpuid_eax(1);
644 if (c->x86 == 15 && ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58)) 677 if (c->x86 == 15 && ((level >= 0x0f48 && level < 0x0f50) ||
645 set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability); 678 level >= 0x0f58))
679 set_cpu_cap(c, X86_FEATURE_REP_GOOD);
646 if (c->x86 == 0x10 || c->x86 == 0x11) 680 if (c->x86 == 0x10 || c->x86 == 0x11)
647 set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability); 681 set_cpu_cap(c, X86_FEATURE_REP_GOOD);
648 682
649 /* Enable workaround for FXSAVE leak */ 683 /* Enable workaround for FXSAVE leak */
650 if (c->x86 >= 6) 684 if (c->x86 >= 6)
651 set_bit(X86_FEATURE_FXSAVE_LEAK, &c->x86_capability); 685 set_cpu_cap(c, X86_FEATURE_FXSAVE_LEAK);
652 686
653 level = get_model_name(c); 687 level = get_model_name(c);
654 if (!level) { 688 if (!level) {
655 switch (c->x86) { 689 switch (c->x86) {
656 case 15: 690 case 15:
657 /* Should distinguish Models here, but this is only 691 /* Should distinguish Models here, but this is only
658 a fallback anyways. */ 692 a fallback anyways. */
659 strcpy(c->x86_model_id, "Hammer"); 693 strcpy(c->x86_model_id, "Hammer");
660 break; 694 break;
661 } 695 }
662 } 696 }
663 display_cacheinfo(c); 697 display_cacheinfo(c);
664 698
665 /* c->x86_power is 8000_0007 edx. Bit 8 is constant TSC */
666 if (c->x86_power & (1<<8))
667 set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability);
668
669 /* Multi core CPU? */ 699 /* Multi core CPU? */
670 if (c->extended_cpuid_level >= 0x80000008) 700 if (c->extended_cpuid_level >= 0x80000008)
671 amd_detect_cmp(c); 701 amd_detect_cmp(c);
@@ -677,41 +707,38 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
677 num_cache_leaves = 3; 707 num_cache_leaves = 3;
678 708
679 if (c->x86 == 0xf || c->x86 == 0x10 || c->x86 == 0x11) 709 if (c->x86 == 0xf || c->x86 == 0x10 || c->x86 == 0x11)
680 set_bit(X86_FEATURE_K8, &c->x86_capability); 710 set_cpu_cap(c, X86_FEATURE_K8);
681
682 /* RDTSC can be speculated around */
683 clear_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability);
684 711
685 /* Family 10 doesn't support C states in MWAIT so don't use it */ 712 /* MFENCE stops RDTSC speculation */
686 if (c->x86 == 0x10 && !force_mwait) 713 set_cpu_cap(c, X86_FEATURE_MFENCE_RDTSC);
687 clear_bit(X86_FEATURE_MWAIT, &c->x86_capability);
688 714
689 if (amd_apic_timer_broken()) 715 if (amd_apic_timer_broken())
690 disable_apic_timer = 1; 716 disable_apic_timer = 1;
691} 717}
692 718
693static void __cpuinit detect_ht(struct cpuinfo_x86 *c) 719void __cpuinit detect_ht(struct cpuinfo_x86 *c)
694{ 720{
695#ifdef CONFIG_SMP 721#ifdef CONFIG_SMP
696 u32 eax, ebx, ecx, edx; 722 u32 eax, ebx, ecx, edx;
697 int index_msb, core_bits; 723 int index_msb, core_bits;
698 724
699 cpuid(1, &eax, &ebx, &ecx, &edx); 725 cpuid(1, &eax, &ebx, &ecx, &edx);
700 726
701 727
702 if (!cpu_has(c, X86_FEATURE_HT)) 728 if (!cpu_has(c, X86_FEATURE_HT))
703 return; 729 return;
704 if (cpu_has(c, X86_FEATURE_CMP_LEGACY)) 730 if (cpu_has(c, X86_FEATURE_CMP_LEGACY))
705 goto out; 731 goto out;
706 732
707 smp_num_siblings = (ebx & 0xff0000) >> 16; 733 smp_num_siblings = (ebx & 0xff0000) >> 16;
708 734
709 if (smp_num_siblings == 1) { 735 if (smp_num_siblings == 1) {
710 printk(KERN_INFO "CPU: Hyper-Threading is disabled\n"); 736 printk(KERN_INFO "CPU: Hyper-Threading is disabled\n");
711 } else if (smp_num_siblings > 1 ) { 737 } else if (smp_num_siblings > 1) {
712 738
713 if (smp_num_siblings > NR_CPUS) { 739 if (smp_num_siblings > NR_CPUS) {
714 printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings); 740 printk(KERN_WARNING "CPU: Unsupported number of "
741 "siblings %d", smp_num_siblings);
715 smp_num_siblings = 1; 742 smp_num_siblings = 1;
716 return; 743 return;
717 } 744 }
@@ -721,7 +748,7 @@ static void __cpuinit detect_ht(struct cpuinfo_x86 *c)
721 748
722 smp_num_siblings = smp_num_siblings / c->x86_max_cores; 749 smp_num_siblings = smp_num_siblings / c->x86_max_cores;
723 750
724 index_msb = get_count_order(smp_num_siblings) ; 751 index_msb = get_count_order(smp_num_siblings);
725 752
726 core_bits = get_count_order(c->x86_max_cores); 753 core_bits = get_count_order(c->x86_max_cores);
727 754
@@ -730,8 +757,10 @@ static void __cpuinit detect_ht(struct cpuinfo_x86 *c)
730 } 757 }
731out: 758out:
732 if ((c->x86_max_cores * smp_num_siblings) > 1) { 759 if ((c->x86_max_cores * smp_num_siblings) > 1) {
733 printk(KERN_INFO "CPU: Physical Processor ID: %d\n", c->phys_proc_id); 760 printk(KERN_INFO "CPU: Physical Processor ID: %d\n",
734 printk(KERN_INFO "CPU: Processor Core ID: %d\n", c->cpu_core_id); 761 c->phys_proc_id);
762 printk(KERN_INFO "CPU: Processor Core ID: %d\n",
763 c->cpu_core_id);
735 } 764 }
736 765
737#endif 766#endif
@@ -773,28 +802,39 @@ static void srat_detect_node(void)
773#endif 802#endif
774} 803}
775 804
805static void __cpuinit early_init_intel(struct cpuinfo_x86 *c)
806{
807 if ((c->x86 == 0xf && c->x86_model >= 0x03) ||
808 (c->x86 == 0x6 && c->x86_model >= 0x0e))
809 set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability);
810}
811
776static void __cpuinit init_intel(struct cpuinfo_x86 *c) 812static void __cpuinit init_intel(struct cpuinfo_x86 *c)
777{ 813{
778 /* Cache sizes */ 814 /* Cache sizes */
779 unsigned n; 815 unsigned n;
780 816
781 init_intel_cacheinfo(c); 817 init_intel_cacheinfo(c);
782 if (c->cpuid_level > 9 ) { 818 if (c->cpuid_level > 9) {
783 unsigned eax = cpuid_eax(10); 819 unsigned eax = cpuid_eax(10);
784 /* Check for version and the number of counters */ 820 /* Check for version and the number of counters */
785 if ((eax & 0xff) && (((eax>>8) & 0xff) > 1)) 821 if ((eax & 0xff) && (((eax>>8) & 0xff) > 1))
786 set_bit(X86_FEATURE_ARCH_PERFMON, &c->x86_capability); 822 set_cpu_cap(c, X86_FEATURE_ARCH_PERFMON);
787 } 823 }
788 824
789 if (cpu_has_ds) { 825 if (cpu_has_ds) {
790 unsigned int l1, l2; 826 unsigned int l1, l2;
791 rdmsr(MSR_IA32_MISC_ENABLE, l1, l2); 827 rdmsr(MSR_IA32_MISC_ENABLE, l1, l2);
792 if (!(l1 & (1<<11))) 828 if (!(l1 & (1<<11)))
793 set_bit(X86_FEATURE_BTS, c->x86_capability); 829 set_cpu_cap(c, X86_FEATURE_BTS);
794 if (!(l1 & (1<<12))) 830 if (!(l1 & (1<<12)))
795 set_bit(X86_FEATURE_PEBS, c->x86_capability); 831 set_cpu_cap(c, X86_FEATURE_PEBS);
796 } 832 }
797 833
834
835 if (cpu_has_bts)
836 ds_init_intel(c);
837
798 n = c->extended_cpuid_level; 838 n = c->extended_cpuid_level;
799 if (n >= 0x80000008) { 839 if (n >= 0x80000008) {
800 unsigned eax = cpuid_eax(0x80000008); 840 unsigned eax = cpuid_eax(0x80000008);
@@ -811,14 +851,11 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
811 c->x86_cache_alignment = c->x86_clflush_size * 2; 851 c->x86_cache_alignment = c->x86_clflush_size * 2;
812 if ((c->x86 == 0xf && c->x86_model >= 0x03) || 852 if ((c->x86 == 0xf && c->x86_model >= 0x03) ||
813 (c->x86 == 0x6 && c->x86_model >= 0x0e)) 853 (c->x86 == 0x6 && c->x86_model >= 0x0e))
814 set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability); 854 set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
815 if (c->x86 == 6) 855 if (c->x86 == 6)
816 set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability); 856 set_cpu_cap(c, X86_FEATURE_REP_GOOD);
817 if (c->x86 == 15) 857 set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
818 set_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); 858 c->x86_max_cores = intel_num_cpu_cores(c);
819 else
820 clear_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability);
821 c->x86_max_cores = intel_num_cpu_cores(c);
822 859
823 srat_detect_node(); 860 srat_detect_node();
824} 861}
@@ -835,18 +872,12 @@ static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c)
835 c->x86_vendor = X86_VENDOR_UNKNOWN; 872 c->x86_vendor = X86_VENDOR_UNKNOWN;
836} 873}
837 874
838struct cpu_model_info {
839 int vendor;
840 int family;
841 char *model_names[16];
842};
843
844/* Do some early cpuid on the boot CPU to get some parameter that are 875/* Do some early cpuid on the boot CPU to get some parameter that are
845 needed before check_bugs. Everything advanced is in identify_cpu 876 needed before check_bugs. Everything advanced is in identify_cpu
846 below. */ 877 below. */
847void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c) 878static void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c)
848{ 879{
849 u32 tfms; 880 u32 tfms, xlvl;
850 881
851 c->loops_per_jiffy = loops_per_jiffy; 882 c->loops_per_jiffy = loops_per_jiffy;
852 c->x86_cache_size = -1; 883 c->x86_cache_size = -1;
@@ -857,6 +888,7 @@ void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c)
857 c->x86_clflush_size = 64; 888 c->x86_clflush_size = 64;
858 c->x86_cache_alignment = c->x86_clflush_size; 889 c->x86_cache_alignment = c->x86_clflush_size;
859 c->x86_max_cores = 1; 890 c->x86_max_cores = 1;
891 c->x86_coreid_bits = 0;
860 c->extended_cpuid_level = 0; 892 c->extended_cpuid_level = 0;
861 memset(&c->x86_capability, 0, sizeof c->x86_capability); 893 memset(&c->x86_capability, 0, sizeof c->x86_capability);
862 894
@@ -865,7 +897,7 @@ void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c)
865 (unsigned int *)&c->x86_vendor_id[0], 897 (unsigned int *)&c->x86_vendor_id[0],
866 (unsigned int *)&c->x86_vendor_id[8], 898 (unsigned int *)&c->x86_vendor_id[8],
867 (unsigned int *)&c->x86_vendor_id[4]); 899 (unsigned int *)&c->x86_vendor_id[4]);
868 900
869 get_cpu_vendor(c); 901 get_cpu_vendor(c);
870 902
871 /* Initialize the standard set of capabilities */ 903 /* Initialize the standard set of capabilities */
@@ -883,7 +915,7 @@ void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c)
883 c->x86 += (tfms >> 20) & 0xff; 915 c->x86 += (tfms >> 20) & 0xff;
884 if (c->x86 >= 0x6) 916 if (c->x86 >= 0x6)
885 c->x86_model += ((tfms >> 16) & 0xF) << 4; 917 c->x86_model += ((tfms >> 16) & 0xF) << 4;
886 if (c->x86_capability[0] & (1<<19)) 918 if (c->x86_capability[0] & (1<<19))
887 c->x86_clflush_size = ((misc >> 8) & 0xff) * 8; 919 c->x86_clflush_size = ((misc >> 8) & 0xff) * 8;
888 } else { 920 } else {
889 /* Have CPUID level 0 only - unheard of */ 921 /* Have CPUID level 0 only - unheard of */
@@ -893,18 +925,6 @@ void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c)
893#ifdef CONFIG_SMP 925#ifdef CONFIG_SMP
894 c->phys_proc_id = (cpuid_ebx(1) >> 24) & 0xff; 926 c->phys_proc_id = (cpuid_ebx(1) >> 24) & 0xff;
895#endif 927#endif
896}
897
898/*
899 * This does the hard work of actually picking apart the CPU stuff...
900 */
901void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
902{
903 int i;
904 u32 xlvl;
905
906 early_identify_cpu(c);
907
908 /* AMD-defined flags: level 0x80000001 */ 928 /* AMD-defined flags: level 0x80000001 */
909 xlvl = cpuid_eax(0x80000000); 929 xlvl = cpuid_eax(0x80000000);
910 c->extended_cpuid_level = xlvl; 930 c->extended_cpuid_level = xlvl;
@@ -925,6 +945,30 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
925 c->x86_capability[2] = cpuid_edx(0x80860001); 945 c->x86_capability[2] = cpuid_edx(0x80860001);
926 } 946 }
927 947
948 c->extended_cpuid_level = cpuid_eax(0x80000000);
949 if (c->extended_cpuid_level >= 0x80000007)
950 c->x86_power = cpuid_edx(0x80000007);
951
952 switch (c->x86_vendor) {
953 case X86_VENDOR_AMD:
954 early_init_amd(c);
955 break;
956 case X86_VENDOR_INTEL:
957 early_init_intel(c);
958 break;
959 }
960
961}
962
963/*
964 * This does the hard work of actually picking apart the CPU stuff...
965 */
966void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
967{
968 int i;
969
970 early_identify_cpu(c);
971
928 init_scattered_cpuid_features(c); 972 init_scattered_cpuid_features(c);
929 973
930 c->apicid = phys_pkg_id(0); 974 c->apicid = phys_pkg_id(0);
@@ -954,8 +998,7 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
954 break; 998 break;
955 } 999 }
956 1000
957 select_idle_routine(c); 1001 detect_ht(c);
958 detect_ht(c);
959 1002
960 /* 1003 /*
961 * On SMP, boot_cpu_data holds the common feature set between 1004 * On SMP, boot_cpu_data holds the common feature set between
@@ -965,32 +1008,56 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
965 */ 1008 */
966 if (c != &boot_cpu_data) { 1009 if (c != &boot_cpu_data) {
967 /* AND the already accumulated flags with these */ 1010 /* AND the already accumulated flags with these */
968 for (i = 0 ; i < NCAPINTS ; i++) 1011 for (i = 0; i < NCAPINTS; i++)
969 boot_cpu_data.x86_capability[i] &= c->x86_capability[i]; 1012 boot_cpu_data.x86_capability[i] &= c->x86_capability[i];
970 } 1013 }
971 1014
1015 /* Clear all flags overriden by options */
1016 for (i = 0; i < NCAPINTS; i++)
1017 c->x86_capability[i] ^= cleared_cpu_caps[i];
1018
972#ifdef CONFIG_X86_MCE 1019#ifdef CONFIG_X86_MCE
973 mcheck_init(c); 1020 mcheck_init(c);
974#endif 1021#endif
1022 select_idle_routine(c);
1023
975 if (c != &boot_cpu_data) 1024 if (c != &boot_cpu_data)
976 mtrr_ap_init(); 1025 mtrr_ap_init();
977#ifdef CONFIG_NUMA 1026#ifdef CONFIG_NUMA
978 numa_add_cpu(smp_processor_id()); 1027 numa_add_cpu(smp_processor_id());
979#endif 1028#endif
1029
1030}
1031
1032static __init int setup_noclflush(char *arg)
1033{
1034 setup_clear_cpu_cap(X86_FEATURE_CLFLSH);
1035 return 1;
980} 1036}
981 1037__setup("noclflush", setup_noclflush);
982 1038
983void __cpuinit print_cpu_info(struct cpuinfo_x86 *c) 1039void __cpuinit print_cpu_info(struct cpuinfo_x86 *c)
984{ 1040{
985 if (c->x86_model_id[0]) 1041 if (c->x86_model_id[0])
986 printk("%s", c->x86_model_id); 1042 printk(KERN_INFO "%s", c->x86_model_id);
987 1043
988 if (c->x86_mask || c->cpuid_level >= 0) 1044 if (c->x86_mask || c->cpuid_level >= 0)
989 printk(" stepping %02x\n", c->x86_mask); 1045 printk(KERN_CONT " stepping %02x\n", c->x86_mask);
990 else 1046 else
991 printk("\n"); 1047 printk(KERN_CONT "\n");
992} 1048}
993 1049
1050static __init int setup_disablecpuid(char *arg)
1051{
1052 int bit;
1053 if (get_option(&arg, &bit) && bit < NCAPINTS*32)
1054 setup_clear_cpu_cap(bit);
1055 else
1056 return 0;
1057 return 1;
1058}
1059__setup("clearcpuid=", setup_disablecpuid);
1060
994/* 1061/*
995 * Get CPU information for use by the procfs. 1062 * Get CPU information for use by the procfs.
996 */ 1063 */
@@ -998,9 +1065,9 @@ void __cpuinit print_cpu_info(struct cpuinfo_x86 *c)
998static int show_cpuinfo(struct seq_file *m, void *v) 1065static int show_cpuinfo(struct seq_file *m, void *v)
999{ 1066{
1000 struct cpuinfo_x86 *c = v; 1067 struct cpuinfo_x86 *c = v;
1001 int cpu = 0; 1068 int cpu = 0, i;
1002 1069
1003 /* 1070 /*
1004 * These flag bits must match the definitions in <asm/cpufeature.h>. 1071 * These flag bits must match the definitions in <asm/cpufeature.h>.
1005 * NULL means this bit is undefined or reserved; either way it doesn't 1072 * NULL means this bit is undefined or reserved; either way it doesn't
1006 * have meaning as far as Linux is concerned. Note that it's important 1073 * have meaning as far as Linux is concerned. Note that it's important
@@ -1010,10 +1077,10 @@ static int show_cpuinfo(struct seq_file *m, void *v)
1010 */ 1077 */
1011 static const char *const x86_cap_flags[] = { 1078 static const char *const x86_cap_flags[] = {
1012 /* Intel-defined */ 1079 /* Intel-defined */
1013 "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce", 1080 "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
1014 "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov", 1081 "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
1015 "pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx", 1082 "pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx",
1016 "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe", 1083 "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe",
1017 1084
1018 /* AMD-defined */ 1085 /* AMD-defined */
1019 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1086 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -1080,34 +1147,35 @@ static int show_cpuinfo(struct seq_file *m, void *v)
1080 cpu = c->cpu_index; 1147 cpu = c->cpu_index;
1081#endif 1148#endif
1082 1149
1083 seq_printf(m,"processor\t: %u\n" 1150 seq_printf(m, "processor\t: %u\n"
1084 "vendor_id\t: %s\n" 1151 "vendor_id\t: %s\n"
1085 "cpu family\t: %d\n" 1152 "cpu family\t: %d\n"
1086 "model\t\t: %d\n" 1153 "model\t\t: %d\n"
1087 "model name\t: %s\n", 1154 "model name\t: %s\n",
1088 (unsigned)cpu, 1155 (unsigned)cpu,
1089 c->x86_vendor_id[0] ? c->x86_vendor_id : "unknown", 1156 c->x86_vendor_id[0] ? c->x86_vendor_id : "unknown",
1090 c->x86, 1157 c->x86,
1091 (int)c->x86_model, 1158 (int)c->x86_model,
1092 c->x86_model_id[0] ? c->x86_model_id : "unknown"); 1159 c->x86_model_id[0] ? c->x86_model_id : "unknown");
1093 1160
1094 if (c->x86_mask || c->cpuid_level >= 0) 1161 if (c->x86_mask || c->cpuid_level >= 0)
1095 seq_printf(m, "stepping\t: %d\n", c->x86_mask); 1162 seq_printf(m, "stepping\t: %d\n", c->x86_mask);
1096 else 1163 else
1097 seq_printf(m, "stepping\t: unknown\n"); 1164 seq_printf(m, "stepping\t: unknown\n");
1098 1165
1099 if (cpu_has(c,X86_FEATURE_TSC)) { 1166 if (cpu_has(c, X86_FEATURE_TSC)) {
1100 unsigned int freq = cpufreq_quick_get((unsigned)cpu); 1167 unsigned int freq = cpufreq_quick_get((unsigned)cpu);
1168
1101 if (!freq) 1169 if (!freq)
1102 freq = cpu_khz; 1170 freq = cpu_khz;
1103 seq_printf(m, "cpu MHz\t\t: %u.%03u\n", 1171 seq_printf(m, "cpu MHz\t\t: %u.%03u\n",
1104 freq / 1000, (freq % 1000)); 1172 freq / 1000, (freq % 1000));
1105 } 1173 }
1106 1174
1107 /* Cache size */ 1175 /* Cache size */
1108 if (c->x86_cache_size >= 0) 1176 if (c->x86_cache_size >= 0)
1109 seq_printf(m, "cache size\t: %d KB\n", c->x86_cache_size); 1177 seq_printf(m, "cache size\t: %d KB\n", c->x86_cache_size);
1110 1178
1111#ifdef CONFIG_SMP 1179#ifdef CONFIG_SMP
1112 if (smp_num_siblings * c->x86_max_cores > 1) { 1180 if (smp_num_siblings * c->x86_max_cores > 1) {
1113 seq_printf(m, "physical id\t: %d\n", c->phys_proc_id); 1181 seq_printf(m, "physical id\t: %d\n", c->phys_proc_id);
@@ -1116,48 +1184,43 @@ static int show_cpuinfo(struct seq_file *m, void *v)
1116 seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id); 1184 seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id);
1117 seq_printf(m, "cpu cores\t: %d\n", c->booted_cores); 1185 seq_printf(m, "cpu cores\t: %d\n", c->booted_cores);
1118 } 1186 }
1119#endif 1187#endif
1120 1188
1121 seq_printf(m, 1189 seq_printf(m,
1122 "fpu\t\t: yes\n" 1190 "fpu\t\t: yes\n"
1123 "fpu_exception\t: yes\n" 1191 "fpu_exception\t: yes\n"
1124 "cpuid level\t: %d\n" 1192 "cpuid level\t: %d\n"
1125 "wp\t\t: yes\n" 1193 "wp\t\t: yes\n"
1126 "flags\t\t:", 1194 "flags\t\t:",
1127 c->cpuid_level); 1195 c->cpuid_level);
1128 1196
1129 { 1197 for (i = 0; i < 32*NCAPINTS; i++)
1130 int i; 1198 if (cpu_has(c, i) && x86_cap_flags[i] != NULL)
1131 for ( i = 0 ; i < 32*NCAPINTS ; i++ ) 1199 seq_printf(m, " %s", x86_cap_flags[i]);
1132 if (cpu_has(c, i) && x86_cap_flags[i] != NULL) 1200
1133 seq_printf(m, " %s", x86_cap_flags[i]);
1134 }
1135
1136 seq_printf(m, "\nbogomips\t: %lu.%02lu\n", 1201 seq_printf(m, "\nbogomips\t: %lu.%02lu\n",
1137 c->loops_per_jiffy/(500000/HZ), 1202 c->loops_per_jiffy/(500000/HZ),
1138 (c->loops_per_jiffy/(5000/HZ)) % 100); 1203 (c->loops_per_jiffy/(5000/HZ)) % 100);
1139 1204
1140 if (c->x86_tlbsize > 0) 1205 if (c->x86_tlbsize > 0)
1141 seq_printf(m, "TLB size\t: %d 4K pages\n", c->x86_tlbsize); 1206 seq_printf(m, "TLB size\t: %d 4K pages\n", c->x86_tlbsize);
1142 seq_printf(m, "clflush size\t: %d\n", c->x86_clflush_size); 1207 seq_printf(m, "clflush size\t: %d\n", c->x86_clflush_size);
1143 seq_printf(m, "cache_alignment\t: %d\n", c->x86_cache_alignment); 1208 seq_printf(m, "cache_alignment\t: %d\n", c->x86_cache_alignment);
1144 1209
1145 seq_printf(m, "address sizes\t: %u bits physical, %u bits virtual\n", 1210 seq_printf(m, "address sizes\t: %u bits physical, %u bits virtual\n",
1146 c->x86_phys_bits, c->x86_virt_bits); 1211 c->x86_phys_bits, c->x86_virt_bits);
1147 1212
1148 seq_printf(m, "power management:"); 1213 seq_printf(m, "power management:");
1149 { 1214 for (i = 0; i < 32; i++) {
1150 unsigned i; 1215 if (c->x86_power & (1 << i)) {
1151 for (i = 0; i < 32; i++) 1216 if (i < ARRAY_SIZE(x86_power_flags) &&
1152 if (c->x86_power & (1 << i)) { 1217 x86_power_flags[i])
1153 if (i < ARRAY_SIZE(x86_power_flags) && 1218 seq_printf(m, "%s%s",
1154 x86_power_flags[i]) 1219 x86_power_flags[i][0]?" ":"",
1155 seq_printf(m, "%s%s", 1220 x86_power_flags[i]);
1156 x86_power_flags[i][0]?" ":"", 1221 else
1157 x86_power_flags[i]); 1222 seq_printf(m, " [%d]", i);
1158 else 1223 }
1159 seq_printf(m, " [%d]", i);
1160 }
1161 } 1224 }
1162 1225
1163 seq_printf(m, "\n\n"); 1226 seq_printf(m, "\n\n");
@@ -1184,8 +1247,8 @@ static void c_stop(struct seq_file *m, void *v)
1184{ 1247{
1185} 1248}
1186 1249
1187struct seq_operations cpuinfo_op = { 1250const struct seq_operations cpuinfo_op = {
1188 .start =c_start, 1251 .start = c_start,
1189 .next = c_next, 1252 .next = c_next,
1190 .stop = c_stop, 1253 .stop = c_stop,
1191 .show = show_cpuinfo, 1254 .show = show_cpuinfo,
diff --git a/arch/x86/kernel/signal_32.c b/arch/x86/kernel/signal_32.c
index 9bdd83022f5f..caee1f002fed 100644
--- a/arch/x86/kernel/signal_32.c
+++ b/arch/x86/kernel/signal_32.c
@@ -23,6 +23,7 @@
23#include <asm/ucontext.h> 23#include <asm/ucontext.h>
24#include <asm/uaccess.h> 24#include <asm/uaccess.h>
25#include <asm/i387.h> 25#include <asm/i387.h>
26#include <asm/vdso.h>
26#include "sigframe_32.h" 27#include "sigframe_32.h"
27 28
28#define DEBUG_SIG 0 29#define DEBUG_SIG 0
@@ -81,14 +82,14 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,
81} 82}
82 83
83asmlinkage int 84asmlinkage int
84sys_sigaltstack(unsigned long ebx) 85sys_sigaltstack(unsigned long bx)
85{ 86{
86 /* This is needed to make gcc realize it doesn't own the "struct pt_regs" */ 87 /* This is needed to make gcc realize it doesn't own the "struct pt_regs" */
87 struct pt_regs *regs = (struct pt_regs *)&ebx; 88 struct pt_regs *regs = (struct pt_regs *)&bx;
88 const stack_t __user *uss = (const stack_t __user *)ebx; 89 const stack_t __user *uss = (const stack_t __user *)bx;
89 stack_t __user *uoss = (stack_t __user *)regs->ecx; 90 stack_t __user *uoss = (stack_t __user *)regs->cx;
90 91
91 return do_sigaltstack(uss, uoss, regs->esp); 92 return do_sigaltstack(uss, uoss, regs->sp);
92} 93}
93 94
94 95
@@ -109,12 +110,12 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *peax
109#define COPY_SEG(seg) \ 110#define COPY_SEG(seg) \
110 { unsigned short tmp; \ 111 { unsigned short tmp; \
111 err |= __get_user(tmp, &sc->seg); \ 112 err |= __get_user(tmp, &sc->seg); \
112 regs->x##seg = tmp; } 113 regs->seg = tmp; }
113 114
114#define COPY_SEG_STRICT(seg) \ 115#define COPY_SEG_STRICT(seg) \
115 { unsigned short tmp; \ 116 { unsigned short tmp; \
116 err |= __get_user(tmp, &sc->seg); \ 117 err |= __get_user(tmp, &sc->seg); \
117 regs->x##seg = tmp|3; } 118 regs->seg = tmp|3; }
118 119
119#define GET_SEG(seg) \ 120#define GET_SEG(seg) \
120 { unsigned short tmp; \ 121 { unsigned short tmp; \
@@ -130,22 +131,22 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *peax
130 COPY_SEG(fs); 131 COPY_SEG(fs);
131 COPY_SEG(es); 132 COPY_SEG(es);
132 COPY_SEG(ds); 133 COPY_SEG(ds);
133 COPY(edi); 134 COPY(di);
134 COPY(esi); 135 COPY(si);
135 COPY(ebp); 136 COPY(bp);
136 COPY(esp); 137 COPY(sp);
137 COPY(ebx); 138 COPY(bx);
138 COPY(edx); 139 COPY(dx);
139 COPY(ecx); 140 COPY(cx);
140 COPY(eip); 141 COPY(ip);
141 COPY_SEG_STRICT(cs); 142 COPY_SEG_STRICT(cs);
142 COPY_SEG_STRICT(ss); 143 COPY_SEG_STRICT(ss);
143 144
144 { 145 {
145 unsigned int tmpflags; 146 unsigned int tmpflags;
146 err |= __get_user(tmpflags, &sc->eflags); 147 err |= __get_user(tmpflags, &sc->flags);
147 regs->eflags = (regs->eflags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS); 148 regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
148 regs->orig_eax = -1; /* disable syscall checks */ 149 regs->orig_ax = -1; /* disable syscall checks */
149 } 150 }
150 151
151 { 152 {
@@ -164,7 +165,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *peax
164 } 165 }
165 } 166 }
166 167
167 err |= __get_user(*peax, &sc->eax); 168 err |= __get_user(*peax, &sc->ax);
168 return err; 169 return err;
169 170
170badframe: 171badframe:
@@ -174,9 +175,9 @@ badframe:
174asmlinkage int sys_sigreturn(unsigned long __unused) 175asmlinkage int sys_sigreturn(unsigned long __unused)
175{ 176{
176 struct pt_regs *regs = (struct pt_regs *) &__unused; 177 struct pt_regs *regs = (struct pt_regs *) &__unused;
177 struct sigframe __user *frame = (struct sigframe __user *)(regs->esp - 8); 178 struct sigframe __user *frame = (struct sigframe __user *)(regs->sp - 8);
178 sigset_t set; 179 sigset_t set;
179 int eax; 180 int ax;
180 181
181 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 182 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
182 goto badframe; 183 goto badframe;
@@ -192,17 +193,20 @@ asmlinkage int sys_sigreturn(unsigned long __unused)
192 recalc_sigpending(); 193 recalc_sigpending();
193 spin_unlock_irq(&current->sighand->siglock); 194 spin_unlock_irq(&current->sighand->siglock);
194 195
195 if (restore_sigcontext(regs, &frame->sc, &eax)) 196 if (restore_sigcontext(regs, &frame->sc, &ax))
196 goto badframe; 197 goto badframe;
197 return eax; 198 return ax;
198 199
199badframe: 200badframe:
200 if (show_unhandled_signals && printk_ratelimit()) 201 if (show_unhandled_signals && printk_ratelimit()) {
201 printk("%s%s[%d] bad frame in sigreturn frame:%p eip:%lx" 202 printk("%s%s[%d] bad frame in sigreturn frame:%p ip:%lx"
202 " esp:%lx oeax:%lx\n", 203 " sp:%lx oeax:%lx",
203 task_pid_nr(current) > 1 ? KERN_INFO : KERN_EMERG, 204 task_pid_nr(current) > 1 ? KERN_INFO : KERN_EMERG,
204 current->comm, task_pid_nr(current), frame, regs->eip, 205 current->comm, task_pid_nr(current), frame, regs->ip,
205 regs->esp, regs->orig_eax); 206 regs->sp, regs->orig_ax);
207 print_vma_addr(" in ", regs->ip);
208 printk("\n");
209 }
206 210
207 force_sig(SIGSEGV, current); 211 force_sig(SIGSEGV, current);
208 return 0; 212 return 0;
@@ -211,9 +215,9 @@ badframe:
211asmlinkage int sys_rt_sigreturn(unsigned long __unused) 215asmlinkage int sys_rt_sigreturn(unsigned long __unused)
212{ 216{
213 struct pt_regs *regs = (struct pt_regs *) &__unused; 217 struct pt_regs *regs = (struct pt_regs *) &__unused;
214 struct rt_sigframe __user *frame = (struct rt_sigframe __user *)(regs->esp - 4); 218 struct rt_sigframe __user *frame = (struct rt_sigframe __user *)(regs->sp - 4);
215 sigset_t set; 219 sigset_t set;
216 int eax; 220 int ax;
217 221
218 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 222 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
219 goto badframe; 223 goto badframe;
@@ -226,13 +230,13 @@ asmlinkage int sys_rt_sigreturn(unsigned long __unused)
226 recalc_sigpending(); 230 recalc_sigpending();
227 spin_unlock_irq(&current->sighand->siglock); 231 spin_unlock_irq(&current->sighand->siglock);
228 232
229 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &eax)) 233 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
230 goto badframe; 234 goto badframe;
231 235
232 if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->esp) == -EFAULT) 236 if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT)
233 goto badframe; 237 goto badframe;
234 238
235 return eax; 239 return ax;
236 240
237badframe: 241badframe:
238 force_sig(SIGSEGV, current); 242 force_sig(SIGSEGV, current);
@@ -249,27 +253,27 @@ setup_sigcontext(struct sigcontext __user *sc, struct _fpstate __user *fpstate,
249{ 253{
250 int tmp, err = 0; 254 int tmp, err = 0;
251 255
252 err |= __put_user(regs->xfs, (unsigned int __user *)&sc->fs); 256 err |= __put_user(regs->fs, (unsigned int __user *)&sc->fs);
253 savesegment(gs, tmp); 257 savesegment(gs, tmp);
254 err |= __put_user(tmp, (unsigned int __user *)&sc->gs); 258 err |= __put_user(tmp, (unsigned int __user *)&sc->gs);
255 259
256 err |= __put_user(regs->xes, (unsigned int __user *)&sc->es); 260 err |= __put_user(regs->es, (unsigned int __user *)&sc->es);
257 err |= __put_user(regs->xds, (unsigned int __user *)&sc->ds); 261 err |= __put_user(regs->ds, (unsigned int __user *)&sc->ds);
258 err |= __put_user(regs->edi, &sc->edi); 262 err |= __put_user(regs->di, &sc->di);
259 err |= __put_user(regs->esi, &sc->esi); 263 err |= __put_user(regs->si, &sc->si);
260 err |= __put_user(regs->ebp, &sc->ebp); 264 err |= __put_user(regs->bp, &sc->bp);
261 err |= __put_user(regs->esp, &sc->esp); 265 err |= __put_user(regs->sp, &sc->sp);
262 err |= __put_user(regs->ebx, &sc->ebx); 266 err |= __put_user(regs->bx, &sc->bx);
263 err |= __put_user(regs->edx, &sc->edx); 267 err |= __put_user(regs->dx, &sc->dx);
264 err |= __put_user(regs->ecx, &sc->ecx); 268 err |= __put_user(regs->cx, &sc->cx);
265 err |= __put_user(regs->eax, &sc->eax); 269 err |= __put_user(regs->ax, &sc->ax);
266 err |= __put_user(current->thread.trap_no, &sc->trapno); 270 err |= __put_user(current->thread.trap_no, &sc->trapno);
267 err |= __put_user(current->thread.error_code, &sc->err); 271 err |= __put_user(current->thread.error_code, &sc->err);
268 err |= __put_user(regs->eip, &sc->eip); 272 err |= __put_user(regs->ip, &sc->ip);
269 err |= __put_user(regs->xcs, (unsigned int __user *)&sc->cs); 273 err |= __put_user(regs->cs, (unsigned int __user *)&sc->cs);
270 err |= __put_user(regs->eflags, &sc->eflags); 274 err |= __put_user(regs->flags, &sc->flags);
271 err |= __put_user(regs->esp, &sc->esp_at_signal); 275 err |= __put_user(regs->sp, &sc->sp_at_signal);
272 err |= __put_user(regs->xss, (unsigned int __user *)&sc->ss); 276 err |= __put_user(regs->ss, (unsigned int __user *)&sc->ss);
273 277
274 tmp = save_i387(fpstate); 278 tmp = save_i387(fpstate);
275 if (tmp < 0) 279 if (tmp < 0)
@@ -290,29 +294,36 @@ setup_sigcontext(struct sigcontext __user *sc, struct _fpstate __user *fpstate,
290static inline void __user * 294static inline void __user *
291get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) 295get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
292{ 296{
293 unsigned long esp; 297 unsigned long sp;
294 298
295 /* Default to using normal stack */ 299 /* Default to using normal stack */
296 esp = regs->esp; 300 sp = regs->sp;
301
302 /*
303 * If we are on the alternate signal stack and would overflow it, don't.
304 * Return an always-bogus address instead so we will die with SIGSEGV.
305 */
306 if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size)))
307 return (void __user *) -1L;
297 308
298 /* This is the X/Open sanctioned signal stack switching. */ 309 /* This is the X/Open sanctioned signal stack switching. */
299 if (ka->sa.sa_flags & SA_ONSTACK) { 310 if (ka->sa.sa_flags & SA_ONSTACK) {
300 if (sas_ss_flags(esp) == 0) 311 if (sas_ss_flags(sp) == 0)
301 esp = current->sas_ss_sp + current->sas_ss_size; 312 sp = current->sas_ss_sp + current->sas_ss_size;
302 } 313 }
303 314
304 /* This is the legacy signal stack switching. */ 315 /* This is the legacy signal stack switching. */
305 else if ((regs->xss & 0xffff) != __USER_DS && 316 else if ((regs->ss & 0xffff) != __USER_DS &&
306 !(ka->sa.sa_flags & SA_RESTORER) && 317 !(ka->sa.sa_flags & SA_RESTORER) &&
307 ka->sa.sa_restorer) { 318 ka->sa.sa_restorer) {
308 esp = (unsigned long) ka->sa.sa_restorer; 319 sp = (unsigned long) ka->sa.sa_restorer;
309 } 320 }
310 321
311 esp -= frame_size; 322 sp -= frame_size;
312 /* Align the stack pointer according to the i386 ABI, 323 /* Align the stack pointer according to the i386 ABI,
313 * i.e. so that on function entry ((sp + 4) & 15) == 0. */ 324 * i.e. so that on function entry ((sp + 4) & 15) == 0. */
314 esp = ((esp + 4) & -16ul) - 4; 325 sp = ((sp + 4) & -16ul) - 4;
315 return (void __user *) esp; 326 return (void __user *) sp;
316} 327}
317 328
318/* These symbols are defined with the addresses in the vsyscall page. 329/* These symbols are defined with the addresses in the vsyscall page.
@@ -355,9 +366,9 @@ static int setup_frame(int sig, struct k_sigaction *ka,
355 } 366 }
356 367
357 if (current->binfmt->hasvdso) 368 if (current->binfmt->hasvdso)
358 restorer = (void *)VDSO_SYM(&__kernel_sigreturn); 369 restorer = VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
359 else 370 else
360 restorer = (void *)&frame->retcode; 371 restorer = &frame->retcode;
361 if (ka->sa.sa_flags & SA_RESTORER) 372 if (ka->sa.sa_flags & SA_RESTORER)
362 restorer = ka->sa.sa_restorer; 373 restorer = ka->sa.sa_restorer;
363 374
@@ -379,16 +390,16 @@ static int setup_frame(int sig, struct k_sigaction *ka,
379 goto give_sigsegv; 390 goto give_sigsegv;
380 391
381 /* Set up registers for signal handler */ 392 /* Set up registers for signal handler */
382 regs->esp = (unsigned long) frame; 393 regs->sp = (unsigned long) frame;
383 regs->eip = (unsigned long) ka->sa.sa_handler; 394 regs->ip = (unsigned long) ka->sa.sa_handler;
384 regs->eax = (unsigned long) sig; 395 regs->ax = (unsigned long) sig;
385 regs->edx = (unsigned long) 0; 396 regs->dx = (unsigned long) 0;
386 regs->ecx = (unsigned long) 0; 397 regs->cx = (unsigned long) 0;
387 398
388 regs->xds = __USER_DS; 399 regs->ds = __USER_DS;
389 regs->xes = __USER_DS; 400 regs->es = __USER_DS;
390 regs->xss = __USER_DS; 401 regs->ss = __USER_DS;
391 regs->xcs = __USER_CS; 402 regs->cs = __USER_CS;
392 403
393 /* 404 /*
394 * Clear TF when entering the signal handler, but 405 * Clear TF when entering the signal handler, but
@@ -396,13 +407,13 @@ static int setup_frame(int sig, struct k_sigaction *ka,
396 * The tracer may want to single-step inside the 407 * The tracer may want to single-step inside the
397 * handler too. 408 * handler too.
398 */ 409 */
399 regs->eflags &= ~TF_MASK; 410 regs->flags &= ~TF_MASK;
400 if (test_thread_flag(TIF_SINGLESTEP)) 411 if (test_thread_flag(TIF_SINGLESTEP))
401 ptrace_notify(SIGTRAP); 412 ptrace_notify(SIGTRAP);
402 413
403#if DEBUG_SIG 414#if DEBUG_SIG
404 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n", 415 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
405 current->comm, current->pid, frame, regs->eip, frame->pretcode); 416 current->comm, current->pid, frame, regs->ip, frame->pretcode);
406#endif 417#endif
407 418
408 return 0; 419 return 0;
@@ -442,7 +453,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
442 err |= __put_user(0, &frame->uc.uc_flags); 453 err |= __put_user(0, &frame->uc.uc_flags);
443 err |= __put_user(0, &frame->uc.uc_link); 454 err |= __put_user(0, &frame->uc.uc_link);
444 err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); 455 err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
445 err |= __put_user(sas_ss_flags(regs->esp), 456 err |= __put_user(sas_ss_flags(regs->sp),
446 &frame->uc.uc_stack.ss_flags); 457 &frame->uc.uc_stack.ss_flags);
447 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); 458 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
448 err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate, 459 err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate,
@@ -452,13 +463,13 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
452 goto give_sigsegv; 463 goto give_sigsegv;
453 464
454 /* Set up to return from userspace. */ 465 /* Set up to return from userspace. */
455 restorer = (void *)VDSO_SYM(&__kernel_rt_sigreturn); 466 restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
456 if (ka->sa.sa_flags & SA_RESTORER) 467 if (ka->sa.sa_flags & SA_RESTORER)
457 restorer = ka->sa.sa_restorer; 468 restorer = ka->sa.sa_restorer;
458 err |= __put_user(restorer, &frame->pretcode); 469 err |= __put_user(restorer, &frame->pretcode);
459 470
460 /* 471 /*
461 * This is movl $,%eax ; int $0x80 472 * This is movl $,%ax ; int $0x80
462 * 473 *
463 * WE DO NOT USE IT ANY MORE! It's only left here for historical 474 * WE DO NOT USE IT ANY MORE! It's only left here for historical
464 * reasons and because gdb uses it as a signature to notice 475 * reasons and because gdb uses it as a signature to notice
@@ -472,16 +483,16 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
472 goto give_sigsegv; 483 goto give_sigsegv;
473 484
474 /* Set up registers for signal handler */ 485 /* Set up registers for signal handler */
475 regs->esp = (unsigned long) frame; 486 regs->sp = (unsigned long) frame;
476 regs->eip = (unsigned long) ka->sa.sa_handler; 487 regs->ip = (unsigned long) ka->sa.sa_handler;
477 regs->eax = (unsigned long) usig; 488 regs->ax = (unsigned long) usig;
478 regs->edx = (unsigned long) &frame->info; 489 regs->dx = (unsigned long) &frame->info;
479 regs->ecx = (unsigned long) &frame->uc; 490 regs->cx = (unsigned long) &frame->uc;
480 491
481 regs->xds = __USER_DS; 492 regs->ds = __USER_DS;
482 regs->xes = __USER_DS; 493 regs->es = __USER_DS;
483 regs->xss = __USER_DS; 494 regs->ss = __USER_DS;
484 regs->xcs = __USER_CS; 495 regs->cs = __USER_CS;
485 496
486 /* 497 /*
487 * Clear TF when entering the signal handler, but 498 * Clear TF when entering the signal handler, but
@@ -489,13 +500,13 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
489 * The tracer may want to single-step inside the 500 * The tracer may want to single-step inside the
490 * handler too. 501 * handler too.
491 */ 502 */
492 regs->eflags &= ~TF_MASK; 503 regs->flags &= ~TF_MASK;
493 if (test_thread_flag(TIF_SINGLESTEP)) 504 if (test_thread_flag(TIF_SINGLESTEP))
494 ptrace_notify(SIGTRAP); 505 ptrace_notify(SIGTRAP);
495 506
496#if DEBUG_SIG 507#if DEBUG_SIG
497 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n", 508 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
498 current->comm, current->pid, frame, regs->eip, frame->pretcode); 509 current->comm, current->pid, frame, regs->ip, frame->pretcode);
499#endif 510#endif
500 511
501 return 0; 512 return 0;
@@ -516,35 +527,33 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
516 int ret; 527 int ret;
517 528
518 /* Are we from a system call? */ 529 /* Are we from a system call? */
519 if (regs->orig_eax >= 0) { 530 if (regs->orig_ax >= 0) {
520 /* If so, check system call restarting.. */ 531 /* If so, check system call restarting.. */
521 switch (regs->eax) { 532 switch (regs->ax) {
522 case -ERESTART_RESTARTBLOCK: 533 case -ERESTART_RESTARTBLOCK:
523 case -ERESTARTNOHAND: 534 case -ERESTARTNOHAND:
524 regs->eax = -EINTR; 535 regs->ax = -EINTR;
525 break; 536 break;
526 537
527 case -ERESTARTSYS: 538 case -ERESTARTSYS:
528 if (!(ka->sa.sa_flags & SA_RESTART)) { 539 if (!(ka->sa.sa_flags & SA_RESTART)) {
529 regs->eax = -EINTR; 540 regs->ax = -EINTR;
530 break; 541 break;
531 } 542 }
532 /* fallthrough */ 543 /* fallthrough */
533 case -ERESTARTNOINTR: 544 case -ERESTARTNOINTR:
534 regs->eax = regs->orig_eax; 545 regs->ax = regs->orig_ax;
535 regs->eip -= 2; 546 regs->ip -= 2;
536 } 547 }
537 } 548 }
538 549
539 /* 550 /*
540 * If TF is set due to a debugger (PT_DTRACE), clear the TF flag so 551 * If TF is set due to a debugger (TIF_FORCED_TF), clear the TF
541 * that register information in the sigcontext is correct. 552 * flag so that register information in the sigcontext is correct.
542 */ 553 */
543 if (unlikely(regs->eflags & TF_MASK) 554 if (unlikely(regs->flags & X86_EFLAGS_TF) &&
544 && likely(current->ptrace & PT_DTRACE)) { 555 likely(test_and_clear_thread_flag(TIF_FORCED_TF)))
545 current->ptrace &= ~PT_DTRACE; 556 regs->flags &= ~X86_EFLAGS_TF;
546 regs->eflags &= ~TF_MASK;
547 }
548 557
549 /* Set up the stack frame */ 558 /* Set up the stack frame */
550 if (ka->sa.sa_flags & SA_SIGINFO) 559 if (ka->sa.sa_flags & SA_SIGINFO)
@@ -569,7 +578,7 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
569 * want to handle. Thus you cannot kill init even with a SIGKILL even by 578 * want to handle. Thus you cannot kill init even with a SIGKILL even by
570 * mistake. 579 * mistake.
571 */ 580 */
572static void fastcall do_signal(struct pt_regs *regs) 581static void do_signal(struct pt_regs *regs)
573{ 582{
574 siginfo_t info; 583 siginfo_t info;
575 int signr; 584 int signr;
@@ -599,8 +608,8 @@ static void fastcall do_signal(struct pt_regs *regs)
599 * have been cleared if the watchpoint triggered 608 * have been cleared if the watchpoint triggered
600 * inside the kernel. 609 * inside the kernel.
601 */ 610 */
602 if (unlikely(current->thread.debugreg[7])) 611 if (unlikely(current->thread.debugreg7))
603 set_debugreg(current->thread.debugreg[7], 7); 612 set_debugreg(current->thread.debugreg7, 7);
604 613
605 /* Whee! Actually deliver the signal. */ 614 /* Whee! Actually deliver the signal. */
606 if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { 615 if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
@@ -616,19 +625,19 @@ static void fastcall do_signal(struct pt_regs *regs)
616 } 625 }
617 626
618 /* Did we come from a system call? */ 627 /* Did we come from a system call? */
619 if (regs->orig_eax >= 0) { 628 if (regs->orig_ax >= 0) {
620 /* Restart the system call - no handlers present */ 629 /* Restart the system call - no handlers present */
621 switch (regs->eax) { 630 switch (regs->ax) {
622 case -ERESTARTNOHAND: 631 case -ERESTARTNOHAND:
623 case -ERESTARTSYS: 632 case -ERESTARTSYS:
624 case -ERESTARTNOINTR: 633 case -ERESTARTNOINTR:
625 regs->eax = regs->orig_eax; 634 regs->ax = regs->orig_ax;
626 regs->eip -= 2; 635 regs->ip -= 2;
627 break; 636 break;
628 637
629 case -ERESTART_RESTARTBLOCK: 638 case -ERESTART_RESTARTBLOCK:
630 regs->eax = __NR_restart_syscall; 639 regs->ax = __NR_restart_syscall;
631 regs->eip -= 2; 640 regs->ip -= 2;
632 break; 641 break;
633 } 642 }
634 } 643 }
@@ -651,13 +660,16 @@ void do_notify_resume(struct pt_regs *regs, void *_unused,
651{ 660{
652 /* Pending single-step? */ 661 /* Pending single-step? */
653 if (thread_info_flags & _TIF_SINGLESTEP) { 662 if (thread_info_flags & _TIF_SINGLESTEP) {
654 regs->eflags |= TF_MASK; 663 regs->flags |= TF_MASK;
655 clear_thread_flag(TIF_SINGLESTEP); 664 clear_thread_flag(TIF_SINGLESTEP);
656 } 665 }
657 666
658 /* deal with pending signal delivery */ 667 /* deal with pending signal delivery */
659 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) 668 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
660 do_signal(regs); 669 do_signal(regs);
670
671 if (thread_info_flags & _TIF_HRTICK_RESCHED)
672 hrtick_resched();
661 673
662 clear_thread_flag(TIF_IRET); 674 clear_thread_flag(TIF_IRET);
663} 675}
diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c
index ab086b0357fc..7347bb14e306 100644
--- a/arch/x86/kernel/signal_64.c
+++ b/arch/x86/kernel/signal_64.c
@@ -39,7 +39,7 @@ asmlinkage long
39sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, 39sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
40 struct pt_regs *regs) 40 struct pt_regs *regs)
41{ 41{
42 return do_sigaltstack(uss, uoss, regs->rsp); 42 return do_sigaltstack(uss, uoss, regs->sp);
43} 43}
44 44
45 45
@@ -64,8 +64,8 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, unsigned
64 64
65#define COPY(x) err |= __get_user(regs->x, &sc->x) 65#define COPY(x) err |= __get_user(regs->x, &sc->x)
66 66
67 COPY(rdi); COPY(rsi); COPY(rbp); COPY(rsp); COPY(rbx); 67 COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
68 COPY(rdx); COPY(rcx); COPY(rip); 68 COPY(dx); COPY(cx); COPY(ip);
69 COPY(r8); 69 COPY(r8);
70 COPY(r9); 70 COPY(r9);
71 COPY(r10); 71 COPY(r10);
@@ -86,9 +86,9 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, unsigned
86 86
87 { 87 {
88 unsigned int tmpflags; 88 unsigned int tmpflags;
89 err |= __get_user(tmpflags, &sc->eflags); 89 err |= __get_user(tmpflags, &sc->flags);
90 regs->eflags = (regs->eflags & ~0x40DD5) | (tmpflags & 0x40DD5); 90 regs->flags = (regs->flags & ~0x40DD5) | (tmpflags & 0x40DD5);
91 regs->orig_rax = -1; /* disable syscall checks */ 91 regs->orig_ax = -1; /* disable syscall checks */
92 } 92 }
93 93
94 { 94 {
@@ -108,7 +108,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, unsigned
108 } 108 }
109 } 109 }
110 110
111 err |= __get_user(*prax, &sc->rax); 111 err |= __get_user(*prax, &sc->ax);
112 return err; 112 return err;
113 113
114badframe: 114badframe:
@@ -119,9 +119,9 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
119{ 119{
120 struct rt_sigframe __user *frame; 120 struct rt_sigframe __user *frame;
121 sigset_t set; 121 sigset_t set;
122 unsigned long eax; 122 unsigned long ax;
123 123
124 frame = (struct rt_sigframe __user *)(regs->rsp - 8); 124 frame = (struct rt_sigframe __user *)(regs->sp - 8);
125 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) { 125 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) {
126 goto badframe; 126 goto badframe;
127 } 127 }
@@ -135,17 +135,17 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
135 recalc_sigpending(); 135 recalc_sigpending();
136 spin_unlock_irq(&current->sighand->siglock); 136 spin_unlock_irq(&current->sighand->siglock);
137 137
138 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &eax)) 138 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
139 goto badframe; 139 goto badframe;
140 140
141#ifdef DEBUG_SIG 141#ifdef DEBUG_SIG
142 printk("%d sigreturn rip:%lx rsp:%lx frame:%p rax:%lx\n",current->pid,regs->rip,regs->rsp,frame,eax); 142 printk("%d sigreturn ip:%lx sp:%lx frame:%p ax:%lx\n",current->pid,regs->ip,regs->sp,frame,ax);
143#endif 143#endif
144 144
145 if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->rsp) == -EFAULT) 145 if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT)
146 goto badframe; 146 goto badframe;
147 147
148 return eax; 148 return ax;
149 149
150badframe: 150badframe:
151 signal_fault(regs,frame,"sigreturn"); 151 signal_fault(regs,frame,"sigreturn");
@@ -165,14 +165,14 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, unsigned lo
165 err |= __put_user(0, &sc->gs); 165 err |= __put_user(0, &sc->gs);
166 err |= __put_user(0, &sc->fs); 166 err |= __put_user(0, &sc->fs);
167 167
168 err |= __put_user(regs->rdi, &sc->rdi); 168 err |= __put_user(regs->di, &sc->di);
169 err |= __put_user(regs->rsi, &sc->rsi); 169 err |= __put_user(regs->si, &sc->si);
170 err |= __put_user(regs->rbp, &sc->rbp); 170 err |= __put_user(regs->bp, &sc->bp);
171 err |= __put_user(regs->rsp, &sc->rsp); 171 err |= __put_user(regs->sp, &sc->sp);
172 err |= __put_user(regs->rbx, &sc->rbx); 172 err |= __put_user(regs->bx, &sc->bx);
173 err |= __put_user(regs->rdx, &sc->rdx); 173 err |= __put_user(regs->dx, &sc->dx);
174 err |= __put_user(regs->rcx, &sc->rcx); 174 err |= __put_user(regs->cx, &sc->cx);
175 err |= __put_user(regs->rax, &sc->rax); 175 err |= __put_user(regs->ax, &sc->ax);
176 err |= __put_user(regs->r8, &sc->r8); 176 err |= __put_user(regs->r8, &sc->r8);
177 err |= __put_user(regs->r9, &sc->r9); 177 err |= __put_user(regs->r9, &sc->r9);
178 err |= __put_user(regs->r10, &sc->r10); 178 err |= __put_user(regs->r10, &sc->r10);
@@ -183,8 +183,8 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, unsigned lo
183 err |= __put_user(regs->r15, &sc->r15); 183 err |= __put_user(regs->r15, &sc->r15);
184 err |= __put_user(me->thread.trap_no, &sc->trapno); 184 err |= __put_user(me->thread.trap_no, &sc->trapno);
185 err |= __put_user(me->thread.error_code, &sc->err); 185 err |= __put_user(me->thread.error_code, &sc->err);
186 err |= __put_user(regs->rip, &sc->rip); 186 err |= __put_user(regs->ip, &sc->ip);
187 err |= __put_user(regs->eflags, &sc->eflags); 187 err |= __put_user(regs->flags, &sc->flags);
188 err |= __put_user(mask, &sc->oldmask); 188 err |= __put_user(mask, &sc->oldmask);
189 err |= __put_user(me->thread.cr2, &sc->cr2); 189 err |= __put_user(me->thread.cr2, &sc->cr2);
190 190
@@ -198,18 +198,18 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, unsigned lo
198static void __user * 198static void __user *
199get_stack(struct k_sigaction *ka, struct pt_regs *regs, unsigned long size) 199get_stack(struct k_sigaction *ka, struct pt_regs *regs, unsigned long size)
200{ 200{
201 unsigned long rsp; 201 unsigned long sp;
202 202
203 /* Default to using normal stack - redzone*/ 203 /* Default to using normal stack - redzone*/
204 rsp = regs->rsp - 128; 204 sp = regs->sp - 128;
205 205
206 /* This is the X/Open sanctioned signal stack switching. */ 206 /* This is the X/Open sanctioned signal stack switching. */
207 if (ka->sa.sa_flags & SA_ONSTACK) { 207 if (ka->sa.sa_flags & SA_ONSTACK) {
208 if (sas_ss_flags(rsp) == 0) 208 if (sas_ss_flags(sp) == 0)
209 rsp = current->sas_ss_sp + current->sas_ss_size; 209 sp = current->sas_ss_sp + current->sas_ss_size;
210 } 210 }
211 211
212 return (void __user *)round_down(rsp - size, 16); 212 return (void __user *)round_down(sp - size, 16);
213} 213}
214 214
215static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 215static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
@@ -246,7 +246,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
246 err |= __put_user(0, &frame->uc.uc_flags); 246 err |= __put_user(0, &frame->uc.uc_flags);
247 err |= __put_user(0, &frame->uc.uc_link); 247 err |= __put_user(0, &frame->uc.uc_link);
248 err |= __put_user(me->sas_ss_sp, &frame->uc.uc_stack.ss_sp); 248 err |= __put_user(me->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
249 err |= __put_user(sas_ss_flags(regs->rsp), 249 err |= __put_user(sas_ss_flags(regs->sp),
250 &frame->uc.uc_stack.ss_flags); 250 &frame->uc.uc_stack.ss_flags);
251 err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size); 251 err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size);
252 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me); 252 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me);
@@ -271,21 +271,21 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
271 goto give_sigsegv; 271 goto give_sigsegv;
272 272
273#ifdef DEBUG_SIG 273#ifdef DEBUG_SIG
274 printk("%d old rip %lx old rsp %lx old rax %lx\n", current->pid,regs->rip,regs->rsp,regs->rax); 274 printk("%d old ip %lx old sp %lx old ax %lx\n", current->pid,regs->ip,regs->sp,regs->ax);
275#endif 275#endif
276 276
277 /* Set up registers for signal handler */ 277 /* Set up registers for signal handler */
278 regs->rdi = sig; 278 regs->di = sig;
279 /* In case the signal handler was declared without prototypes */ 279 /* In case the signal handler was declared without prototypes */
280 regs->rax = 0; 280 regs->ax = 0;
281 281
282 /* This also works for non SA_SIGINFO handlers because they expect the 282 /* This also works for non SA_SIGINFO handlers because they expect the
283 next argument after the signal number on the stack. */ 283 next argument after the signal number on the stack. */
284 regs->rsi = (unsigned long)&frame->info; 284 regs->si = (unsigned long)&frame->info;
285 regs->rdx = (unsigned long)&frame->uc; 285 regs->dx = (unsigned long)&frame->uc;
286 regs->rip = (unsigned long) ka->sa.sa_handler; 286 regs->ip = (unsigned long) ka->sa.sa_handler;
287 287
288 regs->rsp = (unsigned long)frame; 288 regs->sp = (unsigned long)frame;
289 289
290 /* Set up the CS register to run signal handlers in 64-bit mode, 290 /* Set up the CS register to run signal handlers in 64-bit mode,
291 even if the handler happens to be interrupting 32-bit code. */ 291 even if the handler happens to be interrupting 32-bit code. */
@@ -295,12 +295,12 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
295 see include/asm-x86_64/uaccess.h for details. */ 295 see include/asm-x86_64/uaccess.h for details. */
296 set_fs(USER_DS); 296 set_fs(USER_DS);
297 297
298 regs->eflags &= ~TF_MASK; 298 regs->flags &= ~X86_EFLAGS_TF;
299 if (test_thread_flag(TIF_SINGLESTEP)) 299 if (test_thread_flag(TIF_SINGLESTEP))
300 ptrace_notify(SIGTRAP); 300 ptrace_notify(SIGTRAP);
301#ifdef DEBUG_SIG 301#ifdef DEBUG_SIG
302 printk("SIG deliver (%s:%d): sp=%p pc=%lx ra=%p\n", 302 printk("SIG deliver (%s:%d): sp=%p pc=%lx ra=%p\n",
303 current->comm, current->pid, frame, regs->rip, frame->pretcode); 303 current->comm, current->pid, frame, regs->ip, frame->pretcode);
304#endif 304#endif
305 305
306 return 0; 306 return 0;
@@ -321,44 +321,40 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
321 int ret; 321 int ret;
322 322
323#ifdef DEBUG_SIG 323#ifdef DEBUG_SIG
324 printk("handle_signal pid:%d sig:%lu rip:%lx rsp:%lx regs=%p\n", 324 printk("handle_signal pid:%d sig:%lu ip:%lx sp:%lx regs=%p\n",
325 current->pid, sig, 325 current->pid, sig,
326 regs->rip, regs->rsp, regs); 326 regs->ip, regs->sp, regs);
327#endif 327#endif
328 328
329 /* Are we from a system call? */ 329 /* Are we from a system call? */
330 if ((long)regs->orig_rax >= 0) { 330 if ((long)regs->orig_ax >= 0) {
331 /* If so, check system call restarting.. */ 331 /* If so, check system call restarting.. */
332 switch (regs->rax) { 332 switch (regs->ax) {
333 case -ERESTART_RESTARTBLOCK: 333 case -ERESTART_RESTARTBLOCK:
334 case -ERESTARTNOHAND: 334 case -ERESTARTNOHAND:
335 regs->rax = -EINTR; 335 regs->ax = -EINTR;
336 break; 336 break;
337 337
338 case -ERESTARTSYS: 338 case -ERESTARTSYS:
339 if (!(ka->sa.sa_flags & SA_RESTART)) { 339 if (!(ka->sa.sa_flags & SA_RESTART)) {
340 regs->rax = -EINTR; 340 regs->ax = -EINTR;
341 break; 341 break;
342 } 342 }
343 /* fallthrough */ 343 /* fallthrough */
344 case -ERESTARTNOINTR: 344 case -ERESTARTNOINTR:
345 regs->rax = regs->orig_rax; 345 regs->ax = regs->orig_ax;
346 regs->rip -= 2; 346 regs->ip -= 2;
347 break; 347 break;
348 } 348 }
349 } 349 }
350 350
351 /* 351 /*
352 * If TF is set due to a debugger (PT_DTRACE), clear the TF 352 * If TF is set due to a debugger (TIF_FORCED_TF), clear the TF
353 * flag so that register information in the sigcontext is 353 * flag so that register information in the sigcontext is correct.
354 * correct.
355 */ 354 */
356 if (unlikely(regs->eflags & TF_MASK)) { 355 if (unlikely(regs->flags & X86_EFLAGS_TF) &&
357 if (likely(current->ptrace & PT_DTRACE)) { 356 likely(test_and_clear_thread_flag(TIF_FORCED_TF)))
358 current->ptrace &= ~PT_DTRACE; 357 regs->flags &= ~X86_EFLAGS_TF;
359 regs->eflags &= ~TF_MASK;
360 }
361 }
362 358
363#ifdef CONFIG_IA32_EMULATION 359#ifdef CONFIG_IA32_EMULATION
364 if (test_thread_flag(TIF_IA32)) { 360 if (test_thread_flag(TIF_IA32)) {
@@ -430,21 +426,21 @@ static void do_signal(struct pt_regs *regs)
430 } 426 }
431 427
432 /* Did we come from a system call? */ 428 /* Did we come from a system call? */
433 if ((long)regs->orig_rax >= 0) { 429 if ((long)regs->orig_ax >= 0) {
434 /* Restart the system call - no handlers present */ 430 /* Restart the system call - no handlers present */
435 long res = regs->rax; 431 long res = regs->ax;
436 switch (res) { 432 switch (res) {
437 case -ERESTARTNOHAND: 433 case -ERESTARTNOHAND:
438 case -ERESTARTSYS: 434 case -ERESTARTSYS:
439 case -ERESTARTNOINTR: 435 case -ERESTARTNOINTR:
440 regs->rax = regs->orig_rax; 436 regs->ax = regs->orig_ax;
441 regs->rip -= 2; 437 regs->ip -= 2;
442 break; 438 break;
443 case -ERESTART_RESTARTBLOCK: 439 case -ERESTART_RESTARTBLOCK:
444 regs->rax = test_thread_flag(TIF_IA32) ? 440 regs->ax = test_thread_flag(TIF_IA32) ?
445 __NR_ia32_restart_syscall : 441 __NR_ia32_restart_syscall :
446 __NR_restart_syscall; 442 __NR_restart_syscall;
447 regs->rip -= 2; 443 regs->ip -= 2;
448 break; 444 break;
449 } 445 }
450 } 446 }
@@ -461,13 +457,13 @@ void
461do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) 457do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
462{ 458{
463#ifdef DEBUG_SIG 459#ifdef DEBUG_SIG
464 printk("do_notify_resume flags:%x rip:%lx rsp:%lx caller:%p pending:%x\n", 460 printk("do_notify_resume flags:%x ip:%lx sp:%lx caller:%p pending:%x\n",
465 thread_info_flags, regs->rip, regs->rsp, __builtin_return_address(0),signal_pending(current)); 461 thread_info_flags, regs->ip, regs->sp, __builtin_return_address(0),signal_pending(current));
466#endif 462#endif
467 463
468 /* Pending single-step? */ 464 /* Pending single-step? */
469 if (thread_info_flags & _TIF_SINGLESTEP) { 465 if (thread_info_flags & _TIF_SINGLESTEP) {
470 regs->eflags |= TF_MASK; 466 regs->flags |= X86_EFLAGS_TF;
471 clear_thread_flag(TIF_SINGLESTEP); 467 clear_thread_flag(TIF_SINGLESTEP);
472 } 468 }
473 469
@@ -480,14 +476,20 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
480 /* deal with pending signal delivery */ 476 /* deal with pending signal delivery */
481 if (thread_info_flags & (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK)) 477 if (thread_info_flags & (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK))
482 do_signal(regs); 478 do_signal(regs);
479
480 if (thread_info_flags & _TIF_HRTICK_RESCHED)
481 hrtick_resched();
483} 482}
484 483
485void signal_fault(struct pt_regs *regs, void __user *frame, char *where) 484void signal_fault(struct pt_regs *regs, void __user *frame, char *where)
486{ 485{
487 struct task_struct *me = current; 486 struct task_struct *me = current;
488 if (show_unhandled_signals && printk_ratelimit()) 487 if (show_unhandled_signals && printk_ratelimit()) {
489 printk("%s[%d] bad frame in %s frame:%p rip:%lx rsp:%lx orax:%lx\n", 488 printk("%s[%d] bad frame in %s frame:%p ip:%lx sp:%lx orax:%lx",
490 me->comm,me->pid,where,frame,regs->rip,regs->rsp,regs->orig_rax); 489 me->comm,me->pid,where,frame,regs->ip,regs->sp,regs->orig_ax);
490 print_vma_addr(" in ", regs->ip);
491 printk("\n");
492 }
491 493
492 force_sig(SIGSEGV, me); 494 force_sig(SIGSEGV, me);
493} 495}
diff --git a/arch/x86/kernel/smp_32.c b/arch/x86/kernel/smp_32.c
index fcaa026eb807..dc0cde9d16fb 100644
--- a/arch/x86/kernel/smp_32.c
+++ b/arch/x86/kernel/smp_32.c
@@ -159,7 +159,7 @@ void __send_IPI_shortcut(unsigned int shortcut, int vector)
159 apic_write_around(APIC_ICR, cfg); 159 apic_write_around(APIC_ICR, cfg);
160} 160}
161 161
162void fastcall send_IPI_self(int vector) 162void send_IPI_self(int vector)
163{ 163{
164 __send_IPI_shortcut(APIC_DEST_SELF, vector); 164 __send_IPI_shortcut(APIC_DEST_SELF, vector);
165} 165}
@@ -223,7 +223,7 @@ void send_IPI_mask_sequence(cpumask_t mask, int vector)
223 */ 223 */
224 224
225 local_irq_save(flags); 225 local_irq_save(flags);
226 for (query_cpu = 0; query_cpu < NR_CPUS; ++query_cpu) { 226 for_each_possible_cpu(query_cpu) {
227 if (cpu_isset(query_cpu, mask)) { 227 if (cpu_isset(query_cpu, mask)) {
228 __send_IPI_dest_field(cpu_to_logical_apicid(query_cpu), 228 __send_IPI_dest_field(cpu_to_logical_apicid(query_cpu),
229 vector); 229 vector);
@@ -256,13 +256,14 @@ static DEFINE_SPINLOCK(tlbstate_lock);
256 * We need to reload %cr3 since the page tables may be going 256 * We need to reload %cr3 since the page tables may be going
257 * away from under us.. 257 * away from under us..
258 */ 258 */
259void leave_mm(unsigned long cpu) 259void leave_mm(int cpu)
260{ 260{
261 if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_OK) 261 if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_OK)
262 BUG(); 262 BUG();
263 cpu_clear(cpu, per_cpu(cpu_tlbstate, cpu).active_mm->cpu_vm_mask); 263 cpu_clear(cpu, per_cpu(cpu_tlbstate, cpu).active_mm->cpu_vm_mask);
264 load_cr3(swapper_pg_dir); 264 load_cr3(swapper_pg_dir);
265} 265}
266EXPORT_SYMBOL_GPL(leave_mm);
266 267
267/* 268/*
268 * 269 *
@@ -310,7 +311,7 @@ void leave_mm(unsigned long cpu)
310 * 2) Leave the mm if we are in the lazy tlb mode. 311 * 2) Leave the mm if we are in the lazy tlb mode.
311 */ 312 */
312 313
313fastcall void smp_invalidate_interrupt(struct pt_regs *regs) 314void smp_invalidate_interrupt(struct pt_regs *regs)
314{ 315{
315 unsigned long cpu; 316 unsigned long cpu;
316 317
@@ -638,13 +639,13 @@ static void native_smp_send_stop(void)
638 * all the work is done automatically when 639 * all the work is done automatically when
639 * we return from the interrupt. 640 * we return from the interrupt.
640 */ 641 */
641fastcall void smp_reschedule_interrupt(struct pt_regs *regs) 642void smp_reschedule_interrupt(struct pt_regs *regs)
642{ 643{
643 ack_APIC_irq(); 644 ack_APIC_irq();
644 __get_cpu_var(irq_stat).irq_resched_count++; 645 __get_cpu_var(irq_stat).irq_resched_count++;
645} 646}
646 647
647fastcall void smp_call_function_interrupt(struct pt_regs *regs) 648void smp_call_function_interrupt(struct pt_regs *regs)
648{ 649{
649 void (*func) (void *info) = call_data->func; 650 void (*func) (void *info) = call_data->func;
650 void *info = call_data->info; 651 void *info = call_data->info;
@@ -675,7 +676,7 @@ static int convert_apicid_to_cpu(int apic_id)
675{ 676{
676 int i; 677 int i;
677 678
678 for (i = 0; i < NR_CPUS; i++) { 679 for_each_possible_cpu(i) {
679 if (per_cpu(x86_cpu_to_apicid, i) == apic_id) 680 if (per_cpu(x86_cpu_to_apicid, i) == apic_id)
680 return i; 681 return i;
681 } 682 }
diff --git a/arch/x86/kernel/smp_64.c b/arch/x86/kernel/smp_64.c
index 03fa6ed559c6..2fd74b06db67 100644
--- a/arch/x86/kernel/smp_64.c
+++ b/arch/x86/kernel/smp_64.c
@@ -29,7 +29,7 @@
29#include <asm/idle.h> 29#include <asm/idle.h>
30 30
31/* 31/*
32 * Smarter SMP flushing macros. 32 * Smarter SMP flushing macros.
33 * c/o Linus Torvalds. 33 * c/o Linus Torvalds.
34 * 34 *
35 * These mean you can really definitely utterly forget about 35 * These mean you can really definitely utterly forget about
@@ -37,15 +37,15 @@
37 * 37 *
38 * Optimizations Manfred Spraul <manfred@colorfullife.com> 38 * Optimizations Manfred Spraul <manfred@colorfullife.com>
39 * 39 *
40 * More scalable flush, from Andi Kleen 40 * More scalable flush, from Andi Kleen
41 * 41 *
42 * To avoid global state use 8 different call vectors. 42 * To avoid global state use 8 different call vectors.
43 * Each CPU uses a specific vector to trigger flushes on other 43 * Each CPU uses a specific vector to trigger flushes on other
44 * CPUs. Depending on the received vector the target CPUs look into 44 * CPUs. Depending on the received vector the target CPUs look into
45 * the right per cpu variable for the flush data. 45 * the right per cpu variable for the flush data.
46 * 46 *
47 * With more than 8 CPUs they are hashed to the 8 available 47 * With more than 8 CPUs they are hashed to the 8 available
48 * vectors. The limited global vector space forces us to this right now. 48 * vectors. The limited global vector space forces us to this right now.
49 * In future when interrupts are split into per CPU domains this could be 49 * In future when interrupts are split into per CPU domains this could be
50 * fixed, at the cost of triggering multiple IPIs in some cases. 50 * fixed, at the cost of triggering multiple IPIs in some cases.
51 */ 51 */
@@ -55,7 +55,6 @@ union smp_flush_state {
55 cpumask_t flush_cpumask; 55 cpumask_t flush_cpumask;
56 struct mm_struct *flush_mm; 56 struct mm_struct *flush_mm;
57 unsigned long flush_va; 57 unsigned long flush_va;
58#define FLUSH_ALL -1ULL
59 spinlock_t tlbstate_lock; 58 spinlock_t tlbstate_lock;
60 }; 59 };
61 char pad[SMP_CACHE_BYTES]; 60 char pad[SMP_CACHE_BYTES];
@@ -67,16 +66,17 @@ union smp_flush_state {
67static DEFINE_PER_CPU(union smp_flush_state, flush_state); 66static DEFINE_PER_CPU(union smp_flush_state, flush_state);
68 67
69/* 68/*
70 * We cannot call mmdrop() because we are in interrupt context, 69 * We cannot call mmdrop() because we are in interrupt context,
71 * instead update mm->cpu_vm_mask. 70 * instead update mm->cpu_vm_mask.
72 */ 71 */
73static inline void leave_mm(int cpu) 72void leave_mm(int cpu)
74{ 73{
75 if (read_pda(mmu_state) == TLBSTATE_OK) 74 if (read_pda(mmu_state) == TLBSTATE_OK)
76 BUG(); 75 BUG();
77 cpu_clear(cpu, read_pda(active_mm)->cpu_vm_mask); 76 cpu_clear(cpu, read_pda(active_mm)->cpu_vm_mask);
78 load_cr3(swapper_pg_dir); 77 load_cr3(swapper_pg_dir);
79} 78}
79EXPORT_SYMBOL_GPL(leave_mm);
80 80
81/* 81/*
82 * 82 *
@@ -85,25 +85,25 @@ static inline void leave_mm(int cpu)
85 * 1) switch_mm() either 1a) or 1b) 85 * 1) switch_mm() either 1a) or 1b)
86 * 1a) thread switch to a different mm 86 * 1a) thread switch to a different mm
87 * 1a1) cpu_clear(cpu, old_mm->cpu_vm_mask); 87 * 1a1) cpu_clear(cpu, old_mm->cpu_vm_mask);
88 * Stop ipi delivery for the old mm. This is not synchronized with 88 * Stop ipi delivery for the old mm. This is not synchronized with
89 * the other cpus, but smp_invalidate_interrupt ignore flush ipis 89 * the other cpus, but smp_invalidate_interrupt ignore flush ipis
90 * for the wrong mm, and in the worst case we perform a superfluous 90 * for the wrong mm, and in the worst case we perform a superfluous
91 * tlb flush. 91 * tlb flush.
92 * 1a2) set cpu mmu_state to TLBSTATE_OK 92 * 1a2) set cpu mmu_state to TLBSTATE_OK
93 * Now the smp_invalidate_interrupt won't call leave_mm if cpu0 93 * Now the smp_invalidate_interrupt won't call leave_mm if cpu0
94 * was in lazy tlb mode. 94 * was in lazy tlb mode.
95 * 1a3) update cpu active_mm 95 * 1a3) update cpu active_mm
96 * Now cpu0 accepts tlb flushes for the new mm. 96 * Now cpu0 accepts tlb flushes for the new mm.
97 * 1a4) cpu_set(cpu, new_mm->cpu_vm_mask); 97 * 1a4) cpu_set(cpu, new_mm->cpu_vm_mask);
98 * Now the other cpus will send tlb flush ipis. 98 * Now the other cpus will send tlb flush ipis.
99 * 1a4) change cr3. 99 * 1a4) change cr3.
100 * 1b) thread switch without mm change 100 * 1b) thread switch without mm change
101 * cpu active_mm is correct, cpu0 already handles 101 * cpu active_mm is correct, cpu0 already handles
102 * flush ipis. 102 * flush ipis.
103 * 1b1) set cpu mmu_state to TLBSTATE_OK 103 * 1b1) set cpu mmu_state to TLBSTATE_OK
104 * 1b2) test_and_set the cpu bit in cpu_vm_mask. 104 * 1b2) test_and_set the cpu bit in cpu_vm_mask.
105 * Atomically set the bit [other cpus will start sending flush ipis], 105 * Atomically set the bit [other cpus will start sending flush ipis],
106 * and test the bit. 106 * and test the bit.
107 * 1b3) if the bit was 0: leave_mm was called, flush the tlb. 107 * 1b3) if the bit was 0: leave_mm was called, flush the tlb.
108 * 2) switch %%esp, ie current 108 * 2) switch %%esp, ie current
109 * 109 *
@@ -137,12 +137,12 @@ asmlinkage void smp_invalidate_interrupt(struct pt_regs *regs)
137 * orig_rax contains the negated interrupt vector. 137 * orig_rax contains the negated interrupt vector.
138 * Use that to determine where the sender put the data. 138 * Use that to determine where the sender put the data.
139 */ 139 */
140 sender = ~regs->orig_rax - INVALIDATE_TLB_VECTOR_START; 140 sender = ~regs->orig_ax - INVALIDATE_TLB_VECTOR_START;
141 f = &per_cpu(flush_state, sender); 141 f = &per_cpu(flush_state, sender);
142 142
143 if (!cpu_isset(cpu, f->flush_cpumask)) 143 if (!cpu_isset(cpu, f->flush_cpumask))
144 goto out; 144 goto out;
145 /* 145 /*
146 * This was a BUG() but until someone can quote me the 146 * This was a BUG() but until someone can quote me the
147 * line from the intel manual that guarantees an IPI to 147 * line from the intel manual that guarantees an IPI to
148 * multiple CPUs is retried _only_ on the erroring CPUs 148 * multiple CPUs is retried _only_ on the erroring CPUs
@@ -150,10 +150,10 @@ asmlinkage void smp_invalidate_interrupt(struct pt_regs *regs)
150 * 150 *
151 * BUG(); 151 * BUG();
152 */ 152 */
153 153
154 if (f->flush_mm == read_pda(active_mm)) { 154 if (f->flush_mm == read_pda(active_mm)) {
155 if (read_pda(mmu_state) == TLBSTATE_OK) { 155 if (read_pda(mmu_state) == TLBSTATE_OK) {
156 if (f->flush_va == FLUSH_ALL) 156 if (f->flush_va == TLB_FLUSH_ALL)
157 local_flush_tlb(); 157 local_flush_tlb();
158 else 158 else
159 __flush_tlb_one(f->flush_va); 159 __flush_tlb_one(f->flush_va);
@@ -166,19 +166,22 @@ out:
166 add_pda(irq_tlb_count, 1); 166 add_pda(irq_tlb_count, 1);
167} 167}
168 168
169static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm, 169void native_flush_tlb_others(const cpumask_t *cpumaskp, struct mm_struct *mm,
170 unsigned long va) 170 unsigned long va)
171{ 171{
172 int sender; 172 int sender;
173 union smp_flush_state *f; 173 union smp_flush_state *f;
174 cpumask_t cpumask = *cpumaskp;
174 175
175 /* Caller has disabled preemption */ 176 /* Caller has disabled preemption */
176 sender = smp_processor_id() % NUM_INVALIDATE_TLB_VECTORS; 177 sender = smp_processor_id() % NUM_INVALIDATE_TLB_VECTORS;
177 f = &per_cpu(flush_state, sender); 178 f = &per_cpu(flush_state, sender);
178 179
179 /* Could avoid this lock when 180 /*
180 num_online_cpus() <= NUM_INVALIDATE_TLB_VECTORS, but it is 181 * Could avoid this lock when
181 probably not worth checking this for a cache-hot lock. */ 182 * num_online_cpus() <= NUM_INVALIDATE_TLB_VECTORS, but it is
183 * probably not worth checking this for a cache-hot lock.
184 */
182 spin_lock(&f->tlbstate_lock); 185 spin_lock(&f->tlbstate_lock);
183 186
184 f->flush_mm = mm; 187 f->flush_mm = mm;
@@ -202,14 +205,14 @@ static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm,
202int __cpuinit init_smp_flush(void) 205int __cpuinit init_smp_flush(void)
203{ 206{
204 int i; 207 int i;
208
205 for_each_cpu_mask(i, cpu_possible_map) { 209 for_each_cpu_mask(i, cpu_possible_map) {
206 spin_lock_init(&per_cpu(flush_state, i).tlbstate_lock); 210 spin_lock_init(&per_cpu(flush_state, i).tlbstate_lock);
207 } 211 }
208 return 0; 212 return 0;
209} 213}
210
211core_initcall(init_smp_flush); 214core_initcall(init_smp_flush);
212 215
213void flush_tlb_current_task(void) 216void flush_tlb_current_task(void)
214{ 217{
215 struct mm_struct *mm = current->mm; 218 struct mm_struct *mm = current->mm;
@@ -221,10 +224,9 @@ void flush_tlb_current_task(void)
221 224
222 local_flush_tlb(); 225 local_flush_tlb();
223 if (!cpus_empty(cpu_mask)) 226 if (!cpus_empty(cpu_mask))
224 flush_tlb_others(cpu_mask, mm, FLUSH_ALL); 227 flush_tlb_others(cpu_mask, mm, TLB_FLUSH_ALL);
225 preempt_enable(); 228 preempt_enable();
226} 229}
227EXPORT_SYMBOL(flush_tlb_current_task);
228 230
229void flush_tlb_mm (struct mm_struct * mm) 231void flush_tlb_mm (struct mm_struct * mm)
230{ 232{
@@ -241,11 +243,10 @@ void flush_tlb_mm (struct mm_struct * mm)
241 leave_mm(smp_processor_id()); 243 leave_mm(smp_processor_id());
242 } 244 }
243 if (!cpus_empty(cpu_mask)) 245 if (!cpus_empty(cpu_mask))
244 flush_tlb_others(cpu_mask, mm, FLUSH_ALL); 246 flush_tlb_others(cpu_mask, mm, TLB_FLUSH_ALL);
245 247
246 preempt_enable(); 248 preempt_enable();
247} 249}
248EXPORT_SYMBOL(flush_tlb_mm);
249 250
250void flush_tlb_page(struct vm_area_struct * vma, unsigned long va) 251void flush_tlb_page(struct vm_area_struct * vma, unsigned long va)
251{ 252{
@@ -259,8 +260,8 @@ void flush_tlb_page(struct vm_area_struct * vma, unsigned long va)
259 if (current->active_mm == mm) { 260 if (current->active_mm == mm) {
260 if(current->mm) 261 if(current->mm)
261 __flush_tlb_one(va); 262 __flush_tlb_one(va);
262 else 263 else
263 leave_mm(smp_processor_id()); 264 leave_mm(smp_processor_id());
264 } 265 }
265 266
266 if (!cpus_empty(cpu_mask)) 267 if (!cpus_empty(cpu_mask))
@@ -268,7 +269,6 @@ void flush_tlb_page(struct vm_area_struct * vma, unsigned long va)
268 269
269 preempt_enable(); 270 preempt_enable();
270} 271}
271EXPORT_SYMBOL(flush_tlb_page);
272 272
273static void do_flush_tlb_all(void* info) 273static void do_flush_tlb_all(void* info)
274{ 274{
@@ -325,11 +325,9 @@ void unlock_ipi_call_lock(void)
325 * this function sends a 'generic call function' IPI to all other CPU 325 * this function sends a 'generic call function' IPI to all other CPU
326 * of the system defined in the mask. 326 * of the system defined in the mask.
327 */ 327 */
328 328static int __smp_call_function_mask(cpumask_t mask,
329static int 329 void (*func)(void *), void *info,
330__smp_call_function_mask(cpumask_t mask, 330 int wait)
331 void (*func)(void *), void *info,
332 int wait)
333{ 331{
334 struct call_data_struct data; 332 struct call_data_struct data;
335 cpumask_t allbutself; 333 cpumask_t allbutself;
@@ -417,11 +415,10 @@ EXPORT_SYMBOL(smp_call_function_mask);
417 */ 415 */
418 416
419int smp_call_function_single (int cpu, void (*func) (void *info), void *info, 417int smp_call_function_single (int cpu, void (*func) (void *info), void *info,
420 int nonatomic, int wait) 418 int nonatomic, int wait)
421{ 419{
422 /* prevent preemption and reschedule on another processor */ 420 /* prevent preemption and reschedule on another processor */
423 int ret; 421 int ret, me = get_cpu();
424 int me = get_cpu();
425 422
426 /* Can deadlock when called with interrupts disabled */ 423 /* Can deadlock when called with interrupts disabled */
427 WARN_ON(irqs_disabled()); 424 WARN_ON(irqs_disabled());
@@ -471,9 +468,9 @@ static void stop_this_cpu(void *dummy)
471 */ 468 */
472 cpu_clear(smp_processor_id(), cpu_online_map); 469 cpu_clear(smp_processor_id(), cpu_online_map);
473 disable_local_APIC(); 470 disable_local_APIC();
474 for (;;) 471 for (;;)
475 halt(); 472 halt();
476} 473}
477 474
478void smp_send_stop(void) 475void smp_send_stop(void)
479{ 476{
diff --git a/arch/x86/kernel/smpboot_32.c b/arch/x86/kernel/smpboot_32.c
index 4ea80cbe52e5..5787a0c3e296 100644
--- a/arch/x86/kernel/smpboot_32.c
+++ b/arch/x86/kernel/smpboot_32.c
@@ -83,7 +83,6 @@ EXPORT_SYMBOL(cpu_online_map);
83 83
84cpumask_t cpu_callin_map; 84cpumask_t cpu_callin_map;
85cpumask_t cpu_callout_map; 85cpumask_t cpu_callout_map;
86EXPORT_SYMBOL(cpu_callout_map);
87cpumask_t cpu_possible_map; 86cpumask_t cpu_possible_map;
88EXPORT_SYMBOL(cpu_possible_map); 87EXPORT_SYMBOL(cpu_possible_map);
89static cpumask_t smp_commenced_mask; 88static cpumask_t smp_commenced_mask;
@@ -92,15 +91,10 @@ static cpumask_t smp_commenced_mask;
92DEFINE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info); 91DEFINE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info);
93EXPORT_PER_CPU_SYMBOL(cpu_info); 92EXPORT_PER_CPU_SYMBOL(cpu_info);
94 93
95/* 94/* which logical CPU number maps to which CPU (physical APIC ID) */
96 * The following static array is used during kernel startup
97 * and the x86_cpu_to_apicid_ptr contains the address of the
98 * array during this time. Is it zeroed when the per_cpu
99 * data area is removed.
100 */
101u8 x86_cpu_to_apicid_init[NR_CPUS] __initdata = 95u8 x86_cpu_to_apicid_init[NR_CPUS] __initdata =
102 { [0 ... NR_CPUS-1] = BAD_APICID }; 96 { [0 ... NR_CPUS-1] = BAD_APICID };
103void *x86_cpu_to_apicid_ptr; 97void *x86_cpu_to_apicid_early_ptr;
104DEFINE_PER_CPU(u8, x86_cpu_to_apicid) = BAD_APICID; 98DEFINE_PER_CPU(u8, x86_cpu_to_apicid) = BAD_APICID;
105EXPORT_PER_CPU_SYMBOL(x86_cpu_to_apicid); 99EXPORT_PER_CPU_SYMBOL(x86_cpu_to_apicid);
106 100
@@ -113,7 +107,6 @@ u8 apicid_2_node[MAX_APICID];
113extern const unsigned char trampoline_data []; 107extern const unsigned char trampoline_data [];
114extern const unsigned char trampoline_end []; 108extern const unsigned char trampoline_end [];
115static unsigned char *trampoline_base; 109static unsigned char *trampoline_base;
116static int trampoline_exec;
117 110
118static void map_cpu_to_logical_apicid(void); 111static void map_cpu_to_logical_apicid(void);
119 112
@@ -138,17 +131,13 @@ static unsigned long __cpuinit setup_trampoline(void)
138 */ 131 */
139void __init smp_alloc_memory(void) 132void __init smp_alloc_memory(void)
140{ 133{
141 trampoline_base = (void *) alloc_bootmem_low_pages(PAGE_SIZE); 134 trampoline_base = alloc_bootmem_low_pages(PAGE_SIZE);
142 /* 135 /*
143 * Has to be in very low memory so we can execute 136 * Has to be in very low memory so we can execute
144 * real-mode AP code. 137 * real-mode AP code.
145 */ 138 */
146 if (__pa(trampoline_base) >= 0x9F000) 139 if (__pa(trampoline_base) >= 0x9F000)
147 BUG(); 140 BUG();
148 /*
149 * Make the SMP trampoline executable:
150 */
151 trampoline_exec = set_kernel_exec((unsigned long)trampoline_base, 1);
152} 141}
153 142
154/* 143/*
@@ -405,7 +394,7 @@ static void __cpuinit start_secondary(void *unused)
405 setup_secondary_clock(); 394 setup_secondary_clock();
406 if (nmi_watchdog == NMI_IO_APIC) { 395 if (nmi_watchdog == NMI_IO_APIC) {
407 disable_8259A_irq(0); 396 disable_8259A_irq(0);
408 enable_NMI_through_LVT0(NULL); 397 enable_NMI_through_LVT0();
409 enable_8259A_irq(0); 398 enable_8259A_irq(0);
410 } 399 }
411 /* 400 /*
@@ -448,38 +437,38 @@ void __devinit initialize_secondary(void)
448{ 437{
449 /* 438 /*
450 * We don't actually need to load the full TSS, 439 * We don't actually need to load the full TSS,
451 * basically just the stack pointer and the eip. 440 * basically just the stack pointer and the ip.
452 */ 441 */
453 442
454 asm volatile( 443 asm volatile(
455 "movl %0,%%esp\n\t" 444 "movl %0,%%esp\n\t"
456 "jmp *%1" 445 "jmp *%1"
457 : 446 :
458 :"m" (current->thread.esp),"m" (current->thread.eip)); 447 :"m" (current->thread.sp),"m" (current->thread.ip));
459} 448}
460 449
461/* Static state in head.S used to set up a CPU */ 450/* Static state in head.S used to set up a CPU */
462extern struct { 451extern struct {
463 void * esp; 452 void * sp;
464 unsigned short ss; 453 unsigned short ss;
465} stack_start; 454} stack_start;
466 455
467#ifdef CONFIG_NUMA 456#ifdef CONFIG_NUMA
468 457
469/* which logical CPUs are on which nodes */ 458/* which logical CPUs are on which nodes */
470cpumask_t node_2_cpu_mask[MAX_NUMNODES] __read_mostly = 459cpumask_t node_to_cpumask_map[MAX_NUMNODES] __read_mostly =
471 { [0 ... MAX_NUMNODES-1] = CPU_MASK_NONE }; 460 { [0 ... MAX_NUMNODES-1] = CPU_MASK_NONE };
472EXPORT_SYMBOL(node_2_cpu_mask); 461EXPORT_SYMBOL(node_to_cpumask_map);
473/* which node each logical CPU is on */ 462/* which node each logical CPU is on */
474int cpu_2_node[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = 0 }; 463int cpu_to_node_map[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = 0 };
475EXPORT_SYMBOL(cpu_2_node); 464EXPORT_SYMBOL(cpu_to_node_map);
476 465
477/* set up a mapping between cpu and node. */ 466/* set up a mapping between cpu and node. */
478static inline void map_cpu_to_node(int cpu, int node) 467static inline void map_cpu_to_node(int cpu, int node)
479{ 468{
480 printk("Mapping cpu %d to node %d\n", cpu, node); 469 printk("Mapping cpu %d to node %d\n", cpu, node);
481 cpu_set(cpu, node_2_cpu_mask[node]); 470 cpu_set(cpu, node_to_cpumask_map[node]);
482 cpu_2_node[cpu] = node; 471 cpu_to_node_map[cpu] = node;
483} 472}
484 473
485/* undo a mapping between cpu and node. */ 474/* undo a mapping between cpu and node. */
@@ -489,8 +478,8 @@ static inline void unmap_cpu_to_node(int cpu)
489 478
490 printk("Unmapping cpu %d from all nodes\n", cpu); 479 printk("Unmapping cpu %d from all nodes\n", cpu);
491 for (node = 0; node < MAX_NUMNODES; node ++) 480 for (node = 0; node < MAX_NUMNODES; node ++)
492 cpu_clear(cpu, node_2_cpu_mask[node]); 481 cpu_clear(cpu, node_to_cpumask_map[node]);
493 cpu_2_node[cpu] = 0; 482 cpu_to_node_map[cpu] = 0;
494} 483}
495#else /* !CONFIG_NUMA */ 484#else /* !CONFIG_NUMA */
496 485
@@ -668,7 +657,7 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip)
668 * target processor state. 657 * target processor state.
669 */ 658 */
670 startup_ipi_hook(phys_apicid, (unsigned long) start_secondary, 659 startup_ipi_hook(phys_apicid, (unsigned long) start_secondary,
671 (unsigned long) stack_start.esp); 660 (unsigned long) stack_start.sp);
672 661
673 /* 662 /*
674 * Run STARTUP IPI loop. 663 * Run STARTUP IPI loop.
@@ -754,7 +743,7 @@ static inline struct task_struct * __cpuinit alloc_idle_task(int cpu)
754 /* initialize thread_struct. we really want to avoid destroy 743 /* initialize thread_struct. we really want to avoid destroy
755 * idle tread 744 * idle tread
756 */ 745 */
757 idle->thread.esp = (unsigned long)task_pt_regs(idle); 746 idle->thread.sp = (unsigned long)task_pt_regs(idle);
758 init_idle(idle, cpu); 747 init_idle(idle, cpu);
759 return idle; 748 return idle;
760 } 749 }
@@ -799,7 +788,7 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu)
799 per_cpu(current_task, cpu) = idle; 788 per_cpu(current_task, cpu) = idle;
800 early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); 789 early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
801 790
802 idle->thread.eip = (unsigned long) start_secondary; 791 idle->thread.ip = (unsigned long) start_secondary;
803 /* start_eip had better be page-aligned! */ 792 /* start_eip had better be page-aligned! */
804 start_eip = setup_trampoline(); 793 start_eip = setup_trampoline();
805 794
@@ -807,9 +796,9 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu)
807 alternatives_smp_switch(1); 796 alternatives_smp_switch(1);
808 797
809 /* So we see what's up */ 798 /* So we see what's up */
810 printk("Booting processor %d/%d eip %lx\n", cpu, apicid, start_eip); 799 printk("Booting processor %d/%d ip %lx\n", cpu, apicid, start_eip);
811 /* Stack for startup_32 can be just as for start_secondary onwards */ 800 /* Stack for startup_32 can be just as for start_secondary onwards */
812 stack_start.esp = (void *) idle->thread.esp; 801 stack_start.sp = (void *) idle->thread.sp;
813 802
814 irq_ctx_init(cpu); 803 irq_ctx_init(cpu);
815 804
@@ -1091,7 +1080,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
1091 * Allow the user to impress friends. 1080 * Allow the user to impress friends.
1092 */ 1081 */
1093 Dprintk("Before bogomips.\n"); 1082 Dprintk("Before bogomips.\n");
1094 for (cpu = 0; cpu < NR_CPUS; cpu++) 1083 for_each_possible_cpu(cpu)
1095 if (cpu_isset(cpu, cpu_callout_map)) 1084 if (cpu_isset(cpu, cpu_callout_map))
1096 bogosum += cpu_data(cpu).loops_per_jiffy; 1085 bogosum += cpu_data(cpu).loops_per_jiffy;
1097 printk(KERN_INFO 1086 printk(KERN_INFO
@@ -1122,7 +1111,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
1122 * construct cpu_sibling_map, so that we can tell sibling CPUs 1111 * construct cpu_sibling_map, so that we can tell sibling CPUs
1123 * efficiently. 1112 * efficiently.
1124 */ 1113 */
1125 for (cpu = 0; cpu < NR_CPUS; cpu++) { 1114 for_each_possible_cpu(cpu) {
1126 cpus_clear(per_cpu(cpu_sibling_map, cpu)); 1115 cpus_clear(per_cpu(cpu_sibling_map, cpu));
1127 cpus_clear(per_cpu(cpu_core_map, cpu)); 1116 cpus_clear(per_cpu(cpu_core_map, cpu));
1128 } 1117 }
@@ -1296,12 +1285,6 @@ void __init native_smp_cpus_done(unsigned int max_cpus)
1296 setup_ioapic_dest(); 1285 setup_ioapic_dest();
1297#endif 1286#endif
1298 zap_low_mappings(); 1287 zap_low_mappings();
1299#ifndef CONFIG_HOTPLUG_CPU
1300 /*
1301 * Disable executability of the SMP trampoline:
1302 */
1303 set_kernel_exec((unsigned long)trampoline_base, trampoline_exec);
1304#endif
1305} 1288}
1306 1289
1307void __init smp_intr_init(void) 1290void __init smp_intr_init(void)
diff --git a/arch/x86/kernel/smpboot_64.c b/arch/x86/kernel/smpboot_64.c
index aaf4e1291217..cc64b8085c2a 100644
--- a/arch/x86/kernel/smpboot_64.c
+++ b/arch/x86/kernel/smpboot_64.c
@@ -65,7 +65,7 @@ int smp_num_siblings = 1;
65EXPORT_SYMBOL(smp_num_siblings); 65EXPORT_SYMBOL(smp_num_siblings);
66 66
67/* Last level cache ID of each logical CPU */ 67/* Last level cache ID of each logical CPU */
68DEFINE_PER_CPU(u8, cpu_llc_id) = BAD_APICID; 68DEFINE_PER_CPU(u16, cpu_llc_id) = BAD_APICID;
69 69
70/* Bitmask of currently online CPUs */ 70/* Bitmask of currently online CPUs */
71cpumask_t cpu_online_map __read_mostly; 71cpumask_t cpu_online_map __read_mostly;
@@ -78,8 +78,6 @@ EXPORT_SYMBOL(cpu_online_map);
78 */ 78 */
79cpumask_t cpu_callin_map; 79cpumask_t cpu_callin_map;
80cpumask_t cpu_callout_map; 80cpumask_t cpu_callout_map;
81EXPORT_SYMBOL(cpu_callout_map);
82
83cpumask_t cpu_possible_map; 81cpumask_t cpu_possible_map;
84EXPORT_SYMBOL(cpu_possible_map); 82EXPORT_SYMBOL(cpu_possible_map);
85 83
@@ -113,10 +111,20 @@ DEFINE_PER_CPU(int, cpu_state) = { 0 };
113 * a new thread. Also avoids complicated thread destroy functionality 111 * a new thread. Also avoids complicated thread destroy functionality
114 * for idle threads. 112 * for idle threads.
115 */ 113 */
114#ifdef CONFIG_HOTPLUG_CPU
115/*
116 * Needed only for CONFIG_HOTPLUG_CPU because __cpuinitdata is
117 * removed after init for !CONFIG_HOTPLUG_CPU.
118 */
119static DEFINE_PER_CPU(struct task_struct *, idle_thread_array);
120#define get_idle_for_cpu(x) (per_cpu(idle_thread_array, x))
121#define set_idle_for_cpu(x,p) (per_cpu(idle_thread_array, x) = (p))
122#else
116struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ; 123struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ;
117
118#define get_idle_for_cpu(x) (idle_thread_array[(x)]) 124#define get_idle_for_cpu(x) (idle_thread_array[(x)])
119#define set_idle_for_cpu(x,p) (idle_thread_array[(x)] = (p)) 125#define set_idle_for_cpu(x,p) (idle_thread_array[(x)] = (p))
126#endif
127
120 128
121/* 129/*
122 * Currently trivial. Write the real->protected mode 130 * Currently trivial. Write the real->protected mode
@@ -212,6 +220,7 @@ void __cpuinit smp_callin(void)
212 220
213 Dprintk("CALLIN, before setup_local_APIC().\n"); 221 Dprintk("CALLIN, before setup_local_APIC().\n");
214 setup_local_APIC(); 222 setup_local_APIC();
223 end_local_APIC_setup();
215 224
216 /* 225 /*
217 * Get our bogomips. 226 * Get our bogomips.
@@ -338,7 +347,7 @@ void __cpuinit start_secondary(void)
338 347
339 if (nmi_watchdog == NMI_IO_APIC) { 348 if (nmi_watchdog == NMI_IO_APIC) {
340 disable_8259A_irq(0); 349 disable_8259A_irq(0);
341 enable_NMI_through_LVT0(NULL); 350 enable_NMI_through_LVT0();
342 enable_8259A_irq(0); 351 enable_8259A_irq(0);
343 } 352 }
344 353
@@ -370,7 +379,7 @@ void __cpuinit start_secondary(void)
370 379
371 unlock_ipi_call_lock(); 380 unlock_ipi_call_lock();
372 381
373 setup_secondary_APIC_clock(); 382 setup_secondary_clock();
374 383
375 cpu_idle(); 384 cpu_idle();
376} 385}
@@ -384,19 +393,20 @@ static void inquire_remote_apic(int apicid)
384 unsigned i, regs[] = { APIC_ID >> 4, APIC_LVR >> 4, APIC_SPIV >> 4 }; 393 unsigned i, regs[] = { APIC_ID >> 4, APIC_LVR >> 4, APIC_SPIV >> 4 };
385 char *names[] = { "ID", "VERSION", "SPIV" }; 394 char *names[] = { "ID", "VERSION", "SPIV" };
386 int timeout; 395 int timeout;
387 unsigned int status; 396 u32 status;
388 397
389 printk(KERN_INFO "Inquiring remote APIC #%d...\n", apicid); 398 printk(KERN_INFO "Inquiring remote APIC #%d...\n", apicid);
390 399
391 for (i = 0; i < ARRAY_SIZE(regs); i++) { 400 for (i = 0; i < ARRAY_SIZE(regs); i++) {
392 printk("... APIC #%d %s: ", apicid, names[i]); 401 printk(KERN_INFO "... APIC #%d %s: ", apicid, names[i]);
393 402
394 /* 403 /*
395 * Wait for idle. 404 * Wait for idle.
396 */ 405 */
397 status = safe_apic_wait_icr_idle(); 406 status = safe_apic_wait_icr_idle();
398 if (status) 407 if (status)
399 printk("a previous APIC delivery may have failed\n"); 408 printk(KERN_CONT
409 "a previous APIC delivery may have failed\n");
400 410
401 apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(apicid)); 411 apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(apicid));
402 apic_write(APIC_ICR, APIC_DM_REMRD | regs[i]); 412 apic_write(APIC_ICR, APIC_DM_REMRD | regs[i]);
@@ -410,10 +420,10 @@ static void inquire_remote_apic(int apicid)
410 switch (status) { 420 switch (status) {
411 case APIC_ICR_RR_VALID: 421 case APIC_ICR_RR_VALID:
412 status = apic_read(APIC_RRR); 422 status = apic_read(APIC_RRR);
413 printk("%08x\n", status); 423 printk(KERN_CONT "%08x\n", status);
414 break; 424 break;
415 default: 425 default:
416 printk("failed\n"); 426 printk(KERN_CONT "failed\n");
417 } 427 }
418 } 428 }
419} 429}
@@ -466,7 +476,7 @@ static int __cpuinit wakeup_secondary_via_INIT(int phys_apicid, unsigned int sta
466 */ 476 */
467 Dprintk("#startup loops: %d.\n", num_starts); 477 Dprintk("#startup loops: %d.\n", num_starts);
468 478
469 maxlvt = get_maxlvt(); 479 maxlvt = lapic_get_maxlvt();
470 480
471 for (j = 1; j <= num_starts; j++) { 481 for (j = 1; j <= num_starts; j++) {
472 Dprintk("Sending STARTUP #%d.\n",j); 482 Dprintk("Sending STARTUP #%d.\n",j);
@@ -577,7 +587,7 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid)
577 c_idle.idle = get_idle_for_cpu(cpu); 587 c_idle.idle = get_idle_for_cpu(cpu);
578 588
579 if (c_idle.idle) { 589 if (c_idle.idle) {
580 c_idle.idle->thread.rsp = (unsigned long) (((struct pt_regs *) 590 c_idle.idle->thread.sp = (unsigned long) (((struct pt_regs *)
581 (THREAD_SIZE + task_stack_page(c_idle.idle))) - 1); 591 (THREAD_SIZE + task_stack_page(c_idle.idle))) - 1);
582 init_idle(c_idle.idle, cpu); 592 init_idle(c_idle.idle, cpu);
583 goto do_rest; 593 goto do_rest;
@@ -613,8 +623,8 @@ do_rest:
613 623
614 start_rip = setup_trampoline(); 624 start_rip = setup_trampoline();
615 625
616 init_rsp = c_idle.idle->thread.rsp; 626 init_rsp = c_idle.idle->thread.sp;
617 per_cpu(init_tss,cpu).rsp0 = init_rsp; 627 load_sp0(&per_cpu(init_tss, cpu), &c_idle.idle->thread);
618 initial_code = start_secondary; 628 initial_code = start_secondary;
619 clear_tsk_thread_flag(c_idle.idle, TIF_FORK); 629 clear_tsk_thread_flag(c_idle.idle, TIF_FORK);
620 630
@@ -691,7 +701,7 @@ do_rest:
691 } 701 }
692 if (boot_error) { 702 if (boot_error) {
693 cpu_clear(cpu, cpu_callout_map); /* was set here (do_boot_cpu()) */ 703 cpu_clear(cpu, cpu_callout_map); /* was set here (do_boot_cpu()) */
694 clear_bit(cpu, &cpu_initialized); /* was set by cpu_init() */ 704 clear_bit(cpu, (unsigned long *)&cpu_initialized); /* was set by cpu_init() */
695 clear_node_cpumask(cpu); /* was set by numa_add_cpu */ 705 clear_node_cpumask(cpu); /* was set by numa_add_cpu */
696 cpu_clear(cpu, cpu_present_map); 706 cpu_clear(cpu, cpu_present_map);
697 cpu_clear(cpu, cpu_possible_map); 707 cpu_clear(cpu, cpu_possible_map);
@@ -841,24 +851,16 @@ static int __init smp_sanity_check(unsigned max_cpus)
841 return 0; 851 return 0;
842} 852}
843 853
844/* 854static void __init smp_cpu_index_default(void)
845 * Copy apicid's found by MP_processor_info from initial array to the per cpu
846 * data area. The x86_cpu_to_apicid_init array is then expendable and the
847 * x86_cpu_to_apicid_ptr is zeroed indicating that the static array is no
848 * longer available.
849 */
850void __init smp_set_apicids(void)
851{ 855{
852 int cpu; 856 int i;
857 struct cpuinfo_x86 *c;
853 858
854 for_each_cpu_mask(cpu, cpu_possible_map) { 859 for_each_cpu_mask(i, cpu_possible_map) {
855 if (per_cpu_offset(cpu)) 860 c = &cpu_data(i);
856 per_cpu(x86_cpu_to_apicid, cpu) = 861 /* mark all to hotplug */
857 x86_cpu_to_apicid_init[cpu]; 862 c->cpu_index = NR_CPUS;
858 } 863 }
859
860 /* indicate the static array will be going away soon */
861 x86_cpu_to_apicid_ptr = NULL;
862} 864}
863 865
864/* 866/*
@@ -868,9 +870,9 @@ void __init smp_set_apicids(void)
868void __init smp_prepare_cpus(unsigned int max_cpus) 870void __init smp_prepare_cpus(unsigned int max_cpus)
869{ 871{
870 nmi_watchdog_default(); 872 nmi_watchdog_default();
873 smp_cpu_index_default();
871 current_cpu_data = boot_cpu_data; 874 current_cpu_data = boot_cpu_data;
872 current_thread_info()->cpu = 0; /* needed? */ 875 current_thread_info()->cpu = 0; /* needed? */
873 smp_set_apicids();
874 set_cpu_sibling_map(0); 876 set_cpu_sibling_map(0);
875 877
876 if (smp_sanity_check(max_cpus) < 0) { 878 if (smp_sanity_check(max_cpus) < 0) {
@@ -885,6 +887,13 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
885 */ 887 */
886 setup_local_APIC(); 888 setup_local_APIC();
887 889
890 /*
891 * Enable IO APIC before setting up error vector
892 */
893 if (!skip_ioapic_setup && nr_ioapics)
894 enable_IO_APIC();
895 end_local_APIC_setup();
896
888 if (GET_APIC_ID(apic_read(APIC_ID)) != boot_cpu_id) { 897 if (GET_APIC_ID(apic_read(APIC_ID)) != boot_cpu_id) {
889 panic("Boot APIC ID in local APIC unexpected (%d vs %d)", 898 panic("Boot APIC ID in local APIC unexpected (%d vs %d)",
890 GET_APIC_ID(apic_read(APIC_ID)), boot_cpu_id); 899 GET_APIC_ID(apic_read(APIC_ID)), boot_cpu_id);
@@ -903,7 +912,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
903 * Set up local APIC timer on boot CPU. 912 * Set up local APIC timer on boot CPU.
904 */ 913 */
905 914
906 setup_boot_APIC_clock(); 915 setup_boot_clock();
907} 916}
908 917
909/* 918/*
@@ -912,7 +921,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
912void __init smp_prepare_boot_cpu(void) 921void __init smp_prepare_boot_cpu(void)
913{ 922{
914 int me = smp_processor_id(); 923 int me = smp_processor_id();
915 cpu_set(me, cpu_online_map); 924 /* already set me in cpu_online_map in boot_cpu_init() */
916 cpu_set(me, cpu_callout_map); 925 cpu_set(me, cpu_callout_map);
917 per_cpu(cpu_state, me) = CPU_ONLINE; 926 per_cpu(cpu_state, me) = CPU_ONLINE;
918} 927}
@@ -1016,7 +1025,7 @@ void remove_cpu_from_maps(void)
1016 1025
1017 cpu_clear(cpu, cpu_callout_map); 1026 cpu_clear(cpu, cpu_callout_map);
1018 cpu_clear(cpu, cpu_callin_map); 1027 cpu_clear(cpu, cpu_callin_map);
1019 clear_bit(cpu, &cpu_initialized); /* was set by cpu_init() */ 1028 clear_bit(cpu, (unsigned long *)&cpu_initialized); /* was set by cpu_init() */
1020 clear_node_cpumask(cpu); 1029 clear_node_cpumask(cpu);
1021} 1030}
1022 1031
diff --git a/arch/x86/kernel/smpcommon_32.c b/arch/x86/kernel/smpcommon_32.c
index bbfe85a0f699..8bc38af29aef 100644
--- a/arch/x86/kernel/smpcommon_32.c
+++ b/arch/x86/kernel/smpcommon_32.c
@@ -14,10 +14,11 @@ __cpuinit void init_gdt(int cpu)
14{ 14{
15 struct desc_struct *gdt = get_cpu_gdt_table(cpu); 15 struct desc_struct *gdt = get_cpu_gdt_table(cpu);
16 16
17 pack_descriptor((u32 *)&gdt[GDT_ENTRY_PERCPU].a, 17 pack_descriptor(&gdt[GDT_ENTRY_PERCPU],
18 (u32 *)&gdt[GDT_ENTRY_PERCPU].b,
19 __per_cpu_offset[cpu], 0xFFFFF, 18 __per_cpu_offset[cpu], 0xFFFFF,
20 0x80 | DESCTYPE_S | 0x2, 0x8); 19 0x2 | DESCTYPE_S, 0x8);
20
21 gdt[GDT_ENTRY_PERCPU].s = 1;
21 22
22 per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu]; 23 per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu];
23 per_cpu(cpu_number, cpu) = cpu; 24 per_cpu(cpu_number, cpu) = cpu;
diff --git a/arch/x86/kernel/srat_32.c b/arch/x86/kernel/srat_32.c
index 2a8713ec0f9a..2bf6903cb444 100644
--- a/arch/x86/kernel/srat_32.c
+++ b/arch/x86/kernel/srat_32.c
@@ -57,8 +57,6 @@ static struct node_memory_chunk_s node_memory_chunk[MAXCHUNKS];
57static int num_memory_chunks; /* total number of memory chunks */ 57static int num_memory_chunks; /* total number of memory chunks */
58static u8 __initdata apicid_to_pxm[MAX_APICID]; 58static u8 __initdata apicid_to_pxm[MAX_APICID];
59 59
60extern void * boot_ioremap(unsigned long, unsigned long);
61
62/* Identify CPU proximity domains */ 60/* Identify CPU proximity domains */
63static void __init parse_cpu_affinity_structure(char *p) 61static void __init parse_cpu_affinity_structure(char *p)
64{ 62{
@@ -299,7 +297,7 @@ int __init get_memcfg_from_srat(void)
299 } 297 }
300 298
301 rsdt = (struct acpi_table_rsdt *) 299 rsdt = (struct acpi_table_rsdt *)
302 boot_ioremap(rsdp->rsdt_physical_address, sizeof(struct acpi_table_rsdt)); 300 early_ioremap(rsdp->rsdt_physical_address, sizeof(struct acpi_table_rsdt));
303 301
304 if (!rsdt) { 302 if (!rsdt) {
305 printk(KERN_WARNING 303 printk(KERN_WARNING
@@ -339,11 +337,11 @@ int __init get_memcfg_from_srat(void)
339 for (i = 0; i < tables; i++) { 337 for (i = 0; i < tables; i++) {
340 /* Map in header, then map in full table length. */ 338 /* Map in header, then map in full table length. */
341 header = (struct acpi_table_header *) 339 header = (struct acpi_table_header *)
342 boot_ioremap(saved_rsdt.table.table_offset_entry[i], sizeof(struct acpi_table_header)); 340 early_ioremap(saved_rsdt.table.table_offset_entry[i], sizeof(struct acpi_table_header));
343 if (!header) 341 if (!header)
344 break; 342 break;
345 header = (struct acpi_table_header *) 343 header = (struct acpi_table_header *)
346 boot_ioremap(saved_rsdt.table.table_offset_entry[i], header->length); 344 early_ioremap(saved_rsdt.table.table_offset_entry[i], header->length);
347 if (!header) 345 if (!header)
348 break; 346 break;
349 347
diff --git a/arch/x86/kernel/stacktrace.c b/arch/x86/kernel/stacktrace.c
index 6fa6cf036c70..02f0f61f5b11 100644
--- a/arch/x86/kernel/stacktrace.c
+++ b/arch/x86/kernel/stacktrace.c
@@ -22,9 +22,23 @@ static int save_stack_stack(void *data, char *name)
22 return -1; 22 return -1;
23} 23}
24 24
25static void save_stack_address(void *data, unsigned long addr) 25static void save_stack_address(void *data, unsigned long addr, int reliable)
26{
27 struct stack_trace *trace = data;
28 if (trace->skip > 0) {
29 trace->skip--;
30 return;
31 }
32 if (trace->nr_entries < trace->max_entries)
33 trace->entries[trace->nr_entries++] = addr;
34}
35
36static void
37save_stack_address_nosched(void *data, unsigned long addr, int reliable)
26{ 38{
27 struct stack_trace *trace = (struct stack_trace *)data; 39 struct stack_trace *trace = (struct stack_trace *)data;
40 if (in_sched_functions(addr))
41 return;
28 if (trace->skip > 0) { 42 if (trace->skip > 0) {
29 trace->skip--; 43 trace->skip--;
30 return; 44 return;
@@ -40,13 +54,26 @@ static const struct stacktrace_ops save_stack_ops = {
40 .address = save_stack_address, 54 .address = save_stack_address,
41}; 55};
42 56
57static const struct stacktrace_ops save_stack_ops_nosched = {
58 .warning = save_stack_warning,
59 .warning_symbol = save_stack_warning_symbol,
60 .stack = save_stack_stack,
61 .address = save_stack_address_nosched,
62};
63
43/* 64/*
44 * Save stack-backtrace addresses into a stack_trace buffer. 65 * Save stack-backtrace addresses into a stack_trace buffer.
45 */ 66 */
46void save_stack_trace(struct stack_trace *trace) 67void save_stack_trace(struct stack_trace *trace)
47{ 68{
48 dump_trace(current, NULL, NULL, &save_stack_ops, trace); 69 dump_trace(current, NULL, NULL, 0, &save_stack_ops, trace);
70 if (trace->nr_entries < trace->max_entries)
71 trace->entries[trace->nr_entries++] = ULONG_MAX;
72}
73
74void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
75{
76 dump_trace(tsk, NULL, NULL, 0, &save_stack_ops_nosched, trace);
49 if (trace->nr_entries < trace->max_entries) 77 if (trace->nr_entries < trace->max_entries)
50 trace->entries[trace->nr_entries++] = ULONG_MAX; 78 trace->entries[trace->nr_entries++] = ULONG_MAX;
51} 79}
52EXPORT_SYMBOL(save_stack_trace);
diff --git a/arch/x86/kernel/step.c b/arch/x86/kernel/step.c
new file mode 100644
index 000000000000..2ef1a5f8d675
--- /dev/null
+++ b/arch/x86/kernel/step.c
@@ -0,0 +1,203 @@
1/*
2 * x86 single-step support code, common to 32-bit and 64-bit.
3 */
4#include <linux/sched.h>
5#include <linux/mm.h>
6#include <linux/ptrace.h>
7
8unsigned long convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs)
9{
10 unsigned long addr, seg;
11
12 addr = regs->ip;
13 seg = regs->cs & 0xffff;
14 if (v8086_mode(regs)) {
15 addr = (addr & 0xffff) + (seg << 4);
16 return addr;
17 }
18
19 /*
20 * We'll assume that the code segments in the GDT
21 * are all zero-based. That is largely true: the
22 * TLS segments are used for data, and the PNPBIOS
23 * and APM bios ones we just ignore here.
24 */
25 if ((seg & SEGMENT_TI_MASK) == SEGMENT_LDT) {
26 u32 *desc;
27 unsigned long base;
28
29 seg &= ~7UL;
30
31 mutex_lock(&child->mm->context.lock);
32 if (unlikely((seg >> 3) >= child->mm->context.size))
33 addr = -1L; /* bogus selector, access would fault */
34 else {
35 desc = child->mm->context.ldt + seg;
36 base = ((desc[0] >> 16) |
37 ((desc[1] & 0xff) << 16) |
38 (desc[1] & 0xff000000));
39
40 /* 16-bit code segment? */
41 if (!((desc[1] >> 22) & 1))
42 addr &= 0xffff;
43 addr += base;
44 }
45 mutex_unlock(&child->mm->context.lock);
46 }
47
48 return addr;
49}
50
51static int is_setting_trap_flag(struct task_struct *child, struct pt_regs *regs)
52{
53 int i, copied;
54 unsigned char opcode[15];
55 unsigned long addr = convert_ip_to_linear(child, regs);
56
57 copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
58 for (i = 0; i < copied; i++) {
59 switch (opcode[i]) {
60 /* popf and iret */
61 case 0x9d: case 0xcf:
62 return 1;
63
64 /* CHECKME: 64 65 */
65
66 /* opcode and address size prefixes */
67 case 0x66: case 0x67:
68 continue;
69 /* irrelevant prefixes (segment overrides and repeats) */
70 case 0x26: case 0x2e:
71 case 0x36: case 0x3e:
72 case 0x64: case 0x65:
73 case 0xf0: case 0xf2: case 0xf3:
74 continue;
75
76#ifdef CONFIG_X86_64
77 case 0x40 ... 0x4f:
78 if (regs->cs != __USER_CS)
79 /* 32-bit mode: register increment */
80 return 0;
81 /* 64-bit mode: REX prefix */
82 continue;
83#endif
84
85 /* CHECKME: f2, f3 */
86
87 /*
88 * pushf: NOTE! We should probably not let
89 * the user see the TF bit being set. But
90 * it's more pain than it's worth to avoid
91 * it, and a debugger could emulate this
92 * all in user space if it _really_ cares.
93 */
94 case 0x9c:
95 default:
96 return 0;
97 }
98 }
99 return 0;
100}
101
102/*
103 * Enable single-stepping. Return nonzero if user mode is not using TF itself.
104 */
105static int enable_single_step(struct task_struct *child)
106{
107 struct pt_regs *regs = task_pt_regs(child);
108
109 /*
110 * Always set TIF_SINGLESTEP - this guarantees that
111 * we single-step system calls etc.. This will also
112 * cause us to set TF when returning to user mode.
113 */
114 set_tsk_thread_flag(child, TIF_SINGLESTEP);
115
116 /*
117 * If TF was already set, don't do anything else
118 */
119 if (regs->flags & X86_EFLAGS_TF)
120 return 0;
121
122 /* Set TF on the kernel stack.. */
123 regs->flags |= X86_EFLAGS_TF;
124
125 /*
126 * ..but if TF is changed by the instruction we will trace,
127 * don't mark it as being "us" that set it, so that we
128 * won't clear it by hand later.
129 */
130 if (is_setting_trap_flag(child, regs))
131 return 0;
132
133 set_tsk_thread_flag(child, TIF_FORCED_TF);
134
135 return 1;
136}
137
138/*
139 * Install this value in MSR_IA32_DEBUGCTLMSR whenever child is running.
140 */
141static void write_debugctlmsr(struct task_struct *child, unsigned long val)
142{
143 child->thread.debugctlmsr = val;
144
145 if (child != current)
146 return;
147
148 wrmsrl(MSR_IA32_DEBUGCTLMSR, val);
149}
150
151/*
152 * Enable single or block step.
153 */
154static void enable_step(struct task_struct *child, bool block)
155{
156 /*
157 * Make sure block stepping (BTF) is not enabled unless it should be.
158 * Note that we don't try to worry about any is_setting_trap_flag()
159 * instructions after the first when using block stepping.
160 * So noone should try to use debugger block stepping in a program
161 * that uses user-mode single stepping itself.
162 */
163 if (enable_single_step(child) && block) {
164 set_tsk_thread_flag(child, TIF_DEBUGCTLMSR);
165 write_debugctlmsr(child,
166 child->thread.debugctlmsr | DEBUGCTLMSR_BTF);
167 } else {
168 write_debugctlmsr(child,
169 child->thread.debugctlmsr & ~TIF_DEBUGCTLMSR);
170
171 if (!child->thread.debugctlmsr)
172 clear_tsk_thread_flag(child, TIF_DEBUGCTLMSR);
173 }
174}
175
176void user_enable_single_step(struct task_struct *child)
177{
178 enable_step(child, 0);
179}
180
181void user_enable_block_step(struct task_struct *child)
182{
183 enable_step(child, 1);
184}
185
186void user_disable_single_step(struct task_struct *child)
187{
188 /*
189 * Make sure block stepping (BTF) is disabled.
190 */
191 write_debugctlmsr(child,
192 child->thread.debugctlmsr & ~TIF_DEBUGCTLMSR);
193
194 if (!child->thread.debugctlmsr)
195 clear_tsk_thread_flag(child, TIF_DEBUGCTLMSR);
196
197 /* Always clear TIF_SINGLESTEP... */
198 clear_tsk_thread_flag(child, TIF_SINGLESTEP);
199
200 /* But touch TF only if it was set by us.. */
201 if (test_and_clear_tsk_thread_flag(child, TIF_FORCED_TF))
202 task_pt_regs(child)->flags &= ~X86_EFLAGS_TF;
203}
diff --git a/arch/x86/kernel/suspend_64.c b/arch/x86/kernel/suspend_64.c
index 2e5efaaf8800..09199511c256 100644
--- a/arch/x86/kernel/suspend_64.c
+++ b/arch/x86/kernel/suspend_64.c
@@ -17,9 +17,26 @@
17/* References to section boundaries */ 17/* References to section boundaries */
18extern const void __nosave_begin, __nosave_end; 18extern const void __nosave_begin, __nosave_end;
19 19
20static void fix_processor_context(void);
21
20struct saved_context saved_context; 22struct saved_context saved_context;
21 23
22void __save_processor_state(struct saved_context *ctxt) 24/**
25 * __save_processor_state - save CPU registers before creating a
26 * hibernation image and before restoring the memory state from it
27 * @ctxt - structure to store the registers contents in
28 *
29 * NOTE: If there is a CPU register the modification of which by the
30 * boot kernel (ie. the kernel used for loading the hibernation image)
31 * might affect the operations of the restored target kernel (ie. the one
32 * saved in the hibernation image), then its contents must be saved by this
33 * function. In other words, if kernel A is hibernated and different
34 * kernel B is used for loading the hibernation image into memory, the
35 * kernel A's __save_processor_state() function must save all registers
36 * needed by kernel A, so that it can operate correctly after the resume
37 * regardless of what kernel B does in the meantime.
38 */
39static void __save_processor_state(struct saved_context *ctxt)
23{ 40{
24 kernel_fpu_begin(); 41 kernel_fpu_begin();
25 42
@@ -69,7 +86,12 @@ static void do_fpu_end(void)
69 kernel_fpu_end(); 86 kernel_fpu_end();
70} 87}
71 88
72void __restore_processor_state(struct saved_context *ctxt) 89/**
90 * __restore_processor_state - restore the contents of CPU registers saved
91 * by __save_processor_state()
92 * @ctxt - structure to load the registers contents from
93 */
94static void __restore_processor_state(struct saved_context *ctxt)
73{ 95{
74 /* 96 /*
75 * control registers 97 * control registers
@@ -113,14 +135,14 @@ void restore_processor_state(void)
113 __restore_processor_state(&saved_context); 135 __restore_processor_state(&saved_context);
114} 136}
115 137
116void fix_processor_context(void) 138static void fix_processor_context(void)
117{ 139{
118 int cpu = smp_processor_id(); 140 int cpu = smp_processor_id();
119 struct tss_struct *t = &per_cpu(init_tss, cpu); 141 struct tss_struct *t = &per_cpu(init_tss, cpu);
120 142
121 set_tss_desc(cpu,t); /* This just modifies memory; should not be necessary. But... This is necessary, because 386 hardware has concept of busy TSS or some similar stupidity. */ 143 set_tss_desc(cpu,t); /* This just modifies memory; should not be necessary. But... This is necessary, because 386 hardware has concept of busy TSS or some similar stupidity. */
122 144
123 cpu_gdt(cpu)[GDT_ENTRY_TSS].type = 9; 145 get_cpu_gdt_table(cpu)[GDT_ENTRY_TSS].type = 9;
124 146
125 syscall_init(); /* This sets MSR_*STAR and related */ 147 syscall_init(); /* This sets MSR_*STAR and related */
126 load_TR_desc(); /* This does ltr */ 148 load_TR_desc(); /* This does ltr */
diff --git a/arch/x86/kernel/suspend_asm_64.S b/arch/x86/kernel/suspend_asm_64.S
index 72f952103e50..aeb9a4d7681e 100644
--- a/arch/x86/kernel/suspend_asm_64.S
+++ b/arch/x86/kernel/suspend_asm_64.S
@@ -18,13 +18,13 @@
18 18
19ENTRY(swsusp_arch_suspend) 19ENTRY(swsusp_arch_suspend)
20 movq $saved_context, %rax 20 movq $saved_context, %rax
21 movq %rsp, pt_regs_rsp(%rax) 21 movq %rsp, pt_regs_sp(%rax)
22 movq %rbp, pt_regs_rbp(%rax) 22 movq %rbp, pt_regs_bp(%rax)
23 movq %rsi, pt_regs_rsi(%rax) 23 movq %rsi, pt_regs_si(%rax)
24 movq %rdi, pt_regs_rdi(%rax) 24 movq %rdi, pt_regs_di(%rax)
25 movq %rbx, pt_regs_rbx(%rax) 25 movq %rbx, pt_regs_bx(%rax)
26 movq %rcx, pt_regs_rcx(%rax) 26 movq %rcx, pt_regs_cx(%rax)
27 movq %rdx, pt_regs_rdx(%rax) 27 movq %rdx, pt_regs_dx(%rax)
28 movq %r8, pt_regs_r8(%rax) 28 movq %r8, pt_regs_r8(%rax)
29 movq %r9, pt_regs_r9(%rax) 29 movq %r9, pt_regs_r9(%rax)
30 movq %r10, pt_regs_r10(%rax) 30 movq %r10, pt_regs_r10(%rax)
@@ -34,7 +34,7 @@ ENTRY(swsusp_arch_suspend)
34 movq %r14, pt_regs_r14(%rax) 34 movq %r14, pt_regs_r14(%rax)
35 movq %r15, pt_regs_r15(%rax) 35 movq %r15, pt_regs_r15(%rax)
36 pushfq 36 pushfq
37 popq pt_regs_eflags(%rax) 37 popq pt_regs_flags(%rax)
38 38
39 /* save the address of restore_registers */ 39 /* save the address of restore_registers */
40 movq $restore_registers, %rax 40 movq $restore_registers, %rax
@@ -115,13 +115,13 @@ ENTRY(restore_registers)
115 115
116 /* We don't restore %rax, it must be 0 anyway */ 116 /* We don't restore %rax, it must be 0 anyway */
117 movq $saved_context, %rax 117 movq $saved_context, %rax
118 movq pt_regs_rsp(%rax), %rsp 118 movq pt_regs_sp(%rax), %rsp
119 movq pt_regs_rbp(%rax), %rbp 119 movq pt_regs_bp(%rax), %rbp
120 movq pt_regs_rsi(%rax), %rsi 120 movq pt_regs_si(%rax), %rsi
121 movq pt_regs_rdi(%rax), %rdi 121 movq pt_regs_di(%rax), %rdi
122 movq pt_regs_rbx(%rax), %rbx 122 movq pt_regs_bx(%rax), %rbx
123 movq pt_regs_rcx(%rax), %rcx 123 movq pt_regs_cx(%rax), %rcx
124 movq pt_regs_rdx(%rax), %rdx 124 movq pt_regs_dx(%rax), %rdx
125 movq pt_regs_r8(%rax), %r8 125 movq pt_regs_r8(%rax), %r8
126 movq pt_regs_r9(%rax), %r9 126 movq pt_regs_r9(%rax), %r9
127 movq pt_regs_r10(%rax), %r10 127 movq pt_regs_r10(%rax), %r10
@@ -130,7 +130,7 @@ ENTRY(restore_registers)
130 movq pt_regs_r13(%rax), %r13 130 movq pt_regs_r13(%rax), %r13
131 movq pt_regs_r14(%rax), %r14 131 movq pt_regs_r14(%rax), %r14
132 movq pt_regs_r15(%rax), %r15 132 movq pt_regs_r15(%rax), %r15
133 pushq pt_regs_eflags(%rax) 133 pushq pt_regs_flags(%rax)
134 popfq 134 popfq
135 135
136 xorq %rax, %rax 136 xorq %rax, %rax
diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
index 907942ee6e76..bd802a5e1aa3 100644
--- a/arch/x86/kernel/sys_x86_64.c
+++ b/arch/x86/kernel/sys_x86_64.c
@@ -12,6 +12,7 @@
12#include <linux/file.h> 12#include <linux/file.h>
13#include <linux/utsname.h> 13#include <linux/utsname.h>
14#include <linux/personality.h> 14#include <linux/personality.h>
15#include <linux/random.h>
15 16
16#include <asm/uaccess.h> 17#include <asm/uaccess.h>
17#include <asm/ia32.h> 18#include <asm/ia32.h>
@@ -65,6 +66,7 @@ static void find_start_end(unsigned long flags, unsigned long *begin,
65 unsigned long *end) 66 unsigned long *end)
66{ 67{
67 if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) { 68 if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
69 unsigned long new_begin;
68 /* This is usually used needed to map code in small 70 /* This is usually used needed to map code in small
69 model, so it needs to be in the first 31bit. Limit 71 model, so it needs to be in the first 31bit. Limit
70 it to that. This means we need to move the 72 it to that. This means we need to move the
@@ -74,6 +76,11 @@ static void find_start_end(unsigned long flags, unsigned long *begin,
74 of playground for now. -AK */ 76 of playground for now. -AK */
75 *begin = 0x40000000; 77 *begin = 0x40000000;
76 *end = 0x80000000; 78 *end = 0x80000000;
79 if (current->flags & PF_RANDOMIZE) {
80 new_begin = randomize_range(*begin, *begin + 0x02000000, 0);
81 if (new_begin)
82 *begin = new_begin;
83 }
77 } else { 84 } else {
78 *begin = TASK_UNMAPPED_BASE; 85 *begin = TASK_UNMAPPED_BASE;
79 *end = TASK_SIZE; 86 *end = TASK_SIZE;
@@ -143,6 +150,97 @@ full_search:
143 } 150 }
144} 151}
145 152
153
154unsigned long
155arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
156 const unsigned long len, const unsigned long pgoff,
157 const unsigned long flags)
158{
159 struct vm_area_struct *vma;
160 struct mm_struct *mm = current->mm;
161 unsigned long addr = addr0;
162
163 /* requested length too big for entire address space */
164 if (len > TASK_SIZE)
165 return -ENOMEM;
166
167 if (flags & MAP_FIXED)
168 return addr;
169
170 /* for MAP_32BIT mappings we force the legact mmap base */
171 if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT))
172 goto bottomup;
173
174 /* requesting a specific address */
175 if (addr) {
176 addr = PAGE_ALIGN(addr);
177 vma = find_vma(mm, addr);
178 if (TASK_SIZE - len >= addr &&
179 (!vma || addr + len <= vma->vm_start))
180 return addr;
181 }
182
183 /* check if free_area_cache is useful for us */
184 if (len <= mm->cached_hole_size) {
185 mm->cached_hole_size = 0;
186 mm->free_area_cache = mm->mmap_base;
187 }
188
189 /* either no address requested or can't fit in requested address hole */
190 addr = mm->free_area_cache;
191
192 /* make sure it can fit in the remaining address space */
193 if (addr > len) {
194 vma = find_vma(mm, addr-len);
195 if (!vma || addr <= vma->vm_start)
196 /* remember the address as a hint for next time */
197 return (mm->free_area_cache = addr-len);
198 }
199
200 if (mm->mmap_base < len)
201 goto bottomup;
202
203 addr = mm->mmap_base-len;
204
205 do {
206 /*
207 * Lookup failure means no vma is above this address,
208 * else if new region fits below vma->vm_start,
209 * return with success:
210 */
211 vma = find_vma(mm, addr);
212 if (!vma || addr+len <= vma->vm_start)
213 /* remember the address as a hint for next time */
214 return (mm->free_area_cache = addr);
215
216 /* remember the largest hole we saw so far */
217 if (addr + mm->cached_hole_size < vma->vm_start)
218 mm->cached_hole_size = vma->vm_start - addr;
219
220 /* try just below the current vma->vm_start */
221 addr = vma->vm_start-len;
222 } while (len < vma->vm_start);
223
224bottomup:
225 /*
226 * A failed mmap() very likely causes application failure,
227 * so fall back to the bottom-up function here. This scenario
228 * can happen with large stack limits and large mmap()
229 * allocations.
230 */
231 mm->cached_hole_size = ~0UL;
232 mm->free_area_cache = TASK_UNMAPPED_BASE;
233 addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
234 /*
235 * Restore the topdown base:
236 */
237 mm->free_area_cache = mm->mmap_base;
238 mm->cached_hole_size = ~0UL;
239
240 return addr;
241}
242
243
146asmlinkage long sys_uname(struct new_utsname __user * name) 244asmlinkage long sys_uname(struct new_utsname __user * name)
147{ 245{
148 int err; 246 int err;
diff --git a/arch/x86/kernel/test_nx.c b/arch/x86/kernel/test_nx.c
new file mode 100644
index 000000000000..6d7ef11e7975
--- /dev/null
+++ b/arch/x86/kernel/test_nx.c
@@ -0,0 +1,176 @@
1/*
2 * test_nx.c: functional test for NX functionality
3 *
4 * (C) Copyright 2008 Intel Corporation
5 * Author: Arjan van de Ven <arjan@linux.intel.com>
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; version 2
10 * of the License.
11 */
12#include <linux/module.h>
13#include <linux/sort.h>
14#include <asm/uaccess.h>
15
16extern int rodata_test_data;
17
18/*
19 * This file checks 4 things:
20 * 1) Check if the stack is not executable
21 * 2) Check if kmalloc memory is not executable
22 * 3) Check if the .rodata section is not executable
23 * 4) Check if the .data section of a module is not executable
24 *
25 * To do this, the test code tries to execute memory in stack/kmalloc/etc,
26 * and then checks if the expected trap happens.
27 *
28 * Sadly, this implies having a dynamic exception handling table entry.
29 * ... which can be done (and will make Rusty cry)... but it can only
30 * be done in a stand-alone module with only 1 entry total.
31 * (otherwise we'd have to sort and that's just too messy)
32 */
33
34
35
36/*
37 * We want to set up an exception handling point on our stack,
38 * which means a variable value. This function is rather dirty
39 * and walks the exception table of the module, looking for a magic
40 * marker and replaces it with a specific function.
41 */
42static void fudze_exception_table(void *marker, void *new)
43{
44 struct module *mod = THIS_MODULE;
45 struct exception_table_entry *extable;
46
47 /*
48 * Note: This module has only 1 exception table entry,
49 * so searching and sorting is not needed. If that changes,
50 * this would be the place to search and re-sort the exception
51 * table.
52 */
53 if (mod->num_exentries > 1) {
54 printk(KERN_ERR "test_nx: too many exception table entries!\n");
55 printk(KERN_ERR "test_nx: test results are not reliable.\n");
56 return;
57 }
58 extable = (struct exception_table_entry *)mod->extable;
59 extable[0].insn = (unsigned long)new;
60}
61
62
63/*
64 * exception tables get their symbols translated so we need
65 * to use a fake function to put in there, which we can then
66 * replace at runtime.
67 */
68void foo_label(void);
69
70/*
71 * returns 0 for not-executable, negative for executable
72 *
73 * Note: we cannot allow this function to be inlined, because
74 * that would give us more than 1 exception table entry.
75 * This in turn would break the assumptions above.
76 */
77static noinline int test_address(void *address)
78{
79 unsigned long result;
80
81 /* Set up an exception table entry for our address */
82 fudze_exception_table(&foo_label, address);
83 result = 1;
84 asm volatile(
85 "foo_label:\n"
86 "0: call *%[fake_code]\n"
87 "1:\n"
88 ".section .fixup,\"ax\"\n"
89 "2: mov %[zero], %[rslt]\n"
90 " ret\n"
91 ".previous\n"
92 ".section __ex_table,\"a\"\n"
93 " .align 8\n"
94 " .quad 0b\n"
95 " .quad 2b\n"
96 ".previous\n"
97 : [rslt] "=r" (result)
98 : [fake_code] "r" (address), [zero] "r" (0UL), "0" (result)
99 );
100 /* change the exception table back for the next round */
101 fudze_exception_table(address, &foo_label);
102
103 if (result)
104 return -ENODEV;
105 return 0;
106}
107
108static unsigned char test_data = 0xC3; /* 0xC3 is the opcode for "ret" */
109
110static int test_NX(void)
111{
112 int ret = 0;
113 /* 0xC3 is the opcode for "ret" */
114 char stackcode[] = {0xC3, 0x90, 0 };
115 char *heap;
116
117 test_data = 0xC3;
118
119 printk(KERN_INFO "Testing NX protection\n");
120
121 /* Test 1: check if the stack is not executable */
122 if (test_address(&stackcode)) {
123 printk(KERN_ERR "test_nx: stack was executable\n");
124 ret = -ENODEV;
125 }
126
127
128 /* Test 2: Check if the heap is executable */
129 heap = kmalloc(64, GFP_KERNEL);
130 if (!heap)
131 return -ENOMEM;
132 heap[0] = 0xC3; /* opcode for "ret" */
133
134 if (test_address(heap)) {
135 printk(KERN_ERR "test_nx: heap was executable\n");
136 ret = -ENODEV;
137 }
138 kfree(heap);
139
140 /*
141 * The following 2 tests currently fail, this needs to get fixed
142 * Until then, don't run them to avoid too many people getting scared
143 * by the error message
144 */
145#if 0
146
147#ifdef CONFIG_DEBUG_RODATA
148 /* Test 3: Check if the .rodata section is executable */
149 if (rodata_test_data != 0xC3) {
150 printk(KERN_ERR "test_nx: .rodata marker has invalid value\n");
151 ret = -ENODEV;
152 } else if (test_address(&rodata_test_data)) {
153 printk(KERN_ERR "test_nx: .rodata section is executable\n");
154 ret = -ENODEV;
155 }
156#endif
157
158 /* Test 4: Check if the .data section of a module is executable */
159 if (test_address(&test_data)) {
160 printk(KERN_ERR "test_nx: .data section is executable\n");
161 ret = -ENODEV;
162 }
163
164#endif
165 return 0;
166}
167
168static void test_exit(void)
169{
170}
171
172module_init(test_NX);
173module_exit(test_exit);
174MODULE_LICENSE("GPL");
175MODULE_DESCRIPTION("Testcase for the NX infrastructure");
176MODULE_AUTHOR("Arjan van de Ven <arjan@linux.intel.com>");
diff --git a/arch/x86/kernel/test_rodata.c b/arch/x86/kernel/test_rodata.c
new file mode 100644
index 000000000000..4c163772000e
--- /dev/null
+++ b/arch/x86/kernel/test_rodata.c
@@ -0,0 +1,86 @@
1/*
2 * test_rodata.c: functional test for mark_rodata_ro function
3 *
4 * (C) Copyright 2008 Intel Corporation
5 * Author: Arjan van de Ven <arjan@linux.intel.com>
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; version 2
10 * of the License.
11 */
12#include <linux/module.h>
13#include <asm/sections.h>
14extern int rodata_test_data;
15
16int rodata_test(void)
17{
18 unsigned long result;
19 unsigned long start, end;
20
21 /* test 1: read the value */
22 /* If this test fails, some previous testrun has clobbered the state */
23 if (!rodata_test_data) {
24 printk(KERN_ERR "rodata_test: test 1 fails (start data)\n");
25 return -ENODEV;
26 }
27
28 /* test 2: write to the variable; this should fault */
29 /*
30 * If this test fails, we managed to overwrite the data
31 *
32 * This is written in assembly to be able to catch the
33 * exception that is supposed to happen in the correct
34 * case
35 */
36
37 result = 1;
38 asm volatile(
39 "0: mov %[zero],(%[rodata_test])\n"
40 " mov %[zero], %[rslt]\n"
41 "1:\n"
42 ".section .fixup,\"ax\"\n"
43 "2: jmp 1b\n"
44 ".previous\n"
45 ".section __ex_table,\"a\"\n"
46 " .align 16\n"
47#ifdef CONFIG_X86_32
48 " .long 0b,2b\n"
49#else
50 " .quad 0b,2b\n"
51#endif
52 ".previous"
53 : [rslt] "=r" (result)
54 : [rodata_test] "r" (&rodata_test_data), [zero] "r" (0UL)
55 );
56
57
58 if (!result) {
59 printk(KERN_ERR "rodata_test: test data was not read only\n");
60 return -ENODEV;
61 }
62
63 /* test 3: check the value hasn't changed */
64 /* If this test fails, we managed to overwrite the data */
65 if (!rodata_test_data) {
66 printk(KERN_ERR "rodata_test: Test 3 failes (end data)\n");
67 return -ENODEV;
68 }
69 /* test 4: check if the rodata section is 4Kb aligned */
70 start = (unsigned long)__start_rodata;
71 end = (unsigned long)__end_rodata;
72 if (start & (PAGE_SIZE - 1)) {
73 printk(KERN_ERR "rodata_test: .rodata is not 4k aligned\n");
74 return -ENODEV;
75 }
76 if (end & (PAGE_SIZE - 1)) {
77 printk(KERN_ERR "rodata_test: .rodata end is not 4k aligned\n");
78 return -ENODEV;
79 }
80
81 return 0;
82}
83
84MODULE_LICENSE("GPL");
85MODULE_DESCRIPTION("Testcase for the DEBUG_RODATA infrastructure");
86MODULE_AUTHOR("Arjan van de Ven <arjan@linux.intel.com>");
diff --git a/arch/x86/kernel/time_32.c b/arch/x86/kernel/time_32.c
index 8a322c96bc23..1a89e93f3f1c 100644
--- a/arch/x86/kernel/time_32.c
+++ b/arch/x86/kernel/time_32.c
@@ -28,98 +28,20 @@
28 * serialize accesses to xtime/lost_ticks). 28 * serialize accesses to xtime/lost_ticks).
29 */ 29 */
30 30
31#include <linux/errno.h> 31#include <linux/init.h>
32#include <linux/sched.h>
33#include <linux/kernel.h>
34#include <linux/param.h>
35#include <linux/string.h>
36#include <linux/mm.h>
37#include <linux/interrupt.h> 32#include <linux/interrupt.h>
38#include <linux/time.h> 33#include <linux/time.h>
39#include <linux/delay.h>
40#include <linux/init.h>
41#include <linux/smp.h>
42#include <linux/module.h>
43#include <linux/sysdev.h>
44#include <linux/bcd.h>
45#include <linux/efi.h>
46#include <linux/mca.h> 34#include <linux/mca.h>
47 35
48#include <asm/io.h>
49#include <asm/smp.h>
50#include <asm/irq.h>
51#include <asm/msr.h>
52#include <asm/delay.h>
53#include <asm/mpspec.h>
54#include <asm/uaccess.h>
55#include <asm/processor.h>
56#include <asm/timer.h>
57#include <asm/time.h>
58
59#include "mach_time.h"
60
61#include <linux/timex.h>
62
63#include <asm/hpet.h>
64
65#include <asm/arch_hooks.h> 36#include <asm/arch_hooks.h>
66 37#include <asm/hpet.h>
67#include "io_ports.h" 38#include <asm/time.h>
68
69#include <asm/i8259.h>
70 39
71#include "do_timer.h" 40#include "do_timer.h"
72 41
73unsigned int cpu_khz; /* Detected as we calibrate the TSC */ 42unsigned int cpu_khz; /* Detected as we calibrate the TSC */
74EXPORT_SYMBOL(cpu_khz); 43EXPORT_SYMBOL(cpu_khz);
75 44
76DEFINE_SPINLOCK(rtc_lock);
77EXPORT_SYMBOL(rtc_lock);
78
79/*
80 * This is a special lock that is owned by the CPU and holds the index
81 * register we are working with. It is required for NMI access to the
82 * CMOS/RTC registers. See include/asm-i386/mc146818rtc.h for details.
83 */
84volatile unsigned long cmos_lock = 0;
85EXPORT_SYMBOL(cmos_lock);
86
87/* Routines for accessing the CMOS RAM/RTC. */
88unsigned char rtc_cmos_read(unsigned char addr)
89{
90 unsigned char val;
91 lock_cmos_prefix(addr);
92 outb_p(addr, RTC_PORT(0));
93 val = inb_p(RTC_PORT(1));
94 lock_cmos_suffix(addr);
95 return val;
96}
97EXPORT_SYMBOL(rtc_cmos_read);
98
99void rtc_cmos_write(unsigned char val, unsigned char addr)
100{
101 lock_cmos_prefix(addr);
102 outb_p(addr, RTC_PORT(0));
103 outb_p(val, RTC_PORT(1));
104 lock_cmos_suffix(addr);
105}
106EXPORT_SYMBOL(rtc_cmos_write);
107
108static int set_rtc_mmss(unsigned long nowtime)
109{
110 int retval;
111 unsigned long flags;
112
113 /* gets recalled with irq locally disabled */
114 /* XXX - does irqsave resolve this? -johnstul */
115 spin_lock_irqsave(&rtc_lock, flags);
116 retval = set_wallclock(nowtime);
117 spin_unlock_irqrestore(&rtc_lock, flags);
118
119 return retval;
120}
121
122
123int timer_ack; 45int timer_ack;
124 46
125unsigned long profile_pc(struct pt_regs *regs) 47unsigned long profile_pc(struct pt_regs *regs)
@@ -127,17 +49,17 @@ unsigned long profile_pc(struct pt_regs *regs)
127 unsigned long pc = instruction_pointer(regs); 49 unsigned long pc = instruction_pointer(regs);
128 50
129#ifdef CONFIG_SMP 51#ifdef CONFIG_SMP
130 if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->xcs) && 52 if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->cs) &&
131 in_lock_functions(pc)) { 53 in_lock_functions(pc)) {
132#ifdef CONFIG_FRAME_POINTER 54#ifdef CONFIG_FRAME_POINTER
133 return *(unsigned long *)(regs->ebp + 4); 55 return *(unsigned long *)(regs->bp + 4);
134#else 56#else
135 unsigned long *sp = (unsigned long *)&regs->esp; 57 unsigned long *sp = (unsigned long *)&regs->sp;
136 58
137 /* Return address is either directly at stack pointer 59 /* Return address is either directly at stack pointer
138 or above a saved eflags. Eflags has bits 22-31 zero, 60 or above a saved flags. Eflags has bits 22-31 zero,
139 kernel addresses don't. */ 61 kernel addresses don't. */
140 if (sp[0] >> 22) 62 if (sp[0] >> 22)
141 return sp[0]; 63 return sp[0];
142 if (sp[1] >> 22) 64 if (sp[1] >> 22)
143 return sp[1]; 65 return sp[1];
@@ -193,26 +115,6 @@ irqreturn_t timer_interrupt(int irq, void *dev_id)
193 return IRQ_HANDLED; 115 return IRQ_HANDLED;
194} 116}
195 117
196/* not static: needed by APM */
197unsigned long read_persistent_clock(void)
198{
199 unsigned long retval;
200 unsigned long flags;
201
202 spin_lock_irqsave(&rtc_lock, flags);
203
204 retval = get_wallclock();
205
206 spin_unlock_irqrestore(&rtc_lock, flags);
207
208 return retval;
209}
210
211int update_persistent_clock(struct timespec now)
212{
213 return set_rtc_mmss(now.tv_sec);
214}
215
216extern void (*late_time_init)(void); 118extern void (*late_time_init)(void);
217/* Duplicate of time_init() below, with hpet_enable part added */ 119/* Duplicate of time_init() below, with hpet_enable part added */
218void __init hpet_time_init(void) 120void __init hpet_time_init(void)
diff --git a/arch/x86/kernel/time_64.c b/arch/x86/kernel/time_64.c
index 368b1942b39a..0380795121a6 100644
--- a/arch/x86/kernel/time_64.c
+++ b/arch/x86/kernel/time_64.c
@@ -11,43 +11,18 @@
11 * RTC support code taken from arch/i386/kernel/timers/time_hpet.c 11 * RTC support code taken from arch/i386/kernel/timers/time_hpet.c
12 */ 12 */
13 13
14#include <linux/kernel.h> 14#include <linux/clockchips.h>
15#include <linux/sched.h>
16#include <linux/interrupt.h>
17#include <linux/init.h> 15#include <linux/init.h>
18#include <linux/mc146818rtc.h> 16#include <linux/interrupt.h>
19#include <linux/time.h>
20#include <linux/ioport.h>
21#include <linux/module.h> 17#include <linux/module.h>
22#include <linux/device.h> 18#include <linux/time.h>
23#include <linux/sysdev.h>
24#include <linux/bcd.h>
25#include <linux/notifier.h>
26#include <linux/cpu.h>
27#include <linux/kallsyms.h>
28#include <linux/acpi.h>
29#include <linux/clockchips.h>
30 19
31#ifdef CONFIG_ACPI
32#include <acpi/achware.h> /* for PM timer frequency */
33#include <acpi/acpi_bus.h>
34#endif
35#include <asm/i8253.h> 20#include <asm/i8253.h>
36#include <asm/pgtable.h>
37#include <asm/vsyscall.h>
38#include <asm/timex.h>
39#include <asm/proto.h>
40#include <asm/hpet.h>
41#include <asm/sections.h>
42#include <linux/hpet.h>
43#include <asm/apic.h>
44#include <asm/hpet.h> 21#include <asm/hpet.h>
45#include <asm/mpspec.h>
46#include <asm/nmi.h> 22#include <asm/nmi.h>
47#include <asm/vgtod.h> 23#include <asm/vgtod.h>
48 24#include <asm/time.h>
49DEFINE_SPINLOCK(rtc_lock); 25#include <asm/timer.h>
50EXPORT_SYMBOL(rtc_lock);
51 26
52volatile unsigned long __jiffies __section_jiffies = INITIAL_JIFFIES; 27volatile unsigned long __jiffies __section_jiffies = INITIAL_JIFFIES;
53 28
@@ -56,10 +31,10 @@ unsigned long profile_pc(struct pt_regs *regs)
56 unsigned long pc = instruction_pointer(regs); 31 unsigned long pc = instruction_pointer(regs);
57 32
58 /* Assume the lock function has either no stack frame or a copy 33 /* Assume the lock function has either no stack frame or a copy
59 of eflags from PUSHF 34 of flags from PUSHF
60 Eflags always has bits 22 and up cleared unlike kernel addresses. */ 35 Eflags always has bits 22 and up cleared unlike kernel addresses. */
61 if (!user_mode(regs) && in_lock_functions(pc)) { 36 if (!user_mode(regs) && in_lock_functions(pc)) {
62 unsigned long *sp = (unsigned long *)regs->rsp; 37 unsigned long *sp = (unsigned long *)regs->sp;
63 if (sp[0] >> 22) 38 if (sp[0] >> 22)
64 return sp[0]; 39 return sp[0];
65 if (sp[1] >> 22) 40 if (sp[1] >> 22)
@@ -69,82 +44,6 @@ unsigned long profile_pc(struct pt_regs *regs)
69} 44}
70EXPORT_SYMBOL(profile_pc); 45EXPORT_SYMBOL(profile_pc);
71 46
72/*
73 * In order to set the CMOS clock precisely, set_rtc_mmss has to be called 500
74 * ms after the second nowtime has started, because when nowtime is written
75 * into the registers of the CMOS clock, it will jump to the next second
76 * precisely 500 ms later. Check the Motorola MC146818A or Dallas DS12887 data
77 * sheet for details.
78 */
79
80static int set_rtc_mmss(unsigned long nowtime)
81{
82 int retval = 0;
83 int real_seconds, real_minutes, cmos_minutes;
84 unsigned char control, freq_select;
85 unsigned long flags;
86
87/*
88 * set_rtc_mmss is called when irqs are enabled, so disable irqs here
89 */
90 spin_lock_irqsave(&rtc_lock, flags);
91/*
92 * Tell the clock it's being set and stop it.
93 */
94 control = CMOS_READ(RTC_CONTROL);
95 CMOS_WRITE(control | RTC_SET, RTC_CONTROL);
96
97 freq_select = CMOS_READ(RTC_FREQ_SELECT);
98 CMOS_WRITE(freq_select | RTC_DIV_RESET2, RTC_FREQ_SELECT);
99
100 cmos_minutes = CMOS_READ(RTC_MINUTES);
101 BCD_TO_BIN(cmos_minutes);
102
103/*
104 * since we're only adjusting minutes and seconds, don't interfere with hour
105 * overflow. This avoids messing with unknown time zones but requires your RTC
106 * not to be off by more than 15 minutes. Since we're calling it only when
107 * our clock is externally synchronized using NTP, this shouldn't be a problem.
108 */
109
110 real_seconds = nowtime % 60;
111 real_minutes = nowtime / 60;
112 if (((abs(real_minutes - cmos_minutes) + 15) / 30) & 1)
113 real_minutes += 30; /* correct for half hour time zone */
114 real_minutes %= 60;
115
116 if (abs(real_minutes - cmos_minutes) >= 30) {
117 printk(KERN_WARNING "time.c: can't update CMOS clock "
118 "from %d to %d\n", cmos_minutes, real_minutes);
119 retval = -1;
120 } else {
121 BIN_TO_BCD(real_seconds);
122 BIN_TO_BCD(real_minutes);
123 CMOS_WRITE(real_seconds, RTC_SECONDS);
124 CMOS_WRITE(real_minutes, RTC_MINUTES);
125 }
126
127/*
128 * The following flags have to be released exactly in this order, otherwise the
129 * DS12887 (popular MC146818A clone with integrated battery and quartz) will
130 * not reset the oscillator and will not update precisely 500 ms later. You
131 * won't find this mentioned in the Dallas Semiconductor data sheets, but who
132 * believes data sheets anyway ... -- Markus Kuhn
133 */
134
135 CMOS_WRITE(control, RTC_CONTROL);
136 CMOS_WRITE(freq_select, RTC_FREQ_SELECT);
137
138 spin_unlock_irqrestore(&rtc_lock, flags);
139
140 return retval;
141}
142
143int update_persistent_clock(struct timespec now)
144{
145 return set_rtc_mmss(now.tv_sec);
146}
147
148static irqreturn_t timer_event_interrupt(int irq, void *dev_id) 47static irqreturn_t timer_event_interrupt(int irq, void *dev_id)
149{ 48{
150 add_pda(irq0_irqs, 1); 49 add_pda(irq0_irqs, 1);
@@ -154,67 +53,10 @@ static irqreturn_t timer_event_interrupt(int irq, void *dev_id)
154 return IRQ_HANDLED; 53 return IRQ_HANDLED;
155} 54}
156 55
157unsigned long read_persistent_clock(void)
158{
159 unsigned int year, mon, day, hour, min, sec;
160 unsigned long flags;
161 unsigned century = 0;
162
163 spin_lock_irqsave(&rtc_lock, flags);
164 /*
165 * if UIP is clear, then we have >= 244 microseconds before RTC
166 * registers will be updated. Spec sheet says that this is the
167 * reliable way to read RTC - registers invalid (off bus) during update
168 */
169 while ((CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
170 cpu_relax();
171
172
173 /* now read all RTC registers while stable with interrupts disabled */
174 sec = CMOS_READ(RTC_SECONDS);
175 min = CMOS_READ(RTC_MINUTES);
176 hour = CMOS_READ(RTC_HOURS);
177 day = CMOS_READ(RTC_DAY_OF_MONTH);
178 mon = CMOS_READ(RTC_MONTH);
179 year = CMOS_READ(RTC_YEAR);
180#ifdef CONFIG_ACPI
181 if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID &&
182 acpi_gbl_FADT.century)
183 century = CMOS_READ(acpi_gbl_FADT.century);
184#endif
185 spin_unlock_irqrestore(&rtc_lock, flags);
186
187 /*
188 * We know that x86-64 always uses BCD format, no need to check the
189 * config register.
190 */
191
192 BCD_TO_BIN(sec);
193 BCD_TO_BIN(min);
194 BCD_TO_BIN(hour);
195 BCD_TO_BIN(day);
196 BCD_TO_BIN(mon);
197 BCD_TO_BIN(year);
198
199 if (century) {
200 BCD_TO_BIN(century);
201 year += century * 100;
202 printk(KERN_INFO "Extended CMOS year: %d\n", century * 100);
203 } else {
204 /*
205 * x86-64 systems only exists since 2002.
206 * This will work up to Dec 31, 2100
207 */
208 year += 2000;
209 }
210
211 return mktime(year, mon, day, hour, min, sec);
212}
213
214/* calibrate_cpu is used on systems with fixed rate TSCs to determine 56/* calibrate_cpu is used on systems with fixed rate TSCs to determine
215 * processor frequency */ 57 * processor frequency */
216#define TICK_COUNT 100000000 58#define TICK_COUNT 100000000
217static unsigned int __init tsc_calibrate_cpu_khz(void) 59unsigned long __init native_calculate_cpu_khz(void)
218{ 60{
219 int tsc_start, tsc_now; 61 int tsc_start, tsc_now;
220 int i, no_ctr_free; 62 int i, no_ctr_free;
@@ -241,7 +83,7 @@ static unsigned int __init tsc_calibrate_cpu_khz(void)
241 rdtscl(tsc_start); 83 rdtscl(tsc_start);
242 do { 84 do {
243 rdmsrl(MSR_K7_PERFCTR0 + i, pmc_now); 85 rdmsrl(MSR_K7_PERFCTR0 + i, pmc_now);
244 tsc_now = get_cycles_sync(); 86 tsc_now = get_cycles();
245 } while ((tsc_now - tsc_start) < TICK_COUNT); 87 } while ((tsc_now - tsc_start) < TICK_COUNT);
246 88
247 local_irq_restore(flags); 89 local_irq_restore(flags);
@@ -264,20 +106,22 @@ static struct irqaction irq0 = {
264 .name = "timer" 106 .name = "timer"
265}; 107};
266 108
267void __init time_init(void) 109void __init hpet_time_init(void)
268{ 110{
269 if (!hpet_enable()) 111 if (!hpet_enable())
270 setup_pit_timer(); 112 setup_pit_timer();
271 113
272 setup_irq(0, &irq0); 114 setup_irq(0, &irq0);
115}
273 116
117void __init time_init(void)
118{
274 tsc_calibrate(); 119 tsc_calibrate();
275 120
276 cpu_khz = tsc_khz; 121 cpu_khz = tsc_khz;
277 if (cpu_has(&boot_cpu_data, X86_FEATURE_CONSTANT_TSC) && 122 if (cpu_has(&boot_cpu_data, X86_FEATURE_CONSTANT_TSC) &&
278 boot_cpu_data.x86_vendor == X86_VENDOR_AMD && 123 (boot_cpu_data.x86_vendor == X86_VENDOR_AMD))
279 boot_cpu_data.x86 == 16) 124 cpu_khz = calculate_cpu_khz();
280 cpu_khz = tsc_calibrate_cpu_khz();
281 125
282 if (unsynchronized_tsc()) 126 if (unsynchronized_tsc())
283 mark_tsc_unstable("TSCs unsynchronized"); 127 mark_tsc_unstable("TSCs unsynchronized");
@@ -290,4 +134,5 @@ void __init time_init(void)
290 printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n", 134 printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n",
291 cpu_khz / 1000, cpu_khz % 1000); 135 cpu_khz / 1000, cpu_khz % 1000);
292 init_tsc_clocksource(); 136 init_tsc_clocksource();
137 late_time_init = choose_time_init();
293} 138}
diff --git a/arch/x86/kernel/tls.c b/arch/x86/kernel/tls.c
new file mode 100644
index 000000000000..6dfd4e76661a
--- /dev/null
+++ b/arch/x86/kernel/tls.c
@@ -0,0 +1,213 @@
1#include <linux/kernel.h>
2#include <linux/errno.h>
3#include <linux/sched.h>
4#include <linux/user.h>
5#include <linux/regset.h>
6
7#include <asm/uaccess.h>
8#include <asm/desc.h>
9#include <asm/system.h>
10#include <asm/ldt.h>
11#include <asm/processor.h>
12#include <asm/proto.h>
13
14#include "tls.h"
15
16/*
17 * sys_alloc_thread_area: get a yet unused TLS descriptor index.
18 */
19static int get_free_idx(void)
20{
21 struct thread_struct *t = &current->thread;
22 int idx;
23
24 for (idx = 0; idx < GDT_ENTRY_TLS_ENTRIES; idx++)
25 if (desc_empty(&t->tls_array[idx]))
26 return idx + GDT_ENTRY_TLS_MIN;
27 return -ESRCH;
28}
29
30static void set_tls_desc(struct task_struct *p, int idx,
31 const struct user_desc *info, int n)
32{
33 struct thread_struct *t = &p->thread;
34 struct desc_struct *desc = &t->tls_array[idx - GDT_ENTRY_TLS_MIN];
35 int cpu;
36
37 /*
38 * We must not get preempted while modifying the TLS.
39 */
40 cpu = get_cpu();
41
42 while (n-- > 0) {
43 if (LDT_empty(info))
44 desc->a = desc->b = 0;
45 else
46 fill_ldt(desc, info);
47 ++info;
48 ++desc;
49 }
50
51 if (t == &current->thread)
52 load_TLS(t, cpu);
53
54 put_cpu();
55}
56
57/*
58 * Set a given TLS descriptor:
59 */
60int do_set_thread_area(struct task_struct *p, int idx,
61 struct user_desc __user *u_info,
62 int can_allocate)
63{
64 struct user_desc info;
65
66 if (copy_from_user(&info, u_info, sizeof(info)))
67 return -EFAULT;
68
69 if (idx == -1)
70 idx = info.entry_number;
71
72 /*
73 * index -1 means the kernel should try to find and
74 * allocate an empty descriptor:
75 */
76 if (idx == -1 && can_allocate) {
77 idx = get_free_idx();
78 if (idx < 0)
79 return idx;
80 if (put_user(idx, &u_info->entry_number))
81 return -EFAULT;
82 }
83
84 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
85 return -EINVAL;
86
87 set_tls_desc(p, idx, &info, 1);
88
89 return 0;
90}
91
92asmlinkage int sys_set_thread_area(struct user_desc __user *u_info)
93{
94 return do_set_thread_area(current, -1, u_info, 1);
95}
96
97
98/*
99 * Get the current Thread-Local Storage area:
100 */
101
102static void fill_user_desc(struct user_desc *info, int idx,
103 const struct desc_struct *desc)
104
105{
106 memset(info, 0, sizeof(*info));
107 info->entry_number = idx;
108 info->base_addr = get_desc_base(desc);
109 info->limit = get_desc_limit(desc);
110 info->seg_32bit = desc->d;
111 info->contents = desc->type >> 2;
112 info->read_exec_only = !(desc->type & 2);
113 info->limit_in_pages = desc->g;
114 info->seg_not_present = !desc->p;
115 info->useable = desc->avl;
116#ifdef CONFIG_X86_64
117 info->lm = desc->l;
118#endif
119}
120
121int do_get_thread_area(struct task_struct *p, int idx,
122 struct user_desc __user *u_info)
123{
124 struct user_desc info;
125
126 if (idx == -1 && get_user(idx, &u_info->entry_number))
127 return -EFAULT;
128
129 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
130 return -EINVAL;
131
132 fill_user_desc(&info, idx,
133 &p->thread.tls_array[idx - GDT_ENTRY_TLS_MIN]);
134
135 if (copy_to_user(u_info, &info, sizeof(info)))
136 return -EFAULT;
137 return 0;
138}
139
140asmlinkage int sys_get_thread_area(struct user_desc __user *u_info)
141{
142 return do_get_thread_area(current, -1, u_info);
143}
144
145int regset_tls_active(struct task_struct *target,
146 const struct user_regset *regset)
147{
148 struct thread_struct *t = &target->thread;
149 int n = GDT_ENTRY_TLS_ENTRIES;
150 while (n > 0 && desc_empty(&t->tls_array[n - 1]))
151 --n;
152 return n;
153}
154
155int regset_tls_get(struct task_struct *target, const struct user_regset *regset,
156 unsigned int pos, unsigned int count,
157 void *kbuf, void __user *ubuf)
158{
159 const struct desc_struct *tls;
160
161 if (pos > GDT_ENTRY_TLS_ENTRIES * sizeof(struct user_desc) ||
162 (pos % sizeof(struct user_desc)) != 0 ||
163 (count % sizeof(struct user_desc)) != 0)
164 return -EINVAL;
165
166 pos /= sizeof(struct user_desc);
167 count /= sizeof(struct user_desc);
168
169 tls = &target->thread.tls_array[pos];
170
171 if (kbuf) {
172 struct user_desc *info = kbuf;
173 while (count-- > 0)
174 fill_user_desc(info++, GDT_ENTRY_TLS_MIN + pos++,
175 tls++);
176 } else {
177 struct user_desc __user *u_info = ubuf;
178 while (count-- > 0) {
179 struct user_desc info;
180 fill_user_desc(&info, GDT_ENTRY_TLS_MIN + pos++, tls++);
181 if (__copy_to_user(u_info++, &info, sizeof(info)))
182 return -EFAULT;
183 }
184 }
185
186 return 0;
187}
188
189int regset_tls_set(struct task_struct *target, const struct user_regset *regset,
190 unsigned int pos, unsigned int count,
191 const void *kbuf, const void __user *ubuf)
192{
193 struct user_desc infobuf[GDT_ENTRY_TLS_ENTRIES];
194 const struct user_desc *info;
195
196 if (pos > GDT_ENTRY_TLS_ENTRIES * sizeof(struct user_desc) ||
197 (pos % sizeof(struct user_desc)) != 0 ||
198 (count % sizeof(struct user_desc)) != 0)
199 return -EINVAL;
200
201 if (kbuf)
202 info = kbuf;
203 else if (__copy_from_user(infobuf, ubuf, count))
204 return -EFAULT;
205 else
206 info = infobuf;
207
208 set_tls_desc(target,
209 GDT_ENTRY_TLS_MIN + (pos / sizeof(struct user_desc)),
210 info, count / sizeof(struct user_desc));
211
212 return 0;
213}
diff --git a/arch/x86/kernel/tls.h b/arch/x86/kernel/tls.h
new file mode 100644
index 000000000000..2f083a2fe216
--- /dev/null
+++ b/arch/x86/kernel/tls.h
@@ -0,0 +1,21 @@
1/*
2 * Internal declarations for x86 TLS implementation functions.
3 *
4 * Copyright (C) 2007 Red Hat, Inc. All rights reserved.
5 *
6 * This copyrighted material is made available to anyone wishing to use,
7 * modify, copy, or redistribute it subject to the terms and conditions
8 * of the GNU General Public License v.2.
9 *
10 * Red Hat Author: Roland McGrath.
11 */
12
13#ifndef _ARCH_X86_KERNEL_TLS_H
14
15#include <linux/regset.h>
16
17extern user_regset_active_fn regset_tls_active;
18extern user_regset_get_fn regset_tls_get;
19extern user_regset_set_fn regset_tls_set;
20
21#endif /* _ARCH_X86_KERNEL_TLS_H */
diff --git a/arch/x86/kernel/topology.c b/arch/x86/kernel/topology.c
index 7e16d675eb85..78cbb655aa79 100644
--- a/arch/x86/kernel/topology.c
+++ b/arch/x86/kernel/topology.c
@@ -31,9 +31,10 @@
31#include <linux/mmzone.h> 31#include <linux/mmzone.h>
32#include <asm/cpu.h> 32#include <asm/cpu.h>
33 33
34static struct i386_cpu cpu_devices[NR_CPUS]; 34static DEFINE_PER_CPU(struct x86_cpu, cpu_devices);
35 35
36int __cpuinit arch_register_cpu(int num) 36#ifdef CONFIG_HOTPLUG_CPU
37int arch_register_cpu(int num)
37{ 38{
38 /* 39 /*
39 * CPU0 cannot be offlined due to several 40 * CPU0 cannot be offlined due to several
@@ -44,21 +45,23 @@ int __cpuinit arch_register_cpu(int num)
44 * Also certain PCI quirks require not to enable hotplug control 45 * Also certain PCI quirks require not to enable hotplug control
45 * for all CPU's. 46 * for all CPU's.
46 */ 47 */
47#ifdef CONFIG_HOTPLUG_CPU
48 if (num) 48 if (num)
49 cpu_devices[num].cpu.hotpluggable = 1; 49 per_cpu(cpu_devices, num).cpu.hotpluggable = 1;
50#endif 50 return register_cpu(&per_cpu(cpu_devices, num).cpu, num);
51
52 return register_cpu(&cpu_devices[num].cpu, num);
53} 51}
52EXPORT_SYMBOL(arch_register_cpu);
54 53
55#ifdef CONFIG_HOTPLUG_CPU
56void arch_unregister_cpu(int num) 54void arch_unregister_cpu(int num)
57{ 55{
58 return unregister_cpu(&cpu_devices[num].cpu); 56 return unregister_cpu(&per_cpu(cpu_devices, num).cpu);
59} 57}
60EXPORT_SYMBOL(arch_register_cpu);
61EXPORT_SYMBOL(arch_unregister_cpu); 58EXPORT_SYMBOL(arch_unregister_cpu);
59#else
60int arch_register_cpu(int num)
61{
62 return register_cpu(&per_cpu(cpu_devices, num).cpu, num);
63}
64EXPORT_SYMBOL(arch_register_cpu);
62#endif /*CONFIG_HOTPLUG_CPU*/ 65#endif /*CONFIG_HOTPLUG_CPU*/
63 66
64static int __init topology_init(void) 67static int __init topology_init(void)
diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c
index 02d1e1e58e81..3cf72977d012 100644
--- a/arch/x86/kernel/traps_32.c
+++ b/arch/x86/kernel/traps_32.c
@@ -76,7 +76,8 @@ char ignore_fpu_irq = 0;
76 * F0 0F bug workaround.. We have a special link segment 76 * F0 0F bug workaround.. We have a special link segment
77 * for this. 77 * for this.
78 */ 78 */
79struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, }; 79gate_desc idt_table[256]
80 __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, };
80 81
81asmlinkage void divide_error(void); 82asmlinkage void divide_error(void);
82asmlinkage void debug(void); 83asmlinkage void debug(void);
@@ -101,6 +102,34 @@ asmlinkage void machine_check(void);
101int kstack_depth_to_print = 24; 102int kstack_depth_to_print = 24;
102static unsigned int code_bytes = 64; 103static unsigned int code_bytes = 64;
103 104
105void printk_address(unsigned long address, int reliable)
106{
107#ifdef CONFIG_KALLSYMS
108 unsigned long offset = 0, symsize;
109 const char *symname;
110 char *modname;
111 char *delim = ":";
112 char namebuf[128];
113 char reliab[4] = "";
114
115 symname = kallsyms_lookup(address, &symsize, &offset,
116 &modname, namebuf);
117 if (!symname) {
118 printk(" [<%08lx>]\n", address);
119 return;
120 }
121 if (!reliable)
122 strcpy(reliab, "? ");
123
124 if (!modname)
125 modname = delim = "";
126 printk(" [<%08lx>] %s%s%s%s%s+0x%lx/0x%lx\n",
127 address, reliab, delim, modname, delim, symname, offset, symsize);
128#else
129 printk(" [<%08lx>]\n", address);
130#endif
131}
132
104static inline int valid_stack_ptr(struct thread_info *tinfo, void *p, unsigned size) 133static inline int valid_stack_ptr(struct thread_info *tinfo, void *p, unsigned size)
105{ 134{
106 return p > (void *)tinfo && 135 return p > (void *)tinfo &&
@@ -114,48 +143,35 @@ struct stack_frame {
114}; 143};
115 144
116static inline unsigned long print_context_stack(struct thread_info *tinfo, 145static inline unsigned long print_context_stack(struct thread_info *tinfo,
117 unsigned long *stack, unsigned long ebp, 146 unsigned long *stack, unsigned long bp,
118 const struct stacktrace_ops *ops, void *data) 147 const struct stacktrace_ops *ops, void *data)
119{ 148{
120#ifdef CONFIG_FRAME_POINTER 149 struct stack_frame *frame = (struct stack_frame *)bp;
121 struct stack_frame *frame = (struct stack_frame *)ebp;
122 while (valid_stack_ptr(tinfo, frame, sizeof(*frame))) {
123 struct stack_frame *next;
124 unsigned long addr;
125 150
126 addr = frame->return_address;
127 ops->address(data, addr);
128 /*
129 * break out of recursive entries (such as
130 * end_of_stack_stop_unwind_function). Also,
131 * we can never allow a frame pointer to
132 * move downwards!
133 */
134 next = frame->next_frame;
135 if (next <= frame)
136 break;
137 frame = next;
138 }
139#else
140 while (valid_stack_ptr(tinfo, stack, sizeof(*stack))) { 151 while (valid_stack_ptr(tinfo, stack, sizeof(*stack))) {
141 unsigned long addr; 152 unsigned long addr;
142 153
143 addr = *stack++; 154 addr = *stack;
144 if (__kernel_text_address(addr)) 155 if (__kernel_text_address(addr)) {
145 ops->address(data, addr); 156 if ((unsigned long) stack == bp + 4) {
157 ops->address(data, addr, 1);
158 frame = frame->next_frame;
159 bp = (unsigned long) frame;
160 } else {
161 ops->address(data, addr, bp == 0);
162 }
163 }
164 stack++;
146 } 165 }
147#endif 166 return bp;
148 return ebp;
149} 167}
150 168
151#define MSG(msg) ops->warning(data, msg) 169#define MSG(msg) ops->warning(data, msg)
152 170
153void dump_trace(struct task_struct *task, struct pt_regs *regs, 171void dump_trace(struct task_struct *task, struct pt_regs *regs,
154 unsigned long *stack, 172 unsigned long *stack, unsigned long bp,
155 const struct stacktrace_ops *ops, void *data) 173 const struct stacktrace_ops *ops, void *data)
156{ 174{
157 unsigned long ebp = 0;
158
159 if (!task) 175 if (!task)
160 task = current; 176 task = current;
161 177
@@ -163,17 +179,17 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
163 unsigned long dummy; 179 unsigned long dummy;
164 stack = &dummy; 180 stack = &dummy;
165 if (task != current) 181 if (task != current)
166 stack = (unsigned long *)task->thread.esp; 182 stack = (unsigned long *)task->thread.sp;
167 } 183 }
168 184
169#ifdef CONFIG_FRAME_POINTER 185#ifdef CONFIG_FRAME_POINTER
170 if (!ebp) { 186 if (!bp) {
171 if (task == current) { 187 if (task == current) {
172 /* Grab ebp right from our regs */ 188 /* Grab bp right from our regs */
173 asm ("movl %%ebp, %0" : "=r" (ebp) : ); 189 asm ("movl %%ebp, %0" : "=r" (bp) : );
174 } else { 190 } else {
175 /* ebp is the last reg pushed by switch_to */ 191 /* bp is the last reg pushed by switch_to */
176 ebp = *(unsigned long *) task->thread.esp; 192 bp = *(unsigned long *) task->thread.sp;
177 } 193 }
178 } 194 }
179#endif 195#endif
@@ -182,7 +198,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
182 struct thread_info *context; 198 struct thread_info *context;
183 context = (struct thread_info *) 199 context = (struct thread_info *)
184 ((unsigned long)stack & (~(THREAD_SIZE - 1))); 200 ((unsigned long)stack & (~(THREAD_SIZE - 1)));
185 ebp = print_context_stack(context, stack, ebp, ops, data); 201 bp = print_context_stack(context, stack, bp, ops, data);
186 /* Should be after the line below, but somewhere 202 /* Should be after the line below, but somewhere
187 in early boot context comes out corrupted and we 203 in early boot context comes out corrupted and we
188 can't reference it -AK */ 204 can't reference it -AK */
@@ -217,9 +233,11 @@ static int print_trace_stack(void *data, char *name)
217/* 233/*
218 * Print one address/symbol entries per line. 234 * Print one address/symbol entries per line.
219 */ 235 */
220static void print_trace_address(void *data, unsigned long addr) 236static void print_trace_address(void *data, unsigned long addr, int reliable)
221{ 237{
222 printk("%s [<%08lx>] ", (char *)data, addr); 238 printk("%s [<%08lx>] ", (char *)data, addr);
239 if (!reliable)
240 printk("? ");
223 print_symbol("%s\n", addr); 241 print_symbol("%s\n", addr);
224 touch_nmi_watchdog(); 242 touch_nmi_watchdog();
225} 243}
@@ -233,32 +251,32 @@ static const struct stacktrace_ops print_trace_ops = {
233 251
234static void 252static void
235show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, 253show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
236 unsigned long * stack, char *log_lvl) 254 unsigned long *stack, unsigned long bp, char *log_lvl)
237{ 255{
238 dump_trace(task, regs, stack, &print_trace_ops, log_lvl); 256 dump_trace(task, regs, stack, bp, &print_trace_ops, log_lvl);
239 printk("%s =======================\n", log_lvl); 257 printk("%s =======================\n", log_lvl);
240} 258}
241 259
242void show_trace(struct task_struct *task, struct pt_regs *regs, 260void show_trace(struct task_struct *task, struct pt_regs *regs,
243 unsigned long * stack) 261 unsigned long *stack, unsigned long bp)
244{ 262{
245 show_trace_log_lvl(task, regs, stack, ""); 263 show_trace_log_lvl(task, regs, stack, bp, "");
246} 264}
247 265
248static void show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, 266static void show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
249 unsigned long *esp, char *log_lvl) 267 unsigned long *sp, unsigned long bp, char *log_lvl)
250{ 268{
251 unsigned long *stack; 269 unsigned long *stack;
252 int i; 270 int i;
253 271
254 if (esp == NULL) { 272 if (sp == NULL) {
255 if (task) 273 if (task)
256 esp = (unsigned long*)task->thread.esp; 274 sp = (unsigned long*)task->thread.sp;
257 else 275 else
258 esp = (unsigned long *)&esp; 276 sp = (unsigned long *)&sp;
259 } 277 }
260 278
261 stack = esp; 279 stack = sp;
262 for(i = 0; i < kstack_depth_to_print; i++) { 280 for(i = 0; i < kstack_depth_to_print; i++) {
263 if (kstack_end(stack)) 281 if (kstack_end(stack))
264 break; 282 break;
@@ -267,13 +285,13 @@ static void show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
267 printk("%08lx ", *stack++); 285 printk("%08lx ", *stack++);
268 } 286 }
269 printk("\n%sCall Trace:\n", log_lvl); 287 printk("\n%sCall Trace:\n", log_lvl);
270 show_trace_log_lvl(task, regs, esp, log_lvl); 288 show_trace_log_lvl(task, regs, sp, bp, log_lvl);
271} 289}
272 290
273void show_stack(struct task_struct *task, unsigned long *esp) 291void show_stack(struct task_struct *task, unsigned long *sp)
274{ 292{
275 printk(" "); 293 printk(" ");
276 show_stack_log_lvl(task, NULL, esp, ""); 294 show_stack_log_lvl(task, NULL, sp, 0, "");
277} 295}
278 296
279/* 297/*
@@ -282,13 +300,19 @@ void show_stack(struct task_struct *task, unsigned long *esp)
282void dump_stack(void) 300void dump_stack(void)
283{ 301{
284 unsigned long stack; 302 unsigned long stack;
303 unsigned long bp = 0;
304
305#ifdef CONFIG_FRAME_POINTER
306 if (!bp)
307 asm("movl %%ebp, %0" : "=r" (bp):);
308#endif
285 309
286 printk("Pid: %d, comm: %.20s %s %s %.*s\n", 310 printk("Pid: %d, comm: %.20s %s %s %.*s\n",
287 current->pid, current->comm, print_tainted(), 311 current->pid, current->comm, print_tainted(),
288 init_utsname()->release, 312 init_utsname()->release,
289 (int)strcspn(init_utsname()->version, " "), 313 (int)strcspn(init_utsname()->version, " "),
290 init_utsname()->version); 314 init_utsname()->version);
291 show_trace(current, NULL, &stack); 315 show_trace(current, NULL, &stack, bp);
292} 316}
293 317
294EXPORT_SYMBOL(dump_stack); 318EXPORT_SYMBOL(dump_stack);
@@ -307,30 +331,30 @@ void show_registers(struct pt_regs *regs)
307 * time of the fault.. 331 * time of the fault..
308 */ 332 */
309 if (!user_mode_vm(regs)) { 333 if (!user_mode_vm(regs)) {
310 u8 *eip; 334 u8 *ip;
311 unsigned int code_prologue = code_bytes * 43 / 64; 335 unsigned int code_prologue = code_bytes * 43 / 64;
312 unsigned int code_len = code_bytes; 336 unsigned int code_len = code_bytes;
313 unsigned char c; 337 unsigned char c;
314 338
315 printk("\n" KERN_EMERG "Stack: "); 339 printk("\n" KERN_EMERG "Stack: ");
316 show_stack_log_lvl(NULL, regs, &regs->esp, KERN_EMERG); 340 show_stack_log_lvl(NULL, regs, &regs->sp, 0, KERN_EMERG);
317 341
318 printk(KERN_EMERG "Code: "); 342 printk(KERN_EMERG "Code: ");
319 343
320 eip = (u8 *)regs->eip - code_prologue; 344 ip = (u8 *)regs->ip - code_prologue;
321 if (eip < (u8 *)PAGE_OFFSET || 345 if (ip < (u8 *)PAGE_OFFSET ||
322 probe_kernel_address(eip, c)) { 346 probe_kernel_address(ip, c)) {
323 /* try starting at EIP */ 347 /* try starting at EIP */
324 eip = (u8 *)regs->eip; 348 ip = (u8 *)regs->ip;
325 code_len = code_len - code_prologue + 1; 349 code_len = code_len - code_prologue + 1;
326 } 350 }
327 for (i = 0; i < code_len; i++, eip++) { 351 for (i = 0; i < code_len; i++, ip++) {
328 if (eip < (u8 *)PAGE_OFFSET || 352 if (ip < (u8 *)PAGE_OFFSET ||
329 probe_kernel_address(eip, c)) { 353 probe_kernel_address(ip, c)) {
330 printk(" Bad EIP value."); 354 printk(" Bad EIP value.");
331 break; 355 break;
332 } 356 }
333 if (eip == (u8 *)regs->eip) 357 if (ip == (u8 *)regs->ip)
334 printk("<%02x> ", c); 358 printk("<%02x> ", c);
335 else 359 else
336 printk("%02x ", c); 360 printk("%02x ", c);
@@ -339,18 +363,57 @@ void show_registers(struct pt_regs *regs)
339 printk("\n"); 363 printk("\n");
340} 364}
341 365
342int is_valid_bugaddr(unsigned long eip) 366int is_valid_bugaddr(unsigned long ip)
343{ 367{
344 unsigned short ud2; 368 unsigned short ud2;
345 369
346 if (eip < PAGE_OFFSET) 370 if (ip < PAGE_OFFSET)
347 return 0; 371 return 0;
348 if (probe_kernel_address((unsigned short *)eip, ud2)) 372 if (probe_kernel_address((unsigned short *)ip, ud2))
349 return 0; 373 return 0;
350 374
351 return ud2 == 0x0b0f; 375 return ud2 == 0x0b0f;
352} 376}
353 377
378static int die_counter;
379
380int __kprobes __die(const char * str, struct pt_regs * regs, long err)
381{
382 unsigned long sp;
383 unsigned short ss;
384
385 printk(KERN_EMERG "%s: %04lx [#%d] ", str, err & 0xffff, ++die_counter);
386#ifdef CONFIG_PREEMPT
387 printk("PREEMPT ");
388#endif
389#ifdef CONFIG_SMP
390 printk("SMP ");
391#endif
392#ifdef CONFIG_DEBUG_PAGEALLOC
393 printk("DEBUG_PAGEALLOC");
394#endif
395 printk("\n");
396
397 if (notify_die(DIE_OOPS, str, regs, err,
398 current->thread.trap_no, SIGSEGV) !=
399 NOTIFY_STOP) {
400 show_registers(regs);
401 /* Executive summary in case the oops scrolled away */
402 sp = (unsigned long) (&regs->sp);
403 savesegment(ss, ss);
404 if (user_mode(regs)) {
405 sp = regs->sp;
406 ss = regs->ss & 0xffff;
407 }
408 printk(KERN_EMERG "EIP: [<%08lx>] ", regs->ip);
409 print_symbol("%s", regs->ip);
410 printk(" SS:ESP %04x:%08lx\n", ss, sp);
411 return 0;
412 } else {
413 return 1;
414 }
415}
416
354/* 417/*
355 * This is gone through when something in the kernel has done something bad and 418 * This is gone through when something in the kernel has done something bad and
356 * is about to be terminated. 419 * is about to be terminated.
@@ -366,7 +429,6 @@ void die(const char * str, struct pt_regs * regs, long err)
366 .lock_owner = -1, 429 .lock_owner = -1,
367 .lock_owner_depth = 0 430 .lock_owner_depth = 0
368 }; 431 };
369 static int die_counter;
370 unsigned long flags; 432 unsigned long flags;
371 433
372 oops_enter(); 434 oops_enter();
@@ -382,43 +444,13 @@ void die(const char * str, struct pt_regs * regs, long err)
382 raw_local_irq_save(flags); 444 raw_local_irq_save(flags);
383 445
384 if (++die.lock_owner_depth < 3) { 446 if (++die.lock_owner_depth < 3) {
385 unsigned long esp; 447 report_bug(regs->ip, regs);
386 unsigned short ss;
387 448
388 report_bug(regs->eip, regs); 449 if (__die(str, regs, err))
389
390 printk(KERN_EMERG "%s: %04lx [#%d] ", str, err & 0xffff,
391 ++die_counter);
392#ifdef CONFIG_PREEMPT
393 printk("PREEMPT ");
394#endif
395#ifdef CONFIG_SMP
396 printk("SMP ");
397#endif
398#ifdef CONFIG_DEBUG_PAGEALLOC
399 printk("DEBUG_PAGEALLOC");
400#endif
401 printk("\n");
402
403 if (notify_die(DIE_OOPS, str, regs, err,
404 current->thread.trap_no, SIGSEGV) !=
405 NOTIFY_STOP) {
406 show_registers(regs);
407 /* Executive summary in case the oops scrolled away */
408 esp = (unsigned long) (&regs->esp);
409 savesegment(ss, ss);
410 if (user_mode(regs)) {
411 esp = regs->esp;
412 ss = regs->xss & 0xffff;
413 }
414 printk(KERN_EMERG "EIP: [<%08lx>] ", regs->eip);
415 print_symbol("%s", regs->eip);
416 printk(" SS:ESP %04x:%08lx\n", ss, esp);
417 }
418 else
419 regs = NULL; 450 regs = NULL;
420 } else 451 } else {
421 printk(KERN_EMERG "Recursive die() failure, output suppressed\n"); 452 printk(KERN_EMERG "Recursive die() failure, output suppressed\n");
453 }
422 454
423 bust_spinlocks(0); 455 bust_spinlocks(0);
424 die.lock_owner = -1; 456 die.lock_owner = -1;
@@ -454,7 +486,7 @@ static void __kprobes do_trap(int trapnr, int signr, char *str, int vm86,
454{ 486{
455 struct task_struct *tsk = current; 487 struct task_struct *tsk = current;
456 488
457 if (regs->eflags & VM_MASK) { 489 if (regs->flags & VM_MASK) {
458 if (vm86) 490 if (vm86)
459 goto vm86_trap; 491 goto vm86_trap;
460 goto trap_signal; 492 goto trap_signal;
@@ -500,7 +532,7 @@ static void __kprobes do_trap(int trapnr, int signr, char *str, int vm86,
500} 532}
501 533
502#define DO_ERROR(trapnr, signr, str, name) \ 534#define DO_ERROR(trapnr, signr, str, name) \
503fastcall void do_##name(struct pt_regs * regs, long error_code) \ 535void do_##name(struct pt_regs * regs, long error_code) \
504{ \ 536{ \
505 if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ 537 if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
506 == NOTIFY_STOP) \ 538 == NOTIFY_STOP) \
@@ -509,7 +541,7 @@ fastcall void do_##name(struct pt_regs * regs, long error_code) \
509} 541}
510 542
511#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr, irq) \ 543#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr, irq) \
512fastcall void do_##name(struct pt_regs * regs, long error_code) \ 544void do_##name(struct pt_regs * regs, long error_code) \
513{ \ 545{ \
514 siginfo_t info; \ 546 siginfo_t info; \
515 if (irq) \ 547 if (irq) \
@@ -525,7 +557,7 @@ fastcall void do_##name(struct pt_regs * regs, long error_code) \
525} 557}
526 558
527#define DO_VM86_ERROR(trapnr, signr, str, name) \ 559#define DO_VM86_ERROR(trapnr, signr, str, name) \
528fastcall void do_##name(struct pt_regs * regs, long error_code) \ 560void do_##name(struct pt_regs * regs, long error_code) \
529{ \ 561{ \
530 if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ 562 if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
531 == NOTIFY_STOP) \ 563 == NOTIFY_STOP) \
@@ -534,7 +566,7 @@ fastcall void do_##name(struct pt_regs * regs, long error_code) \
534} 566}
535 567
536#define DO_VM86_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \ 568#define DO_VM86_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
537fastcall void do_##name(struct pt_regs * regs, long error_code) \ 569void do_##name(struct pt_regs * regs, long error_code) \
538{ \ 570{ \
539 siginfo_t info; \ 571 siginfo_t info; \
540 info.si_signo = signr; \ 572 info.si_signo = signr; \
@@ -548,13 +580,13 @@ fastcall void do_##name(struct pt_regs * regs, long error_code) \
548 do_trap(trapnr, signr, str, 1, regs, error_code, &info); \ 580 do_trap(trapnr, signr, str, 1, regs, error_code, &info); \
549} 581}
550 582
551DO_VM86_ERROR_INFO( 0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->eip) 583DO_VM86_ERROR_INFO( 0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->ip)
552#ifndef CONFIG_KPROBES 584#ifndef CONFIG_KPROBES
553DO_VM86_ERROR( 3, SIGTRAP, "int3", int3) 585DO_VM86_ERROR( 3, SIGTRAP, "int3", int3)
554#endif 586#endif
555DO_VM86_ERROR( 4, SIGSEGV, "overflow", overflow) 587DO_VM86_ERROR( 4, SIGSEGV, "overflow", overflow)
556DO_VM86_ERROR( 5, SIGSEGV, "bounds", bounds) 588DO_VM86_ERROR( 5, SIGSEGV, "bounds", bounds)
557DO_ERROR_INFO( 6, SIGILL, "invalid opcode", invalid_op, ILL_ILLOPN, regs->eip, 0) 589DO_ERROR_INFO( 6, SIGILL, "invalid opcode", invalid_op, ILL_ILLOPN, regs->ip, 0)
558DO_ERROR( 9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun) 590DO_ERROR( 9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun)
559DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS) 591DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS)
560DO_ERROR(11, SIGBUS, "segment not present", segment_not_present) 592DO_ERROR(11, SIGBUS, "segment not present", segment_not_present)
@@ -562,7 +594,7 @@ DO_ERROR(12, SIGBUS, "stack segment", stack_segment)
562DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0, 0) 594DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0, 0)
563DO_ERROR_INFO(32, SIGSEGV, "iret exception", iret_error, ILL_BADSTK, 0, 1) 595DO_ERROR_INFO(32, SIGSEGV, "iret exception", iret_error, ILL_BADSTK, 0, 1)
564 596
565fastcall void __kprobes do_general_protection(struct pt_regs * regs, 597void __kprobes do_general_protection(struct pt_regs * regs,
566 long error_code) 598 long error_code)
567{ 599{
568 int cpu = get_cpu(); 600 int cpu = get_cpu();
@@ -596,7 +628,7 @@ fastcall void __kprobes do_general_protection(struct pt_regs * regs,
596 } 628 }
597 put_cpu(); 629 put_cpu();
598 630
599 if (regs->eflags & VM_MASK) 631 if (regs->flags & VM_MASK)
600 goto gp_in_vm86; 632 goto gp_in_vm86;
601 633
602 if (!user_mode(regs)) 634 if (!user_mode(regs))
@@ -605,11 +637,14 @@ fastcall void __kprobes do_general_protection(struct pt_regs * regs,
605 current->thread.error_code = error_code; 637 current->thread.error_code = error_code;
606 current->thread.trap_no = 13; 638 current->thread.trap_no = 13;
607 if (show_unhandled_signals && unhandled_signal(current, SIGSEGV) && 639 if (show_unhandled_signals && unhandled_signal(current, SIGSEGV) &&
608 printk_ratelimit()) 640 printk_ratelimit()) {
609 printk(KERN_INFO 641 printk(KERN_INFO
610 "%s[%d] general protection eip:%lx esp:%lx error:%lx\n", 642 "%s[%d] general protection ip:%lx sp:%lx error:%lx",
611 current->comm, task_pid_nr(current), 643 current->comm, task_pid_nr(current),
612 regs->eip, regs->esp, error_code); 644 regs->ip, regs->sp, error_code);
645 print_vma_addr(" in ", regs->ip);
646 printk("\n");
647 }
613 648
614 force_sig(SIGSEGV, current); 649 force_sig(SIGSEGV, current);
615 return; 650 return;
@@ -705,8 +740,8 @@ void __kprobes die_nmi(struct pt_regs *regs, const char *msg)
705 */ 740 */
706 bust_spinlocks(1); 741 bust_spinlocks(1);
707 printk(KERN_EMERG "%s", msg); 742 printk(KERN_EMERG "%s", msg);
708 printk(" on CPU%d, eip %08lx, registers:\n", 743 printk(" on CPU%d, ip %08lx, registers:\n",
709 smp_processor_id(), regs->eip); 744 smp_processor_id(), regs->ip);
710 show_registers(regs); 745 show_registers(regs);
711 console_silent(); 746 console_silent();
712 spin_unlock(&nmi_print_lock); 747 spin_unlock(&nmi_print_lock);
@@ -763,7 +798,7 @@ static __kprobes void default_do_nmi(struct pt_regs * regs)
763 798
764static int ignore_nmis; 799static int ignore_nmis;
765 800
766fastcall __kprobes void do_nmi(struct pt_regs * regs, long error_code) 801__kprobes void do_nmi(struct pt_regs * regs, long error_code)
767{ 802{
768 int cpu; 803 int cpu;
769 804
@@ -792,7 +827,7 @@ void restart_nmi(void)
792} 827}
793 828
794#ifdef CONFIG_KPROBES 829#ifdef CONFIG_KPROBES
795fastcall void __kprobes do_int3(struct pt_regs *regs, long error_code) 830void __kprobes do_int3(struct pt_regs *regs, long error_code)
796{ 831{
797 trace_hardirqs_fixup(); 832 trace_hardirqs_fixup();
798 833
@@ -828,7 +863,7 @@ fastcall void __kprobes do_int3(struct pt_regs *regs, long error_code)
828 * find every occurrence of the TF bit that could be saved away even 863 * find every occurrence of the TF bit that could be saved away even
829 * by user code) 864 * by user code)
830 */ 865 */
831fastcall void __kprobes do_debug(struct pt_regs * regs, long error_code) 866void __kprobes do_debug(struct pt_regs * regs, long error_code)
832{ 867{
833 unsigned int condition; 868 unsigned int condition;
834 struct task_struct *tsk = current; 869 struct task_struct *tsk = current;
@@ -837,24 +872,30 @@ fastcall void __kprobes do_debug(struct pt_regs * regs, long error_code)
837 872
838 get_debugreg(condition, 6); 873 get_debugreg(condition, 6);
839 874
875 /*
876 * The processor cleared BTF, so don't mark that we need it set.
877 */
878 clear_tsk_thread_flag(tsk, TIF_DEBUGCTLMSR);
879 tsk->thread.debugctlmsr = 0;
880
840 if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code, 881 if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,
841 SIGTRAP) == NOTIFY_STOP) 882 SIGTRAP) == NOTIFY_STOP)
842 return; 883 return;
843 /* It's safe to allow irq's after DR6 has been saved */ 884 /* It's safe to allow irq's after DR6 has been saved */
844 if (regs->eflags & X86_EFLAGS_IF) 885 if (regs->flags & X86_EFLAGS_IF)
845 local_irq_enable(); 886 local_irq_enable();
846 887
847 /* Mask out spurious debug traps due to lazy DR7 setting */ 888 /* Mask out spurious debug traps due to lazy DR7 setting */
848 if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) { 889 if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
849 if (!tsk->thread.debugreg[7]) 890 if (!tsk->thread.debugreg7)
850 goto clear_dr7; 891 goto clear_dr7;
851 } 892 }
852 893
853 if (regs->eflags & VM_MASK) 894 if (regs->flags & VM_MASK)
854 goto debug_vm86; 895 goto debug_vm86;
855 896
856 /* Save debug status register where ptrace can see it */ 897 /* Save debug status register where ptrace can see it */
857 tsk->thread.debugreg[6] = condition; 898 tsk->thread.debugreg6 = condition;
858 899
859 /* 900 /*
860 * Single-stepping through TF: make sure we ignore any events in 901 * Single-stepping through TF: make sure we ignore any events in
@@ -886,7 +927,7 @@ debug_vm86:
886 927
887clear_TF_reenable: 928clear_TF_reenable:
888 set_tsk_thread_flag(tsk, TIF_SINGLESTEP); 929 set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
889 regs->eflags &= ~TF_MASK; 930 regs->flags &= ~TF_MASK;
890 return; 931 return;
891} 932}
892 933
@@ -895,7 +936,7 @@ clear_TF_reenable:
895 * the correct behaviour even in the presence of the asynchronous 936 * the correct behaviour even in the presence of the asynchronous
896 * IRQ13 behaviour 937 * IRQ13 behaviour
897 */ 938 */
898void math_error(void __user *eip) 939void math_error(void __user *ip)
899{ 940{
900 struct task_struct * task; 941 struct task_struct * task;
901 siginfo_t info; 942 siginfo_t info;
@@ -911,7 +952,7 @@ void math_error(void __user *eip)
911 info.si_signo = SIGFPE; 952 info.si_signo = SIGFPE;
912 info.si_errno = 0; 953 info.si_errno = 0;
913 info.si_code = __SI_FAULT; 954 info.si_code = __SI_FAULT;
914 info.si_addr = eip; 955 info.si_addr = ip;
915 /* 956 /*
916 * (~cwd & swd) will mask out exceptions that are not set to unmasked 957 * (~cwd & swd) will mask out exceptions that are not set to unmasked
917 * status. 0x3f is the exception bits in these regs, 0x200 is the 958 * status. 0x3f is the exception bits in these regs, 0x200 is the
@@ -954,13 +995,13 @@ void math_error(void __user *eip)
954 force_sig_info(SIGFPE, &info, task); 995 force_sig_info(SIGFPE, &info, task);
955} 996}
956 997
957fastcall void do_coprocessor_error(struct pt_regs * regs, long error_code) 998void do_coprocessor_error(struct pt_regs * regs, long error_code)
958{ 999{
959 ignore_fpu_irq = 1; 1000 ignore_fpu_irq = 1;
960 math_error((void __user *)regs->eip); 1001 math_error((void __user *)regs->ip);
961} 1002}
962 1003
963static void simd_math_error(void __user *eip) 1004static void simd_math_error(void __user *ip)
964{ 1005{
965 struct task_struct * task; 1006 struct task_struct * task;
966 siginfo_t info; 1007 siginfo_t info;
@@ -976,7 +1017,7 @@ static void simd_math_error(void __user *eip)
976 info.si_signo = SIGFPE; 1017 info.si_signo = SIGFPE;
977 info.si_errno = 0; 1018 info.si_errno = 0;
978 info.si_code = __SI_FAULT; 1019 info.si_code = __SI_FAULT;
979 info.si_addr = eip; 1020 info.si_addr = ip;
980 /* 1021 /*
981 * The SIMD FPU exceptions are handled a little differently, as there 1022 * The SIMD FPU exceptions are handled a little differently, as there
982 * is only a single status/control register. Thus, to determine which 1023 * is only a single status/control register. Thus, to determine which
@@ -1008,19 +1049,19 @@ static void simd_math_error(void __user *eip)
1008 force_sig_info(SIGFPE, &info, task); 1049 force_sig_info(SIGFPE, &info, task);
1009} 1050}
1010 1051
1011fastcall void do_simd_coprocessor_error(struct pt_regs * regs, 1052void do_simd_coprocessor_error(struct pt_regs * regs,
1012 long error_code) 1053 long error_code)
1013{ 1054{
1014 if (cpu_has_xmm) { 1055 if (cpu_has_xmm) {
1015 /* Handle SIMD FPU exceptions on PIII+ processors. */ 1056 /* Handle SIMD FPU exceptions on PIII+ processors. */
1016 ignore_fpu_irq = 1; 1057 ignore_fpu_irq = 1;
1017 simd_math_error((void __user *)regs->eip); 1058 simd_math_error((void __user *)regs->ip);
1018 } else { 1059 } else {
1019 /* 1060 /*
1020 * Handle strange cache flush from user space exception 1061 * Handle strange cache flush from user space exception
1021 * in all other cases. This is undocumented behaviour. 1062 * in all other cases. This is undocumented behaviour.
1022 */ 1063 */
1023 if (regs->eflags & VM_MASK) { 1064 if (regs->flags & VM_MASK) {
1024 handle_vm86_fault((struct kernel_vm86_regs *)regs, 1065 handle_vm86_fault((struct kernel_vm86_regs *)regs,
1025 error_code); 1066 error_code);
1026 return; 1067 return;
@@ -1032,7 +1073,7 @@ fastcall void do_simd_coprocessor_error(struct pt_regs * regs,
1032 } 1073 }
1033} 1074}
1034 1075
1035fastcall void do_spurious_interrupt_bug(struct pt_regs * regs, 1076void do_spurious_interrupt_bug(struct pt_regs * regs,
1036 long error_code) 1077 long error_code)
1037{ 1078{
1038#if 0 1079#if 0
@@ -1041,7 +1082,7 @@ fastcall void do_spurious_interrupt_bug(struct pt_regs * regs,
1041#endif 1082#endif
1042} 1083}
1043 1084
1044fastcall unsigned long patch_espfix_desc(unsigned long uesp, 1085unsigned long patch_espfix_desc(unsigned long uesp,
1045 unsigned long kesp) 1086 unsigned long kesp)
1046{ 1087{
1047 struct desc_struct *gdt = __get_cpu_var(gdt_page).gdt; 1088 struct desc_struct *gdt = __get_cpu_var(gdt_page).gdt;
@@ -1095,51 +1136,17 @@ asmlinkage void math_emulate(long arg)
1095 1136
1096#endif /* CONFIG_MATH_EMULATION */ 1137#endif /* CONFIG_MATH_EMULATION */
1097 1138
1098/*
1099 * This needs to use 'idt_table' rather than 'idt', and
1100 * thus use the _nonmapped_ version of the IDT, as the
1101 * Pentium F0 0F bugfix can have resulted in the mapped
1102 * IDT being write-protected.
1103 */
1104void set_intr_gate(unsigned int n, void *addr)
1105{
1106 _set_gate(n, DESCTYPE_INT, addr, __KERNEL_CS);
1107}
1108
1109/*
1110 * This routine sets up an interrupt gate at directory privilege level 3.
1111 */
1112static inline void set_system_intr_gate(unsigned int n, void *addr)
1113{
1114 _set_gate(n, DESCTYPE_INT | DESCTYPE_DPL3, addr, __KERNEL_CS);
1115}
1116
1117static void __init set_trap_gate(unsigned int n, void *addr)
1118{
1119 _set_gate(n, DESCTYPE_TRAP, addr, __KERNEL_CS);
1120}
1121
1122static void __init set_system_gate(unsigned int n, void *addr)
1123{
1124 _set_gate(n, DESCTYPE_TRAP | DESCTYPE_DPL3, addr, __KERNEL_CS);
1125}
1126
1127static void __init set_task_gate(unsigned int n, unsigned int gdt_entry)
1128{
1129 _set_gate(n, DESCTYPE_TASK, (void *)0, (gdt_entry<<3));
1130}
1131
1132 1139
1133void __init trap_init(void) 1140void __init trap_init(void)
1134{ 1141{
1135 int i; 1142 int i;
1136 1143
1137#ifdef CONFIG_EISA 1144#ifdef CONFIG_EISA
1138 void __iomem *p = ioremap(0x0FFFD9, 4); 1145 void __iomem *p = early_ioremap(0x0FFFD9, 4);
1139 if (readl(p) == 'E'+('I'<<8)+('S'<<16)+('A'<<24)) { 1146 if (readl(p) == 'E'+('I'<<8)+('S'<<16)+('A'<<24)) {
1140 EISA_bus = 1; 1147 EISA_bus = 1;
1141 } 1148 }
1142 iounmap(p); 1149 early_iounmap(p, 4);
1143#endif 1150#endif
1144 1151
1145#ifdef CONFIG_X86_LOCAL_APIC 1152#ifdef CONFIG_X86_LOCAL_APIC
diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c
index cc68b92316cd..efc66df728b6 100644
--- a/arch/x86/kernel/traps_64.c
+++ b/arch/x86/kernel/traps_64.c
@@ -74,22 +74,24 @@ asmlinkage void alignment_check(void);
74asmlinkage void machine_check(void); 74asmlinkage void machine_check(void);
75asmlinkage void spurious_interrupt_bug(void); 75asmlinkage void spurious_interrupt_bug(void);
76 76
77static unsigned int code_bytes = 64;
78
77static inline void conditional_sti(struct pt_regs *regs) 79static inline void conditional_sti(struct pt_regs *regs)
78{ 80{
79 if (regs->eflags & X86_EFLAGS_IF) 81 if (regs->flags & X86_EFLAGS_IF)
80 local_irq_enable(); 82 local_irq_enable();
81} 83}
82 84
83static inline void preempt_conditional_sti(struct pt_regs *regs) 85static inline void preempt_conditional_sti(struct pt_regs *regs)
84{ 86{
85 preempt_disable(); 87 preempt_disable();
86 if (regs->eflags & X86_EFLAGS_IF) 88 if (regs->flags & X86_EFLAGS_IF)
87 local_irq_enable(); 89 local_irq_enable();
88} 90}
89 91
90static inline void preempt_conditional_cli(struct pt_regs *regs) 92static inline void preempt_conditional_cli(struct pt_regs *regs)
91{ 93{
92 if (regs->eflags & X86_EFLAGS_IF) 94 if (regs->flags & X86_EFLAGS_IF)
93 local_irq_disable(); 95 local_irq_disable();
94 /* Make sure to not schedule here because we could be running 96 /* Make sure to not schedule here because we could be running
95 on an exception stack. */ 97 on an exception stack. */
@@ -98,14 +100,15 @@ static inline void preempt_conditional_cli(struct pt_regs *regs)
98 100
99int kstack_depth_to_print = 12; 101int kstack_depth_to_print = 12;
100 102
101#ifdef CONFIG_KALLSYMS 103void printk_address(unsigned long address, int reliable)
102void printk_address(unsigned long address)
103{ 104{
105#ifdef CONFIG_KALLSYMS
104 unsigned long offset = 0, symsize; 106 unsigned long offset = 0, symsize;
105 const char *symname; 107 const char *symname;
106 char *modname; 108 char *modname;
107 char *delim = ":"; 109 char *delim = ":";
108 char namebuf[128]; 110 char namebuf[KSYM_NAME_LEN];
111 char reliab[4] = "";
109 112
110 symname = kallsyms_lookup(address, &symsize, &offset, 113 symname = kallsyms_lookup(address, &symsize, &offset,
111 &modname, namebuf); 114 &modname, namebuf);
@@ -113,17 +116,17 @@ void printk_address(unsigned long address)
113 printk(" [<%016lx>]\n", address); 116 printk(" [<%016lx>]\n", address);
114 return; 117 return;
115 } 118 }
119 if (!reliable)
120 strcpy(reliab, "? ");
121
116 if (!modname) 122 if (!modname)
117 modname = delim = ""; 123 modname = delim = "";
118 printk(" [<%016lx>] %s%s%s%s+0x%lx/0x%lx\n", 124 printk(" [<%016lx>] %s%s%s%s%s+0x%lx/0x%lx\n",
119 address, delim, modname, delim, symname, offset, symsize); 125 address, reliab, delim, modname, delim, symname, offset, symsize);
120}
121#else 126#else
122void printk_address(unsigned long address)
123{
124 printk(" [<%016lx>]\n", address); 127 printk(" [<%016lx>]\n", address);
125}
126#endif 128#endif
129}
127 130
128static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, 131static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
129 unsigned *usedp, char **idp) 132 unsigned *usedp, char **idp)
@@ -208,14 +211,53 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
208 * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack 211 * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack
209 */ 212 */
210 213
211static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) 214static inline int valid_stack_ptr(struct thread_info *tinfo,
215 void *p, unsigned int size, void *end)
216{
217 void *t = tinfo;
218 if (end) {
219 if (p < end && p >= (end-THREAD_SIZE))
220 return 1;
221 else
222 return 0;
223 }
224 return p > t && p < t + THREAD_SIZE - size;
225}
226
227/* The form of the top of the frame on the stack */
228struct stack_frame {
229 struct stack_frame *next_frame;
230 unsigned long return_address;
231};
232
233
234static inline unsigned long print_context_stack(struct thread_info *tinfo,
235 unsigned long *stack, unsigned long bp,
236 const struct stacktrace_ops *ops, void *data,
237 unsigned long *end)
212{ 238{
213 void *t = (void *)tinfo; 239 struct stack_frame *frame = (struct stack_frame *)bp;
214 return p > t && p < t + THREAD_SIZE - 3; 240
241 while (valid_stack_ptr(tinfo, stack, sizeof(*stack), end)) {
242 unsigned long addr;
243
244 addr = *stack;
245 if (__kernel_text_address(addr)) {
246 if ((unsigned long) stack == bp + 8) {
247 ops->address(data, addr, 1);
248 frame = frame->next_frame;
249 bp = (unsigned long) frame;
250 } else {
251 ops->address(data, addr, bp == 0);
252 }
253 }
254 stack++;
255 }
256 return bp;
215} 257}
216 258
217void dump_trace(struct task_struct *tsk, struct pt_regs *regs, 259void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
218 unsigned long *stack, 260 unsigned long *stack, unsigned long bp,
219 const struct stacktrace_ops *ops, void *data) 261 const struct stacktrace_ops *ops, void *data)
220{ 262{
221 const unsigned cpu = get_cpu(); 263 const unsigned cpu = get_cpu();
@@ -225,36 +267,28 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
225 267
226 if (!tsk) 268 if (!tsk)
227 tsk = current; 269 tsk = current;
270 tinfo = task_thread_info(tsk);
228 271
229 if (!stack) { 272 if (!stack) {
230 unsigned long dummy; 273 unsigned long dummy;
231 stack = &dummy; 274 stack = &dummy;
232 if (tsk && tsk != current) 275 if (tsk && tsk != current)
233 stack = (unsigned long *)tsk->thread.rsp; 276 stack = (unsigned long *)tsk->thread.sp;
234 } 277 }
235 278
236 /* 279#ifdef CONFIG_FRAME_POINTER
237 * Print function call entries within a stack. 'cond' is the 280 if (!bp) {
238 * "end of stackframe" condition, that the 'stack++' 281 if (tsk == current) {
239 * iteration will eventually trigger. 282 /* Grab bp right from our regs */
240 */ 283 asm("movq %%rbp, %0" : "=r" (bp):);
241#define HANDLE_STACK(cond) \ 284 } else {
242 do while (cond) { \ 285 /* bp is the last reg pushed by switch_to */
243 unsigned long addr = *stack++; \ 286 bp = *(unsigned long *) tsk->thread.sp;
244 /* Use unlocked access here because except for NMIs \ 287 }
245 we should be already protected against module unloads */ \ 288 }
246 if (__kernel_text_address(addr)) { \ 289#endif
247 /* \ 290
248 * If the address is either in the text segment of the \ 291
249 * kernel, or in the region which contains vmalloc'ed \
250 * memory, it *may* be the address of a calling \
251 * routine; if so, print it so that someone tracing \
252 * down the cause of the crash will be able to figure \
253 * out the call path that was taken. \
254 */ \
255 ops->address(data, addr); \
256 } \
257 } while (0)
258 292
259 /* 293 /*
260 * Print function call entries in all stacks, starting at the 294 * Print function call entries in all stacks, starting at the
@@ -270,7 +304,9 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
270 if (estack_end) { 304 if (estack_end) {
271 if (ops->stack(data, id) < 0) 305 if (ops->stack(data, id) < 0)
272 break; 306 break;
273 HANDLE_STACK (stack < estack_end); 307
308 bp = print_context_stack(tinfo, stack, bp, ops,
309 data, estack_end);
274 ops->stack(data, "<EOE>"); 310 ops->stack(data, "<EOE>");
275 /* 311 /*
276 * We link to the next stack via the 312 * We link to the next stack via the
@@ -288,7 +324,8 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
288 if (stack >= irqstack && stack < irqstack_end) { 324 if (stack >= irqstack && stack < irqstack_end) {
289 if (ops->stack(data, "IRQ") < 0) 325 if (ops->stack(data, "IRQ") < 0)
290 break; 326 break;
291 HANDLE_STACK (stack < irqstack_end); 327 bp = print_context_stack(tinfo, stack, bp,
328 ops, data, irqstack_end);
292 /* 329 /*
293 * We link to the next stack (which would be 330 * We link to the next stack (which would be
294 * the process stack normally) the last 331 * the process stack normally) the last
@@ -306,9 +343,7 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
306 /* 343 /*
307 * This handles the process stack: 344 * This handles the process stack:
308 */ 345 */
309 tinfo = task_thread_info(tsk); 346 bp = print_context_stack(tinfo, stack, bp, ops, data, NULL);
310 HANDLE_STACK (valid_stack_ptr(tinfo, stack));
311#undef HANDLE_STACK
312 put_cpu(); 347 put_cpu();
313} 348}
314EXPORT_SYMBOL(dump_trace); 349EXPORT_SYMBOL(dump_trace);
@@ -331,10 +366,10 @@ static int print_trace_stack(void *data, char *name)
331 return 0; 366 return 0;
332} 367}
333 368
334static void print_trace_address(void *data, unsigned long addr) 369static void print_trace_address(void *data, unsigned long addr, int reliable)
335{ 370{
336 touch_nmi_watchdog(); 371 touch_nmi_watchdog();
337 printk_address(addr); 372 printk_address(addr, reliable);
338} 373}
339 374
340static const struct stacktrace_ops print_trace_ops = { 375static const struct stacktrace_ops print_trace_ops = {
@@ -345,15 +380,17 @@ static const struct stacktrace_ops print_trace_ops = {
345}; 380};
346 381
347void 382void
348show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long *stack) 383show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long *stack,
384 unsigned long bp)
349{ 385{
350 printk("\nCall Trace:\n"); 386 printk("\nCall Trace:\n");
351 dump_trace(tsk, regs, stack, &print_trace_ops, NULL); 387 dump_trace(tsk, regs, stack, bp, &print_trace_ops, NULL);
352 printk("\n"); 388 printk("\n");
353} 389}
354 390
355static void 391static void
356_show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned long *rsp) 392_show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned long *sp,
393 unsigned long bp)
357{ 394{
358 unsigned long *stack; 395 unsigned long *stack;
359 int i; 396 int i;
@@ -364,14 +401,14 @@ _show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned long *rsp)
364 // debugging aid: "show_stack(NULL, NULL);" prints the 401 // debugging aid: "show_stack(NULL, NULL);" prints the
365 // back trace for this cpu. 402 // back trace for this cpu.
366 403
367 if (rsp == NULL) { 404 if (sp == NULL) {
368 if (tsk) 405 if (tsk)
369 rsp = (unsigned long *)tsk->thread.rsp; 406 sp = (unsigned long *)tsk->thread.sp;
370 else 407 else
371 rsp = (unsigned long *)&rsp; 408 sp = (unsigned long *)&sp;
372 } 409 }
373 410
374 stack = rsp; 411 stack = sp;
375 for(i=0; i < kstack_depth_to_print; i++) { 412 for(i=0; i < kstack_depth_to_print; i++) {
376 if (stack >= irqstack && stack <= irqstack_end) { 413 if (stack >= irqstack && stack <= irqstack_end) {
377 if (stack == irqstack_end) { 414 if (stack == irqstack_end) {
@@ -387,12 +424,12 @@ _show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned long *rsp)
387 printk(" %016lx", *stack++); 424 printk(" %016lx", *stack++);
388 touch_nmi_watchdog(); 425 touch_nmi_watchdog();
389 } 426 }
390 show_trace(tsk, regs, rsp); 427 show_trace(tsk, regs, sp, bp);
391} 428}
392 429
393void show_stack(struct task_struct *tsk, unsigned long * rsp) 430void show_stack(struct task_struct *tsk, unsigned long * sp)
394{ 431{
395 _show_stack(tsk, NULL, rsp); 432 _show_stack(tsk, NULL, sp, 0);
396} 433}
397 434
398/* 435/*
@@ -401,13 +438,19 @@ void show_stack(struct task_struct *tsk, unsigned long * rsp)
401void dump_stack(void) 438void dump_stack(void)
402{ 439{
403 unsigned long dummy; 440 unsigned long dummy;
441 unsigned long bp = 0;
442
443#ifdef CONFIG_FRAME_POINTER
444 if (!bp)
445 asm("movq %%rbp, %0" : "=r" (bp):);
446#endif
404 447
405 printk("Pid: %d, comm: %.20s %s %s %.*s\n", 448 printk("Pid: %d, comm: %.20s %s %s %.*s\n",
406 current->pid, current->comm, print_tainted(), 449 current->pid, current->comm, print_tainted(),
407 init_utsname()->release, 450 init_utsname()->release,
408 (int)strcspn(init_utsname()->version, " "), 451 (int)strcspn(init_utsname()->version, " "),
409 init_utsname()->version); 452 init_utsname()->version);
410 show_trace(NULL, NULL, &dummy); 453 show_trace(NULL, NULL, &dummy, bp);
411} 454}
412 455
413EXPORT_SYMBOL(dump_stack); 456EXPORT_SYMBOL(dump_stack);
@@ -415,12 +458,15 @@ EXPORT_SYMBOL(dump_stack);
415void show_registers(struct pt_regs *regs) 458void show_registers(struct pt_regs *regs)
416{ 459{
417 int i; 460 int i;
418 int in_kernel = !user_mode(regs); 461 unsigned long sp;
419 unsigned long rsp;
420 const int cpu = smp_processor_id(); 462 const int cpu = smp_processor_id();
421 struct task_struct *cur = cpu_pda(cpu)->pcurrent; 463 struct task_struct *cur = cpu_pda(cpu)->pcurrent;
464 u8 *ip;
465 unsigned int code_prologue = code_bytes * 43 / 64;
466 unsigned int code_len = code_bytes;
422 467
423 rsp = regs->rsp; 468 sp = regs->sp;
469 ip = (u8 *) regs->ip - code_prologue;
424 printk("CPU %d ", cpu); 470 printk("CPU %d ", cpu);
425 __show_regs(regs); 471 __show_regs(regs);
426 printk("Process %s (pid: %d, threadinfo %p, task %p)\n", 472 printk("Process %s (pid: %d, threadinfo %p, task %p)\n",
@@ -430,45 +476,43 @@ void show_registers(struct pt_regs *regs)
430 * When in-kernel, we also print out the stack and code at the 476 * When in-kernel, we also print out the stack and code at the
431 * time of the fault.. 477 * time of the fault..
432 */ 478 */
433 if (in_kernel) { 479 if (!user_mode(regs)) {
480 unsigned char c;
434 printk("Stack: "); 481 printk("Stack: ");
435 _show_stack(NULL, regs, (unsigned long*)rsp); 482 _show_stack(NULL, regs, (unsigned long *)sp, regs->bp);
436 483 printk("\n");
437 printk("\nCode: "); 484
438 if (regs->rip < PAGE_OFFSET) 485 printk(KERN_EMERG "Code: ");
439 goto bad; 486 if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) {
440 487 /* try starting at RIP */
441 for (i=0; i<20; i++) { 488 ip = (u8 *) regs->ip;
442 unsigned char c; 489 code_len = code_len - code_prologue + 1;
443 if (__get_user(c, &((unsigned char*)regs->rip)[i])) { 490 }
444bad: 491 for (i = 0; i < code_len; i++, ip++) {
492 if (ip < (u8 *)PAGE_OFFSET ||
493 probe_kernel_address(ip, c)) {
445 printk(" Bad RIP value."); 494 printk(" Bad RIP value.");
446 break; 495 break;
447 } 496 }
448 printk("%02x ", c); 497 if (ip == (u8 *)regs->ip)
498 printk("<%02x> ", c);
499 else
500 printk("%02x ", c);
449 } 501 }
450 } 502 }
451 printk("\n"); 503 printk("\n");
452} 504}
453 505
454int is_valid_bugaddr(unsigned long rip) 506int is_valid_bugaddr(unsigned long ip)
455{ 507{
456 unsigned short ud2; 508 unsigned short ud2;
457 509
458 if (__copy_from_user(&ud2, (const void __user *) rip, sizeof(ud2))) 510 if (__copy_from_user(&ud2, (const void __user *) ip, sizeof(ud2)))
459 return 0; 511 return 0;
460 512
461 return ud2 == 0x0b0f; 513 return ud2 == 0x0b0f;
462} 514}
463 515
464#ifdef CONFIG_BUG
465void out_of_line_bug(void)
466{
467 BUG();
468}
469EXPORT_SYMBOL(out_of_line_bug);
470#endif
471
472static raw_spinlock_t die_lock = __RAW_SPIN_LOCK_UNLOCKED; 516static raw_spinlock_t die_lock = __RAW_SPIN_LOCK_UNLOCKED;
473static int die_owner = -1; 517static int die_owner = -1;
474static unsigned int die_nest_count; 518static unsigned int die_nest_count;
@@ -496,7 +540,7 @@ unsigned __kprobes long oops_begin(void)
496 return flags; 540 return flags;
497} 541}
498 542
499void __kprobes oops_end(unsigned long flags) 543void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr)
500{ 544{
501 die_owner = -1; 545 die_owner = -1;
502 bust_spinlocks(0); 546 bust_spinlocks(0);
@@ -505,12 +549,17 @@ void __kprobes oops_end(unsigned long flags)
505 /* Nest count reaches zero, release the lock. */ 549 /* Nest count reaches zero, release the lock. */
506 __raw_spin_unlock(&die_lock); 550 __raw_spin_unlock(&die_lock);
507 raw_local_irq_restore(flags); 551 raw_local_irq_restore(flags);
552 if (!regs) {
553 oops_exit();
554 return;
555 }
508 if (panic_on_oops) 556 if (panic_on_oops)
509 panic("Fatal exception"); 557 panic("Fatal exception");
510 oops_exit(); 558 oops_exit();
559 do_exit(signr);
511} 560}
512 561
513void __kprobes __die(const char * str, struct pt_regs * regs, long err) 562int __kprobes __die(const char * str, struct pt_regs * regs, long err)
514{ 563{
515 static int die_counter; 564 static int die_counter;
516 printk(KERN_EMERG "%s: %04lx [%u] ", str, err & 0xffff,++die_counter); 565 printk(KERN_EMERG "%s: %04lx [%u] ", str, err & 0xffff,++die_counter);
@@ -524,15 +573,17 @@ void __kprobes __die(const char * str, struct pt_regs * regs, long err)
524 printk("DEBUG_PAGEALLOC"); 573 printk("DEBUG_PAGEALLOC");
525#endif 574#endif
526 printk("\n"); 575 printk("\n");
527 notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, SIGSEGV); 576 if (notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, SIGSEGV) == NOTIFY_STOP)
577 return 1;
528 show_registers(regs); 578 show_registers(regs);
529 add_taint(TAINT_DIE); 579 add_taint(TAINT_DIE);
530 /* Executive summary in case the oops scrolled away */ 580 /* Executive summary in case the oops scrolled away */
531 printk(KERN_ALERT "RIP "); 581 printk(KERN_ALERT "RIP ");
532 printk_address(regs->rip); 582 printk_address(regs->ip, 1);
533 printk(" RSP <%016lx>\n", regs->rsp); 583 printk(" RSP <%016lx>\n", regs->sp);
534 if (kexec_should_crash(current)) 584 if (kexec_should_crash(current))
535 crash_kexec(regs); 585 crash_kexec(regs);
586 return 0;
536} 587}
537 588
538void die(const char * str, struct pt_regs * regs, long err) 589void die(const char * str, struct pt_regs * regs, long err)
@@ -540,11 +591,11 @@ void die(const char * str, struct pt_regs * regs, long err)
540 unsigned long flags = oops_begin(); 591 unsigned long flags = oops_begin();
541 592
542 if (!user_mode(regs)) 593 if (!user_mode(regs))
543 report_bug(regs->rip, regs); 594 report_bug(regs->ip, regs);
544 595
545 __die(str, regs, err); 596 if (__die(str, regs, err))
546 oops_end(flags); 597 regs = NULL;
547 do_exit(SIGSEGV); 598 oops_end(flags, regs, SIGSEGV);
548} 599}
549 600
550void __kprobes die_nmi(char *str, struct pt_regs *regs, int do_panic) 601void __kprobes die_nmi(char *str, struct pt_regs *regs, int do_panic)
@@ -561,10 +612,10 @@ void __kprobes die_nmi(char *str, struct pt_regs *regs, int do_panic)
561 crash_kexec(regs); 612 crash_kexec(regs);
562 if (do_panic || panic_on_oops) 613 if (do_panic || panic_on_oops)
563 panic("Non maskable interrupt"); 614 panic("Non maskable interrupt");
564 oops_end(flags); 615 oops_end(flags, NULL, SIGBUS);
565 nmi_exit(); 616 nmi_exit();
566 local_irq_enable(); 617 local_irq_enable();
567 do_exit(SIGSEGV); 618 do_exit(SIGBUS);
568} 619}
569 620
570static void __kprobes do_trap(int trapnr, int signr, char *str, 621static void __kprobes do_trap(int trapnr, int signr, char *str,
@@ -588,11 +639,14 @@ static void __kprobes do_trap(int trapnr, int signr, char *str,
588 tsk->thread.trap_no = trapnr; 639 tsk->thread.trap_no = trapnr;
589 640
590 if (show_unhandled_signals && unhandled_signal(tsk, signr) && 641 if (show_unhandled_signals && unhandled_signal(tsk, signr) &&
591 printk_ratelimit()) 642 printk_ratelimit()) {
592 printk(KERN_INFO 643 printk(KERN_INFO
593 "%s[%d] trap %s rip:%lx rsp:%lx error:%lx\n", 644 "%s[%d] trap %s ip:%lx sp:%lx error:%lx",
594 tsk->comm, tsk->pid, str, 645 tsk->comm, tsk->pid, str,
595 regs->rip, regs->rsp, error_code); 646 regs->ip, regs->sp, error_code);
647 print_vma_addr(" in ", regs->ip);
648 printk("\n");
649 }
596 650
597 if (info) 651 if (info)
598 force_sig_info(signr, info, tsk); 652 force_sig_info(signr, info, tsk);
@@ -602,19 +656,12 @@ static void __kprobes do_trap(int trapnr, int signr, char *str,
602 } 656 }
603 657
604 658
605 /* kernel trap */ 659 if (!fixup_exception(regs)) {
606 { 660 tsk->thread.error_code = error_code;
607 const struct exception_table_entry *fixup; 661 tsk->thread.trap_no = trapnr;
608 fixup = search_exception_tables(regs->rip); 662 die(str, regs, error_code);
609 if (fixup)
610 regs->rip = fixup->fixup;
611 else {
612 tsk->thread.error_code = error_code;
613 tsk->thread.trap_no = trapnr;
614 die(str, regs, error_code);
615 }
616 return;
617 } 663 }
664 return;
618} 665}
619 666
620#define DO_ERROR(trapnr, signr, str, name) \ 667#define DO_ERROR(trapnr, signr, str, name) \
@@ -643,10 +690,10 @@ asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
643 do_trap(trapnr, signr, str, regs, error_code, &info); \ 690 do_trap(trapnr, signr, str, regs, error_code, &info); \
644} 691}
645 692
646DO_ERROR_INFO( 0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->rip) 693DO_ERROR_INFO( 0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->ip)
647DO_ERROR( 4, SIGSEGV, "overflow", overflow) 694DO_ERROR( 4, SIGSEGV, "overflow", overflow)
648DO_ERROR( 5, SIGSEGV, "bounds", bounds) 695DO_ERROR( 5, SIGSEGV, "bounds", bounds)
649DO_ERROR_INFO( 6, SIGILL, "invalid opcode", invalid_op, ILL_ILLOPN, regs->rip) 696DO_ERROR_INFO( 6, SIGILL, "invalid opcode", invalid_op, ILL_ILLOPN, regs->ip)
650DO_ERROR( 7, SIGSEGV, "device not available", device_not_available) 697DO_ERROR( 7, SIGSEGV, "device not available", device_not_available)
651DO_ERROR( 9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun) 698DO_ERROR( 9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun)
652DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS) 699DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS)
@@ -694,32 +741,28 @@ asmlinkage void __kprobes do_general_protection(struct pt_regs * regs,
694 tsk->thread.trap_no = 13; 741 tsk->thread.trap_no = 13;
695 742
696 if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && 743 if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
697 printk_ratelimit()) 744 printk_ratelimit()) {
698 printk(KERN_INFO 745 printk(KERN_INFO
699 "%s[%d] general protection rip:%lx rsp:%lx error:%lx\n", 746 "%s[%d] general protection ip:%lx sp:%lx error:%lx",
700 tsk->comm, tsk->pid, 747 tsk->comm, tsk->pid,
701 regs->rip, regs->rsp, error_code); 748 regs->ip, regs->sp, error_code);
749 print_vma_addr(" in ", regs->ip);
750 printk("\n");
751 }
702 752
703 force_sig(SIGSEGV, tsk); 753 force_sig(SIGSEGV, tsk);
704 return; 754 return;
705 } 755 }
706 756
707 /* kernel gp */ 757 if (fixup_exception(regs))
708 { 758 return;
709 const struct exception_table_entry *fixup;
710 fixup = search_exception_tables(regs->rip);
711 if (fixup) {
712 regs->rip = fixup->fixup;
713 return;
714 }
715 759
716 tsk->thread.error_code = error_code; 760 tsk->thread.error_code = error_code;
717 tsk->thread.trap_no = 13; 761 tsk->thread.trap_no = 13;
718 if (notify_die(DIE_GPF, "general protection fault", regs, 762 if (notify_die(DIE_GPF, "general protection fault", regs,
719 error_code, 13, SIGSEGV) == NOTIFY_STOP) 763 error_code, 13, SIGSEGV) == NOTIFY_STOP)
720 return; 764 return;
721 die("general protection fault", regs, error_code); 765 die("general protection fault", regs, error_code);
722 }
723} 766}
724 767
725static __kprobes void 768static __kprobes void
@@ -832,15 +875,15 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs)
832{ 875{
833 struct pt_regs *regs = eregs; 876 struct pt_regs *regs = eregs;
834 /* Did already sync */ 877 /* Did already sync */
835 if (eregs == (struct pt_regs *)eregs->rsp) 878 if (eregs == (struct pt_regs *)eregs->sp)
836 ; 879 ;
837 /* Exception from user space */ 880 /* Exception from user space */
838 else if (user_mode(eregs)) 881 else if (user_mode(eregs))
839 regs = task_pt_regs(current); 882 regs = task_pt_regs(current);
840 /* Exception from kernel and interrupts are enabled. Move to 883 /* Exception from kernel and interrupts are enabled. Move to
841 kernel process stack. */ 884 kernel process stack. */
842 else if (eregs->eflags & X86_EFLAGS_IF) 885 else if (eregs->flags & X86_EFLAGS_IF)
843 regs = (struct pt_regs *)(eregs->rsp -= sizeof(struct pt_regs)); 886 regs = (struct pt_regs *)(eregs->sp -= sizeof(struct pt_regs));
844 if (eregs != regs) 887 if (eregs != regs)
845 *regs = *eregs; 888 *regs = *eregs;
846 return regs; 889 return regs;
@@ -858,6 +901,12 @@ asmlinkage void __kprobes do_debug(struct pt_regs * regs,
858 901
859 get_debugreg(condition, 6); 902 get_debugreg(condition, 6);
860 903
904 /*
905 * The processor cleared BTF, so don't mark that we need it set.
906 */
907 clear_tsk_thread_flag(tsk, TIF_DEBUGCTLMSR);
908 tsk->thread.debugctlmsr = 0;
909
861 if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code, 910 if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,
862 SIGTRAP) == NOTIFY_STOP) 911 SIGTRAP) == NOTIFY_STOP)
863 return; 912 return;
@@ -873,27 +922,14 @@ asmlinkage void __kprobes do_debug(struct pt_regs * regs,
873 922
874 tsk->thread.debugreg6 = condition; 923 tsk->thread.debugreg6 = condition;
875 924
876 /* Mask out spurious TF errors due to lazy TF clearing */ 925
926 /*
927 * Single-stepping through TF: make sure we ignore any events in
928 * kernel space (but re-enable TF when returning to user mode).
929 */
877 if (condition & DR_STEP) { 930 if (condition & DR_STEP) {
878 /*
879 * The TF error should be masked out only if the current
880 * process is not traced and if the TRAP flag has been set
881 * previously by a tracing process (condition detected by
882 * the PT_DTRACE flag); remember that the i386 TRAP flag
883 * can be modified by the process itself in user mode,
884 * allowing programs to debug themselves without the ptrace()
885 * interface.
886 */
887 if (!user_mode(regs)) 931 if (!user_mode(regs))
888 goto clear_TF_reenable; 932 goto clear_TF_reenable;
889 /*
890 * Was the TF flag set by a debugger? If so, clear it now,
891 * so that register information is correct.
892 */
893 if (tsk->ptrace & PT_DTRACE) {
894 regs->eflags &= ~TF_MASK;
895 tsk->ptrace &= ~PT_DTRACE;
896 }
897 } 933 }
898 934
899 /* Ok, finally something we can handle */ 935 /* Ok, finally something we can handle */
@@ -902,7 +938,7 @@ asmlinkage void __kprobes do_debug(struct pt_regs * regs,
902 info.si_signo = SIGTRAP; 938 info.si_signo = SIGTRAP;
903 info.si_errno = 0; 939 info.si_errno = 0;
904 info.si_code = TRAP_BRKPT; 940 info.si_code = TRAP_BRKPT;
905 info.si_addr = user_mode(regs) ? (void __user *)regs->rip : NULL; 941 info.si_addr = user_mode(regs) ? (void __user *)regs->ip : NULL;
906 force_sig_info(SIGTRAP, &info, tsk); 942 force_sig_info(SIGTRAP, &info, tsk);
907 943
908clear_dr7: 944clear_dr7:
@@ -912,18 +948,15 @@ clear_dr7:
912 948
913clear_TF_reenable: 949clear_TF_reenable:
914 set_tsk_thread_flag(tsk, TIF_SINGLESTEP); 950 set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
915 regs->eflags &= ~TF_MASK; 951 regs->flags &= ~X86_EFLAGS_TF;
916 preempt_conditional_cli(regs); 952 preempt_conditional_cli(regs);
917} 953}
918 954
919static int kernel_math_error(struct pt_regs *regs, const char *str, int trapnr) 955static int kernel_math_error(struct pt_regs *regs, const char *str, int trapnr)
920{ 956{
921 const struct exception_table_entry *fixup; 957 if (fixup_exception(regs))
922 fixup = search_exception_tables(regs->rip);
923 if (fixup) {
924 regs->rip = fixup->fixup;
925 return 1; 958 return 1;
926 } 959
927 notify_die(DIE_GPF, str, regs, 0, trapnr, SIGFPE); 960 notify_die(DIE_GPF, str, regs, 0, trapnr, SIGFPE);
928 /* Illegal floating point operation in the kernel */ 961 /* Illegal floating point operation in the kernel */
929 current->thread.trap_no = trapnr; 962 current->thread.trap_no = trapnr;
@@ -938,7 +971,7 @@ static int kernel_math_error(struct pt_regs *regs, const char *str, int trapnr)
938 */ 971 */
939asmlinkage void do_coprocessor_error(struct pt_regs *regs) 972asmlinkage void do_coprocessor_error(struct pt_regs *regs)
940{ 973{
941 void __user *rip = (void __user *)(regs->rip); 974 void __user *ip = (void __user *)(regs->ip);
942 struct task_struct * task; 975 struct task_struct * task;
943 siginfo_t info; 976 siginfo_t info;
944 unsigned short cwd, swd; 977 unsigned short cwd, swd;
@@ -958,7 +991,7 @@ asmlinkage void do_coprocessor_error(struct pt_regs *regs)
958 info.si_signo = SIGFPE; 991 info.si_signo = SIGFPE;
959 info.si_errno = 0; 992 info.si_errno = 0;
960 info.si_code = __SI_FAULT; 993 info.si_code = __SI_FAULT;
961 info.si_addr = rip; 994 info.si_addr = ip;
962 /* 995 /*
963 * (~cwd & swd) will mask out exceptions that are not set to unmasked 996 * (~cwd & swd) will mask out exceptions that are not set to unmasked
964 * status. 0x3f is the exception bits in these regs, 0x200 is the 997 * status. 0x3f is the exception bits in these regs, 0x200 is the
@@ -1007,7 +1040,7 @@ asmlinkage void bad_intr(void)
1007 1040
1008asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs) 1041asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs)
1009{ 1042{
1010 void __user *rip = (void __user *)(regs->rip); 1043 void __user *ip = (void __user *)(regs->ip);
1011 struct task_struct * task; 1044 struct task_struct * task;
1012 siginfo_t info; 1045 siginfo_t info;
1013 unsigned short mxcsr; 1046 unsigned short mxcsr;
@@ -1027,7 +1060,7 @@ asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs)
1027 info.si_signo = SIGFPE; 1060 info.si_signo = SIGFPE;
1028 info.si_errno = 0; 1061 info.si_errno = 0;
1029 info.si_code = __SI_FAULT; 1062 info.si_code = __SI_FAULT;
1030 info.si_addr = rip; 1063 info.si_addr = ip;
1031 /* 1064 /*
1032 * The SIMD FPU exceptions are handled a little differently, as there 1065 * The SIMD FPU exceptions are handled a little differently, as there
1033 * is only a single status/control register. Thus, to determine which 1066 * is only a single status/control register. Thus, to determine which
@@ -1089,6 +1122,7 @@ asmlinkage void math_state_restore(void)
1089 task_thread_info(me)->status |= TS_USEDFPU; 1122 task_thread_info(me)->status |= TS_USEDFPU;
1090 me->fpu_counter++; 1123 me->fpu_counter++;
1091} 1124}
1125EXPORT_SYMBOL_GPL(math_state_restore);
1092 1126
1093void __init trap_init(void) 1127void __init trap_init(void)
1094{ 1128{
@@ -1144,3 +1178,14 @@ static int __init kstack_setup(char *s)
1144 return 0; 1178 return 0;
1145} 1179}
1146early_param("kstack", kstack_setup); 1180early_param("kstack", kstack_setup);
1181
1182
1183static int __init code_bytes_setup(char *s)
1184{
1185 code_bytes = simple_strtoul(s, NULL, 0);
1186 if (code_bytes > 8192)
1187 code_bytes = 8192;
1188
1189 return 1;
1190}
1191__setup("code_bytes=", code_bytes_setup);
diff --git a/arch/x86/kernel/tsc_32.c b/arch/x86/kernel/tsc_32.c
index 9ebc0dab66b4..43517e324be8 100644
--- a/arch/x86/kernel/tsc_32.c
+++ b/arch/x86/kernel/tsc_32.c
@@ -5,6 +5,7 @@
5#include <linux/jiffies.h> 5#include <linux/jiffies.h>
6#include <linux/init.h> 6#include <linux/init.h>
7#include <linux/dmi.h> 7#include <linux/dmi.h>
8#include <linux/percpu.h>
8 9
9#include <asm/delay.h> 10#include <asm/delay.h>
10#include <asm/tsc.h> 11#include <asm/tsc.h>
@@ -23,8 +24,6 @@ static int tsc_enabled;
23unsigned int tsc_khz; 24unsigned int tsc_khz;
24EXPORT_SYMBOL_GPL(tsc_khz); 25EXPORT_SYMBOL_GPL(tsc_khz);
25 26
26int tsc_disable;
27
28#ifdef CONFIG_X86_TSC 27#ifdef CONFIG_X86_TSC
29static int __init tsc_setup(char *str) 28static int __init tsc_setup(char *str)
30{ 29{
@@ -39,8 +38,7 @@ static int __init tsc_setup(char *str)
39 */ 38 */
40static int __init tsc_setup(char *str) 39static int __init tsc_setup(char *str)
41{ 40{
42 tsc_disable = 1; 41 setup_clear_cpu_cap(X86_FEATURE_TSC);
43
44 return 1; 42 return 1;
45} 43}
46#endif 44#endif
@@ -80,13 +78,31 @@ EXPORT_SYMBOL_GPL(check_tsc_unstable);
80 * 78 *
81 * -johnstul@us.ibm.com "math is hard, lets go shopping!" 79 * -johnstul@us.ibm.com "math is hard, lets go shopping!"
82 */ 80 */
83unsigned long cyc2ns_scale __read_mostly;
84 81
85#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */ 82DEFINE_PER_CPU(unsigned long, cyc2ns);
86 83
87static inline void set_cyc2ns_scale(unsigned long cpu_khz) 84static void set_cyc2ns_scale(unsigned long cpu_khz, int cpu)
88{ 85{
89 cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR)/cpu_khz; 86 unsigned long flags, prev_scale, *scale;
87 unsigned long long tsc_now, ns_now;
88
89 local_irq_save(flags);
90 sched_clock_idle_sleep_event();
91
92 scale = &per_cpu(cyc2ns, cpu);
93
94 rdtscll(tsc_now);
95 ns_now = __cycles_2_ns(tsc_now);
96
97 prev_scale = *scale;
98 if (cpu_khz)
99 *scale = (NSEC_PER_MSEC << CYC2NS_SCALE_FACTOR)/cpu_khz;
100
101 /*
102 * Start smoothly with the new frequency:
103 */
104 sched_clock_idle_wakeup_event(0);
105 local_irq_restore(flags);
90} 106}
91 107
92/* 108/*
@@ -239,7 +255,9 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data)
239 ref_freq, freq->new); 255 ref_freq, freq->new);
240 if (!(freq->flags & CPUFREQ_CONST_LOOPS)) { 256 if (!(freq->flags & CPUFREQ_CONST_LOOPS)) {
241 tsc_khz = cpu_khz; 257 tsc_khz = cpu_khz;
242 set_cyc2ns_scale(cpu_khz); 258 preempt_disable();
259 set_cyc2ns_scale(cpu_khz, smp_processor_id());
260 preempt_enable();
243 /* 261 /*
244 * TSC based sched_clock turns 262 * TSC based sched_clock turns
245 * to junk w/ cpufreq 263 * to junk w/ cpufreq
@@ -333,6 +351,11 @@ __cpuinit int unsynchronized_tsc(void)
333{ 351{
334 if (!cpu_has_tsc || tsc_unstable) 352 if (!cpu_has_tsc || tsc_unstable)
335 return 1; 353 return 1;
354
355 /* Anything with constant TSC should be synchronized */
356 if (boot_cpu_has(X86_FEATURE_CONSTANT_TSC))
357 return 0;
358
336 /* 359 /*
337 * Intel systems are normally all synchronized. 360 * Intel systems are normally all synchronized.
338 * Exceptions must mark TSC as unstable: 361 * Exceptions must mark TSC as unstable:
@@ -367,7 +390,9 @@ static inline void check_geode_tsc_reliable(void) { }
367 390
368void __init tsc_init(void) 391void __init tsc_init(void)
369{ 392{
370 if (!cpu_has_tsc || tsc_disable) 393 int cpu;
394
395 if (!cpu_has_tsc)
371 goto out_no_tsc; 396 goto out_no_tsc;
372 397
373 cpu_khz = calculate_cpu_khz(); 398 cpu_khz = calculate_cpu_khz();
@@ -380,7 +405,15 @@ void __init tsc_init(void)
380 (unsigned long)cpu_khz / 1000, 405 (unsigned long)cpu_khz / 1000,
381 (unsigned long)cpu_khz % 1000); 406 (unsigned long)cpu_khz % 1000);
382 407
383 set_cyc2ns_scale(cpu_khz); 408 /*
409 * Secondary CPUs do not run through tsc_init(), so set up
410 * all the scale factors for all CPUs, assuming the same
411 * speed as the bootup CPU. (cpufreq notifiers will fix this
412 * up if their speed diverges)
413 */
414 for_each_possible_cpu(cpu)
415 set_cyc2ns_scale(cpu_khz, cpu);
416
384 use_tsc_delay(); 417 use_tsc_delay();
385 418
386 /* Check and install the TSC clocksource */ 419 /* Check and install the TSC clocksource */
@@ -403,10 +436,5 @@ void __init tsc_init(void)
403 return; 436 return;
404 437
405out_no_tsc: 438out_no_tsc:
406 /* 439 setup_clear_cpu_cap(X86_FEATURE_TSC);
407 * Set the tsc_disable flag if there's no TSC support, this
408 * makes it a fast flag for the kernel to see whether it
409 * should be using the TSC.
410 */
411 tsc_disable = 1;
412} 440}
diff --git a/arch/x86/kernel/tsc_64.c b/arch/x86/kernel/tsc_64.c
index 9c70af45b42b..947554ddabb6 100644
--- a/arch/x86/kernel/tsc_64.c
+++ b/arch/x86/kernel/tsc_64.c
@@ -10,6 +10,7 @@
10 10
11#include <asm/hpet.h> 11#include <asm/hpet.h>
12#include <asm/timex.h> 12#include <asm/timex.h>
13#include <asm/timer.h>
13 14
14static int notsc __initdata = 0; 15static int notsc __initdata = 0;
15 16
@@ -18,19 +19,51 @@ EXPORT_SYMBOL(cpu_khz);
18unsigned int tsc_khz; 19unsigned int tsc_khz;
19EXPORT_SYMBOL(tsc_khz); 20EXPORT_SYMBOL(tsc_khz);
20 21
21static unsigned int cyc2ns_scale __read_mostly; 22/* Accelerators for sched_clock()
23 * convert from cycles(64bits) => nanoseconds (64bits)
24 * basic equation:
25 * ns = cycles / (freq / ns_per_sec)
26 * ns = cycles * (ns_per_sec / freq)
27 * ns = cycles * (10^9 / (cpu_khz * 10^3))
28 * ns = cycles * (10^6 / cpu_khz)
29 *
30 * Then we use scaling math (suggested by george@mvista.com) to get:
31 * ns = cycles * (10^6 * SC / cpu_khz) / SC
32 * ns = cycles * cyc2ns_scale / SC
33 *
34 * And since SC is a constant power of two, we can convert the div
35 * into a shift.
36 *
37 * We can use khz divisor instead of mhz to keep a better precision, since
38 * cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits.
39 * (mathieu.desnoyers@polymtl.ca)
40 *
41 * -johnstul@us.ibm.com "math is hard, lets go shopping!"
42 */
43DEFINE_PER_CPU(unsigned long, cyc2ns);
22 44
23static inline void set_cyc2ns_scale(unsigned long khz) 45static void set_cyc2ns_scale(unsigned long cpu_khz, int cpu)
24{ 46{
25 cyc2ns_scale = (NSEC_PER_MSEC << NS_SCALE) / khz; 47 unsigned long flags, prev_scale, *scale;
26} 48 unsigned long long tsc_now, ns_now;
27 49
28static unsigned long long cycles_2_ns(unsigned long long cyc) 50 local_irq_save(flags);
29{ 51 sched_clock_idle_sleep_event();
30 return (cyc * cyc2ns_scale) >> NS_SCALE; 52
53 scale = &per_cpu(cyc2ns, cpu);
54
55 rdtscll(tsc_now);
56 ns_now = __cycles_2_ns(tsc_now);
57
58 prev_scale = *scale;
59 if (cpu_khz)
60 *scale = (NSEC_PER_MSEC << CYC2NS_SCALE_FACTOR)/cpu_khz;
61
62 sched_clock_idle_wakeup_event(0);
63 local_irq_restore(flags);
31} 64}
32 65
33unsigned long long sched_clock(void) 66unsigned long long native_sched_clock(void)
34{ 67{
35 unsigned long a = 0; 68 unsigned long a = 0;
36 69
@@ -44,12 +77,27 @@ unsigned long long sched_clock(void)
44 return cycles_2_ns(a); 77 return cycles_2_ns(a);
45} 78}
46 79
80/* We need to define a real function for sched_clock, to override the
81 weak default version */
82#ifdef CONFIG_PARAVIRT
83unsigned long long sched_clock(void)
84{
85 return paravirt_sched_clock();
86}
87#else
88unsigned long long
89sched_clock(void) __attribute__((alias("native_sched_clock")));
90#endif
91
92
47static int tsc_unstable; 93static int tsc_unstable;
48 94
49inline int check_tsc_unstable(void) 95int check_tsc_unstable(void)
50{ 96{
51 return tsc_unstable; 97 return tsc_unstable;
52} 98}
99EXPORT_SYMBOL_GPL(check_tsc_unstable);
100
53#ifdef CONFIG_CPU_FREQ 101#ifdef CONFIG_CPU_FREQ
54 102
55/* Frequency scaling support. Adjust the TSC based timer when the cpu frequency 103/* Frequency scaling support. Adjust the TSC based timer when the cpu frequency
@@ -100,7 +148,9 @@ static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
100 mark_tsc_unstable("cpufreq changes"); 148 mark_tsc_unstable("cpufreq changes");
101 } 149 }
102 150
103 set_cyc2ns_scale(tsc_khz_ref); 151 preempt_disable();
152 set_cyc2ns_scale(tsc_khz_ref, smp_processor_id());
153 preempt_enable();
104 154
105 return 0; 155 return 0;
106} 156}
@@ -133,12 +183,12 @@ static unsigned long __init tsc_read_refs(unsigned long *pm,
133 int i; 183 int i;
134 184
135 for (i = 0; i < MAX_RETRIES; i++) { 185 for (i = 0; i < MAX_RETRIES; i++) {
136 t1 = get_cycles_sync(); 186 t1 = get_cycles();
137 if (hpet) 187 if (hpet)
138 *hpet = hpet_readl(HPET_COUNTER) & 0xFFFFFFFF; 188 *hpet = hpet_readl(HPET_COUNTER) & 0xFFFFFFFF;
139 else 189 else
140 *pm = acpi_pm_read_early(); 190 *pm = acpi_pm_read_early();
141 t2 = get_cycles_sync(); 191 t2 = get_cycles();
142 if ((t2 - t1) < SMI_TRESHOLD) 192 if ((t2 - t1) < SMI_TRESHOLD)
143 return t2; 193 return t2;
144 } 194 }
@@ -151,7 +201,7 @@ static unsigned long __init tsc_read_refs(unsigned long *pm,
151void __init tsc_calibrate(void) 201void __init tsc_calibrate(void)
152{ 202{
153 unsigned long flags, tsc1, tsc2, tr1, tr2, pm1, pm2, hpet1, hpet2; 203 unsigned long flags, tsc1, tsc2, tr1, tr2, pm1, pm2, hpet1, hpet2;
154 int hpet = is_hpet_enabled(); 204 int hpet = is_hpet_enabled(), cpu;
155 205
156 local_irq_save(flags); 206 local_irq_save(flags);
157 207
@@ -162,9 +212,9 @@ void __init tsc_calibrate(void)
162 outb(0xb0, 0x43); 212 outb(0xb0, 0x43);
163 outb((CLOCK_TICK_RATE / (1000 / 50)) & 0xff, 0x42); 213 outb((CLOCK_TICK_RATE / (1000 / 50)) & 0xff, 0x42);
164 outb((CLOCK_TICK_RATE / (1000 / 50)) >> 8, 0x42); 214 outb((CLOCK_TICK_RATE / (1000 / 50)) >> 8, 0x42);
165 tr1 = get_cycles_sync(); 215 tr1 = get_cycles();
166 while ((inb(0x61) & 0x20) == 0); 216 while ((inb(0x61) & 0x20) == 0);
167 tr2 = get_cycles_sync(); 217 tr2 = get_cycles();
168 218
169 tsc2 = tsc_read_refs(&pm2, hpet ? &hpet2 : NULL); 219 tsc2 = tsc_read_refs(&pm2, hpet ? &hpet2 : NULL);
170 220
@@ -206,7 +256,9 @@ void __init tsc_calibrate(void)
206 } 256 }
207 257
208 tsc_khz = tsc2 / tsc1; 258 tsc_khz = tsc2 / tsc1;
209 set_cyc2ns_scale(tsc_khz); 259
260 for_each_possible_cpu(cpu)
261 set_cyc2ns_scale(tsc_khz, cpu);
210} 262}
211 263
212/* 264/*
@@ -222,17 +274,9 @@ __cpuinit int unsynchronized_tsc(void)
222 if (apic_is_clustered_box()) 274 if (apic_is_clustered_box())
223 return 1; 275 return 1;
224#endif 276#endif
225 /* Most intel systems have synchronized TSCs except for 277
226 multi node systems */ 278 if (boot_cpu_has(X86_FEATURE_CONSTANT_TSC))
227 if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) {
228#ifdef CONFIG_ACPI
229 /* But TSC doesn't tick in C3 so don't use it there */
230 if (acpi_gbl_FADT.header.length > 0 &&
231 acpi_gbl_FADT.C3latency < 1000)
232 return 1;
233#endif
234 return 0; 279 return 0;
235 }
236 280
237 /* Assume multi socket systems are not synchronized */ 281 /* Assume multi socket systems are not synchronized */
238 return num_present_cpus() > 1; 282 return num_present_cpus() > 1;
@@ -250,13 +294,13 @@ __setup("notsc", notsc_setup);
250/* clock source code: */ 294/* clock source code: */
251static cycle_t read_tsc(void) 295static cycle_t read_tsc(void)
252{ 296{
253 cycle_t ret = (cycle_t)get_cycles_sync(); 297 cycle_t ret = (cycle_t)get_cycles();
254 return ret; 298 return ret;
255} 299}
256 300
257static cycle_t __vsyscall_fn vread_tsc(void) 301static cycle_t __vsyscall_fn vread_tsc(void)
258{ 302{
259 cycle_t ret = (cycle_t)get_cycles_sync(); 303 cycle_t ret = (cycle_t)vget_cycles();
260 return ret; 304 return ret;
261} 305}
262 306
diff --git a/arch/x86/kernel/tsc_sync.c b/arch/x86/kernel/tsc_sync.c
index 9125efe66a06..0577825cf89b 100644
--- a/arch/x86/kernel/tsc_sync.c
+++ b/arch/x86/kernel/tsc_sync.c
@@ -46,7 +46,7 @@ static __cpuinit void check_tsc_warp(void)
46 cycles_t start, now, prev, end; 46 cycles_t start, now, prev, end;
47 int i; 47 int i;
48 48
49 start = get_cycles_sync(); 49 start = get_cycles();
50 /* 50 /*
51 * The measurement runs for 20 msecs: 51 * The measurement runs for 20 msecs:
52 */ 52 */
@@ -61,18 +61,18 @@ static __cpuinit void check_tsc_warp(void)
61 */ 61 */
62 __raw_spin_lock(&sync_lock); 62 __raw_spin_lock(&sync_lock);
63 prev = last_tsc; 63 prev = last_tsc;
64 now = get_cycles_sync(); 64 now = get_cycles();
65 last_tsc = now; 65 last_tsc = now;
66 __raw_spin_unlock(&sync_lock); 66 __raw_spin_unlock(&sync_lock);
67 67
68 /* 68 /*
69 * Be nice every now and then (and also check whether 69 * Be nice every now and then (and also check whether
70 * measurement is done [we also insert a 100 million 70 * measurement is done [we also insert a 10 million
71 * loops safety exit, so we dont lock up in case the 71 * loops safety exit, so we dont lock up in case the
72 * TSC readout is totally broken]): 72 * TSC readout is totally broken]):
73 */ 73 */
74 if (unlikely(!(i & 7))) { 74 if (unlikely(!(i & 7))) {
75 if (now > end || i > 100000000) 75 if (now > end || i > 10000000)
76 break; 76 break;
77 cpu_relax(); 77 cpu_relax();
78 touch_nmi_watchdog(); 78 touch_nmi_watchdog();
@@ -87,7 +87,11 @@ static __cpuinit void check_tsc_warp(void)
87 nr_warps++; 87 nr_warps++;
88 __raw_spin_unlock(&sync_lock); 88 __raw_spin_unlock(&sync_lock);
89 } 89 }
90 90 }
91 if (!(now-start)) {
92 printk("Warning: zero tsc calibration delta: %Ld [max: %Ld]\n",
93 now-start, end-start);
94 WARN_ON(1);
91 } 95 }
92} 96}
93 97
@@ -129,24 +133,24 @@ void __cpuinit check_tsc_sync_source(int cpu)
129 while (atomic_read(&stop_count) != cpus-1) 133 while (atomic_read(&stop_count) != cpus-1)
130 cpu_relax(); 134 cpu_relax();
131 135
132 /*
133 * Reset it - just in case we boot another CPU later:
134 */
135 atomic_set(&start_count, 0);
136
137 if (nr_warps) { 136 if (nr_warps) {
138 printk("\n"); 137 printk("\n");
139 printk(KERN_WARNING "Measured %Ld cycles TSC warp between CPUs," 138 printk(KERN_WARNING "Measured %Ld cycles TSC warp between CPUs,"
140 " turning off TSC clock.\n", max_warp); 139 " turning off TSC clock.\n", max_warp);
141 mark_tsc_unstable("check_tsc_sync_source failed"); 140 mark_tsc_unstable("check_tsc_sync_source failed");
142 nr_warps = 0;
143 max_warp = 0;
144 last_tsc = 0;
145 } else { 141 } else {
146 printk(" passed.\n"); 142 printk(" passed.\n");
147 } 143 }
148 144
149 /* 145 /*
146 * Reset it - just in case we boot another CPU later:
147 */
148 atomic_set(&start_count, 0);
149 nr_warps = 0;
150 max_warp = 0;
151 last_tsc = 0;
152
153 /*
150 * Let the target continue with the bootup: 154 * Let the target continue with the bootup:
151 */ 155 */
152 atomic_inc(&stop_count); 156 atomic_inc(&stop_count);
diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c
index 157e4bedd3c5..738c2104df30 100644
--- a/arch/x86/kernel/vm86_32.c
+++ b/arch/x86/kernel/vm86_32.c
@@ -70,10 +70,10 @@
70/* 70/*
71 * 8- and 16-bit register defines.. 71 * 8- and 16-bit register defines..
72 */ 72 */
73#define AL(regs) (((unsigned char *)&((regs)->pt.eax))[0]) 73#define AL(regs) (((unsigned char *)&((regs)->pt.ax))[0])
74#define AH(regs) (((unsigned char *)&((regs)->pt.eax))[1]) 74#define AH(regs) (((unsigned char *)&((regs)->pt.ax))[1])
75#define IP(regs) (*(unsigned short *)&((regs)->pt.eip)) 75#define IP(regs) (*(unsigned short *)&((regs)->pt.ip))
76#define SP(regs) (*(unsigned short *)&((regs)->pt.esp)) 76#define SP(regs) (*(unsigned short *)&((regs)->pt.sp))
77 77
78/* 78/*
79 * virtual flags (16 and 32-bit versions) 79 * virtual flags (16 and 32-bit versions)
@@ -93,12 +93,12 @@ static int copy_vm86_regs_to_user(struct vm86_regs __user *user,
93{ 93{
94 int ret = 0; 94 int ret = 0;
95 95
96 /* kernel_vm86_regs is missing xgs, so copy everything up to 96 /* kernel_vm86_regs is missing gs, so copy everything up to
97 (but not including) orig_eax, and then rest including orig_eax. */ 97 (but not including) orig_eax, and then rest including orig_eax. */
98 ret += copy_to_user(user, regs, offsetof(struct kernel_vm86_regs, pt.orig_eax)); 98 ret += copy_to_user(user, regs, offsetof(struct kernel_vm86_regs, pt.orig_ax));
99 ret += copy_to_user(&user->orig_eax, &regs->pt.orig_eax, 99 ret += copy_to_user(&user->orig_eax, &regs->pt.orig_ax,
100 sizeof(struct kernel_vm86_regs) - 100 sizeof(struct kernel_vm86_regs) -
101 offsetof(struct kernel_vm86_regs, pt.orig_eax)); 101 offsetof(struct kernel_vm86_regs, pt.orig_ax));
102 102
103 return ret; 103 return ret;
104} 104}
@@ -110,18 +110,17 @@ static int copy_vm86_regs_from_user(struct kernel_vm86_regs *regs,
110{ 110{
111 int ret = 0; 111 int ret = 0;
112 112
113 /* copy eax-xfs inclusive */ 113 /* copy ax-fs inclusive */
114 ret += copy_from_user(regs, user, offsetof(struct kernel_vm86_regs, pt.orig_eax)); 114 ret += copy_from_user(regs, user, offsetof(struct kernel_vm86_regs, pt.orig_ax));
115 /* copy orig_eax-__gsh+extra */ 115 /* copy orig_ax-__gsh+extra */
116 ret += copy_from_user(&regs->pt.orig_eax, &user->orig_eax, 116 ret += copy_from_user(&regs->pt.orig_ax, &user->orig_eax,
117 sizeof(struct kernel_vm86_regs) - 117 sizeof(struct kernel_vm86_regs) -
118 offsetof(struct kernel_vm86_regs, pt.orig_eax) + 118 offsetof(struct kernel_vm86_regs, pt.orig_ax) +
119 extra); 119 extra);
120 return ret; 120 return ret;
121} 121}
122 122
123struct pt_regs * FASTCALL(save_v86_state(struct kernel_vm86_regs * regs)); 123struct pt_regs * save_v86_state(struct kernel_vm86_regs * regs)
124struct pt_regs * fastcall save_v86_state(struct kernel_vm86_regs * regs)
125{ 124{
126 struct tss_struct *tss; 125 struct tss_struct *tss;
127 struct pt_regs *ret; 126 struct pt_regs *ret;
@@ -138,7 +137,7 @@ struct pt_regs * fastcall save_v86_state(struct kernel_vm86_regs * regs)
138 printk("no vm86_info: BAD\n"); 137 printk("no vm86_info: BAD\n");
139 do_exit(SIGSEGV); 138 do_exit(SIGSEGV);
140 } 139 }
141 set_flags(regs->pt.eflags, VEFLAGS, VIF_MASK | current->thread.v86mask); 140 set_flags(regs->pt.flags, VEFLAGS, VIF_MASK | current->thread.v86mask);
142 tmp = copy_vm86_regs_to_user(&current->thread.vm86_info->regs,regs); 141 tmp = copy_vm86_regs_to_user(&current->thread.vm86_info->regs,regs);
143 tmp += put_user(current->thread.screen_bitmap,&current->thread.vm86_info->screen_bitmap); 142 tmp += put_user(current->thread.screen_bitmap,&current->thread.vm86_info->screen_bitmap);
144 if (tmp) { 143 if (tmp) {
@@ -147,15 +146,15 @@ struct pt_regs * fastcall save_v86_state(struct kernel_vm86_regs * regs)
147 } 146 }
148 147
149 tss = &per_cpu(init_tss, get_cpu()); 148 tss = &per_cpu(init_tss, get_cpu());
150 current->thread.esp0 = current->thread.saved_esp0; 149 current->thread.sp0 = current->thread.saved_sp0;
151 current->thread.sysenter_cs = __KERNEL_CS; 150 current->thread.sysenter_cs = __KERNEL_CS;
152 load_esp0(tss, &current->thread); 151 load_sp0(tss, &current->thread);
153 current->thread.saved_esp0 = 0; 152 current->thread.saved_sp0 = 0;
154 put_cpu(); 153 put_cpu();
155 154
156 ret = KVM86->regs32; 155 ret = KVM86->regs32;
157 156
158 ret->xfs = current->thread.saved_fs; 157 ret->fs = current->thread.saved_fs;
159 loadsegment(gs, current->thread.saved_gs); 158 loadsegment(gs, current->thread.saved_gs);
160 159
161 return ret; 160 return ret;
@@ -197,7 +196,7 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk
197 196
198asmlinkage int sys_vm86old(struct pt_regs regs) 197asmlinkage int sys_vm86old(struct pt_regs regs)
199{ 198{
200 struct vm86_struct __user *v86 = (struct vm86_struct __user *)regs.ebx; 199 struct vm86_struct __user *v86 = (struct vm86_struct __user *)regs.bx;
201 struct kernel_vm86_struct info; /* declare this _on top_, 200 struct kernel_vm86_struct info; /* declare this _on top_,
202 * this avoids wasting of stack space. 201 * this avoids wasting of stack space.
203 * This remains on the stack until we 202 * This remains on the stack until we
@@ -207,7 +206,7 @@ asmlinkage int sys_vm86old(struct pt_regs regs)
207 int tmp, ret = -EPERM; 206 int tmp, ret = -EPERM;
208 207
209 tsk = current; 208 tsk = current;
210 if (tsk->thread.saved_esp0) 209 if (tsk->thread.saved_sp0)
211 goto out; 210 goto out;
212 tmp = copy_vm86_regs_from_user(&info.regs, &v86->regs, 211 tmp = copy_vm86_regs_from_user(&info.regs, &v86->regs,
213 offsetof(struct kernel_vm86_struct, vm86plus) - 212 offsetof(struct kernel_vm86_struct, vm86plus) -
@@ -237,12 +236,12 @@ asmlinkage int sys_vm86(struct pt_regs regs)
237 struct vm86plus_struct __user *v86; 236 struct vm86plus_struct __user *v86;
238 237
239 tsk = current; 238 tsk = current;
240 switch (regs.ebx) { 239 switch (regs.bx) {
241 case VM86_REQUEST_IRQ: 240 case VM86_REQUEST_IRQ:
242 case VM86_FREE_IRQ: 241 case VM86_FREE_IRQ:
243 case VM86_GET_IRQ_BITS: 242 case VM86_GET_IRQ_BITS:
244 case VM86_GET_AND_RESET_IRQ: 243 case VM86_GET_AND_RESET_IRQ:
245 ret = do_vm86_irq_handling(regs.ebx, (int)regs.ecx); 244 ret = do_vm86_irq_handling(regs.bx, (int)regs.cx);
246 goto out; 245 goto out;
247 case VM86_PLUS_INSTALL_CHECK: 246 case VM86_PLUS_INSTALL_CHECK:
248 /* NOTE: on old vm86 stuff this will return the error 247 /* NOTE: on old vm86 stuff this will return the error
@@ -256,9 +255,9 @@ asmlinkage int sys_vm86(struct pt_regs regs)
256 255
257 /* we come here only for functions VM86_ENTER, VM86_ENTER_NO_BYPASS */ 256 /* we come here only for functions VM86_ENTER, VM86_ENTER_NO_BYPASS */
258 ret = -EPERM; 257 ret = -EPERM;
259 if (tsk->thread.saved_esp0) 258 if (tsk->thread.saved_sp0)
260 goto out; 259 goto out;
261 v86 = (struct vm86plus_struct __user *)regs.ecx; 260 v86 = (struct vm86plus_struct __user *)regs.cx;
262 tmp = copy_vm86_regs_from_user(&info.regs, &v86->regs, 261 tmp = copy_vm86_regs_from_user(&info.regs, &v86->regs,
263 offsetof(struct kernel_vm86_struct, regs32) - 262 offsetof(struct kernel_vm86_struct, regs32) -
264 sizeof(info.regs)); 263 sizeof(info.regs));
@@ -281,23 +280,23 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk
281/* 280/*
282 * make sure the vm86() system call doesn't try to do anything silly 281 * make sure the vm86() system call doesn't try to do anything silly
283 */ 282 */
284 info->regs.pt.xds = 0; 283 info->regs.pt.ds = 0;
285 info->regs.pt.xes = 0; 284 info->regs.pt.es = 0;
286 info->regs.pt.xfs = 0; 285 info->regs.pt.fs = 0;
287 286
288/* we are clearing gs later just before "jmp resume_userspace", 287/* we are clearing gs later just before "jmp resume_userspace",
289 * because it is not saved/restored. 288 * because it is not saved/restored.
290 */ 289 */
291 290
292/* 291/*
293 * The eflags register is also special: we cannot trust that the user 292 * The flags register is also special: we cannot trust that the user
294 * has set it up safely, so this makes sure interrupt etc flags are 293 * has set it up safely, so this makes sure interrupt etc flags are
295 * inherited from protected mode. 294 * inherited from protected mode.
296 */ 295 */
297 VEFLAGS = info->regs.pt.eflags; 296 VEFLAGS = info->regs.pt.flags;
298 info->regs.pt.eflags &= SAFE_MASK; 297 info->regs.pt.flags &= SAFE_MASK;
299 info->regs.pt.eflags |= info->regs32->eflags & ~SAFE_MASK; 298 info->regs.pt.flags |= info->regs32->flags & ~SAFE_MASK;
300 info->regs.pt.eflags |= VM_MASK; 299 info->regs.pt.flags |= VM_MASK;
301 300
302 switch (info->cpu_type) { 301 switch (info->cpu_type) {
303 case CPU_286: 302 case CPU_286:
@@ -315,18 +314,18 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk
315 } 314 }
316 315
317/* 316/*
318 * Save old state, set default return value (%eax) to 0 317 * Save old state, set default return value (%ax) to 0
319 */ 318 */
320 info->regs32->eax = 0; 319 info->regs32->ax = 0;
321 tsk->thread.saved_esp0 = tsk->thread.esp0; 320 tsk->thread.saved_sp0 = tsk->thread.sp0;
322 tsk->thread.saved_fs = info->regs32->xfs; 321 tsk->thread.saved_fs = info->regs32->fs;
323 savesegment(gs, tsk->thread.saved_gs); 322 savesegment(gs, tsk->thread.saved_gs);
324 323
325 tss = &per_cpu(init_tss, get_cpu()); 324 tss = &per_cpu(init_tss, get_cpu());
326 tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0; 325 tsk->thread.sp0 = (unsigned long) &info->VM86_TSS_ESP0;
327 if (cpu_has_sep) 326 if (cpu_has_sep)
328 tsk->thread.sysenter_cs = 0; 327 tsk->thread.sysenter_cs = 0;
329 load_esp0(tss, &tsk->thread); 328 load_sp0(tss, &tsk->thread);
330 put_cpu(); 329 put_cpu();
331 330
332 tsk->thread.screen_bitmap = info->screen_bitmap; 331 tsk->thread.screen_bitmap = info->screen_bitmap;
@@ -352,7 +351,7 @@ static inline void return_to_32bit(struct kernel_vm86_regs * regs16, int retval)
352 struct pt_regs * regs32; 351 struct pt_regs * regs32;
353 352
354 regs32 = save_v86_state(regs16); 353 regs32 = save_v86_state(regs16);
355 regs32->eax = retval; 354 regs32->ax = retval;
356 __asm__ __volatile__("movl %0,%%esp\n\t" 355 __asm__ __volatile__("movl %0,%%esp\n\t"
357 "movl %1,%%ebp\n\t" 356 "movl %1,%%ebp\n\t"
358 "jmp resume_userspace" 357 "jmp resume_userspace"
@@ -373,30 +372,30 @@ static inline void clear_IF(struct kernel_vm86_regs * regs)
373 372
374static inline void clear_TF(struct kernel_vm86_regs * regs) 373static inline void clear_TF(struct kernel_vm86_regs * regs)
375{ 374{
376 regs->pt.eflags &= ~TF_MASK; 375 regs->pt.flags &= ~TF_MASK;
377} 376}
378 377
379static inline void clear_AC(struct kernel_vm86_regs * regs) 378static inline void clear_AC(struct kernel_vm86_regs * regs)
380{ 379{
381 regs->pt.eflags &= ~AC_MASK; 380 regs->pt.flags &= ~AC_MASK;
382} 381}
383 382
384/* It is correct to call set_IF(regs) from the set_vflags_* 383/* It is correct to call set_IF(regs) from the set_vflags_*
385 * functions. However someone forgot to call clear_IF(regs) 384 * functions. However someone forgot to call clear_IF(regs)
386 * in the opposite case. 385 * in the opposite case.
387 * After the command sequence CLI PUSHF STI POPF you should 386 * After the command sequence CLI PUSHF STI POPF you should
388 * end up with interrups disabled, but you ended up with 387 * end up with interrupts disabled, but you ended up with
389 * interrupts enabled. 388 * interrupts enabled.
390 * ( I was testing my own changes, but the only bug I 389 * ( I was testing my own changes, but the only bug I
391 * could find was in a function I had not changed. ) 390 * could find was in a function I had not changed. )
392 * [KD] 391 * [KD]
393 */ 392 */
394 393
395static inline void set_vflags_long(unsigned long eflags, struct kernel_vm86_regs * regs) 394static inline void set_vflags_long(unsigned long flags, struct kernel_vm86_regs * regs)
396{ 395{
397 set_flags(VEFLAGS, eflags, current->thread.v86mask); 396 set_flags(VEFLAGS, flags, current->thread.v86mask);
398 set_flags(regs->pt.eflags, eflags, SAFE_MASK); 397 set_flags(regs->pt.flags, flags, SAFE_MASK);
399 if (eflags & IF_MASK) 398 if (flags & IF_MASK)
400 set_IF(regs); 399 set_IF(regs);
401 else 400 else
402 clear_IF(regs); 401 clear_IF(regs);
@@ -405,7 +404,7 @@ static inline void set_vflags_long(unsigned long eflags, struct kernel_vm86_regs
405static inline void set_vflags_short(unsigned short flags, struct kernel_vm86_regs * regs) 404static inline void set_vflags_short(unsigned short flags, struct kernel_vm86_regs * regs)
406{ 405{
407 set_flags(VFLAGS, flags, current->thread.v86mask); 406 set_flags(VFLAGS, flags, current->thread.v86mask);
408 set_flags(regs->pt.eflags, flags, SAFE_MASK); 407 set_flags(regs->pt.flags, flags, SAFE_MASK);
409 if (flags & IF_MASK) 408 if (flags & IF_MASK)
410 set_IF(regs); 409 set_IF(regs);
411 else 410 else
@@ -414,7 +413,7 @@ static inline void set_vflags_short(unsigned short flags, struct kernel_vm86_reg
414 413
415static inline unsigned long get_vflags(struct kernel_vm86_regs * regs) 414static inline unsigned long get_vflags(struct kernel_vm86_regs * regs)
416{ 415{
417 unsigned long flags = regs->pt.eflags & RETURN_MASK; 416 unsigned long flags = regs->pt.flags & RETURN_MASK;
418 417
419 if (VEFLAGS & VIF_MASK) 418 if (VEFLAGS & VIF_MASK)
420 flags |= IF_MASK; 419 flags |= IF_MASK;
@@ -518,7 +517,7 @@ static void do_int(struct kernel_vm86_regs *regs, int i,
518 unsigned long __user *intr_ptr; 517 unsigned long __user *intr_ptr;
519 unsigned long segoffs; 518 unsigned long segoffs;
520 519
521 if (regs->pt.xcs == BIOSSEG) 520 if (regs->pt.cs == BIOSSEG)
522 goto cannot_handle; 521 goto cannot_handle;
523 if (is_revectored(i, &KVM86->int_revectored)) 522 if (is_revectored(i, &KVM86->int_revectored))
524 goto cannot_handle; 523 goto cannot_handle;
@@ -530,9 +529,9 @@ static void do_int(struct kernel_vm86_regs *regs, int i,
530 if ((segoffs >> 16) == BIOSSEG) 529 if ((segoffs >> 16) == BIOSSEG)
531 goto cannot_handle; 530 goto cannot_handle;
532 pushw(ssp, sp, get_vflags(regs), cannot_handle); 531 pushw(ssp, sp, get_vflags(regs), cannot_handle);
533 pushw(ssp, sp, regs->pt.xcs, cannot_handle); 532 pushw(ssp, sp, regs->pt.cs, cannot_handle);
534 pushw(ssp, sp, IP(regs), cannot_handle); 533 pushw(ssp, sp, IP(regs), cannot_handle);
535 regs->pt.xcs = segoffs >> 16; 534 regs->pt.cs = segoffs >> 16;
536 SP(regs) -= 6; 535 SP(regs) -= 6;
537 IP(regs) = segoffs & 0xffff; 536 IP(regs) = segoffs & 0xffff;
538 clear_TF(regs); 537 clear_TF(regs);
@@ -549,7 +548,7 @@ int handle_vm86_trap(struct kernel_vm86_regs * regs, long error_code, int trapno
549 if (VMPI.is_vm86pus) { 548 if (VMPI.is_vm86pus) {
550 if ( (trapno==3) || (trapno==1) ) 549 if ( (trapno==3) || (trapno==1) )
551 return_to_32bit(regs, VM86_TRAP + (trapno << 8)); 550 return_to_32bit(regs, VM86_TRAP + (trapno << 8));
552 do_int(regs, trapno, (unsigned char __user *) (regs->pt.xss << 4), SP(regs)); 551 do_int(regs, trapno, (unsigned char __user *) (regs->pt.ss << 4), SP(regs));
553 return 0; 552 return 0;
554 } 553 }
555 if (trapno !=1) 554 if (trapno !=1)
@@ -585,10 +584,10 @@ void handle_vm86_fault(struct kernel_vm86_regs * regs, long error_code)
585 handle_vm86_trap(regs, 0, 1); \ 584 handle_vm86_trap(regs, 0, 1); \
586 return; } while (0) 585 return; } while (0)
587 586
588 orig_flags = *(unsigned short *)&regs->pt.eflags; 587 orig_flags = *(unsigned short *)&regs->pt.flags;
589 588
590 csp = (unsigned char __user *) (regs->pt.xcs << 4); 589 csp = (unsigned char __user *) (regs->pt.cs << 4);
591 ssp = (unsigned char __user *) (regs->pt.xss << 4); 590 ssp = (unsigned char __user *) (regs->pt.ss << 4);
592 sp = SP(regs); 591 sp = SP(regs);
593 ip = IP(regs); 592 ip = IP(regs);
594 593
@@ -675,7 +674,7 @@ void handle_vm86_fault(struct kernel_vm86_regs * regs, long error_code)
675 SP(regs) += 6; 674 SP(regs) += 6;
676 } 675 }
677 IP(regs) = newip; 676 IP(regs) = newip;
678 regs->pt.xcs = newcs; 677 regs->pt.cs = newcs;
679 CHECK_IF_IN_TRAP; 678 CHECK_IF_IN_TRAP;
680 if (data32) { 679 if (data32) {
681 set_vflags_long(newflags, regs); 680 set_vflags_long(newflags, regs);
diff --git a/arch/x86/kernel/vmi_32.c b/arch/x86/kernel/vmi_32.c
index f02bad68abaa..4525bc2c2e19 100644
--- a/arch/x86/kernel/vmi_32.c
+++ b/arch/x86/kernel/vmi_32.c
@@ -62,7 +62,10 @@ static struct {
62 void (*cpuid)(void /* non-c */); 62 void (*cpuid)(void /* non-c */);
63 void (*_set_ldt)(u32 selector); 63 void (*_set_ldt)(u32 selector);
64 void (*set_tr)(u32 selector); 64 void (*set_tr)(u32 selector);
65 void (*set_kernel_stack)(u32 selector, u32 esp0); 65 void (*write_idt_entry)(struct desc_struct *, int, u32, u32);
66 void (*write_gdt_entry)(struct desc_struct *, int, u32, u32);
67 void (*write_ldt_entry)(struct desc_struct *, int, u32, u32);
68 void (*set_kernel_stack)(u32 selector, u32 sp0);
66 void (*allocate_page)(u32, u32, u32, u32, u32); 69 void (*allocate_page)(u32, u32, u32, u32, u32);
67 void (*release_page)(u32, u32); 70 void (*release_page)(u32, u32);
68 void (*set_pte)(pte_t, pte_t *, unsigned); 71 void (*set_pte)(pte_t, pte_t *, unsigned);
@@ -88,13 +91,13 @@ struct vmi_timer_ops vmi_timer_ops;
88#define IRQ_PATCH_DISABLE 5 91#define IRQ_PATCH_DISABLE 5
89 92
90static inline void patch_offset(void *insnbuf, 93static inline void patch_offset(void *insnbuf,
91 unsigned long eip, unsigned long dest) 94 unsigned long ip, unsigned long dest)
92{ 95{
93 *(unsigned long *)(insnbuf+1) = dest-eip-5; 96 *(unsigned long *)(insnbuf+1) = dest-ip-5;
94} 97}
95 98
96static unsigned patch_internal(int call, unsigned len, void *insnbuf, 99static unsigned patch_internal(int call, unsigned len, void *insnbuf,
97 unsigned long eip) 100 unsigned long ip)
98{ 101{
99 u64 reloc; 102 u64 reloc;
100 struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc; 103 struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc;
@@ -103,13 +106,13 @@ static unsigned patch_internal(int call, unsigned len, void *insnbuf,
103 case VMI_RELOCATION_CALL_REL: 106 case VMI_RELOCATION_CALL_REL:
104 BUG_ON(len < 5); 107 BUG_ON(len < 5);
105 *(char *)insnbuf = MNEM_CALL; 108 *(char *)insnbuf = MNEM_CALL;
106 patch_offset(insnbuf, eip, (unsigned long)rel->eip); 109 patch_offset(insnbuf, ip, (unsigned long)rel->eip);
107 return 5; 110 return 5;
108 111
109 case VMI_RELOCATION_JUMP_REL: 112 case VMI_RELOCATION_JUMP_REL:
110 BUG_ON(len < 5); 113 BUG_ON(len < 5);
111 *(char *)insnbuf = MNEM_JMP; 114 *(char *)insnbuf = MNEM_JMP;
112 patch_offset(insnbuf, eip, (unsigned long)rel->eip); 115 patch_offset(insnbuf, ip, (unsigned long)rel->eip);
113 return 5; 116 return 5;
114 117
115 case VMI_RELOCATION_NOP: 118 case VMI_RELOCATION_NOP:
@@ -131,25 +134,25 @@ static unsigned patch_internal(int call, unsigned len, void *insnbuf,
131 * sequence. The callee does nop padding for us. 134 * sequence. The callee does nop padding for us.
132 */ 135 */
133static unsigned vmi_patch(u8 type, u16 clobbers, void *insns, 136static unsigned vmi_patch(u8 type, u16 clobbers, void *insns,
134 unsigned long eip, unsigned len) 137 unsigned long ip, unsigned len)
135{ 138{
136 switch (type) { 139 switch (type) {
137 case PARAVIRT_PATCH(pv_irq_ops.irq_disable): 140 case PARAVIRT_PATCH(pv_irq_ops.irq_disable):
138 return patch_internal(VMI_CALL_DisableInterrupts, len, 141 return patch_internal(VMI_CALL_DisableInterrupts, len,
139 insns, eip); 142 insns, ip);
140 case PARAVIRT_PATCH(pv_irq_ops.irq_enable): 143 case PARAVIRT_PATCH(pv_irq_ops.irq_enable):
141 return patch_internal(VMI_CALL_EnableInterrupts, len, 144 return patch_internal(VMI_CALL_EnableInterrupts, len,
142 insns, eip); 145 insns, ip);
143 case PARAVIRT_PATCH(pv_irq_ops.restore_fl): 146 case PARAVIRT_PATCH(pv_irq_ops.restore_fl):
144 return patch_internal(VMI_CALL_SetInterruptMask, len, 147 return patch_internal(VMI_CALL_SetInterruptMask, len,
145 insns, eip); 148 insns, ip);
146 case PARAVIRT_PATCH(pv_irq_ops.save_fl): 149 case PARAVIRT_PATCH(pv_irq_ops.save_fl):
147 return patch_internal(VMI_CALL_GetInterruptMask, len, 150 return patch_internal(VMI_CALL_GetInterruptMask, len,
148 insns, eip); 151 insns, ip);
149 case PARAVIRT_PATCH(pv_cpu_ops.iret): 152 case PARAVIRT_PATCH(pv_cpu_ops.iret):
150 return patch_internal(VMI_CALL_IRET, len, insns, eip); 153 return patch_internal(VMI_CALL_IRET, len, insns, ip);
151 case PARAVIRT_PATCH(pv_cpu_ops.irq_enable_sysexit): 154 case PARAVIRT_PATCH(pv_cpu_ops.irq_enable_syscall_ret):
152 return patch_internal(VMI_CALL_SYSEXIT, len, insns, eip); 155 return patch_internal(VMI_CALL_SYSEXIT, len, insns, ip);
153 default: 156 default:
154 break; 157 break;
155 } 158 }
@@ -157,36 +160,36 @@ static unsigned vmi_patch(u8 type, u16 clobbers, void *insns,
157} 160}
158 161
159/* CPUID has non-C semantics, and paravirt-ops API doesn't match hardware ISA */ 162/* CPUID has non-C semantics, and paravirt-ops API doesn't match hardware ISA */
160static void vmi_cpuid(unsigned int *eax, unsigned int *ebx, 163static void vmi_cpuid(unsigned int *ax, unsigned int *bx,
161 unsigned int *ecx, unsigned int *edx) 164 unsigned int *cx, unsigned int *dx)
162{ 165{
163 int override = 0; 166 int override = 0;
164 if (*eax == 1) 167 if (*ax == 1)
165 override = 1; 168 override = 1;
166 asm volatile ("call *%6" 169 asm volatile ("call *%6"
167 : "=a" (*eax), 170 : "=a" (*ax),
168 "=b" (*ebx), 171 "=b" (*bx),
169 "=c" (*ecx), 172 "=c" (*cx),
170 "=d" (*edx) 173 "=d" (*dx)
171 : "0" (*eax), "2" (*ecx), "r" (vmi_ops.cpuid)); 174 : "0" (*ax), "2" (*cx), "r" (vmi_ops.cpuid));
172 if (override) { 175 if (override) {
173 if (disable_pse) 176 if (disable_pse)
174 *edx &= ~X86_FEATURE_PSE; 177 *dx &= ~X86_FEATURE_PSE;
175 if (disable_pge) 178 if (disable_pge)
176 *edx &= ~X86_FEATURE_PGE; 179 *dx &= ~X86_FEATURE_PGE;
177 if (disable_sep) 180 if (disable_sep)
178 *edx &= ~X86_FEATURE_SEP; 181 *dx &= ~X86_FEATURE_SEP;
179 if (disable_tsc) 182 if (disable_tsc)
180 *edx &= ~X86_FEATURE_TSC; 183 *dx &= ~X86_FEATURE_TSC;
181 if (disable_mtrr) 184 if (disable_mtrr)
182 *edx &= ~X86_FEATURE_MTRR; 185 *dx &= ~X86_FEATURE_MTRR;
183 } 186 }
184} 187}
185 188
186static inline void vmi_maybe_load_tls(struct desc_struct *gdt, int nr, struct desc_struct *new) 189static inline void vmi_maybe_load_tls(struct desc_struct *gdt, int nr, struct desc_struct *new)
187{ 190{
188 if (gdt[nr].a != new->a || gdt[nr].b != new->b) 191 if (gdt[nr].a != new->a || gdt[nr].b != new->b)
189 write_gdt_entry(gdt, nr, new->a, new->b); 192 write_gdt_entry(gdt, nr, new, 0);
190} 193}
191 194
192static void vmi_load_tls(struct thread_struct *t, unsigned int cpu) 195static void vmi_load_tls(struct thread_struct *t, unsigned int cpu)
@@ -200,12 +203,12 @@ static void vmi_load_tls(struct thread_struct *t, unsigned int cpu)
200static void vmi_set_ldt(const void *addr, unsigned entries) 203static void vmi_set_ldt(const void *addr, unsigned entries)
201{ 204{
202 unsigned cpu = smp_processor_id(); 205 unsigned cpu = smp_processor_id();
203 u32 low, high; 206 struct desc_struct desc;
204 207
205 pack_descriptor(&low, &high, (unsigned long)addr, 208 pack_descriptor(&desc, (unsigned long)addr,
206 entries * sizeof(struct desc_struct) - 1, 209 entries * sizeof(struct desc_struct) - 1,
207 DESCTYPE_LDT, 0); 210 DESC_LDT, 0);
208 write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_LDT, low, high); 211 write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_LDT, &desc, DESC_LDT);
209 vmi_ops._set_ldt(entries ? GDT_ENTRY_LDT*sizeof(struct desc_struct) : 0); 212 vmi_ops._set_ldt(entries ? GDT_ENTRY_LDT*sizeof(struct desc_struct) : 0);
210} 213}
211 214
@@ -214,17 +217,37 @@ static void vmi_set_tr(void)
214 vmi_ops.set_tr(GDT_ENTRY_TSS*sizeof(struct desc_struct)); 217 vmi_ops.set_tr(GDT_ENTRY_TSS*sizeof(struct desc_struct));
215} 218}
216 219
217static void vmi_load_esp0(struct tss_struct *tss, 220static void vmi_write_idt_entry(gate_desc *dt, int entry, const gate_desc *g)
221{
222 u32 *idt_entry = (u32 *)g;
223 vmi_ops.write_idt_entry(dt, entry, idt_entry[0], idt_entry[2]);
224}
225
226static void vmi_write_gdt_entry(struct desc_struct *dt, int entry,
227 const void *desc, int type)
228{
229 u32 *gdt_entry = (u32 *)desc;
230 vmi_ops.write_gdt_entry(dt, entry, gdt_entry[0], gdt_entry[2]);
231}
232
233static void vmi_write_ldt_entry(struct desc_struct *dt, int entry,
234 const void *desc)
235{
236 u32 *ldt_entry = (u32 *)desc;
237 vmi_ops.write_idt_entry(dt, entry, ldt_entry[0], ldt_entry[2]);
238}
239
240static void vmi_load_sp0(struct tss_struct *tss,
218 struct thread_struct *thread) 241 struct thread_struct *thread)
219{ 242{
220 tss->x86_tss.esp0 = thread->esp0; 243 tss->x86_tss.sp0 = thread->sp0;
221 244
222 /* This can only happen when SEP is enabled, no need to test "SEP"arately */ 245 /* This can only happen when SEP is enabled, no need to test "SEP"arately */
223 if (unlikely(tss->x86_tss.ss1 != thread->sysenter_cs)) { 246 if (unlikely(tss->x86_tss.ss1 != thread->sysenter_cs)) {
224 tss->x86_tss.ss1 = thread->sysenter_cs; 247 tss->x86_tss.ss1 = thread->sysenter_cs;
225 wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0); 248 wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0);
226 } 249 }
227 vmi_ops.set_kernel_stack(__KERNEL_DS, tss->x86_tss.esp0); 250 vmi_ops.set_kernel_stack(__KERNEL_DS, tss->x86_tss.sp0);
228} 251}
229 252
230static void vmi_flush_tlb_user(void) 253static void vmi_flush_tlb_user(void)
@@ -375,7 +398,7 @@ static void vmi_allocate_pt(struct mm_struct *mm, u32 pfn)
375 vmi_ops.allocate_page(pfn, VMI_PAGE_L1, 0, 0, 0); 398 vmi_ops.allocate_page(pfn, VMI_PAGE_L1, 0, 0, 0);
376} 399}
377 400
378static void vmi_allocate_pd(u32 pfn) 401static void vmi_allocate_pd(struct mm_struct *mm, u32 pfn)
379{ 402{
380 /* 403 /*
381 * This call comes in very early, before mem_map is setup. 404 * This call comes in very early, before mem_map is setup.
@@ -452,7 +475,7 @@ static void vmi_set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep
452static void vmi_set_pmd(pmd_t *pmdp, pmd_t pmdval) 475static void vmi_set_pmd(pmd_t *pmdp, pmd_t pmdval)
453{ 476{
454#ifdef CONFIG_X86_PAE 477#ifdef CONFIG_X86_PAE
455 const pte_t pte = { pmdval.pmd, pmdval.pmd >> 32 }; 478 const pte_t pte = { .pte = pmdval.pmd };
456 vmi_check_page_type(__pa(pmdp) >> PAGE_SHIFT, VMI_PAGE_PMD); 479 vmi_check_page_type(__pa(pmdp) >> PAGE_SHIFT, VMI_PAGE_PMD);
457#else 480#else
458 const pte_t pte = { pmdval.pud.pgd.pgd }; 481 const pte_t pte = { pmdval.pud.pgd.pgd };
@@ -485,21 +508,21 @@ static void vmi_set_pte_present(struct mm_struct *mm, unsigned long addr, pte_t
485static void vmi_set_pud(pud_t *pudp, pud_t pudval) 508static void vmi_set_pud(pud_t *pudp, pud_t pudval)
486{ 509{
487 /* Um, eww */ 510 /* Um, eww */
488 const pte_t pte = { pudval.pgd.pgd, pudval.pgd.pgd >> 32 }; 511 const pte_t pte = { .pte = pudval.pgd.pgd };
489 vmi_check_page_type(__pa(pudp) >> PAGE_SHIFT, VMI_PAGE_PGD); 512 vmi_check_page_type(__pa(pudp) >> PAGE_SHIFT, VMI_PAGE_PGD);
490 vmi_ops.set_pte(pte, (pte_t *)pudp, VMI_PAGE_PDP); 513 vmi_ops.set_pte(pte, (pte_t *)pudp, VMI_PAGE_PDP);
491} 514}
492 515
493static void vmi_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) 516static void vmi_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
494{ 517{
495 const pte_t pte = { 0 }; 518 const pte_t pte = { .pte = 0 };
496 vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE); 519 vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE);
497 vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0)); 520 vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0));
498} 521}
499 522
500static void vmi_pmd_clear(pmd_t *pmd) 523static void vmi_pmd_clear(pmd_t *pmd)
501{ 524{
502 const pte_t pte = { 0 }; 525 const pte_t pte = { .pte = 0 };
503 vmi_check_page_type(__pa(pmd) >> PAGE_SHIFT, VMI_PAGE_PMD); 526 vmi_check_page_type(__pa(pmd) >> PAGE_SHIFT, VMI_PAGE_PMD);
504 vmi_ops.set_pte(pte, (pte_t *)pmd, VMI_PAGE_PD); 527 vmi_ops.set_pte(pte, (pte_t *)pmd, VMI_PAGE_PD);
505} 528}
@@ -790,10 +813,13 @@ static inline int __init activate_vmi(void)
790 para_fill(pv_cpu_ops.store_idt, GetIDT); 813 para_fill(pv_cpu_ops.store_idt, GetIDT);
791 para_fill(pv_cpu_ops.store_tr, GetTR); 814 para_fill(pv_cpu_ops.store_tr, GetTR);
792 pv_cpu_ops.load_tls = vmi_load_tls; 815 pv_cpu_ops.load_tls = vmi_load_tls;
793 para_fill(pv_cpu_ops.write_ldt_entry, WriteLDTEntry); 816 para_wrap(pv_cpu_ops.write_ldt_entry, vmi_write_ldt_entry,
794 para_fill(pv_cpu_ops.write_gdt_entry, WriteGDTEntry); 817 write_ldt_entry, WriteLDTEntry);
795 para_fill(pv_cpu_ops.write_idt_entry, WriteIDTEntry); 818 para_wrap(pv_cpu_ops.write_gdt_entry, vmi_write_gdt_entry,
796 para_wrap(pv_cpu_ops.load_esp0, vmi_load_esp0, set_kernel_stack, UpdateKernelStack); 819 write_gdt_entry, WriteGDTEntry);
820 para_wrap(pv_cpu_ops.write_idt_entry, vmi_write_idt_entry,
821 write_idt_entry, WriteIDTEntry);
822 para_wrap(pv_cpu_ops.load_sp0, vmi_load_sp0, set_kernel_stack, UpdateKernelStack);
797 para_fill(pv_cpu_ops.set_iopl_mask, SetIOPLMask); 823 para_fill(pv_cpu_ops.set_iopl_mask, SetIOPLMask);
798 para_fill(pv_cpu_ops.io_delay, IODelay); 824 para_fill(pv_cpu_ops.io_delay, IODelay);
799 825
@@ -870,7 +896,7 @@ static inline int __init activate_vmi(void)
870 * the backend. They are performance critical anyway, so requiring 896 * the backend. They are performance critical anyway, so requiring
871 * a patch is not a big problem. 897 * a patch is not a big problem.
872 */ 898 */
873 pv_cpu_ops.irq_enable_sysexit = (void *)0xfeedbab0; 899 pv_cpu_ops.irq_enable_syscall_ret = (void *)0xfeedbab0;
874 pv_cpu_ops.iret = (void *)0xbadbab0; 900 pv_cpu_ops.iret = (void *)0xbadbab0;
875 901
876#ifdef CONFIG_SMP 902#ifdef CONFIG_SMP
@@ -963,19 +989,19 @@ static int __init parse_vmi(char *arg)
963 return -EINVAL; 989 return -EINVAL;
964 990
965 if (!strcmp(arg, "disable_pge")) { 991 if (!strcmp(arg, "disable_pge")) {
966 clear_bit(X86_FEATURE_PGE, boot_cpu_data.x86_capability); 992 clear_cpu_cap(&boot_cpu_data, X86_FEATURE_PGE);
967 disable_pge = 1; 993 disable_pge = 1;
968 } else if (!strcmp(arg, "disable_pse")) { 994 } else if (!strcmp(arg, "disable_pse")) {
969 clear_bit(X86_FEATURE_PSE, boot_cpu_data.x86_capability); 995 clear_cpu_cap(&boot_cpu_data, X86_FEATURE_PSE);
970 disable_pse = 1; 996 disable_pse = 1;
971 } else if (!strcmp(arg, "disable_sep")) { 997 } else if (!strcmp(arg, "disable_sep")) {
972 clear_bit(X86_FEATURE_SEP, boot_cpu_data.x86_capability); 998 clear_cpu_cap(&boot_cpu_data, X86_FEATURE_SEP);
973 disable_sep = 1; 999 disable_sep = 1;
974 } else if (!strcmp(arg, "disable_tsc")) { 1000 } else if (!strcmp(arg, "disable_tsc")) {
975 clear_bit(X86_FEATURE_TSC, boot_cpu_data.x86_capability); 1001 clear_cpu_cap(&boot_cpu_data, X86_FEATURE_TSC);
976 disable_tsc = 1; 1002 disable_tsc = 1;
977 } else if (!strcmp(arg, "disable_mtrr")) { 1003 } else if (!strcmp(arg, "disable_mtrr")) {
978 clear_bit(X86_FEATURE_MTRR, boot_cpu_data.x86_capability); 1004 clear_cpu_cap(&boot_cpu_data, X86_FEATURE_MTRR);
979 disable_mtrr = 1; 1005 disable_mtrr = 1;
980 } else if (!strcmp(arg, "disable_timer")) { 1006 } else if (!strcmp(arg, "disable_timer")) {
981 disable_vmi_timer = 1; 1007 disable_vmi_timer = 1;
diff --git a/arch/x86/kernel/vmiclock_32.c b/arch/x86/kernel/vmiclock_32.c
index b1b5ab08b26e..a2b030780aa9 100644
--- a/arch/x86/kernel/vmiclock_32.c
+++ b/arch/x86/kernel/vmiclock_32.c
@@ -35,7 +35,6 @@
35#include <asm/i8253.h> 35#include <asm/i8253.h>
36 36
37#include <irq_vectors.h> 37#include <irq_vectors.h>
38#include "io_ports.h"
39 38
40#define VMI_ONESHOT (VMI_ALARM_IS_ONESHOT | VMI_CYCLES_REAL | vmi_get_alarm_wiring()) 39#define VMI_ONESHOT (VMI_ALARM_IS_ONESHOT | VMI_CYCLES_REAL | vmi_get_alarm_wiring())
41#define VMI_PERIODIC (VMI_ALARM_IS_PERIODIC | VMI_CYCLES_REAL | vmi_get_alarm_wiring()) 40#define VMI_PERIODIC (VMI_ALARM_IS_PERIODIC | VMI_CYCLES_REAL | vmi_get_alarm_wiring())
@@ -238,7 +237,7 @@ static void __devinit vmi_time_init_clockevent(void)
238void __init vmi_time_init(void) 237void __init vmi_time_init(void)
239{ 238{
240 /* Disable PIT: BIOSes start PIT CH0 with 18.2hz peridic. */ 239 /* Disable PIT: BIOSes start PIT CH0 with 18.2hz peridic. */
241 outb_p(0x3a, PIT_MODE); /* binary, mode 5, LSB/MSB, ch 0 */ 240 outb_pit(0x3a, PIT_MODE); /* binary, mode 5, LSB/MSB, ch 0 */
242 241
243 vmi_time_init_clockevent(); 242 vmi_time_init_clockevent();
244 setup_irq(0, &vmi_clock_action); 243 setup_irq(0, &vmi_clock_action);
diff --git a/arch/x86/kernel/vmlinux_32.lds.S b/arch/x86/kernel/vmlinux_32.lds.S
index 7d72cce00529..f1148ac8abe3 100644
--- a/arch/x86/kernel/vmlinux_32.lds.S
+++ b/arch/x86/kernel/vmlinux_32.lds.S
@@ -8,12 +8,6 @@
8 * put it inside the section definition. 8 * put it inside the section definition.
9 */ 9 */
10 10
11/* Don't define absolute symbols until and unless you know that symbol
12 * value is should remain constant even if kernel image is relocated
13 * at run time. Absolute symbols are not relocated. If symbol value should
14 * change if kernel is relocated, make the symbol section relative and
15 * put it inside the section definition.
16 */
17#define LOAD_OFFSET __PAGE_OFFSET 11#define LOAD_OFFSET __PAGE_OFFSET
18 12
19#include <asm-generic/vmlinux.lds.h> 13#include <asm-generic/vmlinux.lds.h>
@@ -44,6 +38,8 @@ SECTIONS
44 38
45 /* read-only */ 39 /* read-only */
46 .text : AT(ADDR(.text) - LOAD_OFFSET) { 40 .text : AT(ADDR(.text) - LOAD_OFFSET) {
41 . = ALIGN(4096); /* not really needed, already page aligned */
42 *(.text.page_aligned)
47 TEXT_TEXT 43 TEXT_TEXT
48 SCHED_TEXT 44 SCHED_TEXT
49 LOCK_TEXT 45 LOCK_TEXT
@@ -131,10 +127,12 @@ SECTIONS
131 .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { 127 .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
132 __init_begin = .; 128 __init_begin = .;
133 _sinittext = .; 129 _sinittext = .;
134 *(.init.text) 130 INIT_TEXT
135 _einittext = .; 131 _einittext = .;
136 } 132 }
137 .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) } 133 .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
134 INIT_DATA
135 }
138 . = ALIGN(16); 136 . = ALIGN(16);
139 .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { 137 .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
140 __setup_start = .; 138 __setup_start = .;
@@ -169,8 +167,12 @@ SECTIONS
169 } 167 }
170 /* .exit.text is discard at runtime, not link time, to deal with references 168 /* .exit.text is discard at runtime, not link time, to deal with references
171 from .altinstructions and .eh_frame */ 169 from .altinstructions and .eh_frame */
172 .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) } 170 .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
173 .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) } 171 EXIT_TEXT
172 }
173 .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
174 EXIT_DATA
175 }
174#if defined(CONFIG_BLK_DEV_INITRD) 176#if defined(CONFIG_BLK_DEV_INITRD)
175 . = ALIGN(4096); 177 . = ALIGN(4096);
176 .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { 178 .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
diff --git a/arch/x86/kernel/vmlinux_64.lds.S b/arch/x86/kernel/vmlinux_64.lds.S
index ba8ea97abd21..0992b9946c6f 100644
--- a/arch/x86/kernel/vmlinux_64.lds.S
+++ b/arch/x86/kernel/vmlinux_64.lds.S
@@ -37,16 +37,15 @@ SECTIONS
37 KPROBES_TEXT 37 KPROBES_TEXT
38 *(.fixup) 38 *(.fixup)
39 *(.gnu.warning) 39 *(.gnu.warning)
40 } :text = 0x9090 40 _etext = .; /* End of text section */
41 /* out-of-line lock text */ 41 } :text = 0x9090
42 .text.lock : AT(ADDR(.text.lock) - LOAD_OFFSET) { *(.text.lock) }
43
44 _etext = .; /* End of text section */
45 42
46 . = ALIGN(16); /* Exception table */ 43 . = ALIGN(16); /* Exception table */
47 __start___ex_table = .; 44 __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
48 __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) } 45 __start___ex_table = .;
49 __stop___ex_table = .; 46 *(__ex_table)
47 __stop___ex_table = .;
48 }
50 49
51 NOTES :text :note 50 NOTES :text :note
52 51
@@ -155,12 +154,15 @@ SECTIONS
155 __init_begin = .; 154 __init_begin = .;
156 .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { 155 .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
157 _sinittext = .; 156 _sinittext = .;
158 *(.init.text) 157 INIT_TEXT
159 _einittext = .; 158 _einittext = .;
160 } 159 }
161 __initdata_begin = .; 160 .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
162 .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) } 161 __initdata_begin = .;
163 __initdata_end = .; 162 INIT_DATA
163 __initdata_end = .;
164 }
165
164 . = ALIGN(16); 166 . = ALIGN(16);
165 __setup_start = .; 167 __setup_start = .;
166 .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { *(.init.setup) } 168 .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { *(.init.setup) }
@@ -176,6 +178,14 @@ SECTIONS
176 } 178 }
177 __con_initcall_end = .; 179 __con_initcall_end = .;
178 SECURITY_INIT 180 SECURITY_INIT
181
182 . = ALIGN(8);
183 .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
184 __parainstructions = .;
185 *(.parainstructions)
186 __parainstructions_end = .;
187 }
188
179 . = ALIGN(8); 189 . = ALIGN(8);
180 __alt_instructions = .; 190 __alt_instructions = .;
181 .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) { 191 .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
@@ -187,8 +197,12 @@ SECTIONS
187 } 197 }
188 /* .exit.text is discard at runtime, not link time, to deal with references 198 /* .exit.text is discard at runtime, not link time, to deal with references
189 from .altinstructions and .eh_frame */ 199 from .altinstructions and .eh_frame */
190 .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) } 200 .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
191 .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) } 201 EXIT_TEXT
202 }
203 .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
204 EXIT_DATA
205 }
192 206
193/* vdso blob that is mapped into user space */ 207/* vdso blob that is mapped into user space */
194 vdso_start = . ; 208 vdso_start = . ;
diff --git a/arch/x86/kernel/vsmp_64.c b/arch/x86/kernel/vsmp_64.c
index 414caf0c5f9a..d971210a6d36 100644
--- a/arch/x86/kernel/vsmp_64.c
+++ b/arch/x86/kernel/vsmp_64.c
@@ -25,21 +25,24 @@ static int __init vsmp_init(void)
25 return 0; 25 return 0;
26 26
27 /* Check if we are running on a ScaleMP vSMP box */ 27 /* Check if we are running on a ScaleMP vSMP box */
28 if ((read_pci_config_16(0, 0x1f, 0, PCI_VENDOR_ID) != PCI_VENDOR_ID_SCALEMP) || 28 if ((read_pci_config_16(0, 0x1f, 0, PCI_VENDOR_ID) !=
29 (read_pci_config_16(0, 0x1f, 0, PCI_DEVICE_ID) != PCI_DEVICE_ID_SCALEMP_VSMP_CTL)) 29 PCI_VENDOR_ID_SCALEMP) ||
30 (read_pci_config_16(0, 0x1f, 0, PCI_DEVICE_ID) !=
31 PCI_DEVICE_ID_SCALEMP_VSMP_CTL))
30 return 0; 32 return 0;
31 33
32 /* set vSMP magic bits to indicate vSMP capable kernel */ 34 /* set vSMP magic bits to indicate vSMP capable kernel */
33 address = ioremap(read_pci_config(0, 0x1f, 0, PCI_BASE_ADDRESS_0), 8); 35 address = ioremap(read_pci_config(0, 0x1f, 0, PCI_BASE_ADDRESS_0), 8);
34 cap = readl(address); 36 cap = readl(address);
35 ctl = readl(address + 4); 37 ctl = readl(address + 4);
36 printk("vSMP CTL: capabilities:0x%08x control:0x%08x\n", cap, ctl); 38 printk(KERN_INFO "vSMP CTL: capabilities:0x%08x control:0x%08x\n",
39 cap, ctl);
37 if (cap & ctl & (1 << 4)) { 40 if (cap & ctl & (1 << 4)) {
38 /* Turn on vSMP IRQ fastpath handling (see system.h) */ 41 /* Turn on vSMP IRQ fastpath handling (see system.h) */
39 ctl &= ~(1 << 4); 42 ctl &= ~(1 << 4);
40 writel(ctl, address + 4); 43 writel(ctl, address + 4);
41 ctl = readl(address + 4); 44 ctl = readl(address + 4);
42 printk("vSMP CTL: control set to:0x%08x\n", ctl); 45 printk(KERN_INFO "vSMP CTL: control set to:0x%08x\n", ctl);
43 } 46 }
44 47
45 iounmap(address); 48 iounmap(address);
diff --git a/arch/x86/kernel/vsyscall_32.S b/arch/x86/kernel/vsyscall_32.S
deleted file mode 100644
index a5ab3dc4fd25..000000000000
--- a/arch/x86/kernel/vsyscall_32.S
+++ /dev/null
@@ -1,15 +0,0 @@
1#include <linux/init.h>
2
3__INITDATA
4
5 .globl vsyscall_int80_start, vsyscall_int80_end
6vsyscall_int80_start:
7 .incbin "arch/x86/kernel/vsyscall-int80_32.so"
8vsyscall_int80_end:
9
10 .globl vsyscall_sysenter_start, vsyscall_sysenter_end
11vsyscall_sysenter_start:
12 .incbin "arch/x86/kernel/vsyscall-sysenter_32.so"
13vsyscall_sysenter_end:
14
15__FINIT
diff --git a/arch/x86/kernel/vsyscall_32.lds.S b/arch/x86/kernel/vsyscall_32.lds.S
deleted file mode 100644
index 4a8b0ed9b8fb..000000000000
--- a/arch/x86/kernel/vsyscall_32.lds.S
+++ /dev/null
@@ -1,67 +0,0 @@
1/*
2 * Linker script for vsyscall DSO. The vsyscall page is an ELF shared
3 * object prelinked to its virtual address, and with only one read-only
4 * segment (that fits in one page). This script controls its layout.
5 */
6#include <asm/asm-offsets.h>
7
8SECTIONS
9{
10 . = VDSO_PRELINK_asm + SIZEOF_HEADERS;
11
12 .hash : { *(.hash) } :text
13 .gnu.hash : { *(.gnu.hash) }
14 .dynsym : { *(.dynsym) }
15 .dynstr : { *(.dynstr) }
16 .gnu.version : { *(.gnu.version) }
17 .gnu.version_d : { *(.gnu.version_d) }
18 .gnu.version_r : { *(.gnu.version_r) }
19
20 /* This linker script is used both with -r and with -shared.
21 For the layouts to match, we need to skip more than enough
22 space for the dynamic symbol table et al. If this amount
23 is insufficient, ld -shared will barf. Just increase it here. */
24 . = VDSO_PRELINK_asm + 0x400;
25
26 .text : { *(.text) } :text =0x90909090
27 .note : { *(.note.*) } :text :note
28 .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
29 .eh_frame : { KEEP (*(.eh_frame)) } :text
30 .dynamic : { *(.dynamic) } :text :dynamic
31 .useless : {
32 *(.got.plt) *(.got)
33 *(.data .data.* .gnu.linkonce.d.*)
34 *(.dynbss)
35 *(.bss .bss.* .gnu.linkonce.b.*)
36 } :text
37}
38
39/*
40 * We must supply the ELF program headers explicitly to get just one
41 * PT_LOAD segment, and set the flags explicitly to make segments read-only.
42 */
43PHDRS
44{
45 text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */
46 dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
47 note PT_NOTE FLAGS(4); /* PF_R */
48 eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */
49}
50
51/*
52 * This controls what symbols we export from the DSO.
53 */
54VERSION
55{
56 LINUX_2.5 {
57 global:
58 __kernel_vsyscall;
59 __kernel_sigreturn;
60 __kernel_rt_sigreturn;
61
62 local: *;
63 };
64}
65
66/* The ELF entry point can be used to set the AT_SYSINFO value. */
67ENTRY(__kernel_vsyscall);
diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c
index ad4005c6d4a1..3f8242774580 100644
--- a/arch/x86/kernel/vsyscall_64.c
+++ b/arch/x86/kernel/vsyscall_64.c
@@ -43,7 +43,7 @@
43#include <asm/vgtod.h> 43#include <asm/vgtod.h>
44 44
45#define __vsyscall(nr) __attribute__ ((unused,__section__(".vsyscall_" #nr))) 45#define __vsyscall(nr) __attribute__ ((unused,__section__(".vsyscall_" #nr)))
46#define __syscall_clobber "r11","rcx","memory" 46#define __syscall_clobber "r11","cx","memory"
47#define __pa_vsymbol(x) \ 47#define __pa_vsymbol(x) \
48 ({unsigned long v; \ 48 ({unsigned long v; \
49 extern char __vsyscall_0; \ 49 extern char __vsyscall_0; \
@@ -190,7 +190,7 @@ time_t __vsyscall(1) vtime(time_t *t)
190long __vsyscall(2) 190long __vsyscall(2)
191vgetcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache) 191vgetcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache)
192{ 192{
193 unsigned int dummy, p; 193 unsigned int p;
194 unsigned long j = 0; 194 unsigned long j = 0;
195 195
196 /* Fast cache - only recompute value once per jiffies and avoid 196 /* Fast cache - only recompute value once per jiffies and avoid
@@ -205,7 +205,7 @@ vgetcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache)
205 p = tcache->blob[1]; 205 p = tcache->blob[1];
206 } else if (__vgetcpu_mode == VGETCPU_RDTSCP) { 206 } else if (__vgetcpu_mode == VGETCPU_RDTSCP) {
207 /* Load per CPU data from RDTSCP */ 207 /* Load per CPU data from RDTSCP */
208 rdtscp(dummy, dummy, p); 208 native_read_tscp(&p);
209 } else { 209 } else {
210 /* Load per CPU data from GDT */ 210 /* Load per CPU data from GDT */
211 asm("lsl %1,%0" : "=r" (p) : "r" (__PER_CPU_SEG)); 211 asm("lsl %1,%0" : "=r" (p) : "r" (__PER_CPU_SEG));
@@ -297,7 +297,7 @@ static void __cpuinit vsyscall_set_cpu(int cpu)
297 /* Store cpu number in limit so that it can be loaded quickly 297 /* Store cpu number in limit so that it can be loaded quickly
298 in user space in vgetcpu. 298 in user space in vgetcpu.
299 12 bits for the CPU and 8 bits for the node. */ 299 12 bits for the CPU and 8 bits for the node. */
300 d = (unsigned long *)(cpu_gdt(cpu) + GDT_ENTRY_PER_CPU); 300 d = (unsigned long *)(get_cpu_gdt_table(cpu) + GDT_ENTRY_PER_CPU);
301 *d = 0x0f40000000000ULL; 301 *d = 0x0f40000000000ULL;
302 *d |= cpu; 302 *d |= cpu;
303 *d |= (node & 0xf) << 12; 303 *d |= (node & 0xf) << 12;
@@ -319,7 +319,7 @@ cpu_vsyscall_notifier(struct notifier_block *n, unsigned long action, void *arg)
319 return NOTIFY_DONE; 319 return NOTIFY_DONE;
320} 320}
321 321
322static void __init map_vsyscall(void) 322void __init map_vsyscall(void)
323{ 323{
324 extern char __vsyscall_0; 324 extern char __vsyscall_0;
325 unsigned long physaddr_page0 = __pa_symbol(&__vsyscall_0); 325 unsigned long physaddr_page0 = __pa_symbol(&__vsyscall_0);
@@ -335,7 +335,6 @@ static int __init vsyscall_init(void)
335 BUG_ON((unsigned long) &vtime != VSYSCALL_ADDR(__NR_vtime)); 335 BUG_ON((unsigned long) &vtime != VSYSCALL_ADDR(__NR_vtime));
336 BUG_ON((VSYSCALL_ADDR(0) != __fix_to_virt(VSYSCALL_FIRST_PAGE))); 336 BUG_ON((VSYSCALL_ADDR(0) != __fix_to_virt(VSYSCALL_FIRST_PAGE)));
337 BUG_ON((unsigned long) &vgetcpu != VSYSCALL_ADDR(__NR_vgetcpu)); 337 BUG_ON((unsigned long) &vgetcpu != VSYSCALL_ADDR(__NR_vgetcpu));
338 map_vsyscall();
339#ifdef CONFIG_SYSCTL 338#ifdef CONFIG_SYSCTL
340 register_sysctl_table(kernel_root_table2); 339 register_sysctl_table(kernel_root_table2);
341#endif 340#endif
diff --git a/arch/x86/kernel/x8664_ksyms_64.c b/arch/x86/kernel/x8664_ksyms_64.c
index 77c25b307635..a66e9c1a0537 100644
--- a/arch/x86/kernel/x8664_ksyms_64.c
+++ b/arch/x86/kernel/x8664_ksyms_64.c
@@ -8,6 +8,7 @@
8#include <asm/processor.h> 8#include <asm/processor.h>
9#include <asm/uaccess.h> 9#include <asm/uaccess.h>
10#include <asm/pgtable.h> 10#include <asm/pgtable.h>
11#include <asm/desc.h>
11 12
12EXPORT_SYMBOL(kernel_thread); 13EXPORT_SYMBOL(kernel_thread);
13 14
@@ -34,13 +35,6 @@ EXPORT_SYMBOL(__copy_from_user_inatomic);
34EXPORT_SYMBOL(copy_page); 35EXPORT_SYMBOL(copy_page);
35EXPORT_SYMBOL(clear_page); 36EXPORT_SYMBOL(clear_page);
36 37
37#ifdef CONFIG_SMP
38extern void __write_lock_failed(rwlock_t *rw);
39extern void __read_lock_failed(rwlock_t *rw);
40EXPORT_SYMBOL(__write_lock_failed);
41EXPORT_SYMBOL(__read_lock_failed);
42#endif
43
44/* Export string functions. We normally rely on gcc builtin for most of these, 38/* Export string functions. We normally rely on gcc builtin for most of these,
45 but gcc sometimes decides not to inline them. */ 39 but gcc sometimes decides not to inline them. */
46#undef memcpy 40#undef memcpy
@@ -60,3 +54,8 @@ EXPORT_SYMBOL(init_level4_pgt);
60EXPORT_SYMBOL(load_gs_index); 54EXPORT_SYMBOL(load_gs_index);
61 55
62EXPORT_SYMBOL(_proxy_pda); 56EXPORT_SYMBOL(_proxy_pda);
57
58#ifdef CONFIG_PARAVIRT
59/* Virtualized guests may want to use it */
60EXPORT_SYMBOL_GPL(cpu_gdt_descr);
61#endif
diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig
new file mode 100644
index 000000000000..c83e1c9b5129
--- /dev/null
+++ b/arch/x86/kvm/Kconfig
@@ -0,0 +1,57 @@
1#
2# KVM configuration
3#
4config HAVE_KVM
5 bool
6
7menuconfig VIRTUALIZATION
8 bool "Virtualization"
9 depends on HAVE_KVM || X86
10 default y
11 ---help---
12 Say Y here to get to see options for using your Linux host to run other
13 operating systems inside virtual machines (guests).
14 This option alone does not add any kernel code.
15
16 If you say N, all options in this submenu will be skipped and disabled.
17
18if VIRTUALIZATION
19
20config KVM
21 tristate "Kernel-based Virtual Machine (KVM) support"
22 depends on HAVE_KVM && EXPERIMENTAL
23 select PREEMPT_NOTIFIERS
24 select ANON_INODES
25 ---help---
26 Support hosting fully virtualized guest machines using hardware
27 virtualization extensions. You will need a fairly recent
28 processor equipped with virtualization extensions. You will also
29 need to select one or more of the processor modules below.
30
31 This module provides access to the hardware capabilities through
32 a character device node named /dev/kvm.
33
34 To compile this as a module, choose M here: the module
35 will be called kvm.
36
37 If unsure, say N.
38
39config KVM_INTEL
40 tristate "KVM for Intel processors support"
41 depends on KVM
42 ---help---
43 Provides support for KVM on Intel processors equipped with the VT
44 extensions.
45
46config KVM_AMD
47 tristate "KVM for AMD processors support"
48 depends on KVM
49 ---help---
50 Provides support for KVM on AMD processors equipped with the AMD-V
51 (SVM) extensions.
52
53# OK, it's a little counter-intuitive to do this, but it puts it neatly under
54# the virtualization menu.
55source drivers/lguest/Kconfig
56
57endif # VIRTUALIZATION
diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile
new file mode 100644
index 000000000000..ffdd0b310784
--- /dev/null
+++ b/arch/x86/kvm/Makefile
@@ -0,0 +1,14 @@
1#
2# Makefile for Kernel-based Virtual Machine module
3#
4
5common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o)
6
7EXTRA_CFLAGS += -Ivirt/kvm -Iarch/x86/kvm
8
9kvm-objs := $(common-objs) x86.o mmu.o x86_emulate.o i8259.o irq.o lapic.o
10obj-$(CONFIG_KVM) += kvm.o
11kvm-intel-objs = vmx.o
12obj-$(CONFIG_KVM_INTEL) += kvm-intel.o
13kvm-amd-objs = svm.o
14obj-$(CONFIG_KVM_AMD) += kvm-amd.o
diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c
new file mode 100644
index 000000000000..ab29cf2def47
--- /dev/null
+++ b/arch/x86/kvm/i8259.c
@@ -0,0 +1,450 @@
1/*
2 * 8259 interrupt controller emulation
3 *
4 * Copyright (c) 2003-2004 Fabrice Bellard
5 * Copyright (c) 2007 Intel Corporation
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 * Authors:
25 * Yaozu (Eddie) Dong <Eddie.dong@intel.com>
26 * Port from Qemu.
27 */
28#include <linux/mm.h>
29#include "irq.h"
30
31#include <linux/kvm_host.h>
32
33/*
34 * set irq level. If an edge is detected, then the IRR is set to 1
35 */
36static inline void pic_set_irq1(struct kvm_kpic_state *s, int irq, int level)
37{
38 int mask;
39 mask = 1 << irq;
40 if (s->elcr & mask) /* level triggered */
41 if (level) {
42 s->irr |= mask;
43 s->last_irr |= mask;
44 } else {
45 s->irr &= ~mask;
46 s->last_irr &= ~mask;
47 }
48 else /* edge triggered */
49 if (level) {
50 if ((s->last_irr & mask) == 0)
51 s->irr |= mask;
52 s->last_irr |= mask;
53 } else
54 s->last_irr &= ~mask;
55}
56
57/*
58 * return the highest priority found in mask (highest = smallest
59 * number). Return 8 if no irq
60 */
61static inline int get_priority(struct kvm_kpic_state *s, int mask)
62{
63 int priority;
64 if (mask == 0)
65 return 8;
66 priority = 0;
67 while ((mask & (1 << ((priority + s->priority_add) & 7))) == 0)
68 priority++;
69 return priority;
70}
71
72/*
73 * return the pic wanted interrupt. return -1 if none
74 */
75static int pic_get_irq(struct kvm_kpic_state *s)
76{
77 int mask, cur_priority, priority;
78
79 mask = s->irr & ~s->imr;
80 priority = get_priority(s, mask);
81 if (priority == 8)
82 return -1;
83 /*
84 * compute current priority. If special fully nested mode on the
85 * master, the IRQ coming from the slave is not taken into account
86 * for the priority computation.
87 */
88 mask = s->isr;
89 if (s->special_fully_nested_mode && s == &s->pics_state->pics[0])
90 mask &= ~(1 << 2);
91 cur_priority = get_priority(s, mask);
92 if (priority < cur_priority)
93 /*
94 * higher priority found: an irq should be generated
95 */
96 return (priority + s->priority_add) & 7;
97 else
98 return -1;
99}
100
101/*
102 * raise irq to CPU if necessary. must be called every time the active
103 * irq may change
104 */
105static void pic_update_irq(struct kvm_pic *s)
106{
107 int irq2, irq;
108
109 irq2 = pic_get_irq(&s->pics[1]);
110 if (irq2 >= 0) {
111 /*
112 * if irq request by slave pic, signal master PIC
113 */
114 pic_set_irq1(&s->pics[0], 2, 1);
115 pic_set_irq1(&s->pics[0], 2, 0);
116 }
117 irq = pic_get_irq(&s->pics[0]);
118 if (irq >= 0)
119 s->irq_request(s->irq_request_opaque, 1);
120 else
121 s->irq_request(s->irq_request_opaque, 0);
122}
123
124void kvm_pic_update_irq(struct kvm_pic *s)
125{
126 pic_update_irq(s);
127}
128
129void kvm_pic_set_irq(void *opaque, int irq, int level)
130{
131 struct kvm_pic *s = opaque;
132
133 pic_set_irq1(&s->pics[irq >> 3], irq & 7, level);
134 pic_update_irq(s);
135}
136
137/*
138 * acknowledge interrupt 'irq'
139 */
140static inline void pic_intack(struct kvm_kpic_state *s, int irq)
141{
142 if (s->auto_eoi) {
143 if (s->rotate_on_auto_eoi)
144 s->priority_add = (irq + 1) & 7;
145 } else
146 s->isr |= (1 << irq);
147 /*
148 * We don't clear a level sensitive interrupt here
149 */
150 if (!(s->elcr & (1 << irq)))
151 s->irr &= ~(1 << irq);
152}
153
154int kvm_pic_read_irq(struct kvm_pic *s)
155{
156 int irq, irq2, intno;
157
158 irq = pic_get_irq(&s->pics[0]);
159 if (irq >= 0) {
160 pic_intack(&s->pics[0], irq);
161 if (irq == 2) {
162 irq2 = pic_get_irq(&s->pics[1]);
163 if (irq2 >= 0)
164 pic_intack(&s->pics[1], irq2);
165 else
166 /*
167 * spurious IRQ on slave controller
168 */
169 irq2 = 7;
170 intno = s->pics[1].irq_base + irq2;
171 irq = irq2 + 8;
172 } else
173 intno = s->pics[0].irq_base + irq;
174 } else {
175 /*
176 * spurious IRQ on host controller
177 */
178 irq = 7;
179 intno = s->pics[0].irq_base + irq;
180 }
181 pic_update_irq(s);
182
183 return intno;
184}
185
186void kvm_pic_reset(struct kvm_kpic_state *s)
187{
188 s->last_irr = 0;
189 s->irr = 0;
190 s->imr = 0;
191 s->isr = 0;
192 s->priority_add = 0;
193 s->irq_base = 0;
194 s->read_reg_select = 0;
195 s->poll = 0;
196 s->special_mask = 0;
197 s->init_state = 0;
198 s->auto_eoi = 0;
199 s->rotate_on_auto_eoi = 0;
200 s->special_fully_nested_mode = 0;
201 s->init4 = 0;
202}
203
204static void pic_ioport_write(void *opaque, u32 addr, u32 val)
205{
206 struct kvm_kpic_state *s = opaque;
207 int priority, cmd, irq;
208
209 addr &= 1;
210 if (addr == 0) {
211 if (val & 0x10) {
212 kvm_pic_reset(s); /* init */
213 /*
214 * deassert a pending interrupt
215 */
216 s->pics_state->irq_request(s->pics_state->
217 irq_request_opaque, 0);
218 s->init_state = 1;
219 s->init4 = val & 1;
220 if (val & 0x02)
221 printk(KERN_ERR "single mode not supported");
222 if (val & 0x08)
223 printk(KERN_ERR
224 "level sensitive irq not supported");
225 } else if (val & 0x08) {
226 if (val & 0x04)
227 s->poll = 1;
228 if (val & 0x02)
229 s->read_reg_select = val & 1;
230 if (val & 0x40)
231 s->special_mask = (val >> 5) & 1;
232 } else {
233 cmd = val >> 5;
234 switch (cmd) {
235 case 0:
236 case 4:
237 s->rotate_on_auto_eoi = cmd >> 2;
238 break;
239 case 1: /* end of interrupt */
240 case 5:
241 priority = get_priority(s, s->isr);
242 if (priority != 8) {
243 irq = (priority + s->priority_add) & 7;
244 s->isr &= ~(1 << irq);
245 if (cmd == 5)
246 s->priority_add = (irq + 1) & 7;
247 pic_update_irq(s->pics_state);
248 }
249 break;
250 case 3:
251 irq = val & 7;
252 s->isr &= ~(1 << irq);
253 pic_update_irq(s->pics_state);
254 break;
255 case 6:
256 s->priority_add = (val + 1) & 7;
257 pic_update_irq(s->pics_state);
258 break;
259 case 7:
260 irq = val & 7;
261 s->isr &= ~(1 << irq);
262 s->priority_add = (irq + 1) & 7;
263 pic_update_irq(s->pics_state);
264 break;
265 default:
266 break; /* no operation */
267 }
268 }
269 } else
270 switch (s->init_state) {
271 case 0: /* normal mode */
272 s->imr = val;
273 pic_update_irq(s->pics_state);
274 break;
275 case 1:
276 s->irq_base = val & 0xf8;
277 s->init_state = 2;
278 break;
279 case 2:
280 if (s->init4)
281 s->init_state = 3;
282 else
283 s->init_state = 0;
284 break;
285 case 3:
286 s->special_fully_nested_mode = (val >> 4) & 1;
287 s->auto_eoi = (val >> 1) & 1;
288 s->init_state = 0;
289 break;
290 }
291}
292
293static u32 pic_poll_read(struct kvm_kpic_state *s, u32 addr1)
294{
295 int ret;
296
297 ret = pic_get_irq(s);
298 if (ret >= 0) {
299 if (addr1 >> 7) {
300 s->pics_state->pics[0].isr &= ~(1 << 2);
301 s->pics_state->pics[0].irr &= ~(1 << 2);
302 }
303 s->irr &= ~(1 << ret);
304 s->isr &= ~(1 << ret);
305 if (addr1 >> 7 || ret != 2)
306 pic_update_irq(s->pics_state);
307 } else {
308 ret = 0x07;
309 pic_update_irq(s->pics_state);
310 }
311
312 return ret;
313}
314
315static u32 pic_ioport_read(void *opaque, u32 addr1)
316{
317 struct kvm_kpic_state *s = opaque;
318 unsigned int addr;
319 int ret;
320
321 addr = addr1;
322 addr &= 1;
323 if (s->poll) {
324 ret = pic_poll_read(s, addr1);
325 s->poll = 0;
326 } else
327 if (addr == 0)
328 if (s->read_reg_select)
329 ret = s->isr;
330 else
331 ret = s->irr;
332 else
333 ret = s->imr;
334 return ret;
335}
336
337static void elcr_ioport_write(void *opaque, u32 addr, u32 val)
338{
339 struct kvm_kpic_state *s = opaque;
340 s->elcr = val & s->elcr_mask;
341}
342
343static u32 elcr_ioport_read(void *opaque, u32 addr1)
344{
345 struct kvm_kpic_state *s = opaque;
346 return s->elcr;
347}
348
349static int picdev_in_range(struct kvm_io_device *this, gpa_t addr)
350{
351 switch (addr) {
352 case 0x20:
353 case 0x21:
354 case 0xa0:
355 case 0xa1:
356 case 0x4d0:
357 case 0x4d1:
358 return 1;
359 default:
360 return 0;
361 }
362}
363
364static void picdev_write(struct kvm_io_device *this,
365 gpa_t addr, int len, const void *val)
366{
367 struct kvm_pic *s = this->private;
368 unsigned char data = *(unsigned char *)val;
369
370 if (len != 1) {
371 if (printk_ratelimit())
372 printk(KERN_ERR "PIC: non byte write\n");
373 return;
374 }
375 switch (addr) {
376 case 0x20:
377 case 0x21:
378 case 0xa0:
379 case 0xa1:
380 pic_ioport_write(&s->pics[addr >> 7], addr, data);
381 break;
382 case 0x4d0:
383 case 0x4d1:
384 elcr_ioport_write(&s->pics[addr & 1], addr, data);
385 break;
386 }
387}
388
389static void picdev_read(struct kvm_io_device *this,
390 gpa_t addr, int len, void *val)
391{
392 struct kvm_pic *s = this->private;
393 unsigned char data = 0;
394
395 if (len != 1) {
396 if (printk_ratelimit())
397 printk(KERN_ERR "PIC: non byte read\n");
398 return;
399 }
400 switch (addr) {
401 case 0x20:
402 case 0x21:
403 case 0xa0:
404 case 0xa1:
405 data = pic_ioport_read(&s->pics[addr >> 7], addr);
406 break;
407 case 0x4d0:
408 case 0x4d1:
409 data = elcr_ioport_read(&s->pics[addr & 1], addr);
410 break;
411 }
412 *(unsigned char *)val = data;
413}
414
415/*
416 * callback when PIC0 irq status changed
417 */
418static void pic_irq_request(void *opaque, int level)
419{
420 struct kvm *kvm = opaque;
421 struct kvm_vcpu *vcpu = kvm->vcpus[0];
422
423 pic_irqchip(kvm)->output = level;
424 if (vcpu)
425 kvm_vcpu_kick(vcpu);
426}
427
428struct kvm_pic *kvm_create_pic(struct kvm *kvm)
429{
430 struct kvm_pic *s;
431 s = kzalloc(sizeof(struct kvm_pic), GFP_KERNEL);
432 if (!s)
433 return NULL;
434 s->pics[0].elcr_mask = 0xf8;
435 s->pics[1].elcr_mask = 0xde;
436 s->irq_request = pic_irq_request;
437 s->irq_request_opaque = kvm;
438 s->pics[0].pics_state = s;
439 s->pics[1].pics_state = s;
440
441 /*
442 * Initialize PIO device
443 */
444 s->dev.read = picdev_read;
445 s->dev.write = picdev_write;
446 s->dev.in_range = picdev_in_range;
447 s->dev.private = s;
448 kvm_io_bus_register_dev(&kvm->pio_bus, &s->dev);
449 return s;
450}
diff --git a/arch/x86/kvm/irq.c b/arch/x86/kvm/irq.c
new file mode 100644
index 000000000000..e5714759e97f
--- /dev/null
+++ b/arch/x86/kvm/irq.c
@@ -0,0 +1,78 @@
1/*
2 * irq.c: API for in kernel interrupt controller
3 * Copyright (c) 2007, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16 * Place - Suite 330, Boston, MA 02111-1307 USA.
17 * Authors:
18 * Yaozu (Eddie) Dong <Eddie.dong@intel.com>
19 *
20 */
21
22#include <linux/module.h>
23#include <linux/kvm_host.h>
24
25#include "irq.h"
26
27/*
28 * check if there is pending interrupt without
29 * intack.
30 */
31int kvm_cpu_has_interrupt(struct kvm_vcpu *v)
32{
33 struct kvm_pic *s;
34
35 if (kvm_apic_has_interrupt(v) == -1) { /* LAPIC */
36 if (kvm_apic_accept_pic_intr(v)) {
37 s = pic_irqchip(v->kvm); /* PIC */
38 return s->output;
39 } else
40 return 0;
41 }
42 return 1;
43}
44EXPORT_SYMBOL_GPL(kvm_cpu_has_interrupt);
45
46/*
47 * Read pending interrupt vector and intack.
48 */
49int kvm_cpu_get_interrupt(struct kvm_vcpu *v)
50{
51 struct kvm_pic *s;
52 int vector;
53
54 vector = kvm_get_apic_interrupt(v); /* APIC */
55 if (vector == -1) {
56 if (kvm_apic_accept_pic_intr(v)) {
57 s = pic_irqchip(v->kvm);
58 s->output = 0; /* PIC */
59 vector = kvm_pic_read_irq(s);
60 }
61 }
62 return vector;
63}
64EXPORT_SYMBOL_GPL(kvm_cpu_get_interrupt);
65
66void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu)
67{
68 kvm_inject_apic_timer_irqs(vcpu);
69 /* TODO: PIT, RTC etc. */
70}
71EXPORT_SYMBOL_GPL(kvm_inject_pending_timer_irqs);
72
73void kvm_timer_intr_post(struct kvm_vcpu *vcpu, int vec)
74{
75 kvm_apic_timer_intr_post(vcpu, vec);
76 /* TODO: PIT, RTC etc. */
77}
78EXPORT_SYMBOL_GPL(kvm_timer_intr_post);
diff --git a/arch/x86/kvm/irq.h b/arch/x86/kvm/irq.h
new file mode 100644
index 000000000000..fa5ed5d59b5d
--- /dev/null
+++ b/arch/x86/kvm/irq.h
@@ -0,0 +1,88 @@
1/*
2 * irq.h: in kernel interrupt controller related definitions
3 * Copyright (c) 2007, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16 * Place - Suite 330, Boston, MA 02111-1307 USA.
17 * Authors:
18 * Yaozu (Eddie) Dong <Eddie.dong@intel.com>
19 *
20 */
21
22#ifndef __IRQ_H
23#define __IRQ_H
24
25#include <linux/mm_types.h>
26#include <linux/hrtimer.h>
27#include <linux/kvm_host.h>
28
29#include "iodev.h"
30#include "ioapic.h"
31#include "lapic.h"
32
33struct kvm;
34struct kvm_vcpu;
35
36typedef void irq_request_func(void *opaque, int level);
37
38struct kvm_kpic_state {
39 u8 last_irr; /* edge detection */
40 u8 irr; /* interrupt request register */
41 u8 imr; /* interrupt mask register */
42 u8 isr; /* interrupt service register */
43 u8 priority_add; /* highest irq priority */
44 u8 irq_base;
45 u8 read_reg_select;
46 u8 poll;
47 u8 special_mask;
48 u8 init_state;
49 u8 auto_eoi;
50 u8 rotate_on_auto_eoi;
51 u8 special_fully_nested_mode;
52 u8 init4; /* true if 4 byte init */
53 u8 elcr; /* PIIX edge/trigger selection */
54 u8 elcr_mask;
55 struct kvm_pic *pics_state;
56};
57
58struct kvm_pic {
59 struct kvm_kpic_state pics[2]; /* 0 is master pic, 1 is slave pic */
60 irq_request_func *irq_request;
61 void *irq_request_opaque;
62 int output; /* intr from master PIC */
63 struct kvm_io_device dev;
64};
65
66struct kvm_pic *kvm_create_pic(struct kvm *kvm);
67void kvm_pic_set_irq(void *opaque, int irq, int level);
68int kvm_pic_read_irq(struct kvm_pic *s);
69void kvm_pic_update_irq(struct kvm_pic *s);
70
71static inline struct kvm_pic *pic_irqchip(struct kvm *kvm)
72{
73 return kvm->arch.vpic;
74}
75
76static inline int irqchip_in_kernel(struct kvm *kvm)
77{
78 return pic_irqchip(kvm) != NULL;
79}
80
81void kvm_pic_reset(struct kvm_kpic_state *s);
82
83void kvm_timer_intr_post(struct kvm_vcpu *vcpu, int vec);
84void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu);
85void kvm_inject_apic_timer_irqs(struct kvm_vcpu *vcpu);
86void __kvm_migrate_apic_timer(struct kvm_vcpu *vcpu);
87
88#endif
diff --git a/arch/x86/kvm/kvm_svm.h b/arch/x86/kvm/kvm_svm.h
new file mode 100644
index 000000000000..ecdfe97e4635
--- /dev/null
+++ b/arch/x86/kvm/kvm_svm.h
@@ -0,0 +1,45 @@
1#ifndef __KVM_SVM_H
2#define __KVM_SVM_H
3
4#include <linux/kernel.h>
5#include <linux/types.h>
6#include <linux/list.h>
7#include <linux/kvm_host.h>
8#include <asm/msr.h>
9
10#include "svm.h"
11
12static const u32 host_save_user_msrs[] = {
13#ifdef CONFIG_X86_64
14 MSR_STAR, MSR_LSTAR, MSR_CSTAR, MSR_SYSCALL_MASK, MSR_KERNEL_GS_BASE,
15 MSR_FS_BASE,
16#endif
17 MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP,
18};
19
20#define NR_HOST_SAVE_USER_MSRS ARRAY_SIZE(host_save_user_msrs)
21#define NUM_DB_REGS 4
22
23struct kvm_vcpu;
24
25struct vcpu_svm {
26 struct kvm_vcpu vcpu;
27 struct vmcb *vmcb;
28 unsigned long vmcb_pa;
29 struct svm_cpu_data *svm_data;
30 uint64_t asid_generation;
31
32 unsigned long db_regs[NUM_DB_REGS];
33
34 u64 next_rip;
35
36 u64 host_user_msrs[NR_HOST_SAVE_USER_MSRS];
37 u64 host_gs_base;
38 unsigned long host_cr2;
39 unsigned long host_db_regs[NUM_DB_REGS];
40 unsigned long host_dr6;
41 unsigned long host_dr7;
42};
43
44#endif
45
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
new file mode 100644
index 000000000000..2cbee9479ce4
--- /dev/null
+++ b/arch/x86/kvm/lapic.c
@@ -0,0 +1,1154 @@
1
2/*
3 * Local APIC virtualization
4 *
5 * Copyright (C) 2006 Qumranet, Inc.
6 * Copyright (C) 2007 Novell
7 * Copyright (C) 2007 Intel
8 *
9 * Authors:
10 * Dor Laor <dor.laor@qumranet.com>
11 * Gregory Haskins <ghaskins@novell.com>
12 * Yaozu (Eddie) Dong <eddie.dong@intel.com>
13 *
14 * Based on Xen 3.1 code, Copyright (c) 2004, Intel Corporation.
15 *
16 * This work is licensed under the terms of the GNU GPL, version 2. See
17 * the COPYING file in the top-level directory.
18 */
19
20#include <linux/kvm_host.h>
21#include <linux/kvm.h>
22#include <linux/mm.h>
23#include <linux/highmem.h>
24#include <linux/smp.h>
25#include <linux/hrtimer.h>
26#include <linux/io.h>
27#include <linux/module.h>
28#include <asm/processor.h>
29#include <asm/msr.h>
30#include <asm/page.h>
31#include <asm/current.h>
32#include <asm/apicdef.h>
33#include <asm/atomic.h>
34#include <asm/div64.h>
35#include "irq.h"
36
37#define PRId64 "d"
38#define PRIx64 "llx"
39#define PRIu64 "u"
40#define PRIo64 "o"
41
42#define APIC_BUS_CYCLE_NS 1
43
44/* #define apic_debug(fmt,arg...) printk(KERN_WARNING fmt,##arg) */
45#define apic_debug(fmt, arg...)
46
47#define APIC_LVT_NUM 6
48/* 14 is the version for Xeon and Pentium 8.4.8*/
49#define APIC_VERSION (0x14UL | ((APIC_LVT_NUM - 1) << 16))
50#define LAPIC_MMIO_LENGTH (1 << 12)
51/* followed define is not in apicdef.h */
52#define APIC_SHORT_MASK 0xc0000
53#define APIC_DEST_NOSHORT 0x0
54#define APIC_DEST_MASK 0x800
55#define MAX_APIC_VECTOR 256
56
57#define VEC_POS(v) ((v) & (32 - 1))
58#define REG_POS(v) (((v) >> 5) << 4)
59
60static inline u32 apic_get_reg(struct kvm_lapic *apic, int reg_off)
61{
62 return *((u32 *) (apic->regs + reg_off));
63}
64
65static inline void apic_set_reg(struct kvm_lapic *apic, int reg_off, u32 val)
66{
67 *((u32 *) (apic->regs + reg_off)) = val;
68}
69
70static inline int apic_test_and_set_vector(int vec, void *bitmap)
71{
72 return test_and_set_bit(VEC_POS(vec), (bitmap) + REG_POS(vec));
73}
74
75static inline int apic_test_and_clear_vector(int vec, void *bitmap)
76{
77 return test_and_clear_bit(VEC_POS(vec), (bitmap) + REG_POS(vec));
78}
79
80static inline void apic_set_vector(int vec, void *bitmap)
81{
82 set_bit(VEC_POS(vec), (bitmap) + REG_POS(vec));
83}
84
85static inline void apic_clear_vector(int vec, void *bitmap)
86{
87 clear_bit(VEC_POS(vec), (bitmap) + REG_POS(vec));
88}
89
90static inline int apic_hw_enabled(struct kvm_lapic *apic)
91{
92 return (apic)->vcpu->arch.apic_base & MSR_IA32_APICBASE_ENABLE;
93}
94
95static inline int apic_sw_enabled(struct kvm_lapic *apic)
96{
97 return apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_APIC_ENABLED;
98}
99
100static inline int apic_enabled(struct kvm_lapic *apic)
101{
102 return apic_sw_enabled(apic) && apic_hw_enabled(apic);
103}
104
105#define LVT_MASK \
106 (APIC_LVT_MASKED | APIC_SEND_PENDING | APIC_VECTOR_MASK)
107
108#define LINT_MASK \
109 (LVT_MASK | APIC_MODE_MASK | APIC_INPUT_POLARITY | \
110 APIC_LVT_REMOTE_IRR | APIC_LVT_LEVEL_TRIGGER)
111
112static inline int kvm_apic_id(struct kvm_lapic *apic)
113{
114 return (apic_get_reg(apic, APIC_ID) >> 24) & 0xff;
115}
116
117static inline int apic_lvt_enabled(struct kvm_lapic *apic, int lvt_type)
118{
119 return !(apic_get_reg(apic, lvt_type) & APIC_LVT_MASKED);
120}
121
122static inline int apic_lvt_vector(struct kvm_lapic *apic, int lvt_type)
123{
124 return apic_get_reg(apic, lvt_type) & APIC_VECTOR_MASK;
125}
126
127static inline int apic_lvtt_period(struct kvm_lapic *apic)
128{
129 return apic_get_reg(apic, APIC_LVTT) & APIC_LVT_TIMER_PERIODIC;
130}
131
132static unsigned int apic_lvt_mask[APIC_LVT_NUM] = {
133 LVT_MASK | APIC_LVT_TIMER_PERIODIC, /* LVTT */
134 LVT_MASK | APIC_MODE_MASK, /* LVTTHMR */
135 LVT_MASK | APIC_MODE_MASK, /* LVTPC */
136 LINT_MASK, LINT_MASK, /* LVT0-1 */
137 LVT_MASK /* LVTERR */
138};
139
140static int find_highest_vector(void *bitmap)
141{
142 u32 *word = bitmap;
143 int word_offset = MAX_APIC_VECTOR >> 5;
144
145 while ((word_offset != 0) && (word[(--word_offset) << 2] == 0))
146 continue;
147
148 if (likely(!word_offset && !word[0]))
149 return -1;
150 else
151 return fls(word[word_offset << 2]) - 1 + (word_offset << 5);
152}
153
154static inline int apic_test_and_set_irr(int vec, struct kvm_lapic *apic)
155{
156 return apic_test_and_set_vector(vec, apic->regs + APIC_IRR);
157}
158
159static inline void apic_clear_irr(int vec, struct kvm_lapic *apic)
160{
161 apic_clear_vector(vec, apic->regs + APIC_IRR);
162}
163
164static inline int apic_find_highest_irr(struct kvm_lapic *apic)
165{
166 int result;
167
168 result = find_highest_vector(apic->regs + APIC_IRR);
169 ASSERT(result == -1 || result >= 16);
170
171 return result;
172}
173
174int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu)
175{
176 struct kvm_lapic *apic = vcpu->arch.apic;
177 int highest_irr;
178
179 if (!apic)
180 return 0;
181 highest_irr = apic_find_highest_irr(apic);
182
183 return highest_irr;
184}
185EXPORT_SYMBOL_GPL(kvm_lapic_find_highest_irr);
186
187int kvm_apic_set_irq(struct kvm_vcpu *vcpu, u8 vec, u8 trig)
188{
189 struct kvm_lapic *apic = vcpu->arch.apic;
190
191 if (!apic_test_and_set_irr(vec, apic)) {
192 /* a new pending irq is set in IRR */
193 if (trig)
194 apic_set_vector(vec, apic->regs + APIC_TMR);
195 else
196 apic_clear_vector(vec, apic->regs + APIC_TMR);
197 kvm_vcpu_kick(apic->vcpu);
198 return 1;
199 }
200 return 0;
201}
202
203static inline int apic_find_highest_isr(struct kvm_lapic *apic)
204{
205 int result;
206
207 result = find_highest_vector(apic->regs + APIC_ISR);
208 ASSERT(result == -1 || result >= 16);
209
210 return result;
211}
212
213static void apic_update_ppr(struct kvm_lapic *apic)
214{
215 u32 tpr, isrv, ppr;
216 int isr;
217
218 tpr = apic_get_reg(apic, APIC_TASKPRI);
219 isr = apic_find_highest_isr(apic);
220 isrv = (isr != -1) ? isr : 0;
221
222 if ((tpr & 0xf0) >= (isrv & 0xf0))
223 ppr = tpr & 0xff;
224 else
225 ppr = isrv & 0xf0;
226
227 apic_debug("vlapic %p, ppr 0x%x, isr 0x%x, isrv 0x%x",
228 apic, ppr, isr, isrv);
229
230 apic_set_reg(apic, APIC_PROCPRI, ppr);
231}
232
233static void apic_set_tpr(struct kvm_lapic *apic, u32 tpr)
234{
235 apic_set_reg(apic, APIC_TASKPRI, tpr);
236 apic_update_ppr(apic);
237}
238
239int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest)
240{
241 return kvm_apic_id(apic) == dest;
242}
243
244int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda)
245{
246 int result = 0;
247 u8 logical_id;
248
249 logical_id = GET_APIC_LOGICAL_ID(apic_get_reg(apic, APIC_LDR));
250
251 switch (apic_get_reg(apic, APIC_DFR)) {
252 case APIC_DFR_FLAT:
253 if (logical_id & mda)
254 result = 1;
255 break;
256 case APIC_DFR_CLUSTER:
257 if (((logical_id >> 4) == (mda >> 0x4))
258 && (logical_id & mda & 0xf))
259 result = 1;
260 break;
261 default:
262 printk(KERN_WARNING "Bad DFR vcpu %d: %08x\n",
263 apic->vcpu->vcpu_id, apic_get_reg(apic, APIC_DFR));
264 break;
265 }
266
267 return result;
268}
269
270static int apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source,
271 int short_hand, int dest, int dest_mode)
272{
273 int result = 0;
274 struct kvm_lapic *target = vcpu->arch.apic;
275
276 apic_debug("target %p, source %p, dest 0x%x, "
277 "dest_mode 0x%x, short_hand 0x%x",
278 target, source, dest, dest_mode, short_hand);
279
280 ASSERT(!target);
281 switch (short_hand) {
282 case APIC_DEST_NOSHORT:
283 if (dest_mode == 0) {
284 /* Physical mode. */
285 if ((dest == 0xFF) || (dest == kvm_apic_id(target)))
286 result = 1;
287 } else
288 /* Logical mode. */
289 result = kvm_apic_match_logical_addr(target, dest);
290 break;
291 case APIC_DEST_SELF:
292 if (target == source)
293 result = 1;
294 break;
295 case APIC_DEST_ALLINC:
296 result = 1;
297 break;
298 case APIC_DEST_ALLBUT:
299 if (target != source)
300 result = 1;
301 break;
302 default:
303 printk(KERN_WARNING "Bad dest shorthand value %x\n",
304 short_hand);
305 break;
306 }
307
308 return result;
309}
310
311/*
312 * Add a pending IRQ into lapic.
313 * Return 1 if successfully added and 0 if discarded.
314 */
315static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
316 int vector, int level, int trig_mode)
317{
318 int orig_irr, result = 0;
319 struct kvm_vcpu *vcpu = apic->vcpu;
320
321 switch (delivery_mode) {
322 case APIC_DM_FIXED:
323 case APIC_DM_LOWEST:
324 /* FIXME add logic for vcpu on reset */
325 if (unlikely(!apic_enabled(apic)))
326 break;
327
328 orig_irr = apic_test_and_set_irr(vector, apic);
329 if (orig_irr && trig_mode) {
330 apic_debug("level trig mode repeatedly for vector %d",
331 vector);
332 break;
333 }
334
335 if (trig_mode) {
336 apic_debug("level trig mode for vector %d", vector);
337 apic_set_vector(vector, apic->regs + APIC_TMR);
338 } else
339 apic_clear_vector(vector, apic->regs + APIC_TMR);
340
341 if (vcpu->arch.mp_state == VCPU_MP_STATE_RUNNABLE)
342 kvm_vcpu_kick(vcpu);
343 else if (vcpu->arch.mp_state == VCPU_MP_STATE_HALTED) {
344 vcpu->arch.mp_state = VCPU_MP_STATE_RUNNABLE;
345 if (waitqueue_active(&vcpu->wq))
346 wake_up_interruptible(&vcpu->wq);
347 }
348
349 result = (orig_irr == 0);
350 break;
351
352 case APIC_DM_REMRD:
353 printk(KERN_DEBUG "Ignoring delivery mode 3\n");
354 break;
355
356 case APIC_DM_SMI:
357 printk(KERN_DEBUG "Ignoring guest SMI\n");
358 break;
359 case APIC_DM_NMI:
360 printk(KERN_DEBUG "Ignoring guest NMI\n");
361 break;
362
363 case APIC_DM_INIT:
364 if (level) {
365 if (vcpu->arch.mp_state == VCPU_MP_STATE_RUNNABLE)
366 printk(KERN_DEBUG
367 "INIT on a runnable vcpu %d\n",
368 vcpu->vcpu_id);
369 vcpu->arch.mp_state = VCPU_MP_STATE_INIT_RECEIVED;
370 kvm_vcpu_kick(vcpu);
371 } else {
372 printk(KERN_DEBUG
373 "Ignoring de-assert INIT to vcpu %d\n",
374 vcpu->vcpu_id);
375 }
376
377 break;
378
379 case APIC_DM_STARTUP:
380 printk(KERN_DEBUG "SIPI to vcpu %d vector 0x%02x\n",
381 vcpu->vcpu_id, vector);
382 if (vcpu->arch.mp_state == VCPU_MP_STATE_INIT_RECEIVED) {
383 vcpu->arch.sipi_vector = vector;
384 vcpu->arch.mp_state = VCPU_MP_STATE_SIPI_RECEIVED;
385 if (waitqueue_active(&vcpu->wq))
386 wake_up_interruptible(&vcpu->wq);
387 }
388 break;
389
390 default:
391 printk(KERN_ERR "TODO: unsupported delivery mode %x\n",
392 delivery_mode);
393 break;
394 }
395 return result;
396}
397
398static struct kvm_lapic *kvm_apic_round_robin(struct kvm *kvm, u8 vector,
399 unsigned long bitmap)
400{
401 int last;
402 int next;
403 struct kvm_lapic *apic = NULL;
404
405 last = kvm->arch.round_robin_prev_vcpu;
406 next = last;
407
408 do {
409 if (++next == KVM_MAX_VCPUS)
410 next = 0;
411 if (kvm->vcpus[next] == NULL || !test_bit(next, &bitmap))
412 continue;
413 apic = kvm->vcpus[next]->arch.apic;
414 if (apic && apic_enabled(apic))
415 break;
416 apic = NULL;
417 } while (next != last);
418 kvm->arch.round_robin_prev_vcpu = next;
419
420 if (!apic)
421 printk(KERN_DEBUG "vcpu not ready for apic_round_robin\n");
422
423 return apic;
424}
425
426struct kvm_vcpu *kvm_get_lowest_prio_vcpu(struct kvm *kvm, u8 vector,
427 unsigned long bitmap)
428{
429 struct kvm_lapic *apic;
430
431 apic = kvm_apic_round_robin(kvm, vector, bitmap);
432 if (apic)
433 return apic->vcpu;
434 return NULL;
435}
436
437static void apic_set_eoi(struct kvm_lapic *apic)
438{
439 int vector = apic_find_highest_isr(apic);
440
441 /*
442 * Not every write EOI will has corresponding ISR,
443 * one example is when Kernel check timer on setup_IO_APIC
444 */
445 if (vector == -1)
446 return;
447
448 apic_clear_vector(vector, apic->regs + APIC_ISR);
449 apic_update_ppr(apic);
450
451 if (apic_test_and_clear_vector(vector, apic->regs + APIC_TMR))
452 kvm_ioapic_update_eoi(apic->vcpu->kvm, vector);
453}
454
455static void apic_send_ipi(struct kvm_lapic *apic)
456{
457 u32 icr_low = apic_get_reg(apic, APIC_ICR);
458 u32 icr_high = apic_get_reg(apic, APIC_ICR2);
459
460 unsigned int dest = GET_APIC_DEST_FIELD(icr_high);
461 unsigned int short_hand = icr_low & APIC_SHORT_MASK;
462 unsigned int trig_mode = icr_low & APIC_INT_LEVELTRIG;
463 unsigned int level = icr_low & APIC_INT_ASSERT;
464 unsigned int dest_mode = icr_low & APIC_DEST_MASK;
465 unsigned int delivery_mode = icr_low & APIC_MODE_MASK;
466 unsigned int vector = icr_low & APIC_VECTOR_MASK;
467
468 struct kvm_vcpu *target;
469 struct kvm_vcpu *vcpu;
470 unsigned long lpr_map = 0;
471 int i;
472
473 apic_debug("icr_high 0x%x, icr_low 0x%x, "
474 "short_hand 0x%x, dest 0x%x, trig_mode 0x%x, level 0x%x, "
475 "dest_mode 0x%x, delivery_mode 0x%x, vector 0x%x\n",
476 icr_high, icr_low, short_hand, dest,
477 trig_mode, level, dest_mode, delivery_mode, vector);
478
479 for (i = 0; i < KVM_MAX_VCPUS; i++) {
480 vcpu = apic->vcpu->kvm->vcpus[i];
481 if (!vcpu)
482 continue;
483
484 if (vcpu->arch.apic &&
485 apic_match_dest(vcpu, apic, short_hand, dest, dest_mode)) {
486 if (delivery_mode == APIC_DM_LOWEST)
487 set_bit(vcpu->vcpu_id, &lpr_map);
488 else
489 __apic_accept_irq(vcpu->arch.apic, delivery_mode,
490 vector, level, trig_mode);
491 }
492 }
493
494 if (delivery_mode == APIC_DM_LOWEST) {
495 target = kvm_get_lowest_prio_vcpu(vcpu->kvm, vector, lpr_map);
496 if (target != NULL)
497 __apic_accept_irq(target->arch.apic, delivery_mode,
498 vector, level, trig_mode);
499 }
500}
501
502static u32 apic_get_tmcct(struct kvm_lapic *apic)
503{
504 u64 counter_passed;
505 ktime_t passed, now;
506 u32 tmcct;
507
508 ASSERT(apic != NULL);
509
510 now = apic->timer.dev.base->get_time();
511 tmcct = apic_get_reg(apic, APIC_TMICT);
512
513 /* if initial count is 0, current count should also be 0 */
514 if (tmcct == 0)
515 return 0;
516
517 if (unlikely(ktime_to_ns(now) <=
518 ktime_to_ns(apic->timer.last_update))) {
519 /* Wrap around */
520 passed = ktime_add(( {
521 (ktime_t) {
522 .tv64 = KTIME_MAX -
523 (apic->timer.last_update).tv64}; }
524 ), now);
525 apic_debug("time elapsed\n");
526 } else
527 passed = ktime_sub(now, apic->timer.last_update);
528
529 counter_passed = div64_64(ktime_to_ns(passed),
530 (APIC_BUS_CYCLE_NS * apic->timer.divide_count));
531
532 if (counter_passed > tmcct) {
533 if (unlikely(!apic_lvtt_period(apic))) {
534 /* one-shot timers stick at 0 until reset */
535 tmcct = 0;
536 } else {
537 /*
538 * periodic timers reset to APIC_TMICT when they
539 * hit 0. The while loop simulates this happening N
540 * times. (counter_passed %= tmcct) would also work,
541 * but might be slower or not work on 32-bit??
542 */
543 while (counter_passed > tmcct)
544 counter_passed -= tmcct;
545 tmcct -= counter_passed;
546 }
547 } else {
548 tmcct -= counter_passed;
549 }
550
551 return tmcct;
552}
553
554static void __report_tpr_access(struct kvm_lapic *apic, bool write)
555{
556 struct kvm_vcpu *vcpu = apic->vcpu;
557 struct kvm_run *run = vcpu->run;
558
559 set_bit(KVM_REQ_REPORT_TPR_ACCESS, &vcpu->requests);
560 kvm_x86_ops->cache_regs(vcpu);
561 run->tpr_access.rip = vcpu->arch.rip;
562 run->tpr_access.is_write = write;
563}
564
565static inline void report_tpr_access(struct kvm_lapic *apic, bool write)
566{
567 if (apic->vcpu->arch.tpr_access_reporting)
568 __report_tpr_access(apic, write);
569}
570
571static u32 __apic_read(struct kvm_lapic *apic, unsigned int offset)
572{
573 u32 val = 0;
574
575 if (offset >= LAPIC_MMIO_LENGTH)
576 return 0;
577
578 switch (offset) {
579 case APIC_ARBPRI:
580 printk(KERN_WARNING "Access APIC ARBPRI register "
581 "which is for P6\n");
582 break;
583
584 case APIC_TMCCT: /* Timer CCR */
585 val = apic_get_tmcct(apic);
586 break;
587
588 case APIC_TASKPRI:
589 report_tpr_access(apic, false);
590 /* fall thru */
591 default:
592 apic_update_ppr(apic);
593 val = apic_get_reg(apic, offset);
594 break;
595 }
596
597 return val;
598}
599
600static void apic_mmio_read(struct kvm_io_device *this,
601 gpa_t address, int len, void *data)
602{
603 struct kvm_lapic *apic = (struct kvm_lapic *)this->private;
604 unsigned int offset = address - apic->base_address;
605 unsigned char alignment = offset & 0xf;
606 u32 result;
607
608 if ((alignment + len) > 4) {
609 printk(KERN_ERR "KVM_APIC_READ: alignment error %lx %d",
610 (unsigned long)address, len);
611 return;
612 }
613 result = __apic_read(apic, offset & ~0xf);
614
615 switch (len) {
616 case 1:
617 case 2:
618 case 4:
619 memcpy(data, (char *)&result + alignment, len);
620 break;
621 default:
622 printk(KERN_ERR "Local APIC read with len = %x, "
623 "should be 1,2, or 4 instead\n", len);
624 break;
625 }
626}
627
628static void update_divide_count(struct kvm_lapic *apic)
629{
630 u32 tmp1, tmp2, tdcr;
631
632 tdcr = apic_get_reg(apic, APIC_TDCR);
633 tmp1 = tdcr & 0xf;
634 tmp2 = ((tmp1 & 0x3) | ((tmp1 & 0x8) >> 1)) + 1;
635 apic->timer.divide_count = 0x1 << (tmp2 & 0x7);
636
637 apic_debug("timer divide count is 0x%x\n",
638 apic->timer.divide_count);
639}
640
641static void start_apic_timer(struct kvm_lapic *apic)
642{
643 ktime_t now = apic->timer.dev.base->get_time();
644
645 apic->timer.last_update = now;
646
647 apic->timer.period = apic_get_reg(apic, APIC_TMICT) *
648 APIC_BUS_CYCLE_NS * apic->timer.divide_count;
649 atomic_set(&apic->timer.pending, 0);
650 hrtimer_start(&apic->timer.dev,
651 ktime_add_ns(now, apic->timer.period),
652 HRTIMER_MODE_ABS);
653
654 apic_debug("%s: bus cycle is %" PRId64 "ns, now 0x%016"
655 PRIx64 ", "
656 "timer initial count 0x%x, period %lldns, "
657 "expire @ 0x%016" PRIx64 ".\n", __FUNCTION__,
658 APIC_BUS_CYCLE_NS, ktime_to_ns(now),
659 apic_get_reg(apic, APIC_TMICT),
660 apic->timer.period,
661 ktime_to_ns(ktime_add_ns(now,
662 apic->timer.period)));
663}
664
665static void apic_mmio_write(struct kvm_io_device *this,
666 gpa_t address, int len, const void *data)
667{
668 struct kvm_lapic *apic = (struct kvm_lapic *)this->private;
669 unsigned int offset = address - apic->base_address;
670 unsigned char alignment = offset & 0xf;
671 u32 val;
672
673 /*
674 * APIC register must be aligned on 128-bits boundary.
675 * 32/64/128 bits registers must be accessed thru 32 bits.
676 * Refer SDM 8.4.1
677 */
678 if (len != 4 || alignment) {
679 if (printk_ratelimit())
680 printk(KERN_ERR "apic write: bad size=%d %lx\n",
681 len, (long)address);
682 return;
683 }
684
685 val = *(u32 *) data;
686
687 /* too common printing */
688 if (offset != APIC_EOI)
689 apic_debug("%s: offset 0x%x with length 0x%x, and value is "
690 "0x%x\n", __FUNCTION__, offset, len, val);
691
692 offset &= 0xff0;
693
694 switch (offset) {
695 case APIC_ID: /* Local APIC ID */
696 apic_set_reg(apic, APIC_ID, val);
697 break;
698
699 case APIC_TASKPRI:
700 report_tpr_access(apic, true);
701 apic_set_tpr(apic, val & 0xff);
702 break;
703
704 case APIC_EOI:
705 apic_set_eoi(apic);
706 break;
707
708 case APIC_LDR:
709 apic_set_reg(apic, APIC_LDR, val & APIC_LDR_MASK);
710 break;
711
712 case APIC_DFR:
713 apic_set_reg(apic, APIC_DFR, val | 0x0FFFFFFF);
714 break;
715
716 case APIC_SPIV:
717 apic_set_reg(apic, APIC_SPIV, val & 0x3ff);
718 if (!(val & APIC_SPIV_APIC_ENABLED)) {
719 int i;
720 u32 lvt_val;
721
722 for (i = 0; i < APIC_LVT_NUM; i++) {
723 lvt_val = apic_get_reg(apic,
724 APIC_LVTT + 0x10 * i);
725 apic_set_reg(apic, APIC_LVTT + 0x10 * i,
726 lvt_val | APIC_LVT_MASKED);
727 }
728 atomic_set(&apic->timer.pending, 0);
729
730 }
731 break;
732
733 case APIC_ICR:
734 /* No delay here, so we always clear the pending bit */
735 apic_set_reg(apic, APIC_ICR, val & ~(1 << 12));
736 apic_send_ipi(apic);
737 break;
738
739 case APIC_ICR2:
740 apic_set_reg(apic, APIC_ICR2, val & 0xff000000);
741 break;
742
743 case APIC_LVTT:
744 case APIC_LVTTHMR:
745 case APIC_LVTPC:
746 case APIC_LVT0:
747 case APIC_LVT1:
748 case APIC_LVTERR:
749 /* TODO: Check vector */
750 if (!apic_sw_enabled(apic))
751 val |= APIC_LVT_MASKED;
752
753 val &= apic_lvt_mask[(offset - APIC_LVTT) >> 4];
754 apic_set_reg(apic, offset, val);
755
756 break;
757
758 case APIC_TMICT:
759 hrtimer_cancel(&apic->timer.dev);
760 apic_set_reg(apic, APIC_TMICT, val);
761 start_apic_timer(apic);
762 return;
763
764 case APIC_TDCR:
765 if (val & 4)
766 printk(KERN_ERR "KVM_WRITE:TDCR %x\n", val);
767 apic_set_reg(apic, APIC_TDCR, val);
768 update_divide_count(apic);
769 break;
770
771 default:
772 apic_debug("Local APIC Write to read-only register %x\n",
773 offset);
774 break;
775 }
776
777}
778
779static int apic_mmio_range(struct kvm_io_device *this, gpa_t addr)
780{
781 struct kvm_lapic *apic = (struct kvm_lapic *)this->private;
782 int ret = 0;
783
784
785 if (apic_hw_enabled(apic) &&
786 (addr >= apic->base_address) &&
787 (addr < (apic->base_address + LAPIC_MMIO_LENGTH)))
788 ret = 1;
789
790 return ret;
791}
792
793void kvm_free_lapic(struct kvm_vcpu *vcpu)
794{
795 if (!vcpu->arch.apic)
796 return;
797
798 hrtimer_cancel(&vcpu->arch.apic->timer.dev);
799
800 if (vcpu->arch.apic->regs_page)
801 __free_page(vcpu->arch.apic->regs_page);
802
803 kfree(vcpu->arch.apic);
804}
805
806/*
807 *----------------------------------------------------------------------
808 * LAPIC interface
809 *----------------------------------------------------------------------
810 */
811
812void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8)
813{
814 struct kvm_lapic *apic = vcpu->arch.apic;
815
816 if (!apic)
817 return;
818 apic_set_tpr(apic, ((cr8 & 0x0f) << 4)
819 | (apic_get_reg(apic, APIC_TASKPRI) & 4));
820}
821
822u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu)
823{
824 struct kvm_lapic *apic = vcpu->arch.apic;
825 u64 tpr;
826
827 if (!apic)
828 return 0;
829 tpr = (u64) apic_get_reg(apic, APIC_TASKPRI);
830
831 return (tpr & 0xf0) >> 4;
832}
833EXPORT_SYMBOL_GPL(kvm_lapic_get_cr8);
834
835void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value)
836{
837 struct kvm_lapic *apic = vcpu->arch.apic;
838
839 if (!apic) {
840 value |= MSR_IA32_APICBASE_BSP;
841 vcpu->arch.apic_base = value;
842 return;
843 }
844 if (apic->vcpu->vcpu_id)
845 value &= ~MSR_IA32_APICBASE_BSP;
846
847 vcpu->arch.apic_base = value;
848 apic->base_address = apic->vcpu->arch.apic_base &
849 MSR_IA32_APICBASE_BASE;
850
851 /* with FSB delivery interrupt, we can restart APIC functionality */
852 apic_debug("apic base msr is 0x%016" PRIx64 ", and base address is "
853 "0x%lx.\n", apic->vcpu->arch.apic_base, apic->base_address);
854
855}
856
857u64 kvm_lapic_get_base(struct kvm_vcpu *vcpu)
858{
859 return vcpu->arch.apic_base;
860}
861EXPORT_SYMBOL_GPL(kvm_lapic_get_base);
862
863void kvm_lapic_reset(struct kvm_vcpu *vcpu)
864{
865 struct kvm_lapic *apic;
866 int i;
867
868 apic_debug("%s\n", __FUNCTION__);
869
870 ASSERT(vcpu);
871 apic = vcpu->arch.apic;
872 ASSERT(apic != NULL);
873
874 /* Stop the timer in case it's a reset to an active apic */
875 hrtimer_cancel(&apic->timer.dev);
876
877 apic_set_reg(apic, APIC_ID, vcpu->vcpu_id << 24);
878 apic_set_reg(apic, APIC_LVR, APIC_VERSION);
879
880 for (i = 0; i < APIC_LVT_NUM; i++)
881 apic_set_reg(apic, APIC_LVTT + 0x10 * i, APIC_LVT_MASKED);
882 apic_set_reg(apic, APIC_LVT0,
883 SET_APIC_DELIVERY_MODE(0, APIC_MODE_EXTINT));
884
885 apic_set_reg(apic, APIC_DFR, 0xffffffffU);
886 apic_set_reg(apic, APIC_SPIV, 0xff);
887 apic_set_reg(apic, APIC_TASKPRI, 0);
888 apic_set_reg(apic, APIC_LDR, 0);
889 apic_set_reg(apic, APIC_ESR, 0);
890 apic_set_reg(apic, APIC_ICR, 0);
891 apic_set_reg(apic, APIC_ICR2, 0);
892 apic_set_reg(apic, APIC_TDCR, 0);
893 apic_set_reg(apic, APIC_TMICT, 0);
894 for (i = 0; i < 8; i++) {
895 apic_set_reg(apic, APIC_IRR + 0x10 * i, 0);
896 apic_set_reg(apic, APIC_ISR + 0x10 * i, 0);
897 apic_set_reg(apic, APIC_TMR + 0x10 * i, 0);
898 }
899 update_divide_count(apic);
900 atomic_set(&apic->timer.pending, 0);
901 if (vcpu->vcpu_id == 0)
902 vcpu->arch.apic_base |= MSR_IA32_APICBASE_BSP;
903 apic_update_ppr(apic);
904
905 apic_debug(KERN_INFO "%s: vcpu=%p, id=%d, base_msr="
906 "0x%016" PRIx64 ", base_address=0x%0lx.\n", __FUNCTION__,
907 vcpu, kvm_apic_id(apic),
908 vcpu->arch.apic_base, apic->base_address);
909}
910EXPORT_SYMBOL_GPL(kvm_lapic_reset);
911
912int kvm_lapic_enabled(struct kvm_vcpu *vcpu)
913{
914 struct kvm_lapic *apic = vcpu->arch.apic;
915 int ret = 0;
916
917 if (!apic)
918 return 0;
919 ret = apic_enabled(apic);
920
921 return ret;
922}
923EXPORT_SYMBOL_GPL(kvm_lapic_enabled);
924
925/*
926 *----------------------------------------------------------------------
927 * timer interface
928 *----------------------------------------------------------------------
929 */
930
931/* TODO: make sure __apic_timer_fn runs in current pCPU */
932static int __apic_timer_fn(struct kvm_lapic *apic)
933{
934 int result = 0;
935 wait_queue_head_t *q = &apic->vcpu->wq;
936
937 atomic_inc(&apic->timer.pending);
938 if (waitqueue_active(q)) {
939 apic->vcpu->arch.mp_state = VCPU_MP_STATE_RUNNABLE;
940 wake_up_interruptible(q);
941 }
942 if (apic_lvtt_period(apic)) {
943 result = 1;
944 apic->timer.dev.expires = ktime_add_ns(
945 apic->timer.dev.expires,
946 apic->timer.period);
947 }
948 return result;
949}
950
951static int __inject_apic_timer_irq(struct kvm_lapic *apic)
952{
953 int vector;
954
955 vector = apic_lvt_vector(apic, APIC_LVTT);
956 return __apic_accept_irq(apic, APIC_DM_FIXED, vector, 1, 0);
957}
958
959static enum hrtimer_restart apic_timer_fn(struct hrtimer *data)
960{
961 struct kvm_lapic *apic;
962 int restart_timer = 0;
963
964 apic = container_of(data, struct kvm_lapic, timer.dev);
965
966 restart_timer = __apic_timer_fn(apic);
967
968 if (restart_timer)
969 return HRTIMER_RESTART;
970 else
971 return HRTIMER_NORESTART;
972}
973
974int kvm_create_lapic(struct kvm_vcpu *vcpu)
975{
976 struct kvm_lapic *apic;
977
978 ASSERT(vcpu != NULL);
979 apic_debug("apic_init %d\n", vcpu->vcpu_id);
980
981 apic = kzalloc(sizeof(*apic), GFP_KERNEL);
982 if (!apic)
983 goto nomem;
984
985 vcpu->arch.apic = apic;
986
987 apic->regs_page = alloc_page(GFP_KERNEL);
988 if (apic->regs_page == NULL) {
989 printk(KERN_ERR "malloc apic regs error for vcpu %x\n",
990 vcpu->vcpu_id);
991 goto nomem_free_apic;
992 }
993 apic->regs = page_address(apic->regs_page);
994 memset(apic->regs, 0, PAGE_SIZE);
995 apic->vcpu = vcpu;
996
997 hrtimer_init(&apic->timer.dev, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
998 apic->timer.dev.function = apic_timer_fn;
999 apic->base_address = APIC_DEFAULT_PHYS_BASE;
1000 vcpu->arch.apic_base = APIC_DEFAULT_PHYS_BASE;
1001
1002 kvm_lapic_reset(vcpu);
1003 apic->dev.read = apic_mmio_read;
1004 apic->dev.write = apic_mmio_write;
1005 apic->dev.in_range = apic_mmio_range;
1006 apic->dev.private = apic;
1007
1008 return 0;
1009nomem_free_apic:
1010 kfree(apic);
1011nomem:
1012 return -ENOMEM;
1013}
1014EXPORT_SYMBOL_GPL(kvm_create_lapic);
1015
1016int kvm_apic_has_interrupt(struct kvm_vcpu *vcpu)
1017{
1018 struct kvm_lapic *apic = vcpu->arch.apic;
1019 int highest_irr;
1020
1021 if (!apic || !apic_enabled(apic))
1022 return -1;
1023
1024 apic_update_ppr(apic);
1025 highest_irr = apic_find_highest_irr(apic);
1026 if ((highest_irr == -1) ||
1027 ((highest_irr & 0xF0) <= apic_get_reg(apic, APIC_PROCPRI)))
1028 return -1;
1029 return highest_irr;
1030}
1031
1032int kvm_apic_accept_pic_intr(struct kvm_vcpu *vcpu)
1033{
1034 u32 lvt0 = apic_get_reg(vcpu->arch.apic, APIC_LVT0);
1035 int r = 0;
1036
1037 if (vcpu->vcpu_id == 0) {
1038 if (!apic_hw_enabled(vcpu->arch.apic))
1039 r = 1;
1040 if ((lvt0 & APIC_LVT_MASKED) == 0 &&
1041 GET_APIC_DELIVERY_MODE(lvt0) == APIC_MODE_EXTINT)
1042 r = 1;
1043 }
1044 return r;
1045}
1046
1047void kvm_inject_apic_timer_irqs(struct kvm_vcpu *vcpu)
1048{
1049 struct kvm_lapic *apic = vcpu->arch.apic;
1050
1051 if (apic && apic_lvt_enabled(apic, APIC_LVTT) &&
1052 atomic_read(&apic->timer.pending) > 0) {
1053 if (__inject_apic_timer_irq(apic))
1054 atomic_dec(&apic->timer.pending);
1055 }
1056}
1057
1058void kvm_apic_timer_intr_post(struct kvm_vcpu *vcpu, int vec)
1059{
1060 struct kvm_lapic *apic = vcpu->arch.apic;
1061
1062 if (apic && apic_lvt_vector(apic, APIC_LVTT) == vec)
1063 apic->timer.last_update = ktime_add_ns(
1064 apic->timer.last_update,
1065 apic->timer.period);
1066}
1067
1068int kvm_get_apic_interrupt(struct kvm_vcpu *vcpu)
1069{
1070 int vector = kvm_apic_has_interrupt(vcpu);
1071 struct kvm_lapic *apic = vcpu->arch.apic;
1072
1073 if (vector == -1)
1074 return -1;
1075
1076 apic_set_vector(vector, apic->regs + APIC_ISR);
1077 apic_update_ppr(apic);
1078 apic_clear_irr(vector, apic);
1079 return vector;
1080}
1081
1082void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu)
1083{
1084 struct kvm_lapic *apic = vcpu->arch.apic;
1085
1086 apic->base_address = vcpu->arch.apic_base &
1087 MSR_IA32_APICBASE_BASE;
1088 apic_set_reg(apic, APIC_LVR, APIC_VERSION);
1089 apic_update_ppr(apic);
1090 hrtimer_cancel(&apic->timer.dev);
1091 update_divide_count(apic);
1092 start_apic_timer(apic);
1093}
1094
1095void __kvm_migrate_apic_timer(struct kvm_vcpu *vcpu)
1096{
1097 struct kvm_lapic *apic = vcpu->arch.apic;
1098 struct hrtimer *timer;
1099
1100 if (!apic)
1101 return;
1102
1103 timer = &apic->timer.dev;
1104 if (hrtimer_cancel(timer))
1105 hrtimer_start(timer, timer->expires, HRTIMER_MODE_ABS);
1106}
1107
1108void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu)
1109{
1110 u32 data;
1111 void *vapic;
1112
1113 if (!irqchip_in_kernel(vcpu->kvm) || !vcpu->arch.apic->vapic_addr)
1114 return;
1115
1116 vapic = kmap_atomic(vcpu->arch.apic->vapic_page, KM_USER0);
1117 data = *(u32 *)(vapic + offset_in_page(vcpu->arch.apic->vapic_addr));
1118 kunmap_atomic(vapic, KM_USER0);
1119
1120 apic_set_tpr(vcpu->arch.apic, data & 0xff);
1121}
1122
1123void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu)
1124{
1125 u32 data, tpr;
1126 int max_irr, max_isr;
1127 struct kvm_lapic *apic;
1128 void *vapic;
1129
1130 if (!irqchip_in_kernel(vcpu->kvm) || !vcpu->arch.apic->vapic_addr)
1131 return;
1132
1133 apic = vcpu->arch.apic;
1134 tpr = apic_get_reg(apic, APIC_TASKPRI) & 0xff;
1135 max_irr = apic_find_highest_irr(apic);
1136 if (max_irr < 0)
1137 max_irr = 0;
1138 max_isr = apic_find_highest_isr(apic);
1139 if (max_isr < 0)
1140 max_isr = 0;
1141 data = (tpr & 0xff) | ((max_isr & 0xf0) << 8) | (max_irr << 24);
1142
1143 vapic = kmap_atomic(vcpu->arch.apic->vapic_page, KM_USER0);
1144 *(u32 *)(vapic + offset_in_page(vcpu->arch.apic->vapic_addr)) = data;
1145 kunmap_atomic(vapic, KM_USER0);
1146}
1147
1148void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr)
1149{
1150 if (!irqchip_in_kernel(vcpu->kvm))
1151 return;
1152
1153 vcpu->arch.apic->vapic_addr = vapic_addr;
1154}
diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
new file mode 100644
index 000000000000..676c396c9cee
--- /dev/null
+++ b/arch/x86/kvm/lapic.h
@@ -0,0 +1,50 @@
1#ifndef __KVM_X86_LAPIC_H
2#define __KVM_X86_LAPIC_H
3
4#include "iodev.h"
5
6#include <linux/kvm_host.h>
7
8struct kvm_lapic {
9 unsigned long base_address;
10 struct kvm_io_device dev;
11 struct {
12 atomic_t pending;
13 s64 period; /* unit: ns */
14 u32 divide_count;
15 ktime_t last_update;
16 struct hrtimer dev;
17 } timer;
18 struct kvm_vcpu *vcpu;
19 struct page *regs_page;
20 void *regs;
21 gpa_t vapic_addr;
22 struct page *vapic_page;
23};
24int kvm_create_lapic(struct kvm_vcpu *vcpu);
25void kvm_free_lapic(struct kvm_vcpu *vcpu);
26
27int kvm_apic_has_interrupt(struct kvm_vcpu *vcpu);
28int kvm_apic_accept_pic_intr(struct kvm_vcpu *vcpu);
29int kvm_get_apic_interrupt(struct kvm_vcpu *vcpu);
30void kvm_lapic_reset(struct kvm_vcpu *vcpu);
31u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu);
32void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8);
33void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value);
34
35int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest);
36int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda);
37int kvm_apic_set_irq(struct kvm_vcpu *vcpu, u8 vec, u8 trig);
38
39u64 kvm_get_apic_base(struct kvm_vcpu *vcpu);
40void kvm_set_apic_base(struct kvm_vcpu *vcpu, u64 data);
41void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu);
42int kvm_lapic_enabled(struct kvm_vcpu *vcpu);
43int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu);
44void kvm_apic_timer_intr_post(struct kvm_vcpu *vcpu, int vec);
45
46void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr);
47void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu);
48void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu);
49
50#endif
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
new file mode 100644
index 000000000000..8efdcdbebb03
--- /dev/null
+++ b/arch/x86/kvm/mmu.c
@@ -0,0 +1,1885 @@
1/*
2 * Kernel-based Virtual Machine driver for Linux
3 *
4 * This module enables machines with Intel VT-x extensions to run virtual
5 * machines without emulation or binary translation.
6 *
7 * MMU support
8 *
9 * Copyright (C) 2006 Qumranet, Inc.
10 *
11 * Authors:
12 * Yaniv Kamay <yaniv@qumranet.com>
13 * Avi Kivity <avi@qumranet.com>
14 *
15 * This work is licensed under the terms of the GNU GPL, version 2. See
16 * the COPYING file in the top-level directory.
17 *
18 */
19
20#include "vmx.h"
21#include "mmu.h"
22
23#include <linux/kvm_host.h>
24#include <linux/types.h>
25#include <linux/string.h>
26#include <linux/mm.h>
27#include <linux/highmem.h>
28#include <linux/module.h>
29#include <linux/swap.h>
30
31#include <asm/page.h>
32#include <asm/cmpxchg.h>
33#include <asm/io.h>
34
35#undef MMU_DEBUG
36
37#undef AUDIT
38
39#ifdef AUDIT
40static void kvm_mmu_audit(struct kvm_vcpu *vcpu, const char *msg);
41#else
42static void kvm_mmu_audit(struct kvm_vcpu *vcpu, const char *msg) {}
43#endif
44
45#ifdef MMU_DEBUG
46
47#define pgprintk(x...) do { if (dbg) printk(x); } while (0)
48#define rmap_printk(x...) do { if (dbg) printk(x); } while (0)
49
50#else
51
52#define pgprintk(x...) do { } while (0)
53#define rmap_printk(x...) do { } while (0)
54
55#endif
56
57#if defined(MMU_DEBUG) || defined(AUDIT)
58static int dbg = 1;
59#endif
60
61#ifndef MMU_DEBUG
62#define ASSERT(x) do { } while (0)
63#else
64#define ASSERT(x) \
65 if (!(x)) { \
66 printk(KERN_WARNING "assertion failed %s:%d: %s\n", \
67 __FILE__, __LINE__, #x); \
68 }
69#endif
70
71#define PT64_PT_BITS 9
72#define PT64_ENT_PER_PAGE (1 << PT64_PT_BITS)
73#define PT32_PT_BITS 10
74#define PT32_ENT_PER_PAGE (1 << PT32_PT_BITS)
75
76#define PT_WRITABLE_SHIFT 1
77
78#define PT_PRESENT_MASK (1ULL << 0)
79#define PT_WRITABLE_MASK (1ULL << PT_WRITABLE_SHIFT)
80#define PT_USER_MASK (1ULL << 2)
81#define PT_PWT_MASK (1ULL << 3)
82#define PT_PCD_MASK (1ULL << 4)
83#define PT_ACCESSED_MASK (1ULL << 5)
84#define PT_DIRTY_MASK (1ULL << 6)
85#define PT_PAGE_SIZE_MASK (1ULL << 7)
86#define PT_PAT_MASK (1ULL << 7)
87#define PT_GLOBAL_MASK (1ULL << 8)
88#define PT64_NX_SHIFT 63
89#define PT64_NX_MASK (1ULL << PT64_NX_SHIFT)
90
91#define PT_PAT_SHIFT 7
92#define PT_DIR_PAT_SHIFT 12
93#define PT_DIR_PAT_MASK (1ULL << PT_DIR_PAT_SHIFT)
94
95#define PT32_DIR_PSE36_SIZE 4
96#define PT32_DIR_PSE36_SHIFT 13
97#define PT32_DIR_PSE36_MASK \
98 (((1ULL << PT32_DIR_PSE36_SIZE) - 1) << PT32_DIR_PSE36_SHIFT)
99
100
101#define PT_FIRST_AVAIL_BITS_SHIFT 9
102#define PT64_SECOND_AVAIL_BITS_SHIFT 52
103
104#define PT_SHADOW_IO_MARK (1ULL << PT_FIRST_AVAIL_BITS_SHIFT)
105
106#define VALID_PAGE(x) ((x) != INVALID_PAGE)
107
108#define PT64_LEVEL_BITS 9
109
110#define PT64_LEVEL_SHIFT(level) \
111 (PAGE_SHIFT + (level - 1) * PT64_LEVEL_BITS)
112
113#define PT64_LEVEL_MASK(level) \
114 (((1ULL << PT64_LEVEL_BITS) - 1) << PT64_LEVEL_SHIFT(level))
115
116#define PT64_INDEX(address, level)\
117 (((address) >> PT64_LEVEL_SHIFT(level)) & ((1 << PT64_LEVEL_BITS) - 1))
118
119
120#define PT32_LEVEL_BITS 10
121
122#define PT32_LEVEL_SHIFT(level) \
123 (PAGE_SHIFT + (level - 1) * PT32_LEVEL_BITS)
124
125#define PT32_LEVEL_MASK(level) \
126 (((1ULL << PT32_LEVEL_BITS) - 1) << PT32_LEVEL_SHIFT(level))
127
128#define PT32_INDEX(address, level)\
129 (((address) >> PT32_LEVEL_SHIFT(level)) & ((1 << PT32_LEVEL_BITS) - 1))
130
131
132#define PT64_BASE_ADDR_MASK (((1ULL << 52) - 1) & ~(u64)(PAGE_SIZE-1))
133#define PT64_DIR_BASE_ADDR_MASK \
134 (PT64_BASE_ADDR_MASK & ~((1ULL << (PAGE_SHIFT + PT64_LEVEL_BITS)) - 1))
135
136#define PT32_BASE_ADDR_MASK PAGE_MASK
137#define PT32_DIR_BASE_ADDR_MASK \
138 (PAGE_MASK & ~((1ULL << (PAGE_SHIFT + PT32_LEVEL_BITS)) - 1))
139
140#define PT64_PERM_MASK (PT_PRESENT_MASK | PT_WRITABLE_MASK | PT_USER_MASK \
141 | PT64_NX_MASK)
142
143#define PFERR_PRESENT_MASK (1U << 0)
144#define PFERR_WRITE_MASK (1U << 1)
145#define PFERR_USER_MASK (1U << 2)
146#define PFERR_FETCH_MASK (1U << 4)
147
148#define PT64_ROOT_LEVEL 4
149#define PT32_ROOT_LEVEL 2
150#define PT32E_ROOT_LEVEL 3
151
152#define PT_DIRECTORY_LEVEL 2
153#define PT_PAGE_TABLE_LEVEL 1
154
155#define RMAP_EXT 4
156
157#define ACC_EXEC_MASK 1
158#define ACC_WRITE_MASK PT_WRITABLE_MASK
159#define ACC_USER_MASK PT_USER_MASK
160#define ACC_ALL (ACC_EXEC_MASK | ACC_WRITE_MASK | ACC_USER_MASK)
161
162struct kvm_rmap_desc {
163 u64 *shadow_ptes[RMAP_EXT];
164 struct kvm_rmap_desc *more;
165};
166
167static struct kmem_cache *pte_chain_cache;
168static struct kmem_cache *rmap_desc_cache;
169static struct kmem_cache *mmu_page_header_cache;
170
171static u64 __read_mostly shadow_trap_nonpresent_pte;
172static u64 __read_mostly shadow_notrap_nonpresent_pte;
173
174void kvm_mmu_set_nonpresent_ptes(u64 trap_pte, u64 notrap_pte)
175{
176 shadow_trap_nonpresent_pte = trap_pte;
177 shadow_notrap_nonpresent_pte = notrap_pte;
178}
179EXPORT_SYMBOL_GPL(kvm_mmu_set_nonpresent_ptes);
180
181static int is_write_protection(struct kvm_vcpu *vcpu)
182{
183 return vcpu->arch.cr0 & X86_CR0_WP;
184}
185
186static int is_cpuid_PSE36(void)
187{
188 return 1;
189}
190
191static int is_nx(struct kvm_vcpu *vcpu)
192{
193 return vcpu->arch.shadow_efer & EFER_NX;
194}
195
196static int is_present_pte(unsigned long pte)
197{
198 return pte & PT_PRESENT_MASK;
199}
200
201static int is_shadow_present_pte(u64 pte)
202{
203 pte &= ~PT_SHADOW_IO_MARK;
204 return pte != shadow_trap_nonpresent_pte
205 && pte != shadow_notrap_nonpresent_pte;
206}
207
208static int is_writeble_pte(unsigned long pte)
209{
210 return pte & PT_WRITABLE_MASK;
211}
212
213static int is_dirty_pte(unsigned long pte)
214{
215 return pte & PT_DIRTY_MASK;
216}
217
218static int is_io_pte(unsigned long pte)
219{
220 return pte & PT_SHADOW_IO_MARK;
221}
222
223static int is_rmap_pte(u64 pte)
224{
225 return pte != shadow_trap_nonpresent_pte
226 && pte != shadow_notrap_nonpresent_pte;
227}
228
229static gfn_t pse36_gfn_delta(u32 gpte)
230{
231 int shift = 32 - PT32_DIR_PSE36_SHIFT - PAGE_SHIFT;
232
233 return (gpte & PT32_DIR_PSE36_MASK) << shift;
234}
235
236static void set_shadow_pte(u64 *sptep, u64 spte)
237{
238#ifdef CONFIG_X86_64
239 set_64bit((unsigned long *)sptep, spte);
240#else
241 set_64bit((unsigned long long *)sptep, spte);
242#endif
243}
244
245static int mmu_topup_memory_cache(struct kvm_mmu_memory_cache *cache,
246 struct kmem_cache *base_cache, int min)
247{
248 void *obj;
249
250 if (cache->nobjs >= min)
251 return 0;
252 while (cache->nobjs < ARRAY_SIZE(cache->objects)) {
253 obj = kmem_cache_zalloc(base_cache, GFP_KERNEL);
254 if (!obj)
255 return -ENOMEM;
256 cache->objects[cache->nobjs++] = obj;
257 }
258 return 0;
259}
260
261static void mmu_free_memory_cache(struct kvm_mmu_memory_cache *mc)
262{
263 while (mc->nobjs)
264 kfree(mc->objects[--mc->nobjs]);
265}
266
267static int mmu_topup_memory_cache_page(struct kvm_mmu_memory_cache *cache,
268 int min)
269{
270 struct page *page;
271
272 if (cache->nobjs >= min)
273 return 0;
274 while (cache->nobjs < ARRAY_SIZE(cache->objects)) {
275 page = alloc_page(GFP_KERNEL);
276 if (!page)
277 return -ENOMEM;
278 set_page_private(page, 0);
279 cache->objects[cache->nobjs++] = page_address(page);
280 }
281 return 0;
282}
283
284static void mmu_free_memory_cache_page(struct kvm_mmu_memory_cache *mc)
285{
286 while (mc->nobjs)
287 free_page((unsigned long)mc->objects[--mc->nobjs]);
288}
289
290static int mmu_topup_memory_caches(struct kvm_vcpu *vcpu)
291{
292 int r;
293
294 r = mmu_topup_memory_cache(&vcpu->arch.mmu_pte_chain_cache,
295 pte_chain_cache, 4);
296 if (r)
297 goto out;
298 r = mmu_topup_memory_cache(&vcpu->arch.mmu_rmap_desc_cache,
299 rmap_desc_cache, 1);
300 if (r)
301 goto out;
302 r = mmu_topup_memory_cache_page(&vcpu->arch.mmu_page_cache, 8);
303 if (r)
304 goto out;
305 r = mmu_topup_memory_cache(&vcpu->arch.mmu_page_header_cache,
306 mmu_page_header_cache, 4);
307out:
308 return r;
309}
310
311static void mmu_free_memory_caches(struct kvm_vcpu *vcpu)
312{
313 mmu_free_memory_cache(&vcpu->arch.mmu_pte_chain_cache);
314 mmu_free_memory_cache(&vcpu->arch.mmu_rmap_desc_cache);
315 mmu_free_memory_cache_page(&vcpu->arch.mmu_page_cache);
316 mmu_free_memory_cache(&vcpu->arch.mmu_page_header_cache);
317}
318
319static void *mmu_memory_cache_alloc(struct kvm_mmu_memory_cache *mc,
320 size_t size)
321{
322 void *p;
323
324 BUG_ON(!mc->nobjs);
325 p = mc->objects[--mc->nobjs];
326 memset(p, 0, size);
327 return p;
328}
329
330static struct kvm_pte_chain *mmu_alloc_pte_chain(struct kvm_vcpu *vcpu)
331{
332 return mmu_memory_cache_alloc(&vcpu->arch.mmu_pte_chain_cache,
333 sizeof(struct kvm_pte_chain));
334}
335
336static void mmu_free_pte_chain(struct kvm_pte_chain *pc)
337{
338 kfree(pc);
339}
340
341static struct kvm_rmap_desc *mmu_alloc_rmap_desc(struct kvm_vcpu *vcpu)
342{
343 return mmu_memory_cache_alloc(&vcpu->arch.mmu_rmap_desc_cache,
344 sizeof(struct kvm_rmap_desc));
345}
346
347static void mmu_free_rmap_desc(struct kvm_rmap_desc *rd)
348{
349 kfree(rd);
350}
351
352/*
353 * Take gfn and return the reverse mapping to it.
354 * Note: gfn must be unaliased before this function get called
355 */
356
357static unsigned long *gfn_to_rmap(struct kvm *kvm, gfn_t gfn)
358{
359 struct kvm_memory_slot *slot;
360
361 slot = gfn_to_memslot(kvm, gfn);
362 return &slot->rmap[gfn - slot->base_gfn];
363}
364
365/*
366 * Reverse mapping data structures:
367 *
368 * If rmapp bit zero is zero, then rmapp point to the shadw page table entry
369 * that points to page_address(page).
370 *
371 * If rmapp bit zero is one, (then rmap & ~1) points to a struct kvm_rmap_desc
372 * containing more mappings.
373 */
374static void rmap_add(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn)
375{
376 struct kvm_mmu_page *sp;
377 struct kvm_rmap_desc *desc;
378 unsigned long *rmapp;
379 int i;
380
381 if (!is_rmap_pte(*spte))
382 return;
383 gfn = unalias_gfn(vcpu->kvm, gfn);
384 sp = page_header(__pa(spte));
385 sp->gfns[spte - sp->spt] = gfn;
386 rmapp = gfn_to_rmap(vcpu->kvm, gfn);
387 if (!*rmapp) {
388 rmap_printk("rmap_add: %p %llx 0->1\n", spte, *spte);
389 *rmapp = (unsigned long)spte;
390 } else if (!(*rmapp & 1)) {
391 rmap_printk("rmap_add: %p %llx 1->many\n", spte, *spte);
392 desc = mmu_alloc_rmap_desc(vcpu);
393 desc->shadow_ptes[0] = (u64 *)*rmapp;
394 desc->shadow_ptes[1] = spte;
395 *rmapp = (unsigned long)desc | 1;
396 } else {
397 rmap_printk("rmap_add: %p %llx many->many\n", spte, *spte);
398 desc = (struct kvm_rmap_desc *)(*rmapp & ~1ul);
399 while (desc->shadow_ptes[RMAP_EXT-1] && desc->more)
400 desc = desc->more;
401 if (desc->shadow_ptes[RMAP_EXT-1]) {
402 desc->more = mmu_alloc_rmap_desc(vcpu);
403 desc = desc->more;
404 }
405 for (i = 0; desc->shadow_ptes[i]; ++i)
406 ;
407 desc->shadow_ptes[i] = spte;
408 }
409}
410
411static void rmap_desc_remove_entry(unsigned long *rmapp,
412 struct kvm_rmap_desc *desc,
413 int i,
414 struct kvm_rmap_desc *prev_desc)
415{
416 int j;
417
418 for (j = RMAP_EXT - 1; !desc->shadow_ptes[j] && j > i; --j)
419 ;
420 desc->shadow_ptes[i] = desc->shadow_ptes[j];
421 desc->shadow_ptes[j] = NULL;
422 if (j != 0)
423 return;
424 if (!prev_desc && !desc->more)
425 *rmapp = (unsigned long)desc->shadow_ptes[0];
426 else
427 if (prev_desc)
428 prev_desc->more = desc->more;
429 else
430 *rmapp = (unsigned long)desc->more | 1;
431 mmu_free_rmap_desc(desc);
432}
433
434static void rmap_remove(struct kvm *kvm, u64 *spte)
435{
436 struct kvm_rmap_desc *desc;
437 struct kvm_rmap_desc *prev_desc;
438 struct kvm_mmu_page *sp;
439 struct page *page;
440 unsigned long *rmapp;
441 int i;
442
443 if (!is_rmap_pte(*spte))
444 return;
445 sp = page_header(__pa(spte));
446 page = pfn_to_page((*spte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT);
447 mark_page_accessed(page);
448 if (is_writeble_pte(*spte))
449 kvm_release_page_dirty(page);
450 else
451 kvm_release_page_clean(page);
452 rmapp = gfn_to_rmap(kvm, sp->gfns[spte - sp->spt]);
453 if (!*rmapp) {
454 printk(KERN_ERR "rmap_remove: %p %llx 0->BUG\n", spte, *spte);
455 BUG();
456 } else if (!(*rmapp & 1)) {
457 rmap_printk("rmap_remove: %p %llx 1->0\n", spte, *spte);
458 if ((u64 *)*rmapp != spte) {
459 printk(KERN_ERR "rmap_remove: %p %llx 1->BUG\n",
460 spte, *spte);
461 BUG();
462 }
463 *rmapp = 0;
464 } else {
465 rmap_printk("rmap_remove: %p %llx many->many\n", spte, *spte);
466 desc = (struct kvm_rmap_desc *)(*rmapp & ~1ul);
467 prev_desc = NULL;
468 while (desc) {
469 for (i = 0; i < RMAP_EXT && desc->shadow_ptes[i]; ++i)
470 if (desc->shadow_ptes[i] == spte) {
471 rmap_desc_remove_entry(rmapp,
472 desc, i,
473 prev_desc);
474 return;
475 }
476 prev_desc = desc;
477 desc = desc->more;
478 }
479 BUG();
480 }
481}
482
483static u64 *rmap_next(struct kvm *kvm, unsigned long *rmapp, u64 *spte)
484{
485 struct kvm_rmap_desc *desc;
486 struct kvm_rmap_desc *prev_desc;
487 u64 *prev_spte;
488 int i;
489
490 if (!*rmapp)
491 return NULL;
492 else if (!(*rmapp & 1)) {
493 if (!spte)
494 return (u64 *)*rmapp;
495 return NULL;
496 }
497 desc = (struct kvm_rmap_desc *)(*rmapp & ~1ul);
498 prev_desc = NULL;
499 prev_spte = NULL;
500 while (desc) {
501 for (i = 0; i < RMAP_EXT && desc->shadow_ptes[i]; ++i) {
502 if (prev_spte == spte)
503 return desc->shadow_ptes[i];
504 prev_spte = desc->shadow_ptes[i];
505 }
506 desc = desc->more;
507 }
508 return NULL;
509}
510
511static void rmap_write_protect(struct kvm *kvm, u64 gfn)
512{
513 unsigned long *rmapp;
514 u64 *spte;
515 int write_protected = 0;
516
517 gfn = unalias_gfn(kvm, gfn);
518 rmapp = gfn_to_rmap(kvm, gfn);
519
520 spte = rmap_next(kvm, rmapp, NULL);
521 while (spte) {
522 BUG_ON(!spte);
523 BUG_ON(!(*spte & PT_PRESENT_MASK));
524 rmap_printk("rmap_write_protect: spte %p %llx\n", spte, *spte);
525 if (is_writeble_pte(*spte)) {
526 set_shadow_pte(spte, *spte & ~PT_WRITABLE_MASK);
527 write_protected = 1;
528 }
529 spte = rmap_next(kvm, rmapp, spte);
530 }
531 if (write_protected)
532 kvm_flush_remote_tlbs(kvm);
533}
534
535#ifdef MMU_DEBUG
536static int is_empty_shadow_page(u64 *spt)
537{
538 u64 *pos;
539 u64 *end;
540
541 for (pos = spt, end = pos + PAGE_SIZE / sizeof(u64); pos != end; pos++)
542 if ((*pos & ~PT_SHADOW_IO_MARK) != shadow_trap_nonpresent_pte) {
543 printk(KERN_ERR "%s: %p %llx\n", __FUNCTION__,
544 pos, *pos);
545 return 0;
546 }
547 return 1;
548}
549#endif
550
551static void kvm_mmu_free_page(struct kvm *kvm, struct kvm_mmu_page *sp)
552{
553 ASSERT(is_empty_shadow_page(sp->spt));
554 list_del(&sp->link);
555 __free_page(virt_to_page(sp->spt));
556 __free_page(virt_to_page(sp->gfns));
557 kfree(sp);
558 ++kvm->arch.n_free_mmu_pages;
559}
560
561static unsigned kvm_page_table_hashfn(gfn_t gfn)
562{
563 return gfn;
564}
565
566static struct kvm_mmu_page *kvm_mmu_alloc_page(struct kvm_vcpu *vcpu,
567 u64 *parent_pte)
568{
569 struct kvm_mmu_page *sp;
570
571 sp = mmu_memory_cache_alloc(&vcpu->arch.mmu_page_header_cache, sizeof *sp);
572 sp->spt = mmu_memory_cache_alloc(&vcpu->arch.mmu_page_cache, PAGE_SIZE);
573 sp->gfns = mmu_memory_cache_alloc(&vcpu->arch.mmu_page_cache, PAGE_SIZE);
574 set_page_private(virt_to_page(sp->spt), (unsigned long)sp);
575 list_add(&sp->link, &vcpu->kvm->arch.active_mmu_pages);
576 ASSERT(is_empty_shadow_page(sp->spt));
577 sp->slot_bitmap = 0;
578 sp->multimapped = 0;
579 sp->parent_pte = parent_pte;
580 --vcpu->kvm->arch.n_free_mmu_pages;
581 return sp;
582}
583
584static void mmu_page_add_parent_pte(struct kvm_vcpu *vcpu,
585 struct kvm_mmu_page *sp, u64 *parent_pte)
586{
587 struct kvm_pte_chain *pte_chain;
588 struct hlist_node *node;
589 int i;
590
591 if (!parent_pte)
592 return;
593 if (!sp->multimapped) {
594 u64 *old = sp->parent_pte;
595
596 if (!old) {
597 sp->parent_pte = parent_pte;
598 return;
599 }
600 sp->multimapped = 1;
601 pte_chain = mmu_alloc_pte_chain(vcpu);
602 INIT_HLIST_HEAD(&sp->parent_ptes);
603 hlist_add_head(&pte_chain->link, &sp->parent_ptes);
604 pte_chain->parent_ptes[0] = old;
605 }
606 hlist_for_each_entry(pte_chain, node, &sp->parent_ptes, link) {
607 if (pte_chain->parent_ptes[NR_PTE_CHAIN_ENTRIES-1])
608 continue;
609 for (i = 0; i < NR_PTE_CHAIN_ENTRIES; ++i)
610 if (!pte_chain->parent_ptes[i]) {
611 pte_chain->parent_ptes[i] = parent_pte;
612 return;
613 }
614 }
615 pte_chain = mmu_alloc_pte_chain(vcpu);
616 BUG_ON(!pte_chain);
617 hlist_add_head(&pte_chain->link, &sp->parent_ptes);
618 pte_chain->parent_ptes[0] = parent_pte;
619}
620
621static void mmu_page_remove_parent_pte(struct kvm_mmu_page *sp,
622 u64 *parent_pte)
623{
624 struct kvm_pte_chain *pte_chain;
625 struct hlist_node *node;
626 int i;
627
628 if (!sp->multimapped) {
629 BUG_ON(sp->parent_pte != parent_pte);
630 sp->parent_pte = NULL;
631 return;
632 }
633 hlist_for_each_entry(pte_chain, node, &sp->parent_ptes, link)
634 for (i = 0; i < NR_PTE_CHAIN_ENTRIES; ++i) {
635 if (!pte_chain->parent_ptes[i])
636 break;
637 if (pte_chain->parent_ptes[i] != parent_pte)
638 continue;
639 while (i + 1 < NR_PTE_CHAIN_ENTRIES
640 && pte_chain->parent_ptes[i + 1]) {
641 pte_chain->parent_ptes[i]
642 = pte_chain->parent_ptes[i + 1];
643 ++i;
644 }
645 pte_chain->parent_ptes[i] = NULL;
646 if (i == 0) {
647 hlist_del(&pte_chain->link);
648 mmu_free_pte_chain(pte_chain);
649 if (hlist_empty(&sp->parent_ptes)) {
650 sp->multimapped = 0;
651 sp->parent_pte = NULL;
652 }
653 }
654 return;
655 }
656 BUG();
657}
658
659static struct kvm_mmu_page *kvm_mmu_lookup_page(struct kvm *kvm, gfn_t gfn)
660{
661 unsigned index;
662 struct hlist_head *bucket;
663 struct kvm_mmu_page *sp;
664 struct hlist_node *node;
665
666 pgprintk("%s: looking for gfn %lx\n", __FUNCTION__, gfn);
667 index = kvm_page_table_hashfn(gfn) % KVM_NUM_MMU_PAGES;
668 bucket = &kvm->arch.mmu_page_hash[index];
669 hlist_for_each_entry(sp, node, bucket, hash_link)
670 if (sp->gfn == gfn && !sp->role.metaphysical) {
671 pgprintk("%s: found role %x\n",
672 __FUNCTION__, sp->role.word);
673 return sp;
674 }
675 return NULL;
676}
677
678static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
679 gfn_t gfn,
680 gva_t gaddr,
681 unsigned level,
682 int metaphysical,
683 unsigned access,
684 u64 *parent_pte,
685 bool *new_page)
686{
687 union kvm_mmu_page_role role;
688 unsigned index;
689 unsigned quadrant;
690 struct hlist_head *bucket;
691 struct kvm_mmu_page *sp;
692 struct hlist_node *node;
693
694 role.word = 0;
695 role.glevels = vcpu->arch.mmu.root_level;
696 role.level = level;
697 role.metaphysical = metaphysical;
698 role.access = access;
699 if (vcpu->arch.mmu.root_level <= PT32_ROOT_LEVEL) {
700 quadrant = gaddr >> (PAGE_SHIFT + (PT64_PT_BITS * level));
701 quadrant &= (1 << ((PT32_PT_BITS - PT64_PT_BITS) * level)) - 1;
702 role.quadrant = quadrant;
703 }
704 pgprintk("%s: looking gfn %lx role %x\n", __FUNCTION__,
705 gfn, role.word);
706 index = kvm_page_table_hashfn(gfn) % KVM_NUM_MMU_PAGES;
707 bucket = &vcpu->kvm->arch.mmu_page_hash[index];
708 hlist_for_each_entry(sp, node, bucket, hash_link)
709 if (sp->gfn == gfn && sp->role.word == role.word) {
710 mmu_page_add_parent_pte(vcpu, sp, parent_pte);
711 pgprintk("%s: found\n", __FUNCTION__);
712 return sp;
713 }
714 ++vcpu->kvm->stat.mmu_cache_miss;
715 sp = kvm_mmu_alloc_page(vcpu, parent_pte);
716 if (!sp)
717 return sp;
718 pgprintk("%s: adding gfn %lx role %x\n", __FUNCTION__, gfn, role.word);
719 sp->gfn = gfn;
720 sp->role = role;
721 hlist_add_head(&sp->hash_link, bucket);
722 vcpu->arch.mmu.prefetch_page(vcpu, sp);
723 if (!metaphysical)
724 rmap_write_protect(vcpu->kvm, gfn);
725 if (new_page)
726 *new_page = 1;
727 return sp;
728}
729
730static void kvm_mmu_page_unlink_children(struct kvm *kvm,
731 struct kvm_mmu_page *sp)
732{
733 unsigned i;
734 u64 *pt;
735 u64 ent;
736
737 pt = sp->spt;
738
739 if (sp->role.level == PT_PAGE_TABLE_LEVEL) {
740 for (i = 0; i < PT64_ENT_PER_PAGE; ++i) {
741 if (is_shadow_present_pte(pt[i]))
742 rmap_remove(kvm, &pt[i]);
743 pt[i] = shadow_trap_nonpresent_pte;
744 }
745 kvm_flush_remote_tlbs(kvm);
746 return;
747 }
748
749 for (i = 0; i < PT64_ENT_PER_PAGE; ++i) {
750 ent = pt[i];
751
752 pt[i] = shadow_trap_nonpresent_pte;
753 if (!is_shadow_present_pte(ent))
754 continue;
755 ent &= PT64_BASE_ADDR_MASK;
756 mmu_page_remove_parent_pte(page_header(ent), &pt[i]);
757 }
758 kvm_flush_remote_tlbs(kvm);
759}
760
761static void kvm_mmu_put_page(struct kvm_mmu_page *sp, u64 *parent_pte)
762{
763 mmu_page_remove_parent_pte(sp, parent_pte);
764}
765
766static void kvm_mmu_reset_last_pte_updated(struct kvm *kvm)
767{
768 int i;
769
770 for (i = 0; i < KVM_MAX_VCPUS; ++i)
771 if (kvm->vcpus[i])
772 kvm->vcpus[i]->arch.last_pte_updated = NULL;
773}
774
775static void kvm_mmu_zap_page(struct kvm *kvm, struct kvm_mmu_page *sp)
776{
777 u64 *parent_pte;
778
779 ++kvm->stat.mmu_shadow_zapped;
780 while (sp->multimapped || sp->parent_pte) {
781 if (!sp->multimapped)
782 parent_pte = sp->parent_pte;
783 else {
784 struct kvm_pte_chain *chain;
785
786 chain = container_of(sp->parent_ptes.first,
787 struct kvm_pte_chain, link);
788 parent_pte = chain->parent_ptes[0];
789 }
790 BUG_ON(!parent_pte);
791 kvm_mmu_put_page(sp, parent_pte);
792 set_shadow_pte(parent_pte, shadow_trap_nonpresent_pte);
793 }
794 kvm_mmu_page_unlink_children(kvm, sp);
795 if (!sp->root_count) {
796 hlist_del(&sp->hash_link);
797 kvm_mmu_free_page(kvm, sp);
798 } else
799 list_move(&sp->link, &kvm->arch.active_mmu_pages);
800 kvm_mmu_reset_last_pte_updated(kvm);
801}
802
803/*
804 * Changing the number of mmu pages allocated to the vm
805 * Note: if kvm_nr_mmu_pages is too small, you will get dead lock
806 */
807void kvm_mmu_change_mmu_pages(struct kvm *kvm, unsigned int kvm_nr_mmu_pages)
808{
809 /*
810 * If we set the number of mmu pages to be smaller be than the
811 * number of actived pages , we must to free some mmu pages before we
812 * change the value
813 */
814
815 if ((kvm->arch.n_alloc_mmu_pages - kvm->arch.n_free_mmu_pages) >
816 kvm_nr_mmu_pages) {
817 int n_used_mmu_pages = kvm->arch.n_alloc_mmu_pages
818 - kvm->arch.n_free_mmu_pages;
819
820 while (n_used_mmu_pages > kvm_nr_mmu_pages) {
821 struct kvm_mmu_page *page;
822
823 page = container_of(kvm->arch.active_mmu_pages.prev,
824 struct kvm_mmu_page, link);
825 kvm_mmu_zap_page(kvm, page);
826 n_used_mmu_pages--;
827 }
828 kvm->arch.n_free_mmu_pages = 0;
829 }
830 else
831 kvm->arch.n_free_mmu_pages += kvm_nr_mmu_pages
832 - kvm->arch.n_alloc_mmu_pages;
833
834 kvm->arch.n_alloc_mmu_pages = kvm_nr_mmu_pages;
835}
836
837static int kvm_mmu_unprotect_page(struct kvm *kvm, gfn_t gfn)
838{
839 unsigned index;
840 struct hlist_head *bucket;
841 struct kvm_mmu_page *sp;
842 struct hlist_node *node, *n;
843 int r;
844
845 pgprintk("%s: looking for gfn %lx\n", __FUNCTION__, gfn);
846 r = 0;
847 index = kvm_page_table_hashfn(gfn) % KVM_NUM_MMU_PAGES;
848 bucket = &kvm->arch.mmu_page_hash[index];
849 hlist_for_each_entry_safe(sp, node, n, bucket, hash_link)
850 if (sp->gfn == gfn && !sp->role.metaphysical) {
851 pgprintk("%s: gfn %lx role %x\n", __FUNCTION__, gfn,
852 sp->role.word);
853 kvm_mmu_zap_page(kvm, sp);
854 r = 1;
855 }
856 return r;
857}
858
859static void mmu_unshadow(struct kvm *kvm, gfn_t gfn)
860{
861 struct kvm_mmu_page *sp;
862
863 while ((sp = kvm_mmu_lookup_page(kvm, gfn)) != NULL) {
864 pgprintk("%s: zap %lx %x\n", __FUNCTION__, gfn, sp->role.word);
865 kvm_mmu_zap_page(kvm, sp);
866 }
867}
868
869static void page_header_update_slot(struct kvm *kvm, void *pte, gfn_t gfn)
870{
871 int slot = memslot_id(kvm, gfn_to_memslot(kvm, gfn));
872 struct kvm_mmu_page *sp = page_header(__pa(pte));
873
874 __set_bit(slot, &sp->slot_bitmap);
875}
876
877struct page *gva_to_page(struct kvm_vcpu *vcpu, gva_t gva)
878{
879 gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, gva);
880
881 if (gpa == UNMAPPED_GVA)
882 return NULL;
883 return gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT);
884}
885
886static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
887 unsigned pt_access, unsigned pte_access,
888 int user_fault, int write_fault, int dirty,
889 int *ptwrite, gfn_t gfn, struct page *page)
890{
891 u64 spte;
892 int was_rmapped = is_rmap_pte(*shadow_pte);
893 int was_writeble = is_writeble_pte(*shadow_pte);
894
895 pgprintk("%s: spte %llx access %x write_fault %d"
896 " user_fault %d gfn %lx\n",
897 __FUNCTION__, *shadow_pte, pt_access,
898 write_fault, user_fault, gfn);
899
900 /*
901 * We don't set the accessed bit, since we sometimes want to see
902 * whether the guest actually used the pte (in order to detect
903 * demand paging).
904 */
905 spte = PT_PRESENT_MASK | PT_DIRTY_MASK;
906 if (!dirty)
907 pte_access &= ~ACC_WRITE_MASK;
908 if (!(pte_access & ACC_EXEC_MASK))
909 spte |= PT64_NX_MASK;
910
911 spte |= PT_PRESENT_MASK;
912 if (pte_access & ACC_USER_MASK)
913 spte |= PT_USER_MASK;
914
915 if (is_error_page(page)) {
916 set_shadow_pte(shadow_pte,
917 shadow_trap_nonpresent_pte | PT_SHADOW_IO_MARK);
918 kvm_release_page_clean(page);
919 return;
920 }
921
922 spte |= page_to_phys(page);
923
924 if ((pte_access & ACC_WRITE_MASK)
925 || (write_fault && !is_write_protection(vcpu) && !user_fault)) {
926 struct kvm_mmu_page *shadow;
927
928 spte |= PT_WRITABLE_MASK;
929 if (user_fault) {
930 mmu_unshadow(vcpu->kvm, gfn);
931 goto unshadowed;
932 }
933
934 shadow = kvm_mmu_lookup_page(vcpu->kvm, gfn);
935 if (shadow) {
936 pgprintk("%s: found shadow page for %lx, marking ro\n",
937 __FUNCTION__, gfn);
938 pte_access &= ~ACC_WRITE_MASK;
939 if (is_writeble_pte(spte)) {
940 spte &= ~PT_WRITABLE_MASK;
941 kvm_x86_ops->tlb_flush(vcpu);
942 }
943 if (write_fault)
944 *ptwrite = 1;
945 }
946 }
947
948unshadowed:
949
950 if (pte_access & ACC_WRITE_MASK)
951 mark_page_dirty(vcpu->kvm, gfn);
952
953 pgprintk("%s: setting spte %llx\n", __FUNCTION__, spte);
954 set_shadow_pte(shadow_pte, spte);
955 page_header_update_slot(vcpu->kvm, shadow_pte, gfn);
956 if (!was_rmapped) {
957 rmap_add(vcpu, shadow_pte, gfn);
958 if (!is_rmap_pte(*shadow_pte))
959 kvm_release_page_clean(page);
960 } else {
961 if (was_writeble)
962 kvm_release_page_dirty(page);
963 else
964 kvm_release_page_clean(page);
965 }
966 if (!ptwrite || !*ptwrite)
967 vcpu->arch.last_pte_updated = shadow_pte;
968}
969
970static void nonpaging_new_cr3(struct kvm_vcpu *vcpu)
971{
972}
973
974static int __nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write,
975 gfn_t gfn, struct page *page)
976{
977 int level = PT32E_ROOT_LEVEL;
978 hpa_t table_addr = vcpu->arch.mmu.root_hpa;
979 int pt_write = 0;
980
981 for (; ; level--) {
982 u32 index = PT64_INDEX(v, level);
983 u64 *table;
984
985 ASSERT(VALID_PAGE(table_addr));
986 table = __va(table_addr);
987
988 if (level == 1) {
989 mmu_set_spte(vcpu, &table[index], ACC_ALL, ACC_ALL,
990 0, write, 1, &pt_write, gfn, page);
991 return pt_write || is_io_pte(table[index]);
992 }
993
994 if (table[index] == shadow_trap_nonpresent_pte) {
995 struct kvm_mmu_page *new_table;
996 gfn_t pseudo_gfn;
997
998 pseudo_gfn = (v & PT64_DIR_BASE_ADDR_MASK)
999 >> PAGE_SHIFT;
1000 new_table = kvm_mmu_get_page(vcpu, pseudo_gfn,
1001 v, level - 1,
1002 1, ACC_ALL, &table[index],
1003 NULL);
1004 if (!new_table) {
1005 pgprintk("nonpaging_map: ENOMEM\n");
1006 kvm_release_page_clean(page);
1007 return -ENOMEM;
1008 }
1009
1010 table[index] = __pa(new_table->spt) | PT_PRESENT_MASK
1011 | PT_WRITABLE_MASK | PT_USER_MASK;
1012 }
1013 table_addr = table[index] & PT64_BASE_ADDR_MASK;
1014 }
1015}
1016
1017static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, gfn_t gfn)
1018{
1019 int r;
1020
1021 struct page *page;
1022
1023 down_read(&current->mm->mmap_sem);
1024 page = gfn_to_page(vcpu->kvm, gfn);
1025
1026 spin_lock(&vcpu->kvm->mmu_lock);
1027 kvm_mmu_free_some_pages(vcpu);
1028 r = __nonpaging_map(vcpu, v, write, gfn, page);
1029 spin_unlock(&vcpu->kvm->mmu_lock);
1030
1031 up_read(&current->mm->mmap_sem);
1032
1033 return r;
1034}
1035
1036
1037static void nonpaging_prefetch_page(struct kvm_vcpu *vcpu,
1038 struct kvm_mmu_page *sp)
1039{
1040 int i;
1041
1042 for (i = 0; i < PT64_ENT_PER_PAGE; ++i)
1043 sp->spt[i] = shadow_trap_nonpresent_pte;
1044}
1045
1046static void mmu_free_roots(struct kvm_vcpu *vcpu)
1047{
1048 int i;
1049 struct kvm_mmu_page *sp;
1050
1051 if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
1052 return;
1053 spin_lock(&vcpu->kvm->mmu_lock);
1054#ifdef CONFIG_X86_64
1055 if (vcpu->arch.mmu.shadow_root_level == PT64_ROOT_LEVEL) {
1056 hpa_t root = vcpu->arch.mmu.root_hpa;
1057
1058 sp = page_header(root);
1059 --sp->root_count;
1060 vcpu->arch.mmu.root_hpa = INVALID_PAGE;
1061 spin_unlock(&vcpu->kvm->mmu_lock);
1062 return;
1063 }
1064#endif
1065 for (i = 0; i < 4; ++i) {
1066 hpa_t root = vcpu->arch.mmu.pae_root[i];
1067
1068 if (root) {
1069 root &= PT64_BASE_ADDR_MASK;
1070 sp = page_header(root);
1071 --sp->root_count;
1072 }
1073 vcpu->arch.mmu.pae_root[i] = INVALID_PAGE;
1074 }
1075 spin_unlock(&vcpu->kvm->mmu_lock);
1076 vcpu->arch.mmu.root_hpa = INVALID_PAGE;
1077}
1078
1079static void mmu_alloc_roots(struct kvm_vcpu *vcpu)
1080{
1081 int i;
1082 gfn_t root_gfn;
1083 struct kvm_mmu_page *sp;
1084
1085 root_gfn = vcpu->arch.cr3 >> PAGE_SHIFT;
1086
1087#ifdef CONFIG_X86_64
1088 if (vcpu->arch.mmu.shadow_root_level == PT64_ROOT_LEVEL) {
1089 hpa_t root = vcpu->arch.mmu.root_hpa;
1090
1091 ASSERT(!VALID_PAGE(root));
1092 sp = kvm_mmu_get_page(vcpu, root_gfn, 0,
1093 PT64_ROOT_LEVEL, 0, ACC_ALL, NULL, NULL);
1094 root = __pa(sp->spt);
1095 ++sp->root_count;
1096 vcpu->arch.mmu.root_hpa = root;
1097 return;
1098 }
1099#endif
1100 for (i = 0; i < 4; ++i) {
1101 hpa_t root = vcpu->arch.mmu.pae_root[i];
1102
1103 ASSERT(!VALID_PAGE(root));
1104 if (vcpu->arch.mmu.root_level == PT32E_ROOT_LEVEL) {
1105 if (!is_present_pte(vcpu->arch.pdptrs[i])) {
1106 vcpu->arch.mmu.pae_root[i] = 0;
1107 continue;
1108 }
1109 root_gfn = vcpu->arch.pdptrs[i] >> PAGE_SHIFT;
1110 } else if (vcpu->arch.mmu.root_level == 0)
1111 root_gfn = 0;
1112 sp = kvm_mmu_get_page(vcpu, root_gfn, i << 30,
1113 PT32_ROOT_LEVEL, !is_paging(vcpu),
1114 ACC_ALL, NULL, NULL);
1115 root = __pa(sp->spt);
1116 ++sp->root_count;
1117 vcpu->arch.mmu.pae_root[i] = root | PT_PRESENT_MASK;
1118 }
1119 vcpu->arch.mmu.root_hpa = __pa(vcpu->arch.mmu.pae_root);
1120}
1121
1122static gpa_t nonpaging_gva_to_gpa(struct kvm_vcpu *vcpu, gva_t vaddr)
1123{
1124 return vaddr;
1125}
1126
1127static int nonpaging_page_fault(struct kvm_vcpu *vcpu, gva_t gva,
1128 u32 error_code)
1129{
1130 gfn_t gfn;
1131 int r;
1132
1133 pgprintk("%s: gva %lx error %x\n", __FUNCTION__, gva, error_code);
1134 r = mmu_topup_memory_caches(vcpu);
1135 if (r)
1136 return r;
1137
1138 ASSERT(vcpu);
1139 ASSERT(VALID_PAGE(vcpu->arch.mmu.root_hpa));
1140
1141 gfn = gva >> PAGE_SHIFT;
1142
1143 return nonpaging_map(vcpu, gva & PAGE_MASK,
1144 error_code & PFERR_WRITE_MASK, gfn);
1145}
1146
1147static void nonpaging_free(struct kvm_vcpu *vcpu)
1148{
1149 mmu_free_roots(vcpu);
1150}
1151
1152static int nonpaging_init_context(struct kvm_vcpu *vcpu)
1153{
1154 struct kvm_mmu *context = &vcpu->arch.mmu;
1155
1156 context->new_cr3 = nonpaging_new_cr3;
1157 context->page_fault = nonpaging_page_fault;
1158 context->gva_to_gpa = nonpaging_gva_to_gpa;
1159 context->free = nonpaging_free;
1160 context->prefetch_page = nonpaging_prefetch_page;
1161 context->root_level = 0;
1162 context->shadow_root_level = PT32E_ROOT_LEVEL;
1163 context->root_hpa = INVALID_PAGE;
1164 return 0;
1165}
1166
1167void kvm_mmu_flush_tlb(struct kvm_vcpu *vcpu)
1168{
1169 ++vcpu->stat.tlb_flush;
1170 kvm_x86_ops->tlb_flush(vcpu);
1171}
1172
1173static void paging_new_cr3(struct kvm_vcpu *vcpu)
1174{
1175 pgprintk("%s: cr3 %lx\n", __FUNCTION__, vcpu->cr3);
1176 mmu_free_roots(vcpu);
1177}
1178
1179static void inject_page_fault(struct kvm_vcpu *vcpu,
1180 u64 addr,
1181 u32 err_code)
1182{
1183 kvm_inject_page_fault(vcpu, addr, err_code);
1184}
1185
1186static void paging_free(struct kvm_vcpu *vcpu)
1187{
1188 nonpaging_free(vcpu);
1189}
1190
1191#define PTTYPE 64
1192#include "paging_tmpl.h"
1193#undef PTTYPE
1194
1195#define PTTYPE 32
1196#include "paging_tmpl.h"
1197#undef PTTYPE
1198
1199static int paging64_init_context_common(struct kvm_vcpu *vcpu, int level)
1200{
1201 struct kvm_mmu *context = &vcpu->arch.mmu;
1202
1203 ASSERT(is_pae(vcpu));
1204 context->new_cr3 = paging_new_cr3;
1205 context->page_fault = paging64_page_fault;
1206 context->gva_to_gpa = paging64_gva_to_gpa;
1207 context->prefetch_page = paging64_prefetch_page;
1208 context->free = paging_free;
1209 context->root_level = level;
1210 context->shadow_root_level = level;
1211 context->root_hpa = INVALID_PAGE;
1212 return 0;
1213}
1214
1215static int paging64_init_context(struct kvm_vcpu *vcpu)
1216{
1217 return paging64_init_context_common(vcpu, PT64_ROOT_LEVEL);
1218}
1219
1220static int paging32_init_context(struct kvm_vcpu *vcpu)
1221{
1222 struct kvm_mmu *context = &vcpu->arch.mmu;
1223
1224 context->new_cr3 = paging_new_cr3;
1225 context->page_fault = paging32_page_fault;
1226 context->gva_to_gpa = paging32_gva_to_gpa;
1227 context->free = paging_free;
1228 context->prefetch_page = paging32_prefetch_page;
1229 context->root_level = PT32_ROOT_LEVEL;
1230 context->shadow_root_level = PT32E_ROOT_LEVEL;
1231 context->root_hpa = INVALID_PAGE;
1232 return 0;
1233}
1234
1235static int paging32E_init_context(struct kvm_vcpu *vcpu)
1236{
1237 return paging64_init_context_common(vcpu, PT32E_ROOT_LEVEL);
1238}
1239
1240static int init_kvm_mmu(struct kvm_vcpu *vcpu)
1241{
1242 ASSERT(vcpu);
1243 ASSERT(!VALID_PAGE(vcpu->arch.mmu.root_hpa));
1244
1245 if (!is_paging(vcpu))
1246 return nonpaging_init_context(vcpu);
1247 else if (is_long_mode(vcpu))
1248 return paging64_init_context(vcpu);
1249 else if (is_pae(vcpu))
1250 return paging32E_init_context(vcpu);
1251 else
1252 return paging32_init_context(vcpu);
1253}
1254
1255static void destroy_kvm_mmu(struct kvm_vcpu *vcpu)
1256{
1257 ASSERT(vcpu);
1258 if (VALID_PAGE(vcpu->arch.mmu.root_hpa)) {
1259 vcpu->arch.mmu.free(vcpu);
1260 vcpu->arch.mmu.root_hpa = INVALID_PAGE;
1261 }
1262}
1263
1264int kvm_mmu_reset_context(struct kvm_vcpu *vcpu)
1265{
1266 destroy_kvm_mmu(vcpu);
1267 return init_kvm_mmu(vcpu);
1268}
1269EXPORT_SYMBOL_GPL(kvm_mmu_reset_context);
1270
1271int kvm_mmu_load(struct kvm_vcpu *vcpu)
1272{
1273 int r;
1274
1275 r = mmu_topup_memory_caches(vcpu);
1276 if (r)
1277 goto out;
1278 spin_lock(&vcpu->kvm->mmu_lock);
1279 kvm_mmu_free_some_pages(vcpu);
1280 mmu_alloc_roots(vcpu);
1281 spin_unlock(&vcpu->kvm->mmu_lock);
1282 kvm_x86_ops->set_cr3(vcpu, vcpu->arch.mmu.root_hpa);
1283 kvm_mmu_flush_tlb(vcpu);
1284out:
1285 return r;
1286}
1287EXPORT_SYMBOL_GPL(kvm_mmu_load);
1288
1289void kvm_mmu_unload(struct kvm_vcpu *vcpu)
1290{
1291 mmu_free_roots(vcpu);
1292}
1293
1294static void mmu_pte_write_zap_pte(struct kvm_vcpu *vcpu,
1295 struct kvm_mmu_page *sp,
1296 u64 *spte)
1297{
1298 u64 pte;
1299 struct kvm_mmu_page *child;
1300
1301 pte = *spte;
1302 if (is_shadow_present_pte(pte)) {
1303 if (sp->role.level == PT_PAGE_TABLE_LEVEL)
1304 rmap_remove(vcpu->kvm, spte);
1305 else {
1306 child = page_header(pte & PT64_BASE_ADDR_MASK);
1307 mmu_page_remove_parent_pte(child, spte);
1308 }
1309 }
1310 set_shadow_pte(spte, shadow_trap_nonpresent_pte);
1311}
1312
1313static void mmu_pte_write_new_pte(struct kvm_vcpu *vcpu,
1314 struct kvm_mmu_page *sp,
1315 u64 *spte,
1316 const void *new, int bytes,
1317 int offset_in_pte)
1318{
1319 if (sp->role.level != PT_PAGE_TABLE_LEVEL) {
1320 ++vcpu->kvm->stat.mmu_pde_zapped;
1321 return;
1322 }
1323
1324 ++vcpu->kvm->stat.mmu_pte_updated;
1325 if (sp->role.glevels == PT32_ROOT_LEVEL)
1326 paging32_update_pte(vcpu, sp, spte, new, bytes, offset_in_pte);
1327 else
1328 paging64_update_pte(vcpu, sp, spte, new, bytes, offset_in_pte);
1329}
1330
1331static bool need_remote_flush(u64 old, u64 new)
1332{
1333 if (!is_shadow_present_pte(old))
1334 return false;
1335 if (!is_shadow_present_pte(new))
1336 return true;
1337 if ((old ^ new) & PT64_BASE_ADDR_MASK)
1338 return true;
1339 old ^= PT64_NX_MASK;
1340 new ^= PT64_NX_MASK;
1341 return (old & ~new & PT64_PERM_MASK) != 0;
1342}
1343
1344static void mmu_pte_write_flush_tlb(struct kvm_vcpu *vcpu, u64 old, u64 new)
1345{
1346 if (need_remote_flush(old, new))
1347 kvm_flush_remote_tlbs(vcpu->kvm);
1348 else
1349 kvm_mmu_flush_tlb(vcpu);
1350}
1351
1352static bool last_updated_pte_accessed(struct kvm_vcpu *vcpu)
1353{
1354 u64 *spte = vcpu->arch.last_pte_updated;
1355
1356 return !!(spte && (*spte & PT_ACCESSED_MASK));
1357}
1358
1359static void mmu_guess_page_from_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
1360 const u8 *new, int bytes)
1361{
1362 gfn_t gfn;
1363 int r;
1364 u64 gpte = 0;
1365
1366 if (bytes != 4 && bytes != 8)
1367 return;
1368
1369 /*
1370 * Assume that the pte write on a page table of the same type
1371 * as the current vcpu paging mode. This is nearly always true
1372 * (might be false while changing modes). Note it is verified later
1373 * by update_pte().
1374 */
1375 if (is_pae(vcpu)) {
1376 /* Handle a 32-bit guest writing two halves of a 64-bit gpte */
1377 if ((bytes == 4) && (gpa % 4 == 0)) {
1378 r = kvm_read_guest(vcpu->kvm, gpa & ~(u64)7, &gpte, 8);
1379 if (r)
1380 return;
1381 memcpy((void *)&gpte + (gpa % 8), new, 4);
1382 } else if ((bytes == 8) && (gpa % 8 == 0)) {
1383 memcpy((void *)&gpte, new, 8);
1384 }
1385 } else {
1386 if ((bytes == 4) && (gpa % 4 == 0))
1387 memcpy((void *)&gpte, new, 4);
1388 }
1389 if (!is_present_pte(gpte))
1390 return;
1391 gfn = (gpte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT;
1392 vcpu->arch.update_pte.gfn = gfn;
1393 vcpu->arch.update_pte.page = gfn_to_page(vcpu->kvm, gfn);
1394}
1395
1396void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
1397 const u8 *new, int bytes)
1398{
1399 gfn_t gfn = gpa >> PAGE_SHIFT;
1400 struct kvm_mmu_page *sp;
1401 struct hlist_node *node, *n;
1402 struct hlist_head *bucket;
1403 unsigned index;
1404 u64 entry;
1405 u64 *spte;
1406 unsigned offset = offset_in_page(gpa);
1407 unsigned pte_size;
1408 unsigned page_offset;
1409 unsigned misaligned;
1410 unsigned quadrant;
1411 int level;
1412 int flooded = 0;
1413 int npte;
1414
1415 pgprintk("%s: gpa %llx bytes %d\n", __FUNCTION__, gpa, bytes);
1416 mmu_guess_page_from_pte_write(vcpu, gpa, new, bytes);
1417 spin_lock(&vcpu->kvm->mmu_lock);
1418 kvm_mmu_free_some_pages(vcpu);
1419 ++vcpu->kvm->stat.mmu_pte_write;
1420 kvm_mmu_audit(vcpu, "pre pte write");
1421 if (gfn == vcpu->arch.last_pt_write_gfn
1422 && !last_updated_pte_accessed(vcpu)) {
1423 ++vcpu->arch.last_pt_write_count;
1424 if (vcpu->arch.last_pt_write_count >= 3)
1425 flooded = 1;
1426 } else {
1427 vcpu->arch.last_pt_write_gfn = gfn;
1428 vcpu->arch.last_pt_write_count = 1;
1429 vcpu->arch.last_pte_updated = NULL;
1430 }
1431 index = kvm_page_table_hashfn(gfn) % KVM_NUM_MMU_PAGES;
1432 bucket = &vcpu->kvm->arch.mmu_page_hash[index];
1433 hlist_for_each_entry_safe(sp, node, n, bucket, hash_link) {
1434 if (sp->gfn != gfn || sp->role.metaphysical)
1435 continue;
1436 pte_size = sp->role.glevels == PT32_ROOT_LEVEL ? 4 : 8;
1437 misaligned = (offset ^ (offset + bytes - 1)) & ~(pte_size - 1);
1438 misaligned |= bytes < 4;
1439 if (misaligned || flooded) {
1440 /*
1441 * Misaligned accesses are too much trouble to fix
1442 * up; also, they usually indicate a page is not used
1443 * as a page table.
1444 *
1445 * If we're seeing too many writes to a page,
1446 * it may no longer be a page table, or we may be
1447 * forking, in which case it is better to unmap the
1448 * page.
1449 */
1450 pgprintk("misaligned: gpa %llx bytes %d role %x\n",
1451 gpa, bytes, sp->role.word);
1452 kvm_mmu_zap_page(vcpu->kvm, sp);
1453 ++vcpu->kvm->stat.mmu_flooded;
1454 continue;
1455 }
1456 page_offset = offset;
1457 level = sp->role.level;
1458 npte = 1;
1459 if (sp->role.glevels == PT32_ROOT_LEVEL) {
1460 page_offset <<= 1; /* 32->64 */
1461 /*
1462 * A 32-bit pde maps 4MB while the shadow pdes map
1463 * only 2MB. So we need to double the offset again
1464 * and zap two pdes instead of one.
1465 */
1466 if (level == PT32_ROOT_LEVEL) {
1467 page_offset &= ~7; /* kill rounding error */
1468 page_offset <<= 1;
1469 npte = 2;
1470 }
1471 quadrant = page_offset >> PAGE_SHIFT;
1472 page_offset &= ~PAGE_MASK;
1473 if (quadrant != sp->role.quadrant)
1474 continue;
1475 }
1476 spte = &sp->spt[page_offset / sizeof(*spte)];
1477 while (npte--) {
1478 entry = *spte;
1479 mmu_pte_write_zap_pte(vcpu, sp, spte);
1480 mmu_pte_write_new_pte(vcpu, sp, spte, new, bytes,
1481 page_offset & (pte_size - 1));
1482 mmu_pte_write_flush_tlb(vcpu, entry, *spte);
1483 ++spte;
1484 }
1485 }
1486 kvm_mmu_audit(vcpu, "post pte write");
1487 spin_unlock(&vcpu->kvm->mmu_lock);
1488 if (vcpu->arch.update_pte.page) {
1489 kvm_release_page_clean(vcpu->arch.update_pte.page);
1490 vcpu->arch.update_pte.page = NULL;
1491 }
1492}
1493
1494int kvm_mmu_unprotect_page_virt(struct kvm_vcpu *vcpu, gva_t gva)
1495{
1496 gpa_t gpa;
1497 int r;
1498
1499 down_read(&current->mm->mmap_sem);
1500 gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, gva);
1501 up_read(&current->mm->mmap_sem);
1502
1503 spin_lock(&vcpu->kvm->mmu_lock);
1504 r = kvm_mmu_unprotect_page(vcpu->kvm, gpa >> PAGE_SHIFT);
1505 spin_unlock(&vcpu->kvm->mmu_lock);
1506 return r;
1507}
1508
1509void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu)
1510{
1511 while (vcpu->kvm->arch.n_free_mmu_pages < KVM_REFILL_PAGES) {
1512 struct kvm_mmu_page *sp;
1513
1514 sp = container_of(vcpu->kvm->arch.active_mmu_pages.prev,
1515 struct kvm_mmu_page, link);
1516 kvm_mmu_zap_page(vcpu->kvm, sp);
1517 ++vcpu->kvm->stat.mmu_recycled;
1518 }
1519}
1520
1521int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t cr2, u32 error_code)
1522{
1523 int r;
1524 enum emulation_result er;
1525
1526 r = vcpu->arch.mmu.page_fault(vcpu, cr2, error_code);
1527 if (r < 0)
1528 goto out;
1529
1530 if (!r) {
1531 r = 1;
1532 goto out;
1533 }
1534
1535 r = mmu_topup_memory_caches(vcpu);
1536 if (r)
1537 goto out;
1538
1539 er = emulate_instruction(vcpu, vcpu->run, cr2, error_code, 0);
1540
1541 switch (er) {
1542 case EMULATE_DONE:
1543 return 1;
1544 case EMULATE_DO_MMIO:
1545 ++vcpu->stat.mmio_exits;
1546 return 0;
1547 case EMULATE_FAIL:
1548 kvm_report_emulation_failure(vcpu, "pagetable");
1549 return 1;
1550 default:
1551 BUG();
1552 }
1553out:
1554 return r;
1555}
1556EXPORT_SYMBOL_GPL(kvm_mmu_page_fault);
1557
1558static void free_mmu_pages(struct kvm_vcpu *vcpu)
1559{
1560 struct kvm_mmu_page *sp;
1561
1562 while (!list_empty(&vcpu->kvm->arch.active_mmu_pages)) {
1563 sp = container_of(vcpu->kvm->arch.active_mmu_pages.next,
1564 struct kvm_mmu_page, link);
1565 kvm_mmu_zap_page(vcpu->kvm, sp);
1566 }
1567 free_page((unsigned long)vcpu->arch.mmu.pae_root);
1568}
1569
1570static int alloc_mmu_pages(struct kvm_vcpu *vcpu)
1571{
1572 struct page *page;
1573 int i;
1574
1575 ASSERT(vcpu);
1576
1577 if (vcpu->kvm->arch.n_requested_mmu_pages)
1578 vcpu->kvm->arch.n_free_mmu_pages =
1579 vcpu->kvm->arch.n_requested_mmu_pages;
1580 else
1581 vcpu->kvm->arch.n_free_mmu_pages =
1582 vcpu->kvm->arch.n_alloc_mmu_pages;
1583 /*
1584 * When emulating 32-bit mode, cr3 is only 32 bits even on x86_64.
1585 * Therefore we need to allocate shadow page tables in the first
1586 * 4GB of memory, which happens to fit the DMA32 zone.
1587 */
1588 page = alloc_page(GFP_KERNEL | __GFP_DMA32);
1589 if (!page)
1590 goto error_1;
1591 vcpu->arch.mmu.pae_root = page_address(page);
1592 for (i = 0; i < 4; ++i)
1593 vcpu->arch.mmu.pae_root[i] = INVALID_PAGE;
1594
1595 return 0;
1596
1597error_1:
1598 free_mmu_pages(vcpu);
1599 return -ENOMEM;
1600}
1601
1602int kvm_mmu_create(struct kvm_vcpu *vcpu)
1603{
1604 ASSERT(vcpu);
1605 ASSERT(!VALID_PAGE(vcpu->arch.mmu.root_hpa));
1606
1607 return alloc_mmu_pages(vcpu);
1608}
1609
1610int kvm_mmu_setup(struct kvm_vcpu *vcpu)
1611{
1612 ASSERT(vcpu);
1613 ASSERT(!VALID_PAGE(vcpu->arch.mmu.root_hpa));
1614
1615 return init_kvm_mmu(vcpu);
1616}
1617
1618void kvm_mmu_destroy(struct kvm_vcpu *vcpu)
1619{
1620 ASSERT(vcpu);
1621
1622 destroy_kvm_mmu(vcpu);
1623 free_mmu_pages(vcpu);
1624 mmu_free_memory_caches(vcpu);
1625}
1626
1627void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot)
1628{
1629 struct kvm_mmu_page *sp;
1630
1631 list_for_each_entry(sp, &kvm->arch.active_mmu_pages, link) {
1632 int i;
1633 u64 *pt;
1634
1635 if (!test_bit(slot, &sp->slot_bitmap))
1636 continue;
1637
1638 pt = sp->spt;
1639 for (i = 0; i < PT64_ENT_PER_PAGE; ++i)
1640 /* avoid RMW */
1641 if (pt[i] & PT_WRITABLE_MASK)
1642 pt[i] &= ~PT_WRITABLE_MASK;
1643 }
1644}
1645
1646void kvm_mmu_zap_all(struct kvm *kvm)
1647{
1648 struct kvm_mmu_page *sp, *node;
1649
1650 spin_lock(&kvm->mmu_lock);
1651 list_for_each_entry_safe(sp, node, &kvm->arch.active_mmu_pages, link)
1652 kvm_mmu_zap_page(kvm, sp);
1653 spin_unlock(&kvm->mmu_lock);
1654
1655 kvm_flush_remote_tlbs(kvm);
1656}
1657
1658void kvm_mmu_module_exit(void)
1659{
1660 if (pte_chain_cache)
1661 kmem_cache_destroy(pte_chain_cache);
1662 if (rmap_desc_cache)
1663 kmem_cache_destroy(rmap_desc_cache);
1664 if (mmu_page_header_cache)
1665 kmem_cache_destroy(mmu_page_header_cache);
1666}
1667
1668int kvm_mmu_module_init(void)
1669{
1670 pte_chain_cache = kmem_cache_create("kvm_pte_chain",
1671 sizeof(struct kvm_pte_chain),
1672 0, 0, NULL);
1673 if (!pte_chain_cache)
1674 goto nomem;
1675 rmap_desc_cache = kmem_cache_create("kvm_rmap_desc",
1676 sizeof(struct kvm_rmap_desc),
1677 0, 0, NULL);
1678 if (!rmap_desc_cache)
1679 goto nomem;
1680
1681 mmu_page_header_cache = kmem_cache_create("kvm_mmu_page_header",
1682 sizeof(struct kvm_mmu_page),
1683 0, 0, NULL);
1684 if (!mmu_page_header_cache)
1685 goto nomem;
1686
1687 return 0;
1688
1689nomem:
1690 kvm_mmu_module_exit();
1691 return -ENOMEM;
1692}
1693
1694/*
1695 * Caculate mmu pages needed for kvm.
1696 */
1697unsigned int kvm_mmu_calculate_mmu_pages(struct kvm *kvm)
1698{
1699 int i;
1700 unsigned int nr_mmu_pages;
1701 unsigned int nr_pages = 0;
1702
1703 for (i = 0; i < kvm->nmemslots; i++)
1704 nr_pages += kvm->memslots[i].npages;
1705
1706 nr_mmu_pages = nr_pages * KVM_PERMILLE_MMU_PAGES / 1000;
1707 nr_mmu_pages = max(nr_mmu_pages,
1708 (unsigned int) KVM_MIN_ALLOC_MMU_PAGES);
1709
1710 return nr_mmu_pages;
1711}
1712
1713#ifdef AUDIT
1714
1715static const char *audit_msg;
1716
1717static gva_t canonicalize(gva_t gva)
1718{
1719#ifdef CONFIG_X86_64
1720 gva = (long long)(gva << 16) >> 16;
1721#endif
1722 return gva;
1723}
1724
1725static void audit_mappings_page(struct kvm_vcpu *vcpu, u64 page_pte,
1726 gva_t va, int level)
1727{
1728 u64 *pt = __va(page_pte & PT64_BASE_ADDR_MASK);
1729 int i;
1730 gva_t va_delta = 1ul << (PAGE_SHIFT + 9 * (level - 1));
1731
1732 for (i = 0; i < PT64_ENT_PER_PAGE; ++i, va += va_delta) {
1733 u64 ent = pt[i];
1734
1735 if (ent == shadow_trap_nonpresent_pte)
1736 continue;
1737
1738 va = canonicalize(va);
1739 if (level > 1) {
1740 if (ent == shadow_notrap_nonpresent_pte)
1741 printk(KERN_ERR "audit: (%s) nontrapping pte"
1742 " in nonleaf level: levels %d gva %lx"
1743 " level %d pte %llx\n", audit_msg,
1744 vcpu->arch.mmu.root_level, va, level, ent);
1745
1746 audit_mappings_page(vcpu, ent, va, level - 1);
1747 } else {
1748 gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, va);
1749 struct page *page = gpa_to_page(vcpu, gpa);
1750 hpa_t hpa = page_to_phys(page);
1751
1752 if (is_shadow_present_pte(ent)
1753 && (ent & PT64_BASE_ADDR_MASK) != hpa)
1754 printk(KERN_ERR "xx audit error: (%s) levels %d"
1755 " gva %lx gpa %llx hpa %llx ent %llx %d\n",
1756 audit_msg, vcpu->arch.mmu.root_level,
1757 va, gpa, hpa, ent,
1758 is_shadow_present_pte(ent));
1759 else if (ent == shadow_notrap_nonpresent_pte
1760 && !is_error_hpa(hpa))
1761 printk(KERN_ERR "audit: (%s) notrap shadow,"
1762 " valid guest gva %lx\n", audit_msg, va);
1763 kvm_release_page_clean(page);
1764
1765 }
1766 }
1767}
1768
1769static void audit_mappings(struct kvm_vcpu *vcpu)
1770{
1771 unsigned i;
1772
1773 if (vcpu->arch.mmu.root_level == 4)
1774 audit_mappings_page(vcpu, vcpu->arch.mmu.root_hpa, 0, 4);
1775 else
1776 for (i = 0; i < 4; ++i)
1777 if (vcpu->arch.mmu.pae_root[i] & PT_PRESENT_MASK)
1778 audit_mappings_page(vcpu,
1779 vcpu->arch.mmu.pae_root[i],
1780 i << 30,
1781 2);
1782}
1783
1784static int count_rmaps(struct kvm_vcpu *vcpu)
1785{
1786 int nmaps = 0;
1787 int i, j, k;
1788
1789 for (i = 0; i < KVM_MEMORY_SLOTS; ++i) {
1790 struct kvm_memory_slot *m = &vcpu->kvm->memslots[i];
1791 struct kvm_rmap_desc *d;
1792
1793 for (j = 0; j < m->npages; ++j) {
1794 unsigned long *rmapp = &m->rmap[j];
1795
1796 if (!*rmapp)
1797 continue;
1798 if (!(*rmapp & 1)) {
1799 ++nmaps;
1800 continue;
1801 }
1802 d = (struct kvm_rmap_desc *)(*rmapp & ~1ul);
1803 while (d) {
1804 for (k = 0; k < RMAP_EXT; ++k)
1805 if (d->shadow_ptes[k])
1806 ++nmaps;
1807 else
1808 break;
1809 d = d->more;
1810 }
1811 }
1812 }
1813 return nmaps;
1814}
1815
1816static int count_writable_mappings(struct kvm_vcpu *vcpu)
1817{
1818 int nmaps = 0;
1819 struct kvm_mmu_page *sp;
1820 int i;
1821
1822 list_for_each_entry(sp, &vcpu->kvm->arch.active_mmu_pages, link) {
1823 u64 *pt = sp->spt;
1824
1825 if (sp->role.level != PT_PAGE_TABLE_LEVEL)
1826 continue;
1827
1828 for (i = 0; i < PT64_ENT_PER_PAGE; ++i) {
1829 u64 ent = pt[i];
1830
1831 if (!(ent & PT_PRESENT_MASK))
1832 continue;
1833 if (!(ent & PT_WRITABLE_MASK))
1834 continue;
1835 ++nmaps;
1836 }
1837 }
1838 return nmaps;
1839}
1840
1841static void audit_rmap(struct kvm_vcpu *vcpu)
1842{
1843 int n_rmap = count_rmaps(vcpu);
1844 int n_actual = count_writable_mappings(vcpu);
1845
1846 if (n_rmap != n_actual)
1847 printk(KERN_ERR "%s: (%s) rmap %d actual %d\n",
1848 __FUNCTION__, audit_msg, n_rmap, n_actual);
1849}
1850
1851static void audit_write_protection(struct kvm_vcpu *vcpu)
1852{
1853 struct kvm_mmu_page *sp;
1854 struct kvm_memory_slot *slot;
1855 unsigned long *rmapp;
1856 gfn_t gfn;
1857
1858 list_for_each_entry(sp, &vcpu->kvm->arch.active_mmu_pages, link) {
1859 if (sp->role.metaphysical)
1860 continue;
1861
1862 slot = gfn_to_memslot(vcpu->kvm, sp->gfn);
1863 gfn = unalias_gfn(vcpu->kvm, sp->gfn);
1864 rmapp = &slot->rmap[gfn - slot->base_gfn];
1865 if (*rmapp)
1866 printk(KERN_ERR "%s: (%s) shadow page has writable"
1867 " mappings: gfn %lx role %x\n",
1868 __FUNCTION__, audit_msg, sp->gfn,
1869 sp->role.word);
1870 }
1871}
1872
1873static void kvm_mmu_audit(struct kvm_vcpu *vcpu, const char *msg)
1874{
1875 int olddbg = dbg;
1876
1877 dbg = 0;
1878 audit_msg = msg;
1879 audit_rmap(vcpu);
1880 audit_write_protection(vcpu);
1881 audit_mappings(vcpu);
1882 dbg = olddbg;
1883}
1884
1885#endif
diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h
new file mode 100644
index 000000000000..1fce19ec7a23
--- /dev/null
+++ b/arch/x86/kvm/mmu.h
@@ -0,0 +1,44 @@
1#ifndef __KVM_X86_MMU_H
2#define __KVM_X86_MMU_H
3
4#include <linux/kvm_host.h>
5
6static inline void kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu)
7{
8 if (unlikely(vcpu->kvm->arch.n_free_mmu_pages < KVM_MIN_FREE_MMU_PAGES))
9 __kvm_mmu_free_some_pages(vcpu);
10}
11
12static inline int kvm_mmu_reload(struct kvm_vcpu *vcpu)
13{
14 if (likely(vcpu->arch.mmu.root_hpa != INVALID_PAGE))
15 return 0;
16
17 return kvm_mmu_load(vcpu);
18}
19
20static inline int is_long_mode(struct kvm_vcpu *vcpu)
21{
22#ifdef CONFIG_X86_64
23 return vcpu->arch.shadow_efer & EFER_LME;
24#else
25 return 0;
26#endif
27}
28
29static inline int is_pae(struct kvm_vcpu *vcpu)
30{
31 return vcpu->arch.cr4 & X86_CR4_PAE;
32}
33
34static inline int is_pse(struct kvm_vcpu *vcpu)
35{
36 return vcpu->arch.cr4 & X86_CR4_PSE;
37}
38
39static inline int is_paging(struct kvm_vcpu *vcpu)
40{
41 return vcpu->arch.cr0 & X86_CR0_PG;
42}
43
44#endif
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
new file mode 100644
index 000000000000..03ba8608fe0f
--- /dev/null
+++ b/arch/x86/kvm/paging_tmpl.h
@@ -0,0 +1,484 @@
1/*
2 * Kernel-based Virtual Machine driver for Linux
3 *
4 * This module enables machines with Intel VT-x extensions to run virtual
5 * machines without emulation or binary translation.
6 *
7 * MMU support
8 *
9 * Copyright (C) 2006 Qumranet, Inc.
10 *
11 * Authors:
12 * Yaniv Kamay <yaniv@qumranet.com>
13 * Avi Kivity <avi@qumranet.com>
14 *
15 * This work is licensed under the terms of the GNU GPL, version 2. See
16 * the COPYING file in the top-level directory.
17 *
18 */
19
20/*
21 * We need the mmu code to access both 32-bit and 64-bit guest ptes,
22 * so the code in this file is compiled twice, once per pte size.
23 */
24
25#if PTTYPE == 64
26 #define pt_element_t u64
27 #define guest_walker guest_walker64
28 #define FNAME(name) paging##64_##name
29 #define PT_BASE_ADDR_MASK PT64_BASE_ADDR_MASK
30 #define PT_DIR_BASE_ADDR_MASK PT64_DIR_BASE_ADDR_MASK
31 #define PT_INDEX(addr, level) PT64_INDEX(addr, level)
32 #define SHADOW_PT_INDEX(addr, level) PT64_INDEX(addr, level)
33 #define PT_LEVEL_MASK(level) PT64_LEVEL_MASK(level)
34 #define PT_LEVEL_BITS PT64_LEVEL_BITS
35 #ifdef CONFIG_X86_64
36 #define PT_MAX_FULL_LEVELS 4
37 #define CMPXCHG cmpxchg
38 #else
39 #define CMPXCHG cmpxchg64
40 #define PT_MAX_FULL_LEVELS 2
41 #endif
42#elif PTTYPE == 32
43 #define pt_element_t u32
44 #define guest_walker guest_walker32
45 #define FNAME(name) paging##32_##name
46 #define PT_BASE_ADDR_MASK PT32_BASE_ADDR_MASK
47 #define PT_DIR_BASE_ADDR_MASK PT32_DIR_BASE_ADDR_MASK
48 #define PT_INDEX(addr, level) PT32_INDEX(addr, level)
49 #define SHADOW_PT_INDEX(addr, level) PT64_INDEX(addr, level)
50 #define PT_LEVEL_MASK(level) PT32_LEVEL_MASK(level)
51 #define PT_LEVEL_BITS PT32_LEVEL_BITS
52 #define PT_MAX_FULL_LEVELS 2
53 #define CMPXCHG cmpxchg
54#else
55 #error Invalid PTTYPE value
56#endif
57
58#define gpte_to_gfn FNAME(gpte_to_gfn)
59#define gpte_to_gfn_pde FNAME(gpte_to_gfn_pde)
60
61/*
62 * The guest_walker structure emulates the behavior of the hardware page
63 * table walker.
64 */
65struct guest_walker {
66 int level;
67 gfn_t table_gfn[PT_MAX_FULL_LEVELS];
68 pt_element_t ptes[PT_MAX_FULL_LEVELS];
69 gpa_t pte_gpa[PT_MAX_FULL_LEVELS];
70 unsigned pt_access;
71 unsigned pte_access;
72 gfn_t gfn;
73 u32 error_code;
74};
75
76static gfn_t gpte_to_gfn(pt_element_t gpte)
77{
78 return (gpte & PT_BASE_ADDR_MASK) >> PAGE_SHIFT;
79}
80
81static gfn_t gpte_to_gfn_pde(pt_element_t gpte)
82{
83 return (gpte & PT_DIR_BASE_ADDR_MASK) >> PAGE_SHIFT;
84}
85
86static bool FNAME(cmpxchg_gpte)(struct kvm *kvm,
87 gfn_t table_gfn, unsigned index,
88 pt_element_t orig_pte, pt_element_t new_pte)
89{
90 pt_element_t ret;
91 pt_element_t *table;
92 struct page *page;
93
94 page = gfn_to_page(kvm, table_gfn);
95 table = kmap_atomic(page, KM_USER0);
96
97 ret = CMPXCHG(&table[index], orig_pte, new_pte);
98
99 kunmap_atomic(table, KM_USER0);
100
101 kvm_release_page_dirty(page);
102
103 return (ret != orig_pte);
104}
105
106static unsigned FNAME(gpte_access)(struct kvm_vcpu *vcpu, pt_element_t gpte)
107{
108 unsigned access;
109
110 access = (gpte & (PT_WRITABLE_MASK | PT_USER_MASK)) | ACC_EXEC_MASK;
111#if PTTYPE == 64
112 if (is_nx(vcpu))
113 access &= ~(gpte >> PT64_NX_SHIFT);
114#endif
115 return access;
116}
117
118/*
119 * Fetch a guest pte for a guest virtual address
120 */
121static int FNAME(walk_addr)(struct guest_walker *walker,
122 struct kvm_vcpu *vcpu, gva_t addr,
123 int write_fault, int user_fault, int fetch_fault)
124{
125 pt_element_t pte;
126 gfn_t table_gfn;
127 unsigned index, pt_access, pte_access;
128 gpa_t pte_gpa;
129
130 pgprintk("%s: addr %lx\n", __FUNCTION__, addr);
131walk:
132 walker->level = vcpu->arch.mmu.root_level;
133 pte = vcpu->arch.cr3;
134#if PTTYPE == 64
135 if (!is_long_mode(vcpu)) {
136 pte = vcpu->arch.pdptrs[(addr >> 30) & 3];
137 if (!is_present_pte(pte))
138 goto not_present;
139 --walker->level;
140 }
141#endif
142 ASSERT((!is_long_mode(vcpu) && is_pae(vcpu)) ||
143 (vcpu->cr3 & CR3_NONPAE_RESERVED_BITS) == 0);
144
145 pt_access = ACC_ALL;
146
147 for (;;) {
148 index = PT_INDEX(addr, walker->level);
149
150 table_gfn = gpte_to_gfn(pte);
151 pte_gpa = gfn_to_gpa(table_gfn);
152 pte_gpa += index * sizeof(pt_element_t);
153 walker->table_gfn[walker->level - 1] = table_gfn;
154 walker->pte_gpa[walker->level - 1] = pte_gpa;
155 pgprintk("%s: table_gfn[%d] %lx\n", __FUNCTION__,
156 walker->level - 1, table_gfn);
157
158 kvm_read_guest(vcpu->kvm, pte_gpa, &pte, sizeof(pte));
159
160 if (!is_present_pte(pte))
161 goto not_present;
162
163 if (write_fault && !is_writeble_pte(pte))
164 if (user_fault || is_write_protection(vcpu))
165 goto access_error;
166
167 if (user_fault && !(pte & PT_USER_MASK))
168 goto access_error;
169
170#if PTTYPE == 64
171 if (fetch_fault && is_nx(vcpu) && (pte & PT64_NX_MASK))
172 goto access_error;
173#endif
174
175 if (!(pte & PT_ACCESSED_MASK)) {
176 mark_page_dirty(vcpu->kvm, table_gfn);
177 if (FNAME(cmpxchg_gpte)(vcpu->kvm, table_gfn,
178 index, pte, pte|PT_ACCESSED_MASK))
179 goto walk;
180 pte |= PT_ACCESSED_MASK;
181 }
182
183 pte_access = pt_access & FNAME(gpte_access)(vcpu, pte);
184
185 walker->ptes[walker->level - 1] = pte;
186
187 if (walker->level == PT_PAGE_TABLE_LEVEL) {
188 walker->gfn = gpte_to_gfn(pte);
189 break;
190 }
191
192 if (walker->level == PT_DIRECTORY_LEVEL
193 && (pte & PT_PAGE_SIZE_MASK)
194 && (PTTYPE == 64 || is_pse(vcpu))) {
195 walker->gfn = gpte_to_gfn_pde(pte);
196 walker->gfn += PT_INDEX(addr, PT_PAGE_TABLE_LEVEL);
197 if (PTTYPE == 32 && is_cpuid_PSE36())
198 walker->gfn += pse36_gfn_delta(pte);
199 break;
200 }
201
202 pt_access = pte_access;
203 --walker->level;
204 }
205
206 if (write_fault && !is_dirty_pte(pte)) {
207 bool ret;
208
209 mark_page_dirty(vcpu->kvm, table_gfn);
210 ret = FNAME(cmpxchg_gpte)(vcpu->kvm, table_gfn, index, pte,
211 pte|PT_DIRTY_MASK);
212 if (ret)
213 goto walk;
214 pte |= PT_DIRTY_MASK;
215 kvm_mmu_pte_write(vcpu, pte_gpa, (u8 *)&pte, sizeof(pte));
216 walker->ptes[walker->level - 1] = pte;
217 }
218
219 walker->pt_access = pt_access;
220 walker->pte_access = pte_access;
221 pgprintk("%s: pte %llx pte_access %x pt_access %x\n",
222 __FUNCTION__, (u64)pte, pt_access, pte_access);
223 return 1;
224
225not_present:
226 walker->error_code = 0;
227 goto err;
228
229access_error:
230 walker->error_code = PFERR_PRESENT_MASK;
231
232err:
233 if (write_fault)
234 walker->error_code |= PFERR_WRITE_MASK;
235 if (user_fault)
236 walker->error_code |= PFERR_USER_MASK;
237 if (fetch_fault)
238 walker->error_code |= PFERR_FETCH_MASK;
239 return 0;
240}
241
242static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page,
243 u64 *spte, const void *pte, int bytes,
244 int offset_in_pte)
245{
246 pt_element_t gpte;
247 unsigned pte_access;
248 struct page *npage;
249
250 gpte = *(const pt_element_t *)pte;
251 if (~gpte & (PT_PRESENT_MASK | PT_ACCESSED_MASK)) {
252 if (!offset_in_pte && !is_present_pte(gpte))
253 set_shadow_pte(spte, shadow_notrap_nonpresent_pte);
254 return;
255 }
256 if (bytes < sizeof(pt_element_t))
257 return;
258 pgprintk("%s: gpte %llx spte %p\n", __FUNCTION__, (u64)gpte, spte);
259 pte_access = page->role.access & FNAME(gpte_access)(vcpu, gpte);
260 if (gpte_to_gfn(gpte) != vcpu->arch.update_pte.gfn)
261 return;
262 npage = vcpu->arch.update_pte.page;
263 if (!npage)
264 return;
265 get_page(npage);
266 mmu_set_spte(vcpu, spte, page->role.access, pte_access, 0, 0,
267 gpte & PT_DIRTY_MASK, NULL, gpte_to_gfn(gpte), npage);
268}
269
270/*
271 * Fetch a shadow pte for a specific level in the paging hierarchy.
272 */
273static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
274 struct guest_walker *walker,
275 int user_fault, int write_fault, int *ptwrite,
276 struct page *page)
277{
278 hpa_t shadow_addr;
279 int level;
280 u64 *shadow_ent;
281 unsigned access = walker->pt_access;
282
283 if (!is_present_pte(walker->ptes[walker->level - 1]))
284 return NULL;
285
286 shadow_addr = vcpu->arch.mmu.root_hpa;
287 level = vcpu->arch.mmu.shadow_root_level;
288 if (level == PT32E_ROOT_LEVEL) {
289 shadow_addr = vcpu->arch.mmu.pae_root[(addr >> 30) & 3];
290 shadow_addr &= PT64_BASE_ADDR_MASK;
291 --level;
292 }
293
294 for (; ; level--) {
295 u32 index = SHADOW_PT_INDEX(addr, level);
296 struct kvm_mmu_page *shadow_page;
297 u64 shadow_pte;
298 int metaphysical;
299 gfn_t table_gfn;
300 bool new_page = 0;
301
302 shadow_ent = ((u64 *)__va(shadow_addr)) + index;
303 if (level == PT_PAGE_TABLE_LEVEL)
304 break;
305 if (is_shadow_present_pte(*shadow_ent)) {
306 shadow_addr = *shadow_ent & PT64_BASE_ADDR_MASK;
307 continue;
308 }
309
310 if (level - 1 == PT_PAGE_TABLE_LEVEL
311 && walker->level == PT_DIRECTORY_LEVEL) {
312 metaphysical = 1;
313 if (!is_dirty_pte(walker->ptes[level - 1]))
314 access &= ~ACC_WRITE_MASK;
315 table_gfn = gpte_to_gfn(walker->ptes[level - 1]);
316 } else {
317 metaphysical = 0;
318 table_gfn = walker->table_gfn[level - 2];
319 }
320 shadow_page = kvm_mmu_get_page(vcpu, table_gfn, addr, level-1,
321 metaphysical, access,
322 shadow_ent, &new_page);
323 if (new_page && !metaphysical) {
324 int r;
325 pt_element_t curr_pte;
326 r = kvm_read_guest_atomic(vcpu->kvm,
327 walker->pte_gpa[level - 2],
328 &curr_pte, sizeof(curr_pte));
329 if (r || curr_pte != walker->ptes[level - 2]) {
330 kvm_release_page_clean(page);
331 return NULL;
332 }
333 }
334 shadow_addr = __pa(shadow_page->spt);
335 shadow_pte = shadow_addr | PT_PRESENT_MASK | PT_ACCESSED_MASK
336 | PT_WRITABLE_MASK | PT_USER_MASK;
337 *shadow_ent = shadow_pte;
338 }
339
340 mmu_set_spte(vcpu, shadow_ent, access, walker->pte_access & access,
341 user_fault, write_fault,
342 walker->ptes[walker->level-1] & PT_DIRTY_MASK,
343 ptwrite, walker->gfn, page);
344
345 return shadow_ent;
346}
347
348/*
349 * Page fault handler. There are several causes for a page fault:
350 * - there is no shadow pte for the guest pte
351 * - write access through a shadow pte marked read only so that we can set
352 * the dirty bit
353 * - write access to a shadow pte marked read only so we can update the page
354 * dirty bitmap, when userspace requests it
355 * - mmio access; in this case we will never install a present shadow pte
356 * - normal guest page fault due to the guest pte marked not present, not
357 * writable, or not executable
358 *
359 * Returns: 1 if we need to emulate the instruction, 0 otherwise, or
360 * a negative value on error.
361 */
362static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
363 u32 error_code)
364{
365 int write_fault = error_code & PFERR_WRITE_MASK;
366 int user_fault = error_code & PFERR_USER_MASK;
367 int fetch_fault = error_code & PFERR_FETCH_MASK;
368 struct guest_walker walker;
369 u64 *shadow_pte;
370 int write_pt = 0;
371 int r;
372 struct page *page;
373
374 pgprintk("%s: addr %lx err %x\n", __FUNCTION__, addr, error_code);
375 kvm_mmu_audit(vcpu, "pre page fault");
376
377 r = mmu_topup_memory_caches(vcpu);
378 if (r)
379 return r;
380
381 down_read(&current->mm->mmap_sem);
382 /*
383 * Look up the shadow pte for the faulting address.
384 */
385 r = FNAME(walk_addr)(&walker, vcpu, addr, write_fault, user_fault,
386 fetch_fault);
387
388 /*
389 * The page is not mapped by the guest. Let the guest handle it.
390 */
391 if (!r) {
392 pgprintk("%s: guest page fault\n", __FUNCTION__);
393 inject_page_fault(vcpu, addr, walker.error_code);
394 vcpu->arch.last_pt_write_count = 0; /* reset fork detector */
395 up_read(&current->mm->mmap_sem);
396 return 0;
397 }
398
399 page = gfn_to_page(vcpu->kvm, walker.gfn);
400
401 spin_lock(&vcpu->kvm->mmu_lock);
402 kvm_mmu_free_some_pages(vcpu);
403 shadow_pte = FNAME(fetch)(vcpu, addr, &walker, user_fault, write_fault,
404 &write_pt, page);
405 pgprintk("%s: shadow pte %p %llx ptwrite %d\n", __FUNCTION__,
406 shadow_pte, *shadow_pte, write_pt);
407
408 if (!write_pt)
409 vcpu->arch.last_pt_write_count = 0; /* reset fork detector */
410
411 /*
412 * mmio: emulate if accessible, otherwise its a guest fault.
413 */
414 if (shadow_pte && is_io_pte(*shadow_pte)) {
415 spin_unlock(&vcpu->kvm->mmu_lock);
416 up_read(&current->mm->mmap_sem);
417 return 1;
418 }
419
420 ++vcpu->stat.pf_fixed;
421 kvm_mmu_audit(vcpu, "post page fault (fixed)");
422 spin_unlock(&vcpu->kvm->mmu_lock);
423 up_read(&current->mm->mmap_sem);
424
425 return write_pt;
426}
427
428static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr)
429{
430 struct guest_walker walker;
431 gpa_t gpa = UNMAPPED_GVA;
432 int r;
433
434 r = FNAME(walk_addr)(&walker, vcpu, vaddr, 0, 0, 0);
435
436 if (r) {
437 gpa = gfn_to_gpa(walker.gfn);
438 gpa |= vaddr & ~PAGE_MASK;
439 }
440
441 return gpa;
442}
443
444static void FNAME(prefetch_page)(struct kvm_vcpu *vcpu,
445 struct kvm_mmu_page *sp)
446{
447 int i, offset = 0, r = 0;
448 pt_element_t pt;
449
450 if (sp->role.metaphysical
451 || (PTTYPE == 32 && sp->role.level > PT_PAGE_TABLE_LEVEL)) {
452 nonpaging_prefetch_page(vcpu, sp);
453 return;
454 }
455
456 if (PTTYPE == 32)
457 offset = sp->role.quadrant << PT64_LEVEL_BITS;
458
459 for (i = 0; i < PT64_ENT_PER_PAGE; ++i) {
460 gpa_t pte_gpa = gfn_to_gpa(sp->gfn);
461 pte_gpa += (i+offset) * sizeof(pt_element_t);
462
463 r = kvm_read_guest_atomic(vcpu->kvm, pte_gpa, &pt,
464 sizeof(pt_element_t));
465 if (r || is_present_pte(pt))
466 sp->spt[i] = shadow_trap_nonpresent_pte;
467 else
468 sp->spt[i] = shadow_notrap_nonpresent_pte;
469 }
470}
471
472#undef pt_element_t
473#undef guest_walker
474#undef FNAME
475#undef PT_BASE_ADDR_MASK
476#undef PT_INDEX
477#undef SHADOW_PT_INDEX
478#undef PT_LEVEL_MASK
479#undef PT_DIR_BASE_ADDR_MASK
480#undef PT_LEVEL_BITS
481#undef PT_MAX_FULL_LEVELS
482#undef gpte_to_gfn
483#undef gpte_to_gfn_pde
484#undef CMPXCHG
diff --git a/arch/x86/kvm/segment_descriptor.h b/arch/x86/kvm/segment_descriptor.h
new file mode 100644
index 000000000000..56fc4c873389
--- /dev/null
+++ b/arch/x86/kvm/segment_descriptor.h
@@ -0,0 +1,29 @@
1#ifndef __SEGMENT_DESCRIPTOR_H
2#define __SEGMENT_DESCRIPTOR_H
3
4struct segment_descriptor {
5 u16 limit_low;
6 u16 base_low;
7 u8 base_mid;
8 u8 type : 4;
9 u8 system : 1;
10 u8 dpl : 2;
11 u8 present : 1;
12 u8 limit_high : 4;
13 u8 avl : 1;
14 u8 long_mode : 1;
15 u8 default_op : 1;
16 u8 granularity : 1;
17 u8 base_high;
18} __attribute__((packed));
19
20#ifdef CONFIG_X86_64
21/* LDT or TSS descriptor in the GDT. 16 bytes. */
22struct segment_descriptor_64 {
23 struct segment_descriptor s;
24 u32 base_higher;
25 u32 pad_zero;
26};
27
28#endif
29#endif
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
new file mode 100644
index 000000000000..de755cb1431d
--- /dev/null
+++ b/arch/x86/kvm/svm.c
@@ -0,0 +1,1731 @@
1/*
2 * Kernel-based Virtual Machine driver for Linux
3 *
4 * AMD SVM support
5 *
6 * Copyright (C) 2006 Qumranet, Inc.
7 *
8 * Authors:
9 * Yaniv Kamay <yaniv@qumranet.com>
10 * Avi Kivity <avi@qumranet.com>
11 *
12 * This work is licensed under the terms of the GNU GPL, version 2. See
13 * the COPYING file in the top-level directory.
14 *
15 */
16#include <linux/kvm_host.h>
17
18#include "kvm_svm.h"
19#include "irq.h"
20#include "mmu.h"
21
22#include <linux/module.h>
23#include <linux/kernel.h>
24#include <linux/vmalloc.h>
25#include <linux/highmem.h>
26#include <linux/sched.h>
27
28#include <asm/desc.h>
29
30MODULE_AUTHOR("Qumranet");
31MODULE_LICENSE("GPL");
32
33#define IOPM_ALLOC_ORDER 2
34#define MSRPM_ALLOC_ORDER 1
35
36#define DB_VECTOR 1
37#define UD_VECTOR 6
38#define GP_VECTOR 13
39
40#define DR7_GD_MASK (1 << 13)
41#define DR6_BD_MASK (1 << 13)
42
43#define SEG_TYPE_LDT 2
44#define SEG_TYPE_BUSY_TSS16 3
45
46#define SVM_FEATURE_NPT (1 << 0)
47#define SVM_FEATURE_LBRV (1 << 1)
48#define SVM_DEATURE_SVML (1 << 2)
49
50static void kvm_reput_irq(struct vcpu_svm *svm);
51
52static inline struct vcpu_svm *to_svm(struct kvm_vcpu *vcpu)
53{
54 return container_of(vcpu, struct vcpu_svm, vcpu);
55}
56
57unsigned long iopm_base;
58unsigned long msrpm_base;
59
60struct kvm_ldttss_desc {
61 u16 limit0;
62 u16 base0;
63 unsigned base1 : 8, type : 5, dpl : 2, p : 1;
64 unsigned limit1 : 4, zero0 : 3, g : 1, base2 : 8;
65 u32 base3;
66 u32 zero1;
67} __attribute__((packed));
68
69struct svm_cpu_data {
70 int cpu;
71
72 u64 asid_generation;
73 u32 max_asid;
74 u32 next_asid;
75 struct kvm_ldttss_desc *tss_desc;
76
77 struct page *save_area;
78};
79
80static DEFINE_PER_CPU(struct svm_cpu_data *, svm_data);
81static uint32_t svm_features;
82
83struct svm_init_data {
84 int cpu;
85 int r;
86};
87
88static u32 msrpm_ranges[] = {0, 0xc0000000, 0xc0010000};
89
90#define NUM_MSR_MAPS ARRAY_SIZE(msrpm_ranges)
91#define MSRS_RANGE_SIZE 2048
92#define MSRS_IN_RANGE (MSRS_RANGE_SIZE * 8 / 2)
93
94#define MAX_INST_SIZE 15
95
96static inline u32 svm_has(u32 feat)
97{
98 return svm_features & feat;
99}
100
101static inline u8 pop_irq(struct kvm_vcpu *vcpu)
102{
103 int word_index = __ffs(vcpu->arch.irq_summary);
104 int bit_index = __ffs(vcpu->arch.irq_pending[word_index]);
105 int irq = word_index * BITS_PER_LONG + bit_index;
106
107 clear_bit(bit_index, &vcpu->arch.irq_pending[word_index]);
108 if (!vcpu->arch.irq_pending[word_index])
109 clear_bit(word_index, &vcpu->arch.irq_summary);
110 return irq;
111}
112
113static inline void push_irq(struct kvm_vcpu *vcpu, u8 irq)
114{
115 set_bit(irq, vcpu->arch.irq_pending);
116 set_bit(irq / BITS_PER_LONG, &vcpu->arch.irq_summary);
117}
118
119static inline void clgi(void)
120{
121 asm volatile (SVM_CLGI);
122}
123
124static inline void stgi(void)
125{
126 asm volatile (SVM_STGI);
127}
128
129static inline void invlpga(unsigned long addr, u32 asid)
130{
131 asm volatile (SVM_INVLPGA :: "a"(addr), "c"(asid));
132}
133
134static inline unsigned long kvm_read_cr2(void)
135{
136 unsigned long cr2;
137
138 asm volatile ("mov %%cr2, %0" : "=r" (cr2));
139 return cr2;
140}
141
142static inline void kvm_write_cr2(unsigned long val)
143{
144 asm volatile ("mov %0, %%cr2" :: "r" (val));
145}
146
147static inline unsigned long read_dr6(void)
148{
149 unsigned long dr6;
150
151 asm volatile ("mov %%dr6, %0" : "=r" (dr6));
152 return dr6;
153}
154
155static inline void write_dr6(unsigned long val)
156{
157 asm volatile ("mov %0, %%dr6" :: "r" (val));
158}
159
160static inline unsigned long read_dr7(void)
161{
162 unsigned long dr7;
163
164 asm volatile ("mov %%dr7, %0" : "=r" (dr7));
165 return dr7;
166}
167
168static inline void write_dr7(unsigned long val)
169{
170 asm volatile ("mov %0, %%dr7" :: "r" (val));
171}
172
173static inline void force_new_asid(struct kvm_vcpu *vcpu)
174{
175 to_svm(vcpu)->asid_generation--;
176}
177
178static inline void flush_guest_tlb(struct kvm_vcpu *vcpu)
179{
180 force_new_asid(vcpu);
181}
182
183static void svm_set_efer(struct kvm_vcpu *vcpu, u64 efer)
184{
185 if (!(efer & EFER_LMA))
186 efer &= ~EFER_LME;
187
188 to_svm(vcpu)->vmcb->save.efer = efer | MSR_EFER_SVME_MASK;
189 vcpu->arch.shadow_efer = efer;
190}
191
192static void svm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
193 bool has_error_code, u32 error_code)
194{
195 struct vcpu_svm *svm = to_svm(vcpu);
196
197 svm->vmcb->control.event_inj = nr
198 | SVM_EVTINJ_VALID
199 | (has_error_code ? SVM_EVTINJ_VALID_ERR : 0)
200 | SVM_EVTINJ_TYPE_EXEPT;
201 svm->vmcb->control.event_inj_err = error_code;
202}
203
204static bool svm_exception_injected(struct kvm_vcpu *vcpu)
205{
206 struct vcpu_svm *svm = to_svm(vcpu);
207
208 return !(svm->vmcb->control.exit_int_info & SVM_EXITINTINFO_VALID);
209}
210
211static int is_external_interrupt(u32 info)
212{
213 info &= SVM_EVTINJ_TYPE_MASK | SVM_EVTINJ_VALID;
214 return info == (SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_INTR);
215}
216
217static void skip_emulated_instruction(struct kvm_vcpu *vcpu)
218{
219 struct vcpu_svm *svm = to_svm(vcpu);
220
221 if (!svm->next_rip) {
222 printk(KERN_DEBUG "%s: NOP\n", __FUNCTION__);
223 return;
224 }
225 if (svm->next_rip - svm->vmcb->save.rip > MAX_INST_SIZE)
226 printk(KERN_ERR "%s: ip 0x%llx next 0x%llx\n",
227 __FUNCTION__,
228 svm->vmcb->save.rip,
229 svm->next_rip);
230
231 vcpu->arch.rip = svm->vmcb->save.rip = svm->next_rip;
232 svm->vmcb->control.int_state &= ~SVM_INTERRUPT_SHADOW_MASK;
233
234 vcpu->arch.interrupt_window_open = 1;
235}
236
237static int has_svm(void)
238{
239 uint32_t eax, ebx, ecx, edx;
240
241 if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) {
242 printk(KERN_INFO "has_svm: not amd\n");
243 return 0;
244 }
245
246 cpuid(0x80000000, &eax, &ebx, &ecx, &edx);
247 if (eax < SVM_CPUID_FUNC) {
248 printk(KERN_INFO "has_svm: can't execute cpuid_8000000a\n");
249 return 0;
250 }
251
252 cpuid(0x80000001, &eax, &ebx, &ecx, &edx);
253 if (!(ecx & (1 << SVM_CPUID_FEATURE_SHIFT))) {
254 printk(KERN_DEBUG "has_svm: svm not available\n");
255 return 0;
256 }
257 return 1;
258}
259
260static void svm_hardware_disable(void *garbage)
261{
262 struct svm_cpu_data *svm_data
263 = per_cpu(svm_data, raw_smp_processor_id());
264
265 if (svm_data) {
266 uint64_t efer;
267
268 wrmsrl(MSR_VM_HSAVE_PA, 0);
269 rdmsrl(MSR_EFER, efer);
270 wrmsrl(MSR_EFER, efer & ~MSR_EFER_SVME_MASK);
271 per_cpu(svm_data, raw_smp_processor_id()) = NULL;
272 __free_page(svm_data->save_area);
273 kfree(svm_data);
274 }
275}
276
277static void svm_hardware_enable(void *garbage)
278{
279
280 struct svm_cpu_data *svm_data;
281 uint64_t efer;
282#ifdef CONFIG_X86_64
283 struct desc_ptr gdt_descr;
284#else
285 struct desc_ptr gdt_descr;
286#endif
287 struct desc_struct *gdt;
288 int me = raw_smp_processor_id();
289
290 if (!has_svm()) {
291 printk(KERN_ERR "svm_cpu_init: err EOPNOTSUPP on %d\n", me);
292 return;
293 }
294 svm_data = per_cpu(svm_data, me);
295
296 if (!svm_data) {
297 printk(KERN_ERR "svm_cpu_init: svm_data is NULL on %d\n",
298 me);
299 return;
300 }
301
302 svm_data->asid_generation = 1;
303 svm_data->max_asid = cpuid_ebx(SVM_CPUID_FUNC) - 1;
304 svm_data->next_asid = svm_data->max_asid + 1;
305 svm_features = cpuid_edx(SVM_CPUID_FUNC);
306
307 asm volatile ("sgdt %0" : "=m"(gdt_descr));
308 gdt = (struct desc_struct *)gdt_descr.address;
309 svm_data->tss_desc = (struct kvm_ldttss_desc *)(gdt + GDT_ENTRY_TSS);
310
311 rdmsrl(MSR_EFER, efer);
312 wrmsrl(MSR_EFER, efer | MSR_EFER_SVME_MASK);
313
314 wrmsrl(MSR_VM_HSAVE_PA,
315 page_to_pfn(svm_data->save_area) << PAGE_SHIFT);
316}
317
318static int svm_cpu_init(int cpu)
319{
320 struct svm_cpu_data *svm_data;
321 int r;
322
323 svm_data = kzalloc(sizeof(struct svm_cpu_data), GFP_KERNEL);
324 if (!svm_data)
325 return -ENOMEM;
326 svm_data->cpu = cpu;
327 svm_data->save_area = alloc_page(GFP_KERNEL);
328 r = -ENOMEM;
329 if (!svm_data->save_area)
330 goto err_1;
331
332 per_cpu(svm_data, cpu) = svm_data;
333
334 return 0;
335
336err_1:
337 kfree(svm_data);
338 return r;
339
340}
341
342static void set_msr_interception(u32 *msrpm, unsigned msr,
343 int read, int write)
344{
345 int i;
346
347 for (i = 0; i < NUM_MSR_MAPS; i++) {
348 if (msr >= msrpm_ranges[i] &&
349 msr < msrpm_ranges[i] + MSRS_IN_RANGE) {
350 u32 msr_offset = (i * MSRS_IN_RANGE + msr -
351 msrpm_ranges[i]) * 2;
352
353 u32 *base = msrpm + (msr_offset / 32);
354 u32 msr_shift = msr_offset % 32;
355 u32 mask = ((write) ? 0 : 2) | ((read) ? 0 : 1);
356 *base = (*base & ~(0x3 << msr_shift)) |
357 (mask << msr_shift);
358 return;
359 }
360 }
361 BUG();
362}
363
364static __init int svm_hardware_setup(void)
365{
366 int cpu;
367 struct page *iopm_pages;
368 struct page *msrpm_pages;
369 void *iopm_va, *msrpm_va;
370 int r;
371
372 iopm_pages = alloc_pages(GFP_KERNEL, IOPM_ALLOC_ORDER);
373
374 if (!iopm_pages)
375 return -ENOMEM;
376
377 iopm_va = page_address(iopm_pages);
378 memset(iopm_va, 0xff, PAGE_SIZE * (1 << IOPM_ALLOC_ORDER));
379 clear_bit(0x80, iopm_va); /* allow direct access to PC debug port */
380 iopm_base = page_to_pfn(iopm_pages) << PAGE_SHIFT;
381
382
383 msrpm_pages = alloc_pages(GFP_KERNEL, MSRPM_ALLOC_ORDER);
384
385 r = -ENOMEM;
386 if (!msrpm_pages)
387 goto err_1;
388
389 msrpm_va = page_address(msrpm_pages);
390 memset(msrpm_va, 0xff, PAGE_SIZE * (1 << MSRPM_ALLOC_ORDER));
391 msrpm_base = page_to_pfn(msrpm_pages) << PAGE_SHIFT;
392
393#ifdef CONFIG_X86_64
394 set_msr_interception(msrpm_va, MSR_GS_BASE, 1, 1);
395 set_msr_interception(msrpm_va, MSR_FS_BASE, 1, 1);
396 set_msr_interception(msrpm_va, MSR_KERNEL_GS_BASE, 1, 1);
397 set_msr_interception(msrpm_va, MSR_LSTAR, 1, 1);
398 set_msr_interception(msrpm_va, MSR_CSTAR, 1, 1);
399 set_msr_interception(msrpm_va, MSR_SYSCALL_MASK, 1, 1);
400#endif
401 set_msr_interception(msrpm_va, MSR_K6_STAR, 1, 1);
402 set_msr_interception(msrpm_va, MSR_IA32_SYSENTER_CS, 1, 1);
403 set_msr_interception(msrpm_va, MSR_IA32_SYSENTER_ESP, 1, 1);
404 set_msr_interception(msrpm_va, MSR_IA32_SYSENTER_EIP, 1, 1);
405
406 for_each_online_cpu(cpu) {
407 r = svm_cpu_init(cpu);
408 if (r)
409 goto err_2;
410 }
411 return 0;
412
413err_2:
414 __free_pages(msrpm_pages, MSRPM_ALLOC_ORDER);
415 msrpm_base = 0;
416err_1:
417 __free_pages(iopm_pages, IOPM_ALLOC_ORDER);
418 iopm_base = 0;
419 return r;
420}
421
422static __exit void svm_hardware_unsetup(void)
423{
424 __free_pages(pfn_to_page(msrpm_base >> PAGE_SHIFT), MSRPM_ALLOC_ORDER);
425 __free_pages(pfn_to_page(iopm_base >> PAGE_SHIFT), IOPM_ALLOC_ORDER);
426 iopm_base = msrpm_base = 0;
427}
428
429static void init_seg(struct vmcb_seg *seg)
430{
431 seg->selector = 0;
432 seg->attrib = SVM_SELECTOR_P_MASK | SVM_SELECTOR_S_MASK |
433 SVM_SELECTOR_WRITE_MASK; /* Read/Write Data Segment */
434 seg->limit = 0xffff;
435 seg->base = 0;
436}
437
438static void init_sys_seg(struct vmcb_seg *seg, uint32_t type)
439{
440 seg->selector = 0;
441 seg->attrib = SVM_SELECTOR_P_MASK | type;
442 seg->limit = 0xffff;
443 seg->base = 0;
444}
445
446static void init_vmcb(struct vmcb *vmcb)
447{
448 struct vmcb_control_area *control = &vmcb->control;
449 struct vmcb_save_area *save = &vmcb->save;
450
451 control->intercept_cr_read = INTERCEPT_CR0_MASK |
452 INTERCEPT_CR3_MASK |
453 INTERCEPT_CR4_MASK |
454 INTERCEPT_CR8_MASK;
455
456 control->intercept_cr_write = INTERCEPT_CR0_MASK |
457 INTERCEPT_CR3_MASK |
458 INTERCEPT_CR4_MASK |
459 INTERCEPT_CR8_MASK;
460
461 control->intercept_dr_read = INTERCEPT_DR0_MASK |
462 INTERCEPT_DR1_MASK |
463 INTERCEPT_DR2_MASK |
464 INTERCEPT_DR3_MASK;
465
466 control->intercept_dr_write = INTERCEPT_DR0_MASK |
467 INTERCEPT_DR1_MASK |
468 INTERCEPT_DR2_MASK |
469 INTERCEPT_DR3_MASK |
470 INTERCEPT_DR5_MASK |
471 INTERCEPT_DR7_MASK;
472
473 control->intercept_exceptions = (1 << PF_VECTOR) |
474 (1 << UD_VECTOR);
475
476
477 control->intercept = (1ULL << INTERCEPT_INTR) |
478 (1ULL << INTERCEPT_NMI) |
479 (1ULL << INTERCEPT_SMI) |
480 /*
481 * selective cr0 intercept bug?
482 * 0: 0f 22 d8 mov %eax,%cr3
483 * 3: 0f 20 c0 mov %cr0,%eax
484 * 6: 0d 00 00 00 80 or $0x80000000,%eax
485 * b: 0f 22 c0 mov %eax,%cr0
486 * set cr3 ->interception
487 * get cr0 ->interception
488 * set cr0 -> no interception
489 */
490 /* (1ULL << INTERCEPT_SELECTIVE_CR0) | */
491 (1ULL << INTERCEPT_CPUID) |
492 (1ULL << INTERCEPT_INVD) |
493 (1ULL << INTERCEPT_HLT) |
494 (1ULL << INTERCEPT_INVLPGA) |
495 (1ULL << INTERCEPT_IOIO_PROT) |
496 (1ULL << INTERCEPT_MSR_PROT) |
497 (1ULL << INTERCEPT_TASK_SWITCH) |
498 (1ULL << INTERCEPT_SHUTDOWN) |
499 (1ULL << INTERCEPT_VMRUN) |
500 (1ULL << INTERCEPT_VMMCALL) |
501 (1ULL << INTERCEPT_VMLOAD) |
502 (1ULL << INTERCEPT_VMSAVE) |
503 (1ULL << INTERCEPT_STGI) |
504 (1ULL << INTERCEPT_CLGI) |
505 (1ULL << INTERCEPT_SKINIT) |
506 (1ULL << INTERCEPT_WBINVD) |
507 (1ULL << INTERCEPT_MONITOR) |
508 (1ULL << INTERCEPT_MWAIT);
509
510 control->iopm_base_pa = iopm_base;
511 control->msrpm_base_pa = msrpm_base;
512 control->tsc_offset = 0;
513 control->int_ctl = V_INTR_MASKING_MASK;
514
515 init_seg(&save->es);
516 init_seg(&save->ss);
517 init_seg(&save->ds);
518 init_seg(&save->fs);
519 init_seg(&save->gs);
520
521 save->cs.selector = 0xf000;
522 /* Executable/Readable Code Segment */
523 save->cs.attrib = SVM_SELECTOR_READ_MASK | SVM_SELECTOR_P_MASK |
524 SVM_SELECTOR_S_MASK | SVM_SELECTOR_CODE_MASK;
525 save->cs.limit = 0xffff;
526 /*
527 * cs.base should really be 0xffff0000, but vmx can't handle that, so
528 * be consistent with it.
529 *
530 * Replace when we have real mode working for vmx.
531 */
532 save->cs.base = 0xf0000;
533
534 save->gdtr.limit = 0xffff;
535 save->idtr.limit = 0xffff;
536
537 init_sys_seg(&save->ldtr, SEG_TYPE_LDT);
538 init_sys_seg(&save->tr, SEG_TYPE_BUSY_TSS16);
539
540 save->efer = MSR_EFER_SVME_MASK;
541 save->dr6 = 0xffff0ff0;
542 save->dr7 = 0x400;
543 save->rflags = 2;
544 save->rip = 0x0000fff0;
545
546 /*
547 * cr0 val on cpu init should be 0x60000010, we enable cpu
548 * cache by default. the orderly way is to enable cache in bios.
549 */
550 save->cr0 = 0x00000010 | X86_CR0_PG | X86_CR0_WP;
551 save->cr4 = X86_CR4_PAE;
552 /* rdx = ?? */
553}
554
555static int svm_vcpu_reset(struct kvm_vcpu *vcpu)
556{
557 struct vcpu_svm *svm = to_svm(vcpu);
558
559 init_vmcb(svm->vmcb);
560
561 if (vcpu->vcpu_id != 0) {
562 svm->vmcb->save.rip = 0;
563 svm->vmcb->save.cs.base = svm->vcpu.arch.sipi_vector << 12;
564 svm->vmcb->save.cs.selector = svm->vcpu.arch.sipi_vector << 8;
565 }
566
567 return 0;
568}
569
570static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id)
571{
572 struct vcpu_svm *svm;
573 struct page *page;
574 int err;
575
576 svm = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL);
577 if (!svm) {
578 err = -ENOMEM;
579 goto out;
580 }
581
582 err = kvm_vcpu_init(&svm->vcpu, kvm, id);
583 if (err)
584 goto free_svm;
585
586 page = alloc_page(GFP_KERNEL);
587 if (!page) {
588 err = -ENOMEM;
589 goto uninit;
590 }
591
592 svm->vmcb = page_address(page);
593 clear_page(svm->vmcb);
594 svm->vmcb_pa = page_to_pfn(page) << PAGE_SHIFT;
595 svm->asid_generation = 0;
596 memset(svm->db_regs, 0, sizeof(svm->db_regs));
597 init_vmcb(svm->vmcb);
598
599 fx_init(&svm->vcpu);
600 svm->vcpu.fpu_active = 1;
601 svm->vcpu.arch.apic_base = 0xfee00000 | MSR_IA32_APICBASE_ENABLE;
602 if (svm->vcpu.vcpu_id == 0)
603 svm->vcpu.arch.apic_base |= MSR_IA32_APICBASE_BSP;
604
605 return &svm->vcpu;
606
607uninit:
608 kvm_vcpu_uninit(&svm->vcpu);
609free_svm:
610 kmem_cache_free(kvm_vcpu_cache, svm);
611out:
612 return ERR_PTR(err);
613}
614
615static void svm_free_vcpu(struct kvm_vcpu *vcpu)
616{
617 struct vcpu_svm *svm = to_svm(vcpu);
618
619 __free_page(pfn_to_page(svm->vmcb_pa >> PAGE_SHIFT));
620 kvm_vcpu_uninit(vcpu);
621 kmem_cache_free(kvm_vcpu_cache, svm);
622}
623
624static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
625{
626 struct vcpu_svm *svm = to_svm(vcpu);
627 int i;
628
629 if (unlikely(cpu != vcpu->cpu)) {
630 u64 tsc_this, delta;
631
632 /*
633 * Make sure that the guest sees a monotonically
634 * increasing TSC.
635 */
636 rdtscll(tsc_this);
637 delta = vcpu->arch.host_tsc - tsc_this;
638 svm->vmcb->control.tsc_offset += delta;
639 vcpu->cpu = cpu;
640 kvm_migrate_apic_timer(vcpu);
641 }
642
643 for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++)
644 rdmsrl(host_save_user_msrs[i], svm->host_user_msrs[i]);
645}
646
647static void svm_vcpu_put(struct kvm_vcpu *vcpu)
648{
649 struct vcpu_svm *svm = to_svm(vcpu);
650 int i;
651
652 ++vcpu->stat.host_state_reload;
653 for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++)
654 wrmsrl(host_save_user_msrs[i], svm->host_user_msrs[i]);
655
656 rdtscll(vcpu->arch.host_tsc);
657}
658
659static void svm_vcpu_decache(struct kvm_vcpu *vcpu)
660{
661}
662
663static void svm_cache_regs(struct kvm_vcpu *vcpu)
664{
665 struct vcpu_svm *svm = to_svm(vcpu);
666
667 vcpu->arch.regs[VCPU_REGS_RAX] = svm->vmcb->save.rax;
668 vcpu->arch.regs[VCPU_REGS_RSP] = svm->vmcb->save.rsp;
669 vcpu->arch.rip = svm->vmcb->save.rip;
670}
671
672static void svm_decache_regs(struct kvm_vcpu *vcpu)
673{
674 struct vcpu_svm *svm = to_svm(vcpu);
675 svm->vmcb->save.rax = vcpu->arch.regs[VCPU_REGS_RAX];
676 svm->vmcb->save.rsp = vcpu->arch.regs[VCPU_REGS_RSP];
677 svm->vmcb->save.rip = vcpu->arch.rip;
678}
679
680static unsigned long svm_get_rflags(struct kvm_vcpu *vcpu)
681{
682 return to_svm(vcpu)->vmcb->save.rflags;
683}
684
685static void svm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
686{
687 to_svm(vcpu)->vmcb->save.rflags = rflags;
688}
689
690static struct vmcb_seg *svm_seg(struct kvm_vcpu *vcpu, int seg)
691{
692 struct vmcb_save_area *save = &to_svm(vcpu)->vmcb->save;
693
694 switch (seg) {
695 case VCPU_SREG_CS: return &save->cs;
696 case VCPU_SREG_DS: return &save->ds;
697 case VCPU_SREG_ES: return &save->es;
698 case VCPU_SREG_FS: return &save->fs;
699 case VCPU_SREG_GS: return &save->gs;
700 case VCPU_SREG_SS: return &save->ss;
701 case VCPU_SREG_TR: return &save->tr;
702 case VCPU_SREG_LDTR: return &save->ldtr;
703 }
704 BUG();
705 return NULL;
706}
707
708static u64 svm_get_segment_base(struct kvm_vcpu *vcpu, int seg)
709{
710 struct vmcb_seg *s = svm_seg(vcpu, seg);
711
712 return s->base;
713}
714
715static void svm_get_segment(struct kvm_vcpu *vcpu,
716 struct kvm_segment *var, int seg)
717{
718 struct vmcb_seg *s = svm_seg(vcpu, seg);
719
720 var->base = s->base;
721 var->limit = s->limit;
722 var->selector = s->selector;
723 var->type = s->attrib & SVM_SELECTOR_TYPE_MASK;
724 var->s = (s->attrib >> SVM_SELECTOR_S_SHIFT) & 1;
725 var->dpl = (s->attrib >> SVM_SELECTOR_DPL_SHIFT) & 3;
726 var->present = (s->attrib >> SVM_SELECTOR_P_SHIFT) & 1;
727 var->avl = (s->attrib >> SVM_SELECTOR_AVL_SHIFT) & 1;
728 var->l = (s->attrib >> SVM_SELECTOR_L_SHIFT) & 1;
729 var->db = (s->attrib >> SVM_SELECTOR_DB_SHIFT) & 1;
730 var->g = (s->attrib >> SVM_SELECTOR_G_SHIFT) & 1;
731 var->unusable = !var->present;
732}
733
734static void svm_get_idt(struct kvm_vcpu *vcpu, struct descriptor_table *dt)
735{
736 struct vcpu_svm *svm = to_svm(vcpu);
737
738 dt->limit = svm->vmcb->save.idtr.limit;
739 dt->base = svm->vmcb->save.idtr.base;
740}
741
742static void svm_set_idt(struct kvm_vcpu *vcpu, struct descriptor_table *dt)
743{
744 struct vcpu_svm *svm = to_svm(vcpu);
745
746 svm->vmcb->save.idtr.limit = dt->limit;
747 svm->vmcb->save.idtr.base = dt->base ;
748}
749
750static void svm_get_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt)
751{
752 struct vcpu_svm *svm = to_svm(vcpu);
753
754 dt->limit = svm->vmcb->save.gdtr.limit;
755 dt->base = svm->vmcb->save.gdtr.base;
756}
757
758static void svm_set_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt)
759{
760 struct vcpu_svm *svm = to_svm(vcpu);
761
762 svm->vmcb->save.gdtr.limit = dt->limit;
763 svm->vmcb->save.gdtr.base = dt->base ;
764}
765
766static void svm_decache_cr4_guest_bits(struct kvm_vcpu *vcpu)
767{
768}
769
770static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
771{
772 struct vcpu_svm *svm = to_svm(vcpu);
773
774#ifdef CONFIG_X86_64
775 if (vcpu->arch.shadow_efer & EFER_LME) {
776 if (!is_paging(vcpu) && (cr0 & X86_CR0_PG)) {
777 vcpu->arch.shadow_efer |= EFER_LMA;
778 svm->vmcb->save.efer |= EFER_LMA | EFER_LME;
779 }
780
781 if (is_paging(vcpu) && !(cr0 & X86_CR0_PG)) {
782 vcpu->arch.shadow_efer &= ~EFER_LMA;
783 svm->vmcb->save.efer &= ~(EFER_LMA | EFER_LME);
784 }
785 }
786#endif
787 if ((vcpu->arch.cr0 & X86_CR0_TS) && !(cr0 & X86_CR0_TS)) {
788 svm->vmcb->control.intercept_exceptions &= ~(1 << NM_VECTOR);
789 vcpu->fpu_active = 1;
790 }
791
792 vcpu->arch.cr0 = cr0;
793 cr0 |= X86_CR0_PG | X86_CR0_WP;
794 cr0 &= ~(X86_CR0_CD | X86_CR0_NW);
795 svm->vmcb->save.cr0 = cr0;
796}
797
798static void svm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
799{
800 vcpu->arch.cr4 = cr4;
801 to_svm(vcpu)->vmcb->save.cr4 = cr4 | X86_CR4_PAE;
802}
803
804static void svm_set_segment(struct kvm_vcpu *vcpu,
805 struct kvm_segment *var, int seg)
806{
807 struct vcpu_svm *svm = to_svm(vcpu);
808 struct vmcb_seg *s = svm_seg(vcpu, seg);
809
810 s->base = var->base;
811 s->limit = var->limit;
812 s->selector = var->selector;
813 if (var->unusable)
814 s->attrib = 0;
815 else {
816 s->attrib = (var->type & SVM_SELECTOR_TYPE_MASK);
817 s->attrib |= (var->s & 1) << SVM_SELECTOR_S_SHIFT;
818 s->attrib |= (var->dpl & 3) << SVM_SELECTOR_DPL_SHIFT;
819 s->attrib |= (var->present & 1) << SVM_SELECTOR_P_SHIFT;
820 s->attrib |= (var->avl & 1) << SVM_SELECTOR_AVL_SHIFT;
821 s->attrib |= (var->l & 1) << SVM_SELECTOR_L_SHIFT;
822 s->attrib |= (var->db & 1) << SVM_SELECTOR_DB_SHIFT;
823 s->attrib |= (var->g & 1) << SVM_SELECTOR_G_SHIFT;
824 }
825 if (seg == VCPU_SREG_CS)
826 svm->vmcb->save.cpl
827 = (svm->vmcb->save.cs.attrib
828 >> SVM_SELECTOR_DPL_SHIFT) & 3;
829
830}
831
832/* FIXME:
833
834 svm(vcpu)->vmcb->control.int_ctl &= ~V_TPR_MASK;
835 svm(vcpu)->vmcb->control.int_ctl |= (sregs->cr8 & V_TPR_MASK);
836
837*/
838
839static int svm_guest_debug(struct kvm_vcpu *vcpu, struct kvm_debug_guest *dbg)
840{
841 return -EOPNOTSUPP;
842}
843
844static int svm_get_irq(struct kvm_vcpu *vcpu)
845{
846 struct vcpu_svm *svm = to_svm(vcpu);
847 u32 exit_int_info = svm->vmcb->control.exit_int_info;
848
849 if (is_external_interrupt(exit_int_info))
850 return exit_int_info & SVM_EVTINJ_VEC_MASK;
851 return -1;
852}
853
854static void load_host_msrs(struct kvm_vcpu *vcpu)
855{
856#ifdef CONFIG_X86_64
857 wrmsrl(MSR_GS_BASE, to_svm(vcpu)->host_gs_base);
858#endif
859}
860
861static void save_host_msrs(struct kvm_vcpu *vcpu)
862{
863#ifdef CONFIG_X86_64
864 rdmsrl(MSR_GS_BASE, to_svm(vcpu)->host_gs_base);
865#endif
866}
867
868static void new_asid(struct vcpu_svm *svm, struct svm_cpu_data *svm_data)
869{
870 if (svm_data->next_asid > svm_data->max_asid) {
871 ++svm_data->asid_generation;
872 svm_data->next_asid = 1;
873 svm->vmcb->control.tlb_ctl = TLB_CONTROL_FLUSH_ALL_ASID;
874 }
875
876 svm->vcpu.cpu = svm_data->cpu;
877 svm->asid_generation = svm_data->asid_generation;
878 svm->vmcb->control.asid = svm_data->next_asid++;
879}
880
881static unsigned long svm_get_dr(struct kvm_vcpu *vcpu, int dr)
882{
883 return to_svm(vcpu)->db_regs[dr];
884}
885
886static void svm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long value,
887 int *exception)
888{
889 struct vcpu_svm *svm = to_svm(vcpu);
890
891 *exception = 0;
892
893 if (svm->vmcb->save.dr7 & DR7_GD_MASK) {
894 svm->vmcb->save.dr7 &= ~DR7_GD_MASK;
895 svm->vmcb->save.dr6 |= DR6_BD_MASK;
896 *exception = DB_VECTOR;
897 return;
898 }
899
900 switch (dr) {
901 case 0 ... 3:
902 svm->db_regs[dr] = value;
903 return;
904 case 4 ... 5:
905 if (vcpu->arch.cr4 & X86_CR4_DE) {
906 *exception = UD_VECTOR;
907 return;
908 }
909 case 7: {
910 if (value & ~((1ULL << 32) - 1)) {
911 *exception = GP_VECTOR;
912 return;
913 }
914 svm->vmcb->save.dr7 = value;
915 return;
916 }
917 default:
918 printk(KERN_DEBUG "%s: unexpected dr %u\n",
919 __FUNCTION__, dr);
920 *exception = UD_VECTOR;
921 return;
922 }
923}
924
925static int pf_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
926{
927 u32 exit_int_info = svm->vmcb->control.exit_int_info;
928 struct kvm *kvm = svm->vcpu.kvm;
929 u64 fault_address;
930 u32 error_code;
931
932 if (!irqchip_in_kernel(kvm) &&
933 is_external_interrupt(exit_int_info))
934 push_irq(&svm->vcpu, exit_int_info & SVM_EVTINJ_VEC_MASK);
935
936 fault_address = svm->vmcb->control.exit_info_2;
937 error_code = svm->vmcb->control.exit_info_1;
938 return kvm_mmu_page_fault(&svm->vcpu, fault_address, error_code);
939}
940
941static int ud_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
942{
943 int er;
944
945 er = emulate_instruction(&svm->vcpu, kvm_run, 0, 0, EMULTYPE_TRAP_UD);
946 if (er != EMULATE_DONE)
947 kvm_queue_exception(&svm->vcpu, UD_VECTOR);
948 return 1;
949}
950
951static int nm_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
952{
953 svm->vmcb->control.intercept_exceptions &= ~(1 << NM_VECTOR);
954 if (!(svm->vcpu.arch.cr0 & X86_CR0_TS))
955 svm->vmcb->save.cr0 &= ~X86_CR0_TS;
956 svm->vcpu.fpu_active = 1;
957
958 return 1;
959}
960
961static int shutdown_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
962{
963 /*
964 * VMCB is undefined after a SHUTDOWN intercept
965 * so reinitialize it.
966 */
967 clear_page(svm->vmcb);
968 init_vmcb(svm->vmcb);
969
970 kvm_run->exit_reason = KVM_EXIT_SHUTDOWN;
971 return 0;
972}
973
974static int io_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
975{
976 u32 io_info = svm->vmcb->control.exit_info_1; /* address size bug? */
977 int size, down, in, string, rep;
978 unsigned port;
979
980 ++svm->vcpu.stat.io_exits;
981
982 svm->next_rip = svm->vmcb->control.exit_info_2;
983
984 string = (io_info & SVM_IOIO_STR_MASK) != 0;
985
986 if (string) {
987 if (emulate_instruction(&svm->vcpu,
988 kvm_run, 0, 0, 0) == EMULATE_DO_MMIO)
989 return 0;
990 return 1;
991 }
992
993 in = (io_info & SVM_IOIO_TYPE_MASK) != 0;
994 port = io_info >> 16;
995 size = (io_info & SVM_IOIO_SIZE_MASK) >> SVM_IOIO_SIZE_SHIFT;
996 rep = (io_info & SVM_IOIO_REP_MASK) != 0;
997 down = (svm->vmcb->save.rflags & X86_EFLAGS_DF) != 0;
998
999 return kvm_emulate_pio(&svm->vcpu, kvm_run, in, size, port);
1000}
1001
1002static int nop_on_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
1003{
1004 return 1;
1005}
1006
1007static int halt_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
1008{
1009 svm->next_rip = svm->vmcb->save.rip + 1;
1010 skip_emulated_instruction(&svm->vcpu);
1011 return kvm_emulate_halt(&svm->vcpu);
1012}
1013
1014static int vmmcall_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
1015{
1016 svm->next_rip = svm->vmcb->save.rip + 3;
1017 skip_emulated_instruction(&svm->vcpu);
1018 kvm_emulate_hypercall(&svm->vcpu);
1019 return 1;
1020}
1021
1022static int invalid_op_interception(struct vcpu_svm *svm,
1023 struct kvm_run *kvm_run)
1024{
1025 kvm_queue_exception(&svm->vcpu, UD_VECTOR);
1026 return 1;
1027}
1028
1029static int task_switch_interception(struct vcpu_svm *svm,
1030 struct kvm_run *kvm_run)
1031{
1032 pr_unimpl(&svm->vcpu, "%s: task switch is unsupported\n", __FUNCTION__);
1033 kvm_run->exit_reason = KVM_EXIT_UNKNOWN;
1034 return 0;
1035}
1036
1037static int cpuid_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
1038{
1039 svm->next_rip = svm->vmcb->save.rip + 2;
1040 kvm_emulate_cpuid(&svm->vcpu);
1041 return 1;
1042}
1043
1044static int emulate_on_interception(struct vcpu_svm *svm,
1045 struct kvm_run *kvm_run)
1046{
1047 if (emulate_instruction(&svm->vcpu, NULL, 0, 0, 0) != EMULATE_DONE)
1048 pr_unimpl(&svm->vcpu, "%s: failed\n", __FUNCTION__);
1049 return 1;
1050}
1051
1052static int cr8_write_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
1053{
1054 emulate_instruction(&svm->vcpu, NULL, 0, 0, 0);
1055 if (irqchip_in_kernel(svm->vcpu.kvm))
1056 return 1;
1057 kvm_run->exit_reason = KVM_EXIT_SET_TPR;
1058 return 0;
1059}
1060
1061static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)
1062{
1063 struct vcpu_svm *svm = to_svm(vcpu);
1064
1065 switch (ecx) {
1066 case MSR_IA32_TIME_STAMP_COUNTER: {
1067 u64 tsc;
1068
1069 rdtscll(tsc);
1070 *data = svm->vmcb->control.tsc_offset + tsc;
1071 break;
1072 }
1073 case MSR_K6_STAR:
1074 *data = svm->vmcb->save.star;
1075 break;
1076#ifdef CONFIG_X86_64
1077 case MSR_LSTAR:
1078 *data = svm->vmcb->save.lstar;
1079 break;
1080 case MSR_CSTAR:
1081 *data = svm->vmcb->save.cstar;
1082 break;
1083 case MSR_KERNEL_GS_BASE:
1084 *data = svm->vmcb->save.kernel_gs_base;
1085 break;
1086 case MSR_SYSCALL_MASK:
1087 *data = svm->vmcb->save.sfmask;
1088 break;
1089#endif
1090 case MSR_IA32_SYSENTER_CS:
1091 *data = svm->vmcb->save.sysenter_cs;
1092 break;
1093 case MSR_IA32_SYSENTER_EIP:
1094 *data = svm->vmcb->save.sysenter_eip;
1095 break;
1096 case MSR_IA32_SYSENTER_ESP:
1097 *data = svm->vmcb->save.sysenter_esp;
1098 break;
1099 default:
1100 return kvm_get_msr_common(vcpu, ecx, data);
1101 }
1102 return 0;
1103}
1104
1105static int rdmsr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
1106{
1107 u32 ecx = svm->vcpu.arch.regs[VCPU_REGS_RCX];
1108 u64 data;
1109
1110 if (svm_get_msr(&svm->vcpu, ecx, &data))
1111 kvm_inject_gp(&svm->vcpu, 0);
1112 else {
1113 svm->vmcb->save.rax = data & 0xffffffff;
1114 svm->vcpu.arch.regs[VCPU_REGS_RDX] = data >> 32;
1115 svm->next_rip = svm->vmcb->save.rip + 2;
1116 skip_emulated_instruction(&svm->vcpu);
1117 }
1118 return 1;
1119}
1120
1121static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
1122{
1123 struct vcpu_svm *svm = to_svm(vcpu);
1124
1125 switch (ecx) {
1126 case MSR_IA32_TIME_STAMP_COUNTER: {
1127 u64 tsc;
1128
1129 rdtscll(tsc);
1130 svm->vmcb->control.tsc_offset = data - tsc;
1131 break;
1132 }
1133 case MSR_K6_STAR:
1134 svm->vmcb->save.star = data;
1135 break;
1136#ifdef CONFIG_X86_64
1137 case MSR_LSTAR:
1138 svm->vmcb->save.lstar = data;
1139 break;
1140 case MSR_CSTAR:
1141 svm->vmcb->save.cstar = data;
1142 break;
1143 case MSR_KERNEL_GS_BASE:
1144 svm->vmcb->save.kernel_gs_base = data;
1145 break;
1146 case MSR_SYSCALL_MASK:
1147 svm->vmcb->save.sfmask = data;
1148 break;
1149#endif
1150 case MSR_IA32_SYSENTER_CS:
1151 svm->vmcb->save.sysenter_cs = data;
1152 break;
1153 case MSR_IA32_SYSENTER_EIP:
1154 svm->vmcb->save.sysenter_eip = data;
1155 break;
1156 case MSR_IA32_SYSENTER_ESP:
1157 svm->vmcb->save.sysenter_esp = data;
1158 break;
1159 case MSR_K7_EVNTSEL0:
1160 case MSR_K7_EVNTSEL1:
1161 case MSR_K7_EVNTSEL2:
1162 case MSR_K7_EVNTSEL3:
1163 /*
1164 * only support writing 0 to the performance counters for now
1165 * to make Windows happy. Should be replaced by a real
1166 * performance counter emulation later.
1167 */
1168 if (data != 0)
1169 goto unhandled;
1170 break;
1171 default:
1172 unhandled:
1173 return kvm_set_msr_common(vcpu, ecx, data);
1174 }
1175 return 0;
1176}
1177
1178static int wrmsr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
1179{
1180 u32 ecx = svm->vcpu.arch.regs[VCPU_REGS_RCX];
1181 u64 data = (svm->vmcb->save.rax & -1u)
1182 | ((u64)(svm->vcpu.arch.regs[VCPU_REGS_RDX] & -1u) << 32);
1183 svm->next_rip = svm->vmcb->save.rip + 2;
1184 if (svm_set_msr(&svm->vcpu, ecx, data))
1185 kvm_inject_gp(&svm->vcpu, 0);
1186 else
1187 skip_emulated_instruction(&svm->vcpu);
1188 return 1;
1189}
1190
1191static int msr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
1192{
1193 if (svm->vmcb->control.exit_info_1)
1194 return wrmsr_interception(svm, kvm_run);
1195 else
1196 return rdmsr_interception(svm, kvm_run);
1197}
1198
1199static int interrupt_window_interception(struct vcpu_svm *svm,
1200 struct kvm_run *kvm_run)
1201{
1202 svm->vmcb->control.intercept &= ~(1ULL << INTERCEPT_VINTR);
1203 svm->vmcb->control.int_ctl &= ~V_IRQ_MASK;
1204 /*
1205 * If the user space waits to inject interrupts, exit as soon as
1206 * possible
1207 */
1208 if (kvm_run->request_interrupt_window &&
1209 !svm->vcpu.arch.irq_summary) {
1210 ++svm->vcpu.stat.irq_window_exits;
1211 kvm_run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN;
1212 return 0;
1213 }
1214
1215 return 1;
1216}
1217
1218static int (*svm_exit_handlers[])(struct vcpu_svm *svm,
1219 struct kvm_run *kvm_run) = {
1220 [SVM_EXIT_READ_CR0] = emulate_on_interception,
1221 [SVM_EXIT_READ_CR3] = emulate_on_interception,
1222 [SVM_EXIT_READ_CR4] = emulate_on_interception,
1223 [SVM_EXIT_READ_CR8] = emulate_on_interception,
1224 /* for now: */
1225 [SVM_EXIT_WRITE_CR0] = emulate_on_interception,
1226 [SVM_EXIT_WRITE_CR3] = emulate_on_interception,
1227 [SVM_EXIT_WRITE_CR4] = emulate_on_interception,
1228 [SVM_EXIT_WRITE_CR8] = cr8_write_interception,
1229 [SVM_EXIT_READ_DR0] = emulate_on_interception,
1230 [SVM_EXIT_READ_DR1] = emulate_on_interception,
1231 [SVM_EXIT_READ_DR2] = emulate_on_interception,
1232 [SVM_EXIT_READ_DR3] = emulate_on_interception,
1233 [SVM_EXIT_WRITE_DR0] = emulate_on_interception,
1234 [SVM_EXIT_WRITE_DR1] = emulate_on_interception,
1235 [SVM_EXIT_WRITE_DR2] = emulate_on_interception,
1236 [SVM_EXIT_WRITE_DR3] = emulate_on_interception,
1237 [SVM_EXIT_WRITE_DR5] = emulate_on_interception,
1238 [SVM_EXIT_WRITE_DR7] = emulate_on_interception,
1239 [SVM_EXIT_EXCP_BASE + UD_VECTOR] = ud_interception,
1240 [SVM_EXIT_EXCP_BASE + PF_VECTOR] = pf_interception,
1241 [SVM_EXIT_EXCP_BASE + NM_VECTOR] = nm_interception,
1242 [SVM_EXIT_INTR] = nop_on_interception,
1243 [SVM_EXIT_NMI] = nop_on_interception,
1244 [SVM_EXIT_SMI] = nop_on_interception,
1245 [SVM_EXIT_INIT] = nop_on_interception,
1246 [SVM_EXIT_VINTR] = interrupt_window_interception,
1247 /* [SVM_EXIT_CR0_SEL_WRITE] = emulate_on_interception, */
1248 [SVM_EXIT_CPUID] = cpuid_interception,
1249 [SVM_EXIT_INVD] = emulate_on_interception,
1250 [SVM_EXIT_HLT] = halt_interception,
1251 [SVM_EXIT_INVLPG] = emulate_on_interception,
1252 [SVM_EXIT_INVLPGA] = invalid_op_interception,
1253 [SVM_EXIT_IOIO] = io_interception,
1254 [SVM_EXIT_MSR] = msr_interception,
1255 [SVM_EXIT_TASK_SWITCH] = task_switch_interception,
1256 [SVM_EXIT_SHUTDOWN] = shutdown_interception,
1257 [SVM_EXIT_VMRUN] = invalid_op_interception,
1258 [SVM_EXIT_VMMCALL] = vmmcall_interception,
1259 [SVM_EXIT_VMLOAD] = invalid_op_interception,
1260 [SVM_EXIT_VMSAVE] = invalid_op_interception,
1261 [SVM_EXIT_STGI] = invalid_op_interception,
1262 [SVM_EXIT_CLGI] = invalid_op_interception,
1263 [SVM_EXIT_SKINIT] = invalid_op_interception,
1264 [SVM_EXIT_WBINVD] = emulate_on_interception,
1265 [SVM_EXIT_MONITOR] = invalid_op_interception,
1266 [SVM_EXIT_MWAIT] = invalid_op_interception,
1267};
1268
1269
1270static int handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
1271{
1272 struct vcpu_svm *svm = to_svm(vcpu);
1273 u32 exit_code = svm->vmcb->control.exit_code;
1274
1275 kvm_reput_irq(svm);
1276
1277 if (svm->vmcb->control.exit_code == SVM_EXIT_ERR) {
1278 kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY;
1279 kvm_run->fail_entry.hardware_entry_failure_reason
1280 = svm->vmcb->control.exit_code;
1281 return 0;
1282 }
1283
1284 if (is_external_interrupt(svm->vmcb->control.exit_int_info) &&
1285 exit_code != SVM_EXIT_EXCP_BASE + PF_VECTOR)
1286 printk(KERN_ERR "%s: unexpected exit_ini_info 0x%x "
1287 "exit_code 0x%x\n",
1288 __FUNCTION__, svm->vmcb->control.exit_int_info,
1289 exit_code);
1290
1291 if (exit_code >= ARRAY_SIZE(svm_exit_handlers)
1292 || !svm_exit_handlers[exit_code]) {
1293 kvm_run->exit_reason = KVM_EXIT_UNKNOWN;
1294 kvm_run->hw.hardware_exit_reason = exit_code;
1295 return 0;
1296 }
1297
1298 return svm_exit_handlers[exit_code](svm, kvm_run);
1299}
1300
1301static void reload_tss(struct kvm_vcpu *vcpu)
1302{
1303 int cpu = raw_smp_processor_id();
1304
1305 struct svm_cpu_data *svm_data = per_cpu(svm_data, cpu);
1306 svm_data->tss_desc->type = 9; /* available 32/64-bit TSS */
1307 load_TR_desc();
1308}
1309
1310static void pre_svm_run(struct vcpu_svm *svm)
1311{
1312 int cpu = raw_smp_processor_id();
1313
1314 struct svm_cpu_data *svm_data = per_cpu(svm_data, cpu);
1315
1316 svm->vmcb->control.tlb_ctl = TLB_CONTROL_DO_NOTHING;
1317 if (svm->vcpu.cpu != cpu ||
1318 svm->asid_generation != svm_data->asid_generation)
1319 new_asid(svm, svm_data);
1320}
1321
1322
1323static inline void svm_inject_irq(struct vcpu_svm *svm, int irq)
1324{
1325 struct vmcb_control_area *control;
1326
1327 control = &svm->vmcb->control;
1328 control->int_vector = irq;
1329 control->int_ctl &= ~V_INTR_PRIO_MASK;
1330 control->int_ctl |= V_IRQ_MASK |
1331 ((/*control->int_vector >> 4*/ 0xf) << V_INTR_PRIO_SHIFT);
1332}
1333
1334static void svm_set_irq(struct kvm_vcpu *vcpu, int irq)
1335{
1336 struct vcpu_svm *svm = to_svm(vcpu);
1337
1338 svm_inject_irq(svm, irq);
1339}
1340
1341static void svm_intr_assist(struct kvm_vcpu *vcpu)
1342{
1343 struct vcpu_svm *svm = to_svm(vcpu);
1344 struct vmcb *vmcb = svm->vmcb;
1345 int intr_vector = -1;
1346
1347 if ((vmcb->control.exit_int_info & SVM_EVTINJ_VALID) &&
1348 ((vmcb->control.exit_int_info & SVM_EVTINJ_TYPE_MASK) == 0)) {
1349 intr_vector = vmcb->control.exit_int_info &
1350 SVM_EVTINJ_VEC_MASK;
1351 vmcb->control.exit_int_info = 0;
1352 svm_inject_irq(svm, intr_vector);
1353 return;
1354 }
1355
1356 if (vmcb->control.int_ctl & V_IRQ_MASK)
1357 return;
1358
1359 if (!kvm_cpu_has_interrupt(vcpu))
1360 return;
1361
1362 if (!(vmcb->save.rflags & X86_EFLAGS_IF) ||
1363 (vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK) ||
1364 (vmcb->control.event_inj & SVM_EVTINJ_VALID)) {
1365 /* unable to deliver irq, set pending irq */
1366 vmcb->control.intercept |= (1ULL << INTERCEPT_VINTR);
1367 svm_inject_irq(svm, 0x0);
1368 return;
1369 }
1370 /* Okay, we can deliver the interrupt: grab it and update PIC state. */
1371 intr_vector = kvm_cpu_get_interrupt(vcpu);
1372 svm_inject_irq(svm, intr_vector);
1373 kvm_timer_intr_post(vcpu, intr_vector);
1374}
1375
1376static void kvm_reput_irq(struct vcpu_svm *svm)
1377{
1378 struct vmcb_control_area *control = &svm->vmcb->control;
1379
1380 if ((control->int_ctl & V_IRQ_MASK)
1381 && !irqchip_in_kernel(svm->vcpu.kvm)) {
1382 control->int_ctl &= ~V_IRQ_MASK;
1383 push_irq(&svm->vcpu, control->int_vector);
1384 }
1385
1386 svm->vcpu.arch.interrupt_window_open =
1387 !(control->int_state & SVM_INTERRUPT_SHADOW_MASK);
1388}
1389
1390static void svm_do_inject_vector(struct vcpu_svm *svm)
1391{
1392 struct kvm_vcpu *vcpu = &svm->vcpu;
1393 int word_index = __ffs(vcpu->arch.irq_summary);
1394 int bit_index = __ffs(vcpu->arch.irq_pending[word_index]);
1395 int irq = word_index * BITS_PER_LONG + bit_index;
1396
1397 clear_bit(bit_index, &vcpu->arch.irq_pending[word_index]);
1398 if (!vcpu->arch.irq_pending[word_index])
1399 clear_bit(word_index, &vcpu->arch.irq_summary);
1400 svm_inject_irq(svm, irq);
1401}
1402
1403static void do_interrupt_requests(struct kvm_vcpu *vcpu,
1404 struct kvm_run *kvm_run)
1405{
1406 struct vcpu_svm *svm = to_svm(vcpu);
1407 struct vmcb_control_area *control = &svm->vmcb->control;
1408
1409 svm->vcpu.arch.interrupt_window_open =
1410 (!(control->int_state & SVM_INTERRUPT_SHADOW_MASK) &&
1411 (svm->vmcb->save.rflags & X86_EFLAGS_IF));
1412
1413 if (svm->vcpu.arch.interrupt_window_open && svm->vcpu.arch.irq_summary)
1414 /*
1415 * If interrupts enabled, and not blocked by sti or mov ss. Good.
1416 */
1417 svm_do_inject_vector(svm);
1418
1419 /*
1420 * Interrupts blocked. Wait for unblock.
1421 */
1422 if (!svm->vcpu.arch.interrupt_window_open &&
1423 (svm->vcpu.arch.irq_summary || kvm_run->request_interrupt_window))
1424 control->intercept |= 1ULL << INTERCEPT_VINTR;
1425 else
1426 control->intercept &= ~(1ULL << INTERCEPT_VINTR);
1427}
1428
1429static int svm_set_tss_addr(struct kvm *kvm, unsigned int addr)
1430{
1431 return 0;
1432}
1433
1434static void save_db_regs(unsigned long *db_regs)
1435{
1436 asm volatile ("mov %%dr0, %0" : "=r"(db_regs[0]));
1437 asm volatile ("mov %%dr1, %0" : "=r"(db_regs[1]));
1438 asm volatile ("mov %%dr2, %0" : "=r"(db_regs[2]));
1439 asm volatile ("mov %%dr3, %0" : "=r"(db_regs[3]));
1440}
1441
1442static void load_db_regs(unsigned long *db_regs)
1443{
1444 asm volatile ("mov %0, %%dr0" : : "r"(db_regs[0]));
1445 asm volatile ("mov %0, %%dr1" : : "r"(db_regs[1]));
1446 asm volatile ("mov %0, %%dr2" : : "r"(db_regs[2]));
1447 asm volatile ("mov %0, %%dr3" : : "r"(db_regs[3]));
1448}
1449
1450static void svm_flush_tlb(struct kvm_vcpu *vcpu)
1451{
1452 force_new_asid(vcpu);
1453}
1454
1455static void svm_prepare_guest_switch(struct kvm_vcpu *vcpu)
1456{
1457}
1458
1459static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
1460{
1461 struct vcpu_svm *svm = to_svm(vcpu);
1462 u16 fs_selector;
1463 u16 gs_selector;
1464 u16 ldt_selector;
1465
1466 pre_svm_run(svm);
1467
1468 save_host_msrs(vcpu);
1469 fs_selector = read_fs();
1470 gs_selector = read_gs();
1471 ldt_selector = read_ldt();
1472 svm->host_cr2 = kvm_read_cr2();
1473 svm->host_dr6 = read_dr6();
1474 svm->host_dr7 = read_dr7();
1475 svm->vmcb->save.cr2 = vcpu->arch.cr2;
1476
1477 if (svm->vmcb->save.dr7 & 0xff) {
1478 write_dr7(0);
1479 save_db_regs(svm->host_db_regs);
1480 load_db_regs(svm->db_regs);
1481 }
1482
1483 clgi();
1484
1485 local_irq_enable();
1486
1487 asm volatile (
1488#ifdef CONFIG_X86_64
1489 "push %%rbp; \n\t"
1490#else
1491 "push %%ebp; \n\t"
1492#endif
1493
1494#ifdef CONFIG_X86_64
1495 "mov %c[rbx](%[svm]), %%rbx \n\t"
1496 "mov %c[rcx](%[svm]), %%rcx \n\t"
1497 "mov %c[rdx](%[svm]), %%rdx \n\t"
1498 "mov %c[rsi](%[svm]), %%rsi \n\t"
1499 "mov %c[rdi](%[svm]), %%rdi \n\t"
1500 "mov %c[rbp](%[svm]), %%rbp \n\t"
1501 "mov %c[r8](%[svm]), %%r8 \n\t"
1502 "mov %c[r9](%[svm]), %%r9 \n\t"
1503 "mov %c[r10](%[svm]), %%r10 \n\t"
1504 "mov %c[r11](%[svm]), %%r11 \n\t"
1505 "mov %c[r12](%[svm]), %%r12 \n\t"
1506 "mov %c[r13](%[svm]), %%r13 \n\t"
1507 "mov %c[r14](%[svm]), %%r14 \n\t"
1508 "mov %c[r15](%[svm]), %%r15 \n\t"
1509#else
1510 "mov %c[rbx](%[svm]), %%ebx \n\t"
1511 "mov %c[rcx](%[svm]), %%ecx \n\t"
1512 "mov %c[rdx](%[svm]), %%edx \n\t"
1513 "mov %c[rsi](%[svm]), %%esi \n\t"
1514 "mov %c[rdi](%[svm]), %%edi \n\t"
1515 "mov %c[rbp](%[svm]), %%ebp \n\t"
1516#endif
1517
1518#ifdef CONFIG_X86_64
1519 /* Enter guest mode */
1520 "push %%rax \n\t"
1521 "mov %c[vmcb](%[svm]), %%rax \n\t"
1522 SVM_VMLOAD "\n\t"
1523 SVM_VMRUN "\n\t"
1524 SVM_VMSAVE "\n\t"
1525 "pop %%rax \n\t"
1526#else
1527 /* Enter guest mode */
1528 "push %%eax \n\t"
1529 "mov %c[vmcb](%[svm]), %%eax \n\t"
1530 SVM_VMLOAD "\n\t"
1531 SVM_VMRUN "\n\t"
1532 SVM_VMSAVE "\n\t"
1533 "pop %%eax \n\t"
1534#endif
1535
1536 /* Save guest registers, load host registers */
1537#ifdef CONFIG_X86_64
1538 "mov %%rbx, %c[rbx](%[svm]) \n\t"
1539 "mov %%rcx, %c[rcx](%[svm]) \n\t"
1540 "mov %%rdx, %c[rdx](%[svm]) \n\t"
1541 "mov %%rsi, %c[rsi](%[svm]) \n\t"
1542 "mov %%rdi, %c[rdi](%[svm]) \n\t"
1543 "mov %%rbp, %c[rbp](%[svm]) \n\t"
1544 "mov %%r8, %c[r8](%[svm]) \n\t"
1545 "mov %%r9, %c[r9](%[svm]) \n\t"
1546 "mov %%r10, %c[r10](%[svm]) \n\t"
1547 "mov %%r11, %c[r11](%[svm]) \n\t"
1548 "mov %%r12, %c[r12](%[svm]) \n\t"
1549 "mov %%r13, %c[r13](%[svm]) \n\t"
1550 "mov %%r14, %c[r14](%[svm]) \n\t"
1551 "mov %%r15, %c[r15](%[svm]) \n\t"
1552
1553 "pop %%rbp; \n\t"
1554#else
1555 "mov %%ebx, %c[rbx](%[svm]) \n\t"
1556 "mov %%ecx, %c[rcx](%[svm]) \n\t"
1557 "mov %%edx, %c[rdx](%[svm]) \n\t"
1558 "mov %%esi, %c[rsi](%[svm]) \n\t"
1559 "mov %%edi, %c[rdi](%[svm]) \n\t"
1560 "mov %%ebp, %c[rbp](%[svm]) \n\t"
1561
1562 "pop %%ebp; \n\t"
1563#endif
1564 :
1565 : [svm]"a"(svm),
1566 [vmcb]"i"(offsetof(struct vcpu_svm, vmcb_pa)),
1567 [rbx]"i"(offsetof(struct vcpu_svm, vcpu.arch.regs[VCPU_REGS_RBX])),
1568 [rcx]"i"(offsetof(struct vcpu_svm, vcpu.arch.regs[VCPU_REGS_RCX])),
1569 [rdx]"i"(offsetof(struct vcpu_svm, vcpu.arch.regs[VCPU_REGS_RDX])),
1570 [rsi]"i"(offsetof(struct vcpu_svm, vcpu.arch.regs[VCPU_REGS_RSI])),
1571 [rdi]"i"(offsetof(struct vcpu_svm, vcpu.arch.regs[VCPU_REGS_RDI])),
1572 [rbp]"i"(offsetof(struct vcpu_svm, vcpu.arch.regs[VCPU_REGS_RBP]))
1573#ifdef CONFIG_X86_64
1574 , [r8]"i"(offsetof(struct vcpu_svm, vcpu.arch.regs[VCPU_REGS_R8])),
1575 [r9]"i"(offsetof(struct vcpu_svm, vcpu.arch.regs[VCPU_REGS_R9])),
1576 [r10]"i"(offsetof(struct vcpu_svm, vcpu.arch.regs[VCPU_REGS_R10])),
1577 [r11]"i"(offsetof(struct vcpu_svm, vcpu.arch.regs[VCPU_REGS_R11])),
1578 [r12]"i"(offsetof(struct vcpu_svm, vcpu.arch.regs[VCPU_REGS_R12])),
1579 [r13]"i"(offsetof(struct vcpu_svm, vcpu.arch.regs[VCPU_REGS_R13])),
1580 [r14]"i"(offsetof(struct vcpu_svm, vcpu.arch.regs[VCPU_REGS_R14])),
1581 [r15]"i"(offsetof(struct vcpu_svm, vcpu.arch.regs[VCPU_REGS_R15]))
1582#endif
1583 : "cc", "memory"
1584#ifdef CONFIG_X86_64
1585 , "rbx", "rcx", "rdx", "rsi", "rdi"
1586 , "r8", "r9", "r10", "r11" , "r12", "r13", "r14", "r15"
1587#else
1588 , "ebx", "ecx", "edx" , "esi", "edi"
1589#endif
1590 );
1591
1592 if ((svm->vmcb->save.dr7 & 0xff))
1593 load_db_regs(svm->host_db_regs);
1594
1595 vcpu->arch.cr2 = svm->vmcb->save.cr2;
1596
1597 write_dr6(svm->host_dr6);
1598 write_dr7(svm->host_dr7);
1599 kvm_write_cr2(svm->host_cr2);
1600
1601 load_fs(fs_selector);
1602 load_gs(gs_selector);
1603 load_ldt(ldt_selector);
1604 load_host_msrs(vcpu);
1605
1606 reload_tss(vcpu);
1607
1608 local_irq_disable();
1609
1610 stgi();
1611
1612 svm->next_rip = 0;
1613}
1614
1615static void svm_set_cr3(struct kvm_vcpu *vcpu, unsigned long root)
1616{
1617 struct vcpu_svm *svm = to_svm(vcpu);
1618
1619 svm->vmcb->save.cr3 = root;
1620 force_new_asid(vcpu);
1621
1622 if (vcpu->fpu_active) {
1623 svm->vmcb->control.intercept_exceptions |= (1 << NM_VECTOR);
1624 svm->vmcb->save.cr0 |= X86_CR0_TS;
1625 vcpu->fpu_active = 0;
1626 }
1627}
1628
1629static int is_disabled(void)
1630{
1631 u64 vm_cr;
1632
1633 rdmsrl(MSR_VM_CR, vm_cr);
1634 if (vm_cr & (1 << SVM_VM_CR_SVM_DISABLE))
1635 return 1;
1636
1637 return 0;
1638}
1639
1640static void
1641svm_patch_hypercall(struct kvm_vcpu *vcpu, unsigned char *hypercall)
1642{
1643 /*
1644 * Patch in the VMMCALL instruction:
1645 */
1646 hypercall[0] = 0x0f;
1647 hypercall[1] = 0x01;
1648 hypercall[2] = 0xd9;
1649}
1650
1651static void svm_check_processor_compat(void *rtn)
1652{
1653 *(int *)rtn = 0;
1654}
1655
1656static bool svm_cpu_has_accelerated_tpr(void)
1657{
1658 return false;
1659}
1660
1661static struct kvm_x86_ops svm_x86_ops = {
1662 .cpu_has_kvm_support = has_svm,
1663 .disabled_by_bios = is_disabled,
1664 .hardware_setup = svm_hardware_setup,
1665 .hardware_unsetup = svm_hardware_unsetup,
1666 .check_processor_compatibility = svm_check_processor_compat,
1667 .hardware_enable = svm_hardware_enable,
1668 .hardware_disable = svm_hardware_disable,
1669 .cpu_has_accelerated_tpr = svm_cpu_has_accelerated_tpr,
1670
1671 .vcpu_create = svm_create_vcpu,
1672 .vcpu_free = svm_free_vcpu,
1673 .vcpu_reset = svm_vcpu_reset,
1674
1675 .prepare_guest_switch = svm_prepare_guest_switch,
1676 .vcpu_load = svm_vcpu_load,
1677 .vcpu_put = svm_vcpu_put,
1678 .vcpu_decache = svm_vcpu_decache,
1679
1680 .set_guest_debug = svm_guest_debug,
1681 .get_msr = svm_get_msr,
1682 .set_msr = svm_set_msr,
1683 .get_segment_base = svm_get_segment_base,
1684 .get_segment = svm_get_segment,
1685 .set_segment = svm_set_segment,
1686 .get_cs_db_l_bits = kvm_get_cs_db_l_bits,
1687 .decache_cr4_guest_bits = svm_decache_cr4_guest_bits,
1688 .set_cr0 = svm_set_cr0,
1689 .set_cr3 = svm_set_cr3,
1690 .set_cr4 = svm_set_cr4,
1691 .set_efer = svm_set_efer,
1692 .get_idt = svm_get_idt,
1693 .set_idt = svm_set_idt,
1694 .get_gdt = svm_get_gdt,
1695 .set_gdt = svm_set_gdt,
1696 .get_dr = svm_get_dr,
1697 .set_dr = svm_set_dr,
1698 .cache_regs = svm_cache_regs,
1699 .decache_regs = svm_decache_regs,
1700 .get_rflags = svm_get_rflags,
1701 .set_rflags = svm_set_rflags,
1702
1703 .tlb_flush = svm_flush_tlb,
1704
1705 .run = svm_vcpu_run,
1706 .handle_exit = handle_exit,
1707 .skip_emulated_instruction = skip_emulated_instruction,
1708 .patch_hypercall = svm_patch_hypercall,
1709 .get_irq = svm_get_irq,
1710 .set_irq = svm_set_irq,
1711 .queue_exception = svm_queue_exception,
1712 .exception_injected = svm_exception_injected,
1713 .inject_pending_irq = svm_intr_assist,
1714 .inject_pending_vectors = do_interrupt_requests,
1715
1716 .set_tss_addr = svm_set_tss_addr,
1717};
1718
1719static int __init svm_init(void)
1720{
1721 return kvm_init(&svm_x86_ops, sizeof(struct vcpu_svm),
1722 THIS_MODULE);
1723}
1724
1725static void __exit svm_exit(void)
1726{
1727 kvm_exit();
1728}
1729
1730module_init(svm_init)
1731module_exit(svm_exit)
diff --git a/arch/x86/kvm/svm.h b/arch/x86/kvm/svm.h
new file mode 100644
index 000000000000..5fd50491b555
--- /dev/null
+++ b/arch/x86/kvm/svm.h
@@ -0,0 +1,325 @@
1#ifndef __SVM_H
2#define __SVM_H
3
4enum {
5 INTERCEPT_INTR,
6 INTERCEPT_NMI,
7 INTERCEPT_SMI,
8 INTERCEPT_INIT,
9 INTERCEPT_VINTR,
10 INTERCEPT_SELECTIVE_CR0,
11 INTERCEPT_STORE_IDTR,
12 INTERCEPT_STORE_GDTR,
13 INTERCEPT_STORE_LDTR,
14 INTERCEPT_STORE_TR,
15 INTERCEPT_LOAD_IDTR,
16 INTERCEPT_LOAD_GDTR,
17 INTERCEPT_LOAD_LDTR,
18 INTERCEPT_LOAD_TR,
19 INTERCEPT_RDTSC,
20 INTERCEPT_RDPMC,
21 INTERCEPT_PUSHF,
22 INTERCEPT_POPF,
23 INTERCEPT_CPUID,
24 INTERCEPT_RSM,
25 INTERCEPT_IRET,
26 INTERCEPT_INTn,
27 INTERCEPT_INVD,
28 INTERCEPT_PAUSE,
29 INTERCEPT_HLT,
30 INTERCEPT_INVLPG,
31 INTERCEPT_INVLPGA,
32 INTERCEPT_IOIO_PROT,
33 INTERCEPT_MSR_PROT,
34 INTERCEPT_TASK_SWITCH,
35 INTERCEPT_FERR_FREEZE,
36 INTERCEPT_SHUTDOWN,
37 INTERCEPT_VMRUN,
38 INTERCEPT_VMMCALL,
39 INTERCEPT_VMLOAD,
40 INTERCEPT_VMSAVE,
41 INTERCEPT_STGI,
42 INTERCEPT_CLGI,
43 INTERCEPT_SKINIT,
44 INTERCEPT_RDTSCP,
45 INTERCEPT_ICEBP,
46 INTERCEPT_WBINVD,
47 INTERCEPT_MONITOR,
48 INTERCEPT_MWAIT,
49 INTERCEPT_MWAIT_COND,
50};
51
52
53struct __attribute__ ((__packed__)) vmcb_control_area {
54 u16 intercept_cr_read;
55 u16 intercept_cr_write;
56 u16 intercept_dr_read;
57 u16 intercept_dr_write;
58 u32 intercept_exceptions;
59 u64 intercept;
60 u8 reserved_1[44];
61 u64 iopm_base_pa;
62 u64 msrpm_base_pa;
63 u64 tsc_offset;
64 u32 asid;
65 u8 tlb_ctl;
66 u8 reserved_2[3];
67 u32 int_ctl;
68 u32 int_vector;
69 u32 int_state;
70 u8 reserved_3[4];
71 u32 exit_code;
72 u32 exit_code_hi;
73 u64 exit_info_1;
74 u64 exit_info_2;
75 u32 exit_int_info;
76 u32 exit_int_info_err;
77 u64 nested_ctl;
78 u8 reserved_4[16];
79 u32 event_inj;
80 u32 event_inj_err;
81 u64 nested_cr3;
82 u64 lbr_ctl;
83 u8 reserved_5[832];
84};
85
86
87#define TLB_CONTROL_DO_NOTHING 0
88#define TLB_CONTROL_FLUSH_ALL_ASID 1
89
90#define V_TPR_MASK 0x0f
91
92#define V_IRQ_SHIFT 8
93#define V_IRQ_MASK (1 << V_IRQ_SHIFT)
94
95#define V_INTR_PRIO_SHIFT 16
96#define V_INTR_PRIO_MASK (0x0f << V_INTR_PRIO_SHIFT)
97
98#define V_IGN_TPR_SHIFT 20
99#define V_IGN_TPR_MASK (1 << V_IGN_TPR_SHIFT)
100
101#define V_INTR_MASKING_SHIFT 24
102#define V_INTR_MASKING_MASK (1 << V_INTR_MASKING_SHIFT)
103
104#define SVM_INTERRUPT_SHADOW_MASK 1
105
106#define SVM_IOIO_STR_SHIFT 2
107#define SVM_IOIO_REP_SHIFT 3
108#define SVM_IOIO_SIZE_SHIFT 4
109#define SVM_IOIO_ASIZE_SHIFT 7
110
111#define SVM_IOIO_TYPE_MASK 1
112#define SVM_IOIO_STR_MASK (1 << SVM_IOIO_STR_SHIFT)
113#define SVM_IOIO_REP_MASK (1 << SVM_IOIO_REP_SHIFT)
114#define SVM_IOIO_SIZE_MASK (7 << SVM_IOIO_SIZE_SHIFT)
115#define SVM_IOIO_ASIZE_MASK (7 << SVM_IOIO_ASIZE_SHIFT)
116
117struct __attribute__ ((__packed__)) vmcb_seg {
118 u16 selector;
119 u16 attrib;
120 u32 limit;
121 u64 base;
122};
123
124struct __attribute__ ((__packed__)) vmcb_save_area {
125 struct vmcb_seg es;
126 struct vmcb_seg cs;
127 struct vmcb_seg ss;
128 struct vmcb_seg ds;
129 struct vmcb_seg fs;
130 struct vmcb_seg gs;
131 struct vmcb_seg gdtr;
132 struct vmcb_seg ldtr;
133 struct vmcb_seg idtr;
134 struct vmcb_seg tr;
135 u8 reserved_1[43];
136 u8 cpl;
137 u8 reserved_2[4];
138 u64 efer;
139 u8 reserved_3[112];
140 u64 cr4;
141 u64 cr3;
142 u64 cr0;
143 u64 dr7;
144 u64 dr6;
145 u64 rflags;
146 u64 rip;
147 u8 reserved_4[88];
148 u64 rsp;
149 u8 reserved_5[24];
150 u64 rax;
151 u64 star;
152 u64 lstar;
153 u64 cstar;
154 u64 sfmask;
155 u64 kernel_gs_base;
156 u64 sysenter_cs;
157 u64 sysenter_esp;
158 u64 sysenter_eip;
159 u64 cr2;
160 u8 reserved_6[32];
161 u64 g_pat;
162 u64 dbgctl;
163 u64 br_from;
164 u64 br_to;
165 u64 last_excp_from;
166 u64 last_excp_to;
167};
168
169struct __attribute__ ((__packed__)) vmcb {
170 struct vmcb_control_area control;
171 struct vmcb_save_area save;
172};
173
174#define SVM_CPUID_FEATURE_SHIFT 2
175#define SVM_CPUID_FUNC 0x8000000a
176
177#define MSR_EFER_SVME_MASK (1ULL << 12)
178#define MSR_VM_CR 0xc0010114
179#define MSR_VM_HSAVE_PA 0xc0010117ULL
180
181#define SVM_VM_CR_SVM_DISABLE 4
182
183#define SVM_SELECTOR_S_SHIFT 4
184#define SVM_SELECTOR_DPL_SHIFT 5
185#define SVM_SELECTOR_P_SHIFT 7
186#define SVM_SELECTOR_AVL_SHIFT 8
187#define SVM_SELECTOR_L_SHIFT 9
188#define SVM_SELECTOR_DB_SHIFT 10
189#define SVM_SELECTOR_G_SHIFT 11
190
191#define SVM_SELECTOR_TYPE_MASK (0xf)
192#define SVM_SELECTOR_S_MASK (1 << SVM_SELECTOR_S_SHIFT)
193#define SVM_SELECTOR_DPL_MASK (3 << SVM_SELECTOR_DPL_SHIFT)
194#define SVM_SELECTOR_P_MASK (1 << SVM_SELECTOR_P_SHIFT)
195#define SVM_SELECTOR_AVL_MASK (1 << SVM_SELECTOR_AVL_SHIFT)
196#define SVM_SELECTOR_L_MASK (1 << SVM_SELECTOR_L_SHIFT)
197#define SVM_SELECTOR_DB_MASK (1 << SVM_SELECTOR_DB_SHIFT)
198#define SVM_SELECTOR_G_MASK (1 << SVM_SELECTOR_G_SHIFT)
199
200#define SVM_SELECTOR_WRITE_MASK (1 << 1)
201#define SVM_SELECTOR_READ_MASK SVM_SELECTOR_WRITE_MASK
202#define SVM_SELECTOR_CODE_MASK (1 << 3)
203
204#define INTERCEPT_CR0_MASK 1
205#define INTERCEPT_CR3_MASK (1 << 3)
206#define INTERCEPT_CR4_MASK (1 << 4)
207#define INTERCEPT_CR8_MASK (1 << 8)
208
209#define INTERCEPT_DR0_MASK 1
210#define INTERCEPT_DR1_MASK (1 << 1)
211#define INTERCEPT_DR2_MASK (1 << 2)
212#define INTERCEPT_DR3_MASK (1 << 3)
213#define INTERCEPT_DR4_MASK (1 << 4)
214#define INTERCEPT_DR5_MASK (1 << 5)
215#define INTERCEPT_DR6_MASK (1 << 6)
216#define INTERCEPT_DR7_MASK (1 << 7)
217
218#define SVM_EVTINJ_VEC_MASK 0xff
219
220#define SVM_EVTINJ_TYPE_SHIFT 8
221#define SVM_EVTINJ_TYPE_MASK (7 << SVM_EVTINJ_TYPE_SHIFT)
222
223#define SVM_EVTINJ_TYPE_INTR (0 << SVM_EVTINJ_TYPE_SHIFT)
224#define SVM_EVTINJ_TYPE_NMI (2 << SVM_EVTINJ_TYPE_SHIFT)
225#define SVM_EVTINJ_TYPE_EXEPT (3 << SVM_EVTINJ_TYPE_SHIFT)
226#define SVM_EVTINJ_TYPE_SOFT (4 << SVM_EVTINJ_TYPE_SHIFT)
227
228#define SVM_EVTINJ_VALID (1 << 31)
229#define SVM_EVTINJ_VALID_ERR (1 << 11)
230
231#define SVM_EXITINTINFO_VEC_MASK SVM_EVTINJ_VEC_MASK
232
233#define SVM_EXITINTINFO_TYPE_INTR SVM_EVTINJ_TYPE_INTR
234#define SVM_EXITINTINFO_TYPE_NMI SVM_EVTINJ_TYPE_NMI
235#define SVM_EXITINTINFO_TYPE_EXEPT SVM_EVTINJ_TYPE_EXEPT
236#define SVM_EXITINTINFO_TYPE_SOFT SVM_EVTINJ_TYPE_SOFT
237
238#define SVM_EXITINTINFO_VALID SVM_EVTINJ_VALID
239#define SVM_EXITINTINFO_VALID_ERR SVM_EVTINJ_VALID_ERR
240
241#define SVM_EXIT_READ_CR0 0x000
242#define SVM_EXIT_READ_CR3 0x003
243#define SVM_EXIT_READ_CR4 0x004
244#define SVM_EXIT_READ_CR8 0x008
245#define SVM_EXIT_WRITE_CR0 0x010
246#define SVM_EXIT_WRITE_CR3 0x013
247#define SVM_EXIT_WRITE_CR4 0x014
248#define SVM_EXIT_WRITE_CR8 0x018
249#define SVM_EXIT_READ_DR0 0x020
250#define SVM_EXIT_READ_DR1 0x021
251#define SVM_EXIT_READ_DR2 0x022
252#define SVM_EXIT_READ_DR3 0x023
253#define SVM_EXIT_READ_DR4 0x024
254#define SVM_EXIT_READ_DR5 0x025
255#define SVM_EXIT_READ_DR6 0x026
256#define SVM_EXIT_READ_DR7 0x027
257#define SVM_EXIT_WRITE_DR0 0x030
258#define SVM_EXIT_WRITE_DR1 0x031
259#define SVM_EXIT_WRITE_DR2 0x032
260#define SVM_EXIT_WRITE_DR3 0x033
261#define SVM_EXIT_WRITE_DR4 0x034
262#define SVM_EXIT_WRITE_DR5 0x035
263#define SVM_EXIT_WRITE_DR6 0x036
264#define SVM_EXIT_WRITE_DR7 0x037
265#define SVM_EXIT_EXCP_BASE 0x040
266#define SVM_EXIT_INTR 0x060
267#define SVM_EXIT_NMI 0x061
268#define SVM_EXIT_SMI 0x062
269#define SVM_EXIT_INIT 0x063
270#define SVM_EXIT_VINTR 0x064
271#define SVM_EXIT_CR0_SEL_WRITE 0x065
272#define SVM_EXIT_IDTR_READ 0x066
273#define SVM_EXIT_GDTR_READ 0x067
274#define SVM_EXIT_LDTR_READ 0x068
275#define SVM_EXIT_TR_READ 0x069
276#define SVM_EXIT_IDTR_WRITE 0x06a
277#define SVM_EXIT_GDTR_WRITE 0x06b
278#define SVM_EXIT_LDTR_WRITE 0x06c
279#define SVM_EXIT_TR_WRITE 0x06d
280#define SVM_EXIT_RDTSC 0x06e
281#define SVM_EXIT_RDPMC 0x06f
282#define SVM_EXIT_PUSHF 0x070
283#define SVM_EXIT_POPF 0x071
284#define SVM_EXIT_CPUID 0x072
285#define SVM_EXIT_RSM 0x073
286#define SVM_EXIT_IRET 0x074
287#define SVM_EXIT_SWINT 0x075
288#define SVM_EXIT_INVD 0x076
289#define SVM_EXIT_PAUSE 0x077
290#define SVM_EXIT_HLT 0x078
291#define SVM_EXIT_INVLPG 0x079
292#define SVM_EXIT_INVLPGA 0x07a
293#define SVM_EXIT_IOIO 0x07b
294#define SVM_EXIT_MSR 0x07c
295#define SVM_EXIT_TASK_SWITCH 0x07d
296#define SVM_EXIT_FERR_FREEZE 0x07e
297#define SVM_EXIT_SHUTDOWN 0x07f
298#define SVM_EXIT_VMRUN 0x080
299#define SVM_EXIT_VMMCALL 0x081
300#define SVM_EXIT_VMLOAD 0x082
301#define SVM_EXIT_VMSAVE 0x083
302#define SVM_EXIT_STGI 0x084
303#define SVM_EXIT_CLGI 0x085
304#define SVM_EXIT_SKINIT 0x086
305#define SVM_EXIT_RDTSCP 0x087
306#define SVM_EXIT_ICEBP 0x088
307#define SVM_EXIT_WBINVD 0x089
308#define SVM_EXIT_MONITOR 0x08a
309#define SVM_EXIT_MWAIT 0x08b
310#define SVM_EXIT_MWAIT_COND 0x08c
311#define SVM_EXIT_NPF 0x400
312
313#define SVM_EXIT_ERR -1
314
315#define SVM_CR0_SELECTIVE_MASK (1 << 3 | 1) /* TS and MP */
316
317#define SVM_VMLOAD ".byte 0x0f, 0x01, 0xda"
318#define SVM_VMRUN ".byte 0x0f, 0x01, 0xd8"
319#define SVM_VMSAVE ".byte 0x0f, 0x01, 0xdb"
320#define SVM_CLGI ".byte 0x0f, 0x01, 0xdd"
321#define SVM_STGI ".byte 0x0f, 0x01, 0xdc"
322#define SVM_INVLPGA ".byte 0x0f, 0x01, 0xdf"
323
324#endif
325
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
new file mode 100644
index 000000000000..ad36447e696e
--- /dev/null
+++ b/arch/x86/kvm/vmx.c
@@ -0,0 +1,2679 @@
1/*
2 * Kernel-based Virtual Machine driver for Linux
3 *
4 * This module enables machines with Intel VT-x extensions to run virtual
5 * machines without emulation or binary translation.
6 *
7 * Copyright (C) 2006 Qumranet, Inc.
8 *
9 * Authors:
10 * Avi Kivity <avi@qumranet.com>
11 * Yaniv Kamay <yaniv@qumranet.com>
12 *
13 * This work is licensed under the terms of the GNU GPL, version 2. See
14 * the COPYING file in the top-level directory.
15 *
16 */
17
18#include "irq.h"
19#include "vmx.h"
20#include "segment_descriptor.h"
21#include "mmu.h"
22
23#include <linux/kvm_host.h>
24#include <linux/module.h>
25#include <linux/kernel.h>
26#include <linux/mm.h>
27#include <linux/highmem.h>
28#include <linux/sched.h>
29#include <linux/moduleparam.h>
30
31#include <asm/io.h>
32#include <asm/desc.h>
33
34MODULE_AUTHOR("Qumranet");
35MODULE_LICENSE("GPL");
36
37static int bypass_guest_pf = 1;
38module_param(bypass_guest_pf, bool, 0);
39
40struct vmcs {
41 u32 revision_id;
42 u32 abort;
43 char data[0];
44};
45
46struct vcpu_vmx {
47 struct kvm_vcpu vcpu;
48 int launched;
49 u8 fail;
50 u32 idt_vectoring_info;
51 struct kvm_msr_entry *guest_msrs;
52 struct kvm_msr_entry *host_msrs;
53 int nmsrs;
54 int save_nmsrs;
55 int msr_offset_efer;
56#ifdef CONFIG_X86_64
57 int msr_offset_kernel_gs_base;
58#endif
59 struct vmcs *vmcs;
60 struct {
61 int loaded;
62 u16 fs_sel, gs_sel, ldt_sel;
63 int gs_ldt_reload_needed;
64 int fs_reload_needed;
65 int guest_efer_loaded;
66 } host_state;
67 struct {
68 struct {
69 bool pending;
70 u8 vector;
71 unsigned rip;
72 } irq;
73 } rmode;
74};
75
76static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu)
77{
78 return container_of(vcpu, struct vcpu_vmx, vcpu);
79}
80
81static int init_rmode_tss(struct kvm *kvm);
82
83static DEFINE_PER_CPU(struct vmcs *, vmxarea);
84static DEFINE_PER_CPU(struct vmcs *, current_vmcs);
85
86static struct page *vmx_io_bitmap_a;
87static struct page *vmx_io_bitmap_b;
88
89static struct vmcs_config {
90 int size;
91 int order;
92 u32 revision_id;
93 u32 pin_based_exec_ctrl;
94 u32 cpu_based_exec_ctrl;
95 u32 cpu_based_2nd_exec_ctrl;
96 u32 vmexit_ctrl;
97 u32 vmentry_ctrl;
98} vmcs_config;
99
100#define VMX_SEGMENT_FIELD(seg) \
101 [VCPU_SREG_##seg] = { \
102 .selector = GUEST_##seg##_SELECTOR, \
103 .base = GUEST_##seg##_BASE, \
104 .limit = GUEST_##seg##_LIMIT, \
105 .ar_bytes = GUEST_##seg##_AR_BYTES, \
106 }
107
108static struct kvm_vmx_segment_field {
109 unsigned selector;
110 unsigned base;
111 unsigned limit;
112 unsigned ar_bytes;
113} kvm_vmx_segment_fields[] = {
114 VMX_SEGMENT_FIELD(CS),
115 VMX_SEGMENT_FIELD(DS),
116 VMX_SEGMENT_FIELD(ES),
117 VMX_SEGMENT_FIELD(FS),
118 VMX_SEGMENT_FIELD(GS),
119 VMX_SEGMENT_FIELD(SS),
120 VMX_SEGMENT_FIELD(TR),
121 VMX_SEGMENT_FIELD(LDTR),
122};
123
124/*
125 * Keep MSR_K6_STAR at the end, as setup_msrs() will try to optimize it
126 * away by decrementing the array size.
127 */
128static const u32 vmx_msr_index[] = {
129#ifdef CONFIG_X86_64
130 MSR_SYSCALL_MASK, MSR_LSTAR, MSR_CSTAR, MSR_KERNEL_GS_BASE,
131#endif
132 MSR_EFER, MSR_K6_STAR,
133};
134#define NR_VMX_MSR ARRAY_SIZE(vmx_msr_index)
135
136static void load_msrs(struct kvm_msr_entry *e, int n)
137{
138 int i;
139
140 for (i = 0; i < n; ++i)
141 wrmsrl(e[i].index, e[i].data);
142}
143
144static void save_msrs(struct kvm_msr_entry *e, int n)
145{
146 int i;
147
148 for (i = 0; i < n; ++i)
149 rdmsrl(e[i].index, e[i].data);
150}
151
152static inline int is_page_fault(u32 intr_info)
153{
154 return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK |
155 INTR_INFO_VALID_MASK)) ==
156 (INTR_TYPE_EXCEPTION | PF_VECTOR | INTR_INFO_VALID_MASK);
157}
158
159static inline int is_no_device(u32 intr_info)
160{
161 return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK |
162 INTR_INFO_VALID_MASK)) ==
163 (INTR_TYPE_EXCEPTION | NM_VECTOR | INTR_INFO_VALID_MASK);
164}
165
166static inline int is_invalid_opcode(u32 intr_info)
167{
168 return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK |
169 INTR_INFO_VALID_MASK)) ==
170 (INTR_TYPE_EXCEPTION | UD_VECTOR | INTR_INFO_VALID_MASK);
171}
172
173static inline int is_external_interrupt(u32 intr_info)
174{
175 return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VALID_MASK))
176 == (INTR_TYPE_EXT_INTR | INTR_INFO_VALID_MASK);
177}
178
179static inline int cpu_has_vmx_tpr_shadow(void)
180{
181 return (vmcs_config.cpu_based_exec_ctrl & CPU_BASED_TPR_SHADOW);
182}
183
184static inline int vm_need_tpr_shadow(struct kvm *kvm)
185{
186 return ((cpu_has_vmx_tpr_shadow()) && (irqchip_in_kernel(kvm)));
187}
188
189static inline int cpu_has_secondary_exec_ctrls(void)
190{
191 return (vmcs_config.cpu_based_exec_ctrl &
192 CPU_BASED_ACTIVATE_SECONDARY_CONTROLS);
193}
194
195static inline bool cpu_has_vmx_virtualize_apic_accesses(void)
196{
197 return (vmcs_config.cpu_based_2nd_exec_ctrl &
198 SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES);
199}
200
201static inline int vm_need_virtualize_apic_accesses(struct kvm *kvm)
202{
203 return ((cpu_has_vmx_virtualize_apic_accesses()) &&
204 (irqchip_in_kernel(kvm)));
205}
206
207static int __find_msr_index(struct vcpu_vmx *vmx, u32 msr)
208{
209 int i;
210
211 for (i = 0; i < vmx->nmsrs; ++i)
212 if (vmx->guest_msrs[i].index == msr)
213 return i;
214 return -1;
215}
216
217static struct kvm_msr_entry *find_msr_entry(struct vcpu_vmx *vmx, u32 msr)
218{
219 int i;
220
221 i = __find_msr_index(vmx, msr);
222 if (i >= 0)
223 return &vmx->guest_msrs[i];
224 return NULL;
225}
226
227static void vmcs_clear(struct vmcs *vmcs)
228{
229 u64 phys_addr = __pa(vmcs);
230 u8 error;
231
232 asm volatile (ASM_VMX_VMCLEAR_RAX "; setna %0"
233 : "=g"(error) : "a"(&phys_addr), "m"(phys_addr)
234 : "cc", "memory");
235 if (error)
236 printk(KERN_ERR "kvm: vmclear fail: %p/%llx\n",
237 vmcs, phys_addr);
238}
239
240static void __vcpu_clear(void *arg)
241{
242 struct vcpu_vmx *vmx = arg;
243 int cpu = raw_smp_processor_id();
244
245 if (vmx->vcpu.cpu == cpu)
246 vmcs_clear(vmx->vmcs);
247 if (per_cpu(current_vmcs, cpu) == vmx->vmcs)
248 per_cpu(current_vmcs, cpu) = NULL;
249 rdtscll(vmx->vcpu.arch.host_tsc);
250}
251
252static void vcpu_clear(struct vcpu_vmx *vmx)
253{
254 if (vmx->vcpu.cpu == -1)
255 return;
256 smp_call_function_single(vmx->vcpu.cpu, __vcpu_clear, vmx, 0, 1);
257 vmx->launched = 0;
258}
259
260static unsigned long vmcs_readl(unsigned long field)
261{
262 unsigned long value;
263
264 asm volatile (ASM_VMX_VMREAD_RDX_RAX
265 : "=a"(value) : "d"(field) : "cc");
266 return value;
267}
268
269static u16 vmcs_read16(unsigned long field)
270{
271 return vmcs_readl(field);
272}
273
274static u32 vmcs_read32(unsigned long field)
275{
276 return vmcs_readl(field);
277}
278
279static u64 vmcs_read64(unsigned long field)
280{
281#ifdef CONFIG_X86_64
282 return vmcs_readl(field);
283#else
284 return vmcs_readl(field) | ((u64)vmcs_readl(field+1) << 32);
285#endif
286}
287
288static noinline void vmwrite_error(unsigned long field, unsigned long value)
289{
290 printk(KERN_ERR "vmwrite error: reg %lx value %lx (err %d)\n",
291 field, value, vmcs_read32(VM_INSTRUCTION_ERROR));
292 dump_stack();
293}
294
295static void vmcs_writel(unsigned long field, unsigned long value)
296{
297 u8 error;
298
299 asm volatile (ASM_VMX_VMWRITE_RAX_RDX "; setna %0"
300 : "=q"(error) : "a"(value), "d"(field) : "cc");
301 if (unlikely(error))
302 vmwrite_error(field, value);
303}
304
305static void vmcs_write16(unsigned long field, u16 value)
306{
307 vmcs_writel(field, value);
308}
309
310static void vmcs_write32(unsigned long field, u32 value)
311{
312 vmcs_writel(field, value);
313}
314
315static void vmcs_write64(unsigned long field, u64 value)
316{
317#ifdef CONFIG_X86_64
318 vmcs_writel(field, value);
319#else
320 vmcs_writel(field, value);
321 asm volatile ("");
322 vmcs_writel(field+1, value >> 32);
323#endif
324}
325
326static void vmcs_clear_bits(unsigned long field, u32 mask)
327{
328 vmcs_writel(field, vmcs_readl(field) & ~mask);
329}
330
331static void vmcs_set_bits(unsigned long field, u32 mask)
332{
333 vmcs_writel(field, vmcs_readl(field) | mask);
334}
335
336static void update_exception_bitmap(struct kvm_vcpu *vcpu)
337{
338 u32 eb;
339
340 eb = (1u << PF_VECTOR) | (1u << UD_VECTOR);
341 if (!vcpu->fpu_active)
342 eb |= 1u << NM_VECTOR;
343 if (vcpu->guest_debug.enabled)
344 eb |= 1u << 1;
345 if (vcpu->arch.rmode.active)
346 eb = ~0;
347 vmcs_write32(EXCEPTION_BITMAP, eb);
348}
349
350static void reload_tss(void)
351{
352#ifndef CONFIG_X86_64
353
354 /*
355 * VT restores TR but not its size. Useless.
356 */
357 struct descriptor_table gdt;
358 struct segment_descriptor *descs;
359
360 get_gdt(&gdt);
361 descs = (void *)gdt.base;
362 descs[GDT_ENTRY_TSS].type = 9; /* available TSS */
363 load_TR_desc();
364#endif
365}
366
367static void load_transition_efer(struct vcpu_vmx *vmx)
368{
369 int efer_offset = vmx->msr_offset_efer;
370 u64 host_efer = vmx->host_msrs[efer_offset].data;
371 u64 guest_efer = vmx->guest_msrs[efer_offset].data;
372 u64 ignore_bits;
373
374 if (efer_offset < 0)
375 return;
376 /*
377 * NX is emulated; LMA and LME handled by hardware; SCE meaninless
378 * outside long mode
379 */
380 ignore_bits = EFER_NX | EFER_SCE;
381#ifdef CONFIG_X86_64
382 ignore_bits |= EFER_LMA | EFER_LME;
383 /* SCE is meaningful only in long mode on Intel */
384 if (guest_efer & EFER_LMA)
385 ignore_bits &= ~(u64)EFER_SCE;
386#endif
387 if ((guest_efer & ~ignore_bits) == (host_efer & ~ignore_bits))
388 return;
389
390 vmx->host_state.guest_efer_loaded = 1;
391 guest_efer &= ~ignore_bits;
392 guest_efer |= host_efer & ignore_bits;
393 wrmsrl(MSR_EFER, guest_efer);
394 vmx->vcpu.stat.efer_reload++;
395}
396
397static void reload_host_efer(struct vcpu_vmx *vmx)
398{
399 if (vmx->host_state.guest_efer_loaded) {
400 vmx->host_state.guest_efer_loaded = 0;
401 load_msrs(vmx->host_msrs + vmx->msr_offset_efer, 1);
402 }
403}
404
405static void vmx_save_host_state(struct kvm_vcpu *vcpu)
406{
407 struct vcpu_vmx *vmx = to_vmx(vcpu);
408
409 if (vmx->host_state.loaded)
410 return;
411
412 vmx->host_state.loaded = 1;
413 /*
414 * Set host fs and gs selectors. Unfortunately, 22.2.3 does not
415 * allow segment selectors with cpl > 0 or ti == 1.
416 */
417 vmx->host_state.ldt_sel = read_ldt();
418 vmx->host_state.gs_ldt_reload_needed = vmx->host_state.ldt_sel;
419 vmx->host_state.fs_sel = read_fs();
420 if (!(vmx->host_state.fs_sel & 7)) {
421 vmcs_write16(HOST_FS_SELECTOR, vmx->host_state.fs_sel);
422 vmx->host_state.fs_reload_needed = 0;
423 } else {
424 vmcs_write16(HOST_FS_SELECTOR, 0);
425 vmx->host_state.fs_reload_needed = 1;
426 }
427 vmx->host_state.gs_sel = read_gs();
428 if (!(vmx->host_state.gs_sel & 7))
429 vmcs_write16(HOST_GS_SELECTOR, vmx->host_state.gs_sel);
430 else {
431 vmcs_write16(HOST_GS_SELECTOR, 0);
432 vmx->host_state.gs_ldt_reload_needed = 1;
433 }
434
435#ifdef CONFIG_X86_64
436 vmcs_writel(HOST_FS_BASE, read_msr(MSR_FS_BASE));
437 vmcs_writel(HOST_GS_BASE, read_msr(MSR_GS_BASE));
438#else
439 vmcs_writel(HOST_FS_BASE, segment_base(vmx->host_state.fs_sel));
440 vmcs_writel(HOST_GS_BASE, segment_base(vmx->host_state.gs_sel));
441#endif
442
443#ifdef CONFIG_X86_64
444 if (is_long_mode(&vmx->vcpu))
445 save_msrs(vmx->host_msrs +
446 vmx->msr_offset_kernel_gs_base, 1);
447
448#endif
449 load_msrs(vmx->guest_msrs, vmx->save_nmsrs);
450 load_transition_efer(vmx);
451}
452
453static void vmx_load_host_state(struct vcpu_vmx *vmx)
454{
455 unsigned long flags;
456
457 if (!vmx->host_state.loaded)
458 return;
459
460 ++vmx->vcpu.stat.host_state_reload;
461 vmx->host_state.loaded = 0;
462 if (vmx->host_state.fs_reload_needed)
463 load_fs(vmx->host_state.fs_sel);
464 if (vmx->host_state.gs_ldt_reload_needed) {
465 load_ldt(vmx->host_state.ldt_sel);
466 /*
467 * If we have to reload gs, we must take care to
468 * preserve our gs base.
469 */
470 local_irq_save(flags);
471 load_gs(vmx->host_state.gs_sel);
472#ifdef CONFIG_X86_64
473 wrmsrl(MSR_GS_BASE, vmcs_readl(HOST_GS_BASE));
474#endif
475 local_irq_restore(flags);
476 }
477 reload_tss();
478 save_msrs(vmx->guest_msrs, vmx->save_nmsrs);
479 load_msrs(vmx->host_msrs, vmx->save_nmsrs);
480 reload_host_efer(vmx);
481}
482
483/*
484 * Switches to specified vcpu, until a matching vcpu_put(), but assumes
485 * vcpu mutex is already taken.
486 */
487static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
488{
489 struct vcpu_vmx *vmx = to_vmx(vcpu);
490 u64 phys_addr = __pa(vmx->vmcs);
491 u64 tsc_this, delta;
492
493 if (vcpu->cpu != cpu) {
494 vcpu_clear(vmx);
495 kvm_migrate_apic_timer(vcpu);
496 }
497
498 if (per_cpu(current_vmcs, cpu) != vmx->vmcs) {
499 u8 error;
500
501 per_cpu(current_vmcs, cpu) = vmx->vmcs;
502 asm volatile (ASM_VMX_VMPTRLD_RAX "; setna %0"
503 : "=g"(error) : "a"(&phys_addr), "m"(phys_addr)
504 : "cc");
505 if (error)
506 printk(KERN_ERR "kvm: vmptrld %p/%llx fail\n",
507 vmx->vmcs, phys_addr);
508 }
509
510 if (vcpu->cpu != cpu) {
511 struct descriptor_table dt;
512 unsigned long sysenter_esp;
513
514 vcpu->cpu = cpu;
515 /*
516 * Linux uses per-cpu TSS and GDT, so set these when switching
517 * processors.
518 */
519 vmcs_writel(HOST_TR_BASE, read_tr_base()); /* 22.2.4 */
520 get_gdt(&dt);
521 vmcs_writel(HOST_GDTR_BASE, dt.base); /* 22.2.4 */
522
523 rdmsrl(MSR_IA32_SYSENTER_ESP, sysenter_esp);
524 vmcs_writel(HOST_IA32_SYSENTER_ESP, sysenter_esp); /* 22.2.3 */
525
526 /*
527 * Make sure the time stamp counter is monotonous.
528 */
529 rdtscll(tsc_this);
530 delta = vcpu->arch.host_tsc - tsc_this;
531 vmcs_write64(TSC_OFFSET, vmcs_read64(TSC_OFFSET) + delta);
532 }
533}
534
535static void vmx_vcpu_put(struct kvm_vcpu *vcpu)
536{
537 vmx_load_host_state(to_vmx(vcpu));
538}
539
540static void vmx_fpu_activate(struct kvm_vcpu *vcpu)
541{
542 if (vcpu->fpu_active)
543 return;
544 vcpu->fpu_active = 1;
545 vmcs_clear_bits(GUEST_CR0, X86_CR0_TS);
546 if (vcpu->arch.cr0 & X86_CR0_TS)
547 vmcs_set_bits(GUEST_CR0, X86_CR0_TS);
548 update_exception_bitmap(vcpu);
549}
550
551static void vmx_fpu_deactivate(struct kvm_vcpu *vcpu)
552{
553 if (!vcpu->fpu_active)
554 return;
555 vcpu->fpu_active = 0;
556 vmcs_set_bits(GUEST_CR0, X86_CR0_TS);
557 update_exception_bitmap(vcpu);
558}
559
560static void vmx_vcpu_decache(struct kvm_vcpu *vcpu)
561{
562 vcpu_clear(to_vmx(vcpu));
563}
564
565static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu)
566{
567 return vmcs_readl(GUEST_RFLAGS);
568}
569
570static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
571{
572 if (vcpu->arch.rmode.active)
573 rflags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM;
574 vmcs_writel(GUEST_RFLAGS, rflags);
575}
576
577static void skip_emulated_instruction(struct kvm_vcpu *vcpu)
578{
579 unsigned long rip;
580 u32 interruptibility;
581
582 rip = vmcs_readl(GUEST_RIP);
583 rip += vmcs_read32(VM_EXIT_INSTRUCTION_LEN);
584 vmcs_writel(GUEST_RIP, rip);
585
586 /*
587 * We emulated an instruction, so temporary interrupt blocking
588 * should be removed, if set.
589 */
590 interruptibility = vmcs_read32(GUEST_INTERRUPTIBILITY_INFO);
591 if (interruptibility & 3)
592 vmcs_write32(GUEST_INTERRUPTIBILITY_INFO,
593 interruptibility & ~3);
594 vcpu->arch.interrupt_window_open = 1;
595}
596
597static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
598 bool has_error_code, u32 error_code)
599{
600 vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
601 nr | INTR_TYPE_EXCEPTION
602 | (has_error_code ? INTR_INFO_DELIEVER_CODE_MASK : 0)
603 | INTR_INFO_VALID_MASK);
604 if (has_error_code)
605 vmcs_write32(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code);
606}
607
608static bool vmx_exception_injected(struct kvm_vcpu *vcpu)
609{
610 struct vcpu_vmx *vmx = to_vmx(vcpu);
611
612 return !(vmx->idt_vectoring_info & VECTORING_INFO_VALID_MASK);
613}
614
615/*
616 * Swap MSR entry in host/guest MSR entry array.
617 */
618#ifdef CONFIG_X86_64
619static void move_msr_up(struct vcpu_vmx *vmx, int from, int to)
620{
621 struct kvm_msr_entry tmp;
622
623 tmp = vmx->guest_msrs[to];
624 vmx->guest_msrs[to] = vmx->guest_msrs[from];
625 vmx->guest_msrs[from] = tmp;
626 tmp = vmx->host_msrs[to];
627 vmx->host_msrs[to] = vmx->host_msrs[from];
628 vmx->host_msrs[from] = tmp;
629}
630#endif
631
632/*
633 * Set up the vmcs to automatically save and restore system
634 * msrs. Don't touch the 64-bit msrs if the guest is in legacy
635 * mode, as fiddling with msrs is very expensive.
636 */
637static void setup_msrs(struct vcpu_vmx *vmx)
638{
639 int save_nmsrs;
640
641 save_nmsrs = 0;
642#ifdef CONFIG_X86_64
643 if (is_long_mode(&vmx->vcpu)) {
644 int index;
645
646 index = __find_msr_index(vmx, MSR_SYSCALL_MASK);
647 if (index >= 0)
648 move_msr_up(vmx, index, save_nmsrs++);
649 index = __find_msr_index(vmx, MSR_LSTAR);
650 if (index >= 0)
651 move_msr_up(vmx, index, save_nmsrs++);
652 index = __find_msr_index(vmx, MSR_CSTAR);
653 if (index >= 0)
654 move_msr_up(vmx, index, save_nmsrs++);
655 index = __find_msr_index(vmx, MSR_KERNEL_GS_BASE);
656 if (index >= 0)
657 move_msr_up(vmx, index, save_nmsrs++);
658 /*
659 * MSR_K6_STAR is only needed on long mode guests, and only
660 * if efer.sce is enabled.
661 */
662 index = __find_msr_index(vmx, MSR_K6_STAR);
663 if ((index >= 0) && (vmx->vcpu.arch.shadow_efer & EFER_SCE))
664 move_msr_up(vmx, index, save_nmsrs++);
665 }
666#endif
667 vmx->save_nmsrs = save_nmsrs;
668
669#ifdef CONFIG_X86_64
670 vmx->msr_offset_kernel_gs_base =
671 __find_msr_index(vmx, MSR_KERNEL_GS_BASE);
672#endif
673 vmx->msr_offset_efer = __find_msr_index(vmx, MSR_EFER);
674}
675
676/*
677 * reads and returns guest's timestamp counter "register"
678 * guest_tsc = host_tsc + tsc_offset -- 21.3
679 */
680static u64 guest_read_tsc(void)
681{
682 u64 host_tsc, tsc_offset;
683
684 rdtscll(host_tsc);
685 tsc_offset = vmcs_read64(TSC_OFFSET);
686 return host_tsc + tsc_offset;
687}
688
689/*
690 * writes 'guest_tsc' into guest's timestamp counter "register"
691 * guest_tsc = host_tsc + tsc_offset ==> tsc_offset = guest_tsc - host_tsc
692 */
693static void guest_write_tsc(u64 guest_tsc)
694{
695 u64 host_tsc;
696
697 rdtscll(host_tsc);
698 vmcs_write64(TSC_OFFSET, guest_tsc - host_tsc);
699}
700
701/*
702 * Reads an msr value (of 'msr_index') into 'pdata'.
703 * Returns 0 on success, non-0 otherwise.
704 * Assumes vcpu_load() was already called.
705 */
706static int vmx_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
707{
708 u64 data;
709 struct kvm_msr_entry *msr;
710
711 if (!pdata) {
712 printk(KERN_ERR "BUG: get_msr called with NULL pdata\n");
713 return -EINVAL;
714 }
715
716 switch (msr_index) {
717#ifdef CONFIG_X86_64
718 case MSR_FS_BASE:
719 data = vmcs_readl(GUEST_FS_BASE);
720 break;
721 case MSR_GS_BASE:
722 data = vmcs_readl(GUEST_GS_BASE);
723 break;
724 case MSR_EFER:
725 return kvm_get_msr_common(vcpu, msr_index, pdata);
726#endif
727 case MSR_IA32_TIME_STAMP_COUNTER:
728 data = guest_read_tsc();
729 break;
730 case MSR_IA32_SYSENTER_CS:
731 data = vmcs_read32(GUEST_SYSENTER_CS);
732 break;
733 case MSR_IA32_SYSENTER_EIP:
734 data = vmcs_readl(GUEST_SYSENTER_EIP);
735 break;
736 case MSR_IA32_SYSENTER_ESP:
737 data = vmcs_readl(GUEST_SYSENTER_ESP);
738 break;
739 default:
740 msr = find_msr_entry(to_vmx(vcpu), msr_index);
741 if (msr) {
742 data = msr->data;
743 break;
744 }
745 return kvm_get_msr_common(vcpu, msr_index, pdata);
746 }
747
748 *pdata = data;
749 return 0;
750}
751
752/*
753 * Writes msr value into into the appropriate "register".
754 * Returns 0 on success, non-0 otherwise.
755 * Assumes vcpu_load() was already called.
756 */
757static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
758{
759 struct vcpu_vmx *vmx = to_vmx(vcpu);
760 struct kvm_msr_entry *msr;
761 int ret = 0;
762
763 switch (msr_index) {
764#ifdef CONFIG_X86_64
765 case MSR_EFER:
766 ret = kvm_set_msr_common(vcpu, msr_index, data);
767 if (vmx->host_state.loaded) {
768 reload_host_efer(vmx);
769 load_transition_efer(vmx);
770 }
771 break;
772 case MSR_FS_BASE:
773 vmcs_writel(GUEST_FS_BASE, data);
774 break;
775 case MSR_GS_BASE:
776 vmcs_writel(GUEST_GS_BASE, data);
777 break;
778#endif
779 case MSR_IA32_SYSENTER_CS:
780 vmcs_write32(GUEST_SYSENTER_CS, data);
781 break;
782 case MSR_IA32_SYSENTER_EIP:
783 vmcs_writel(GUEST_SYSENTER_EIP, data);
784 break;
785 case MSR_IA32_SYSENTER_ESP:
786 vmcs_writel(GUEST_SYSENTER_ESP, data);
787 break;
788 case MSR_IA32_TIME_STAMP_COUNTER:
789 guest_write_tsc(data);
790 break;
791 default:
792 msr = find_msr_entry(vmx, msr_index);
793 if (msr) {
794 msr->data = data;
795 if (vmx->host_state.loaded)
796 load_msrs(vmx->guest_msrs, vmx->save_nmsrs);
797 break;
798 }
799 ret = kvm_set_msr_common(vcpu, msr_index, data);
800 }
801
802 return ret;
803}
804
805/*
806 * Sync the rsp and rip registers into the vcpu structure. This allows
807 * registers to be accessed by indexing vcpu->arch.regs.
808 */
809static void vcpu_load_rsp_rip(struct kvm_vcpu *vcpu)
810{
811 vcpu->arch.regs[VCPU_REGS_RSP] = vmcs_readl(GUEST_RSP);
812 vcpu->arch.rip = vmcs_readl(GUEST_RIP);
813}
814
815/*
816 * Syncs rsp and rip back into the vmcs. Should be called after possible
817 * modification.
818 */
819static void vcpu_put_rsp_rip(struct kvm_vcpu *vcpu)
820{
821 vmcs_writel(GUEST_RSP, vcpu->arch.regs[VCPU_REGS_RSP]);
822 vmcs_writel(GUEST_RIP, vcpu->arch.rip);
823}
824
825static int set_guest_debug(struct kvm_vcpu *vcpu, struct kvm_debug_guest *dbg)
826{
827 unsigned long dr7 = 0x400;
828 int old_singlestep;
829
830 old_singlestep = vcpu->guest_debug.singlestep;
831
832 vcpu->guest_debug.enabled = dbg->enabled;
833 if (vcpu->guest_debug.enabled) {
834 int i;
835
836 dr7 |= 0x200; /* exact */
837 for (i = 0; i < 4; ++i) {
838 if (!dbg->breakpoints[i].enabled)
839 continue;
840 vcpu->guest_debug.bp[i] = dbg->breakpoints[i].address;
841 dr7 |= 2 << (i*2); /* global enable */
842 dr7 |= 0 << (i*4+16); /* execution breakpoint */
843 }
844
845 vcpu->guest_debug.singlestep = dbg->singlestep;
846 } else
847 vcpu->guest_debug.singlestep = 0;
848
849 if (old_singlestep && !vcpu->guest_debug.singlestep) {
850 unsigned long flags;
851
852 flags = vmcs_readl(GUEST_RFLAGS);
853 flags &= ~(X86_EFLAGS_TF | X86_EFLAGS_RF);
854 vmcs_writel(GUEST_RFLAGS, flags);
855 }
856
857 update_exception_bitmap(vcpu);
858 vmcs_writel(GUEST_DR7, dr7);
859
860 return 0;
861}
862
863static int vmx_get_irq(struct kvm_vcpu *vcpu)
864{
865 struct vcpu_vmx *vmx = to_vmx(vcpu);
866 u32 idtv_info_field;
867
868 idtv_info_field = vmx->idt_vectoring_info;
869 if (idtv_info_field & INTR_INFO_VALID_MASK) {
870 if (is_external_interrupt(idtv_info_field))
871 return idtv_info_field & VECTORING_INFO_VECTOR_MASK;
872 else
873 printk(KERN_DEBUG "pending exception: not handled yet\n");
874 }
875 return -1;
876}
877
878static __init int cpu_has_kvm_support(void)
879{
880 unsigned long ecx = cpuid_ecx(1);
881 return test_bit(5, &ecx); /* CPUID.1:ECX.VMX[bit 5] -> VT */
882}
883
884static __init int vmx_disabled_by_bios(void)
885{
886 u64 msr;
887
888 rdmsrl(MSR_IA32_FEATURE_CONTROL, msr);
889 return (msr & (MSR_IA32_FEATURE_CONTROL_LOCKED |
890 MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED))
891 == MSR_IA32_FEATURE_CONTROL_LOCKED;
892 /* locked but not enabled */
893}
894
895static void hardware_enable(void *garbage)
896{
897 int cpu = raw_smp_processor_id();
898 u64 phys_addr = __pa(per_cpu(vmxarea, cpu));
899 u64 old;
900
901 rdmsrl(MSR_IA32_FEATURE_CONTROL, old);
902 if ((old & (MSR_IA32_FEATURE_CONTROL_LOCKED |
903 MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED))
904 != (MSR_IA32_FEATURE_CONTROL_LOCKED |
905 MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED))
906 /* enable and lock */
907 wrmsrl(MSR_IA32_FEATURE_CONTROL, old |
908 MSR_IA32_FEATURE_CONTROL_LOCKED |
909 MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED);
910 write_cr4(read_cr4() | X86_CR4_VMXE); /* FIXME: not cpu hotplug safe */
911 asm volatile (ASM_VMX_VMXON_RAX : : "a"(&phys_addr), "m"(phys_addr)
912 : "memory", "cc");
913}
914
915static void hardware_disable(void *garbage)
916{
917 asm volatile (ASM_VMX_VMXOFF : : : "cc");
918}
919
920static __init int adjust_vmx_controls(u32 ctl_min, u32 ctl_opt,
921 u32 msr, u32 *result)
922{
923 u32 vmx_msr_low, vmx_msr_high;
924 u32 ctl = ctl_min | ctl_opt;
925
926 rdmsr(msr, vmx_msr_low, vmx_msr_high);
927
928 ctl &= vmx_msr_high; /* bit == 0 in high word ==> must be zero */
929 ctl |= vmx_msr_low; /* bit == 1 in low word ==> must be one */
930
931 /* Ensure minimum (required) set of control bits are supported. */
932 if (ctl_min & ~ctl)
933 return -EIO;
934
935 *result = ctl;
936 return 0;
937}
938
939static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
940{
941 u32 vmx_msr_low, vmx_msr_high;
942 u32 min, opt;
943 u32 _pin_based_exec_control = 0;
944 u32 _cpu_based_exec_control = 0;
945 u32 _cpu_based_2nd_exec_control = 0;
946 u32 _vmexit_control = 0;
947 u32 _vmentry_control = 0;
948
949 min = PIN_BASED_EXT_INTR_MASK | PIN_BASED_NMI_EXITING;
950 opt = 0;
951 if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_PINBASED_CTLS,
952 &_pin_based_exec_control) < 0)
953 return -EIO;
954
955 min = CPU_BASED_HLT_EXITING |
956#ifdef CONFIG_X86_64
957 CPU_BASED_CR8_LOAD_EXITING |
958 CPU_BASED_CR8_STORE_EXITING |
959#endif
960 CPU_BASED_USE_IO_BITMAPS |
961 CPU_BASED_MOV_DR_EXITING |
962 CPU_BASED_USE_TSC_OFFSETING;
963 opt = CPU_BASED_TPR_SHADOW |
964 CPU_BASED_ACTIVATE_SECONDARY_CONTROLS;
965 if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_PROCBASED_CTLS,
966 &_cpu_based_exec_control) < 0)
967 return -EIO;
968#ifdef CONFIG_X86_64
969 if ((_cpu_based_exec_control & CPU_BASED_TPR_SHADOW))
970 _cpu_based_exec_control &= ~CPU_BASED_CR8_LOAD_EXITING &
971 ~CPU_BASED_CR8_STORE_EXITING;
972#endif
973 if (_cpu_based_exec_control & CPU_BASED_ACTIVATE_SECONDARY_CONTROLS) {
974 min = 0;
975 opt = SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
976 SECONDARY_EXEC_WBINVD_EXITING;
977 if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_PROCBASED_CTLS2,
978 &_cpu_based_2nd_exec_control) < 0)
979 return -EIO;
980 }
981#ifndef CONFIG_X86_64
982 if (!(_cpu_based_2nd_exec_control &
983 SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES))
984 _cpu_based_exec_control &= ~CPU_BASED_TPR_SHADOW;
985#endif
986
987 min = 0;
988#ifdef CONFIG_X86_64
989 min |= VM_EXIT_HOST_ADDR_SPACE_SIZE;
990#endif
991 opt = 0;
992 if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_EXIT_CTLS,
993 &_vmexit_control) < 0)
994 return -EIO;
995
996 min = opt = 0;
997 if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_ENTRY_CTLS,
998 &_vmentry_control) < 0)
999 return -EIO;
1000
1001 rdmsr(MSR_IA32_VMX_BASIC, vmx_msr_low, vmx_msr_high);
1002
1003 /* IA-32 SDM Vol 3B: VMCS size is never greater than 4kB. */
1004 if ((vmx_msr_high & 0x1fff) > PAGE_SIZE)
1005 return -EIO;
1006
1007#ifdef CONFIG_X86_64
1008 /* IA-32 SDM Vol 3B: 64-bit CPUs always have VMX_BASIC_MSR[48]==0. */
1009 if (vmx_msr_high & (1u<<16))
1010 return -EIO;
1011#endif
1012
1013 /* Require Write-Back (WB) memory type for VMCS accesses. */
1014 if (((vmx_msr_high >> 18) & 15) != 6)
1015 return -EIO;
1016
1017 vmcs_conf->size = vmx_msr_high & 0x1fff;
1018 vmcs_conf->order = get_order(vmcs_config.size);
1019 vmcs_conf->revision_id = vmx_msr_low;
1020
1021 vmcs_conf->pin_based_exec_ctrl = _pin_based_exec_control;
1022 vmcs_conf->cpu_based_exec_ctrl = _cpu_based_exec_control;
1023 vmcs_conf->cpu_based_2nd_exec_ctrl = _cpu_based_2nd_exec_control;
1024 vmcs_conf->vmexit_ctrl = _vmexit_control;
1025 vmcs_conf->vmentry_ctrl = _vmentry_control;
1026
1027 return 0;
1028}
1029
1030static struct vmcs *alloc_vmcs_cpu(int cpu)
1031{
1032 int node = cpu_to_node(cpu);
1033 struct page *pages;
1034 struct vmcs *vmcs;
1035
1036 pages = alloc_pages_node(node, GFP_KERNEL, vmcs_config.order);
1037 if (!pages)
1038 return NULL;
1039 vmcs = page_address(pages);
1040 memset(vmcs, 0, vmcs_config.size);
1041 vmcs->revision_id = vmcs_config.revision_id; /* vmcs revision id */
1042 return vmcs;
1043}
1044
1045static struct vmcs *alloc_vmcs(void)
1046{
1047 return alloc_vmcs_cpu(raw_smp_processor_id());
1048}
1049
1050static void free_vmcs(struct vmcs *vmcs)
1051{
1052 free_pages((unsigned long)vmcs, vmcs_config.order);
1053}
1054
1055static void free_kvm_area(void)
1056{
1057 int cpu;
1058
1059 for_each_online_cpu(cpu)
1060 free_vmcs(per_cpu(vmxarea, cpu));
1061}
1062
1063static __init int alloc_kvm_area(void)
1064{
1065 int cpu;
1066
1067 for_each_online_cpu(cpu) {
1068 struct vmcs *vmcs;
1069
1070 vmcs = alloc_vmcs_cpu(cpu);
1071 if (!vmcs) {
1072 free_kvm_area();
1073 return -ENOMEM;
1074 }
1075
1076 per_cpu(vmxarea, cpu) = vmcs;
1077 }
1078 return 0;
1079}
1080
1081static __init int hardware_setup(void)
1082{
1083 if (setup_vmcs_config(&vmcs_config) < 0)
1084 return -EIO;
1085 return alloc_kvm_area();
1086}
1087
1088static __exit void hardware_unsetup(void)
1089{
1090 free_kvm_area();
1091}
1092
1093static void fix_pmode_dataseg(int seg, struct kvm_save_segment *save)
1094{
1095 struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
1096
1097 if (vmcs_readl(sf->base) == save->base && (save->base & AR_S_MASK)) {
1098 vmcs_write16(sf->selector, save->selector);
1099 vmcs_writel(sf->base, save->base);
1100 vmcs_write32(sf->limit, save->limit);
1101 vmcs_write32(sf->ar_bytes, save->ar);
1102 } else {
1103 u32 dpl = (vmcs_read16(sf->selector) & SELECTOR_RPL_MASK)
1104 << AR_DPL_SHIFT;
1105 vmcs_write32(sf->ar_bytes, 0x93 | dpl);
1106 }
1107}
1108
1109static void enter_pmode(struct kvm_vcpu *vcpu)
1110{
1111 unsigned long flags;
1112
1113 vcpu->arch.rmode.active = 0;
1114
1115 vmcs_writel(GUEST_TR_BASE, vcpu->arch.rmode.tr.base);
1116 vmcs_write32(GUEST_TR_LIMIT, vcpu->arch.rmode.tr.limit);
1117 vmcs_write32(GUEST_TR_AR_BYTES, vcpu->arch.rmode.tr.ar);
1118
1119 flags = vmcs_readl(GUEST_RFLAGS);
1120 flags &= ~(X86_EFLAGS_IOPL | X86_EFLAGS_VM);
1121 flags |= (vcpu->arch.rmode.save_iopl << IOPL_SHIFT);
1122 vmcs_writel(GUEST_RFLAGS, flags);
1123
1124 vmcs_writel(GUEST_CR4, (vmcs_readl(GUEST_CR4) & ~X86_CR4_VME) |
1125 (vmcs_readl(CR4_READ_SHADOW) & X86_CR4_VME));
1126
1127 update_exception_bitmap(vcpu);
1128
1129 fix_pmode_dataseg(VCPU_SREG_ES, &vcpu->arch.rmode.es);
1130 fix_pmode_dataseg(VCPU_SREG_DS, &vcpu->arch.rmode.ds);
1131 fix_pmode_dataseg(VCPU_SREG_GS, &vcpu->arch.rmode.gs);
1132 fix_pmode_dataseg(VCPU_SREG_FS, &vcpu->arch.rmode.fs);
1133
1134 vmcs_write16(GUEST_SS_SELECTOR, 0);
1135 vmcs_write32(GUEST_SS_AR_BYTES, 0x93);
1136
1137 vmcs_write16(GUEST_CS_SELECTOR,
1138 vmcs_read16(GUEST_CS_SELECTOR) & ~SELECTOR_RPL_MASK);
1139 vmcs_write32(GUEST_CS_AR_BYTES, 0x9b);
1140}
1141
1142static gva_t rmode_tss_base(struct kvm *kvm)
1143{
1144 if (!kvm->arch.tss_addr) {
1145 gfn_t base_gfn = kvm->memslots[0].base_gfn +
1146 kvm->memslots[0].npages - 3;
1147 return base_gfn << PAGE_SHIFT;
1148 }
1149 return kvm->arch.tss_addr;
1150}
1151
1152static void fix_rmode_seg(int seg, struct kvm_save_segment *save)
1153{
1154 struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
1155
1156 save->selector = vmcs_read16(sf->selector);
1157 save->base = vmcs_readl(sf->base);
1158 save->limit = vmcs_read32(sf->limit);
1159 save->ar = vmcs_read32(sf->ar_bytes);
1160 vmcs_write16(sf->selector, save->base >> 4);
1161 vmcs_write32(sf->base, save->base & 0xfffff);
1162 vmcs_write32(sf->limit, 0xffff);
1163 vmcs_write32(sf->ar_bytes, 0xf3);
1164}
1165
1166static void enter_rmode(struct kvm_vcpu *vcpu)
1167{
1168 unsigned long flags;
1169
1170 vcpu->arch.rmode.active = 1;
1171
1172 vcpu->arch.rmode.tr.base = vmcs_readl(GUEST_TR_BASE);
1173 vmcs_writel(GUEST_TR_BASE, rmode_tss_base(vcpu->kvm));
1174
1175 vcpu->arch.rmode.tr.limit = vmcs_read32(GUEST_TR_LIMIT);
1176 vmcs_write32(GUEST_TR_LIMIT, RMODE_TSS_SIZE - 1);
1177
1178 vcpu->arch.rmode.tr.ar = vmcs_read32(GUEST_TR_AR_BYTES);
1179 vmcs_write32(GUEST_TR_AR_BYTES, 0x008b);
1180
1181 flags = vmcs_readl(GUEST_RFLAGS);
1182 vcpu->arch.rmode.save_iopl
1183 = (flags & X86_EFLAGS_IOPL) >> IOPL_SHIFT;
1184
1185 flags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM;
1186
1187 vmcs_writel(GUEST_RFLAGS, flags);
1188 vmcs_writel(GUEST_CR4, vmcs_readl(GUEST_CR4) | X86_CR4_VME);
1189 update_exception_bitmap(vcpu);
1190
1191 vmcs_write16(GUEST_SS_SELECTOR, vmcs_readl(GUEST_SS_BASE) >> 4);
1192 vmcs_write32(GUEST_SS_LIMIT, 0xffff);
1193 vmcs_write32(GUEST_SS_AR_BYTES, 0xf3);
1194
1195 vmcs_write32(GUEST_CS_AR_BYTES, 0xf3);
1196 vmcs_write32(GUEST_CS_LIMIT, 0xffff);
1197 if (vmcs_readl(GUEST_CS_BASE) == 0xffff0000)
1198 vmcs_writel(GUEST_CS_BASE, 0xf0000);
1199 vmcs_write16(GUEST_CS_SELECTOR, vmcs_readl(GUEST_CS_BASE) >> 4);
1200
1201 fix_rmode_seg(VCPU_SREG_ES, &vcpu->arch.rmode.es);
1202 fix_rmode_seg(VCPU_SREG_DS, &vcpu->arch.rmode.ds);
1203 fix_rmode_seg(VCPU_SREG_GS, &vcpu->arch.rmode.gs);
1204 fix_rmode_seg(VCPU_SREG_FS, &vcpu->arch.rmode.fs);
1205
1206 kvm_mmu_reset_context(vcpu);
1207 init_rmode_tss(vcpu->kvm);
1208}
1209
1210#ifdef CONFIG_X86_64
1211
1212static void enter_lmode(struct kvm_vcpu *vcpu)
1213{
1214 u32 guest_tr_ar;
1215
1216 guest_tr_ar = vmcs_read32(GUEST_TR_AR_BYTES);
1217 if ((guest_tr_ar & AR_TYPE_MASK) != AR_TYPE_BUSY_64_TSS) {
1218 printk(KERN_DEBUG "%s: tss fixup for long mode. \n",
1219 __FUNCTION__);
1220 vmcs_write32(GUEST_TR_AR_BYTES,
1221 (guest_tr_ar & ~AR_TYPE_MASK)
1222 | AR_TYPE_BUSY_64_TSS);
1223 }
1224
1225 vcpu->arch.shadow_efer |= EFER_LMA;
1226
1227 find_msr_entry(to_vmx(vcpu), MSR_EFER)->data |= EFER_LMA | EFER_LME;
1228 vmcs_write32(VM_ENTRY_CONTROLS,
1229 vmcs_read32(VM_ENTRY_CONTROLS)
1230 | VM_ENTRY_IA32E_MODE);
1231}
1232
1233static void exit_lmode(struct kvm_vcpu *vcpu)
1234{
1235 vcpu->arch.shadow_efer &= ~EFER_LMA;
1236
1237 vmcs_write32(VM_ENTRY_CONTROLS,
1238 vmcs_read32(VM_ENTRY_CONTROLS)
1239 & ~VM_ENTRY_IA32E_MODE);
1240}
1241
1242#endif
1243
1244static void vmx_decache_cr4_guest_bits(struct kvm_vcpu *vcpu)
1245{
1246 vcpu->arch.cr4 &= KVM_GUEST_CR4_MASK;
1247 vcpu->arch.cr4 |= vmcs_readl(GUEST_CR4) & ~KVM_GUEST_CR4_MASK;
1248}
1249
1250static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
1251{
1252 vmx_fpu_deactivate(vcpu);
1253
1254 if (vcpu->arch.rmode.active && (cr0 & X86_CR0_PE))
1255 enter_pmode(vcpu);
1256
1257 if (!vcpu->arch.rmode.active && !(cr0 & X86_CR0_PE))
1258 enter_rmode(vcpu);
1259
1260#ifdef CONFIG_X86_64
1261 if (vcpu->arch.shadow_efer & EFER_LME) {
1262 if (!is_paging(vcpu) && (cr0 & X86_CR0_PG))
1263 enter_lmode(vcpu);
1264 if (is_paging(vcpu) && !(cr0 & X86_CR0_PG))
1265 exit_lmode(vcpu);
1266 }
1267#endif
1268
1269 vmcs_writel(CR0_READ_SHADOW, cr0);
1270 vmcs_writel(GUEST_CR0,
1271 (cr0 & ~KVM_GUEST_CR0_MASK) | KVM_VM_CR0_ALWAYS_ON);
1272 vcpu->arch.cr0 = cr0;
1273
1274 if (!(cr0 & X86_CR0_TS) || !(cr0 & X86_CR0_PE))
1275 vmx_fpu_activate(vcpu);
1276}
1277
1278static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
1279{
1280 vmcs_writel(GUEST_CR3, cr3);
1281 if (vcpu->arch.cr0 & X86_CR0_PE)
1282 vmx_fpu_deactivate(vcpu);
1283}
1284
1285static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
1286{
1287 vmcs_writel(CR4_READ_SHADOW, cr4);
1288 vmcs_writel(GUEST_CR4, cr4 | (vcpu->arch.rmode.active ?
1289 KVM_RMODE_VM_CR4_ALWAYS_ON : KVM_PMODE_VM_CR4_ALWAYS_ON));
1290 vcpu->arch.cr4 = cr4;
1291}
1292
1293#ifdef CONFIG_X86_64
1294
1295static void vmx_set_efer(struct kvm_vcpu *vcpu, u64 efer)
1296{
1297 struct vcpu_vmx *vmx = to_vmx(vcpu);
1298 struct kvm_msr_entry *msr = find_msr_entry(vmx, MSR_EFER);
1299
1300 vcpu->arch.shadow_efer = efer;
1301 if (efer & EFER_LMA) {
1302 vmcs_write32(VM_ENTRY_CONTROLS,
1303 vmcs_read32(VM_ENTRY_CONTROLS) |
1304 VM_ENTRY_IA32E_MODE);
1305 msr->data = efer;
1306
1307 } else {
1308 vmcs_write32(VM_ENTRY_CONTROLS,
1309 vmcs_read32(VM_ENTRY_CONTROLS) &
1310 ~VM_ENTRY_IA32E_MODE);
1311
1312 msr->data = efer & ~EFER_LME;
1313 }
1314 setup_msrs(vmx);
1315}
1316
1317#endif
1318
1319static u64 vmx_get_segment_base(struct kvm_vcpu *vcpu, int seg)
1320{
1321 struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
1322
1323 return vmcs_readl(sf->base);
1324}
1325
1326static void vmx_get_segment(struct kvm_vcpu *vcpu,
1327 struct kvm_segment *var, int seg)
1328{
1329 struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
1330 u32 ar;
1331
1332 var->base = vmcs_readl(sf->base);
1333 var->limit = vmcs_read32(sf->limit);
1334 var->selector = vmcs_read16(sf->selector);
1335 ar = vmcs_read32(sf->ar_bytes);
1336 if (ar & AR_UNUSABLE_MASK)
1337 ar = 0;
1338 var->type = ar & 15;
1339 var->s = (ar >> 4) & 1;
1340 var->dpl = (ar >> 5) & 3;
1341 var->present = (ar >> 7) & 1;
1342 var->avl = (ar >> 12) & 1;
1343 var->l = (ar >> 13) & 1;
1344 var->db = (ar >> 14) & 1;
1345 var->g = (ar >> 15) & 1;
1346 var->unusable = (ar >> 16) & 1;
1347}
1348
1349static u32 vmx_segment_access_rights(struct kvm_segment *var)
1350{
1351 u32 ar;
1352
1353 if (var->unusable)
1354 ar = 1 << 16;
1355 else {
1356 ar = var->type & 15;
1357 ar |= (var->s & 1) << 4;
1358 ar |= (var->dpl & 3) << 5;
1359 ar |= (var->present & 1) << 7;
1360 ar |= (var->avl & 1) << 12;
1361 ar |= (var->l & 1) << 13;
1362 ar |= (var->db & 1) << 14;
1363 ar |= (var->g & 1) << 15;
1364 }
1365 if (ar == 0) /* a 0 value means unusable */
1366 ar = AR_UNUSABLE_MASK;
1367
1368 return ar;
1369}
1370
1371static void vmx_set_segment(struct kvm_vcpu *vcpu,
1372 struct kvm_segment *var, int seg)
1373{
1374 struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
1375 u32 ar;
1376
1377 if (vcpu->arch.rmode.active && seg == VCPU_SREG_TR) {
1378 vcpu->arch.rmode.tr.selector = var->selector;
1379 vcpu->arch.rmode.tr.base = var->base;
1380 vcpu->arch.rmode.tr.limit = var->limit;
1381 vcpu->arch.rmode.tr.ar = vmx_segment_access_rights(var);
1382 return;
1383 }
1384 vmcs_writel(sf->base, var->base);
1385 vmcs_write32(sf->limit, var->limit);
1386 vmcs_write16(sf->selector, var->selector);
1387 if (vcpu->arch.rmode.active && var->s) {
1388 /*
1389 * Hack real-mode segments into vm86 compatibility.
1390 */
1391 if (var->base == 0xffff0000 && var->selector == 0xf000)
1392 vmcs_writel(sf->base, 0xf0000);
1393 ar = 0xf3;
1394 } else
1395 ar = vmx_segment_access_rights(var);
1396 vmcs_write32(sf->ar_bytes, ar);
1397}
1398
1399static void vmx_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l)
1400{
1401 u32 ar = vmcs_read32(GUEST_CS_AR_BYTES);
1402
1403 *db = (ar >> 14) & 1;
1404 *l = (ar >> 13) & 1;
1405}
1406
1407static void vmx_get_idt(struct kvm_vcpu *vcpu, struct descriptor_table *dt)
1408{
1409 dt->limit = vmcs_read32(GUEST_IDTR_LIMIT);
1410 dt->base = vmcs_readl(GUEST_IDTR_BASE);
1411}
1412
1413static void vmx_set_idt(struct kvm_vcpu *vcpu, struct descriptor_table *dt)
1414{
1415 vmcs_write32(GUEST_IDTR_LIMIT, dt->limit);
1416 vmcs_writel(GUEST_IDTR_BASE, dt->base);
1417}
1418
1419static void vmx_get_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt)
1420{
1421 dt->limit = vmcs_read32(GUEST_GDTR_LIMIT);
1422 dt->base = vmcs_readl(GUEST_GDTR_BASE);
1423}
1424
1425static void vmx_set_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt)
1426{
1427 vmcs_write32(GUEST_GDTR_LIMIT, dt->limit);
1428 vmcs_writel(GUEST_GDTR_BASE, dt->base);
1429}
1430
1431static int init_rmode_tss(struct kvm *kvm)
1432{
1433 gfn_t fn = rmode_tss_base(kvm) >> PAGE_SHIFT;
1434 u16 data = 0;
1435 int ret = 0;
1436 int r;
1437
1438 down_read(&current->mm->mmap_sem);
1439 r = kvm_clear_guest_page(kvm, fn, 0, PAGE_SIZE);
1440 if (r < 0)
1441 goto out;
1442 data = TSS_BASE_SIZE + TSS_REDIRECTION_SIZE;
1443 r = kvm_write_guest_page(kvm, fn++, &data, 0x66, sizeof(u16));
1444 if (r < 0)
1445 goto out;
1446 r = kvm_clear_guest_page(kvm, fn++, 0, PAGE_SIZE);
1447 if (r < 0)
1448 goto out;
1449 r = kvm_clear_guest_page(kvm, fn, 0, PAGE_SIZE);
1450 if (r < 0)
1451 goto out;
1452 data = ~0;
1453 r = kvm_write_guest_page(kvm, fn, &data,
1454 RMODE_TSS_SIZE - 2 * PAGE_SIZE - 1,
1455 sizeof(u8));
1456 if (r < 0)
1457 goto out;
1458
1459 ret = 1;
1460out:
1461 up_read(&current->mm->mmap_sem);
1462 return ret;
1463}
1464
1465static void seg_setup(int seg)
1466{
1467 struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
1468
1469 vmcs_write16(sf->selector, 0);
1470 vmcs_writel(sf->base, 0);
1471 vmcs_write32(sf->limit, 0xffff);
1472 vmcs_write32(sf->ar_bytes, 0x93);
1473}
1474
1475static int alloc_apic_access_page(struct kvm *kvm)
1476{
1477 struct kvm_userspace_memory_region kvm_userspace_mem;
1478 int r = 0;
1479
1480 down_write(&current->mm->mmap_sem);
1481 if (kvm->arch.apic_access_page)
1482 goto out;
1483 kvm_userspace_mem.slot = APIC_ACCESS_PAGE_PRIVATE_MEMSLOT;
1484 kvm_userspace_mem.flags = 0;
1485 kvm_userspace_mem.guest_phys_addr = 0xfee00000ULL;
1486 kvm_userspace_mem.memory_size = PAGE_SIZE;
1487 r = __kvm_set_memory_region(kvm, &kvm_userspace_mem, 0);
1488 if (r)
1489 goto out;
1490 kvm->arch.apic_access_page = gfn_to_page(kvm, 0xfee00);
1491out:
1492 up_write(&current->mm->mmap_sem);
1493 return r;
1494}
1495
1496/*
1497 * Sets up the vmcs for emulated real mode.
1498 */
1499static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
1500{
1501 u32 host_sysenter_cs;
1502 u32 junk;
1503 unsigned long a;
1504 struct descriptor_table dt;
1505 int i;
1506 unsigned long kvm_vmx_return;
1507 u32 exec_control;
1508
1509 /* I/O */
1510 vmcs_write64(IO_BITMAP_A, page_to_phys(vmx_io_bitmap_a));
1511 vmcs_write64(IO_BITMAP_B, page_to_phys(vmx_io_bitmap_b));
1512
1513 vmcs_write64(VMCS_LINK_POINTER, -1ull); /* 22.3.1.5 */
1514
1515 /* Control */
1516 vmcs_write32(PIN_BASED_VM_EXEC_CONTROL,
1517 vmcs_config.pin_based_exec_ctrl);
1518
1519 exec_control = vmcs_config.cpu_based_exec_ctrl;
1520 if (!vm_need_tpr_shadow(vmx->vcpu.kvm)) {
1521 exec_control &= ~CPU_BASED_TPR_SHADOW;
1522#ifdef CONFIG_X86_64
1523 exec_control |= CPU_BASED_CR8_STORE_EXITING |
1524 CPU_BASED_CR8_LOAD_EXITING;
1525#endif
1526 }
1527 vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, exec_control);
1528
1529 if (cpu_has_secondary_exec_ctrls()) {
1530 exec_control = vmcs_config.cpu_based_2nd_exec_ctrl;
1531 if (!vm_need_virtualize_apic_accesses(vmx->vcpu.kvm))
1532 exec_control &=
1533 ~SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
1534 vmcs_write32(SECONDARY_VM_EXEC_CONTROL, exec_control);
1535 }
1536
1537 vmcs_write32(PAGE_FAULT_ERROR_CODE_MASK, !!bypass_guest_pf);
1538 vmcs_write32(PAGE_FAULT_ERROR_CODE_MATCH, !!bypass_guest_pf);
1539 vmcs_write32(CR3_TARGET_COUNT, 0); /* 22.2.1 */
1540
1541 vmcs_writel(HOST_CR0, read_cr0()); /* 22.2.3 */
1542 vmcs_writel(HOST_CR4, read_cr4()); /* 22.2.3, 22.2.5 */
1543 vmcs_writel(HOST_CR3, read_cr3()); /* 22.2.3 FIXME: shadow tables */
1544
1545 vmcs_write16(HOST_CS_SELECTOR, __KERNEL_CS); /* 22.2.4 */
1546 vmcs_write16(HOST_DS_SELECTOR, __KERNEL_DS); /* 22.2.4 */
1547 vmcs_write16(HOST_ES_SELECTOR, __KERNEL_DS); /* 22.2.4 */
1548 vmcs_write16(HOST_FS_SELECTOR, read_fs()); /* 22.2.4 */
1549 vmcs_write16(HOST_GS_SELECTOR, read_gs()); /* 22.2.4 */
1550 vmcs_write16(HOST_SS_SELECTOR, __KERNEL_DS); /* 22.2.4 */
1551#ifdef CONFIG_X86_64
1552 rdmsrl(MSR_FS_BASE, a);
1553 vmcs_writel(HOST_FS_BASE, a); /* 22.2.4 */
1554 rdmsrl(MSR_GS_BASE, a);
1555 vmcs_writel(HOST_GS_BASE, a); /* 22.2.4 */
1556#else
1557 vmcs_writel(HOST_FS_BASE, 0); /* 22.2.4 */
1558 vmcs_writel(HOST_GS_BASE, 0); /* 22.2.4 */
1559#endif
1560
1561 vmcs_write16(HOST_TR_SELECTOR, GDT_ENTRY_TSS*8); /* 22.2.4 */
1562
1563 get_idt(&dt);
1564 vmcs_writel(HOST_IDTR_BASE, dt.base); /* 22.2.4 */
1565
1566 asm("mov $.Lkvm_vmx_return, %0" : "=r"(kvm_vmx_return));
1567 vmcs_writel(HOST_RIP, kvm_vmx_return); /* 22.2.5 */
1568 vmcs_write32(VM_EXIT_MSR_STORE_COUNT, 0);
1569 vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, 0);
1570 vmcs_write32(VM_ENTRY_MSR_LOAD_COUNT, 0);
1571
1572 rdmsr(MSR_IA32_SYSENTER_CS, host_sysenter_cs, junk);
1573 vmcs_write32(HOST_IA32_SYSENTER_CS, host_sysenter_cs);
1574 rdmsrl(MSR_IA32_SYSENTER_ESP, a);
1575 vmcs_writel(HOST_IA32_SYSENTER_ESP, a); /* 22.2.3 */
1576 rdmsrl(MSR_IA32_SYSENTER_EIP, a);
1577 vmcs_writel(HOST_IA32_SYSENTER_EIP, a); /* 22.2.3 */
1578
1579 for (i = 0; i < NR_VMX_MSR; ++i) {
1580 u32 index = vmx_msr_index[i];
1581 u32 data_low, data_high;
1582 u64 data;
1583 int j = vmx->nmsrs;
1584
1585 if (rdmsr_safe(index, &data_low, &data_high) < 0)
1586 continue;
1587 if (wrmsr_safe(index, data_low, data_high) < 0)
1588 continue;
1589 data = data_low | ((u64)data_high << 32);
1590 vmx->host_msrs[j].index = index;
1591 vmx->host_msrs[j].reserved = 0;
1592 vmx->host_msrs[j].data = data;
1593 vmx->guest_msrs[j] = vmx->host_msrs[j];
1594 ++vmx->nmsrs;
1595 }
1596
1597 vmcs_write32(VM_EXIT_CONTROLS, vmcs_config.vmexit_ctrl);
1598
1599 /* 22.2.1, 20.8.1 */
1600 vmcs_write32(VM_ENTRY_CONTROLS, vmcs_config.vmentry_ctrl);
1601
1602 vmcs_writel(CR0_GUEST_HOST_MASK, ~0UL);
1603 vmcs_writel(CR4_GUEST_HOST_MASK, KVM_GUEST_CR4_MASK);
1604
1605 if (vm_need_virtualize_apic_accesses(vmx->vcpu.kvm))
1606 if (alloc_apic_access_page(vmx->vcpu.kvm) != 0)
1607 return -ENOMEM;
1608
1609 return 0;
1610}
1611
1612static int vmx_vcpu_reset(struct kvm_vcpu *vcpu)
1613{
1614 struct vcpu_vmx *vmx = to_vmx(vcpu);
1615 u64 msr;
1616 int ret;
1617
1618 if (!init_rmode_tss(vmx->vcpu.kvm)) {
1619 ret = -ENOMEM;
1620 goto out;
1621 }
1622
1623 vmx->vcpu.arch.rmode.active = 0;
1624
1625 vmx->vcpu.arch.regs[VCPU_REGS_RDX] = get_rdx_init_val();
1626 set_cr8(&vmx->vcpu, 0);
1627 msr = 0xfee00000 | MSR_IA32_APICBASE_ENABLE;
1628 if (vmx->vcpu.vcpu_id == 0)
1629 msr |= MSR_IA32_APICBASE_BSP;
1630 kvm_set_apic_base(&vmx->vcpu, msr);
1631
1632 fx_init(&vmx->vcpu);
1633
1634 /*
1635 * GUEST_CS_BASE should really be 0xffff0000, but VT vm86 mode
1636 * insists on having GUEST_CS_BASE == GUEST_CS_SELECTOR << 4. Sigh.
1637 */
1638 if (vmx->vcpu.vcpu_id == 0) {
1639 vmcs_write16(GUEST_CS_SELECTOR, 0xf000);
1640 vmcs_writel(GUEST_CS_BASE, 0x000f0000);
1641 } else {
1642 vmcs_write16(GUEST_CS_SELECTOR, vmx->vcpu.arch.sipi_vector << 8);
1643 vmcs_writel(GUEST_CS_BASE, vmx->vcpu.arch.sipi_vector << 12);
1644 }
1645 vmcs_write32(GUEST_CS_LIMIT, 0xffff);
1646 vmcs_write32(GUEST_CS_AR_BYTES, 0x9b);
1647
1648 seg_setup(VCPU_SREG_DS);
1649 seg_setup(VCPU_SREG_ES);
1650 seg_setup(VCPU_SREG_FS);
1651 seg_setup(VCPU_SREG_GS);
1652 seg_setup(VCPU_SREG_SS);
1653
1654 vmcs_write16(GUEST_TR_SELECTOR, 0);
1655 vmcs_writel(GUEST_TR_BASE, 0);
1656 vmcs_write32(GUEST_TR_LIMIT, 0xffff);
1657 vmcs_write32(GUEST_TR_AR_BYTES, 0x008b);
1658
1659 vmcs_write16(GUEST_LDTR_SELECTOR, 0);
1660 vmcs_writel(GUEST_LDTR_BASE, 0);
1661 vmcs_write32(GUEST_LDTR_LIMIT, 0xffff);
1662 vmcs_write32(GUEST_LDTR_AR_BYTES, 0x00082);
1663
1664 vmcs_write32(GUEST_SYSENTER_CS, 0);
1665 vmcs_writel(GUEST_SYSENTER_ESP, 0);
1666 vmcs_writel(GUEST_SYSENTER_EIP, 0);
1667
1668 vmcs_writel(GUEST_RFLAGS, 0x02);
1669 if (vmx->vcpu.vcpu_id == 0)
1670 vmcs_writel(GUEST_RIP, 0xfff0);
1671 else
1672 vmcs_writel(GUEST_RIP, 0);
1673 vmcs_writel(GUEST_RSP, 0);
1674
1675 /* todo: dr0 = dr1 = dr2 = dr3 = 0; dr6 = 0xffff0ff0 */
1676 vmcs_writel(GUEST_DR7, 0x400);
1677
1678 vmcs_writel(GUEST_GDTR_BASE, 0);
1679 vmcs_write32(GUEST_GDTR_LIMIT, 0xffff);
1680
1681 vmcs_writel(GUEST_IDTR_BASE, 0);
1682 vmcs_write32(GUEST_IDTR_LIMIT, 0xffff);
1683
1684 vmcs_write32(GUEST_ACTIVITY_STATE, 0);
1685 vmcs_write32(GUEST_INTERRUPTIBILITY_INFO, 0);
1686 vmcs_write32(GUEST_PENDING_DBG_EXCEPTIONS, 0);
1687
1688 guest_write_tsc(0);
1689
1690 /* Special registers */
1691 vmcs_write64(GUEST_IA32_DEBUGCTL, 0);
1692
1693 setup_msrs(vmx);
1694
1695 vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, 0); /* 22.2.1 */
1696
1697 if (cpu_has_vmx_tpr_shadow()) {
1698 vmcs_write64(VIRTUAL_APIC_PAGE_ADDR, 0);
1699 if (vm_need_tpr_shadow(vmx->vcpu.kvm))
1700 vmcs_write64(VIRTUAL_APIC_PAGE_ADDR,
1701 page_to_phys(vmx->vcpu.arch.apic->regs_page));
1702 vmcs_write32(TPR_THRESHOLD, 0);
1703 }
1704
1705 if (vm_need_virtualize_apic_accesses(vmx->vcpu.kvm))
1706 vmcs_write64(APIC_ACCESS_ADDR,
1707 page_to_phys(vmx->vcpu.kvm->arch.apic_access_page));
1708
1709 vmx->vcpu.arch.cr0 = 0x60000010;
1710 vmx_set_cr0(&vmx->vcpu, vmx->vcpu.arch.cr0); /* enter rmode */
1711 vmx_set_cr4(&vmx->vcpu, 0);
1712#ifdef CONFIG_X86_64
1713 vmx_set_efer(&vmx->vcpu, 0);
1714#endif
1715 vmx_fpu_activate(&vmx->vcpu);
1716 update_exception_bitmap(&vmx->vcpu);
1717
1718 return 0;
1719
1720out:
1721 return ret;
1722}
1723
1724static void vmx_inject_irq(struct kvm_vcpu *vcpu, int irq)
1725{
1726 struct vcpu_vmx *vmx = to_vmx(vcpu);
1727
1728 if (vcpu->arch.rmode.active) {
1729 vmx->rmode.irq.pending = true;
1730 vmx->rmode.irq.vector = irq;
1731 vmx->rmode.irq.rip = vmcs_readl(GUEST_RIP);
1732 vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
1733 irq | INTR_TYPE_SOFT_INTR | INTR_INFO_VALID_MASK);
1734 vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1);
1735 vmcs_writel(GUEST_RIP, vmx->rmode.irq.rip - 1);
1736 return;
1737 }
1738 vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
1739 irq | INTR_TYPE_EXT_INTR | INTR_INFO_VALID_MASK);
1740}
1741
1742static void kvm_do_inject_irq(struct kvm_vcpu *vcpu)
1743{
1744 int word_index = __ffs(vcpu->arch.irq_summary);
1745 int bit_index = __ffs(vcpu->arch.irq_pending[word_index]);
1746 int irq = word_index * BITS_PER_LONG + bit_index;
1747
1748 clear_bit(bit_index, &vcpu->arch.irq_pending[word_index]);
1749 if (!vcpu->arch.irq_pending[word_index])
1750 clear_bit(word_index, &vcpu->arch.irq_summary);
1751 vmx_inject_irq(vcpu, irq);
1752}
1753
1754
1755static void do_interrupt_requests(struct kvm_vcpu *vcpu,
1756 struct kvm_run *kvm_run)
1757{
1758 u32 cpu_based_vm_exec_control;
1759
1760 vcpu->arch.interrupt_window_open =
1761 ((vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_IF) &&
1762 (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0);
1763
1764 if (vcpu->arch.interrupt_window_open &&
1765 vcpu->arch.irq_summary &&
1766 !(vmcs_read32(VM_ENTRY_INTR_INFO_FIELD) & INTR_INFO_VALID_MASK))
1767 /*
1768 * If interrupts enabled, and not blocked by sti or mov ss. Good.
1769 */
1770 kvm_do_inject_irq(vcpu);
1771
1772 cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL);
1773 if (!vcpu->arch.interrupt_window_open &&
1774 (vcpu->arch.irq_summary || kvm_run->request_interrupt_window))
1775 /*
1776 * Interrupts blocked. Wait for unblock.
1777 */
1778 cpu_based_vm_exec_control |= CPU_BASED_VIRTUAL_INTR_PENDING;
1779 else
1780 cpu_based_vm_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING;
1781 vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control);
1782}
1783
1784static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr)
1785{
1786 int ret;
1787 struct kvm_userspace_memory_region tss_mem = {
1788 .slot = 8,
1789 .guest_phys_addr = addr,
1790 .memory_size = PAGE_SIZE * 3,
1791 .flags = 0,
1792 };
1793
1794 ret = kvm_set_memory_region(kvm, &tss_mem, 0);
1795 if (ret)
1796 return ret;
1797 kvm->arch.tss_addr = addr;
1798 return 0;
1799}
1800
1801static void kvm_guest_debug_pre(struct kvm_vcpu *vcpu)
1802{
1803 struct kvm_guest_debug *dbg = &vcpu->guest_debug;
1804
1805 set_debugreg(dbg->bp[0], 0);
1806 set_debugreg(dbg->bp[1], 1);
1807 set_debugreg(dbg->bp[2], 2);
1808 set_debugreg(dbg->bp[3], 3);
1809
1810 if (dbg->singlestep) {
1811 unsigned long flags;
1812
1813 flags = vmcs_readl(GUEST_RFLAGS);
1814 flags |= X86_EFLAGS_TF | X86_EFLAGS_RF;
1815 vmcs_writel(GUEST_RFLAGS, flags);
1816 }
1817}
1818
1819static int handle_rmode_exception(struct kvm_vcpu *vcpu,
1820 int vec, u32 err_code)
1821{
1822 if (!vcpu->arch.rmode.active)
1823 return 0;
1824
1825 /*
1826 * Instruction with address size override prefix opcode 0x67
1827 * Cause the #SS fault with 0 error code in VM86 mode.
1828 */
1829 if (((vec == GP_VECTOR) || (vec == SS_VECTOR)) && err_code == 0)
1830 if (emulate_instruction(vcpu, NULL, 0, 0, 0) == EMULATE_DONE)
1831 return 1;
1832 return 0;
1833}
1834
1835static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
1836{
1837 struct vcpu_vmx *vmx = to_vmx(vcpu);
1838 u32 intr_info, error_code;
1839 unsigned long cr2, rip;
1840 u32 vect_info;
1841 enum emulation_result er;
1842
1843 vect_info = vmx->idt_vectoring_info;
1844 intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
1845
1846 if ((vect_info & VECTORING_INFO_VALID_MASK) &&
1847 !is_page_fault(intr_info))
1848 printk(KERN_ERR "%s: unexpected, vectoring info 0x%x "
1849 "intr info 0x%x\n", __FUNCTION__, vect_info, intr_info);
1850
1851 if (!irqchip_in_kernel(vcpu->kvm) && is_external_interrupt(vect_info)) {
1852 int irq = vect_info & VECTORING_INFO_VECTOR_MASK;
1853 set_bit(irq, vcpu->arch.irq_pending);
1854 set_bit(irq / BITS_PER_LONG, &vcpu->arch.irq_summary);
1855 }
1856
1857 if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200) /* nmi */
1858 return 1; /* already handled by vmx_vcpu_run() */
1859
1860 if (is_no_device(intr_info)) {
1861 vmx_fpu_activate(vcpu);
1862 return 1;
1863 }
1864
1865 if (is_invalid_opcode(intr_info)) {
1866 er = emulate_instruction(vcpu, kvm_run, 0, 0, EMULTYPE_TRAP_UD);
1867 if (er != EMULATE_DONE)
1868 kvm_queue_exception(vcpu, UD_VECTOR);
1869 return 1;
1870 }
1871
1872 error_code = 0;
1873 rip = vmcs_readl(GUEST_RIP);
1874 if (intr_info & INTR_INFO_DELIEVER_CODE_MASK)
1875 error_code = vmcs_read32(VM_EXIT_INTR_ERROR_CODE);
1876 if (is_page_fault(intr_info)) {
1877 cr2 = vmcs_readl(EXIT_QUALIFICATION);
1878 return kvm_mmu_page_fault(vcpu, cr2, error_code);
1879 }
1880
1881 if (vcpu->arch.rmode.active &&
1882 handle_rmode_exception(vcpu, intr_info & INTR_INFO_VECTOR_MASK,
1883 error_code)) {
1884 if (vcpu->arch.halt_request) {
1885 vcpu->arch.halt_request = 0;
1886 return kvm_emulate_halt(vcpu);
1887 }
1888 return 1;
1889 }
1890
1891 if ((intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK)) ==
1892 (INTR_TYPE_EXCEPTION | 1)) {
1893 kvm_run->exit_reason = KVM_EXIT_DEBUG;
1894 return 0;
1895 }
1896 kvm_run->exit_reason = KVM_EXIT_EXCEPTION;
1897 kvm_run->ex.exception = intr_info & INTR_INFO_VECTOR_MASK;
1898 kvm_run->ex.error_code = error_code;
1899 return 0;
1900}
1901
1902static int handle_external_interrupt(struct kvm_vcpu *vcpu,
1903 struct kvm_run *kvm_run)
1904{
1905 ++vcpu->stat.irq_exits;
1906 return 1;
1907}
1908
1909static int handle_triple_fault(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
1910{
1911 kvm_run->exit_reason = KVM_EXIT_SHUTDOWN;
1912 return 0;
1913}
1914
1915static int handle_io(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
1916{
1917 unsigned long exit_qualification;
1918 int size, down, in, string, rep;
1919 unsigned port;
1920
1921 ++vcpu->stat.io_exits;
1922 exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
1923 string = (exit_qualification & 16) != 0;
1924
1925 if (string) {
1926 if (emulate_instruction(vcpu,
1927 kvm_run, 0, 0, 0) == EMULATE_DO_MMIO)
1928 return 0;
1929 return 1;
1930 }
1931
1932 size = (exit_qualification & 7) + 1;
1933 in = (exit_qualification & 8) != 0;
1934 down = (vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_DF) != 0;
1935 rep = (exit_qualification & 32) != 0;
1936 port = exit_qualification >> 16;
1937
1938 return kvm_emulate_pio(vcpu, kvm_run, in, size, port);
1939}
1940
1941static void
1942vmx_patch_hypercall(struct kvm_vcpu *vcpu, unsigned char *hypercall)
1943{
1944 /*
1945 * Patch in the VMCALL instruction:
1946 */
1947 hypercall[0] = 0x0f;
1948 hypercall[1] = 0x01;
1949 hypercall[2] = 0xc1;
1950}
1951
1952static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
1953{
1954 unsigned long exit_qualification;
1955 int cr;
1956 int reg;
1957
1958 exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
1959 cr = exit_qualification & 15;
1960 reg = (exit_qualification >> 8) & 15;
1961 switch ((exit_qualification >> 4) & 3) {
1962 case 0: /* mov to cr */
1963 switch (cr) {
1964 case 0:
1965 vcpu_load_rsp_rip(vcpu);
1966 set_cr0(vcpu, vcpu->arch.regs[reg]);
1967 skip_emulated_instruction(vcpu);
1968 return 1;
1969 case 3:
1970 vcpu_load_rsp_rip(vcpu);
1971 set_cr3(vcpu, vcpu->arch.regs[reg]);
1972 skip_emulated_instruction(vcpu);
1973 return 1;
1974 case 4:
1975 vcpu_load_rsp_rip(vcpu);
1976 set_cr4(vcpu, vcpu->arch.regs[reg]);
1977 skip_emulated_instruction(vcpu);
1978 return 1;
1979 case 8:
1980 vcpu_load_rsp_rip(vcpu);
1981 set_cr8(vcpu, vcpu->arch.regs[reg]);
1982 skip_emulated_instruction(vcpu);
1983 if (irqchip_in_kernel(vcpu->kvm))
1984 return 1;
1985 kvm_run->exit_reason = KVM_EXIT_SET_TPR;
1986 return 0;
1987 };
1988 break;
1989 case 2: /* clts */
1990 vcpu_load_rsp_rip(vcpu);
1991 vmx_fpu_deactivate(vcpu);
1992 vcpu->arch.cr0 &= ~X86_CR0_TS;
1993 vmcs_writel(CR0_READ_SHADOW, vcpu->arch.cr0);
1994 vmx_fpu_activate(vcpu);
1995 skip_emulated_instruction(vcpu);
1996 return 1;
1997 case 1: /*mov from cr*/
1998 switch (cr) {
1999 case 3:
2000 vcpu_load_rsp_rip(vcpu);
2001 vcpu->arch.regs[reg] = vcpu->arch.cr3;
2002 vcpu_put_rsp_rip(vcpu);
2003 skip_emulated_instruction(vcpu);
2004 return 1;
2005 case 8:
2006 vcpu_load_rsp_rip(vcpu);
2007 vcpu->arch.regs[reg] = get_cr8(vcpu);
2008 vcpu_put_rsp_rip(vcpu);
2009 skip_emulated_instruction(vcpu);
2010 return 1;
2011 }
2012 break;
2013 case 3: /* lmsw */
2014 lmsw(vcpu, (exit_qualification >> LMSW_SOURCE_DATA_SHIFT) & 0x0f);
2015
2016 skip_emulated_instruction(vcpu);
2017 return 1;
2018 default:
2019 break;
2020 }
2021 kvm_run->exit_reason = 0;
2022 pr_unimpl(vcpu, "unhandled control register: op %d cr %d\n",
2023 (int)(exit_qualification >> 4) & 3, cr);
2024 return 0;
2025}
2026
2027static int handle_dr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2028{
2029 unsigned long exit_qualification;
2030 unsigned long val;
2031 int dr, reg;
2032
2033 /*
2034 * FIXME: this code assumes the host is debugging the guest.
2035 * need to deal with guest debugging itself too.
2036 */
2037 exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
2038 dr = exit_qualification & 7;
2039 reg = (exit_qualification >> 8) & 15;
2040 vcpu_load_rsp_rip(vcpu);
2041 if (exit_qualification & 16) {
2042 /* mov from dr */
2043 switch (dr) {
2044 case 6:
2045 val = 0xffff0ff0;
2046 break;
2047 case 7:
2048 val = 0x400;
2049 break;
2050 default:
2051 val = 0;
2052 }
2053 vcpu->arch.regs[reg] = val;
2054 } else {
2055 /* mov to dr */
2056 }
2057 vcpu_put_rsp_rip(vcpu);
2058 skip_emulated_instruction(vcpu);
2059 return 1;
2060}
2061
2062static int handle_cpuid(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2063{
2064 kvm_emulate_cpuid(vcpu);
2065 return 1;
2066}
2067
2068static int handle_rdmsr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2069{
2070 u32 ecx = vcpu->arch.regs[VCPU_REGS_RCX];
2071 u64 data;
2072
2073 if (vmx_get_msr(vcpu, ecx, &data)) {
2074 kvm_inject_gp(vcpu, 0);
2075 return 1;
2076 }
2077
2078 /* FIXME: handling of bits 32:63 of rax, rdx */
2079 vcpu->arch.regs[VCPU_REGS_RAX] = data & -1u;
2080 vcpu->arch.regs[VCPU_REGS_RDX] = (data >> 32) & -1u;
2081 skip_emulated_instruction(vcpu);
2082 return 1;
2083}
2084
2085static int handle_wrmsr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2086{
2087 u32 ecx = vcpu->arch.regs[VCPU_REGS_RCX];
2088 u64 data = (vcpu->arch.regs[VCPU_REGS_RAX] & -1u)
2089 | ((u64)(vcpu->arch.regs[VCPU_REGS_RDX] & -1u) << 32);
2090
2091 if (vmx_set_msr(vcpu, ecx, data) != 0) {
2092 kvm_inject_gp(vcpu, 0);
2093 return 1;
2094 }
2095
2096 skip_emulated_instruction(vcpu);
2097 return 1;
2098}
2099
2100static int handle_tpr_below_threshold(struct kvm_vcpu *vcpu,
2101 struct kvm_run *kvm_run)
2102{
2103 return 1;
2104}
2105
2106static int handle_interrupt_window(struct kvm_vcpu *vcpu,
2107 struct kvm_run *kvm_run)
2108{
2109 u32 cpu_based_vm_exec_control;
2110
2111 /* clear pending irq */
2112 cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL);
2113 cpu_based_vm_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING;
2114 vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control);
2115 /*
2116 * If the user space waits to inject interrupts, exit as soon as
2117 * possible
2118 */
2119 if (kvm_run->request_interrupt_window &&
2120 !vcpu->arch.irq_summary) {
2121 kvm_run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN;
2122 ++vcpu->stat.irq_window_exits;
2123 return 0;
2124 }
2125 return 1;
2126}
2127
2128static int handle_halt(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2129{
2130 skip_emulated_instruction(vcpu);
2131 return kvm_emulate_halt(vcpu);
2132}
2133
2134static int handle_vmcall(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2135{
2136 skip_emulated_instruction(vcpu);
2137 kvm_emulate_hypercall(vcpu);
2138 return 1;
2139}
2140
2141static int handle_wbinvd(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2142{
2143 skip_emulated_instruction(vcpu);
2144 /* TODO: Add support for VT-d/pass-through device */
2145 return 1;
2146}
2147
2148static int handle_apic_access(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2149{
2150 u64 exit_qualification;
2151 enum emulation_result er;
2152 unsigned long offset;
2153
2154 exit_qualification = vmcs_read64(EXIT_QUALIFICATION);
2155 offset = exit_qualification & 0xffful;
2156
2157 er = emulate_instruction(vcpu, kvm_run, 0, 0, 0);
2158
2159 if (er != EMULATE_DONE) {
2160 printk(KERN_ERR
2161 "Fail to handle apic access vmexit! Offset is 0x%lx\n",
2162 offset);
2163 return -ENOTSUPP;
2164 }
2165 return 1;
2166}
2167
2168/*
2169 * The exit handlers return 1 if the exit was handled fully and guest execution
2170 * may resume. Otherwise they set the kvm_run parameter to indicate what needs
2171 * to be done to userspace and return 0.
2172 */
2173static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu,
2174 struct kvm_run *kvm_run) = {
2175 [EXIT_REASON_EXCEPTION_NMI] = handle_exception,
2176 [EXIT_REASON_EXTERNAL_INTERRUPT] = handle_external_interrupt,
2177 [EXIT_REASON_TRIPLE_FAULT] = handle_triple_fault,
2178 [EXIT_REASON_IO_INSTRUCTION] = handle_io,
2179 [EXIT_REASON_CR_ACCESS] = handle_cr,
2180 [EXIT_REASON_DR_ACCESS] = handle_dr,
2181 [EXIT_REASON_CPUID] = handle_cpuid,
2182 [EXIT_REASON_MSR_READ] = handle_rdmsr,
2183 [EXIT_REASON_MSR_WRITE] = handle_wrmsr,
2184 [EXIT_REASON_PENDING_INTERRUPT] = handle_interrupt_window,
2185 [EXIT_REASON_HLT] = handle_halt,
2186 [EXIT_REASON_VMCALL] = handle_vmcall,
2187 [EXIT_REASON_TPR_BELOW_THRESHOLD] = handle_tpr_below_threshold,
2188 [EXIT_REASON_APIC_ACCESS] = handle_apic_access,
2189 [EXIT_REASON_WBINVD] = handle_wbinvd,
2190};
2191
2192static const int kvm_vmx_max_exit_handlers =
2193 ARRAY_SIZE(kvm_vmx_exit_handlers);
2194
2195/*
2196 * The guest has exited. See if we can fix it or if we need userspace
2197 * assistance.
2198 */
2199static int kvm_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
2200{
2201 u32 exit_reason = vmcs_read32(VM_EXIT_REASON);
2202 struct vcpu_vmx *vmx = to_vmx(vcpu);
2203 u32 vectoring_info = vmx->idt_vectoring_info;
2204
2205 if (unlikely(vmx->fail)) {
2206 kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY;
2207 kvm_run->fail_entry.hardware_entry_failure_reason
2208 = vmcs_read32(VM_INSTRUCTION_ERROR);
2209 return 0;
2210 }
2211
2212 if ((vectoring_info & VECTORING_INFO_VALID_MASK) &&
2213 exit_reason != EXIT_REASON_EXCEPTION_NMI)
2214 printk(KERN_WARNING "%s: unexpected, valid vectoring info and "
2215 "exit reason is 0x%x\n", __FUNCTION__, exit_reason);
2216 if (exit_reason < kvm_vmx_max_exit_handlers
2217 && kvm_vmx_exit_handlers[exit_reason])
2218 return kvm_vmx_exit_handlers[exit_reason](vcpu, kvm_run);
2219 else {
2220 kvm_run->exit_reason = KVM_EXIT_UNKNOWN;
2221 kvm_run->hw.hardware_exit_reason = exit_reason;
2222 }
2223 return 0;
2224}
2225
2226static void vmx_flush_tlb(struct kvm_vcpu *vcpu)
2227{
2228}
2229
2230static void update_tpr_threshold(struct kvm_vcpu *vcpu)
2231{
2232 int max_irr, tpr;
2233
2234 if (!vm_need_tpr_shadow(vcpu->kvm))
2235 return;
2236
2237 if (!kvm_lapic_enabled(vcpu) ||
2238 ((max_irr = kvm_lapic_find_highest_irr(vcpu)) == -1)) {
2239 vmcs_write32(TPR_THRESHOLD, 0);
2240 return;
2241 }
2242
2243 tpr = (kvm_lapic_get_cr8(vcpu) & 0x0f) << 4;
2244 vmcs_write32(TPR_THRESHOLD, (max_irr > tpr) ? tpr >> 4 : max_irr >> 4);
2245}
2246
2247static void enable_irq_window(struct kvm_vcpu *vcpu)
2248{
2249 u32 cpu_based_vm_exec_control;
2250
2251 cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL);
2252 cpu_based_vm_exec_control |= CPU_BASED_VIRTUAL_INTR_PENDING;
2253 vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control);
2254}
2255
2256static void vmx_intr_assist(struct kvm_vcpu *vcpu)
2257{
2258 struct vcpu_vmx *vmx = to_vmx(vcpu);
2259 u32 idtv_info_field, intr_info_field;
2260 int has_ext_irq, interrupt_window_open;
2261 int vector;
2262
2263 update_tpr_threshold(vcpu);
2264
2265 has_ext_irq = kvm_cpu_has_interrupt(vcpu);
2266 intr_info_field = vmcs_read32(VM_ENTRY_INTR_INFO_FIELD);
2267 idtv_info_field = vmx->idt_vectoring_info;
2268 if (intr_info_field & INTR_INFO_VALID_MASK) {
2269 if (idtv_info_field & INTR_INFO_VALID_MASK) {
2270 /* TODO: fault when IDT_Vectoring */
2271 if (printk_ratelimit())
2272 printk(KERN_ERR "Fault when IDT_Vectoring\n");
2273 }
2274 if (has_ext_irq)
2275 enable_irq_window(vcpu);
2276 return;
2277 }
2278 if (unlikely(idtv_info_field & INTR_INFO_VALID_MASK)) {
2279 if ((idtv_info_field & VECTORING_INFO_TYPE_MASK)
2280 == INTR_TYPE_EXT_INTR
2281 && vcpu->arch.rmode.active) {
2282 u8 vect = idtv_info_field & VECTORING_INFO_VECTOR_MASK;
2283
2284 vmx_inject_irq(vcpu, vect);
2285 if (unlikely(has_ext_irq))
2286 enable_irq_window(vcpu);
2287 return;
2288 }
2289
2290 vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, idtv_info_field);
2291 vmcs_write32(VM_ENTRY_INSTRUCTION_LEN,
2292 vmcs_read32(VM_EXIT_INSTRUCTION_LEN));
2293
2294 if (unlikely(idtv_info_field & INTR_INFO_DELIEVER_CODE_MASK))
2295 vmcs_write32(VM_ENTRY_EXCEPTION_ERROR_CODE,
2296 vmcs_read32(IDT_VECTORING_ERROR_CODE));
2297 if (unlikely(has_ext_irq))
2298 enable_irq_window(vcpu);
2299 return;
2300 }
2301 if (!has_ext_irq)
2302 return;
2303 interrupt_window_open =
2304 ((vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_IF) &&
2305 (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0);
2306 if (interrupt_window_open) {
2307 vector = kvm_cpu_get_interrupt(vcpu);
2308 vmx_inject_irq(vcpu, vector);
2309 kvm_timer_intr_post(vcpu, vector);
2310 } else
2311 enable_irq_window(vcpu);
2312}
2313
2314/*
2315 * Failure to inject an interrupt should give us the information
2316 * in IDT_VECTORING_INFO_FIELD. However, if the failure occurs
2317 * when fetching the interrupt redirection bitmap in the real-mode
2318 * tss, this doesn't happen. So we do it ourselves.
2319 */
2320static void fixup_rmode_irq(struct vcpu_vmx *vmx)
2321{
2322 vmx->rmode.irq.pending = 0;
2323 if (vmcs_readl(GUEST_RIP) + 1 != vmx->rmode.irq.rip)
2324 return;
2325 vmcs_writel(GUEST_RIP, vmx->rmode.irq.rip);
2326 if (vmx->idt_vectoring_info & VECTORING_INFO_VALID_MASK) {
2327 vmx->idt_vectoring_info &= ~VECTORING_INFO_TYPE_MASK;
2328 vmx->idt_vectoring_info |= INTR_TYPE_EXT_INTR;
2329 return;
2330 }
2331 vmx->idt_vectoring_info =
2332 VECTORING_INFO_VALID_MASK
2333 | INTR_TYPE_EXT_INTR
2334 | vmx->rmode.irq.vector;
2335}
2336
2337static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2338{
2339 struct vcpu_vmx *vmx = to_vmx(vcpu);
2340 u32 intr_info;
2341
2342 /*
2343 * Loading guest fpu may have cleared host cr0.ts
2344 */
2345 vmcs_writel(HOST_CR0, read_cr0());
2346
2347 asm(
2348 /* Store host registers */
2349#ifdef CONFIG_X86_64
2350 "push %%rdx; push %%rbp;"
2351 "push %%rcx \n\t"
2352#else
2353 "push %%edx; push %%ebp;"
2354 "push %%ecx \n\t"
2355#endif
2356 ASM_VMX_VMWRITE_RSP_RDX "\n\t"
2357 /* Check if vmlaunch of vmresume is needed */
2358 "cmpl $0, %c[launched](%0) \n\t"
2359 /* Load guest registers. Don't clobber flags. */
2360#ifdef CONFIG_X86_64
2361 "mov %c[cr2](%0), %%rax \n\t"
2362 "mov %%rax, %%cr2 \n\t"
2363 "mov %c[rax](%0), %%rax \n\t"
2364 "mov %c[rbx](%0), %%rbx \n\t"
2365 "mov %c[rdx](%0), %%rdx \n\t"
2366 "mov %c[rsi](%0), %%rsi \n\t"
2367 "mov %c[rdi](%0), %%rdi \n\t"
2368 "mov %c[rbp](%0), %%rbp \n\t"
2369 "mov %c[r8](%0), %%r8 \n\t"
2370 "mov %c[r9](%0), %%r9 \n\t"
2371 "mov %c[r10](%0), %%r10 \n\t"
2372 "mov %c[r11](%0), %%r11 \n\t"
2373 "mov %c[r12](%0), %%r12 \n\t"
2374 "mov %c[r13](%0), %%r13 \n\t"
2375 "mov %c[r14](%0), %%r14 \n\t"
2376 "mov %c[r15](%0), %%r15 \n\t"
2377 "mov %c[rcx](%0), %%rcx \n\t" /* kills %0 (rcx) */
2378#else
2379 "mov %c[cr2](%0), %%eax \n\t"
2380 "mov %%eax, %%cr2 \n\t"
2381 "mov %c[rax](%0), %%eax \n\t"
2382 "mov %c[rbx](%0), %%ebx \n\t"
2383 "mov %c[rdx](%0), %%edx \n\t"
2384 "mov %c[rsi](%0), %%esi \n\t"
2385 "mov %c[rdi](%0), %%edi \n\t"
2386 "mov %c[rbp](%0), %%ebp \n\t"
2387 "mov %c[rcx](%0), %%ecx \n\t" /* kills %0 (ecx) */
2388#endif
2389 /* Enter guest mode */
2390 "jne .Llaunched \n\t"
2391 ASM_VMX_VMLAUNCH "\n\t"
2392 "jmp .Lkvm_vmx_return \n\t"
2393 ".Llaunched: " ASM_VMX_VMRESUME "\n\t"
2394 ".Lkvm_vmx_return: "
2395 /* Save guest registers, load host registers, keep flags */
2396#ifdef CONFIG_X86_64
2397 "xchg %0, (%%rsp) \n\t"
2398 "mov %%rax, %c[rax](%0) \n\t"
2399 "mov %%rbx, %c[rbx](%0) \n\t"
2400 "pushq (%%rsp); popq %c[rcx](%0) \n\t"
2401 "mov %%rdx, %c[rdx](%0) \n\t"
2402 "mov %%rsi, %c[rsi](%0) \n\t"
2403 "mov %%rdi, %c[rdi](%0) \n\t"
2404 "mov %%rbp, %c[rbp](%0) \n\t"
2405 "mov %%r8, %c[r8](%0) \n\t"
2406 "mov %%r9, %c[r9](%0) \n\t"
2407 "mov %%r10, %c[r10](%0) \n\t"
2408 "mov %%r11, %c[r11](%0) \n\t"
2409 "mov %%r12, %c[r12](%0) \n\t"
2410 "mov %%r13, %c[r13](%0) \n\t"
2411 "mov %%r14, %c[r14](%0) \n\t"
2412 "mov %%r15, %c[r15](%0) \n\t"
2413 "mov %%cr2, %%rax \n\t"
2414 "mov %%rax, %c[cr2](%0) \n\t"
2415
2416 "pop %%rbp; pop %%rbp; pop %%rdx \n\t"
2417#else
2418 "xchg %0, (%%esp) \n\t"
2419 "mov %%eax, %c[rax](%0) \n\t"
2420 "mov %%ebx, %c[rbx](%0) \n\t"
2421 "pushl (%%esp); popl %c[rcx](%0) \n\t"
2422 "mov %%edx, %c[rdx](%0) \n\t"
2423 "mov %%esi, %c[rsi](%0) \n\t"
2424 "mov %%edi, %c[rdi](%0) \n\t"
2425 "mov %%ebp, %c[rbp](%0) \n\t"
2426 "mov %%cr2, %%eax \n\t"
2427 "mov %%eax, %c[cr2](%0) \n\t"
2428
2429 "pop %%ebp; pop %%ebp; pop %%edx \n\t"
2430#endif
2431 "setbe %c[fail](%0) \n\t"
2432 : : "c"(vmx), "d"((unsigned long)HOST_RSP),
2433 [launched]"i"(offsetof(struct vcpu_vmx, launched)),
2434 [fail]"i"(offsetof(struct vcpu_vmx, fail)),
2435 [rax]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RAX])),
2436 [rbx]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RBX])),
2437 [rcx]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RCX])),
2438 [rdx]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RDX])),
2439 [rsi]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RSI])),
2440 [rdi]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RDI])),
2441 [rbp]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RBP])),
2442#ifdef CONFIG_X86_64
2443 [r8]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R8])),
2444 [r9]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R9])),
2445 [r10]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R10])),
2446 [r11]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R11])),
2447 [r12]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R12])),
2448 [r13]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R13])),
2449 [r14]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R14])),
2450 [r15]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R15])),
2451#endif
2452 [cr2]"i"(offsetof(struct vcpu_vmx, vcpu.arch.cr2))
2453 : "cc", "memory"
2454#ifdef CONFIG_X86_64
2455 , "rbx", "rdi", "rsi"
2456 , "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
2457#else
2458 , "ebx", "edi", "rsi"
2459#endif
2460 );
2461
2462 vmx->idt_vectoring_info = vmcs_read32(IDT_VECTORING_INFO_FIELD);
2463 if (vmx->rmode.irq.pending)
2464 fixup_rmode_irq(vmx);
2465
2466 vcpu->arch.interrupt_window_open =
2467 (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0;
2468
2469 asm("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
2470 vmx->launched = 1;
2471
2472 intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
2473
2474 /* We need to handle NMIs before interrupts are enabled */
2475 if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200) /* nmi */
2476 asm("int $2");
2477}
2478
2479static void vmx_free_vmcs(struct kvm_vcpu *vcpu)
2480{
2481 struct vcpu_vmx *vmx = to_vmx(vcpu);
2482
2483 if (vmx->vmcs) {
2484 on_each_cpu(__vcpu_clear, vmx, 0, 1);
2485 free_vmcs(vmx->vmcs);
2486 vmx->vmcs = NULL;
2487 }
2488}
2489
2490static void vmx_free_vcpu(struct kvm_vcpu *vcpu)
2491{
2492 struct vcpu_vmx *vmx = to_vmx(vcpu);
2493
2494 vmx_free_vmcs(vcpu);
2495 kfree(vmx->host_msrs);
2496 kfree(vmx->guest_msrs);
2497 kvm_vcpu_uninit(vcpu);
2498 kmem_cache_free(kvm_vcpu_cache, vmx);
2499}
2500
2501static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
2502{
2503 int err;
2504 struct vcpu_vmx *vmx = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL);
2505 int cpu;
2506
2507 if (!vmx)
2508 return ERR_PTR(-ENOMEM);
2509
2510 err = kvm_vcpu_init(&vmx->vcpu, kvm, id);
2511 if (err)
2512 goto free_vcpu;
2513
2514 vmx->guest_msrs = kmalloc(PAGE_SIZE, GFP_KERNEL);
2515 if (!vmx->guest_msrs) {
2516 err = -ENOMEM;
2517 goto uninit_vcpu;
2518 }
2519
2520 vmx->host_msrs = kmalloc(PAGE_SIZE, GFP_KERNEL);
2521 if (!vmx->host_msrs)
2522 goto free_guest_msrs;
2523
2524 vmx->vmcs = alloc_vmcs();
2525 if (!vmx->vmcs)
2526 goto free_msrs;
2527
2528 vmcs_clear(vmx->vmcs);
2529
2530 cpu = get_cpu();
2531 vmx_vcpu_load(&vmx->vcpu, cpu);
2532 err = vmx_vcpu_setup(vmx);
2533 vmx_vcpu_put(&vmx->vcpu);
2534 put_cpu();
2535 if (err)
2536 goto free_vmcs;
2537
2538 return &vmx->vcpu;
2539
2540free_vmcs:
2541 free_vmcs(vmx->vmcs);
2542free_msrs:
2543 kfree(vmx->host_msrs);
2544free_guest_msrs:
2545 kfree(vmx->guest_msrs);
2546uninit_vcpu:
2547 kvm_vcpu_uninit(&vmx->vcpu);
2548free_vcpu:
2549 kmem_cache_free(kvm_vcpu_cache, vmx);
2550 return ERR_PTR(err);
2551}
2552
2553static void __init vmx_check_processor_compat(void *rtn)
2554{
2555 struct vmcs_config vmcs_conf;
2556
2557 *(int *)rtn = 0;
2558 if (setup_vmcs_config(&vmcs_conf) < 0)
2559 *(int *)rtn = -EIO;
2560 if (memcmp(&vmcs_config, &vmcs_conf, sizeof(struct vmcs_config)) != 0) {
2561 printk(KERN_ERR "kvm: CPU %d feature inconsistency!\n",
2562 smp_processor_id());
2563 *(int *)rtn = -EIO;
2564 }
2565}
2566
2567static struct kvm_x86_ops vmx_x86_ops = {
2568 .cpu_has_kvm_support = cpu_has_kvm_support,
2569 .disabled_by_bios = vmx_disabled_by_bios,
2570 .hardware_setup = hardware_setup,
2571 .hardware_unsetup = hardware_unsetup,
2572 .check_processor_compatibility = vmx_check_processor_compat,
2573 .hardware_enable = hardware_enable,
2574 .hardware_disable = hardware_disable,
2575 .cpu_has_accelerated_tpr = cpu_has_vmx_virtualize_apic_accesses,
2576
2577 .vcpu_create = vmx_create_vcpu,
2578 .vcpu_free = vmx_free_vcpu,
2579 .vcpu_reset = vmx_vcpu_reset,
2580
2581 .prepare_guest_switch = vmx_save_host_state,
2582 .vcpu_load = vmx_vcpu_load,
2583 .vcpu_put = vmx_vcpu_put,
2584 .vcpu_decache = vmx_vcpu_decache,
2585
2586 .set_guest_debug = set_guest_debug,
2587 .guest_debug_pre = kvm_guest_debug_pre,
2588 .get_msr = vmx_get_msr,
2589 .set_msr = vmx_set_msr,
2590 .get_segment_base = vmx_get_segment_base,
2591 .get_segment = vmx_get_segment,
2592 .set_segment = vmx_set_segment,
2593 .get_cs_db_l_bits = vmx_get_cs_db_l_bits,
2594 .decache_cr4_guest_bits = vmx_decache_cr4_guest_bits,
2595 .set_cr0 = vmx_set_cr0,
2596 .set_cr3 = vmx_set_cr3,
2597 .set_cr4 = vmx_set_cr4,
2598#ifdef CONFIG_X86_64
2599 .set_efer = vmx_set_efer,
2600#endif
2601 .get_idt = vmx_get_idt,
2602 .set_idt = vmx_set_idt,
2603 .get_gdt = vmx_get_gdt,
2604 .set_gdt = vmx_set_gdt,
2605 .cache_regs = vcpu_load_rsp_rip,
2606 .decache_regs = vcpu_put_rsp_rip,
2607 .get_rflags = vmx_get_rflags,
2608 .set_rflags = vmx_set_rflags,
2609
2610 .tlb_flush = vmx_flush_tlb,
2611
2612 .run = vmx_vcpu_run,
2613 .handle_exit = kvm_handle_exit,
2614 .skip_emulated_instruction = skip_emulated_instruction,
2615 .patch_hypercall = vmx_patch_hypercall,
2616 .get_irq = vmx_get_irq,
2617 .set_irq = vmx_inject_irq,
2618 .queue_exception = vmx_queue_exception,
2619 .exception_injected = vmx_exception_injected,
2620 .inject_pending_irq = vmx_intr_assist,
2621 .inject_pending_vectors = do_interrupt_requests,
2622
2623 .set_tss_addr = vmx_set_tss_addr,
2624};
2625
2626static int __init vmx_init(void)
2627{
2628 void *iova;
2629 int r;
2630
2631 vmx_io_bitmap_a = alloc_page(GFP_KERNEL | __GFP_HIGHMEM);
2632 if (!vmx_io_bitmap_a)
2633 return -ENOMEM;
2634
2635 vmx_io_bitmap_b = alloc_page(GFP_KERNEL | __GFP_HIGHMEM);
2636 if (!vmx_io_bitmap_b) {
2637 r = -ENOMEM;
2638 goto out;
2639 }
2640
2641 /*
2642 * Allow direct access to the PC debug port (it is often used for I/O
2643 * delays, but the vmexits simply slow things down).
2644 */
2645 iova = kmap(vmx_io_bitmap_a);
2646 memset(iova, 0xff, PAGE_SIZE);
2647 clear_bit(0x80, iova);
2648 kunmap(vmx_io_bitmap_a);
2649
2650 iova = kmap(vmx_io_bitmap_b);
2651 memset(iova, 0xff, PAGE_SIZE);
2652 kunmap(vmx_io_bitmap_b);
2653
2654 r = kvm_init(&vmx_x86_ops, sizeof(struct vcpu_vmx), THIS_MODULE);
2655 if (r)
2656 goto out1;
2657
2658 if (bypass_guest_pf)
2659 kvm_mmu_set_nonpresent_ptes(~0xffeull, 0ull);
2660
2661 return 0;
2662
2663out1:
2664 __free_page(vmx_io_bitmap_b);
2665out:
2666 __free_page(vmx_io_bitmap_a);
2667 return r;
2668}
2669
2670static void __exit vmx_exit(void)
2671{
2672 __free_page(vmx_io_bitmap_b);
2673 __free_page(vmx_io_bitmap_a);
2674
2675 kvm_exit();
2676}
2677
2678module_init(vmx_init)
2679module_exit(vmx_exit)
diff --git a/arch/x86/kvm/vmx.h b/arch/x86/kvm/vmx.h
new file mode 100644
index 000000000000..d52ae8d7303d
--- /dev/null
+++ b/arch/x86/kvm/vmx.h
@@ -0,0 +1,324 @@
1#ifndef VMX_H
2#define VMX_H
3
4/*
5 * vmx.h: VMX Architecture related definitions
6 * Copyright (c) 2004, Intel Corporation.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19 * Place - Suite 330, Boston, MA 02111-1307 USA.
20 *
21 * A few random additions are:
22 * Copyright (C) 2006 Qumranet
23 * Avi Kivity <avi@qumranet.com>
24 * Yaniv Kamay <yaniv@qumranet.com>
25 *
26 */
27
28/*
29 * Definitions of Primary Processor-Based VM-Execution Controls.
30 */
31#define CPU_BASED_VIRTUAL_INTR_PENDING 0x00000004
32#define CPU_BASED_USE_TSC_OFFSETING 0x00000008
33#define CPU_BASED_HLT_EXITING 0x00000080
34#define CPU_BASED_INVLPG_EXITING 0x00000200
35#define CPU_BASED_MWAIT_EXITING 0x00000400
36#define CPU_BASED_RDPMC_EXITING 0x00000800
37#define CPU_BASED_RDTSC_EXITING 0x00001000
38#define CPU_BASED_CR8_LOAD_EXITING 0x00080000
39#define CPU_BASED_CR8_STORE_EXITING 0x00100000
40#define CPU_BASED_TPR_SHADOW 0x00200000
41#define CPU_BASED_MOV_DR_EXITING 0x00800000
42#define CPU_BASED_UNCOND_IO_EXITING 0x01000000
43#define CPU_BASED_USE_IO_BITMAPS 0x02000000
44#define CPU_BASED_USE_MSR_BITMAPS 0x10000000
45#define CPU_BASED_MONITOR_EXITING 0x20000000
46#define CPU_BASED_PAUSE_EXITING 0x40000000
47#define CPU_BASED_ACTIVATE_SECONDARY_CONTROLS 0x80000000
48/*
49 * Definitions of Secondary Processor-Based VM-Execution Controls.
50 */
51#define SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES 0x00000001
52#define SECONDARY_EXEC_WBINVD_EXITING 0x00000040
53
54
55#define PIN_BASED_EXT_INTR_MASK 0x00000001
56#define PIN_BASED_NMI_EXITING 0x00000008
57#define PIN_BASED_VIRTUAL_NMIS 0x00000020
58
59#define VM_EXIT_HOST_ADDR_SPACE_SIZE 0x00000200
60#define VM_EXIT_ACK_INTR_ON_EXIT 0x00008000
61
62#define VM_ENTRY_IA32E_MODE 0x00000200
63#define VM_ENTRY_SMM 0x00000400
64#define VM_ENTRY_DEACT_DUAL_MONITOR 0x00000800
65
66/* VMCS Encodings */
67enum vmcs_field {
68 GUEST_ES_SELECTOR = 0x00000800,
69 GUEST_CS_SELECTOR = 0x00000802,
70 GUEST_SS_SELECTOR = 0x00000804,
71 GUEST_DS_SELECTOR = 0x00000806,
72 GUEST_FS_SELECTOR = 0x00000808,
73 GUEST_GS_SELECTOR = 0x0000080a,
74 GUEST_LDTR_SELECTOR = 0x0000080c,
75 GUEST_TR_SELECTOR = 0x0000080e,
76 HOST_ES_SELECTOR = 0x00000c00,
77 HOST_CS_SELECTOR = 0x00000c02,
78 HOST_SS_SELECTOR = 0x00000c04,
79 HOST_DS_SELECTOR = 0x00000c06,
80 HOST_FS_SELECTOR = 0x00000c08,
81 HOST_GS_SELECTOR = 0x00000c0a,
82 HOST_TR_SELECTOR = 0x00000c0c,
83 IO_BITMAP_A = 0x00002000,
84 IO_BITMAP_A_HIGH = 0x00002001,
85 IO_BITMAP_B = 0x00002002,
86 IO_BITMAP_B_HIGH = 0x00002003,
87 MSR_BITMAP = 0x00002004,
88 MSR_BITMAP_HIGH = 0x00002005,
89 VM_EXIT_MSR_STORE_ADDR = 0x00002006,
90 VM_EXIT_MSR_STORE_ADDR_HIGH = 0x00002007,
91 VM_EXIT_MSR_LOAD_ADDR = 0x00002008,
92 VM_EXIT_MSR_LOAD_ADDR_HIGH = 0x00002009,
93 VM_ENTRY_MSR_LOAD_ADDR = 0x0000200a,
94 VM_ENTRY_MSR_LOAD_ADDR_HIGH = 0x0000200b,
95 TSC_OFFSET = 0x00002010,
96 TSC_OFFSET_HIGH = 0x00002011,
97 VIRTUAL_APIC_PAGE_ADDR = 0x00002012,
98 VIRTUAL_APIC_PAGE_ADDR_HIGH = 0x00002013,
99 APIC_ACCESS_ADDR = 0x00002014,
100 APIC_ACCESS_ADDR_HIGH = 0x00002015,
101 VMCS_LINK_POINTER = 0x00002800,
102 VMCS_LINK_POINTER_HIGH = 0x00002801,
103 GUEST_IA32_DEBUGCTL = 0x00002802,
104 GUEST_IA32_DEBUGCTL_HIGH = 0x00002803,
105 PIN_BASED_VM_EXEC_CONTROL = 0x00004000,
106 CPU_BASED_VM_EXEC_CONTROL = 0x00004002,
107 EXCEPTION_BITMAP = 0x00004004,
108 PAGE_FAULT_ERROR_CODE_MASK = 0x00004006,
109 PAGE_FAULT_ERROR_CODE_MATCH = 0x00004008,
110 CR3_TARGET_COUNT = 0x0000400a,
111 VM_EXIT_CONTROLS = 0x0000400c,
112 VM_EXIT_MSR_STORE_COUNT = 0x0000400e,
113 VM_EXIT_MSR_LOAD_COUNT = 0x00004010,
114 VM_ENTRY_CONTROLS = 0x00004012,
115 VM_ENTRY_MSR_LOAD_COUNT = 0x00004014,
116 VM_ENTRY_INTR_INFO_FIELD = 0x00004016,
117 VM_ENTRY_EXCEPTION_ERROR_CODE = 0x00004018,
118 VM_ENTRY_INSTRUCTION_LEN = 0x0000401a,
119 TPR_THRESHOLD = 0x0000401c,
120 SECONDARY_VM_EXEC_CONTROL = 0x0000401e,
121 VM_INSTRUCTION_ERROR = 0x00004400,
122 VM_EXIT_REASON = 0x00004402,
123 VM_EXIT_INTR_INFO = 0x00004404,
124 VM_EXIT_INTR_ERROR_CODE = 0x00004406,
125 IDT_VECTORING_INFO_FIELD = 0x00004408,
126 IDT_VECTORING_ERROR_CODE = 0x0000440a,
127 VM_EXIT_INSTRUCTION_LEN = 0x0000440c,
128 VMX_INSTRUCTION_INFO = 0x0000440e,
129 GUEST_ES_LIMIT = 0x00004800,
130 GUEST_CS_LIMIT = 0x00004802,
131 GUEST_SS_LIMIT = 0x00004804,
132 GUEST_DS_LIMIT = 0x00004806,
133 GUEST_FS_LIMIT = 0x00004808,
134 GUEST_GS_LIMIT = 0x0000480a,
135 GUEST_LDTR_LIMIT = 0x0000480c,
136 GUEST_TR_LIMIT = 0x0000480e,
137 GUEST_GDTR_LIMIT = 0x00004810,
138 GUEST_IDTR_LIMIT = 0x00004812,
139 GUEST_ES_AR_BYTES = 0x00004814,
140 GUEST_CS_AR_BYTES = 0x00004816,
141 GUEST_SS_AR_BYTES = 0x00004818,
142 GUEST_DS_AR_BYTES = 0x0000481a,
143 GUEST_FS_AR_BYTES = 0x0000481c,
144 GUEST_GS_AR_BYTES = 0x0000481e,
145 GUEST_LDTR_AR_BYTES = 0x00004820,
146 GUEST_TR_AR_BYTES = 0x00004822,
147 GUEST_INTERRUPTIBILITY_INFO = 0x00004824,
148 GUEST_ACTIVITY_STATE = 0X00004826,
149 GUEST_SYSENTER_CS = 0x0000482A,
150 HOST_IA32_SYSENTER_CS = 0x00004c00,
151 CR0_GUEST_HOST_MASK = 0x00006000,
152 CR4_GUEST_HOST_MASK = 0x00006002,
153 CR0_READ_SHADOW = 0x00006004,
154 CR4_READ_SHADOW = 0x00006006,
155 CR3_TARGET_VALUE0 = 0x00006008,
156 CR3_TARGET_VALUE1 = 0x0000600a,
157 CR3_TARGET_VALUE2 = 0x0000600c,
158 CR3_TARGET_VALUE3 = 0x0000600e,
159 EXIT_QUALIFICATION = 0x00006400,
160 GUEST_LINEAR_ADDRESS = 0x0000640a,
161 GUEST_CR0 = 0x00006800,
162 GUEST_CR3 = 0x00006802,
163 GUEST_CR4 = 0x00006804,
164 GUEST_ES_BASE = 0x00006806,
165 GUEST_CS_BASE = 0x00006808,
166 GUEST_SS_BASE = 0x0000680a,
167 GUEST_DS_BASE = 0x0000680c,
168 GUEST_FS_BASE = 0x0000680e,
169 GUEST_GS_BASE = 0x00006810,
170 GUEST_LDTR_BASE = 0x00006812,
171 GUEST_TR_BASE = 0x00006814,
172 GUEST_GDTR_BASE = 0x00006816,
173 GUEST_IDTR_BASE = 0x00006818,
174 GUEST_DR7 = 0x0000681a,
175 GUEST_RSP = 0x0000681c,
176 GUEST_RIP = 0x0000681e,
177 GUEST_RFLAGS = 0x00006820,
178 GUEST_PENDING_DBG_EXCEPTIONS = 0x00006822,
179 GUEST_SYSENTER_ESP = 0x00006824,
180 GUEST_SYSENTER_EIP = 0x00006826,
181 HOST_CR0 = 0x00006c00,
182 HOST_CR3 = 0x00006c02,
183 HOST_CR4 = 0x00006c04,
184 HOST_FS_BASE = 0x00006c06,
185 HOST_GS_BASE = 0x00006c08,
186 HOST_TR_BASE = 0x00006c0a,
187 HOST_GDTR_BASE = 0x00006c0c,
188 HOST_IDTR_BASE = 0x00006c0e,
189 HOST_IA32_SYSENTER_ESP = 0x00006c10,
190 HOST_IA32_SYSENTER_EIP = 0x00006c12,
191 HOST_RSP = 0x00006c14,
192 HOST_RIP = 0x00006c16,
193};
194
195#define VMX_EXIT_REASONS_FAILED_VMENTRY 0x80000000
196
197#define EXIT_REASON_EXCEPTION_NMI 0
198#define EXIT_REASON_EXTERNAL_INTERRUPT 1
199#define EXIT_REASON_TRIPLE_FAULT 2
200
201#define EXIT_REASON_PENDING_INTERRUPT 7
202
203#define EXIT_REASON_TASK_SWITCH 9
204#define EXIT_REASON_CPUID 10
205#define EXIT_REASON_HLT 12
206#define EXIT_REASON_INVLPG 14
207#define EXIT_REASON_RDPMC 15
208#define EXIT_REASON_RDTSC 16
209#define EXIT_REASON_VMCALL 18
210#define EXIT_REASON_VMCLEAR 19
211#define EXIT_REASON_VMLAUNCH 20
212#define EXIT_REASON_VMPTRLD 21
213#define EXIT_REASON_VMPTRST 22
214#define EXIT_REASON_VMREAD 23
215#define EXIT_REASON_VMRESUME 24
216#define EXIT_REASON_VMWRITE 25
217#define EXIT_REASON_VMOFF 26
218#define EXIT_REASON_VMON 27
219#define EXIT_REASON_CR_ACCESS 28
220#define EXIT_REASON_DR_ACCESS 29
221#define EXIT_REASON_IO_INSTRUCTION 30
222#define EXIT_REASON_MSR_READ 31
223#define EXIT_REASON_MSR_WRITE 32
224#define EXIT_REASON_MWAIT_INSTRUCTION 36
225#define EXIT_REASON_TPR_BELOW_THRESHOLD 43
226#define EXIT_REASON_APIC_ACCESS 44
227#define EXIT_REASON_WBINVD 54
228
229/*
230 * Interruption-information format
231 */
232#define INTR_INFO_VECTOR_MASK 0xff /* 7:0 */
233#define INTR_INFO_INTR_TYPE_MASK 0x700 /* 10:8 */
234#define INTR_INFO_DELIEVER_CODE_MASK 0x800 /* 11 */
235#define INTR_INFO_VALID_MASK 0x80000000 /* 31 */
236
237#define VECTORING_INFO_VECTOR_MASK INTR_INFO_VECTOR_MASK
238#define VECTORING_INFO_TYPE_MASK INTR_INFO_INTR_TYPE_MASK
239#define VECTORING_INFO_DELIEVER_CODE_MASK INTR_INFO_DELIEVER_CODE_MASK
240#define VECTORING_INFO_VALID_MASK INTR_INFO_VALID_MASK
241
242#define INTR_TYPE_EXT_INTR (0 << 8) /* external interrupt */
243#define INTR_TYPE_EXCEPTION (3 << 8) /* processor exception */
244#define INTR_TYPE_SOFT_INTR (4 << 8) /* software interrupt */
245
246/*
247 * Exit Qualifications for MOV for Control Register Access
248 */
249#define CONTROL_REG_ACCESS_NUM 0x7 /* 2:0, number of control reg.*/
250#define CONTROL_REG_ACCESS_TYPE 0x30 /* 5:4, access type */
251#define CONTROL_REG_ACCESS_REG 0xf00 /* 10:8, general purpose reg. */
252#define LMSW_SOURCE_DATA_SHIFT 16
253#define LMSW_SOURCE_DATA (0xFFFF << LMSW_SOURCE_DATA_SHIFT) /* 16:31 lmsw source */
254#define REG_EAX (0 << 8)
255#define REG_ECX (1 << 8)
256#define REG_EDX (2 << 8)
257#define REG_EBX (3 << 8)
258#define REG_ESP (4 << 8)
259#define REG_EBP (5 << 8)
260#define REG_ESI (6 << 8)
261#define REG_EDI (7 << 8)
262#define REG_R8 (8 << 8)
263#define REG_R9 (9 << 8)
264#define REG_R10 (10 << 8)
265#define REG_R11 (11 << 8)
266#define REG_R12 (12 << 8)
267#define REG_R13 (13 << 8)
268#define REG_R14 (14 << 8)
269#define REG_R15 (15 << 8)
270
271/*
272 * Exit Qualifications for MOV for Debug Register Access
273 */
274#define DEBUG_REG_ACCESS_NUM 0x7 /* 2:0, number of debug reg. */
275#define DEBUG_REG_ACCESS_TYPE 0x10 /* 4, direction of access */
276#define TYPE_MOV_TO_DR (0 << 4)
277#define TYPE_MOV_FROM_DR (1 << 4)
278#define DEBUG_REG_ACCESS_REG 0xf00 /* 11:8, general purpose reg. */
279
280
281/* segment AR */
282#define SEGMENT_AR_L_MASK (1 << 13)
283
284#define AR_TYPE_ACCESSES_MASK 1
285#define AR_TYPE_READABLE_MASK (1 << 1)
286#define AR_TYPE_WRITEABLE_MASK (1 << 2)
287#define AR_TYPE_CODE_MASK (1 << 3)
288#define AR_TYPE_MASK 0x0f
289#define AR_TYPE_BUSY_64_TSS 11
290#define AR_TYPE_BUSY_32_TSS 11
291#define AR_TYPE_BUSY_16_TSS 3
292#define AR_TYPE_LDT 2
293
294#define AR_UNUSABLE_MASK (1 << 16)
295#define AR_S_MASK (1 << 4)
296#define AR_P_MASK (1 << 7)
297#define AR_L_MASK (1 << 13)
298#define AR_DB_MASK (1 << 14)
299#define AR_G_MASK (1 << 15)
300#define AR_DPL_SHIFT 5
301#define AR_DPL(ar) (((ar) >> AR_DPL_SHIFT) & 3)
302
303#define AR_RESERVD_MASK 0xfffe0f00
304
305#define MSR_IA32_VMX_BASIC 0x480
306#define MSR_IA32_VMX_PINBASED_CTLS 0x481
307#define MSR_IA32_VMX_PROCBASED_CTLS 0x482
308#define MSR_IA32_VMX_EXIT_CTLS 0x483
309#define MSR_IA32_VMX_ENTRY_CTLS 0x484
310#define MSR_IA32_VMX_MISC 0x485
311#define MSR_IA32_VMX_CR0_FIXED0 0x486
312#define MSR_IA32_VMX_CR0_FIXED1 0x487
313#define MSR_IA32_VMX_CR4_FIXED0 0x488
314#define MSR_IA32_VMX_CR4_FIXED1 0x489
315#define MSR_IA32_VMX_VMCS_ENUM 0x48a
316#define MSR_IA32_VMX_PROCBASED_CTLS2 0x48b
317
318#define MSR_IA32_FEATURE_CONTROL 0x3a
319#define MSR_IA32_FEATURE_CONTROL_LOCKED 0x1
320#define MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED 0x4
321
322#define APIC_ACCESS_PAGE_PRIVATE_MEMSLOT 9
323
324#endif
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
new file mode 100644
index 000000000000..8f94a0b89dff
--- /dev/null
+++ b/arch/x86/kvm/x86.c
@@ -0,0 +1,3287 @@
1/*
2 * Kernel-based Virtual Machine driver for Linux
3 *
4 * derived from drivers/kvm/kvm_main.c
5 *
6 * Copyright (C) 2006 Qumranet, Inc.
7 *
8 * Authors:
9 * Avi Kivity <avi@qumranet.com>
10 * Yaniv Kamay <yaniv@qumranet.com>
11 *
12 * This work is licensed under the terms of the GNU GPL, version 2. See
13 * the COPYING file in the top-level directory.
14 *
15 */
16
17#include <linux/kvm_host.h>
18#include "segment_descriptor.h"
19#include "irq.h"
20#include "mmu.h"
21
22#include <linux/kvm.h>
23#include <linux/fs.h>
24#include <linux/vmalloc.h>
25#include <linux/module.h>
26#include <linux/mman.h>
27#include <linux/highmem.h>
28
29#include <asm/uaccess.h>
30#include <asm/msr.h>
31
32#define MAX_IO_MSRS 256
33#define CR0_RESERVED_BITS \
34 (~(unsigned long)(X86_CR0_PE | X86_CR0_MP | X86_CR0_EM | X86_CR0_TS \
35 | X86_CR0_ET | X86_CR0_NE | X86_CR0_WP | X86_CR0_AM \
36 | X86_CR0_NW | X86_CR0_CD | X86_CR0_PG))
37#define CR4_RESERVED_BITS \
38 (~(unsigned long)(X86_CR4_VME | X86_CR4_PVI | X86_CR4_TSD | X86_CR4_DE\
39 | X86_CR4_PSE | X86_CR4_PAE | X86_CR4_MCE \
40 | X86_CR4_PGE | X86_CR4_PCE | X86_CR4_OSFXSR \
41 | X86_CR4_OSXMMEXCPT | X86_CR4_VMXE))
42
43#define CR8_RESERVED_BITS (~(unsigned long)X86_CR8_TPR)
44#define EFER_RESERVED_BITS 0xfffffffffffff2fe
45
46#define VM_STAT(x) offsetof(struct kvm, stat.x), KVM_STAT_VM
47#define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU
48
49struct kvm_x86_ops *kvm_x86_ops;
50
51struct kvm_stats_debugfs_item debugfs_entries[] = {
52 { "pf_fixed", VCPU_STAT(pf_fixed) },
53 { "pf_guest", VCPU_STAT(pf_guest) },
54 { "tlb_flush", VCPU_STAT(tlb_flush) },
55 { "invlpg", VCPU_STAT(invlpg) },
56 { "exits", VCPU_STAT(exits) },
57 { "io_exits", VCPU_STAT(io_exits) },
58 { "mmio_exits", VCPU_STAT(mmio_exits) },
59 { "signal_exits", VCPU_STAT(signal_exits) },
60 { "irq_window", VCPU_STAT(irq_window_exits) },
61 { "halt_exits", VCPU_STAT(halt_exits) },
62 { "halt_wakeup", VCPU_STAT(halt_wakeup) },
63 { "request_irq", VCPU_STAT(request_irq_exits) },
64 { "irq_exits", VCPU_STAT(irq_exits) },
65 { "host_state_reload", VCPU_STAT(host_state_reload) },
66 { "efer_reload", VCPU_STAT(efer_reload) },
67 { "fpu_reload", VCPU_STAT(fpu_reload) },
68 { "insn_emulation", VCPU_STAT(insn_emulation) },
69 { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail) },
70 { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped) },
71 { "mmu_pte_write", VM_STAT(mmu_pte_write) },
72 { "mmu_pte_updated", VM_STAT(mmu_pte_updated) },
73 { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped) },
74 { "mmu_flooded", VM_STAT(mmu_flooded) },
75 { "mmu_recycled", VM_STAT(mmu_recycled) },
76 { "mmu_cache_miss", VM_STAT(mmu_cache_miss) },
77 { "remote_tlb_flush", VM_STAT(remote_tlb_flush) },
78 { NULL }
79};
80
81
82unsigned long segment_base(u16 selector)
83{
84 struct descriptor_table gdt;
85 struct segment_descriptor *d;
86 unsigned long table_base;
87 unsigned long v;
88
89 if (selector == 0)
90 return 0;
91
92 asm("sgdt %0" : "=m"(gdt));
93 table_base = gdt.base;
94
95 if (selector & 4) { /* from ldt */
96 u16 ldt_selector;
97
98 asm("sldt %0" : "=g"(ldt_selector));
99 table_base = segment_base(ldt_selector);
100 }
101 d = (struct segment_descriptor *)(table_base + (selector & ~7));
102 v = d->base_low | ((unsigned long)d->base_mid << 16) |
103 ((unsigned long)d->base_high << 24);
104#ifdef CONFIG_X86_64
105 if (d->system == 0 && (d->type == 2 || d->type == 9 || d->type == 11))
106 v |= ((unsigned long) \
107 ((struct segment_descriptor_64 *)d)->base_higher) << 32;
108#endif
109 return v;
110}
111EXPORT_SYMBOL_GPL(segment_base);
112
113u64 kvm_get_apic_base(struct kvm_vcpu *vcpu)
114{
115 if (irqchip_in_kernel(vcpu->kvm))
116 return vcpu->arch.apic_base;
117 else
118 return vcpu->arch.apic_base;
119}
120EXPORT_SYMBOL_GPL(kvm_get_apic_base);
121
122void kvm_set_apic_base(struct kvm_vcpu *vcpu, u64 data)
123{
124 /* TODO: reserve bits check */
125 if (irqchip_in_kernel(vcpu->kvm))
126 kvm_lapic_set_base(vcpu, data);
127 else
128 vcpu->arch.apic_base = data;
129}
130EXPORT_SYMBOL_GPL(kvm_set_apic_base);
131
132void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr)
133{
134 WARN_ON(vcpu->arch.exception.pending);
135 vcpu->arch.exception.pending = true;
136 vcpu->arch.exception.has_error_code = false;
137 vcpu->arch.exception.nr = nr;
138}
139EXPORT_SYMBOL_GPL(kvm_queue_exception);
140
141void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long addr,
142 u32 error_code)
143{
144 ++vcpu->stat.pf_guest;
145 if (vcpu->arch.exception.pending && vcpu->arch.exception.nr == PF_VECTOR) {
146 printk(KERN_DEBUG "kvm: inject_page_fault:"
147 " double fault 0x%lx\n", addr);
148 vcpu->arch.exception.nr = DF_VECTOR;
149 vcpu->arch.exception.error_code = 0;
150 return;
151 }
152 vcpu->arch.cr2 = addr;
153 kvm_queue_exception_e(vcpu, PF_VECTOR, error_code);
154}
155
156void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code)
157{
158 WARN_ON(vcpu->arch.exception.pending);
159 vcpu->arch.exception.pending = true;
160 vcpu->arch.exception.has_error_code = true;
161 vcpu->arch.exception.nr = nr;
162 vcpu->arch.exception.error_code = error_code;
163}
164EXPORT_SYMBOL_GPL(kvm_queue_exception_e);
165
166static void __queue_exception(struct kvm_vcpu *vcpu)
167{
168 kvm_x86_ops->queue_exception(vcpu, vcpu->arch.exception.nr,
169 vcpu->arch.exception.has_error_code,
170 vcpu->arch.exception.error_code);
171}
172
173/*
174 * Load the pae pdptrs. Return true is they are all valid.
175 */
176int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3)
177{
178 gfn_t pdpt_gfn = cr3 >> PAGE_SHIFT;
179 unsigned offset = ((cr3 & (PAGE_SIZE-1)) >> 5) << 2;
180 int i;
181 int ret;
182 u64 pdpte[ARRAY_SIZE(vcpu->arch.pdptrs)];
183
184 down_read(&current->mm->mmap_sem);
185 ret = kvm_read_guest_page(vcpu->kvm, pdpt_gfn, pdpte,
186 offset * sizeof(u64), sizeof(pdpte));
187 if (ret < 0) {
188 ret = 0;
189 goto out;
190 }
191 for (i = 0; i < ARRAY_SIZE(pdpte); ++i) {
192 if ((pdpte[i] & 1) && (pdpte[i] & 0xfffffff0000001e6ull)) {
193 ret = 0;
194 goto out;
195 }
196 }
197 ret = 1;
198
199 memcpy(vcpu->arch.pdptrs, pdpte, sizeof(vcpu->arch.pdptrs));
200out:
201 up_read(&current->mm->mmap_sem);
202
203 return ret;
204}
205
206static bool pdptrs_changed(struct kvm_vcpu *vcpu)
207{
208 u64 pdpte[ARRAY_SIZE(vcpu->arch.pdptrs)];
209 bool changed = true;
210 int r;
211
212 if (is_long_mode(vcpu) || !is_pae(vcpu))
213 return false;
214
215 down_read(&current->mm->mmap_sem);
216 r = kvm_read_guest(vcpu->kvm, vcpu->arch.cr3 & ~31u, pdpte, sizeof(pdpte));
217 if (r < 0)
218 goto out;
219 changed = memcmp(pdpte, vcpu->arch.pdptrs, sizeof(pdpte)) != 0;
220out:
221 up_read(&current->mm->mmap_sem);
222
223 return changed;
224}
225
226void set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
227{
228 if (cr0 & CR0_RESERVED_BITS) {
229 printk(KERN_DEBUG "set_cr0: 0x%lx #GP, reserved bits 0x%lx\n",
230 cr0, vcpu->arch.cr0);
231 kvm_inject_gp(vcpu, 0);
232 return;
233 }
234
235 if ((cr0 & X86_CR0_NW) && !(cr0 & X86_CR0_CD)) {
236 printk(KERN_DEBUG "set_cr0: #GP, CD == 0 && NW == 1\n");
237 kvm_inject_gp(vcpu, 0);
238 return;
239 }
240
241 if ((cr0 & X86_CR0_PG) && !(cr0 & X86_CR0_PE)) {
242 printk(KERN_DEBUG "set_cr0: #GP, set PG flag "
243 "and a clear PE flag\n");
244 kvm_inject_gp(vcpu, 0);
245 return;
246 }
247
248 if (!is_paging(vcpu) && (cr0 & X86_CR0_PG)) {
249#ifdef CONFIG_X86_64
250 if ((vcpu->arch.shadow_efer & EFER_LME)) {
251 int cs_db, cs_l;
252
253 if (!is_pae(vcpu)) {
254 printk(KERN_DEBUG "set_cr0: #GP, start paging "
255 "in long mode while PAE is disabled\n");
256 kvm_inject_gp(vcpu, 0);
257 return;
258 }
259 kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
260 if (cs_l) {
261 printk(KERN_DEBUG "set_cr0: #GP, start paging "
262 "in long mode while CS.L == 1\n");
263 kvm_inject_gp(vcpu, 0);
264 return;
265
266 }
267 } else
268#endif
269 if (is_pae(vcpu) && !load_pdptrs(vcpu, vcpu->arch.cr3)) {
270 printk(KERN_DEBUG "set_cr0: #GP, pdptrs "
271 "reserved bits\n");
272 kvm_inject_gp(vcpu, 0);
273 return;
274 }
275
276 }
277
278 kvm_x86_ops->set_cr0(vcpu, cr0);
279 vcpu->arch.cr0 = cr0;
280
281 kvm_mmu_reset_context(vcpu);
282 return;
283}
284EXPORT_SYMBOL_GPL(set_cr0);
285
286void lmsw(struct kvm_vcpu *vcpu, unsigned long msw)
287{
288 set_cr0(vcpu, (vcpu->arch.cr0 & ~0x0ful) | (msw & 0x0f));
289}
290EXPORT_SYMBOL_GPL(lmsw);
291
292void set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
293{
294 if (cr4 & CR4_RESERVED_BITS) {
295 printk(KERN_DEBUG "set_cr4: #GP, reserved bits\n");
296 kvm_inject_gp(vcpu, 0);
297 return;
298 }
299
300 if (is_long_mode(vcpu)) {
301 if (!(cr4 & X86_CR4_PAE)) {
302 printk(KERN_DEBUG "set_cr4: #GP, clearing PAE while "
303 "in long mode\n");
304 kvm_inject_gp(vcpu, 0);
305 return;
306 }
307 } else if (is_paging(vcpu) && !is_pae(vcpu) && (cr4 & X86_CR4_PAE)
308 && !load_pdptrs(vcpu, vcpu->arch.cr3)) {
309 printk(KERN_DEBUG "set_cr4: #GP, pdptrs reserved bits\n");
310 kvm_inject_gp(vcpu, 0);
311 return;
312 }
313
314 if (cr4 & X86_CR4_VMXE) {
315 printk(KERN_DEBUG "set_cr4: #GP, setting VMXE\n");
316 kvm_inject_gp(vcpu, 0);
317 return;
318 }
319 kvm_x86_ops->set_cr4(vcpu, cr4);
320 vcpu->arch.cr4 = cr4;
321 kvm_mmu_reset_context(vcpu);
322}
323EXPORT_SYMBOL_GPL(set_cr4);
324
325void set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
326{
327 if (cr3 == vcpu->arch.cr3 && !pdptrs_changed(vcpu)) {
328 kvm_mmu_flush_tlb(vcpu);
329 return;
330 }
331
332 if (is_long_mode(vcpu)) {
333 if (cr3 & CR3_L_MODE_RESERVED_BITS) {
334 printk(KERN_DEBUG "set_cr3: #GP, reserved bits\n");
335 kvm_inject_gp(vcpu, 0);
336 return;
337 }
338 } else {
339 if (is_pae(vcpu)) {
340 if (cr3 & CR3_PAE_RESERVED_BITS) {
341 printk(KERN_DEBUG
342 "set_cr3: #GP, reserved bits\n");
343 kvm_inject_gp(vcpu, 0);
344 return;
345 }
346 if (is_paging(vcpu) && !load_pdptrs(vcpu, cr3)) {
347 printk(KERN_DEBUG "set_cr3: #GP, pdptrs "
348 "reserved bits\n");
349 kvm_inject_gp(vcpu, 0);
350 return;
351 }
352 }
353 /*
354 * We don't check reserved bits in nonpae mode, because
355 * this isn't enforced, and VMware depends on this.
356 */
357 }
358
359 down_read(&current->mm->mmap_sem);
360 /*
361 * Does the new cr3 value map to physical memory? (Note, we
362 * catch an invalid cr3 even in real-mode, because it would
363 * cause trouble later on when we turn on paging anyway.)
364 *
365 * A real CPU would silently accept an invalid cr3 and would
366 * attempt to use it - with largely undefined (and often hard
367 * to debug) behavior on the guest side.
368 */
369 if (unlikely(!gfn_to_memslot(vcpu->kvm, cr3 >> PAGE_SHIFT)))
370 kvm_inject_gp(vcpu, 0);
371 else {
372 vcpu->arch.cr3 = cr3;
373 vcpu->arch.mmu.new_cr3(vcpu);
374 }
375 up_read(&current->mm->mmap_sem);
376}
377EXPORT_SYMBOL_GPL(set_cr3);
378
379void set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8)
380{
381 if (cr8 & CR8_RESERVED_BITS) {
382 printk(KERN_DEBUG "set_cr8: #GP, reserved bits 0x%lx\n", cr8);
383 kvm_inject_gp(vcpu, 0);
384 return;
385 }
386 if (irqchip_in_kernel(vcpu->kvm))
387 kvm_lapic_set_tpr(vcpu, cr8);
388 else
389 vcpu->arch.cr8 = cr8;
390}
391EXPORT_SYMBOL_GPL(set_cr8);
392
393unsigned long get_cr8(struct kvm_vcpu *vcpu)
394{
395 if (irqchip_in_kernel(vcpu->kvm))
396 return kvm_lapic_get_cr8(vcpu);
397 else
398 return vcpu->arch.cr8;
399}
400EXPORT_SYMBOL_GPL(get_cr8);
401
402/*
403 * List of msr numbers which we expose to userspace through KVM_GET_MSRS
404 * and KVM_SET_MSRS, and KVM_GET_MSR_INDEX_LIST.
405 *
406 * This list is modified at module load time to reflect the
407 * capabilities of the host cpu.
408 */
409static u32 msrs_to_save[] = {
410 MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP,
411 MSR_K6_STAR,
412#ifdef CONFIG_X86_64
413 MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR,
414#endif
415 MSR_IA32_TIME_STAMP_COUNTER,
416};
417
418static unsigned num_msrs_to_save;
419
420static u32 emulated_msrs[] = {
421 MSR_IA32_MISC_ENABLE,
422};
423
424#ifdef CONFIG_X86_64
425
426static void set_efer(struct kvm_vcpu *vcpu, u64 efer)
427{
428 if (efer & EFER_RESERVED_BITS) {
429 printk(KERN_DEBUG "set_efer: 0x%llx #GP, reserved bits\n",
430 efer);
431 kvm_inject_gp(vcpu, 0);
432 return;
433 }
434
435 if (is_paging(vcpu)
436 && (vcpu->arch.shadow_efer & EFER_LME) != (efer & EFER_LME)) {
437 printk(KERN_DEBUG "set_efer: #GP, change LME while paging\n");
438 kvm_inject_gp(vcpu, 0);
439 return;
440 }
441
442 kvm_x86_ops->set_efer(vcpu, efer);
443
444 efer &= ~EFER_LMA;
445 efer |= vcpu->arch.shadow_efer & EFER_LMA;
446
447 vcpu->arch.shadow_efer = efer;
448}
449
450#endif
451
452/*
453 * Writes msr value into into the appropriate "register".
454 * Returns 0 on success, non-0 otherwise.
455 * Assumes vcpu_load() was already called.
456 */
457int kvm_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
458{
459 return kvm_x86_ops->set_msr(vcpu, msr_index, data);
460}
461
462/*
463 * Adapt set_msr() to msr_io()'s calling convention
464 */
465static int do_set_msr(struct kvm_vcpu *vcpu, unsigned index, u64 *data)
466{
467 return kvm_set_msr(vcpu, index, *data);
468}
469
470
471int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
472{
473 switch (msr) {
474#ifdef CONFIG_X86_64
475 case MSR_EFER:
476 set_efer(vcpu, data);
477 break;
478#endif
479 case MSR_IA32_MC0_STATUS:
480 pr_unimpl(vcpu, "%s: MSR_IA32_MC0_STATUS 0x%llx, nop\n",
481 __FUNCTION__, data);
482 break;
483 case MSR_IA32_MCG_STATUS:
484 pr_unimpl(vcpu, "%s: MSR_IA32_MCG_STATUS 0x%llx, nop\n",
485 __FUNCTION__, data);
486 break;
487 case MSR_IA32_UCODE_REV:
488 case MSR_IA32_UCODE_WRITE:
489 case 0x200 ... 0x2ff: /* MTRRs */
490 break;
491 case MSR_IA32_APICBASE:
492 kvm_set_apic_base(vcpu, data);
493 break;
494 case MSR_IA32_MISC_ENABLE:
495 vcpu->arch.ia32_misc_enable_msr = data;
496 break;
497 default:
498 pr_unimpl(vcpu, "unhandled wrmsr: 0x%x data %llx\n", msr, data);
499 return 1;
500 }
501 return 0;
502}
503EXPORT_SYMBOL_GPL(kvm_set_msr_common);
504
505
506/*
507 * Reads an msr value (of 'msr_index') into 'pdata'.
508 * Returns 0 on success, non-0 otherwise.
509 * Assumes vcpu_load() was already called.
510 */
511int kvm_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
512{
513 return kvm_x86_ops->get_msr(vcpu, msr_index, pdata);
514}
515
516int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
517{
518 u64 data;
519
520 switch (msr) {
521 case 0xc0010010: /* SYSCFG */
522 case 0xc0010015: /* HWCR */
523 case MSR_IA32_PLATFORM_ID:
524 case MSR_IA32_P5_MC_ADDR:
525 case MSR_IA32_P5_MC_TYPE:
526 case MSR_IA32_MC0_CTL:
527 case MSR_IA32_MCG_STATUS:
528 case MSR_IA32_MCG_CAP:
529 case MSR_IA32_MC0_MISC:
530 case MSR_IA32_MC0_MISC+4:
531 case MSR_IA32_MC0_MISC+8:
532 case MSR_IA32_MC0_MISC+12:
533 case MSR_IA32_MC0_MISC+16:
534 case MSR_IA32_UCODE_REV:
535 case MSR_IA32_PERF_STATUS:
536 case MSR_IA32_EBL_CR_POWERON:
537 /* MTRR registers */
538 case 0xfe:
539 case 0x200 ... 0x2ff:
540 data = 0;
541 break;
542 case 0xcd: /* fsb frequency */
543 data = 3;
544 break;
545 case MSR_IA32_APICBASE:
546 data = kvm_get_apic_base(vcpu);
547 break;
548 case MSR_IA32_MISC_ENABLE:
549 data = vcpu->arch.ia32_misc_enable_msr;
550 break;
551#ifdef CONFIG_X86_64
552 case MSR_EFER:
553 data = vcpu->arch.shadow_efer;
554 break;
555#endif
556 default:
557 pr_unimpl(vcpu, "unhandled rdmsr: 0x%x\n", msr);
558 return 1;
559 }
560 *pdata = data;
561 return 0;
562}
563EXPORT_SYMBOL_GPL(kvm_get_msr_common);
564
565/*
566 * Read or write a bunch of msrs. All parameters are kernel addresses.
567 *
568 * @return number of msrs set successfully.
569 */
570static int __msr_io(struct kvm_vcpu *vcpu, struct kvm_msrs *msrs,
571 struct kvm_msr_entry *entries,
572 int (*do_msr)(struct kvm_vcpu *vcpu,
573 unsigned index, u64 *data))
574{
575 int i;
576
577 vcpu_load(vcpu);
578
579 for (i = 0; i < msrs->nmsrs; ++i)
580 if (do_msr(vcpu, entries[i].index, &entries[i].data))
581 break;
582
583 vcpu_put(vcpu);
584
585 return i;
586}
587
588/*
589 * Read or write a bunch of msrs. Parameters are user addresses.
590 *
591 * @return number of msrs set successfully.
592 */
593static int msr_io(struct kvm_vcpu *vcpu, struct kvm_msrs __user *user_msrs,
594 int (*do_msr)(struct kvm_vcpu *vcpu,
595 unsigned index, u64 *data),
596 int writeback)
597{
598 struct kvm_msrs msrs;
599 struct kvm_msr_entry *entries;
600 int r, n;
601 unsigned size;
602
603 r = -EFAULT;
604 if (copy_from_user(&msrs, user_msrs, sizeof msrs))
605 goto out;
606
607 r = -E2BIG;
608 if (msrs.nmsrs >= MAX_IO_MSRS)
609 goto out;
610
611 r = -ENOMEM;
612 size = sizeof(struct kvm_msr_entry) * msrs.nmsrs;
613 entries = vmalloc(size);
614 if (!entries)
615 goto out;
616
617 r = -EFAULT;
618 if (copy_from_user(entries, user_msrs->entries, size))
619 goto out_free;
620
621 r = n = __msr_io(vcpu, &msrs, entries, do_msr);
622 if (r < 0)
623 goto out_free;
624
625 r = -EFAULT;
626 if (writeback && copy_to_user(user_msrs->entries, entries, size))
627 goto out_free;
628
629 r = n;
630
631out_free:
632 vfree(entries);
633out:
634 return r;
635}
636
637/*
638 * Make sure that a cpu that is being hot-unplugged does not have any vcpus
639 * cached on it.
640 */
641void decache_vcpus_on_cpu(int cpu)
642{
643 struct kvm *vm;
644 struct kvm_vcpu *vcpu;
645 int i;
646
647 spin_lock(&kvm_lock);
648 list_for_each_entry(vm, &vm_list, vm_list)
649 for (i = 0; i < KVM_MAX_VCPUS; ++i) {
650 vcpu = vm->vcpus[i];
651 if (!vcpu)
652 continue;
653 /*
654 * If the vcpu is locked, then it is running on some
655 * other cpu and therefore it is not cached on the
656 * cpu in question.
657 *
658 * If it's not locked, check the last cpu it executed
659 * on.
660 */
661 if (mutex_trylock(&vcpu->mutex)) {
662 if (vcpu->cpu == cpu) {
663 kvm_x86_ops->vcpu_decache(vcpu);
664 vcpu->cpu = -1;
665 }
666 mutex_unlock(&vcpu->mutex);
667 }
668 }
669 spin_unlock(&kvm_lock);
670}
671
672int kvm_dev_ioctl_check_extension(long ext)
673{
674 int r;
675
676 switch (ext) {
677 case KVM_CAP_IRQCHIP:
678 case KVM_CAP_HLT:
679 case KVM_CAP_MMU_SHADOW_CACHE_CONTROL:
680 case KVM_CAP_USER_MEMORY:
681 case KVM_CAP_SET_TSS_ADDR:
682 case KVM_CAP_EXT_CPUID:
683 r = 1;
684 break;
685 case KVM_CAP_VAPIC:
686 r = !kvm_x86_ops->cpu_has_accelerated_tpr();
687 break;
688 default:
689 r = 0;
690 break;
691 }
692 return r;
693
694}
695
696long kvm_arch_dev_ioctl(struct file *filp,
697 unsigned int ioctl, unsigned long arg)
698{
699 void __user *argp = (void __user *)arg;
700 long r;
701
702 switch (ioctl) {
703 case KVM_GET_MSR_INDEX_LIST: {
704 struct kvm_msr_list __user *user_msr_list = argp;
705 struct kvm_msr_list msr_list;
706 unsigned n;
707
708 r = -EFAULT;
709 if (copy_from_user(&msr_list, user_msr_list, sizeof msr_list))
710 goto out;
711 n = msr_list.nmsrs;
712 msr_list.nmsrs = num_msrs_to_save + ARRAY_SIZE(emulated_msrs);
713 if (copy_to_user(user_msr_list, &msr_list, sizeof msr_list))
714 goto out;
715 r = -E2BIG;
716 if (n < num_msrs_to_save)
717 goto out;
718 r = -EFAULT;
719 if (copy_to_user(user_msr_list->indices, &msrs_to_save,
720 num_msrs_to_save * sizeof(u32)))
721 goto out;
722 if (copy_to_user(user_msr_list->indices
723 + num_msrs_to_save * sizeof(u32),
724 &emulated_msrs,
725 ARRAY_SIZE(emulated_msrs) * sizeof(u32)))
726 goto out;
727 r = 0;
728 break;
729 }
730 default:
731 r = -EINVAL;
732 }
733out:
734 return r;
735}
736
737void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
738{
739 kvm_x86_ops->vcpu_load(vcpu, cpu);
740}
741
742void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
743{
744 kvm_x86_ops->vcpu_put(vcpu);
745 kvm_put_guest_fpu(vcpu);
746}
747
748static int is_efer_nx(void)
749{
750 u64 efer;
751
752 rdmsrl(MSR_EFER, efer);
753 return efer & EFER_NX;
754}
755
756static void cpuid_fix_nx_cap(struct kvm_vcpu *vcpu)
757{
758 int i;
759 struct kvm_cpuid_entry2 *e, *entry;
760
761 entry = NULL;
762 for (i = 0; i < vcpu->arch.cpuid_nent; ++i) {
763 e = &vcpu->arch.cpuid_entries[i];
764 if (e->function == 0x80000001) {
765 entry = e;
766 break;
767 }
768 }
769 if (entry && (entry->edx & (1 << 20)) && !is_efer_nx()) {
770 entry->edx &= ~(1 << 20);
771 printk(KERN_INFO "kvm: guest NX capability removed\n");
772 }
773}
774
775/* when an old userspace process fills a new kernel module */
776static int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
777 struct kvm_cpuid *cpuid,
778 struct kvm_cpuid_entry __user *entries)
779{
780 int r, i;
781 struct kvm_cpuid_entry *cpuid_entries;
782
783 r = -E2BIG;
784 if (cpuid->nent > KVM_MAX_CPUID_ENTRIES)
785 goto out;
786 r = -ENOMEM;
787 cpuid_entries = vmalloc(sizeof(struct kvm_cpuid_entry) * cpuid->nent);
788 if (!cpuid_entries)
789 goto out;
790 r = -EFAULT;
791 if (copy_from_user(cpuid_entries, entries,
792 cpuid->nent * sizeof(struct kvm_cpuid_entry)))
793 goto out_free;
794 for (i = 0; i < cpuid->nent; i++) {
795 vcpu->arch.cpuid_entries[i].function = cpuid_entries[i].function;
796 vcpu->arch.cpuid_entries[i].eax = cpuid_entries[i].eax;
797 vcpu->arch.cpuid_entries[i].ebx = cpuid_entries[i].ebx;
798 vcpu->arch.cpuid_entries[i].ecx = cpuid_entries[i].ecx;
799 vcpu->arch.cpuid_entries[i].edx = cpuid_entries[i].edx;
800 vcpu->arch.cpuid_entries[i].index = 0;
801 vcpu->arch.cpuid_entries[i].flags = 0;
802 vcpu->arch.cpuid_entries[i].padding[0] = 0;
803 vcpu->arch.cpuid_entries[i].padding[1] = 0;
804 vcpu->arch.cpuid_entries[i].padding[2] = 0;
805 }
806 vcpu->arch.cpuid_nent = cpuid->nent;
807 cpuid_fix_nx_cap(vcpu);
808 r = 0;
809
810out_free:
811 vfree(cpuid_entries);
812out:
813 return r;
814}
815
816static int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu,
817 struct kvm_cpuid2 *cpuid,
818 struct kvm_cpuid_entry2 __user *entries)
819{
820 int r;
821
822 r = -E2BIG;
823 if (cpuid->nent > KVM_MAX_CPUID_ENTRIES)
824 goto out;
825 r = -EFAULT;
826 if (copy_from_user(&vcpu->arch.cpuid_entries, entries,
827 cpuid->nent * sizeof(struct kvm_cpuid_entry2)))
828 goto out;
829 vcpu->arch.cpuid_nent = cpuid->nent;
830 return 0;
831
832out:
833 return r;
834}
835
836static int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu,
837 struct kvm_cpuid2 *cpuid,
838 struct kvm_cpuid_entry2 __user *entries)
839{
840 int r;
841
842 r = -E2BIG;
843 if (cpuid->nent < vcpu->arch.cpuid_nent)
844 goto out;
845 r = -EFAULT;
846 if (copy_to_user(entries, &vcpu->arch.cpuid_entries,
847 vcpu->arch.cpuid_nent * sizeof(struct kvm_cpuid_entry2)))
848 goto out;
849 return 0;
850
851out:
852 cpuid->nent = vcpu->arch.cpuid_nent;
853 return r;
854}
855
856static inline u32 bit(int bitno)
857{
858 return 1 << (bitno & 31);
859}
860
861static void do_cpuid_1_ent(struct kvm_cpuid_entry2 *entry, u32 function,
862 u32 index)
863{
864 entry->function = function;
865 entry->index = index;
866 cpuid_count(entry->function, entry->index,
867 &entry->eax, &entry->ebx, &entry->ecx, &entry->edx);
868 entry->flags = 0;
869}
870
871static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
872 u32 index, int *nent, int maxnent)
873{
874 const u32 kvm_supported_word0_x86_features = bit(X86_FEATURE_FPU) |
875 bit(X86_FEATURE_VME) | bit(X86_FEATURE_DE) |
876 bit(X86_FEATURE_PSE) | bit(X86_FEATURE_TSC) |
877 bit(X86_FEATURE_MSR) | bit(X86_FEATURE_PAE) |
878 bit(X86_FEATURE_CX8) | bit(X86_FEATURE_APIC) |
879 bit(X86_FEATURE_SEP) | bit(X86_FEATURE_PGE) |
880 bit(X86_FEATURE_CMOV) | bit(X86_FEATURE_PSE36) |
881 bit(X86_FEATURE_CLFLSH) | bit(X86_FEATURE_MMX) |
882 bit(X86_FEATURE_FXSR) | bit(X86_FEATURE_XMM) |
883 bit(X86_FEATURE_XMM2) | bit(X86_FEATURE_SELFSNOOP);
884 const u32 kvm_supported_word1_x86_features = bit(X86_FEATURE_FPU) |
885 bit(X86_FEATURE_VME) | bit(X86_FEATURE_DE) |
886 bit(X86_FEATURE_PSE) | bit(X86_FEATURE_TSC) |
887 bit(X86_FEATURE_MSR) | bit(X86_FEATURE_PAE) |
888 bit(X86_FEATURE_CX8) | bit(X86_FEATURE_APIC) |
889 bit(X86_FEATURE_PGE) |
890 bit(X86_FEATURE_CMOV) | bit(X86_FEATURE_PSE36) |
891 bit(X86_FEATURE_MMX) | bit(X86_FEATURE_FXSR) |
892 bit(X86_FEATURE_SYSCALL) |
893 (bit(X86_FEATURE_NX) && is_efer_nx()) |
894#ifdef CONFIG_X86_64
895 bit(X86_FEATURE_LM) |
896#endif
897 bit(X86_FEATURE_MMXEXT) |
898 bit(X86_FEATURE_3DNOWEXT) |
899 bit(X86_FEATURE_3DNOW);
900 const u32 kvm_supported_word3_x86_features =
901 bit(X86_FEATURE_XMM3) | bit(X86_FEATURE_CX16);
902 const u32 kvm_supported_word6_x86_features =
903 bit(X86_FEATURE_LAHF_LM) | bit(X86_FEATURE_CMP_LEGACY);
904
905 /* all func 2 cpuid_count() should be called on the same cpu */
906 get_cpu();
907 do_cpuid_1_ent(entry, function, index);
908 ++*nent;
909
910 switch (function) {
911 case 0:
912 entry->eax = min(entry->eax, (u32)0xb);
913 break;
914 case 1:
915 entry->edx &= kvm_supported_word0_x86_features;
916 entry->ecx &= kvm_supported_word3_x86_features;
917 break;
918 /* function 2 entries are STATEFUL. That is, repeated cpuid commands
919 * may return different values. This forces us to get_cpu() before
920 * issuing the first command, and also to emulate this annoying behavior
921 * in kvm_emulate_cpuid() using KVM_CPUID_FLAG_STATE_READ_NEXT */
922 case 2: {
923 int t, times = entry->eax & 0xff;
924
925 entry->flags |= KVM_CPUID_FLAG_STATEFUL_FUNC;
926 for (t = 1; t < times && *nent < maxnent; ++t) {
927 do_cpuid_1_ent(&entry[t], function, 0);
928 entry[t].flags |= KVM_CPUID_FLAG_STATEFUL_FUNC;
929 ++*nent;
930 }
931 break;
932 }
933 /* function 4 and 0xb have additional index. */
934 case 4: {
935 int index, cache_type;
936
937 entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
938 /* read more entries until cache_type is zero */
939 for (index = 1; *nent < maxnent; ++index) {
940 cache_type = entry[index - 1].eax & 0x1f;
941 if (!cache_type)
942 break;
943 do_cpuid_1_ent(&entry[index], function, index);
944 entry[index].flags |=
945 KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
946 ++*nent;
947 }
948 break;
949 }
950 case 0xb: {
951 int index, level_type;
952
953 entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
954 /* read more entries until level_type is zero */
955 for (index = 1; *nent < maxnent; ++index) {
956 level_type = entry[index - 1].ecx & 0xff;
957 if (!level_type)
958 break;
959 do_cpuid_1_ent(&entry[index], function, index);
960 entry[index].flags |=
961 KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
962 ++*nent;
963 }
964 break;
965 }
966 case 0x80000000:
967 entry->eax = min(entry->eax, 0x8000001a);
968 break;
969 case 0x80000001:
970 entry->edx &= kvm_supported_word1_x86_features;
971 entry->ecx &= kvm_supported_word6_x86_features;
972 break;
973 }
974 put_cpu();
975}
976
977static int kvm_vm_ioctl_get_supported_cpuid(struct kvm *kvm,
978 struct kvm_cpuid2 *cpuid,
979 struct kvm_cpuid_entry2 __user *entries)
980{
981 struct kvm_cpuid_entry2 *cpuid_entries;
982 int limit, nent = 0, r = -E2BIG;
983 u32 func;
984
985 if (cpuid->nent < 1)
986 goto out;
987 r = -ENOMEM;
988 cpuid_entries = vmalloc(sizeof(struct kvm_cpuid_entry2) * cpuid->nent);
989 if (!cpuid_entries)
990 goto out;
991
992 do_cpuid_ent(&cpuid_entries[0], 0, 0, &nent, cpuid->nent);
993 limit = cpuid_entries[0].eax;
994 for (func = 1; func <= limit && nent < cpuid->nent; ++func)
995 do_cpuid_ent(&cpuid_entries[nent], func, 0,
996 &nent, cpuid->nent);
997 r = -E2BIG;
998 if (nent >= cpuid->nent)
999 goto out_free;
1000
1001 do_cpuid_ent(&cpuid_entries[nent], 0x80000000, 0, &nent, cpuid->nent);
1002 limit = cpuid_entries[nent - 1].eax;
1003 for (func = 0x80000001; func <= limit && nent < cpuid->nent; ++func)
1004 do_cpuid_ent(&cpuid_entries[nent], func, 0,
1005 &nent, cpuid->nent);
1006 r = -EFAULT;
1007 if (copy_to_user(entries, cpuid_entries,
1008 nent * sizeof(struct kvm_cpuid_entry2)))
1009 goto out_free;
1010 cpuid->nent = nent;
1011 r = 0;
1012
1013out_free:
1014 vfree(cpuid_entries);
1015out:
1016 return r;
1017}
1018
1019static int kvm_vcpu_ioctl_get_lapic(struct kvm_vcpu *vcpu,
1020 struct kvm_lapic_state *s)
1021{
1022 vcpu_load(vcpu);
1023 memcpy(s->regs, vcpu->arch.apic->regs, sizeof *s);
1024 vcpu_put(vcpu);
1025
1026 return 0;
1027}
1028
1029static int kvm_vcpu_ioctl_set_lapic(struct kvm_vcpu *vcpu,
1030 struct kvm_lapic_state *s)
1031{
1032 vcpu_load(vcpu);
1033 memcpy(vcpu->arch.apic->regs, s->regs, sizeof *s);
1034 kvm_apic_post_state_restore(vcpu);
1035 vcpu_put(vcpu);
1036
1037 return 0;
1038}
1039
1040static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
1041 struct kvm_interrupt *irq)
1042{
1043 if (irq->irq < 0 || irq->irq >= 256)
1044 return -EINVAL;
1045 if (irqchip_in_kernel(vcpu->kvm))
1046 return -ENXIO;
1047 vcpu_load(vcpu);
1048
1049 set_bit(irq->irq, vcpu->arch.irq_pending);
1050 set_bit(irq->irq / BITS_PER_LONG, &vcpu->arch.irq_summary);
1051
1052 vcpu_put(vcpu);
1053
1054 return 0;
1055}
1056
1057static int vcpu_ioctl_tpr_access_reporting(struct kvm_vcpu *vcpu,
1058 struct kvm_tpr_access_ctl *tac)
1059{
1060 if (tac->flags)
1061 return -EINVAL;
1062 vcpu->arch.tpr_access_reporting = !!tac->enabled;
1063 return 0;
1064}
1065
1066long kvm_arch_vcpu_ioctl(struct file *filp,
1067 unsigned int ioctl, unsigned long arg)
1068{
1069 struct kvm_vcpu *vcpu = filp->private_data;
1070 void __user *argp = (void __user *)arg;
1071 int r;
1072
1073 switch (ioctl) {
1074 case KVM_GET_LAPIC: {
1075 struct kvm_lapic_state lapic;
1076
1077 memset(&lapic, 0, sizeof lapic);
1078 r = kvm_vcpu_ioctl_get_lapic(vcpu, &lapic);
1079 if (r)
1080 goto out;
1081 r = -EFAULT;
1082 if (copy_to_user(argp, &lapic, sizeof lapic))
1083 goto out;
1084 r = 0;
1085 break;
1086 }
1087 case KVM_SET_LAPIC: {
1088 struct kvm_lapic_state lapic;
1089
1090 r = -EFAULT;
1091 if (copy_from_user(&lapic, argp, sizeof lapic))
1092 goto out;
1093 r = kvm_vcpu_ioctl_set_lapic(vcpu, &lapic);;
1094 if (r)
1095 goto out;
1096 r = 0;
1097 break;
1098 }
1099 case KVM_INTERRUPT: {
1100 struct kvm_interrupt irq;
1101
1102 r = -EFAULT;
1103 if (copy_from_user(&irq, argp, sizeof irq))
1104 goto out;
1105 r = kvm_vcpu_ioctl_interrupt(vcpu, &irq);
1106 if (r)
1107 goto out;
1108 r = 0;
1109 break;
1110 }
1111 case KVM_SET_CPUID: {
1112 struct kvm_cpuid __user *cpuid_arg = argp;
1113 struct kvm_cpuid cpuid;
1114
1115 r = -EFAULT;
1116 if (copy_from_user(&cpuid, cpuid_arg, sizeof cpuid))
1117 goto out;
1118 r = kvm_vcpu_ioctl_set_cpuid(vcpu, &cpuid, cpuid_arg->entries);
1119 if (r)
1120 goto out;
1121 break;
1122 }
1123 case KVM_SET_CPUID2: {
1124 struct kvm_cpuid2 __user *cpuid_arg = argp;
1125 struct kvm_cpuid2 cpuid;
1126
1127 r = -EFAULT;
1128 if (copy_from_user(&cpuid, cpuid_arg, sizeof cpuid))
1129 goto out;
1130 r = kvm_vcpu_ioctl_set_cpuid2(vcpu, &cpuid,
1131 cpuid_arg->entries);
1132 if (r)
1133 goto out;
1134 break;
1135 }
1136 case KVM_GET_CPUID2: {
1137 struct kvm_cpuid2 __user *cpuid_arg = argp;
1138 struct kvm_cpuid2 cpuid;
1139
1140 r = -EFAULT;
1141 if (copy_from_user(&cpuid, cpuid_arg, sizeof cpuid))
1142 goto out;
1143 r = kvm_vcpu_ioctl_get_cpuid2(vcpu, &cpuid,
1144 cpuid_arg->entries);
1145 if (r)
1146 goto out;
1147 r = -EFAULT;
1148 if (copy_to_user(cpuid_arg, &cpuid, sizeof cpuid))
1149 goto out;
1150 r = 0;
1151 break;
1152 }
1153 case KVM_GET_MSRS:
1154 r = msr_io(vcpu, argp, kvm_get_msr, 1);
1155 break;
1156 case KVM_SET_MSRS:
1157 r = msr_io(vcpu, argp, do_set_msr, 0);
1158 break;
1159 case KVM_TPR_ACCESS_REPORTING: {
1160 struct kvm_tpr_access_ctl tac;
1161
1162 r = -EFAULT;
1163 if (copy_from_user(&tac, argp, sizeof tac))
1164 goto out;
1165 r = vcpu_ioctl_tpr_access_reporting(vcpu, &tac);
1166 if (r)
1167 goto out;
1168 r = -EFAULT;
1169 if (copy_to_user(argp, &tac, sizeof tac))
1170 goto out;
1171 r = 0;
1172 break;
1173 };
1174 case KVM_SET_VAPIC_ADDR: {
1175 struct kvm_vapic_addr va;
1176
1177 r = -EINVAL;
1178 if (!irqchip_in_kernel(vcpu->kvm))
1179 goto out;
1180 r = -EFAULT;
1181 if (copy_from_user(&va, argp, sizeof va))
1182 goto out;
1183 r = 0;
1184 kvm_lapic_set_vapic_addr(vcpu, va.vapic_addr);
1185 break;
1186 }
1187 default:
1188 r = -EINVAL;
1189 }
1190out:
1191 return r;
1192}
1193
1194static int kvm_vm_ioctl_set_tss_addr(struct kvm *kvm, unsigned long addr)
1195{
1196 int ret;
1197
1198 if (addr > (unsigned int)(-3 * PAGE_SIZE))
1199 return -1;
1200 ret = kvm_x86_ops->set_tss_addr(kvm, addr);
1201 return ret;
1202}
1203
1204static int kvm_vm_ioctl_set_nr_mmu_pages(struct kvm *kvm,
1205 u32 kvm_nr_mmu_pages)
1206{
1207 if (kvm_nr_mmu_pages < KVM_MIN_ALLOC_MMU_PAGES)
1208 return -EINVAL;
1209
1210 down_write(&current->mm->mmap_sem);
1211
1212 kvm_mmu_change_mmu_pages(kvm, kvm_nr_mmu_pages);
1213 kvm->arch.n_requested_mmu_pages = kvm_nr_mmu_pages;
1214
1215 up_write(&current->mm->mmap_sem);
1216 return 0;
1217}
1218
1219static int kvm_vm_ioctl_get_nr_mmu_pages(struct kvm *kvm)
1220{
1221 return kvm->arch.n_alloc_mmu_pages;
1222}
1223
1224gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn)
1225{
1226 int i;
1227 struct kvm_mem_alias *alias;
1228
1229 for (i = 0; i < kvm->arch.naliases; ++i) {
1230 alias = &kvm->arch.aliases[i];
1231 if (gfn >= alias->base_gfn
1232 && gfn < alias->base_gfn + alias->npages)
1233 return alias->target_gfn + gfn - alias->base_gfn;
1234 }
1235 return gfn;
1236}
1237
1238/*
1239 * Set a new alias region. Aliases map a portion of physical memory into
1240 * another portion. This is useful for memory windows, for example the PC
1241 * VGA region.
1242 */
1243static int kvm_vm_ioctl_set_memory_alias(struct kvm *kvm,
1244 struct kvm_memory_alias *alias)
1245{
1246 int r, n;
1247 struct kvm_mem_alias *p;
1248
1249 r = -EINVAL;
1250 /* General sanity checks */
1251 if (alias->memory_size & (PAGE_SIZE - 1))
1252 goto out;
1253 if (alias->guest_phys_addr & (PAGE_SIZE - 1))
1254 goto out;
1255 if (alias->slot >= KVM_ALIAS_SLOTS)
1256 goto out;
1257 if (alias->guest_phys_addr + alias->memory_size
1258 < alias->guest_phys_addr)
1259 goto out;
1260 if (alias->target_phys_addr + alias->memory_size
1261 < alias->target_phys_addr)
1262 goto out;
1263
1264 down_write(&current->mm->mmap_sem);
1265
1266 p = &kvm->arch.aliases[alias->slot];
1267 p->base_gfn = alias->guest_phys_addr >> PAGE_SHIFT;
1268 p->npages = alias->memory_size >> PAGE_SHIFT;
1269 p->target_gfn = alias->target_phys_addr >> PAGE_SHIFT;
1270
1271 for (n = KVM_ALIAS_SLOTS; n > 0; --n)
1272 if (kvm->arch.aliases[n - 1].npages)
1273 break;
1274 kvm->arch.naliases = n;
1275
1276 kvm_mmu_zap_all(kvm);
1277
1278 up_write(&current->mm->mmap_sem);
1279
1280 return 0;
1281
1282out:
1283 return r;
1284}
1285
1286static int kvm_vm_ioctl_get_irqchip(struct kvm *kvm, struct kvm_irqchip *chip)
1287{
1288 int r;
1289
1290 r = 0;
1291 switch (chip->chip_id) {
1292 case KVM_IRQCHIP_PIC_MASTER:
1293 memcpy(&chip->chip.pic,
1294 &pic_irqchip(kvm)->pics[0],
1295 sizeof(struct kvm_pic_state));
1296 break;
1297 case KVM_IRQCHIP_PIC_SLAVE:
1298 memcpy(&chip->chip.pic,
1299 &pic_irqchip(kvm)->pics[1],
1300 sizeof(struct kvm_pic_state));
1301 break;
1302 case KVM_IRQCHIP_IOAPIC:
1303 memcpy(&chip->chip.ioapic,
1304 ioapic_irqchip(kvm),
1305 sizeof(struct kvm_ioapic_state));
1306 break;
1307 default:
1308 r = -EINVAL;
1309 break;
1310 }
1311 return r;
1312}
1313
1314static int kvm_vm_ioctl_set_irqchip(struct kvm *kvm, struct kvm_irqchip *chip)
1315{
1316 int r;
1317
1318 r = 0;
1319 switch (chip->chip_id) {
1320 case KVM_IRQCHIP_PIC_MASTER:
1321 memcpy(&pic_irqchip(kvm)->pics[0],
1322 &chip->chip.pic,
1323 sizeof(struct kvm_pic_state));
1324 break;
1325 case KVM_IRQCHIP_PIC_SLAVE:
1326 memcpy(&pic_irqchip(kvm)->pics[1],
1327 &chip->chip.pic,
1328 sizeof(struct kvm_pic_state));
1329 break;
1330 case KVM_IRQCHIP_IOAPIC:
1331 memcpy(ioapic_irqchip(kvm),
1332 &chip->chip.ioapic,
1333 sizeof(struct kvm_ioapic_state));
1334 break;
1335 default:
1336 r = -EINVAL;
1337 break;
1338 }
1339 kvm_pic_update_irq(pic_irqchip(kvm));
1340 return r;
1341}
1342
1343/*
1344 * Get (and clear) the dirty memory log for a memory slot.
1345 */
1346int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
1347 struct kvm_dirty_log *log)
1348{
1349 int r;
1350 int n;
1351 struct kvm_memory_slot *memslot;
1352 int is_dirty = 0;
1353
1354 down_write(&current->mm->mmap_sem);
1355
1356 r = kvm_get_dirty_log(kvm, log, &is_dirty);
1357 if (r)
1358 goto out;
1359
1360 /* If nothing is dirty, don't bother messing with page tables. */
1361 if (is_dirty) {
1362 kvm_mmu_slot_remove_write_access(kvm, log->slot);
1363 kvm_flush_remote_tlbs(kvm);
1364 memslot = &kvm->memslots[log->slot];
1365 n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
1366 memset(memslot->dirty_bitmap, 0, n);
1367 }
1368 r = 0;
1369out:
1370 up_write(&current->mm->mmap_sem);
1371 return r;
1372}
1373
1374long kvm_arch_vm_ioctl(struct file *filp,
1375 unsigned int ioctl, unsigned long arg)
1376{
1377 struct kvm *kvm = filp->private_data;
1378 void __user *argp = (void __user *)arg;
1379 int r = -EINVAL;
1380
1381 switch (ioctl) {
1382 case KVM_SET_TSS_ADDR:
1383 r = kvm_vm_ioctl_set_tss_addr(kvm, arg);
1384 if (r < 0)
1385 goto out;
1386 break;
1387 case KVM_SET_MEMORY_REGION: {
1388 struct kvm_memory_region kvm_mem;
1389 struct kvm_userspace_memory_region kvm_userspace_mem;
1390
1391 r = -EFAULT;
1392 if (copy_from_user(&kvm_mem, argp, sizeof kvm_mem))
1393 goto out;
1394 kvm_userspace_mem.slot = kvm_mem.slot;
1395 kvm_userspace_mem.flags = kvm_mem.flags;
1396 kvm_userspace_mem.guest_phys_addr = kvm_mem.guest_phys_addr;
1397 kvm_userspace_mem.memory_size = kvm_mem.memory_size;
1398 r = kvm_vm_ioctl_set_memory_region(kvm, &kvm_userspace_mem, 0);
1399 if (r)
1400 goto out;
1401 break;
1402 }
1403 case KVM_SET_NR_MMU_PAGES:
1404 r = kvm_vm_ioctl_set_nr_mmu_pages(kvm, arg);
1405 if (r)
1406 goto out;
1407 break;
1408 case KVM_GET_NR_MMU_PAGES:
1409 r = kvm_vm_ioctl_get_nr_mmu_pages(kvm);
1410 break;
1411 case KVM_SET_MEMORY_ALIAS: {
1412 struct kvm_memory_alias alias;
1413
1414 r = -EFAULT;
1415 if (copy_from_user(&alias, argp, sizeof alias))
1416 goto out;
1417 r = kvm_vm_ioctl_set_memory_alias(kvm, &alias);
1418 if (r)
1419 goto out;
1420 break;
1421 }
1422 case KVM_CREATE_IRQCHIP:
1423 r = -ENOMEM;
1424 kvm->arch.vpic = kvm_create_pic(kvm);
1425 if (kvm->arch.vpic) {
1426 r = kvm_ioapic_init(kvm);
1427 if (r) {
1428 kfree(kvm->arch.vpic);
1429 kvm->arch.vpic = NULL;
1430 goto out;
1431 }
1432 } else
1433 goto out;
1434 break;
1435 case KVM_IRQ_LINE: {
1436 struct kvm_irq_level irq_event;
1437
1438 r = -EFAULT;
1439 if (copy_from_user(&irq_event, argp, sizeof irq_event))
1440 goto out;
1441 if (irqchip_in_kernel(kvm)) {
1442 mutex_lock(&kvm->lock);
1443 if (irq_event.irq < 16)
1444 kvm_pic_set_irq(pic_irqchip(kvm),
1445 irq_event.irq,
1446 irq_event.level);
1447 kvm_ioapic_set_irq(kvm->arch.vioapic,
1448 irq_event.irq,
1449 irq_event.level);
1450 mutex_unlock(&kvm->lock);
1451 r = 0;
1452 }
1453 break;
1454 }
1455 case KVM_GET_IRQCHIP: {
1456 /* 0: PIC master, 1: PIC slave, 2: IOAPIC */
1457 struct kvm_irqchip chip;
1458
1459 r = -EFAULT;
1460 if (copy_from_user(&chip, argp, sizeof chip))
1461 goto out;
1462 r = -ENXIO;
1463 if (!irqchip_in_kernel(kvm))
1464 goto out;
1465 r = kvm_vm_ioctl_get_irqchip(kvm, &chip);
1466 if (r)
1467 goto out;
1468 r = -EFAULT;
1469 if (copy_to_user(argp, &chip, sizeof chip))
1470 goto out;
1471 r = 0;
1472 break;
1473 }
1474 case KVM_SET_IRQCHIP: {
1475 /* 0: PIC master, 1: PIC slave, 2: IOAPIC */
1476 struct kvm_irqchip chip;
1477
1478 r = -EFAULT;
1479 if (copy_from_user(&chip, argp, sizeof chip))
1480 goto out;
1481 r = -ENXIO;
1482 if (!irqchip_in_kernel(kvm))
1483 goto out;
1484 r = kvm_vm_ioctl_set_irqchip(kvm, &chip);
1485 if (r)
1486 goto out;
1487 r = 0;
1488 break;
1489 }
1490 case KVM_GET_SUPPORTED_CPUID: {
1491 struct kvm_cpuid2 __user *cpuid_arg = argp;
1492 struct kvm_cpuid2 cpuid;
1493
1494 r = -EFAULT;
1495 if (copy_from_user(&cpuid, cpuid_arg, sizeof cpuid))
1496 goto out;
1497 r = kvm_vm_ioctl_get_supported_cpuid(kvm, &cpuid,
1498 cpuid_arg->entries);
1499 if (r)
1500 goto out;
1501
1502 r = -EFAULT;
1503 if (copy_to_user(cpuid_arg, &cpuid, sizeof cpuid))
1504 goto out;
1505 r = 0;
1506 break;
1507 }
1508 default:
1509 ;
1510 }
1511out:
1512 return r;
1513}
1514
1515static void kvm_init_msr_list(void)
1516{
1517 u32 dummy[2];
1518 unsigned i, j;
1519
1520 for (i = j = 0; i < ARRAY_SIZE(msrs_to_save); i++) {
1521 if (rdmsr_safe(msrs_to_save[i], &dummy[0], &dummy[1]) < 0)
1522 continue;
1523 if (j < i)
1524 msrs_to_save[j] = msrs_to_save[i];
1525 j++;
1526 }
1527 num_msrs_to_save = j;
1528}
1529
1530/*
1531 * Only apic need an MMIO device hook, so shortcut now..
1532 */
1533static struct kvm_io_device *vcpu_find_pervcpu_dev(struct kvm_vcpu *vcpu,
1534 gpa_t addr)
1535{
1536 struct kvm_io_device *dev;
1537
1538 if (vcpu->arch.apic) {
1539 dev = &vcpu->arch.apic->dev;
1540 if (dev->in_range(dev, addr))
1541 return dev;
1542 }
1543 return NULL;
1544}
1545
1546
1547static struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu,
1548 gpa_t addr)
1549{
1550 struct kvm_io_device *dev;
1551
1552 dev = vcpu_find_pervcpu_dev(vcpu, addr);
1553 if (dev == NULL)
1554 dev = kvm_io_bus_find_dev(&vcpu->kvm->mmio_bus, addr);
1555 return dev;
1556}
1557
1558int emulator_read_std(unsigned long addr,
1559 void *val,
1560 unsigned int bytes,
1561 struct kvm_vcpu *vcpu)
1562{
1563 void *data = val;
1564 int r = X86EMUL_CONTINUE;
1565
1566 down_read(&current->mm->mmap_sem);
1567 while (bytes) {
1568 gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
1569 unsigned offset = addr & (PAGE_SIZE-1);
1570 unsigned tocopy = min(bytes, (unsigned)PAGE_SIZE - offset);
1571 int ret;
1572
1573 if (gpa == UNMAPPED_GVA) {
1574 r = X86EMUL_PROPAGATE_FAULT;
1575 goto out;
1576 }
1577 ret = kvm_read_guest(vcpu->kvm, gpa, data, tocopy);
1578 if (ret < 0) {
1579 r = X86EMUL_UNHANDLEABLE;
1580 goto out;
1581 }
1582
1583 bytes -= tocopy;
1584 data += tocopy;
1585 addr += tocopy;
1586 }
1587out:
1588 up_read(&current->mm->mmap_sem);
1589 return r;
1590}
1591EXPORT_SYMBOL_GPL(emulator_read_std);
1592
1593static int emulator_read_emulated(unsigned long addr,
1594 void *val,
1595 unsigned int bytes,
1596 struct kvm_vcpu *vcpu)
1597{
1598 struct kvm_io_device *mmio_dev;
1599 gpa_t gpa;
1600
1601 if (vcpu->mmio_read_completed) {
1602 memcpy(val, vcpu->mmio_data, bytes);
1603 vcpu->mmio_read_completed = 0;
1604 return X86EMUL_CONTINUE;
1605 }
1606
1607 down_read(&current->mm->mmap_sem);
1608 gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
1609 up_read(&current->mm->mmap_sem);
1610
1611 /* For APIC access vmexit */
1612 if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE)
1613 goto mmio;
1614
1615 if (emulator_read_std(addr, val, bytes, vcpu)
1616 == X86EMUL_CONTINUE)
1617 return X86EMUL_CONTINUE;
1618 if (gpa == UNMAPPED_GVA)
1619 return X86EMUL_PROPAGATE_FAULT;
1620
1621mmio:
1622 /*
1623 * Is this MMIO handled locally?
1624 */
1625 mutex_lock(&vcpu->kvm->lock);
1626 mmio_dev = vcpu_find_mmio_dev(vcpu, gpa);
1627 if (mmio_dev) {
1628 kvm_iodevice_read(mmio_dev, gpa, bytes, val);
1629 mutex_unlock(&vcpu->kvm->lock);
1630 return X86EMUL_CONTINUE;
1631 }
1632 mutex_unlock(&vcpu->kvm->lock);
1633
1634 vcpu->mmio_needed = 1;
1635 vcpu->mmio_phys_addr = gpa;
1636 vcpu->mmio_size = bytes;
1637 vcpu->mmio_is_write = 0;
1638
1639 return X86EMUL_UNHANDLEABLE;
1640}
1641
1642static int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
1643 const void *val, int bytes)
1644{
1645 int ret;
1646
1647 down_read(&current->mm->mmap_sem);
1648 ret = kvm_write_guest(vcpu->kvm, gpa, val, bytes);
1649 if (ret < 0) {
1650 up_read(&current->mm->mmap_sem);
1651 return 0;
1652 }
1653 kvm_mmu_pte_write(vcpu, gpa, val, bytes);
1654 up_read(&current->mm->mmap_sem);
1655 return 1;
1656}
1657
1658static int emulator_write_emulated_onepage(unsigned long addr,
1659 const void *val,
1660 unsigned int bytes,
1661 struct kvm_vcpu *vcpu)
1662{
1663 struct kvm_io_device *mmio_dev;
1664 gpa_t gpa;
1665
1666 down_read(&current->mm->mmap_sem);
1667 gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
1668 up_read(&current->mm->mmap_sem);
1669
1670 if (gpa == UNMAPPED_GVA) {
1671 kvm_inject_page_fault(vcpu, addr, 2);
1672 return X86EMUL_PROPAGATE_FAULT;
1673 }
1674
1675 /* For APIC access vmexit */
1676 if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE)
1677 goto mmio;
1678
1679 if (emulator_write_phys(vcpu, gpa, val, bytes))
1680 return X86EMUL_CONTINUE;
1681
1682mmio:
1683 /*
1684 * Is this MMIO handled locally?
1685 */
1686 mutex_lock(&vcpu->kvm->lock);
1687 mmio_dev = vcpu_find_mmio_dev(vcpu, gpa);
1688 if (mmio_dev) {
1689 kvm_iodevice_write(mmio_dev, gpa, bytes, val);
1690 mutex_unlock(&vcpu->kvm->lock);
1691 return X86EMUL_CONTINUE;
1692 }
1693 mutex_unlock(&vcpu->kvm->lock);
1694
1695 vcpu->mmio_needed = 1;
1696 vcpu->mmio_phys_addr = gpa;
1697 vcpu->mmio_size = bytes;
1698 vcpu->mmio_is_write = 1;
1699 memcpy(vcpu->mmio_data, val, bytes);
1700
1701 return X86EMUL_CONTINUE;
1702}
1703
1704int emulator_write_emulated(unsigned long addr,
1705 const void *val,
1706 unsigned int bytes,
1707 struct kvm_vcpu *vcpu)
1708{
1709 /* Crossing a page boundary? */
1710 if (((addr + bytes - 1) ^ addr) & PAGE_MASK) {
1711 int rc, now;
1712
1713 now = -addr & ~PAGE_MASK;
1714 rc = emulator_write_emulated_onepage(addr, val, now, vcpu);
1715 if (rc != X86EMUL_CONTINUE)
1716 return rc;
1717 addr += now;
1718 val += now;
1719 bytes -= now;
1720 }
1721 return emulator_write_emulated_onepage(addr, val, bytes, vcpu);
1722}
1723EXPORT_SYMBOL_GPL(emulator_write_emulated);
1724
1725static int emulator_cmpxchg_emulated(unsigned long addr,
1726 const void *old,
1727 const void *new,
1728 unsigned int bytes,
1729 struct kvm_vcpu *vcpu)
1730{
1731 static int reported;
1732
1733 if (!reported) {
1734 reported = 1;
1735 printk(KERN_WARNING "kvm: emulating exchange as write\n");
1736 }
1737#ifndef CONFIG_X86_64
1738 /* guests cmpxchg8b have to be emulated atomically */
1739 if (bytes == 8) {
1740 gpa_t gpa;
1741 struct page *page;
1742 char *addr;
1743 u64 val;
1744
1745 down_read(&current->mm->mmap_sem);
1746 gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
1747
1748 if (gpa == UNMAPPED_GVA ||
1749 (gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE)
1750 goto emul_write;
1751
1752 if (((gpa + bytes - 1) & PAGE_MASK) != (gpa & PAGE_MASK))
1753 goto emul_write;
1754
1755 val = *(u64 *)new;
1756 page = gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT);
1757 addr = kmap_atomic(page, KM_USER0);
1758 set_64bit((u64 *)(addr + offset_in_page(gpa)), val);
1759 kunmap_atomic(addr, KM_USER0);
1760 kvm_release_page_dirty(page);
1761 emul_write:
1762 up_read(&current->mm->mmap_sem);
1763 }
1764#endif
1765
1766 return emulator_write_emulated(addr, new, bytes, vcpu);
1767}
1768
1769static unsigned long get_segment_base(struct kvm_vcpu *vcpu, int seg)
1770{
1771 return kvm_x86_ops->get_segment_base(vcpu, seg);
1772}
1773
1774int emulate_invlpg(struct kvm_vcpu *vcpu, gva_t address)
1775{
1776 return X86EMUL_CONTINUE;
1777}
1778
1779int emulate_clts(struct kvm_vcpu *vcpu)
1780{
1781 kvm_x86_ops->set_cr0(vcpu, vcpu->arch.cr0 & ~X86_CR0_TS);
1782 return X86EMUL_CONTINUE;
1783}
1784
1785int emulator_get_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long *dest)
1786{
1787 struct kvm_vcpu *vcpu = ctxt->vcpu;
1788
1789 switch (dr) {
1790 case 0 ... 3:
1791 *dest = kvm_x86_ops->get_dr(vcpu, dr);
1792 return X86EMUL_CONTINUE;
1793 default:
1794 pr_unimpl(vcpu, "%s: unexpected dr %u\n", __FUNCTION__, dr);
1795 return X86EMUL_UNHANDLEABLE;
1796 }
1797}
1798
1799int emulator_set_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long value)
1800{
1801 unsigned long mask = (ctxt->mode == X86EMUL_MODE_PROT64) ? ~0ULL : ~0U;
1802 int exception;
1803
1804 kvm_x86_ops->set_dr(ctxt->vcpu, dr, value & mask, &exception);
1805 if (exception) {
1806 /* FIXME: better handling */
1807 return X86EMUL_UNHANDLEABLE;
1808 }
1809 return X86EMUL_CONTINUE;
1810}
1811
1812void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context)
1813{
1814 static int reported;
1815 u8 opcodes[4];
1816 unsigned long rip = vcpu->arch.rip;
1817 unsigned long rip_linear;
1818
1819 rip_linear = rip + get_segment_base(vcpu, VCPU_SREG_CS);
1820
1821 if (reported)
1822 return;
1823
1824 emulator_read_std(rip_linear, (void *)opcodes, 4, vcpu);
1825
1826 printk(KERN_ERR "emulation failed (%s) rip %lx %02x %02x %02x %02x\n",
1827 context, rip, opcodes[0], opcodes[1], opcodes[2], opcodes[3]);
1828 reported = 1;
1829}
1830EXPORT_SYMBOL_GPL(kvm_report_emulation_failure);
1831
1832struct x86_emulate_ops emulate_ops = {
1833 .read_std = emulator_read_std,
1834 .read_emulated = emulator_read_emulated,
1835 .write_emulated = emulator_write_emulated,
1836 .cmpxchg_emulated = emulator_cmpxchg_emulated,
1837};
1838
1839int emulate_instruction(struct kvm_vcpu *vcpu,
1840 struct kvm_run *run,
1841 unsigned long cr2,
1842 u16 error_code,
1843 int emulation_type)
1844{
1845 int r;
1846 struct decode_cache *c;
1847
1848 vcpu->arch.mmio_fault_cr2 = cr2;
1849 kvm_x86_ops->cache_regs(vcpu);
1850
1851 vcpu->mmio_is_write = 0;
1852 vcpu->arch.pio.string = 0;
1853
1854 if (!(emulation_type & EMULTYPE_NO_DECODE)) {
1855 int cs_db, cs_l;
1856 kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
1857
1858 vcpu->arch.emulate_ctxt.vcpu = vcpu;
1859 vcpu->arch.emulate_ctxt.eflags = kvm_x86_ops->get_rflags(vcpu);
1860 vcpu->arch.emulate_ctxt.mode =
1861 (vcpu->arch.emulate_ctxt.eflags & X86_EFLAGS_VM)
1862 ? X86EMUL_MODE_REAL : cs_l
1863 ? X86EMUL_MODE_PROT64 : cs_db
1864 ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16;
1865
1866 if (vcpu->arch.emulate_ctxt.mode == X86EMUL_MODE_PROT64) {
1867 vcpu->arch.emulate_ctxt.cs_base = 0;
1868 vcpu->arch.emulate_ctxt.ds_base = 0;
1869 vcpu->arch.emulate_ctxt.es_base = 0;
1870 vcpu->arch.emulate_ctxt.ss_base = 0;
1871 } else {
1872 vcpu->arch.emulate_ctxt.cs_base =
1873 get_segment_base(vcpu, VCPU_SREG_CS);
1874 vcpu->arch.emulate_ctxt.ds_base =
1875 get_segment_base(vcpu, VCPU_SREG_DS);
1876 vcpu->arch.emulate_ctxt.es_base =
1877 get_segment_base(vcpu, VCPU_SREG_ES);
1878 vcpu->arch.emulate_ctxt.ss_base =
1879 get_segment_base(vcpu, VCPU_SREG_SS);
1880 }
1881
1882 vcpu->arch.emulate_ctxt.gs_base =
1883 get_segment_base(vcpu, VCPU_SREG_GS);
1884 vcpu->arch.emulate_ctxt.fs_base =
1885 get_segment_base(vcpu, VCPU_SREG_FS);
1886
1887 r = x86_decode_insn(&vcpu->arch.emulate_ctxt, &emulate_ops);
1888
1889 /* Reject the instructions other than VMCALL/VMMCALL when
1890 * try to emulate invalid opcode */
1891 c = &vcpu->arch.emulate_ctxt.decode;
1892 if ((emulation_type & EMULTYPE_TRAP_UD) &&
1893 (!(c->twobyte && c->b == 0x01 &&
1894 (c->modrm_reg == 0 || c->modrm_reg == 3) &&
1895 c->modrm_mod == 3 && c->modrm_rm == 1)))
1896 return EMULATE_FAIL;
1897
1898 ++vcpu->stat.insn_emulation;
1899 if (r) {
1900 ++vcpu->stat.insn_emulation_fail;
1901 if (kvm_mmu_unprotect_page_virt(vcpu, cr2))
1902 return EMULATE_DONE;
1903 return EMULATE_FAIL;
1904 }
1905 }
1906
1907 r = x86_emulate_insn(&vcpu->arch.emulate_ctxt, &emulate_ops);
1908
1909 if (vcpu->arch.pio.string)
1910 return EMULATE_DO_MMIO;
1911
1912 if ((r || vcpu->mmio_is_write) && run) {
1913 run->exit_reason = KVM_EXIT_MMIO;
1914 run->mmio.phys_addr = vcpu->mmio_phys_addr;
1915 memcpy(run->mmio.data, vcpu->mmio_data, 8);
1916 run->mmio.len = vcpu->mmio_size;
1917 run->mmio.is_write = vcpu->mmio_is_write;
1918 }
1919
1920 if (r) {
1921 if (kvm_mmu_unprotect_page_virt(vcpu, cr2))
1922 return EMULATE_DONE;
1923 if (!vcpu->mmio_needed) {
1924 kvm_report_emulation_failure(vcpu, "mmio");
1925 return EMULATE_FAIL;
1926 }
1927 return EMULATE_DO_MMIO;
1928 }
1929
1930 kvm_x86_ops->decache_regs(vcpu);
1931 kvm_x86_ops->set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags);
1932
1933 if (vcpu->mmio_is_write) {
1934 vcpu->mmio_needed = 0;
1935 return EMULATE_DO_MMIO;
1936 }
1937
1938 return EMULATE_DONE;
1939}
1940EXPORT_SYMBOL_GPL(emulate_instruction);
1941
1942static void free_pio_guest_pages(struct kvm_vcpu *vcpu)
1943{
1944 int i;
1945
1946 for (i = 0; i < ARRAY_SIZE(vcpu->arch.pio.guest_pages); ++i)
1947 if (vcpu->arch.pio.guest_pages[i]) {
1948 kvm_release_page_dirty(vcpu->arch.pio.guest_pages[i]);
1949 vcpu->arch.pio.guest_pages[i] = NULL;
1950 }
1951}
1952
1953static int pio_copy_data(struct kvm_vcpu *vcpu)
1954{
1955 void *p = vcpu->arch.pio_data;
1956 void *q;
1957 unsigned bytes;
1958 int nr_pages = vcpu->arch.pio.guest_pages[1] ? 2 : 1;
1959
1960 q = vmap(vcpu->arch.pio.guest_pages, nr_pages, VM_READ|VM_WRITE,
1961 PAGE_KERNEL);
1962 if (!q) {
1963 free_pio_guest_pages(vcpu);
1964 return -ENOMEM;
1965 }
1966 q += vcpu->arch.pio.guest_page_offset;
1967 bytes = vcpu->arch.pio.size * vcpu->arch.pio.cur_count;
1968 if (vcpu->arch.pio.in)
1969 memcpy(q, p, bytes);
1970 else
1971 memcpy(p, q, bytes);
1972 q -= vcpu->arch.pio.guest_page_offset;
1973 vunmap(q);
1974 free_pio_guest_pages(vcpu);
1975 return 0;
1976}
1977
1978int complete_pio(struct kvm_vcpu *vcpu)
1979{
1980 struct kvm_pio_request *io = &vcpu->arch.pio;
1981 long delta;
1982 int r;
1983
1984 kvm_x86_ops->cache_regs(vcpu);
1985
1986 if (!io->string) {
1987 if (io->in)
1988 memcpy(&vcpu->arch.regs[VCPU_REGS_RAX], vcpu->arch.pio_data,
1989 io->size);
1990 } else {
1991 if (io->in) {
1992 r = pio_copy_data(vcpu);
1993 if (r) {
1994 kvm_x86_ops->cache_regs(vcpu);
1995 return r;
1996 }
1997 }
1998
1999 delta = 1;
2000 if (io->rep) {
2001 delta *= io->cur_count;
2002 /*
2003 * The size of the register should really depend on
2004 * current address size.
2005 */
2006 vcpu->arch.regs[VCPU_REGS_RCX] -= delta;
2007 }
2008 if (io->down)
2009 delta = -delta;
2010 delta *= io->size;
2011 if (io->in)
2012 vcpu->arch.regs[VCPU_REGS_RDI] += delta;
2013 else
2014 vcpu->arch.regs[VCPU_REGS_RSI] += delta;
2015 }
2016
2017 kvm_x86_ops->decache_regs(vcpu);
2018
2019 io->count -= io->cur_count;
2020 io->cur_count = 0;
2021
2022 return 0;
2023}
2024
2025static void kernel_pio(struct kvm_io_device *pio_dev,
2026 struct kvm_vcpu *vcpu,
2027 void *pd)
2028{
2029 /* TODO: String I/O for in kernel device */
2030
2031 mutex_lock(&vcpu->kvm->lock);
2032 if (vcpu->arch.pio.in)
2033 kvm_iodevice_read(pio_dev, vcpu->arch.pio.port,
2034 vcpu->arch.pio.size,
2035 pd);
2036 else
2037 kvm_iodevice_write(pio_dev, vcpu->arch.pio.port,
2038 vcpu->arch.pio.size,
2039 pd);
2040 mutex_unlock(&vcpu->kvm->lock);
2041}
2042
2043static void pio_string_write(struct kvm_io_device *pio_dev,
2044 struct kvm_vcpu *vcpu)
2045{
2046 struct kvm_pio_request *io = &vcpu->arch.pio;
2047 void *pd = vcpu->arch.pio_data;
2048 int i;
2049
2050 mutex_lock(&vcpu->kvm->lock);
2051 for (i = 0; i < io->cur_count; i++) {
2052 kvm_iodevice_write(pio_dev, io->port,
2053 io->size,
2054 pd);
2055 pd += io->size;
2056 }
2057 mutex_unlock(&vcpu->kvm->lock);
2058}
2059
2060static struct kvm_io_device *vcpu_find_pio_dev(struct kvm_vcpu *vcpu,
2061 gpa_t addr)
2062{
2063 return kvm_io_bus_find_dev(&vcpu->kvm->pio_bus, addr);
2064}
2065
2066int kvm_emulate_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
2067 int size, unsigned port)
2068{
2069 struct kvm_io_device *pio_dev;
2070
2071 vcpu->run->exit_reason = KVM_EXIT_IO;
2072 vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT;
2073 vcpu->run->io.size = vcpu->arch.pio.size = size;
2074 vcpu->run->io.data_offset = KVM_PIO_PAGE_OFFSET * PAGE_SIZE;
2075 vcpu->run->io.count = vcpu->arch.pio.count = vcpu->arch.pio.cur_count = 1;
2076 vcpu->run->io.port = vcpu->arch.pio.port = port;
2077 vcpu->arch.pio.in = in;
2078 vcpu->arch.pio.string = 0;
2079 vcpu->arch.pio.down = 0;
2080 vcpu->arch.pio.guest_page_offset = 0;
2081 vcpu->arch.pio.rep = 0;
2082
2083 kvm_x86_ops->cache_regs(vcpu);
2084 memcpy(vcpu->arch.pio_data, &vcpu->arch.regs[VCPU_REGS_RAX], 4);
2085 kvm_x86_ops->decache_regs(vcpu);
2086
2087 kvm_x86_ops->skip_emulated_instruction(vcpu);
2088
2089 pio_dev = vcpu_find_pio_dev(vcpu, port);
2090 if (pio_dev) {
2091 kernel_pio(pio_dev, vcpu, vcpu->arch.pio_data);
2092 complete_pio(vcpu);
2093 return 1;
2094 }
2095 return 0;
2096}
2097EXPORT_SYMBOL_GPL(kvm_emulate_pio);
2098
2099int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
2100 int size, unsigned long count, int down,
2101 gva_t address, int rep, unsigned port)
2102{
2103 unsigned now, in_page;
2104 int i, ret = 0;
2105 int nr_pages = 1;
2106 struct page *page;
2107 struct kvm_io_device *pio_dev;
2108
2109 vcpu->run->exit_reason = KVM_EXIT_IO;
2110 vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT;
2111 vcpu->run->io.size = vcpu->arch.pio.size = size;
2112 vcpu->run->io.data_offset = KVM_PIO_PAGE_OFFSET * PAGE_SIZE;
2113 vcpu->run->io.count = vcpu->arch.pio.count = vcpu->arch.pio.cur_count = count;
2114 vcpu->run->io.port = vcpu->arch.pio.port = port;
2115 vcpu->arch.pio.in = in;
2116 vcpu->arch.pio.string = 1;
2117 vcpu->arch.pio.down = down;
2118 vcpu->arch.pio.guest_page_offset = offset_in_page(address);
2119 vcpu->arch.pio.rep = rep;
2120
2121 if (!count) {
2122 kvm_x86_ops->skip_emulated_instruction(vcpu);
2123 return 1;
2124 }
2125
2126 if (!down)
2127 in_page = PAGE_SIZE - offset_in_page(address);
2128 else
2129 in_page = offset_in_page(address) + size;
2130 now = min(count, (unsigned long)in_page / size);
2131 if (!now) {
2132 /*
2133 * String I/O straddles page boundary. Pin two guest pages
2134 * so that we satisfy atomicity constraints. Do just one
2135 * transaction to avoid complexity.
2136 */
2137 nr_pages = 2;
2138 now = 1;
2139 }
2140 if (down) {
2141 /*
2142 * String I/O in reverse. Yuck. Kill the guest, fix later.
2143 */
2144 pr_unimpl(vcpu, "guest string pio down\n");
2145 kvm_inject_gp(vcpu, 0);
2146 return 1;
2147 }
2148 vcpu->run->io.count = now;
2149 vcpu->arch.pio.cur_count = now;
2150
2151 if (vcpu->arch.pio.cur_count == vcpu->arch.pio.count)
2152 kvm_x86_ops->skip_emulated_instruction(vcpu);
2153
2154 for (i = 0; i < nr_pages; ++i) {
2155 down_read(&current->mm->mmap_sem);
2156 page = gva_to_page(vcpu, address + i * PAGE_SIZE);
2157 vcpu->arch.pio.guest_pages[i] = page;
2158 up_read(&current->mm->mmap_sem);
2159 if (!page) {
2160 kvm_inject_gp(vcpu, 0);
2161 free_pio_guest_pages(vcpu);
2162 return 1;
2163 }
2164 }
2165
2166 pio_dev = vcpu_find_pio_dev(vcpu, port);
2167 if (!vcpu->arch.pio.in) {
2168 /* string PIO write */
2169 ret = pio_copy_data(vcpu);
2170 if (ret >= 0 && pio_dev) {
2171 pio_string_write(pio_dev, vcpu);
2172 complete_pio(vcpu);
2173 if (vcpu->arch.pio.count == 0)
2174 ret = 1;
2175 }
2176 } else if (pio_dev)
2177 pr_unimpl(vcpu, "no string pio read support yet, "
2178 "port %x size %d count %ld\n",
2179 port, size, count);
2180
2181 return ret;
2182}
2183EXPORT_SYMBOL_GPL(kvm_emulate_pio_string);
2184
2185int kvm_arch_init(void *opaque)
2186{
2187 int r;
2188 struct kvm_x86_ops *ops = (struct kvm_x86_ops *)opaque;
2189
2190 if (kvm_x86_ops) {
2191 printk(KERN_ERR "kvm: already loaded the other module\n");
2192 r = -EEXIST;
2193 goto out;
2194 }
2195
2196 if (!ops->cpu_has_kvm_support()) {
2197 printk(KERN_ERR "kvm: no hardware support\n");
2198 r = -EOPNOTSUPP;
2199 goto out;
2200 }
2201 if (ops->disabled_by_bios()) {
2202 printk(KERN_ERR "kvm: disabled by bios\n");
2203 r = -EOPNOTSUPP;
2204 goto out;
2205 }
2206
2207 r = kvm_mmu_module_init();
2208 if (r)
2209 goto out;
2210
2211 kvm_init_msr_list();
2212
2213 kvm_x86_ops = ops;
2214 kvm_mmu_set_nonpresent_ptes(0ull, 0ull);
2215 return 0;
2216
2217out:
2218 return r;
2219}
2220
2221void kvm_arch_exit(void)
2222{
2223 kvm_x86_ops = NULL;
2224 kvm_mmu_module_exit();
2225}
2226
2227int kvm_emulate_halt(struct kvm_vcpu *vcpu)
2228{
2229 ++vcpu->stat.halt_exits;
2230 if (irqchip_in_kernel(vcpu->kvm)) {
2231 vcpu->arch.mp_state = VCPU_MP_STATE_HALTED;
2232 kvm_vcpu_block(vcpu);
2233 if (vcpu->arch.mp_state != VCPU_MP_STATE_RUNNABLE)
2234 return -EINTR;
2235 return 1;
2236 } else {
2237 vcpu->run->exit_reason = KVM_EXIT_HLT;
2238 return 0;
2239 }
2240}
2241EXPORT_SYMBOL_GPL(kvm_emulate_halt);
2242
2243int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
2244{
2245 unsigned long nr, a0, a1, a2, a3, ret;
2246
2247 kvm_x86_ops->cache_regs(vcpu);
2248
2249 nr = vcpu->arch.regs[VCPU_REGS_RAX];
2250 a0 = vcpu->arch.regs[VCPU_REGS_RBX];
2251 a1 = vcpu->arch.regs[VCPU_REGS_RCX];
2252 a2 = vcpu->arch.regs[VCPU_REGS_RDX];
2253 a3 = vcpu->arch.regs[VCPU_REGS_RSI];
2254
2255 if (!is_long_mode(vcpu)) {
2256 nr &= 0xFFFFFFFF;
2257 a0 &= 0xFFFFFFFF;
2258 a1 &= 0xFFFFFFFF;
2259 a2 &= 0xFFFFFFFF;
2260 a3 &= 0xFFFFFFFF;
2261 }
2262
2263 switch (nr) {
2264 case KVM_HC_VAPIC_POLL_IRQ:
2265 ret = 0;
2266 break;
2267 default:
2268 ret = -KVM_ENOSYS;
2269 break;
2270 }
2271 vcpu->arch.regs[VCPU_REGS_RAX] = ret;
2272 kvm_x86_ops->decache_regs(vcpu);
2273 return 0;
2274}
2275EXPORT_SYMBOL_GPL(kvm_emulate_hypercall);
2276
2277int kvm_fix_hypercall(struct kvm_vcpu *vcpu)
2278{
2279 char instruction[3];
2280 int ret = 0;
2281
2282
2283 /*
2284 * Blow out the MMU to ensure that no other VCPU has an active mapping
2285 * to ensure that the updated hypercall appears atomically across all
2286 * VCPUs.
2287 */
2288 kvm_mmu_zap_all(vcpu->kvm);
2289
2290 kvm_x86_ops->cache_regs(vcpu);
2291 kvm_x86_ops->patch_hypercall(vcpu, instruction);
2292 if (emulator_write_emulated(vcpu->arch.rip, instruction, 3, vcpu)
2293 != X86EMUL_CONTINUE)
2294 ret = -EFAULT;
2295
2296 return ret;
2297}
2298
2299static u64 mk_cr_64(u64 curr_cr, u32 new_val)
2300{
2301 return (curr_cr & ~((1ULL << 32) - 1)) | new_val;
2302}
2303
2304void realmode_lgdt(struct kvm_vcpu *vcpu, u16 limit, unsigned long base)
2305{
2306 struct descriptor_table dt = { limit, base };
2307
2308 kvm_x86_ops->set_gdt(vcpu, &dt);
2309}
2310
2311void realmode_lidt(struct kvm_vcpu *vcpu, u16 limit, unsigned long base)
2312{
2313 struct descriptor_table dt = { limit, base };
2314
2315 kvm_x86_ops->set_idt(vcpu, &dt);
2316}
2317
2318void realmode_lmsw(struct kvm_vcpu *vcpu, unsigned long msw,
2319 unsigned long *rflags)
2320{
2321 lmsw(vcpu, msw);
2322 *rflags = kvm_x86_ops->get_rflags(vcpu);
2323}
2324
2325unsigned long realmode_get_cr(struct kvm_vcpu *vcpu, int cr)
2326{
2327 kvm_x86_ops->decache_cr4_guest_bits(vcpu);
2328 switch (cr) {
2329 case 0:
2330 return vcpu->arch.cr0;
2331 case 2:
2332 return vcpu->arch.cr2;
2333 case 3:
2334 return vcpu->arch.cr3;
2335 case 4:
2336 return vcpu->arch.cr4;
2337 case 8:
2338 return get_cr8(vcpu);
2339 default:
2340 vcpu_printf(vcpu, "%s: unexpected cr %u\n", __FUNCTION__, cr);
2341 return 0;
2342 }
2343}
2344
2345void realmode_set_cr(struct kvm_vcpu *vcpu, int cr, unsigned long val,
2346 unsigned long *rflags)
2347{
2348 switch (cr) {
2349 case 0:
2350 set_cr0(vcpu, mk_cr_64(vcpu->arch.cr0, val));
2351 *rflags = kvm_x86_ops->get_rflags(vcpu);
2352 break;
2353 case 2:
2354 vcpu->arch.cr2 = val;
2355 break;
2356 case 3:
2357 set_cr3(vcpu, val);
2358 break;
2359 case 4:
2360 set_cr4(vcpu, mk_cr_64(vcpu->arch.cr4, val));
2361 break;
2362 case 8:
2363 set_cr8(vcpu, val & 0xfUL);
2364 break;
2365 default:
2366 vcpu_printf(vcpu, "%s: unexpected cr %u\n", __FUNCTION__, cr);
2367 }
2368}
2369
2370static int move_to_next_stateful_cpuid_entry(struct kvm_vcpu *vcpu, int i)
2371{
2372 struct kvm_cpuid_entry2 *e = &vcpu->arch.cpuid_entries[i];
2373 int j, nent = vcpu->arch.cpuid_nent;
2374
2375 e->flags &= ~KVM_CPUID_FLAG_STATE_READ_NEXT;
2376 /* when no next entry is found, the current entry[i] is reselected */
2377 for (j = i + 1; j == i; j = (j + 1) % nent) {
2378 struct kvm_cpuid_entry2 *ej = &vcpu->arch.cpuid_entries[j];
2379 if (ej->function == e->function) {
2380 ej->flags |= KVM_CPUID_FLAG_STATE_READ_NEXT;
2381 return j;
2382 }
2383 }
2384 return 0; /* silence gcc, even though control never reaches here */
2385}
2386
2387/* find an entry with matching function, matching index (if needed), and that
2388 * should be read next (if it's stateful) */
2389static int is_matching_cpuid_entry(struct kvm_cpuid_entry2 *e,
2390 u32 function, u32 index)
2391{
2392 if (e->function != function)
2393 return 0;
2394 if ((e->flags & KVM_CPUID_FLAG_SIGNIFCANT_INDEX) && e->index != index)
2395 return 0;
2396 if ((e->flags & KVM_CPUID_FLAG_STATEFUL_FUNC) &&
2397 !(e->flags & KVM_CPUID_FLAG_STATE_READ_NEXT))
2398 return 0;
2399 return 1;
2400}
2401
2402void kvm_emulate_cpuid(struct kvm_vcpu *vcpu)
2403{
2404 int i;
2405 u32 function, index;
2406 struct kvm_cpuid_entry2 *e, *best;
2407
2408 kvm_x86_ops->cache_regs(vcpu);
2409 function = vcpu->arch.regs[VCPU_REGS_RAX];
2410 index = vcpu->arch.regs[VCPU_REGS_RCX];
2411 vcpu->arch.regs[VCPU_REGS_RAX] = 0;
2412 vcpu->arch.regs[VCPU_REGS_RBX] = 0;
2413 vcpu->arch.regs[VCPU_REGS_RCX] = 0;
2414 vcpu->arch.regs[VCPU_REGS_RDX] = 0;
2415 best = NULL;
2416 for (i = 0; i < vcpu->arch.cpuid_nent; ++i) {
2417 e = &vcpu->arch.cpuid_entries[i];
2418 if (is_matching_cpuid_entry(e, function, index)) {
2419 if (e->flags & KVM_CPUID_FLAG_STATEFUL_FUNC)
2420 move_to_next_stateful_cpuid_entry(vcpu, i);
2421 best = e;
2422 break;
2423 }
2424 /*
2425 * Both basic or both extended?
2426 */
2427 if (((e->function ^ function) & 0x80000000) == 0)
2428 if (!best || e->function > best->function)
2429 best = e;
2430 }
2431 if (best) {
2432 vcpu->arch.regs[VCPU_REGS_RAX] = best->eax;
2433 vcpu->arch.regs[VCPU_REGS_RBX] = best->ebx;
2434 vcpu->arch.regs[VCPU_REGS_RCX] = best->ecx;
2435 vcpu->arch.regs[VCPU_REGS_RDX] = best->edx;
2436 }
2437 kvm_x86_ops->decache_regs(vcpu);
2438 kvm_x86_ops->skip_emulated_instruction(vcpu);
2439}
2440EXPORT_SYMBOL_GPL(kvm_emulate_cpuid);
2441
2442/*
2443 * Check if userspace requested an interrupt window, and that the
2444 * interrupt window is open.
2445 *
2446 * No need to exit to userspace if we already have an interrupt queued.
2447 */
2448static int dm_request_for_irq_injection(struct kvm_vcpu *vcpu,
2449 struct kvm_run *kvm_run)
2450{
2451 return (!vcpu->arch.irq_summary &&
2452 kvm_run->request_interrupt_window &&
2453 vcpu->arch.interrupt_window_open &&
2454 (kvm_x86_ops->get_rflags(vcpu) & X86_EFLAGS_IF));
2455}
2456
2457static void post_kvm_run_save(struct kvm_vcpu *vcpu,
2458 struct kvm_run *kvm_run)
2459{
2460 kvm_run->if_flag = (kvm_x86_ops->get_rflags(vcpu) & X86_EFLAGS_IF) != 0;
2461 kvm_run->cr8 = get_cr8(vcpu);
2462 kvm_run->apic_base = kvm_get_apic_base(vcpu);
2463 if (irqchip_in_kernel(vcpu->kvm))
2464 kvm_run->ready_for_interrupt_injection = 1;
2465 else
2466 kvm_run->ready_for_interrupt_injection =
2467 (vcpu->arch.interrupt_window_open &&
2468 vcpu->arch.irq_summary == 0);
2469}
2470
2471static void vapic_enter(struct kvm_vcpu *vcpu)
2472{
2473 struct kvm_lapic *apic = vcpu->arch.apic;
2474 struct page *page;
2475
2476 if (!apic || !apic->vapic_addr)
2477 return;
2478
2479 down_read(&current->mm->mmap_sem);
2480 page = gfn_to_page(vcpu->kvm, apic->vapic_addr >> PAGE_SHIFT);
2481 vcpu->arch.apic->vapic_page = page;
2482 up_read(&current->mm->mmap_sem);
2483}
2484
2485static void vapic_exit(struct kvm_vcpu *vcpu)
2486{
2487 struct kvm_lapic *apic = vcpu->arch.apic;
2488
2489 if (!apic || !apic->vapic_addr)
2490 return;
2491
2492 kvm_release_page_dirty(apic->vapic_page);
2493 mark_page_dirty(vcpu->kvm, apic->vapic_addr >> PAGE_SHIFT);
2494}
2495
2496static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2497{
2498 int r;
2499
2500 if (unlikely(vcpu->arch.mp_state == VCPU_MP_STATE_SIPI_RECEIVED)) {
2501 pr_debug("vcpu %d received sipi with vector # %x\n",
2502 vcpu->vcpu_id, vcpu->arch.sipi_vector);
2503 kvm_lapic_reset(vcpu);
2504 r = kvm_x86_ops->vcpu_reset(vcpu);
2505 if (r)
2506 return r;
2507 vcpu->arch.mp_state = VCPU_MP_STATE_RUNNABLE;
2508 }
2509
2510 vapic_enter(vcpu);
2511
2512preempted:
2513 if (vcpu->guest_debug.enabled)
2514 kvm_x86_ops->guest_debug_pre(vcpu);
2515
2516again:
2517 r = kvm_mmu_reload(vcpu);
2518 if (unlikely(r))
2519 goto out;
2520
2521 if (vcpu->requests) {
2522 if (test_and_clear_bit(KVM_REQ_MIGRATE_TIMER, &vcpu->requests))
2523 __kvm_migrate_apic_timer(vcpu);
2524 if (test_and_clear_bit(KVM_REQ_REPORT_TPR_ACCESS,
2525 &vcpu->requests)) {
2526 kvm_run->exit_reason = KVM_EXIT_TPR_ACCESS;
2527 r = 0;
2528 goto out;
2529 }
2530 }
2531
2532 kvm_inject_pending_timer_irqs(vcpu);
2533
2534 preempt_disable();
2535
2536 kvm_x86_ops->prepare_guest_switch(vcpu);
2537 kvm_load_guest_fpu(vcpu);
2538
2539 local_irq_disable();
2540
2541 if (need_resched()) {
2542 local_irq_enable();
2543 preempt_enable();
2544 r = 1;
2545 goto out;
2546 }
2547
2548 if (signal_pending(current)) {
2549 local_irq_enable();
2550 preempt_enable();
2551 r = -EINTR;
2552 kvm_run->exit_reason = KVM_EXIT_INTR;
2553 ++vcpu->stat.signal_exits;
2554 goto out;
2555 }
2556
2557 if (vcpu->arch.exception.pending)
2558 __queue_exception(vcpu);
2559 else if (irqchip_in_kernel(vcpu->kvm))
2560 kvm_x86_ops->inject_pending_irq(vcpu);
2561 else
2562 kvm_x86_ops->inject_pending_vectors(vcpu, kvm_run);
2563
2564 kvm_lapic_sync_to_vapic(vcpu);
2565
2566 vcpu->guest_mode = 1;
2567 kvm_guest_enter();
2568
2569 if (vcpu->requests)
2570 if (test_and_clear_bit(KVM_REQ_TLB_FLUSH, &vcpu->requests))
2571 kvm_x86_ops->tlb_flush(vcpu);
2572
2573 kvm_x86_ops->run(vcpu, kvm_run);
2574
2575 vcpu->guest_mode = 0;
2576 local_irq_enable();
2577
2578 ++vcpu->stat.exits;
2579
2580 /*
2581 * We must have an instruction between local_irq_enable() and
2582 * kvm_guest_exit(), so the timer interrupt isn't delayed by
2583 * the interrupt shadow. The stat.exits increment will do nicely.
2584 * But we need to prevent reordering, hence this barrier():
2585 */
2586 barrier();
2587
2588 kvm_guest_exit();
2589
2590 preempt_enable();
2591
2592 /*
2593 * Profile KVM exit RIPs:
2594 */
2595 if (unlikely(prof_on == KVM_PROFILING)) {
2596 kvm_x86_ops->cache_regs(vcpu);
2597 profile_hit(KVM_PROFILING, (void *)vcpu->arch.rip);
2598 }
2599
2600 if (vcpu->arch.exception.pending && kvm_x86_ops->exception_injected(vcpu))
2601 vcpu->arch.exception.pending = false;
2602
2603 kvm_lapic_sync_from_vapic(vcpu);
2604
2605 r = kvm_x86_ops->handle_exit(kvm_run, vcpu);
2606
2607 if (r > 0) {
2608 if (dm_request_for_irq_injection(vcpu, kvm_run)) {
2609 r = -EINTR;
2610 kvm_run->exit_reason = KVM_EXIT_INTR;
2611 ++vcpu->stat.request_irq_exits;
2612 goto out;
2613 }
2614 if (!need_resched())
2615 goto again;
2616 }
2617
2618out:
2619 if (r > 0) {
2620 kvm_resched(vcpu);
2621 goto preempted;
2622 }
2623
2624 post_kvm_run_save(vcpu, kvm_run);
2625
2626 vapic_exit(vcpu);
2627
2628 return r;
2629}
2630
2631int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2632{
2633 int r;
2634 sigset_t sigsaved;
2635
2636 vcpu_load(vcpu);
2637
2638 if (unlikely(vcpu->arch.mp_state == VCPU_MP_STATE_UNINITIALIZED)) {
2639 kvm_vcpu_block(vcpu);
2640 vcpu_put(vcpu);
2641 return -EAGAIN;
2642 }
2643
2644 if (vcpu->sigset_active)
2645 sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
2646
2647 /* re-sync apic's tpr */
2648 if (!irqchip_in_kernel(vcpu->kvm))
2649 set_cr8(vcpu, kvm_run->cr8);
2650
2651 if (vcpu->arch.pio.cur_count) {
2652 r = complete_pio(vcpu);
2653 if (r)
2654 goto out;
2655 }
2656#if CONFIG_HAS_IOMEM
2657 if (vcpu->mmio_needed) {
2658 memcpy(vcpu->mmio_data, kvm_run->mmio.data, 8);
2659 vcpu->mmio_read_completed = 1;
2660 vcpu->mmio_needed = 0;
2661 r = emulate_instruction(vcpu, kvm_run,
2662 vcpu->arch.mmio_fault_cr2, 0,
2663 EMULTYPE_NO_DECODE);
2664 if (r == EMULATE_DO_MMIO) {
2665 /*
2666 * Read-modify-write. Back to userspace.
2667 */
2668 r = 0;
2669 goto out;
2670 }
2671 }
2672#endif
2673 if (kvm_run->exit_reason == KVM_EXIT_HYPERCALL) {
2674 kvm_x86_ops->cache_regs(vcpu);
2675 vcpu->arch.regs[VCPU_REGS_RAX] = kvm_run->hypercall.ret;
2676 kvm_x86_ops->decache_regs(vcpu);
2677 }
2678
2679 r = __vcpu_run(vcpu, kvm_run);
2680
2681out:
2682 if (vcpu->sigset_active)
2683 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
2684
2685 vcpu_put(vcpu);
2686 return r;
2687}
2688
2689int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
2690{
2691 vcpu_load(vcpu);
2692
2693 kvm_x86_ops->cache_regs(vcpu);
2694
2695 regs->rax = vcpu->arch.regs[VCPU_REGS_RAX];
2696 regs->rbx = vcpu->arch.regs[VCPU_REGS_RBX];
2697 regs->rcx = vcpu->arch.regs[VCPU_REGS_RCX];
2698 regs->rdx = vcpu->arch.regs[VCPU_REGS_RDX];
2699 regs->rsi = vcpu->arch.regs[VCPU_REGS_RSI];
2700 regs->rdi = vcpu->arch.regs[VCPU_REGS_RDI];
2701 regs->rsp = vcpu->arch.regs[VCPU_REGS_RSP];
2702 regs->rbp = vcpu->arch.regs[VCPU_REGS_RBP];
2703#ifdef CONFIG_X86_64
2704 regs->r8 = vcpu->arch.regs[VCPU_REGS_R8];
2705 regs->r9 = vcpu->arch.regs[VCPU_REGS_R9];
2706 regs->r10 = vcpu->arch.regs[VCPU_REGS_R10];
2707 regs->r11 = vcpu->arch.regs[VCPU_REGS_R11];
2708 regs->r12 = vcpu->arch.regs[VCPU_REGS_R12];
2709 regs->r13 = vcpu->arch.regs[VCPU_REGS_R13];
2710 regs->r14 = vcpu->arch.regs[VCPU_REGS_R14];
2711 regs->r15 = vcpu->arch.regs[VCPU_REGS_R15];
2712#endif
2713
2714 regs->rip = vcpu->arch.rip;
2715 regs->rflags = kvm_x86_ops->get_rflags(vcpu);
2716
2717 /*
2718 * Don't leak debug flags in case they were set for guest debugging
2719 */
2720 if (vcpu->guest_debug.enabled && vcpu->guest_debug.singlestep)
2721 regs->rflags &= ~(X86_EFLAGS_TF | X86_EFLAGS_RF);
2722
2723 vcpu_put(vcpu);
2724
2725 return 0;
2726}
2727
2728int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
2729{
2730 vcpu_load(vcpu);
2731
2732 vcpu->arch.regs[VCPU_REGS_RAX] = regs->rax;
2733 vcpu->arch.regs[VCPU_REGS_RBX] = regs->rbx;
2734 vcpu->arch.regs[VCPU_REGS_RCX] = regs->rcx;
2735 vcpu->arch.regs[VCPU_REGS_RDX] = regs->rdx;
2736 vcpu->arch.regs[VCPU_REGS_RSI] = regs->rsi;
2737 vcpu->arch.regs[VCPU_REGS_RDI] = regs->rdi;
2738 vcpu->arch.regs[VCPU_REGS_RSP] = regs->rsp;
2739 vcpu->arch.regs[VCPU_REGS_RBP] = regs->rbp;
2740#ifdef CONFIG_X86_64
2741 vcpu->arch.regs[VCPU_REGS_R8] = regs->r8;
2742 vcpu->arch.regs[VCPU_REGS_R9] = regs->r9;
2743 vcpu->arch.regs[VCPU_REGS_R10] = regs->r10;
2744 vcpu->arch.regs[VCPU_REGS_R11] = regs->r11;
2745 vcpu->arch.regs[VCPU_REGS_R12] = regs->r12;
2746 vcpu->arch.regs[VCPU_REGS_R13] = regs->r13;
2747 vcpu->arch.regs[VCPU_REGS_R14] = regs->r14;
2748 vcpu->arch.regs[VCPU_REGS_R15] = regs->r15;
2749#endif
2750
2751 vcpu->arch.rip = regs->rip;
2752 kvm_x86_ops->set_rflags(vcpu, regs->rflags);
2753
2754 kvm_x86_ops->decache_regs(vcpu);
2755
2756 vcpu_put(vcpu);
2757
2758 return 0;
2759}
2760
2761static void get_segment(struct kvm_vcpu *vcpu,
2762 struct kvm_segment *var, int seg)
2763{
2764 return kvm_x86_ops->get_segment(vcpu, var, seg);
2765}
2766
2767void kvm_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l)
2768{
2769 struct kvm_segment cs;
2770
2771 get_segment(vcpu, &cs, VCPU_SREG_CS);
2772 *db = cs.db;
2773 *l = cs.l;
2774}
2775EXPORT_SYMBOL_GPL(kvm_get_cs_db_l_bits);
2776
2777int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
2778 struct kvm_sregs *sregs)
2779{
2780 struct descriptor_table dt;
2781 int pending_vec;
2782
2783 vcpu_load(vcpu);
2784
2785 get_segment(vcpu, &sregs->cs, VCPU_SREG_CS);
2786 get_segment(vcpu, &sregs->ds, VCPU_SREG_DS);
2787 get_segment(vcpu, &sregs->es, VCPU_SREG_ES);
2788 get_segment(vcpu, &sregs->fs, VCPU_SREG_FS);
2789 get_segment(vcpu, &sregs->gs, VCPU_SREG_GS);
2790 get_segment(vcpu, &sregs->ss, VCPU_SREG_SS);
2791
2792 get_segment(vcpu, &sregs->tr, VCPU_SREG_TR);
2793 get_segment(vcpu, &sregs->ldt, VCPU_SREG_LDTR);
2794
2795 kvm_x86_ops->get_idt(vcpu, &dt);
2796 sregs->idt.limit = dt.limit;
2797 sregs->idt.base = dt.base;
2798 kvm_x86_ops->get_gdt(vcpu, &dt);
2799 sregs->gdt.limit = dt.limit;
2800 sregs->gdt.base = dt.base;
2801
2802 kvm_x86_ops->decache_cr4_guest_bits(vcpu);
2803 sregs->cr0 = vcpu->arch.cr0;
2804 sregs->cr2 = vcpu->arch.cr2;
2805 sregs->cr3 = vcpu->arch.cr3;
2806 sregs->cr4 = vcpu->arch.cr4;
2807 sregs->cr8 = get_cr8(vcpu);
2808 sregs->efer = vcpu->arch.shadow_efer;
2809 sregs->apic_base = kvm_get_apic_base(vcpu);
2810
2811 if (irqchip_in_kernel(vcpu->kvm)) {
2812 memset(sregs->interrupt_bitmap, 0,
2813 sizeof sregs->interrupt_bitmap);
2814 pending_vec = kvm_x86_ops->get_irq(vcpu);
2815 if (pending_vec >= 0)
2816 set_bit(pending_vec,
2817 (unsigned long *)sregs->interrupt_bitmap);
2818 } else
2819 memcpy(sregs->interrupt_bitmap, vcpu->arch.irq_pending,
2820 sizeof sregs->interrupt_bitmap);
2821
2822 vcpu_put(vcpu);
2823
2824 return 0;
2825}
2826
2827static void set_segment(struct kvm_vcpu *vcpu,
2828 struct kvm_segment *var, int seg)
2829{
2830 return kvm_x86_ops->set_segment(vcpu, var, seg);
2831}
2832
2833int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
2834 struct kvm_sregs *sregs)
2835{
2836 int mmu_reset_needed = 0;
2837 int i, pending_vec, max_bits;
2838 struct descriptor_table dt;
2839
2840 vcpu_load(vcpu);
2841
2842 dt.limit = sregs->idt.limit;
2843 dt.base = sregs->idt.base;
2844 kvm_x86_ops->set_idt(vcpu, &dt);
2845 dt.limit = sregs->gdt.limit;
2846 dt.base = sregs->gdt.base;
2847 kvm_x86_ops->set_gdt(vcpu, &dt);
2848
2849 vcpu->arch.cr2 = sregs->cr2;
2850 mmu_reset_needed |= vcpu->arch.cr3 != sregs->cr3;
2851 vcpu->arch.cr3 = sregs->cr3;
2852
2853 set_cr8(vcpu, sregs->cr8);
2854
2855 mmu_reset_needed |= vcpu->arch.shadow_efer != sregs->efer;
2856#ifdef CONFIG_X86_64
2857 kvm_x86_ops->set_efer(vcpu, sregs->efer);
2858#endif
2859 kvm_set_apic_base(vcpu, sregs->apic_base);
2860
2861 kvm_x86_ops->decache_cr4_guest_bits(vcpu);
2862
2863 mmu_reset_needed |= vcpu->arch.cr0 != sregs->cr0;
2864 vcpu->arch.cr0 = sregs->cr0;
2865 kvm_x86_ops->set_cr0(vcpu, sregs->cr0);
2866
2867 mmu_reset_needed |= vcpu->arch.cr4 != sregs->cr4;
2868 kvm_x86_ops->set_cr4(vcpu, sregs->cr4);
2869 if (!is_long_mode(vcpu) && is_pae(vcpu))
2870 load_pdptrs(vcpu, vcpu->arch.cr3);
2871
2872 if (mmu_reset_needed)
2873 kvm_mmu_reset_context(vcpu);
2874
2875 if (!irqchip_in_kernel(vcpu->kvm)) {
2876 memcpy(vcpu->arch.irq_pending, sregs->interrupt_bitmap,
2877 sizeof vcpu->arch.irq_pending);
2878 vcpu->arch.irq_summary = 0;
2879 for (i = 0; i < ARRAY_SIZE(vcpu->arch.irq_pending); ++i)
2880 if (vcpu->arch.irq_pending[i])
2881 __set_bit(i, &vcpu->arch.irq_summary);
2882 } else {
2883 max_bits = (sizeof sregs->interrupt_bitmap) << 3;
2884 pending_vec = find_first_bit(
2885 (const unsigned long *)sregs->interrupt_bitmap,
2886 max_bits);
2887 /* Only pending external irq is handled here */
2888 if (pending_vec < max_bits) {
2889 kvm_x86_ops->set_irq(vcpu, pending_vec);
2890 pr_debug("Set back pending irq %d\n",
2891 pending_vec);
2892 }
2893 }
2894
2895 set_segment(vcpu, &sregs->cs, VCPU_SREG_CS);
2896 set_segment(vcpu, &sregs->ds, VCPU_SREG_DS);
2897 set_segment(vcpu, &sregs->es, VCPU_SREG_ES);
2898 set_segment(vcpu, &sregs->fs, VCPU_SREG_FS);
2899 set_segment(vcpu, &sregs->gs, VCPU_SREG_GS);
2900 set_segment(vcpu, &sregs->ss, VCPU_SREG_SS);
2901
2902 set_segment(vcpu, &sregs->tr, VCPU_SREG_TR);
2903 set_segment(vcpu, &sregs->ldt, VCPU_SREG_LDTR);
2904
2905 vcpu_put(vcpu);
2906
2907 return 0;
2908}
2909
2910int kvm_arch_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu,
2911 struct kvm_debug_guest *dbg)
2912{
2913 int r;
2914
2915 vcpu_load(vcpu);
2916
2917 r = kvm_x86_ops->set_guest_debug(vcpu, dbg);
2918
2919 vcpu_put(vcpu);
2920
2921 return r;
2922}
2923
2924/*
2925 * fxsave fpu state. Taken from x86_64/processor.h. To be killed when
2926 * we have asm/x86/processor.h
2927 */
2928struct fxsave {
2929 u16 cwd;
2930 u16 swd;
2931 u16 twd;
2932 u16 fop;
2933 u64 rip;
2934 u64 rdp;
2935 u32 mxcsr;
2936 u32 mxcsr_mask;
2937 u32 st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */
2938#ifdef CONFIG_X86_64
2939 u32 xmm_space[64]; /* 16*16 bytes for each XMM-reg = 256 bytes */
2940#else
2941 u32 xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */
2942#endif
2943};
2944
2945/*
2946 * Translate a guest virtual address to a guest physical address.
2947 */
2948int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
2949 struct kvm_translation *tr)
2950{
2951 unsigned long vaddr = tr->linear_address;
2952 gpa_t gpa;
2953
2954 vcpu_load(vcpu);
2955 down_read(&current->mm->mmap_sem);
2956 gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, vaddr);
2957 up_read(&current->mm->mmap_sem);
2958 tr->physical_address = gpa;
2959 tr->valid = gpa != UNMAPPED_GVA;
2960 tr->writeable = 1;
2961 tr->usermode = 0;
2962 vcpu_put(vcpu);
2963
2964 return 0;
2965}
2966
2967int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
2968{
2969 struct fxsave *fxsave = (struct fxsave *)&vcpu->arch.guest_fx_image;
2970
2971 vcpu_load(vcpu);
2972
2973 memcpy(fpu->fpr, fxsave->st_space, 128);
2974 fpu->fcw = fxsave->cwd;
2975 fpu->fsw = fxsave->swd;
2976 fpu->ftwx = fxsave->twd;
2977 fpu->last_opcode = fxsave->fop;
2978 fpu->last_ip = fxsave->rip;
2979 fpu->last_dp = fxsave->rdp;
2980 memcpy(fpu->xmm, fxsave->xmm_space, sizeof fxsave->xmm_space);
2981
2982 vcpu_put(vcpu);
2983
2984 return 0;
2985}
2986
2987int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
2988{
2989 struct fxsave *fxsave = (struct fxsave *)&vcpu->arch.guest_fx_image;
2990
2991 vcpu_load(vcpu);
2992
2993 memcpy(fxsave->st_space, fpu->fpr, 128);
2994 fxsave->cwd = fpu->fcw;
2995 fxsave->swd = fpu->fsw;
2996 fxsave->twd = fpu->ftwx;
2997 fxsave->fop = fpu->last_opcode;
2998 fxsave->rip = fpu->last_ip;
2999 fxsave->rdp = fpu->last_dp;
3000 memcpy(fxsave->xmm_space, fpu->xmm, sizeof fxsave->xmm_space);
3001
3002 vcpu_put(vcpu);
3003
3004 return 0;
3005}
3006
3007void fx_init(struct kvm_vcpu *vcpu)
3008{
3009 unsigned after_mxcsr_mask;
3010
3011 /* Initialize guest FPU by resetting ours and saving into guest's */
3012 preempt_disable();
3013 fx_save(&vcpu->arch.host_fx_image);
3014 fpu_init();
3015 fx_save(&vcpu->arch.guest_fx_image);
3016 fx_restore(&vcpu->arch.host_fx_image);
3017 preempt_enable();
3018
3019 vcpu->arch.cr0 |= X86_CR0_ET;
3020 after_mxcsr_mask = offsetof(struct i387_fxsave_struct, st_space);
3021 vcpu->arch.guest_fx_image.mxcsr = 0x1f80;
3022 memset((void *)&vcpu->arch.guest_fx_image + after_mxcsr_mask,
3023 0, sizeof(struct i387_fxsave_struct) - after_mxcsr_mask);
3024}
3025EXPORT_SYMBOL_GPL(fx_init);
3026
3027void kvm_load_guest_fpu(struct kvm_vcpu *vcpu)
3028{
3029 if (!vcpu->fpu_active || vcpu->guest_fpu_loaded)
3030 return;
3031
3032 vcpu->guest_fpu_loaded = 1;
3033 fx_save(&vcpu->arch.host_fx_image);
3034 fx_restore(&vcpu->arch.guest_fx_image);
3035}
3036EXPORT_SYMBOL_GPL(kvm_load_guest_fpu);
3037
3038void kvm_put_guest_fpu(struct kvm_vcpu *vcpu)
3039{
3040 if (!vcpu->guest_fpu_loaded)
3041 return;
3042
3043 vcpu->guest_fpu_loaded = 0;
3044 fx_save(&vcpu->arch.guest_fx_image);
3045 fx_restore(&vcpu->arch.host_fx_image);
3046 ++vcpu->stat.fpu_reload;
3047}
3048EXPORT_SYMBOL_GPL(kvm_put_guest_fpu);
3049
3050void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
3051{
3052 kvm_x86_ops->vcpu_free(vcpu);
3053}
3054
3055struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
3056 unsigned int id)
3057{
3058 return kvm_x86_ops->vcpu_create(kvm, id);
3059}
3060
3061int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
3062{
3063 int r;
3064
3065 /* We do fxsave: this must be aligned. */
3066 BUG_ON((unsigned long)&vcpu->arch.host_fx_image & 0xF);
3067
3068 vcpu_load(vcpu);
3069 r = kvm_arch_vcpu_reset(vcpu);
3070 if (r == 0)
3071 r = kvm_mmu_setup(vcpu);
3072 vcpu_put(vcpu);
3073 if (r < 0)
3074 goto free_vcpu;
3075
3076 return 0;
3077free_vcpu:
3078 kvm_x86_ops->vcpu_free(vcpu);
3079 return r;
3080}
3081
3082void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
3083{
3084 vcpu_load(vcpu);
3085 kvm_mmu_unload(vcpu);
3086 vcpu_put(vcpu);
3087
3088 kvm_x86_ops->vcpu_free(vcpu);
3089}
3090
3091int kvm_arch_vcpu_reset(struct kvm_vcpu *vcpu)
3092{
3093 return kvm_x86_ops->vcpu_reset(vcpu);
3094}
3095
3096void kvm_arch_hardware_enable(void *garbage)
3097{
3098 kvm_x86_ops->hardware_enable(garbage);
3099}
3100
3101void kvm_arch_hardware_disable(void *garbage)
3102{
3103 kvm_x86_ops->hardware_disable(garbage);
3104}
3105
3106int kvm_arch_hardware_setup(void)
3107{
3108 return kvm_x86_ops->hardware_setup();
3109}
3110
3111void kvm_arch_hardware_unsetup(void)
3112{
3113 kvm_x86_ops->hardware_unsetup();
3114}
3115
3116void kvm_arch_check_processor_compat(void *rtn)
3117{
3118 kvm_x86_ops->check_processor_compatibility(rtn);
3119}
3120
3121int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
3122{
3123 struct page *page;
3124 struct kvm *kvm;
3125 int r;
3126
3127 BUG_ON(vcpu->kvm == NULL);
3128 kvm = vcpu->kvm;
3129
3130 vcpu->arch.mmu.root_hpa = INVALID_PAGE;
3131 if (!irqchip_in_kernel(kvm) || vcpu->vcpu_id == 0)
3132 vcpu->arch.mp_state = VCPU_MP_STATE_RUNNABLE;
3133 else
3134 vcpu->arch.mp_state = VCPU_MP_STATE_UNINITIALIZED;
3135
3136 page = alloc_page(GFP_KERNEL | __GFP_ZERO);
3137 if (!page) {
3138 r = -ENOMEM;
3139 goto fail;
3140 }
3141 vcpu->arch.pio_data = page_address(page);
3142
3143 r = kvm_mmu_create(vcpu);
3144 if (r < 0)
3145 goto fail_free_pio_data;
3146
3147 if (irqchip_in_kernel(kvm)) {
3148 r = kvm_create_lapic(vcpu);
3149 if (r < 0)
3150 goto fail_mmu_destroy;
3151 }
3152
3153 return 0;
3154
3155fail_mmu_destroy:
3156 kvm_mmu_destroy(vcpu);
3157fail_free_pio_data:
3158 free_page((unsigned long)vcpu->arch.pio_data);
3159fail:
3160 return r;
3161}
3162
3163void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
3164{
3165 kvm_free_lapic(vcpu);
3166 kvm_mmu_destroy(vcpu);
3167 free_page((unsigned long)vcpu->arch.pio_data);
3168}
3169
3170struct kvm *kvm_arch_create_vm(void)
3171{
3172 struct kvm *kvm = kzalloc(sizeof(struct kvm), GFP_KERNEL);
3173
3174 if (!kvm)
3175 return ERR_PTR(-ENOMEM);
3176
3177 INIT_LIST_HEAD(&kvm->arch.active_mmu_pages);
3178
3179 return kvm;
3180}
3181
3182static void kvm_unload_vcpu_mmu(struct kvm_vcpu *vcpu)
3183{
3184 vcpu_load(vcpu);
3185 kvm_mmu_unload(vcpu);
3186 vcpu_put(vcpu);
3187}
3188
3189static void kvm_free_vcpus(struct kvm *kvm)
3190{
3191 unsigned int i;
3192
3193 /*
3194 * Unpin any mmu pages first.
3195 */
3196 for (i = 0; i < KVM_MAX_VCPUS; ++i)
3197 if (kvm->vcpus[i])
3198 kvm_unload_vcpu_mmu(kvm->vcpus[i]);
3199 for (i = 0; i < KVM_MAX_VCPUS; ++i) {
3200 if (kvm->vcpus[i]) {
3201 kvm_arch_vcpu_free(kvm->vcpus[i]);
3202 kvm->vcpus[i] = NULL;
3203 }
3204 }
3205
3206}
3207
3208void kvm_arch_destroy_vm(struct kvm *kvm)
3209{
3210 kfree(kvm->arch.vpic);
3211 kfree(kvm->arch.vioapic);
3212 kvm_free_vcpus(kvm);
3213 kvm_free_physmem(kvm);
3214 kfree(kvm);
3215}
3216
3217int kvm_arch_set_memory_region(struct kvm *kvm,
3218 struct kvm_userspace_memory_region *mem,
3219 struct kvm_memory_slot old,
3220 int user_alloc)
3221{
3222 int npages = mem->memory_size >> PAGE_SHIFT;
3223 struct kvm_memory_slot *memslot = &kvm->memslots[mem->slot];
3224
3225 /*To keep backward compatibility with older userspace,
3226 *x86 needs to hanlde !user_alloc case.
3227 */
3228 if (!user_alloc) {
3229 if (npages && !old.rmap) {
3230 memslot->userspace_addr = do_mmap(NULL, 0,
3231 npages * PAGE_SIZE,
3232 PROT_READ | PROT_WRITE,
3233 MAP_SHARED | MAP_ANONYMOUS,
3234 0);
3235
3236 if (IS_ERR((void *)memslot->userspace_addr))
3237 return PTR_ERR((void *)memslot->userspace_addr);
3238 } else {
3239 if (!old.user_alloc && old.rmap) {
3240 int ret;
3241
3242 ret = do_munmap(current->mm, old.userspace_addr,
3243 old.npages * PAGE_SIZE);
3244 if (ret < 0)
3245 printk(KERN_WARNING
3246 "kvm_vm_ioctl_set_memory_region: "
3247 "failed to munmap memory\n");
3248 }
3249 }
3250 }
3251
3252 if (!kvm->arch.n_requested_mmu_pages) {
3253 unsigned int nr_mmu_pages = kvm_mmu_calculate_mmu_pages(kvm);
3254 kvm_mmu_change_mmu_pages(kvm, nr_mmu_pages);
3255 }
3256
3257 kvm_mmu_slot_remove_write_access(kvm, mem->slot);
3258 kvm_flush_remote_tlbs(kvm);
3259
3260 return 0;
3261}
3262
3263int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
3264{
3265 return vcpu->arch.mp_state == VCPU_MP_STATE_RUNNABLE
3266 || vcpu->arch.mp_state == VCPU_MP_STATE_SIPI_RECEIVED;
3267}
3268
3269static void vcpu_kick_intr(void *info)
3270{
3271#ifdef DEBUG
3272 struct kvm_vcpu *vcpu = (struct kvm_vcpu *)info;
3273 printk(KERN_DEBUG "vcpu_kick_intr %p \n", vcpu);
3274#endif
3275}
3276
3277void kvm_vcpu_kick(struct kvm_vcpu *vcpu)
3278{
3279 int ipi_pcpu = vcpu->cpu;
3280
3281 if (waitqueue_active(&vcpu->wq)) {
3282 wake_up_interruptible(&vcpu->wq);
3283 ++vcpu->stat.halt_wakeup;
3284 }
3285 if (vcpu->guest_mode)
3286 smp_call_function_single(ipi_pcpu, vcpu_kick_intr, vcpu, 0, 0);
3287}
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c
new file mode 100644
index 000000000000..79586003397a
--- /dev/null
+++ b/arch/x86/kvm/x86_emulate.c
@@ -0,0 +1,1912 @@
1/******************************************************************************
2 * x86_emulate.c
3 *
4 * Generic x86 (32-bit and 64-bit) instruction decoder and emulator.
5 *
6 * Copyright (c) 2005 Keir Fraser
7 *
8 * Linux coding style, mod r/m decoder, segment base fixes, real-mode
9 * privileged instructions:
10 *
11 * Copyright (C) 2006 Qumranet
12 *
13 * Avi Kivity <avi@qumranet.com>
14 * Yaniv Kamay <yaniv@qumranet.com>
15 *
16 * This work is licensed under the terms of the GNU GPL, version 2. See
17 * the COPYING file in the top-level directory.
18 *
19 * From: xen-unstable 10676:af9809f51f81a3c43f276f00c81a52ef558afda4
20 */
21
22#ifndef __KERNEL__
23#include <stdio.h>
24#include <stdint.h>
25#include <public/xen.h>
26#define DPRINTF(_f, _a ...) printf(_f , ## _a)
27#else
28#include <linux/kvm_host.h>
29#define DPRINTF(x...) do {} while (0)
30#endif
31#include <linux/module.h>
32#include <asm/kvm_x86_emulate.h>
33
34/*
35 * Opcode effective-address decode tables.
36 * Note that we only emulate instructions that have at least one memory
37 * operand (excluding implicit stack references). We assume that stack
38 * references and instruction fetches will never occur in special memory
39 * areas that require emulation. So, for example, 'mov <imm>,<reg>' need
40 * not be handled.
41 */
42
43/* Operand sizes: 8-bit operands or specified/overridden size. */
44#define ByteOp (1<<0) /* 8-bit operands. */
45/* Destination operand type. */
46#define ImplicitOps (1<<1) /* Implicit in opcode. No generic decode. */
47#define DstReg (2<<1) /* Register operand. */
48#define DstMem (3<<1) /* Memory operand. */
49#define DstMask (3<<1)
50/* Source operand type. */
51#define SrcNone (0<<3) /* No source operand. */
52#define SrcImplicit (0<<3) /* Source operand is implicit in the opcode. */
53#define SrcReg (1<<3) /* Register operand. */
54#define SrcMem (2<<3) /* Memory operand. */
55#define SrcMem16 (3<<3) /* Memory operand (16-bit). */
56#define SrcMem32 (4<<3) /* Memory operand (32-bit). */
57#define SrcImm (5<<3) /* Immediate operand. */
58#define SrcImmByte (6<<3) /* 8-bit sign-extended immediate operand. */
59#define SrcMask (7<<3)
60/* Generic ModRM decode. */
61#define ModRM (1<<6)
62/* Destination is only written; never read. */
63#define Mov (1<<7)
64#define BitOp (1<<8)
65#define MemAbs (1<<9) /* Memory operand is absolute displacement */
66#define String (1<<10) /* String instruction (rep capable) */
67#define Stack (1<<11) /* Stack instruction (push/pop) */
68
69static u16 opcode_table[256] = {
70 /* 0x00 - 0x07 */
71 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
72 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
73 0, 0, 0, 0,
74 /* 0x08 - 0x0F */
75 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
76 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
77 0, 0, 0, 0,
78 /* 0x10 - 0x17 */
79 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
80 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
81 0, 0, 0, 0,
82 /* 0x18 - 0x1F */
83 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
84 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
85 0, 0, 0, 0,
86 /* 0x20 - 0x27 */
87 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
88 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
89 SrcImmByte, SrcImm, 0, 0,
90 /* 0x28 - 0x2F */
91 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
92 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
93 0, 0, 0, 0,
94 /* 0x30 - 0x37 */
95 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
96 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
97 0, 0, 0, 0,
98 /* 0x38 - 0x3F */
99 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
100 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
101 0, 0, 0, 0,
102 /* 0x40 - 0x47 */
103 DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg,
104 /* 0x48 - 0x4F */
105 DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg,
106 /* 0x50 - 0x57 */
107 SrcReg | Stack, SrcReg | Stack, SrcReg | Stack, SrcReg | Stack,
108 SrcReg | Stack, SrcReg | Stack, SrcReg | Stack, SrcReg | Stack,
109 /* 0x58 - 0x5F */
110 DstReg | Stack, DstReg | Stack, DstReg | Stack, DstReg | Stack,
111 DstReg | Stack, DstReg | Stack, DstReg | Stack, DstReg | Stack,
112 /* 0x60 - 0x67 */
113 0, 0, 0, DstReg | SrcMem32 | ModRM | Mov /* movsxd (x86/64) */ ,
114 0, 0, 0, 0,
115 /* 0x68 - 0x6F */
116 0, 0, ImplicitOps | Mov | Stack, 0,
117 SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, /* insb, insw/insd */
118 SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, /* outsb, outsw/outsd */
119 /* 0x70 - 0x77 */
120 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
121 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
122 /* 0x78 - 0x7F */
123 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
124 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
125 /* 0x80 - 0x87 */
126 ByteOp | DstMem | SrcImm | ModRM, DstMem | SrcImm | ModRM,
127 ByteOp | DstMem | SrcImm | ModRM, DstMem | SrcImmByte | ModRM,
128 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
129 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
130 /* 0x88 - 0x8F */
131 ByteOp | DstMem | SrcReg | ModRM | Mov, DstMem | SrcReg | ModRM | Mov,
132 ByteOp | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
133 0, ModRM | DstReg, 0, DstMem | SrcNone | ModRM | Mov | Stack,
134 /* 0x90 - 0x9F */
135 0, 0, 0, 0, 0, 0, 0, 0,
136 0, 0, 0, 0, ImplicitOps | Stack, ImplicitOps | Stack, 0, 0,
137 /* 0xA0 - 0xA7 */
138 ByteOp | DstReg | SrcMem | Mov | MemAbs, DstReg | SrcMem | Mov | MemAbs,
139 ByteOp | DstMem | SrcReg | Mov | MemAbs, DstMem | SrcReg | Mov | MemAbs,
140 ByteOp | ImplicitOps | Mov | String, ImplicitOps | Mov | String,
141 ByteOp | ImplicitOps | String, ImplicitOps | String,
142 /* 0xA8 - 0xAF */
143 0, 0, ByteOp | ImplicitOps | Mov | String, ImplicitOps | Mov | String,
144 ByteOp | ImplicitOps | Mov | String, ImplicitOps | Mov | String,
145 ByteOp | ImplicitOps | String, ImplicitOps | String,
146 /* 0xB0 - 0xBF */
147 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
148 /* 0xC0 - 0xC7 */
149 ByteOp | DstMem | SrcImm | ModRM, DstMem | SrcImmByte | ModRM,
150 0, ImplicitOps | Stack, 0, 0,
151 ByteOp | DstMem | SrcImm | ModRM | Mov, DstMem | SrcImm | ModRM | Mov,
152 /* 0xC8 - 0xCF */
153 0, 0, 0, 0, 0, 0, 0, 0,
154 /* 0xD0 - 0xD7 */
155 ByteOp | DstMem | SrcImplicit | ModRM, DstMem | SrcImplicit | ModRM,
156 ByteOp | DstMem | SrcImplicit | ModRM, DstMem | SrcImplicit | ModRM,
157 0, 0, 0, 0,
158 /* 0xD8 - 0xDF */
159 0, 0, 0, 0, 0, 0, 0, 0,
160 /* 0xE0 - 0xE7 */
161 0, 0, 0, 0, 0, 0, 0, 0,
162 /* 0xE8 - 0xEF */
163 ImplicitOps | Stack, SrcImm|ImplicitOps, 0, SrcImmByte|ImplicitOps,
164 0, 0, 0, 0,
165 /* 0xF0 - 0xF7 */
166 0, 0, 0, 0,
167 ImplicitOps, ImplicitOps,
168 ByteOp | DstMem | SrcNone | ModRM, DstMem | SrcNone | ModRM,
169 /* 0xF8 - 0xFF */
170 ImplicitOps, 0, ImplicitOps, ImplicitOps,
171 0, 0, ByteOp | DstMem | SrcNone | ModRM, DstMem | SrcNone | ModRM
172};
173
174static u16 twobyte_table[256] = {
175 /* 0x00 - 0x0F */
176 0, SrcMem | ModRM | DstReg, 0, 0, 0, 0, ImplicitOps, 0,
177 ImplicitOps, ImplicitOps, 0, 0, 0, ImplicitOps | ModRM, 0, 0,
178 /* 0x10 - 0x1F */
179 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, 0,
180 /* 0x20 - 0x2F */
181 ModRM | ImplicitOps, ModRM, ModRM | ImplicitOps, ModRM, 0, 0, 0, 0,
182 0, 0, 0, 0, 0, 0, 0, 0,
183 /* 0x30 - 0x3F */
184 ImplicitOps, 0, ImplicitOps, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
185 /* 0x40 - 0x47 */
186 DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
187 DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
188 DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
189 DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
190 /* 0x48 - 0x4F */
191 DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
192 DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
193 DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
194 DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
195 /* 0x50 - 0x5F */
196 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
197 /* 0x60 - 0x6F */
198 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
199 /* 0x70 - 0x7F */
200 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
201 /* 0x80 - 0x8F */
202 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
203 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
204 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
205 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
206 /* 0x90 - 0x9F */
207 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
208 /* 0xA0 - 0xA7 */
209 0, 0, 0, DstMem | SrcReg | ModRM | BitOp, 0, 0, 0, 0,
210 /* 0xA8 - 0xAF */
211 0, 0, 0, DstMem | SrcReg | ModRM | BitOp, 0, 0, 0, 0,
212 /* 0xB0 - 0xB7 */
213 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, 0,
214 DstMem | SrcReg | ModRM | BitOp,
215 0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov,
216 DstReg | SrcMem16 | ModRM | Mov,
217 /* 0xB8 - 0xBF */
218 0, 0, DstMem | SrcImmByte | ModRM, DstMem | SrcReg | ModRM | BitOp,
219 0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov,
220 DstReg | SrcMem16 | ModRM | Mov,
221 /* 0xC0 - 0xCF */
222 0, 0, 0, DstMem | SrcReg | ModRM | Mov, 0, 0, 0, ImplicitOps | ModRM,
223 0, 0, 0, 0, 0, 0, 0, 0,
224 /* 0xD0 - 0xDF */
225 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
226 /* 0xE0 - 0xEF */
227 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
228 /* 0xF0 - 0xFF */
229 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
230};
231
232/* EFLAGS bit definitions. */
233#define EFLG_OF (1<<11)
234#define EFLG_DF (1<<10)
235#define EFLG_SF (1<<7)
236#define EFLG_ZF (1<<6)
237#define EFLG_AF (1<<4)
238#define EFLG_PF (1<<2)
239#define EFLG_CF (1<<0)
240
241/*
242 * Instruction emulation:
243 * Most instructions are emulated directly via a fragment of inline assembly
244 * code. This allows us to save/restore EFLAGS and thus very easily pick up
245 * any modified flags.
246 */
247
248#if defined(CONFIG_X86_64)
249#define _LO32 "k" /* force 32-bit operand */
250#define _STK "%%rsp" /* stack pointer */
251#elif defined(__i386__)
252#define _LO32 "" /* force 32-bit operand */
253#define _STK "%%esp" /* stack pointer */
254#endif
255
256/*
257 * These EFLAGS bits are restored from saved value during emulation, and
258 * any changes are written back to the saved value after emulation.
259 */
260#define EFLAGS_MASK (EFLG_OF|EFLG_SF|EFLG_ZF|EFLG_AF|EFLG_PF|EFLG_CF)
261
262/* Before executing instruction: restore necessary bits in EFLAGS. */
263#define _PRE_EFLAGS(_sav, _msk, _tmp) \
264 /* EFLAGS = (_sav & _msk) | (EFLAGS & ~_msk); _sav &= ~_msk; */ \
265 "movl %"_sav",%"_LO32 _tmp"; " \
266 "push %"_tmp"; " \
267 "push %"_tmp"; " \
268 "movl %"_msk",%"_LO32 _tmp"; " \
269 "andl %"_LO32 _tmp",("_STK"); " \
270 "pushf; " \
271 "notl %"_LO32 _tmp"; " \
272 "andl %"_LO32 _tmp",("_STK"); " \
273 "andl %"_LO32 _tmp","__stringify(BITS_PER_LONG/4)"("_STK"); " \
274 "pop %"_tmp"; " \
275 "orl %"_LO32 _tmp",("_STK"); " \
276 "popf; " \
277 "pop %"_sav"; "
278
279/* After executing instruction: write-back necessary bits in EFLAGS. */
280#define _POST_EFLAGS(_sav, _msk, _tmp) \
281 /* _sav |= EFLAGS & _msk; */ \
282 "pushf; " \
283 "pop %"_tmp"; " \
284 "andl %"_msk",%"_LO32 _tmp"; " \
285 "orl %"_LO32 _tmp",%"_sav"; "
286
287/* Raw emulation: instruction has two explicit operands. */
288#define __emulate_2op_nobyte(_op,_src,_dst,_eflags,_wx,_wy,_lx,_ly,_qx,_qy) \
289 do { \
290 unsigned long _tmp; \
291 \
292 switch ((_dst).bytes) { \
293 case 2: \
294 __asm__ __volatile__ ( \
295 _PRE_EFLAGS("0", "4", "2") \
296 _op"w %"_wx"3,%1; " \
297 _POST_EFLAGS("0", "4", "2") \
298 : "=m" (_eflags), "=m" ((_dst).val), \
299 "=&r" (_tmp) \
300 : _wy ((_src).val), "i" (EFLAGS_MASK)); \
301 break; \
302 case 4: \
303 __asm__ __volatile__ ( \
304 _PRE_EFLAGS("0", "4", "2") \
305 _op"l %"_lx"3,%1; " \
306 _POST_EFLAGS("0", "4", "2") \
307 : "=m" (_eflags), "=m" ((_dst).val), \
308 "=&r" (_tmp) \
309 : _ly ((_src).val), "i" (EFLAGS_MASK)); \
310 break; \
311 case 8: \
312 __emulate_2op_8byte(_op, _src, _dst, \
313 _eflags, _qx, _qy); \
314 break; \
315 } \
316 } while (0)
317
318#define __emulate_2op(_op,_src,_dst,_eflags,_bx,_by,_wx,_wy,_lx,_ly,_qx,_qy) \
319 do { \
320 unsigned long _tmp; \
321 switch ((_dst).bytes) { \
322 case 1: \
323 __asm__ __volatile__ ( \
324 _PRE_EFLAGS("0", "4", "2") \
325 _op"b %"_bx"3,%1; " \
326 _POST_EFLAGS("0", "4", "2") \
327 : "=m" (_eflags), "=m" ((_dst).val), \
328 "=&r" (_tmp) \
329 : _by ((_src).val), "i" (EFLAGS_MASK)); \
330 break; \
331 default: \
332 __emulate_2op_nobyte(_op, _src, _dst, _eflags, \
333 _wx, _wy, _lx, _ly, _qx, _qy); \
334 break; \
335 } \
336 } while (0)
337
338/* Source operand is byte-sized and may be restricted to just %cl. */
339#define emulate_2op_SrcB(_op, _src, _dst, _eflags) \
340 __emulate_2op(_op, _src, _dst, _eflags, \
341 "b", "c", "b", "c", "b", "c", "b", "c")
342
343/* Source operand is byte, word, long or quad sized. */
344#define emulate_2op_SrcV(_op, _src, _dst, _eflags) \
345 __emulate_2op(_op, _src, _dst, _eflags, \
346 "b", "q", "w", "r", _LO32, "r", "", "r")
347
348/* Source operand is word, long or quad sized. */
349#define emulate_2op_SrcV_nobyte(_op, _src, _dst, _eflags) \
350 __emulate_2op_nobyte(_op, _src, _dst, _eflags, \
351 "w", "r", _LO32, "r", "", "r")
352
353/* Instruction has only one explicit operand (no source operand). */
354#define emulate_1op(_op, _dst, _eflags) \
355 do { \
356 unsigned long _tmp; \
357 \
358 switch ((_dst).bytes) { \
359 case 1: \
360 __asm__ __volatile__ ( \
361 _PRE_EFLAGS("0", "3", "2") \
362 _op"b %1; " \
363 _POST_EFLAGS("0", "3", "2") \
364 : "=m" (_eflags), "=m" ((_dst).val), \
365 "=&r" (_tmp) \
366 : "i" (EFLAGS_MASK)); \
367 break; \
368 case 2: \
369 __asm__ __volatile__ ( \
370 _PRE_EFLAGS("0", "3", "2") \
371 _op"w %1; " \
372 _POST_EFLAGS("0", "3", "2") \
373 : "=m" (_eflags), "=m" ((_dst).val), \
374 "=&r" (_tmp) \
375 : "i" (EFLAGS_MASK)); \
376 break; \
377 case 4: \
378 __asm__ __volatile__ ( \
379 _PRE_EFLAGS("0", "3", "2") \
380 _op"l %1; " \
381 _POST_EFLAGS("0", "3", "2") \
382 : "=m" (_eflags), "=m" ((_dst).val), \
383 "=&r" (_tmp) \
384 : "i" (EFLAGS_MASK)); \
385 break; \
386 case 8: \
387 __emulate_1op_8byte(_op, _dst, _eflags); \
388 break; \
389 } \
390 } while (0)
391
392/* Emulate an instruction with quadword operands (x86/64 only). */
393#if defined(CONFIG_X86_64)
394#define __emulate_2op_8byte(_op, _src, _dst, _eflags, _qx, _qy) \
395 do { \
396 __asm__ __volatile__ ( \
397 _PRE_EFLAGS("0", "4", "2") \
398 _op"q %"_qx"3,%1; " \
399 _POST_EFLAGS("0", "4", "2") \
400 : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp) \
401 : _qy ((_src).val), "i" (EFLAGS_MASK)); \
402 } while (0)
403
404#define __emulate_1op_8byte(_op, _dst, _eflags) \
405 do { \
406 __asm__ __volatile__ ( \
407 _PRE_EFLAGS("0", "3", "2") \
408 _op"q %1; " \
409 _POST_EFLAGS("0", "3", "2") \
410 : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp) \
411 : "i" (EFLAGS_MASK)); \
412 } while (0)
413
414#elif defined(__i386__)
415#define __emulate_2op_8byte(_op, _src, _dst, _eflags, _qx, _qy)
416#define __emulate_1op_8byte(_op, _dst, _eflags)
417#endif /* __i386__ */
418
419/* Fetch next part of the instruction being emulated. */
420#define insn_fetch(_type, _size, _eip) \
421({ unsigned long _x; \
422 rc = do_insn_fetch(ctxt, ops, (_eip), &_x, (_size)); \
423 if (rc != 0) \
424 goto done; \
425 (_eip) += (_size); \
426 (_type)_x; \
427})
428
429/* Access/update address held in a register, based on addressing mode. */
430#define address_mask(reg) \
431 ((c->ad_bytes == sizeof(unsigned long)) ? \
432 (reg) : ((reg) & ((1UL << (c->ad_bytes << 3)) - 1)))
433#define register_address(base, reg) \
434 ((base) + address_mask(reg))
435#define register_address_increment(reg, inc) \
436 do { \
437 /* signed type ensures sign extension to long */ \
438 int _inc = (inc); \
439 if (c->ad_bytes == sizeof(unsigned long)) \
440 (reg) += _inc; \
441 else \
442 (reg) = ((reg) & \
443 ~((1UL << (c->ad_bytes << 3)) - 1)) | \
444 (((reg) + _inc) & \
445 ((1UL << (c->ad_bytes << 3)) - 1)); \
446 } while (0)
447
448#define JMP_REL(rel) \
449 do { \
450 register_address_increment(c->eip, rel); \
451 } while (0)
452
453static int do_fetch_insn_byte(struct x86_emulate_ctxt *ctxt,
454 struct x86_emulate_ops *ops,
455 unsigned long linear, u8 *dest)
456{
457 struct fetch_cache *fc = &ctxt->decode.fetch;
458 int rc;
459 int size;
460
461 if (linear < fc->start || linear >= fc->end) {
462 size = min(15UL, PAGE_SIZE - offset_in_page(linear));
463 rc = ops->read_std(linear, fc->data, size, ctxt->vcpu);
464 if (rc)
465 return rc;
466 fc->start = linear;
467 fc->end = linear + size;
468 }
469 *dest = fc->data[linear - fc->start];
470 return 0;
471}
472
473static int do_insn_fetch(struct x86_emulate_ctxt *ctxt,
474 struct x86_emulate_ops *ops,
475 unsigned long eip, void *dest, unsigned size)
476{
477 int rc = 0;
478
479 eip += ctxt->cs_base;
480 while (size--) {
481 rc = do_fetch_insn_byte(ctxt, ops, eip++, dest++);
482 if (rc)
483 return rc;
484 }
485 return 0;
486}
487
488/*
489 * Given the 'reg' portion of a ModRM byte, and a register block, return a
490 * pointer into the block that addresses the relevant register.
491 * @highbyte_regs specifies whether to decode AH,CH,DH,BH.
492 */
493static void *decode_register(u8 modrm_reg, unsigned long *regs,
494 int highbyte_regs)
495{
496 void *p;
497
498 p = &regs[modrm_reg];
499 if (highbyte_regs && modrm_reg >= 4 && modrm_reg < 8)
500 p = (unsigned char *)&regs[modrm_reg & 3] + 1;
501 return p;
502}
503
504static int read_descriptor(struct x86_emulate_ctxt *ctxt,
505 struct x86_emulate_ops *ops,
506 void *ptr,
507 u16 *size, unsigned long *address, int op_bytes)
508{
509 int rc;
510
511 if (op_bytes == 2)
512 op_bytes = 3;
513 *address = 0;
514 rc = ops->read_std((unsigned long)ptr, (unsigned long *)size, 2,
515 ctxt->vcpu);
516 if (rc)
517 return rc;
518 rc = ops->read_std((unsigned long)ptr + 2, address, op_bytes,
519 ctxt->vcpu);
520 return rc;
521}
522
523static int test_cc(unsigned int condition, unsigned int flags)
524{
525 int rc = 0;
526
527 switch ((condition & 15) >> 1) {
528 case 0: /* o */
529 rc |= (flags & EFLG_OF);
530 break;
531 case 1: /* b/c/nae */
532 rc |= (flags & EFLG_CF);
533 break;
534 case 2: /* z/e */
535 rc |= (flags & EFLG_ZF);
536 break;
537 case 3: /* be/na */
538 rc |= (flags & (EFLG_CF|EFLG_ZF));
539 break;
540 case 4: /* s */
541 rc |= (flags & EFLG_SF);
542 break;
543 case 5: /* p/pe */
544 rc |= (flags & EFLG_PF);
545 break;
546 case 7: /* le/ng */
547 rc |= (flags & EFLG_ZF);
548 /* fall through */
549 case 6: /* l/nge */
550 rc |= (!(flags & EFLG_SF) != !(flags & EFLG_OF));
551 break;
552 }
553
554 /* Odd condition identifiers (lsb == 1) have inverted sense. */
555 return (!!rc ^ (condition & 1));
556}
557
558static void decode_register_operand(struct operand *op,
559 struct decode_cache *c,
560 int inhibit_bytereg)
561{
562 unsigned reg = c->modrm_reg;
563 int highbyte_regs = c->rex_prefix == 0;
564
565 if (!(c->d & ModRM))
566 reg = (c->b & 7) | ((c->rex_prefix & 1) << 3);
567 op->type = OP_REG;
568 if ((c->d & ByteOp) && !inhibit_bytereg) {
569 op->ptr = decode_register(reg, c->regs, highbyte_regs);
570 op->val = *(u8 *)op->ptr;
571 op->bytes = 1;
572 } else {
573 op->ptr = decode_register(reg, c->regs, 0);
574 op->bytes = c->op_bytes;
575 switch (op->bytes) {
576 case 2:
577 op->val = *(u16 *)op->ptr;
578 break;
579 case 4:
580 op->val = *(u32 *)op->ptr;
581 break;
582 case 8:
583 op->val = *(u64 *) op->ptr;
584 break;
585 }
586 }
587 op->orig_val = op->val;
588}
589
590static int decode_modrm(struct x86_emulate_ctxt *ctxt,
591 struct x86_emulate_ops *ops)
592{
593 struct decode_cache *c = &ctxt->decode;
594 u8 sib;
595 int index_reg = 0, base_reg = 0, scale, rip_relative = 0;
596 int rc = 0;
597
598 if (c->rex_prefix) {
599 c->modrm_reg = (c->rex_prefix & 4) << 1; /* REX.R */
600 index_reg = (c->rex_prefix & 2) << 2; /* REX.X */
601 c->modrm_rm = base_reg = (c->rex_prefix & 1) << 3; /* REG.B */
602 }
603
604 c->modrm = insn_fetch(u8, 1, c->eip);
605 c->modrm_mod |= (c->modrm & 0xc0) >> 6;
606 c->modrm_reg |= (c->modrm & 0x38) >> 3;
607 c->modrm_rm |= (c->modrm & 0x07);
608 c->modrm_ea = 0;
609 c->use_modrm_ea = 1;
610
611 if (c->modrm_mod == 3) {
612 c->modrm_val = *(unsigned long *)
613 decode_register(c->modrm_rm, c->regs, c->d & ByteOp);
614 return rc;
615 }
616
617 if (c->ad_bytes == 2) {
618 unsigned bx = c->regs[VCPU_REGS_RBX];
619 unsigned bp = c->regs[VCPU_REGS_RBP];
620 unsigned si = c->regs[VCPU_REGS_RSI];
621 unsigned di = c->regs[VCPU_REGS_RDI];
622
623 /* 16-bit ModR/M decode. */
624 switch (c->modrm_mod) {
625 case 0:
626 if (c->modrm_rm == 6)
627 c->modrm_ea += insn_fetch(u16, 2, c->eip);
628 break;
629 case 1:
630 c->modrm_ea += insn_fetch(s8, 1, c->eip);
631 break;
632 case 2:
633 c->modrm_ea += insn_fetch(u16, 2, c->eip);
634 break;
635 }
636 switch (c->modrm_rm) {
637 case 0:
638 c->modrm_ea += bx + si;
639 break;
640 case 1:
641 c->modrm_ea += bx + di;
642 break;
643 case 2:
644 c->modrm_ea += bp + si;
645 break;
646 case 3:
647 c->modrm_ea += bp + di;
648 break;
649 case 4:
650 c->modrm_ea += si;
651 break;
652 case 5:
653 c->modrm_ea += di;
654 break;
655 case 6:
656 if (c->modrm_mod != 0)
657 c->modrm_ea += bp;
658 break;
659 case 7:
660 c->modrm_ea += bx;
661 break;
662 }
663 if (c->modrm_rm == 2 || c->modrm_rm == 3 ||
664 (c->modrm_rm == 6 && c->modrm_mod != 0))
665 if (!c->override_base)
666 c->override_base = &ctxt->ss_base;
667 c->modrm_ea = (u16)c->modrm_ea;
668 } else {
669 /* 32/64-bit ModR/M decode. */
670 switch (c->modrm_rm) {
671 case 4:
672 case 12:
673 sib = insn_fetch(u8, 1, c->eip);
674 index_reg |= (sib >> 3) & 7;
675 base_reg |= sib & 7;
676 scale = sib >> 6;
677
678 switch (base_reg) {
679 case 5:
680 if (c->modrm_mod != 0)
681 c->modrm_ea += c->regs[base_reg];
682 else
683 c->modrm_ea +=
684 insn_fetch(s32, 4, c->eip);
685 break;
686 default:
687 c->modrm_ea += c->regs[base_reg];
688 }
689 switch (index_reg) {
690 case 4:
691 break;
692 default:
693 c->modrm_ea += c->regs[index_reg] << scale;
694 }
695 break;
696 case 5:
697 if (c->modrm_mod != 0)
698 c->modrm_ea += c->regs[c->modrm_rm];
699 else if (ctxt->mode == X86EMUL_MODE_PROT64)
700 rip_relative = 1;
701 break;
702 default:
703 c->modrm_ea += c->regs[c->modrm_rm];
704 break;
705 }
706 switch (c->modrm_mod) {
707 case 0:
708 if (c->modrm_rm == 5)
709 c->modrm_ea += insn_fetch(s32, 4, c->eip);
710 break;
711 case 1:
712 c->modrm_ea += insn_fetch(s8, 1, c->eip);
713 break;
714 case 2:
715 c->modrm_ea += insn_fetch(s32, 4, c->eip);
716 break;
717 }
718 }
719 if (rip_relative) {
720 c->modrm_ea += c->eip;
721 switch (c->d & SrcMask) {
722 case SrcImmByte:
723 c->modrm_ea += 1;
724 break;
725 case SrcImm:
726 if (c->d & ByteOp)
727 c->modrm_ea += 1;
728 else
729 if (c->op_bytes == 8)
730 c->modrm_ea += 4;
731 else
732 c->modrm_ea += c->op_bytes;
733 }
734 }
735done:
736 return rc;
737}
738
739static int decode_abs(struct x86_emulate_ctxt *ctxt,
740 struct x86_emulate_ops *ops)
741{
742 struct decode_cache *c = &ctxt->decode;
743 int rc = 0;
744
745 switch (c->ad_bytes) {
746 case 2:
747 c->modrm_ea = insn_fetch(u16, 2, c->eip);
748 break;
749 case 4:
750 c->modrm_ea = insn_fetch(u32, 4, c->eip);
751 break;
752 case 8:
753 c->modrm_ea = insn_fetch(u64, 8, c->eip);
754 break;
755 }
756done:
757 return rc;
758}
759
760int
761x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
762{
763 struct decode_cache *c = &ctxt->decode;
764 int rc = 0;
765 int mode = ctxt->mode;
766 int def_op_bytes, def_ad_bytes;
767
768 /* Shadow copy of register state. Committed on successful emulation. */
769
770 memset(c, 0, sizeof(struct decode_cache));
771 c->eip = ctxt->vcpu->arch.rip;
772 memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs);
773
774 switch (mode) {
775 case X86EMUL_MODE_REAL:
776 case X86EMUL_MODE_PROT16:
777 def_op_bytes = def_ad_bytes = 2;
778 break;
779 case X86EMUL_MODE_PROT32:
780 def_op_bytes = def_ad_bytes = 4;
781 break;
782#ifdef CONFIG_X86_64
783 case X86EMUL_MODE_PROT64:
784 def_op_bytes = 4;
785 def_ad_bytes = 8;
786 break;
787#endif
788 default:
789 return -1;
790 }
791
792 c->op_bytes = def_op_bytes;
793 c->ad_bytes = def_ad_bytes;
794
795 /* Legacy prefixes. */
796 for (;;) {
797 switch (c->b = insn_fetch(u8, 1, c->eip)) {
798 case 0x66: /* operand-size override */
799 /* switch between 2/4 bytes */
800 c->op_bytes = def_op_bytes ^ 6;
801 break;
802 case 0x67: /* address-size override */
803 if (mode == X86EMUL_MODE_PROT64)
804 /* switch between 4/8 bytes */
805 c->ad_bytes = def_ad_bytes ^ 12;
806 else
807 /* switch between 2/4 bytes */
808 c->ad_bytes = def_ad_bytes ^ 6;
809 break;
810 case 0x2e: /* CS override */
811 c->override_base = &ctxt->cs_base;
812 break;
813 case 0x3e: /* DS override */
814 c->override_base = &ctxt->ds_base;
815 break;
816 case 0x26: /* ES override */
817 c->override_base = &ctxt->es_base;
818 break;
819 case 0x64: /* FS override */
820 c->override_base = &ctxt->fs_base;
821 break;
822 case 0x65: /* GS override */
823 c->override_base = &ctxt->gs_base;
824 break;
825 case 0x36: /* SS override */
826 c->override_base = &ctxt->ss_base;
827 break;
828 case 0x40 ... 0x4f: /* REX */
829 if (mode != X86EMUL_MODE_PROT64)
830 goto done_prefixes;
831 c->rex_prefix = c->b;
832 continue;
833 case 0xf0: /* LOCK */
834 c->lock_prefix = 1;
835 break;
836 case 0xf2: /* REPNE/REPNZ */
837 c->rep_prefix = REPNE_PREFIX;
838 break;
839 case 0xf3: /* REP/REPE/REPZ */
840 c->rep_prefix = REPE_PREFIX;
841 break;
842 default:
843 goto done_prefixes;
844 }
845
846 /* Any legacy prefix after a REX prefix nullifies its effect. */
847
848 c->rex_prefix = 0;
849 }
850
851done_prefixes:
852
853 /* REX prefix. */
854 if (c->rex_prefix)
855 if (c->rex_prefix & 8)
856 c->op_bytes = 8; /* REX.W */
857
858 /* Opcode byte(s). */
859 c->d = opcode_table[c->b];
860 if (c->d == 0) {
861 /* Two-byte opcode? */
862 if (c->b == 0x0f) {
863 c->twobyte = 1;
864 c->b = insn_fetch(u8, 1, c->eip);
865 c->d = twobyte_table[c->b];
866 }
867
868 /* Unrecognised? */
869 if (c->d == 0) {
870 DPRINTF("Cannot emulate %02x\n", c->b);
871 return -1;
872 }
873 }
874
875 if (mode == X86EMUL_MODE_PROT64 && (c->d & Stack))
876 c->op_bytes = 8;
877
878 /* ModRM and SIB bytes. */
879 if (c->d & ModRM)
880 rc = decode_modrm(ctxt, ops);
881 else if (c->d & MemAbs)
882 rc = decode_abs(ctxt, ops);
883 if (rc)
884 goto done;
885
886 if (!c->override_base)
887 c->override_base = &ctxt->ds_base;
888 if (mode == X86EMUL_MODE_PROT64 &&
889 c->override_base != &ctxt->fs_base &&
890 c->override_base != &ctxt->gs_base)
891 c->override_base = NULL;
892
893 if (c->override_base)
894 c->modrm_ea += *c->override_base;
895
896 if (c->ad_bytes != 8)
897 c->modrm_ea = (u32)c->modrm_ea;
898 /*
899 * Decode and fetch the source operand: register, memory
900 * or immediate.
901 */
902 switch (c->d & SrcMask) {
903 case SrcNone:
904 break;
905 case SrcReg:
906 decode_register_operand(&c->src, c, 0);
907 break;
908 case SrcMem16:
909 c->src.bytes = 2;
910 goto srcmem_common;
911 case SrcMem32:
912 c->src.bytes = 4;
913 goto srcmem_common;
914 case SrcMem:
915 c->src.bytes = (c->d & ByteOp) ? 1 :
916 c->op_bytes;
917 /* Don't fetch the address for invlpg: it could be unmapped. */
918 if (c->twobyte && c->b == 0x01 && c->modrm_reg == 7)
919 break;
920 srcmem_common:
921 /*
922 * For instructions with a ModR/M byte, switch to register
923 * access if Mod = 3.
924 */
925 if ((c->d & ModRM) && c->modrm_mod == 3) {
926 c->src.type = OP_REG;
927 break;
928 }
929 c->src.type = OP_MEM;
930 break;
931 case SrcImm:
932 c->src.type = OP_IMM;
933 c->src.ptr = (unsigned long *)c->eip;
934 c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
935 if (c->src.bytes == 8)
936 c->src.bytes = 4;
937 /* NB. Immediates are sign-extended as necessary. */
938 switch (c->src.bytes) {
939 case 1:
940 c->src.val = insn_fetch(s8, 1, c->eip);
941 break;
942 case 2:
943 c->src.val = insn_fetch(s16, 2, c->eip);
944 break;
945 case 4:
946 c->src.val = insn_fetch(s32, 4, c->eip);
947 break;
948 }
949 break;
950 case SrcImmByte:
951 c->src.type = OP_IMM;
952 c->src.ptr = (unsigned long *)c->eip;
953 c->src.bytes = 1;
954 c->src.val = insn_fetch(s8, 1, c->eip);
955 break;
956 }
957
958 /* Decode and fetch the destination operand: register or memory. */
959 switch (c->d & DstMask) {
960 case ImplicitOps:
961 /* Special instructions do their own operand decoding. */
962 return 0;
963 case DstReg:
964 decode_register_operand(&c->dst, c,
965 c->twobyte && (c->b == 0xb6 || c->b == 0xb7));
966 break;
967 case DstMem:
968 if ((c->d & ModRM) && c->modrm_mod == 3) {
969 c->dst.type = OP_REG;
970 break;
971 }
972 c->dst.type = OP_MEM;
973 break;
974 }
975
976done:
977 return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0;
978}
979
980static inline void emulate_push(struct x86_emulate_ctxt *ctxt)
981{
982 struct decode_cache *c = &ctxt->decode;
983
984 c->dst.type = OP_MEM;
985 c->dst.bytes = c->op_bytes;
986 c->dst.val = c->src.val;
987 register_address_increment(c->regs[VCPU_REGS_RSP], -c->op_bytes);
988 c->dst.ptr = (void *) register_address(ctxt->ss_base,
989 c->regs[VCPU_REGS_RSP]);
990}
991
992static inline int emulate_grp1a(struct x86_emulate_ctxt *ctxt,
993 struct x86_emulate_ops *ops)
994{
995 struct decode_cache *c = &ctxt->decode;
996 int rc;
997
998 rc = ops->read_std(register_address(ctxt->ss_base,
999 c->regs[VCPU_REGS_RSP]),
1000 &c->dst.val, c->dst.bytes, ctxt->vcpu);
1001 if (rc != 0)
1002 return rc;
1003
1004 register_address_increment(c->regs[VCPU_REGS_RSP], c->dst.bytes);
1005
1006 return 0;
1007}
1008
1009static inline void emulate_grp2(struct x86_emulate_ctxt *ctxt)
1010{
1011 struct decode_cache *c = &ctxt->decode;
1012 switch (c->modrm_reg) {
1013 case 0: /* rol */
1014 emulate_2op_SrcB("rol", c->src, c->dst, ctxt->eflags);
1015 break;
1016 case 1: /* ror */
1017 emulate_2op_SrcB("ror", c->src, c->dst, ctxt->eflags);
1018 break;
1019 case 2: /* rcl */
1020 emulate_2op_SrcB("rcl", c->src, c->dst, ctxt->eflags);
1021 break;
1022 case 3: /* rcr */
1023 emulate_2op_SrcB("rcr", c->src, c->dst, ctxt->eflags);
1024 break;
1025 case 4: /* sal/shl */
1026 case 6: /* sal/shl */
1027 emulate_2op_SrcB("sal", c->src, c->dst, ctxt->eflags);
1028 break;
1029 case 5: /* shr */
1030 emulate_2op_SrcB("shr", c->src, c->dst, ctxt->eflags);
1031 break;
1032 case 7: /* sar */
1033 emulate_2op_SrcB("sar", c->src, c->dst, ctxt->eflags);
1034 break;
1035 }
1036}
1037
1038static inline int emulate_grp3(struct x86_emulate_ctxt *ctxt,
1039 struct x86_emulate_ops *ops)
1040{
1041 struct decode_cache *c = &ctxt->decode;
1042 int rc = 0;
1043
1044 switch (c->modrm_reg) {
1045 case 0 ... 1: /* test */
1046 /*
1047 * Special case in Grp3: test has an immediate
1048 * source operand.
1049 */
1050 c->src.type = OP_IMM;
1051 c->src.ptr = (unsigned long *)c->eip;
1052 c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
1053 if (c->src.bytes == 8)
1054 c->src.bytes = 4;
1055 switch (c->src.bytes) {
1056 case 1:
1057 c->src.val = insn_fetch(s8, 1, c->eip);
1058 break;
1059 case 2:
1060 c->src.val = insn_fetch(s16, 2, c->eip);
1061 break;
1062 case 4:
1063 c->src.val = insn_fetch(s32, 4, c->eip);
1064 break;
1065 }
1066 emulate_2op_SrcV("test", c->src, c->dst, ctxt->eflags);
1067 break;
1068 case 2: /* not */
1069 c->dst.val = ~c->dst.val;
1070 break;
1071 case 3: /* neg */
1072 emulate_1op("neg", c->dst, ctxt->eflags);
1073 break;
1074 default:
1075 DPRINTF("Cannot emulate %02x\n", c->b);
1076 rc = X86EMUL_UNHANDLEABLE;
1077 break;
1078 }
1079done:
1080 return rc;
1081}
1082
1083static inline int emulate_grp45(struct x86_emulate_ctxt *ctxt,
1084 struct x86_emulate_ops *ops)
1085{
1086 struct decode_cache *c = &ctxt->decode;
1087 int rc;
1088
1089 switch (c->modrm_reg) {
1090 case 0: /* inc */
1091 emulate_1op("inc", c->dst, ctxt->eflags);
1092 break;
1093 case 1: /* dec */
1094 emulate_1op("dec", c->dst, ctxt->eflags);
1095 break;
1096 case 4: /* jmp abs */
1097 if (c->b == 0xff)
1098 c->eip = c->dst.val;
1099 else {
1100 DPRINTF("Cannot emulate %02x\n", c->b);
1101 return X86EMUL_UNHANDLEABLE;
1102 }
1103 break;
1104 case 6: /* push */
1105
1106 /* 64-bit mode: PUSH always pushes a 64-bit operand. */
1107
1108 if (ctxt->mode == X86EMUL_MODE_PROT64) {
1109 c->dst.bytes = 8;
1110 rc = ops->read_std((unsigned long)c->dst.ptr,
1111 &c->dst.val, 8, ctxt->vcpu);
1112 if (rc != 0)
1113 return rc;
1114 }
1115 register_address_increment(c->regs[VCPU_REGS_RSP],
1116 -c->dst.bytes);
1117 rc = ops->write_emulated(register_address(ctxt->ss_base,
1118 c->regs[VCPU_REGS_RSP]), &c->dst.val,
1119 c->dst.bytes, ctxt->vcpu);
1120 if (rc != 0)
1121 return rc;
1122 c->dst.type = OP_NONE;
1123 break;
1124 default:
1125 DPRINTF("Cannot emulate %02x\n", c->b);
1126 return X86EMUL_UNHANDLEABLE;
1127 }
1128 return 0;
1129}
1130
1131static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt,
1132 struct x86_emulate_ops *ops,
1133 unsigned long memop)
1134{
1135 struct decode_cache *c = &ctxt->decode;
1136 u64 old, new;
1137 int rc;
1138
1139 rc = ops->read_emulated(memop, &old, 8, ctxt->vcpu);
1140 if (rc != 0)
1141 return rc;
1142
1143 if (((u32) (old >> 0) != (u32) c->regs[VCPU_REGS_RAX]) ||
1144 ((u32) (old >> 32) != (u32) c->regs[VCPU_REGS_RDX])) {
1145
1146 c->regs[VCPU_REGS_RAX] = (u32) (old >> 0);
1147 c->regs[VCPU_REGS_RDX] = (u32) (old >> 32);
1148 ctxt->eflags &= ~EFLG_ZF;
1149
1150 } else {
1151 new = ((u64)c->regs[VCPU_REGS_RCX] << 32) |
1152 (u32) c->regs[VCPU_REGS_RBX];
1153
1154 rc = ops->cmpxchg_emulated(memop, &old, &new, 8, ctxt->vcpu);
1155 if (rc != 0)
1156 return rc;
1157 ctxt->eflags |= EFLG_ZF;
1158 }
1159 return 0;
1160}
1161
1162static inline int writeback(struct x86_emulate_ctxt *ctxt,
1163 struct x86_emulate_ops *ops)
1164{
1165 int rc;
1166 struct decode_cache *c = &ctxt->decode;
1167
1168 switch (c->dst.type) {
1169 case OP_REG:
1170 /* The 4-byte case *is* correct:
1171 * in 64-bit mode we zero-extend.
1172 */
1173 switch (c->dst.bytes) {
1174 case 1:
1175 *(u8 *)c->dst.ptr = (u8)c->dst.val;
1176 break;
1177 case 2:
1178 *(u16 *)c->dst.ptr = (u16)c->dst.val;
1179 break;
1180 case 4:
1181 *c->dst.ptr = (u32)c->dst.val;
1182 break; /* 64b: zero-ext */
1183 case 8:
1184 *c->dst.ptr = c->dst.val;
1185 break;
1186 }
1187 break;
1188 case OP_MEM:
1189 if (c->lock_prefix)
1190 rc = ops->cmpxchg_emulated(
1191 (unsigned long)c->dst.ptr,
1192 &c->dst.orig_val,
1193 &c->dst.val,
1194 c->dst.bytes,
1195 ctxt->vcpu);
1196 else
1197 rc = ops->write_emulated(
1198 (unsigned long)c->dst.ptr,
1199 &c->dst.val,
1200 c->dst.bytes,
1201 ctxt->vcpu);
1202 if (rc != 0)
1203 return rc;
1204 break;
1205 case OP_NONE:
1206 /* no writeback */
1207 break;
1208 default:
1209 break;
1210 }
1211 return 0;
1212}
1213
1214int
1215x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
1216{
1217 unsigned long memop = 0;
1218 u64 msr_data;
1219 unsigned long saved_eip = 0;
1220 struct decode_cache *c = &ctxt->decode;
1221 int rc = 0;
1222
1223 /* Shadow copy of register state. Committed on successful emulation.
1224 * NOTE: we can copy them from vcpu as x86_decode_insn() doesn't
1225 * modify them.
1226 */
1227
1228 memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs);
1229 saved_eip = c->eip;
1230
1231 if (((c->d & ModRM) && (c->modrm_mod != 3)) || (c->d & MemAbs))
1232 memop = c->modrm_ea;
1233
1234 if (c->rep_prefix && (c->d & String)) {
1235 /* All REP prefixes have the same first termination condition */
1236 if (c->regs[VCPU_REGS_RCX] == 0) {
1237 ctxt->vcpu->arch.rip = c->eip;
1238 goto done;
1239 }
1240 /* The second termination condition only applies for REPE
1241 * and REPNE. Test if the repeat string operation prefix is
1242 * REPE/REPZ or REPNE/REPNZ and if it's the case it tests the
1243 * corresponding termination condition according to:
1244 * - if REPE/REPZ and ZF = 0 then done
1245 * - if REPNE/REPNZ and ZF = 1 then done
1246 */
1247 if ((c->b == 0xa6) || (c->b == 0xa7) ||
1248 (c->b == 0xae) || (c->b == 0xaf)) {
1249 if ((c->rep_prefix == REPE_PREFIX) &&
1250 ((ctxt->eflags & EFLG_ZF) == 0)) {
1251 ctxt->vcpu->arch.rip = c->eip;
1252 goto done;
1253 }
1254 if ((c->rep_prefix == REPNE_PREFIX) &&
1255 ((ctxt->eflags & EFLG_ZF) == EFLG_ZF)) {
1256 ctxt->vcpu->arch.rip = c->eip;
1257 goto done;
1258 }
1259 }
1260 c->regs[VCPU_REGS_RCX]--;
1261 c->eip = ctxt->vcpu->arch.rip;
1262 }
1263
1264 if (c->src.type == OP_MEM) {
1265 c->src.ptr = (unsigned long *)memop;
1266 c->src.val = 0;
1267 rc = ops->read_emulated((unsigned long)c->src.ptr,
1268 &c->src.val,
1269 c->src.bytes,
1270 ctxt->vcpu);
1271 if (rc != 0)
1272 goto done;
1273 c->src.orig_val = c->src.val;
1274 }
1275
1276 if ((c->d & DstMask) == ImplicitOps)
1277 goto special_insn;
1278
1279
1280 if (c->dst.type == OP_MEM) {
1281 c->dst.ptr = (unsigned long *)memop;
1282 c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
1283 c->dst.val = 0;
1284 if (c->d & BitOp) {
1285 unsigned long mask = ~(c->dst.bytes * 8 - 1);
1286
1287 c->dst.ptr = (void *)c->dst.ptr +
1288 (c->src.val & mask) / 8;
1289 }
1290 if (!(c->d & Mov) &&
1291 /* optimisation - avoid slow emulated read */
1292 ((rc = ops->read_emulated((unsigned long)c->dst.ptr,
1293 &c->dst.val,
1294 c->dst.bytes, ctxt->vcpu)) != 0))
1295 goto done;
1296 }
1297 c->dst.orig_val = c->dst.val;
1298
1299special_insn:
1300
1301 if (c->twobyte)
1302 goto twobyte_insn;
1303
1304 switch (c->b) {
1305 case 0x00 ... 0x05:
1306 add: /* add */
1307 emulate_2op_SrcV("add", c->src, c->dst, ctxt->eflags);
1308 break;
1309 case 0x08 ... 0x0d:
1310 or: /* or */
1311 emulate_2op_SrcV("or", c->src, c->dst, ctxt->eflags);
1312 break;
1313 case 0x10 ... 0x15:
1314 adc: /* adc */
1315 emulate_2op_SrcV("adc", c->src, c->dst, ctxt->eflags);
1316 break;
1317 case 0x18 ... 0x1d:
1318 sbb: /* sbb */
1319 emulate_2op_SrcV("sbb", c->src, c->dst, ctxt->eflags);
1320 break;
1321 case 0x20 ... 0x23:
1322 and: /* and */
1323 emulate_2op_SrcV("and", c->src, c->dst, ctxt->eflags);
1324 break;
1325 case 0x24: /* and al imm8 */
1326 c->dst.type = OP_REG;
1327 c->dst.ptr = &c->regs[VCPU_REGS_RAX];
1328 c->dst.val = *(u8 *)c->dst.ptr;
1329 c->dst.bytes = 1;
1330 c->dst.orig_val = c->dst.val;
1331 goto and;
1332 case 0x25: /* and ax imm16, or eax imm32 */
1333 c->dst.type = OP_REG;
1334 c->dst.bytes = c->op_bytes;
1335 c->dst.ptr = &c->regs[VCPU_REGS_RAX];
1336 if (c->op_bytes == 2)
1337 c->dst.val = *(u16 *)c->dst.ptr;
1338 else
1339 c->dst.val = *(u32 *)c->dst.ptr;
1340 c->dst.orig_val = c->dst.val;
1341 goto and;
1342 case 0x28 ... 0x2d:
1343 sub: /* sub */
1344 emulate_2op_SrcV("sub", c->src, c->dst, ctxt->eflags);
1345 break;
1346 case 0x30 ... 0x35:
1347 xor: /* xor */
1348 emulate_2op_SrcV("xor", c->src, c->dst, ctxt->eflags);
1349 break;
1350 case 0x38 ... 0x3d:
1351 cmp: /* cmp */
1352 emulate_2op_SrcV("cmp", c->src, c->dst, ctxt->eflags);
1353 break;
1354 case 0x40 ... 0x47: /* inc r16/r32 */
1355 emulate_1op("inc", c->dst, ctxt->eflags);
1356 break;
1357 case 0x48 ... 0x4f: /* dec r16/r32 */
1358 emulate_1op("dec", c->dst, ctxt->eflags);
1359 break;
1360 case 0x50 ... 0x57: /* push reg */
1361 c->dst.type = OP_MEM;
1362 c->dst.bytes = c->op_bytes;
1363 c->dst.val = c->src.val;
1364 register_address_increment(c->regs[VCPU_REGS_RSP],
1365 -c->op_bytes);
1366 c->dst.ptr = (void *) register_address(
1367 ctxt->ss_base, c->regs[VCPU_REGS_RSP]);
1368 break;
1369 case 0x58 ... 0x5f: /* pop reg */
1370 pop_instruction:
1371 if ((rc = ops->read_std(register_address(ctxt->ss_base,
1372 c->regs[VCPU_REGS_RSP]), c->dst.ptr,
1373 c->op_bytes, ctxt->vcpu)) != 0)
1374 goto done;
1375
1376 register_address_increment(c->regs[VCPU_REGS_RSP],
1377 c->op_bytes);
1378 c->dst.type = OP_NONE; /* Disable writeback. */
1379 break;
1380 case 0x63: /* movsxd */
1381 if (ctxt->mode != X86EMUL_MODE_PROT64)
1382 goto cannot_emulate;
1383 c->dst.val = (s32) c->src.val;
1384 break;
1385 case 0x6a: /* push imm8 */
1386 c->src.val = 0L;
1387 c->src.val = insn_fetch(s8, 1, c->eip);
1388 emulate_push(ctxt);
1389 break;
1390 case 0x6c: /* insb */
1391 case 0x6d: /* insw/insd */
1392 if (kvm_emulate_pio_string(ctxt->vcpu, NULL,
1393 1,
1394 (c->d & ByteOp) ? 1 : c->op_bytes,
1395 c->rep_prefix ?
1396 address_mask(c->regs[VCPU_REGS_RCX]) : 1,
1397 (ctxt->eflags & EFLG_DF),
1398 register_address(ctxt->es_base,
1399 c->regs[VCPU_REGS_RDI]),
1400 c->rep_prefix,
1401 c->regs[VCPU_REGS_RDX]) == 0) {
1402 c->eip = saved_eip;
1403 return -1;
1404 }
1405 return 0;
1406 case 0x6e: /* outsb */
1407 case 0x6f: /* outsw/outsd */
1408 if (kvm_emulate_pio_string(ctxt->vcpu, NULL,
1409 0,
1410 (c->d & ByteOp) ? 1 : c->op_bytes,
1411 c->rep_prefix ?
1412 address_mask(c->regs[VCPU_REGS_RCX]) : 1,
1413 (ctxt->eflags & EFLG_DF),
1414 register_address(c->override_base ?
1415 *c->override_base :
1416 ctxt->ds_base,
1417 c->regs[VCPU_REGS_RSI]),
1418 c->rep_prefix,
1419 c->regs[VCPU_REGS_RDX]) == 0) {
1420 c->eip = saved_eip;
1421 return -1;
1422 }
1423 return 0;
1424 case 0x70 ... 0x7f: /* jcc (short) */ {
1425 int rel = insn_fetch(s8, 1, c->eip);
1426
1427 if (test_cc(c->b, ctxt->eflags))
1428 JMP_REL(rel);
1429 break;
1430 }
1431 case 0x80 ... 0x83: /* Grp1 */
1432 switch (c->modrm_reg) {
1433 case 0:
1434 goto add;
1435 case 1:
1436 goto or;
1437 case 2:
1438 goto adc;
1439 case 3:
1440 goto sbb;
1441 case 4:
1442 goto and;
1443 case 5:
1444 goto sub;
1445 case 6:
1446 goto xor;
1447 case 7:
1448 goto cmp;
1449 }
1450 break;
1451 case 0x84 ... 0x85:
1452 emulate_2op_SrcV("test", c->src, c->dst, ctxt->eflags);
1453 break;
1454 case 0x86 ... 0x87: /* xchg */
1455 /* Write back the register source. */
1456 switch (c->dst.bytes) {
1457 case 1:
1458 *(u8 *) c->src.ptr = (u8) c->dst.val;
1459 break;
1460 case 2:
1461 *(u16 *) c->src.ptr = (u16) c->dst.val;
1462 break;
1463 case 4:
1464 *c->src.ptr = (u32) c->dst.val;
1465 break; /* 64b reg: zero-extend */
1466 case 8:
1467 *c->src.ptr = c->dst.val;
1468 break;
1469 }
1470 /*
1471 * Write back the memory destination with implicit LOCK
1472 * prefix.
1473 */
1474 c->dst.val = c->src.val;
1475 c->lock_prefix = 1;
1476 break;
1477 case 0x88 ... 0x8b: /* mov */
1478 goto mov;
1479 case 0x8d: /* lea r16/r32, m */
1480 c->dst.val = c->modrm_val;
1481 break;
1482 case 0x8f: /* pop (sole member of Grp1a) */
1483 rc = emulate_grp1a(ctxt, ops);
1484 if (rc != 0)
1485 goto done;
1486 break;
1487 case 0x9c: /* pushf */
1488 c->src.val = (unsigned long) ctxt->eflags;
1489 emulate_push(ctxt);
1490 break;
1491 case 0x9d: /* popf */
1492 c->dst.ptr = (unsigned long *) &ctxt->eflags;
1493 goto pop_instruction;
1494 case 0xa0 ... 0xa1: /* mov */
1495 c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX];
1496 c->dst.val = c->src.val;
1497 break;
1498 case 0xa2 ... 0xa3: /* mov */
1499 c->dst.val = (unsigned long)c->regs[VCPU_REGS_RAX];
1500 break;
1501 case 0xa4 ... 0xa5: /* movs */
1502 c->dst.type = OP_MEM;
1503 c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
1504 c->dst.ptr = (unsigned long *)register_address(
1505 ctxt->es_base,
1506 c->regs[VCPU_REGS_RDI]);
1507 if ((rc = ops->read_emulated(register_address(
1508 c->override_base ? *c->override_base :
1509 ctxt->ds_base,
1510 c->regs[VCPU_REGS_RSI]),
1511 &c->dst.val,
1512 c->dst.bytes, ctxt->vcpu)) != 0)
1513 goto done;
1514 register_address_increment(c->regs[VCPU_REGS_RSI],
1515 (ctxt->eflags & EFLG_DF) ? -c->dst.bytes
1516 : c->dst.bytes);
1517 register_address_increment(c->regs[VCPU_REGS_RDI],
1518 (ctxt->eflags & EFLG_DF) ? -c->dst.bytes
1519 : c->dst.bytes);
1520 break;
1521 case 0xa6 ... 0xa7: /* cmps */
1522 c->src.type = OP_NONE; /* Disable writeback. */
1523 c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
1524 c->src.ptr = (unsigned long *)register_address(
1525 c->override_base ? *c->override_base :
1526 ctxt->ds_base,
1527 c->regs[VCPU_REGS_RSI]);
1528 if ((rc = ops->read_emulated((unsigned long)c->src.ptr,
1529 &c->src.val,
1530 c->src.bytes,
1531 ctxt->vcpu)) != 0)
1532 goto done;
1533
1534 c->dst.type = OP_NONE; /* Disable writeback. */
1535 c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
1536 c->dst.ptr = (unsigned long *)register_address(
1537 ctxt->es_base,
1538 c->regs[VCPU_REGS_RDI]);
1539 if ((rc = ops->read_emulated((unsigned long)c->dst.ptr,
1540 &c->dst.val,
1541 c->dst.bytes,
1542 ctxt->vcpu)) != 0)
1543 goto done;
1544
1545 DPRINTF("cmps: mem1=0x%p mem2=0x%p\n", c->src.ptr, c->dst.ptr);
1546
1547 emulate_2op_SrcV("cmp", c->src, c->dst, ctxt->eflags);
1548
1549 register_address_increment(c->regs[VCPU_REGS_RSI],
1550 (ctxt->eflags & EFLG_DF) ? -c->src.bytes
1551 : c->src.bytes);
1552 register_address_increment(c->regs[VCPU_REGS_RDI],
1553 (ctxt->eflags & EFLG_DF) ? -c->dst.bytes
1554 : c->dst.bytes);
1555
1556 break;
1557 case 0xaa ... 0xab: /* stos */
1558 c->dst.type = OP_MEM;
1559 c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
1560 c->dst.ptr = (unsigned long *)register_address(
1561 ctxt->es_base,
1562 c->regs[VCPU_REGS_RDI]);
1563 c->dst.val = c->regs[VCPU_REGS_RAX];
1564 register_address_increment(c->regs[VCPU_REGS_RDI],
1565 (ctxt->eflags & EFLG_DF) ? -c->dst.bytes
1566 : c->dst.bytes);
1567 break;
1568 case 0xac ... 0xad: /* lods */
1569 c->dst.type = OP_REG;
1570 c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
1571 c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX];
1572 if ((rc = ops->read_emulated(register_address(
1573 c->override_base ? *c->override_base :
1574 ctxt->ds_base,
1575 c->regs[VCPU_REGS_RSI]),
1576 &c->dst.val,
1577 c->dst.bytes,
1578 ctxt->vcpu)) != 0)
1579 goto done;
1580 register_address_increment(c->regs[VCPU_REGS_RSI],
1581 (ctxt->eflags & EFLG_DF) ? -c->dst.bytes
1582 : c->dst.bytes);
1583 break;
1584 case 0xae ... 0xaf: /* scas */
1585 DPRINTF("Urk! I don't handle SCAS.\n");
1586 goto cannot_emulate;
1587 case 0xc0 ... 0xc1:
1588 emulate_grp2(ctxt);
1589 break;
1590 case 0xc3: /* ret */
1591 c->dst.ptr = &c->eip;
1592 goto pop_instruction;
1593 case 0xc6 ... 0xc7: /* mov (sole member of Grp11) */
1594 mov:
1595 c->dst.val = c->src.val;
1596 break;
1597 case 0xd0 ... 0xd1: /* Grp2 */
1598 c->src.val = 1;
1599 emulate_grp2(ctxt);
1600 break;
1601 case 0xd2 ... 0xd3: /* Grp2 */
1602 c->src.val = c->regs[VCPU_REGS_RCX];
1603 emulate_grp2(ctxt);
1604 break;
1605 case 0xe8: /* call (near) */ {
1606 long int rel;
1607 switch (c->op_bytes) {
1608 case 2:
1609 rel = insn_fetch(s16, 2, c->eip);
1610 break;
1611 case 4:
1612 rel = insn_fetch(s32, 4, c->eip);
1613 break;
1614 default:
1615 DPRINTF("Call: Invalid op_bytes\n");
1616 goto cannot_emulate;
1617 }
1618 c->src.val = (unsigned long) c->eip;
1619 JMP_REL(rel);
1620 c->op_bytes = c->ad_bytes;
1621 emulate_push(ctxt);
1622 break;
1623 }
1624 case 0xe9: /* jmp rel */
1625 case 0xeb: /* jmp rel short */
1626 JMP_REL(c->src.val);
1627 c->dst.type = OP_NONE; /* Disable writeback. */
1628 break;
1629 case 0xf4: /* hlt */
1630 ctxt->vcpu->arch.halt_request = 1;
1631 goto done;
1632 case 0xf5: /* cmc */
1633 /* complement carry flag from eflags reg */
1634 ctxt->eflags ^= EFLG_CF;
1635 c->dst.type = OP_NONE; /* Disable writeback. */
1636 break;
1637 case 0xf6 ... 0xf7: /* Grp3 */
1638 rc = emulate_grp3(ctxt, ops);
1639 if (rc != 0)
1640 goto done;
1641 break;
1642 case 0xf8: /* clc */
1643 ctxt->eflags &= ~EFLG_CF;
1644 c->dst.type = OP_NONE; /* Disable writeback. */
1645 break;
1646 case 0xfa: /* cli */
1647 ctxt->eflags &= ~X86_EFLAGS_IF;
1648 c->dst.type = OP_NONE; /* Disable writeback. */
1649 break;
1650 case 0xfb: /* sti */
1651 ctxt->eflags |= X86_EFLAGS_IF;
1652 c->dst.type = OP_NONE; /* Disable writeback. */
1653 break;
1654 case 0xfe ... 0xff: /* Grp4/Grp5 */
1655 rc = emulate_grp45(ctxt, ops);
1656 if (rc != 0)
1657 goto done;
1658 break;
1659 }
1660
1661writeback:
1662 rc = writeback(ctxt, ops);
1663 if (rc != 0)
1664 goto done;
1665
1666 /* Commit shadow register state. */
1667 memcpy(ctxt->vcpu->arch.regs, c->regs, sizeof c->regs);
1668 ctxt->vcpu->arch.rip = c->eip;
1669
1670done:
1671 if (rc == X86EMUL_UNHANDLEABLE) {
1672 c->eip = saved_eip;
1673 return -1;
1674 }
1675 return 0;
1676
1677twobyte_insn:
1678 switch (c->b) {
1679 case 0x01: /* lgdt, lidt, lmsw */
1680 switch (c->modrm_reg) {
1681 u16 size;
1682 unsigned long address;
1683
1684 case 0: /* vmcall */
1685 if (c->modrm_mod != 3 || c->modrm_rm != 1)
1686 goto cannot_emulate;
1687
1688 rc = kvm_fix_hypercall(ctxt->vcpu);
1689 if (rc)
1690 goto done;
1691
1692 kvm_emulate_hypercall(ctxt->vcpu);
1693 break;
1694 case 2: /* lgdt */
1695 rc = read_descriptor(ctxt, ops, c->src.ptr,
1696 &size, &address, c->op_bytes);
1697 if (rc)
1698 goto done;
1699 realmode_lgdt(ctxt->vcpu, size, address);
1700 break;
1701 case 3: /* lidt/vmmcall */
1702 if (c->modrm_mod == 3 && c->modrm_rm == 1) {
1703 rc = kvm_fix_hypercall(ctxt->vcpu);
1704 if (rc)
1705 goto done;
1706 kvm_emulate_hypercall(ctxt->vcpu);
1707 } else {
1708 rc = read_descriptor(ctxt, ops, c->src.ptr,
1709 &size, &address,
1710 c->op_bytes);
1711 if (rc)
1712 goto done;
1713 realmode_lidt(ctxt->vcpu, size, address);
1714 }
1715 break;
1716 case 4: /* smsw */
1717 if (c->modrm_mod != 3)
1718 goto cannot_emulate;
1719 *(u16 *)&c->regs[c->modrm_rm]
1720 = realmode_get_cr(ctxt->vcpu, 0);
1721 break;
1722 case 6: /* lmsw */
1723 if (c->modrm_mod != 3)
1724 goto cannot_emulate;
1725 realmode_lmsw(ctxt->vcpu, (u16)c->modrm_val,
1726 &ctxt->eflags);
1727 break;
1728 case 7: /* invlpg*/
1729 emulate_invlpg(ctxt->vcpu, memop);
1730 break;
1731 default:
1732 goto cannot_emulate;
1733 }
1734 /* Disable writeback. */
1735 c->dst.type = OP_NONE;
1736 break;
1737 case 0x06:
1738 emulate_clts(ctxt->vcpu);
1739 c->dst.type = OP_NONE;
1740 break;
1741 case 0x08: /* invd */
1742 case 0x09: /* wbinvd */
1743 case 0x0d: /* GrpP (prefetch) */
1744 case 0x18: /* Grp16 (prefetch/nop) */
1745 c->dst.type = OP_NONE;
1746 break;
1747 case 0x20: /* mov cr, reg */
1748 if (c->modrm_mod != 3)
1749 goto cannot_emulate;
1750 c->regs[c->modrm_rm] =
1751 realmode_get_cr(ctxt->vcpu, c->modrm_reg);
1752 c->dst.type = OP_NONE; /* no writeback */
1753 break;
1754 case 0x21: /* mov from dr to reg */
1755 if (c->modrm_mod != 3)
1756 goto cannot_emulate;
1757 rc = emulator_get_dr(ctxt, c->modrm_reg, &c->regs[c->modrm_rm]);
1758 if (rc)
1759 goto cannot_emulate;
1760 c->dst.type = OP_NONE; /* no writeback */
1761 break;
1762 case 0x22: /* mov reg, cr */
1763 if (c->modrm_mod != 3)
1764 goto cannot_emulate;
1765 realmode_set_cr(ctxt->vcpu,
1766 c->modrm_reg, c->modrm_val, &ctxt->eflags);
1767 c->dst.type = OP_NONE;
1768 break;
1769 case 0x23: /* mov from reg to dr */
1770 if (c->modrm_mod != 3)
1771 goto cannot_emulate;
1772 rc = emulator_set_dr(ctxt, c->modrm_reg,
1773 c->regs[c->modrm_rm]);
1774 if (rc)
1775 goto cannot_emulate;
1776 c->dst.type = OP_NONE; /* no writeback */
1777 break;
1778 case 0x30:
1779 /* wrmsr */
1780 msr_data = (u32)c->regs[VCPU_REGS_RAX]
1781 | ((u64)c->regs[VCPU_REGS_RDX] << 32);
1782 rc = kvm_set_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], msr_data);
1783 if (rc) {
1784 kvm_inject_gp(ctxt->vcpu, 0);
1785 c->eip = ctxt->vcpu->arch.rip;
1786 }
1787 rc = X86EMUL_CONTINUE;
1788 c->dst.type = OP_NONE;
1789 break;
1790 case 0x32:
1791 /* rdmsr */
1792 rc = kvm_get_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], &msr_data);
1793 if (rc) {
1794 kvm_inject_gp(ctxt->vcpu, 0);
1795 c->eip = ctxt->vcpu->arch.rip;
1796 } else {
1797 c->regs[VCPU_REGS_RAX] = (u32)msr_data;
1798 c->regs[VCPU_REGS_RDX] = msr_data >> 32;
1799 }
1800 rc = X86EMUL_CONTINUE;
1801 c->dst.type = OP_NONE;
1802 break;
1803 case 0x40 ... 0x4f: /* cmov */
1804 c->dst.val = c->dst.orig_val = c->src.val;
1805 if (!test_cc(c->b, ctxt->eflags))
1806 c->dst.type = OP_NONE; /* no writeback */
1807 break;
1808 case 0x80 ... 0x8f: /* jnz rel, etc*/ {
1809 long int rel;
1810
1811 switch (c->op_bytes) {
1812 case 2:
1813 rel = insn_fetch(s16, 2, c->eip);
1814 break;
1815 case 4:
1816 rel = insn_fetch(s32, 4, c->eip);
1817 break;
1818 case 8:
1819 rel = insn_fetch(s64, 8, c->eip);
1820 break;
1821 default:
1822 DPRINTF("jnz: Invalid op_bytes\n");
1823 goto cannot_emulate;
1824 }
1825 if (test_cc(c->b, ctxt->eflags))
1826 JMP_REL(rel);
1827 c->dst.type = OP_NONE;
1828 break;
1829 }
1830 case 0xa3:
1831 bt: /* bt */
1832 c->dst.type = OP_NONE;
1833 /* only subword offset */
1834 c->src.val &= (c->dst.bytes << 3) - 1;
1835 emulate_2op_SrcV_nobyte("bt", c->src, c->dst, ctxt->eflags);
1836 break;
1837 case 0xab:
1838 bts: /* bts */
1839 /* only subword offset */
1840 c->src.val &= (c->dst.bytes << 3) - 1;
1841 emulate_2op_SrcV_nobyte("bts", c->src, c->dst, ctxt->eflags);
1842 break;
1843 case 0xb0 ... 0xb1: /* cmpxchg */
1844 /*
1845 * Save real source value, then compare EAX against
1846 * destination.
1847 */
1848 c->src.orig_val = c->src.val;
1849 c->src.val = c->regs[VCPU_REGS_RAX];
1850 emulate_2op_SrcV("cmp", c->src, c->dst, ctxt->eflags);
1851 if (ctxt->eflags & EFLG_ZF) {
1852 /* Success: write back to memory. */
1853 c->dst.val = c->src.orig_val;
1854 } else {
1855 /* Failure: write the value we saw to EAX. */
1856 c->dst.type = OP_REG;
1857 c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX];
1858 }
1859 break;
1860 case 0xb3:
1861 btr: /* btr */
1862 /* only subword offset */
1863 c->src.val &= (c->dst.bytes << 3) - 1;
1864 emulate_2op_SrcV_nobyte("btr", c->src, c->dst, ctxt->eflags);
1865 break;
1866 case 0xb6 ... 0xb7: /* movzx */
1867 c->dst.bytes = c->op_bytes;
1868 c->dst.val = (c->d & ByteOp) ? (u8) c->src.val
1869 : (u16) c->src.val;
1870 break;
1871 case 0xba: /* Grp8 */
1872 switch (c->modrm_reg & 3) {
1873 case 0:
1874 goto bt;
1875 case 1:
1876 goto bts;
1877 case 2:
1878 goto btr;
1879 case 3:
1880 goto btc;
1881 }
1882 break;
1883 case 0xbb:
1884 btc: /* btc */
1885 /* only subword offset */
1886 c->src.val &= (c->dst.bytes << 3) - 1;
1887 emulate_2op_SrcV_nobyte("btc", c->src, c->dst, ctxt->eflags);
1888 break;
1889 case 0xbe ... 0xbf: /* movsx */
1890 c->dst.bytes = c->op_bytes;
1891 c->dst.val = (c->d & ByteOp) ? (s8) c->src.val :
1892 (s16) c->src.val;
1893 break;
1894 case 0xc3: /* movnti */
1895 c->dst.bytes = c->op_bytes;
1896 c->dst.val = (c->op_bytes == 4) ? (u32) c->src.val :
1897 (u64) c->src.val;
1898 break;
1899 case 0xc7: /* Grp9 (cmpxchg8b) */
1900 rc = emulate_grp9(ctxt, ops, memop);
1901 if (rc != 0)
1902 goto done;
1903 c->dst.type = OP_NONE;
1904 break;
1905 }
1906 goto writeback;
1907
1908cannot_emulate:
1909 DPRINTF("Cannot emulate %02x\n", c->b);
1910 c->eip = saved_eip;
1911 return -1;
1912}
diff --git a/arch/x86/lguest/Kconfig b/arch/x86/lguest/Kconfig
index 19626ace0f50..964dfa36d367 100644
--- a/arch/x86/lguest/Kconfig
+++ b/arch/x86/lguest/Kconfig
@@ -1,6 +1,7 @@
1config LGUEST_GUEST 1config LGUEST_GUEST
2 bool "Lguest guest support" 2 bool "Lguest guest support"
3 select PARAVIRT 3 select PARAVIRT
4 depends on X86_32
4 depends on !X86_PAE 5 depends on !X86_PAE
5 depends on !(X86_VISWS || X86_VOYAGER) 6 depends on !(X86_VISWS || X86_VOYAGER)
6 select VIRTIO 7 select VIRTIO
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index 92c56117eae5..5afdde4895dc 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -67,6 +67,7 @@
67#include <asm/mce.h> 67#include <asm/mce.h>
68#include <asm/io.h> 68#include <asm/io.h>
69#include <asm/i387.h> 69#include <asm/i387.h>
70#include <asm/reboot.h> /* for struct machine_ops */
70 71
71/*G:010 Welcome to the Guest! 72/*G:010 Welcome to the Guest!
72 * 73 *
@@ -175,8 +176,8 @@ static void lguest_leave_lazy_mode(void)
175 * check there when it wants to deliver an interrupt. 176 * check there when it wants to deliver an interrupt.
176 */ 177 */
177 178
178/* save_flags() is expected to return the processor state (ie. "eflags"). The 179/* save_flags() is expected to return the processor state (ie. "flags"). The
179 * eflags word contains all kind of stuff, but in practice Linux only cares 180 * flags word contains all kind of stuff, but in practice Linux only cares
180 * about the interrupt flag. Our "save_flags()" just returns that. */ 181 * about the interrupt flag. Our "save_flags()" just returns that. */
181static unsigned long save_fl(void) 182static unsigned long save_fl(void)
182{ 183{
@@ -217,19 +218,20 @@ static void irq_enable(void)
217 * address of the handler, and... well, who cares? The Guest just asks the 218 * address of the handler, and... well, who cares? The Guest just asks the
218 * Host to make the change anyway, because the Host controls the real IDT. 219 * Host to make the change anyway, because the Host controls the real IDT.
219 */ 220 */
220static void lguest_write_idt_entry(struct desc_struct *dt, 221static void lguest_write_idt_entry(gate_desc *dt,
221 int entrynum, u32 low, u32 high) 222 int entrynum, const gate_desc *g)
222{ 223{
224 u32 *desc = (u32 *)g;
223 /* Keep the local copy up to date. */ 225 /* Keep the local copy up to date. */
224 write_dt_entry(dt, entrynum, low, high); 226 native_write_idt_entry(dt, entrynum, g);
225 /* Tell Host about this new entry. */ 227 /* Tell Host about this new entry. */
226 hcall(LHCALL_LOAD_IDT_ENTRY, entrynum, low, high); 228 hcall(LHCALL_LOAD_IDT_ENTRY, entrynum, desc[0], desc[1]);
227} 229}
228 230
229/* Changing to a different IDT is very rare: we keep the IDT up-to-date every 231/* Changing to a different IDT is very rare: we keep the IDT up-to-date every
230 * time it is written, so we can simply loop through all entries and tell the 232 * time it is written, so we can simply loop through all entries and tell the
231 * Host about them. */ 233 * Host about them. */
232static void lguest_load_idt(const struct Xgt_desc_struct *desc) 234static void lguest_load_idt(const struct desc_ptr *desc)
233{ 235{
234 unsigned int i; 236 unsigned int i;
235 struct desc_struct *idt = (void *)desc->address; 237 struct desc_struct *idt = (void *)desc->address;
@@ -252,7 +254,7 @@ static void lguest_load_idt(const struct Xgt_desc_struct *desc)
252 * hypercall and use that repeatedly to load a new IDT. I don't think it 254 * hypercall and use that repeatedly to load a new IDT. I don't think it
253 * really matters, but wouldn't it be nice if they were the same? 255 * really matters, but wouldn't it be nice if they were the same?
254 */ 256 */
255static void lguest_load_gdt(const struct Xgt_desc_struct *desc) 257static void lguest_load_gdt(const struct desc_ptr *desc)
256{ 258{
257 BUG_ON((desc->size+1)/8 != GDT_ENTRIES); 259 BUG_ON((desc->size+1)/8 != GDT_ENTRIES);
258 hcall(LHCALL_LOAD_GDT, __pa(desc->address), GDT_ENTRIES, 0); 260 hcall(LHCALL_LOAD_GDT, __pa(desc->address), GDT_ENTRIES, 0);
@@ -261,10 +263,10 @@ static void lguest_load_gdt(const struct Xgt_desc_struct *desc)
261/* For a single GDT entry which changes, we do the lazy thing: alter our GDT, 263/* For a single GDT entry which changes, we do the lazy thing: alter our GDT,
262 * then tell the Host to reload the entire thing. This operation is so rare 264 * then tell the Host to reload the entire thing. This operation is so rare
263 * that this naive implementation is reasonable. */ 265 * that this naive implementation is reasonable. */
264static void lguest_write_gdt_entry(struct desc_struct *dt, 266static void lguest_write_gdt_entry(struct desc_struct *dt, int entrynum,
265 int entrynum, u32 low, u32 high) 267 const void *desc, int type)
266{ 268{
267 write_dt_entry(dt, entrynum, low, high); 269 native_write_gdt_entry(dt, entrynum, desc, type);
268 hcall(LHCALL_LOAD_GDT, __pa(dt), GDT_ENTRIES, 0); 270 hcall(LHCALL_LOAD_GDT, __pa(dt), GDT_ENTRIES, 0);
269} 271}
270 272
@@ -323,30 +325,30 @@ static void lguest_load_tr_desc(void)
323 * anyone (including userspace) can just use the raw "cpuid" instruction and 325 * anyone (including userspace) can just use the raw "cpuid" instruction and
324 * the Host won't even notice since it isn't privileged. So we try not to get 326 * the Host won't even notice since it isn't privileged. So we try not to get
325 * too worked up about it. */ 327 * too worked up about it. */
326static void lguest_cpuid(unsigned int *eax, unsigned int *ebx, 328static void lguest_cpuid(unsigned int *ax, unsigned int *bx,
327 unsigned int *ecx, unsigned int *edx) 329 unsigned int *cx, unsigned int *dx)
328{ 330{
329 int function = *eax; 331 int function = *ax;
330 332
331 native_cpuid(eax, ebx, ecx, edx); 333 native_cpuid(ax, bx, cx, dx);
332 switch (function) { 334 switch (function) {
333 case 1: /* Basic feature request. */ 335 case 1: /* Basic feature request. */
334 /* We only allow kernel to see SSE3, CMPXCHG16B and SSSE3 */ 336 /* We only allow kernel to see SSE3, CMPXCHG16B and SSSE3 */
335 *ecx &= 0x00002201; 337 *cx &= 0x00002201;
336 /* SSE, SSE2, FXSR, MMX, CMOV, CMPXCHG8B, FPU. */ 338 /* SSE, SSE2, FXSR, MMX, CMOV, CMPXCHG8B, FPU. */
337 *edx &= 0x07808101; 339 *dx &= 0x07808101;
338 /* The Host can do a nice optimization if it knows that the 340 /* The Host can do a nice optimization if it knows that the
339 * kernel mappings (addresses above 0xC0000000 or whatever 341 * kernel mappings (addresses above 0xC0000000 or whatever
340 * PAGE_OFFSET is set to) haven't changed. But Linux calls 342 * PAGE_OFFSET is set to) haven't changed. But Linux calls
341 * flush_tlb_user() for both user and kernel mappings unless 343 * flush_tlb_user() for both user and kernel mappings unless
342 * the Page Global Enable (PGE) feature bit is set. */ 344 * the Page Global Enable (PGE) feature bit is set. */
343 *edx |= 0x00002000; 345 *dx |= 0x00002000;
344 break; 346 break;
345 case 0x80000000: 347 case 0x80000000:
346 /* Futureproof this a little: if they ask how much extended 348 /* Futureproof this a little: if they ask how much extended
347 * processor information there is, limit it to known fields. */ 349 * processor information there is, limit it to known fields. */
348 if (*eax > 0x80000008) 350 if (*ax > 0x80000008)
349 *eax = 0x80000008; 351 *ax = 0x80000008;
350 break; 352 break;
351 } 353 }
352} 354}
@@ -755,10 +757,10 @@ static void lguest_time_init(void)
755 * segment), the privilege level (we're privilege level 1, the Host is 0 and 757 * segment), the privilege level (we're privilege level 1, the Host is 0 and
756 * will not tolerate us trying to use that), the stack pointer, and the number 758 * will not tolerate us trying to use that), the stack pointer, and the number
757 * of pages in the stack. */ 759 * of pages in the stack. */
758static void lguest_load_esp0(struct tss_struct *tss, 760static void lguest_load_sp0(struct tss_struct *tss,
759 struct thread_struct *thread) 761 struct thread_struct *thread)
760{ 762{
761 lazy_hcall(LHCALL_SET_STACK, __KERNEL_DS|0x1, thread->esp0, 763 lazy_hcall(LHCALL_SET_STACK, __KERNEL_DS|0x1, thread->sp0,
762 THREAD_SIZE/PAGE_SIZE); 764 THREAD_SIZE/PAGE_SIZE);
763} 765}
764 766
@@ -788,11 +790,11 @@ static void lguest_wbinvd(void)
788 * code qualifies for Advanced. It will also never interrupt anything. It 790 * code qualifies for Advanced. It will also never interrupt anything. It
789 * does, however, allow us to get through the Linux boot code. */ 791 * does, however, allow us to get through the Linux boot code. */
790#ifdef CONFIG_X86_LOCAL_APIC 792#ifdef CONFIG_X86_LOCAL_APIC
791static void lguest_apic_write(unsigned long reg, unsigned long v) 793static void lguest_apic_write(unsigned long reg, u32 v)
792{ 794{
793} 795}
794 796
795static unsigned long lguest_apic_read(unsigned long reg) 797static u32 lguest_apic_read(unsigned long reg)
796{ 798{
797 return 0; 799 return 0;
798} 800}
@@ -812,7 +814,7 @@ static void lguest_safe_halt(void)
812 * rather than virtual addresses, so we use __pa() here. */ 814 * rather than virtual addresses, so we use __pa() here. */
813static void lguest_power_off(void) 815static void lguest_power_off(void)
814{ 816{
815 hcall(LHCALL_CRASH, __pa("Power down"), 0, 0); 817 hcall(LHCALL_SHUTDOWN, __pa("Power down"), LGUEST_SHUTDOWN_POWEROFF, 0);
816} 818}
817 819
818/* 820/*
@@ -822,7 +824,7 @@ static void lguest_power_off(void)
822 */ 824 */
823static int lguest_panic(struct notifier_block *nb, unsigned long l, void *p) 825static int lguest_panic(struct notifier_block *nb, unsigned long l, void *p)
824{ 826{
825 hcall(LHCALL_CRASH, __pa(p), 0, 0); 827 hcall(LHCALL_SHUTDOWN, __pa(p), LGUEST_SHUTDOWN_POWEROFF, 0);
826 /* The hcall won't return, but to keep gcc happy, we're "done". */ 828 /* The hcall won't return, but to keep gcc happy, we're "done". */
827 return NOTIFY_DONE; 829 return NOTIFY_DONE;
828} 830}
@@ -926,6 +928,11 @@ static unsigned lguest_patch(u8 type, u16 clobber, void *ibuf,
926 return insn_len; 928 return insn_len;
927} 929}
928 930
931static void lguest_restart(char *reason)
932{
933 hcall(LHCALL_SHUTDOWN, __pa(reason), LGUEST_SHUTDOWN_RESTART, 0);
934}
935
929/*G:030 Once we get to lguest_init(), we know we're a Guest. The pv_ops 936/*G:030 Once we get to lguest_init(), we know we're a Guest. The pv_ops
930 * structures in the kernel provide points for (almost) every routine we have 937 * structures in the kernel provide points for (almost) every routine we have
931 * to override to avoid privileged instructions. */ 938 * to override to avoid privileged instructions. */
@@ -957,7 +964,7 @@ __init void lguest_init(void)
957 pv_cpu_ops.cpuid = lguest_cpuid; 964 pv_cpu_ops.cpuid = lguest_cpuid;
958 pv_cpu_ops.load_idt = lguest_load_idt; 965 pv_cpu_ops.load_idt = lguest_load_idt;
959 pv_cpu_ops.iret = lguest_iret; 966 pv_cpu_ops.iret = lguest_iret;
960 pv_cpu_ops.load_esp0 = lguest_load_esp0; 967 pv_cpu_ops.load_sp0 = lguest_load_sp0;
961 pv_cpu_ops.load_tr_desc = lguest_load_tr_desc; 968 pv_cpu_ops.load_tr_desc = lguest_load_tr_desc;
962 pv_cpu_ops.set_ldt = lguest_set_ldt; 969 pv_cpu_ops.set_ldt = lguest_set_ldt;
963 pv_cpu_ops.load_tls = lguest_load_tls; 970 pv_cpu_ops.load_tls = lguest_load_tls;
@@ -1059,6 +1066,7 @@ __init void lguest_init(void)
1059 * the Guest routine to power off. */ 1066 * the Guest routine to power off. */
1060 pm_power_off = lguest_power_off; 1067 pm_power_off = lguest_power_off;
1061 1068
1069 machine_ops.restart = lguest_restart;
1062 /* Now we're set up, call start_kernel() in init/main.c and we proceed 1070 /* Now we're set up, call start_kernel() in init/main.c and we proceed
1063 * to boot as normal. It never returns. */ 1071 * to boot as normal. It never returns. */
1064 start_kernel(); 1072 start_kernel();
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index 329da276c6f1..4876182daf8a 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -1,5 +1,27 @@
1#
2# Makefile for x86 specific library files.
3#
4
5obj-$(CONFIG_SMP) := msr-on-cpu.o
6
7lib-y := delay_$(BITS).o
8lib-y += usercopy_$(BITS).o getuser_$(BITS).o putuser_$(BITS).o
9lib-y += memcpy_$(BITS).o
10
1ifeq ($(CONFIG_X86_32),y) 11ifeq ($(CONFIG_X86_32),y)
2include ${srctree}/arch/x86/lib/Makefile_32 12 lib-y += checksum_32.o
13 lib-y += strstr_32.o
14 lib-y += bitops_32.o semaphore_32.o string_32.o
15
16 lib-$(CONFIG_X86_USE_3DNOW) += mmx_32.o
3else 17else
4include ${srctree}/arch/x86/lib/Makefile_64 18 obj-y += io_64.o iomap_copy_64.o
19
20 CFLAGS_csum-partial_64.o := -funroll-loops
21
22 lib-y += csum-partial_64.o csum-copy_64.o csum-wrappers_64.o
23 lib-y += thunk_64.o clear_page_64.o copy_page_64.o
24 lib-y += bitstr_64.o bitops_64.o
25 lib-y += memmove_64.o memset_64.o
26 lib-y += copy_user_64.o rwlock_64.o copy_user_nocache_64.o
5endif 27endif
diff --git a/arch/x86/lib/Makefile_32 b/arch/x86/lib/Makefile_32
deleted file mode 100644
index 98d1f1e2e2ef..000000000000
--- a/arch/x86/lib/Makefile_32
+++ /dev/null
@@ -1,11 +0,0 @@
1#
2# Makefile for i386-specific library files..
3#
4
5
6lib-y = checksum_32.o delay_32.o usercopy_32.o getuser_32.o putuser_32.o memcpy_32.o strstr_32.o \
7 bitops_32.o semaphore_32.o string_32.o
8
9lib-$(CONFIG_X86_USE_3DNOW) += mmx_32.o
10
11obj-$(CONFIG_SMP) += msr-on-cpu.o
diff --git a/arch/x86/lib/Makefile_64 b/arch/x86/lib/Makefile_64
deleted file mode 100644
index bbabad3c9335..000000000000
--- a/arch/x86/lib/Makefile_64
+++ /dev/null
@@ -1,13 +0,0 @@
1#
2# Makefile for x86_64-specific library files.
3#
4
5CFLAGS_csum-partial_64.o := -funroll-loops
6
7obj-y := io_64.o iomap_copy_64.o
8obj-$(CONFIG_SMP) += msr-on-cpu.o
9
10lib-y := csum-partial_64.o csum-copy_64.o csum-wrappers_64.o delay_64.o \
11 usercopy_64.o getuser_64.o putuser_64.o \
12 thunk_64.o clear_page_64.o copy_page_64.o bitstr_64.o bitops_64.o
13lib-y += memcpy_64.o memmove_64.o memset_64.o copy_user_64.o rwlock_64.o copy_user_nocache_64.o
diff --git a/arch/x86/lib/memcpy_32.c b/arch/x86/lib/memcpy_32.c
index 8ac51b82a632..37756b6fb329 100644
--- a/arch/x86/lib/memcpy_32.c
+++ b/arch/x86/lib/memcpy_32.c
@@ -34,8 +34,8 @@ void *memmove(void *dest, const void *src, size_t n)
34 "cld" 34 "cld"
35 : "=&c" (d0), "=&S" (d1), "=&D" (d2) 35 : "=&c" (d0), "=&S" (d1), "=&D" (d2)
36 :"0" (n), 36 :"0" (n),
37 "1" (n-1+(const char *)src), 37 "1" (n-1+src),
38 "2" (n-1+(char *)dest) 38 "2" (n-1+dest)
39 :"memory"); 39 :"memory");
40 } 40 }
41 return dest; 41 return dest;
diff --git a/arch/x86/lib/memmove_64.c b/arch/x86/lib/memmove_64.c
index 751ebae8ec42..80175e47b190 100644
--- a/arch/x86/lib/memmove_64.c
+++ b/arch/x86/lib/memmove_64.c
@@ -11,8 +11,8 @@ void *memmove(void * dest,const void *src,size_t count)
11 if (dest < src) { 11 if (dest < src) {
12 return memcpy(dest,src,count); 12 return memcpy(dest,src,count);
13 } else { 13 } else {
14 char *p = (char *) dest + count; 14 char *p = dest + count;
15 char *s = (char *) src + count; 15 const char *s = src + count;
16 while (count--) 16 while (count--)
17 *--p = *--s; 17 *--p = *--s;
18 } 18 }
diff --git a/arch/x86/lib/semaphore_32.S b/arch/x86/lib/semaphore_32.S
index 444fba400983..3899bd37fdf0 100644
--- a/arch/x86/lib/semaphore_32.S
+++ b/arch/x86/lib/semaphore_32.S
@@ -29,7 +29,7 @@
29 * registers (%eax, %edx and %ecx) except %eax whish is either a return 29 * registers (%eax, %edx and %ecx) except %eax whish is either a return
30 * value or just clobbered.. 30 * value or just clobbered..
31 */ 31 */
32 .section .sched.text 32 .section .sched.text, "ax"
33ENTRY(__down_failed) 33ENTRY(__down_failed)
34 CFI_STARTPROC 34 CFI_STARTPROC
35 FRAME 35 FRAME
@@ -49,7 +49,7 @@ ENTRY(__down_failed)
49 ENDFRAME 49 ENDFRAME
50 ret 50 ret
51 CFI_ENDPROC 51 CFI_ENDPROC
52 END(__down_failed) 52 ENDPROC(__down_failed)
53 53
54ENTRY(__down_failed_interruptible) 54ENTRY(__down_failed_interruptible)
55 CFI_STARTPROC 55 CFI_STARTPROC
@@ -70,7 +70,7 @@ ENTRY(__down_failed_interruptible)
70 ENDFRAME 70 ENDFRAME
71 ret 71 ret
72 CFI_ENDPROC 72 CFI_ENDPROC
73 END(__down_failed_interruptible) 73 ENDPROC(__down_failed_interruptible)
74 74
75ENTRY(__down_failed_trylock) 75ENTRY(__down_failed_trylock)
76 CFI_STARTPROC 76 CFI_STARTPROC
@@ -91,7 +91,7 @@ ENTRY(__down_failed_trylock)
91 ENDFRAME 91 ENDFRAME
92 ret 92 ret
93 CFI_ENDPROC 93 CFI_ENDPROC
94 END(__down_failed_trylock) 94 ENDPROC(__down_failed_trylock)
95 95
96ENTRY(__up_wakeup) 96ENTRY(__up_wakeup)
97 CFI_STARTPROC 97 CFI_STARTPROC
@@ -112,7 +112,7 @@ ENTRY(__up_wakeup)
112 ENDFRAME 112 ENDFRAME
113 ret 113 ret
114 CFI_ENDPROC 114 CFI_ENDPROC
115 END(__up_wakeup) 115 ENDPROC(__up_wakeup)
116 116
117/* 117/*
118 * rw spinlock fallbacks 118 * rw spinlock fallbacks
@@ -132,7 +132,7 @@ ENTRY(__write_lock_failed)
132 ENDFRAME 132 ENDFRAME
133 ret 133 ret
134 CFI_ENDPROC 134 CFI_ENDPROC
135 END(__write_lock_failed) 135 ENDPROC(__write_lock_failed)
136 136
137ENTRY(__read_lock_failed) 137ENTRY(__read_lock_failed)
138 CFI_STARTPROC 138 CFI_STARTPROC
@@ -148,7 +148,7 @@ ENTRY(__read_lock_failed)
148 ENDFRAME 148 ENDFRAME
149 ret 149 ret
150 CFI_ENDPROC 150 CFI_ENDPROC
151 END(__read_lock_failed) 151 ENDPROC(__read_lock_failed)
152 152
153#endif 153#endif
154 154
@@ -170,7 +170,7 @@ ENTRY(call_rwsem_down_read_failed)
170 CFI_ADJUST_CFA_OFFSET -4 170 CFI_ADJUST_CFA_OFFSET -4
171 ret 171 ret
172 CFI_ENDPROC 172 CFI_ENDPROC
173 END(call_rwsem_down_read_failed) 173 ENDPROC(call_rwsem_down_read_failed)
174 174
175ENTRY(call_rwsem_down_write_failed) 175ENTRY(call_rwsem_down_write_failed)
176 CFI_STARTPROC 176 CFI_STARTPROC
@@ -182,7 +182,7 @@ ENTRY(call_rwsem_down_write_failed)
182 CFI_ADJUST_CFA_OFFSET -4 182 CFI_ADJUST_CFA_OFFSET -4
183 ret 183 ret
184 CFI_ENDPROC 184 CFI_ENDPROC
185 END(call_rwsem_down_write_failed) 185 ENDPROC(call_rwsem_down_write_failed)
186 186
187ENTRY(call_rwsem_wake) 187ENTRY(call_rwsem_wake)
188 CFI_STARTPROC 188 CFI_STARTPROC
@@ -196,7 +196,7 @@ ENTRY(call_rwsem_wake)
196 CFI_ADJUST_CFA_OFFSET -4 196 CFI_ADJUST_CFA_OFFSET -4
1971: ret 1971: ret
198 CFI_ENDPROC 198 CFI_ENDPROC
199 END(call_rwsem_wake) 199 ENDPROC(call_rwsem_wake)
200 200
201/* Fix up special calling conventions */ 201/* Fix up special calling conventions */
202ENTRY(call_rwsem_downgrade_wake) 202ENTRY(call_rwsem_downgrade_wake)
@@ -214,6 +214,6 @@ ENTRY(call_rwsem_downgrade_wake)
214 CFI_ADJUST_CFA_OFFSET -4 214 CFI_ADJUST_CFA_OFFSET -4
215 ret 215 ret
216 CFI_ENDPROC 216 CFI_ENDPROC
217 END(call_rwsem_downgrade_wake) 217 ENDPROC(call_rwsem_downgrade_wake)
218 218
219#endif 219#endif
diff --git a/arch/x86/lib/thunk_64.S b/arch/x86/lib/thunk_64.S
index 6ea73f3de567..8b92d428ab02 100644
--- a/arch/x86/lib/thunk_64.S
+++ b/arch/x86/lib/thunk_64.S
@@ -33,7 +33,7 @@
33 .endm 33 .endm
34 34
35 35
36 .section .sched.text 36 .section .sched.text, "ax"
37#ifdef CONFIG_RWSEM_XCHGADD_ALGORITHM 37#ifdef CONFIG_RWSEM_XCHGADD_ALGORITHM
38 thunk rwsem_down_read_failed_thunk,rwsem_down_read_failed 38 thunk rwsem_down_read_failed_thunk,rwsem_down_read_failed
39 thunk rwsem_down_write_failed_thunk,rwsem_down_write_failed 39 thunk rwsem_down_write_failed_thunk,rwsem_down_write_failed
diff --git a/arch/x86/mach-rdc321x/Makefile b/arch/x86/mach-rdc321x/Makefile
new file mode 100644
index 000000000000..1faac8125e3d
--- /dev/null
+++ b/arch/x86/mach-rdc321x/Makefile
@@ -0,0 +1,5 @@
1#
2# Makefile for the RDC321x specific parts of the kernel
3#
4obj-$(CONFIG_X86_RDC321X) := gpio.o platform.o wdt.o
5
diff --git a/arch/x86/mach-rdc321x/gpio.c b/arch/x86/mach-rdc321x/gpio.c
new file mode 100644
index 000000000000..031269163bd6
--- /dev/null
+++ b/arch/x86/mach-rdc321x/gpio.c
@@ -0,0 +1,91 @@
1/*
2 * Copyright (C) 2007, OpenWrt.org, Florian Fainelli <florian@openwrt.org>
3 * RDC321x architecture specific GPIO support
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 */
10
11#include <linux/autoconf.h>
12#include <linux/init.h>
13#include <linux/io.h>
14#include <linux/types.h>
15#include <linux/module.h>
16#include <linux/delay.h>
17
18#include <asm/mach-rdc321x/rdc321x_defs.h>
19
20static inline int rdc_gpio_is_valid(unsigned gpio)
21{
22 return (gpio <= RDC_MAX_GPIO);
23}
24
25static unsigned int rdc_gpio_read(unsigned gpio)
26{
27 unsigned int val;
28
29 val = 0x80000000 | (7 << 11) | ((gpio&0x20?0x84:0x48));
30 outl(val, RDC3210_CFGREG_ADDR);
31 udelay(10);
32 val = inl(RDC3210_CFGREG_DATA);
33 val |= (0x1 << (gpio & 0x1F));
34 outl(val, RDC3210_CFGREG_DATA);
35 udelay(10);
36 val = 0x80000000 | (7 << 11) | ((gpio&0x20?0x88:0x4C));
37 outl(val, RDC3210_CFGREG_ADDR);
38 udelay(10);
39 val = inl(RDC3210_CFGREG_DATA);
40
41 return val;
42}
43
44static void rdc_gpio_write(unsigned int val)
45{
46 if (val) {
47 outl(val, RDC3210_CFGREG_DATA);
48 udelay(10);
49 }
50}
51
52int rdc_gpio_get_value(unsigned gpio)
53{
54 if (rdc_gpio_is_valid(gpio))
55 return (int)rdc_gpio_read(gpio);
56 else
57 return -EINVAL;
58}
59EXPORT_SYMBOL(rdc_gpio_get_value);
60
61void rdc_gpio_set_value(unsigned gpio, int value)
62{
63 unsigned int val;
64
65 if (!rdc_gpio_is_valid(gpio))
66 return;
67
68 val = rdc_gpio_read(gpio);
69
70 if (value)
71 val &= ~(0x1 << (gpio & 0x1F));
72 else
73 val |= (0x1 << (gpio & 0x1F));
74
75 rdc_gpio_write(val);
76}
77EXPORT_SYMBOL(rdc_gpio_set_value);
78
79int rdc_gpio_direction_input(unsigned gpio)
80{
81 return 0;
82}
83EXPORT_SYMBOL(rdc_gpio_direction_input);
84
85int rdc_gpio_direction_output(unsigned gpio, int value)
86{
87 return 0;
88}
89EXPORT_SYMBOL(rdc_gpio_direction_output);
90
91
diff --git a/arch/x86/mach-rdc321x/platform.c b/arch/x86/mach-rdc321x/platform.c
new file mode 100644
index 000000000000..dda6024a5862
--- /dev/null
+++ b/arch/x86/mach-rdc321x/platform.c
@@ -0,0 +1,68 @@
1/*
2 * Generic RDC321x platform devices
3 *
4 * Copyright (C) 2007 Florian Fainelli <florian@openwrt.org>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 *
21 */
22
23#include <linux/init.h>
24#include <linux/kernel.h>
25#include <linux/list.h>
26#include <linux/device.h>
27#include <linux/platform_device.h>
28#include <linux/version.h>
29#include <linux/leds.h>
30
31#include <asm/gpio.h>
32
33/* LEDS */
34static struct gpio_led default_leds[] = {
35 { .name = "rdc:dmz", .gpio = 1, },
36};
37
38static struct gpio_led_platform_data rdc321x_led_data = {
39 .num_leds = ARRAY_SIZE(default_leds),
40 .leds = default_leds,
41};
42
43static struct platform_device rdc321x_leds = {
44 .name = "leds-gpio",
45 .id = -1,
46 .dev = {
47 .platform_data = &rdc321x_led_data,
48 }
49};
50
51/* Watchdog */
52static struct platform_device rdc321x_wdt = {
53 .name = "rdc321x-wdt",
54 .id = -1,
55 .num_resources = 0,
56};
57
58static struct platform_device *rdc321x_devs[] = {
59 &rdc321x_leds,
60 &rdc321x_wdt
61};
62
63static int __init rdc_board_setup(void)
64{
65 return platform_add_devices(rdc321x_devs, ARRAY_SIZE(rdc321x_devs));
66}
67
68arch_initcall(rdc_board_setup);
diff --git a/arch/x86/mach-rdc321x/wdt.c b/arch/x86/mach-rdc321x/wdt.c
new file mode 100644
index 000000000000..ec5625ae7061
--- /dev/null
+++ b/arch/x86/mach-rdc321x/wdt.c
@@ -0,0 +1,275 @@
1/*
2 * RDC321x watchdog driver
3 *
4 * Copyright (C) 2007 Florian Fainelli <florian@openwrt.org>
5 *
6 * This driver is highly inspired from the cpu5_wdt driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 */
23
24#include <linux/module.h>
25#include <linux/moduleparam.h>
26#include <linux/types.h>
27#include <linux/errno.h>
28#include <linux/miscdevice.h>
29#include <linux/fs.h>
30#include <linux/init.h>
31#include <linux/ioport.h>
32#include <linux/timer.h>
33#include <linux/completion.h>
34#include <linux/jiffies.h>
35#include <linux/platform_device.h>
36#include <linux/watchdog.h>
37#include <linux/io.h>
38#include <linux/uaccess.h>
39
40#include <asm/mach-rdc321x/rdc321x_defs.h>
41
42#define RDC_WDT_MASK 0x80000000 /* Mask */
43#define RDC_WDT_EN 0x00800000 /* Enable bit */
44#define RDC_WDT_WTI 0x00200000 /* Generate CPU reset/NMI/WDT on timeout */
45#define RDC_WDT_RST 0x00100000 /* Reset bit */
46#define RDC_WDT_WIF 0x00040000 /* WDT IRQ Flag */
47#define RDC_WDT_IRT 0x00000100 /* IRQ Routing table */
48#define RDC_WDT_CNT 0x00000001 /* WDT count */
49
50#define RDC_CLS_TMR 0x80003844 /* Clear timer */
51
52#define RDC_WDT_INTERVAL (HZ/10+1)
53
54int nowayout = WATCHDOG_NOWAYOUT;
55module_param(nowayout, int, 0);
56MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
57
58static int ticks = 1000;
59
60/* some device data */
61
62static struct {
63 struct completion stop;
64 volatile int running;
65 struct timer_list timer;
66 volatile int queue;
67 int default_ticks;
68 unsigned long inuse;
69} rdc321x_wdt_device;
70
71/* generic helper functions */
72
73static void rdc321x_wdt_trigger(unsigned long unused)
74{
75 if (rdc321x_wdt_device.running)
76 ticks--;
77
78 /* keep watchdog alive */
79 outl(RDC_WDT_EN|inl(RDC3210_CFGREG_DATA), RDC3210_CFGREG_DATA);
80
81 /* requeue?? */
82 if (rdc321x_wdt_device.queue && ticks)
83 mod_timer(&rdc321x_wdt_device.timer,
84 jiffies + RDC_WDT_INTERVAL);
85 else {
86 /* ticks doesn't matter anyway */
87 complete(&rdc321x_wdt_device.stop);
88 }
89
90}
91
92static void rdc321x_wdt_reset(void)
93{
94 ticks = rdc321x_wdt_device.default_ticks;
95}
96
97static void rdc321x_wdt_start(void)
98{
99 if (!rdc321x_wdt_device.queue) {
100 rdc321x_wdt_device.queue = 1;
101
102 /* Clear the timer */
103 outl(RDC_CLS_TMR, RDC3210_CFGREG_ADDR);
104
105 /* Enable watchdog and set the timeout to 81.92 us */
106 outl(RDC_WDT_EN|RDC_WDT_CNT, RDC3210_CFGREG_DATA);
107
108 mod_timer(&rdc321x_wdt_device.timer,
109 jiffies + RDC_WDT_INTERVAL);
110 }
111
112 /* if process dies, counter is not decremented */
113 rdc321x_wdt_device.running++;
114}
115
116static int rdc321x_wdt_stop(void)
117{
118 if (rdc321x_wdt_device.running)
119 rdc321x_wdt_device.running = 0;
120
121 ticks = rdc321x_wdt_device.default_ticks;
122
123 return -EIO;
124}
125
126/* filesystem operations */
127
128static int rdc321x_wdt_open(struct inode *inode, struct file *file)
129{
130 if (test_and_set_bit(0, &rdc321x_wdt_device.inuse))
131 return -EBUSY;
132
133 return nonseekable_open(inode, file);
134}
135
136static int rdc321x_wdt_release(struct inode *inode, struct file *file)
137{
138 clear_bit(0, &rdc321x_wdt_device.inuse);
139 return 0;
140}
141
142static int rdc321x_wdt_ioctl(struct inode *inode, struct file *file,
143 unsigned int cmd, unsigned long arg)
144{
145 void __user *argp = (void __user *)arg;
146 unsigned int value;
147 static struct watchdog_info ident = {
148 .options = WDIOF_CARDRESET,
149 .identity = "RDC321x WDT",
150 };
151
152 switch (cmd) {
153 case WDIOC_KEEPALIVE:
154 rdc321x_wdt_reset();
155 break;
156 case WDIOC_GETSTATUS:
157 /* Read the value from the DATA register */
158 value = inl(RDC3210_CFGREG_DATA);
159 if (copy_to_user(argp, &value, sizeof(int)))
160 return -EFAULT;
161 break;
162 case WDIOC_GETSUPPORT:
163 if (copy_to_user(argp, &ident, sizeof(ident)))
164 return -EFAULT;
165 break;
166 case WDIOC_SETOPTIONS:
167 if (copy_from_user(&value, argp, sizeof(int)))
168 return -EFAULT;
169 switch (value) {
170 case WDIOS_ENABLECARD:
171 rdc321x_wdt_start();
172 break;
173 case WDIOS_DISABLECARD:
174 return rdc321x_wdt_stop();
175 default:
176 return -EINVAL;
177 }
178 break;
179 default:
180 return -ENOTTY;
181 }
182 return 0;
183}
184
185static ssize_t rdc321x_wdt_write(struct file *file, const char __user *buf,
186 size_t count, loff_t *ppos)
187{
188 if (!count)
189 return -EIO;
190
191 rdc321x_wdt_reset();
192
193 return count;
194}
195
196static const struct file_operations rdc321x_wdt_fops = {
197 .owner = THIS_MODULE,
198 .llseek = no_llseek,
199 .ioctl = rdc321x_wdt_ioctl,
200 .open = rdc321x_wdt_open,
201 .write = rdc321x_wdt_write,
202 .release = rdc321x_wdt_release,
203};
204
205static struct miscdevice rdc321x_wdt_misc = {
206 .minor = WATCHDOG_MINOR,
207 .name = "watchdog",
208 .fops = &rdc321x_wdt_fops,
209};
210
211static int __devinit rdc321x_wdt_probe(struct platform_device *pdev)
212{
213 int err;
214
215 err = misc_register(&rdc321x_wdt_misc);
216 if (err < 0) {
217 printk(KERN_ERR PFX "watchdog misc_register failed\n");
218 return err;
219 }
220
221 /* Reset the watchdog */
222 outl(RDC_WDT_RST, RDC3210_CFGREG_DATA);
223
224 init_completion(&rdc321x_wdt_device.stop);
225 rdc321x_wdt_device.queue = 0;
226
227 clear_bit(0, &rdc321x_wdt_device.inuse);
228
229 setup_timer(&rdc321x_wdt_device.timer, rdc321x_wdt_trigger, 0);
230
231 rdc321x_wdt_device.default_ticks = ticks;
232
233 printk(KERN_INFO PFX "watchdog init success\n");
234
235 return 0;
236}
237
238static int rdc321x_wdt_remove(struct platform_device *pdev)
239{
240 if (rdc321x_wdt_device.queue) {
241 rdc321x_wdt_device.queue = 0;
242 wait_for_completion(&rdc321x_wdt_device.stop);
243 }
244
245 misc_deregister(&rdc321x_wdt_misc);
246
247 return 0;
248}
249
250static struct platform_driver rdc321x_wdt_driver = {
251 .probe = rdc321x_wdt_probe,
252 .remove = rdc321x_wdt_remove,
253 .driver = {
254 .owner = THIS_MODULE,
255 .name = "rdc321x-wdt",
256 },
257};
258
259static int __init rdc321x_wdt_init(void)
260{
261 return platform_driver_register(&rdc321x_wdt_driver);
262}
263
264static void __exit rdc321x_wdt_exit(void)
265{
266 platform_driver_unregister(&rdc321x_wdt_driver);
267}
268
269module_init(rdc321x_wdt_init);
270module_exit(rdc321x_wdt_exit);
271
272MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
273MODULE_DESCRIPTION("RDC321x watchdog driver");
274MODULE_LICENSE("GPL");
275MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/arch/x86/mach-visws/mpparse.c b/arch/x86/mach-visws/mpparse.c
index f3c74fab8b95..2a8456a1f44f 100644
--- a/arch/x86/mach-visws/mpparse.c
+++ b/arch/x86/mach-visws/mpparse.c
@@ -36,19 +36,19 @@ unsigned int __initdata maxcpus = NR_CPUS;
36 36
37static void __init MP_processor_info (struct mpc_config_processor *m) 37static void __init MP_processor_info (struct mpc_config_processor *m)
38{ 38{
39 int ver, logical_apicid; 39 int ver, logical_apicid;
40 physid_mask_t apic_cpus; 40 physid_mask_t apic_cpus;
41 41
42 if (!(m->mpc_cpuflag & CPU_ENABLED)) 42 if (!(m->mpc_cpuflag & CPU_ENABLED))
43 return; 43 return;
44 44
45 logical_apicid = m->mpc_apicid; 45 logical_apicid = m->mpc_apicid;
46 printk(KERN_INFO "%sCPU #%d %ld:%ld APIC version %d\n", 46 printk(KERN_INFO "%sCPU #%d %u:%u APIC version %d\n",
47 m->mpc_cpuflag & CPU_BOOTPROCESSOR ? "Bootup " : "", 47 m->mpc_cpuflag & CPU_BOOTPROCESSOR ? "Bootup " : "",
48 m->mpc_apicid, 48 m->mpc_apicid,
49 (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8, 49 (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8,
50 (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4, 50 (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4,
51 m->mpc_apicver); 51 m->mpc_apicver);
52 52
53 if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) 53 if (m->mpc_cpuflag & CPU_BOOTPROCESSOR)
54 boot_cpu_physical_apicid = m->mpc_apicid; 54 boot_cpu_physical_apicid = m->mpc_apicid;
diff --git a/arch/x86/mach-voyager/setup.c b/arch/x86/mach-voyager/setup.c
index 3bef977cb29b..5ae5466b9eb9 100644
--- a/arch/x86/mach-voyager/setup.c
+++ b/arch/x86/mach-voyager/setup.c
@@ -37,14 +37,14 @@ void __init pre_setup_arch_hook(void)
37{ 37{
38 /* Voyagers run their CPUs from independent clocks, so disable 38 /* Voyagers run their CPUs from independent clocks, so disable
39 * the TSC code because we can't sync them */ 39 * the TSC code because we can't sync them */
40 tsc_disable = 1; 40 setup_clear_cpu_cap(X86_FEATURE_TSC);
41} 41}
42 42
43void __init trap_init_hook(void) 43void __init trap_init_hook(void)
44{ 44{
45} 45}
46 46
47static struct irqaction irq0 = { 47static struct irqaction irq0 = {
48 .handler = timer_interrupt, 48 .handler = timer_interrupt,
49 .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL, 49 .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL,
50 .mask = CPU_MASK_NONE, 50 .mask = CPU_MASK_NONE,
@@ -59,44 +59,47 @@ void __init time_init_hook(void)
59 59
60/* Hook for machine specific memory setup. */ 60/* Hook for machine specific memory setup. */
61 61
62char * __init machine_specific_memory_setup(void) 62char *__init machine_specific_memory_setup(void)
63{ 63{
64 char *who; 64 char *who;
65 65
66 who = "NOT VOYAGER"; 66 who = "NOT VOYAGER";
67 67
68 if(voyager_level == 5) { 68 if (voyager_level == 5) {
69 __u32 addr, length; 69 __u32 addr, length;
70 int i; 70 int i;
71 71
72 who = "Voyager-SUS"; 72 who = "Voyager-SUS";
73 73
74 e820.nr_map = 0; 74 e820.nr_map = 0;
75 for(i=0; voyager_memory_detect(i, &addr, &length); i++) { 75 for (i = 0; voyager_memory_detect(i, &addr, &length); i++) {
76 add_memory_region(addr, length, E820_RAM); 76 add_memory_region(addr, length, E820_RAM);
77 } 77 }
78 return who; 78 return who;
79 } else if(voyager_level == 4) { 79 } else if (voyager_level == 4) {
80 __u32 tom; 80 __u32 tom;
81 __u16 catbase = inb(VOYAGER_SSPB_RELOCATION_PORT)<<8; 81 __u16 catbase = inb(VOYAGER_SSPB_RELOCATION_PORT) << 8;
82 /* select the DINO config space */ 82 /* select the DINO config space */
83 outb(VOYAGER_DINO, VOYAGER_CAT_CONFIG_PORT); 83 outb(VOYAGER_DINO, VOYAGER_CAT_CONFIG_PORT);
84 /* Read DINO top of memory register */ 84 /* Read DINO top of memory register */
85 tom = ((inb(catbase + 0x4) & 0xf0) << 16) 85 tom = ((inb(catbase + 0x4) & 0xf0) << 16)
86 + ((inb(catbase + 0x5) & 0x7f) << 24); 86 + ((inb(catbase + 0x5) & 0x7f) << 24);
87 87
88 if(inb(catbase) != VOYAGER_DINO) { 88 if (inb(catbase) != VOYAGER_DINO) {
89 printk(KERN_ERR "Voyager: Failed to get DINO for L4, setting tom to EXT_MEM_K\n"); 89 printk(KERN_ERR
90 tom = (boot_params.screen_info.ext_mem_k)<<10; 90 "Voyager: Failed to get DINO for L4, setting tom to EXT_MEM_K\n");
91 tom = (boot_params.screen_info.ext_mem_k) << 10;
91 } 92 }
92 who = "Voyager-TOM"; 93 who = "Voyager-TOM";
93 add_memory_region(0, 0x9f000, E820_RAM); 94 add_memory_region(0, 0x9f000, E820_RAM);
94 /* map from 1M to top of memory */ 95 /* map from 1M to top of memory */
95 add_memory_region(1*1024*1024, tom - 1*1024*1024, E820_RAM); 96 add_memory_region(1 * 1024 * 1024, tom - 1 * 1024 * 1024,
97 E820_RAM);
96 /* FIXME: Should check the ASICs to see if I need to 98 /* FIXME: Should check the ASICs to see if I need to
97 * take out the 8M window. Just do it at the moment 99 * take out the 8M window. Just do it at the moment
98 * */ 100 * */
99 add_memory_region(8*1024*1024, 8*1024*1024, E820_RESERVED); 101 add_memory_region(8 * 1024 * 1024, 8 * 1024 * 1024,
102 E820_RESERVED);
100 return who; 103 return who;
101 } 104 }
102 105
@@ -114,8 +117,7 @@ char * __init machine_specific_memory_setup(void)
114 unsigned long mem_size; 117 unsigned long mem_size;
115 118
116 /* compare results from other methods and take the greater */ 119 /* compare results from other methods and take the greater */
117 if (boot_params.alt_mem_k 120 if (boot_params.alt_mem_k < boot_params.screen_info.ext_mem_k) {
118 < boot_params.screen_info.ext_mem_k) {
119 mem_size = boot_params.screen_info.ext_mem_k; 121 mem_size = boot_params.screen_info.ext_mem_k;
120 who = "BIOS-88"; 122 who = "BIOS-88";
121 } else { 123 } else {
@@ -126,6 +128,6 @@ char * __init machine_specific_memory_setup(void)
126 e820.nr_map = 0; 128 e820.nr_map = 0;
127 add_memory_region(0, LOWMEMSIZE(), E820_RAM); 129 add_memory_region(0, LOWMEMSIZE(), E820_RAM);
128 add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM); 130 add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM);
129 } 131 }
130 return who; 132 return who;
131} 133}
diff --git a/arch/x86/mach-voyager/voyager_basic.c b/arch/x86/mach-voyager/voyager_basic.c
index 9b77b39b71a6..6a949e4edde8 100644
--- a/arch/x86/mach-voyager/voyager_basic.c
+++ b/arch/x86/mach-voyager/voyager_basic.c
@@ -35,7 +35,7 @@
35/* 35/*
36 * Power off function, if any 36 * Power off function, if any
37 */ 37 */
38void (*pm_power_off)(void); 38void (*pm_power_off) (void);
39EXPORT_SYMBOL(pm_power_off); 39EXPORT_SYMBOL(pm_power_off);
40 40
41int voyager_level = 0; 41int voyager_level = 0;
@@ -43,39 +43,38 @@ int voyager_level = 0;
43struct voyager_SUS *voyager_SUS = NULL; 43struct voyager_SUS *voyager_SUS = NULL;
44 44
45#ifdef CONFIG_SMP 45#ifdef CONFIG_SMP
46static void 46static void voyager_dump(int dummy1, struct tty_struct *dummy3)
47voyager_dump(int dummy1, struct tty_struct *dummy3)
48{ 47{
49 /* get here via a sysrq */ 48 /* get here via a sysrq */
50 voyager_smp_dump(); 49 voyager_smp_dump();
51} 50}
52 51
53static struct sysrq_key_op sysrq_voyager_dump_op = { 52static struct sysrq_key_op sysrq_voyager_dump_op = {
54 .handler = voyager_dump, 53 .handler = voyager_dump,
55 .help_msg = "Voyager", 54 .help_msg = "Voyager",
56 .action_msg = "Dump Voyager Status", 55 .action_msg = "Dump Voyager Status",
57}; 56};
58#endif 57#endif
59 58
60void 59void voyager_detect(struct voyager_bios_info *bios)
61voyager_detect(struct voyager_bios_info *bios)
62{ 60{
63 if(bios->len != 0xff) { 61 if (bios->len != 0xff) {
64 int class = (bios->class_1 << 8) 62 int class = (bios->class_1 << 8)
65 | (bios->class_2 & 0xff); 63 | (bios->class_2 & 0xff);
66 64
67 printk("Voyager System detected.\n" 65 printk("Voyager System detected.\n"
68 " Class %x, Revision %d.%d\n", 66 " Class %x, Revision %d.%d\n",
69 class, bios->major, bios->minor); 67 class, bios->major, bios->minor);
70 if(class == VOYAGER_LEVEL4) 68 if (class == VOYAGER_LEVEL4)
71 voyager_level = 4; 69 voyager_level = 4;
72 else if(class < VOYAGER_LEVEL5_AND_ABOVE) 70 else if (class < VOYAGER_LEVEL5_AND_ABOVE)
73 voyager_level = 3; 71 voyager_level = 3;
74 else 72 else
75 voyager_level = 5; 73 voyager_level = 5;
76 printk(" Architecture Level %d\n", voyager_level); 74 printk(" Architecture Level %d\n", voyager_level);
77 if(voyager_level < 4) 75 if (voyager_level < 4)
78 printk("\n**WARNING**: Voyager HAL only supports Levels 4 and 5 Architectures at the moment\n\n"); 76 printk
77 ("\n**WARNING**: Voyager HAL only supports Levels 4 and 5 Architectures at the moment\n\n");
79 /* install the power off handler */ 78 /* install the power off handler */
80 pm_power_off = voyager_power_off; 79 pm_power_off = voyager_power_off;
81#ifdef CONFIG_SMP 80#ifdef CONFIG_SMP
@@ -86,15 +85,13 @@ voyager_detect(struct voyager_bios_info *bios)
86 } 85 }
87} 86}
88 87
89void 88void voyager_system_interrupt(int cpl, void *dev_id)
90voyager_system_interrupt(int cpl, void *dev_id)
91{ 89{
92 printk("Voyager: detected system interrupt\n"); 90 printk("Voyager: detected system interrupt\n");
93} 91}
94 92
95/* Routine to read information from the extended CMOS area */ 93/* Routine to read information from the extended CMOS area */
96__u8 94__u8 voyager_extended_cmos_read(__u16 addr)
97voyager_extended_cmos_read(__u16 addr)
98{ 95{
99 outb(addr & 0xff, 0x74); 96 outb(addr & 0xff, 0x74);
100 outb((addr >> 8) & 0xff, 0x75); 97 outb((addr >> 8) & 0xff, 0x75);
@@ -108,12 +105,11 @@ voyager_extended_cmos_read(__u16 addr)
108 105
109typedef struct ClickMap { 106typedef struct ClickMap {
110 struct Entry { 107 struct Entry {
111 __u32 Address; 108 __u32 Address;
112 __u32 Length; 109 __u32 Length;
113 } Entry[CLICK_ENTRIES]; 110 } Entry[CLICK_ENTRIES];
114} ClickMap_t; 111} ClickMap_t;
115 112
116
117/* This routine is pretty much an awful hack to read the bios clickmap by 113/* This routine is pretty much an awful hack to read the bios clickmap by
118 * mapping it into page 0. There are usually three regions in the map: 114 * mapping it into page 0. There are usually three regions in the map:
119 * Base Memory 115 * Base Memory
@@ -122,8 +118,7 @@ typedef struct ClickMap {
122 * 118 *
123 * Returns are 0 for failure and 1 for success on extracting region. 119 * Returns are 0 for failure and 1 for success on extracting region.
124 */ 120 */
125int __init 121int __init voyager_memory_detect(int region, __u32 * start, __u32 * length)
126voyager_memory_detect(int region, __u32 *start, __u32 *length)
127{ 122{
128 int i; 123 int i;
129 int retval = 0; 124 int retval = 0;
@@ -132,13 +127,14 @@ voyager_memory_detect(int region, __u32 *start, __u32 *length)
132 unsigned long map_addr; 127 unsigned long map_addr;
133 unsigned long old; 128 unsigned long old;
134 129
135 if(region >= CLICK_ENTRIES) { 130 if (region >= CLICK_ENTRIES) {
136 printk("Voyager: Illegal ClickMap region %d\n", region); 131 printk("Voyager: Illegal ClickMap region %d\n", region);
137 return 0; 132 return 0;
138 } 133 }
139 134
140 for(i = 0; i < sizeof(cmos); i++) 135 for (i = 0; i < sizeof(cmos); i++)
141 cmos[i] = voyager_extended_cmos_read(VOYAGER_MEMORY_CLICKMAP + i); 136 cmos[i] =
137 voyager_extended_cmos_read(VOYAGER_MEMORY_CLICKMAP + i);
142 138
143 map_addr = *(unsigned long *)cmos; 139 map_addr = *(unsigned long *)cmos;
144 140
@@ -147,10 +143,10 @@ voyager_memory_detect(int region, __u32 *start, __u32 *length)
147 pg0[0] = ((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT); 143 pg0[0] = ((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
148 local_flush_tlb(); 144 local_flush_tlb();
149 /* now clear everything out but page 0 */ 145 /* now clear everything out but page 0 */
150 map = (ClickMap_t *)(map_addr & (~PAGE_MASK)); 146 map = (ClickMap_t *) (map_addr & (~PAGE_MASK));
151 147
152 /* zero length is the end of the clickmap */ 148 /* zero length is the end of the clickmap */
153 if(map->Entry[region].Length != 0) { 149 if (map->Entry[region].Length != 0) {
154 *length = map->Entry[region].Length * CLICK_SIZE; 150 *length = map->Entry[region].Length * CLICK_SIZE;
155 *start = map->Entry[region].Address; 151 *start = map->Entry[region].Address;
156 retval = 1; 152 retval = 1;
@@ -165,10 +161,9 @@ voyager_memory_detect(int region, __u32 *start, __u32 *length)
165/* voyager specific handling code for timer interrupts. Used to hand 161/* voyager specific handling code for timer interrupts. Used to hand
166 * off the timer tick to the SMP code, since the VIC doesn't have an 162 * off the timer tick to the SMP code, since the VIC doesn't have an
167 * internal timer (The QIC does, but that's another story). */ 163 * internal timer (The QIC does, but that's another story). */
168void 164void voyager_timer_interrupt(void)
169voyager_timer_interrupt(void)
170{ 165{
171 if((jiffies & 0x3ff) == 0) { 166 if ((jiffies & 0x3ff) == 0) {
172 167
173 /* There seems to be something flaky in either 168 /* There seems to be something flaky in either
174 * hardware or software that is resetting the timer 0 169 * hardware or software that is resetting the timer 0
@@ -186,18 +181,20 @@ voyager_timer_interrupt(void)
186 __u16 val; 181 __u16 val;
187 182
188 spin_lock(&i8253_lock); 183 spin_lock(&i8253_lock);
189 184
190 outb_p(0x00, 0x43); 185 outb_p(0x00, 0x43);
191 val = inb_p(0x40); 186 val = inb_p(0x40);
192 val |= inb(0x40) << 8; 187 val |= inb(0x40) << 8;
193 spin_unlock(&i8253_lock); 188 spin_unlock(&i8253_lock);
194 189
195 if(val > LATCH) { 190 if (val > LATCH) {
196 printk("\nVOYAGER: countdown timer value too high (%d), resetting\n\n", val); 191 printk
192 ("\nVOYAGER: countdown timer value too high (%d), resetting\n\n",
193 val);
197 spin_lock(&i8253_lock); 194 spin_lock(&i8253_lock);
198 outb(0x34,0x43); 195 outb(0x34, 0x43);
199 outb_p(LATCH & 0xff , 0x40); /* LSB */ 196 outb_p(LATCH & 0xff, 0x40); /* LSB */
200 outb(LATCH >> 8 , 0x40); /* MSB */ 197 outb(LATCH >> 8, 0x40); /* MSB */
201 spin_unlock(&i8253_lock); 198 spin_unlock(&i8253_lock);
202 } 199 }
203 } 200 }
@@ -206,14 +203,13 @@ voyager_timer_interrupt(void)
206#endif 203#endif
207} 204}
208 205
209void 206void voyager_power_off(void)
210voyager_power_off(void)
211{ 207{
212 printk("VOYAGER Power Off\n"); 208 printk("VOYAGER Power Off\n");
213 209
214 if(voyager_level == 5) { 210 if (voyager_level == 5) {
215 voyager_cat_power_off(); 211 voyager_cat_power_off();
216 } else if(voyager_level == 4) { 212 } else if (voyager_level == 4) {
217 /* This doesn't apparently work on most L4 machines, 213 /* This doesn't apparently work on most L4 machines,
218 * but the specs say to do this to get automatic power 214 * but the specs say to do this to get automatic power
219 * off. Unfortunately, if it doesn't power off the 215 * off. Unfortunately, if it doesn't power off the
@@ -222,10 +218,8 @@ voyager_power_off(void)
222#if 0 218#if 0
223 int port; 219 int port;
224 220
225
226 /* enable the voyager Configuration Space */ 221 /* enable the voyager Configuration Space */
227 outb((inb(VOYAGER_MC_SETUP) & 0xf0) | 0x8, 222 outb((inb(VOYAGER_MC_SETUP) & 0xf0) | 0x8, VOYAGER_MC_SETUP);
228 VOYAGER_MC_SETUP);
229 /* the port for the power off flag is an offset from the 223 /* the port for the power off flag is an offset from the
230 floating base */ 224 floating base */
231 port = (inb(VOYAGER_SSPB_RELOCATION_PORT) << 8) + 0x21; 225 port = (inb(VOYAGER_SSPB_RELOCATION_PORT) << 8) + 0x21;
@@ -235,62 +229,57 @@ voyager_power_off(void)
235 } 229 }
236 /* and wait for it to happen */ 230 /* and wait for it to happen */
237 local_irq_disable(); 231 local_irq_disable();
238 for(;;) 232 for (;;)
239 halt(); 233 halt();
240} 234}
241 235
242/* copied from process.c */ 236/* copied from process.c */
243static inline void 237static inline void kb_wait(void)
244kb_wait(void)
245{ 238{
246 int i; 239 int i;
247 240
248 for (i=0; i<0x10000; i++) 241 for (i = 0; i < 0x10000; i++)
249 if ((inb_p(0x64) & 0x02) == 0) 242 if ((inb_p(0x64) & 0x02) == 0)
250 break; 243 break;
251} 244}
252 245
253void 246void machine_shutdown(void)
254machine_shutdown(void)
255{ 247{
256 /* Architecture specific shutdown needed before a kexec */ 248 /* Architecture specific shutdown needed before a kexec */
257} 249}
258 250
259void 251void machine_restart(char *cmd)
260machine_restart(char *cmd)
261{ 252{
262 printk("Voyager Warm Restart\n"); 253 printk("Voyager Warm Restart\n");
263 kb_wait(); 254 kb_wait();
264 255
265 if(voyager_level == 5) { 256 if (voyager_level == 5) {
266 /* write magic values to the RTC to inform system that 257 /* write magic values to the RTC to inform system that
267 * shutdown is beginning */ 258 * shutdown is beginning */
268 outb(0x8f, 0x70); 259 outb(0x8f, 0x70);
269 outb(0x5 , 0x71); 260 outb(0x5, 0x71);
270 261
271 udelay(50); 262 udelay(50);
272 outb(0xfe,0x64); /* pull reset low */ 263 outb(0xfe, 0x64); /* pull reset low */
273 } else if(voyager_level == 4) { 264 } else if (voyager_level == 4) {
274 __u16 catbase = inb(VOYAGER_SSPB_RELOCATION_PORT)<<8; 265 __u16 catbase = inb(VOYAGER_SSPB_RELOCATION_PORT) << 8;
275 __u8 basebd = inb(VOYAGER_MC_SETUP); 266 __u8 basebd = inb(VOYAGER_MC_SETUP);
276 267
277 outb(basebd | 0x08, VOYAGER_MC_SETUP); 268 outb(basebd | 0x08, VOYAGER_MC_SETUP);
278 outb(0x02, catbase + 0x21); 269 outb(0x02, catbase + 0x21);
279 } 270 }
280 local_irq_disable(); 271 local_irq_disable();
281 for(;;) 272 for (;;)
282 halt(); 273 halt();
283} 274}
284 275
285void 276void machine_emergency_restart(void)
286machine_emergency_restart(void)
287{ 277{
288 /*for now, just hook this to a warm restart */ 278 /*for now, just hook this to a warm restart */
289 machine_restart(NULL); 279 machine_restart(NULL);
290} 280}
291 281
292void 282void mca_nmi_hook(void)
293mca_nmi_hook(void)
294{ 283{
295 __u8 dumpval __maybe_unused = inb(0xf823); 284 __u8 dumpval __maybe_unused = inb(0xf823);
296 __u8 swnmi __maybe_unused = inb(0xf813); 285 __u8 swnmi __maybe_unused = inb(0xf813);
@@ -301,8 +290,8 @@ mca_nmi_hook(void)
301 /* clear swnmi */ 290 /* clear swnmi */
302 outb(0xff, 0xf813); 291 outb(0xff, 0xf813);
303 /* tell SUS to ignore dump */ 292 /* tell SUS to ignore dump */
304 if(voyager_level == 5 && voyager_SUS != NULL) { 293 if (voyager_level == 5 && voyager_SUS != NULL) {
305 if(voyager_SUS->SUS_mbox == VOYAGER_DUMP_BUTTON_NMI) { 294 if (voyager_SUS->SUS_mbox == VOYAGER_DUMP_BUTTON_NMI) {
306 voyager_SUS->kernel_mbox = VOYAGER_NO_COMMAND; 295 voyager_SUS->kernel_mbox = VOYAGER_NO_COMMAND;
307 voyager_SUS->kernel_flags |= VOYAGER_OS_IN_PROGRESS; 296 voyager_SUS->kernel_flags |= VOYAGER_OS_IN_PROGRESS;
308 udelay(1000); 297 udelay(1000);
@@ -310,15 +299,14 @@ mca_nmi_hook(void)
310 voyager_SUS->kernel_flags &= ~VOYAGER_OS_IN_PROGRESS; 299 voyager_SUS->kernel_flags &= ~VOYAGER_OS_IN_PROGRESS;
311 } 300 }
312 } 301 }
313 printk(KERN_ERR "VOYAGER: Dump switch pressed, printing CPU%d tracebacks\n", smp_processor_id()); 302 printk(KERN_ERR
303 "VOYAGER: Dump switch pressed, printing CPU%d tracebacks\n",
304 smp_processor_id());
314 show_stack(NULL, NULL); 305 show_stack(NULL, NULL);
315 show_state(); 306 show_state();
316} 307}
317 308
318 309void machine_halt(void)
319
320void
321machine_halt(void)
322{ 310{
323 /* treat a halt like a power off */ 311 /* treat a halt like a power off */
324 machine_power_off(); 312 machine_power_off();
diff --git a/arch/x86/mach-voyager/voyager_cat.c b/arch/x86/mach-voyager/voyager_cat.c
index 2132ca652df1..17a7904f75b1 100644
--- a/arch/x86/mach-voyager/voyager_cat.c
+++ b/arch/x86/mach-voyager/voyager_cat.c
@@ -39,34 +39,32 @@
39#define CAT_DATA (sspb + 0xd) 39#define CAT_DATA (sspb + 0xd)
40 40
41/* the internal cat functions */ 41/* the internal cat functions */
42static void cat_pack(__u8 *msg, __u16 start_bit, __u8 *data, 42static void cat_pack(__u8 * msg, __u16 start_bit, __u8 * data, __u16 num_bits);
43 __u16 num_bits); 43static void cat_unpack(__u8 * msg, __u16 start_bit, __u8 * data,
44static void cat_unpack(__u8 *msg, __u16 start_bit, __u8 *data,
45 __u16 num_bits); 44 __u16 num_bits);
46static void cat_build_header(__u8 *header, const __u16 len, 45static void cat_build_header(__u8 * header, const __u16 len,
47 const __u16 smallest_reg_bits, 46 const __u16 smallest_reg_bits,
48 const __u16 longest_reg_bits); 47 const __u16 longest_reg_bits);
49static int cat_sendinst(voyager_module_t *modp, voyager_asic_t *asicp, 48static int cat_sendinst(voyager_module_t * modp, voyager_asic_t * asicp,
50 __u8 reg, __u8 op); 49 __u8 reg, __u8 op);
51static int cat_getdata(voyager_module_t *modp, voyager_asic_t *asicp, 50static int cat_getdata(voyager_module_t * modp, voyager_asic_t * asicp,
52 __u8 reg, __u8 *value); 51 __u8 reg, __u8 * value);
53static int cat_shiftout(__u8 *data, __u16 data_bytes, __u16 header_bytes, 52static int cat_shiftout(__u8 * data, __u16 data_bytes, __u16 header_bytes,
54 __u8 pad_bits); 53 __u8 pad_bits);
55static int cat_write(voyager_module_t *modp, voyager_asic_t *asicp, __u8 reg, 54static int cat_write(voyager_module_t * modp, voyager_asic_t * asicp, __u8 reg,
56 __u8 value); 55 __u8 value);
57static int cat_read(voyager_module_t *modp, voyager_asic_t *asicp, __u8 reg, 56static int cat_read(voyager_module_t * modp, voyager_asic_t * asicp, __u8 reg,
58 __u8 *value); 57 __u8 * value);
59static int cat_subread(voyager_module_t *modp, voyager_asic_t *asicp, 58static int cat_subread(voyager_module_t * modp, voyager_asic_t * asicp,
60 __u16 offset, __u16 len, void *buf); 59 __u16 offset, __u16 len, void *buf);
61static int cat_senddata(voyager_module_t *modp, voyager_asic_t *asicp, 60static int cat_senddata(voyager_module_t * modp, voyager_asic_t * asicp,
62 __u8 reg, __u8 value); 61 __u8 reg, __u8 value);
63static int cat_disconnect(voyager_module_t *modp, voyager_asic_t *asicp); 62static int cat_disconnect(voyager_module_t * modp, voyager_asic_t * asicp);
64static int cat_connect(voyager_module_t *modp, voyager_asic_t *asicp); 63static int cat_connect(voyager_module_t * modp, voyager_asic_t * asicp);
65 64
66static inline const char * 65static inline const char *cat_module_name(int module_id)
67cat_module_name(int module_id)
68{ 66{
69 switch(module_id) { 67 switch (module_id) {
70 case 0x10: 68 case 0x10:
71 return "Processor Slot 0"; 69 return "Processor Slot 0";
72 case 0x11: 70 case 0x11:
@@ -105,14 +103,14 @@ voyager_module_t *voyager_cat_list;
105 103
106/* the I/O port assignments for the VIC and QIC */ 104/* the I/O port assignments for the VIC and QIC */
107static struct resource vic_res = { 105static struct resource vic_res = {
108 .name = "Voyager Interrupt Controller", 106 .name = "Voyager Interrupt Controller",
109 .start = 0xFC00, 107 .start = 0xFC00,
110 .end = 0xFC6F 108 .end = 0xFC6F
111}; 109};
112static struct resource qic_res = { 110static struct resource qic_res = {
113 .name = "Quad Interrupt Controller", 111 .name = "Quad Interrupt Controller",
114 .start = 0xFC70, 112 .start = 0xFC70,
115 .end = 0xFCFF 113 .end = 0xFCFF
116}; 114};
117 115
118/* This function is used to pack a data bit stream inside a message. 116/* This function is used to pack a data bit stream inside a message.
@@ -120,7 +118,7 @@ static struct resource qic_res = {
120 * Note: This function assumes that any unused bit in the data stream 118 * Note: This function assumes that any unused bit in the data stream
121 * is set to zero so that the ors will work correctly */ 119 * is set to zero so that the ors will work correctly */
122static void 120static void
123cat_pack(__u8 *msg, const __u16 start_bit, __u8 *data, const __u16 num_bits) 121cat_pack(__u8 * msg, const __u16 start_bit, __u8 * data, const __u16 num_bits)
124{ 122{
125 /* compute initial shift needed */ 123 /* compute initial shift needed */
126 const __u16 offset = start_bit % BITS_PER_BYTE; 124 const __u16 offset = start_bit % BITS_PER_BYTE;
@@ -130,7 +128,7 @@ cat_pack(__u8 *msg, const __u16 start_bit, __u8 *data, const __u16 num_bits)
130 int i; 128 int i;
131 129
132 /* adjust if we have more than a byte of residue */ 130 /* adjust if we have more than a byte of residue */
133 if(residue >= BITS_PER_BYTE) { 131 if (residue >= BITS_PER_BYTE) {
134 residue -= BITS_PER_BYTE; 132 residue -= BITS_PER_BYTE;
135 len++; 133 len++;
136 } 134 }
@@ -138,24 +136,25 @@ cat_pack(__u8 *msg, const __u16 start_bit, __u8 *data, const __u16 num_bits)
138 /* clear out the bits. We assume here that if len==0 then 136 /* clear out the bits. We assume here that if len==0 then
139 * residue >= offset. This is always true for the catbus 137 * residue >= offset. This is always true for the catbus
140 * operations */ 138 * operations */
141 msg[byte] &= 0xff << (BITS_PER_BYTE - offset); 139 msg[byte] &= 0xff << (BITS_PER_BYTE - offset);
142 msg[byte++] |= data[0] >> offset; 140 msg[byte++] |= data[0] >> offset;
143 if(len == 0) 141 if (len == 0)
144 return; 142 return;
145 for(i = 1; i < len; i++) 143 for (i = 1; i < len; i++)
146 msg[byte++] = (data[i-1] << (BITS_PER_BYTE - offset)) 144 msg[byte++] = (data[i - 1] << (BITS_PER_BYTE - offset))
147 | (data[i] >> offset); 145 | (data[i] >> offset);
148 if(residue != 0) { 146 if (residue != 0) {
149 __u8 mask = 0xff >> residue; 147 __u8 mask = 0xff >> residue;
150 __u8 last_byte = data[i-1] << (BITS_PER_BYTE - offset) 148 __u8 last_byte = data[i - 1] << (BITS_PER_BYTE - offset)
151 | (data[i] >> offset); 149 | (data[i] >> offset);
152 150
153 last_byte &= ~mask; 151 last_byte &= ~mask;
154 msg[byte] &= mask; 152 msg[byte] &= mask;
155 msg[byte] |= last_byte; 153 msg[byte] |= last_byte;
156 } 154 }
157 return; 155 return;
158} 156}
157
159/* unpack the data again (same arguments as cat_pack()). data buffer 158/* unpack the data again (same arguments as cat_pack()). data buffer
160 * must be zero populated. 159 * must be zero populated.
161 * 160 *
@@ -163,7 +162,7 @@ cat_pack(__u8 *msg, const __u16 start_bit, __u8 *data, const __u16 num_bits)
163 * data (starting at bit 0 in data). 162 * data (starting at bit 0 in data).
164 */ 163 */
165static void 164static void
166cat_unpack(__u8 *msg, const __u16 start_bit, __u8 *data, const __u16 num_bits) 165cat_unpack(__u8 * msg, const __u16 start_bit, __u8 * data, const __u16 num_bits)
167{ 166{
168 /* compute initial shift needed */ 167 /* compute initial shift needed */
169 const __u16 offset = start_bit % BITS_PER_BYTE; 168 const __u16 offset = start_bit % BITS_PER_BYTE;
@@ -172,97 +171,97 @@ cat_unpack(__u8 *msg, const __u16 start_bit, __u8 *data, const __u16 num_bits)
172 __u16 byte = start_bit / BITS_PER_BYTE; 171 __u16 byte = start_bit / BITS_PER_BYTE;
173 int i; 172 int i;
174 173
175 if(last_bits != 0) 174 if (last_bits != 0)
176 len++; 175 len++;
177 176
178 /* special case: want < 8 bits from msg and we can get it from 177 /* special case: want < 8 bits from msg and we can get it from
179 * a single byte of the msg */ 178 * a single byte of the msg */
180 if(len == 0 && BITS_PER_BYTE - offset >= num_bits) { 179 if (len == 0 && BITS_PER_BYTE - offset >= num_bits) {
181 data[0] = msg[byte] << offset; 180 data[0] = msg[byte] << offset;
182 data[0] &= 0xff >> (BITS_PER_BYTE - num_bits); 181 data[0] &= 0xff >> (BITS_PER_BYTE - num_bits);
183 return; 182 return;
184 } 183 }
185 for(i = 0; i < len; i++) { 184 for (i = 0; i < len; i++) {
186 /* this annoying if has to be done just in case a read of 185 /* this annoying if has to be done just in case a read of
187 * msg one beyond the array causes a panic */ 186 * msg one beyond the array causes a panic */
188 if(offset != 0) { 187 if (offset != 0) {
189 data[i] = msg[byte++] << offset; 188 data[i] = msg[byte++] << offset;
190 data[i] |= msg[byte] >> (BITS_PER_BYTE - offset); 189 data[i] |= msg[byte] >> (BITS_PER_BYTE - offset);
191 } 190 } else {
192 else {
193 data[i] = msg[byte++]; 191 data[i] = msg[byte++];
194 } 192 }
195 } 193 }
196 /* do we need to truncate the final byte */ 194 /* do we need to truncate the final byte */
197 if(last_bits != 0) { 195 if (last_bits != 0) {
198 data[i-1] &= 0xff << (BITS_PER_BYTE - last_bits); 196 data[i - 1] &= 0xff << (BITS_PER_BYTE - last_bits);
199 } 197 }
200 return; 198 return;
201} 199}
202 200
203static void 201static void
204cat_build_header(__u8 *header, const __u16 len, const __u16 smallest_reg_bits, 202cat_build_header(__u8 * header, const __u16 len, const __u16 smallest_reg_bits,
205 const __u16 longest_reg_bits) 203 const __u16 longest_reg_bits)
206{ 204{
207 int i; 205 int i;
208 __u16 start_bit = (smallest_reg_bits - 1) % BITS_PER_BYTE; 206 __u16 start_bit = (smallest_reg_bits - 1) % BITS_PER_BYTE;
209 __u8 *last_byte = &header[len - 1]; 207 __u8 *last_byte = &header[len - 1];
210 208
211 if(start_bit == 0) 209 if (start_bit == 0)
212 start_bit = 1; /* must have at least one bit in the hdr */ 210 start_bit = 1; /* must have at least one bit in the hdr */
213 211
214 for(i=0; i < len; i++) 212 for (i = 0; i < len; i++)
215 header[i] = 0; 213 header[i] = 0;
216 214
217 for(i = start_bit; i > 0; i--) 215 for (i = start_bit; i > 0; i--)
218 *last_byte = ((*last_byte) << 1) + 1; 216 *last_byte = ((*last_byte) << 1) + 1;
219 217
220} 218}
221 219
222static int 220static int
223cat_sendinst(voyager_module_t *modp, voyager_asic_t *asicp, __u8 reg, __u8 op) 221cat_sendinst(voyager_module_t * modp, voyager_asic_t * asicp, __u8 reg, __u8 op)
224{ 222{
225 __u8 parity, inst, inst_buf[4] = { 0 }; 223 __u8 parity, inst, inst_buf[4] = { 0 };
226 __u8 iseq[VOYAGER_MAX_SCAN_PATH], hseq[VOYAGER_MAX_REG_SIZE]; 224 __u8 iseq[VOYAGER_MAX_SCAN_PATH], hseq[VOYAGER_MAX_REG_SIZE];
227 __u16 ibytes, hbytes, padbits; 225 __u16 ibytes, hbytes, padbits;
228 int i; 226 int i;
229 227
230 /* 228 /*
231 * Parity is the parity of the register number + 1 (READ_REGISTER 229 * Parity is the parity of the register number + 1 (READ_REGISTER
232 * and WRITE_REGISTER always add '1' to the number of bits == 1) 230 * and WRITE_REGISTER always add '1' to the number of bits == 1)
233 */ 231 */
234 parity = (__u8)(1 + (reg & 0x01) + 232 parity = (__u8) (1 + (reg & 0x01) +
235 ((__u8)(reg & 0x02) >> 1) + 233 ((__u8) (reg & 0x02) >> 1) +
236 ((__u8)(reg & 0x04) >> 2) + 234 ((__u8) (reg & 0x04) >> 2) +
237 ((__u8)(reg & 0x08) >> 3)) % 2; 235 ((__u8) (reg & 0x08) >> 3)) % 2;
238 236
239 inst = ((parity << 7) | (reg << 2) | op); 237 inst = ((parity << 7) | (reg << 2) | op);
240 238
241 outb(VOYAGER_CAT_IRCYC, CAT_CMD); 239 outb(VOYAGER_CAT_IRCYC, CAT_CMD);
242 if(!modp->scan_path_connected) { 240 if (!modp->scan_path_connected) {
243 if(asicp->asic_id != VOYAGER_CAT_ID) { 241 if (asicp->asic_id != VOYAGER_CAT_ID) {
244 printk("**WARNING***: cat_sendinst has disconnected scan path not to CAT asic\n"); 242 printk
243 ("**WARNING***: cat_sendinst has disconnected scan path not to CAT asic\n");
245 return 1; 244 return 1;
246 } 245 }
247 outb(VOYAGER_CAT_HEADER, CAT_DATA); 246 outb(VOYAGER_CAT_HEADER, CAT_DATA);
248 outb(inst, CAT_DATA); 247 outb(inst, CAT_DATA);
249 if(inb(CAT_DATA) != VOYAGER_CAT_HEADER) { 248 if (inb(CAT_DATA) != VOYAGER_CAT_HEADER) {
250 CDEBUG(("VOYAGER CAT: cat_sendinst failed to get CAT_HEADER\n")); 249 CDEBUG(("VOYAGER CAT: cat_sendinst failed to get CAT_HEADER\n"));
251 return 1; 250 return 1;
252 } 251 }
253 return 0; 252 return 0;
254 } 253 }
255 ibytes = modp->inst_bits / BITS_PER_BYTE; 254 ibytes = modp->inst_bits / BITS_PER_BYTE;
256 if((padbits = modp->inst_bits % BITS_PER_BYTE) != 0) { 255 if ((padbits = modp->inst_bits % BITS_PER_BYTE) != 0) {
257 padbits = BITS_PER_BYTE - padbits; 256 padbits = BITS_PER_BYTE - padbits;
258 ibytes++; 257 ibytes++;
259 } 258 }
260 hbytes = modp->largest_reg / BITS_PER_BYTE; 259 hbytes = modp->largest_reg / BITS_PER_BYTE;
261 if(modp->largest_reg % BITS_PER_BYTE) 260 if (modp->largest_reg % BITS_PER_BYTE)
262 hbytes++; 261 hbytes++;
263 CDEBUG(("cat_sendinst: ibytes=%d, hbytes=%d\n", ibytes, hbytes)); 262 CDEBUG(("cat_sendinst: ibytes=%d, hbytes=%d\n", ibytes, hbytes));
264 /* initialise the instruction sequence to 0xff */ 263 /* initialise the instruction sequence to 0xff */
265 for(i=0; i < ibytes + hbytes; i++) 264 for (i = 0; i < ibytes + hbytes; i++)
266 iseq[i] = 0xff; 265 iseq[i] = 0xff;
267 cat_build_header(hseq, hbytes, modp->smallest_reg, modp->largest_reg); 266 cat_build_header(hseq, hbytes, modp->smallest_reg, modp->largest_reg);
268 cat_pack(iseq, modp->inst_bits, hseq, hbytes * BITS_PER_BYTE); 267 cat_pack(iseq, modp->inst_bits, hseq, hbytes * BITS_PER_BYTE);
@@ -271,11 +270,11 @@ cat_sendinst(voyager_module_t *modp, voyager_asic_t *asicp, __u8 reg, __u8 op)
271 cat_pack(iseq, asicp->bit_location, inst_buf, asicp->ireg_length); 270 cat_pack(iseq, asicp->bit_location, inst_buf, asicp->ireg_length);
272#ifdef VOYAGER_CAT_DEBUG 271#ifdef VOYAGER_CAT_DEBUG
273 printk("ins = 0x%x, iseq: ", inst); 272 printk("ins = 0x%x, iseq: ", inst);
274 for(i=0; i< ibytes + hbytes; i++) 273 for (i = 0; i < ibytes + hbytes; i++)
275 printk("0x%x ", iseq[i]); 274 printk("0x%x ", iseq[i]);
276 printk("\n"); 275 printk("\n");
277#endif 276#endif
278 if(cat_shiftout(iseq, ibytes, hbytes, padbits)) { 277 if (cat_shiftout(iseq, ibytes, hbytes, padbits)) {
279 CDEBUG(("VOYAGER CAT: cat_sendinst: cat_shiftout failed\n")); 278 CDEBUG(("VOYAGER CAT: cat_sendinst: cat_shiftout failed\n"));
280 return 1; 279 return 1;
281 } 280 }
@@ -284,72 +283,74 @@ cat_sendinst(voyager_module_t *modp, voyager_asic_t *asicp, __u8 reg, __u8 op)
284} 283}
285 284
286static int 285static int
287cat_getdata(voyager_module_t *modp, voyager_asic_t *asicp, __u8 reg, 286cat_getdata(voyager_module_t * modp, voyager_asic_t * asicp, __u8 reg,
288 __u8 *value) 287 __u8 * value)
289{ 288{
290 if(!modp->scan_path_connected) { 289 if (!modp->scan_path_connected) {
291 if(asicp->asic_id != VOYAGER_CAT_ID) { 290 if (asicp->asic_id != VOYAGER_CAT_ID) {
292 CDEBUG(("VOYAGER CAT: ERROR: cat_getdata to CAT asic with scan path connected\n")); 291 CDEBUG(("VOYAGER CAT: ERROR: cat_getdata to CAT asic with scan path connected\n"));
293 return 1; 292 return 1;
294 } 293 }
295 if(reg > VOYAGER_SUBADDRHI) 294 if (reg > VOYAGER_SUBADDRHI)
296 outb(VOYAGER_CAT_RUN, CAT_CMD); 295 outb(VOYAGER_CAT_RUN, CAT_CMD);
297 outb(VOYAGER_CAT_DRCYC, CAT_CMD); 296 outb(VOYAGER_CAT_DRCYC, CAT_CMD);
298 outb(VOYAGER_CAT_HEADER, CAT_DATA); 297 outb(VOYAGER_CAT_HEADER, CAT_DATA);
299 *value = inb(CAT_DATA); 298 *value = inb(CAT_DATA);
300 outb(0xAA, CAT_DATA); 299 outb(0xAA, CAT_DATA);
301 if(inb(CAT_DATA) != VOYAGER_CAT_HEADER) { 300 if (inb(CAT_DATA) != VOYAGER_CAT_HEADER) {
302 CDEBUG(("cat_getdata: failed to get VOYAGER_CAT_HEADER\n")); 301 CDEBUG(("cat_getdata: failed to get VOYAGER_CAT_HEADER\n"));
303 return 1; 302 return 1;
304 } 303 }
305 return 0; 304 return 0;
306 } 305 } else {
307 else { 306 __u16 sbits = modp->num_asics - 1 + asicp->ireg_length;
308 __u16 sbits = modp->num_asics -1 + asicp->ireg_length;
309 __u16 sbytes = sbits / BITS_PER_BYTE; 307 __u16 sbytes = sbits / BITS_PER_BYTE;
310 __u16 tbytes; 308 __u16 tbytes;
311 __u8 string[VOYAGER_MAX_SCAN_PATH], trailer[VOYAGER_MAX_REG_SIZE]; 309 __u8 string[VOYAGER_MAX_SCAN_PATH],
310 trailer[VOYAGER_MAX_REG_SIZE];
312 __u8 padbits; 311 __u8 padbits;
313 int i; 312 int i;
314 313
315 outb(VOYAGER_CAT_DRCYC, CAT_CMD); 314 outb(VOYAGER_CAT_DRCYC, CAT_CMD);
316 315
317 if((padbits = sbits % BITS_PER_BYTE) != 0) { 316 if ((padbits = sbits % BITS_PER_BYTE) != 0) {
318 padbits = BITS_PER_BYTE - padbits; 317 padbits = BITS_PER_BYTE - padbits;
319 sbytes++; 318 sbytes++;
320 } 319 }
321 tbytes = asicp->ireg_length / BITS_PER_BYTE; 320 tbytes = asicp->ireg_length / BITS_PER_BYTE;
322 if(asicp->ireg_length % BITS_PER_BYTE) 321 if (asicp->ireg_length % BITS_PER_BYTE)
323 tbytes++; 322 tbytes++;
324 CDEBUG(("cat_getdata: tbytes = %d, sbytes = %d, padbits = %d\n", 323 CDEBUG(("cat_getdata: tbytes = %d, sbytes = %d, padbits = %d\n",
325 tbytes, sbytes, padbits)); 324 tbytes, sbytes, padbits));
326 cat_build_header(trailer, tbytes, 1, asicp->ireg_length); 325 cat_build_header(trailer, tbytes, 1, asicp->ireg_length);
327 326
328 327 for (i = tbytes - 1; i >= 0; i--) {
329 for(i = tbytes - 1; i >= 0; i--) {
330 outb(trailer[i], CAT_DATA); 328 outb(trailer[i], CAT_DATA);
331 string[sbytes + i] = inb(CAT_DATA); 329 string[sbytes + i] = inb(CAT_DATA);
332 } 330 }
333 331
334 for(i = sbytes - 1; i >= 0; i--) { 332 for (i = sbytes - 1; i >= 0; i--) {
335 outb(0xaa, CAT_DATA); 333 outb(0xaa, CAT_DATA);
336 string[i] = inb(CAT_DATA); 334 string[i] = inb(CAT_DATA);
337 } 335 }
338 *value = 0; 336 *value = 0;
339 cat_unpack(string, padbits + (tbytes * BITS_PER_BYTE) + asicp->asic_location, value, asicp->ireg_length); 337 cat_unpack(string,
338 padbits + (tbytes * BITS_PER_BYTE) +
339 asicp->asic_location, value, asicp->ireg_length);
340#ifdef VOYAGER_CAT_DEBUG 340#ifdef VOYAGER_CAT_DEBUG
341 printk("value=0x%x, string: ", *value); 341 printk("value=0x%x, string: ", *value);
342 for(i=0; i< tbytes+sbytes; i++) 342 for (i = 0; i < tbytes + sbytes; i++)
343 printk("0x%x ", string[i]); 343 printk("0x%x ", string[i]);
344 printk("\n"); 344 printk("\n");
345#endif 345#endif
346 346
347 /* sanity check the rest of the return */ 347 /* sanity check the rest of the return */
348 for(i=0; i < tbytes; i++) { 348 for (i = 0; i < tbytes; i++) {
349 __u8 input = 0; 349 __u8 input = 0;
350 350
351 cat_unpack(string, padbits + (i * BITS_PER_BYTE), &input, BITS_PER_BYTE); 351 cat_unpack(string, padbits + (i * BITS_PER_BYTE),
352 if(trailer[i] != input) { 352 &input, BITS_PER_BYTE);
353 if (trailer[i] != input) {
353 CDEBUG(("cat_getdata: failed to sanity check rest of ret(%d) 0x%x != 0x%x\n", i, input, trailer[i])); 354 CDEBUG(("cat_getdata: failed to sanity check rest of ret(%d) 0x%x != 0x%x\n", i, input, trailer[i]));
354 return 1; 355 return 1;
355 } 356 }
@@ -360,14 +361,14 @@ cat_getdata(voyager_module_t *modp, voyager_asic_t *asicp, __u8 reg,
360} 361}
361 362
362static int 363static int
363cat_shiftout(__u8 *data, __u16 data_bytes, __u16 header_bytes, __u8 pad_bits) 364cat_shiftout(__u8 * data, __u16 data_bytes, __u16 header_bytes, __u8 pad_bits)
364{ 365{
365 int i; 366 int i;
366 367
367 for(i = data_bytes + header_bytes - 1; i >= header_bytes; i--) 368 for (i = data_bytes + header_bytes - 1; i >= header_bytes; i--)
368 outb(data[i], CAT_DATA); 369 outb(data[i], CAT_DATA);
369 370
370 for(i = header_bytes - 1; i >= 0; i--) { 371 for (i = header_bytes - 1; i >= 0; i--) {
371 __u8 header = 0; 372 __u8 header = 0;
372 __u8 input; 373 __u8 input;
373 374
@@ -376,7 +377,7 @@ cat_shiftout(__u8 *data, __u16 data_bytes, __u16 header_bytes, __u8 pad_bits)
376 CDEBUG(("cat_shiftout: returned 0x%x\n", input)); 377 CDEBUG(("cat_shiftout: returned 0x%x\n", input));
377 cat_unpack(data, ((data_bytes + i) * BITS_PER_BYTE) - pad_bits, 378 cat_unpack(data, ((data_bytes + i) * BITS_PER_BYTE) - pad_bits,
378 &header, BITS_PER_BYTE); 379 &header, BITS_PER_BYTE);
379 if(input != header) { 380 if (input != header) {
380 CDEBUG(("VOYAGER CAT: cat_shiftout failed to return header 0x%x != 0x%x\n", input, header)); 381 CDEBUG(("VOYAGER CAT: cat_shiftout failed to return header 0x%x != 0x%x\n", input, header));
381 return 1; 382 return 1;
382 } 383 }
@@ -385,57 +386,57 @@ cat_shiftout(__u8 *data, __u16 data_bytes, __u16 header_bytes, __u8 pad_bits)
385} 386}
386 387
387static int 388static int
388cat_senddata(voyager_module_t *modp, voyager_asic_t *asicp, 389cat_senddata(voyager_module_t * modp, voyager_asic_t * asicp,
389 __u8 reg, __u8 value) 390 __u8 reg, __u8 value)
390{ 391{
391 outb(VOYAGER_CAT_DRCYC, CAT_CMD); 392 outb(VOYAGER_CAT_DRCYC, CAT_CMD);
392 if(!modp->scan_path_connected) { 393 if (!modp->scan_path_connected) {
393 if(asicp->asic_id != VOYAGER_CAT_ID) { 394 if (asicp->asic_id != VOYAGER_CAT_ID) {
394 CDEBUG(("VOYAGER CAT: ERROR: scan path disconnected when asic != CAT\n")); 395 CDEBUG(("VOYAGER CAT: ERROR: scan path disconnected when asic != CAT\n"));
395 return 1; 396 return 1;
396 } 397 }
397 outb(VOYAGER_CAT_HEADER, CAT_DATA); 398 outb(VOYAGER_CAT_HEADER, CAT_DATA);
398 outb(value, CAT_DATA); 399 outb(value, CAT_DATA);
399 if(inb(CAT_DATA) != VOYAGER_CAT_HEADER) { 400 if (inb(CAT_DATA) != VOYAGER_CAT_HEADER) {
400 CDEBUG(("cat_senddata: failed to get correct header response to sent data\n")); 401 CDEBUG(("cat_senddata: failed to get correct header response to sent data\n"));
401 return 1; 402 return 1;
402 } 403 }
403 if(reg > VOYAGER_SUBADDRHI) { 404 if (reg > VOYAGER_SUBADDRHI) {
404 outb(VOYAGER_CAT_RUN, CAT_CMD); 405 outb(VOYAGER_CAT_RUN, CAT_CMD);
405 outb(VOYAGER_CAT_END, CAT_CMD); 406 outb(VOYAGER_CAT_END, CAT_CMD);
406 outb(VOYAGER_CAT_RUN, CAT_CMD); 407 outb(VOYAGER_CAT_RUN, CAT_CMD);
407 } 408 }
408 409
409 return 0; 410 return 0;
410 } 411 } else {
411 else {
412 __u16 hbytes = asicp->ireg_length / BITS_PER_BYTE; 412 __u16 hbytes = asicp->ireg_length / BITS_PER_BYTE;
413 __u16 dbytes = (modp->num_asics - 1 + asicp->ireg_length)/BITS_PER_BYTE; 413 __u16 dbytes =
414 __u8 padbits, dseq[VOYAGER_MAX_SCAN_PATH], 414 (modp->num_asics - 1 + asicp->ireg_length) / BITS_PER_BYTE;
415 hseq[VOYAGER_MAX_REG_SIZE]; 415 __u8 padbits, dseq[VOYAGER_MAX_SCAN_PATH],
416 hseq[VOYAGER_MAX_REG_SIZE];
416 int i; 417 int i;
417 418
418 if((padbits = (modp->num_asics - 1 419 if ((padbits = (modp->num_asics - 1
419 + asicp->ireg_length) % BITS_PER_BYTE) != 0) { 420 + asicp->ireg_length) % BITS_PER_BYTE) != 0) {
420 padbits = BITS_PER_BYTE - padbits; 421 padbits = BITS_PER_BYTE - padbits;
421 dbytes++; 422 dbytes++;
422 } 423 }
423 if(asicp->ireg_length % BITS_PER_BYTE) 424 if (asicp->ireg_length % BITS_PER_BYTE)
424 hbytes++; 425 hbytes++;
425 426
426 cat_build_header(hseq, hbytes, 1, asicp->ireg_length); 427 cat_build_header(hseq, hbytes, 1, asicp->ireg_length);
427 428
428 for(i = 0; i < dbytes + hbytes; i++) 429 for (i = 0; i < dbytes + hbytes; i++)
429 dseq[i] = 0xff; 430 dseq[i] = 0xff;
430 CDEBUG(("cat_senddata: dbytes=%d, hbytes=%d, padbits=%d\n", 431 CDEBUG(("cat_senddata: dbytes=%d, hbytes=%d, padbits=%d\n",
431 dbytes, hbytes, padbits)); 432 dbytes, hbytes, padbits));
432 cat_pack(dseq, modp->num_asics - 1 + asicp->ireg_length, 433 cat_pack(dseq, modp->num_asics - 1 + asicp->ireg_length,
433 hseq, hbytes * BITS_PER_BYTE); 434 hseq, hbytes * BITS_PER_BYTE);
434 cat_pack(dseq, asicp->asic_location, &value, 435 cat_pack(dseq, asicp->asic_location, &value,
435 asicp->ireg_length); 436 asicp->ireg_length);
436#ifdef VOYAGER_CAT_DEBUG 437#ifdef VOYAGER_CAT_DEBUG
437 printk("dseq "); 438 printk("dseq ");
438 for(i=0; i<hbytes+dbytes; i++) { 439 for (i = 0; i < hbytes + dbytes; i++) {
439 printk("0x%x ", dseq[i]); 440 printk("0x%x ", dseq[i]);
440 } 441 }
441 printk("\n"); 442 printk("\n");
@@ -445,121 +446,125 @@ cat_senddata(voyager_module_t *modp, voyager_asic_t *asicp,
445} 446}
446 447
447static int 448static int
448cat_write(voyager_module_t *modp, voyager_asic_t *asicp, __u8 reg, 449cat_write(voyager_module_t * modp, voyager_asic_t * asicp, __u8 reg, __u8 value)
449 __u8 value)
450{ 450{
451 if(cat_sendinst(modp, asicp, reg, VOYAGER_WRITE_CONFIG)) 451 if (cat_sendinst(modp, asicp, reg, VOYAGER_WRITE_CONFIG))
452 return 1; 452 return 1;
453 return cat_senddata(modp, asicp, reg, value); 453 return cat_senddata(modp, asicp, reg, value);
454} 454}
455 455
456static int 456static int
457cat_read(voyager_module_t *modp, voyager_asic_t *asicp, __u8 reg, 457cat_read(voyager_module_t * modp, voyager_asic_t * asicp, __u8 reg,
458 __u8 *value) 458 __u8 * value)
459{ 459{
460 if(cat_sendinst(modp, asicp, reg, VOYAGER_READ_CONFIG)) 460 if (cat_sendinst(modp, asicp, reg, VOYAGER_READ_CONFIG))
461 return 1; 461 return 1;
462 return cat_getdata(modp, asicp, reg, value); 462 return cat_getdata(modp, asicp, reg, value);
463} 463}
464 464
465static int 465static int
466cat_subaddrsetup(voyager_module_t *modp, voyager_asic_t *asicp, __u16 offset, 466cat_subaddrsetup(voyager_module_t * modp, voyager_asic_t * asicp, __u16 offset,
467 __u16 len) 467 __u16 len)
468{ 468{
469 __u8 val; 469 __u8 val;
470 470
471 if(len > 1) { 471 if (len > 1) {
472 /* set auto increment */ 472 /* set auto increment */
473 __u8 newval; 473 __u8 newval;
474 474
475 if(cat_read(modp, asicp, VOYAGER_AUTO_INC_REG, &val)) { 475 if (cat_read(modp, asicp, VOYAGER_AUTO_INC_REG, &val)) {
476 CDEBUG(("cat_subaddrsetup: read of VOYAGER_AUTO_INC_REG failed\n")); 476 CDEBUG(("cat_subaddrsetup: read of VOYAGER_AUTO_INC_REG failed\n"));
477 return 1; 477 return 1;
478 } 478 }
479 CDEBUG(("cat_subaddrsetup: VOYAGER_AUTO_INC_REG = 0x%x\n", val)); 479 CDEBUG(("cat_subaddrsetup: VOYAGER_AUTO_INC_REG = 0x%x\n",
480 val));
480 newval = val | VOYAGER_AUTO_INC; 481 newval = val | VOYAGER_AUTO_INC;
481 if(newval != val) { 482 if (newval != val) {
482 if(cat_write(modp, asicp, VOYAGER_AUTO_INC_REG, val)) { 483 if (cat_write(modp, asicp, VOYAGER_AUTO_INC_REG, val)) {
483 CDEBUG(("cat_subaddrsetup: write to VOYAGER_AUTO_INC_REG failed\n")); 484 CDEBUG(("cat_subaddrsetup: write to VOYAGER_AUTO_INC_REG failed\n"));
484 return 1; 485 return 1;
485 } 486 }
486 } 487 }
487 } 488 }
488 if(cat_write(modp, asicp, VOYAGER_SUBADDRLO, (__u8)(offset &0xff))) { 489 if (cat_write(modp, asicp, VOYAGER_SUBADDRLO, (__u8) (offset & 0xff))) {
489 CDEBUG(("cat_subaddrsetup: write to SUBADDRLO failed\n")); 490 CDEBUG(("cat_subaddrsetup: write to SUBADDRLO failed\n"));
490 return 1; 491 return 1;
491 } 492 }
492 if(asicp->subaddr > VOYAGER_SUBADDR_LO) { 493 if (asicp->subaddr > VOYAGER_SUBADDR_LO) {
493 if(cat_write(modp, asicp, VOYAGER_SUBADDRHI, (__u8)(offset >> 8))) { 494 if (cat_write
495 (modp, asicp, VOYAGER_SUBADDRHI, (__u8) (offset >> 8))) {
494 CDEBUG(("cat_subaddrsetup: write to SUBADDRHI failed\n")); 496 CDEBUG(("cat_subaddrsetup: write to SUBADDRHI failed\n"));
495 return 1; 497 return 1;
496 } 498 }
497 cat_read(modp, asicp, VOYAGER_SUBADDRHI, &val); 499 cat_read(modp, asicp, VOYAGER_SUBADDRHI, &val);
498 CDEBUG(("cat_subaddrsetup: offset = %d, hi = %d\n", offset, val)); 500 CDEBUG(("cat_subaddrsetup: offset = %d, hi = %d\n", offset,
501 val));
499 } 502 }
500 cat_read(modp, asicp, VOYAGER_SUBADDRLO, &val); 503 cat_read(modp, asicp, VOYAGER_SUBADDRLO, &val);
501 CDEBUG(("cat_subaddrsetup: offset = %d, lo = %d\n", offset, val)); 504 CDEBUG(("cat_subaddrsetup: offset = %d, lo = %d\n", offset, val));
502 return 0; 505 return 0;
503} 506}
504 507
505static int 508static int
506cat_subwrite(voyager_module_t *modp, voyager_asic_t *asicp, __u16 offset, 509cat_subwrite(voyager_module_t * modp, voyager_asic_t * asicp, __u16 offset,
507 __u16 len, void *buf) 510 __u16 len, void *buf)
508{ 511{
509 int i, retval; 512 int i, retval;
510 513
511 /* FIXME: need special actions for VOYAGER_CAT_ID here */ 514 /* FIXME: need special actions for VOYAGER_CAT_ID here */
512 if(asicp->asic_id == VOYAGER_CAT_ID) { 515 if (asicp->asic_id == VOYAGER_CAT_ID) {
513 CDEBUG(("cat_subwrite: ATTEMPT TO WRITE TO CAT ASIC\n")); 516 CDEBUG(("cat_subwrite: ATTEMPT TO WRITE TO CAT ASIC\n"));
514 /* FIXME -- This is supposed to be handled better 517 /* FIXME -- This is supposed to be handled better
515 * There is a problem writing to the cat asic in the 518 * There is a problem writing to the cat asic in the
516 * PSI. The 30us delay seems to work, though */ 519 * PSI. The 30us delay seems to work, though */
517 udelay(30); 520 udelay(30);
518 } 521 }
519 522
520 if((retval = cat_subaddrsetup(modp, asicp, offset, len)) != 0) { 523 if ((retval = cat_subaddrsetup(modp, asicp, offset, len)) != 0) {
521 printk("cat_subwrite: cat_subaddrsetup FAILED\n"); 524 printk("cat_subwrite: cat_subaddrsetup FAILED\n");
522 return retval; 525 return retval;
523 } 526 }
524 527
525 if(cat_sendinst(modp, asicp, VOYAGER_SUBADDRDATA, VOYAGER_WRITE_CONFIG)) { 528 if (cat_sendinst
529 (modp, asicp, VOYAGER_SUBADDRDATA, VOYAGER_WRITE_CONFIG)) {
526 printk("cat_subwrite: cat_sendinst FAILED\n"); 530 printk("cat_subwrite: cat_sendinst FAILED\n");
527 return 1; 531 return 1;
528 } 532 }
529 for(i = 0; i < len; i++) { 533 for (i = 0; i < len; i++) {
530 if(cat_senddata(modp, asicp, 0xFF, ((__u8 *)buf)[i])) { 534 if (cat_senddata(modp, asicp, 0xFF, ((__u8 *) buf)[i])) {
531 printk("cat_subwrite: cat_sendata element at %d FAILED\n", i); 535 printk
536 ("cat_subwrite: cat_sendata element at %d FAILED\n",
537 i);
532 return 1; 538 return 1;
533 } 539 }
534 } 540 }
535 return 0; 541 return 0;
536} 542}
537static int 543static int
538cat_subread(voyager_module_t *modp, voyager_asic_t *asicp, __u16 offset, 544cat_subread(voyager_module_t * modp, voyager_asic_t * asicp, __u16 offset,
539 __u16 len, void *buf) 545 __u16 len, void *buf)
540{ 546{
541 int i, retval; 547 int i, retval;
542 548
543 if((retval = cat_subaddrsetup(modp, asicp, offset, len)) != 0) { 549 if ((retval = cat_subaddrsetup(modp, asicp, offset, len)) != 0) {
544 CDEBUG(("cat_subread: cat_subaddrsetup FAILED\n")); 550 CDEBUG(("cat_subread: cat_subaddrsetup FAILED\n"));
545 return retval; 551 return retval;
546 } 552 }
547 553
548 if(cat_sendinst(modp, asicp, VOYAGER_SUBADDRDATA, VOYAGER_READ_CONFIG)) { 554 if (cat_sendinst(modp, asicp, VOYAGER_SUBADDRDATA, VOYAGER_READ_CONFIG)) {
549 CDEBUG(("cat_subread: cat_sendinst failed\n")); 555 CDEBUG(("cat_subread: cat_sendinst failed\n"));
550 return 1; 556 return 1;
551 } 557 }
552 for(i = 0; i < len; i++) { 558 for (i = 0; i < len; i++) {
553 if(cat_getdata(modp, asicp, 0xFF, 559 if (cat_getdata(modp, asicp, 0xFF, &((__u8 *) buf)[i])) {
554 &((__u8 *)buf)[i])) { 560 CDEBUG(("cat_subread: cat_getdata element %d failed\n",
555 CDEBUG(("cat_subread: cat_getdata element %d failed\n", i)); 561 i));
556 return 1; 562 return 1;
557 } 563 }
558 } 564 }
559 return 0; 565 return 0;
560} 566}
561 567
562
563/* buffer for storing EPROM data read in during initialisation */ 568/* buffer for storing EPROM data read in during initialisation */
564static __initdata __u8 eprom_buf[0xFFFF]; 569static __initdata __u8 eprom_buf[0xFFFF];
565static voyager_module_t *voyager_initial_module; 570static voyager_module_t *voyager_initial_module;
@@ -568,8 +573,7 @@ static voyager_module_t *voyager_initial_module;
568 * boot cpu *after* all memory initialisation has been done (so we can 573 * boot cpu *after* all memory initialisation has been done (so we can
569 * use kmalloc) but before smp initialisation, so we can probe the SMP 574 * use kmalloc) but before smp initialisation, so we can probe the SMP
570 * configuration and pick up necessary information. */ 575 * configuration and pick up necessary information. */
571void __init 576void __init voyager_cat_init(void)
572voyager_cat_init(void)
573{ 577{
574 voyager_module_t **modpp = &voyager_initial_module; 578 voyager_module_t **modpp = &voyager_initial_module;
575 voyager_asic_t **asicpp; 579 voyager_asic_t **asicpp;
@@ -578,27 +582,29 @@ voyager_cat_init(void)
578 unsigned long qic_addr = 0; 582 unsigned long qic_addr = 0;
579 __u8 qabc_data[0x20]; 583 __u8 qabc_data[0x20];
580 __u8 num_submodules, val; 584 __u8 num_submodules, val;
581 voyager_eprom_hdr_t *eprom_hdr = (voyager_eprom_hdr_t *)&eprom_buf[0]; 585 voyager_eprom_hdr_t *eprom_hdr = (voyager_eprom_hdr_t *) & eprom_buf[0];
582 586
583 __u8 cmos[4]; 587 __u8 cmos[4];
584 unsigned long addr; 588 unsigned long addr;
585 589
586 /* initiallise the SUS mailbox */ 590 /* initiallise the SUS mailbox */
587 for(i=0; i<sizeof(cmos); i++) 591 for (i = 0; i < sizeof(cmos); i++)
588 cmos[i] = voyager_extended_cmos_read(VOYAGER_DUMP_LOCATION + i); 592 cmos[i] = voyager_extended_cmos_read(VOYAGER_DUMP_LOCATION + i);
589 addr = *(unsigned long *)cmos; 593 addr = *(unsigned long *)cmos;
590 if((addr & 0xff000000) != 0xff000000) { 594 if ((addr & 0xff000000) != 0xff000000) {
591 printk(KERN_ERR "Voyager failed to get SUS mailbox (addr = 0x%lx\n", addr); 595 printk(KERN_ERR
596 "Voyager failed to get SUS mailbox (addr = 0x%lx\n",
597 addr);
592 } else { 598 } else {
593 static struct resource res; 599 static struct resource res;
594 600
595 res.name = "voyager SUS"; 601 res.name = "voyager SUS";
596 res.start = addr; 602 res.start = addr;
597 res.end = addr+0x3ff; 603 res.end = addr + 0x3ff;
598 604
599 request_resource(&iomem_resource, &res); 605 request_resource(&iomem_resource, &res);
600 voyager_SUS = (struct voyager_SUS *) 606 voyager_SUS = (struct voyager_SUS *)
601 ioremap(addr, 0x400); 607 ioremap(addr, 0x400);
602 printk(KERN_NOTICE "Voyager SUS mailbox version 0x%x\n", 608 printk(KERN_NOTICE "Voyager SUS mailbox version 0x%x\n",
603 voyager_SUS->SUS_version); 609 voyager_SUS->SUS_version);
604 voyager_SUS->kernel_version = VOYAGER_MAILBOX_VERSION; 610 voyager_SUS->kernel_version = VOYAGER_MAILBOX_VERSION;
@@ -609,8 +615,6 @@ voyager_cat_init(void)
609 voyager_extended_vic_processors = 0; 615 voyager_extended_vic_processors = 0;
610 voyager_quad_processors = 0; 616 voyager_quad_processors = 0;
611 617
612
613
614 printk("VOYAGER: beginning CAT bus probe\n"); 618 printk("VOYAGER: beginning CAT bus probe\n");
615 /* set up the SuperSet Port Block which tells us where the 619 /* set up the SuperSet Port Block which tells us where the
616 * CAT communication port is */ 620 * CAT communication port is */
@@ -618,14 +622,14 @@ voyager_cat_init(void)
618 VDEBUG(("VOYAGER DEBUG: sspb = 0x%x\n", sspb)); 622 VDEBUG(("VOYAGER DEBUG: sspb = 0x%x\n", sspb));
619 623
620 /* now find out if were 8 slot or normal */ 624 /* now find out if were 8 slot or normal */
621 if((inb(VIC_PROC_WHO_AM_I) & EIGHT_SLOT_IDENTIFIER) 625 if ((inb(VIC_PROC_WHO_AM_I) & EIGHT_SLOT_IDENTIFIER)
622 == EIGHT_SLOT_IDENTIFIER) { 626 == EIGHT_SLOT_IDENTIFIER) {
623 voyager_8slot = 1; 627 voyager_8slot = 1;
624 printk(KERN_NOTICE "Voyager: Eight slot 51xx configuration detected\n"); 628 printk(KERN_NOTICE
629 "Voyager: Eight slot 51xx configuration detected\n");
625 } 630 }
626 631
627 for(i = VOYAGER_MIN_MODULE; 632 for (i = VOYAGER_MIN_MODULE; i <= VOYAGER_MAX_MODULE; i++) {
628 i <= VOYAGER_MAX_MODULE; i++) {
629 __u8 input; 633 __u8 input;
630 int asic; 634 int asic;
631 __u16 eprom_size; 635 __u16 eprom_size;
@@ -643,21 +647,21 @@ voyager_cat_init(void)
643 outb(0xAA, CAT_DATA); 647 outb(0xAA, CAT_DATA);
644 input = inb(CAT_DATA); 648 input = inb(CAT_DATA);
645 outb(VOYAGER_CAT_END, CAT_CMD); 649 outb(VOYAGER_CAT_END, CAT_CMD);
646 if(input != VOYAGER_CAT_HEADER) { 650 if (input != VOYAGER_CAT_HEADER) {
647 continue; 651 continue;
648 } 652 }
649 CDEBUG(("VOYAGER DEBUG: found module id 0x%x, %s\n", i, 653 CDEBUG(("VOYAGER DEBUG: found module id 0x%x, %s\n", i,
650 cat_module_name(i))); 654 cat_module_name(i)));
651 *modpp = kmalloc(sizeof(voyager_module_t), GFP_KERNEL); /*&voyager_module_storage[cat_count++];*/ 655 *modpp = kmalloc(sizeof(voyager_module_t), GFP_KERNEL); /*&voyager_module_storage[cat_count++]; */
652 if(*modpp == NULL) { 656 if (*modpp == NULL) {
653 printk("**WARNING** kmalloc failure in cat_init\n"); 657 printk("**WARNING** kmalloc failure in cat_init\n");
654 continue; 658 continue;
655 } 659 }
656 memset(*modpp, 0, sizeof(voyager_module_t)); 660 memset(*modpp, 0, sizeof(voyager_module_t));
657 /* need temporary asic for cat_subread. It will be 661 /* need temporary asic for cat_subread. It will be
658 * filled in correctly later */ 662 * filled in correctly later */
659 (*modpp)->asic = kmalloc(sizeof(voyager_asic_t), GFP_KERNEL); /*&voyager_asic_storage[asic_count];*/ 663 (*modpp)->asic = kmalloc(sizeof(voyager_asic_t), GFP_KERNEL); /*&voyager_asic_storage[asic_count]; */
660 if((*modpp)->asic == NULL) { 664 if ((*modpp)->asic == NULL) {
661 printk("**WARNING** kmalloc failure in cat_init\n"); 665 printk("**WARNING** kmalloc failure in cat_init\n");
662 continue; 666 continue;
663 } 667 }
@@ -666,47 +670,52 @@ voyager_cat_init(void)
666 (*modpp)->asic->subaddr = VOYAGER_SUBADDR_HI; 670 (*modpp)->asic->subaddr = VOYAGER_SUBADDR_HI;
667 (*modpp)->module_addr = i; 671 (*modpp)->module_addr = i;
668 (*modpp)->scan_path_connected = 0; 672 (*modpp)->scan_path_connected = 0;
669 if(i == VOYAGER_PSI) { 673 if (i == VOYAGER_PSI) {
670 /* Exception leg for modules with no EEPROM */ 674 /* Exception leg for modules with no EEPROM */
671 printk("Module \"%s\"\n", cat_module_name(i)); 675 printk("Module \"%s\"\n", cat_module_name(i));
672 continue; 676 continue;
673 } 677 }
674 678
675 CDEBUG(("cat_init: Reading eeprom for module 0x%x at offset %d\n", i, VOYAGER_XSUM_END_OFFSET)); 679 CDEBUG(("cat_init: Reading eeprom for module 0x%x at offset %d\n", i, VOYAGER_XSUM_END_OFFSET));
676 outb(VOYAGER_CAT_RUN, CAT_CMD); 680 outb(VOYAGER_CAT_RUN, CAT_CMD);
677 cat_disconnect(*modpp, (*modpp)->asic); 681 cat_disconnect(*modpp, (*modpp)->asic);
678 if(cat_subread(*modpp, (*modpp)->asic, 682 if (cat_subread(*modpp, (*modpp)->asic,
679 VOYAGER_XSUM_END_OFFSET, sizeof(eprom_size), 683 VOYAGER_XSUM_END_OFFSET, sizeof(eprom_size),
680 &eprom_size)) { 684 &eprom_size)) {
681 printk("**WARNING**: Voyager couldn't read EPROM size for module 0x%x\n", i); 685 printk
686 ("**WARNING**: Voyager couldn't read EPROM size for module 0x%x\n",
687 i);
682 outb(VOYAGER_CAT_END, CAT_CMD); 688 outb(VOYAGER_CAT_END, CAT_CMD);
683 continue; 689 continue;
684 } 690 }
685 if(eprom_size > sizeof(eprom_buf)) { 691 if (eprom_size > sizeof(eprom_buf)) {
686 printk("**WARNING**: Voyager insufficient size to read EPROM data, module 0x%x. Need %d\n", i, eprom_size); 692 printk
693 ("**WARNING**: Voyager insufficient size to read EPROM data, module 0x%x. Need %d\n",
694 i, eprom_size);
687 outb(VOYAGER_CAT_END, CAT_CMD); 695 outb(VOYAGER_CAT_END, CAT_CMD);
688 continue; 696 continue;
689 } 697 }
690 outb(VOYAGER_CAT_END, CAT_CMD); 698 outb(VOYAGER_CAT_END, CAT_CMD);
691 outb(VOYAGER_CAT_RUN, CAT_CMD); 699 outb(VOYAGER_CAT_RUN, CAT_CMD);
692 CDEBUG(("cat_init: module 0x%x, eeprom_size %d\n", i, eprom_size)); 700 CDEBUG(("cat_init: module 0x%x, eeprom_size %d\n", i,
693 if(cat_subread(*modpp, (*modpp)->asic, 0, 701 eprom_size));
694 eprom_size, eprom_buf)) { 702 if (cat_subread
703 (*modpp, (*modpp)->asic, 0, eprom_size, eprom_buf)) {
695 outb(VOYAGER_CAT_END, CAT_CMD); 704 outb(VOYAGER_CAT_END, CAT_CMD);
696 continue; 705 continue;
697 } 706 }
698 outb(VOYAGER_CAT_END, CAT_CMD); 707 outb(VOYAGER_CAT_END, CAT_CMD);
699 printk("Module \"%s\", version 0x%x, tracer 0x%x, asics %d\n", 708 printk("Module \"%s\", version 0x%x, tracer 0x%x, asics %d\n",
700 cat_module_name(i), eprom_hdr->version_id, 709 cat_module_name(i), eprom_hdr->version_id,
701 *((__u32 *)eprom_hdr->tracer), eprom_hdr->num_asics); 710 *((__u32 *) eprom_hdr->tracer), eprom_hdr->num_asics);
702 (*modpp)->ee_size = eprom_hdr->ee_size; 711 (*modpp)->ee_size = eprom_hdr->ee_size;
703 (*modpp)->num_asics = eprom_hdr->num_asics; 712 (*modpp)->num_asics = eprom_hdr->num_asics;
704 asicpp = &((*modpp)->asic); 713 asicpp = &((*modpp)->asic);
705 sp_offset = eprom_hdr->scan_path_offset; 714 sp_offset = eprom_hdr->scan_path_offset;
706 /* All we really care about are the Quad cards. We 715 /* All we really care about are the Quad cards. We
707 * identify them because they are in a processor slot 716 * identify them because they are in a processor slot
708 * and have only four asics */ 717 * and have only four asics */
709 if((i < 0x10 || (i>=0x14 && i < 0x1c) || i>0x1f)) { 718 if ((i < 0x10 || (i >= 0x14 && i < 0x1c) || i > 0x1f)) {
710 modpp = &((*modpp)->next); 719 modpp = &((*modpp)->next);
711 continue; 720 continue;
712 } 721 }
@@ -717,16 +726,17 @@ voyager_cat_init(void)
717 &num_submodules); 726 &num_submodules);
718 /* lowest two bits, active low */ 727 /* lowest two bits, active low */
719 num_submodules = ~(0xfc | num_submodules); 728 num_submodules = ~(0xfc | num_submodules);
720 CDEBUG(("VOYAGER CAT: %d submodules present\n", num_submodules)); 729 CDEBUG(("VOYAGER CAT: %d submodules present\n",
721 if(num_submodules == 0) { 730 num_submodules));
731 if (num_submodules == 0) {
722 /* fill in the dyadic extended processors */ 732 /* fill in the dyadic extended processors */
723 __u8 cpu = i & 0x07; 733 __u8 cpu = i & 0x07;
724 734
725 printk("Module \"%s\": Dyadic Processor Card\n", 735 printk("Module \"%s\": Dyadic Processor Card\n",
726 cat_module_name(i)); 736 cat_module_name(i));
727 voyager_extended_vic_processors |= (1<<cpu); 737 voyager_extended_vic_processors |= (1 << cpu);
728 cpu += 4; 738 cpu += 4;
729 voyager_extended_vic_processors |= (1<<cpu); 739 voyager_extended_vic_processors |= (1 << cpu);
730 outb(VOYAGER_CAT_END, CAT_CMD); 740 outb(VOYAGER_CAT_END, CAT_CMD);
731 continue; 741 continue;
732 } 742 }
@@ -740,28 +750,32 @@ voyager_cat_init(void)
740 cat_write(*modpp, (*modpp)->asic, VOYAGER_SUBMODSELECT, val); 750 cat_write(*modpp, (*modpp)->asic, VOYAGER_SUBMODSELECT, val);
741 751
742 outb(VOYAGER_CAT_END, CAT_CMD); 752 outb(VOYAGER_CAT_END, CAT_CMD);
743
744 753
745 CDEBUG(("cat_init: Reading eeprom for module 0x%x at offset %d\n", i, VOYAGER_XSUM_END_OFFSET)); 754 CDEBUG(("cat_init: Reading eeprom for module 0x%x at offset %d\n", i, VOYAGER_XSUM_END_OFFSET));
746 outb(VOYAGER_CAT_RUN, CAT_CMD); 755 outb(VOYAGER_CAT_RUN, CAT_CMD);
747 cat_disconnect(*modpp, (*modpp)->asic); 756 cat_disconnect(*modpp, (*modpp)->asic);
748 if(cat_subread(*modpp, (*modpp)->asic, 757 if (cat_subread(*modpp, (*modpp)->asic,
749 VOYAGER_XSUM_END_OFFSET, sizeof(eprom_size), 758 VOYAGER_XSUM_END_OFFSET, sizeof(eprom_size),
750 &eprom_size)) { 759 &eprom_size)) {
751 printk("**WARNING**: Voyager couldn't read EPROM size for module 0x%x\n", i); 760 printk
761 ("**WARNING**: Voyager couldn't read EPROM size for module 0x%x\n",
762 i);
752 outb(VOYAGER_CAT_END, CAT_CMD); 763 outb(VOYAGER_CAT_END, CAT_CMD);
753 continue; 764 continue;
754 } 765 }
755 if(eprom_size > sizeof(eprom_buf)) { 766 if (eprom_size > sizeof(eprom_buf)) {
756 printk("**WARNING**: Voyager insufficient size to read EPROM data, module 0x%x. Need %d\n", i, eprom_size); 767 printk
768 ("**WARNING**: Voyager insufficient size to read EPROM data, module 0x%x. Need %d\n",
769 i, eprom_size);
757 outb(VOYAGER_CAT_END, CAT_CMD); 770 outb(VOYAGER_CAT_END, CAT_CMD);
758 continue; 771 continue;
759 } 772 }
760 outb(VOYAGER_CAT_END, CAT_CMD); 773 outb(VOYAGER_CAT_END, CAT_CMD);
761 outb(VOYAGER_CAT_RUN, CAT_CMD); 774 outb(VOYAGER_CAT_RUN, CAT_CMD);
762 CDEBUG(("cat_init: module 0x%x, eeprom_size %d\n", i, eprom_size)); 775 CDEBUG(("cat_init: module 0x%x, eeprom_size %d\n", i,
763 if(cat_subread(*modpp, (*modpp)->asic, 0, 776 eprom_size));
764 eprom_size, eprom_buf)) { 777 if (cat_subread
778 (*modpp, (*modpp)->asic, 0, eprom_size, eprom_buf)) {
765 outb(VOYAGER_CAT_END, CAT_CMD); 779 outb(VOYAGER_CAT_END, CAT_CMD);
766 continue; 780 continue;
767 } 781 }
@@ -773,30 +787,35 @@ voyager_cat_init(void)
773 sp_offset = eprom_hdr->scan_path_offset; 787 sp_offset = eprom_hdr->scan_path_offset;
774 /* get rid of the dummy CAT asic and read the real one */ 788 /* get rid of the dummy CAT asic and read the real one */
775 kfree((*modpp)->asic); 789 kfree((*modpp)->asic);
776 for(asic=0; asic < (*modpp)->num_asics; asic++) { 790 for (asic = 0; asic < (*modpp)->num_asics; asic++) {
777 int j; 791 int j;
778 voyager_asic_t *asicp = *asicpp 792 voyager_asic_t *asicp = *asicpp = kzalloc(sizeof(voyager_asic_t), GFP_KERNEL); /*&voyager_asic_storage[asic_count++]; */
779 = kzalloc(sizeof(voyager_asic_t), GFP_KERNEL); /*&voyager_asic_storage[asic_count++];*/
780 voyager_sp_table_t *sp_table; 793 voyager_sp_table_t *sp_table;
781 voyager_at_t *asic_table; 794 voyager_at_t *asic_table;
782 voyager_jtt_t *jtag_table; 795 voyager_jtt_t *jtag_table;
783 796
784 if(asicp == NULL) { 797 if (asicp == NULL) {
785 printk("**WARNING** kmalloc failure in cat_init\n"); 798 printk
799 ("**WARNING** kmalloc failure in cat_init\n");
786 continue; 800 continue;
787 } 801 }
788 asicpp = &(asicp->next); 802 asicpp = &(asicp->next);
789 asicp->asic_location = asic; 803 asicp->asic_location = asic;
790 sp_table = (voyager_sp_table_t *)(eprom_buf + sp_offset); 804 sp_table =
805 (voyager_sp_table_t *) (eprom_buf + sp_offset);
791 asicp->asic_id = sp_table->asic_id; 806 asicp->asic_id = sp_table->asic_id;
792 asic_table = (voyager_at_t *)(eprom_buf + sp_table->asic_data_offset); 807 asic_table =
793 for(j=0; j<4; j++) 808 (voyager_at_t *) (eprom_buf +
809 sp_table->asic_data_offset);
810 for (j = 0; j < 4; j++)
794 asicp->jtag_id[j] = asic_table->jtag_id[j]; 811 asicp->jtag_id[j] = asic_table->jtag_id[j];
795 jtag_table = (voyager_jtt_t *)(eprom_buf + asic_table->jtag_offset); 812 jtag_table =
813 (voyager_jtt_t *) (eprom_buf +
814 asic_table->jtag_offset);
796 asicp->ireg_length = jtag_table->ireg_len; 815 asicp->ireg_length = jtag_table->ireg_len;
797 asicp->bit_location = (*modpp)->inst_bits; 816 asicp->bit_location = (*modpp)->inst_bits;
798 (*modpp)->inst_bits += asicp->ireg_length; 817 (*modpp)->inst_bits += asicp->ireg_length;
799 if(asicp->ireg_length > (*modpp)->largest_reg) 818 if (asicp->ireg_length > (*modpp)->largest_reg)
800 (*modpp)->largest_reg = asicp->ireg_length; 819 (*modpp)->largest_reg = asicp->ireg_length;
801 if (asicp->ireg_length < (*modpp)->smallest_reg || 820 if (asicp->ireg_length < (*modpp)->smallest_reg ||
802 (*modpp)->smallest_reg == 0) 821 (*modpp)->smallest_reg == 0)
@@ -804,15 +823,13 @@ voyager_cat_init(void)
804 CDEBUG(("asic 0x%x, ireg_length=%d, bit_location=%d\n", 823 CDEBUG(("asic 0x%x, ireg_length=%d, bit_location=%d\n",
805 asicp->asic_id, asicp->ireg_length, 824 asicp->asic_id, asicp->ireg_length,
806 asicp->bit_location)); 825 asicp->bit_location));
807 if(asicp->asic_id == VOYAGER_QUAD_QABC) { 826 if (asicp->asic_id == VOYAGER_QUAD_QABC) {
808 CDEBUG(("VOYAGER CAT: QABC ASIC found\n")); 827 CDEBUG(("VOYAGER CAT: QABC ASIC found\n"));
809 qabc_asic = asicp; 828 qabc_asic = asicp;
810 } 829 }
811 sp_offset += sizeof(voyager_sp_table_t); 830 sp_offset += sizeof(voyager_sp_table_t);
812 } 831 }
813 CDEBUG(("Module inst_bits = %d, largest_reg = %d, smallest_reg=%d\n", 832 CDEBUG(("Module inst_bits = %d, largest_reg = %d, smallest_reg=%d\n", (*modpp)->inst_bits, (*modpp)->largest_reg, (*modpp)->smallest_reg));
814 (*modpp)->inst_bits, (*modpp)->largest_reg,
815 (*modpp)->smallest_reg));
816 /* OK, now we have the QUAD ASICs set up, use them. 833 /* OK, now we have the QUAD ASICs set up, use them.
817 * we need to: 834 * we need to:
818 * 835 *
@@ -828,10 +845,11 @@ voyager_cat_init(void)
828 qic_addr = qabc_data[5] << 8; 845 qic_addr = qabc_data[5] << 8;
829 qic_addr = (qic_addr | qabc_data[6]) << 8; 846 qic_addr = (qic_addr | qabc_data[6]) << 8;
830 qic_addr = (qic_addr | qabc_data[7]) << 8; 847 qic_addr = (qic_addr | qabc_data[7]) << 8;
831 printk("Module \"%s\": Quad Processor Card; CPI 0x%lx, SET=0x%x\n", 848 printk
832 cat_module_name(i), qic_addr, qabc_data[8]); 849 ("Module \"%s\": Quad Processor Card; CPI 0x%lx, SET=0x%x\n",
850 cat_module_name(i), qic_addr, qabc_data[8]);
833#if 0 /* plumbing fails---FIXME */ 851#if 0 /* plumbing fails---FIXME */
834 if((qabc_data[8] & 0xf0) == 0) { 852 if ((qabc_data[8] & 0xf0) == 0) {
835 /* FIXME: 32 way 8 CPU slot monster cannot be 853 /* FIXME: 32 way 8 CPU slot monster cannot be
836 * plumbed this way---need to check for it */ 854 * plumbed this way---need to check for it */
837 855
@@ -842,94 +860,97 @@ voyager_cat_init(void)
842#ifdef VOYAGER_CAT_DEBUG 860#ifdef VOYAGER_CAT_DEBUG
843 /* verify plumbing */ 861 /* verify plumbing */
844 cat_subread(*modpp, qabc_asic, 8, 1, &qabc_data[8]); 862 cat_subread(*modpp, qabc_asic, 8, 1, &qabc_data[8]);
845 if((qabc_data[8] & 0xf0) == 0) { 863 if ((qabc_data[8] & 0xf0) == 0) {
846 CDEBUG(("PLUMBING FAILED: 0x%x\n", qabc_data[8])); 864 CDEBUG(("PLUMBING FAILED: 0x%x\n",
865 qabc_data[8]));
847 } 866 }
848#endif 867#endif
849 } 868 }
850#endif 869#endif
851 870
852 { 871 {
853 struct resource *res = kzalloc(sizeof(struct resource),GFP_KERNEL); 872 struct resource *res =
873 kzalloc(sizeof(struct resource), GFP_KERNEL);
854 res->name = kmalloc(128, GFP_KERNEL); 874 res->name = kmalloc(128, GFP_KERNEL);
855 sprintf((char *)res->name, "Voyager %s Quad CPI", cat_module_name(i)); 875 sprintf((char *)res->name, "Voyager %s Quad CPI",
876 cat_module_name(i));
856 res->start = qic_addr; 877 res->start = qic_addr;
857 res->end = qic_addr + 0x3ff; 878 res->end = qic_addr + 0x3ff;
858 request_resource(&iomem_resource, res); 879 request_resource(&iomem_resource, res);
859 } 880 }
860 881
861 qic_addr = (unsigned long)ioremap(qic_addr, 0x400); 882 qic_addr = (unsigned long)ioremap(qic_addr, 0x400);
862 883
863 for(j = 0; j < 4; j++) { 884 for (j = 0; j < 4; j++) {
864 __u8 cpu; 885 __u8 cpu;
865 886
866 if(voyager_8slot) { 887 if (voyager_8slot) {
867 /* 8 slot has a different mapping, 888 /* 8 slot has a different mapping,
868 * each slot has only one vic line, so 889 * each slot has only one vic line, so
869 * 1 cpu in each slot must be < 8 */ 890 * 1 cpu in each slot must be < 8 */
870 cpu = (i & 0x07) + j*8; 891 cpu = (i & 0x07) + j * 8;
871 } else { 892 } else {
872 cpu = (i & 0x03) + j*4; 893 cpu = (i & 0x03) + j * 4;
873 } 894 }
874 if( (qabc_data[8] & (1<<j))) { 895 if ((qabc_data[8] & (1 << j))) {
875 voyager_extended_vic_processors |= (1<<cpu); 896 voyager_extended_vic_processors |= (1 << cpu);
876 } 897 }
877 if(qabc_data[8] & (1<<(j+4)) ) { 898 if (qabc_data[8] & (1 << (j + 4))) {
878 /* Second SET register plumbed: Quad 899 /* Second SET register plumbed: Quad
879 * card has two VIC connected CPUs. 900 * card has two VIC connected CPUs.
880 * Secondary cannot be booted as a VIC 901 * Secondary cannot be booted as a VIC
881 * CPU */ 902 * CPU */
882 voyager_extended_vic_processors |= (1<<cpu); 903 voyager_extended_vic_processors |= (1 << cpu);
883 voyager_allowed_boot_processors &= (~(1<<cpu)); 904 voyager_allowed_boot_processors &=
905 (~(1 << cpu));
884 } 906 }
885 907
886 voyager_quad_processors |= (1<<cpu); 908 voyager_quad_processors |= (1 << cpu);
887 voyager_quad_cpi_addr[cpu] = (struct voyager_qic_cpi *) 909 voyager_quad_cpi_addr[cpu] = (struct voyager_qic_cpi *)
888 (qic_addr+(j<<8)); 910 (qic_addr + (j << 8));
889 CDEBUG(("CPU%d: CPI address 0x%lx\n", cpu, 911 CDEBUG(("CPU%d: CPI address 0x%lx\n", cpu,
890 (unsigned long)voyager_quad_cpi_addr[cpu])); 912 (unsigned long)voyager_quad_cpi_addr[cpu]));
891 } 913 }
892 outb(VOYAGER_CAT_END, CAT_CMD); 914 outb(VOYAGER_CAT_END, CAT_CMD);
893 915
894
895
896 *asicpp = NULL; 916 *asicpp = NULL;
897 modpp = &((*modpp)->next); 917 modpp = &((*modpp)->next);
898 } 918 }
899 *modpp = NULL; 919 *modpp = NULL;
900 printk("CAT Bus Initialisation finished: extended procs 0x%x, quad procs 0x%x, allowed vic boot = 0x%x\n", voyager_extended_vic_processors, voyager_quad_processors, voyager_allowed_boot_processors); 920 printk
921 ("CAT Bus Initialisation finished: extended procs 0x%x, quad procs 0x%x, allowed vic boot = 0x%x\n",
922 voyager_extended_vic_processors, voyager_quad_processors,
923 voyager_allowed_boot_processors);
901 request_resource(&ioport_resource, &vic_res); 924 request_resource(&ioport_resource, &vic_res);
902 if(voyager_quad_processors) 925 if (voyager_quad_processors)
903 request_resource(&ioport_resource, &qic_res); 926 request_resource(&ioport_resource, &qic_res);
904 /* set up the front power switch */ 927 /* set up the front power switch */
905} 928}
906 929
907int 930int voyager_cat_readb(__u8 module, __u8 asic, int reg)
908voyager_cat_readb(__u8 module, __u8 asic, int reg)
909{ 931{
910 return 0; 932 return 0;
911} 933}
912 934
913static int 935static int cat_disconnect(voyager_module_t * modp, voyager_asic_t * asicp)
914cat_disconnect(voyager_module_t *modp, voyager_asic_t *asicp)
915{ 936{
916 __u8 val; 937 __u8 val;
917 int err = 0; 938 int err = 0;
918 939
919 if(!modp->scan_path_connected) 940 if (!modp->scan_path_connected)
920 return 0; 941 return 0;
921 if(asicp->asic_id != VOYAGER_CAT_ID) { 942 if (asicp->asic_id != VOYAGER_CAT_ID) {
922 CDEBUG(("cat_disconnect: ASIC is not CAT\n")); 943 CDEBUG(("cat_disconnect: ASIC is not CAT\n"));
923 return 1; 944 return 1;
924 } 945 }
925 err = cat_read(modp, asicp, VOYAGER_SCANPATH, &val); 946 err = cat_read(modp, asicp, VOYAGER_SCANPATH, &val);
926 if(err) { 947 if (err) {
927 CDEBUG(("cat_disconnect: failed to read SCANPATH\n")); 948 CDEBUG(("cat_disconnect: failed to read SCANPATH\n"));
928 return err; 949 return err;
929 } 950 }
930 val &= VOYAGER_DISCONNECT_ASIC; 951 val &= VOYAGER_DISCONNECT_ASIC;
931 err = cat_write(modp, asicp, VOYAGER_SCANPATH, val); 952 err = cat_write(modp, asicp, VOYAGER_SCANPATH, val);
932 if(err) { 953 if (err) {
933 CDEBUG(("cat_disconnect: failed to write SCANPATH\n")); 954 CDEBUG(("cat_disconnect: failed to write SCANPATH\n"));
934 return err; 955 return err;
935 } 956 }
@@ -940,27 +961,26 @@ cat_disconnect(voyager_module_t *modp, voyager_asic_t *asicp)
940 return 0; 961 return 0;
941} 962}
942 963
943static int 964static int cat_connect(voyager_module_t * modp, voyager_asic_t * asicp)
944cat_connect(voyager_module_t *modp, voyager_asic_t *asicp)
945{ 965{
946 __u8 val; 966 __u8 val;
947 int err = 0; 967 int err = 0;
948 968
949 if(modp->scan_path_connected) 969 if (modp->scan_path_connected)
950 return 0; 970 return 0;
951 if(asicp->asic_id != VOYAGER_CAT_ID) { 971 if (asicp->asic_id != VOYAGER_CAT_ID) {
952 CDEBUG(("cat_connect: ASIC is not CAT\n")); 972 CDEBUG(("cat_connect: ASIC is not CAT\n"));
953 return 1; 973 return 1;
954 } 974 }
955 975
956 err = cat_read(modp, asicp, VOYAGER_SCANPATH, &val); 976 err = cat_read(modp, asicp, VOYAGER_SCANPATH, &val);
957 if(err) { 977 if (err) {
958 CDEBUG(("cat_connect: failed to read SCANPATH\n")); 978 CDEBUG(("cat_connect: failed to read SCANPATH\n"));
959 return err; 979 return err;
960 } 980 }
961 val |= VOYAGER_CONNECT_ASIC; 981 val |= VOYAGER_CONNECT_ASIC;
962 err = cat_write(modp, asicp, VOYAGER_SCANPATH, val); 982 err = cat_write(modp, asicp, VOYAGER_SCANPATH, val);
963 if(err) { 983 if (err) {
964 CDEBUG(("cat_connect: failed to write SCANPATH\n")); 984 CDEBUG(("cat_connect: failed to write SCANPATH\n"));
965 return err; 985 return err;
966 } 986 }
@@ -971,11 +991,10 @@ cat_connect(voyager_module_t *modp, voyager_asic_t *asicp)
971 return 0; 991 return 0;
972} 992}
973 993
974void 994void voyager_cat_power_off(void)
975voyager_cat_power_off(void)
976{ 995{
977 /* Power the machine off by writing to the PSI over the CAT 996 /* Power the machine off by writing to the PSI over the CAT
978 * bus */ 997 * bus */
979 __u8 data; 998 __u8 data;
980 voyager_module_t psi = { 0 }; 999 voyager_module_t psi = { 0 };
981 voyager_asic_t psi_asic = { 0 }; 1000 voyager_asic_t psi_asic = { 0 };
@@ -1009,8 +1028,7 @@ voyager_cat_power_off(void)
1009 1028
1010struct voyager_status voyager_status = { 0 }; 1029struct voyager_status voyager_status = { 0 };
1011 1030
1012void 1031void voyager_cat_psi(__u8 cmd, __u16 reg, __u8 * data)
1013voyager_cat_psi(__u8 cmd, __u16 reg, __u8 *data)
1014{ 1032{
1015 voyager_module_t psi = { 0 }; 1033 voyager_module_t psi = { 0 };
1016 voyager_asic_t psi_asic = { 0 }; 1034 voyager_asic_t psi_asic = { 0 };
@@ -1027,7 +1045,7 @@ voyager_cat_psi(__u8 cmd, __u16 reg, __u8 *data)
1027 outb(VOYAGER_PSI, VOYAGER_CAT_CONFIG_PORT); 1045 outb(VOYAGER_PSI, VOYAGER_CAT_CONFIG_PORT);
1028 outb(VOYAGER_CAT_RUN, CAT_CMD); 1046 outb(VOYAGER_CAT_RUN, CAT_CMD);
1029 cat_disconnect(&psi, &psi_asic); 1047 cat_disconnect(&psi, &psi_asic);
1030 switch(cmd) { 1048 switch (cmd) {
1031 case VOYAGER_PSI_READ: 1049 case VOYAGER_PSI_READ:
1032 cat_read(&psi, &psi_asic, reg, data); 1050 cat_read(&psi, &psi_asic, reg, data);
1033 break; 1051 break;
@@ -1047,8 +1065,7 @@ voyager_cat_psi(__u8 cmd, __u16 reg, __u8 *data)
1047 outb(VOYAGER_CAT_END, CAT_CMD); 1065 outb(VOYAGER_CAT_END, CAT_CMD);
1048} 1066}
1049 1067
1050void 1068void voyager_cat_do_common_interrupt(void)
1051voyager_cat_do_common_interrupt(void)
1052{ 1069{
1053 /* This is caused either by a memory parity error or something 1070 /* This is caused either by a memory parity error or something
1054 * in the PSI */ 1071 * in the PSI */
@@ -1057,7 +1074,7 @@ voyager_cat_do_common_interrupt(void)
1057 voyager_asic_t psi_asic = { 0 }; 1074 voyager_asic_t psi_asic = { 0 };
1058 struct voyager_psi psi_reg; 1075 struct voyager_psi psi_reg;
1059 int i; 1076 int i;
1060 re_read: 1077 re_read:
1061 psi.asic = &psi_asic; 1078 psi.asic = &psi_asic;
1062 psi.asic->asic_id = VOYAGER_CAT_ID; 1079 psi.asic->asic_id = VOYAGER_CAT_ID;
1063 psi.asic->subaddr = VOYAGER_SUBADDR_HI; 1080 psi.asic->subaddr = VOYAGER_SUBADDR_HI;
@@ -1072,43 +1089,45 @@ voyager_cat_do_common_interrupt(void)
1072 cat_disconnect(&psi, &psi_asic); 1089 cat_disconnect(&psi, &psi_asic);
1073 /* Read the status. NOTE: Need to read *all* the PSI regs here 1090 /* Read the status. NOTE: Need to read *all* the PSI regs here
1074 * otherwise the cmn int will be reasserted */ 1091 * otherwise the cmn int will be reasserted */
1075 for(i = 0; i < sizeof(psi_reg.regs); i++) { 1092 for (i = 0; i < sizeof(psi_reg.regs); i++) {
1076 cat_read(&psi, &psi_asic, i, &((__u8 *)&psi_reg.regs)[i]); 1093 cat_read(&psi, &psi_asic, i, &((__u8 *) & psi_reg.regs)[i]);
1077 } 1094 }
1078 outb(VOYAGER_CAT_END, CAT_CMD); 1095 outb(VOYAGER_CAT_END, CAT_CMD);
1079 if((psi_reg.regs.checkbit & 0x02) == 0) { 1096 if ((psi_reg.regs.checkbit & 0x02) == 0) {
1080 psi_reg.regs.checkbit |= 0x02; 1097 psi_reg.regs.checkbit |= 0x02;
1081 cat_write(&psi, &psi_asic, 5, psi_reg.regs.checkbit); 1098 cat_write(&psi, &psi_asic, 5, psi_reg.regs.checkbit);
1082 printk("VOYAGER RE-READ PSI\n"); 1099 printk("VOYAGER RE-READ PSI\n");
1083 goto re_read; 1100 goto re_read;
1084 } 1101 }
1085 outb(VOYAGER_CAT_RUN, CAT_CMD); 1102 outb(VOYAGER_CAT_RUN, CAT_CMD);
1086 for(i = 0; i < sizeof(psi_reg.subregs); i++) { 1103 for (i = 0; i < sizeof(psi_reg.subregs); i++) {
1087 /* This looks strange, but the PSI doesn't do auto increment 1104 /* This looks strange, but the PSI doesn't do auto increment
1088 * correctly */ 1105 * correctly */
1089 cat_subread(&psi, &psi_asic, VOYAGER_PSI_SUPPLY_REG + i, 1106 cat_subread(&psi, &psi_asic, VOYAGER_PSI_SUPPLY_REG + i,
1090 1, &((__u8 *)&psi_reg.subregs)[i]); 1107 1, &((__u8 *) & psi_reg.subregs)[i]);
1091 } 1108 }
1092 outb(VOYAGER_CAT_END, CAT_CMD); 1109 outb(VOYAGER_CAT_END, CAT_CMD);
1093#ifdef VOYAGER_CAT_DEBUG 1110#ifdef VOYAGER_CAT_DEBUG
1094 printk("VOYAGER PSI: "); 1111 printk("VOYAGER PSI: ");
1095 for(i=0; i<sizeof(psi_reg.regs); i++) 1112 for (i = 0; i < sizeof(psi_reg.regs); i++)
1096 printk("%02x ", ((__u8 *)&psi_reg.regs)[i]); 1113 printk("%02x ", ((__u8 *) & psi_reg.regs)[i]);
1097 printk("\n "); 1114 printk("\n ");
1098 for(i=0; i<sizeof(psi_reg.subregs); i++) 1115 for (i = 0; i < sizeof(psi_reg.subregs); i++)
1099 printk("%02x ", ((__u8 *)&psi_reg.subregs)[i]); 1116 printk("%02x ", ((__u8 *) & psi_reg.subregs)[i]);
1100 printk("\n"); 1117 printk("\n");
1101#endif 1118#endif
1102 if(psi_reg.regs.intstatus & PSI_MON) { 1119 if (psi_reg.regs.intstatus & PSI_MON) {
1103 /* switch off or power fail */ 1120 /* switch off or power fail */
1104 1121
1105 if(psi_reg.subregs.supply & PSI_SWITCH_OFF) { 1122 if (psi_reg.subregs.supply & PSI_SWITCH_OFF) {
1106 if(voyager_status.switch_off) { 1123 if (voyager_status.switch_off) {
1107 printk(KERN_ERR "Voyager front panel switch turned off again---Immediate power off!\n"); 1124 printk(KERN_ERR
1125 "Voyager front panel switch turned off again---Immediate power off!\n");
1108 voyager_cat_power_off(); 1126 voyager_cat_power_off();
1109 /* not reached */ 1127 /* not reached */
1110 } else { 1128 } else {
1111 printk(KERN_ERR "Voyager front panel switch turned off\n"); 1129 printk(KERN_ERR
1130 "Voyager front panel switch turned off\n");
1112 voyager_status.switch_off = 1; 1131 voyager_status.switch_off = 1;
1113 voyager_status.request_from_kernel = 1; 1132 voyager_status.request_from_kernel = 1;
1114 wake_up_process(voyager_thread); 1133 wake_up_process(voyager_thread);
@@ -1127,7 +1146,7 @@ voyager_cat_do_common_interrupt(void)
1127 1146
1128 VDEBUG(("Voyager ac fail reg 0x%x\n", 1147 VDEBUG(("Voyager ac fail reg 0x%x\n",
1129 psi_reg.subregs.ACfail)); 1148 psi_reg.subregs.ACfail));
1130 if((psi_reg.subregs.ACfail & AC_FAIL_STAT_CHANGE) == 0) { 1149 if ((psi_reg.subregs.ACfail & AC_FAIL_STAT_CHANGE) == 0) {
1131 /* No further update */ 1150 /* No further update */
1132 return; 1151 return;
1133 } 1152 }
@@ -1135,20 +1154,20 @@ voyager_cat_do_common_interrupt(void)
1135 /* Don't bother trying to find out who failed. 1154 /* Don't bother trying to find out who failed.
1136 * FIXME: This probably makes the code incorrect on 1155 * FIXME: This probably makes the code incorrect on
1137 * anything other than a 345x */ 1156 * anything other than a 345x */
1138 for(i=0; i< 5; i++) { 1157 for (i = 0; i < 5; i++) {
1139 if( psi_reg.subregs.ACfail &(1<<i)) { 1158 if (psi_reg.subregs.ACfail & (1 << i)) {
1140 break; 1159 break;
1141 } 1160 }
1142 } 1161 }
1143 printk(KERN_NOTICE "AC FAIL IN SUPPLY %d\n", i); 1162 printk(KERN_NOTICE "AC FAIL IN SUPPLY %d\n", i);
1144#endif 1163#endif
1145 /* DON'T do this: it shuts down the AC PSI 1164 /* DON'T do this: it shuts down the AC PSI
1146 outb(VOYAGER_CAT_RUN, CAT_CMD); 1165 outb(VOYAGER_CAT_RUN, CAT_CMD);
1147 data = PSI_MASK_MASK | i; 1166 data = PSI_MASK_MASK | i;
1148 cat_subwrite(&psi, &psi_asic, VOYAGER_PSI_MASK, 1167 cat_subwrite(&psi, &psi_asic, VOYAGER_PSI_MASK,
1149 1, &data); 1168 1, &data);
1150 outb(VOYAGER_CAT_END, CAT_CMD); 1169 outb(VOYAGER_CAT_END, CAT_CMD);
1151 */ 1170 */
1152 printk(KERN_ERR "Voyager AC power failure\n"); 1171 printk(KERN_ERR "Voyager AC power failure\n");
1153 outb(VOYAGER_CAT_RUN, CAT_CMD); 1172 outb(VOYAGER_CAT_RUN, CAT_CMD);
1154 data = PSI_COLD_START; 1173 data = PSI_COLD_START;
@@ -1159,16 +1178,16 @@ voyager_cat_do_common_interrupt(void)
1159 voyager_status.request_from_kernel = 1; 1178 voyager_status.request_from_kernel = 1;
1160 wake_up_process(voyager_thread); 1179 wake_up_process(voyager_thread);
1161 } 1180 }
1162 1181
1163 1182 } else if (psi_reg.regs.intstatus & PSI_FAULT) {
1164 } else if(psi_reg.regs.intstatus & PSI_FAULT) {
1165 /* Major fault! */ 1183 /* Major fault! */
1166 printk(KERN_ERR "Voyager PSI Detected major fault, immediate power off!\n"); 1184 printk(KERN_ERR
1185 "Voyager PSI Detected major fault, immediate power off!\n");
1167 voyager_cat_power_off(); 1186 voyager_cat_power_off();
1168 /* not reached */ 1187 /* not reached */
1169 } else if(psi_reg.regs.intstatus & (PSI_DC_FAIL | PSI_ALARM 1188 } else if (psi_reg.regs.intstatus & (PSI_DC_FAIL | PSI_ALARM
1170 | PSI_CURRENT | PSI_DVM 1189 | PSI_CURRENT | PSI_DVM
1171 | PSI_PSCFAULT | PSI_STAT_CHG)) { 1190 | PSI_PSCFAULT | PSI_STAT_CHG)) {
1172 /* other psi fault */ 1191 /* other psi fault */
1173 1192
1174 printk(KERN_WARNING "Voyager PSI status 0x%x\n", data); 1193 printk(KERN_WARNING "Voyager PSI status 0x%x\n", data);
diff --git a/arch/x86/mach-voyager/voyager_smp.c b/arch/x86/mach-voyager/voyager_smp.c
index 88124dd35406..dffa786f61fe 100644
--- a/arch/x86/mach-voyager/voyager_smp.c
+++ b/arch/x86/mach-voyager/voyager_smp.c
@@ -32,7 +32,8 @@
32DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate) = { &init_mm, 0 }; 32DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate) = { &init_mm, 0 };
33 33
34/* CPU IRQ affinity -- set to all ones initially */ 34/* CPU IRQ affinity -- set to all ones initially */
35static unsigned long cpu_irq_affinity[NR_CPUS] __cacheline_aligned = { [0 ... NR_CPUS-1] = ~0UL }; 35static unsigned long cpu_irq_affinity[NR_CPUS] __cacheline_aligned =
36 {[0 ... NR_CPUS-1] = ~0UL };
36 37
37/* per CPU data structure (for /proc/cpuinfo et al), visible externally 38/* per CPU data structure (for /proc/cpuinfo et al), visible externally
38 * indexed physically */ 39 * indexed physically */
@@ -76,7 +77,6 @@ EXPORT_SYMBOL(cpu_online_map);
76 * by scheduler but indexed physically */ 77 * by scheduler but indexed physically */
77cpumask_t phys_cpu_present_map = CPU_MASK_NONE; 78cpumask_t phys_cpu_present_map = CPU_MASK_NONE;
78 79
79
80/* The internal functions */ 80/* The internal functions */
81static void send_CPI(__u32 cpuset, __u8 cpi); 81static void send_CPI(__u32 cpuset, __u8 cpi);
82static void ack_CPI(__u8 cpi); 82static void ack_CPI(__u8 cpi);
@@ -101,94 +101,86 @@ int hard_smp_processor_id(void);
101int safe_smp_processor_id(void); 101int safe_smp_processor_id(void);
102 102
103/* Inline functions */ 103/* Inline functions */
104static inline void 104static inline void send_one_QIC_CPI(__u8 cpu, __u8 cpi)
105send_one_QIC_CPI(__u8 cpu, __u8 cpi)
106{ 105{
107 voyager_quad_cpi_addr[cpu]->qic_cpi[cpi].cpi = 106 voyager_quad_cpi_addr[cpu]->qic_cpi[cpi].cpi =
108 (smp_processor_id() << 16) + cpi; 107 (smp_processor_id() << 16) + cpi;
109} 108}
110 109
111static inline void 110static inline void send_QIC_CPI(__u32 cpuset, __u8 cpi)
112send_QIC_CPI(__u32 cpuset, __u8 cpi)
113{ 111{
114 int cpu; 112 int cpu;
115 113
116 for_each_online_cpu(cpu) { 114 for_each_online_cpu(cpu) {
117 if(cpuset & (1<<cpu)) { 115 if (cpuset & (1 << cpu)) {
118#ifdef VOYAGER_DEBUG 116#ifdef VOYAGER_DEBUG
119 if(!cpu_isset(cpu, cpu_online_map)) 117 if (!cpu_isset(cpu, cpu_online_map))
120 VDEBUG(("CPU%d sending cpi %d to CPU%d not in cpu_online_map\n", hard_smp_processor_id(), cpi, cpu)); 118 VDEBUG(("CPU%d sending cpi %d to CPU%d not in "
119 "cpu_online_map\n",
120 hard_smp_processor_id(), cpi, cpu));
121#endif 121#endif
122 send_one_QIC_CPI(cpu, cpi - QIC_CPI_OFFSET); 122 send_one_QIC_CPI(cpu, cpi - QIC_CPI_OFFSET);
123 } 123 }
124 } 124 }
125} 125}
126 126
127static inline void 127static inline void wrapper_smp_local_timer_interrupt(void)
128wrapper_smp_local_timer_interrupt(void)
129{ 128{
130 irq_enter(); 129 irq_enter();
131 smp_local_timer_interrupt(); 130 smp_local_timer_interrupt();
132 irq_exit(); 131 irq_exit();
133} 132}
134 133
135static inline void 134static inline void send_one_CPI(__u8 cpu, __u8 cpi)
136send_one_CPI(__u8 cpu, __u8 cpi)
137{ 135{
138 if(voyager_quad_processors & (1<<cpu)) 136 if (voyager_quad_processors & (1 << cpu))
139 send_one_QIC_CPI(cpu, cpi - QIC_CPI_OFFSET); 137 send_one_QIC_CPI(cpu, cpi - QIC_CPI_OFFSET);
140 else 138 else
141 send_CPI(1<<cpu, cpi); 139 send_CPI(1 << cpu, cpi);
142} 140}
143 141
144static inline void 142static inline void send_CPI_allbutself(__u8 cpi)
145send_CPI_allbutself(__u8 cpi)
146{ 143{
147 __u8 cpu = smp_processor_id(); 144 __u8 cpu = smp_processor_id();
148 __u32 mask = cpus_addr(cpu_online_map)[0] & ~(1 << cpu); 145 __u32 mask = cpus_addr(cpu_online_map)[0] & ~(1 << cpu);
149 send_CPI(mask, cpi); 146 send_CPI(mask, cpi);
150} 147}
151 148
152static inline int 149static inline int is_cpu_quad(void)
153is_cpu_quad(void)
154{ 150{
155 __u8 cpumask = inb(VIC_PROC_WHO_AM_I); 151 __u8 cpumask = inb(VIC_PROC_WHO_AM_I);
156 return ((cpumask & QUAD_IDENTIFIER) == QUAD_IDENTIFIER); 152 return ((cpumask & QUAD_IDENTIFIER) == QUAD_IDENTIFIER);
157} 153}
158 154
159static inline int 155static inline int is_cpu_extended(void)
160is_cpu_extended(void)
161{ 156{
162 __u8 cpu = hard_smp_processor_id(); 157 __u8 cpu = hard_smp_processor_id();
163 158
164 return(voyager_extended_vic_processors & (1<<cpu)); 159 return (voyager_extended_vic_processors & (1 << cpu));
165} 160}
166 161
167static inline int 162static inline int is_cpu_vic_boot(void)
168is_cpu_vic_boot(void)
169{ 163{
170 __u8 cpu = hard_smp_processor_id(); 164 __u8 cpu = hard_smp_processor_id();
171 165
172 return(voyager_extended_vic_processors 166 return (voyager_extended_vic_processors
173 & voyager_allowed_boot_processors & (1<<cpu)); 167 & voyager_allowed_boot_processors & (1 << cpu));
174} 168}
175 169
176 170static inline void ack_CPI(__u8 cpi)
177static inline void
178ack_CPI(__u8 cpi)
179{ 171{
180 switch(cpi) { 172 switch (cpi) {
181 case VIC_CPU_BOOT_CPI: 173 case VIC_CPU_BOOT_CPI:
182 if(is_cpu_quad() && !is_cpu_vic_boot()) 174 if (is_cpu_quad() && !is_cpu_vic_boot())
183 ack_QIC_CPI(cpi); 175 ack_QIC_CPI(cpi);
184 else 176 else
185 ack_VIC_CPI(cpi); 177 ack_VIC_CPI(cpi);
186 break; 178 break;
187 case VIC_SYS_INT: 179 case VIC_SYS_INT:
188 case VIC_CMN_INT: 180 case VIC_CMN_INT:
189 /* These are slightly strange. Even on the Quad card, 181 /* These are slightly strange. Even on the Quad card,
190 * They are vectored as VIC CPIs */ 182 * They are vectored as VIC CPIs */
191 if(is_cpu_quad()) 183 if (is_cpu_quad())
192 ack_special_QIC_CPI(cpi); 184 ack_special_QIC_CPI(cpi);
193 else 185 else
194 ack_VIC_CPI(cpi); 186 ack_VIC_CPI(cpi);
@@ -205,11 +197,11 @@ ack_CPI(__u8 cpi)
205 * 8259 IRQs except that masks and things must be kept per processor 197 * 8259 IRQs except that masks and things must be kept per processor
206 */ 198 */
207static struct irq_chip vic_chip = { 199static struct irq_chip vic_chip = {
208 .name = "VIC", 200 .name = "VIC",
209 .startup = startup_vic_irq, 201 .startup = startup_vic_irq,
210 .mask = mask_vic_irq, 202 .mask = mask_vic_irq,
211 .unmask = unmask_vic_irq, 203 .unmask = unmask_vic_irq,
212 .set_affinity = set_vic_irq_affinity, 204 .set_affinity = set_vic_irq_affinity,
213}; 205};
214 206
215/* used to count up as CPUs are brought on line (starts at 0) */ 207/* used to count up as CPUs are brought on line (starts at 0) */
@@ -223,7 +215,7 @@ static __u32 trampoline_base;
223/* The per cpu profile stuff - used in smp_local_timer_interrupt */ 215/* The per cpu profile stuff - used in smp_local_timer_interrupt */
224static DEFINE_PER_CPU(int, prof_multiplier) = 1; 216static DEFINE_PER_CPU(int, prof_multiplier) = 1;
225static DEFINE_PER_CPU(int, prof_old_multiplier) = 1; 217static DEFINE_PER_CPU(int, prof_old_multiplier) = 1;
226static DEFINE_PER_CPU(int, prof_counter) = 1; 218static DEFINE_PER_CPU(int, prof_counter) = 1;
227 219
228/* the map used to check if a CPU has booted */ 220/* the map used to check if a CPU has booted */
229static __u32 cpu_booted_map; 221static __u32 cpu_booted_map;
@@ -235,7 +227,6 @@ static cpumask_t smp_commenced_mask = CPU_MASK_NONE;
235/* This is for the new dynamic CPU boot code */ 227/* This is for the new dynamic CPU boot code */
236cpumask_t cpu_callin_map = CPU_MASK_NONE; 228cpumask_t cpu_callin_map = CPU_MASK_NONE;
237cpumask_t cpu_callout_map = CPU_MASK_NONE; 229cpumask_t cpu_callout_map = CPU_MASK_NONE;
238EXPORT_SYMBOL(cpu_callout_map);
239cpumask_t cpu_possible_map = CPU_MASK_NONE; 230cpumask_t cpu_possible_map = CPU_MASK_NONE;
240EXPORT_SYMBOL(cpu_possible_map); 231EXPORT_SYMBOL(cpu_possible_map);
241 232
@@ -246,9 +237,9 @@ static __u16 vic_irq_mask[NR_CPUS] __cacheline_aligned;
246static __u16 vic_irq_enable_mask[NR_CPUS] __cacheline_aligned = { 0 }; 237static __u16 vic_irq_enable_mask[NR_CPUS] __cacheline_aligned = { 0 };
247 238
248/* Lock for enable/disable of VIC interrupts */ 239/* Lock for enable/disable of VIC interrupts */
249static __cacheline_aligned DEFINE_SPINLOCK(vic_irq_lock); 240static __cacheline_aligned DEFINE_SPINLOCK(vic_irq_lock);
250 241
251/* The boot processor is correctly set up in PC mode when it 242/* The boot processor is correctly set up in PC mode when it
252 * comes up, but the secondaries need their master/slave 8259 243 * comes up, but the secondaries need their master/slave 8259
253 * pairs initializing correctly */ 244 * pairs initializing correctly */
254 245
@@ -262,8 +253,7 @@ static unsigned long vic_tick[NR_CPUS] __cacheline_aligned = { 0 };
262static unsigned long vic_cpi_mailbox[NR_CPUS] __cacheline_aligned; 253static unsigned long vic_cpi_mailbox[NR_CPUS] __cacheline_aligned;
263 254
264/* debugging routine to read the isr of the cpu's pic */ 255/* debugging routine to read the isr of the cpu's pic */
265static inline __u16 256static inline __u16 vic_read_isr(void)
266vic_read_isr(void)
267{ 257{
268 __u16 isr; 258 __u16 isr;
269 259
@@ -275,17 +265,16 @@ vic_read_isr(void)
275 return isr; 265 return isr;
276} 266}
277 267
278static __init void 268static __init void qic_setup(void)
279qic_setup(void)
280{ 269{
281 if(!is_cpu_quad()) { 270 if (!is_cpu_quad()) {
282 /* not a quad, no setup */ 271 /* not a quad, no setup */
283 return; 272 return;
284 } 273 }
285 outb(QIC_DEFAULT_MASK0, QIC_MASK_REGISTER0); 274 outb(QIC_DEFAULT_MASK0, QIC_MASK_REGISTER0);
286 outb(QIC_CPI_ENABLE, QIC_MASK_REGISTER1); 275 outb(QIC_CPI_ENABLE, QIC_MASK_REGISTER1);
287 276
288 if(is_cpu_extended()) { 277 if (is_cpu_extended()) {
289 /* the QIC duplicate of the VIC base register */ 278 /* the QIC duplicate of the VIC base register */
290 outb(VIC_DEFAULT_CPI_BASE, QIC_VIC_CPI_BASE_REGISTER); 279 outb(VIC_DEFAULT_CPI_BASE, QIC_VIC_CPI_BASE_REGISTER);
291 outb(QIC_DEFAULT_CPI_BASE, QIC_CPI_BASE_REGISTER); 280 outb(QIC_DEFAULT_CPI_BASE, QIC_CPI_BASE_REGISTER);
@@ -295,8 +284,7 @@ qic_setup(void)
295 } 284 }
296} 285}
297 286
298static __init void 287static __init void vic_setup_pic(void)
299vic_setup_pic(void)
300{ 288{
301 outb(1, VIC_REDIRECT_REGISTER_1); 289 outb(1, VIC_REDIRECT_REGISTER_1);
302 /* clear the claim registers for dynamic routing */ 290 /* clear the claim registers for dynamic routing */
@@ -333,7 +321,7 @@ vic_setup_pic(void)
333 321
334 /* ICW2: slave vector base */ 322 /* ICW2: slave vector base */
335 outb(FIRST_EXTERNAL_VECTOR + 8, 0xA1); 323 outb(FIRST_EXTERNAL_VECTOR + 8, 0xA1);
336 324
337 /* ICW3: slave ID */ 325 /* ICW3: slave ID */
338 outb(0x02, 0xA1); 326 outb(0x02, 0xA1);
339 327
@@ -341,19 +329,18 @@ vic_setup_pic(void)
341 outb(0x01, 0xA1); 329 outb(0x01, 0xA1);
342} 330}
343 331
344static void 332static void do_quad_bootstrap(void)
345do_quad_bootstrap(void)
346{ 333{
347 if(is_cpu_quad() && is_cpu_vic_boot()) { 334 if (is_cpu_quad() && is_cpu_vic_boot()) {
348 int i; 335 int i;
349 unsigned long flags; 336 unsigned long flags;
350 __u8 cpuid = hard_smp_processor_id(); 337 __u8 cpuid = hard_smp_processor_id();
351 338
352 local_irq_save(flags); 339 local_irq_save(flags);
353 340
354 for(i = 0; i<4; i++) { 341 for (i = 0; i < 4; i++) {
355 /* FIXME: this would be >>3 &0x7 on the 32 way */ 342 /* FIXME: this would be >>3 &0x7 on the 32 way */
356 if(((cpuid >> 2) & 0x03) == i) 343 if (((cpuid >> 2) & 0x03) == i)
357 /* don't lower our own mask! */ 344 /* don't lower our own mask! */
358 continue; 345 continue;
359 346
@@ -368,12 +355,10 @@ do_quad_bootstrap(void)
368 } 355 }
369} 356}
370 357
371
372/* Set up all the basic stuff: read the SMP config and make all the 358/* Set up all the basic stuff: read the SMP config and make all the
373 * SMP information reflect only the boot cpu. All others will be 359 * SMP information reflect only the boot cpu. All others will be
374 * brought on-line later. */ 360 * brought on-line later. */
375void __init 361void __init find_smp_config(void)
376find_smp_config(void)
377{ 362{
378 int i; 363 int i;
379 364
@@ -382,24 +367,31 @@ find_smp_config(void)
382 printk("VOYAGER SMP: Boot cpu is %d\n", boot_cpu_id); 367 printk("VOYAGER SMP: Boot cpu is %d\n", boot_cpu_id);
383 368
384 /* initialize the CPU structures (moved from smp_boot_cpus) */ 369 /* initialize the CPU structures (moved from smp_boot_cpus) */
385 for(i=0; i<NR_CPUS; i++) { 370 for (i = 0; i < NR_CPUS; i++) {
386 cpu_irq_affinity[i] = ~0; 371 cpu_irq_affinity[i] = ~0;
387 } 372 }
388 cpu_online_map = cpumask_of_cpu(boot_cpu_id); 373 cpu_online_map = cpumask_of_cpu(boot_cpu_id);
389 374
390 /* The boot CPU must be extended */ 375 /* The boot CPU must be extended */
391 voyager_extended_vic_processors = 1<<boot_cpu_id; 376 voyager_extended_vic_processors = 1 << boot_cpu_id;
392 /* initially, all of the first 8 CPUs can boot */ 377 /* initially, all of the first 8 CPUs can boot */
393 voyager_allowed_boot_processors = 0xff; 378 voyager_allowed_boot_processors = 0xff;
394 /* set up everything for just this CPU, we can alter 379 /* set up everything for just this CPU, we can alter
395 * this as we start the other CPUs later */ 380 * this as we start the other CPUs later */
396 /* now get the CPU disposition from the extended CMOS */ 381 /* now get the CPU disposition from the extended CMOS */
397 cpus_addr(phys_cpu_present_map)[0] = voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK); 382 cpus_addr(phys_cpu_present_map)[0] =
398 cpus_addr(phys_cpu_present_map)[0] |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 1) << 8; 383 voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK);
399 cpus_addr(phys_cpu_present_map)[0] |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 2) << 16; 384 cpus_addr(phys_cpu_present_map)[0] |=
400 cpus_addr(phys_cpu_present_map)[0] |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 3) << 24; 385 voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 1) << 8;
386 cpus_addr(phys_cpu_present_map)[0] |=
387 voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK +
388 2) << 16;
389 cpus_addr(phys_cpu_present_map)[0] |=
390 voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK +
391 3) << 24;
401 cpu_possible_map = phys_cpu_present_map; 392 cpu_possible_map = phys_cpu_present_map;
402 printk("VOYAGER SMP: phys_cpu_present_map = 0x%lx\n", cpus_addr(phys_cpu_present_map)[0]); 393 printk("VOYAGER SMP: phys_cpu_present_map = 0x%lx\n",
394 cpus_addr(phys_cpu_present_map)[0]);
403 /* Here we set up the VIC to enable SMP */ 395 /* Here we set up the VIC to enable SMP */
404 /* enable the CPIs by writing the base vector to their register */ 396 /* enable the CPIs by writing the base vector to their register */
405 outb(VIC_DEFAULT_CPI_BASE, VIC_CPI_BASE_REGISTER); 397 outb(VIC_DEFAULT_CPI_BASE, VIC_CPI_BASE_REGISTER);
@@ -427,8 +419,7 @@ find_smp_config(void)
427/* 419/*
428 * The bootstrap kernel entry code has set these up. Save them 420 * The bootstrap kernel entry code has set these up. Save them
429 * for a given CPU, id is physical */ 421 * for a given CPU, id is physical */
430void __init 422void __init smp_store_cpu_info(int id)
431smp_store_cpu_info(int id)
432{ 423{
433 struct cpuinfo_x86 *c = &cpu_data(id); 424 struct cpuinfo_x86 *c = &cpu_data(id);
434 425
@@ -438,21 +429,19 @@ smp_store_cpu_info(int id)
438} 429}
439 430
440/* set up the trampoline and return the physical address of the code */ 431/* set up the trampoline and return the physical address of the code */
441static __u32 __init 432static __u32 __init setup_trampoline(void)
442setup_trampoline(void)
443{ 433{
444 /* these two are global symbols in trampoline.S */ 434 /* these two are global symbols in trampoline.S */
445 extern const __u8 trampoline_end[]; 435 extern const __u8 trampoline_end[];
446 extern const __u8 trampoline_data[]; 436 extern const __u8 trampoline_data[];
447 437
448 memcpy((__u8 *)trampoline_base, trampoline_data, 438 memcpy((__u8 *) trampoline_base, trampoline_data,
449 trampoline_end - trampoline_data); 439 trampoline_end - trampoline_data);
450 return virt_to_phys((__u8 *)trampoline_base); 440 return virt_to_phys((__u8 *) trampoline_base);
451} 441}
452 442
453/* Routine initially called when a non-boot CPU is brought online */ 443/* Routine initially called when a non-boot CPU is brought online */
454static void __init 444static void __init start_secondary(void *unused)
455start_secondary(void *unused)
456{ 445{
457 __u8 cpuid = hard_smp_processor_id(); 446 __u8 cpuid = hard_smp_processor_id();
458 /* external functions not defined in the headers */ 447 /* external functions not defined in the headers */
@@ -464,17 +453,18 @@ start_secondary(void *unused)
464 ack_CPI(VIC_CPU_BOOT_CPI); 453 ack_CPI(VIC_CPU_BOOT_CPI);
465 454
466 /* setup the 8259 master slave pair belonging to this CPU --- 455 /* setup the 8259 master slave pair belonging to this CPU ---
467 * we won't actually receive any until the boot CPU 456 * we won't actually receive any until the boot CPU
468 * relinquishes it's static routing mask */ 457 * relinquishes it's static routing mask */
469 vic_setup_pic(); 458 vic_setup_pic();
470 459
471 qic_setup(); 460 qic_setup();
472 461
473 if(is_cpu_quad() && !is_cpu_vic_boot()) { 462 if (is_cpu_quad() && !is_cpu_vic_boot()) {
474 /* clear the boot CPI */ 463 /* clear the boot CPI */
475 __u8 dummy; 464 __u8 dummy;
476 465
477 dummy = voyager_quad_cpi_addr[cpuid]->qic_cpi[VIC_CPU_BOOT_CPI].cpi; 466 dummy =
467 voyager_quad_cpi_addr[cpuid]->qic_cpi[VIC_CPU_BOOT_CPI].cpi;
478 printk("read dummy %d\n", dummy); 468 printk("read dummy %d\n", dummy);
479 } 469 }
480 470
@@ -516,7 +506,6 @@ start_secondary(void *unused)
516 cpu_idle(); 506 cpu_idle();
517} 507}
518 508
519
520/* Routine to kick start the given CPU and wait for it to report ready 509/* Routine to kick start the given CPU and wait for it to report ready
521 * (or timeout in startup). When this routine returns, the requested 510 * (or timeout in startup). When this routine returns, the requested
522 * CPU is either fully running and configured or known to be dead. 511 * CPU is either fully running and configured or known to be dead.
@@ -524,29 +513,28 @@ start_secondary(void *unused)
524 * We call this routine sequentially 1 CPU at a time, so no need for 513 * We call this routine sequentially 1 CPU at a time, so no need for
525 * locking */ 514 * locking */
526 515
527static void __init 516static void __init do_boot_cpu(__u8 cpu)
528do_boot_cpu(__u8 cpu)
529{ 517{
530 struct task_struct *idle; 518 struct task_struct *idle;
531 int timeout; 519 int timeout;
532 unsigned long flags; 520 unsigned long flags;
533 int quad_boot = (1<<cpu) & voyager_quad_processors 521 int quad_boot = (1 << cpu) & voyager_quad_processors
534 & ~( voyager_extended_vic_processors 522 & ~(voyager_extended_vic_processors
535 & voyager_allowed_boot_processors); 523 & voyager_allowed_boot_processors);
536 524
537 /* This is an area in head.S which was used to set up the 525 /* This is an area in head.S which was used to set up the
538 * initial kernel stack. We need to alter this to give the 526 * initial kernel stack. We need to alter this to give the
539 * booting CPU a new stack (taken from its idle process) */ 527 * booting CPU a new stack (taken from its idle process) */
540 extern struct { 528 extern struct {
541 __u8 *esp; 529 __u8 *sp;
542 unsigned short ss; 530 unsigned short ss;
543 } stack_start; 531 } stack_start;
544 /* This is the format of the CPI IDT gate (in real mode) which 532 /* This is the format of the CPI IDT gate (in real mode) which
545 * we're hijacking to boot the CPU */ 533 * we're hijacking to boot the CPU */
546 union IDTFormat { 534 union IDTFormat {
547 struct seg { 535 struct seg {
548 __u16 Offset; 536 __u16 Offset;
549 __u16 Segment; 537 __u16 Segment;
550 } idt; 538 } idt;
551 __u32 val; 539 __u32 val;
552 } hijack_source; 540 } hijack_source;
@@ -565,37 +553,44 @@ do_boot_cpu(__u8 cpu)
565 alternatives_smp_switch(1); 553 alternatives_smp_switch(1);
566 554
567 idle = fork_idle(cpu); 555 idle = fork_idle(cpu);
568 if(IS_ERR(idle)) 556 if (IS_ERR(idle))
569 panic("failed fork for CPU%d", cpu); 557 panic("failed fork for CPU%d", cpu);
570 idle->thread.eip = (unsigned long) start_secondary; 558 idle->thread.ip = (unsigned long)start_secondary;
571 /* init_tasks (in sched.c) is indexed logically */ 559 /* init_tasks (in sched.c) is indexed logically */
572 stack_start.esp = (void *) idle->thread.esp; 560 stack_start.sp = (void *)idle->thread.sp;
573 561
574 init_gdt(cpu); 562 init_gdt(cpu);
575 per_cpu(current_task, cpu) = idle; 563 per_cpu(current_task, cpu) = idle;
576 early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); 564 early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
577 irq_ctx_init(cpu); 565 irq_ctx_init(cpu);
578 566
579 /* Note: Don't modify initial ss override */ 567 /* Note: Don't modify initial ss override */
580 VDEBUG(("VOYAGER SMP: Booting CPU%d at 0x%lx[%x:%x], stack %p\n", cpu, 568 VDEBUG(("VOYAGER SMP: Booting CPU%d at 0x%lx[%x:%x], stack %p\n", cpu,
581 (unsigned long)hijack_source.val, hijack_source.idt.Segment, 569 (unsigned long)hijack_source.val, hijack_source.idt.Segment,
582 hijack_source.idt.Offset, stack_start.esp)); 570 hijack_source.idt.Offset, stack_start.sp));
583 571
584 /* init lowmem identity mapping */ 572 /* init lowmem identity mapping */
585 clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS, 573 clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
586 min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS)); 574 min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS));
587 flush_tlb_all(); 575 flush_tlb_all();
588 576
589 if(quad_boot) { 577 if (quad_boot) {
590 printk("CPU %d: non extended Quad boot\n", cpu); 578 printk("CPU %d: non extended Quad boot\n", cpu);
591 hijack_vector = (__u32 *)phys_to_virt((VIC_CPU_BOOT_CPI + QIC_DEFAULT_CPI_BASE)*4); 579 hijack_vector =
580 (__u32 *)
581 phys_to_virt((VIC_CPU_BOOT_CPI + QIC_DEFAULT_CPI_BASE) * 4);
592 *hijack_vector = hijack_source.val; 582 *hijack_vector = hijack_source.val;
593 } else { 583 } else {
594 printk("CPU%d: extended VIC boot\n", cpu); 584 printk("CPU%d: extended VIC boot\n", cpu);
595 hijack_vector = (__u32 *)phys_to_virt((VIC_CPU_BOOT_CPI + VIC_DEFAULT_CPI_BASE)*4); 585 hijack_vector =
586 (__u32 *)
587 phys_to_virt((VIC_CPU_BOOT_CPI + VIC_DEFAULT_CPI_BASE) * 4);
596 *hijack_vector = hijack_source.val; 588 *hijack_vector = hijack_source.val;
597 /* VIC errata, may also receive interrupt at this address */ 589 /* VIC errata, may also receive interrupt at this address */
598 hijack_vector = (__u32 *)phys_to_virt((VIC_CPU_BOOT_ERRATA_CPI + VIC_DEFAULT_CPI_BASE)*4); 590 hijack_vector =
591 (__u32 *)
592 phys_to_virt((VIC_CPU_BOOT_ERRATA_CPI +
593 VIC_DEFAULT_CPI_BASE) * 4);
599 *hijack_vector = hijack_source.val; 594 *hijack_vector = hijack_source.val;
600 } 595 }
601 /* All non-boot CPUs start with interrupts fully masked. Need 596 /* All non-boot CPUs start with interrupts fully masked. Need
@@ -603,73 +598,76 @@ do_boot_cpu(__u8 cpu)
603 * this in the VIC by masquerading as the processor we're 598 * this in the VIC by masquerading as the processor we're
604 * about to boot and lowering its interrupt mask */ 599 * about to boot and lowering its interrupt mask */
605 local_irq_save(flags); 600 local_irq_save(flags);
606 if(quad_boot) { 601 if (quad_boot) {
607 send_one_QIC_CPI(cpu, VIC_CPU_BOOT_CPI); 602 send_one_QIC_CPI(cpu, VIC_CPU_BOOT_CPI);
608 } else { 603 } else {
609 outb(VIC_CPU_MASQUERADE_ENABLE | cpu, VIC_PROCESSOR_ID); 604 outb(VIC_CPU_MASQUERADE_ENABLE | cpu, VIC_PROCESSOR_ID);
610 /* here we're altering registers belonging to `cpu' */ 605 /* here we're altering registers belonging to `cpu' */
611 606
612 outb(VIC_BOOT_INTERRUPT_MASK, 0x21); 607 outb(VIC_BOOT_INTERRUPT_MASK, 0x21);
613 /* now go back to our original identity */ 608 /* now go back to our original identity */
614 outb(boot_cpu_id, VIC_PROCESSOR_ID); 609 outb(boot_cpu_id, VIC_PROCESSOR_ID);
615 610
616 /* and boot the CPU */ 611 /* and boot the CPU */
617 612
618 send_CPI((1<<cpu), VIC_CPU_BOOT_CPI); 613 send_CPI((1 << cpu), VIC_CPU_BOOT_CPI);
619 } 614 }
620 cpu_booted_map = 0; 615 cpu_booted_map = 0;
621 local_irq_restore(flags); 616 local_irq_restore(flags);
622 617
623 /* now wait for it to become ready (or timeout) */ 618 /* now wait for it to become ready (or timeout) */
624 for(timeout = 0; timeout < 50000; timeout++) { 619 for (timeout = 0; timeout < 50000; timeout++) {
625 if(cpu_booted_map) 620 if (cpu_booted_map)
626 break; 621 break;
627 udelay(100); 622 udelay(100);
628 } 623 }
629 /* reset the page table */ 624 /* reset the page table */
630 zap_low_mappings(); 625 zap_low_mappings();
631 626
632 if (cpu_booted_map) { 627 if (cpu_booted_map) {
633 VDEBUG(("CPU%d: Booted successfully, back in CPU %d\n", 628 VDEBUG(("CPU%d: Booted successfully, back in CPU %d\n",
634 cpu, smp_processor_id())); 629 cpu, smp_processor_id()));
635 630
636 printk("CPU%d: ", cpu); 631 printk("CPU%d: ", cpu);
637 print_cpu_info(&cpu_data(cpu)); 632 print_cpu_info(&cpu_data(cpu));
638 wmb(); 633 wmb();
639 cpu_set(cpu, cpu_callout_map); 634 cpu_set(cpu, cpu_callout_map);
640 cpu_set(cpu, cpu_present_map); 635 cpu_set(cpu, cpu_present_map);
641 } 636 } else {
642 else {
643 printk("CPU%d FAILED TO BOOT: ", cpu); 637 printk("CPU%d FAILED TO BOOT: ", cpu);
644 if (*((volatile unsigned char *)phys_to_virt(start_phys_address))==0xA5) 638 if (*
639 ((volatile unsigned char *)phys_to_virt(start_phys_address))
640 == 0xA5)
645 printk("Stuck.\n"); 641 printk("Stuck.\n");
646 else 642 else
647 printk("Not responding.\n"); 643 printk("Not responding.\n");
648 644
649 cpucount--; 645 cpucount--;
650 } 646 }
651} 647}
652 648
653void __init 649void __init smp_boot_cpus(void)
654smp_boot_cpus(void)
655{ 650{
656 int i; 651 int i;
657 652
658 /* CAT BUS initialisation must be done after the memory */ 653 /* CAT BUS initialisation must be done after the memory */
659 /* FIXME: The L4 has a catbus too, it just needs to be 654 /* FIXME: The L4 has a catbus too, it just needs to be
660 * accessed in a totally different way */ 655 * accessed in a totally different way */
661 if(voyager_level == 5) { 656 if (voyager_level == 5) {
662 voyager_cat_init(); 657 voyager_cat_init();
663 658
664 /* now that the cat has probed the Voyager System Bus, sanity 659 /* now that the cat has probed the Voyager System Bus, sanity
665 * check the cpu map */ 660 * check the cpu map */
666 if( ((voyager_quad_processors | voyager_extended_vic_processors) 661 if (((voyager_quad_processors | voyager_extended_vic_processors)
667 & cpus_addr(phys_cpu_present_map)[0]) != cpus_addr(phys_cpu_present_map)[0]) { 662 & cpus_addr(phys_cpu_present_map)[0]) !=
663 cpus_addr(phys_cpu_present_map)[0]) {
668 /* should panic */ 664 /* should panic */
669 printk("\n\n***WARNING*** Sanity check of CPU present map FAILED\n"); 665 printk("\n\n***WARNING*** "
666 "Sanity check of CPU present map FAILED\n");
670 } 667 }
671 } else if(voyager_level == 4) 668 } else if (voyager_level == 4)
672 voyager_extended_vic_processors = cpus_addr(phys_cpu_present_map)[0]; 669 voyager_extended_vic_processors =
670 cpus_addr(phys_cpu_present_map)[0];
673 671
674 /* this sets up the idle task to run on the current cpu */ 672 /* this sets up the idle task to run on the current cpu */
675 voyager_extended_cpus = 1; 673 voyager_extended_cpus = 1;
@@ -678,14 +676,14 @@ smp_boot_cpus(void)
678 //global_irq_holder = boot_cpu_id; 676 //global_irq_holder = boot_cpu_id;
679 677
680 /* FIXME: Need to do something about this but currently only works 678 /* FIXME: Need to do something about this but currently only works
681 * on CPUs with a tsc which none of mine have. 679 * on CPUs with a tsc which none of mine have.
682 smp_tune_scheduling(); 680 smp_tune_scheduling();
683 */ 681 */
684 smp_store_cpu_info(boot_cpu_id); 682 smp_store_cpu_info(boot_cpu_id);
685 printk("CPU%d: ", boot_cpu_id); 683 printk("CPU%d: ", boot_cpu_id);
686 print_cpu_info(&cpu_data(boot_cpu_id)); 684 print_cpu_info(&cpu_data(boot_cpu_id));
687 685
688 if(is_cpu_quad()) { 686 if (is_cpu_quad()) {
689 /* booting on a Quad CPU */ 687 /* booting on a Quad CPU */
690 printk("VOYAGER SMP: Boot CPU is Quad\n"); 688 printk("VOYAGER SMP: Boot CPU is Quad\n");
691 qic_setup(); 689 qic_setup();
@@ -697,11 +695,11 @@ smp_boot_cpus(void)
697 695
698 cpu_set(boot_cpu_id, cpu_online_map); 696 cpu_set(boot_cpu_id, cpu_online_map);
699 cpu_set(boot_cpu_id, cpu_callout_map); 697 cpu_set(boot_cpu_id, cpu_callout_map);
700 698
701 /* loop over all the extended VIC CPUs and boot them. The 699 /* loop over all the extended VIC CPUs and boot them. The
702 * Quad CPUs must be bootstrapped by their extended VIC cpu */ 700 * Quad CPUs must be bootstrapped by their extended VIC cpu */
703 for(i = 0; i < NR_CPUS; i++) { 701 for (i = 0; i < NR_CPUS; i++) {
704 if(i == boot_cpu_id || !cpu_isset(i, phys_cpu_present_map)) 702 if (i == boot_cpu_id || !cpu_isset(i, phys_cpu_present_map))
705 continue; 703 continue;
706 do_boot_cpu(i); 704 do_boot_cpu(i);
707 /* This udelay seems to be needed for the Quad boots 705 /* This udelay seems to be needed for the Quad boots
@@ -715,25 +713,26 @@ smp_boot_cpus(void)
715 for (i = 0; i < NR_CPUS; i++) 713 for (i = 0; i < NR_CPUS; i++)
716 if (cpu_isset(i, cpu_online_map)) 714 if (cpu_isset(i, cpu_online_map))
717 bogosum += cpu_data(i).loops_per_jiffy; 715 bogosum += cpu_data(i).loops_per_jiffy;
718 printk(KERN_INFO "Total of %d processors activated (%lu.%02lu BogoMIPS).\n", 716 printk(KERN_INFO "Total of %d processors activated "
719 cpucount+1, 717 "(%lu.%02lu BogoMIPS).\n",
720 bogosum/(500000/HZ), 718 cpucount + 1, bogosum / (500000 / HZ),
721 (bogosum/(5000/HZ))%100); 719 (bogosum / (5000 / HZ)) % 100);
722 } 720 }
723 voyager_extended_cpus = hweight32(voyager_extended_vic_processors); 721 voyager_extended_cpus = hweight32(voyager_extended_vic_processors);
724 printk("VOYAGER: Extended (interrupt handling CPUs): %d, non-extended: %d\n", voyager_extended_cpus, num_booting_cpus() - voyager_extended_cpus); 722 printk("VOYAGER: Extended (interrupt handling CPUs): "
723 "%d, non-extended: %d\n", voyager_extended_cpus,
724 num_booting_cpus() - voyager_extended_cpus);
725 /* that's it, switch to symmetric mode */ 725 /* that's it, switch to symmetric mode */
726 outb(0, VIC_PRIORITY_REGISTER); 726 outb(0, VIC_PRIORITY_REGISTER);
727 outb(0, VIC_CLAIM_REGISTER_0); 727 outb(0, VIC_CLAIM_REGISTER_0);
728 outb(0, VIC_CLAIM_REGISTER_1); 728 outb(0, VIC_CLAIM_REGISTER_1);
729 729
730 VDEBUG(("VOYAGER SMP: Booted with %d CPUs\n", num_booting_cpus())); 730 VDEBUG(("VOYAGER SMP: Booted with %d CPUs\n", num_booting_cpus()));
731} 731}
732 732
733/* Reload the secondary CPUs task structure (this function does not 733/* Reload the secondary CPUs task structure (this function does not
734 * return ) */ 734 * return ) */
735void __init 735void __init initialize_secondary(void)
736initialize_secondary(void)
737{ 736{
738#if 0 737#if 0
739 // AC kernels only 738 // AC kernels only
@@ -745,11 +744,9 @@ initialize_secondary(void)
745 * basically just the stack pointer and the eip. 744 * basically just the stack pointer and the eip.
746 */ 745 */
747 746
748 asm volatile( 747 asm volatile ("movl %0,%%esp\n\t"
749 "movl %0,%%esp\n\t" 748 "jmp *%1"::"r" (current->thread.sp),
750 "jmp *%1" 749 "r"(current->thread.ip));
751 :
752 :"r" (current->thread.esp),"r" (current->thread.eip));
753} 750}
754 751
755/* handle a Voyager SYS_INT -- If we don't, the base board will 752/* handle a Voyager SYS_INT -- If we don't, the base board will
@@ -758,25 +755,23 @@ initialize_secondary(void)
758 * System interrupts occur because some problem was detected on the 755 * System interrupts occur because some problem was detected on the
759 * various busses. To find out what you have to probe all the 756 * various busses. To find out what you have to probe all the
760 * hardware via the CAT bus. FIXME: At the moment we do nothing. */ 757 * hardware via the CAT bus. FIXME: At the moment we do nothing. */
761fastcall void 758void smp_vic_sys_interrupt(struct pt_regs *regs)
762smp_vic_sys_interrupt(struct pt_regs *regs)
763{ 759{
764 ack_CPI(VIC_SYS_INT); 760 ack_CPI(VIC_SYS_INT);
765 printk("Voyager SYSTEM INTERRUPT\n"); 761 printk("Voyager SYSTEM INTERRUPT\n");
766} 762}
767 763
768/* Handle a voyager CMN_INT; These interrupts occur either because of 764/* Handle a voyager CMN_INT; These interrupts occur either because of
769 * a system status change or because a single bit memory error 765 * a system status change or because a single bit memory error
770 * occurred. FIXME: At the moment, ignore all this. */ 766 * occurred. FIXME: At the moment, ignore all this. */
771fastcall void 767void smp_vic_cmn_interrupt(struct pt_regs *regs)
772smp_vic_cmn_interrupt(struct pt_regs *regs)
773{ 768{
774 static __u8 in_cmn_int = 0; 769 static __u8 in_cmn_int = 0;
775 static DEFINE_SPINLOCK(cmn_int_lock); 770 static DEFINE_SPINLOCK(cmn_int_lock);
776 771
777 /* common ints are broadcast, so make sure we only do this once */ 772 /* common ints are broadcast, so make sure we only do this once */
778 _raw_spin_lock(&cmn_int_lock); 773 _raw_spin_lock(&cmn_int_lock);
779 if(in_cmn_int) 774 if (in_cmn_int)
780 goto unlock_end; 775 goto unlock_end;
781 776
782 in_cmn_int++; 777 in_cmn_int++;
@@ -784,12 +779,12 @@ smp_vic_cmn_interrupt(struct pt_regs *regs)
784 779
785 VDEBUG(("Voyager COMMON INTERRUPT\n")); 780 VDEBUG(("Voyager COMMON INTERRUPT\n"));
786 781
787 if(voyager_level == 5) 782 if (voyager_level == 5)
788 voyager_cat_do_common_interrupt(); 783 voyager_cat_do_common_interrupt();
789 784
790 _raw_spin_lock(&cmn_int_lock); 785 _raw_spin_lock(&cmn_int_lock);
791 in_cmn_int = 0; 786 in_cmn_int = 0;
792 unlock_end: 787 unlock_end:
793 _raw_spin_unlock(&cmn_int_lock); 788 _raw_spin_unlock(&cmn_int_lock);
794 ack_CPI(VIC_CMN_INT); 789 ack_CPI(VIC_CMN_INT);
795} 790}
@@ -797,26 +792,23 @@ smp_vic_cmn_interrupt(struct pt_regs *regs)
797/* 792/*
798 * Reschedule call back. Nothing to do, all the work is done 793 * Reschedule call back. Nothing to do, all the work is done
799 * automatically when we return from the interrupt. */ 794 * automatically when we return from the interrupt. */
800static void 795static void smp_reschedule_interrupt(void)
801smp_reschedule_interrupt(void)
802{ 796{
803 /* do nothing */ 797 /* do nothing */
804} 798}
805 799
806static struct mm_struct * flush_mm; 800static struct mm_struct *flush_mm;
807static unsigned long flush_va; 801static unsigned long flush_va;
808static DEFINE_SPINLOCK(tlbstate_lock); 802static DEFINE_SPINLOCK(tlbstate_lock);
809#define FLUSH_ALL 0xffffffff
810 803
811/* 804/*
812 * We cannot call mmdrop() because we are in interrupt context, 805 * We cannot call mmdrop() because we are in interrupt context,
813 * instead update mm->cpu_vm_mask. 806 * instead update mm->cpu_vm_mask.
814 * 807 *
815 * We need to reload %cr3 since the page tables may be going 808 * We need to reload %cr3 since the page tables may be going
816 * away from under us.. 809 * away from under us..
817 */ 810 */
818static inline void 811static inline void voyager_leave_mm(unsigned long cpu)
819leave_mm (unsigned long cpu)
820{ 812{
821 if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_OK) 813 if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_OK)
822 BUG(); 814 BUG();
@@ -824,12 +816,10 @@ leave_mm (unsigned long cpu)
824 load_cr3(swapper_pg_dir); 816 load_cr3(swapper_pg_dir);
825} 817}
826 818
827
828/* 819/*
829 * Invalidate call-back 820 * Invalidate call-back
830 */ 821 */
831static void 822static void smp_invalidate_interrupt(void)
832smp_invalidate_interrupt(void)
833{ 823{
834 __u8 cpu = smp_processor_id(); 824 __u8 cpu = smp_processor_id();
835 825
@@ -837,18 +827,18 @@ smp_invalidate_interrupt(void)
837 return; 827 return;
838 /* This will flood messages. Don't uncomment unless you see 828 /* This will flood messages. Don't uncomment unless you see
839 * Problems with cross cpu invalidation 829 * Problems with cross cpu invalidation
840 VDEBUG(("VOYAGER SMP: CPU%d received INVALIDATE_CPI\n", 830 VDEBUG(("VOYAGER SMP: CPU%d received INVALIDATE_CPI\n",
841 smp_processor_id())); 831 smp_processor_id()));
842 */ 832 */
843 833
844 if (flush_mm == per_cpu(cpu_tlbstate, cpu).active_mm) { 834 if (flush_mm == per_cpu(cpu_tlbstate, cpu).active_mm) {
845 if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_OK) { 835 if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_OK) {
846 if (flush_va == FLUSH_ALL) 836 if (flush_va == TLB_FLUSH_ALL)
847 local_flush_tlb(); 837 local_flush_tlb();
848 else 838 else
849 __flush_tlb_one(flush_va); 839 __flush_tlb_one(flush_va);
850 } else 840 } else
851 leave_mm(cpu); 841 voyager_leave_mm(cpu);
852 } 842 }
853 smp_mb__before_clear_bit(); 843 smp_mb__before_clear_bit();
854 clear_bit(cpu, &smp_invalidate_needed); 844 clear_bit(cpu, &smp_invalidate_needed);
@@ -857,11 +847,10 @@ smp_invalidate_interrupt(void)
857 847
858/* All the new flush operations for 2.4 */ 848/* All the new flush operations for 2.4 */
859 849
860
861/* This routine is called with a physical cpu mask */ 850/* This routine is called with a physical cpu mask */
862static void 851static void
863voyager_flush_tlb_others (unsigned long cpumask, struct mm_struct *mm, 852voyager_flush_tlb_others(unsigned long cpumask, struct mm_struct *mm,
864 unsigned long va) 853 unsigned long va)
865{ 854{
866 int stuck = 50000; 855 int stuck = 50000;
867 856
@@ -875,7 +864,7 @@ voyager_flush_tlb_others (unsigned long cpumask, struct mm_struct *mm,
875 BUG(); 864 BUG();
876 865
877 spin_lock(&tlbstate_lock); 866 spin_lock(&tlbstate_lock);
878 867
879 flush_mm = mm; 868 flush_mm = mm;
880 flush_va = va; 869 flush_va = va;
881 atomic_set_mask(cpumask, &smp_invalidate_needed); 870 atomic_set_mask(cpumask, &smp_invalidate_needed);
@@ -887,23 +876,23 @@ voyager_flush_tlb_others (unsigned long cpumask, struct mm_struct *mm,
887 876
888 while (smp_invalidate_needed) { 877 while (smp_invalidate_needed) {
889 mb(); 878 mb();
890 if(--stuck == 0) { 879 if (--stuck == 0) {
891 printk("***WARNING*** Stuck doing invalidate CPI (CPU%d)\n", smp_processor_id()); 880 printk("***WARNING*** Stuck doing invalidate CPI "
881 "(CPU%d)\n", smp_processor_id());
892 break; 882 break;
893 } 883 }
894 } 884 }
895 885
896 /* Uncomment only to debug invalidation problems 886 /* Uncomment only to debug invalidation problems
897 VDEBUG(("VOYAGER SMP: Completed invalidate CPI (CPU%d)\n", cpu)); 887 VDEBUG(("VOYAGER SMP: Completed invalidate CPI (CPU%d)\n", cpu));
898 */ 888 */
899 889
900 flush_mm = NULL; 890 flush_mm = NULL;
901 flush_va = 0; 891 flush_va = 0;
902 spin_unlock(&tlbstate_lock); 892 spin_unlock(&tlbstate_lock);
903} 893}
904 894
905void 895void flush_tlb_current_task(void)
906flush_tlb_current_task(void)
907{ 896{
908 struct mm_struct *mm = current->mm; 897 struct mm_struct *mm = current->mm;
909 unsigned long cpu_mask; 898 unsigned long cpu_mask;
@@ -913,14 +902,12 @@ flush_tlb_current_task(void)
913 cpu_mask = cpus_addr(mm->cpu_vm_mask)[0] & ~(1 << smp_processor_id()); 902 cpu_mask = cpus_addr(mm->cpu_vm_mask)[0] & ~(1 << smp_processor_id());
914 local_flush_tlb(); 903 local_flush_tlb();
915 if (cpu_mask) 904 if (cpu_mask)
916 voyager_flush_tlb_others(cpu_mask, mm, FLUSH_ALL); 905 voyager_flush_tlb_others(cpu_mask, mm, TLB_FLUSH_ALL);
917 906
918 preempt_enable(); 907 preempt_enable();
919} 908}
920 909
921 910void flush_tlb_mm(struct mm_struct *mm)
922void
923flush_tlb_mm (struct mm_struct * mm)
924{ 911{
925 unsigned long cpu_mask; 912 unsigned long cpu_mask;
926 913
@@ -932,15 +919,15 @@ flush_tlb_mm (struct mm_struct * mm)
932 if (current->mm) 919 if (current->mm)
933 local_flush_tlb(); 920 local_flush_tlb();
934 else 921 else
935 leave_mm(smp_processor_id()); 922 voyager_leave_mm(smp_processor_id());
936 } 923 }
937 if (cpu_mask) 924 if (cpu_mask)
938 voyager_flush_tlb_others(cpu_mask, mm, FLUSH_ALL); 925 voyager_flush_tlb_others(cpu_mask, mm, TLB_FLUSH_ALL);
939 926
940 preempt_enable(); 927 preempt_enable();
941} 928}
942 929
943void flush_tlb_page(struct vm_area_struct * vma, unsigned long va) 930void flush_tlb_page(struct vm_area_struct *vma, unsigned long va)
944{ 931{
945 struct mm_struct *mm = vma->vm_mm; 932 struct mm_struct *mm = vma->vm_mm;
946 unsigned long cpu_mask; 933 unsigned long cpu_mask;
@@ -949,10 +936,10 @@ void flush_tlb_page(struct vm_area_struct * vma, unsigned long va)
949 936
950 cpu_mask = cpus_addr(mm->cpu_vm_mask)[0] & ~(1 << smp_processor_id()); 937 cpu_mask = cpus_addr(mm->cpu_vm_mask)[0] & ~(1 << smp_processor_id());
951 if (current->active_mm == mm) { 938 if (current->active_mm == mm) {
952 if(current->mm) 939 if (current->mm)
953 __flush_tlb_one(va); 940 __flush_tlb_one(va);
954 else 941 else
955 leave_mm(smp_processor_id()); 942 voyager_leave_mm(smp_processor_id());
956 } 943 }
957 944
958 if (cpu_mask) 945 if (cpu_mask)
@@ -960,21 +947,21 @@ void flush_tlb_page(struct vm_area_struct * vma, unsigned long va)
960 947
961 preempt_enable(); 948 preempt_enable();
962} 949}
950
963EXPORT_SYMBOL(flush_tlb_page); 951EXPORT_SYMBOL(flush_tlb_page);
964 952
965/* enable the requested IRQs */ 953/* enable the requested IRQs */
966static void 954static void smp_enable_irq_interrupt(void)
967smp_enable_irq_interrupt(void)
968{ 955{
969 __u8 irq; 956 __u8 irq;
970 __u8 cpu = get_cpu(); 957 __u8 cpu = get_cpu();
971 958
972 VDEBUG(("VOYAGER SMP: CPU%d enabling irq mask 0x%x\n", cpu, 959 VDEBUG(("VOYAGER SMP: CPU%d enabling irq mask 0x%x\n", cpu,
973 vic_irq_enable_mask[cpu])); 960 vic_irq_enable_mask[cpu]));
974 961
975 spin_lock(&vic_irq_lock); 962 spin_lock(&vic_irq_lock);
976 for(irq = 0; irq < 16; irq++) { 963 for (irq = 0; irq < 16; irq++) {
977 if(vic_irq_enable_mask[cpu] & (1<<irq)) 964 if (vic_irq_enable_mask[cpu] & (1 << irq))
978 enable_local_vic_irq(irq); 965 enable_local_vic_irq(irq);
979 } 966 }
980 vic_irq_enable_mask[cpu] = 0; 967 vic_irq_enable_mask[cpu] = 0;
@@ -982,17 +969,16 @@ smp_enable_irq_interrupt(void)
982 969
983 put_cpu_no_resched(); 970 put_cpu_no_resched();
984} 971}
985 972
986/* 973/*
987 * CPU halt call-back 974 * CPU halt call-back
988 */ 975 */
989static void 976static void smp_stop_cpu_function(void *dummy)
990smp_stop_cpu_function(void *dummy)
991{ 977{
992 VDEBUG(("VOYAGER SMP: CPU%d is STOPPING\n", smp_processor_id())); 978 VDEBUG(("VOYAGER SMP: CPU%d is STOPPING\n", smp_processor_id()));
993 cpu_clear(smp_processor_id(), cpu_online_map); 979 cpu_clear(smp_processor_id(), cpu_online_map);
994 local_irq_disable(); 980 local_irq_disable();
995 for(;;) 981 for (;;)
996 halt(); 982 halt();
997} 983}
998 984
@@ -1006,14 +992,13 @@ struct call_data_struct {
1006 int wait; 992 int wait;
1007}; 993};
1008 994
1009static struct call_data_struct * call_data; 995static struct call_data_struct *call_data;
1010 996
1011/* execute a thread on a new CPU. The function to be called must be 997/* execute a thread on a new CPU. The function to be called must be
1012 * previously set up. This is used to schedule a function for 998 * previously set up. This is used to schedule a function for
1013 * execution on all CPUs - set up the function then broadcast a 999 * execution on all CPUs - set up the function then broadcast a
1014 * function_interrupt CPI to come here on each CPU */ 1000 * function_interrupt CPI to come here on each CPU */
1015static void 1001static void smp_call_function_interrupt(void)
1016smp_call_function_interrupt(void)
1017{ 1002{
1018 void (*func) (void *info) = call_data->func; 1003 void (*func) (void *info) = call_data->func;
1019 void *info = call_data->info; 1004 void *info = call_data->info;
@@ -1027,16 +1012,17 @@ smp_call_function_interrupt(void)
1027 * about to execute the function 1012 * about to execute the function
1028 */ 1013 */
1029 mb(); 1014 mb();
1030 if(!test_and_clear_bit(cpu, &call_data->started)) { 1015 if (!test_and_clear_bit(cpu, &call_data->started)) {
1031 /* If the bit wasn't set, this could be a replay */ 1016 /* If the bit wasn't set, this could be a replay */
1032 printk(KERN_WARNING "VOYAGER SMP: CPU %d received call funtion with no call pending\n", cpu); 1017 printk(KERN_WARNING "VOYAGER SMP: CPU %d received call funtion"
1018 " with no call pending\n", cpu);
1033 return; 1019 return;
1034 } 1020 }
1035 /* 1021 /*
1036 * At this point the info structure may be out of scope unless wait==1 1022 * At this point the info structure may be out of scope unless wait==1
1037 */ 1023 */
1038 irq_enter(); 1024 irq_enter();
1039 (*func)(info); 1025 (*func) (info);
1040 __get_cpu_var(irq_stat).irq_call_count++; 1026 __get_cpu_var(irq_stat).irq_call_count++;
1041 irq_exit(); 1027 irq_exit();
1042 if (wait) { 1028 if (wait) {
@@ -1046,14 +1032,13 @@ smp_call_function_interrupt(void)
1046} 1032}
1047 1033
1048static int 1034static int
1049voyager_smp_call_function_mask (cpumask_t cpumask, 1035voyager_smp_call_function_mask(cpumask_t cpumask,
1050 void (*func) (void *info), void *info, 1036 void (*func) (void *info), void *info, int wait)
1051 int wait)
1052{ 1037{
1053 struct call_data_struct data; 1038 struct call_data_struct data;
1054 u32 mask = cpus_addr(cpumask)[0]; 1039 u32 mask = cpus_addr(cpumask)[0];
1055 1040
1056 mask &= ~(1<<smp_processor_id()); 1041 mask &= ~(1 << smp_processor_id());
1057 1042
1058 if (!mask) 1043 if (!mask)
1059 return 0; 1044 return 0;
@@ -1093,7 +1078,7 @@ voyager_smp_call_function_mask (cpumask_t cpumask,
1093 * so we use the system clock to interrupt one processor, which in 1078 * so we use the system clock to interrupt one processor, which in
1094 * turn, broadcasts a timer CPI to all the others --- we receive that 1079 * turn, broadcasts a timer CPI to all the others --- we receive that
1095 * CPI here. We don't use this actually for counting so losing 1080 * CPI here. We don't use this actually for counting so losing
1096 * ticks doesn't matter 1081 * ticks doesn't matter
1097 * 1082 *
1098 * FIXME: For those CPUs which actually have a local APIC, we could 1083 * FIXME: For those CPUs which actually have a local APIC, we could
1099 * try to use it to trigger this interrupt instead of having to 1084 * try to use it to trigger this interrupt instead of having to
@@ -1101,8 +1086,7 @@ voyager_smp_call_function_mask (cpumask_t cpumask,
1101 * no local APIC, so I can't do this 1086 * no local APIC, so I can't do this
1102 * 1087 *
1103 * This function is currently a placeholder and is unused in the code */ 1088 * This function is currently a placeholder and is unused in the code */
1104fastcall void 1089void smp_apic_timer_interrupt(struct pt_regs *regs)
1105smp_apic_timer_interrupt(struct pt_regs *regs)
1106{ 1090{
1107 struct pt_regs *old_regs = set_irq_regs(regs); 1091 struct pt_regs *old_regs = set_irq_regs(regs);
1108 wrapper_smp_local_timer_interrupt(); 1092 wrapper_smp_local_timer_interrupt();
@@ -1110,8 +1094,7 @@ smp_apic_timer_interrupt(struct pt_regs *regs)
1110} 1094}
1111 1095
1112/* All of the QUAD interrupt GATES */ 1096/* All of the QUAD interrupt GATES */
1113fastcall void 1097void smp_qic_timer_interrupt(struct pt_regs *regs)
1114smp_qic_timer_interrupt(struct pt_regs *regs)
1115{ 1098{
1116 struct pt_regs *old_regs = set_irq_regs(regs); 1099 struct pt_regs *old_regs = set_irq_regs(regs);
1117 ack_QIC_CPI(QIC_TIMER_CPI); 1100 ack_QIC_CPI(QIC_TIMER_CPI);
@@ -1119,127 +1102,112 @@ smp_qic_timer_interrupt(struct pt_regs *regs)
1119 set_irq_regs(old_regs); 1102 set_irq_regs(old_regs);
1120} 1103}
1121 1104
1122fastcall void 1105void smp_qic_invalidate_interrupt(struct pt_regs *regs)
1123smp_qic_invalidate_interrupt(struct pt_regs *regs)
1124{ 1106{
1125 ack_QIC_CPI(QIC_INVALIDATE_CPI); 1107 ack_QIC_CPI(QIC_INVALIDATE_CPI);
1126 smp_invalidate_interrupt(); 1108 smp_invalidate_interrupt();
1127} 1109}
1128 1110
1129fastcall void 1111void smp_qic_reschedule_interrupt(struct pt_regs *regs)
1130smp_qic_reschedule_interrupt(struct pt_regs *regs)
1131{ 1112{
1132 ack_QIC_CPI(QIC_RESCHEDULE_CPI); 1113 ack_QIC_CPI(QIC_RESCHEDULE_CPI);
1133 smp_reschedule_interrupt(); 1114 smp_reschedule_interrupt();
1134} 1115}
1135 1116
1136fastcall void 1117void smp_qic_enable_irq_interrupt(struct pt_regs *regs)
1137smp_qic_enable_irq_interrupt(struct pt_regs *regs)
1138{ 1118{
1139 ack_QIC_CPI(QIC_ENABLE_IRQ_CPI); 1119 ack_QIC_CPI(QIC_ENABLE_IRQ_CPI);
1140 smp_enable_irq_interrupt(); 1120 smp_enable_irq_interrupt();
1141} 1121}
1142 1122
1143fastcall void 1123void smp_qic_call_function_interrupt(struct pt_regs *regs)
1144smp_qic_call_function_interrupt(struct pt_regs *regs)
1145{ 1124{
1146 ack_QIC_CPI(QIC_CALL_FUNCTION_CPI); 1125 ack_QIC_CPI(QIC_CALL_FUNCTION_CPI);
1147 smp_call_function_interrupt(); 1126 smp_call_function_interrupt();
1148} 1127}
1149 1128
1150fastcall void 1129void smp_vic_cpi_interrupt(struct pt_regs *regs)
1151smp_vic_cpi_interrupt(struct pt_regs *regs)
1152{ 1130{
1153 struct pt_regs *old_regs = set_irq_regs(regs); 1131 struct pt_regs *old_regs = set_irq_regs(regs);
1154 __u8 cpu = smp_processor_id(); 1132 __u8 cpu = smp_processor_id();
1155 1133
1156 if(is_cpu_quad()) 1134 if (is_cpu_quad())
1157 ack_QIC_CPI(VIC_CPI_LEVEL0); 1135 ack_QIC_CPI(VIC_CPI_LEVEL0);
1158 else 1136 else
1159 ack_VIC_CPI(VIC_CPI_LEVEL0); 1137 ack_VIC_CPI(VIC_CPI_LEVEL0);
1160 1138
1161 if(test_and_clear_bit(VIC_TIMER_CPI, &vic_cpi_mailbox[cpu])) 1139 if (test_and_clear_bit(VIC_TIMER_CPI, &vic_cpi_mailbox[cpu]))
1162 wrapper_smp_local_timer_interrupt(); 1140 wrapper_smp_local_timer_interrupt();
1163 if(test_and_clear_bit(VIC_INVALIDATE_CPI, &vic_cpi_mailbox[cpu])) 1141 if (test_and_clear_bit(VIC_INVALIDATE_CPI, &vic_cpi_mailbox[cpu]))
1164 smp_invalidate_interrupt(); 1142 smp_invalidate_interrupt();
1165 if(test_and_clear_bit(VIC_RESCHEDULE_CPI, &vic_cpi_mailbox[cpu])) 1143 if (test_and_clear_bit(VIC_RESCHEDULE_CPI, &vic_cpi_mailbox[cpu]))
1166 smp_reschedule_interrupt(); 1144 smp_reschedule_interrupt();
1167 if(test_and_clear_bit(VIC_ENABLE_IRQ_CPI, &vic_cpi_mailbox[cpu])) 1145 if (test_and_clear_bit(VIC_ENABLE_IRQ_CPI, &vic_cpi_mailbox[cpu]))
1168 smp_enable_irq_interrupt(); 1146 smp_enable_irq_interrupt();
1169 if(test_and_clear_bit(VIC_CALL_FUNCTION_CPI, &vic_cpi_mailbox[cpu])) 1147 if (test_and_clear_bit(VIC_CALL_FUNCTION_CPI, &vic_cpi_mailbox[cpu]))
1170 smp_call_function_interrupt(); 1148 smp_call_function_interrupt();
1171 set_irq_regs(old_regs); 1149 set_irq_regs(old_regs);
1172} 1150}
1173 1151
1174static void 1152static void do_flush_tlb_all(void *info)
1175do_flush_tlb_all(void* info)
1176{ 1153{
1177 unsigned long cpu = smp_processor_id(); 1154 unsigned long cpu = smp_processor_id();
1178 1155
1179 __flush_tlb_all(); 1156 __flush_tlb_all();
1180 if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_LAZY) 1157 if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_LAZY)
1181 leave_mm(cpu); 1158 voyager_leave_mm(cpu);
1182} 1159}
1183 1160
1184
1185/* flush the TLB of every active CPU in the system */ 1161/* flush the TLB of every active CPU in the system */
1186void 1162void flush_tlb_all(void)
1187flush_tlb_all(void)
1188{ 1163{
1189 on_each_cpu(do_flush_tlb_all, 0, 1, 1); 1164 on_each_cpu(do_flush_tlb_all, 0, 1, 1);
1190} 1165}
1191 1166
1192/* used to set up the trampoline for other CPUs when the memory manager 1167/* used to set up the trampoline for other CPUs when the memory manager
1193 * is sorted out */ 1168 * is sorted out */
1194void __init 1169void __init smp_alloc_memory(void)
1195smp_alloc_memory(void)
1196{ 1170{
1197 trampoline_base = (__u32)alloc_bootmem_low_pages(PAGE_SIZE); 1171 trampoline_base = (__u32) alloc_bootmem_low_pages(PAGE_SIZE);
1198 if(__pa(trampoline_base) >= 0x93000) 1172 if (__pa(trampoline_base) >= 0x93000)
1199 BUG(); 1173 BUG();
1200} 1174}
1201 1175
1202/* send a reschedule CPI to one CPU by physical CPU number*/ 1176/* send a reschedule CPI to one CPU by physical CPU number*/
1203static void 1177static void voyager_smp_send_reschedule(int cpu)
1204voyager_smp_send_reschedule(int cpu)
1205{ 1178{
1206 send_one_CPI(cpu, VIC_RESCHEDULE_CPI); 1179 send_one_CPI(cpu, VIC_RESCHEDULE_CPI);
1207} 1180}
1208 1181
1209 1182int hard_smp_processor_id(void)
1210int
1211hard_smp_processor_id(void)
1212{ 1183{
1213 __u8 i; 1184 __u8 i;
1214 __u8 cpumask = inb(VIC_PROC_WHO_AM_I); 1185 __u8 cpumask = inb(VIC_PROC_WHO_AM_I);
1215 if((cpumask & QUAD_IDENTIFIER) == QUAD_IDENTIFIER) 1186 if ((cpumask & QUAD_IDENTIFIER) == QUAD_IDENTIFIER)
1216 return cpumask & 0x1F; 1187 return cpumask & 0x1F;
1217 1188
1218 for(i = 0; i < 8; i++) { 1189 for (i = 0; i < 8; i++) {
1219 if(cpumask & (1<<i)) 1190 if (cpumask & (1 << i))
1220 return i; 1191 return i;
1221 } 1192 }
1222 printk("** WARNING ** Illegal cpuid returned by VIC: %d", cpumask); 1193 printk("** WARNING ** Illegal cpuid returned by VIC: %d", cpumask);
1223 return 0; 1194 return 0;
1224} 1195}
1225 1196
1226int 1197int safe_smp_processor_id(void)
1227safe_smp_processor_id(void)
1228{ 1198{
1229 return hard_smp_processor_id(); 1199 return hard_smp_processor_id();
1230} 1200}
1231 1201
1232/* broadcast a halt to all other CPUs */ 1202/* broadcast a halt to all other CPUs */
1233static void 1203static void voyager_smp_send_stop(void)
1234voyager_smp_send_stop(void)
1235{ 1204{
1236 smp_call_function(smp_stop_cpu_function, NULL, 1, 1); 1205 smp_call_function(smp_stop_cpu_function, NULL, 1, 1);
1237} 1206}
1238 1207
1239/* this function is triggered in time.c when a clock tick fires 1208/* this function is triggered in time.c when a clock tick fires
1240 * we need to re-broadcast the tick to all CPUs */ 1209 * we need to re-broadcast the tick to all CPUs */
1241void 1210void smp_vic_timer_interrupt(void)
1242smp_vic_timer_interrupt(void)
1243{ 1211{
1244 send_CPI_allbutself(VIC_TIMER_CPI); 1212 send_CPI_allbutself(VIC_TIMER_CPI);
1245 smp_local_timer_interrupt(); 1213 smp_local_timer_interrupt();
@@ -1253,8 +1221,7 @@ smp_vic_timer_interrupt(void)
1253 * multiplier is 1 and it can be changed by writing the new multiplier 1221 * multiplier is 1 and it can be changed by writing the new multiplier
1254 * value into /proc/profile. 1222 * value into /proc/profile.
1255 */ 1223 */
1256void 1224void smp_local_timer_interrupt(void)
1257smp_local_timer_interrupt(void)
1258{ 1225{
1259 int cpu = smp_processor_id(); 1226 int cpu = smp_processor_id();
1260 long weight; 1227 long weight;
@@ -1269,18 +1236,18 @@ smp_local_timer_interrupt(void)
1269 * 1236 *
1270 * Interrupts are already masked off at this point. 1237 * Interrupts are already masked off at this point.
1271 */ 1238 */
1272 per_cpu(prof_counter,cpu) = per_cpu(prof_multiplier, cpu); 1239 per_cpu(prof_counter, cpu) = per_cpu(prof_multiplier, cpu);
1273 if (per_cpu(prof_counter, cpu) != 1240 if (per_cpu(prof_counter, cpu) !=
1274 per_cpu(prof_old_multiplier, cpu)) { 1241 per_cpu(prof_old_multiplier, cpu)) {
1275 /* FIXME: need to update the vic timer tick here */ 1242 /* FIXME: need to update the vic timer tick here */
1276 per_cpu(prof_old_multiplier, cpu) = 1243 per_cpu(prof_old_multiplier, cpu) =
1277 per_cpu(prof_counter, cpu); 1244 per_cpu(prof_counter, cpu);
1278 } 1245 }
1279 1246
1280 update_process_times(user_mode_vm(get_irq_regs())); 1247 update_process_times(user_mode_vm(get_irq_regs()));
1281 } 1248 }
1282 1249
1283 if( ((1<<cpu) & voyager_extended_vic_processors) == 0) 1250 if (((1 << cpu) & voyager_extended_vic_processors) == 0)
1284 /* only extended VIC processors participate in 1251 /* only extended VIC processors participate in
1285 * interrupt distribution */ 1252 * interrupt distribution */
1286 return; 1253 return;
@@ -1296,12 +1263,12 @@ smp_local_timer_interrupt(void)
1296 * we can take more than 100K local irqs per second on a 100 MHz P5. 1263 * we can take more than 100K local irqs per second on a 100 MHz P5.
1297 */ 1264 */
1298 1265
1299 if((++vic_tick[cpu] & 0x7) != 0) 1266 if ((++vic_tick[cpu] & 0x7) != 0)
1300 return; 1267 return;
1301 /* get here every 16 ticks (about every 1/6 of a second) */ 1268 /* get here every 16 ticks (about every 1/6 of a second) */
1302 1269
1303 /* Change our priority to give someone else a chance at getting 1270 /* Change our priority to give someone else a chance at getting
1304 * the IRQ. The algorithm goes like this: 1271 * the IRQ. The algorithm goes like this:
1305 * 1272 *
1306 * In the VIC, the dynamically routed interrupt is always 1273 * In the VIC, the dynamically routed interrupt is always
1307 * handled by the lowest priority eligible (i.e. receiving 1274 * handled by the lowest priority eligible (i.e. receiving
@@ -1325,18 +1292,18 @@ smp_local_timer_interrupt(void)
1325 * affinity code since we now try to even up the interrupt 1292 * affinity code since we now try to even up the interrupt
1326 * counts when an affinity binding is keeping them on a 1293 * counts when an affinity binding is keeping them on a
1327 * particular CPU*/ 1294 * particular CPU*/
1328 weight = (vic_intr_count[cpu]*voyager_extended_cpus 1295 weight = (vic_intr_count[cpu] * voyager_extended_cpus
1329 - vic_intr_total) >> 4; 1296 - vic_intr_total) >> 4;
1330 weight += 4; 1297 weight += 4;
1331 if(weight > 7) 1298 if (weight > 7)
1332 weight = 7; 1299 weight = 7;
1333 if(weight < 0) 1300 if (weight < 0)
1334 weight = 0; 1301 weight = 0;
1335 1302
1336 outb((__u8)weight, VIC_PRIORITY_REGISTER); 1303 outb((__u8) weight, VIC_PRIORITY_REGISTER);
1337 1304
1338#ifdef VOYAGER_DEBUG 1305#ifdef VOYAGER_DEBUG
1339 if((vic_tick[cpu] & 0xFFF) == 0) { 1306 if ((vic_tick[cpu] & 0xFFF) == 0) {
1340 /* print this message roughly every 25 secs */ 1307 /* print this message roughly every 25 secs */
1341 printk("VOYAGER SMP: vic_tick[%d] = %lu, weight = %ld\n", 1308 printk("VOYAGER SMP: vic_tick[%d] = %lu, weight = %ld\n",
1342 cpu, vic_tick[cpu], weight); 1309 cpu, vic_tick[cpu], weight);
@@ -1345,15 +1312,14 @@ smp_local_timer_interrupt(void)
1345} 1312}
1346 1313
1347/* setup the profiling timer */ 1314/* setup the profiling timer */
1348int 1315int setup_profiling_timer(unsigned int multiplier)
1349setup_profiling_timer(unsigned int multiplier)
1350{ 1316{
1351 int i; 1317 int i;
1352 1318
1353 if ( (!multiplier)) 1319 if ((!multiplier))
1354 return -EINVAL; 1320 return -EINVAL;
1355 1321
1356 /* 1322 /*
1357 * Set the new multiplier for each CPU. CPUs don't start using the 1323 * Set the new multiplier for each CPU. CPUs don't start using the
1358 * new values until the next timer interrupt in which they do process 1324 * new values until the next timer interrupt in which they do process
1359 * accounting. 1325 * accounting.
@@ -1367,15 +1333,13 @@ setup_profiling_timer(unsigned int multiplier)
1367/* This is a bit of a mess, but forced on us by the genirq changes 1333/* This is a bit of a mess, but forced on us by the genirq changes
1368 * there's no genirq handler that really does what voyager wants 1334 * there's no genirq handler that really does what voyager wants
1369 * so hack it up with the simple IRQ handler */ 1335 * so hack it up with the simple IRQ handler */
1370static void fastcall 1336static void handle_vic_irq(unsigned int irq, struct irq_desc *desc)
1371handle_vic_irq(unsigned int irq, struct irq_desc *desc)
1372{ 1337{
1373 before_handle_vic_irq(irq); 1338 before_handle_vic_irq(irq);
1374 handle_simple_irq(irq, desc); 1339 handle_simple_irq(irq, desc);
1375 after_handle_vic_irq(irq); 1340 after_handle_vic_irq(irq);
1376} 1341}
1377 1342
1378
1379/* The CPIs are handled in the per cpu 8259s, so they must be 1343/* The CPIs are handled in the per cpu 8259s, so they must be
1380 * enabled to be received: FIX: enabling the CPIs in the early 1344 * enabled to be received: FIX: enabling the CPIs in the early
1381 * boot sequence interferes with bug checking; enable them later 1345 * boot sequence interferes with bug checking; enable them later
@@ -1385,13 +1349,12 @@ handle_vic_irq(unsigned int irq, struct irq_desc *desc)
1385#define QIC_SET_GATE(cpi, vector) \ 1349#define QIC_SET_GATE(cpi, vector) \
1386 set_intr_gate((cpi) + QIC_DEFAULT_CPI_BASE, (vector)) 1350 set_intr_gate((cpi) + QIC_DEFAULT_CPI_BASE, (vector))
1387 1351
1388void __init 1352void __init smp_intr_init(void)
1389smp_intr_init(void)
1390{ 1353{
1391 int i; 1354 int i;
1392 1355
1393 /* initialize the per cpu irq mask to all disabled */ 1356 /* initialize the per cpu irq mask to all disabled */
1394 for(i = 0; i < NR_CPUS; i++) 1357 for (i = 0; i < NR_CPUS; i++)
1395 vic_irq_mask[i] = 0xFFFF; 1358 vic_irq_mask[i] = 0xFFFF;
1396 1359
1397 VIC_SET_GATE(VIC_CPI_LEVEL0, vic_cpi_interrupt); 1360 VIC_SET_GATE(VIC_CPI_LEVEL0, vic_cpi_interrupt);
@@ -1404,42 +1367,40 @@ smp_intr_init(void)
1404 QIC_SET_GATE(QIC_RESCHEDULE_CPI, qic_reschedule_interrupt); 1367 QIC_SET_GATE(QIC_RESCHEDULE_CPI, qic_reschedule_interrupt);
1405 QIC_SET_GATE(QIC_ENABLE_IRQ_CPI, qic_enable_irq_interrupt); 1368 QIC_SET_GATE(QIC_ENABLE_IRQ_CPI, qic_enable_irq_interrupt);
1406 QIC_SET_GATE(QIC_CALL_FUNCTION_CPI, qic_call_function_interrupt); 1369 QIC_SET_GATE(QIC_CALL_FUNCTION_CPI, qic_call_function_interrupt);
1407
1408 1370
1409 /* now put the VIC descriptor into the first 48 IRQs 1371 /* now put the VIC descriptor into the first 48 IRQs
1410 * 1372 *
1411 * This is for later: first 16 correspond to PC IRQs; next 16 1373 * This is for later: first 16 correspond to PC IRQs; next 16
1412 * are Primary MC IRQs and final 16 are Secondary MC IRQs */ 1374 * are Primary MC IRQs and final 16 are Secondary MC IRQs */
1413 for(i = 0; i < 48; i++) 1375 for (i = 0; i < 48; i++)
1414 set_irq_chip_and_handler(i, &vic_chip, handle_vic_irq); 1376 set_irq_chip_and_handler(i, &vic_chip, handle_vic_irq);
1415} 1377}
1416 1378
1417/* send a CPI at level cpi to a set of cpus in cpuset (set 1 bit per 1379/* send a CPI at level cpi to a set of cpus in cpuset (set 1 bit per
1418 * processor to receive CPI */ 1380 * processor to receive CPI */
1419static void 1381static void send_CPI(__u32 cpuset, __u8 cpi)
1420send_CPI(__u32 cpuset, __u8 cpi)
1421{ 1382{
1422 int cpu; 1383 int cpu;
1423 __u32 quad_cpuset = (cpuset & voyager_quad_processors); 1384 __u32 quad_cpuset = (cpuset & voyager_quad_processors);
1424 1385
1425 if(cpi < VIC_START_FAKE_CPI) { 1386 if (cpi < VIC_START_FAKE_CPI) {
1426 /* fake CPI are only used for booting, so send to the 1387 /* fake CPI are only used for booting, so send to the
1427 * extended quads as well---Quads must be VIC booted */ 1388 * extended quads as well---Quads must be VIC booted */
1428 outb((__u8)(cpuset), VIC_CPI_Registers[cpi]); 1389 outb((__u8) (cpuset), VIC_CPI_Registers[cpi]);
1429 return; 1390 return;
1430 } 1391 }
1431 if(quad_cpuset) 1392 if (quad_cpuset)
1432 send_QIC_CPI(quad_cpuset, cpi); 1393 send_QIC_CPI(quad_cpuset, cpi);
1433 cpuset &= ~quad_cpuset; 1394 cpuset &= ~quad_cpuset;
1434 cpuset &= 0xff; /* only first 8 CPUs vaild for VIC CPI */ 1395 cpuset &= 0xff; /* only first 8 CPUs vaild for VIC CPI */
1435 if(cpuset == 0) 1396 if (cpuset == 0)
1436 return; 1397 return;
1437 for_each_online_cpu(cpu) { 1398 for_each_online_cpu(cpu) {
1438 if(cpuset & (1<<cpu)) 1399 if (cpuset & (1 << cpu))
1439 set_bit(cpi, &vic_cpi_mailbox[cpu]); 1400 set_bit(cpi, &vic_cpi_mailbox[cpu]);
1440 } 1401 }
1441 if(cpuset) 1402 if (cpuset)
1442 outb((__u8)cpuset, VIC_CPI_Registers[VIC_CPI_LEVEL0]); 1403 outb((__u8) cpuset, VIC_CPI_Registers[VIC_CPI_LEVEL0]);
1443} 1404}
1444 1405
1445/* Acknowledge receipt of CPI in the QIC, clear in QIC hardware and 1406/* Acknowledge receipt of CPI in the QIC, clear in QIC hardware and
@@ -1448,20 +1409,19 @@ send_CPI(__u32 cpuset, __u8 cpi)
1448 * DON'T make this inline otherwise the cache line read will be 1409 * DON'T make this inline otherwise the cache line read will be
1449 * optimised away 1410 * optimised away
1450 * */ 1411 * */
1451static int 1412static int ack_QIC_CPI(__u8 cpi)
1452ack_QIC_CPI(__u8 cpi) { 1413{
1453 __u8 cpu = hard_smp_processor_id(); 1414 __u8 cpu = hard_smp_processor_id();
1454 1415
1455 cpi &= 7; 1416 cpi &= 7;
1456 1417
1457 outb(1<<cpi, QIC_INTERRUPT_CLEAR1); 1418 outb(1 << cpi, QIC_INTERRUPT_CLEAR1);
1458 return voyager_quad_cpi_addr[cpu]->qic_cpi[cpi].cpi; 1419 return voyager_quad_cpi_addr[cpu]->qic_cpi[cpi].cpi;
1459} 1420}
1460 1421
1461static void 1422static void ack_special_QIC_CPI(__u8 cpi)
1462ack_special_QIC_CPI(__u8 cpi)
1463{ 1423{
1464 switch(cpi) { 1424 switch (cpi) {
1465 case VIC_CMN_INT: 1425 case VIC_CMN_INT:
1466 outb(QIC_CMN_INT, QIC_INTERRUPT_CLEAR0); 1426 outb(QIC_CMN_INT, QIC_INTERRUPT_CLEAR0);
1467 break; 1427 break;
@@ -1474,8 +1434,7 @@ ack_special_QIC_CPI(__u8 cpi)
1474} 1434}
1475 1435
1476/* Acknowledge receipt of CPI in the VIC (essentially an EOI) */ 1436/* Acknowledge receipt of CPI in the VIC (essentially an EOI) */
1477static void 1437static void ack_VIC_CPI(__u8 cpi)
1478ack_VIC_CPI(__u8 cpi)
1479{ 1438{
1480#ifdef VOYAGER_DEBUG 1439#ifdef VOYAGER_DEBUG
1481 unsigned long flags; 1440 unsigned long flags;
@@ -1484,17 +1443,17 @@ ack_VIC_CPI(__u8 cpi)
1484 1443
1485 local_irq_save(flags); 1444 local_irq_save(flags);
1486 isr = vic_read_isr(); 1445 isr = vic_read_isr();
1487 if((isr & (1<<(cpi &7))) == 0) { 1446 if ((isr & (1 << (cpi & 7))) == 0) {
1488 printk("VOYAGER SMP: CPU%d lost CPI%d\n", cpu, cpi); 1447 printk("VOYAGER SMP: CPU%d lost CPI%d\n", cpu, cpi);
1489 } 1448 }
1490#endif 1449#endif
1491 /* send specific EOI; the two system interrupts have 1450 /* send specific EOI; the two system interrupts have
1492 * bit 4 set for a separate vector but behave as the 1451 * bit 4 set for a separate vector but behave as the
1493 * corresponding 3 bit intr */ 1452 * corresponding 3 bit intr */
1494 outb_p(0x60|(cpi & 7),0x20); 1453 outb_p(0x60 | (cpi & 7), 0x20);
1495 1454
1496#ifdef VOYAGER_DEBUG 1455#ifdef VOYAGER_DEBUG
1497 if((vic_read_isr() & (1<<(cpi &7))) != 0) { 1456 if ((vic_read_isr() & (1 << (cpi & 7))) != 0) {
1498 printk("VOYAGER SMP: CPU%d still asserting CPI%d\n", cpu, cpi); 1457 printk("VOYAGER SMP: CPU%d still asserting CPI%d\n", cpu, cpi);
1499 } 1458 }
1500 local_irq_restore(flags); 1459 local_irq_restore(flags);
@@ -1502,12 +1461,11 @@ ack_VIC_CPI(__u8 cpi)
1502} 1461}
1503 1462
1504/* cribbed with thanks from irq.c */ 1463/* cribbed with thanks from irq.c */
1505#define __byte(x,y) (((unsigned char *)&(y))[x]) 1464#define __byte(x,y) (((unsigned char *)&(y))[x])
1506#define cached_21(cpu) (__byte(0,vic_irq_mask[cpu])) 1465#define cached_21(cpu) (__byte(0,vic_irq_mask[cpu]))
1507#define cached_A1(cpu) (__byte(1,vic_irq_mask[cpu])) 1466#define cached_A1(cpu) (__byte(1,vic_irq_mask[cpu]))
1508 1467
1509static unsigned int 1468static unsigned int startup_vic_irq(unsigned int irq)
1510startup_vic_irq(unsigned int irq)
1511{ 1469{
1512 unmask_vic_irq(irq); 1470 unmask_vic_irq(irq);
1513 1471
@@ -1535,13 +1493,12 @@ startup_vic_irq(unsigned int irq)
1535 * broadcast an Interrupt enable CPI which causes all other CPUs to 1493 * broadcast an Interrupt enable CPI which causes all other CPUs to
1536 * adjust their masks accordingly. */ 1494 * adjust their masks accordingly. */
1537 1495
1538static void 1496static void unmask_vic_irq(unsigned int irq)
1539unmask_vic_irq(unsigned int irq)
1540{ 1497{
1541 /* linux doesn't to processor-irq affinity, so enable on 1498 /* linux doesn't to processor-irq affinity, so enable on
1542 * all CPUs we know about */ 1499 * all CPUs we know about */
1543 int cpu = smp_processor_id(), real_cpu; 1500 int cpu = smp_processor_id(), real_cpu;
1544 __u16 mask = (1<<irq); 1501 __u16 mask = (1 << irq);
1545 __u32 processorList = 0; 1502 __u32 processorList = 0;
1546 unsigned long flags; 1503 unsigned long flags;
1547 1504
@@ -1549,78 +1506,72 @@ unmask_vic_irq(unsigned int irq)
1549 irq, cpu, cpu_irq_affinity[cpu])); 1506 irq, cpu, cpu_irq_affinity[cpu]));
1550 spin_lock_irqsave(&vic_irq_lock, flags); 1507 spin_lock_irqsave(&vic_irq_lock, flags);
1551 for_each_online_cpu(real_cpu) { 1508 for_each_online_cpu(real_cpu) {
1552 if(!(voyager_extended_vic_processors & (1<<real_cpu))) 1509 if (!(voyager_extended_vic_processors & (1 << real_cpu)))
1553 continue; 1510 continue;
1554 if(!(cpu_irq_affinity[real_cpu] & mask)) { 1511 if (!(cpu_irq_affinity[real_cpu] & mask)) {
1555 /* irq has no affinity for this CPU, ignore */ 1512 /* irq has no affinity for this CPU, ignore */
1556 continue; 1513 continue;
1557 } 1514 }
1558 if(real_cpu == cpu) { 1515 if (real_cpu == cpu) {
1559 enable_local_vic_irq(irq); 1516 enable_local_vic_irq(irq);
1560 } 1517 } else if (vic_irq_mask[real_cpu] & mask) {
1561 else if(vic_irq_mask[real_cpu] & mask) {
1562 vic_irq_enable_mask[real_cpu] |= mask; 1518 vic_irq_enable_mask[real_cpu] |= mask;
1563 processorList |= (1<<real_cpu); 1519 processorList |= (1 << real_cpu);
1564 } 1520 }
1565 } 1521 }
1566 spin_unlock_irqrestore(&vic_irq_lock, flags); 1522 spin_unlock_irqrestore(&vic_irq_lock, flags);
1567 if(processorList) 1523 if (processorList)
1568 send_CPI(processorList, VIC_ENABLE_IRQ_CPI); 1524 send_CPI(processorList, VIC_ENABLE_IRQ_CPI);
1569} 1525}
1570 1526
1571static void 1527static void mask_vic_irq(unsigned int irq)
1572mask_vic_irq(unsigned int irq)
1573{ 1528{
1574 /* lazy disable, do nothing */ 1529 /* lazy disable, do nothing */
1575} 1530}
1576 1531
1577static void 1532static void enable_local_vic_irq(unsigned int irq)
1578enable_local_vic_irq(unsigned int irq)
1579{ 1533{
1580 __u8 cpu = smp_processor_id(); 1534 __u8 cpu = smp_processor_id();
1581 __u16 mask = ~(1 << irq); 1535 __u16 mask = ~(1 << irq);
1582 __u16 old_mask = vic_irq_mask[cpu]; 1536 __u16 old_mask = vic_irq_mask[cpu];
1583 1537
1584 vic_irq_mask[cpu] &= mask; 1538 vic_irq_mask[cpu] &= mask;
1585 if(vic_irq_mask[cpu] == old_mask) 1539 if (vic_irq_mask[cpu] == old_mask)
1586 return; 1540 return;
1587 1541
1588 VDEBUG(("VOYAGER DEBUG: Enabling irq %d in hardware on CPU %d\n", 1542 VDEBUG(("VOYAGER DEBUG: Enabling irq %d in hardware on CPU %d\n",
1589 irq, cpu)); 1543 irq, cpu));
1590 1544
1591 if (irq & 8) { 1545 if (irq & 8) {
1592 outb_p(cached_A1(cpu),0xA1); 1546 outb_p(cached_A1(cpu), 0xA1);
1593 (void)inb_p(0xA1); 1547 (void)inb_p(0xA1);
1594 } 1548 } else {
1595 else { 1549 outb_p(cached_21(cpu), 0x21);
1596 outb_p(cached_21(cpu),0x21);
1597 (void)inb_p(0x21); 1550 (void)inb_p(0x21);
1598 } 1551 }
1599} 1552}
1600 1553
1601static void 1554static void disable_local_vic_irq(unsigned int irq)
1602disable_local_vic_irq(unsigned int irq)
1603{ 1555{
1604 __u8 cpu = smp_processor_id(); 1556 __u8 cpu = smp_processor_id();
1605 __u16 mask = (1 << irq); 1557 __u16 mask = (1 << irq);
1606 __u16 old_mask = vic_irq_mask[cpu]; 1558 __u16 old_mask = vic_irq_mask[cpu];
1607 1559
1608 if(irq == 7) 1560 if (irq == 7)
1609 return; 1561 return;
1610 1562
1611 vic_irq_mask[cpu] |= mask; 1563 vic_irq_mask[cpu] |= mask;
1612 if(old_mask == vic_irq_mask[cpu]) 1564 if (old_mask == vic_irq_mask[cpu])
1613 return; 1565 return;
1614 1566
1615 VDEBUG(("VOYAGER DEBUG: Disabling irq %d in hardware on CPU %d\n", 1567 VDEBUG(("VOYAGER DEBUG: Disabling irq %d in hardware on CPU %d\n",
1616 irq, cpu)); 1568 irq, cpu));
1617 1569
1618 if (irq & 8) { 1570 if (irq & 8) {
1619 outb_p(cached_A1(cpu),0xA1); 1571 outb_p(cached_A1(cpu), 0xA1);
1620 (void)inb_p(0xA1); 1572 (void)inb_p(0xA1);
1621 } 1573 } else {
1622 else { 1574 outb_p(cached_21(cpu), 0x21);
1623 outb_p(cached_21(cpu),0x21);
1624 (void)inb_p(0x21); 1575 (void)inb_p(0x21);
1625 } 1576 }
1626} 1577}
@@ -1631,8 +1582,7 @@ disable_local_vic_irq(unsigned int irq)
1631 * interrupt in the vic, so we merely set a flag (IRQ_DISABLED). If 1582 * interrupt in the vic, so we merely set a flag (IRQ_DISABLED). If
1632 * this interrupt actually comes in, then we mask and ack here to push 1583 * this interrupt actually comes in, then we mask and ack here to push
1633 * the interrupt off to another CPU */ 1584 * the interrupt off to another CPU */
1634static void 1585static void before_handle_vic_irq(unsigned int irq)
1635before_handle_vic_irq(unsigned int irq)
1636{ 1586{
1637 irq_desc_t *desc = irq_desc + irq; 1587 irq_desc_t *desc = irq_desc + irq;
1638 __u8 cpu = smp_processor_id(); 1588 __u8 cpu = smp_processor_id();
@@ -1641,16 +1591,16 @@ before_handle_vic_irq(unsigned int irq)
1641 vic_intr_total++; 1591 vic_intr_total++;
1642 vic_intr_count[cpu]++; 1592 vic_intr_count[cpu]++;
1643 1593
1644 if(!(cpu_irq_affinity[cpu] & (1<<irq))) { 1594 if (!(cpu_irq_affinity[cpu] & (1 << irq))) {
1645 /* The irq is not in our affinity mask, push it off 1595 /* The irq is not in our affinity mask, push it off
1646 * onto another CPU */ 1596 * onto another CPU */
1647 VDEBUG(("VOYAGER DEBUG: affinity triggered disable of irq %d on cpu %d\n", 1597 VDEBUG(("VOYAGER DEBUG: affinity triggered disable of irq %d "
1648 irq, cpu)); 1598 "on cpu %d\n", irq, cpu));
1649 disable_local_vic_irq(irq); 1599 disable_local_vic_irq(irq);
1650 /* set IRQ_INPROGRESS to prevent the handler in irq.c from 1600 /* set IRQ_INPROGRESS to prevent the handler in irq.c from
1651 * actually calling the interrupt routine */ 1601 * actually calling the interrupt routine */
1652 desc->status |= IRQ_REPLAY | IRQ_INPROGRESS; 1602 desc->status |= IRQ_REPLAY | IRQ_INPROGRESS;
1653 } else if(desc->status & IRQ_DISABLED) { 1603 } else if (desc->status & IRQ_DISABLED) {
1654 /* Damn, the interrupt actually arrived, do the lazy 1604 /* Damn, the interrupt actually arrived, do the lazy
1655 * disable thing. The interrupt routine in irq.c will 1605 * disable thing. The interrupt routine in irq.c will
1656 * not handle a IRQ_DISABLED interrupt, so nothing more 1606 * not handle a IRQ_DISABLED interrupt, so nothing more
@@ -1667,8 +1617,7 @@ before_handle_vic_irq(unsigned int irq)
1667} 1617}
1668 1618
1669/* Finish the VIC interrupt: basically mask */ 1619/* Finish the VIC interrupt: basically mask */
1670static void 1620static void after_handle_vic_irq(unsigned int irq)
1671after_handle_vic_irq(unsigned int irq)
1672{ 1621{
1673 irq_desc_t *desc = irq_desc + irq; 1622 irq_desc_t *desc = irq_desc + irq;
1674 1623
@@ -1685,11 +1634,11 @@ after_handle_vic_irq(unsigned int irq)
1685#ifdef VOYAGER_DEBUG 1634#ifdef VOYAGER_DEBUG
1686 /* DEBUG: before we ack, check what's in progress */ 1635 /* DEBUG: before we ack, check what's in progress */
1687 isr = vic_read_isr(); 1636 isr = vic_read_isr();
1688 if((isr & (1<<irq) && !(status & IRQ_REPLAY)) == 0) { 1637 if ((isr & (1 << irq) && !(status & IRQ_REPLAY)) == 0) {
1689 int i; 1638 int i;
1690 __u8 cpu = smp_processor_id(); 1639 __u8 cpu = smp_processor_id();
1691 __u8 real_cpu; 1640 __u8 real_cpu;
1692 int mask; /* Um... initialize me??? --RR */ 1641 int mask; /* Um... initialize me??? --RR */
1693 1642
1694 printk("VOYAGER SMP: CPU%d lost interrupt %d\n", 1643 printk("VOYAGER SMP: CPU%d lost interrupt %d\n",
1695 cpu, irq); 1644 cpu, irq);
@@ -1698,9 +1647,10 @@ after_handle_vic_irq(unsigned int irq)
1698 outb(VIC_CPU_MASQUERADE_ENABLE | real_cpu, 1647 outb(VIC_CPU_MASQUERADE_ENABLE | real_cpu,
1699 VIC_PROCESSOR_ID); 1648 VIC_PROCESSOR_ID);
1700 isr = vic_read_isr(); 1649 isr = vic_read_isr();
1701 if(isr & (1<<irq)) { 1650 if (isr & (1 << irq)) {
1702 printk("VOYAGER SMP: CPU%d ack irq %d\n", 1651 printk
1703 real_cpu, irq); 1652 ("VOYAGER SMP: CPU%d ack irq %d\n",
1653 real_cpu, irq);
1704 ack_vic_irq(irq); 1654 ack_vic_irq(irq);
1705 } 1655 }
1706 outb(cpu, VIC_PROCESSOR_ID); 1656 outb(cpu, VIC_PROCESSOR_ID);
@@ -1711,7 +1661,7 @@ after_handle_vic_irq(unsigned int irq)
1711 * receipt by another CPU so everything must be in 1661 * receipt by another CPU so everything must be in
1712 * order here */ 1662 * order here */
1713 ack_vic_irq(irq); 1663 ack_vic_irq(irq);
1714 if(status & IRQ_REPLAY) { 1664 if (status & IRQ_REPLAY) {
1715 /* replay is set if we disable the interrupt 1665 /* replay is set if we disable the interrupt
1716 * in the before_handle_vic_irq() routine, so 1666 * in the before_handle_vic_irq() routine, so
1717 * clear the in progress bit here to allow the 1667 * clear the in progress bit here to allow the
@@ -1720,9 +1670,9 @@ after_handle_vic_irq(unsigned int irq)
1720 } 1670 }
1721#ifdef VOYAGER_DEBUG 1671#ifdef VOYAGER_DEBUG
1722 isr = vic_read_isr(); 1672 isr = vic_read_isr();
1723 if((isr & (1<<irq)) != 0) 1673 if ((isr & (1 << irq)) != 0)
1724 printk("VOYAGER SMP: after_handle_vic_irq() after ack irq=%d, isr=0x%x\n", 1674 printk("VOYAGER SMP: after_handle_vic_irq() after "
1725 irq, isr); 1675 "ack irq=%d, isr=0x%x\n", irq, isr);
1726#endif /* VOYAGER_DEBUG */ 1676#endif /* VOYAGER_DEBUG */
1727 } 1677 }
1728 _raw_spin_unlock(&vic_irq_lock); 1678 _raw_spin_unlock(&vic_irq_lock);
@@ -1731,7 +1681,6 @@ after_handle_vic_irq(unsigned int irq)
1731 * may be intercepted by another CPU if reasserted */ 1681 * may be intercepted by another CPU if reasserted */
1732} 1682}
1733 1683
1734
1735/* Linux processor - interrupt affinity manipulations. 1684/* Linux processor - interrupt affinity manipulations.
1736 * 1685 *
1737 * For each processor, we maintain a 32 bit irq affinity mask. 1686 * For each processor, we maintain a 32 bit irq affinity mask.
@@ -1748,8 +1697,7 @@ after_handle_vic_irq(unsigned int irq)
1748 * change the mask and then do an interrupt enable CPI to re-enable on 1697 * change the mask and then do an interrupt enable CPI to re-enable on
1749 * the selected processors */ 1698 * the selected processors */
1750 1699
1751void 1700void set_vic_irq_affinity(unsigned int irq, cpumask_t mask)
1752set_vic_irq_affinity(unsigned int irq, cpumask_t mask)
1753{ 1701{
1754 /* Only extended processors handle interrupts */ 1702 /* Only extended processors handle interrupts */
1755 unsigned long real_mask; 1703 unsigned long real_mask;
@@ -1757,13 +1705,13 @@ set_vic_irq_affinity(unsigned int irq, cpumask_t mask)
1757 int cpu; 1705 int cpu;
1758 1706
1759 real_mask = cpus_addr(mask)[0] & voyager_extended_vic_processors; 1707 real_mask = cpus_addr(mask)[0] & voyager_extended_vic_processors;
1760 1708
1761 if(cpus_addr(mask)[0] == 0) 1709 if (cpus_addr(mask)[0] == 0)
1762 /* can't have no CPUs to accept the interrupt -- extremely 1710 /* can't have no CPUs to accept the interrupt -- extremely
1763 * bad things will happen */ 1711 * bad things will happen */
1764 return; 1712 return;
1765 1713
1766 if(irq == 0) 1714 if (irq == 0)
1767 /* can't change the affinity of the timer IRQ. This 1715 /* can't change the affinity of the timer IRQ. This
1768 * is due to the constraint in the voyager 1716 * is due to the constraint in the voyager
1769 * architecture that the CPI also comes in on and IRQ 1717 * architecture that the CPI also comes in on and IRQ
@@ -1772,7 +1720,7 @@ set_vic_irq_affinity(unsigned int irq, cpumask_t mask)
1772 * will no-longer be able to accept VIC CPIs */ 1720 * will no-longer be able to accept VIC CPIs */
1773 return; 1721 return;
1774 1722
1775 if(irq >= 32) 1723 if (irq >= 32)
1776 /* You can only have 32 interrupts in a voyager system 1724 /* You can only have 32 interrupts in a voyager system
1777 * (and 32 only if you have a secondary microchannel 1725 * (and 32 only if you have a secondary microchannel
1778 * bus) */ 1726 * bus) */
@@ -1780,8 +1728,8 @@ set_vic_irq_affinity(unsigned int irq, cpumask_t mask)
1780 1728
1781 for_each_online_cpu(cpu) { 1729 for_each_online_cpu(cpu) {
1782 unsigned long cpu_mask = 1 << cpu; 1730 unsigned long cpu_mask = 1 << cpu;
1783 1731
1784 if(cpu_mask & real_mask) { 1732 if (cpu_mask & real_mask) {
1785 /* enable the interrupt for this cpu */ 1733 /* enable the interrupt for this cpu */
1786 cpu_irq_affinity[cpu] |= irq_mask; 1734 cpu_irq_affinity[cpu] |= irq_mask;
1787 } else { 1735 } else {
@@ -1800,25 +1748,23 @@ set_vic_irq_affinity(unsigned int irq, cpumask_t mask)
1800 unmask_vic_irq(irq); 1748 unmask_vic_irq(irq);
1801} 1749}
1802 1750
1803static void 1751static void ack_vic_irq(unsigned int irq)
1804ack_vic_irq(unsigned int irq)
1805{ 1752{
1806 if (irq & 8) { 1753 if (irq & 8) {
1807 outb(0x62,0x20); /* Specific EOI to cascade */ 1754 outb(0x62, 0x20); /* Specific EOI to cascade */
1808 outb(0x60|(irq & 7),0xA0); 1755 outb(0x60 | (irq & 7), 0xA0);
1809 } else { 1756 } else {
1810 outb(0x60 | (irq & 7),0x20); 1757 outb(0x60 | (irq & 7), 0x20);
1811 } 1758 }
1812} 1759}
1813 1760
1814/* enable the CPIs. In the VIC, the CPIs are delivered by the 8259 1761/* enable the CPIs. In the VIC, the CPIs are delivered by the 8259
1815 * but are not vectored by it. This means that the 8259 mask must be 1762 * but are not vectored by it. This means that the 8259 mask must be
1816 * lowered to receive them */ 1763 * lowered to receive them */
1817static __init void 1764static __init void vic_enable_cpi(void)
1818vic_enable_cpi(void)
1819{ 1765{
1820 __u8 cpu = smp_processor_id(); 1766 __u8 cpu = smp_processor_id();
1821 1767
1822 /* just take a copy of the current mask (nop for boot cpu) */ 1768 /* just take a copy of the current mask (nop for boot cpu) */
1823 vic_irq_mask[cpu] = vic_irq_mask[boot_cpu_id]; 1769 vic_irq_mask[cpu] = vic_irq_mask[boot_cpu_id];
1824 1770
@@ -1827,7 +1773,7 @@ vic_enable_cpi(void)
1827 /* for sys int and cmn int */ 1773 /* for sys int and cmn int */
1828 enable_local_vic_irq(7); 1774 enable_local_vic_irq(7);
1829 1775
1830 if(is_cpu_quad()) { 1776 if (is_cpu_quad()) {
1831 outb(QIC_DEFAULT_MASK0, QIC_MASK_REGISTER0); 1777 outb(QIC_DEFAULT_MASK0, QIC_MASK_REGISTER0);
1832 outb(QIC_CPI_ENABLE, QIC_MASK_REGISTER1); 1778 outb(QIC_CPI_ENABLE, QIC_MASK_REGISTER1);
1833 VDEBUG(("VOYAGER SMP: QIC ENABLE CPI: CPU%d: MASK 0x%x\n", 1779 VDEBUG(("VOYAGER SMP: QIC ENABLE CPI: CPU%d: MASK 0x%x\n",
@@ -1838,8 +1784,7 @@ vic_enable_cpi(void)
1838 cpu, vic_irq_mask[cpu])); 1784 cpu, vic_irq_mask[cpu]));
1839} 1785}
1840 1786
1841void 1787void voyager_smp_dump()
1842voyager_smp_dump()
1843{ 1788{
1844 int old_cpu = smp_processor_id(), cpu; 1789 int old_cpu = smp_processor_id(), cpu;
1845 1790
@@ -1865,10 +1810,10 @@ voyager_smp_dump()
1865 cpu, vic_irq_mask[cpu], imr, irr, isr); 1810 cpu, vic_irq_mask[cpu], imr, irr, isr);
1866#if 0 1811#if 0
1867 /* These lines are put in to try to unstick an un ack'd irq */ 1812 /* These lines are put in to try to unstick an un ack'd irq */
1868 if(isr != 0) { 1813 if (isr != 0) {
1869 int irq; 1814 int irq;
1870 for(irq=0; irq<16; irq++) { 1815 for (irq = 0; irq < 16; irq++) {
1871 if(isr & (1<<irq)) { 1816 if (isr & (1 << irq)) {
1872 printk("\tCPU%d: ack irq %d\n", 1817 printk("\tCPU%d: ack irq %d\n",
1873 cpu, irq); 1818 cpu, irq);
1874 local_irq_save(flags); 1819 local_irq_save(flags);
@@ -1884,17 +1829,15 @@ voyager_smp_dump()
1884 } 1829 }
1885} 1830}
1886 1831
1887void 1832void smp_voyager_power_off(void *dummy)
1888smp_voyager_power_off(void *dummy)
1889{ 1833{
1890 if(smp_processor_id() == boot_cpu_id) 1834 if (smp_processor_id() == boot_cpu_id)
1891 voyager_power_off(); 1835 voyager_power_off();
1892 else 1836 else
1893 smp_stop_cpu_function(NULL); 1837 smp_stop_cpu_function(NULL);
1894} 1838}
1895 1839
1896static void __init 1840static void __init voyager_smp_prepare_cpus(unsigned int max_cpus)
1897voyager_smp_prepare_cpus(unsigned int max_cpus)
1898{ 1841{
1899 /* FIXME: ignore max_cpus for now */ 1842 /* FIXME: ignore max_cpus for now */
1900 smp_boot_cpus(); 1843 smp_boot_cpus();
@@ -1911,8 +1854,7 @@ static void __cpuinit voyager_smp_prepare_boot_cpu(void)
1911 cpu_set(smp_processor_id(), cpu_present_map); 1854 cpu_set(smp_processor_id(), cpu_present_map);
1912} 1855}
1913 1856
1914static int __cpuinit 1857static int __cpuinit voyager_cpu_up(unsigned int cpu)
1915voyager_cpu_up(unsigned int cpu)
1916{ 1858{
1917 /* This only works at boot for x86. See "rewrite" above. */ 1859 /* This only works at boot for x86. See "rewrite" above. */
1918 if (cpu_isset(cpu, smp_commenced_mask)) 1860 if (cpu_isset(cpu, smp_commenced_mask))
@@ -1928,14 +1870,12 @@ voyager_cpu_up(unsigned int cpu)
1928 return 0; 1870 return 0;
1929} 1871}
1930 1872
1931static void __init 1873static void __init voyager_smp_cpus_done(unsigned int max_cpus)
1932voyager_smp_cpus_done(unsigned int max_cpus)
1933{ 1874{
1934 zap_low_mappings(); 1875 zap_low_mappings();
1935} 1876}
1936 1877
1937void __init 1878void __init smp_setup_processor_id(void)
1938smp_setup_processor_id(void)
1939{ 1879{
1940 current_thread_info()->cpu = hard_smp_processor_id(); 1880 current_thread_info()->cpu = hard_smp_processor_id();
1941 x86_write_percpu(cpu_number, hard_smp_processor_id()); 1881 x86_write_percpu(cpu_number, hard_smp_processor_id());
diff --git a/arch/x86/mach-voyager/voyager_thread.c b/arch/x86/mach-voyager/voyager_thread.c
index 50f9366c411e..c69c931818ed 100644
--- a/arch/x86/mach-voyager/voyager_thread.c
+++ b/arch/x86/mach-voyager/voyager_thread.c
@@ -30,12 +30,10 @@
30#include <asm/mtrr.h> 30#include <asm/mtrr.h>
31#include <asm/msr.h> 31#include <asm/msr.h>
32 32
33
34struct task_struct *voyager_thread; 33struct task_struct *voyager_thread;
35static __u8 set_timeout; 34static __u8 set_timeout;
36 35
37static int 36static int execute(const char *string)
38execute(const char *string)
39{ 37{
40 int ret; 38 int ret;
41 39
@@ -52,48 +50,48 @@ execute(const char *string)
52 NULL, 50 NULL,
53 }; 51 };
54 52
55 if ((ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC)) != 0) { 53 if ((ret =
56 printk(KERN_ERR "Voyager failed to run \"%s\": %i\n", 54 call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC)) != 0) {
57 string, ret); 55 printk(KERN_ERR "Voyager failed to run \"%s\": %i\n", string,
56 ret);
58 } 57 }
59 return ret; 58 return ret;
60} 59}
61 60
62static void 61static void check_from_kernel(void)
63check_from_kernel(void)
64{ 62{
65 if(voyager_status.switch_off) { 63 if (voyager_status.switch_off) {
66 64
67 /* FIXME: This should be configurable via proc */ 65 /* FIXME: This should be configurable via proc */
68 execute("umask 600; echo 0 > /etc/initrunlvl; kill -HUP 1"); 66 execute("umask 600; echo 0 > /etc/initrunlvl; kill -HUP 1");
69 } else if(voyager_status.power_fail) { 67 } else if (voyager_status.power_fail) {
70 VDEBUG(("Voyager daemon detected AC power failure\n")); 68 VDEBUG(("Voyager daemon detected AC power failure\n"));
71 69
72 /* FIXME: This should be configureable via proc */ 70 /* FIXME: This should be configureable via proc */
73 execute("umask 600; echo F > /etc/powerstatus; kill -PWR 1"); 71 execute("umask 600; echo F > /etc/powerstatus; kill -PWR 1");
74 set_timeout = 1; 72 set_timeout = 1;
75 } 73 }
76} 74}
77 75
78static void 76static void check_continuing_condition(void)
79check_continuing_condition(void)
80{ 77{
81 if(voyager_status.power_fail) { 78 if (voyager_status.power_fail) {
82 __u8 data; 79 __u8 data;
83 voyager_cat_psi(VOYAGER_PSI_SUBREAD, 80 voyager_cat_psi(VOYAGER_PSI_SUBREAD,
84 VOYAGER_PSI_AC_FAIL_REG, &data); 81 VOYAGER_PSI_AC_FAIL_REG, &data);
85 if((data & 0x1f) == 0) { 82 if ((data & 0x1f) == 0) {
86 /* all power restored */ 83 /* all power restored */
87 printk(KERN_NOTICE "VOYAGER AC power restored, cancelling shutdown\n"); 84 printk(KERN_NOTICE
85 "VOYAGER AC power restored, cancelling shutdown\n");
88 /* FIXME: should be user configureable */ 86 /* FIXME: should be user configureable */
89 execute("umask 600; echo O > /etc/powerstatus; kill -PWR 1"); 87 execute
88 ("umask 600; echo O > /etc/powerstatus; kill -PWR 1");
90 set_timeout = 0; 89 set_timeout = 0;
91 } 90 }
92 } 91 }
93} 92}
94 93
95static int 94static int thread(void *unused)
96thread(void *unused)
97{ 95{
98 printk(KERN_NOTICE "Voyager starting monitor thread\n"); 96 printk(KERN_NOTICE "Voyager starting monitor thread\n");
99 97
@@ -102,7 +100,7 @@ thread(void *unused)
102 schedule_timeout(set_timeout ? HZ : MAX_SCHEDULE_TIMEOUT); 100 schedule_timeout(set_timeout ? HZ : MAX_SCHEDULE_TIMEOUT);
103 101
104 VDEBUG(("Voyager Daemon awoken\n")); 102 VDEBUG(("Voyager Daemon awoken\n"));
105 if(voyager_status.request_from_kernel == 0) { 103 if (voyager_status.request_from_kernel == 0) {
106 /* probably awoken from timeout */ 104 /* probably awoken from timeout */
107 check_continuing_condition(); 105 check_continuing_condition();
108 } else { 106 } else {
@@ -112,20 +110,18 @@ thread(void *unused)
112 } 110 }
113} 111}
114 112
115static int __init 113static int __init voyager_thread_start(void)
116voyager_thread_start(void)
117{ 114{
118 voyager_thread = kthread_run(thread, NULL, "kvoyagerd"); 115 voyager_thread = kthread_run(thread, NULL, "kvoyagerd");
119 if (IS_ERR(voyager_thread)) { 116 if (IS_ERR(voyager_thread)) {
120 printk(KERN_ERR "Voyager: Failed to create system monitor thread.\n"); 117 printk(KERN_ERR
118 "Voyager: Failed to create system monitor thread.\n");
121 return PTR_ERR(voyager_thread); 119 return PTR_ERR(voyager_thread);
122 } 120 }
123 return 0; 121 return 0;
124} 122}
125 123
126 124static void __exit voyager_thread_stop(void)
127static void __exit
128voyager_thread_stop(void)
129{ 125{
130 kthread_stop(voyager_thread); 126 kthread_stop(voyager_thread);
131} 127}
diff --git a/arch/x86/math-emu/errors.c b/arch/x86/math-emu/errors.c
index a1b0d22f6978..59d353d2c599 100644
--- a/arch/x86/math-emu/errors.c
+++ b/arch/x86/math-emu/errors.c
@@ -33,45 +33,41 @@
33#undef PRINT_MESSAGES 33#undef PRINT_MESSAGES
34/* */ 34/* */
35 35
36
37#if 0 36#if 0
38void Un_impl(void) 37void Un_impl(void)
39{ 38{
40 u_char byte1, FPU_modrm; 39 u_char byte1, FPU_modrm;
41 unsigned long address = FPU_ORIG_EIP; 40 unsigned long address = FPU_ORIG_EIP;
42 41
43 RE_ENTRANT_CHECK_OFF; 42 RE_ENTRANT_CHECK_OFF;
44 /* No need to check access_ok(), we have previously fetched these bytes. */ 43 /* No need to check access_ok(), we have previously fetched these bytes. */
45 printk("Unimplemented FPU Opcode at eip=%p : ", (void __user *) address); 44 printk("Unimplemented FPU Opcode at eip=%p : ", (void __user *)address);
46 if ( FPU_CS == __USER_CS ) 45 if (FPU_CS == __USER_CS) {
47 { 46 while (1) {
48 while ( 1 ) 47 FPU_get_user(byte1, (u_char __user *) address);
49 { 48 if ((byte1 & 0xf8) == 0xd8)
50 FPU_get_user(byte1, (u_char __user *) address); 49 break;
51 if ( (byte1 & 0xf8) == 0xd8 ) break; 50 printk("[%02x]", byte1);
52 printk("[%02x]", byte1); 51 address++;
53 address++; 52 }
53 printk("%02x ", byte1);
54 FPU_get_user(FPU_modrm, 1 + (u_char __user *) address);
55
56 if (FPU_modrm >= 0300)
57 printk("%02x (%02x+%d)\n", FPU_modrm, FPU_modrm & 0xf8,
58 FPU_modrm & 7);
59 else
60 printk("/%d\n", (FPU_modrm >> 3) & 7);
61 } else {
62 printk("cs selector = %04x\n", FPU_CS);
54 } 63 }
55 printk("%02x ", byte1);
56 FPU_get_user(FPU_modrm, 1 + (u_char __user *) address);
57
58 if (FPU_modrm >= 0300)
59 printk("%02x (%02x+%d)\n", FPU_modrm, FPU_modrm & 0xf8, FPU_modrm & 7);
60 else
61 printk("/%d\n", (FPU_modrm >> 3) & 7);
62 }
63 else
64 {
65 printk("cs selector = %04x\n", FPU_CS);
66 }
67
68 RE_ENTRANT_CHECK_ON;
69
70 EXCEPTION(EX_Invalid);
71 64
72} 65 RE_ENTRANT_CHECK_ON;
73#endif /* 0 */
74 66
67 EXCEPTION(EX_Invalid);
68
69}
70#endif /* 0 */
75 71
76/* 72/*
77 Called for opcodes which are illegal and which are known to result in a 73 Called for opcodes which are illegal and which are known to result in a
@@ -79,139 +75,152 @@ void Un_impl(void)
79 */ 75 */
80void FPU_illegal(void) 76void FPU_illegal(void)
81{ 77{
82 math_abort(FPU_info,SIGILL); 78 math_abort(FPU_info, SIGILL);
83} 79}
84 80
85
86
87void FPU_printall(void) 81void FPU_printall(void)
88{ 82{
89 int i; 83 int i;
90 static const char *tag_desc[] = { "Valid", "Zero", "ERROR", "Empty", 84 static const char *tag_desc[] = { "Valid", "Zero", "ERROR", "Empty",
91 "DeNorm", "Inf", "NaN" }; 85 "DeNorm", "Inf", "NaN"
92 u_char byte1, FPU_modrm; 86 };
93 unsigned long address = FPU_ORIG_EIP; 87 u_char byte1, FPU_modrm;
94 88 unsigned long address = FPU_ORIG_EIP;
95 RE_ENTRANT_CHECK_OFF; 89
96 /* No need to check access_ok(), we have previously fetched these bytes. */ 90 RE_ENTRANT_CHECK_OFF;
97 printk("At %p:", (void *) address); 91 /* No need to check access_ok(), we have previously fetched these bytes. */
98 if ( FPU_CS == __USER_CS ) 92 printk("At %p:", (void *)address);
99 { 93 if (FPU_CS == __USER_CS) {
100#define MAX_PRINTED_BYTES 20 94#define MAX_PRINTED_BYTES 20
101 for ( i = 0; i < MAX_PRINTED_BYTES; i++ ) 95 for (i = 0; i < MAX_PRINTED_BYTES; i++) {
102 { 96 FPU_get_user(byte1, (u_char __user *) address);
103 FPU_get_user(byte1, (u_char __user *) address); 97 if ((byte1 & 0xf8) == 0xd8) {
104 if ( (byte1 & 0xf8) == 0xd8 ) 98 printk(" %02x", byte1);
105 { 99 break;
106 printk(" %02x", byte1); 100 }
107 break; 101 printk(" [%02x]", byte1);
108 } 102 address++;
109 printk(" [%02x]", byte1); 103 }
110 address++; 104 if (i == MAX_PRINTED_BYTES)
111 } 105 printk(" [more..]\n");
112 if ( i == MAX_PRINTED_BYTES ) 106 else {
113 printk(" [more..]\n"); 107 FPU_get_user(FPU_modrm, 1 + (u_char __user *) address);
114 else 108
115 { 109 if (FPU_modrm >= 0300)
116 FPU_get_user(FPU_modrm, 1 + (u_char __user *) address); 110 printk(" %02x (%02x+%d)\n", FPU_modrm,
117 111 FPU_modrm & 0xf8, FPU_modrm & 7);
118 if (FPU_modrm >= 0300) 112 else
119 printk(" %02x (%02x+%d)\n", FPU_modrm, FPU_modrm & 0xf8, FPU_modrm & 7); 113 printk(" /%d, mod=%d rm=%d\n",
120 else 114 (FPU_modrm >> 3) & 7,
121 printk(" /%d, mod=%d rm=%d\n", 115 (FPU_modrm >> 6) & 3, FPU_modrm & 7);
122 (FPU_modrm >> 3) & 7, (FPU_modrm >> 6) & 3, FPU_modrm & 7); 116 }
117 } else {
118 printk("%04x\n", FPU_CS);
123 } 119 }
124 }
125 else
126 {
127 printk("%04x\n", FPU_CS);
128 }
129 120
130 partial_status = status_word(); 121 partial_status = status_word();
131 122
132#ifdef DEBUGGING 123#ifdef DEBUGGING
133if ( partial_status & SW_Backward ) printk("SW: backward compatibility\n"); 124 if (partial_status & SW_Backward)
134if ( partial_status & SW_C3 ) printk("SW: condition bit 3\n"); 125 printk("SW: backward compatibility\n");
135if ( partial_status & SW_C2 ) printk("SW: condition bit 2\n"); 126 if (partial_status & SW_C3)
136if ( partial_status & SW_C1 ) printk("SW: condition bit 1\n"); 127 printk("SW: condition bit 3\n");
137if ( partial_status & SW_C0 ) printk("SW: condition bit 0\n"); 128 if (partial_status & SW_C2)
138if ( partial_status & SW_Summary ) printk("SW: exception summary\n"); 129 printk("SW: condition bit 2\n");
139if ( partial_status & SW_Stack_Fault ) printk("SW: stack fault\n"); 130 if (partial_status & SW_C1)
140if ( partial_status & SW_Precision ) printk("SW: loss of precision\n"); 131 printk("SW: condition bit 1\n");
141if ( partial_status & SW_Underflow ) printk("SW: underflow\n"); 132 if (partial_status & SW_C0)
142if ( partial_status & SW_Overflow ) printk("SW: overflow\n"); 133 printk("SW: condition bit 0\n");
143if ( partial_status & SW_Zero_Div ) printk("SW: divide by zero\n"); 134 if (partial_status & SW_Summary)
144if ( partial_status & SW_Denorm_Op ) printk("SW: denormalized operand\n"); 135 printk("SW: exception summary\n");
145if ( partial_status & SW_Invalid ) printk("SW: invalid operation\n"); 136 if (partial_status & SW_Stack_Fault)
137 printk("SW: stack fault\n");
138 if (partial_status & SW_Precision)
139 printk("SW: loss of precision\n");
140 if (partial_status & SW_Underflow)
141 printk("SW: underflow\n");
142 if (partial_status & SW_Overflow)
143 printk("SW: overflow\n");
144 if (partial_status & SW_Zero_Div)
145 printk("SW: divide by zero\n");
146 if (partial_status & SW_Denorm_Op)
147 printk("SW: denormalized operand\n");
148 if (partial_status & SW_Invalid)
149 printk("SW: invalid operation\n");
146#endif /* DEBUGGING */ 150#endif /* DEBUGGING */
147 151
148 printk(" SW: b=%d st=%ld es=%d sf=%d cc=%d%d%d%d ef=%d%d%d%d%d%d\n", 152 printk(" SW: b=%d st=%d es=%d sf=%d cc=%d%d%d%d ef=%d%d%d%d%d%d\n", partial_status & 0x8000 ? 1 : 0, /* busy */
149 partial_status & 0x8000 ? 1 : 0, /* busy */ 153 (partial_status & 0x3800) >> 11, /* stack top pointer */
150 (partial_status & 0x3800) >> 11, /* stack top pointer */ 154 partial_status & 0x80 ? 1 : 0, /* Error summary status */
151 partial_status & 0x80 ? 1 : 0, /* Error summary status */ 155 partial_status & 0x40 ? 1 : 0, /* Stack flag */
152 partial_status & 0x40 ? 1 : 0, /* Stack flag */ 156 partial_status & SW_C3 ? 1 : 0, partial_status & SW_C2 ? 1 : 0, /* cc */
153 partial_status & SW_C3?1:0, partial_status & SW_C2?1:0, /* cc */ 157 partial_status & SW_C1 ? 1 : 0, partial_status & SW_C0 ? 1 : 0, /* cc */
154 partial_status & SW_C1?1:0, partial_status & SW_C0?1:0, /* cc */ 158 partial_status & SW_Precision ? 1 : 0,
155 partial_status & SW_Precision?1:0, partial_status & SW_Underflow?1:0, 159 partial_status & SW_Underflow ? 1 : 0,
156 partial_status & SW_Overflow?1:0, partial_status & SW_Zero_Div?1:0, 160 partial_status & SW_Overflow ? 1 : 0,
157 partial_status & SW_Denorm_Op?1:0, partial_status & SW_Invalid?1:0); 161 partial_status & SW_Zero_Div ? 1 : 0,
158 162 partial_status & SW_Denorm_Op ? 1 : 0,
159printk(" CW: ic=%d rc=%ld%ld pc=%ld%ld iem=%d ef=%d%d%d%d%d%d\n", 163 partial_status & SW_Invalid ? 1 : 0);
160 control_word & 0x1000 ? 1 : 0, 164
161 (control_word & 0x800) >> 11, (control_word & 0x400) >> 10, 165 printk(" CW: ic=%d rc=%d%d pc=%d%d iem=%d ef=%d%d%d%d%d%d\n",
162 (control_word & 0x200) >> 9, (control_word & 0x100) >> 8, 166 control_word & 0x1000 ? 1 : 0,
163 control_word & 0x80 ? 1 : 0, 167 (control_word & 0x800) >> 11, (control_word & 0x400) >> 10,
164 control_word & SW_Precision?1:0, control_word & SW_Underflow?1:0, 168 (control_word & 0x200) >> 9, (control_word & 0x100) >> 8,
165 control_word & SW_Overflow?1:0, control_word & SW_Zero_Div?1:0, 169 control_word & 0x80 ? 1 : 0,
166 control_word & SW_Denorm_Op?1:0, control_word & SW_Invalid?1:0); 170 control_word & SW_Precision ? 1 : 0,
167 171 control_word & SW_Underflow ? 1 : 0,
168 for ( i = 0; i < 8; i++ ) 172 control_word & SW_Overflow ? 1 : 0,
169 { 173 control_word & SW_Zero_Div ? 1 : 0,
170 FPU_REG *r = &st(i); 174 control_word & SW_Denorm_Op ? 1 : 0,
171 u_char tagi = FPU_gettagi(i); 175 control_word & SW_Invalid ? 1 : 0);
172 switch (tagi) 176
173 { 177 for (i = 0; i < 8; i++) {
174 case TAG_Empty: 178 FPU_REG *r = &st(i);
175 continue; 179 u_char tagi = FPU_gettagi(i);
176 break; 180 switch (tagi) {
177 case TAG_Zero: 181 case TAG_Empty:
178 case TAG_Special: 182 continue;
179 tagi = FPU_Special(r); 183 break;
180 case TAG_Valid: 184 case TAG_Zero:
181 printk("st(%d) %c .%04lx %04lx %04lx %04lx e%+-6d ", i, 185 case TAG_Special:
182 getsign(r) ? '-' : '+', 186 tagi = FPU_Special(r);
183 (long)(r->sigh >> 16), 187 case TAG_Valid:
184 (long)(r->sigh & 0xFFFF), 188 printk("st(%d) %c .%04lx %04lx %04lx %04lx e%+-6d ", i,
185 (long)(r->sigl >> 16), 189 getsign(r) ? '-' : '+',
186 (long)(r->sigl & 0xFFFF), 190 (long)(r->sigh >> 16),
187 exponent(r) - EXP_BIAS + 1); 191 (long)(r->sigh & 0xFFFF),
188 break; 192 (long)(r->sigl >> 16),
189 default: 193 (long)(r->sigl & 0xFFFF),
190 printk("Whoops! Error in errors.c: tag%d is %d ", i, tagi); 194 exponent(r) - EXP_BIAS + 1);
191 continue; 195 break;
192 break; 196 default:
197 printk("Whoops! Error in errors.c: tag%d is %d ", i,
198 tagi);
199 continue;
200 break;
201 }
202 printk("%s\n", tag_desc[(int)(unsigned)tagi]);
193 } 203 }
194 printk("%s\n", tag_desc[(int) (unsigned) tagi]);
195 }
196 204
197 RE_ENTRANT_CHECK_ON; 205 RE_ENTRANT_CHECK_ON;
198 206
199} 207}
200 208
201static struct { 209static struct {
202 int type; 210 int type;
203 const char *name; 211 const char *name;
204} exception_names[] = { 212} exception_names[] = {
205 { EX_StackOver, "stack overflow" }, 213 {
206 { EX_StackUnder, "stack underflow" }, 214 EX_StackOver, "stack overflow"}, {
207 { EX_Precision, "loss of precision" }, 215 EX_StackUnder, "stack underflow"}, {
208 { EX_Underflow, "underflow" }, 216 EX_Precision, "loss of precision"}, {
209 { EX_Overflow, "overflow" }, 217 EX_Underflow, "underflow"}, {
210 { EX_ZeroDiv, "divide by zero" }, 218 EX_Overflow, "overflow"}, {
211 { EX_Denormal, "denormalized operand" }, 219 EX_ZeroDiv, "divide by zero"}, {
212 { EX_Invalid, "invalid operation" }, 220 EX_Denormal, "denormalized operand"}, {
213 { EX_INTERNAL, "INTERNAL BUG in "FPU_VERSION }, 221 EX_Invalid, "invalid operation"}, {
214 { 0, NULL } 222 EX_INTERNAL, "INTERNAL BUG in " FPU_VERSION}, {
223 0, NULL}
215}; 224};
216 225
217/* 226/*
@@ -295,445 +304,386 @@ static struct {
295 304
296asmlinkage void FPU_exception(int n) 305asmlinkage void FPU_exception(int n)
297{ 306{
298 int i, int_type; 307 int i, int_type;
299 308
300 int_type = 0; /* Needed only to stop compiler warnings */ 309 int_type = 0; /* Needed only to stop compiler warnings */
301 if ( n & EX_INTERNAL ) 310 if (n & EX_INTERNAL) {
302 { 311 int_type = n - EX_INTERNAL;
303 int_type = n - EX_INTERNAL; 312 n = EX_INTERNAL;
304 n = EX_INTERNAL; 313 /* Set lots of exception bits! */
305 /* Set lots of exception bits! */ 314 partial_status |= (SW_Exc_Mask | SW_Summary | SW_Backward);
306 partial_status |= (SW_Exc_Mask | SW_Summary | SW_Backward); 315 } else {
307 } 316 /* Extract only the bits which we use to set the status word */
308 else 317 n &= (SW_Exc_Mask);
309 { 318 /* Set the corresponding exception bit */
310 /* Extract only the bits which we use to set the status word */ 319 partial_status |= n;
311 n &= (SW_Exc_Mask); 320 /* Set summary bits iff exception isn't masked */
312 /* Set the corresponding exception bit */ 321 if (partial_status & ~control_word & CW_Exceptions)
313 partial_status |= n; 322 partial_status |= (SW_Summary | SW_Backward);
314 /* Set summary bits iff exception isn't masked */ 323 if (n & (SW_Stack_Fault | EX_Precision)) {
315 if ( partial_status & ~control_word & CW_Exceptions ) 324 if (!(n & SW_C1))
316 partial_status |= (SW_Summary | SW_Backward); 325 /* This bit distinguishes over- from underflow for a stack fault,
317 if ( n & (SW_Stack_Fault | EX_Precision) ) 326 and roundup from round-down for precision loss. */
318 { 327 partial_status &= ~SW_C1;
319 if ( !(n & SW_C1) ) 328 }
320 /* This bit distinguishes over- from underflow for a stack fault,
321 and roundup from round-down for precision loss. */
322 partial_status &= ~SW_C1;
323 } 329 }
324 }
325 330
326 RE_ENTRANT_CHECK_OFF; 331 RE_ENTRANT_CHECK_OFF;
327 if ( (~control_word & n & CW_Exceptions) || (n == EX_INTERNAL) ) 332 if ((~control_word & n & CW_Exceptions) || (n == EX_INTERNAL)) {
328 {
329#ifdef PRINT_MESSAGES 333#ifdef PRINT_MESSAGES
330 /* My message from the sponsor */ 334 /* My message from the sponsor */
331 printk(FPU_VERSION" "__DATE__" (C) W. Metzenthen.\n"); 335 printk(FPU_VERSION " " __DATE__ " (C) W. Metzenthen.\n");
332#endif /* PRINT_MESSAGES */ 336#endif /* PRINT_MESSAGES */
333 337
334 /* Get a name string for error reporting */ 338 /* Get a name string for error reporting */
335 for (i=0; exception_names[i].type; i++) 339 for (i = 0; exception_names[i].type; i++)
336 if ( (exception_names[i].type & n) == exception_names[i].type ) 340 if ((exception_names[i].type & n) ==
337 break; 341 exception_names[i].type)
338 342 break;
339 if (exception_names[i].type) 343
340 { 344 if (exception_names[i].type) {
341#ifdef PRINT_MESSAGES 345#ifdef PRINT_MESSAGES
342 printk("FP Exception: %s!\n", exception_names[i].name); 346 printk("FP Exception: %s!\n", exception_names[i].name);
343#endif /* PRINT_MESSAGES */ 347#endif /* PRINT_MESSAGES */
344 } 348 } else
345 else 349 printk("FPU emulator: Unknown Exception: 0x%04x!\n", n);
346 printk("FPU emulator: Unknown Exception: 0x%04x!\n", n); 350
347 351 if (n == EX_INTERNAL) {
348 if ( n == EX_INTERNAL ) 352 printk("FPU emulator: Internal error type 0x%04x\n",
349 { 353 int_type);
350 printk("FPU emulator: Internal error type 0x%04x\n", int_type); 354 FPU_printall();
351 FPU_printall(); 355 }
352 }
353#ifdef PRINT_MESSAGES 356#ifdef PRINT_MESSAGES
354 else 357 else
355 FPU_printall(); 358 FPU_printall();
356#endif /* PRINT_MESSAGES */ 359#endif /* PRINT_MESSAGES */
357 360
358 /* 361 /*
359 * The 80486 generates an interrupt on the next non-control FPU 362 * The 80486 generates an interrupt on the next non-control FPU
360 * instruction. So we need some means of flagging it. 363 * instruction. So we need some means of flagging it.
361 * We use the ES (Error Summary) bit for this. 364 * We use the ES (Error Summary) bit for this.
362 */ 365 */
363 } 366 }
364 RE_ENTRANT_CHECK_ON; 367 RE_ENTRANT_CHECK_ON;
365 368
366#ifdef __DEBUG__ 369#ifdef __DEBUG__
367 math_abort(FPU_info,SIGFPE); 370 math_abort(FPU_info, SIGFPE);
368#endif /* __DEBUG__ */ 371#endif /* __DEBUG__ */
369 372
370} 373}
371 374
372
373/* Real operation attempted on a NaN. */ 375/* Real operation attempted on a NaN. */
374/* Returns < 0 if the exception is unmasked */ 376/* Returns < 0 if the exception is unmasked */
375int real_1op_NaN(FPU_REG *a) 377int real_1op_NaN(FPU_REG *a)
376{ 378{
377 int signalling, isNaN; 379 int signalling, isNaN;
378 380
379 isNaN = (exponent(a) == EXP_OVER) && (a->sigh & 0x80000000); 381 isNaN = (exponent(a) == EXP_OVER) && (a->sigh & 0x80000000);
380 382
381 /* The default result for the case of two "equal" NaNs (signs may 383 /* The default result for the case of two "equal" NaNs (signs may
382 differ) is chosen to reproduce 80486 behaviour */ 384 differ) is chosen to reproduce 80486 behaviour */
383 signalling = isNaN && !(a->sigh & 0x40000000); 385 signalling = isNaN && !(a->sigh & 0x40000000);
384 386
385 if ( !signalling ) 387 if (!signalling) {
386 { 388 if (!isNaN) { /* pseudo-NaN, or other unsupported? */
387 if ( !isNaN ) /* pseudo-NaN, or other unsupported? */ 389 if (control_word & CW_Invalid) {
388 { 390 /* Masked response */
389 if ( control_word & CW_Invalid ) 391 reg_copy(&CONST_QNaN, a);
390 { 392 }
391 /* Masked response */ 393 EXCEPTION(EX_Invalid);
392 reg_copy(&CONST_QNaN, a); 394 return (!(control_word & CW_Invalid) ? FPU_Exception :
393 } 395 0) | TAG_Special;
394 EXCEPTION(EX_Invalid); 396 }
395 return (!(control_word & CW_Invalid) ? FPU_Exception : 0) | TAG_Special; 397 return TAG_Special;
396 } 398 }
397 return TAG_Special;
398 }
399 399
400 if ( control_word & CW_Invalid ) 400 if (control_word & CW_Invalid) {
401 { 401 /* The masked response */
402 /* The masked response */ 402 if (!(a->sigh & 0x80000000)) { /* pseudo-NaN ? */
403 if ( !(a->sigh & 0x80000000) ) /* pseudo-NaN ? */ 403 reg_copy(&CONST_QNaN, a);
404 { 404 }
405 reg_copy(&CONST_QNaN, a); 405 /* ensure a Quiet NaN */
406 a->sigh |= 0x40000000;
406 } 407 }
407 /* ensure a Quiet NaN */
408 a->sigh |= 0x40000000;
409 }
410 408
411 EXCEPTION(EX_Invalid); 409 EXCEPTION(EX_Invalid);
412 410
413 return (!(control_word & CW_Invalid) ? FPU_Exception : 0) | TAG_Special; 411 return (!(control_word & CW_Invalid) ? FPU_Exception : 0) | TAG_Special;
414} 412}
415 413
416
417/* Real operation attempted on two operands, one a NaN. */ 414/* Real operation attempted on two operands, one a NaN. */
418/* Returns < 0 if the exception is unmasked */ 415/* Returns < 0 if the exception is unmasked */
419int real_2op_NaN(FPU_REG const *b, u_char tagb, 416int real_2op_NaN(FPU_REG const *b, u_char tagb,
420 int deststnr, 417 int deststnr, FPU_REG const *defaultNaN)
421 FPU_REG const *defaultNaN)
422{ 418{
423 FPU_REG *dest = &st(deststnr); 419 FPU_REG *dest = &st(deststnr);
424 FPU_REG const *a = dest; 420 FPU_REG const *a = dest;
425 u_char taga = FPU_gettagi(deststnr); 421 u_char taga = FPU_gettagi(deststnr);
426 FPU_REG const *x; 422 FPU_REG const *x;
427 int signalling, unsupported; 423 int signalling, unsupported;
428 424
429 if ( taga == TAG_Special ) 425 if (taga == TAG_Special)
430 taga = FPU_Special(a); 426 taga = FPU_Special(a);
431 if ( tagb == TAG_Special ) 427 if (tagb == TAG_Special)
432 tagb = FPU_Special(b); 428 tagb = FPU_Special(b);
433 429
434 /* TW_NaN is also used for unsupported data types. */ 430 /* TW_NaN is also used for unsupported data types. */
435 unsupported = ((taga == TW_NaN) 431 unsupported = ((taga == TW_NaN)
436 && !((exponent(a) == EXP_OVER) && (a->sigh & 0x80000000))) 432 && !((exponent(a) == EXP_OVER)
437 || ((tagb == TW_NaN) 433 && (a->sigh & 0x80000000)))
438 && !((exponent(b) == EXP_OVER) && (b->sigh & 0x80000000))); 434 || ((tagb == TW_NaN)
439 if ( unsupported ) 435 && !((exponent(b) == EXP_OVER) && (b->sigh & 0x80000000)));
440 { 436 if (unsupported) {
441 if ( control_word & CW_Invalid ) 437 if (control_word & CW_Invalid) {
442 { 438 /* Masked response */
443 /* Masked response */ 439 FPU_copy_to_regi(&CONST_QNaN, TAG_Special, deststnr);
444 FPU_copy_to_regi(&CONST_QNaN, TAG_Special, deststnr); 440 }
445 } 441 EXCEPTION(EX_Invalid);
446 EXCEPTION(EX_Invalid); 442 return (!(control_word & CW_Invalid) ? FPU_Exception : 0) |
447 return (!(control_word & CW_Invalid) ? FPU_Exception : 0) | TAG_Special; 443 TAG_Special;
448 }
449
450 if (taga == TW_NaN)
451 {
452 x = a;
453 if (tagb == TW_NaN)
454 {
455 signalling = !(a->sigh & b->sigh & 0x40000000);
456 if ( significand(b) > significand(a) )
457 x = b;
458 else if ( significand(b) == significand(a) )
459 {
460 /* The default result for the case of two "equal" NaNs (signs may
461 differ) is chosen to reproduce 80486 behaviour */
462 x = defaultNaN;
463 }
464 }
465 else
466 {
467 /* return the quiet version of the NaN in a */
468 signalling = !(a->sigh & 0x40000000);
469 } 444 }
470 } 445
471 else 446 if (taga == TW_NaN) {
447 x = a;
448 if (tagb == TW_NaN) {
449 signalling = !(a->sigh & b->sigh & 0x40000000);
450 if (significand(b) > significand(a))
451 x = b;
452 else if (significand(b) == significand(a)) {
453 /* The default result for the case of two "equal" NaNs (signs may
454 differ) is chosen to reproduce 80486 behaviour */
455 x = defaultNaN;
456 }
457 } else {
458 /* return the quiet version of the NaN in a */
459 signalling = !(a->sigh & 0x40000000);
460 }
461 } else
472#ifdef PARANOID 462#ifdef PARANOID
473 if (tagb == TW_NaN) 463 if (tagb == TW_NaN)
474#endif /* PARANOID */ 464#endif /* PARANOID */
475 { 465 {
476 signalling = !(b->sigh & 0x40000000); 466 signalling = !(b->sigh & 0x40000000);
477 x = b; 467 x = b;
478 } 468 }
479#ifdef PARANOID 469#ifdef PARANOID
480 else 470 else {
481 { 471 signalling = 0;
482 signalling = 0; 472 EXCEPTION(EX_INTERNAL | 0x113);
483 EXCEPTION(EX_INTERNAL|0x113); 473 x = &CONST_QNaN;
484 x = &CONST_QNaN; 474 }
485 }
486#endif /* PARANOID */ 475#endif /* PARANOID */
487 476
488 if ( (!signalling) || (control_word & CW_Invalid) ) 477 if ((!signalling) || (control_word & CW_Invalid)) {
489 { 478 if (!x)
490 if ( ! x ) 479 x = b;
491 x = b;
492 480
493 if ( !(x->sigh & 0x80000000) ) /* pseudo-NaN ? */ 481 if (!(x->sigh & 0x80000000)) /* pseudo-NaN ? */
494 x = &CONST_QNaN; 482 x = &CONST_QNaN;
495 483
496 FPU_copy_to_regi(x, TAG_Special, deststnr); 484 FPU_copy_to_regi(x, TAG_Special, deststnr);
497 485
498 if ( !signalling ) 486 if (!signalling)
499 return TAG_Special; 487 return TAG_Special;
500 488
501 /* ensure a Quiet NaN */ 489 /* ensure a Quiet NaN */
502 dest->sigh |= 0x40000000; 490 dest->sigh |= 0x40000000;
503 } 491 }
504 492
505 EXCEPTION(EX_Invalid); 493 EXCEPTION(EX_Invalid);
506 494
507 return (!(control_word & CW_Invalid) ? FPU_Exception : 0) | TAG_Special; 495 return (!(control_word & CW_Invalid) ? FPU_Exception : 0) | TAG_Special;
508} 496}
509 497
510
511/* Invalid arith operation on Valid registers */ 498/* Invalid arith operation on Valid registers */
512/* Returns < 0 if the exception is unmasked */ 499/* Returns < 0 if the exception is unmasked */
513asmlinkage int arith_invalid(int deststnr) 500asmlinkage int arith_invalid(int deststnr)
514{ 501{
515 502
516 EXCEPTION(EX_Invalid); 503 EXCEPTION(EX_Invalid);
517
518 if ( control_word & CW_Invalid )
519 {
520 /* The masked response */
521 FPU_copy_to_regi(&CONST_QNaN, TAG_Special, deststnr);
522 }
523
524 return (!(control_word & CW_Invalid) ? FPU_Exception : 0) | TAG_Valid;
525 504
526} 505 if (control_word & CW_Invalid) {
506 /* The masked response */
507 FPU_copy_to_regi(&CONST_QNaN, TAG_Special, deststnr);
508 }
527 509
510 return (!(control_word & CW_Invalid) ? FPU_Exception : 0) | TAG_Valid;
511
512}
528 513
529/* Divide a finite number by zero */ 514/* Divide a finite number by zero */
530asmlinkage int FPU_divide_by_zero(int deststnr, u_char sign) 515asmlinkage int FPU_divide_by_zero(int deststnr, u_char sign)
531{ 516{
532 FPU_REG *dest = &st(deststnr); 517 FPU_REG *dest = &st(deststnr);
533 int tag = TAG_Valid; 518 int tag = TAG_Valid;
519
520 if (control_word & CW_ZeroDiv) {
521 /* The masked response */
522 FPU_copy_to_regi(&CONST_INF, TAG_Special, deststnr);
523 setsign(dest, sign);
524 tag = TAG_Special;
525 }
534 526
535 if ( control_word & CW_ZeroDiv ) 527 EXCEPTION(EX_ZeroDiv);
536 {
537 /* The masked response */
538 FPU_copy_to_regi(&CONST_INF, TAG_Special, deststnr);
539 setsign(dest, sign);
540 tag = TAG_Special;
541 }
542
543 EXCEPTION(EX_ZeroDiv);
544 528
545 return (!(control_word & CW_ZeroDiv) ? FPU_Exception : 0) | tag; 529 return (!(control_word & CW_ZeroDiv) ? FPU_Exception : 0) | tag;
546 530
547} 531}
548 532
549
550/* This may be called often, so keep it lean */ 533/* This may be called often, so keep it lean */
551int set_precision_flag(int flags) 534int set_precision_flag(int flags)
552{ 535{
553 if ( control_word & CW_Precision ) 536 if (control_word & CW_Precision) {
554 { 537 partial_status &= ~(SW_C1 & flags);
555 partial_status &= ~(SW_C1 & flags); 538 partial_status |= flags; /* The masked response */
556 partial_status |= flags; /* The masked response */ 539 return 0;
557 return 0; 540 } else {
558 } 541 EXCEPTION(flags);
559 else 542 return 1;
560 { 543 }
561 EXCEPTION(flags);
562 return 1;
563 }
564} 544}
565 545
566
567/* This may be called often, so keep it lean */ 546/* This may be called often, so keep it lean */
568asmlinkage void set_precision_flag_up(void) 547asmlinkage void set_precision_flag_up(void)
569{ 548{
570 if ( control_word & CW_Precision ) 549 if (control_word & CW_Precision)
571 partial_status |= (SW_Precision | SW_C1); /* The masked response */ 550 partial_status |= (SW_Precision | SW_C1); /* The masked response */
572 else 551 else
573 EXCEPTION(EX_Precision | SW_C1); 552 EXCEPTION(EX_Precision | SW_C1);
574} 553}
575 554
576
577/* This may be called often, so keep it lean */ 555/* This may be called often, so keep it lean */
578asmlinkage void set_precision_flag_down(void) 556asmlinkage void set_precision_flag_down(void)
579{ 557{
580 if ( control_word & CW_Precision ) 558 if (control_word & CW_Precision) { /* The masked response */
581 { /* The masked response */ 559 partial_status &= ~SW_C1;
582 partial_status &= ~SW_C1; 560 partial_status |= SW_Precision;
583 partial_status |= SW_Precision; 561 } else
584 } 562 EXCEPTION(EX_Precision);
585 else
586 EXCEPTION(EX_Precision);
587} 563}
588 564
589
590asmlinkage int denormal_operand(void) 565asmlinkage int denormal_operand(void)
591{ 566{
592 if ( control_word & CW_Denormal ) 567 if (control_word & CW_Denormal) { /* The masked response */
593 { /* The masked response */ 568 partial_status |= SW_Denorm_Op;
594 partial_status |= SW_Denorm_Op; 569 return TAG_Special;
595 return TAG_Special; 570 } else {
596 } 571 EXCEPTION(EX_Denormal);
597 else 572 return TAG_Special | FPU_Exception;
598 { 573 }
599 EXCEPTION(EX_Denormal);
600 return TAG_Special | FPU_Exception;
601 }
602} 574}
603 575
604
605asmlinkage int arith_overflow(FPU_REG *dest) 576asmlinkage int arith_overflow(FPU_REG *dest)
606{ 577{
607 int tag = TAG_Valid; 578 int tag = TAG_Valid;
608 579
609 if ( control_word & CW_Overflow ) 580 if (control_word & CW_Overflow) {
610 { 581 /* The masked response */
611 /* The masked response */
612/* ###### The response here depends upon the rounding mode */ 582/* ###### The response here depends upon the rounding mode */
613 reg_copy(&CONST_INF, dest); 583 reg_copy(&CONST_INF, dest);
614 tag = TAG_Special; 584 tag = TAG_Special;
615 } 585 } else {
616 else 586 /* Subtract the magic number from the exponent */
617 { 587 addexponent(dest, (-3 * (1 << 13)));
618 /* Subtract the magic number from the exponent */ 588 }
619 addexponent(dest, (-3 * (1 << 13)));
620 }
621
622 EXCEPTION(EX_Overflow);
623 if ( control_word & CW_Overflow )
624 {
625 /* The overflow exception is masked. */
626 /* By definition, precision is lost.
627 The roundup bit (C1) is also set because we have
628 "rounded" upwards to Infinity. */
629 EXCEPTION(EX_Precision | SW_C1);
630 return tag;
631 }
632
633 return tag;
634 589
635} 590 EXCEPTION(EX_Overflow);
591 if (control_word & CW_Overflow) {
592 /* The overflow exception is masked. */
593 /* By definition, precision is lost.
594 The roundup bit (C1) is also set because we have
595 "rounded" upwards to Infinity. */
596 EXCEPTION(EX_Precision | SW_C1);
597 return tag;
598 }
599
600 return tag;
636 601
602}
637 603
638asmlinkage int arith_underflow(FPU_REG *dest) 604asmlinkage int arith_underflow(FPU_REG *dest)
639{ 605{
640 int tag = TAG_Valid; 606 int tag = TAG_Valid;
641 607
642 if ( control_word & CW_Underflow ) 608 if (control_word & CW_Underflow) {
643 { 609 /* The masked response */
644 /* The masked response */ 610 if (exponent16(dest) <= EXP_UNDER - 63) {
645 if ( exponent16(dest) <= EXP_UNDER - 63 ) 611 reg_copy(&CONST_Z, dest);
646 { 612 partial_status &= ~SW_C1; /* Round down. */
647 reg_copy(&CONST_Z, dest); 613 tag = TAG_Zero;
648 partial_status &= ~SW_C1; /* Round down. */ 614 } else {
649 tag = TAG_Zero; 615 stdexp(dest);
616 }
617 } else {
618 /* Add the magic number to the exponent. */
619 addexponent(dest, (3 * (1 << 13)) + EXTENDED_Ebias);
650 } 620 }
651 else 621
652 { 622 EXCEPTION(EX_Underflow);
653 stdexp(dest); 623 if (control_word & CW_Underflow) {
624 /* The underflow exception is masked. */
625 EXCEPTION(EX_Precision);
626 return tag;
654 } 627 }
655 }
656 else
657 {
658 /* Add the magic number to the exponent. */
659 addexponent(dest, (3 * (1 << 13)) + EXTENDED_Ebias);
660 }
661
662 EXCEPTION(EX_Underflow);
663 if ( control_word & CW_Underflow )
664 {
665 /* The underflow exception is masked. */
666 EXCEPTION(EX_Precision);
667 return tag;
668 }
669
670 return tag;
671 628
672} 629 return tag;
673 630
631}
674 632
675void FPU_stack_overflow(void) 633void FPU_stack_overflow(void)
676{ 634{
677 635
678 if ( control_word & CW_Invalid ) 636 if (control_word & CW_Invalid) {
679 { 637 /* The masked response */
680 /* The masked response */ 638 top--;
681 top--; 639 FPU_copy_to_reg0(&CONST_QNaN, TAG_Special);
682 FPU_copy_to_reg0(&CONST_QNaN, TAG_Special); 640 }
683 }
684 641
685 EXCEPTION(EX_StackOver); 642 EXCEPTION(EX_StackOver);
686 643
687 return; 644 return;
688 645
689} 646}
690 647
691
692void FPU_stack_underflow(void) 648void FPU_stack_underflow(void)
693{ 649{
694 650
695 if ( control_word & CW_Invalid ) 651 if (control_word & CW_Invalid) {
696 { 652 /* The masked response */
697 /* The masked response */ 653 FPU_copy_to_reg0(&CONST_QNaN, TAG_Special);
698 FPU_copy_to_reg0(&CONST_QNaN, TAG_Special); 654 }
699 }
700 655
701 EXCEPTION(EX_StackUnder); 656 EXCEPTION(EX_StackUnder);
702 657
703 return; 658 return;
704 659
705} 660}
706 661
707
708void FPU_stack_underflow_i(int i) 662void FPU_stack_underflow_i(int i)
709{ 663{
710 664
711 if ( control_word & CW_Invalid ) 665 if (control_word & CW_Invalid) {
712 { 666 /* The masked response */
713 /* The masked response */ 667 FPU_copy_to_regi(&CONST_QNaN, TAG_Special, i);
714 FPU_copy_to_regi(&CONST_QNaN, TAG_Special, i); 668 }
715 }
716 669
717 EXCEPTION(EX_StackUnder); 670 EXCEPTION(EX_StackUnder);
718 671
719 return; 672 return;
720 673
721} 674}
722 675
723
724void FPU_stack_underflow_pop(int i) 676void FPU_stack_underflow_pop(int i)
725{ 677{
726 678
727 if ( control_word & CW_Invalid ) 679 if (control_word & CW_Invalid) {
728 { 680 /* The masked response */
729 /* The masked response */ 681 FPU_copy_to_regi(&CONST_QNaN, TAG_Special, i);
730 FPU_copy_to_regi(&CONST_QNaN, TAG_Special, i); 682 FPU_pop();
731 FPU_pop(); 683 }
732 }
733 684
734 EXCEPTION(EX_StackUnder); 685 EXCEPTION(EX_StackUnder);
735 686
736 return; 687 return;
737 688
738} 689}
739
diff --git a/arch/x86/math-emu/exception.h b/arch/x86/math-emu/exception.h
index b463f21a811e..67f43a4683d5 100644
--- a/arch/x86/math-emu/exception.h
+++ b/arch/x86/math-emu/exception.h
@@ -9,7 +9,6 @@
9#ifndef _EXCEPTION_H_ 9#ifndef _EXCEPTION_H_
10#define _EXCEPTION_H_ 10#define _EXCEPTION_H_
11 11
12
13#ifdef __ASSEMBLY__ 12#ifdef __ASSEMBLY__
14#define Const_(x) $##x 13#define Const_(x) $##x
15#else 14#else
@@ -20,8 +19,8 @@
20#include "fpu_emu.h" 19#include "fpu_emu.h"
21#endif /* SW_C1 */ 20#endif /* SW_C1 */
22 21
23#define FPU_BUSY Const_(0x8000) /* FPU busy bit (8087 compatibility) */ 22#define FPU_BUSY Const_(0x8000) /* FPU busy bit (8087 compatibility) */
24#define EX_ErrorSummary Const_(0x0080) /* Error summary status */ 23#define EX_ErrorSummary Const_(0x0080) /* Error summary status */
25/* Special exceptions: */ 24/* Special exceptions: */
26#define EX_INTERNAL Const_(0x8000) /* Internal error in wm-FPU-emu */ 25#define EX_INTERNAL Const_(0x8000) /* Internal error in wm-FPU-emu */
27#define EX_StackOver Const_(0x0041|SW_C1) /* stack overflow */ 26#define EX_StackOver Const_(0x0041|SW_C1) /* stack overflow */
@@ -34,11 +33,9 @@
34#define EX_Denormal Const_(0x0002) /* denormalized operand */ 33#define EX_Denormal Const_(0x0002) /* denormalized operand */
35#define EX_Invalid Const_(0x0001) /* invalid operation */ 34#define EX_Invalid Const_(0x0001) /* invalid operation */
36 35
37
38#define PRECISION_LOST_UP Const_((EX_Precision | SW_C1)) 36#define PRECISION_LOST_UP Const_((EX_Precision | SW_C1))
39#define PRECISION_LOST_DOWN Const_(EX_Precision) 37#define PRECISION_LOST_DOWN Const_(EX_Precision)
40 38
41
42#ifndef __ASSEMBLY__ 39#ifndef __ASSEMBLY__
43 40
44#ifdef DEBUG 41#ifdef DEBUG
@@ -48,6 +45,6 @@
48#define EXCEPTION(x) FPU_exception(x) 45#define EXCEPTION(x) FPU_exception(x)
49#endif 46#endif
50 47
51#endif /* __ASSEMBLY__ */ 48#endif /* __ASSEMBLY__ */
52 49
53#endif /* _EXCEPTION_H_ */ 50#endif /* _EXCEPTION_H_ */
diff --git a/arch/x86/math-emu/fpu_arith.c b/arch/x86/math-emu/fpu_arith.c
index 6972dec01af6..aeab24e083c4 100644
--- a/arch/x86/math-emu/fpu_arith.c
+++ b/arch/x86/math-emu/fpu_arith.c
@@ -15,160 +15,138 @@
15#include "control_w.h" 15#include "control_w.h"
16#include "status_w.h" 16#include "status_w.h"
17 17
18
19void fadd__(void) 18void fadd__(void)
20{ 19{
21 /* fadd st,st(i) */ 20 /* fadd st,st(i) */
22 int i = FPU_rm; 21 int i = FPU_rm;
23 clear_C1(); 22 clear_C1();
24 FPU_add(&st(i), FPU_gettagi(i), 0, control_word); 23 FPU_add(&st(i), FPU_gettagi(i), 0, control_word);
25} 24}
26 25
27
28void fmul__(void) 26void fmul__(void)
29{ 27{
30 /* fmul st,st(i) */ 28 /* fmul st,st(i) */
31 int i = FPU_rm; 29 int i = FPU_rm;
32 clear_C1(); 30 clear_C1();
33 FPU_mul(&st(i), FPU_gettagi(i), 0, control_word); 31 FPU_mul(&st(i), FPU_gettagi(i), 0, control_word);
34} 32}
35 33
36
37
38void fsub__(void) 34void fsub__(void)
39{ 35{
40 /* fsub st,st(i) */ 36 /* fsub st,st(i) */
41 clear_C1(); 37 clear_C1();
42 FPU_sub(0, FPU_rm, control_word); 38 FPU_sub(0, FPU_rm, control_word);
43} 39}
44 40
45
46void fsubr_(void) 41void fsubr_(void)
47{ 42{
48 /* fsubr st,st(i) */ 43 /* fsubr st,st(i) */
49 clear_C1(); 44 clear_C1();
50 FPU_sub(REV, FPU_rm, control_word); 45 FPU_sub(REV, FPU_rm, control_word);
51} 46}
52 47
53
54void fdiv__(void) 48void fdiv__(void)
55{ 49{
56 /* fdiv st,st(i) */ 50 /* fdiv st,st(i) */
57 clear_C1(); 51 clear_C1();
58 FPU_div(0, FPU_rm, control_word); 52 FPU_div(0, FPU_rm, control_word);
59} 53}
60 54
61
62void fdivr_(void) 55void fdivr_(void)
63{ 56{
64 /* fdivr st,st(i) */ 57 /* fdivr st,st(i) */
65 clear_C1(); 58 clear_C1();
66 FPU_div(REV, FPU_rm, control_word); 59 FPU_div(REV, FPU_rm, control_word);
67} 60}
68 61
69
70
71void fadd_i(void) 62void fadd_i(void)
72{ 63{
73 /* fadd st(i),st */ 64 /* fadd st(i),st */
74 int i = FPU_rm; 65 int i = FPU_rm;
75 clear_C1(); 66 clear_C1();
76 FPU_add(&st(i), FPU_gettagi(i), i, control_word); 67 FPU_add(&st(i), FPU_gettagi(i), i, control_word);
77} 68}
78 69
79
80void fmul_i(void) 70void fmul_i(void)
81{ 71{
82 /* fmul st(i),st */ 72 /* fmul st(i),st */
83 clear_C1(); 73 clear_C1();
84 FPU_mul(&st(0), FPU_gettag0(), FPU_rm, control_word); 74 FPU_mul(&st(0), FPU_gettag0(), FPU_rm, control_word);
85} 75}
86 76
87
88void fsubri(void) 77void fsubri(void)
89{ 78{
90 /* fsubr st(i),st */ 79 /* fsubr st(i),st */
91 clear_C1(); 80 clear_C1();
92 FPU_sub(DEST_RM, FPU_rm, control_word); 81 FPU_sub(DEST_RM, FPU_rm, control_word);
93} 82}
94 83
95
96void fsub_i(void) 84void fsub_i(void)
97{ 85{
98 /* fsub st(i),st */ 86 /* fsub st(i),st */
99 clear_C1(); 87 clear_C1();
100 FPU_sub(REV|DEST_RM, FPU_rm, control_word); 88 FPU_sub(REV | DEST_RM, FPU_rm, control_word);
101} 89}
102 90
103
104void fdivri(void) 91void fdivri(void)
105{ 92{
106 /* fdivr st(i),st */ 93 /* fdivr st(i),st */
107 clear_C1(); 94 clear_C1();
108 FPU_div(DEST_RM, FPU_rm, control_word); 95 FPU_div(DEST_RM, FPU_rm, control_word);
109} 96}
110 97
111
112void fdiv_i(void) 98void fdiv_i(void)
113{ 99{
114 /* fdiv st(i),st */ 100 /* fdiv st(i),st */
115 clear_C1(); 101 clear_C1();
116 FPU_div(REV|DEST_RM, FPU_rm, control_word); 102 FPU_div(REV | DEST_RM, FPU_rm, control_word);
117} 103}
118 104
119
120
121void faddp_(void) 105void faddp_(void)
122{ 106{
123 /* faddp st(i),st */ 107 /* faddp st(i),st */
124 int i = FPU_rm; 108 int i = FPU_rm;
125 clear_C1(); 109 clear_C1();
126 if ( FPU_add(&st(i), FPU_gettagi(i), i, control_word) >= 0 ) 110 if (FPU_add(&st(i), FPU_gettagi(i), i, control_word) >= 0)
127 FPU_pop(); 111 FPU_pop();
128} 112}
129 113
130
131void fmulp_(void) 114void fmulp_(void)
132{ 115{
133 /* fmulp st(i),st */ 116 /* fmulp st(i),st */
134 clear_C1(); 117 clear_C1();
135 if ( FPU_mul(&st(0), FPU_gettag0(), FPU_rm, control_word) >= 0 ) 118 if (FPU_mul(&st(0), FPU_gettag0(), FPU_rm, control_word) >= 0)
136 FPU_pop(); 119 FPU_pop();
137} 120}
138 121
139
140
141void fsubrp(void) 122void fsubrp(void)
142{ 123{
143 /* fsubrp st(i),st */ 124 /* fsubrp st(i),st */
144 clear_C1(); 125 clear_C1();
145 if ( FPU_sub(DEST_RM, FPU_rm, control_word) >= 0 ) 126 if (FPU_sub(DEST_RM, FPU_rm, control_word) >= 0)
146 FPU_pop(); 127 FPU_pop();
147} 128}
148 129
149
150void fsubp_(void) 130void fsubp_(void)
151{ 131{
152 /* fsubp st(i),st */ 132 /* fsubp st(i),st */
153 clear_C1(); 133 clear_C1();
154 if ( FPU_sub(REV|DEST_RM, FPU_rm, control_word) >= 0 ) 134 if (FPU_sub(REV | DEST_RM, FPU_rm, control_word) >= 0)
155 FPU_pop(); 135 FPU_pop();
156} 136}
157 137
158
159void fdivrp(void) 138void fdivrp(void)
160{ 139{
161 /* fdivrp st(i),st */ 140 /* fdivrp st(i),st */
162 clear_C1(); 141 clear_C1();
163 if ( FPU_div(DEST_RM, FPU_rm, control_word) >= 0 ) 142 if (FPU_div(DEST_RM, FPU_rm, control_word) >= 0)
164 FPU_pop(); 143 FPU_pop();
165} 144}
166 145
167
168void fdivp_(void) 146void fdivp_(void)
169{ 147{
170 /* fdivp st(i),st */ 148 /* fdivp st(i),st */
171 clear_C1(); 149 clear_C1();
172 if ( FPU_div(REV|DEST_RM, FPU_rm, control_word) >= 0 ) 150 if (FPU_div(REV | DEST_RM, FPU_rm, control_word) >= 0)
173 FPU_pop(); 151 FPU_pop();
174} 152}
diff --git a/arch/x86/math-emu/fpu_asm.h b/arch/x86/math-emu/fpu_asm.h
index 9ba12416df12..955b932735a4 100644
--- a/arch/x86/math-emu/fpu_asm.h
+++ b/arch/x86/math-emu/fpu_asm.h
@@ -14,7 +14,6 @@
14 14
15#define EXCEPTION FPU_exception 15#define EXCEPTION FPU_exception
16 16
17
18#define PARAM1 8(%ebp) 17#define PARAM1 8(%ebp)
19#define PARAM2 12(%ebp) 18#define PARAM2 12(%ebp)
20#define PARAM3 16(%ebp) 19#define PARAM3 16(%ebp)
diff --git a/arch/x86/math-emu/fpu_aux.c b/arch/x86/math-emu/fpu_aux.c
index 20886cfb9f76..491e737ce547 100644
--- a/arch/x86/math-emu/fpu_aux.c
+++ b/arch/x86/math-emu/fpu_aux.c
@@ -16,34 +16,34 @@
16#include "status_w.h" 16#include "status_w.h"
17#include "control_w.h" 17#include "control_w.h"
18 18
19
20static void fnop(void) 19static void fnop(void)
21{ 20{
22} 21}
23 22
24static void fclex(void) 23static void fclex(void)
25{ 24{
26 partial_status &= ~(SW_Backward|SW_Summary|SW_Stack_Fault|SW_Precision| 25 partial_status &=
27 SW_Underflow|SW_Overflow|SW_Zero_Div|SW_Denorm_Op| 26 ~(SW_Backward | SW_Summary | SW_Stack_Fault | SW_Precision |
28 SW_Invalid); 27 SW_Underflow | SW_Overflow | SW_Zero_Div | SW_Denorm_Op |
29 no_ip_update = 1; 28 SW_Invalid);
29 no_ip_update = 1;
30} 30}
31 31
32/* Needs to be externally visible */ 32/* Needs to be externally visible */
33void finit(void) 33void finit(void)
34{ 34{
35 control_word = 0x037f; 35 control_word = 0x037f;
36 partial_status = 0; 36 partial_status = 0;
37 top = 0; /* We don't keep top in the status word internally. */ 37 top = 0; /* We don't keep top in the status word internally. */
38 fpu_tag_word = 0xffff; 38 fpu_tag_word = 0xffff;
39 /* The behaviour is different from that detailed in 39 /* The behaviour is different from that detailed in
40 Section 15.1.6 of the Intel manual */ 40 Section 15.1.6 of the Intel manual */
41 operand_address.offset = 0; 41 operand_address.offset = 0;
42 operand_address.selector = 0; 42 operand_address.selector = 0;
43 instruction_address.offset = 0; 43 instruction_address.offset = 0;
44 instruction_address.selector = 0; 44 instruction_address.selector = 0;
45 instruction_address.opcode = 0; 45 instruction_address.opcode = 0;
46 no_ip_update = 1; 46 no_ip_update = 1;
47} 47}
48 48
49/* 49/*
@@ -54,151 +54,134 @@ void finit(void)
54#define fsetpm fnop 54#define fsetpm fnop
55 55
56static FUNC const finit_table[] = { 56static FUNC const finit_table[] = {
57 feni, fdisi, fclex, finit, 57 feni, fdisi, fclex, finit,
58 fsetpm, FPU_illegal, FPU_illegal, FPU_illegal 58 fsetpm, FPU_illegal, FPU_illegal, FPU_illegal
59}; 59};
60 60
61void finit_(void) 61void finit_(void)
62{ 62{
63 (finit_table[FPU_rm])(); 63 (finit_table[FPU_rm]) ();
64} 64}
65 65
66
67static void fstsw_ax(void) 66static void fstsw_ax(void)
68{ 67{
69 *(short *) &FPU_EAX = status_word(); 68 *(short *)&FPU_EAX = status_word();
70 no_ip_update = 1; 69 no_ip_update = 1;
71} 70}
72 71
73static FUNC const fstsw_table[] = { 72static FUNC const fstsw_table[] = {
74 fstsw_ax, FPU_illegal, FPU_illegal, FPU_illegal, 73 fstsw_ax, FPU_illegal, FPU_illegal, FPU_illegal,
75 FPU_illegal, FPU_illegal, FPU_illegal, FPU_illegal 74 FPU_illegal, FPU_illegal, FPU_illegal, FPU_illegal
76}; 75};
77 76
78void fstsw_(void) 77void fstsw_(void)
79{ 78{
80 (fstsw_table[FPU_rm])(); 79 (fstsw_table[FPU_rm]) ();
81} 80}
82 81
83
84static FUNC const fp_nop_table[] = { 82static FUNC const fp_nop_table[] = {
85 fnop, FPU_illegal, FPU_illegal, FPU_illegal, 83 fnop, FPU_illegal, FPU_illegal, FPU_illegal,
86 FPU_illegal, FPU_illegal, FPU_illegal, FPU_illegal 84 FPU_illegal, FPU_illegal, FPU_illegal, FPU_illegal
87}; 85};
88 86
89void fp_nop(void) 87void fp_nop(void)
90{ 88{
91 (fp_nop_table[FPU_rm])(); 89 (fp_nop_table[FPU_rm]) ();
92} 90}
93 91
94
95void fld_i_(void) 92void fld_i_(void)
96{ 93{
97 FPU_REG *st_new_ptr; 94 FPU_REG *st_new_ptr;
98 int i; 95 int i;
99 u_char tag; 96 u_char tag;
100 97
101 if ( STACK_OVERFLOW ) 98 if (STACK_OVERFLOW) {
102 { FPU_stack_overflow(); return; } 99 FPU_stack_overflow();
103 100 return;
104 /* fld st(i) */
105 i = FPU_rm;
106 if ( NOT_EMPTY(i) )
107 {
108 reg_copy(&st(i), st_new_ptr);
109 tag = FPU_gettagi(i);
110 push();
111 FPU_settag0(tag);
112 }
113 else
114 {
115 if ( control_word & CW_Invalid )
116 {
117 /* The masked response */
118 FPU_stack_underflow();
119 } 101 }
120 else
121 EXCEPTION(EX_StackUnder);
122 }
123 102
124} 103 /* fld st(i) */
104 i = FPU_rm;
105 if (NOT_EMPTY(i)) {
106 reg_copy(&st(i), st_new_ptr);
107 tag = FPU_gettagi(i);
108 push();
109 FPU_settag0(tag);
110 } else {
111 if (control_word & CW_Invalid) {
112 /* The masked response */
113 FPU_stack_underflow();
114 } else
115 EXCEPTION(EX_StackUnder);
116 }
125 117
118}
126 119
127void fxch_i(void) 120void fxch_i(void)
128{ 121{
129 /* fxch st(i) */ 122 /* fxch st(i) */
130 FPU_REG t; 123 FPU_REG t;
131 int i = FPU_rm; 124 int i = FPU_rm;
132 FPU_REG *st0_ptr = &st(0), *sti_ptr = &st(i); 125 FPU_REG *st0_ptr = &st(0), *sti_ptr = &st(i);
133 long tag_word = fpu_tag_word; 126 long tag_word = fpu_tag_word;
134 int regnr = top & 7, regnri = ((regnr + i) & 7); 127 int regnr = top & 7, regnri = ((regnr + i) & 7);
135 u_char st0_tag = (tag_word >> (regnr*2)) & 3; 128 u_char st0_tag = (tag_word >> (regnr * 2)) & 3;
136 u_char sti_tag = (tag_word >> (regnri*2)) & 3; 129 u_char sti_tag = (tag_word >> (regnri * 2)) & 3;
137 130
138 if ( st0_tag == TAG_Empty ) 131 if (st0_tag == TAG_Empty) {
139 { 132 if (sti_tag == TAG_Empty) {
140 if ( sti_tag == TAG_Empty ) 133 FPU_stack_underflow();
141 { 134 FPU_stack_underflow_i(i);
142 FPU_stack_underflow(); 135 return;
143 FPU_stack_underflow_i(i); 136 }
144 return; 137 if (control_word & CW_Invalid) {
138 /* Masked response */
139 FPU_copy_to_reg0(sti_ptr, sti_tag);
140 }
141 FPU_stack_underflow_i(i);
142 return;
145 } 143 }
146 if ( control_word & CW_Invalid ) 144 if (sti_tag == TAG_Empty) {
147 { 145 if (control_word & CW_Invalid) {
148 /* Masked response */ 146 /* Masked response */
149 FPU_copy_to_reg0(sti_ptr, sti_tag); 147 FPU_copy_to_regi(st0_ptr, st0_tag, i);
148 }
149 FPU_stack_underflow();
150 return;
150 } 151 }
151 FPU_stack_underflow_i(i); 152 clear_C1();
152 return;
153 }
154 if ( sti_tag == TAG_Empty )
155 {
156 if ( control_word & CW_Invalid )
157 {
158 /* Masked response */
159 FPU_copy_to_regi(st0_ptr, st0_tag, i);
160 }
161 FPU_stack_underflow();
162 return;
163 }
164 clear_C1();
165
166 reg_copy(st0_ptr, &t);
167 reg_copy(sti_ptr, st0_ptr);
168 reg_copy(&t, sti_ptr);
169
170 tag_word &= ~(3 << (regnr*2)) & ~(3 << (regnri*2));
171 tag_word |= (sti_tag << (regnr*2)) | (st0_tag << (regnri*2));
172 fpu_tag_word = tag_word;
173}
174 153
154 reg_copy(st0_ptr, &t);
155 reg_copy(sti_ptr, st0_ptr);
156 reg_copy(&t, sti_ptr);
157
158 tag_word &= ~(3 << (regnr * 2)) & ~(3 << (regnri * 2));
159 tag_word |= (sti_tag << (regnr * 2)) | (st0_tag << (regnri * 2));
160 fpu_tag_word = tag_word;
161}
175 162
176void ffree_(void) 163void ffree_(void)
177{ 164{
178 /* ffree st(i) */ 165 /* ffree st(i) */
179 FPU_settagi(FPU_rm, TAG_Empty); 166 FPU_settagi(FPU_rm, TAG_Empty);
180} 167}
181 168
182
183void ffreep(void) 169void ffreep(void)
184{ 170{
185 /* ffree st(i) + pop - unofficial code */ 171 /* ffree st(i) + pop - unofficial code */
186 FPU_settagi(FPU_rm, TAG_Empty); 172 FPU_settagi(FPU_rm, TAG_Empty);
187 FPU_pop(); 173 FPU_pop();
188} 174}
189 175
190
191void fst_i_(void) 176void fst_i_(void)
192{ 177{
193 /* fst st(i) */ 178 /* fst st(i) */
194 FPU_copy_to_regi(&st(0), FPU_gettag0(), FPU_rm); 179 FPU_copy_to_regi(&st(0), FPU_gettag0(), FPU_rm);
195} 180}
196 181
197
198void fstp_i(void) 182void fstp_i(void)
199{ 183{
200 /* fstp st(i) */ 184 /* fstp st(i) */
201 FPU_copy_to_regi(&st(0), FPU_gettag0(), FPU_rm); 185 FPU_copy_to_regi(&st(0), FPU_gettag0(), FPU_rm);
202 FPU_pop(); 186 FPU_pop();
203} 187}
204
diff --git a/arch/x86/math-emu/fpu_emu.h b/arch/x86/math-emu/fpu_emu.h
index 65120f523853..4dae511c85ad 100644
--- a/arch/x86/math-emu/fpu_emu.h
+++ b/arch/x86/math-emu/fpu_emu.h
@@ -7,7 +7,6 @@
7 | | 7 | |
8 +---------------------------------------------------------------------------*/ 8 +---------------------------------------------------------------------------*/
9 9
10
11#ifndef _FPU_EMU_H_ 10#ifndef _FPU_EMU_H_
12#define _FPU_EMU_H_ 11#define _FPU_EMU_H_
13 12
@@ -28,15 +27,15 @@
28#endif 27#endif
29 28
30#define EXP_BIAS Const(0) 29#define EXP_BIAS Const(0)
31#define EXP_OVER Const(0x4000) /* smallest invalid large exponent */ 30#define EXP_OVER Const(0x4000) /* smallest invalid large exponent */
32#define EXP_UNDER Const(-0x3fff) /* largest invalid small exponent */ 31#define EXP_UNDER Const(-0x3fff) /* largest invalid small exponent */
33#define EXP_WAY_UNDER Const(-0x6000) /* Below the smallest denormal, but 32#define EXP_WAY_UNDER Const(-0x6000) /* Below the smallest denormal, but
34 still a 16 bit nr. */ 33 still a 16 bit nr. */
35#define EXP_Infinity EXP_OVER 34#define EXP_Infinity EXP_OVER
36#define EXP_NaN EXP_OVER 35#define EXP_NaN EXP_OVER
37 36
38#define EXTENDED_Ebias Const(0x3fff) 37#define EXTENDED_Ebias Const(0x3fff)
39#define EXTENDED_Emin (-0x3ffe) /* smallest valid exponent */ 38#define EXTENDED_Emin (-0x3ffe) /* smallest valid exponent */
40 39
41#define SIGN_POS Const(0) 40#define SIGN_POS Const(0)
42#define SIGN_NEG Const(0x80) 41#define SIGN_NEG Const(0x80)
@@ -44,10 +43,9 @@
44#define SIGN_Positive Const(0) 43#define SIGN_Positive Const(0)
45#define SIGN_Negative Const(0x8000) 44#define SIGN_Negative Const(0x8000)
46 45
47
48/* Keep the order TAG_Valid, TAG_Zero, TW_Denormal */ 46/* Keep the order TAG_Valid, TAG_Zero, TW_Denormal */
49/* The following fold to 2 (Special) in the Tag Word */ 47/* The following fold to 2 (Special) in the Tag Word */
50#define TW_Denormal Const(4) /* De-normal */ 48#define TW_Denormal Const(4) /* De-normal */
51#define TW_Infinity Const(5) /* + or - infinity */ 49#define TW_Infinity Const(5) /* + or - infinity */
52#define TW_NaN Const(6) /* Not a Number */ 50#define TW_NaN Const(6) /* Not a Number */
53#define TW_Unsupported Const(7) /* Not supported by an 80486 */ 51#define TW_Unsupported Const(7) /* Not supported by an 80486 */
@@ -67,14 +65,13 @@
67#define DEST_RM 0x20 65#define DEST_RM 0x20
68#define LOADED 0x40 66#define LOADED 0x40
69 67
70#define FPU_Exception Const(0x80000000) /* Added to tag returns. */ 68#define FPU_Exception Const(0x80000000) /* Added to tag returns. */
71
72 69
73#ifndef __ASSEMBLY__ 70#ifndef __ASSEMBLY__
74 71
75#include "fpu_system.h" 72#include "fpu_system.h"
76 73
77#include <asm/sigcontext.h> /* for struct _fpstate */ 74#include <asm/sigcontext.h> /* for struct _fpstate */
78#include <asm/math_emu.h> 75#include <asm/math_emu.h>
79#include <linux/linkage.h> 76#include <linux/linkage.h>
80 77
@@ -112,30 +109,33 @@ extern u_char emulating;
112#define PREFIX_DEFAULT 7 109#define PREFIX_DEFAULT 7
113 110
114struct address { 111struct address {
115 unsigned int offset; 112 unsigned int offset;
116 unsigned int selector:16; 113 unsigned int selector:16;
117 unsigned int opcode:11; 114 unsigned int opcode:11;
118 unsigned int empty:5; 115 unsigned int empty:5;
119}; 116};
120struct fpu__reg { 117struct fpu__reg {
121 unsigned sigl; 118 unsigned sigl;
122 unsigned sigh; 119 unsigned sigh;
123 short exp; 120 short exp;
124}; 121};
125 122
126typedef void (*FUNC)(void); 123typedef void (*FUNC) (void);
127typedef struct fpu__reg FPU_REG; 124typedef struct fpu__reg FPU_REG;
128typedef void (*FUNC_ST0)(FPU_REG *st0_ptr, u_char st0_tag); 125typedef void (*FUNC_ST0) (FPU_REG *st0_ptr, u_char st0_tag);
129typedef struct { u_char address_size, operand_size, segment; } 126typedef struct {
130 overrides; 127 u_char address_size, operand_size, segment;
128} overrides;
131/* This structure is 32 bits: */ 129/* This structure is 32 bits: */
132typedef struct { overrides override; 130typedef struct {
133 u_char default_mode; } fpu_addr_modes; 131 overrides override;
132 u_char default_mode;
133} fpu_addr_modes;
134/* PROTECTED has a restricted meaning in the emulator; it is used 134/* PROTECTED has a restricted meaning in the emulator; it is used
135 to signal that the emulator needs to do special things to ensure 135 to signal that the emulator needs to do special things to ensure
136 that protection is respected in a segmented model. */ 136 that protection is respected in a segmented model. */
137#define PROTECTED 4 137#define PROTECTED 4
138#define SIXTEEN 1 /* We rely upon this being 1 (true) */ 138#define SIXTEEN 1 /* We rely upon this being 1 (true) */
139#define VM86 SIXTEEN 139#define VM86 SIXTEEN
140#define PM16 (SIXTEEN | PROTECTED) 140#define PM16 (SIXTEEN | PROTECTED)
141#define SEG32 PROTECTED 141#define SEG32 PROTECTED
@@ -168,8 +168,8 @@ extern u_char const data_sizes_16[32];
168 168
169static inline void reg_copy(FPU_REG const *x, FPU_REG *y) 169static inline void reg_copy(FPU_REG const *x, FPU_REG *y)
170{ 170{
171 *(short *)&(y->exp) = *(const short *)&(x->exp); 171 *(short *)&(y->exp) = *(const short *)&(x->exp);
172 *(long long *)&(y->sigl) = *(const long long *)&(x->sigl); 172 *(long long *)&(y->sigl) = *(const long long *)&(x->sigl);
173} 173}
174 174
175#define exponent(x) (((*(short *)&((x)->exp)) & 0x7fff) - EXTENDED_Ebias) 175#define exponent(x) (((*(short *)&((x)->exp)) & 0x7fff) - EXTENDED_Ebias)
@@ -184,27 +184,26 @@ static inline void reg_copy(FPU_REG const *x, FPU_REG *y)
184 184
185#define significand(x) ( ((unsigned long long *)&((x)->sigl))[0] ) 185#define significand(x) ( ((unsigned long long *)&((x)->sigl))[0] )
186 186
187
188/*----- Prototypes for functions written in assembler -----*/ 187/*----- Prototypes for functions written in assembler -----*/
189/* extern void reg_move(FPU_REG *a, FPU_REG *b); */ 188/* extern void reg_move(FPU_REG *a, FPU_REG *b); */
190 189
191asmlinkage int FPU_normalize(FPU_REG *x); 190asmlinkage int FPU_normalize(FPU_REG *x);
192asmlinkage int FPU_normalize_nuo(FPU_REG *x); 191asmlinkage int FPU_normalize_nuo(FPU_REG *x);
193asmlinkage int FPU_u_sub(FPU_REG const *arg1, FPU_REG const *arg2, 192asmlinkage int FPU_u_sub(FPU_REG const *arg1, FPU_REG const *arg2,
194 FPU_REG *answ, unsigned int control_w, u_char sign, 193 FPU_REG * answ, unsigned int control_w, u_char sign,
195 int expa, int expb); 194 int expa, int expb);
196asmlinkage int FPU_u_mul(FPU_REG const *arg1, FPU_REG const *arg2, 195asmlinkage int FPU_u_mul(FPU_REG const *arg1, FPU_REG const *arg2,
197 FPU_REG *answ, unsigned int control_w, u_char sign, 196 FPU_REG * answ, unsigned int control_w, u_char sign,
198 int expon); 197 int expon);
199asmlinkage int FPU_u_div(FPU_REG const *arg1, FPU_REG const *arg2, 198asmlinkage int FPU_u_div(FPU_REG const *arg1, FPU_REG const *arg2,
200 FPU_REG *answ, unsigned int control_w, u_char sign); 199 FPU_REG * answ, unsigned int control_w, u_char sign);
201asmlinkage int FPU_u_add(FPU_REG const *arg1, FPU_REG const *arg2, 200asmlinkage int FPU_u_add(FPU_REG const *arg1, FPU_REG const *arg2,
202 FPU_REG *answ, unsigned int control_w, u_char sign, 201 FPU_REG * answ, unsigned int control_w, u_char sign,
203 int expa, int expb); 202 int expa, int expb);
204asmlinkage int wm_sqrt(FPU_REG *n, int dummy1, int dummy2, 203asmlinkage int wm_sqrt(FPU_REG *n, int dummy1, int dummy2,
205 unsigned int control_w, u_char sign); 204 unsigned int control_w, u_char sign);
206asmlinkage unsigned FPU_shrx(void *l, unsigned x); 205asmlinkage unsigned FPU_shrx(void *l, unsigned x);
207asmlinkage unsigned FPU_shrxs(void *v, unsigned x); 206asmlinkage unsigned FPU_shrxs(void *v, unsigned x);
208asmlinkage unsigned long FPU_div_small(unsigned long long *x, unsigned long y); 207asmlinkage unsigned long FPU_div_small(unsigned long long *x, unsigned long y);
209asmlinkage int FPU_round(FPU_REG *arg, unsigned int extent, int dummy, 208asmlinkage int FPU_round(FPU_REG *arg, unsigned int extent, int dummy,
210 unsigned int control_w, u_char sign); 209 unsigned int control_w, u_char sign);
diff --git a/arch/x86/math-emu/fpu_entry.c b/arch/x86/math-emu/fpu_entry.c
index 1853524c8b57..760baeea5f07 100644
--- a/arch/x86/math-emu/fpu_entry.c
+++ b/arch/x86/math-emu/fpu_entry.c
@@ -25,10 +25,11 @@
25 +---------------------------------------------------------------------------*/ 25 +---------------------------------------------------------------------------*/
26 26
27#include <linux/signal.h> 27#include <linux/signal.h>
28#include <linux/ptrace.h> 28#include <linux/regset.h>
29 29
30#include <asm/uaccess.h> 30#include <asm/uaccess.h>
31#include <asm/desc.h> 31#include <asm/desc.h>
32#include <asm/user.h>
32 33
33#include "fpu_system.h" 34#include "fpu_system.h"
34#include "fpu_emu.h" 35#include "fpu_emu.h"
@@ -36,726 +37,727 @@
36#include "control_w.h" 37#include "control_w.h"
37#include "status_w.h" 38#include "status_w.h"
38 39
39#define __BAD__ FPU_illegal /* Illegal on an 80486, causes SIGILL */ 40#define __BAD__ FPU_illegal /* Illegal on an 80486, causes SIGILL */
40 41
41#ifndef NO_UNDOC_CODE /* Un-documented FPU op-codes supported by default. */ 42#ifndef NO_UNDOC_CODE /* Un-documented FPU op-codes supported by default. */
42 43
43/* WARNING: These codes are not documented by Intel in their 80486 manual 44/* WARNING: These codes are not documented by Intel in their 80486 manual
44 and may not work on FPU clones or later Intel FPUs. */ 45 and may not work on FPU clones or later Intel FPUs. */
45 46
46/* Changes to support the un-doc codes provided by Linus Torvalds. */ 47/* Changes to support the un-doc codes provided by Linus Torvalds. */
47 48
48#define _d9_d8_ fstp_i /* unofficial code (19) */ 49#define _d9_d8_ fstp_i /* unofficial code (19) */
49#define _dc_d0_ fcom_st /* unofficial code (14) */ 50#define _dc_d0_ fcom_st /* unofficial code (14) */
50#define _dc_d8_ fcompst /* unofficial code (1c) */ 51#define _dc_d8_ fcompst /* unofficial code (1c) */
51#define _dd_c8_ fxch_i /* unofficial code (0d) */ 52#define _dd_c8_ fxch_i /* unofficial code (0d) */
52#define _de_d0_ fcompst /* unofficial code (16) */ 53#define _de_d0_ fcompst /* unofficial code (16) */
53#define _df_c0_ ffreep /* unofficial code (07) ffree + pop */ 54#define _df_c0_ ffreep /* unofficial code (07) ffree + pop */
54#define _df_c8_ fxch_i /* unofficial code (0f) */ 55#define _df_c8_ fxch_i /* unofficial code (0f) */
55#define _df_d0_ fstp_i /* unofficial code (17) */ 56#define _df_d0_ fstp_i /* unofficial code (17) */
56#define _df_d8_ fstp_i /* unofficial code (1f) */ 57#define _df_d8_ fstp_i /* unofficial code (1f) */
57 58
58static FUNC const st_instr_table[64] = { 59static FUNC const st_instr_table[64] = {
59 fadd__, fld_i_, __BAD__, __BAD__, fadd_i, ffree_, faddp_, _df_c0_, 60 fadd__, fld_i_, __BAD__, __BAD__, fadd_i, ffree_, faddp_, _df_c0_,
60 fmul__, fxch_i, __BAD__, __BAD__, fmul_i, _dd_c8_, fmulp_, _df_c8_, 61 fmul__, fxch_i, __BAD__, __BAD__, fmul_i, _dd_c8_, fmulp_, _df_c8_,
61 fcom_st, fp_nop, __BAD__, __BAD__, _dc_d0_, fst_i_, _de_d0_, _df_d0_, 62 fcom_st, fp_nop, __BAD__, __BAD__, _dc_d0_, fst_i_, _de_d0_, _df_d0_,
62 fcompst, _d9_d8_, __BAD__, __BAD__, _dc_d8_, fstp_i, fcompp, _df_d8_, 63 fcompst, _d9_d8_, __BAD__, __BAD__, _dc_d8_, fstp_i, fcompp, _df_d8_,
63 fsub__, FPU_etc, __BAD__, finit_, fsubri, fucom_, fsubrp, fstsw_, 64 fsub__, FPU_etc, __BAD__, finit_, fsubri, fucom_, fsubrp, fstsw_,
64 fsubr_, fconst, fucompp, __BAD__, fsub_i, fucomp, fsubp_, __BAD__, 65 fsubr_, fconst, fucompp, __BAD__, fsub_i, fucomp, fsubp_, __BAD__,
65 fdiv__, FPU_triga, __BAD__, __BAD__, fdivri, __BAD__, fdivrp, __BAD__, 66 fdiv__, FPU_triga, __BAD__, __BAD__, fdivri, __BAD__, fdivrp, __BAD__,
66 fdivr_, FPU_trigb, __BAD__, __BAD__, fdiv_i, __BAD__, fdivp_, __BAD__, 67 fdivr_, FPU_trigb, __BAD__, __BAD__, fdiv_i, __BAD__, fdivp_, __BAD__,
67}; 68};
68 69
69#else /* Support only documented FPU op-codes */ 70#else /* Support only documented FPU op-codes */
70 71
71static FUNC const st_instr_table[64] = { 72static FUNC const st_instr_table[64] = {
72 fadd__, fld_i_, __BAD__, __BAD__, fadd_i, ffree_, faddp_, __BAD__, 73 fadd__, fld_i_, __BAD__, __BAD__, fadd_i, ffree_, faddp_, __BAD__,
73 fmul__, fxch_i, __BAD__, __BAD__, fmul_i, __BAD__, fmulp_, __BAD__, 74 fmul__, fxch_i, __BAD__, __BAD__, fmul_i, __BAD__, fmulp_, __BAD__,
74 fcom_st, fp_nop, __BAD__, __BAD__, __BAD__, fst_i_, __BAD__, __BAD__, 75 fcom_st, fp_nop, __BAD__, __BAD__, __BAD__, fst_i_, __BAD__, __BAD__,
75 fcompst, __BAD__, __BAD__, __BAD__, __BAD__, fstp_i, fcompp, __BAD__, 76 fcompst, __BAD__, __BAD__, __BAD__, __BAD__, fstp_i, fcompp, __BAD__,
76 fsub__, FPU_etc, __BAD__, finit_, fsubri, fucom_, fsubrp, fstsw_, 77 fsub__, FPU_etc, __BAD__, finit_, fsubri, fucom_, fsubrp, fstsw_,
77 fsubr_, fconst, fucompp, __BAD__, fsub_i, fucomp, fsubp_, __BAD__, 78 fsubr_, fconst, fucompp, __BAD__, fsub_i, fucomp, fsubp_, __BAD__,
78 fdiv__, FPU_triga, __BAD__, __BAD__, fdivri, __BAD__, fdivrp, __BAD__, 79 fdiv__, FPU_triga, __BAD__, __BAD__, fdivri, __BAD__, fdivrp, __BAD__,
79 fdivr_, FPU_trigb, __BAD__, __BAD__, fdiv_i, __BAD__, fdivp_, __BAD__, 80 fdivr_, FPU_trigb, __BAD__, __BAD__, fdiv_i, __BAD__, fdivp_, __BAD__,
80}; 81};
81 82
82#endif /* NO_UNDOC_CODE */ 83#endif /* NO_UNDOC_CODE */
83 84
84 85#define _NONE_ 0 /* Take no special action */
85#define _NONE_ 0 /* Take no special action */ 86#define _REG0_ 1 /* Need to check for not empty st(0) */
86#define _REG0_ 1 /* Need to check for not empty st(0) */ 87#define _REGI_ 2 /* Need to check for not empty st(0) and st(rm) */
87#define _REGI_ 2 /* Need to check for not empty st(0) and st(rm) */ 88#define _REGi_ 0 /* Uses st(rm) */
88#define _REGi_ 0 /* Uses st(rm) */ 89#define _PUSH_ 3 /* Need to check for space to push onto stack */
89#define _PUSH_ 3 /* Need to check for space to push onto stack */ 90#define _null_ 4 /* Function illegal or not implemented */
90#define _null_ 4 /* Function illegal or not implemented */ 91#define _REGIi 5 /* Uses st(0) and st(rm), result to st(rm) */
91#define _REGIi 5 /* Uses st(0) and st(rm), result to st(rm) */ 92#define _REGIp 6 /* Uses st(0) and st(rm), result to st(rm) then pop */
92#define _REGIp 6 /* Uses st(0) and st(rm), result to st(rm) then pop */ 93#define _REGIc 0 /* Compare st(0) and st(rm) */
93#define _REGIc 0 /* Compare st(0) and st(rm) */ 94#define _REGIn 0 /* Uses st(0) and st(rm), but handle checks later */
94#define _REGIn 0 /* Uses st(0) and st(rm), but handle checks later */
95 95
96#ifndef NO_UNDOC_CODE 96#ifndef NO_UNDOC_CODE
97 97
98/* Un-documented FPU op-codes supported by default. (see above) */ 98/* Un-documented FPU op-codes supported by default. (see above) */
99 99
100static u_char const type_table[64] = { 100static u_char const type_table[64] = {
101 _REGI_, _NONE_, _null_, _null_, _REGIi, _REGi_, _REGIp, _REGi_, 101 _REGI_, _NONE_, _null_, _null_, _REGIi, _REGi_, _REGIp, _REGi_,
102 _REGI_, _REGIn, _null_, _null_, _REGIi, _REGI_, _REGIp, _REGI_, 102 _REGI_, _REGIn, _null_, _null_, _REGIi, _REGI_, _REGIp, _REGI_,
103 _REGIc, _NONE_, _null_, _null_, _REGIc, _REG0_, _REGIc, _REG0_, 103 _REGIc, _NONE_, _null_, _null_, _REGIc, _REG0_, _REGIc, _REG0_,
104 _REGIc, _REG0_, _null_, _null_, _REGIc, _REG0_, _REGIc, _REG0_, 104 _REGIc, _REG0_, _null_, _null_, _REGIc, _REG0_, _REGIc, _REG0_,
105 _REGI_, _NONE_, _null_, _NONE_, _REGIi, _REGIc, _REGIp, _NONE_, 105 _REGI_, _NONE_, _null_, _NONE_, _REGIi, _REGIc, _REGIp, _NONE_,
106 _REGI_, _NONE_, _REGIc, _null_, _REGIi, _REGIc, _REGIp, _null_, 106 _REGI_, _NONE_, _REGIc, _null_, _REGIi, _REGIc, _REGIp, _null_,
107 _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_, 107 _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_,
108 _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_ 108 _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_
109}; 109};
110 110
111#else /* Support only documented FPU op-codes */ 111#else /* Support only documented FPU op-codes */
112 112
113static u_char const type_table[64] = { 113static u_char const type_table[64] = {
114 _REGI_, _NONE_, _null_, _null_, _REGIi, _REGi_, _REGIp, _null_, 114 _REGI_, _NONE_, _null_, _null_, _REGIi, _REGi_, _REGIp, _null_,
115 _REGI_, _REGIn, _null_, _null_, _REGIi, _null_, _REGIp, _null_, 115 _REGI_, _REGIn, _null_, _null_, _REGIi, _null_, _REGIp, _null_,
116 _REGIc, _NONE_, _null_, _null_, _null_, _REG0_, _null_, _null_, 116 _REGIc, _NONE_, _null_, _null_, _null_, _REG0_, _null_, _null_,
117 _REGIc, _null_, _null_, _null_, _null_, _REG0_, _REGIc, _null_, 117 _REGIc, _null_, _null_, _null_, _null_, _REG0_, _REGIc, _null_,
118 _REGI_, _NONE_, _null_, _NONE_, _REGIi, _REGIc, _REGIp, _NONE_, 118 _REGI_, _NONE_, _null_, _NONE_, _REGIi, _REGIc, _REGIp, _NONE_,
119 _REGI_, _NONE_, _REGIc, _null_, _REGIi, _REGIc, _REGIp, _null_, 119 _REGI_, _NONE_, _REGIc, _null_, _REGIi, _REGIc, _REGIp, _null_,
120 _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_, 120 _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_,
121 _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_ 121 _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_
122}; 122};
123 123
124#endif /* NO_UNDOC_CODE */ 124#endif /* NO_UNDOC_CODE */
125 125
126
127#ifdef RE_ENTRANT_CHECKING 126#ifdef RE_ENTRANT_CHECKING
128u_char emulating=0; 127u_char emulating = 0;
129#endif /* RE_ENTRANT_CHECKING */ 128#endif /* RE_ENTRANT_CHECKING */
130 129
131static int valid_prefix(u_char *Byte, u_char __user **fpu_eip, 130static int valid_prefix(u_char *Byte, u_char __user ** fpu_eip,
132 overrides *override); 131 overrides * override);
133 132
134asmlinkage void math_emulate(long arg) 133asmlinkage void math_emulate(long arg)
135{ 134{
136 u_char FPU_modrm, byte1; 135 u_char FPU_modrm, byte1;
137 unsigned short code; 136 unsigned short code;
138 fpu_addr_modes addr_modes; 137 fpu_addr_modes addr_modes;
139 int unmasked; 138 int unmasked;
140 FPU_REG loaded_data; 139 FPU_REG loaded_data;
141 FPU_REG *st0_ptr; 140 FPU_REG *st0_ptr;
142 u_char loaded_tag, st0_tag; 141 u_char loaded_tag, st0_tag;
143 void __user *data_address; 142 void __user *data_address;
144 struct address data_sel_off; 143 struct address data_sel_off;
145 struct address entry_sel_off; 144 struct address entry_sel_off;
146 unsigned long code_base = 0; 145 unsigned long code_base = 0;
147 unsigned long code_limit = 0; /* Initialized to stop compiler warnings */ 146 unsigned long code_limit = 0; /* Initialized to stop compiler warnings */
148 struct desc_struct code_descriptor; 147 struct desc_struct code_descriptor;
149 148
150#ifdef RE_ENTRANT_CHECKING 149#ifdef RE_ENTRANT_CHECKING
151 if ( emulating ) 150 if (emulating) {
152 { 151 printk("ERROR: wm-FPU-emu is not RE-ENTRANT!\n");
153 printk("ERROR: wm-FPU-emu is not RE-ENTRANT!\n"); 152 }
154 } 153 RE_ENTRANT_CHECK_ON;
155 RE_ENTRANT_CHECK_ON;
156#endif /* RE_ENTRANT_CHECKING */ 154#endif /* RE_ENTRANT_CHECKING */
157 155
158 if (!used_math()) 156 if (!used_math()) {
159 { 157 finit();
160 finit(); 158 set_used_math();
161 set_used_math();
162 }
163
164 SETUP_DATA_AREA(arg);
165
166 FPU_ORIG_EIP = FPU_EIP;
167
168 if ( (FPU_EFLAGS & 0x00020000) != 0 )
169 {
170 /* Virtual 8086 mode */
171 addr_modes.default_mode = VM86;
172 FPU_EIP += code_base = FPU_CS << 4;
173 code_limit = code_base + 0xffff; /* Assumes code_base <= 0xffff0000 */
174 }
175 else if ( FPU_CS == __USER_CS && FPU_DS == __USER_DS )
176 {
177 addr_modes.default_mode = 0;
178 }
179 else if ( FPU_CS == __KERNEL_CS )
180 {
181 printk("math_emulate: %04x:%08lx\n",FPU_CS,FPU_EIP);
182 panic("Math emulation needed in kernel");
183 }
184 else
185 {
186
187 if ( (FPU_CS & 4) != 4 ) /* Must be in the LDT */
188 {
189 /* Can only handle segmented addressing via the LDT
190 for now, and it must be 16 bit */
191 printk("FPU emulator: Unsupported addressing mode\n");
192 math_abort(FPU_info, SIGILL);
193 } 159 }
194 160
195 code_descriptor = LDT_DESCRIPTOR(FPU_CS); 161 SETUP_DATA_AREA(arg);
196 if ( SEG_D_SIZE(code_descriptor) ) 162
197 { 163 FPU_ORIG_EIP = FPU_EIP;
198 /* The above test may be wrong, the book is not clear */ 164
199 /* Segmented 32 bit protected mode */ 165 if ((FPU_EFLAGS & 0x00020000) != 0) {
200 addr_modes.default_mode = SEG32; 166 /* Virtual 8086 mode */
167 addr_modes.default_mode = VM86;
168 FPU_EIP += code_base = FPU_CS << 4;
169 code_limit = code_base + 0xffff; /* Assumes code_base <= 0xffff0000 */
170 } else if (FPU_CS == __USER_CS && FPU_DS == __USER_DS) {
171 addr_modes.default_mode = 0;
172 } else if (FPU_CS == __KERNEL_CS) {
173 printk("math_emulate: %04x:%08lx\n", FPU_CS, FPU_EIP);
174 panic("Math emulation needed in kernel");
175 } else {
176
177 if ((FPU_CS & 4) != 4) { /* Must be in the LDT */
178 /* Can only handle segmented addressing via the LDT
179 for now, and it must be 16 bit */
180 printk("FPU emulator: Unsupported addressing mode\n");
181 math_abort(FPU_info, SIGILL);
182 }
183
184 code_descriptor = LDT_DESCRIPTOR(FPU_CS);
185 if (SEG_D_SIZE(code_descriptor)) {
186 /* The above test may be wrong, the book is not clear */
187 /* Segmented 32 bit protected mode */
188 addr_modes.default_mode = SEG32;
189 } else {
190 /* 16 bit protected mode */
191 addr_modes.default_mode = PM16;
192 }
193 FPU_EIP += code_base = SEG_BASE_ADDR(code_descriptor);
194 code_limit = code_base
195 + (SEG_LIMIT(code_descriptor) +
196 1) * SEG_GRANULARITY(code_descriptor)
197 - 1;
198 if (code_limit < code_base)
199 code_limit = 0xffffffff;
201 } 200 }
202 else 201
203 { 202 FPU_lookahead = !(FPU_EFLAGS & X86_EFLAGS_TF);
204 /* 16 bit protected mode */ 203
205 addr_modes.default_mode = PM16; 204 if (!valid_prefix(&byte1, (u_char __user **) & FPU_EIP,
205 &addr_modes.override)) {
206 RE_ENTRANT_CHECK_OFF;
207 printk
208 ("FPU emulator: Unknown prefix byte 0x%02x, probably due to\n"
209 "FPU emulator: self-modifying code! (emulation impossible)\n",
210 byte1);
211 RE_ENTRANT_CHECK_ON;
212 EXCEPTION(EX_INTERNAL | 0x126);
213 math_abort(FPU_info, SIGILL);
206 } 214 }
207 FPU_EIP += code_base = SEG_BASE_ADDR(code_descriptor); 215
208 code_limit = code_base 216 do_another_FPU_instruction:
209 + (SEG_LIMIT(code_descriptor)+1) * SEG_GRANULARITY(code_descriptor) 217
210 - 1; 218 no_ip_update = 0;
211 if ( code_limit < code_base ) code_limit = 0xffffffff; 219
212 } 220 FPU_EIP++; /* We have fetched the prefix and first code bytes. */
213 221
214 FPU_lookahead = 1; 222 if (addr_modes.default_mode) {
215 if (current->ptrace & PT_PTRACED) 223 /* This checks for the minimum instruction bytes.
216 FPU_lookahead = 0; 224 We also need to check any extra (address mode) code access. */
217 225 if (FPU_EIP > code_limit)
218 if ( !valid_prefix(&byte1, (u_char __user **)&FPU_EIP, 226 math_abort(FPU_info, SIGSEGV);
219 &addr_modes.override) )
220 {
221 RE_ENTRANT_CHECK_OFF;
222 printk("FPU emulator: Unknown prefix byte 0x%02x, probably due to\n"
223 "FPU emulator: self-modifying code! (emulation impossible)\n",
224 byte1);
225 RE_ENTRANT_CHECK_ON;
226 EXCEPTION(EX_INTERNAL|0x126);
227 math_abort(FPU_info,SIGILL);
228 }
229
230do_another_FPU_instruction:
231
232 no_ip_update = 0;
233
234 FPU_EIP++; /* We have fetched the prefix and first code bytes. */
235
236 if ( addr_modes.default_mode )
237 {
238 /* This checks for the minimum instruction bytes.
239 We also need to check any extra (address mode) code access. */
240 if ( FPU_EIP > code_limit )
241 math_abort(FPU_info,SIGSEGV);
242 }
243
244 if ( (byte1 & 0xf8) != 0xd8 )
245 {
246 if ( byte1 == FWAIT_OPCODE )
247 {
248 if (partial_status & SW_Summary)
249 goto do_the_FPU_interrupt;
250 else
251 goto FPU_fwait_done;
252 } 227 }
228
229 if ((byte1 & 0xf8) != 0xd8) {
230 if (byte1 == FWAIT_OPCODE) {
231 if (partial_status & SW_Summary)
232 goto do_the_FPU_interrupt;
233 else
234 goto FPU_fwait_done;
235 }
253#ifdef PARANOID 236#ifdef PARANOID
254 EXCEPTION(EX_INTERNAL|0x128); 237 EXCEPTION(EX_INTERNAL | 0x128);
255 math_abort(FPU_info,SIGILL); 238 math_abort(FPU_info, SIGILL);
256#endif /* PARANOID */ 239#endif /* PARANOID */
257 }
258
259 RE_ENTRANT_CHECK_OFF;
260 FPU_code_access_ok(1);
261 FPU_get_user(FPU_modrm, (u_char __user *) FPU_EIP);
262 RE_ENTRANT_CHECK_ON;
263 FPU_EIP++;
264
265 if (partial_status & SW_Summary)
266 {
267 /* Ignore the error for now if the current instruction is a no-wait
268 control instruction */
269 /* The 80486 manual contradicts itself on this topic,
270 but a real 80486 uses the following instructions:
271 fninit, fnstenv, fnsave, fnstsw, fnstenv, fnclex.
272 */
273 code = (FPU_modrm << 8) | byte1;
274 if ( ! ( (((code & 0xf803) == 0xe003) || /* fnclex, fninit, fnstsw */
275 (((code & 0x3003) == 0x3001) && /* fnsave, fnstcw, fnstenv,
276 fnstsw */
277 ((code & 0xc000) != 0xc000))) ) )
278 {
279 /*
280 * We need to simulate the action of the kernel to FPU
281 * interrupts here.
282 */
283 do_the_FPU_interrupt:
284
285 FPU_EIP = FPU_ORIG_EIP; /* Point to current FPU instruction. */
286
287 RE_ENTRANT_CHECK_OFF;
288 current->thread.trap_no = 16;
289 current->thread.error_code = 0;
290 send_sig(SIGFPE, current, 1);
291 return;
292 }
293 }
294
295 entry_sel_off.offset = FPU_ORIG_EIP;
296 entry_sel_off.selector = FPU_CS;
297 entry_sel_off.opcode = (byte1 << 8) | FPU_modrm;
298
299 FPU_rm = FPU_modrm & 7;
300
301 if ( FPU_modrm < 0300 )
302 {
303 /* All of these instructions use the mod/rm byte to get a data address */
304
305 if ( (addr_modes.default_mode & SIXTEEN)
306 ^ (addr_modes.override.address_size == ADDR_SIZE_PREFIX) )
307 data_address = FPU_get_address_16(FPU_modrm, &FPU_EIP, &data_sel_off,
308 addr_modes);
309 else
310 data_address = FPU_get_address(FPU_modrm, &FPU_EIP, &data_sel_off,
311 addr_modes);
312
313 if ( addr_modes.default_mode )
314 {
315 if ( FPU_EIP-1 > code_limit )
316 math_abort(FPU_info,SIGSEGV);
317 } 240 }
318 241
319 if ( !(byte1 & 1) ) 242 RE_ENTRANT_CHECK_OFF;
320 { 243 FPU_code_access_ok(1);
321 unsigned short status1 = partial_status; 244 FPU_get_user(FPU_modrm, (u_char __user *) FPU_EIP);
322 245 RE_ENTRANT_CHECK_ON;
323 st0_ptr = &st(0); 246 FPU_EIP++;
324 st0_tag = FPU_gettag0(); 247
325 248 if (partial_status & SW_Summary) {
326 /* Stack underflow has priority */ 249 /* Ignore the error for now if the current instruction is a no-wait
327 if ( NOT_EMPTY_ST0 ) 250 control instruction */
328 { 251 /* The 80486 manual contradicts itself on this topic,
329 if ( addr_modes.default_mode & PROTECTED ) 252 but a real 80486 uses the following instructions:
330 { 253 fninit, fnstenv, fnsave, fnstsw, fnstenv, fnclex.
331 /* This table works for 16 and 32 bit protected mode */ 254 */
332 if ( access_limit < data_sizes_16[(byte1 >> 1) & 3] ) 255 code = (FPU_modrm << 8) | byte1;
333 math_abort(FPU_info,SIGSEGV); 256 if (!((((code & 0xf803) == 0xe003) || /* fnclex, fninit, fnstsw */
257 (((code & 0x3003) == 0x3001) && /* fnsave, fnstcw, fnstenv,
258 fnstsw */
259 ((code & 0xc000) != 0xc000))))) {
260 /*
261 * We need to simulate the action of the kernel to FPU
262 * interrupts here.
263 */
264 do_the_FPU_interrupt:
265
266 FPU_EIP = FPU_ORIG_EIP; /* Point to current FPU instruction. */
267
268 RE_ENTRANT_CHECK_OFF;
269 current->thread.trap_no = 16;
270 current->thread.error_code = 0;
271 send_sig(SIGFPE, current, 1);
272 return;
334 } 273 }
274 }
335 275
336 unmasked = 0; /* Do this here to stop compiler warnings. */ 276 entry_sel_off.offset = FPU_ORIG_EIP;
337 switch ( (byte1 >> 1) & 3 ) 277 entry_sel_off.selector = FPU_CS;
338 { 278 entry_sel_off.opcode = (byte1 << 8) | FPU_modrm;
339 case 0:
340 unmasked = FPU_load_single((float __user *)data_address,
341 &loaded_data);
342 loaded_tag = unmasked & 0xff;
343 unmasked &= ~0xff;
344 break;
345 case 1:
346 loaded_tag = FPU_load_int32((long __user *)data_address, &loaded_data);
347 break;
348 case 2:
349 unmasked = FPU_load_double((double __user *)data_address,
350 &loaded_data);
351 loaded_tag = unmasked & 0xff;
352 unmasked &= ~0xff;
353 break;
354 case 3:
355 default: /* Used here to suppress gcc warnings. */
356 loaded_tag = FPU_load_int16((short __user *)data_address, &loaded_data);
357 break;
358 }
359 279
360 /* No more access to user memory, it is safe 280 FPU_rm = FPU_modrm & 7;
361 to use static data now */
362
363 /* NaN operands have the next priority. */
364 /* We have to delay looking at st(0) until after
365 loading the data, because that data might contain an SNaN */
366 if ( ((st0_tag == TAG_Special) && isNaN(st0_ptr)) ||
367 ((loaded_tag == TAG_Special) && isNaN(&loaded_data)) )
368 {
369 /* Restore the status word; we might have loaded a
370 denormal. */
371 partial_status = status1;
372 if ( (FPU_modrm & 0x30) == 0x10 )
373 {
374 /* fcom or fcomp */
375 EXCEPTION(EX_Invalid);
376 setcc(SW_C3 | SW_C2 | SW_C0);
377 if ( (FPU_modrm & 0x08) && (control_word & CW_Invalid) )
378 FPU_pop(); /* fcomp, masked, so we pop. */
379 }
380 else
381 {
382 if ( loaded_tag == TAG_Special )
383 loaded_tag = FPU_Special(&loaded_data);
384#ifdef PECULIAR_486
385 /* This is not really needed, but gives behaviour
386 identical to an 80486 */
387 if ( (FPU_modrm & 0x28) == 0x20 )
388 /* fdiv or fsub */
389 real_2op_NaN(&loaded_data, loaded_tag, 0, &loaded_data);
390 else
391#endif /* PECULIAR_486 */
392 /* fadd, fdivr, fmul, or fsubr */
393 real_2op_NaN(&loaded_data, loaded_tag, 0, st0_ptr);
394 }
395 goto reg_mem_instr_done;
396 }
397 281
398 if ( unmasked && !((FPU_modrm & 0x30) == 0x10) ) 282 if (FPU_modrm < 0300) {
399 { 283 /* All of these instructions use the mod/rm byte to get a data address */
400 /* Is not a comparison instruction. */
401 if ( (FPU_modrm & 0x38) == 0x38 )
402 {
403 /* fdivr */
404 if ( (st0_tag == TAG_Zero) &&
405 ((loaded_tag == TAG_Valid)
406 || (loaded_tag == TAG_Special
407 && isdenormal(&loaded_data))) )
408 {
409 if ( FPU_divide_by_zero(0, getsign(&loaded_data))
410 < 0 )
411 {
412 /* We use the fact here that the unmasked
413 exception in the loaded data was for a
414 denormal operand */
415 /* Restore the state of the denormal op bit */
416 partial_status &= ~SW_Denorm_Op;
417 partial_status |= status1 & SW_Denorm_Op;
418 }
419 else
420 setsign(st0_ptr, getsign(&loaded_data));
421 }
422 }
423 goto reg_mem_instr_done;
424 }
425 284
426 switch ( (FPU_modrm >> 3) & 7 ) 285 if ((addr_modes.default_mode & SIXTEEN)
427 { 286 ^ (addr_modes.override.address_size == ADDR_SIZE_PREFIX))
428 case 0: /* fadd */ 287 data_address =
429 clear_C1(); 288 FPU_get_address_16(FPU_modrm, &FPU_EIP,
430 FPU_add(&loaded_data, loaded_tag, 0, control_word); 289 &data_sel_off, addr_modes);
431 break; 290 else
432 case 1: /* fmul */ 291 data_address =
433 clear_C1(); 292 FPU_get_address(FPU_modrm, &FPU_EIP, &data_sel_off,
434 FPU_mul(&loaded_data, loaded_tag, 0, control_word); 293 addr_modes);
435 break; 294
436 case 2: /* fcom */ 295 if (addr_modes.default_mode) {
437 FPU_compare_st_data(&loaded_data, loaded_tag); 296 if (FPU_EIP - 1 > code_limit)
438 break; 297 math_abort(FPU_info, SIGSEGV);
439 case 3: /* fcomp */
440 if ( !FPU_compare_st_data(&loaded_data, loaded_tag)
441 && !unmasked )
442 FPU_pop();
443 break;
444 case 4: /* fsub */
445 clear_C1();
446 FPU_sub(LOADED|loaded_tag, (int)&loaded_data, control_word);
447 break;
448 case 5: /* fsubr */
449 clear_C1();
450 FPU_sub(REV|LOADED|loaded_tag, (int)&loaded_data, control_word);
451 break;
452 case 6: /* fdiv */
453 clear_C1();
454 FPU_div(LOADED|loaded_tag, (int)&loaded_data, control_word);
455 break;
456 case 7: /* fdivr */
457 clear_C1();
458 if ( st0_tag == TAG_Zero )
459 partial_status = status1; /* Undo any denorm tag,
460 zero-divide has priority. */
461 FPU_div(REV|LOADED|loaded_tag, (int)&loaded_data, control_word);
462 break;
463 } 298 }
464 } 299
465 else 300 if (!(byte1 & 1)) {
466 { 301 unsigned short status1 = partial_status;
467 if ( (FPU_modrm & 0x30) == 0x10 ) 302
468 { 303 st0_ptr = &st(0);
469 /* The instruction is fcom or fcomp */ 304 st0_tag = FPU_gettag0();
470 EXCEPTION(EX_StackUnder); 305
471 setcc(SW_C3 | SW_C2 | SW_C0); 306 /* Stack underflow has priority */
472 if ( (FPU_modrm & 0x08) && (control_word & CW_Invalid) ) 307 if (NOT_EMPTY_ST0) {
473 FPU_pop(); /* fcomp */ 308 if (addr_modes.default_mode & PROTECTED) {
309 /* This table works for 16 and 32 bit protected mode */
310 if (access_limit <
311 data_sizes_16[(byte1 >> 1) & 3])
312 math_abort(FPU_info, SIGSEGV);
313 }
314
315 unmasked = 0; /* Do this here to stop compiler warnings. */
316 switch ((byte1 >> 1) & 3) {
317 case 0:
318 unmasked =
319 FPU_load_single((float __user *)
320 data_address,
321 &loaded_data);
322 loaded_tag = unmasked & 0xff;
323 unmasked &= ~0xff;
324 break;
325 case 1:
326 loaded_tag =
327 FPU_load_int32((long __user *)
328 data_address,
329 &loaded_data);
330 break;
331 case 2:
332 unmasked =
333 FPU_load_double((double __user *)
334 data_address,
335 &loaded_data);
336 loaded_tag = unmasked & 0xff;
337 unmasked &= ~0xff;
338 break;
339 case 3:
340 default: /* Used here to suppress gcc warnings. */
341 loaded_tag =
342 FPU_load_int16((short __user *)
343 data_address,
344 &loaded_data);
345 break;
346 }
347
348 /* No more access to user memory, it is safe
349 to use static data now */
350
351 /* NaN operands have the next priority. */
352 /* We have to delay looking at st(0) until after
353 loading the data, because that data might contain an SNaN */
354 if (((st0_tag == TAG_Special) && isNaN(st0_ptr))
355 || ((loaded_tag == TAG_Special)
356 && isNaN(&loaded_data))) {
357 /* Restore the status word; we might have loaded a
358 denormal. */
359 partial_status = status1;
360 if ((FPU_modrm & 0x30) == 0x10) {
361 /* fcom or fcomp */
362 EXCEPTION(EX_Invalid);
363 setcc(SW_C3 | SW_C2 | SW_C0);
364 if ((FPU_modrm & 0x08)
365 && (control_word &
366 CW_Invalid))
367 FPU_pop(); /* fcomp, masked, so we pop. */
368 } else {
369 if (loaded_tag == TAG_Special)
370 loaded_tag =
371 FPU_Special
372 (&loaded_data);
373#ifdef PECULIAR_486
374 /* This is not really needed, but gives behaviour
375 identical to an 80486 */
376 if ((FPU_modrm & 0x28) == 0x20)
377 /* fdiv or fsub */
378 real_2op_NaN
379 (&loaded_data,
380 loaded_tag, 0,
381 &loaded_data);
382 else
383#endif /* PECULIAR_486 */
384 /* fadd, fdivr, fmul, or fsubr */
385 real_2op_NaN
386 (&loaded_data,
387 loaded_tag, 0,
388 st0_ptr);
389 }
390 goto reg_mem_instr_done;
391 }
392
393 if (unmasked && !((FPU_modrm & 0x30) == 0x10)) {
394 /* Is not a comparison instruction. */
395 if ((FPU_modrm & 0x38) == 0x38) {
396 /* fdivr */
397 if ((st0_tag == TAG_Zero) &&
398 ((loaded_tag == TAG_Valid)
399 || (loaded_tag ==
400 TAG_Special
401 &&
402 isdenormal
403 (&loaded_data)))) {
404 if (FPU_divide_by_zero
405 (0,
406 getsign
407 (&loaded_data))
408 < 0) {
409 /* We use the fact here that the unmasked
410 exception in the loaded data was for a
411 denormal operand */
412 /* Restore the state of the denormal op bit */
413 partial_status
414 &=
415 ~SW_Denorm_Op;
416 partial_status
417 |=
418 status1 &
419 SW_Denorm_Op;
420 } else
421 setsign(st0_ptr,
422 getsign
423 (&loaded_data));
424 }
425 }
426 goto reg_mem_instr_done;
427 }
428
429 switch ((FPU_modrm >> 3) & 7) {
430 case 0: /* fadd */
431 clear_C1();
432 FPU_add(&loaded_data, loaded_tag, 0,
433 control_word);
434 break;
435 case 1: /* fmul */
436 clear_C1();
437 FPU_mul(&loaded_data, loaded_tag, 0,
438 control_word);
439 break;
440 case 2: /* fcom */
441 FPU_compare_st_data(&loaded_data,
442 loaded_tag);
443 break;
444 case 3: /* fcomp */
445 if (!FPU_compare_st_data
446 (&loaded_data, loaded_tag)
447 && !unmasked)
448 FPU_pop();
449 break;
450 case 4: /* fsub */
451 clear_C1();
452 FPU_sub(LOADED | loaded_tag,
453 (int)&loaded_data,
454 control_word);
455 break;
456 case 5: /* fsubr */
457 clear_C1();
458 FPU_sub(REV | LOADED | loaded_tag,
459 (int)&loaded_data,
460 control_word);
461 break;
462 case 6: /* fdiv */
463 clear_C1();
464 FPU_div(LOADED | loaded_tag,
465 (int)&loaded_data,
466 control_word);
467 break;
468 case 7: /* fdivr */
469 clear_C1();
470 if (st0_tag == TAG_Zero)
471 partial_status = status1; /* Undo any denorm tag,
472 zero-divide has priority. */
473 FPU_div(REV | LOADED | loaded_tag,
474 (int)&loaded_data,
475 control_word);
476 break;
477 }
478 } else {
479 if ((FPU_modrm & 0x30) == 0x10) {
480 /* The instruction is fcom or fcomp */
481 EXCEPTION(EX_StackUnder);
482 setcc(SW_C3 | SW_C2 | SW_C0);
483 if ((FPU_modrm & 0x08)
484 && (control_word & CW_Invalid))
485 FPU_pop(); /* fcomp */
486 } else
487 FPU_stack_underflow();
488 }
489 reg_mem_instr_done:
490 operand_address = data_sel_off;
491 } else {
492 if (!(no_ip_update =
493 FPU_load_store(((FPU_modrm & 0x38) | (byte1 & 6))
494 >> 1, addr_modes, data_address))) {
495 operand_address = data_sel_off;
496 }
474 } 497 }
475 else
476 FPU_stack_underflow();
477 }
478 reg_mem_instr_done:
479 operand_address = data_sel_off;
480 }
481 else
482 {
483 if ( !(no_ip_update =
484 FPU_load_store(((FPU_modrm & 0x38) | (byte1 & 6)) >> 1,
485 addr_modes, data_address)) )
486 {
487 operand_address = data_sel_off;
488 }
489 }
490 498
491 } 499 } else {
492 else 500 /* None of these instructions access user memory */
493 { 501 u_char instr_index = (FPU_modrm & 0x38) | (byte1 & 7);
494 /* None of these instructions access user memory */
495 u_char instr_index = (FPU_modrm & 0x38) | (byte1 & 7);
496 502
497#ifdef PECULIAR_486 503#ifdef PECULIAR_486
498 /* This is supposed to be undefined, but a real 80486 seems 504 /* This is supposed to be undefined, but a real 80486 seems
499 to do this: */ 505 to do this: */
500 operand_address.offset = 0; 506 operand_address.offset = 0;
501 operand_address.selector = FPU_DS; 507 operand_address.selector = FPU_DS;
502#endif /* PECULIAR_486 */ 508#endif /* PECULIAR_486 */
503 509
504 st0_ptr = &st(0); 510 st0_ptr = &st(0);
505 st0_tag = FPU_gettag0(); 511 st0_tag = FPU_gettag0();
506 switch ( type_table[(int) instr_index] ) 512 switch (type_table[(int)instr_index]) {
507 { 513 case _NONE_: /* also _REGIc: _REGIn */
508 case _NONE_: /* also _REGIc: _REGIn */ 514 break;
509 break; 515 case _REG0_:
510 case _REG0_: 516 if (!NOT_EMPTY_ST0) {
511 if ( !NOT_EMPTY_ST0 ) 517 FPU_stack_underflow();
512 { 518 goto FPU_instruction_done;
513 FPU_stack_underflow(); 519 }
514 goto FPU_instruction_done; 520 break;
515 } 521 case _REGIi:
516 break; 522 if (!NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm)) {
517 case _REGIi: 523 FPU_stack_underflow_i(FPU_rm);
518 if ( !NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm) ) 524 goto FPU_instruction_done;
519 { 525 }
520 FPU_stack_underflow_i(FPU_rm); 526 break;
521 goto FPU_instruction_done; 527 case _REGIp:
522 } 528 if (!NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm)) {
523 break; 529 FPU_stack_underflow_pop(FPU_rm);
524 case _REGIp: 530 goto FPU_instruction_done;
525 if ( !NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm) ) 531 }
526 { 532 break;
527 FPU_stack_underflow_pop(FPU_rm); 533 case _REGI_:
528 goto FPU_instruction_done; 534 if (!NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm)) {
529 } 535 FPU_stack_underflow();
530 break; 536 goto FPU_instruction_done;
531 case _REGI_: 537 }
532 if ( !NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm) ) 538 break;
533 { 539 case _PUSH_: /* Only used by the fld st(i) instruction */
534 FPU_stack_underflow(); 540 break;
535 goto FPU_instruction_done; 541 case _null_:
536 } 542 FPU_illegal();
537 break; 543 goto FPU_instruction_done;
538 case _PUSH_: /* Only used by the fld st(i) instruction */ 544 default:
539 break; 545 EXCEPTION(EX_INTERNAL | 0x111);
540 case _null_: 546 goto FPU_instruction_done;
541 FPU_illegal(); 547 }
542 goto FPU_instruction_done; 548 (*st_instr_table[(int)instr_index]) ();
543 default:
544 EXCEPTION(EX_INTERNAL|0x111);
545 goto FPU_instruction_done;
546 }
547 (*st_instr_table[(int) instr_index])();
548 549
549FPU_instruction_done: 550 FPU_instruction_done:
550 ; 551 ;
551 } 552 }
552 553
553 if ( ! no_ip_update ) 554 if (!no_ip_update)
554 instruction_address = entry_sel_off; 555 instruction_address = entry_sel_off;
555 556
556FPU_fwait_done: 557 FPU_fwait_done:
557 558
558#ifdef DEBUG 559#ifdef DEBUG
559 RE_ENTRANT_CHECK_OFF; 560 RE_ENTRANT_CHECK_OFF;
560 FPU_printall(); 561 FPU_printall();
561 RE_ENTRANT_CHECK_ON; 562 RE_ENTRANT_CHECK_ON;
562#endif /* DEBUG */ 563#endif /* DEBUG */
563 564
564 if (FPU_lookahead && !need_resched()) 565 if (FPU_lookahead && !need_resched()) {
565 { 566 FPU_ORIG_EIP = FPU_EIP - code_base;
566 FPU_ORIG_EIP = FPU_EIP - code_base; 567 if (valid_prefix(&byte1, (u_char __user **) & FPU_EIP,
567 if ( valid_prefix(&byte1, (u_char __user **)&FPU_EIP, 568 &addr_modes.override))
568 &addr_modes.override) ) 569 goto do_another_FPU_instruction;
569 goto do_another_FPU_instruction; 570 }
570 }
571 571
572 if ( addr_modes.default_mode ) 572 if (addr_modes.default_mode)
573 FPU_EIP -= code_base; 573 FPU_EIP -= code_base;
574 574
575 RE_ENTRANT_CHECK_OFF; 575 RE_ENTRANT_CHECK_OFF;
576} 576}
577 577
578
579/* Support for prefix bytes is not yet complete. To properly handle 578/* Support for prefix bytes is not yet complete. To properly handle
580 all prefix bytes, further changes are needed in the emulator code 579 all prefix bytes, further changes are needed in the emulator code
581 which accesses user address space. Access to separate segments is 580 which accesses user address space. Access to separate segments is
582 important for msdos emulation. */ 581 important for msdos emulation. */
583static int valid_prefix(u_char *Byte, u_char __user **fpu_eip, 582static int valid_prefix(u_char *Byte, u_char __user **fpu_eip,
584 overrides *override) 583 overrides * override)
585{ 584{
586 u_char byte; 585 u_char byte;
587 u_char __user *ip = *fpu_eip; 586 u_char __user *ip = *fpu_eip;
588 587
589 *override = (overrides) { 0, 0, PREFIX_DEFAULT }; /* defaults */ 588 *override = (overrides) {
590 589 0, 0, PREFIX_DEFAULT}; /* defaults */
591 RE_ENTRANT_CHECK_OFF; 590
592 FPU_code_access_ok(1); 591 RE_ENTRANT_CHECK_OFF;
593 FPU_get_user(byte, ip); 592 FPU_code_access_ok(1);
594 RE_ENTRANT_CHECK_ON; 593 FPU_get_user(byte, ip);
595 594 RE_ENTRANT_CHECK_ON;
596 while ( 1 ) 595
597 { 596 while (1) {
598 switch ( byte ) 597 switch (byte) {
599 { 598 case ADDR_SIZE_PREFIX:
600 case ADDR_SIZE_PREFIX: 599 override->address_size = ADDR_SIZE_PREFIX;
601 override->address_size = ADDR_SIZE_PREFIX; 600 goto do_next_byte;
602 goto do_next_byte; 601
603 602 case OP_SIZE_PREFIX:
604 case OP_SIZE_PREFIX: 603 override->operand_size = OP_SIZE_PREFIX;
605 override->operand_size = OP_SIZE_PREFIX; 604 goto do_next_byte;
606 goto do_next_byte; 605
607 606 case PREFIX_CS:
608 case PREFIX_CS: 607 override->segment = PREFIX_CS_;
609 override->segment = PREFIX_CS_; 608 goto do_next_byte;
610 goto do_next_byte; 609 case PREFIX_ES:
611 case PREFIX_ES: 610 override->segment = PREFIX_ES_;
612 override->segment = PREFIX_ES_; 611 goto do_next_byte;
613 goto do_next_byte; 612 case PREFIX_SS:
614 case PREFIX_SS: 613 override->segment = PREFIX_SS_;
615 override->segment = PREFIX_SS_; 614 goto do_next_byte;
616 goto do_next_byte; 615 case PREFIX_FS:
617 case PREFIX_FS: 616 override->segment = PREFIX_FS_;
618 override->segment = PREFIX_FS_; 617 goto do_next_byte;
619 goto do_next_byte; 618 case PREFIX_GS:
620 case PREFIX_GS: 619 override->segment = PREFIX_GS_;
621 override->segment = PREFIX_GS_; 620 goto do_next_byte;
622 goto do_next_byte; 621 case PREFIX_DS:
623 case PREFIX_DS: 622 override->segment = PREFIX_DS_;
624 override->segment = PREFIX_DS_; 623 goto do_next_byte;
625 goto do_next_byte;
626 624
627/* lock is not a valid prefix for FPU instructions, 625/* lock is not a valid prefix for FPU instructions,
628 let the cpu handle it to generate a SIGILL. */ 626 let the cpu handle it to generate a SIGILL. */
629/* case PREFIX_LOCK: */ 627/* case PREFIX_LOCK: */
630 628
631 /* rep.. prefixes have no meaning for FPU instructions */ 629 /* rep.. prefixes have no meaning for FPU instructions */
632 case PREFIX_REPE: 630 case PREFIX_REPE:
633 case PREFIX_REPNE: 631 case PREFIX_REPNE:
634 632
635 do_next_byte: 633 do_next_byte:
636 ip++; 634 ip++;
637 RE_ENTRANT_CHECK_OFF; 635 RE_ENTRANT_CHECK_OFF;
638 FPU_code_access_ok(1); 636 FPU_code_access_ok(1);
639 FPU_get_user(byte, ip); 637 FPU_get_user(byte, ip);
640 RE_ENTRANT_CHECK_ON; 638 RE_ENTRANT_CHECK_ON;
641 break; 639 break;
642 case FWAIT_OPCODE: 640 case FWAIT_OPCODE:
643 *Byte = byte; 641 *Byte = byte;
644 return 1; 642 return 1;
645 default: 643 default:
646 if ( (byte & 0xf8) == 0xd8 ) 644 if ((byte & 0xf8) == 0xd8) {
647 { 645 *Byte = byte;
648 *Byte = byte; 646 *fpu_eip = ip;
649 *fpu_eip = ip; 647 return 1;
650 return 1; 648 } else {
651 } 649 /* Not a valid sequence of prefix bytes followed by
652 else 650 an FPU instruction. */
653 { 651 *Byte = byte; /* Needed for error message. */
654 /* Not a valid sequence of prefix bytes followed by 652 return 0;
655 an FPU instruction. */ 653 }
656 *Byte = byte; /* Needed for error message. */ 654 }
657 return 0;
658 }
659 } 655 }
660 }
661} 656}
662 657
663 658void math_abort(struct info *info, unsigned int signal)
664void math_abort(struct info * info, unsigned int signal)
665{ 659{
666 FPU_EIP = FPU_ORIG_EIP; 660 FPU_EIP = FPU_ORIG_EIP;
667 current->thread.trap_no = 16; 661 current->thread.trap_no = 16;
668 current->thread.error_code = 0; 662 current->thread.error_code = 0;
669 send_sig(signal,current,1); 663 send_sig(signal, current, 1);
670 RE_ENTRANT_CHECK_OFF; 664 RE_ENTRANT_CHECK_OFF;
671 __asm__("movl %0,%%esp ; ret": :"g" (((long) info)-4)); 665 __asm__("movl %0,%%esp ; ret": :"g"(((long)info) - 4));
672#ifdef PARANOID 666#ifdef PARANOID
673 printk("ERROR: wm-FPU-emu math_abort failed!\n"); 667 printk("ERROR: wm-FPU-emu math_abort failed!\n");
674#endif /* PARANOID */ 668#endif /* PARANOID */
675} 669}
676 670
677
678
679#define S387 ((struct i387_soft_struct *)s387) 671#define S387 ((struct i387_soft_struct *)s387)
680#define sstatus_word() \ 672#define sstatus_word() \
681 ((S387->swd & ~SW_Top & 0xffff) | ((S387->ftop << SW_Top_Shift) & SW_Top)) 673 ((S387->swd & ~SW_Top & 0xffff) | ((S387->ftop << SW_Top_Shift) & SW_Top))
682 674
683int restore_i387_soft(void *s387, struct _fpstate __user *buf) 675int fpregs_soft_set(struct task_struct *target,
676 const struct user_regset *regset,
677 unsigned int pos, unsigned int count,
678 const void *kbuf, const void __user *ubuf)
684{ 679{
685 u_char __user *d = (u_char __user *)buf; 680 struct i387_soft_struct *s387 = &target->thread.i387.soft;
686 int offset, other, i, tags, regnr, tag, newtop; 681 void *space = s387->st_space;
687 682 int ret;
688 RE_ENTRANT_CHECK_OFF; 683 int offset, other, i, tags, regnr, tag, newtop;
689 FPU_access_ok(VERIFY_READ, d, 7*4 + 8*10); 684
690 if (__copy_from_user(&S387->cwd, d, 7*4)) 685 RE_ENTRANT_CHECK_OFF;
691 return -1; 686 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, s387, 0,
692 RE_ENTRANT_CHECK_ON; 687 offsetof(struct i387_soft_struct, st_space));
693 688 RE_ENTRANT_CHECK_ON;
694 d += 7*4; 689
695 690 if (ret)
696 S387->ftop = (S387->swd >> SW_Top_Shift) & 7; 691 return ret;
697 offset = (S387->ftop & 7) * 10; 692
698 other = 80 - offset; 693 S387->ftop = (S387->swd >> SW_Top_Shift) & 7;
699 694 offset = (S387->ftop & 7) * 10;
700 RE_ENTRANT_CHECK_OFF; 695 other = 80 - offset;
701 /* Copy all registers in stack order. */ 696
702 if (__copy_from_user(((u_char *)&S387->st_space)+offset, d, other)) 697 RE_ENTRANT_CHECK_OFF;
703 return -1; 698
704 if ( offset ) 699 /* Copy all registers in stack order. */
705 if (__copy_from_user((u_char *)&S387->st_space, d+other, offset)) 700 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
706 return -1; 701 space + offset, 0, other);
707 RE_ENTRANT_CHECK_ON; 702 if (!ret && offset)
708 703 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
709 /* The tags may need to be corrected now. */ 704 space, 0, offset);
710 tags = S387->twd; 705
711 newtop = S387->ftop; 706 RE_ENTRANT_CHECK_ON;
712 for ( i = 0; i < 8; i++ ) 707
713 { 708 /* The tags may need to be corrected now. */
714 regnr = (i+newtop) & 7; 709 tags = S387->twd;
715 if ( ((tags >> ((regnr & 7)*2)) & 3) != TAG_Empty ) 710 newtop = S387->ftop;
716 { 711 for (i = 0; i < 8; i++) {
717 /* The loaded data over-rides all other cases. */ 712 regnr = (i + newtop) & 7;
718 tag = FPU_tagof((FPU_REG *)((u_char *)S387->st_space + 10*regnr)); 713 if (((tags >> ((regnr & 7) * 2)) & 3) != TAG_Empty) {
719 tags &= ~(3 << (regnr*2)); 714 /* The loaded data over-rides all other cases. */
720 tags |= (tag & 3) << (regnr*2); 715 tag =
716 FPU_tagof((FPU_REG *) ((u_char *) S387->st_space +
717 10 * regnr));
718 tags &= ~(3 << (regnr * 2));
719 tags |= (tag & 3) << (regnr * 2);
720 }
721 } 721 }
722 } 722 S387->twd = tags;
723 S387->twd = tags;
724 723
725 return 0; 724 return ret;
726} 725}
727 726
728 727int fpregs_soft_get(struct task_struct *target,
729int save_i387_soft(void *s387, struct _fpstate __user * buf) 728 const struct user_regset *regset,
729 unsigned int pos, unsigned int count,
730 void *kbuf, void __user *ubuf)
730{ 731{
731 u_char __user *d = (u_char __user *)buf; 732 struct i387_soft_struct *s387 = &target->thread.i387.soft;
732 int offset = (S387->ftop & 7) * 10, other = 80 - offset; 733 const void *space = s387->st_space;
734 int ret;
735 int offset = (S387->ftop & 7) * 10, other = 80 - offset;
736
737 RE_ENTRANT_CHECK_OFF;
733 738
734 RE_ENTRANT_CHECK_OFF;
735 FPU_access_ok(VERIFY_WRITE, d, 7*4 + 8*10);
736#ifdef PECULIAR_486 739#ifdef PECULIAR_486
737 S387->cwd &= ~0xe080; 740 S387->cwd &= ~0xe080;
738 /* An 80486 sets nearly all of the reserved bits to 1. */ 741 /* An 80486 sets nearly all of the reserved bits to 1. */
739 S387->cwd |= 0xffff0040; 742 S387->cwd |= 0xffff0040;
740 S387->swd = sstatus_word() | 0xffff0000; 743 S387->swd = sstatus_word() | 0xffff0000;
741 S387->twd |= 0xffff0000; 744 S387->twd |= 0xffff0000;
742 S387->fcs &= ~0xf8000000; 745 S387->fcs &= ~0xf8000000;
743 S387->fos |= 0xffff0000; 746 S387->fos |= 0xffff0000;
744#endif /* PECULIAR_486 */ 747#endif /* PECULIAR_486 */
745 if (__copy_to_user(d, &S387->cwd, 7*4)) 748
746 return -1; 749 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, s387, 0,
747 RE_ENTRANT_CHECK_ON; 750 offsetof(struct i387_soft_struct, st_space));
748 751
749 d += 7*4; 752 /* Copy all registers in stack order. */
750 753 if (!ret)
751 RE_ENTRANT_CHECK_OFF; 754 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
752 /* Copy all registers in stack order. */ 755 space + offset, 0, other);
753 if (__copy_to_user(d, ((u_char *)&S387->st_space)+offset, other)) 756 if (!ret)
754 return -1; 757 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
755 if ( offset ) 758 space, 0, offset);
756 if (__copy_to_user(d+other, (u_char *)&S387->st_space, offset)) 759
757 return -1; 760 RE_ENTRANT_CHECK_ON;
758 RE_ENTRANT_CHECK_ON; 761
759 762 return ret;
760 return 1;
761} 763}
diff --git a/arch/x86/math-emu/fpu_etc.c b/arch/x86/math-emu/fpu_etc.c
index e3b5d465587f..233e5af566f5 100644
--- a/arch/x86/math-emu/fpu_etc.c
+++ b/arch/x86/math-emu/fpu_etc.c
@@ -16,128 +16,115 @@
16#include "status_w.h" 16#include "status_w.h"
17#include "reg_constant.h" 17#include "reg_constant.h"
18 18
19
20static void fchs(FPU_REG *st0_ptr, u_char st0tag) 19static void fchs(FPU_REG *st0_ptr, u_char st0tag)
21{ 20{
22 if ( st0tag ^ TAG_Empty ) 21 if (st0tag ^ TAG_Empty) {
23 { 22 signbyte(st0_ptr) ^= SIGN_NEG;
24 signbyte(st0_ptr) ^= SIGN_NEG; 23 clear_C1();
25 clear_C1(); 24 } else
26 } 25 FPU_stack_underflow();
27 else
28 FPU_stack_underflow();
29} 26}
30 27
31
32static void fabs(FPU_REG *st0_ptr, u_char st0tag) 28static void fabs(FPU_REG *st0_ptr, u_char st0tag)
33{ 29{
34 if ( st0tag ^ TAG_Empty ) 30 if (st0tag ^ TAG_Empty) {
35 { 31 setpositive(st0_ptr);
36 setpositive(st0_ptr); 32 clear_C1();
37 clear_C1(); 33 } else
38 } 34 FPU_stack_underflow();
39 else
40 FPU_stack_underflow();
41} 35}
42 36
43
44static void ftst_(FPU_REG *st0_ptr, u_char st0tag) 37static void ftst_(FPU_REG *st0_ptr, u_char st0tag)
45{ 38{
46 switch (st0tag) 39 switch (st0tag) {
47 { 40 case TAG_Zero:
48 case TAG_Zero:
49 setcc(SW_C3);
50 break;
51 case TAG_Valid:
52 if (getsign(st0_ptr) == SIGN_POS)
53 setcc(0);
54 else
55 setcc(SW_C0);
56 break;
57 case TAG_Special:
58 switch ( FPU_Special(st0_ptr) )
59 {
60 case TW_Denormal:
61 if (getsign(st0_ptr) == SIGN_POS)
62 setcc(0);
63 else
64 setcc(SW_C0);
65 if ( denormal_operand() < 0 )
66 {
67#ifdef PECULIAR_486
68 /* This is weird! */
69 if (getsign(st0_ptr) == SIGN_POS)
70 setcc(SW_C3); 41 setcc(SW_C3);
42 break;
43 case TAG_Valid:
44 if (getsign(st0_ptr) == SIGN_POS)
45 setcc(0);
46 else
47 setcc(SW_C0);
48 break;
49 case TAG_Special:
50 switch (FPU_Special(st0_ptr)) {
51 case TW_Denormal:
52 if (getsign(st0_ptr) == SIGN_POS)
53 setcc(0);
54 else
55 setcc(SW_C0);
56 if (denormal_operand() < 0) {
57#ifdef PECULIAR_486
58 /* This is weird! */
59 if (getsign(st0_ptr) == SIGN_POS)
60 setcc(SW_C3);
71#endif /* PECULIAR_486 */ 61#endif /* PECULIAR_486 */
72 return; 62 return;
73 } 63 }
74 break; 64 break;
75 case TW_NaN: 65 case TW_NaN:
76 setcc(SW_C0|SW_C2|SW_C3); /* Operand is not comparable */ 66 setcc(SW_C0 | SW_C2 | SW_C3); /* Operand is not comparable */
77 EXCEPTION(EX_Invalid); 67 EXCEPTION(EX_Invalid);
78 break; 68 break;
79 case TW_Infinity: 69 case TW_Infinity:
80 if (getsign(st0_ptr) == SIGN_POS) 70 if (getsign(st0_ptr) == SIGN_POS)
81 setcc(0); 71 setcc(0);
82 else 72 else
83 setcc(SW_C0); 73 setcc(SW_C0);
84 break; 74 break;
85 default: 75 default:
86 setcc(SW_C0|SW_C2|SW_C3); /* Operand is not comparable */ 76 setcc(SW_C0 | SW_C2 | SW_C3); /* Operand is not comparable */
87 EXCEPTION(EX_INTERNAL|0x14); 77 EXCEPTION(EX_INTERNAL | 0x14);
88 break; 78 break;
79 }
80 break;
81 case TAG_Empty:
82 setcc(SW_C0 | SW_C2 | SW_C3);
83 EXCEPTION(EX_StackUnder);
84 break;
89 } 85 }
90 break;
91 case TAG_Empty:
92 setcc(SW_C0|SW_C2|SW_C3);
93 EXCEPTION(EX_StackUnder);
94 break;
95 }
96} 86}
97 87
98
99static void fxam(FPU_REG *st0_ptr, u_char st0tag) 88static void fxam(FPU_REG *st0_ptr, u_char st0tag)
100{ 89{
101 int c = 0; 90 int c = 0;
102 switch (st0tag) 91 switch (st0tag) {
103 { 92 case TAG_Empty:
104 case TAG_Empty: 93 c = SW_C3 | SW_C0;
105 c = SW_C3|SW_C0; 94 break;
106 break; 95 case TAG_Zero:
107 case TAG_Zero: 96 c = SW_C3;
108 c = SW_C3; 97 break;
109 break; 98 case TAG_Valid:
110 case TAG_Valid: 99 c = SW_C2;
111 c = SW_C2; 100 break;
112 break; 101 case TAG_Special:
113 case TAG_Special: 102 switch (FPU_Special(st0_ptr)) {
114 switch ( FPU_Special(st0_ptr) ) 103 case TW_Denormal:
115 { 104 c = SW_C2 | SW_C3; /* Denormal */
116 case TW_Denormal: 105 break;
117 c = SW_C2|SW_C3; /* Denormal */ 106 case TW_NaN:
118 break; 107 /* We also use NaN for unsupported types. */
119 case TW_NaN: 108 if ((st0_ptr->sigh & 0x80000000)
120 /* We also use NaN for unsupported types. */ 109 && (exponent(st0_ptr) == EXP_OVER))
121 if ( (st0_ptr->sigh & 0x80000000) && (exponent(st0_ptr) == EXP_OVER) ) 110 c = SW_C0;
122 c = SW_C0; 111 break;
123 break; 112 case TW_Infinity:
124 case TW_Infinity: 113 c = SW_C2 | SW_C0;
125 c = SW_C2|SW_C0; 114 break;
126 break; 115 }
127 } 116 }
128 } 117 if (getsign(st0_ptr) == SIGN_NEG)
129 if ( getsign(st0_ptr) == SIGN_NEG ) 118 c |= SW_C1;
130 c |= SW_C1; 119 setcc(c);
131 setcc(c);
132} 120}
133 121
134
135static FUNC_ST0 const fp_etc_table[] = { 122static FUNC_ST0 const fp_etc_table[] = {
136 fchs, fabs, (FUNC_ST0)FPU_illegal, (FUNC_ST0)FPU_illegal, 123 fchs, fabs, (FUNC_ST0) FPU_illegal, (FUNC_ST0) FPU_illegal,
137 ftst_, fxam, (FUNC_ST0)FPU_illegal, (FUNC_ST0)FPU_illegal 124 ftst_, fxam, (FUNC_ST0) FPU_illegal, (FUNC_ST0) FPU_illegal
138}; 125};
139 126
140void FPU_etc(void) 127void FPU_etc(void)
141{ 128{
142 (fp_etc_table[FPU_rm])(&st(0), FPU_gettag0()); 129 (fp_etc_table[FPU_rm]) (&st(0), FPU_gettag0());
143} 130}
diff --git a/arch/x86/math-emu/fpu_proto.h b/arch/x86/math-emu/fpu_proto.h
index 37a8a7fe7e2b..aa49b6a0d850 100644
--- a/arch/x86/math-emu/fpu_proto.h
+++ b/arch/x86/math-emu/fpu_proto.h
@@ -66,7 +66,7 @@ extern int FPU_Special(FPU_REG const *ptr);
66extern int isNaN(FPU_REG const *ptr); 66extern int isNaN(FPU_REG const *ptr);
67extern void FPU_pop(void); 67extern void FPU_pop(void);
68extern int FPU_empty_i(int stnr); 68extern int FPU_empty_i(int stnr);
69extern int FPU_stackoverflow(FPU_REG **st_new_ptr); 69extern int FPU_stackoverflow(FPU_REG ** st_new_ptr);
70extern void FPU_copy_to_regi(FPU_REG const *r, u_char tag, int stnr); 70extern void FPU_copy_to_regi(FPU_REG const *r, u_char tag, int stnr);
71extern void FPU_copy_to_reg1(FPU_REG const *r, u_char tag); 71extern void FPU_copy_to_reg1(FPU_REG const *r, u_char tag);
72extern void FPU_copy_to_reg0(FPU_REG const *r, u_char tag); 72extern void FPU_copy_to_reg0(FPU_REG const *r, u_char tag);
@@ -75,21 +75,23 @@ extern void FPU_triga(void);
75extern void FPU_trigb(void); 75extern void FPU_trigb(void);
76/* get_address.c */ 76/* get_address.c */
77extern void __user *FPU_get_address(u_char FPU_modrm, unsigned long *fpu_eip, 77extern void __user *FPU_get_address(u_char FPU_modrm, unsigned long *fpu_eip,
78 struct address *addr, fpu_addr_modes addr_modes); 78 struct address *addr,
79 fpu_addr_modes addr_modes);
79extern void __user *FPU_get_address_16(u_char FPU_modrm, unsigned long *fpu_eip, 80extern void __user *FPU_get_address_16(u_char FPU_modrm, unsigned long *fpu_eip,
80 struct address *addr, fpu_addr_modes addr_modes); 81 struct address *addr,
82 fpu_addr_modes addr_modes);
81/* load_store.c */ 83/* load_store.c */
82extern int FPU_load_store(u_char type, fpu_addr_modes addr_modes, 84extern int FPU_load_store(u_char type, fpu_addr_modes addr_modes,
83 void __user *data_address); 85 void __user * data_address);
84/* poly_2xm1.c */ 86/* poly_2xm1.c */
85extern int poly_2xm1(u_char sign, FPU_REG *arg, FPU_REG *result); 87extern int poly_2xm1(u_char sign, FPU_REG * arg, FPU_REG *result);
86/* poly_atan.c */ 88/* poly_atan.c */
87extern void poly_atan(FPU_REG *st0_ptr, u_char st0_tag, FPU_REG *st1_ptr, 89extern void poly_atan(FPU_REG * st0_ptr, u_char st0_tag, FPU_REG *st1_ptr,
88 u_char st1_tag); 90 u_char st1_tag);
89/* poly_l2.c */ 91/* poly_l2.c */
90extern void poly_l2(FPU_REG *st0_ptr, FPU_REG *st1_ptr, u_char st1_sign); 92extern void poly_l2(FPU_REG *st0_ptr, FPU_REG *st1_ptr, u_char st1_sign);
91extern int poly_l2p1(u_char s0, u_char s1, FPU_REG *r0, FPU_REG *r1, 93extern int poly_l2p1(u_char s0, u_char s1, FPU_REG *r0, FPU_REG *r1,
92 FPU_REG *d); 94 FPU_REG * d);
93/* poly_sin.c */ 95/* poly_sin.c */
94extern void poly_sine(FPU_REG *st0_ptr); 96extern void poly_sine(FPU_REG *st0_ptr);
95extern void poly_cos(FPU_REG *st0_ptr); 97extern void poly_cos(FPU_REG *st0_ptr);
@@ -117,10 +119,13 @@ extern int FPU_load_int32(long __user *_s, FPU_REG *loaded_data);
117extern int FPU_load_int16(short __user *_s, FPU_REG *loaded_data); 119extern int FPU_load_int16(short __user *_s, FPU_REG *loaded_data);
118extern int FPU_load_bcd(u_char __user *s); 120extern int FPU_load_bcd(u_char __user *s);
119extern int FPU_store_extended(FPU_REG *st0_ptr, u_char st0_tag, 121extern int FPU_store_extended(FPU_REG *st0_ptr, u_char st0_tag,
120 long double __user *d); 122 long double __user * d);
121extern int FPU_store_double(FPU_REG *st0_ptr, u_char st0_tag, double __user *dfloat); 123extern int FPU_store_double(FPU_REG *st0_ptr, u_char st0_tag,
122extern int FPU_store_single(FPU_REG *st0_ptr, u_char st0_tag, float __user *single); 124 double __user * dfloat);
123extern int FPU_store_int64(FPU_REG *st0_ptr, u_char st0_tag, long long __user *d); 125extern int FPU_store_single(FPU_REG *st0_ptr, u_char st0_tag,
126 float __user * single);
127extern int FPU_store_int64(FPU_REG *st0_ptr, u_char st0_tag,
128 long long __user * d);
124extern int FPU_store_int32(FPU_REG *st0_ptr, u_char st0_tag, long __user *d); 129extern int FPU_store_int32(FPU_REG *st0_ptr, u_char st0_tag, long __user *d);
125extern int FPU_store_int16(FPU_REG *st0_ptr, u_char st0_tag, short __user *d); 130extern int FPU_store_int16(FPU_REG *st0_ptr, u_char st0_tag, short __user *d);
126extern int FPU_store_bcd(FPU_REG *st0_ptr, u_char st0_tag, u_char __user *d); 131extern int FPU_store_bcd(FPU_REG *st0_ptr, u_char st0_tag, u_char __user *d);
@@ -137,4 +142,3 @@ extern int FPU_div(int flags, int regrm, int control_w);
137/* reg_convert.c */ 142/* reg_convert.c */
138extern int FPU_to_exp16(FPU_REG const *a, FPU_REG *x); 143extern int FPU_to_exp16(FPU_REG const *a, FPU_REG *x);
139#endif /* _FPU_PROTO_H */ 144#endif /* _FPU_PROTO_H */
140
diff --git a/arch/x86/math-emu/fpu_tags.c b/arch/x86/math-emu/fpu_tags.c
index cb436fe20e4c..d9c657cd7746 100644
--- a/arch/x86/math-emu/fpu_tags.c
+++ b/arch/x86/math-emu/fpu_tags.c
@@ -14,114 +14,102 @@
14#include "fpu_system.h" 14#include "fpu_system.h"
15#include "exception.h" 15#include "exception.h"
16 16
17
18void FPU_pop(void) 17void FPU_pop(void)
19{ 18{
20 fpu_tag_word |= 3 << ((top & 7)*2); 19 fpu_tag_word |= 3 << ((top & 7) * 2);
21 top++; 20 top++;
22} 21}
23 22
24
25int FPU_gettag0(void) 23int FPU_gettag0(void)
26{ 24{
27 return (fpu_tag_word >> ((top & 7)*2)) & 3; 25 return (fpu_tag_word >> ((top & 7) * 2)) & 3;
28} 26}
29 27
30
31int FPU_gettagi(int stnr) 28int FPU_gettagi(int stnr)
32{ 29{
33 return (fpu_tag_word >> (((top+stnr) & 7)*2)) & 3; 30 return (fpu_tag_word >> (((top + stnr) & 7) * 2)) & 3;
34} 31}
35 32
36
37int FPU_gettag(int regnr) 33int FPU_gettag(int regnr)
38{ 34{
39 return (fpu_tag_word >> ((regnr & 7)*2)) & 3; 35 return (fpu_tag_word >> ((regnr & 7) * 2)) & 3;
40} 36}
41 37
42
43void FPU_settag0(int tag) 38void FPU_settag0(int tag)
44{ 39{
45 int regnr = top; 40 int regnr = top;
46 regnr &= 7; 41 regnr &= 7;
47 fpu_tag_word &= ~(3 << (regnr*2)); 42 fpu_tag_word &= ~(3 << (regnr * 2));
48 fpu_tag_word |= (tag & 3) << (regnr*2); 43 fpu_tag_word |= (tag & 3) << (regnr * 2);
49} 44}
50 45
51
52void FPU_settagi(int stnr, int tag) 46void FPU_settagi(int stnr, int tag)
53{ 47{
54 int regnr = stnr+top; 48 int regnr = stnr + top;
55 regnr &= 7; 49 regnr &= 7;
56 fpu_tag_word &= ~(3 << (regnr*2)); 50 fpu_tag_word &= ~(3 << (regnr * 2));
57 fpu_tag_word |= (tag & 3) << (regnr*2); 51 fpu_tag_word |= (tag & 3) << (regnr * 2);
58} 52}
59 53
60
61void FPU_settag(int regnr, int tag) 54void FPU_settag(int regnr, int tag)
62{ 55{
63 regnr &= 7; 56 regnr &= 7;
64 fpu_tag_word &= ~(3 << (regnr*2)); 57 fpu_tag_word &= ~(3 << (regnr * 2));
65 fpu_tag_word |= (tag & 3) << (regnr*2); 58 fpu_tag_word |= (tag & 3) << (regnr * 2);
66} 59}
67 60
68
69int FPU_Special(FPU_REG const *ptr) 61int FPU_Special(FPU_REG const *ptr)
70{ 62{
71 int exp = exponent(ptr); 63 int exp = exponent(ptr);
72 64
73 if ( exp == EXP_BIAS+EXP_UNDER ) 65 if (exp == EXP_BIAS + EXP_UNDER)
74 return TW_Denormal; 66 return TW_Denormal;
75 else if ( exp != EXP_BIAS+EXP_OVER ) 67 else if (exp != EXP_BIAS + EXP_OVER)
76 return TW_NaN; 68 return TW_NaN;
77 else if ( (ptr->sigh == 0x80000000) && (ptr->sigl == 0) ) 69 else if ((ptr->sigh == 0x80000000) && (ptr->sigl == 0))
78 return TW_Infinity; 70 return TW_Infinity;
79 return TW_NaN; 71 return TW_NaN;
80} 72}
81 73
82
83int isNaN(FPU_REG const *ptr) 74int isNaN(FPU_REG const *ptr)
84{ 75{
85 return ( (exponent(ptr) == EXP_BIAS+EXP_OVER) 76 return ((exponent(ptr) == EXP_BIAS + EXP_OVER)
86 && !((ptr->sigh == 0x80000000) && (ptr->sigl == 0)) ); 77 && !((ptr->sigh == 0x80000000) && (ptr->sigl == 0)));
87} 78}
88 79
89
90int FPU_empty_i(int stnr) 80int FPU_empty_i(int stnr)
91{ 81{
92 int regnr = (top+stnr) & 7; 82 int regnr = (top + stnr) & 7;
93 83
94 return ((fpu_tag_word >> (regnr*2)) & 3) == TAG_Empty; 84 return ((fpu_tag_word >> (regnr * 2)) & 3) == TAG_Empty;
95} 85}
96 86
97 87int FPU_stackoverflow(FPU_REG ** st_new_ptr)
98int FPU_stackoverflow(FPU_REG **st_new_ptr)
99{ 88{
100 *st_new_ptr = &st(-1); 89 *st_new_ptr = &st(-1);
101 90
102 return ((fpu_tag_word >> (((top - 1) & 7)*2)) & 3) != TAG_Empty; 91 return ((fpu_tag_word >> (((top - 1) & 7) * 2)) & 3) != TAG_Empty;
103} 92}
104 93
105
106void FPU_copy_to_regi(FPU_REG const *r, u_char tag, int stnr) 94void FPU_copy_to_regi(FPU_REG const *r, u_char tag, int stnr)
107{ 95{
108 reg_copy(r, &st(stnr)); 96 reg_copy(r, &st(stnr));
109 FPU_settagi(stnr, tag); 97 FPU_settagi(stnr, tag);
110} 98}
111 99
112void FPU_copy_to_reg1(FPU_REG const *r, u_char tag) 100void FPU_copy_to_reg1(FPU_REG const *r, u_char tag)
113{ 101{
114 reg_copy(r, &st(1)); 102 reg_copy(r, &st(1));
115 FPU_settagi(1, tag); 103 FPU_settagi(1, tag);
116} 104}
117 105
118void FPU_copy_to_reg0(FPU_REG const *r, u_char tag) 106void FPU_copy_to_reg0(FPU_REG const *r, u_char tag)
119{ 107{
120 int regnr = top; 108 int regnr = top;
121 regnr &= 7; 109 regnr &= 7;
122 110
123 reg_copy(r, &st(0)); 111 reg_copy(r, &st(0));
124 112
125 fpu_tag_word &= ~(3 << (regnr*2)); 113 fpu_tag_word &= ~(3 << (regnr * 2));
126 fpu_tag_word |= (tag & 3) << (regnr*2); 114 fpu_tag_word |= (tag & 3) << (regnr * 2);
127} 115}
diff --git a/arch/x86/math-emu/fpu_trig.c b/arch/x86/math-emu/fpu_trig.c
index 403cbde1d425..ecd06680581c 100644
--- a/arch/x86/math-emu/fpu_trig.c
+++ b/arch/x86/math-emu/fpu_trig.c
@@ -15,11 +15,10 @@
15#include "fpu_emu.h" 15#include "fpu_emu.h"
16#include "status_w.h" 16#include "status_w.h"
17#include "control_w.h" 17#include "control_w.h"
18#include "reg_constant.h" 18#include "reg_constant.h"
19 19
20static void rem_kernel(unsigned long long st0, unsigned long long *y, 20static void rem_kernel(unsigned long long st0, unsigned long long *y,
21 unsigned long long st1, 21 unsigned long long st1, unsigned long long q, int n);
22 unsigned long long q, int n);
23 22
24#define BETTER_THAN_486 23#define BETTER_THAN_486
25 24
@@ -33,788 +32,706 @@ static void rem_kernel(unsigned long long st0, unsigned long long *y,
33 precision of the result sometimes degrades to about 63.9 bits */ 32 precision of the result sometimes degrades to about 63.9 bits */
34static int trig_arg(FPU_REG *st0_ptr, int even) 33static int trig_arg(FPU_REG *st0_ptr, int even)
35{ 34{
36 FPU_REG tmp; 35 FPU_REG tmp;
37 u_char tmptag; 36 u_char tmptag;
38 unsigned long long q; 37 unsigned long long q;
39 int old_cw = control_word, saved_status = partial_status; 38 int old_cw = control_word, saved_status = partial_status;
40 int tag, st0_tag = TAG_Valid; 39 int tag, st0_tag = TAG_Valid;
41 40
42 if ( exponent(st0_ptr) >= 63 ) 41 if (exponent(st0_ptr) >= 63) {
43 { 42 partial_status |= SW_C2; /* Reduction incomplete. */
44 partial_status |= SW_C2; /* Reduction incomplete. */ 43 return -1;
45 return -1; 44 }
46 }
47
48 control_word &= ~CW_RC;
49 control_word |= RC_CHOP;
50
51 setpositive(st0_ptr);
52 tag = FPU_u_div(st0_ptr, &CONST_PI2, &tmp, PR_64_BITS | RC_CHOP | 0x3f,
53 SIGN_POS);
54
55 FPU_round_to_int(&tmp, tag); /* Fortunately, this can't overflow
56 to 2^64 */
57 q = significand(&tmp);
58 if ( q )
59 {
60 rem_kernel(significand(st0_ptr),
61 &significand(&tmp),
62 significand(&CONST_PI2),
63 q, exponent(st0_ptr) - exponent(&CONST_PI2));
64 setexponent16(&tmp, exponent(&CONST_PI2));
65 st0_tag = FPU_normalize(&tmp);
66 FPU_copy_to_reg0(&tmp, st0_tag);
67 }
68
69 if ( (even && !(q & 1)) || (!even && (q & 1)) )
70 {
71 st0_tag = FPU_sub(REV|LOADED|TAG_Valid, (int)&CONST_PI2, FULL_PRECISION);
72 45
73#ifdef BETTER_THAN_486 46 control_word &= ~CW_RC;
74 /* So far, the results are exact but based upon a 64 bit 47 control_word |= RC_CHOP;
75 precision approximation to pi/2. The technique used 48
76 now is equivalent to using an approximation to pi/2 which 49 setpositive(st0_ptr);
77 is accurate to about 128 bits. */ 50 tag = FPU_u_div(st0_ptr, &CONST_PI2, &tmp, PR_64_BITS | RC_CHOP | 0x3f,
78 if ( (exponent(st0_ptr) <= exponent(&CONST_PI2extra) + 64) || (q > 1) ) 51 SIGN_POS);
79 { 52
80 /* This code gives the effect of having pi/2 to better than 53 FPU_round_to_int(&tmp, tag); /* Fortunately, this can't overflow
81 128 bits precision. */ 54 to 2^64 */
82 55 q = significand(&tmp);
83 significand(&tmp) = q + 1; 56 if (q) {
84 setexponent16(&tmp, 63); 57 rem_kernel(significand(st0_ptr),
85 FPU_normalize(&tmp); 58 &significand(&tmp),
86 tmptag = 59 significand(&CONST_PI2),
87 FPU_u_mul(&CONST_PI2extra, &tmp, &tmp, FULL_PRECISION, SIGN_POS, 60 q, exponent(st0_ptr) - exponent(&CONST_PI2));
88 exponent(&CONST_PI2extra) + exponent(&tmp)); 61 setexponent16(&tmp, exponent(&CONST_PI2));
89 setsign(&tmp, getsign(&CONST_PI2extra)); 62 st0_tag = FPU_normalize(&tmp);
90 st0_tag = FPU_add(&tmp, tmptag, 0, FULL_PRECISION); 63 FPU_copy_to_reg0(&tmp, st0_tag);
91 if ( signnegative(st0_ptr) )
92 {
93 /* CONST_PI2extra is negative, so the result of the addition
94 can be negative. This means that the argument is actually
95 in a different quadrant. The correction is always < pi/2,
96 so it can't overflow into yet another quadrant. */
97 setpositive(st0_ptr);
98 q++;
99 }
100 } 64 }
65
66 if ((even && !(q & 1)) || (!even && (q & 1))) {
67 st0_tag =
68 FPU_sub(REV | LOADED | TAG_Valid, (int)&CONST_PI2,
69 FULL_PRECISION);
70
71#ifdef BETTER_THAN_486
72 /* So far, the results are exact but based upon a 64 bit
73 precision approximation to pi/2. The technique used
74 now is equivalent to using an approximation to pi/2 which
75 is accurate to about 128 bits. */
76 if ((exponent(st0_ptr) <= exponent(&CONST_PI2extra) + 64)
77 || (q > 1)) {
78 /* This code gives the effect of having pi/2 to better than
79 128 bits precision. */
80
81 significand(&tmp) = q + 1;
82 setexponent16(&tmp, 63);
83 FPU_normalize(&tmp);
84 tmptag =
85 FPU_u_mul(&CONST_PI2extra, &tmp, &tmp,
86 FULL_PRECISION, SIGN_POS,
87 exponent(&CONST_PI2extra) +
88 exponent(&tmp));
89 setsign(&tmp, getsign(&CONST_PI2extra));
90 st0_tag = FPU_add(&tmp, tmptag, 0, FULL_PRECISION);
91 if (signnegative(st0_ptr)) {
92 /* CONST_PI2extra is negative, so the result of the addition
93 can be negative. This means that the argument is actually
94 in a different quadrant. The correction is always < pi/2,
95 so it can't overflow into yet another quadrant. */
96 setpositive(st0_ptr);
97 q++;
98 }
99 }
101#endif /* BETTER_THAN_486 */ 100#endif /* BETTER_THAN_486 */
102 } 101 }
103#ifdef BETTER_THAN_486 102#ifdef BETTER_THAN_486
104 else 103 else {
105 { 104 /* So far, the results are exact but based upon a 64 bit
106 /* So far, the results are exact but based upon a 64 bit 105 precision approximation to pi/2. The technique used
107 precision approximation to pi/2. The technique used 106 now is equivalent to using an approximation to pi/2 which
108 now is equivalent to using an approximation to pi/2 which 107 is accurate to about 128 bits. */
109 is accurate to about 128 bits. */ 108 if (((q > 0)
110 if ( ((q > 0) && (exponent(st0_ptr) <= exponent(&CONST_PI2extra) + 64)) 109 && (exponent(st0_ptr) <= exponent(&CONST_PI2extra) + 64))
111 || (q > 1) ) 110 || (q > 1)) {
112 { 111 /* This code gives the effect of having p/2 to better than
113 /* This code gives the effect of having p/2 to better than 112 128 bits precision. */
114 128 bits precision. */ 113
115 114 significand(&tmp) = q;
116 significand(&tmp) = q; 115 setexponent16(&tmp, 63);
117 setexponent16(&tmp, 63); 116 FPU_normalize(&tmp); /* This must return TAG_Valid */
118 FPU_normalize(&tmp); /* This must return TAG_Valid */ 117 tmptag =
119 tmptag = FPU_u_mul(&CONST_PI2extra, &tmp, &tmp, FULL_PRECISION, 118 FPU_u_mul(&CONST_PI2extra, &tmp, &tmp,
120 SIGN_POS, 119 FULL_PRECISION, SIGN_POS,
121 exponent(&CONST_PI2extra) + exponent(&tmp)); 120 exponent(&CONST_PI2extra) +
122 setsign(&tmp, getsign(&CONST_PI2extra)); 121 exponent(&tmp));
123 st0_tag = FPU_sub(LOADED|(tmptag & 0x0f), (int)&tmp, 122 setsign(&tmp, getsign(&CONST_PI2extra));
124 FULL_PRECISION); 123 st0_tag = FPU_sub(LOADED | (tmptag & 0x0f), (int)&tmp,
125 if ( (exponent(st0_ptr) == exponent(&CONST_PI2)) && 124 FULL_PRECISION);
126 ((st0_ptr->sigh > CONST_PI2.sigh) 125 if ((exponent(st0_ptr) == exponent(&CONST_PI2)) &&
127 || ((st0_ptr->sigh == CONST_PI2.sigh) 126 ((st0_ptr->sigh > CONST_PI2.sigh)
128 && (st0_ptr->sigl > CONST_PI2.sigl))) ) 127 || ((st0_ptr->sigh == CONST_PI2.sigh)
129 { 128 && (st0_ptr->sigl > CONST_PI2.sigl)))) {
130 /* CONST_PI2extra is negative, so the result of the 129 /* CONST_PI2extra is negative, so the result of the
131 subtraction can be larger than pi/2. This means 130 subtraction can be larger than pi/2. This means
132 that the argument is actually in a different quadrant. 131 that the argument is actually in a different quadrant.
133 The correction is always < pi/2, so it can't overflow 132 The correction is always < pi/2, so it can't overflow
134 into yet another quadrant. */ 133 into yet another quadrant. */
135 st0_tag = FPU_sub(REV|LOADED|TAG_Valid, (int)&CONST_PI2, 134 st0_tag =
136 FULL_PRECISION); 135 FPU_sub(REV | LOADED | TAG_Valid,
137 q++; 136 (int)&CONST_PI2, FULL_PRECISION);
138 } 137 q++;
138 }
139 }
139 } 140 }
140 }
141#endif /* BETTER_THAN_486 */ 141#endif /* BETTER_THAN_486 */
142 142
143 FPU_settag0(st0_tag); 143 FPU_settag0(st0_tag);
144 control_word = old_cw; 144 control_word = old_cw;
145 partial_status = saved_status & ~SW_C2; /* Reduction complete. */ 145 partial_status = saved_status & ~SW_C2; /* Reduction complete. */
146 146
147 return (q & 3) | even; 147 return (q & 3) | even;
148} 148}
149 149
150
151/* Convert a long to register */ 150/* Convert a long to register */
152static void convert_l2reg(long const *arg, int deststnr) 151static void convert_l2reg(long const *arg, int deststnr)
153{ 152{
154 int tag; 153 int tag;
155 long num = *arg; 154 long num = *arg;
156 u_char sign; 155 u_char sign;
157 FPU_REG *dest = &st(deststnr); 156 FPU_REG *dest = &st(deststnr);
158
159 if (num == 0)
160 {
161 FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
162 return;
163 }
164
165 if (num > 0)
166 { sign = SIGN_POS; }
167 else
168 { num = -num; sign = SIGN_NEG; }
169
170 dest->sigh = num;
171 dest->sigl = 0;
172 setexponent16(dest, 31);
173 tag = FPU_normalize(dest);
174 FPU_settagi(deststnr, tag);
175 setsign(dest, sign);
176 return;
177}
178 157
158 if (num == 0) {
159 FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
160 return;
161 }
162
163 if (num > 0) {
164 sign = SIGN_POS;
165 } else {
166 num = -num;
167 sign = SIGN_NEG;
168 }
169
170 dest->sigh = num;
171 dest->sigl = 0;
172 setexponent16(dest, 31);
173 tag = FPU_normalize(dest);
174 FPU_settagi(deststnr, tag);
175 setsign(dest, sign);
176 return;
177}
179 178
180static void single_arg_error(FPU_REG *st0_ptr, u_char st0_tag) 179static void single_arg_error(FPU_REG *st0_ptr, u_char st0_tag)
181{ 180{
182 if ( st0_tag == TAG_Empty ) 181 if (st0_tag == TAG_Empty)
183 FPU_stack_underflow(); /* Puts a QNaN in st(0) */ 182 FPU_stack_underflow(); /* Puts a QNaN in st(0) */
184 else if ( st0_tag == TW_NaN ) 183 else if (st0_tag == TW_NaN)
185 real_1op_NaN(st0_ptr); /* return with a NaN in st(0) */ 184 real_1op_NaN(st0_ptr); /* return with a NaN in st(0) */
186#ifdef PARANOID 185#ifdef PARANOID
187 else 186 else
188 EXCEPTION(EX_INTERNAL|0x0112); 187 EXCEPTION(EX_INTERNAL | 0x0112);
189#endif /* PARANOID */ 188#endif /* PARANOID */
190} 189}
191 190
192
193static void single_arg_2_error(FPU_REG *st0_ptr, u_char st0_tag) 191static void single_arg_2_error(FPU_REG *st0_ptr, u_char st0_tag)
194{ 192{
195 int isNaN; 193 int isNaN;
196 194
197 switch ( st0_tag ) 195 switch (st0_tag) {
198 { 196 case TW_NaN:
199 case TW_NaN: 197 isNaN = (exponent(st0_ptr) == EXP_OVER)
200 isNaN = (exponent(st0_ptr) == EXP_OVER) && (st0_ptr->sigh & 0x80000000); 198 && (st0_ptr->sigh & 0x80000000);
201 if ( isNaN && !(st0_ptr->sigh & 0x40000000) ) /* Signaling ? */ 199 if (isNaN && !(st0_ptr->sigh & 0x40000000)) { /* Signaling ? */
202 { 200 EXCEPTION(EX_Invalid);
203 EXCEPTION(EX_Invalid); 201 if (control_word & CW_Invalid) {
204 if ( control_word & CW_Invalid ) 202 /* The masked response */
205 { 203 /* Convert to a QNaN */
206 /* The masked response */ 204 st0_ptr->sigh |= 0x40000000;
207 /* Convert to a QNaN */ 205 push();
208 st0_ptr->sigh |= 0x40000000; 206 FPU_copy_to_reg0(st0_ptr, TAG_Special);
209 push(); 207 }
210 FPU_copy_to_reg0(st0_ptr, TAG_Special); 208 } else if (isNaN) {
211 } 209 /* A QNaN */
212 } 210 push();
213 else if ( isNaN ) 211 FPU_copy_to_reg0(st0_ptr, TAG_Special);
214 { 212 } else {
215 /* A QNaN */ 213 /* pseudoNaN or other unsupported */
216 push(); 214 EXCEPTION(EX_Invalid);
217 FPU_copy_to_reg0(st0_ptr, TAG_Special); 215 if (control_word & CW_Invalid) {
218 } 216 /* The masked response */
219 else 217 FPU_copy_to_reg0(&CONST_QNaN, TAG_Special);
220 { 218 push();
221 /* pseudoNaN or other unsupported */ 219 FPU_copy_to_reg0(&CONST_QNaN, TAG_Special);
222 EXCEPTION(EX_Invalid); 220 }
223 if ( control_word & CW_Invalid ) 221 }
224 { 222 break; /* return with a NaN in st(0) */
225 /* The masked response */
226 FPU_copy_to_reg0(&CONST_QNaN, TAG_Special);
227 push();
228 FPU_copy_to_reg0(&CONST_QNaN, TAG_Special);
229 }
230 }
231 break; /* return with a NaN in st(0) */
232#ifdef PARANOID 223#ifdef PARANOID
233 default: 224 default:
234 EXCEPTION(EX_INTERNAL|0x0112); 225 EXCEPTION(EX_INTERNAL | 0x0112);
235#endif /* PARANOID */ 226#endif /* PARANOID */
236 } 227 }
237} 228}
238 229
239
240/*---------------------------------------------------------------------------*/ 230/*---------------------------------------------------------------------------*/
241 231
242static void f2xm1(FPU_REG *st0_ptr, u_char tag) 232static void f2xm1(FPU_REG *st0_ptr, u_char tag)
243{ 233{
244 FPU_REG a; 234 FPU_REG a;
245 235
246 clear_C1(); 236 clear_C1();
247 237
248 if ( tag == TAG_Valid ) 238 if (tag == TAG_Valid) {
249 { 239 /* For an 80486 FPU, the result is undefined if the arg is >= 1.0 */
250 /* For an 80486 FPU, the result is undefined if the arg is >= 1.0 */ 240 if (exponent(st0_ptr) < 0) {
251 if ( exponent(st0_ptr) < 0 ) 241 denormal_arg:
252 {
253 denormal_arg:
254 242
255 FPU_to_exp16(st0_ptr, &a); 243 FPU_to_exp16(st0_ptr, &a);
256 244
257 /* poly_2xm1(x) requires 0 < st(0) < 1. */ 245 /* poly_2xm1(x) requires 0 < st(0) < 1. */
258 poly_2xm1(getsign(st0_ptr), &a, st0_ptr); 246 poly_2xm1(getsign(st0_ptr), &a, st0_ptr);
247 }
248 set_precision_flag_up(); /* 80486 appears to always do this */
249 return;
259 } 250 }
260 set_precision_flag_up(); /* 80486 appears to always do this */
261 return;
262 }
263 251
264 if ( tag == TAG_Zero ) 252 if (tag == TAG_Zero)
265 return; 253 return;
266 254
267 if ( tag == TAG_Special ) 255 if (tag == TAG_Special)
268 tag = FPU_Special(st0_ptr); 256 tag = FPU_Special(st0_ptr);
269 257
270 switch ( tag ) 258 switch (tag) {
271 { 259 case TW_Denormal:
272 case TW_Denormal: 260 if (denormal_operand() < 0)
273 if ( denormal_operand() < 0 ) 261 return;
274 return; 262 goto denormal_arg;
275 goto denormal_arg; 263 case TW_Infinity:
276 case TW_Infinity: 264 if (signnegative(st0_ptr)) {
277 if ( signnegative(st0_ptr) ) 265 /* -infinity gives -1 (p16-10) */
278 { 266 FPU_copy_to_reg0(&CONST_1, TAG_Valid);
279 /* -infinity gives -1 (p16-10) */ 267 setnegative(st0_ptr);
280 FPU_copy_to_reg0(&CONST_1, TAG_Valid); 268 }
281 setnegative(st0_ptr); 269 return;
270 default:
271 single_arg_error(st0_ptr, tag);
282 } 272 }
283 return;
284 default:
285 single_arg_error(st0_ptr, tag);
286 }
287} 273}
288 274
289
290static void fptan(FPU_REG *st0_ptr, u_char st0_tag) 275static void fptan(FPU_REG *st0_ptr, u_char st0_tag)
291{ 276{
292 FPU_REG *st_new_ptr; 277 FPU_REG *st_new_ptr;
293 int q; 278 int q;
294 u_char arg_sign = getsign(st0_ptr); 279 u_char arg_sign = getsign(st0_ptr);
295 280
296 /* Stack underflow has higher priority */ 281 /* Stack underflow has higher priority */
297 if ( st0_tag == TAG_Empty ) 282 if (st0_tag == TAG_Empty) {
298 { 283 FPU_stack_underflow(); /* Puts a QNaN in st(0) */
299 FPU_stack_underflow(); /* Puts a QNaN in st(0) */ 284 if (control_word & CW_Invalid) {
300 if ( control_word & CW_Invalid ) 285 st_new_ptr = &st(-1);
301 { 286 push();
302 st_new_ptr = &st(-1); 287 FPU_stack_underflow(); /* Puts a QNaN in the new st(0) */
303 push(); 288 }
304 FPU_stack_underflow(); /* Puts a QNaN in the new st(0) */ 289 return;
305 } 290 }
306 return; 291
307 } 292 if (STACK_OVERFLOW) {
308 293 FPU_stack_overflow();
309 if ( STACK_OVERFLOW ) 294 return;
310 { FPU_stack_overflow(); return; }
311
312 if ( st0_tag == TAG_Valid )
313 {
314 if ( exponent(st0_ptr) > -40 )
315 {
316 if ( (q = trig_arg(st0_ptr, 0)) == -1 )
317 {
318 /* Operand is out of range */
319 return;
320 }
321
322 poly_tan(st0_ptr);
323 setsign(st0_ptr, (q & 1) ^ (arg_sign != 0));
324 set_precision_flag_up(); /* We do not really know if up or down */
325 } 295 }
326 else
327 {
328 /* For a small arg, the result == the argument */
329 /* Underflow may happen */
330 296
331 denormal_arg: 297 if (st0_tag == TAG_Valid) {
298 if (exponent(st0_ptr) > -40) {
299 if ((q = trig_arg(st0_ptr, 0)) == -1) {
300 /* Operand is out of range */
301 return;
302 }
303
304 poly_tan(st0_ptr);
305 setsign(st0_ptr, (q & 1) ^ (arg_sign != 0));
306 set_precision_flag_up(); /* We do not really know if up or down */
307 } else {
308 /* For a small arg, the result == the argument */
309 /* Underflow may happen */
310
311 denormal_arg:
312
313 FPU_to_exp16(st0_ptr, st0_ptr);
332 314
333 FPU_to_exp16(st0_ptr, st0_ptr); 315 st0_tag =
334 316 FPU_round(st0_ptr, 1, 0, FULL_PRECISION, arg_sign);
335 st0_tag = FPU_round(st0_ptr, 1, 0, FULL_PRECISION, arg_sign); 317 FPU_settag0(st0_tag);
336 FPU_settag0(st0_tag); 318 }
319 push();
320 FPU_copy_to_reg0(&CONST_1, TAG_Valid);
321 return;
337 } 322 }
338 push();
339 FPU_copy_to_reg0(&CONST_1, TAG_Valid);
340 return;
341 }
342
343 if ( st0_tag == TAG_Zero )
344 {
345 push();
346 FPU_copy_to_reg0(&CONST_1, TAG_Valid);
347 setcc(0);
348 return;
349 }
350
351 if ( st0_tag == TAG_Special )
352 st0_tag = FPU_Special(st0_ptr);
353
354 if ( st0_tag == TW_Denormal )
355 {
356 if ( denormal_operand() < 0 )
357 return;
358 323
359 goto denormal_arg; 324 if (st0_tag == TAG_Zero) {
360 } 325 push();
361 326 FPU_copy_to_reg0(&CONST_1, TAG_Valid);
362 if ( st0_tag == TW_Infinity ) 327 setcc(0);
363 { 328 return;
364 /* The 80486 treats infinity as an invalid operand */ 329 }
365 if ( arith_invalid(0) >= 0 ) 330
366 { 331 if (st0_tag == TAG_Special)
367 st_new_ptr = &st(-1); 332 st0_tag = FPU_Special(st0_ptr);
368 push(); 333
369 arith_invalid(0); 334 if (st0_tag == TW_Denormal) {
335 if (denormal_operand() < 0)
336 return;
337
338 goto denormal_arg;
370 } 339 }
371 return;
372 }
373 340
374 single_arg_2_error(st0_ptr, st0_tag); 341 if (st0_tag == TW_Infinity) {
375} 342 /* The 80486 treats infinity as an invalid operand */
343 if (arith_invalid(0) >= 0) {
344 st_new_ptr = &st(-1);
345 push();
346 arith_invalid(0);
347 }
348 return;
349 }
376 350
351 single_arg_2_error(st0_ptr, st0_tag);
352}
377 353
378static void fxtract(FPU_REG *st0_ptr, u_char st0_tag) 354static void fxtract(FPU_REG *st0_ptr, u_char st0_tag)
379{ 355{
380 FPU_REG *st_new_ptr; 356 FPU_REG *st_new_ptr;
381 u_char sign; 357 u_char sign;
382 register FPU_REG *st1_ptr = st0_ptr; /* anticipate */ 358 register FPU_REG *st1_ptr = st0_ptr; /* anticipate */
383
384 if ( STACK_OVERFLOW )
385 { FPU_stack_overflow(); return; }
386
387 clear_C1();
388
389 if ( st0_tag == TAG_Valid )
390 {
391 long e;
392
393 push();
394 sign = getsign(st1_ptr);
395 reg_copy(st1_ptr, st_new_ptr);
396 setexponent16(st_new_ptr, exponent(st_new_ptr));
397
398 denormal_arg:
399
400 e = exponent16(st_new_ptr);
401 convert_l2reg(&e, 1);
402 setexponentpos(st_new_ptr, 0);
403 setsign(st_new_ptr, sign);
404 FPU_settag0(TAG_Valid); /* Needed if arg was a denormal */
405 return;
406 }
407 else if ( st0_tag == TAG_Zero )
408 {
409 sign = getsign(st0_ptr);
410
411 if ( FPU_divide_by_zero(0, SIGN_NEG) < 0 )
412 return;
413 359
414 push(); 360 if (STACK_OVERFLOW) {
415 FPU_copy_to_reg0(&CONST_Z, TAG_Zero); 361 FPU_stack_overflow();
416 setsign(st_new_ptr, sign); 362 return;
417 return; 363 }
418 }
419 364
420 if ( st0_tag == TAG_Special ) 365 clear_C1();
421 st0_tag = FPU_Special(st0_ptr);
422 366
423 if ( st0_tag == TW_Denormal ) 367 if (st0_tag == TAG_Valid) {
424 { 368 long e;
425 if (denormal_operand() < 0 )
426 return;
427 369
428 push(); 370 push();
429 sign = getsign(st1_ptr); 371 sign = getsign(st1_ptr);
430 FPU_to_exp16(st1_ptr, st_new_ptr); 372 reg_copy(st1_ptr, st_new_ptr);
431 goto denormal_arg; 373 setexponent16(st_new_ptr, exponent(st_new_ptr));
432 } 374
433 else if ( st0_tag == TW_Infinity ) 375 denormal_arg:
434 { 376
435 sign = getsign(st0_ptr); 377 e = exponent16(st_new_ptr);
436 setpositive(st0_ptr); 378 convert_l2reg(&e, 1);
437 push(); 379 setexponentpos(st_new_ptr, 0);
438 FPU_copy_to_reg0(&CONST_INF, TAG_Special); 380 setsign(st_new_ptr, sign);
439 setsign(st_new_ptr, sign); 381 FPU_settag0(TAG_Valid); /* Needed if arg was a denormal */
440 return; 382 return;
441 } 383 } else if (st0_tag == TAG_Zero) {
442 else if ( st0_tag == TW_NaN ) 384 sign = getsign(st0_ptr);
443 { 385
444 if ( real_1op_NaN(st0_ptr) < 0 ) 386 if (FPU_divide_by_zero(0, SIGN_NEG) < 0)
445 return; 387 return;
446 388
447 push(); 389 push();
448 FPU_copy_to_reg0(st0_ptr, TAG_Special); 390 FPU_copy_to_reg0(&CONST_Z, TAG_Zero);
449 return; 391 setsign(st_new_ptr, sign);
450 } 392 return;
451 else if ( st0_tag == TAG_Empty ) 393 }
452 { 394
453 /* Is this the correct behaviour? */ 395 if (st0_tag == TAG_Special)
454 if ( control_word & EX_Invalid ) 396 st0_tag = FPU_Special(st0_ptr);
455 { 397
456 FPU_stack_underflow(); 398 if (st0_tag == TW_Denormal) {
457 push(); 399 if (denormal_operand() < 0)
458 FPU_stack_underflow(); 400 return;
401
402 push();
403 sign = getsign(st1_ptr);
404 FPU_to_exp16(st1_ptr, st_new_ptr);
405 goto denormal_arg;
406 } else if (st0_tag == TW_Infinity) {
407 sign = getsign(st0_ptr);
408 setpositive(st0_ptr);
409 push();
410 FPU_copy_to_reg0(&CONST_INF, TAG_Special);
411 setsign(st_new_ptr, sign);
412 return;
413 } else if (st0_tag == TW_NaN) {
414 if (real_1op_NaN(st0_ptr) < 0)
415 return;
416
417 push();
418 FPU_copy_to_reg0(st0_ptr, TAG_Special);
419 return;
420 } else if (st0_tag == TAG_Empty) {
421 /* Is this the correct behaviour? */
422 if (control_word & EX_Invalid) {
423 FPU_stack_underflow();
424 push();
425 FPU_stack_underflow();
426 } else
427 EXCEPTION(EX_StackUnder);
459 } 428 }
460 else
461 EXCEPTION(EX_StackUnder);
462 }
463#ifdef PARANOID 429#ifdef PARANOID
464 else 430 else
465 EXCEPTION(EX_INTERNAL | 0x119); 431 EXCEPTION(EX_INTERNAL | 0x119);
466#endif /* PARANOID */ 432#endif /* PARANOID */
467} 433}
468 434
469
470static void fdecstp(void) 435static void fdecstp(void)
471{ 436{
472 clear_C1(); 437 clear_C1();
473 top--; 438 top--;
474} 439}
475 440
476static void fincstp(void) 441static void fincstp(void)
477{ 442{
478 clear_C1(); 443 clear_C1();
479 top++; 444 top++;
480} 445}
481 446
482
483static void fsqrt_(FPU_REG *st0_ptr, u_char st0_tag) 447static void fsqrt_(FPU_REG *st0_ptr, u_char st0_tag)
484{ 448{
485 int expon; 449 int expon;
486 450
487 clear_C1(); 451 clear_C1();
488
489 if ( st0_tag == TAG_Valid )
490 {
491 u_char tag;
492
493 if (signnegative(st0_ptr))
494 {
495 arith_invalid(0); /* sqrt(negative) is invalid */
496 return;
497 }
498 452
499 /* make st(0) in [1.0 .. 4.0) */ 453 if (st0_tag == TAG_Valid) {
500 expon = exponent(st0_ptr); 454 u_char tag;
501 455
502 denormal_arg: 456 if (signnegative(st0_ptr)) {
503 457 arith_invalid(0); /* sqrt(negative) is invalid */
504 setexponent16(st0_ptr, (expon & 1)); 458 return;
505 459 }
506 /* Do the computation, the sign of the result will be positive. */ 460
507 tag = wm_sqrt(st0_ptr, 0, 0, control_word, SIGN_POS); 461 /* make st(0) in [1.0 .. 4.0) */
508 addexponent(st0_ptr, expon >> 1); 462 expon = exponent(st0_ptr);
509 FPU_settag0(tag); 463
510 return; 464 denormal_arg:
511 } 465
512 466 setexponent16(st0_ptr, (expon & 1));
513 if ( st0_tag == TAG_Zero ) 467
514 return; 468 /* Do the computation, the sign of the result will be positive. */
515 469 tag = wm_sqrt(st0_ptr, 0, 0, control_word, SIGN_POS);
516 if ( st0_tag == TAG_Special ) 470 addexponent(st0_ptr, expon >> 1);
517 st0_tag = FPU_Special(st0_ptr); 471 FPU_settag0(tag);
518 472 return;
519 if ( st0_tag == TW_Infinity )
520 {
521 if ( signnegative(st0_ptr) )
522 arith_invalid(0); /* sqrt(-Infinity) is invalid */
523 return;
524 }
525 else if ( st0_tag == TW_Denormal )
526 {
527 if (signnegative(st0_ptr))
528 {
529 arith_invalid(0); /* sqrt(negative) is invalid */
530 return;
531 } 473 }
532 474
533 if ( denormal_operand() < 0 ) 475 if (st0_tag == TAG_Zero)
534 return; 476 return;
535 477
536 FPU_to_exp16(st0_ptr, st0_ptr); 478 if (st0_tag == TAG_Special)
479 st0_tag = FPU_Special(st0_ptr);
537 480
538 expon = exponent16(st0_ptr); 481 if (st0_tag == TW_Infinity) {
482 if (signnegative(st0_ptr))
483 arith_invalid(0); /* sqrt(-Infinity) is invalid */
484 return;
485 } else if (st0_tag == TW_Denormal) {
486 if (signnegative(st0_ptr)) {
487 arith_invalid(0); /* sqrt(negative) is invalid */
488 return;
489 }
539 490
540 goto denormal_arg; 491 if (denormal_operand() < 0)
541 } 492 return;
542 493
543 single_arg_error(st0_ptr, st0_tag); 494 FPU_to_exp16(st0_ptr, st0_ptr);
544 495
545} 496 expon = exponent16(st0_ptr);
497
498 goto denormal_arg;
499 }
546 500
501 single_arg_error(st0_ptr, st0_tag);
502
503}
547 504
548static void frndint_(FPU_REG *st0_ptr, u_char st0_tag) 505static void frndint_(FPU_REG *st0_ptr, u_char st0_tag)
549{ 506{
550 int flags, tag; 507 int flags, tag;
551 508
552 if ( st0_tag == TAG_Valid ) 509 if (st0_tag == TAG_Valid) {
553 { 510 u_char sign;
554 u_char sign;
555 511
556 denormal_arg: 512 denormal_arg:
557 513
558 sign = getsign(st0_ptr); 514 sign = getsign(st0_ptr);
559 515
560 if (exponent(st0_ptr) > 63) 516 if (exponent(st0_ptr) > 63)
561 return; 517 return;
518
519 if (st0_tag == TW_Denormal) {
520 if (denormal_operand() < 0)
521 return;
522 }
523
524 /* Fortunately, this can't overflow to 2^64 */
525 if ((flags = FPU_round_to_int(st0_ptr, st0_tag)))
526 set_precision_flag(flags);
562 527
563 if ( st0_tag == TW_Denormal ) 528 setexponent16(st0_ptr, 63);
564 { 529 tag = FPU_normalize(st0_ptr);
565 if (denormal_operand() < 0 ) 530 setsign(st0_ptr, sign);
566 return; 531 FPU_settag0(tag);
532 return;
567 } 533 }
568 534
569 /* Fortunately, this can't overflow to 2^64 */ 535 if (st0_tag == TAG_Zero)
570 if ( (flags = FPU_round_to_int(st0_ptr, st0_tag)) ) 536 return;
571 set_precision_flag(flags);
572
573 setexponent16(st0_ptr, 63);
574 tag = FPU_normalize(st0_ptr);
575 setsign(st0_ptr, sign);
576 FPU_settag0(tag);
577 return;
578 }
579
580 if ( st0_tag == TAG_Zero )
581 return;
582
583 if ( st0_tag == TAG_Special )
584 st0_tag = FPU_Special(st0_ptr);
585
586 if ( st0_tag == TW_Denormal )
587 goto denormal_arg;
588 else if ( st0_tag == TW_Infinity )
589 return;
590 else
591 single_arg_error(st0_ptr, st0_tag);
592}
593 537
538 if (st0_tag == TAG_Special)
539 st0_tag = FPU_Special(st0_ptr);
540
541 if (st0_tag == TW_Denormal)
542 goto denormal_arg;
543 else if (st0_tag == TW_Infinity)
544 return;
545 else
546 single_arg_error(st0_ptr, st0_tag);
547}
594 548
595static int fsin(FPU_REG *st0_ptr, u_char tag) 549static int fsin(FPU_REG *st0_ptr, u_char tag)
596{ 550{
597 u_char arg_sign = getsign(st0_ptr); 551 u_char arg_sign = getsign(st0_ptr);
598 552
599 if ( tag == TAG_Valid ) 553 if (tag == TAG_Valid) {
600 { 554 int q;
601 int q; 555
602 556 if (exponent(st0_ptr) > -40) {
603 if ( exponent(st0_ptr) > -40 ) 557 if ((q = trig_arg(st0_ptr, 0)) == -1) {
604 { 558 /* Operand is out of range */
605 if ( (q = trig_arg(st0_ptr, 0)) == -1 ) 559 return 1;
606 { 560 }
607 /* Operand is out of range */ 561
608 return 1; 562 poly_sine(st0_ptr);
609 } 563
610 564 if (q & 2)
611 poly_sine(st0_ptr); 565 changesign(st0_ptr);
612 566
613 if (q & 2) 567 setsign(st0_ptr, getsign(st0_ptr) ^ arg_sign);
614 changesign(st0_ptr); 568
615 569 /* We do not really know if up or down */
616 setsign(st0_ptr, getsign(st0_ptr) ^ arg_sign); 570 set_precision_flag_up();
617 571 return 0;
618 /* We do not really know if up or down */ 572 } else {
619 set_precision_flag_up(); 573 /* For a small arg, the result == the argument */
620 return 0; 574 set_precision_flag_up(); /* Must be up. */
575 return 0;
576 }
621 } 577 }
622 else 578
623 { 579 if (tag == TAG_Zero) {
624 /* For a small arg, the result == the argument */ 580 setcc(0);
625 set_precision_flag_up(); /* Must be up. */ 581 return 0;
626 return 0;
627 } 582 }
628 }
629
630 if ( tag == TAG_Zero )
631 {
632 setcc(0);
633 return 0;
634 }
635
636 if ( tag == TAG_Special )
637 tag = FPU_Special(st0_ptr);
638
639 if ( tag == TW_Denormal )
640 {
641 if ( denormal_operand() < 0 )
642 return 1;
643
644 /* For a small arg, the result == the argument */
645 /* Underflow may happen */
646 FPU_to_exp16(st0_ptr, st0_ptr);
647
648 tag = FPU_round(st0_ptr, 1, 0, FULL_PRECISION, arg_sign);
649
650 FPU_settag0(tag);
651
652 return 0;
653 }
654 else if ( tag == TW_Infinity )
655 {
656 /* The 80486 treats infinity as an invalid operand */
657 arith_invalid(0);
658 return 1;
659 }
660 else
661 {
662 single_arg_error(st0_ptr, tag);
663 return 1;
664 }
665}
666 583
584 if (tag == TAG_Special)
585 tag = FPU_Special(st0_ptr);
586
587 if (tag == TW_Denormal) {
588 if (denormal_operand() < 0)
589 return 1;
590
591 /* For a small arg, the result == the argument */
592 /* Underflow may happen */
593 FPU_to_exp16(st0_ptr, st0_ptr);
594
595 tag = FPU_round(st0_ptr, 1, 0, FULL_PRECISION, arg_sign);
596
597 FPU_settag0(tag);
598
599 return 0;
600 } else if (tag == TW_Infinity) {
601 /* The 80486 treats infinity as an invalid operand */
602 arith_invalid(0);
603 return 1;
604 } else {
605 single_arg_error(st0_ptr, tag);
606 return 1;
607 }
608}
667 609
668static int f_cos(FPU_REG *st0_ptr, u_char tag) 610static int f_cos(FPU_REG *st0_ptr, u_char tag)
669{ 611{
670 u_char st0_sign; 612 u_char st0_sign;
671 613
672 st0_sign = getsign(st0_ptr); 614 st0_sign = getsign(st0_ptr);
673
674 if ( tag == TAG_Valid )
675 {
676 int q;
677
678 if ( exponent(st0_ptr) > -40 )
679 {
680 if ( (exponent(st0_ptr) < 0)
681 || ((exponent(st0_ptr) == 0)
682 && (significand(st0_ptr) <= 0xc90fdaa22168c234LL)) )
683 {
684 poly_cos(st0_ptr);
685
686 /* We do not really know if up or down */
687 set_precision_flag_down();
688
689 return 0;
690 }
691 else if ( (q = trig_arg(st0_ptr, FCOS)) != -1 )
692 {
693 poly_sine(st0_ptr);
694
695 if ((q+1) & 2)
696 changesign(st0_ptr);
697
698 /* We do not really know if up or down */
699 set_precision_flag_down();
700
701 return 0;
702 }
703 else
704 {
705 /* Operand is out of range */
706 return 1;
707 }
708 }
709 else
710 {
711 denormal_arg:
712 615
713 setcc(0); 616 if (tag == TAG_Valid) {
714 FPU_copy_to_reg0(&CONST_1, TAG_Valid); 617 int q;
618
619 if (exponent(st0_ptr) > -40) {
620 if ((exponent(st0_ptr) < 0)
621 || ((exponent(st0_ptr) == 0)
622 && (significand(st0_ptr) <=
623 0xc90fdaa22168c234LL))) {
624 poly_cos(st0_ptr);
625
626 /* We do not really know if up or down */
627 set_precision_flag_down();
628
629 return 0;
630 } else if ((q = trig_arg(st0_ptr, FCOS)) != -1) {
631 poly_sine(st0_ptr);
632
633 if ((q + 1) & 2)
634 changesign(st0_ptr);
635
636 /* We do not really know if up or down */
637 set_precision_flag_down();
638
639 return 0;
640 } else {
641 /* Operand is out of range */
642 return 1;
643 }
644 } else {
645 denormal_arg:
646
647 setcc(0);
648 FPU_copy_to_reg0(&CONST_1, TAG_Valid);
715#ifdef PECULIAR_486 649#ifdef PECULIAR_486
716 set_precision_flag_down(); /* 80486 appears to do this. */ 650 set_precision_flag_down(); /* 80486 appears to do this. */
717#else 651#else
718 set_precision_flag_up(); /* Must be up. */ 652 set_precision_flag_up(); /* Must be up. */
719#endif /* PECULIAR_486 */ 653#endif /* PECULIAR_486 */
720 return 0; 654 return 0;
655 }
656 } else if (tag == TAG_Zero) {
657 FPU_copy_to_reg0(&CONST_1, TAG_Valid);
658 setcc(0);
659 return 0;
721 } 660 }
722 }
723 else if ( tag == TAG_Zero )
724 {
725 FPU_copy_to_reg0(&CONST_1, TAG_Valid);
726 setcc(0);
727 return 0;
728 }
729
730 if ( tag == TAG_Special )
731 tag = FPU_Special(st0_ptr);
732
733 if ( tag == TW_Denormal )
734 {
735 if ( denormal_operand() < 0 )
736 return 1;
737
738 goto denormal_arg;
739 }
740 else if ( tag == TW_Infinity )
741 {
742 /* The 80486 treats infinity as an invalid operand */
743 arith_invalid(0);
744 return 1;
745 }
746 else
747 {
748 single_arg_error(st0_ptr, tag); /* requires st0_ptr == &st(0) */
749 return 1;
750 }
751}
752 661
662 if (tag == TAG_Special)
663 tag = FPU_Special(st0_ptr);
664
665 if (tag == TW_Denormal) {
666 if (denormal_operand() < 0)
667 return 1;
668
669 goto denormal_arg;
670 } else if (tag == TW_Infinity) {
671 /* The 80486 treats infinity as an invalid operand */
672 arith_invalid(0);
673 return 1;
674 } else {
675 single_arg_error(st0_ptr, tag); /* requires st0_ptr == &st(0) */
676 return 1;
677 }
678}
753 679
754static void fcos(FPU_REG *st0_ptr, u_char st0_tag) 680static void fcos(FPU_REG *st0_ptr, u_char st0_tag)
755{ 681{
756 f_cos(st0_ptr, st0_tag); 682 f_cos(st0_ptr, st0_tag);
757} 683}
758 684
759
760static void fsincos(FPU_REG *st0_ptr, u_char st0_tag) 685static void fsincos(FPU_REG *st0_ptr, u_char st0_tag)
761{ 686{
762 FPU_REG *st_new_ptr; 687 FPU_REG *st_new_ptr;
763 FPU_REG arg; 688 FPU_REG arg;
764 u_char tag; 689 u_char tag;
765 690
766 /* Stack underflow has higher priority */ 691 /* Stack underflow has higher priority */
767 if ( st0_tag == TAG_Empty ) 692 if (st0_tag == TAG_Empty) {
768 { 693 FPU_stack_underflow(); /* Puts a QNaN in st(0) */
769 FPU_stack_underflow(); /* Puts a QNaN in st(0) */ 694 if (control_word & CW_Invalid) {
770 if ( control_word & CW_Invalid ) 695 st_new_ptr = &st(-1);
771 { 696 push();
772 st_new_ptr = &st(-1); 697 FPU_stack_underflow(); /* Puts a QNaN in the new st(0) */
773 push(); 698 }
774 FPU_stack_underflow(); /* Puts a QNaN in the new st(0) */ 699 return;
775 } 700 }
776 return; 701
777 } 702 if (STACK_OVERFLOW) {
778 703 FPU_stack_overflow();
779 if ( STACK_OVERFLOW ) 704 return;
780 { FPU_stack_overflow(); return; }
781
782 if ( st0_tag == TAG_Special )
783 tag = FPU_Special(st0_ptr);
784 else
785 tag = st0_tag;
786
787 if ( tag == TW_NaN )
788 {
789 single_arg_2_error(st0_ptr, TW_NaN);
790 return;
791 }
792 else if ( tag == TW_Infinity )
793 {
794 /* The 80486 treats infinity as an invalid operand */
795 if ( arith_invalid(0) >= 0 )
796 {
797 /* Masked response */
798 push();
799 arith_invalid(0);
800 } 705 }
801 return;
802 }
803
804 reg_copy(st0_ptr, &arg);
805 if ( !fsin(st0_ptr, st0_tag) )
806 {
807 push();
808 FPU_copy_to_reg0(&arg, st0_tag);
809 f_cos(&st(0), st0_tag);
810 }
811 else
812 {
813 /* An error, so restore st(0) */
814 FPU_copy_to_reg0(&arg, st0_tag);
815 }
816}
817 706
707 if (st0_tag == TAG_Special)
708 tag = FPU_Special(st0_ptr);
709 else
710 tag = st0_tag;
711
712 if (tag == TW_NaN) {
713 single_arg_2_error(st0_ptr, TW_NaN);
714 return;
715 } else if (tag == TW_Infinity) {
716 /* The 80486 treats infinity as an invalid operand */
717 if (arith_invalid(0) >= 0) {
718 /* Masked response */
719 push();
720 arith_invalid(0);
721 }
722 return;
723 }
724
725 reg_copy(st0_ptr, &arg);
726 if (!fsin(st0_ptr, st0_tag)) {
727 push();
728 FPU_copy_to_reg0(&arg, st0_tag);
729 f_cos(&st(0), st0_tag);
730 } else {
731 /* An error, so restore st(0) */
732 FPU_copy_to_reg0(&arg, st0_tag);
733 }
734}
818 735
819/*---------------------------------------------------------------------------*/ 736/*---------------------------------------------------------------------------*/
820/* The following all require two arguments: st(0) and st(1) */ 737/* The following all require two arguments: st(0) and st(1) */
@@ -826,1020 +743,901 @@ static void fsincos(FPU_REG *st0_ptr, u_char st0_tag)
826 result must be zero. 743 result must be zero.
827 */ 744 */
828static void rem_kernel(unsigned long long st0, unsigned long long *y, 745static void rem_kernel(unsigned long long st0, unsigned long long *y,
829 unsigned long long st1, 746 unsigned long long st1, unsigned long long q, int n)
830 unsigned long long q, int n)
831{ 747{
832 int dummy; 748 int dummy;
833 unsigned long long x; 749 unsigned long long x;
834 750
835 x = st0 << n; 751 x = st0 << n;
836 752
837 /* Do the required multiplication and subtraction in the one operation */ 753 /* Do the required multiplication and subtraction in the one operation */
838 754
839 /* lsw x -= lsw st1 * lsw q */ 755 /* lsw x -= lsw st1 * lsw q */
840 asm volatile ("mull %4; subl %%eax,%0; sbbl %%edx,%1" 756 asm volatile ("mull %4; subl %%eax,%0; sbbl %%edx,%1":"=m"
841 :"=m" (((unsigned *)&x)[0]), "=m" (((unsigned *)&x)[1]), 757 (((unsigned *)&x)[0]), "=m"(((unsigned *)&x)[1]),
842 "=a" (dummy) 758 "=a"(dummy)
843 :"2" (((unsigned *)&st1)[0]), "m" (((unsigned *)&q)[0]) 759 :"2"(((unsigned *)&st1)[0]), "m"(((unsigned *)&q)[0])
844 :"%dx"); 760 :"%dx");
845 /* msw x -= msw st1 * lsw q */ 761 /* msw x -= msw st1 * lsw q */
846 asm volatile ("mull %3; subl %%eax,%0" 762 asm volatile ("mull %3; subl %%eax,%0":"=m" (((unsigned *)&x)[1]),
847 :"=m" (((unsigned *)&x)[1]), "=a" (dummy) 763 "=a"(dummy)
848 :"1" (((unsigned *)&st1)[1]), "m" (((unsigned *)&q)[0]) 764 :"1"(((unsigned *)&st1)[1]), "m"(((unsigned *)&q)[0])
849 :"%dx"); 765 :"%dx");
850 /* msw x -= lsw st1 * msw q */ 766 /* msw x -= lsw st1 * msw q */
851 asm volatile ("mull %3; subl %%eax,%0" 767 asm volatile ("mull %3; subl %%eax,%0":"=m" (((unsigned *)&x)[1]),
852 :"=m" (((unsigned *)&x)[1]), "=a" (dummy) 768 "=a"(dummy)
853 :"1" (((unsigned *)&st1)[0]), "m" (((unsigned *)&q)[1]) 769 :"1"(((unsigned *)&st1)[0]), "m"(((unsigned *)&q)[1])
854 :"%dx"); 770 :"%dx");
855 771
856 *y = x; 772 *y = x;
857} 773}
858 774
859
860/* Remainder of st(0) / st(1) */ 775/* Remainder of st(0) / st(1) */
861/* This routine produces exact results, i.e. there is never any 776/* This routine produces exact results, i.e. there is never any
862 rounding or truncation, etc of the result. */ 777 rounding or truncation, etc of the result. */
863static void do_fprem(FPU_REG *st0_ptr, u_char st0_tag, int round) 778static void do_fprem(FPU_REG *st0_ptr, u_char st0_tag, int round)
864{ 779{
865 FPU_REG *st1_ptr = &st(1); 780 FPU_REG *st1_ptr = &st(1);
866 u_char st1_tag = FPU_gettagi(1); 781 u_char st1_tag = FPU_gettagi(1);
867 782
868 if ( !((st0_tag ^ TAG_Valid) | (st1_tag ^ TAG_Valid)) ) 783 if (!((st0_tag ^ TAG_Valid) | (st1_tag ^ TAG_Valid))) {
869 { 784 FPU_REG tmp, st0, st1;
870 FPU_REG tmp, st0, st1; 785 u_char st0_sign, st1_sign;
871 u_char st0_sign, st1_sign; 786 u_char tmptag;
872 u_char tmptag; 787 int tag;
873 int tag; 788 int old_cw;
874 int old_cw; 789 int expdif;
875 int expdif; 790 long long q;
876 long long q; 791 unsigned short saved_status;
877 unsigned short saved_status; 792 int cc;
878 int cc; 793
879 794 fprem_valid:
880 fprem_valid: 795 /* Convert registers for internal use. */
881 /* Convert registers for internal use. */ 796 st0_sign = FPU_to_exp16(st0_ptr, &st0);
882 st0_sign = FPU_to_exp16(st0_ptr, &st0); 797 st1_sign = FPU_to_exp16(st1_ptr, &st1);
883 st1_sign = FPU_to_exp16(st1_ptr, &st1); 798 expdif = exponent16(&st0) - exponent16(&st1);
884 expdif = exponent16(&st0) - exponent16(&st1); 799
885 800 old_cw = control_word;
886 old_cw = control_word; 801 cc = 0;
887 cc = 0; 802
888 803 /* We want the status following the denorm tests, but don't want
889 /* We want the status following the denorm tests, but don't want 804 the status changed by the arithmetic operations. */
890 the status changed by the arithmetic operations. */ 805 saved_status = partial_status;
891 saved_status = partial_status; 806 control_word &= ~CW_RC;
892 control_word &= ~CW_RC; 807 control_word |= RC_CHOP;
893 control_word |= RC_CHOP; 808
894 809 if (expdif < 64) {
895 if ( expdif < 64 ) 810 /* This should be the most common case */
896 { 811
897 /* This should be the most common case */ 812 if (expdif > -2) {
898 813 u_char sign = st0_sign ^ st1_sign;
899 if ( expdif > -2 ) 814 tag = FPU_u_div(&st0, &st1, &tmp,
900 { 815 PR_64_BITS | RC_CHOP | 0x3f,
901 u_char sign = st0_sign ^ st1_sign; 816 sign);
902 tag = FPU_u_div(&st0, &st1, &tmp, 817 setsign(&tmp, sign);
903 PR_64_BITS | RC_CHOP | 0x3f, 818
904 sign); 819 if (exponent(&tmp) >= 0) {
905 setsign(&tmp, sign); 820 FPU_round_to_int(&tmp, tag); /* Fortunately, this can't
906 821 overflow to 2^64 */
907 if ( exponent(&tmp) >= 0 ) 822 q = significand(&tmp);
908 { 823
909 FPU_round_to_int(&tmp, tag); /* Fortunately, this can't 824 rem_kernel(significand(&st0),
910 overflow to 2^64 */ 825 &significand(&tmp),
911 q = significand(&tmp); 826 significand(&st1),
912 827 q, expdif);
913 rem_kernel(significand(&st0), 828
914 &significand(&tmp), 829 setexponent16(&tmp, exponent16(&st1));
915 significand(&st1), 830 } else {
916 q, expdif); 831 reg_copy(&st0, &tmp);
917 832 q = 0;
918 setexponent16(&tmp, exponent16(&st1)); 833 }
919 } 834
920 else 835 if ((round == RC_RND)
921 { 836 && (tmp.sigh & 0xc0000000)) {
922 reg_copy(&st0, &tmp); 837 /* We may need to subtract st(1) once more,
923 q = 0; 838 to get a result <= 1/2 of st(1). */
924 } 839 unsigned long long x;
925 840 expdif =
926 if ( (round == RC_RND) && (tmp.sigh & 0xc0000000) ) 841 exponent16(&st1) - exponent16(&tmp);
927 { 842 if (expdif <= 1) {
928 /* We may need to subtract st(1) once more, 843 if (expdif == 0)
929 to get a result <= 1/2 of st(1). */ 844 x = significand(&st1) -
930 unsigned long long x; 845 significand(&tmp);
931 expdif = exponent16(&st1) - exponent16(&tmp); 846 else /* expdif is 1 */
932 if ( expdif <= 1 ) 847 x = (significand(&st1)
933 { 848 << 1) -
934 if ( expdif == 0 ) 849 significand(&tmp);
935 x = significand(&st1) - significand(&tmp); 850 if ((x < significand(&tmp)) ||
936 else /* expdif is 1 */ 851 /* or equi-distant (from 0 & st(1)) and q is odd */
937 x = (significand(&st1) << 1) - significand(&tmp); 852 ((x == significand(&tmp))
938 if ( (x < significand(&tmp)) || 853 && (q & 1))) {
939 /* or equi-distant (from 0 & st(1)) and q is odd */ 854 st0_sign = !st0_sign;
940 ((x == significand(&tmp)) && (q & 1) ) ) 855 significand(&tmp) = x;
941 { 856 q++;
942 st0_sign = ! st0_sign; 857 }
943 significand(&tmp) = x; 858 }
944 q++; 859 }
860
861 if (q & 4)
862 cc |= SW_C0;
863 if (q & 2)
864 cc |= SW_C3;
865 if (q & 1)
866 cc |= SW_C1;
867 } else {
868 control_word = old_cw;
869 setcc(0);
870 return;
945 } 871 }
946 } 872 } else {
947 } 873 /* There is a large exponent difference ( >= 64 ) */
948 874 /* To make much sense, the code in this section should
949 if (q & 4) cc |= SW_C0; 875 be done at high precision. */
950 if (q & 2) cc |= SW_C3; 876 int exp_1, N;
951 if (q & 1) cc |= SW_C1; 877 u_char sign;
952 } 878
953 else 879 /* prevent overflow here */
954 { 880 /* N is 'a number between 32 and 63' (p26-113) */
955 control_word = old_cw; 881 reg_copy(&st0, &tmp);
956 setcc(0); 882 tmptag = st0_tag;
957 return; 883 N = (expdif & 0x0000001f) + 32; /* This choice gives results
958 } 884 identical to an AMD 486 */
959 } 885 setexponent16(&tmp, N);
960 else 886 exp_1 = exponent16(&st1);
961 { 887 setexponent16(&st1, 0);
962 /* There is a large exponent difference ( >= 64 ) */ 888 expdif -= N;
963 /* To make much sense, the code in this section should 889
964 be done at high precision. */ 890 sign = getsign(&tmp) ^ st1_sign;
965 int exp_1, N; 891 tag =
966 u_char sign; 892 FPU_u_div(&tmp, &st1, &tmp,
967 893 PR_64_BITS | RC_CHOP | 0x3f, sign);
968 /* prevent overflow here */ 894 setsign(&tmp, sign);
969 /* N is 'a number between 32 and 63' (p26-113) */ 895
970 reg_copy(&st0, &tmp); 896 FPU_round_to_int(&tmp, tag); /* Fortunately, this can't
971 tmptag = st0_tag; 897 overflow to 2^64 */
972 N = (expdif & 0x0000001f) + 32; /* This choice gives results 898
973 identical to an AMD 486 */ 899 rem_kernel(significand(&st0),
974 setexponent16(&tmp, N); 900 &significand(&tmp),
975 exp_1 = exponent16(&st1); 901 significand(&st1),
976 setexponent16(&st1, 0); 902 significand(&tmp), exponent(&tmp)
977 expdif -= N; 903 );
978 904 setexponent16(&tmp, exp_1 + expdif);
979 sign = getsign(&tmp) ^ st1_sign; 905
980 tag = FPU_u_div(&tmp, &st1, &tmp, PR_64_BITS | RC_CHOP | 0x3f, 906 /* It is possible for the operation to be complete here.
981 sign); 907 What does the IEEE standard say? The Intel 80486 manual
982 setsign(&tmp, sign); 908 implies that the operation will never be completed at this
983 909 point, and the behaviour of a real 80486 confirms this.
984 FPU_round_to_int(&tmp, tag); /* Fortunately, this can't 910 */
985 overflow to 2^64 */ 911 if (!(tmp.sigh | tmp.sigl)) {
986 912 /* The result is zero */
987 rem_kernel(significand(&st0), 913 control_word = old_cw;
988 &significand(&tmp), 914 partial_status = saved_status;
989 significand(&st1), 915 FPU_copy_to_reg0(&CONST_Z, TAG_Zero);
990 significand(&tmp), 916 setsign(&st0, st0_sign);
991 exponent(&tmp)
992 );
993 setexponent16(&tmp, exp_1 + expdif);
994
995 /* It is possible for the operation to be complete here.
996 What does the IEEE standard say? The Intel 80486 manual
997 implies that the operation will never be completed at this
998 point, and the behaviour of a real 80486 confirms this.
999 */
1000 if ( !(tmp.sigh | tmp.sigl) )
1001 {
1002 /* The result is zero */
1003 control_word = old_cw;
1004 partial_status = saved_status;
1005 FPU_copy_to_reg0(&CONST_Z, TAG_Zero);
1006 setsign(&st0, st0_sign);
1007#ifdef PECULIAR_486 917#ifdef PECULIAR_486
1008 setcc(SW_C2); 918 setcc(SW_C2);
1009#else 919#else
1010 setcc(0); 920 setcc(0);
1011#endif /* PECULIAR_486 */ 921#endif /* PECULIAR_486 */
1012 return; 922 return;
1013 } 923 }
1014 cc = SW_C2; 924 cc = SW_C2;
1015 } 925 }
1016 926
1017 control_word = old_cw; 927 control_word = old_cw;
1018 partial_status = saved_status; 928 partial_status = saved_status;
1019 tag = FPU_normalize_nuo(&tmp); 929 tag = FPU_normalize_nuo(&tmp);
1020 reg_copy(&tmp, st0_ptr); 930 reg_copy(&tmp, st0_ptr);
1021 931
1022 /* The only condition to be looked for is underflow, 932 /* The only condition to be looked for is underflow,
1023 and it can occur here only if underflow is unmasked. */ 933 and it can occur here only if underflow is unmasked. */
1024 if ( (exponent16(&tmp) <= EXP_UNDER) && (tag != TAG_Zero) 934 if ((exponent16(&tmp) <= EXP_UNDER) && (tag != TAG_Zero)
1025 && !(control_word & CW_Underflow) ) 935 && !(control_word & CW_Underflow)) {
1026 { 936 setcc(cc);
1027 setcc(cc); 937 tag = arith_underflow(st0_ptr);
1028 tag = arith_underflow(st0_ptr); 938 setsign(st0_ptr, st0_sign);
1029 setsign(st0_ptr, st0_sign); 939 FPU_settag0(tag);
1030 FPU_settag0(tag); 940 return;
1031 return; 941 } else if ((exponent16(&tmp) > EXP_UNDER) || (tag == TAG_Zero)) {
1032 } 942 stdexp(st0_ptr);
1033 else if ( (exponent16(&tmp) > EXP_UNDER) || (tag == TAG_Zero) ) 943 setsign(st0_ptr, st0_sign);
1034 { 944 } else {
1035 stdexp(st0_ptr); 945 tag =
1036 setsign(st0_ptr, st0_sign); 946 FPU_round(st0_ptr, 0, 0, FULL_PRECISION, st0_sign);
1037 } 947 }
1038 else 948 FPU_settag0(tag);
1039 { 949 setcc(cc);
1040 tag = FPU_round(st0_ptr, 0, 0, FULL_PRECISION, st0_sign);
1041 }
1042 FPU_settag0(tag);
1043 setcc(cc);
1044 950
1045 return; 951 return;
1046 } 952 }
1047 953
1048 if ( st0_tag == TAG_Special ) 954 if (st0_tag == TAG_Special)
1049 st0_tag = FPU_Special(st0_ptr); 955 st0_tag = FPU_Special(st0_ptr);
1050 if ( st1_tag == TAG_Special ) 956 if (st1_tag == TAG_Special)
1051 st1_tag = FPU_Special(st1_ptr); 957 st1_tag = FPU_Special(st1_ptr);
1052 958
1053 if ( ((st0_tag == TAG_Valid) && (st1_tag == TW_Denormal)) 959 if (((st0_tag == TAG_Valid) && (st1_tag == TW_Denormal))
1054 || ((st0_tag == TW_Denormal) && (st1_tag == TAG_Valid)) 960 || ((st0_tag == TW_Denormal) && (st1_tag == TAG_Valid))
1055 || ((st0_tag == TW_Denormal) && (st1_tag == TW_Denormal)) ) 961 || ((st0_tag == TW_Denormal) && (st1_tag == TW_Denormal))) {
1056 { 962 if (denormal_operand() < 0)
1057 if ( denormal_operand() < 0 ) 963 return;
1058 return; 964 goto fprem_valid;
1059 goto fprem_valid; 965 } else if ((st0_tag == TAG_Empty) || (st1_tag == TAG_Empty)) {
1060 } 966 FPU_stack_underflow();
1061 else if ( (st0_tag == TAG_Empty) || (st1_tag == TAG_Empty) ) 967 return;
1062 { 968 } else if (st0_tag == TAG_Zero) {
1063 FPU_stack_underflow(); 969 if (st1_tag == TAG_Valid) {
1064 return; 970 setcc(0);
1065 } 971 return;
1066 else if ( st0_tag == TAG_Zero ) 972 } else if (st1_tag == TW_Denormal) {
1067 { 973 if (denormal_operand() < 0)
1068 if ( st1_tag == TAG_Valid ) 974 return;
1069 { 975 setcc(0);
1070 setcc(0); return; 976 return;
1071 } 977 } else if (st1_tag == TAG_Zero) {
1072 else if ( st1_tag == TW_Denormal ) 978 arith_invalid(0);
1073 { 979 return;
1074 if ( denormal_operand() < 0 ) 980 } /* fprem(?,0) always invalid */
1075 return; 981 else if (st1_tag == TW_Infinity) {
1076 setcc(0); return; 982 setcc(0);
1077 } 983 return;
1078 else if ( st1_tag == TAG_Zero ) 984 }
1079 { arith_invalid(0); return; } /* fprem(?,0) always invalid */ 985 } else if ((st0_tag == TAG_Valid) || (st0_tag == TW_Denormal)) {
1080 else if ( st1_tag == TW_Infinity ) 986 if (st1_tag == TAG_Zero) {
1081 { setcc(0); return; } 987 arith_invalid(0); /* fprem(Valid,Zero) is invalid */
1082 } 988 return;
1083 else if ( (st0_tag == TAG_Valid) || (st0_tag == TW_Denormal) ) 989 } else if (st1_tag != TW_NaN) {
1084 { 990 if (((st0_tag == TW_Denormal)
1085 if ( st1_tag == TAG_Zero ) 991 || (st1_tag == TW_Denormal))
1086 { 992 && (denormal_operand() < 0))
1087 arith_invalid(0); /* fprem(Valid,Zero) is invalid */ 993 return;
1088 return; 994
1089 } 995 if (st1_tag == TW_Infinity) {
1090 else if ( st1_tag != TW_NaN ) 996 /* fprem(Valid,Infinity) is o.k. */
1091 { 997 setcc(0);
1092 if ( ((st0_tag == TW_Denormal) || (st1_tag == TW_Denormal)) 998 return;
1093 && (denormal_operand() < 0) ) 999 }
1094 return; 1000 }
1095 1001 } else if (st0_tag == TW_Infinity) {
1096 if ( st1_tag == TW_Infinity ) 1002 if (st1_tag != TW_NaN) {
1097 { 1003 arith_invalid(0); /* fprem(Infinity,?) is invalid */
1098 /* fprem(Valid,Infinity) is o.k. */ 1004 return;
1099 setcc(0); return; 1005 }
1100 }
1101 }
1102 }
1103 else if ( st0_tag == TW_Infinity )
1104 {
1105 if ( st1_tag != TW_NaN )
1106 {
1107 arith_invalid(0); /* fprem(Infinity,?) is invalid */
1108 return;
1109 } 1006 }
1110 }
1111 1007
1112 /* One of the registers must contain a NaN if we got here. */ 1008 /* One of the registers must contain a NaN if we got here. */
1113 1009
1114#ifdef PARANOID 1010#ifdef PARANOID
1115 if ( (st0_tag != TW_NaN) && (st1_tag != TW_NaN) ) 1011 if ((st0_tag != TW_NaN) && (st1_tag != TW_NaN))
1116 EXCEPTION(EX_INTERNAL | 0x118); 1012 EXCEPTION(EX_INTERNAL | 0x118);
1117#endif /* PARANOID */ 1013#endif /* PARANOID */
1118 1014
1119 real_2op_NaN(st1_ptr, st1_tag, 0, st1_ptr); 1015 real_2op_NaN(st1_ptr, st1_tag, 0, st1_ptr);
1120 1016
1121} 1017}
1122 1018
1123
1124/* ST(1) <- ST(1) * log ST; pop ST */ 1019/* ST(1) <- ST(1) * log ST; pop ST */
1125static void fyl2x(FPU_REG *st0_ptr, u_char st0_tag) 1020static void fyl2x(FPU_REG *st0_ptr, u_char st0_tag)
1126{ 1021{
1127 FPU_REG *st1_ptr = &st(1), exponent; 1022 FPU_REG *st1_ptr = &st(1), exponent;
1128 u_char st1_tag = FPU_gettagi(1); 1023 u_char st1_tag = FPU_gettagi(1);
1129 u_char sign; 1024 u_char sign;
1130 int e, tag; 1025 int e, tag;
1131 1026
1132 clear_C1(); 1027 clear_C1();
1133 1028
1134 if ( (st0_tag == TAG_Valid) && (st1_tag == TAG_Valid) ) 1029 if ((st0_tag == TAG_Valid) && (st1_tag == TAG_Valid)) {
1135 { 1030 both_valid:
1136 both_valid: 1031 /* Both regs are Valid or Denormal */
1137 /* Both regs are Valid or Denormal */ 1032 if (signpositive(st0_ptr)) {
1138 if ( signpositive(st0_ptr) ) 1033 if (st0_tag == TW_Denormal)
1139 { 1034 FPU_to_exp16(st0_ptr, st0_ptr);
1140 if ( st0_tag == TW_Denormal ) 1035 else
1141 FPU_to_exp16(st0_ptr, st0_ptr); 1036 /* Convert st(0) for internal use. */
1142 else 1037 setexponent16(st0_ptr, exponent(st0_ptr));
1143 /* Convert st(0) for internal use. */ 1038
1144 setexponent16(st0_ptr, exponent(st0_ptr)); 1039 if ((st0_ptr->sigh == 0x80000000)
1145 1040 && (st0_ptr->sigl == 0)) {
1146 if ( (st0_ptr->sigh == 0x80000000) && (st0_ptr->sigl == 0) ) 1041 /* Special case. The result can be precise. */
1147 { 1042 u_char esign;
1148 /* Special case. The result can be precise. */ 1043 e = exponent16(st0_ptr);
1149 u_char esign; 1044 if (e >= 0) {
1150 e = exponent16(st0_ptr); 1045 exponent.sigh = e;
1151 if ( e >= 0 ) 1046 esign = SIGN_POS;
1152 { 1047 } else {
1153 exponent.sigh = e; 1048 exponent.sigh = -e;
1154 esign = SIGN_POS; 1049 esign = SIGN_NEG;
1155 } 1050 }
1156 else 1051 exponent.sigl = 0;
1157 { 1052 setexponent16(&exponent, 31);
1158 exponent.sigh = -e; 1053 tag = FPU_normalize_nuo(&exponent);
1159 esign = SIGN_NEG; 1054 stdexp(&exponent);
1055 setsign(&exponent, esign);
1056 tag =
1057 FPU_mul(&exponent, tag, 1, FULL_PRECISION);
1058 if (tag >= 0)
1059 FPU_settagi(1, tag);
1060 } else {
1061 /* The usual case */
1062 sign = getsign(st1_ptr);
1063 if (st1_tag == TW_Denormal)
1064 FPU_to_exp16(st1_ptr, st1_ptr);
1065 else
1066 /* Convert st(1) for internal use. */
1067 setexponent16(st1_ptr,
1068 exponent(st1_ptr));
1069 poly_l2(st0_ptr, st1_ptr, sign);
1070 }
1071 } else {
1072 /* negative */
1073 if (arith_invalid(1) < 0)
1074 return;
1160 } 1075 }
1161 exponent.sigl = 0;
1162 setexponent16(&exponent, 31);
1163 tag = FPU_normalize_nuo(&exponent);
1164 stdexp(&exponent);
1165 setsign(&exponent, esign);
1166 tag = FPU_mul(&exponent, tag, 1, FULL_PRECISION);
1167 if ( tag >= 0 )
1168 FPU_settagi(1, tag);
1169 }
1170 else
1171 {
1172 /* The usual case */
1173 sign = getsign(st1_ptr);
1174 if ( st1_tag == TW_Denormal )
1175 FPU_to_exp16(st1_ptr, st1_ptr);
1176 else
1177 /* Convert st(1) for internal use. */
1178 setexponent16(st1_ptr, exponent(st1_ptr));
1179 poly_l2(st0_ptr, st1_ptr, sign);
1180 }
1181 }
1182 else
1183 {
1184 /* negative */
1185 if ( arith_invalid(1) < 0 )
1186 return;
1187 }
1188 1076
1189 FPU_pop(); 1077 FPU_pop();
1190
1191 return;
1192 }
1193
1194 if ( st0_tag == TAG_Special )
1195 st0_tag = FPU_Special(st0_ptr);
1196 if ( st1_tag == TAG_Special )
1197 st1_tag = FPU_Special(st1_ptr);
1198
1199 if ( (st0_tag == TAG_Empty) || (st1_tag == TAG_Empty) )
1200 {
1201 FPU_stack_underflow_pop(1);
1202 return;
1203 }
1204 else if ( (st0_tag <= TW_Denormal) && (st1_tag <= TW_Denormal) )
1205 {
1206 if ( st0_tag == TAG_Zero )
1207 {
1208 if ( st1_tag == TAG_Zero )
1209 {
1210 /* Both args zero is invalid */
1211 if ( arith_invalid(1) < 0 )
1212 return;
1213 }
1214 else
1215 {
1216 u_char sign;
1217 sign = getsign(st1_ptr)^SIGN_NEG;
1218 if ( FPU_divide_by_zero(1, sign) < 0 )
1219 return;
1220 1078
1221 setsign(st1_ptr, sign);
1222 }
1223 }
1224 else if ( st1_tag == TAG_Zero )
1225 {
1226 /* st(1) contains zero, st(0) valid <> 0 */
1227 /* Zero is the valid answer */
1228 sign = getsign(st1_ptr);
1229
1230 if ( signnegative(st0_ptr) )
1231 {
1232 /* log(negative) */
1233 if ( arith_invalid(1) < 0 )
1234 return; 1079 return;
1235 }
1236 else if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
1237 return;
1238 else
1239 {
1240 if ( exponent(st0_ptr) < 0 )
1241 sign ^= SIGN_NEG;
1242
1243 FPU_copy_to_reg1(&CONST_Z, TAG_Zero);
1244 setsign(st1_ptr, sign);
1245 }
1246 } 1080 }
1247 else
1248 {
1249 /* One or both operands are denormals. */
1250 if ( denormal_operand() < 0 )
1251 return;
1252 goto both_valid;
1253 }
1254 }
1255 else if ( (st0_tag == TW_NaN) || (st1_tag == TW_NaN) )
1256 {
1257 if ( real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0 )
1258 return;
1259 }
1260 /* One or both arg must be an infinity */
1261 else if ( st0_tag == TW_Infinity )
1262 {
1263 if ( (signnegative(st0_ptr)) || (st1_tag == TAG_Zero) )
1264 {
1265 /* log(-infinity) or 0*log(infinity) */
1266 if ( arith_invalid(1) < 0 )
1267 return;
1268 }
1269 else
1270 {
1271 u_char sign = getsign(st1_ptr);
1272 1081
1273 if ( (st1_tag == TW_Denormal) && (denormal_operand() < 0) ) 1082 if (st0_tag == TAG_Special)
1274 return; 1083 st0_tag = FPU_Special(st0_ptr);
1084 if (st1_tag == TAG_Special)
1085 st1_tag = FPU_Special(st1_ptr);
1275 1086
1276 FPU_copy_to_reg1(&CONST_INF, TAG_Special); 1087 if ((st0_tag == TAG_Empty) || (st1_tag == TAG_Empty)) {
1277 setsign(st1_ptr, sign); 1088 FPU_stack_underflow_pop(1);
1278 }
1279 }
1280 /* st(1) must be infinity here */
1281 else if ( ((st0_tag == TAG_Valid) || (st0_tag == TW_Denormal))
1282 && ( signpositive(st0_ptr) ) )
1283 {
1284 if ( exponent(st0_ptr) >= 0 )
1285 {
1286 if ( (exponent(st0_ptr) == 0) &&
1287 (st0_ptr->sigh == 0x80000000) &&
1288 (st0_ptr->sigl == 0) )
1289 {
1290 /* st(0) holds 1.0 */
1291 /* infinity*log(1) */
1292 if ( arith_invalid(1) < 0 )
1293 return; 1089 return;
1294 } 1090 } else if ((st0_tag <= TW_Denormal) && (st1_tag <= TW_Denormal)) {
1295 /* else st(0) is positive and > 1.0 */ 1091 if (st0_tag == TAG_Zero) {
1092 if (st1_tag == TAG_Zero) {
1093 /* Both args zero is invalid */
1094 if (arith_invalid(1) < 0)
1095 return;
1096 } else {
1097 u_char sign;
1098 sign = getsign(st1_ptr) ^ SIGN_NEG;
1099 if (FPU_divide_by_zero(1, sign) < 0)
1100 return;
1101
1102 setsign(st1_ptr, sign);
1103 }
1104 } else if (st1_tag == TAG_Zero) {
1105 /* st(1) contains zero, st(0) valid <> 0 */
1106 /* Zero is the valid answer */
1107 sign = getsign(st1_ptr);
1108
1109 if (signnegative(st0_ptr)) {
1110 /* log(negative) */
1111 if (arith_invalid(1) < 0)
1112 return;
1113 } else if ((st0_tag == TW_Denormal)
1114 && (denormal_operand() < 0))
1115 return;
1116 else {
1117 if (exponent(st0_ptr) < 0)
1118 sign ^= SIGN_NEG;
1119
1120 FPU_copy_to_reg1(&CONST_Z, TAG_Zero);
1121 setsign(st1_ptr, sign);
1122 }
1123 } else {
1124 /* One or both operands are denormals. */
1125 if (denormal_operand() < 0)
1126 return;
1127 goto both_valid;
1128 }
1129 } else if ((st0_tag == TW_NaN) || (st1_tag == TW_NaN)) {
1130 if (real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0)
1131 return;
1132 }
1133 /* One or both arg must be an infinity */
1134 else if (st0_tag == TW_Infinity) {
1135 if ((signnegative(st0_ptr)) || (st1_tag == TAG_Zero)) {
1136 /* log(-infinity) or 0*log(infinity) */
1137 if (arith_invalid(1) < 0)
1138 return;
1139 } else {
1140 u_char sign = getsign(st1_ptr);
1141
1142 if ((st1_tag == TW_Denormal)
1143 && (denormal_operand() < 0))
1144 return;
1145
1146 FPU_copy_to_reg1(&CONST_INF, TAG_Special);
1147 setsign(st1_ptr, sign);
1148 }
1296 } 1149 }
1297 else 1150 /* st(1) must be infinity here */
1298 { 1151 else if (((st0_tag == TAG_Valid) || (st0_tag == TW_Denormal))
1299 /* st(0) is positive and < 1.0 */ 1152 && (signpositive(st0_ptr))) {
1153 if (exponent(st0_ptr) >= 0) {
1154 if ((exponent(st0_ptr) == 0) &&
1155 (st0_ptr->sigh == 0x80000000) &&
1156 (st0_ptr->sigl == 0)) {
1157 /* st(0) holds 1.0 */
1158 /* infinity*log(1) */
1159 if (arith_invalid(1) < 0)
1160 return;
1161 }
1162 /* else st(0) is positive and > 1.0 */
1163 } else {
1164 /* st(0) is positive and < 1.0 */
1300 1165
1301 if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) ) 1166 if ((st0_tag == TW_Denormal)
1302 return; 1167 && (denormal_operand() < 0))
1168 return;
1303 1169
1304 changesign(st1_ptr); 1170 changesign(st1_ptr);
1305 } 1171 }
1306 } 1172 } else {
1307 else 1173 /* st(0) must be zero or negative */
1308 { 1174 if (st0_tag == TAG_Zero) {
1309 /* st(0) must be zero or negative */ 1175 /* This should be invalid, but a real 80486 is happy with it. */
1310 if ( st0_tag == TAG_Zero )
1311 {
1312 /* This should be invalid, but a real 80486 is happy with it. */
1313 1176
1314#ifndef PECULIAR_486 1177#ifndef PECULIAR_486
1315 sign = getsign(st1_ptr); 1178 sign = getsign(st1_ptr);
1316 if ( FPU_divide_by_zero(1, sign) < 0 ) 1179 if (FPU_divide_by_zero(1, sign) < 0)
1317 return; 1180 return;
1318#endif /* PECULIAR_486 */ 1181#endif /* PECULIAR_486 */
1319 1182
1320 changesign(st1_ptr); 1183 changesign(st1_ptr);
1184 } else if (arith_invalid(1) < 0) /* log(negative) */
1185 return;
1321 } 1186 }
1322 else if ( arith_invalid(1) < 0 ) /* log(negative) */
1323 return;
1324 }
1325 1187
1326 FPU_pop(); 1188 FPU_pop();
1327} 1189}
1328 1190
1329
1330static void fpatan(FPU_REG *st0_ptr, u_char st0_tag) 1191static void fpatan(FPU_REG *st0_ptr, u_char st0_tag)
1331{ 1192{
1332 FPU_REG *st1_ptr = &st(1); 1193 FPU_REG *st1_ptr = &st(1);
1333 u_char st1_tag = FPU_gettagi(1); 1194 u_char st1_tag = FPU_gettagi(1);
1334 int tag; 1195 int tag;
1335 1196
1336 clear_C1(); 1197 clear_C1();
1337 if ( !((st0_tag ^ TAG_Valid) | (st1_tag ^ TAG_Valid)) ) 1198 if (!((st0_tag ^ TAG_Valid) | (st1_tag ^ TAG_Valid))) {
1338 { 1199 valid_atan:
1339 valid_atan:
1340 1200
1341 poly_atan(st0_ptr, st0_tag, st1_ptr, st1_tag); 1201 poly_atan(st0_ptr, st0_tag, st1_ptr, st1_tag);
1342 1202
1343 FPU_pop(); 1203 FPU_pop();
1344 1204
1345 return; 1205 return;
1346 } 1206 }
1347 1207
1348 if ( st0_tag == TAG_Special ) 1208 if (st0_tag == TAG_Special)
1349 st0_tag = FPU_Special(st0_ptr); 1209 st0_tag = FPU_Special(st0_ptr);
1350 if ( st1_tag == TAG_Special ) 1210 if (st1_tag == TAG_Special)
1351 st1_tag = FPU_Special(st1_ptr); 1211 st1_tag = FPU_Special(st1_ptr);
1352 1212
1353 if ( ((st0_tag == TAG_Valid) && (st1_tag == TW_Denormal)) 1213 if (((st0_tag == TAG_Valid) && (st1_tag == TW_Denormal))
1354 || ((st0_tag == TW_Denormal) && (st1_tag == TAG_Valid)) 1214 || ((st0_tag == TW_Denormal) && (st1_tag == TAG_Valid))
1355 || ((st0_tag == TW_Denormal) && (st1_tag == TW_Denormal)) ) 1215 || ((st0_tag == TW_Denormal) && (st1_tag == TW_Denormal))) {
1356 { 1216 if (denormal_operand() < 0)
1357 if ( denormal_operand() < 0 ) 1217 return;
1358 return;
1359 1218
1360 goto valid_atan; 1219 goto valid_atan;
1361 } 1220 } else if ((st0_tag == TAG_Empty) || (st1_tag == TAG_Empty)) {
1362 else if ( (st0_tag == TAG_Empty) || (st1_tag == TAG_Empty) ) 1221 FPU_stack_underflow_pop(1);
1363 { 1222 return;
1364 FPU_stack_underflow_pop(1); 1223 } else if ((st0_tag == TW_NaN) || (st1_tag == TW_NaN)) {
1365 return; 1224 if (real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) >= 0)
1366 } 1225 FPU_pop();
1367 else if ( (st0_tag == TW_NaN) || (st1_tag == TW_NaN) )
1368 {
1369 if ( real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) >= 0 )
1370 FPU_pop();
1371 return;
1372 }
1373 else if ( (st0_tag == TW_Infinity) || (st1_tag == TW_Infinity) )
1374 {
1375 u_char sign = getsign(st1_ptr);
1376 if ( st0_tag == TW_Infinity )
1377 {
1378 if ( st1_tag == TW_Infinity )
1379 {
1380 if ( signpositive(st0_ptr) )
1381 {
1382 FPU_copy_to_reg1(&CONST_PI4, TAG_Valid);
1383 }
1384 else
1385 {
1386 setpositive(st1_ptr);
1387 tag = FPU_u_add(&CONST_PI4, &CONST_PI2, st1_ptr,
1388 FULL_PRECISION, SIGN_POS,
1389 exponent(&CONST_PI4), exponent(&CONST_PI2));
1390 if ( tag >= 0 )
1391 FPU_settagi(1, tag);
1392 }
1393 }
1394 else
1395 {
1396 if ( (st1_tag == TW_Denormal) && (denormal_operand() < 0) )
1397 return; 1226 return;
1227 } else if ((st0_tag == TW_Infinity) || (st1_tag == TW_Infinity)) {
1228 u_char sign = getsign(st1_ptr);
1229 if (st0_tag == TW_Infinity) {
1230 if (st1_tag == TW_Infinity) {
1231 if (signpositive(st0_ptr)) {
1232 FPU_copy_to_reg1(&CONST_PI4, TAG_Valid);
1233 } else {
1234 setpositive(st1_ptr);
1235 tag =
1236 FPU_u_add(&CONST_PI4, &CONST_PI2,
1237 st1_ptr, FULL_PRECISION,
1238 SIGN_POS,
1239 exponent(&CONST_PI4),
1240 exponent(&CONST_PI2));
1241 if (tag >= 0)
1242 FPU_settagi(1, tag);
1243 }
1244 } else {
1245 if ((st1_tag == TW_Denormal)
1246 && (denormal_operand() < 0))
1247 return;
1248
1249 if (signpositive(st0_ptr)) {
1250 FPU_copy_to_reg1(&CONST_Z, TAG_Zero);
1251 setsign(st1_ptr, sign); /* An 80486 preserves the sign */
1252 FPU_pop();
1253 return;
1254 } else {
1255 FPU_copy_to_reg1(&CONST_PI, TAG_Valid);
1256 }
1257 }
1258 } else {
1259 /* st(1) is infinity, st(0) not infinity */
1260 if ((st0_tag == TW_Denormal)
1261 && (denormal_operand() < 0))
1262 return;
1398 1263
1399 if ( signpositive(st0_ptr) ) 1264 FPU_copy_to_reg1(&CONST_PI2, TAG_Valid);
1400 {
1401 FPU_copy_to_reg1(&CONST_Z, TAG_Zero);
1402 setsign(st1_ptr, sign); /* An 80486 preserves the sign */
1403 FPU_pop();
1404 return;
1405 } 1265 }
1406 else 1266 setsign(st1_ptr, sign);
1407 { 1267 } else if (st1_tag == TAG_Zero) {
1408 FPU_copy_to_reg1(&CONST_PI, TAG_Valid); 1268 /* st(0) must be valid or zero */
1269 u_char sign = getsign(st1_ptr);
1270
1271 if ((st0_tag == TW_Denormal) && (denormal_operand() < 0))
1272 return;
1273
1274 if (signpositive(st0_ptr)) {
1275 /* An 80486 preserves the sign */
1276 FPU_pop();
1277 return;
1409 } 1278 }
1410 }
1411 }
1412 else
1413 {
1414 /* st(1) is infinity, st(0) not infinity */
1415 if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
1416 return;
1417 1279
1418 FPU_copy_to_reg1(&CONST_PI2, TAG_Valid); 1280 FPU_copy_to_reg1(&CONST_PI, TAG_Valid);
1419 } 1281 setsign(st1_ptr, sign);
1420 setsign(st1_ptr, sign); 1282 } else if (st0_tag == TAG_Zero) {
1421 } 1283 /* st(1) must be TAG_Valid here */
1422 else if ( st1_tag == TAG_Zero ) 1284 u_char sign = getsign(st1_ptr);
1423 {
1424 /* st(0) must be valid or zero */
1425 u_char sign = getsign(st1_ptr);
1426
1427 if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
1428 return;
1429 1285
1430 if ( signpositive(st0_ptr) ) 1286 if ((st1_tag == TW_Denormal) && (denormal_operand() < 0))
1431 { 1287 return;
1432 /* An 80486 preserves the sign */
1433 FPU_pop();
1434 return;
1435 }
1436 1288
1437 FPU_copy_to_reg1(&CONST_PI, TAG_Valid); 1289 FPU_copy_to_reg1(&CONST_PI2, TAG_Valid);
1438 setsign(st1_ptr, sign); 1290 setsign(st1_ptr, sign);
1439 } 1291 }
1440 else if ( st0_tag == TAG_Zero )
1441 {
1442 /* st(1) must be TAG_Valid here */
1443 u_char sign = getsign(st1_ptr);
1444
1445 if ( (st1_tag == TW_Denormal) && (denormal_operand() < 0) )
1446 return;
1447
1448 FPU_copy_to_reg1(&CONST_PI2, TAG_Valid);
1449 setsign(st1_ptr, sign);
1450 }
1451#ifdef PARANOID 1292#ifdef PARANOID
1452 else 1293 else
1453 EXCEPTION(EX_INTERNAL | 0x125); 1294 EXCEPTION(EX_INTERNAL | 0x125);
1454#endif /* PARANOID */ 1295#endif /* PARANOID */
1455 1296
1456 FPU_pop(); 1297 FPU_pop();
1457 set_precision_flag_up(); /* We do not really know if up or down */ 1298 set_precision_flag_up(); /* We do not really know if up or down */
1458} 1299}
1459 1300
1460
1461static void fprem(FPU_REG *st0_ptr, u_char st0_tag) 1301static void fprem(FPU_REG *st0_ptr, u_char st0_tag)
1462{ 1302{
1463 do_fprem(st0_ptr, st0_tag, RC_CHOP); 1303 do_fprem(st0_ptr, st0_tag, RC_CHOP);
1464} 1304}
1465 1305
1466
1467static void fprem1(FPU_REG *st0_ptr, u_char st0_tag) 1306static void fprem1(FPU_REG *st0_ptr, u_char st0_tag)
1468{ 1307{
1469 do_fprem(st0_ptr, st0_tag, RC_RND); 1308 do_fprem(st0_ptr, st0_tag, RC_RND);
1470} 1309}
1471 1310
1472
1473static void fyl2xp1(FPU_REG *st0_ptr, u_char st0_tag) 1311static void fyl2xp1(FPU_REG *st0_ptr, u_char st0_tag)
1474{ 1312{
1475 u_char sign, sign1; 1313 u_char sign, sign1;
1476 FPU_REG *st1_ptr = &st(1), a, b; 1314 FPU_REG *st1_ptr = &st(1), a, b;
1477 u_char st1_tag = FPU_gettagi(1); 1315 u_char st1_tag = FPU_gettagi(1);
1478 1316
1479 clear_C1(); 1317 clear_C1();
1480 if ( !((st0_tag ^ TAG_Valid) | (st1_tag ^ TAG_Valid)) ) 1318 if (!((st0_tag ^ TAG_Valid) | (st1_tag ^ TAG_Valid))) {
1481 { 1319 valid_yl2xp1:
1482 valid_yl2xp1:
1483 1320
1484 sign = getsign(st0_ptr); 1321 sign = getsign(st0_ptr);
1485 sign1 = getsign(st1_ptr); 1322 sign1 = getsign(st1_ptr);
1486 1323
1487 FPU_to_exp16(st0_ptr, &a); 1324 FPU_to_exp16(st0_ptr, &a);
1488 FPU_to_exp16(st1_ptr, &b); 1325 FPU_to_exp16(st1_ptr, &b);
1489 1326
1490 if ( poly_l2p1(sign, sign1, &a, &b, st1_ptr) ) 1327 if (poly_l2p1(sign, sign1, &a, &b, st1_ptr))
1491 return; 1328 return;
1492 1329
1493 FPU_pop(); 1330 FPU_pop();
1494 return; 1331 return;
1495 } 1332 }
1496 1333
1497 if ( st0_tag == TAG_Special ) 1334 if (st0_tag == TAG_Special)
1498 st0_tag = FPU_Special(st0_ptr); 1335 st0_tag = FPU_Special(st0_ptr);
1499 if ( st1_tag == TAG_Special ) 1336 if (st1_tag == TAG_Special)
1500 st1_tag = FPU_Special(st1_ptr); 1337 st1_tag = FPU_Special(st1_ptr);
1501 1338
1502 if ( ((st0_tag == TAG_Valid) && (st1_tag == TW_Denormal)) 1339 if (((st0_tag == TAG_Valid) && (st1_tag == TW_Denormal))
1503 || ((st0_tag == TW_Denormal) && (st1_tag == TAG_Valid)) 1340 || ((st0_tag == TW_Denormal) && (st1_tag == TAG_Valid))
1504 || ((st0_tag == TW_Denormal) && (st1_tag == TW_Denormal)) ) 1341 || ((st0_tag == TW_Denormal) && (st1_tag == TW_Denormal))) {
1505 { 1342 if (denormal_operand() < 0)
1506 if ( denormal_operand() < 0 ) 1343 return;
1507 return;
1508
1509 goto valid_yl2xp1;
1510 }
1511 else if ( (st0_tag == TAG_Empty) | (st1_tag == TAG_Empty) )
1512 {
1513 FPU_stack_underflow_pop(1);
1514 return;
1515 }
1516 else if ( st0_tag == TAG_Zero )
1517 {
1518 switch ( st1_tag )
1519 {
1520 case TW_Denormal:
1521 if ( denormal_operand() < 0 )
1522 return;
1523
1524 case TAG_Zero:
1525 case TAG_Valid:
1526 setsign(st0_ptr, getsign(st0_ptr) ^ getsign(st1_ptr));
1527 FPU_copy_to_reg1(st0_ptr, st0_tag);
1528 break;
1529
1530 case TW_Infinity:
1531 /* Infinity*log(1) */
1532 if ( arith_invalid(1) < 0 )
1533 return;
1534 break;
1535 1344
1536 case TW_NaN: 1345 goto valid_yl2xp1;
1537 if ( real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0 ) 1346 } else if ((st0_tag == TAG_Empty) | (st1_tag == TAG_Empty)) {
1538 return; 1347 FPU_stack_underflow_pop(1);
1539 break; 1348 return;
1540 1349 } else if (st0_tag == TAG_Zero) {
1541 default: 1350 switch (st1_tag) {
1351 case TW_Denormal:
1352 if (denormal_operand() < 0)
1353 return;
1354
1355 case TAG_Zero:
1356 case TAG_Valid:
1357 setsign(st0_ptr, getsign(st0_ptr) ^ getsign(st1_ptr));
1358 FPU_copy_to_reg1(st0_ptr, st0_tag);
1359 break;
1360
1361 case TW_Infinity:
1362 /* Infinity*log(1) */
1363 if (arith_invalid(1) < 0)
1364 return;
1365 break;
1366
1367 case TW_NaN:
1368 if (real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0)
1369 return;
1370 break;
1371
1372 default:
1542#ifdef PARANOID 1373#ifdef PARANOID
1543 EXCEPTION(EX_INTERNAL | 0x116); 1374 EXCEPTION(EX_INTERNAL | 0x116);
1544 return; 1375 return;
1545#endif /* PARANOID */ 1376#endif /* PARANOID */
1546 break; 1377 break;
1547 } 1378 }
1548 } 1379 } else if ((st0_tag == TAG_Valid) || (st0_tag == TW_Denormal)) {
1549 else if ( (st0_tag == TAG_Valid) || (st0_tag == TW_Denormal) ) 1380 switch (st1_tag) {
1550 { 1381 case TAG_Zero:
1551 switch ( st1_tag ) 1382 if (signnegative(st0_ptr)) {
1552 { 1383 if (exponent(st0_ptr) >= 0) {
1553 case TAG_Zero: 1384 /* st(0) holds <= -1.0 */
1554 if ( signnegative(st0_ptr) ) 1385#ifdef PECULIAR_486 /* Stupid 80486 doesn't worry about log(negative). */
1555 { 1386 changesign(st1_ptr);
1556 if ( exponent(st0_ptr) >= 0 )
1557 {
1558 /* st(0) holds <= -1.0 */
1559#ifdef PECULIAR_486 /* Stupid 80486 doesn't worry about log(negative). */
1560 changesign(st1_ptr);
1561#else 1387#else
1562 if ( arith_invalid(1) < 0 ) 1388 if (arith_invalid(1) < 0)
1563 return; 1389 return;
1564#endif /* PECULIAR_486 */ 1390#endif /* PECULIAR_486 */
1565 } 1391 } else if ((st0_tag == TW_Denormal)
1566 else if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) ) 1392 && (denormal_operand() < 0))
1567 return; 1393 return;
1568 else 1394 else
1569 changesign(st1_ptr); 1395 changesign(st1_ptr);
1570 } 1396 } else if ((st0_tag == TW_Denormal)
1571 else if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) ) 1397 && (denormal_operand() < 0))
1572 return; 1398 return;
1573 break; 1399 break;
1574 1400
1575 case TW_Infinity: 1401 case TW_Infinity:
1576 if ( signnegative(st0_ptr) ) 1402 if (signnegative(st0_ptr)) {
1577 { 1403 if ((exponent(st0_ptr) >= 0) &&
1578 if ( (exponent(st0_ptr) >= 0) && 1404 !((st0_ptr->sigh == 0x80000000) &&
1579 !((st0_ptr->sigh == 0x80000000) && 1405 (st0_ptr->sigl == 0))) {
1580 (st0_ptr->sigl == 0)) ) 1406 /* st(0) holds < -1.0 */
1581 { 1407#ifdef PECULIAR_486 /* Stupid 80486 doesn't worry about log(negative). */
1582 /* st(0) holds < -1.0 */ 1408 changesign(st1_ptr);
1583#ifdef PECULIAR_486 /* Stupid 80486 doesn't worry about log(negative). */
1584 changesign(st1_ptr);
1585#else 1409#else
1586 if ( arith_invalid(1) < 0 ) return; 1410 if (arith_invalid(1) < 0)
1411 return;
1587#endif /* PECULIAR_486 */ 1412#endif /* PECULIAR_486 */
1413 } else if ((st0_tag == TW_Denormal)
1414 && (denormal_operand() < 0))
1415 return;
1416 else
1417 changesign(st1_ptr);
1418 } else if ((st0_tag == TW_Denormal)
1419 && (denormal_operand() < 0))
1420 return;
1421 break;
1422
1423 case TW_NaN:
1424 if (real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0)
1425 return;
1588 } 1426 }
1589 else if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
1590 return;
1591 else
1592 changesign(st1_ptr);
1593 }
1594 else if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
1595 return;
1596 break;
1597
1598 case TW_NaN:
1599 if ( real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0 )
1600 return;
1601 }
1602 1427
1603 } 1428 } else if (st0_tag == TW_NaN) {
1604 else if ( st0_tag == TW_NaN ) 1429 if (real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0)
1605 { 1430 return;
1606 if ( real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0 ) 1431 } else if (st0_tag == TW_Infinity) {
1607 return; 1432 if (st1_tag == TW_NaN) {
1608 } 1433 if (real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0)
1609 else if ( st0_tag == TW_Infinity ) 1434 return;
1610 { 1435 } else if (signnegative(st0_ptr)) {
1611 if ( st1_tag == TW_NaN )
1612 {
1613 if ( real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0 )
1614 return;
1615 }
1616 else if ( signnegative(st0_ptr) )
1617 {
1618#ifndef PECULIAR_486 1436#ifndef PECULIAR_486
1619 /* This should have higher priority than denormals, but... */ 1437 /* This should have higher priority than denormals, but... */
1620 if ( arith_invalid(1) < 0 ) /* log(-infinity) */ 1438 if (arith_invalid(1) < 0) /* log(-infinity) */
1621 return; 1439 return;
1622#endif /* PECULIAR_486 */ 1440#endif /* PECULIAR_486 */
1623 if ( (st1_tag == TW_Denormal) && (denormal_operand() < 0) ) 1441 if ((st1_tag == TW_Denormal)
1624 return; 1442 && (denormal_operand() < 0))
1443 return;
1625#ifdef PECULIAR_486 1444#ifdef PECULIAR_486
1626 /* Denormal operands actually get higher priority */ 1445 /* Denormal operands actually get higher priority */
1627 if ( arith_invalid(1) < 0 ) /* log(-infinity) */ 1446 if (arith_invalid(1) < 0) /* log(-infinity) */
1628 return; 1447 return;
1629#endif /* PECULIAR_486 */ 1448#endif /* PECULIAR_486 */
1630 } 1449 } else if (st1_tag == TAG_Zero) {
1631 else if ( st1_tag == TAG_Zero ) 1450 /* log(infinity) */
1632 { 1451 if (arith_invalid(1) < 0)
1633 /* log(infinity) */ 1452 return;
1634 if ( arith_invalid(1) < 0 ) 1453 }
1635 return;
1636 }
1637
1638 /* st(1) must be valid here. */
1639 1454
1640 else if ( (st1_tag == TW_Denormal) && (denormal_operand() < 0) ) 1455 /* st(1) must be valid here. */
1641 return; 1456
1457 else if ((st1_tag == TW_Denormal) && (denormal_operand() < 0))
1458 return;
1642 1459
1643 /* The Manual says that log(Infinity) is invalid, but a real 1460 /* The Manual says that log(Infinity) is invalid, but a real
1644 80486 sensibly says that it is o.k. */ 1461 80486 sensibly says that it is o.k. */
1645 else 1462 else {
1646 { 1463 u_char sign = getsign(st1_ptr);
1647 u_char sign = getsign(st1_ptr); 1464 FPU_copy_to_reg1(&CONST_INF, TAG_Special);
1648 FPU_copy_to_reg1(&CONST_INF, TAG_Special); 1465 setsign(st1_ptr, sign);
1649 setsign(st1_ptr, sign); 1466 }
1650 } 1467 }
1651 }
1652#ifdef PARANOID 1468#ifdef PARANOID
1653 else 1469 else {
1654 { 1470 EXCEPTION(EX_INTERNAL | 0x117);
1655 EXCEPTION(EX_INTERNAL | 0x117); 1471 return;
1656 return; 1472 }
1657 }
1658#endif /* PARANOID */ 1473#endif /* PARANOID */
1659 1474
1660 FPU_pop(); 1475 FPU_pop();
1661 return; 1476 return;
1662 1477
1663} 1478}
1664 1479
1665
1666static void fscale(FPU_REG *st0_ptr, u_char st0_tag) 1480static void fscale(FPU_REG *st0_ptr, u_char st0_tag)
1667{ 1481{
1668 FPU_REG *st1_ptr = &st(1); 1482 FPU_REG *st1_ptr = &st(1);
1669 u_char st1_tag = FPU_gettagi(1); 1483 u_char st1_tag = FPU_gettagi(1);
1670 int old_cw = control_word; 1484 int old_cw = control_word;
1671 u_char sign = getsign(st0_ptr); 1485 u_char sign = getsign(st0_ptr);
1672 1486
1673 clear_C1(); 1487 clear_C1();
1674 if ( !((st0_tag ^ TAG_Valid) | (st1_tag ^ TAG_Valid)) ) 1488 if (!((st0_tag ^ TAG_Valid) | (st1_tag ^ TAG_Valid))) {
1675 { 1489 long scale;
1676 long scale; 1490 FPU_REG tmp;
1677 FPU_REG tmp; 1491
1678 1492 /* Convert register for internal use. */
1679 /* Convert register for internal use. */ 1493 setexponent16(st0_ptr, exponent(st0_ptr));
1680 setexponent16(st0_ptr, exponent(st0_ptr)); 1494
1681 1495 valid_scale:
1682 valid_scale: 1496
1683 1497 if (exponent(st1_ptr) > 30) {
1684 if ( exponent(st1_ptr) > 30 ) 1498 /* 2^31 is far too large, would require 2^(2^30) or 2^(-2^30) */
1685 { 1499
1686 /* 2^31 is far too large, would require 2^(2^30) or 2^(-2^30) */ 1500 if (signpositive(st1_ptr)) {
1687 1501 EXCEPTION(EX_Overflow);
1688 if ( signpositive(st1_ptr) ) 1502 FPU_copy_to_reg0(&CONST_INF, TAG_Special);
1689 { 1503 } else {
1690 EXCEPTION(EX_Overflow); 1504 EXCEPTION(EX_Underflow);
1691 FPU_copy_to_reg0(&CONST_INF, TAG_Special); 1505 FPU_copy_to_reg0(&CONST_Z, TAG_Zero);
1692 } 1506 }
1693 else 1507 setsign(st0_ptr, sign);
1694 { 1508 return;
1695 EXCEPTION(EX_Underflow); 1509 }
1696 FPU_copy_to_reg0(&CONST_Z, TAG_Zero);
1697 }
1698 setsign(st0_ptr, sign);
1699 return;
1700 }
1701
1702 control_word &= ~CW_RC;
1703 control_word |= RC_CHOP;
1704 reg_copy(st1_ptr, &tmp);
1705 FPU_round_to_int(&tmp, st1_tag); /* This can never overflow here */
1706 control_word = old_cw;
1707 scale = signnegative(st1_ptr) ? -tmp.sigl : tmp.sigl;
1708 scale += exponent16(st0_ptr);
1709
1710 setexponent16(st0_ptr, scale);
1711
1712 /* Use FPU_round() to properly detect under/overflow etc */
1713 FPU_round(st0_ptr, 0, 0, control_word, sign);
1714
1715 return;
1716 }
1717
1718 if ( st0_tag == TAG_Special )
1719 st0_tag = FPU_Special(st0_ptr);
1720 if ( st1_tag == TAG_Special )
1721 st1_tag = FPU_Special(st1_ptr);
1722
1723 if ( (st0_tag == TAG_Valid) || (st0_tag == TW_Denormal) )
1724 {
1725 switch ( st1_tag )
1726 {
1727 case TAG_Valid:
1728 /* st(0) must be a denormal */
1729 if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
1730 return;
1731
1732 FPU_to_exp16(st0_ptr, st0_ptr); /* Will not be left on stack */
1733 goto valid_scale;
1734
1735 case TAG_Zero:
1736 if ( st0_tag == TW_Denormal )
1737 denormal_operand();
1738 return;
1739
1740 case TW_Denormal:
1741 denormal_operand();
1742 return;
1743
1744 case TW_Infinity:
1745 if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
1746 return;
1747
1748 if ( signpositive(st1_ptr) )
1749 FPU_copy_to_reg0(&CONST_INF, TAG_Special);
1750 else
1751 FPU_copy_to_reg0(&CONST_Z, TAG_Zero);
1752 setsign(st0_ptr, sign);
1753 return;
1754 1510
1755 case TW_NaN: 1511 control_word &= ~CW_RC;
1756 real_2op_NaN(st1_ptr, st1_tag, 0, st0_ptr); 1512 control_word |= RC_CHOP;
1757 return; 1513 reg_copy(st1_ptr, &tmp);
1758 } 1514 FPU_round_to_int(&tmp, st1_tag); /* This can never overflow here */
1759 } 1515 control_word = old_cw;
1760 else if ( st0_tag == TAG_Zero ) 1516 scale = signnegative(st1_ptr) ? -tmp.sigl : tmp.sigl;
1761 { 1517 scale += exponent16(st0_ptr);
1762 switch ( st1_tag )
1763 {
1764 case TAG_Valid:
1765 case TAG_Zero:
1766 return;
1767 1518
1768 case TW_Denormal: 1519 setexponent16(st0_ptr, scale);
1769 denormal_operand();
1770 return;
1771 1520
1772 case TW_Infinity: 1521 /* Use FPU_round() to properly detect under/overflow etc */
1773 if ( signpositive(st1_ptr) ) 1522 FPU_round(st0_ptr, 0, 0, control_word, sign);
1774 arith_invalid(0); /* Zero scaled by +Infinity */
1775 return;
1776 1523
1777 case TW_NaN: 1524 return;
1778 real_2op_NaN(st1_ptr, st1_tag, 0, st0_ptr);
1779 return;
1780 } 1525 }
1781 }
1782 else if ( st0_tag == TW_Infinity )
1783 {
1784 switch ( st1_tag )
1785 {
1786 case TAG_Valid:
1787 case TAG_Zero:
1788 return;
1789
1790 case TW_Denormal:
1791 denormal_operand();
1792 return;
1793 1526
1794 case TW_Infinity: 1527 if (st0_tag == TAG_Special)
1795 if ( signnegative(st1_ptr) ) 1528 st0_tag = FPU_Special(st0_ptr);
1796 arith_invalid(0); /* Infinity scaled by -Infinity */ 1529 if (st1_tag == TAG_Special)
1797 return; 1530 st1_tag = FPU_Special(st1_ptr);
1798 1531
1799 case TW_NaN: 1532 if ((st0_tag == TAG_Valid) || (st0_tag == TW_Denormal)) {
1800 real_2op_NaN(st1_ptr, st1_tag, 0, st0_ptr); 1533 switch (st1_tag) {
1801 return; 1534 case TAG_Valid:
1535 /* st(0) must be a denormal */
1536 if ((st0_tag == TW_Denormal)
1537 && (denormal_operand() < 0))
1538 return;
1539
1540 FPU_to_exp16(st0_ptr, st0_ptr); /* Will not be left on stack */
1541 goto valid_scale;
1542
1543 case TAG_Zero:
1544 if (st0_tag == TW_Denormal)
1545 denormal_operand();
1546 return;
1547
1548 case TW_Denormal:
1549 denormal_operand();
1550 return;
1551
1552 case TW_Infinity:
1553 if ((st0_tag == TW_Denormal)
1554 && (denormal_operand() < 0))
1555 return;
1556
1557 if (signpositive(st1_ptr))
1558 FPU_copy_to_reg0(&CONST_INF, TAG_Special);
1559 else
1560 FPU_copy_to_reg0(&CONST_Z, TAG_Zero);
1561 setsign(st0_ptr, sign);
1562 return;
1563
1564 case TW_NaN:
1565 real_2op_NaN(st1_ptr, st1_tag, 0, st0_ptr);
1566 return;
1567 }
1568 } else if (st0_tag == TAG_Zero) {
1569 switch (st1_tag) {
1570 case TAG_Valid:
1571 case TAG_Zero:
1572 return;
1573
1574 case TW_Denormal:
1575 denormal_operand();
1576 return;
1577
1578 case TW_Infinity:
1579 if (signpositive(st1_ptr))
1580 arith_invalid(0); /* Zero scaled by +Infinity */
1581 return;
1582
1583 case TW_NaN:
1584 real_2op_NaN(st1_ptr, st1_tag, 0, st0_ptr);
1585 return;
1586 }
1587 } else if (st0_tag == TW_Infinity) {
1588 switch (st1_tag) {
1589 case TAG_Valid:
1590 case TAG_Zero:
1591 return;
1592
1593 case TW_Denormal:
1594 denormal_operand();
1595 return;
1596
1597 case TW_Infinity:
1598 if (signnegative(st1_ptr))
1599 arith_invalid(0); /* Infinity scaled by -Infinity */
1600 return;
1601
1602 case TW_NaN:
1603 real_2op_NaN(st1_ptr, st1_tag, 0, st0_ptr);
1604 return;
1605 }
1606 } else if (st0_tag == TW_NaN) {
1607 if (st1_tag != TAG_Empty) {
1608 real_2op_NaN(st1_ptr, st1_tag, 0, st0_ptr);
1609 return;
1610 }
1802 } 1611 }
1803 }
1804 else if ( st0_tag == TW_NaN )
1805 {
1806 if ( st1_tag != TAG_Empty )
1807 { real_2op_NaN(st1_ptr, st1_tag, 0, st0_ptr); return; }
1808 }
1809
1810#ifdef PARANOID 1612#ifdef PARANOID
1811 if ( !((st0_tag == TAG_Empty) || (st1_tag == TAG_Empty)) ) 1613 if (!((st0_tag == TAG_Empty) || (st1_tag == TAG_Empty))) {
1812 { 1614 EXCEPTION(EX_INTERNAL | 0x115);
1813 EXCEPTION(EX_INTERNAL | 0x115); 1615 return;
1814 return; 1616 }
1815 }
1816#endif 1617#endif
1817 1618
1818 /* At least one of st(0), st(1) must be empty */ 1619 /* At least one of st(0), st(1) must be empty */
1819 FPU_stack_underflow(); 1620 FPU_stack_underflow();
1820 1621
1821} 1622}
1822 1623
1823
1824/*---------------------------------------------------------------------------*/ 1624/*---------------------------------------------------------------------------*/
1825 1625
1826static FUNC_ST0 const trig_table_a[] = { 1626static FUNC_ST0 const trig_table_a[] = {
1827 f2xm1, fyl2x, fptan, fpatan, 1627 f2xm1, fyl2x, fptan, fpatan,
1828 fxtract, fprem1, (FUNC_ST0)fdecstp, (FUNC_ST0)fincstp 1628 fxtract, fprem1, (FUNC_ST0) fdecstp, (FUNC_ST0) fincstp
1829}; 1629};
1830 1630
1831void FPU_triga(void) 1631void FPU_triga(void)
1832{ 1632{
1833 (trig_table_a[FPU_rm])(&st(0), FPU_gettag0()); 1633 (trig_table_a[FPU_rm]) (&st(0), FPU_gettag0());
1834} 1634}
1835 1635
1836 1636static FUNC_ST0 const trig_table_b[] = {
1837static FUNC_ST0 const trig_table_b[] = 1637 fprem, fyl2xp1, fsqrt_, fsincos, frndint_, fscale, (FUNC_ST0) fsin, fcos
1838 { 1638};
1839 fprem, fyl2xp1, fsqrt_, fsincos, frndint_, fscale, (FUNC_ST0)fsin, fcos
1840 };
1841 1639
1842void FPU_trigb(void) 1640void FPU_trigb(void)
1843{ 1641{
1844 (trig_table_b[FPU_rm])(&st(0), FPU_gettag0()); 1642 (trig_table_b[FPU_rm]) (&st(0), FPU_gettag0());
1845} 1643}
diff --git a/arch/x86/math-emu/get_address.c b/arch/x86/math-emu/get_address.c
index 2e2c51a8bd3a..d701e2b39e44 100644
--- a/arch/x86/math-emu/get_address.c
+++ b/arch/x86/math-emu/get_address.c
@@ -17,7 +17,6 @@
17 | other processes using the emulator while swapping is in progress. | 17 | other processes using the emulator while swapping is in progress. |
18 +---------------------------------------------------------------------------*/ 18 +---------------------------------------------------------------------------*/
19 19
20
21#include <linux/stddef.h> 20#include <linux/stddef.h>
22 21
23#include <asm/uaccess.h> 22#include <asm/uaccess.h>
@@ -27,31 +26,30 @@
27#include "exception.h" 26#include "exception.h"
28#include "fpu_emu.h" 27#include "fpu_emu.h"
29 28
30
31#define FPU_WRITE_BIT 0x10 29#define FPU_WRITE_BIT 0x10
32 30
33static int reg_offset[] = { 31static int reg_offset[] = {
34 offsetof(struct info,___eax), 32 offsetof(struct info, ___eax),
35 offsetof(struct info,___ecx), 33 offsetof(struct info, ___ecx),
36 offsetof(struct info,___edx), 34 offsetof(struct info, ___edx),
37 offsetof(struct info,___ebx), 35 offsetof(struct info, ___ebx),
38 offsetof(struct info,___esp), 36 offsetof(struct info, ___esp),
39 offsetof(struct info,___ebp), 37 offsetof(struct info, ___ebp),
40 offsetof(struct info,___esi), 38 offsetof(struct info, ___esi),
41 offsetof(struct info,___edi) 39 offsetof(struct info, ___edi)
42}; 40};
43 41
44#define REG_(x) (*(long *)(reg_offset[(x)]+(u_char *) FPU_info)) 42#define REG_(x) (*(long *)(reg_offset[(x)]+(u_char *) FPU_info))
45 43
46static int reg_offset_vm86[] = { 44static int reg_offset_vm86[] = {
47 offsetof(struct info,___cs), 45 offsetof(struct info, ___cs),
48 offsetof(struct info,___vm86_ds), 46 offsetof(struct info, ___vm86_ds),
49 offsetof(struct info,___vm86_es), 47 offsetof(struct info, ___vm86_es),
50 offsetof(struct info,___vm86_fs), 48 offsetof(struct info, ___vm86_fs),
51 offsetof(struct info,___vm86_gs), 49 offsetof(struct info, ___vm86_gs),
52 offsetof(struct info,___ss), 50 offsetof(struct info, ___ss),
53 offsetof(struct info,___vm86_ds) 51 offsetof(struct info, ___vm86_ds)
54 }; 52};
55 53
56#define VM86_REG_(x) (*(unsigned short *) \ 54#define VM86_REG_(x) (*(unsigned short *) \
57 (reg_offset_vm86[((unsigned)x)]+(u_char *) FPU_info)) 55 (reg_offset_vm86[((unsigned)x)]+(u_char *) FPU_info))
@@ -60,158 +58,141 @@ static int reg_offset_vm86[] = {
60#define ___GS ___ds 58#define ___GS ___ds
61 59
62static int reg_offset_pm[] = { 60static int reg_offset_pm[] = {
63 offsetof(struct info,___cs), 61 offsetof(struct info, ___cs),
64 offsetof(struct info,___ds), 62 offsetof(struct info, ___ds),
65 offsetof(struct info,___es), 63 offsetof(struct info, ___es),
66 offsetof(struct info,___fs), 64 offsetof(struct info, ___fs),
67 offsetof(struct info,___GS), 65 offsetof(struct info, ___GS),
68 offsetof(struct info,___ss), 66 offsetof(struct info, ___ss),
69 offsetof(struct info,___ds) 67 offsetof(struct info, ___ds)
70 }; 68};
71 69
72#define PM_REG_(x) (*(unsigned short *) \ 70#define PM_REG_(x) (*(unsigned short *) \
73 (reg_offset_pm[((unsigned)x)]+(u_char *) FPU_info)) 71 (reg_offset_pm[((unsigned)x)]+(u_char *) FPU_info))
74 72
75
76/* Decode the SIB byte. This function assumes mod != 0 */ 73/* Decode the SIB byte. This function assumes mod != 0 */
77static int sib(int mod, unsigned long *fpu_eip) 74static int sib(int mod, unsigned long *fpu_eip)
78{ 75{
79 u_char ss,index,base; 76 u_char ss, index, base;
80 long offset; 77 long offset;
81 78
82 RE_ENTRANT_CHECK_OFF; 79 RE_ENTRANT_CHECK_OFF;
83 FPU_code_access_ok(1); 80 FPU_code_access_ok(1);
84 FPU_get_user(base, (u_char __user *) (*fpu_eip)); /* The SIB byte */ 81 FPU_get_user(base, (u_char __user *) (*fpu_eip)); /* The SIB byte */
85 RE_ENTRANT_CHECK_ON; 82 RE_ENTRANT_CHECK_ON;
86 (*fpu_eip)++; 83 (*fpu_eip)++;
87 ss = base >> 6; 84 ss = base >> 6;
88 index = (base >> 3) & 7; 85 index = (base >> 3) & 7;
89 base &= 7; 86 base &= 7;
90 87
91 if ((mod == 0) && (base == 5)) 88 if ((mod == 0) && (base == 5))
92 offset = 0; /* No base register */ 89 offset = 0; /* No base register */
93 else 90 else
94 offset = REG_(base); 91 offset = REG_(base);
95 92
96 if (index == 4) 93 if (index == 4) {
97 { 94 /* No index register */
98 /* No index register */ 95 /* A non-zero ss is illegal */
99 /* A non-zero ss is illegal */ 96 if (ss)
100 if ( ss ) 97 EXCEPTION(EX_Invalid);
101 EXCEPTION(EX_Invalid); 98 } else {
102 } 99 offset += (REG_(index)) << ss;
103 else 100 }
104 { 101
105 offset += (REG_(index)) << ss; 102 if (mod == 1) {
106 } 103 /* 8 bit signed displacement */
107 104 long displacement;
108 if (mod == 1) 105 RE_ENTRANT_CHECK_OFF;
109 { 106 FPU_code_access_ok(1);
110 /* 8 bit signed displacement */ 107 FPU_get_user(displacement, (signed char __user *)(*fpu_eip));
111 long displacement; 108 offset += displacement;
112 RE_ENTRANT_CHECK_OFF; 109 RE_ENTRANT_CHECK_ON;
113 FPU_code_access_ok(1); 110 (*fpu_eip)++;
114 FPU_get_user(displacement, (signed char __user *) (*fpu_eip)); 111 } else if (mod == 2 || base == 5) { /* The second condition also has mod==0 */
115 offset += displacement; 112 /* 32 bit displacement */
116 RE_ENTRANT_CHECK_ON; 113 long displacement;
117 (*fpu_eip)++; 114 RE_ENTRANT_CHECK_OFF;
118 } 115 FPU_code_access_ok(4);
119 else if (mod == 2 || base == 5) /* The second condition also has mod==0 */ 116 FPU_get_user(displacement, (long __user *)(*fpu_eip));
120 { 117 offset += displacement;
121 /* 32 bit displacement */ 118 RE_ENTRANT_CHECK_ON;
122 long displacement; 119 (*fpu_eip) += 4;
123 RE_ENTRANT_CHECK_OFF; 120 }
124 FPU_code_access_ok(4);
125 FPU_get_user(displacement, (long __user *) (*fpu_eip));
126 offset += displacement;
127 RE_ENTRANT_CHECK_ON;
128 (*fpu_eip) += 4;
129 }
130
131 return offset;
132}
133 121
122 return offset;
123}
134 124
135static unsigned long vm86_segment(u_char segment, 125static unsigned long vm86_segment(u_char segment, struct address *addr)
136 struct address *addr)
137{ 126{
138 segment--; 127 segment--;
139#ifdef PARANOID 128#ifdef PARANOID
140 if ( segment > PREFIX_SS_ ) 129 if (segment > PREFIX_SS_) {
141 { 130 EXCEPTION(EX_INTERNAL | 0x130);
142 EXCEPTION(EX_INTERNAL|0x130); 131 math_abort(FPU_info, SIGSEGV);
143 math_abort(FPU_info,SIGSEGV); 132 }
144 }
145#endif /* PARANOID */ 133#endif /* PARANOID */
146 addr->selector = VM86_REG_(segment); 134 addr->selector = VM86_REG_(segment);
147 return (unsigned long)VM86_REG_(segment) << 4; 135 return (unsigned long)VM86_REG_(segment) << 4;
148} 136}
149 137
150
151/* This should work for 16 and 32 bit protected mode. */ 138/* This should work for 16 and 32 bit protected mode. */
152static long pm_address(u_char FPU_modrm, u_char segment, 139static long pm_address(u_char FPU_modrm, u_char segment,
153 struct address *addr, long offset) 140 struct address *addr, long offset)
154{ 141{
155 struct desc_struct descriptor; 142 struct desc_struct descriptor;
156 unsigned long base_address, limit, address, seg_top; 143 unsigned long base_address, limit, address, seg_top;
157 144
158 segment--; 145 segment--;
159 146
160#ifdef PARANOID 147#ifdef PARANOID
161 /* segment is unsigned, so this also detects if segment was 0: */ 148 /* segment is unsigned, so this also detects if segment was 0: */
162 if ( segment > PREFIX_SS_ ) 149 if (segment > PREFIX_SS_) {
163 { 150 EXCEPTION(EX_INTERNAL | 0x132);
164 EXCEPTION(EX_INTERNAL|0x132); 151 math_abort(FPU_info, SIGSEGV);
165 math_abort(FPU_info,SIGSEGV); 152 }
166 }
167#endif /* PARANOID */ 153#endif /* PARANOID */
168 154
169 switch ( segment ) 155 switch (segment) {
170 { 156 /* gs isn't used by the kernel, so it still has its
171 /* gs isn't used by the kernel, so it still has its 157 user-space value. */
172 user-space value. */ 158 case PREFIX_GS_ - 1:
173 case PREFIX_GS_-1: 159 /* N.B. - movl %seg, mem is a 2 byte write regardless of prefix */
174 /* N.B. - movl %seg, mem is a 2 byte write regardless of prefix */ 160 savesegment(gs, addr->selector);
175 savesegment(gs, addr->selector); 161 break;
176 break; 162 default:
177 default: 163 addr->selector = PM_REG_(segment);
178 addr->selector = PM_REG_(segment);
179 }
180
181 descriptor = LDT_DESCRIPTOR(PM_REG_(segment));
182 base_address = SEG_BASE_ADDR(descriptor);
183 address = base_address + offset;
184 limit = base_address
185 + (SEG_LIMIT(descriptor)+1) * SEG_GRANULARITY(descriptor) - 1;
186 if ( limit < base_address ) limit = 0xffffffff;
187
188 if ( SEG_EXPAND_DOWN(descriptor) )
189 {
190 if ( SEG_G_BIT(descriptor) )
191 seg_top = 0xffffffff;
192 else
193 {
194 seg_top = base_address + (1 << 20);
195 if ( seg_top < base_address ) seg_top = 0xffffffff;
196 } 164 }
197 access_limit =
198 (address <= limit) || (address >= seg_top) ? 0 :
199 ((seg_top-address) >= 255 ? 255 : seg_top-address);
200 }
201 else
202 {
203 access_limit =
204 (address > limit) || (address < base_address) ? 0 :
205 ((limit-address) >= 254 ? 255 : limit-address+1);
206 }
207 if ( SEG_EXECUTE_ONLY(descriptor) ||
208 (!SEG_WRITE_PERM(descriptor) && (FPU_modrm & FPU_WRITE_BIT)) )
209 {
210 access_limit = 0;
211 }
212 return address;
213}
214 165
166 descriptor = LDT_DESCRIPTOR(PM_REG_(segment));
167 base_address = SEG_BASE_ADDR(descriptor);
168 address = base_address + offset;
169 limit = base_address
170 + (SEG_LIMIT(descriptor) + 1) * SEG_GRANULARITY(descriptor) - 1;
171 if (limit < base_address)
172 limit = 0xffffffff;
173
174 if (SEG_EXPAND_DOWN(descriptor)) {
175 if (SEG_G_BIT(descriptor))
176 seg_top = 0xffffffff;
177 else {
178 seg_top = base_address + (1 << 20);
179 if (seg_top < base_address)
180 seg_top = 0xffffffff;
181 }
182 access_limit =
183 (address <= limit) || (address >= seg_top) ? 0 :
184 ((seg_top - address) >= 255 ? 255 : seg_top - address);
185 } else {
186 access_limit =
187 (address > limit) || (address < base_address) ? 0 :
188 ((limit - address) >= 254 ? 255 : limit - address + 1);
189 }
190 if (SEG_EXECUTE_ONLY(descriptor) ||
191 (!SEG_WRITE_PERM(descriptor) && (FPU_modrm & FPU_WRITE_BIT))) {
192 access_limit = 0;
193 }
194 return address;
195}
215 196
216/* 197/*
217 MOD R/M byte: MOD == 3 has a special use for the FPU 198 MOD R/M byte: MOD == 3 has a special use for the FPU
@@ -221,7 +202,6 @@ static long pm_address(u_char FPU_modrm, u_char segment,
221 ..... ......... ......... 202 ..... ......... .........
222 MOD OPCODE(2) R/M 203 MOD OPCODE(2) R/M
223 204
224
225 SIB byte 205 SIB byte
226 206
227 7 6 5 4 3 2 1 0 207 7 6 5 4 3 2 1 0
@@ -231,208 +211,194 @@ static long pm_address(u_char FPU_modrm, u_char segment,
231*/ 211*/
232 212
233void __user *FPU_get_address(u_char FPU_modrm, unsigned long *fpu_eip, 213void __user *FPU_get_address(u_char FPU_modrm, unsigned long *fpu_eip,
234 struct address *addr, 214 struct address *addr, fpu_addr_modes addr_modes)
235 fpu_addr_modes addr_modes) 215{
216 u_char mod;
217 unsigned rm = FPU_modrm & 7;
218 long *cpu_reg_ptr;
219 int address = 0; /* Initialized just to stop compiler warnings. */
220
221 /* Memory accessed via the cs selector is write protected
222 in `non-segmented' 32 bit protected mode. */
223 if (!addr_modes.default_mode && (FPU_modrm & FPU_WRITE_BIT)
224 && (addr_modes.override.segment == PREFIX_CS_)) {
225 math_abort(FPU_info, SIGSEGV);
226 }
227
228 addr->selector = FPU_DS; /* Default, for 32 bit non-segmented mode. */
229
230 mod = (FPU_modrm >> 6) & 3;
231
232 if (rm == 4 && mod != 3) {
233 address = sib(mod, fpu_eip);
234 } else {
235 cpu_reg_ptr = &REG_(rm);
236 switch (mod) {
237 case 0:
238 if (rm == 5) {
239 /* Special case: disp32 */
240 RE_ENTRANT_CHECK_OFF;
241 FPU_code_access_ok(4);
242 FPU_get_user(address,
243 (unsigned long __user
244 *)(*fpu_eip));
245 (*fpu_eip) += 4;
246 RE_ENTRANT_CHECK_ON;
247 addr->offset = address;
248 return (void __user *)address;
249 } else {
250 address = *cpu_reg_ptr; /* Just return the contents
251 of the cpu register */
252 addr->offset = address;
253 return (void __user *)address;
254 }
255 case 1:
256 /* 8 bit signed displacement */
257 RE_ENTRANT_CHECK_OFF;
258 FPU_code_access_ok(1);
259 FPU_get_user(address, (signed char __user *)(*fpu_eip));
260 RE_ENTRANT_CHECK_ON;
261 (*fpu_eip)++;
262 break;
263 case 2:
264 /* 32 bit displacement */
265 RE_ENTRANT_CHECK_OFF;
266 FPU_code_access_ok(4);
267 FPU_get_user(address, (long __user *)(*fpu_eip));
268 (*fpu_eip) += 4;
269 RE_ENTRANT_CHECK_ON;
270 break;
271 case 3:
272 /* Not legal for the FPU */
273 EXCEPTION(EX_Invalid);
274 }
275 address += *cpu_reg_ptr;
276 }
277
278 addr->offset = address;
279
280 switch (addr_modes.default_mode) {
281 case 0:
282 break;
283 case VM86:
284 address += vm86_segment(addr_modes.override.segment, addr);
285 break;
286 case PM16:
287 case SEG32:
288 address = pm_address(FPU_modrm, addr_modes.override.segment,
289 addr, address);
290 break;
291 default:
292 EXCEPTION(EX_INTERNAL | 0x133);
293 }
294
295 return (void __user *)address;
296}
297
298void __user *FPU_get_address_16(u_char FPU_modrm, unsigned long *fpu_eip,
299 struct address *addr, fpu_addr_modes addr_modes)
236{ 300{
237 u_char mod; 301 u_char mod;
238 unsigned rm = FPU_modrm & 7; 302 unsigned rm = FPU_modrm & 7;
239 long *cpu_reg_ptr; 303 int address = 0; /* Default used for mod == 0 */
240 int address = 0; /* Initialized just to stop compiler warnings. */ 304
241 305 /* Memory accessed via the cs selector is write protected
242 /* Memory accessed via the cs selector is write protected 306 in `non-segmented' 32 bit protected mode. */
243 in `non-segmented' 32 bit protected mode. */ 307 if (!addr_modes.default_mode && (FPU_modrm & FPU_WRITE_BIT)
244 if ( !addr_modes.default_mode && (FPU_modrm & FPU_WRITE_BIT) 308 && (addr_modes.override.segment == PREFIX_CS_)) {
245 && (addr_modes.override.segment == PREFIX_CS_) ) 309 math_abort(FPU_info, SIGSEGV);
246 { 310 }
247 math_abort(FPU_info,SIGSEGV); 311
248 } 312 addr->selector = FPU_DS; /* Default, for 32 bit non-segmented mode. */
249 313
250 addr->selector = FPU_DS; /* Default, for 32 bit non-segmented mode. */ 314 mod = (FPU_modrm >> 6) & 3;
251 315
252 mod = (FPU_modrm >> 6) & 3; 316 switch (mod) {
253
254 if (rm == 4 && mod != 3)
255 {
256 address = sib(mod, fpu_eip);
257 }
258 else
259 {
260 cpu_reg_ptr = & REG_(rm);
261 switch (mod)
262 {
263 case 0: 317 case 0:
264 if (rm == 5) 318 if (rm == 6) {
265 { 319 /* Special case: disp16 */
266 /* Special case: disp32 */ 320 RE_ENTRANT_CHECK_OFF;
267 RE_ENTRANT_CHECK_OFF; 321 FPU_code_access_ok(2);
268 FPU_code_access_ok(4); 322 FPU_get_user(address,
269 FPU_get_user(address, (unsigned long __user *) (*fpu_eip)); 323 (unsigned short __user *)(*fpu_eip));
270 (*fpu_eip) += 4; 324 (*fpu_eip) += 2;
271 RE_ENTRANT_CHECK_ON; 325 RE_ENTRANT_CHECK_ON;
272 addr->offset = address; 326 goto add_segment;
273 return (void __user *) address; 327 }
274 } 328 break;
275 else
276 {
277 address = *cpu_reg_ptr; /* Just return the contents
278 of the cpu register */
279 addr->offset = address;
280 return (void __user *) address;
281 }
282 case 1: 329 case 1:
283 /* 8 bit signed displacement */ 330 /* 8 bit signed displacement */
284 RE_ENTRANT_CHECK_OFF; 331 RE_ENTRANT_CHECK_OFF;
285 FPU_code_access_ok(1); 332 FPU_code_access_ok(1);
286 FPU_get_user(address, (signed char __user *) (*fpu_eip)); 333 FPU_get_user(address, (signed char __user *)(*fpu_eip));
287 RE_ENTRANT_CHECK_ON; 334 RE_ENTRANT_CHECK_ON;
288 (*fpu_eip)++; 335 (*fpu_eip)++;
289 break; 336 break;
290 case 2: 337 case 2:
291 /* 32 bit displacement */ 338 /* 16 bit displacement */
292 RE_ENTRANT_CHECK_OFF; 339 RE_ENTRANT_CHECK_OFF;
293 FPU_code_access_ok(4); 340 FPU_code_access_ok(2);
294 FPU_get_user(address, (long __user *) (*fpu_eip)); 341 FPU_get_user(address, (unsigned short __user *)(*fpu_eip));
295 (*fpu_eip) += 4; 342 (*fpu_eip) += 2;
296 RE_ENTRANT_CHECK_ON; 343 RE_ENTRANT_CHECK_ON;
297 break; 344 break;
298 case 3: 345 case 3:
299 /* Not legal for the FPU */ 346 /* Not legal for the FPU */
300 EXCEPTION(EX_Invalid); 347 EXCEPTION(EX_Invalid);
348 break;
349 }
350 switch (rm) {
351 case 0:
352 address += FPU_info->___ebx + FPU_info->___esi;
353 break;
354 case 1:
355 address += FPU_info->___ebx + FPU_info->___edi;
356 break;
357 case 2:
358 address += FPU_info->___ebp + FPU_info->___esi;
359 if (addr_modes.override.segment == PREFIX_DEFAULT)
360 addr_modes.override.segment = PREFIX_SS_;
361 break;
362 case 3:
363 address += FPU_info->___ebp + FPU_info->___edi;
364 if (addr_modes.override.segment == PREFIX_DEFAULT)
365 addr_modes.override.segment = PREFIX_SS_;
366 break;
367 case 4:
368 address += FPU_info->___esi;
369 break;
370 case 5:
371 address += FPU_info->___edi;
372 break;
373 case 6:
374 address += FPU_info->___ebp;
375 if (addr_modes.override.segment == PREFIX_DEFAULT)
376 addr_modes.override.segment = PREFIX_SS_;
377 break;
378 case 7:
379 address += FPU_info->___ebx;
380 break;
301 } 381 }
302 address += *cpu_reg_ptr;
303 }
304
305 addr->offset = address;
306
307 switch ( addr_modes.default_mode )
308 {
309 case 0:
310 break;
311 case VM86:
312 address += vm86_segment(addr_modes.override.segment, addr);
313 break;
314 case PM16:
315 case SEG32:
316 address = pm_address(FPU_modrm, addr_modes.override.segment,
317 addr, address);
318 break;
319 default:
320 EXCEPTION(EX_INTERNAL|0x133);
321 }
322
323 return (void __user *)address;
324}
325 382
383 add_segment:
384 address &= 0xffff;
326 385
327void __user *FPU_get_address_16(u_char FPU_modrm, unsigned long *fpu_eip, 386 addr->offset = address;
328 struct address *addr, 387
329 fpu_addr_modes addr_modes) 388 switch (addr_modes.default_mode) {
330{ 389 case 0:
331 u_char mod; 390 break;
332 unsigned rm = FPU_modrm & 7; 391 case VM86:
333 int address = 0; /* Default used for mod == 0 */ 392 address += vm86_segment(addr_modes.override.segment, addr);
334 393 break;
335 /* Memory accessed via the cs selector is write protected 394 case PM16:
336 in `non-segmented' 32 bit protected mode. */ 395 case SEG32:
337 if ( !addr_modes.default_mode && (FPU_modrm & FPU_WRITE_BIT) 396 address = pm_address(FPU_modrm, addr_modes.override.segment,
338 && (addr_modes.override.segment == PREFIX_CS_) ) 397 addr, address);
339 { 398 break;
340 math_abort(FPU_info,SIGSEGV); 399 default:
341 } 400 EXCEPTION(EX_INTERNAL | 0x131);
342
343 addr->selector = FPU_DS; /* Default, for 32 bit non-segmented mode. */
344
345 mod = (FPU_modrm >> 6) & 3;
346
347 switch (mod)
348 {
349 case 0:
350 if (rm == 6)
351 {
352 /* Special case: disp16 */
353 RE_ENTRANT_CHECK_OFF;
354 FPU_code_access_ok(2);
355 FPU_get_user(address, (unsigned short __user *) (*fpu_eip));
356 (*fpu_eip) += 2;
357 RE_ENTRANT_CHECK_ON;
358 goto add_segment;
359 } 401 }
360 break; 402
361 case 1: 403 return (void __user *)address;
362 /* 8 bit signed displacement */
363 RE_ENTRANT_CHECK_OFF;
364 FPU_code_access_ok(1);
365 FPU_get_user(address, (signed char __user *) (*fpu_eip));
366 RE_ENTRANT_CHECK_ON;
367 (*fpu_eip)++;
368 break;
369 case 2:
370 /* 16 bit displacement */
371 RE_ENTRANT_CHECK_OFF;
372 FPU_code_access_ok(2);
373 FPU_get_user(address, (unsigned short __user *) (*fpu_eip));
374 (*fpu_eip) += 2;
375 RE_ENTRANT_CHECK_ON;
376 break;
377 case 3:
378 /* Not legal for the FPU */
379 EXCEPTION(EX_Invalid);
380 break;
381 }
382 switch ( rm )
383 {
384 case 0:
385 address += FPU_info->___ebx + FPU_info->___esi;
386 break;
387 case 1:
388 address += FPU_info->___ebx + FPU_info->___edi;
389 break;
390 case 2:
391 address += FPU_info->___ebp + FPU_info->___esi;
392 if ( addr_modes.override.segment == PREFIX_DEFAULT )
393 addr_modes.override.segment = PREFIX_SS_;
394 break;
395 case 3:
396 address += FPU_info->___ebp + FPU_info->___edi;
397 if ( addr_modes.override.segment == PREFIX_DEFAULT )
398 addr_modes.override.segment = PREFIX_SS_;
399 break;
400 case 4:
401 address += FPU_info->___esi;
402 break;
403 case 5:
404 address += FPU_info->___edi;
405 break;
406 case 6:
407 address += FPU_info->___ebp;
408 if ( addr_modes.override.segment == PREFIX_DEFAULT )
409 addr_modes.override.segment = PREFIX_SS_;
410 break;
411 case 7:
412 address += FPU_info->___ebx;
413 break;
414 }
415
416 add_segment:
417 address &= 0xffff;
418
419 addr->offset = address;
420
421 switch ( addr_modes.default_mode )
422 {
423 case 0:
424 break;
425 case VM86:
426 address += vm86_segment(addr_modes.override.segment, addr);
427 break;
428 case PM16:
429 case SEG32:
430 address = pm_address(FPU_modrm, addr_modes.override.segment,
431 addr, address);
432 break;
433 default:
434 EXCEPTION(EX_INTERNAL|0x131);
435 }
436
437 return (void __user *)address ;
438} 404}
diff --git a/arch/x86/math-emu/load_store.c b/arch/x86/math-emu/load_store.c
index eebd6fb1c8a8..2931ff355218 100644
--- a/arch/x86/math-emu/load_store.c
+++ b/arch/x86/math-emu/load_store.c
@@ -26,247 +26,257 @@
26#include "status_w.h" 26#include "status_w.h"
27#include "control_w.h" 27#include "control_w.h"
28 28
29 29#define _NONE_ 0 /* st0_ptr etc not needed */
30#define _NONE_ 0 /* st0_ptr etc not needed */ 30#define _REG0_ 1 /* Will be storing st(0) */
31#define _REG0_ 1 /* Will be storing st(0) */ 31#define _PUSH_ 3 /* Need to check for space to push onto stack */
32#define _PUSH_ 3 /* Need to check for space to push onto stack */ 32#define _null_ 4 /* Function illegal or not implemented */
33#define _null_ 4 /* Function illegal or not implemented */
34 33
35#define pop_0() { FPU_settag0(TAG_Empty); top++; } 34#define pop_0() { FPU_settag0(TAG_Empty); top++; }
36 35
37
38static u_char const type_table[32] = { 36static u_char const type_table[32] = {
39 _PUSH_, _PUSH_, _PUSH_, _PUSH_, 37 _PUSH_, _PUSH_, _PUSH_, _PUSH_,
40 _null_, _null_, _null_, _null_, 38 _null_, _null_, _null_, _null_,
41 _REG0_, _REG0_, _REG0_, _REG0_, 39 _REG0_, _REG0_, _REG0_, _REG0_,
42 _REG0_, _REG0_, _REG0_, _REG0_, 40 _REG0_, _REG0_, _REG0_, _REG0_,
43 _NONE_, _null_, _NONE_, _PUSH_, 41 _NONE_, _null_, _NONE_, _PUSH_,
44 _NONE_, _PUSH_, _null_, _PUSH_, 42 _NONE_, _PUSH_, _null_, _PUSH_,
45 _NONE_, _null_, _NONE_, _REG0_, 43 _NONE_, _null_, _NONE_, _REG0_,
46 _NONE_, _REG0_, _NONE_, _REG0_ 44 _NONE_, _REG0_, _NONE_, _REG0_
47 }; 45};
48 46
49u_char const data_sizes_16[32] = { 47u_char const data_sizes_16[32] = {
50 4, 4, 8, 2, 0, 0, 0, 0, 48 4, 4, 8, 2, 0, 0, 0, 0,
51 4, 4, 8, 2, 4, 4, 8, 2, 49 4, 4, 8, 2, 4, 4, 8, 2,
52 14, 0, 94, 10, 2, 10, 0, 8, 50 14, 0, 94, 10, 2, 10, 0, 8,
53 14, 0, 94, 10, 2, 10, 2, 8 51 14, 0, 94, 10, 2, 10, 2, 8
54}; 52};
55 53
56static u_char const data_sizes_32[32] = { 54static u_char const data_sizes_32[32] = {
57 4, 4, 8, 2, 0, 0, 0, 0, 55 4, 4, 8, 2, 0, 0, 0, 0,
58 4, 4, 8, 2, 4, 4, 8, 2, 56 4, 4, 8, 2, 4, 4, 8, 2,
59 28, 0,108, 10, 2, 10, 0, 8, 57 28, 0, 108, 10, 2, 10, 0, 8,
60 28, 0,108, 10, 2, 10, 2, 8 58 28, 0, 108, 10, 2, 10, 2, 8
61}; 59};
62 60
63int FPU_load_store(u_char type, fpu_addr_modes addr_modes, 61int FPU_load_store(u_char type, fpu_addr_modes addr_modes,
64 void __user *data_address) 62 void __user * data_address)
65{ 63{
66 FPU_REG loaded_data; 64 FPU_REG loaded_data;
67 FPU_REG *st0_ptr; 65 FPU_REG *st0_ptr;
68 u_char st0_tag = TAG_Empty; /* This is just to stop a gcc warning. */ 66 u_char st0_tag = TAG_Empty; /* This is just to stop a gcc warning. */
69 u_char loaded_tag; 67 u_char loaded_tag;
70 68
71 st0_ptr = NULL; /* Initialized just to stop compiler warnings. */ 69 st0_ptr = NULL; /* Initialized just to stop compiler warnings. */
72 70
73 if ( addr_modes.default_mode & PROTECTED ) 71 if (addr_modes.default_mode & PROTECTED) {
74 { 72 if (addr_modes.default_mode == SEG32) {
75 if ( addr_modes.default_mode == SEG32 ) 73 if (access_limit < data_sizes_32[type])
76 { 74 math_abort(FPU_info, SIGSEGV);
77 if ( access_limit < data_sizes_32[type] ) 75 } else if (addr_modes.default_mode == PM16) {
78 math_abort(FPU_info,SIGSEGV); 76 if (access_limit < data_sizes_16[type])
79 } 77 math_abort(FPU_info, SIGSEGV);
80 else if ( addr_modes.default_mode == PM16 ) 78 }
81 {
82 if ( access_limit < data_sizes_16[type] )
83 math_abort(FPU_info,SIGSEGV);
84 }
85#ifdef PARANOID 79#ifdef PARANOID
86 else 80 else
87 EXCEPTION(EX_INTERNAL|0x140); 81 EXCEPTION(EX_INTERNAL | 0x140);
88#endif /* PARANOID */ 82#endif /* PARANOID */
89 } 83 }
90 84
91 switch ( type_table[type] ) 85 switch (type_table[type]) {
92 { 86 case _NONE_:
93 case _NONE_: 87 break;
94 break; 88 case _REG0_:
95 case _REG0_: 89 st0_ptr = &st(0); /* Some of these instructions pop after
96 st0_ptr = &st(0); /* Some of these instructions pop after 90 storing */
97 storing */ 91 st0_tag = FPU_gettag0();
98 st0_tag = FPU_gettag0(); 92 break;
99 break; 93 case _PUSH_:
100 case _PUSH_: 94 {
101 { 95 if (FPU_gettagi(-1) != TAG_Empty) {
102 if ( FPU_gettagi(-1) != TAG_Empty ) 96 FPU_stack_overflow();
103 { FPU_stack_overflow(); return 0; } 97 return 0;
104 top--; 98 }
105 st0_ptr = &st(0); 99 top--;
106 } 100 st0_ptr = &st(0);
107 break; 101 }
108 case _null_: 102 break;
109 FPU_illegal(); 103 case _null_:
110 return 0; 104 FPU_illegal();
105 return 0;
111#ifdef PARANOID 106#ifdef PARANOID
112 default: 107 default:
113 EXCEPTION(EX_INTERNAL|0x141); 108 EXCEPTION(EX_INTERNAL | 0x141);
114 return 0; 109 return 0;
115#endif /* PARANOID */ 110#endif /* PARANOID */
116 }
117
118 switch ( type )
119 {
120 case 000: /* fld m32real */
121 clear_C1();
122 loaded_tag = FPU_load_single((float __user *)data_address, &loaded_data);
123 if ( (loaded_tag == TAG_Special)
124 && isNaN(&loaded_data)
125 && (real_1op_NaN(&loaded_data) < 0) )
126 {
127 top++;
128 break;
129 }
130 FPU_copy_to_reg0(&loaded_data, loaded_tag);
131 break;
132 case 001: /* fild m32int */
133 clear_C1();
134 loaded_tag = FPU_load_int32((long __user *)data_address, &loaded_data);
135 FPU_copy_to_reg0(&loaded_data, loaded_tag);
136 break;
137 case 002: /* fld m64real */
138 clear_C1();
139 loaded_tag = FPU_load_double((double __user *)data_address, &loaded_data);
140 if ( (loaded_tag == TAG_Special)
141 && isNaN(&loaded_data)
142 && (real_1op_NaN(&loaded_data) < 0) )
143 {
144 top++;
145 break;
146 } 111 }
147 FPU_copy_to_reg0(&loaded_data, loaded_tag); 112
148 break; 113 switch (type) {
149 case 003: /* fild m16int */ 114 case 000: /* fld m32real */
150 clear_C1(); 115 clear_C1();
151 loaded_tag = FPU_load_int16((short __user *)data_address, &loaded_data); 116 loaded_tag =
152 FPU_copy_to_reg0(&loaded_data, loaded_tag); 117 FPU_load_single((float __user *)data_address, &loaded_data);
153 break; 118 if ((loaded_tag == TAG_Special)
154 case 010: /* fst m32real */ 119 && isNaN(&loaded_data)
155 clear_C1(); 120 && (real_1op_NaN(&loaded_data) < 0)) {
156 FPU_store_single(st0_ptr, st0_tag, (float __user *)data_address); 121 top++;
157 break; 122 break;
158 case 011: /* fist m32int */ 123 }
159 clear_C1(); 124 FPU_copy_to_reg0(&loaded_data, loaded_tag);
160 FPU_store_int32(st0_ptr, st0_tag, (long __user *)data_address); 125 break;
161 break; 126 case 001: /* fild m32int */
162 case 012: /* fst m64real */ 127 clear_C1();
163 clear_C1(); 128 loaded_tag =
164 FPU_store_double(st0_ptr, st0_tag, (double __user *)data_address); 129 FPU_load_int32((long __user *)data_address, &loaded_data);
165 break; 130 FPU_copy_to_reg0(&loaded_data, loaded_tag);
166 case 013: /* fist m16int */ 131 break;
167 clear_C1(); 132 case 002: /* fld m64real */
168 FPU_store_int16(st0_ptr, st0_tag, (short __user *)data_address); 133 clear_C1();
169 break; 134 loaded_tag =
170 case 014: /* fstp m32real */ 135 FPU_load_double((double __user *)data_address,
171 clear_C1(); 136 &loaded_data);
172 if ( FPU_store_single(st0_ptr, st0_tag, (float __user *)data_address) ) 137 if ((loaded_tag == TAG_Special)
173 pop_0(); /* pop only if the number was actually stored 138 && isNaN(&loaded_data)
174 (see the 80486 manual p16-28) */ 139 && (real_1op_NaN(&loaded_data) < 0)) {
175 break; 140 top++;
176 case 015: /* fistp m32int */ 141 break;
177 clear_C1(); 142 }
178 if ( FPU_store_int32(st0_ptr, st0_tag, (long __user *)data_address) ) 143 FPU_copy_to_reg0(&loaded_data, loaded_tag);
179 pop_0(); /* pop only if the number was actually stored 144 break;
180 (see the 80486 manual p16-28) */ 145 case 003: /* fild m16int */
181 break; 146 clear_C1();
182 case 016: /* fstp m64real */ 147 loaded_tag =
183 clear_C1(); 148 FPU_load_int16((short __user *)data_address, &loaded_data);
184 if ( FPU_store_double(st0_ptr, st0_tag, (double __user *)data_address) ) 149 FPU_copy_to_reg0(&loaded_data, loaded_tag);
185 pop_0(); /* pop only if the number was actually stored 150 break;
186 (see the 80486 manual p16-28) */ 151 case 010: /* fst m32real */
187 break; 152 clear_C1();
188 case 017: /* fistp m16int */ 153 FPU_store_single(st0_ptr, st0_tag,
189 clear_C1(); 154 (float __user *)data_address);
190 if ( FPU_store_int16(st0_ptr, st0_tag, (short __user *)data_address) ) 155 break;
191 pop_0(); /* pop only if the number was actually stored 156 case 011: /* fist m32int */
192 (see the 80486 manual p16-28) */ 157 clear_C1();
193 break; 158 FPU_store_int32(st0_ptr, st0_tag, (long __user *)data_address);
194 case 020: /* fldenv m14/28byte */ 159 break;
195 fldenv(addr_modes, (u_char __user *)data_address); 160 case 012: /* fst m64real */
196 /* Ensure that the values just loaded are not changed by 161 clear_C1();
197 fix-up operations. */ 162 FPU_store_double(st0_ptr, st0_tag,
198 return 1; 163 (double __user *)data_address);
199 case 022: /* frstor m94/108byte */ 164 break;
200 frstor(addr_modes, (u_char __user *)data_address); 165 case 013: /* fist m16int */
201 /* Ensure that the values just loaded are not changed by 166 clear_C1();
202 fix-up operations. */ 167 FPU_store_int16(st0_ptr, st0_tag, (short __user *)data_address);
203 return 1; 168 break;
204 case 023: /* fbld m80dec */ 169 case 014: /* fstp m32real */
205 clear_C1(); 170 clear_C1();
206 loaded_tag = FPU_load_bcd((u_char __user *)data_address); 171 if (FPU_store_single
207 FPU_settag0(loaded_tag); 172 (st0_ptr, st0_tag, (float __user *)data_address))
208 break; 173 pop_0(); /* pop only if the number was actually stored
209 case 024: /* fldcw */ 174 (see the 80486 manual p16-28) */
210 RE_ENTRANT_CHECK_OFF; 175 break;
211 FPU_access_ok(VERIFY_READ, data_address, 2); 176 case 015: /* fistp m32int */
212 FPU_get_user(control_word, (unsigned short __user *) data_address); 177 clear_C1();
213 RE_ENTRANT_CHECK_ON; 178 if (FPU_store_int32
214 if ( partial_status & ~control_word & CW_Exceptions ) 179 (st0_ptr, st0_tag, (long __user *)data_address))
215 partial_status |= (SW_Summary | SW_Backward); 180 pop_0(); /* pop only if the number was actually stored
216 else 181 (see the 80486 manual p16-28) */
217 partial_status &= ~(SW_Summary | SW_Backward); 182 break;
183 case 016: /* fstp m64real */
184 clear_C1();
185 if (FPU_store_double
186 (st0_ptr, st0_tag, (double __user *)data_address))
187 pop_0(); /* pop only if the number was actually stored
188 (see the 80486 manual p16-28) */
189 break;
190 case 017: /* fistp m16int */
191 clear_C1();
192 if (FPU_store_int16
193 (st0_ptr, st0_tag, (short __user *)data_address))
194 pop_0(); /* pop only if the number was actually stored
195 (see the 80486 manual p16-28) */
196 break;
197 case 020: /* fldenv m14/28byte */
198 fldenv(addr_modes, (u_char __user *) data_address);
199 /* Ensure that the values just loaded are not changed by
200 fix-up operations. */
201 return 1;
202 case 022: /* frstor m94/108byte */
203 frstor(addr_modes, (u_char __user *) data_address);
204 /* Ensure that the values just loaded are not changed by
205 fix-up operations. */
206 return 1;
207 case 023: /* fbld m80dec */
208 clear_C1();
209 loaded_tag = FPU_load_bcd((u_char __user *) data_address);
210 FPU_settag0(loaded_tag);
211 break;
212 case 024: /* fldcw */
213 RE_ENTRANT_CHECK_OFF;
214 FPU_access_ok(VERIFY_READ, data_address, 2);
215 FPU_get_user(control_word,
216 (unsigned short __user *)data_address);
217 RE_ENTRANT_CHECK_ON;
218 if (partial_status & ~control_word & CW_Exceptions)
219 partial_status |= (SW_Summary | SW_Backward);
220 else
221 partial_status &= ~(SW_Summary | SW_Backward);
218#ifdef PECULIAR_486 222#ifdef PECULIAR_486
219 control_word |= 0x40; /* An 80486 appears to always set this bit */ 223 control_word |= 0x40; /* An 80486 appears to always set this bit */
220#endif /* PECULIAR_486 */ 224#endif /* PECULIAR_486 */
221 return 1; 225 return 1;
222 case 025: /* fld m80real */ 226 case 025: /* fld m80real */
223 clear_C1(); 227 clear_C1();
224 loaded_tag = FPU_load_extended((long double __user *)data_address, 0); 228 loaded_tag =
225 FPU_settag0(loaded_tag); 229 FPU_load_extended((long double __user *)data_address, 0);
226 break; 230 FPU_settag0(loaded_tag);
227 case 027: /* fild m64int */ 231 break;
228 clear_C1(); 232 case 027: /* fild m64int */
229 loaded_tag = FPU_load_int64((long long __user *)data_address); 233 clear_C1();
230 if (loaded_tag == TAG_Error) 234 loaded_tag = FPU_load_int64((long long __user *)data_address);
235 if (loaded_tag == TAG_Error)
236 return 0;
237 FPU_settag0(loaded_tag);
238 break;
239 case 030: /* fstenv m14/28byte */
240 fstenv(addr_modes, (u_char __user *) data_address);
241 return 1;
242 case 032: /* fsave */
243 fsave(addr_modes, (u_char __user *) data_address);
244 return 1;
245 case 033: /* fbstp m80dec */
246 clear_C1();
247 if (FPU_store_bcd
248 (st0_ptr, st0_tag, (u_char __user *) data_address))
249 pop_0(); /* pop only if the number was actually stored
250 (see the 80486 manual p16-28) */
251 break;
252 case 034: /* fstcw m16int */
253 RE_ENTRANT_CHECK_OFF;
254 FPU_access_ok(VERIFY_WRITE, data_address, 2);
255 FPU_put_user(control_word,
256 (unsigned short __user *)data_address);
257 RE_ENTRANT_CHECK_ON;
258 return 1;
259 case 035: /* fstp m80real */
260 clear_C1();
261 if (FPU_store_extended
262 (st0_ptr, st0_tag, (long double __user *)data_address))
263 pop_0(); /* pop only if the number was actually stored
264 (see the 80486 manual p16-28) */
265 break;
266 case 036: /* fstsw m2byte */
267 RE_ENTRANT_CHECK_OFF;
268 FPU_access_ok(VERIFY_WRITE, data_address, 2);
269 FPU_put_user(status_word(),
270 (unsigned short __user *)data_address);
271 RE_ENTRANT_CHECK_ON;
272 return 1;
273 case 037: /* fistp m64int */
274 clear_C1();
275 if (FPU_store_int64
276 (st0_ptr, st0_tag, (long long __user *)data_address))
277 pop_0(); /* pop only if the number was actually stored
278 (see the 80486 manual p16-28) */
279 break;
280 }
231 return 0; 281 return 0;
232 FPU_settag0(loaded_tag);
233 break;
234 case 030: /* fstenv m14/28byte */
235 fstenv(addr_modes, (u_char __user *)data_address);
236 return 1;
237 case 032: /* fsave */
238 fsave(addr_modes, (u_char __user *)data_address);
239 return 1;
240 case 033: /* fbstp m80dec */
241 clear_C1();
242 if ( FPU_store_bcd(st0_ptr, st0_tag, (u_char __user *)data_address) )
243 pop_0(); /* pop only if the number was actually stored
244 (see the 80486 manual p16-28) */
245 break;
246 case 034: /* fstcw m16int */
247 RE_ENTRANT_CHECK_OFF;
248 FPU_access_ok(VERIFY_WRITE,data_address,2);
249 FPU_put_user(control_word, (unsigned short __user *) data_address);
250 RE_ENTRANT_CHECK_ON;
251 return 1;
252 case 035: /* fstp m80real */
253 clear_C1();
254 if ( FPU_store_extended(st0_ptr, st0_tag, (long double __user *)data_address) )
255 pop_0(); /* pop only if the number was actually stored
256 (see the 80486 manual p16-28) */
257 break;
258 case 036: /* fstsw m2byte */
259 RE_ENTRANT_CHECK_OFF;
260 FPU_access_ok(VERIFY_WRITE,data_address,2);
261 FPU_put_user(status_word(),(unsigned short __user *) data_address);
262 RE_ENTRANT_CHECK_ON;
263 return 1;
264 case 037: /* fistp m64int */
265 clear_C1();
266 if ( FPU_store_int64(st0_ptr, st0_tag, (long long __user *)data_address) )
267 pop_0(); /* pop only if the number was actually stored
268 (see the 80486 manual p16-28) */
269 break;
270 }
271 return 0;
272} 282}
diff --git a/arch/x86/math-emu/poly.h b/arch/x86/math-emu/poly.h
index 4db798114923..168eb44c93c8 100644
--- a/arch/x86/math-emu/poly.h
+++ b/arch/x86/math-emu/poly.h
@@ -21,9 +21,9 @@
21 allows. 9-byte would probably be sufficient. 21 allows. 9-byte would probably be sufficient.
22 */ 22 */
23typedef struct { 23typedef struct {
24 unsigned long lsw; 24 unsigned long lsw;
25 unsigned long midw; 25 unsigned long midw;
26 unsigned long msw; 26 unsigned long msw;
27} Xsig; 27} Xsig;
28 28
29asmlinkage void mul64(unsigned long long const *a, unsigned long long const *b, 29asmlinkage void mul64(unsigned long long const *a, unsigned long long const *b,
@@ -49,7 +49,6 @@ asmlinkage void div_Xsig(Xsig *x1, const Xsig *x2, const Xsig *dest);
49/* Macro to access the 8 ms bytes of an Xsig as a long long */ 49/* Macro to access the 8 ms bytes of an Xsig as a long long */
50#define XSIG_LL(x) (*(unsigned long long *)&x.midw) 50#define XSIG_LL(x) (*(unsigned long long *)&x.midw)
51 51
52
53/* 52/*
54 Need to run gcc with optimizations on to get these to 53 Need to run gcc with optimizations on to get these to
55 actually be in-line. 54 actually be in-line.
@@ -63,59 +62,53 @@ asmlinkage void div_Xsig(Xsig *x1, const Xsig *x2, const Xsig *dest);
63static inline unsigned long mul_32_32(const unsigned long arg1, 62static inline unsigned long mul_32_32(const unsigned long arg1,
64 const unsigned long arg2) 63 const unsigned long arg2)
65{ 64{
66 int retval; 65 int retval;
67 asm volatile ("mull %2; movl %%edx,%%eax" \ 66 asm volatile ("mull %2; movl %%edx,%%eax":"=a" (retval)
68 :"=a" (retval) \ 67 :"0"(arg1), "g"(arg2)
69 :"0" (arg1), "g" (arg2) \ 68 :"dx");
70 :"dx"); 69 return retval;
71 return retval;
72} 70}
73 71
74
75/* Add the 12 byte Xsig x2 to Xsig dest, with no checks for overflow. */ 72/* Add the 12 byte Xsig x2 to Xsig dest, with no checks for overflow. */
76static inline void add_Xsig_Xsig(Xsig *dest, const Xsig *x2) 73static inline void add_Xsig_Xsig(Xsig *dest, const Xsig *x2)
77{ 74{
78 asm volatile ("movl %1,%%edi; movl %2,%%esi;\n" 75 asm volatile ("movl %1,%%edi; movl %2,%%esi;\n"
79 "movl (%%esi),%%eax; addl %%eax,(%%edi);\n" 76 "movl (%%esi),%%eax; addl %%eax,(%%edi);\n"
80 "movl 4(%%esi),%%eax; adcl %%eax,4(%%edi);\n" 77 "movl 4(%%esi),%%eax; adcl %%eax,4(%%edi);\n"
81 "movl 8(%%esi),%%eax; adcl %%eax,8(%%edi);\n" 78 "movl 8(%%esi),%%eax; adcl %%eax,8(%%edi);\n":"=g"
82 :"=g" (*dest):"g" (dest), "g" (x2) 79 (*dest):"g"(dest), "g"(x2)
83 :"ax","si","di"); 80 :"ax", "si", "di");
84} 81}
85 82
86
87/* Add the 12 byte Xsig x2 to Xsig dest, adjust exp if overflow occurs. */ 83/* Add the 12 byte Xsig x2 to Xsig dest, adjust exp if overflow occurs. */
88/* Note: the constraints in the asm statement didn't always work properly 84/* Note: the constraints in the asm statement didn't always work properly
89 with gcc 2.5.8. Changing from using edi to using ecx got around the 85 with gcc 2.5.8. Changing from using edi to using ecx got around the
90 problem, but keep fingers crossed! */ 86 problem, but keep fingers crossed! */
91static inline void add_two_Xsig(Xsig *dest, const Xsig *x2, long int *exp) 87static inline void add_two_Xsig(Xsig *dest, const Xsig *x2, long int *exp)
92{ 88{
93 asm volatile ("movl %2,%%ecx; movl %3,%%esi;\n" 89 asm volatile ("movl %2,%%ecx; movl %3,%%esi;\n"
94 "movl (%%esi),%%eax; addl %%eax,(%%ecx);\n" 90 "movl (%%esi),%%eax; addl %%eax,(%%ecx);\n"
95 "movl 4(%%esi),%%eax; adcl %%eax,4(%%ecx);\n" 91 "movl 4(%%esi),%%eax; adcl %%eax,4(%%ecx);\n"
96 "movl 8(%%esi),%%eax; adcl %%eax,8(%%ecx);\n" 92 "movl 8(%%esi),%%eax; adcl %%eax,8(%%ecx);\n"
97 "jnc 0f;\n" 93 "jnc 0f;\n"
98 "rcrl 8(%%ecx); rcrl 4(%%ecx); rcrl (%%ecx)\n" 94 "rcrl 8(%%ecx); rcrl 4(%%ecx); rcrl (%%ecx)\n"
99 "movl %4,%%ecx; incl (%%ecx)\n" 95 "movl %4,%%ecx; incl (%%ecx)\n"
100 "movl $1,%%eax; jmp 1f;\n" 96 "movl $1,%%eax; jmp 1f;\n"
101 "0: xorl %%eax,%%eax;\n" 97 "0: xorl %%eax,%%eax;\n" "1:\n":"=g" (*exp), "=g"(*dest)
102 "1:\n" 98 :"g"(dest), "g"(x2), "g"(exp)
103 :"=g" (*exp), "=g" (*dest) 99 :"cx", "si", "ax");
104 :"g" (dest), "g" (x2), "g" (exp)
105 :"cx","si","ax");
106} 100}
107 101
108
109/* Negate (subtract from 1.0) the 12 byte Xsig */ 102/* Negate (subtract from 1.0) the 12 byte Xsig */
110/* This is faster in a loop on my 386 than using the "neg" instruction. */ 103/* This is faster in a loop on my 386 than using the "neg" instruction. */
111static inline void negate_Xsig(Xsig *x) 104static inline void negate_Xsig(Xsig *x)
112{ 105{
113 asm volatile("movl %1,%%esi;\n" 106 asm volatile ("movl %1,%%esi;\n"
114 "xorl %%ecx,%%ecx;\n" 107 "xorl %%ecx,%%ecx;\n"
115 "movl %%ecx,%%eax; subl (%%esi),%%eax; movl %%eax,(%%esi);\n" 108 "movl %%ecx,%%eax; subl (%%esi),%%eax; movl %%eax,(%%esi);\n"
116 "movl %%ecx,%%eax; sbbl 4(%%esi),%%eax; movl %%eax,4(%%esi);\n" 109 "movl %%ecx,%%eax; sbbl 4(%%esi),%%eax; movl %%eax,4(%%esi);\n"
117 "movl %%ecx,%%eax; sbbl 8(%%esi),%%eax; movl %%eax,8(%%esi);\n" 110 "movl %%ecx,%%eax; sbbl 8(%%esi),%%eax; movl %%eax,8(%%esi);\n":"=g"
118 :"=g" (*x):"g" (x):"si","ax","cx"); 111 (*x):"g"(x):"si", "ax", "cx");
119} 112}
120 113
121#endif /* _POLY_H */ 114#endif /* _POLY_H */
diff --git a/arch/x86/math-emu/poly_2xm1.c b/arch/x86/math-emu/poly_2xm1.c
index 9766ad5e9743..b00e9e10cdce 100644
--- a/arch/x86/math-emu/poly_2xm1.c
+++ b/arch/x86/math-emu/poly_2xm1.c
@@ -17,21 +17,19 @@
17#include "control_w.h" 17#include "control_w.h"
18#include "poly.h" 18#include "poly.h"
19 19
20
21#define HIPOWER 11 20#define HIPOWER 11
22static const unsigned long long lterms[HIPOWER] = 21static const unsigned long long lterms[HIPOWER] = {
23{ 22 0x0000000000000000LL, /* This term done separately as 12 bytes */
24 0x0000000000000000LL, /* This term done separately as 12 bytes */ 23 0xf5fdeffc162c7543LL,
25 0xf5fdeffc162c7543LL, 24 0x1c6b08d704a0bfa6LL,
26 0x1c6b08d704a0bfa6LL, 25 0x0276556df749cc21LL,
27 0x0276556df749cc21LL, 26 0x002bb0ffcf14f6b8LL,
28 0x002bb0ffcf14f6b8LL, 27 0x0002861225ef751cLL,
29 0x0002861225ef751cLL, 28 0x00001ffcbfcd5422LL,
30 0x00001ffcbfcd5422LL, 29 0x00000162c005d5f1LL,
31 0x00000162c005d5f1LL, 30 0x0000000da96ccb1bLL,
32 0x0000000da96ccb1bLL, 31 0x0000000078d1b897LL,
33 0x0000000078d1b897LL, 32 0x000000000422b029LL
34 0x000000000422b029LL
35}; 33};
36 34
37static const Xsig hiterm = MK_XSIG(0xb17217f7, 0xd1cf79ab, 0xc8a39194); 35static const Xsig hiterm = MK_XSIG(0xb17217f7, 0xd1cf79ab, 0xc8a39194);
@@ -45,112 +43,103 @@ static const Xsig shiftterm2 = MK_XSIG(0xb504f333, 0xf9de6484, 0x597d89b3);
45static const Xsig shiftterm3 = MK_XSIG(0xd744fcca, 0xd69d6af4, 0x39a68bb9); 43static const Xsig shiftterm3 = MK_XSIG(0xd744fcca, 0xd69d6af4, 0x39a68bb9);
46 44
47static const Xsig *shiftterm[] = { &shiftterm0, &shiftterm1, 45static const Xsig *shiftterm[] = { &shiftterm0, &shiftterm1,
48 &shiftterm2, &shiftterm3 }; 46 &shiftterm2, &shiftterm3
49 47};
50 48
51/*--- poly_2xm1() -----------------------------------------------------------+ 49/*--- poly_2xm1() -----------------------------------------------------------+
52 | Requires st(0) which is TAG_Valid and < 1. | 50 | Requires st(0) which is TAG_Valid and < 1. |
53 +---------------------------------------------------------------------------*/ 51 +---------------------------------------------------------------------------*/
54int poly_2xm1(u_char sign, FPU_REG *arg, FPU_REG *result) 52int poly_2xm1(u_char sign, FPU_REG *arg, FPU_REG *result)
55{ 53{
56 long int exponent, shift; 54 long int exponent, shift;
57 unsigned long long Xll; 55 unsigned long long Xll;
58 Xsig accumulator, Denom, argSignif; 56 Xsig accumulator, Denom, argSignif;
59 u_char tag; 57 u_char tag;
60 58
61 exponent = exponent16(arg); 59 exponent = exponent16(arg);
62 60
63#ifdef PARANOID 61#ifdef PARANOID
64 if ( exponent >= 0 ) /* Don't want a |number| >= 1.0 */ 62 if (exponent >= 0) { /* Don't want a |number| >= 1.0 */
65 { 63 /* Number negative, too large, or not Valid. */
66 /* Number negative, too large, or not Valid. */ 64 EXCEPTION(EX_INTERNAL | 0x127);
67 EXCEPTION(EX_INTERNAL|0x127); 65 return 1;
68 return 1; 66 }
69 }
70#endif /* PARANOID */ 67#endif /* PARANOID */
71 68
72 argSignif.lsw = 0; 69 argSignif.lsw = 0;
73 XSIG_LL(argSignif) = Xll = significand(arg); 70 XSIG_LL(argSignif) = Xll = significand(arg);
74 71
75 if ( exponent == -1 ) 72 if (exponent == -1) {
76 { 73 shift = (argSignif.msw & 0x40000000) ? 3 : 2;
77 shift = (argSignif.msw & 0x40000000) ? 3 : 2; 74 /* subtract 0.5 or 0.75 */
78 /* subtract 0.5 or 0.75 */ 75 exponent -= 2;
79 exponent -= 2; 76 XSIG_LL(argSignif) <<= 2;
80 XSIG_LL(argSignif) <<= 2; 77 Xll <<= 2;
81 Xll <<= 2; 78 } else if (exponent == -2) {
82 } 79 shift = 1;
83 else if ( exponent == -2 ) 80 /* subtract 0.25 */
84 { 81 exponent--;
85 shift = 1; 82 XSIG_LL(argSignif) <<= 1;
86 /* subtract 0.25 */ 83 Xll <<= 1;
87 exponent--; 84 } else
88 XSIG_LL(argSignif) <<= 1; 85 shift = 0;
89 Xll <<= 1; 86
90 } 87 if (exponent < -2) {
91 else 88 /* Shift the argument right by the required places. */
92 shift = 0; 89 if (FPU_shrx(&Xll, -2 - exponent) >= 0x80000000U)
93 90 Xll++; /* round up */
94 if ( exponent < -2 ) 91 }
95 { 92
96 /* Shift the argument right by the required places. */ 93 accumulator.lsw = accumulator.midw = accumulator.msw = 0;
97 if ( FPU_shrx(&Xll, -2-exponent) >= 0x80000000U ) 94 polynomial_Xsig(&accumulator, &Xll, lterms, HIPOWER - 1);
98 Xll++; /* round up */ 95 mul_Xsig_Xsig(&accumulator, &argSignif);
99 } 96 shr_Xsig(&accumulator, 3);
100 97
101 accumulator.lsw = accumulator.midw = accumulator.msw = 0; 98 mul_Xsig_Xsig(&argSignif, &hiterm); /* The leading term */
102 polynomial_Xsig(&accumulator, &Xll, lterms, HIPOWER-1); 99 add_two_Xsig(&accumulator, &argSignif, &exponent);
103 mul_Xsig_Xsig(&accumulator, &argSignif); 100
104 shr_Xsig(&accumulator, 3); 101 if (shift) {
105 102 /* The argument is large, use the identity:
106 mul_Xsig_Xsig(&argSignif, &hiterm); /* The leading term */ 103 f(x+a) = f(a) * (f(x) + 1) - 1;
107 add_two_Xsig(&accumulator, &argSignif, &exponent); 104 */
108 105 shr_Xsig(&accumulator, -exponent);
109 if ( shift ) 106 accumulator.msw |= 0x80000000; /* add 1.0 */
110 { 107 mul_Xsig_Xsig(&accumulator, shiftterm[shift]);
111 /* The argument is large, use the identity: 108 accumulator.msw &= 0x3fffffff; /* subtract 1.0 */
112 f(x+a) = f(a) * (f(x) + 1) - 1; 109 exponent = 1;
113 */ 110 }
114 shr_Xsig(&accumulator, - exponent); 111
115 accumulator.msw |= 0x80000000; /* add 1.0 */ 112 if (sign != SIGN_POS) {
116 mul_Xsig_Xsig(&accumulator, shiftterm[shift]); 113 /* The argument is negative, use the identity:
117 accumulator.msw &= 0x3fffffff; /* subtract 1.0 */ 114 f(-x) = -f(x) / (1 + f(x))
118 exponent = 1; 115 */
119 } 116 Denom.lsw = accumulator.lsw;
120 117 XSIG_LL(Denom) = XSIG_LL(accumulator);
121 if ( sign != SIGN_POS ) 118 if (exponent < 0)
122 { 119 shr_Xsig(&Denom, -exponent);
123 /* The argument is negative, use the identity: 120 else if (exponent > 0) {
124 f(-x) = -f(x) / (1 + f(x)) 121 /* exponent must be 1 here */
125 */ 122 XSIG_LL(Denom) <<= 1;
126 Denom.lsw = accumulator.lsw; 123 if (Denom.lsw & 0x80000000)
127 XSIG_LL(Denom) = XSIG_LL(accumulator); 124 XSIG_LL(Denom) |= 1;
128 if ( exponent < 0 ) 125 (Denom.lsw) <<= 1;
129 shr_Xsig(&Denom, - exponent); 126 }
130 else if ( exponent > 0 ) 127 Denom.msw |= 0x80000000; /* add 1.0 */
131 { 128 div_Xsig(&accumulator, &Denom, &accumulator);
132 /* exponent must be 1 here */
133 XSIG_LL(Denom) <<= 1;
134 if ( Denom.lsw & 0x80000000 )
135 XSIG_LL(Denom) |= 1;
136 (Denom.lsw) <<= 1;
137 } 129 }
138 Denom.msw |= 0x80000000; /* add 1.0 */
139 div_Xsig(&accumulator, &Denom, &accumulator);
140 }
141 130
142 /* Convert to 64 bit signed-compatible */ 131 /* Convert to 64 bit signed-compatible */
143 exponent += round_Xsig(&accumulator); 132 exponent += round_Xsig(&accumulator);
144 133
145 result = &st(0); 134 result = &st(0);
146 significand(result) = XSIG_LL(accumulator); 135 significand(result) = XSIG_LL(accumulator);
147 setexponent16(result, exponent); 136 setexponent16(result, exponent);
148 137
149 tag = FPU_round(result, 1, 0, FULL_PRECISION, sign); 138 tag = FPU_round(result, 1, 0, FULL_PRECISION, sign);
150 139
151 setsign(result, sign); 140 setsign(result, sign);
152 FPU_settag0(tag); 141 FPU_settag0(tag);
153 142
154 return 0; 143 return 0;
155 144
156} 145}
diff --git a/arch/x86/math-emu/poly_atan.c b/arch/x86/math-emu/poly_atan.c
index 82f702952f69..20c28e58e2d4 100644
--- a/arch/x86/math-emu/poly_atan.c
+++ b/arch/x86/math-emu/poly_atan.c
@@ -18,28 +18,25 @@
18#include "control_w.h" 18#include "control_w.h"
19#include "poly.h" 19#include "poly.h"
20 20
21
22#define HIPOWERon 6 /* odd poly, negative terms */ 21#define HIPOWERon 6 /* odd poly, negative terms */
23static const unsigned long long oddnegterms[HIPOWERon] = 22static const unsigned long long oddnegterms[HIPOWERon] = {
24{ 23 0x0000000000000000LL, /* Dummy (not for - 1.0) */
25 0x0000000000000000LL, /* Dummy (not for - 1.0) */ 24 0x015328437f756467LL,
26 0x015328437f756467LL, 25 0x0005dda27b73dec6LL,
27 0x0005dda27b73dec6LL, 26 0x0000226bf2bfb91aLL,
28 0x0000226bf2bfb91aLL, 27 0x000000ccc439c5f7LL,
29 0x000000ccc439c5f7LL, 28 0x0000000355438407LL
30 0x0000000355438407LL 29};
31} ;
32 30
33#define HIPOWERop 6 /* odd poly, positive terms */ 31#define HIPOWERop 6 /* odd poly, positive terms */
34static const unsigned long long oddplterms[HIPOWERop] = 32static const unsigned long long oddplterms[HIPOWERop] = {
35{
36/* 0xaaaaaaaaaaaaaaabLL, transferred to fixedpterm[] */ 33/* 0xaaaaaaaaaaaaaaabLL, transferred to fixedpterm[] */
37 0x0db55a71875c9ac2LL, 34 0x0db55a71875c9ac2LL,
38 0x0029fce2d67880b0LL, 35 0x0029fce2d67880b0LL,
39 0x0000dfd3908b4596LL, 36 0x0000dfd3908b4596LL,
40 0x00000550fd61dab4LL, 37 0x00000550fd61dab4LL,
41 0x0000001c9422b3f9LL, 38 0x0000001c9422b3f9LL,
42 0x000000003e3301e1LL 39 0x000000003e3301e1LL
43}; 40};
44 41
45static const unsigned long long denomterm = 0xebd9b842c5c53a0eLL; 42static const unsigned long long denomterm = 0xebd9b842c5c53a0eLL;
@@ -48,182 +45,164 @@ static const Xsig fixedpterm = MK_XSIG(0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa);
48 45
49static const Xsig pi_signif = MK_XSIG(0xc90fdaa2, 0x2168c234, 0xc4c6628b); 46static const Xsig pi_signif = MK_XSIG(0xc90fdaa2, 0x2168c234, 0xc4c6628b);
50 47
51
52/*--- poly_atan() -----------------------------------------------------------+ 48/*--- poly_atan() -----------------------------------------------------------+
53 | | 49 | |
54 +---------------------------------------------------------------------------*/ 50 +---------------------------------------------------------------------------*/
55void poly_atan(FPU_REG *st0_ptr, u_char st0_tag, 51void poly_atan(FPU_REG *st0_ptr, u_char st0_tag,
56 FPU_REG *st1_ptr, u_char st1_tag) 52 FPU_REG *st1_ptr, u_char st1_tag)
57{ 53{
58 u_char transformed, inverted, 54 u_char transformed, inverted, sign1, sign2;
59 sign1, sign2; 55 int exponent;
60 int exponent; 56 long int dummy_exp;
61 long int dummy_exp; 57 Xsig accumulator, Numer, Denom, accumulatore, argSignif, argSq, argSqSq;
62 Xsig accumulator, Numer, Denom, accumulatore, argSignif, 58 u_char tag;
63 argSq, argSqSq; 59
64 u_char tag; 60 sign1 = getsign(st0_ptr);
65 61 sign2 = getsign(st1_ptr);
66 sign1 = getsign(st0_ptr); 62 if (st0_tag == TAG_Valid) {
67 sign2 = getsign(st1_ptr); 63 exponent = exponent(st0_ptr);
68 if ( st0_tag == TAG_Valid ) 64 } else {
69 { 65 /* This gives non-compatible stack contents... */
70 exponent = exponent(st0_ptr); 66 FPU_to_exp16(st0_ptr, st0_ptr);
71 } 67 exponent = exponent16(st0_ptr);
72 else 68 }
73 { 69 if (st1_tag == TAG_Valid) {
74 /* This gives non-compatible stack contents... */ 70 exponent -= exponent(st1_ptr);
75 FPU_to_exp16(st0_ptr, st0_ptr); 71 } else {
76 exponent = exponent16(st0_ptr); 72 /* This gives non-compatible stack contents... */
77 } 73 FPU_to_exp16(st1_ptr, st1_ptr);
78 if ( st1_tag == TAG_Valid ) 74 exponent -= exponent16(st1_ptr);
79 { 75 }
80 exponent -= exponent(st1_ptr); 76
81 } 77 if ((exponent < 0) || ((exponent == 0) &&
82 else 78 ((st0_ptr->sigh < st1_ptr->sigh) ||
83 { 79 ((st0_ptr->sigh == st1_ptr->sigh) &&
84 /* This gives non-compatible stack contents... */ 80 (st0_ptr->sigl < st1_ptr->sigl))))) {
85 FPU_to_exp16(st1_ptr, st1_ptr); 81 inverted = 1;
86 exponent -= exponent16(st1_ptr); 82 Numer.lsw = Denom.lsw = 0;
87 } 83 XSIG_LL(Numer) = significand(st0_ptr);
88 84 XSIG_LL(Denom) = significand(st1_ptr);
89 if ( (exponent < 0) || ((exponent == 0) && 85 } else {
90 ((st0_ptr->sigh < st1_ptr->sigh) || 86 inverted = 0;
91 ((st0_ptr->sigh == st1_ptr->sigh) && 87 exponent = -exponent;
92 (st0_ptr->sigl < st1_ptr->sigl))) ) ) 88 Numer.lsw = Denom.lsw = 0;
93 { 89 XSIG_LL(Numer) = significand(st1_ptr);
94 inverted = 1; 90 XSIG_LL(Denom) = significand(st0_ptr);
95 Numer.lsw = Denom.lsw = 0; 91 }
96 XSIG_LL(Numer) = significand(st0_ptr); 92 div_Xsig(&Numer, &Denom, &argSignif);
97 XSIG_LL(Denom) = significand(st1_ptr); 93 exponent += norm_Xsig(&argSignif);
98 } 94
99 else 95 if ((exponent >= -1)
100 { 96 || ((exponent == -2) && (argSignif.msw > 0xd413ccd0))) {
101 inverted = 0; 97 /* The argument is greater than sqrt(2)-1 (=0.414213562...) */
102 exponent = -exponent; 98 /* Convert the argument by an identity for atan */
103 Numer.lsw = Denom.lsw = 0; 99 transformed = 1;
104 XSIG_LL(Numer) = significand(st1_ptr); 100
105 XSIG_LL(Denom) = significand(st0_ptr); 101 if (exponent >= 0) {
106 }
107 div_Xsig(&Numer, &Denom, &argSignif);
108 exponent += norm_Xsig(&argSignif);
109
110 if ( (exponent >= -1)
111 || ((exponent == -2) && (argSignif.msw > 0xd413ccd0)) )
112 {
113 /* The argument is greater than sqrt(2)-1 (=0.414213562...) */
114 /* Convert the argument by an identity for atan */
115 transformed = 1;
116
117 if ( exponent >= 0 )
118 {
119#ifdef PARANOID 102#ifdef PARANOID
120 if ( !( (exponent == 0) && 103 if (!((exponent == 0) &&
121 (argSignif.lsw == 0) && (argSignif.midw == 0) && 104 (argSignif.lsw == 0) && (argSignif.midw == 0) &&
122 (argSignif.msw == 0x80000000) ) ) 105 (argSignif.msw == 0x80000000))) {
123 { 106 EXCEPTION(EX_INTERNAL | 0x104); /* There must be a logic error */
124 EXCEPTION(EX_INTERNAL|0x104); /* There must be a logic error */ 107 return;
125 return; 108 }
126 }
127#endif /* PARANOID */ 109#endif /* PARANOID */
128 argSignif.msw = 0; /* Make the transformed arg -> 0.0 */ 110 argSignif.msw = 0; /* Make the transformed arg -> 0.0 */
111 } else {
112 Numer.lsw = Denom.lsw = argSignif.lsw;
113 XSIG_LL(Numer) = XSIG_LL(Denom) = XSIG_LL(argSignif);
114
115 if (exponent < -1)
116 shr_Xsig(&Numer, -1 - exponent);
117 negate_Xsig(&Numer);
118
119 shr_Xsig(&Denom, -exponent);
120 Denom.msw |= 0x80000000;
121
122 div_Xsig(&Numer, &Denom, &argSignif);
123
124 exponent = -1 + norm_Xsig(&argSignif);
125 }
126 } else {
127 transformed = 0;
128 }
129
130 argSq.lsw = argSignif.lsw;
131 argSq.midw = argSignif.midw;
132 argSq.msw = argSignif.msw;
133 mul_Xsig_Xsig(&argSq, &argSq);
134
135 argSqSq.lsw = argSq.lsw;
136 argSqSq.midw = argSq.midw;
137 argSqSq.msw = argSq.msw;
138 mul_Xsig_Xsig(&argSqSq, &argSqSq);
139
140 accumulatore.lsw = argSq.lsw;
141 XSIG_LL(accumulatore) = XSIG_LL(argSq);
142
143 shr_Xsig(&argSq, 2 * (-1 - exponent - 1));
144 shr_Xsig(&argSqSq, 4 * (-1 - exponent - 1));
145
146 /* Now have argSq etc with binary point at the left
147 .1xxxxxxxx */
148
149 /* Do the basic fixed point polynomial evaluation */
150 accumulator.msw = accumulator.midw = accumulator.lsw = 0;
151 polynomial_Xsig(&accumulator, &XSIG_LL(argSqSq),
152 oddplterms, HIPOWERop - 1);
153 mul64_Xsig(&accumulator, &XSIG_LL(argSq));
154 negate_Xsig(&accumulator);
155 polynomial_Xsig(&accumulator, &XSIG_LL(argSqSq), oddnegterms,
156 HIPOWERon - 1);
157 negate_Xsig(&accumulator);
158 add_two_Xsig(&accumulator, &fixedpterm, &dummy_exp);
159
160 mul64_Xsig(&accumulatore, &denomterm);
161 shr_Xsig(&accumulatore, 1 + 2 * (-1 - exponent));
162 accumulatore.msw |= 0x80000000;
163
164 div_Xsig(&accumulator, &accumulatore, &accumulator);
165
166 mul_Xsig_Xsig(&accumulator, &argSignif);
167 mul_Xsig_Xsig(&accumulator, &argSq);
168
169 shr_Xsig(&accumulator, 3);
170 negate_Xsig(&accumulator);
171 add_Xsig_Xsig(&accumulator, &argSignif);
172
173 if (transformed) {
174 /* compute pi/4 - accumulator */
175 shr_Xsig(&accumulator, -1 - exponent);
176 negate_Xsig(&accumulator);
177 add_Xsig_Xsig(&accumulator, &pi_signif);
178 exponent = -1;
179 }
180
181 if (inverted) {
182 /* compute pi/2 - accumulator */
183 shr_Xsig(&accumulator, -exponent);
184 negate_Xsig(&accumulator);
185 add_Xsig_Xsig(&accumulator, &pi_signif);
186 exponent = 0;
129 } 187 }
130 else 188
131 { 189 if (sign1) {
132 Numer.lsw = Denom.lsw = argSignif.lsw; 190 /* compute pi - accumulator */
133 XSIG_LL(Numer) = XSIG_LL(Denom) = XSIG_LL(argSignif); 191 shr_Xsig(&accumulator, 1 - exponent);
134 192 negate_Xsig(&accumulator);
135 if ( exponent < -1 ) 193 add_Xsig_Xsig(&accumulator, &pi_signif);
136 shr_Xsig(&Numer, -1-exponent); 194 exponent = 1;
137 negate_Xsig(&Numer);
138
139 shr_Xsig(&Denom, -exponent);
140 Denom.msw |= 0x80000000;
141
142 div_Xsig(&Numer, &Denom, &argSignif);
143
144 exponent = -1 + norm_Xsig(&argSignif);
145 } 195 }
146 } 196
147 else 197 exponent += round_Xsig(&accumulator);
148 { 198
149 transformed = 0; 199 significand(st1_ptr) = XSIG_LL(accumulator);
150 } 200 setexponent16(st1_ptr, exponent);
151 201
152 argSq.lsw = argSignif.lsw; argSq.midw = argSignif.midw; 202 tag = FPU_round(st1_ptr, 1, 0, FULL_PRECISION, sign2);
153 argSq.msw = argSignif.msw; 203 FPU_settagi(1, tag);
154 mul_Xsig_Xsig(&argSq, &argSq); 204
155 205 set_precision_flag_up(); /* We do not really know if up or down,
156 argSqSq.lsw = argSq.lsw; argSqSq.midw = argSq.midw; argSqSq.msw = argSq.msw; 206 use this as the default. */
157 mul_Xsig_Xsig(&argSqSq, &argSqSq);
158
159 accumulatore.lsw = argSq.lsw;
160 XSIG_LL(accumulatore) = XSIG_LL(argSq);
161
162 shr_Xsig(&argSq, 2*(-1-exponent-1));
163 shr_Xsig(&argSqSq, 4*(-1-exponent-1));
164
165 /* Now have argSq etc with binary point at the left
166 .1xxxxxxxx */
167
168 /* Do the basic fixed point polynomial evaluation */
169 accumulator.msw = accumulator.midw = accumulator.lsw = 0;
170 polynomial_Xsig(&accumulator, &XSIG_LL(argSqSq),
171 oddplterms, HIPOWERop-1);
172 mul64_Xsig(&accumulator, &XSIG_LL(argSq));
173 negate_Xsig(&accumulator);
174 polynomial_Xsig(&accumulator, &XSIG_LL(argSqSq), oddnegterms, HIPOWERon-1);
175 negate_Xsig(&accumulator);
176 add_two_Xsig(&accumulator, &fixedpterm, &dummy_exp);
177
178 mul64_Xsig(&accumulatore, &denomterm);
179 shr_Xsig(&accumulatore, 1 + 2*(-1-exponent));
180 accumulatore.msw |= 0x80000000;
181
182 div_Xsig(&accumulator, &accumulatore, &accumulator);
183
184 mul_Xsig_Xsig(&accumulator, &argSignif);
185 mul_Xsig_Xsig(&accumulator, &argSq);
186
187 shr_Xsig(&accumulator, 3);
188 negate_Xsig(&accumulator);
189 add_Xsig_Xsig(&accumulator, &argSignif);
190
191 if ( transformed )
192 {
193 /* compute pi/4 - accumulator */
194 shr_Xsig(&accumulator, -1-exponent);
195 negate_Xsig(&accumulator);
196 add_Xsig_Xsig(&accumulator, &pi_signif);
197 exponent = -1;
198 }
199
200 if ( inverted )
201 {
202 /* compute pi/2 - accumulator */
203 shr_Xsig(&accumulator, -exponent);
204 negate_Xsig(&accumulator);
205 add_Xsig_Xsig(&accumulator, &pi_signif);
206 exponent = 0;
207 }
208
209 if ( sign1 )
210 {
211 /* compute pi - accumulator */
212 shr_Xsig(&accumulator, 1 - exponent);
213 negate_Xsig(&accumulator);
214 add_Xsig_Xsig(&accumulator, &pi_signif);
215 exponent = 1;
216 }
217
218 exponent += round_Xsig(&accumulator);
219
220 significand(st1_ptr) = XSIG_LL(accumulator);
221 setexponent16(st1_ptr, exponent);
222
223 tag = FPU_round(st1_ptr, 1, 0, FULL_PRECISION, sign2);
224 FPU_settagi(1, tag);
225
226 set_precision_flag_up(); /* We do not really know if up or down,
227 use this as the default. */
228 207
229} 208}
diff --git a/arch/x86/math-emu/poly_l2.c b/arch/x86/math-emu/poly_l2.c
index dd00e1d5b074..8e2ff4b28a0a 100644
--- a/arch/x86/math-emu/poly_l2.c
+++ b/arch/x86/math-emu/poly_l2.c
@@ -10,7 +10,6 @@
10 | | 10 | |
11 +---------------------------------------------------------------------------*/ 11 +---------------------------------------------------------------------------*/
12 12
13
14#include "exception.h" 13#include "exception.h"
15#include "reg_constant.h" 14#include "reg_constant.h"
16#include "fpu_emu.h" 15#include "fpu_emu.h"
@@ -18,184 +17,163 @@
18#include "control_w.h" 17#include "control_w.h"
19#include "poly.h" 18#include "poly.h"
20 19
21
22static void log2_kernel(FPU_REG const *arg, u_char argsign, 20static void log2_kernel(FPU_REG const *arg, u_char argsign,
23 Xsig *accum_result, long int *expon); 21 Xsig * accum_result, long int *expon);
24
25 22
26/*--- poly_l2() -------------------------------------------------------------+ 23/*--- poly_l2() -------------------------------------------------------------+
27 | Base 2 logarithm by a polynomial approximation. | 24 | Base 2 logarithm by a polynomial approximation. |
28 +---------------------------------------------------------------------------*/ 25 +---------------------------------------------------------------------------*/
29void poly_l2(FPU_REG *st0_ptr, FPU_REG *st1_ptr, u_char st1_sign) 26void poly_l2(FPU_REG *st0_ptr, FPU_REG *st1_ptr, u_char st1_sign)
30{ 27{
31 long int exponent, expon, expon_expon; 28 long int exponent, expon, expon_expon;
32 Xsig accumulator, expon_accum, yaccum; 29 Xsig accumulator, expon_accum, yaccum;
33 u_char sign, argsign; 30 u_char sign, argsign;
34 FPU_REG x; 31 FPU_REG x;
35 int tag; 32 int tag;
36 33
37 exponent = exponent16(st0_ptr); 34 exponent = exponent16(st0_ptr);
38 35
39 /* From st0_ptr, make a number > sqrt(2)/2 and < sqrt(2) */ 36 /* From st0_ptr, make a number > sqrt(2)/2 and < sqrt(2) */
40 if ( st0_ptr->sigh > (unsigned)0xb504f334 ) 37 if (st0_ptr->sigh > (unsigned)0xb504f334) {
41 { 38 /* Treat as sqrt(2)/2 < st0_ptr < 1 */
42 /* Treat as sqrt(2)/2 < st0_ptr < 1 */ 39 significand(&x) = -significand(st0_ptr);
43 significand(&x) = - significand(st0_ptr); 40 setexponent16(&x, -1);
44 setexponent16(&x, -1); 41 exponent++;
45 exponent++; 42 argsign = SIGN_NEG;
46 argsign = SIGN_NEG; 43 } else {
47 } 44 /* Treat as 1 <= st0_ptr < sqrt(2) */
48 else 45 x.sigh = st0_ptr->sigh - 0x80000000;
49 { 46 x.sigl = st0_ptr->sigl;
50 /* Treat as 1 <= st0_ptr < sqrt(2) */ 47 setexponent16(&x, 0);
51 x.sigh = st0_ptr->sigh - 0x80000000; 48 argsign = SIGN_POS;
52 x.sigl = st0_ptr->sigl; 49 }
53 setexponent16(&x, 0); 50 tag = FPU_normalize_nuo(&x);
54 argsign = SIGN_POS;
55 }
56 tag = FPU_normalize_nuo(&x);
57
58 if ( tag == TAG_Zero )
59 {
60 expon = 0;
61 accumulator.msw = accumulator.midw = accumulator.lsw = 0;
62 }
63 else
64 {
65 log2_kernel(&x, argsign, &accumulator, &expon);
66 }
67
68 if ( exponent < 0 )
69 {
70 sign = SIGN_NEG;
71 exponent = -exponent;
72 }
73 else
74 sign = SIGN_POS;
75 expon_accum.msw = exponent; expon_accum.midw = expon_accum.lsw = 0;
76 if ( exponent )
77 {
78 expon_expon = 31 + norm_Xsig(&expon_accum);
79 shr_Xsig(&accumulator, expon_expon - expon);
80
81 if ( sign ^ argsign )
82 negate_Xsig(&accumulator);
83 add_Xsig_Xsig(&accumulator, &expon_accum);
84 }
85 else
86 {
87 expon_expon = expon;
88 sign = argsign;
89 }
90
91 yaccum.lsw = 0; XSIG_LL(yaccum) = significand(st1_ptr);
92 mul_Xsig_Xsig(&accumulator, &yaccum);
93
94 expon_expon += round_Xsig(&accumulator);
95
96 if ( accumulator.msw == 0 )
97 {
98 FPU_copy_to_reg1(&CONST_Z, TAG_Zero);
99 return;
100 }
101
102 significand(st1_ptr) = XSIG_LL(accumulator);
103 setexponent16(st1_ptr, expon_expon + exponent16(st1_ptr) + 1);
104
105 tag = FPU_round(st1_ptr, 1, 0, FULL_PRECISION, sign ^ st1_sign);
106 FPU_settagi(1, tag);
107
108 set_precision_flag_up(); /* 80486 appears to always do this */
109
110 return;
111 51
112} 52 if (tag == TAG_Zero) {
53 expon = 0;
54 accumulator.msw = accumulator.midw = accumulator.lsw = 0;
55 } else {
56 log2_kernel(&x, argsign, &accumulator, &expon);
57 }
58
59 if (exponent < 0) {
60 sign = SIGN_NEG;
61 exponent = -exponent;
62 } else
63 sign = SIGN_POS;
64 expon_accum.msw = exponent;
65 expon_accum.midw = expon_accum.lsw = 0;
66 if (exponent) {
67 expon_expon = 31 + norm_Xsig(&expon_accum);
68 shr_Xsig(&accumulator, expon_expon - expon);
69
70 if (sign ^ argsign)
71 negate_Xsig(&accumulator);
72 add_Xsig_Xsig(&accumulator, &expon_accum);
73 } else {
74 expon_expon = expon;
75 sign = argsign;
76 }
77
78 yaccum.lsw = 0;
79 XSIG_LL(yaccum) = significand(st1_ptr);
80 mul_Xsig_Xsig(&accumulator, &yaccum);
81
82 expon_expon += round_Xsig(&accumulator);
83
84 if (accumulator.msw == 0) {
85 FPU_copy_to_reg1(&CONST_Z, TAG_Zero);
86 return;
87 }
88
89 significand(st1_ptr) = XSIG_LL(accumulator);
90 setexponent16(st1_ptr, expon_expon + exponent16(st1_ptr) + 1);
113 91
92 tag = FPU_round(st1_ptr, 1, 0, FULL_PRECISION, sign ^ st1_sign);
93 FPU_settagi(1, tag);
94
95 set_precision_flag_up(); /* 80486 appears to always do this */
96
97 return;
98
99}
114 100
115/*--- poly_l2p1() -----------------------------------------------------------+ 101/*--- poly_l2p1() -----------------------------------------------------------+
116 | Base 2 logarithm by a polynomial approximation. | 102 | Base 2 logarithm by a polynomial approximation. |
117 | log2(x+1) | 103 | log2(x+1) |
118 +---------------------------------------------------------------------------*/ 104 +---------------------------------------------------------------------------*/
119int poly_l2p1(u_char sign0, u_char sign1, 105int poly_l2p1(u_char sign0, u_char sign1,
120 FPU_REG *st0_ptr, FPU_REG *st1_ptr, FPU_REG *dest) 106 FPU_REG * st0_ptr, FPU_REG * st1_ptr, FPU_REG * dest)
121{ 107{
122 u_char tag; 108 u_char tag;
123 long int exponent; 109 long int exponent;
124 Xsig accumulator, yaccum; 110 Xsig accumulator, yaccum;
125 111
126 if ( exponent16(st0_ptr) < 0 ) 112 if (exponent16(st0_ptr) < 0) {
127 { 113 log2_kernel(st0_ptr, sign0, &accumulator, &exponent);
128 log2_kernel(st0_ptr, sign0, &accumulator, &exponent);
129 114
130 yaccum.lsw = 0; 115 yaccum.lsw = 0;
131 XSIG_LL(yaccum) = significand(st1_ptr); 116 XSIG_LL(yaccum) = significand(st1_ptr);
132 mul_Xsig_Xsig(&accumulator, &yaccum); 117 mul_Xsig_Xsig(&accumulator, &yaccum);
133 118
134 exponent += round_Xsig(&accumulator); 119 exponent += round_Xsig(&accumulator);
135 120
136 exponent += exponent16(st1_ptr) + 1; 121 exponent += exponent16(st1_ptr) + 1;
137 if ( exponent < EXP_WAY_UNDER ) exponent = EXP_WAY_UNDER; 122 if (exponent < EXP_WAY_UNDER)
123 exponent = EXP_WAY_UNDER;
138 124
139 significand(dest) = XSIG_LL(accumulator); 125 significand(dest) = XSIG_LL(accumulator);
140 setexponent16(dest, exponent); 126 setexponent16(dest, exponent);
141 127
142 tag = FPU_round(dest, 1, 0, FULL_PRECISION, sign0 ^ sign1); 128 tag = FPU_round(dest, 1, 0, FULL_PRECISION, sign0 ^ sign1);
143 FPU_settagi(1, tag); 129 FPU_settagi(1, tag);
144 130
145 if ( tag == TAG_Valid ) 131 if (tag == TAG_Valid)
146 set_precision_flag_up(); /* 80486 appears to always do this */ 132 set_precision_flag_up(); /* 80486 appears to always do this */
147 } 133 } else {
148 else 134 /* The magnitude of st0_ptr is far too large. */
149 {
150 /* The magnitude of st0_ptr is far too large. */
151 135
152 if ( sign0 != SIGN_POS ) 136 if (sign0 != SIGN_POS) {
153 { 137 /* Trying to get the log of a negative number. */
154 /* Trying to get the log of a negative number. */ 138#ifdef PECULIAR_486 /* Stupid 80486 doesn't worry about log(negative). */
155#ifdef PECULIAR_486 /* Stupid 80486 doesn't worry about log(negative). */ 139 changesign(st1_ptr);
156 changesign(st1_ptr);
157#else 140#else
158 if ( arith_invalid(1) < 0 ) 141 if (arith_invalid(1) < 0)
159 return 1; 142 return 1;
160#endif /* PECULIAR_486 */ 143#endif /* PECULIAR_486 */
161 } 144 }
162 145
163 /* 80486 appears to do this */ 146 /* 80486 appears to do this */
164 if ( sign0 == SIGN_NEG ) 147 if (sign0 == SIGN_NEG)
165 set_precision_flag_down(); 148 set_precision_flag_down();
166 else 149 else
167 set_precision_flag_up(); 150 set_precision_flag_up();
168 } 151 }
169 152
170 if ( exponent(dest) <= EXP_UNDER ) 153 if (exponent(dest) <= EXP_UNDER)
171 EXCEPTION(EX_Underflow); 154 EXCEPTION(EX_Underflow);
172 155
173 return 0; 156 return 0;
174 157
175} 158}
176 159
177
178
179
180#undef HIPOWER 160#undef HIPOWER
181#define HIPOWER 10 161#define HIPOWER 10
182static const unsigned long long logterms[HIPOWER] = 162static const unsigned long long logterms[HIPOWER] = {
183{ 163 0x2a8eca5705fc2ef0LL,
184 0x2a8eca5705fc2ef0LL, 164 0xf6384ee1d01febceLL,
185 0xf6384ee1d01febceLL, 165 0x093bb62877cdf642LL,
186 0x093bb62877cdf642LL, 166 0x006985d8a9ec439bLL,
187 0x006985d8a9ec439bLL, 167 0x0005212c4f55a9c8LL,
188 0x0005212c4f55a9c8LL, 168 0x00004326a16927f0LL,
189 0x00004326a16927f0LL, 169 0x0000038d1d80a0e7LL,
190 0x0000038d1d80a0e7LL, 170 0x0000003141cc80c6LL,
191 0x0000003141cc80c6LL, 171 0x00000002b1668c9fLL,
192 0x00000002b1668c9fLL, 172 0x000000002c7a46aaLL
193 0x000000002c7a46aaLL
194}; 173};
195 174
196static const unsigned long leadterm = 0xb8000000; 175static const unsigned long leadterm = 0xb8000000;
197 176
198
199/*--- log2_kernel() ---------------------------------------------------------+ 177/*--- log2_kernel() ---------------------------------------------------------+
200 | Base 2 logarithm by a polynomial approximation. | 178 | Base 2 logarithm by a polynomial approximation. |
201 | log2(x+1) | 179 | log2(x+1) |
@@ -203,70 +181,64 @@ static const unsigned long leadterm = 0xb8000000;
203static void log2_kernel(FPU_REG const *arg, u_char argsign, Xsig *accum_result, 181static void log2_kernel(FPU_REG const *arg, u_char argsign, Xsig *accum_result,
204 long int *expon) 182 long int *expon)
205{ 183{
206 long int exponent, adj; 184 long int exponent, adj;
207 unsigned long long Xsq; 185 unsigned long long Xsq;
208 Xsig accumulator, Numer, Denom, argSignif, arg_signif; 186 Xsig accumulator, Numer, Denom, argSignif, arg_signif;
209 187
210 exponent = exponent16(arg); 188 exponent = exponent16(arg);
211 Numer.lsw = Denom.lsw = 0; 189 Numer.lsw = Denom.lsw = 0;
212 XSIG_LL(Numer) = XSIG_LL(Denom) = significand(arg); 190 XSIG_LL(Numer) = XSIG_LL(Denom) = significand(arg);
213 if ( argsign == SIGN_POS ) 191 if (argsign == SIGN_POS) {
214 { 192 shr_Xsig(&Denom, 2 - (1 + exponent));
215 shr_Xsig(&Denom, 2 - (1 + exponent)); 193 Denom.msw |= 0x80000000;
216 Denom.msw |= 0x80000000; 194 div_Xsig(&Numer, &Denom, &argSignif);
217 div_Xsig(&Numer, &Denom, &argSignif); 195 } else {
218 } 196 shr_Xsig(&Denom, 1 - (1 + exponent));
219 else 197 negate_Xsig(&Denom);
220 { 198 if (Denom.msw & 0x80000000) {
221 shr_Xsig(&Denom, 1 - (1 + exponent)); 199 div_Xsig(&Numer, &Denom, &argSignif);
222 negate_Xsig(&Denom); 200 exponent++;
223 if ( Denom.msw & 0x80000000 ) 201 } else {
224 { 202 /* Denom must be 1.0 */
225 div_Xsig(&Numer, &Denom, &argSignif); 203 argSignif.lsw = Numer.lsw;
226 exponent ++; 204 argSignif.midw = Numer.midw;
227 } 205 argSignif.msw = Numer.msw;
228 else 206 }
229 {
230 /* Denom must be 1.0 */
231 argSignif.lsw = Numer.lsw; argSignif.midw = Numer.midw;
232 argSignif.msw = Numer.msw;
233 } 207 }
234 }
235 208
236#ifndef PECULIAR_486 209#ifndef PECULIAR_486
237 /* Should check here that |local_arg| is within the valid range */ 210 /* Should check here that |local_arg| is within the valid range */
238 if ( exponent >= -2 ) 211 if (exponent >= -2) {
239 { 212 if ((exponent > -2) || (argSignif.msw > (unsigned)0xafb0ccc0)) {
240 if ( (exponent > -2) || 213 /* The argument is too large */
241 (argSignif.msw > (unsigned)0xafb0ccc0) ) 214 }
242 {
243 /* The argument is too large */
244 } 215 }
245 }
246#endif /* PECULIAR_486 */ 216#endif /* PECULIAR_486 */
247 217
248 arg_signif.lsw = argSignif.lsw; XSIG_LL(arg_signif) = XSIG_LL(argSignif); 218 arg_signif.lsw = argSignif.lsw;
249 adj = norm_Xsig(&argSignif); 219 XSIG_LL(arg_signif) = XSIG_LL(argSignif);
250 accumulator.lsw = argSignif.lsw; XSIG_LL(accumulator) = XSIG_LL(argSignif); 220 adj = norm_Xsig(&argSignif);
251 mul_Xsig_Xsig(&accumulator, &accumulator); 221 accumulator.lsw = argSignif.lsw;
252 shr_Xsig(&accumulator, 2*(-1 - (1 + exponent + adj))); 222 XSIG_LL(accumulator) = XSIG_LL(argSignif);
253 Xsq = XSIG_LL(accumulator); 223 mul_Xsig_Xsig(&accumulator, &accumulator);
254 if ( accumulator.lsw & 0x80000000 ) 224 shr_Xsig(&accumulator, 2 * (-1 - (1 + exponent + adj)));
255 Xsq++; 225 Xsq = XSIG_LL(accumulator);
256 226 if (accumulator.lsw & 0x80000000)
257 accumulator.msw = accumulator.midw = accumulator.lsw = 0; 227 Xsq++;
258 /* Do the basic fixed point polynomial evaluation */ 228
259 polynomial_Xsig(&accumulator, &Xsq, logterms, HIPOWER-1); 229 accumulator.msw = accumulator.midw = accumulator.lsw = 0;
260 230 /* Do the basic fixed point polynomial evaluation */
261 mul_Xsig_Xsig(&accumulator, &argSignif); 231 polynomial_Xsig(&accumulator, &Xsq, logterms, HIPOWER - 1);
262 shr_Xsig(&accumulator, 6 - adj); 232
263 233 mul_Xsig_Xsig(&accumulator, &argSignif);
264 mul32_Xsig(&arg_signif, leadterm); 234 shr_Xsig(&accumulator, 6 - adj);
265 add_two_Xsig(&accumulator, &arg_signif, &exponent); 235
266 236 mul32_Xsig(&arg_signif, leadterm);
267 *expon = exponent + 1; 237 add_two_Xsig(&accumulator, &arg_signif, &exponent);
268 accum_result->lsw = accumulator.lsw; 238
269 accum_result->midw = accumulator.midw; 239 *expon = exponent + 1;
270 accum_result->msw = accumulator.msw; 240 accum_result->lsw = accumulator.lsw;
241 accum_result->midw = accumulator.midw;
242 accum_result->msw = accumulator.msw;
271 243
272} 244}
diff --git a/arch/x86/math-emu/poly_sin.c b/arch/x86/math-emu/poly_sin.c
index a36313fb06f1..b862039c728e 100644
--- a/arch/x86/math-emu/poly_sin.c
+++ b/arch/x86/math-emu/poly_sin.c
@@ -11,7 +11,6 @@
11 | | 11 | |
12 +---------------------------------------------------------------------------*/ 12 +---------------------------------------------------------------------------*/
13 13
14
15#include "exception.h" 14#include "exception.h"
16#include "reg_constant.h" 15#include "reg_constant.h"
17#include "fpu_emu.h" 16#include "fpu_emu.h"
@@ -19,379 +18,361 @@
19#include "control_w.h" 18#include "control_w.h"
20#include "poly.h" 19#include "poly.h"
21 20
22
23#define N_COEFF_P 4 21#define N_COEFF_P 4
24#define N_COEFF_N 4 22#define N_COEFF_N 4
25 23
26static const unsigned long long pos_terms_l[N_COEFF_P] = 24static const unsigned long long pos_terms_l[N_COEFF_P] = {
27{ 25 0xaaaaaaaaaaaaaaabLL,
28 0xaaaaaaaaaaaaaaabLL, 26 0x00d00d00d00cf906LL,
29 0x00d00d00d00cf906LL, 27 0x000006b99159a8bbLL,
30 0x000006b99159a8bbLL, 28 0x000000000d7392e6LL
31 0x000000000d7392e6LL
32}; 29};
33 30
34static const unsigned long long neg_terms_l[N_COEFF_N] = 31static const unsigned long long neg_terms_l[N_COEFF_N] = {
35{ 32 0x2222222222222167LL,
36 0x2222222222222167LL, 33 0x0002e3bc74aab624LL,
37 0x0002e3bc74aab624LL, 34 0x0000000b09229062LL,
38 0x0000000b09229062LL, 35 0x00000000000c7973LL
39 0x00000000000c7973LL
40}; 36};
41 37
42
43
44#define N_COEFF_PH 4 38#define N_COEFF_PH 4
45#define N_COEFF_NH 4 39#define N_COEFF_NH 4
46static const unsigned long long pos_terms_h[N_COEFF_PH] = 40static const unsigned long long pos_terms_h[N_COEFF_PH] = {
47{ 41 0x0000000000000000LL,
48 0x0000000000000000LL, 42 0x05b05b05b05b0406LL,
49 0x05b05b05b05b0406LL, 43 0x000049f93edd91a9LL,
50 0x000049f93edd91a9LL, 44 0x00000000c9c9ed62LL
51 0x00000000c9c9ed62LL
52}; 45};
53 46
54static const unsigned long long neg_terms_h[N_COEFF_NH] = 47static const unsigned long long neg_terms_h[N_COEFF_NH] = {
55{ 48 0xaaaaaaaaaaaaaa98LL,
56 0xaaaaaaaaaaaaaa98LL, 49 0x001a01a01a019064LL,
57 0x001a01a01a019064LL, 50 0x0000008f76c68a77LL,
58 0x0000008f76c68a77LL, 51 0x0000000000d58f5eLL
59 0x0000000000d58f5eLL
60}; 52};
61 53
62
63/*--- poly_sine() -----------------------------------------------------------+ 54/*--- poly_sine() -----------------------------------------------------------+
64 | | 55 | |
65 +---------------------------------------------------------------------------*/ 56 +---------------------------------------------------------------------------*/
66void poly_sine(FPU_REG *st0_ptr) 57void poly_sine(FPU_REG *st0_ptr)
67{ 58{
68 int exponent, echange; 59 int exponent, echange;
69 Xsig accumulator, argSqrd, argTo4; 60 Xsig accumulator, argSqrd, argTo4;
70 unsigned long fix_up, adj; 61 unsigned long fix_up, adj;
71 unsigned long long fixed_arg; 62 unsigned long long fixed_arg;
72 FPU_REG result; 63 FPU_REG result;
73 64
74 exponent = exponent(st0_ptr); 65 exponent = exponent(st0_ptr);
75 66
76 accumulator.lsw = accumulator.midw = accumulator.msw = 0; 67 accumulator.lsw = accumulator.midw = accumulator.msw = 0;
77 68
78 /* Split into two ranges, for arguments below and above 1.0 */ 69 /* Split into two ranges, for arguments below and above 1.0 */
79 /* The boundary between upper and lower is approx 0.88309101259 */ 70 /* The boundary between upper and lower is approx 0.88309101259 */
80 if ( (exponent < -1) || ((exponent == -1) && (st0_ptr->sigh <= 0xe21240aa)) ) 71 if ((exponent < -1)
81 { 72 || ((exponent == -1) && (st0_ptr->sigh <= 0xe21240aa))) {
82 /* The argument is <= 0.88309101259 */ 73 /* The argument is <= 0.88309101259 */
74
75 argSqrd.msw = st0_ptr->sigh;
76 argSqrd.midw = st0_ptr->sigl;
77 argSqrd.lsw = 0;
78 mul64_Xsig(&argSqrd, &significand(st0_ptr));
79 shr_Xsig(&argSqrd, 2 * (-1 - exponent));
80 argTo4.msw = argSqrd.msw;
81 argTo4.midw = argSqrd.midw;
82 argTo4.lsw = argSqrd.lsw;
83 mul_Xsig_Xsig(&argTo4, &argTo4);
83 84
84 argSqrd.msw = st0_ptr->sigh; argSqrd.midw = st0_ptr->sigl; argSqrd.lsw = 0; 85 polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), neg_terms_l,
85 mul64_Xsig(&argSqrd, &significand(st0_ptr)); 86 N_COEFF_N - 1);
86 shr_Xsig(&argSqrd, 2*(-1-exponent)); 87 mul_Xsig_Xsig(&accumulator, &argSqrd);
87 argTo4.msw = argSqrd.msw; argTo4.midw = argSqrd.midw; 88 negate_Xsig(&accumulator);
88 argTo4.lsw = argSqrd.lsw;
89 mul_Xsig_Xsig(&argTo4, &argTo4);
90 89
91 polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), neg_terms_l, 90 polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), pos_terms_l,
92 N_COEFF_N-1); 91 N_COEFF_P - 1);
93 mul_Xsig_Xsig(&accumulator, &argSqrd);
94 negate_Xsig(&accumulator);
95 92
96 polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), pos_terms_l, 93 shr_Xsig(&accumulator, 2); /* Divide by four */
97 N_COEFF_P-1); 94 accumulator.msw |= 0x80000000; /* Add 1.0 */
98 95
99 shr_Xsig(&accumulator, 2); /* Divide by four */ 96 mul64_Xsig(&accumulator, &significand(st0_ptr));
100 accumulator.msw |= 0x80000000; /* Add 1.0 */ 97 mul64_Xsig(&accumulator, &significand(st0_ptr));
98 mul64_Xsig(&accumulator, &significand(st0_ptr));
101 99
102 mul64_Xsig(&accumulator, &significand(st0_ptr)); 100 /* Divide by four, FPU_REG compatible, etc */
103 mul64_Xsig(&accumulator, &significand(st0_ptr)); 101 exponent = 3 * exponent;
104 mul64_Xsig(&accumulator, &significand(st0_ptr));
105 102
106 /* Divide by four, FPU_REG compatible, etc */ 103 /* The minimum exponent difference is 3 */
107 exponent = 3*exponent; 104 shr_Xsig(&accumulator, exponent(st0_ptr) - exponent);
108 105
109 /* The minimum exponent difference is 3 */ 106 negate_Xsig(&accumulator);
110 shr_Xsig(&accumulator, exponent(st0_ptr) - exponent); 107 XSIG_LL(accumulator) += significand(st0_ptr);
111 108
112 negate_Xsig(&accumulator); 109 echange = round_Xsig(&accumulator);
113 XSIG_LL(accumulator) += significand(st0_ptr);
114 110
115 echange = round_Xsig(&accumulator); 111 setexponentpos(&result, exponent(st0_ptr) + echange);
112 } else {
113 /* The argument is > 0.88309101259 */
114 /* We use sin(st(0)) = cos(pi/2-st(0)) */
116 115
117 setexponentpos(&result, exponent(st0_ptr) + echange); 116 fixed_arg = significand(st0_ptr);
118 }
119 else
120 {
121 /* The argument is > 0.88309101259 */
122 /* We use sin(st(0)) = cos(pi/2-st(0)) */
123 117
124 fixed_arg = significand(st0_ptr); 118 if (exponent == 0) {
119 /* The argument is >= 1.0 */
125 120
126 if ( exponent == 0 ) 121 /* Put the binary point at the left. */
127 { 122 fixed_arg <<= 1;
128 /* The argument is >= 1.0 */ 123 }
124 /* pi/2 in hex is: 1.921fb54442d18469 898CC51701B839A2 52049C1 */
125 fixed_arg = 0x921fb54442d18469LL - fixed_arg;
126 /* There is a special case which arises due to rounding, to fix here. */
127 if (fixed_arg == 0xffffffffffffffffLL)
128 fixed_arg = 0;
129 129
130 /* Put the binary point at the left. */ 130 XSIG_LL(argSqrd) = fixed_arg;
131 fixed_arg <<= 1; 131 argSqrd.lsw = 0;
132 } 132 mul64_Xsig(&argSqrd, &fixed_arg);
133 /* pi/2 in hex is: 1.921fb54442d18469 898CC51701B839A2 52049C1 */
134 fixed_arg = 0x921fb54442d18469LL - fixed_arg;
135 /* There is a special case which arises due to rounding, to fix here. */
136 if ( fixed_arg == 0xffffffffffffffffLL )
137 fixed_arg = 0;
138 133
139 XSIG_LL(argSqrd) = fixed_arg; argSqrd.lsw = 0; 134 XSIG_LL(argTo4) = XSIG_LL(argSqrd);
140 mul64_Xsig(&argSqrd, &fixed_arg); 135 argTo4.lsw = argSqrd.lsw;
136 mul_Xsig_Xsig(&argTo4, &argTo4);
141 137
142 XSIG_LL(argTo4) = XSIG_LL(argSqrd); argTo4.lsw = argSqrd.lsw; 138 polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), neg_terms_h,
143 mul_Xsig_Xsig(&argTo4, &argTo4); 139 N_COEFF_NH - 1);
140 mul_Xsig_Xsig(&accumulator, &argSqrd);
141 negate_Xsig(&accumulator);
144 142
145 polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), neg_terms_h, 143 polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), pos_terms_h,
146 N_COEFF_NH-1); 144 N_COEFF_PH - 1);
147 mul_Xsig_Xsig(&accumulator, &argSqrd); 145 negate_Xsig(&accumulator);
148 negate_Xsig(&accumulator);
149 146
150 polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), pos_terms_h, 147 mul64_Xsig(&accumulator, &fixed_arg);
151 N_COEFF_PH-1); 148 mul64_Xsig(&accumulator, &fixed_arg);
152 negate_Xsig(&accumulator);
153 149
154 mul64_Xsig(&accumulator, &fixed_arg); 150 shr_Xsig(&accumulator, 3);
155 mul64_Xsig(&accumulator, &fixed_arg); 151 negate_Xsig(&accumulator);
156 152
157 shr_Xsig(&accumulator, 3); 153 add_Xsig_Xsig(&accumulator, &argSqrd);
158 negate_Xsig(&accumulator);
159 154
160 add_Xsig_Xsig(&accumulator, &argSqrd); 155 shr_Xsig(&accumulator, 1);
161 156
162 shr_Xsig(&accumulator, 1); 157 accumulator.lsw |= 1; /* A zero accumulator here would cause problems */
158 negate_Xsig(&accumulator);
163 159
164 accumulator.lsw |= 1; /* A zero accumulator here would cause problems */ 160 /* The basic computation is complete. Now fix the answer to
165 negate_Xsig(&accumulator); 161 compensate for the error due to the approximation used for
162 pi/2
163 */
166 164
167 /* The basic computation is complete. Now fix the answer to 165 /* This has an exponent of -65 */
168 compensate for the error due to the approximation used for 166 fix_up = 0x898cc517;
169 pi/2 167 /* The fix-up needs to be improved for larger args */
170 */ 168 if (argSqrd.msw & 0xffc00000) {
169 /* Get about 32 bit precision in these: */
170 fix_up -= mul_32_32(0x898cc517, argSqrd.msw) / 6;
171 }
172 fix_up = mul_32_32(fix_up, LL_MSW(fixed_arg));
171 173
172 /* This has an exponent of -65 */ 174 adj = accumulator.lsw; /* temp save */
173 fix_up = 0x898cc517; 175 accumulator.lsw -= fix_up;
174 /* The fix-up needs to be improved for larger args */ 176 if (accumulator.lsw > adj)
175 if ( argSqrd.msw & 0xffc00000 ) 177 XSIG_LL(accumulator)--;
176 {
177 /* Get about 32 bit precision in these: */
178 fix_up -= mul_32_32(0x898cc517, argSqrd.msw) / 6;
179 }
180 fix_up = mul_32_32(fix_up, LL_MSW(fixed_arg));
181 178
182 adj = accumulator.lsw; /* temp save */ 179 echange = round_Xsig(&accumulator);
183 accumulator.lsw -= fix_up;
184 if ( accumulator.lsw > adj )
185 XSIG_LL(accumulator) --;
186 180
187 echange = round_Xsig(&accumulator); 181 setexponentpos(&result, echange - 1);
188 182 }
189 setexponentpos(&result, echange - 1);
190 }
191 183
192 significand(&result) = XSIG_LL(accumulator); 184 significand(&result) = XSIG_LL(accumulator);
193 setsign(&result, getsign(st0_ptr)); 185 setsign(&result, getsign(st0_ptr));
194 FPU_copy_to_reg0(&result, TAG_Valid); 186 FPU_copy_to_reg0(&result, TAG_Valid);
195 187
196#ifdef PARANOID 188#ifdef PARANOID
197 if ( (exponent(&result) >= 0) 189 if ((exponent(&result) >= 0)
198 && (significand(&result) > 0x8000000000000000LL) ) 190 && (significand(&result) > 0x8000000000000000LL)) {
199 { 191 EXCEPTION(EX_INTERNAL | 0x150);
200 EXCEPTION(EX_INTERNAL|0x150); 192 }
201 }
202#endif /* PARANOID */ 193#endif /* PARANOID */
203 194
204} 195}
205 196
206
207
208/*--- poly_cos() ------------------------------------------------------------+ 197/*--- poly_cos() ------------------------------------------------------------+
209 | | 198 | |
210 +---------------------------------------------------------------------------*/ 199 +---------------------------------------------------------------------------*/
211void poly_cos(FPU_REG *st0_ptr) 200void poly_cos(FPU_REG *st0_ptr)
212{ 201{
213 FPU_REG result; 202 FPU_REG result;
214 long int exponent, exp2, echange; 203 long int exponent, exp2, echange;
215 Xsig accumulator, argSqrd, fix_up, argTo4; 204 Xsig accumulator, argSqrd, fix_up, argTo4;
216 unsigned long long fixed_arg; 205 unsigned long long fixed_arg;
217 206
218#ifdef PARANOID 207#ifdef PARANOID
219 if ( (exponent(st0_ptr) > 0) 208 if ((exponent(st0_ptr) > 0)
220 || ((exponent(st0_ptr) == 0) 209 || ((exponent(st0_ptr) == 0)
221 && (significand(st0_ptr) > 0xc90fdaa22168c234LL)) ) 210 && (significand(st0_ptr) > 0xc90fdaa22168c234LL))) {
222 { 211 EXCEPTION(EX_Invalid);
223 EXCEPTION(EX_Invalid); 212 FPU_copy_to_reg0(&CONST_QNaN, TAG_Special);
224 FPU_copy_to_reg0(&CONST_QNaN, TAG_Special); 213 return;
225 return;
226 }
227#endif /* PARANOID */
228
229 exponent = exponent(st0_ptr);
230
231 accumulator.lsw = accumulator.midw = accumulator.msw = 0;
232
233 if ( (exponent < -1) || ((exponent == -1) && (st0_ptr->sigh <= 0xb00d6f54)) )
234 {
235 /* arg is < 0.687705 */
236
237 argSqrd.msw = st0_ptr->sigh; argSqrd.midw = st0_ptr->sigl;
238 argSqrd.lsw = 0;
239 mul64_Xsig(&argSqrd, &significand(st0_ptr));
240
241 if ( exponent < -1 )
242 {
243 /* shift the argument right by the required places */
244 shr_Xsig(&argSqrd, 2*(-1-exponent));
245 }
246
247 argTo4.msw = argSqrd.msw; argTo4.midw = argSqrd.midw;
248 argTo4.lsw = argSqrd.lsw;
249 mul_Xsig_Xsig(&argTo4, &argTo4);
250
251 polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), neg_terms_h,
252 N_COEFF_NH-1);
253 mul_Xsig_Xsig(&accumulator, &argSqrd);
254 negate_Xsig(&accumulator);
255
256 polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), pos_terms_h,
257 N_COEFF_PH-1);
258 negate_Xsig(&accumulator);
259
260 mul64_Xsig(&accumulator, &significand(st0_ptr));
261 mul64_Xsig(&accumulator, &significand(st0_ptr));
262 shr_Xsig(&accumulator, -2*(1+exponent));
263
264 shr_Xsig(&accumulator, 3);
265 negate_Xsig(&accumulator);
266
267 add_Xsig_Xsig(&accumulator, &argSqrd);
268
269 shr_Xsig(&accumulator, 1);
270
271 /* It doesn't matter if accumulator is all zero here, the
272 following code will work ok */
273 negate_Xsig(&accumulator);
274
275 if ( accumulator.lsw & 0x80000000 )
276 XSIG_LL(accumulator) ++;
277 if ( accumulator.msw == 0 )
278 {
279 /* The result is 1.0 */
280 FPU_copy_to_reg0(&CONST_1, TAG_Valid);
281 return;
282 }
283 else
284 {
285 significand(&result) = XSIG_LL(accumulator);
286
287 /* will be a valid positive nr with expon = -1 */
288 setexponentpos(&result, -1);
289 }
290 }
291 else
292 {
293 fixed_arg = significand(st0_ptr);
294
295 if ( exponent == 0 )
296 {
297 /* The argument is >= 1.0 */
298
299 /* Put the binary point at the left. */
300 fixed_arg <<= 1;
301 }
302 /* pi/2 in hex is: 1.921fb54442d18469 898CC51701B839A2 52049C1 */
303 fixed_arg = 0x921fb54442d18469LL - fixed_arg;
304 /* There is a special case which arises due to rounding, to fix here. */
305 if ( fixed_arg == 0xffffffffffffffffLL )
306 fixed_arg = 0;
307
308 exponent = -1;
309 exp2 = -1;
310
311 /* A shift is needed here only for a narrow range of arguments,
312 i.e. for fixed_arg approx 2^-32, but we pick up more... */
313 if ( !(LL_MSW(fixed_arg) & 0xffff0000) )
314 {
315 fixed_arg <<= 16;
316 exponent -= 16;
317 exp2 -= 16;
318 } 214 }
215#endif /* PARANOID */
319 216
320 XSIG_LL(argSqrd) = fixed_arg; argSqrd.lsw = 0; 217 exponent = exponent(st0_ptr);
321 mul64_Xsig(&argSqrd, &fixed_arg); 218
322 219 accumulator.lsw = accumulator.midw = accumulator.msw = 0;
323 if ( exponent < -1 ) 220
324 { 221 if ((exponent < -1)
325 /* shift the argument right by the required places */ 222 || ((exponent == -1) && (st0_ptr->sigh <= 0xb00d6f54))) {
326 shr_Xsig(&argSqrd, 2*(-1-exponent)); 223 /* arg is < 0.687705 */
327 } 224
328 225 argSqrd.msw = st0_ptr->sigh;
329 argTo4.msw = argSqrd.msw; argTo4.midw = argSqrd.midw; 226 argSqrd.midw = st0_ptr->sigl;
330 argTo4.lsw = argSqrd.lsw; 227 argSqrd.lsw = 0;
331 mul_Xsig_Xsig(&argTo4, &argTo4); 228 mul64_Xsig(&argSqrd, &significand(st0_ptr));
332 229
333 polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), neg_terms_l, 230 if (exponent < -1) {
334 N_COEFF_N-1); 231 /* shift the argument right by the required places */
335 mul_Xsig_Xsig(&accumulator, &argSqrd); 232 shr_Xsig(&argSqrd, 2 * (-1 - exponent));
336 negate_Xsig(&accumulator); 233 }
337 234
338 polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), pos_terms_l, 235 argTo4.msw = argSqrd.msw;
339 N_COEFF_P-1); 236 argTo4.midw = argSqrd.midw;
340 237 argTo4.lsw = argSqrd.lsw;
341 shr_Xsig(&accumulator, 2); /* Divide by four */ 238 mul_Xsig_Xsig(&argTo4, &argTo4);
342 accumulator.msw |= 0x80000000; /* Add 1.0 */ 239
343 240 polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), neg_terms_h,
344 mul64_Xsig(&accumulator, &fixed_arg); 241 N_COEFF_NH - 1);
345 mul64_Xsig(&accumulator, &fixed_arg); 242 mul_Xsig_Xsig(&accumulator, &argSqrd);
346 mul64_Xsig(&accumulator, &fixed_arg); 243 negate_Xsig(&accumulator);
347 244
348 /* Divide by four, FPU_REG compatible, etc */ 245 polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), pos_terms_h,
349 exponent = 3*exponent; 246 N_COEFF_PH - 1);
350 247 negate_Xsig(&accumulator);
351 /* The minimum exponent difference is 3 */ 248
352 shr_Xsig(&accumulator, exp2 - exponent); 249 mul64_Xsig(&accumulator, &significand(st0_ptr));
353 250 mul64_Xsig(&accumulator, &significand(st0_ptr));
354 negate_Xsig(&accumulator); 251 shr_Xsig(&accumulator, -2 * (1 + exponent));
355 XSIG_LL(accumulator) += fixed_arg; 252
356 253 shr_Xsig(&accumulator, 3);
357 /* The basic computation is complete. Now fix the answer to 254 negate_Xsig(&accumulator);
358 compensate for the error due to the approximation used for 255
359 pi/2 256 add_Xsig_Xsig(&accumulator, &argSqrd);
360 */ 257
361 258 shr_Xsig(&accumulator, 1);
362 /* This has an exponent of -65 */ 259
363 XSIG_LL(fix_up) = 0x898cc51701b839a2ll; 260 /* It doesn't matter if accumulator is all zero here, the
364 fix_up.lsw = 0; 261 following code will work ok */
365 262 negate_Xsig(&accumulator);
366 /* The fix-up needs to be improved for larger args */ 263
367 if ( argSqrd.msw & 0xffc00000 ) 264 if (accumulator.lsw & 0x80000000)
368 { 265 XSIG_LL(accumulator)++;
369 /* Get about 32 bit precision in these: */ 266 if (accumulator.msw == 0) {
370 fix_up.msw -= mul_32_32(0x898cc517, argSqrd.msw) / 2; 267 /* The result is 1.0 */
371 fix_up.msw += mul_32_32(0x898cc517, argTo4.msw) / 24; 268 FPU_copy_to_reg0(&CONST_1, TAG_Valid);
269 return;
270 } else {
271 significand(&result) = XSIG_LL(accumulator);
272
273 /* will be a valid positive nr with expon = -1 */
274 setexponentpos(&result, -1);
275 }
276 } else {
277 fixed_arg = significand(st0_ptr);
278
279 if (exponent == 0) {
280 /* The argument is >= 1.0 */
281
282 /* Put the binary point at the left. */
283 fixed_arg <<= 1;
284 }
285 /* pi/2 in hex is: 1.921fb54442d18469 898CC51701B839A2 52049C1 */
286 fixed_arg = 0x921fb54442d18469LL - fixed_arg;
287 /* There is a special case which arises due to rounding, to fix here. */
288 if (fixed_arg == 0xffffffffffffffffLL)
289 fixed_arg = 0;
290
291 exponent = -1;
292 exp2 = -1;
293
294 /* A shift is needed here only for a narrow range of arguments,
295 i.e. for fixed_arg approx 2^-32, but we pick up more... */
296 if (!(LL_MSW(fixed_arg) & 0xffff0000)) {
297 fixed_arg <<= 16;
298 exponent -= 16;
299 exp2 -= 16;
300 }
301
302 XSIG_LL(argSqrd) = fixed_arg;
303 argSqrd.lsw = 0;
304 mul64_Xsig(&argSqrd, &fixed_arg);
305
306 if (exponent < -1) {
307 /* shift the argument right by the required places */
308 shr_Xsig(&argSqrd, 2 * (-1 - exponent));
309 }
310
311 argTo4.msw = argSqrd.msw;
312 argTo4.midw = argSqrd.midw;
313 argTo4.lsw = argSqrd.lsw;
314 mul_Xsig_Xsig(&argTo4, &argTo4);
315
316 polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), neg_terms_l,
317 N_COEFF_N - 1);
318 mul_Xsig_Xsig(&accumulator, &argSqrd);
319 negate_Xsig(&accumulator);
320
321 polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), pos_terms_l,
322 N_COEFF_P - 1);
323
324 shr_Xsig(&accumulator, 2); /* Divide by four */
325 accumulator.msw |= 0x80000000; /* Add 1.0 */
326
327 mul64_Xsig(&accumulator, &fixed_arg);
328 mul64_Xsig(&accumulator, &fixed_arg);
329 mul64_Xsig(&accumulator, &fixed_arg);
330
331 /* Divide by four, FPU_REG compatible, etc */
332 exponent = 3 * exponent;
333
334 /* The minimum exponent difference is 3 */
335 shr_Xsig(&accumulator, exp2 - exponent);
336
337 negate_Xsig(&accumulator);
338 XSIG_LL(accumulator) += fixed_arg;
339
340 /* The basic computation is complete. Now fix the answer to
341 compensate for the error due to the approximation used for
342 pi/2
343 */
344
345 /* This has an exponent of -65 */
346 XSIG_LL(fix_up) = 0x898cc51701b839a2ll;
347 fix_up.lsw = 0;
348
349 /* The fix-up needs to be improved for larger args */
350 if (argSqrd.msw & 0xffc00000) {
351 /* Get about 32 bit precision in these: */
352 fix_up.msw -= mul_32_32(0x898cc517, argSqrd.msw) / 2;
353 fix_up.msw += mul_32_32(0x898cc517, argTo4.msw) / 24;
354 }
355
356 exp2 += norm_Xsig(&accumulator);
357 shr_Xsig(&accumulator, 1); /* Prevent overflow */
358 exp2++;
359 shr_Xsig(&fix_up, 65 + exp2);
360
361 add_Xsig_Xsig(&accumulator, &fix_up);
362
363 echange = round_Xsig(&accumulator);
364
365 setexponentpos(&result, exp2 + echange);
366 significand(&result) = XSIG_LL(accumulator);
372 } 367 }
373 368
374 exp2 += norm_Xsig(&accumulator); 369 FPU_copy_to_reg0(&result, TAG_Valid);
375 shr_Xsig(&accumulator, 1); /* Prevent overflow */
376 exp2++;
377 shr_Xsig(&fix_up, 65 + exp2);
378
379 add_Xsig_Xsig(&accumulator, &fix_up);
380
381 echange = round_Xsig(&accumulator);
382
383 setexponentpos(&result, exp2 + echange);
384 significand(&result) = XSIG_LL(accumulator);
385 }
386
387 FPU_copy_to_reg0(&result, TAG_Valid);
388 370
389#ifdef PARANOID 371#ifdef PARANOID
390 if ( (exponent(&result) >= 0) 372 if ((exponent(&result) >= 0)
391 && (significand(&result) > 0x8000000000000000LL) ) 373 && (significand(&result) > 0x8000000000000000LL)) {
392 { 374 EXCEPTION(EX_INTERNAL | 0x151);
393 EXCEPTION(EX_INTERNAL|0x151); 375 }
394 }
395#endif /* PARANOID */ 376#endif /* PARANOID */
396 377
397} 378}
diff --git a/arch/x86/math-emu/poly_tan.c b/arch/x86/math-emu/poly_tan.c
index 8df3e03b6e6f..1875763e0c02 100644
--- a/arch/x86/math-emu/poly_tan.c
+++ b/arch/x86/math-emu/poly_tan.c
@@ -17,206 +17,196 @@
17#include "control_w.h" 17#include "control_w.h"
18#include "poly.h" 18#include "poly.h"
19 19
20
21#define HiPOWERop 3 /* odd poly, positive terms */ 20#define HiPOWERop 3 /* odd poly, positive terms */
22static const unsigned long long oddplterm[HiPOWERop] = 21static const unsigned long long oddplterm[HiPOWERop] = {
23{ 22 0x0000000000000000LL,
24 0x0000000000000000LL, 23 0x0051a1cf08fca228LL,
25 0x0051a1cf08fca228LL, 24 0x0000000071284ff7LL
26 0x0000000071284ff7LL
27}; 25};
28 26
29#define HiPOWERon 2 /* odd poly, negative terms */ 27#define HiPOWERon 2 /* odd poly, negative terms */
30static const unsigned long long oddnegterm[HiPOWERon] = 28static const unsigned long long oddnegterm[HiPOWERon] = {
31{ 29 0x1291a9a184244e80LL,
32 0x1291a9a184244e80LL, 30 0x0000583245819c21LL
33 0x0000583245819c21LL
34}; 31};
35 32
36#define HiPOWERep 2 /* even poly, positive terms */ 33#define HiPOWERep 2 /* even poly, positive terms */
37static const unsigned long long evenplterm[HiPOWERep] = 34static const unsigned long long evenplterm[HiPOWERep] = {
38{ 35 0x0e848884b539e888LL,
39 0x0e848884b539e888LL, 36 0x00003c7f18b887daLL
40 0x00003c7f18b887daLL
41}; 37};
42 38
43#define HiPOWERen 2 /* even poly, negative terms */ 39#define HiPOWERen 2 /* even poly, negative terms */
44static const unsigned long long evennegterm[HiPOWERen] = 40static const unsigned long long evennegterm[HiPOWERen] = {
45{ 41 0xf1f0200fd51569ccLL,
46 0xf1f0200fd51569ccLL, 42 0x003afb46105c4432LL
47 0x003afb46105c4432LL
48}; 43};
49 44
50static const unsigned long long twothirds = 0xaaaaaaaaaaaaaaabLL; 45static const unsigned long long twothirds = 0xaaaaaaaaaaaaaaabLL;
51 46
52
53/*--- poly_tan() ------------------------------------------------------------+ 47/*--- poly_tan() ------------------------------------------------------------+
54 | | 48 | |
55 +---------------------------------------------------------------------------*/ 49 +---------------------------------------------------------------------------*/
56void poly_tan(FPU_REG *st0_ptr) 50void poly_tan(FPU_REG *st0_ptr)
57{ 51{
58 long int exponent; 52 long int exponent;
59 int invert; 53 int invert;
60 Xsig argSq, argSqSq, accumulatoro, accumulatore, accum, 54 Xsig argSq, argSqSq, accumulatoro, accumulatore, accum,
61 argSignif, fix_up; 55 argSignif, fix_up;
62 unsigned long adj; 56 unsigned long adj;
63 57
64 exponent = exponent(st0_ptr); 58 exponent = exponent(st0_ptr);
65 59
66#ifdef PARANOID 60#ifdef PARANOID
67 if ( signnegative(st0_ptr) ) /* Can't hack a number < 0.0 */ 61 if (signnegative(st0_ptr)) { /* Can't hack a number < 0.0 */
68 { arith_invalid(0); return; } /* Need a positive number */ 62 arith_invalid(0);
63 return;
64 } /* Need a positive number */
69#endif /* PARANOID */ 65#endif /* PARANOID */
70 66
71 /* Split the problem into two domains, smaller and larger than pi/4 */ 67 /* Split the problem into two domains, smaller and larger than pi/4 */
72 if ( (exponent == 0) || ((exponent == -1) && (st0_ptr->sigh > 0xc90fdaa2)) ) 68 if ((exponent == 0)
73 { 69 || ((exponent == -1) && (st0_ptr->sigh > 0xc90fdaa2))) {
74 /* The argument is greater than (approx) pi/4 */ 70 /* The argument is greater than (approx) pi/4 */
75 invert = 1; 71 invert = 1;
76 accum.lsw = 0; 72 accum.lsw = 0;
77 XSIG_LL(accum) = significand(st0_ptr); 73 XSIG_LL(accum) = significand(st0_ptr);
78 74
79 if ( exponent == 0 ) 75 if (exponent == 0) {
80 { 76 /* The argument is >= 1.0 */
81 /* The argument is >= 1.0 */ 77 /* Put the binary point at the left. */
82 /* Put the binary point at the left. */ 78 XSIG_LL(accum) <<= 1;
83 XSIG_LL(accum) <<= 1; 79 }
84 } 80 /* pi/2 in hex is: 1.921fb54442d18469 898CC51701B839A2 52049C1 */
85 /* pi/2 in hex is: 1.921fb54442d18469 898CC51701B839A2 52049C1 */ 81 XSIG_LL(accum) = 0x921fb54442d18469LL - XSIG_LL(accum);
86 XSIG_LL(accum) = 0x921fb54442d18469LL - XSIG_LL(accum); 82 /* This is a special case which arises due to rounding. */
87 /* This is a special case which arises due to rounding. */ 83 if (XSIG_LL(accum) == 0xffffffffffffffffLL) {
88 if ( XSIG_LL(accum) == 0xffffffffffffffffLL ) 84 FPU_settag0(TAG_Valid);
89 { 85 significand(st0_ptr) = 0x8a51e04daabda360LL;
90 FPU_settag0(TAG_Valid); 86 setexponent16(st0_ptr,
91 significand(st0_ptr) = 0x8a51e04daabda360LL; 87 (0x41 + EXTENDED_Ebias) | SIGN_Negative);
92 setexponent16(st0_ptr, (0x41 + EXTENDED_Ebias) | SIGN_Negative); 88 return;
93 return; 89 }
90
91 argSignif.lsw = accum.lsw;
92 XSIG_LL(argSignif) = XSIG_LL(accum);
93 exponent = -1 + norm_Xsig(&argSignif);
94 } else {
95 invert = 0;
96 argSignif.lsw = 0;
97 XSIG_LL(accum) = XSIG_LL(argSignif) = significand(st0_ptr);
98
99 if (exponent < -1) {
100 /* shift the argument right by the required places */
101 if (FPU_shrx(&XSIG_LL(accum), -1 - exponent) >=
102 0x80000000U)
103 XSIG_LL(accum)++; /* round up */
104 }
94 } 105 }
95 106
96 argSignif.lsw = accum.lsw; 107 XSIG_LL(argSq) = XSIG_LL(accum);
97 XSIG_LL(argSignif) = XSIG_LL(accum); 108 argSq.lsw = accum.lsw;
98 exponent = -1 + norm_Xsig(&argSignif); 109 mul_Xsig_Xsig(&argSq, &argSq);
99 } 110 XSIG_LL(argSqSq) = XSIG_LL(argSq);
100 else 111 argSqSq.lsw = argSq.lsw;
101 { 112 mul_Xsig_Xsig(&argSqSq, &argSqSq);
102 invert = 0; 113
103 argSignif.lsw = 0; 114 /* Compute the negative terms for the numerator polynomial */
104 XSIG_LL(accum) = XSIG_LL(argSignif) = significand(st0_ptr); 115 accumulatoro.msw = accumulatoro.midw = accumulatoro.lsw = 0;
105 116 polynomial_Xsig(&accumulatoro, &XSIG_LL(argSqSq), oddnegterm,
106 if ( exponent < -1 ) 117 HiPOWERon - 1);
107 { 118 mul_Xsig_Xsig(&accumulatoro, &argSq);
108 /* shift the argument right by the required places */ 119 negate_Xsig(&accumulatoro);
109 if ( FPU_shrx(&XSIG_LL(accum), -1-exponent) >= 0x80000000U ) 120 /* Add the positive terms */
110 XSIG_LL(accum) ++; /* round up */ 121 polynomial_Xsig(&accumulatoro, &XSIG_LL(argSqSq), oddplterm,
111 } 122 HiPOWERop - 1);
112 } 123
113 124 /* Compute the positive terms for the denominator polynomial */
114 XSIG_LL(argSq) = XSIG_LL(accum); argSq.lsw = accum.lsw; 125 accumulatore.msw = accumulatore.midw = accumulatore.lsw = 0;
115 mul_Xsig_Xsig(&argSq, &argSq); 126 polynomial_Xsig(&accumulatore, &XSIG_LL(argSqSq), evenplterm,
116 XSIG_LL(argSqSq) = XSIG_LL(argSq); argSqSq.lsw = argSq.lsw; 127 HiPOWERep - 1);
117 mul_Xsig_Xsig(&argSqSq, &argSqSq); 128 mul_Xsig_Xsig(&accumulatore, &argSq);
118 129 negate_Xsig(&accumulatore);
119 /* Compute the negative terms for the numerator polynomial */ 130 /* Add the negative terms */
120 accumulatoro.msw = accumulatoro.midw = accumulatoro.lsw = 0; 131 polynomial_Xsig(&accumulatore, &XSIG_LL(argSqSq), evennegterm,
121 polynomial_Xsig(&accumulatoro, &XSIG_LL(argSqSq), oddnegterm, HiPOWERon-1); 132 HiPOWERen - 1);
122 mul_Xsig_Xsig(&accumulatoro, &argSq); 133 /* Multiply by arg^2 */
123 negate_Xsig(&accumulatoro); 134 mul64_Xsig(&accumulatore, &XSIG_LL(argSignif));
124 /* Add the positive terms */ 135 mul64_Xsig(&accumulatore, &XSIG_LL(argSignif));
125 polynomial_Xsig(&accumulatoro, &XSIG_LL(argSqSq), oddplterm, HiPOWERop-1); 136 /* de-normalize and divide by 2 */
126 137 shr_Xsig(&accumulatore, -2 * (1 + exponent) + 1);
127 138 negate_Xsig(&accumulatore); /* This does 1 - accumulator */
128 /* Compute the positive terms for the denominator polynomial */ 139
129 accumulatore.msw = accumulatore.midw = accumulatore.lsw = 0; 140 /* Now find the ratio. */
130 polynomial_Xsig(&accumulatore, &XSIG_LL(argSqSq), evenplterm, HiPOWERep-1); 141 if (accumulatore.msw == 0) {
131 mul_Xsig_Xsig(&accumulatore, &argSq); 142 /* accumulatoro must contain 1.0 here, (actually, 0) but it
132 negate_Xsig(&accumulatore); 143 really doesn't matter what value we use because it will
133 /* Add the negative terms */ 144 have negligible effect in later calculations
134 polynomial_Xsig(&accumulatore, &XSIG_LL(argSqSq), evennegterm, HiPOWERen-1); 145 */
135 /* Multiply by arg^2 */ 146 XSIG_LL(accum) = 0x8000000000000000LL;
136 mul64_Xsig(&accumulatore, &XSIG_LL(argSignif)); 147 accum.lsw = 0;
137 mul64_Xsig(&accumulatore, &XSIG_LL(argSignif)); 148 } else {
138 /* de-normalize and divide by 2 */ 149 div_Xsig(&accumulatoro, &accumulatore, &accum);
139 shr_Xsig(&accumulatore, -2*(1+exponent) + 1);
140 negate_Xsig(&accumulatore); /* This does 1 - accumulator */
141
142 /* Now find the ratio. */
143 if ( accumulatore.msw == 0 )
144 {
145 /* accumulatoro must contain 1.0 here, (actually, 0) but it
146 really doesn't matter what value we use because it will
147 have negligible effect in later calculations
148 */
149 XSIG_LL(accum) = 0x8000000000000000LL;
150 accum.lsw = 0;
151 }
152 else
153 {
154 div_Xsig(&accumulatoro, &accumulatore, &accum);
155 }
156
157 /* Multiply by 1/3 * arg^3 */
158 mul64_Xsig(&accum, &XSIG_LL(argSignif));
159 mul64_Xsig(&accum, &XSIG_LL(argSignif));
160 mul64_Xsig(&accum, &XSIG_LL(argSignif));
161 mul64_Xsig(&accum, &twothirds);
162 shr_Xsig(&accum, -2*(exponent+1));
163
164 /* tan(arg) = arg + accum */
165 add_two_Xsig(&accum, &argSignif, &exponent);
166
167 if ( invert )
168 {
169 /* We now have the value of tan(pi_2 - arg) where pi_2 is an
170 approximation for pi/2
171 */
172 /* The next step is to fix the answer to compensate for the
173 error due to the approximation used for pi/2
174 */
175
176 /* This is (approx) delta, the error in our approx for pi/2
177 (see above). It has an exponent of -65
178 */
179 XSIG_LL(fix_up) = 0x898cc51701b839a2LL;
180 fix_up.lsw = 0;
181
182 if ( exponent == 0 )
183 adj = 0xffffffff; /* We want approx 1.0 here, but
184 this is close enough. */
185 else if ( exponent > -30 )
186 {
187 adj = accum.msw >> -(exponent+1); /* tan */
188 adj = mul_32_32(adj, adj); /* tan^2 */
189 } 150 }
190 else 151
191 adj = 0; 152 /* Multiply by 1/3 * arg^3 */
192 adj = mul_32_32(0x898cc517, adj); /* delta * tan^2 */ 153 mul64_Xsig(&accum, &XSIG_LL(argSignif));
193 154 mul64_Xsig(&accum, &XSIG_LL(argSignif));
194 fix_up.msw += adj; 155 mul64_Xsig(&accum, &XSIG_LL(argSignif));
195 if ( !(fix_up.msw & 0x80000000) ) /* did fix_up overflow ? */ 156 mul64_Xsig(&accum, &twothirds);
196 { 157 shr_Xsig(&accum, -2 * (exponent + 1));
197 /* Yes, we need to add an msb */ 158
198 shr_Xsig(&fix_up, 1); 159 /* tan(arg) = arg + accum */
199 fix_up.msw |= 0x80000000; 160 add_two_Xsig(&accum, &argSignif, &exponent);
200 shr_Xsig(&fix_up, 64 + exponent); 161
162 if (invert) {
163 /* We now have the value of tan(pi_2 - arg) where pi_2 is an
164 approximation for pi/2
165 */
166 /* The next step is to fix the answer to compensate for the
167 error due to the approximation used for pi/2
168 */
169
170 /* This is (approx) delta, the error in our approx for pi/2
171 (see above). It has an exponent of -65
172 */
173 XSIG_LL(fix_up) = 0x898cc51701b839a2LL;
174 fix_up.lsw = 0;
175
176 if (exponent == 0)
177 adj = 0xffffffff; /* We want approx 1.0 here, but
178 this is close enough. */
179 else if (exponent > -30) {
180 adj = accum.msw >> -(exponent + 1); /* tan */
181 adj = mul_32_32(adj, adj); /* tan^2 */
182 } else
183 adj = 0;
184 adj = mul_32_32(0x898cc517, adj); /* delta * tan^2 */
185
186 fix_up.msw += adj;
187 if (!(fix_up.msw & 0x80000000)) { /* did fix_up overflow ? */
188 /* Yes, we need to add an msb */
189 shr_Xsig(&fix_up, 1);
190 fix_up.msw |= 0x80000000;
191 shr_Xsig(&fix_up, 64 + exponent);
192 } else
193 shr_Xsig(&fix_up, 65 + exponent);
194
195 add_two_Xsig(&accum, &fix_up, &exponent);
196
197 /* accum now contains tan(pi/2 - arg).
198 Use tan(arg) = 1.0 / tan(pi/2 - arg)
199 */
200 accumulatoro.lsw = accumulatoro.midw = 0;
201 accumulatoro.msw = 0x80000000;
202 div_Xsig(&accumulatoro, &accum, &accum);
203 exponent = -exponent - 1;
201 } 204 }
202 else 205
203 shr_Xsig(&fix_up, 65 + exponent); 206 /* Transfer the result */
204 207 round_Xsig(&accum);
205 add_two_Xsig(&accum, &fix_up, &exponent); 208 FPU_settag0(TAG_Valid);
206 209 significand(st0_ptr) = XSIG_LL(accum);
207 /* accum now contains tan(pi/2 - arg). 210 setexponent16(st0_ptr, exponent + EXTENDED_Ebias); /* Result is positive. */
208 Use tan(arg) = 1.0 / tan(pi/2 - arg)
209 */
210 accumulatoro.lsw = accumulatoro.midw = 0;
211 accumulatoro.msw = 0x80000000;
212 div_Xsig(&accumulatoro, &accum, &accum);
213 exponent = - exponent - 1;
214 }
215
216 /* Transfer the result */
217 round_Xsig(&accum);
218 FPU_settag0(TAG_Valid);
219 significand(st0_ptr) = XSIG_LL(accum);
220 setexponent16(st0_ptr, exponent + EXTENDED_Ebias); /* Result is positive. */
221 211
222} 212}
diff --git a/arch/x86/math-emu/reg_add_sub.c b/arch/x86/math-emu/reg_add_sub.c
index 7cd3b37ac084..deea48b9f13a 100644
--- a/arch/x86/math-emu/reg_add_sub.c
+++ b/arch/x86/math-emu/reg_add_sub.c
@@ -27,7 +27,7 @@
27static 27static
28int add_sub_specials(FPU_REG const *a, u_char taga, u_char signa, 28int add_sub_specials(FPU_REG const *a, u_char taga, u_char signa,
29 FPU_REG const *b, u_char tagb, u_char signb, 29 FPU_REG const *b, u_char tagb, u_char signb,
30 FPU_REG *dest, int deststnr, int control_w); 30 FPU_REG * dest, int deststnr, int control_w);
31 31
32/* 32/*
33 Operates on st(0) and st(n), or on st(0) and temporary data. 33 Operates on st(0) and st(n), or on st(0) and temporary data.
@@ -35,340 +35,299 @@ int add_sub_specials(FPU_REG const *a, u_char taga, u_char signa,
35 */ 35 */
36int FPU_add(FPU_REG const *b, u_char tagb, int deststnr, int control_w) 36int FPU_add(FPU_REG const *b, u_char tagb, int deststnr, int control_w)
37{ 37{
38 FPU_REG *a = &st(0); 38 FPU_REG *a = &st(0);
39 FPU_REG *dest = &st(deststnr); 39 FPU_REG *dest = &st(deststnr);
40 u_char signb = getsign(b); 40 u_char signb = getsign(b);
41 u_char taga = FPU_gettag0(); 41 u_char taga = FPU_gettag0();
42 u_char signa = getsign(a); 42 u_char signa = getsign(a);
43 u_char saved_sign = getsign(dest); 43 u_char saved_sign = getsign(dest);
44 int diff, tag, expa, expb; 44 int diff, tag, expa, expb;
45 45
46 if ( !(taga | tagb) ) 46 if (!(taga | tagb)) {
47 { 47 expa = exponent(a);
48 expa = exponent(a); 48 expb = exponent(b);
49 expb = exponent(b); 49
50 50 valid_add:
51 valid_add: 51 /* Both registers are valid */
52 /* Both registers are valid */ 52 if (!(signa ^ signb)) {
53 if (!(signa ^ signb)) 53 /* signs are the same */
54 { 54 tag =
55 /* signs are the same */ 55 FPU_u_add(a, b, dest, control_w, signa, expa, expb);
56 tag = FPU_u_add(a, b, dest, control_w, signa, expa, expb); 56 } else {
57 } 57 /* The signs are different, so do a subtraction */
58 else 58 diff = expa - expb;
59 { 59 if (!diff) {
60 /* The signs are different, so do a subtraction */ 60 diff = a->sigh - b->sigh; /* This works only if the ms bits
61 diff = expa - expb; 61 are identical. */
62 if (!diff) 62 if (!diff) {
63 { 63 diff = a->sigl > b->sigl;
64 diff = a->sigh - b->sigh; /* This works only if the ms bits 64 if (!diff)
65 are identical. */ 65 diff = -(a->sigl < b->sigl);
66 if (!diff) 66 }
67 { 67 }
68 diff = a->sigl > b->sigl; 68
69 if (!diff) 69 if (diff > 0) {
70 diff = -(a->sigl < b->sigl); 70 tag =
71 FPU_u_sub(a, b, dest, control_w, signa,
72 expa, expb);
73 } else if (diff < 0) {
74 tag =
75 FPU_u_sub(b, a, dest, control_w, signb,
76 expb, expa);
77 } else {
78 FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
79 /* sign depends upon rounding mode */
80 setsign(dest, ((control_w & CW_RC) != RC_DOWN)
81 ? SIGN_POS : SIGN_NEG);
82 return TAG_Zero;
83 }
71 } 84 }
72 }
73
74 if (diff > 0)
75 {
76 tag = FPU_u_sub(a, b, dest, control_w, signa, expa, expb);
77 }
78 else if ( diff < 0 )
79 {
80 tag = FPU_u_sub(b, a, dest, control_w, signb, expb, expa);
81 }
82 else
83 {
84 FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
85 /* sign depends upon rounding mode */
86 setsign(dest, ((control_w & CW_RC) != RC_DOWN)
87 ? SIGN_POS : SIGN_NEG);
88 return TAG_Zero;
89 }
90 }
91 85
92 if ( tag < 0 ) 86 if (tag < 0) {
93 { 87 setsign(dest, saved_sign);
94 setsign(dest, saved_sign); 88 return tag;
95 return tag; 89 }
90 FPU_settagi(deststnr, tag);
91 return tag;
96 } 92 }
97 FPU_settagi(deststnr, tag);
98 return tag;
99 }
100 93
101 if ( taga == TAG_Special ) 94 if (taga == TAG_Special)
102 taga = FPU_Special(a); 95 taga = FPU_Special(a);
103 if ( tagb == TAG_Special ) 96 if (tagb == TAG_Special)
104 tagb = FPU_Special(b); 97 tagb = FPU_Special(b);
105 98
106 if ( ((taga == TAG_Valid) && (tagb == TW_Denormal)) 99 if (((taga == TAG_Valid) && (tagb == TW_Denormal))
107 || ((taga == TW_Denormal) && (tagb == TAG_Valid)) 100 || ((taga == TW_Denormal) && (tagb == TAG_Valid))
108 || ((taga == TW_Denormal) && (tagb == TW_Denormal)) ) 101 || ((taga == TW_Denormal) && (tagb == TW_Denormal))) {
109 { 102 FPU_REG x, y;
110 FPU_REG x, y; 103
104 if (denormal_operand() < 0)
105 return FPU_Exception;
106
107 FPU_to_exp16(a, &x);
108 FPU_to_exp16(b, &y);
109 a = &x;
110 b = &y;
111 expa = exponent16(a);
112 expb = exponent16(b);
113 goto valid_add;
114 }
111 115
112 if ( denormal_operand() < 0 ) 116 if ((taga == TW_NaN) || (tagb == TW_NaN)) {
113 return FPU_Exception; 117 if (deststnr == 0)
118 return real_2op_NaN(b, tagb, deststnr, a);
119 else
120 return real_2op_NaN(a, taga, deststnr, a);
121 }
114 122
115 FPU_to_exp16(a, &x); 123 return add_sub_specials(a, taga, signa, b, tagb, signb,
116 FPU_to_exp16(b, &y); 124 dest, deststnr, control_w);
117 a = &x;
118 b = &y;
119 expa = exponent16(a);
120 expb = exponent16(b);
121 goto valid_add;
122 }
123
124 if ( (taga == TW_NaN) || (tagb == TW_NaN) )
125 {
126 if ( deststnr == 0 )
127 return real_2op_NaN(b, tagb, deststnr, a);
128 else
129 return real_2op_NaN(a, taga, deststnr, a);
130 }
131
132 return add_sub_specials(a, taga, signa, b, tagb, signb,
133 dest, deststnr, control_w);
134} 125}
135 126
136
137/* Subtract b from a. (a-b) -> dest */ 127/* Subtract b from a. (a-b) -> dest */
138int FPU_sub(int flags, int rm, int control_w) 128int FPU_sub(int flags, int rm, int control_w)
139{ 129{
140 FPU_REG const *a, *b; 130 FPU_REG const *a, *b;
141 FPU_REG *dest; 131 FPU_REG *dest;
142 u_char taga, tagb, signa, signb, saved_sign, sign; 132 u_char taga, tagb, signa, signb, saved_sign, sign;
143 int diff, tag = 0, expa, expb, deststnr; 133 int diff, tag = 0, expa, expb, deststnr;
144 134
145 a = &st(0); 135 a = &st(0);
146 taga = FPU_gettag0(); 136 taga = FPU_gettag0();
147 137
148 deststnr = 0; 138 deststnr = 0;
149 if ( flags & LOADED ) 139 if (flags & LOADED) {
150 { 140 b = (FPU_REG *) rm;
151 b = (FPU_REG *)rm; 141 tagb = flags & 0x0f;
152 tagb = flags & 0x0f; 142 } else {
153 } 143 b = &st(rm);
154 else 144 tagb = FPU_gettagi(rm);
155 { 145
156 b = &st(rm); 146 if (flags & DEST_RM)
157 tagb = FPU_gettagi(rm); 147 deststnr = rm;
158
159 if ( flags & DEST_RM )
160 deststnr = rm;
161 }
162
163 signa = getsign(a);
164 signb = getsign(b);
165
166 if ( flags & REV )
167 {
168 signa ^= SIGN_NEG;
169 signb ^= SIGN_NEG;
170 }
171
172 dest = &st(deststnr);
173 saved_sign = getsign(dest);
174
175 if ( !(taga | tagb) )
176 {
177 expa = exponent(a);
178 expb = exponent(b);
179
180 valid_subtract:
181 /* Both registers are valid */
182
183 diff = expa - expb;
184
185 if (!diff)
186 {
187 diff = a->sigh - b->sigh; /* Works only if ms bits are identical */
188 if (!diff)
189 {
190 diff = a->sigl > b->sigl;
191 if (!diff)
192 diff = -(a->sigl < b->sigl);
193 }
194 } 148 }
195 149
196 switch ( (((int)signa)*2 + signb) / SIGN_NEG ) 150 signa = getsign(a);
197 { 151 signb = getsign(b);
198 case 0: /* P - P */ 152
199 case 3: /* N - N */ 153 if (flags & REV) {
200 if (diff > 0) 154 signa ^= SIGN_NEG;
201 { 155 signb ^= SIGN_NEG;
202 /* |a| > |b| */ 156 }
203 tag = FPU_u_sub(a, b, dest, control_w, signa, expa, expb); 157
204 } 158 dest = &st(deststnr);
205 else if ( diff == 0 ) 159 saved_sign = getsign(dest);
206 { 160
207 FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr); 161 if (!(taga | tagb)) {
208 162 expa = exponent(a);
209 /* sign depends upon rounding mode */ 163 expb = exponent(b);
210 setsign(dest, ((control_w & CW_RC) != RC_DOWN) 164
211 ? SIGN_POS : SIGN_NEG); 165 valid_subtract:
212 return TAG_Zero; 166 /* Both registers are valid */
213 } 167
214 else 168 diff = expa - expb;
215 { 169
216 sign = signa ^ SIGN_NEG; 170 if (!diff) {
217 tag = FPU_u_sub(b, a, dest, control_w, sign, expb, expa); 171 diff = a->sigh - b->sigh; /* Works only if ms bits are identical */
218 } 172 if (!diff) {
219 break; 173 diff = a->sigl > b->sigl;
220 case 1: /* P - N */ 174 if (!diff)
221 tag = FPU_u_add(a, b, dest, control_w, SIGN_POS, expa, expb); 175 diff = -(a->sigl < b->sigl);
222 break; 176 }
223 case 2: /* N - P */ 177 }
224 tag = FPU_u_add(a, b, dest, control_w, SIGN_NEG, expa, expb); 178
225 break; 179 switch ((((int)signa) * 2 + signb) / SIGN_NEG) {
180 case 0: /* P - P */
181 case 3: /* N - N */
182 if (diff > 0) {
183 /* |a| > |b| */
184 tag =
185 FPU_u_sub(a, b, dest, control_w, signa,
186 expa, expb);
187 } else if (diff == 0) {
188 FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
189
190 /* sign depends upon rounding mode */
191 setsign(dest, ((control_w & CW_RC) != RC_DOWN)
192 ? SIGN_POS : SIGN_NEG);
193 return TAG_Zero;
194 } else {
195 sign = signa ^ SIGN_NEG;
196 tag =
197 FPU_u_sub(b, a, dest, control_w, sign, expb,
198 expa);
199 }
200 break;
201 case 1: /* P - N */
202 tag =
203 FPU_u_add(a, b, dest, control_w, SIGN_POS, expa,
204 expb);
205 break;
206 case 2: /* N - P */
207 tag =
208 FPU_u_add(a, b, dest, control_w, SIGN_NEG, expa,
209 expb);
210 break;
226#ifdef PARANOID 211#ifdef PARANOID
227 default: 212 default:
228 EXCEPTION(EX_INTERNAL|0x111); 213 EXCEPTION(EX_INTERNAL | 0x111);
229 return -1; 214 return -1;
230#endif 215#endif
216 }
217 if (tag < 0) {
218 setsign(dest, saved_sign);
219 return tag;
220 }
221 FPU_settagi(deststnr, tag);
222 return tag;
231 } 223 }
232 if ( tag < 0 )
233 {
234 setsign(dest, saved_sign);
235 return tag;
236 }
237 FPU_settagi(deststnr, tag);
238 return tag;
239 }
240 224
241 if ( taga == TAG_Special ) 225 if (taga == TAG_Special)
242 taga = FPU_Special(a); 226 taga = FPU_Special(a);
243 if ( tagb == TAG_Special ) 227 if (tagb == TAG_Special)
244 tagb = FPU_Special(b); 228 tagb = FPU_Special(b);
245 229
246 if ( ((taga == TAG_Valid) && (tagb == TW_Denormal)) 230 if (((taga == TAG_Valid) && (tagb == TW_Denormal))
247 || ((taga == TW_Denormal) && (tagb == TAG_Valid)) 231 || ((taga == TW_Denormal) && (tagb == TAG_Valid))
248 || ((taga == TW_Denormal) && (tagb == TW_Denormal)) ) 232 || ((taga == TW_Denormal) && (tagb == TW_Denormal))) {
249 { 233 FPU_REG x, y;
250 FPU_REG x, y;
251 234
252 if ( denormal_operand() < 0 ) 235 if (denormal_operand() < 0)
253 return FPU_Exception; 236 return FPU_Exception;
237
238 FPU_to_exp16(a, &x);
239 FPU_to_exp16(b, &y);
240 a = &x;
241 b = &y;
242 expa = exponent16(a);
243 expb = exponent16(b);
254 244
255 FPU_to_exp16(a, &x); 245 goto valid_subtract;
256 FPU_to_exp16(b, &y);
257 a = &x;
258 b = &y;
259 expa = exponent16(a);
260 expb = exponent16(b);
261
262 goto valid_subtract;
263 }
264
265 if ( (taga == TW_NaN) || (tagb == TW_NaN) )
266 {
267 FPU_REG const *d1, *d2;
268 if ( flags & REV )
269 {
270 d1 = b;
271 d2 = a;
272 } 246 }
273 else 247
274 { 248 if ((taga == TW_NaN) || (tagb == TW_NaN)) {
275 d1 = a; 249 FPU_REG const *d1, *d2;
276 d2 = b; 250 if (flags & REV) {
251 d1 = b;
252 d2 = a;
253 } else {
254 d1 = a;
255 d2 = b;
256 }
257 if (flags & LOADED)
258 return real_2op_NaN(b, tagb, deststnr, d1);
259 if (flags & DEST_RM)
260 return real_2op_NaN(a, taga, deststnr, d2);
261 else
262 return real_2op_NaN(b, tagb, deststnr, d2);
277 } 263 }
278 if ( flags & LOADED )
279 return real_2op_NaN(b, tagb, deststnr, d1);
280 if ( flags & DEST_RM )
281 return real_2op_NaN(a, taga, deststnr, d2);
282 else
283 return real_2op_NaN(b, tagb, deststnr, d2);
284 }
285
286 return add_sub_specials(a, taga, signa, b, tagb, signb ^ SIGN_NEG,
287 dest, deststnr, control_w);
288}
289 264
265 return add_sub_specials(a, taga, signa, b, tagb, signb ^ SIGN_NEG,
266 dest, deststnr, control_w);
267}
290 268
291static 269static
292int add_sub_specials(FPU_REG const *a, u_char taga, u_char signa, 270int add_sub_specials(FPU_REG const *a, u_char taga, u_char signa,
293 FPU_REG const *b, u_char tagb, u_char signb, 271 FPU_REG const *b, u_char tagb, u_char signb,
294 FPU_REG *dest, int deststnr, int control_w) 272 FPU_REG * dest, int deststnr, int control_w)
295{ 273{
296 if ( ((taga == TW_Denormal) || (tagb == TW_Denormal)) 274 if (((taga == TW_Denormal) || (tagb == TW_Denormal))
297 && (denormal_operand() < 0) ) 275 && (denormal_operand() < 0))
298 return FPU_Exception; 276 return FPU_Exception;
299 277
300 if (taga == TAG_Zero) 278 if (taga == TAG_Zero) {
301 { 279 if (tagb == TAG_Zero) {
302 if (tagb == TAG_Zero) 280 /* Both are zero, result will be zero. */
303 { 281 u_char different_signs = signa ^ signb;
304 /* Both are zero, result will be zero. */ 282
305 u_char different_signs = signa ^ signb; 283 FPU_copy_to_regi(a, TAG_Zero, deststnr);
306 284 if (different_signs) {
307 FPU_copy_to_regi(a, TAG_Zero, deststnr); 285 /* Signs are different. */
308 if ( different_signs ) 286 /* Sign of answer depends upon rounding mode. */
309 { 287 setsign(dest, ((control_w & CW_RC) != RC_DOWN)
310 /* Signs are different. */ 288 ? SIGN_POS : SIGN_NEG);
311 /* Sign of answer depends upon rounding mode. */ 289 } else
312 setsign(dest, ((control_w & CW_RC) != RC_DOWN) 290 setsign(dest, signa); /* signa may differ from the sign of a. */
313 ? SIGN_POS : SIGN_NEG); 291 return TAG_Zero;
314 } 292 } else {
315 else 293 reg_copy(b, dest);
316 setsign(dest, signa); /* signa may differ from the sign of a. */ 294 if ((tagb == TW_Denormal) && (b->sigh & 0x80000000)) {
317 return TAG_Zero; 295 /* A pseudoDenormal, convert it. */
318 } 296 addexponent(dest, 1);
319 else 297 tagb = TAG_Valid;
320 { 298 } else if (tagb > TAG_Empty)
321 reg_copy(b, dest); 299 tagb = TAG_Special;
322 if ( (tagb == TW_Denormal) && (b->sigh & 0x80000000) ) 300 setsign(dest, signb); /* signb may differ from the sign of b. */
323 { 301 FPU_settagi(deststnr, tagb);
324 /* A pseudoDenormal, convert it. */ 302 return tagb;
325 addexponent(dest, 1); 303 }
326 tagb = TAG_Valid; 304 } else if (tagb == TAG_Zero) {
327 } 305 reg_copy(a, dest);
328 else if ( tagb > TAG_Empty ) 306 if ((taga == TW_Denormal) && (a->sigh & 0x80000000)) {
329 tagb = TAG_Special; 307 /* A pseudoDenormal */
330 setsign(dest, signb); /* signb may differ from the sign of b. */ 308 addexponent(dest, 1);
331 FPU_settagi(deststnr, tagb); 309 taga = TAG_Valid;
332 return tagb; 310 } else if (taga > TAG_Empty)
333 } 311 taga = TAG_Special;
334 } 312 setsign(dest, signa); /* signa may differ from the sign of a. */
335 else if (tagb == TAG_Zero) 313 FPU_settagi(deststnr, taga);
336 { 314 return taga;
337 reg_copy(a, dest); 315 } else if (taga == TW_Infinity) {
338 if ( (taga == TW_Denormal) && (a->sigh & 0x80000000) ) 316 if ((tagb != TW_Infinity) || (signa == signb)) {
339 { 317 FPU_copy_to_regi(a, TAG_Special, deststnr);
340 /* A pseudoDenormal */ 318 setsign(dest, signa); /* signa may differ from the sign of a. */
341 addexponent(dest, 1); 319 return taga;
342 taga = TAG_Valid; 320 }
343 } 321 /* Infinity-Infinity is undefined. */
344 else if ( taga > TAG_Empty ) 322 return arith_invalid(deststnr);
345 taga = TAG_Special; 323 } else if (tagb == TW_Infinity) {
346 setsign(dest, signa); /* signa may differ from the sign of a. */ 324 FPU_copy_to_regi(b, TAG_Special, deststnr);
347 FPU_settagi(deststnr, taga); 325 setsign(dest, signb); /* signb may differ from the sign of b. */
348 return taga; 326 return tagb;
349 }
350 else if (taga == TW_Infinity)
351 {
352 if ( (tagb != TW_Infinity) || (signa == signb) )
353 {
354 FPU_copy_to_regi(a, TAG_Special, deststnr);
355 setsign(dest, signa); /* signa may differ from the sign of a. */
356 return taga;
357 } 327 }
358 /* Infinity-Infinity is undefined. */
359 return arith_invalid(deststnr);
360 }
361 else if (tagb == TW_Infinity)
362 {
363 FPU_copy_to_regi(b, TAG_Special, deststnr);
364 setsign(dest, signb); /* signb may differ from the sign of b. */
365 return tagb;
366 }
367
368#ifdef PARANOID 328#ifdef PARANOID
369 EXCEPTION(EX_INTERNAL|0x101); 329 EXCEPTION(EX_INTERNAL | 0x101);
370#endif 330#endif
371 331
372 return FPU_Exception; 332 return FPU_Exception;
373} 333}
374
diff --git a/arch/x86/math-emu/reg_compare.c b/arch/x86/math-emu/reg_compare.c
index f37c5b5a35ad..ecce55fc2e2e 100644
--- a/arch/x86/math-emu/reg_compare.c
+++ b/arch/x86/math-emu/reg_compare.c
@@ -20,362 +20,331 @@
20#include "control_w.h" 20#include "control_w.h"
21#include "status_w.h" 21#include "status_w.h"
22 22
23
24static int compare(FPU_REG const *b, int tagb) 23static int compare(FPU_REG const *b, int tagb)
25{ 24{
26 int diff, exp0, expb; 25 int diff, exp0, expb;
27 u_char st0_tag; 26 u_char st0_tag;
28 FPU_REG *st0_ptr; 27 FPU_REG *st0_ptr;
29 FPU_REG x, y; 28 FPU_REG x, y;
30 u_char st0_sign, signb = getsign(b); 29 u_char st0_sign, signb = getsign(b);
31 30
32 st0_ptr = &st(0); 31 st0_ptr = &st(0);
33 st0_tag = FPU_gettag0(); 32 st0_tag = FPU_gettag0();
34 st0_sign = getsign(st0_ptr); 33 st0_sign = getsign(st0_ptr);
35 34
36 if ( tagb == TAG_Special ) 35 if (tagb == TAG_Special)
37 tagb = FPU_Special(b); 36 tagb = FPU_Special(b);
38 if ( st0_tag == TAG_Special ) 37 if (st0_tag == TAG_Special)
39 st0_tag = FPU_Special(st0_ptr); 38 st0_tag = FPU_Special(st0_ptr);
40 39
41 if ( ((st0_tag != TAG_Valid) && (st0_tag != TW_Denormal)) 40 if (((st0_tag != TAG_Valid) && (st0_tag != TW_Denormal))
42 || ((tagb != TAG_Valid) && (tagb != TW_Denormal)) ) 41 || ((tagb != TAG_Valid) && (tagb != TW_Denormal))) {
43 { 42 if (st0_tag == TAG_Zero) {
44 if ( st0_tag == TAG_Zero ) 43 if (tagb == TAG_Zero)
45 { 44 return COMP_A_eq_B;
46 if ( tagb == TAG_Zero ) return COMP_A_eq_B; 45 if (tagb == TAG_Valid)
47 if ( tagb == TAG_Valid ) 46 return ((signb ==
48 return ((signb == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B); 47 SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B);
49 if ( tagb == TW_Denormal ) 48 if (tagb == TW_Denormal)
50 return ((signb == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B) 49 return ((signb ==
51 | COMP_Denormal; 50 SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B)
52 } 51 | COMP_Denormal;
53 else if ( tagb == TAG_Zero ) 52 } else if (tagb == TAG_Zero) {
54 { 53 if (st0_tag == TAG_Valid)
55 if ( st0_tag == TAG_Valid ) 54 return ((st0_sign ==
56 return ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B); 55 SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B);
57 if ( st0_tag == TW_Denormal ) 56 if (st0_tag == TW_Denormal)
58 return ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B) 57 return ((st0_sign ==
59 | COMP_Denormal; 58 SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B)
59 | COMP_Denormal;
60 }
61
62 if (st0_tag == TW_Infinity) {
63 if ((tagb == TAG_Valid) || (tagb == TAG_Zero))
64 return ((st0_sign ==
65 SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B);
66 else if (tagb == TW_Denormal)
67 return ((st0_sign ==
68 SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B)
69 | COMP_Denormal;
70 else if (tagb == TW_Infinity) {
71 /* The 80486 book says that infinities can be equal! */
72 return (st0_sign == signb) ? COMP_A_eq_B :
73 ((st0_sign ==
74 SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B);
75 }
76 /* Fall through to the NaN code */
77 } else if (tagb == TW_Infinity) {
78 if ((st0_tag == TAG_Valid) || (st0_tag == TAG_Zero))
79 return ((signb ==
80 SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B);
81 if (st0_tag == TW_Denormal)
82 return ((signb ==
83 SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B)
84 | COMP_Denormal;
85 /* Fall through to the NaN code */
86 }
87
88 /* The only possibility now should be that one of the arguments
89 is a NaN */
90 if ((st0_tag == TW_NaN) || (tagb == TW_NaN)) {
91 int signalling = 0, unsupported = 0;
92 if (st0_tag == TW_NaN) {
93 signalling =
94 (st0_ptr->sigh & 0xc0000000) == 0x80000000;
95 unsupported = !((exponent(st0_ptr) == EXP_OVER)
96 && (st0_ptr->
97 sigh & 0x80000000));
98 }
99 if (tagb == TW_NaN) {
100 signalling |=
101 (b->sigh & 0xc0000000) == 0x80000000;
102 unsupported |= !((exponent(b) == EXP_OVER)
103 && (b->sigh & 0x80000000));
104 }
105 if (signalling || unsupported)
106 return COMP_No_Comp | COMP_SNaN | COMP_NaN;
107 else
108 /* Neither is a signaling NaN */
109 return COMP_No_Comp | COMP_NaN;
110 }
111
112 EXCEPTION(EX_Invalid);
60 } 113 }
61 114
62 if ( st0_tag == TW_Infinity ) 115 if (st0_sign != signb) {
63 { 116 return ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B)
64 if ( (tagb == TAG_Valid) || (tagb == TAG_Zero) ) 117 | (((st0_tag == TW_Denormal) || (tagb == TW_Denormal)) ?
65 return ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B); 118 COMP_Denormal : 0);
66 else if ( tagb == TW_Denormal )
67 return ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B)
68 | COMP_Denormal;
69 else if ( tagb == TW_Infinity )
70 {
71 /* The 80486 book says that infinities can be equal! */
72 return (st0_sign == signb) ? COMP_A_eq_B :
73 ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B);
74 }
75 /* Fall through to the NaN code */
76 }
77 else if ( tagb == TW_Infinity )
78 {
79 if ( (st0_tag == TAG_Valid) || (st0_tag == TAG_Zero) )
80 return ((signb == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B);
81 if ( st0_tag == TW_Denormal )
82 return ((signb == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B)
83 | COMP_Denormal;
84 /* Fall through to the NaN code */
85 } 119 }
86 120
87 /* The only possibility now should be that one of the arguments 121 if ((st0_tag == TW_Denormal) || (tagb == TW_Denormal)) {
88 is a NaN */ 122 FPU_to_exp16(st0_ptr, &x);
89 if ( (st0_tag == TW_NaN) || (tagb == TW_NaN) ) 123 FPU_to_exp16(b, &y);
90 { 124 st0_ptr = &x;
91 int signalling = 0, unsupported = 0; 125 b = &y;
92 if ( st0_tag == TW_NaN ) 126 exp0 = exponent16(st0_ptr);
93 { 127 expb = exponent16(b);
94 signalling = (st0_ptr->sigh & 0xc0000000) == 0x80000000; 128 } else {
95 unsupported = !((exponent(st0_ptr) == EXP_OVER) 129 exp0 = exponent(st0_ptr);
96 && (st0_ptr->sigh & 0x80000000)); 130 expb = exponent(b);
97 }
98 if ( tagb == TW_NaN )
99 {
100 signalling |= (b->sigh & 0xc0000000) == 0x80000000;
101 unsupported |= !((exponent(b) == EXP_OVER)
102 && (b->sigh & 0x80000000));
103 }
104 if ( signalling || unsupported )
105 return COMP_No_Comp | COMP_SNaN | COMP_NaN;
106 else
107 /* Neither is a signaling NaN */
108 return COMP_No_Comp | COMP_NaN;
109 } 131 }
110
111 EXCEPTION(EX_Invalid);
112 }
113
114 if (st0_sign != signb)
115 {
116 return ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B)
117 | ( ((st0_tag == TW_Denormal) || (tagb == TW_Denormal)) ?
118 COMP_Denormal : 0);
119 }
120
121 if ( (st0_tag == TW_Denormal) || (tagb == TW_Denormal) )
122 {
123 FPU_to_exp16(st0_ptr, &x);
124 FPU_to_exp16(b, &y);
125 st0_ptr = &x;
126 b = &y;
127 exp0 = exponent16(st0_ptr);
128 expb = exponent16(b);
129 }
130 else
131 {
132 exp0 = exponent(st0_ptr);
133 expb = exponent(b);
134 }
135 132
136#ifdef PARANOID 133#ifdef PARANOID
137 if (!(st0_ptr->sigh & 0x80000000)) EXCEPTION(EX_Invalid); 134 if (!(st0_ptr->sigh & 0x80000000))
138 if (!(b->sigh & 0x80000000)) EXCEPTION(EX_Invalid); 135 EXCEPTION(EX_Invalid);
136 if (!(b->sigh & 0x80000000))
137 EXCEPTION(EX_Invalid);
139#endif /* PARANOID */ 138#endif /* PARANOID */
140 139
141 diff = exp0 - expb; 140 diff = exp0 - expb;
142 if ( diff == 0 ) 141 if (diff == 0) {
143 { 142 diff = st0_ptr->sigh - b->sigh; /* Works only if ms bits are
144 diff = st0_ptr->sigh - b->sigh; /* Works only if ms bits are 143 identical */
145 identical */ 144 if (diff == 0) {
146 if ( diff == 0 ) 145 diff = st0_ptr->sigl > b->sigl;
147 { 146 if (diff == 0)
148 diff = st0_ptr->sigl > b->sigl; 147 diff = -(st0_ptr->sigl < b->sigl);
149 if ( diff == 0 ) 148 }
150 diff = -(st0_ptr->sigl < b->sigl);
151 } 149 }
152 }
153
154 if ( diff > 0 )
155 {
156 return ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B)
157 | ( ((st0_tag == TW_Denormal) || (tagb == TW_Denormal)) ?
158 COMP_Denormal : 0);
159 }
160 if ( diff < 0 )
161 {
162 return ((st0_sign == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B)
163 | ( ((st0_tag == TW_Denormal) || (tagb == TW_Denormal)) ?
164 COMP_Denormal : 0);
165 }
166
167 return COMP_A_eq_B
168 | ( ((st0_tag == TW_Denormal) || (tagb == TW_Denormal)) ?
169 COMP_Denormal : 0);
170 150
171} 151 if (diff > 0) {
152 return ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B)
153 | (((st0_tag == TW_Denormal) || (tagb == TW_Denormal)) ?
154 COMP_Denormal : 0);
155 }
156 if (diff < 0) {
157 return ((st0_sign == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B)
158 | (((st0_tag == TW_Denormal) || (tagb == TW_Denormal)) ?
159 COMP_Denormal : 0);
160 }
172 161
162 return COMP_A_eq_B
163 | (((st0_tag == TW_Denormal) || (tagb == TW_Denormal)) ?
164 COMP_Denormal : 0);
165
166}
173 167
174/* This function requires that st(0) is not empty */ 168/* This function requires that st(0) is not empty */
175int FPU_compare_st_data(FPU_REG const *loaded_data, u_char loaded_tag) 169int FPU_compare_st_data(FPU_REG const *loaded_data, u_char loaded_tag)
176{ 170{
177 int f = 0, c; 171 int f = 0, c;
178 172
179 c = compare(loaded_data, loaded_tag); 173 c = compare(loaded_data, loaded_tag);
180 174
181 if (c & COMP_NaN) 175 if (c & COMP_NaN) {
182 { 176 EXCEPTION(EX_Invalid);
183 EXCEPTION(EX_Invalid); 177 f = SW_C3 | SW_C2 | SW_C0;
184 f = SW_C3 | SW_C2 | SW_C0; 178 } else
185 } 179 switch (c & 7) {
186 else 180 case COMP_A_lt_B:
187 switch (c & 7) 181 f = SW_C0;
188 { 182 break;
189 case COMP_A_lt_B: 183 case COMP_A_eq_B:
190 f = SW_C0; 184 f = SW_C3;
191 break; 185 break;
192 case COMP_A_eq_B: 186 case COMP_A_gt_B:
193 f = SW_C3; 187 f = 0;
194 break; 188 break;
195 case COMP_A_gt_B: 189 case COMP_No_Comp:
196 f = 0; 190 f = SW_C3 | SW_C2 | SW_C0;
197 break; 191 break;
198 case COMP_No_Comp:
199 f = SW_C3 | SW_C2 | SW_C0;
200 break;
201#ifdef PARANOID 192#ifdef PARANOID
202 default: 193 default:
203 EXCEPTION(EX_INTERNAL|0x121); 194 EXCEPTION(EX_INTERNAL | 0x121);
204 f = SW_C3 | SW_C2 | SW_C0; 195 f = SW_C3 | SW_C2 | SW_C0;
205 break; 196 break;
206#endif /* PARANOID */ 197#endif /* PARANOID */
207 } 198 }
208 setcc(f); 199 setcc(f);
209 if (c & COMP_Denormal) 200 if (c & COMP_Denormal) {
210 { 201 return denormal_operand() < 0;
211 return denormal_operand() < 0; 202 }
212 } 203 return 0;
213 return 0;
214} 204}
215 205
216
217static int compare_st_st(int nr) 206static int compare_st_st(int nr)
218{ 207{
219 int f = 0, c; 208 int f = 0, c;
220 FPU_REG *st_ptr; 209 FPU_REG *st_ptr;
221 210
222 if ( !NOT_EMPTY(0) || !NOT_EMPTY(nr) ) 211 if (!NOT_EMPTY(0) || !NOT_EMPTY(nr)) {
223 { 212 setcc(SW_C3 | SW_C2 | SW_C0);
224 setcc(SW_C3 | SW_C2 | SW_C0); 213 /* Stack fault */
225 /* Stack fault */ 214 EXCEPTION(EX_StackUnder);
226 EXCEPTION(EX_StackUnder); 215 return !(control_word & CW_Invalid);
227 return !(control_word & CW_Invalid); 216 }
228 } 217
229 218 st_ptr = &st(nr);
230 st_ptr = &st(nr); 219 c = compare(st_ptr, FPU_gettagi(nr));
231 c = compare(st_ptr, FPU_gettagi(nr)); 220 if (c & COMP_NaN) {
232 if (c & COMP_NaN) 221 setcc(SW_C3 | SW_C2 | SW_C0);
233 { 222 EXCEPTION(EX_Invalid);
234 setcc(SW_C3 | SW_C2 | SW_C0); 223 return !(control_word & CW_Invalid);
235 EXCEPTION(EX_Invalid); 224 } else
236 return !(control_word & CW_Invalid); 225 switch (c & 7) {
237 } 226 case COMP_A_lt_B:
238 else 227 f = SW_C0;
239 switch (c & 7) 228 break;
240 { 229 case COMP_A_eq_B:
241 case COMP_A_lt_B: 230 f = SW_C3;
242 f = SW_C0; 231 break;
243 break; 232 case COMP_A_gt_B:
244 case COMP_A_eq_B: 233 f = 0;
245 f = SW_C3; 234 break;
246 break; 235 case COMP_No_Comp:
247 case COMP_A_gt_B: 236 f = SW_C3 | SW_C2 | SW_C0;
248 f = 0; 237 break;
249 break;
250 case COMP_No_Comp:
251 f = SW_C3 | SW_C2 | SW_C0;
252 break;
253#ifdef PARANOID 238#ifdef PARANOID
254 default: 239 default:
255 EXCEPTION(EX_INTERNAL|0x122); 240 EXCEPTION(EX_INTERNAL | 0x122);
256 f = SW_C3 | SW_C2 | SW_C0; 241 f = SW_C3 | SW_C2 | SW_C0;
257 break; 242 break;
258#endif /* PARANOID */ 243#endif /* PARANOID */
259 } 244 }
260 setcc(f); 245 setcc(f);
261 if (c & COMP_Denormal) 246 if (c & COMP_Denormal) {
262 { 247 return denormal_operand() < 0;
263 return denormal_operand() < 0; 248 }
264 } 249 return 0;
265 return 0;
266} 250}
267 251
268
269static int compare_u_st_st(int nr) 252static int compare_u_st_st(int nr)
270{ 253{
271 int f = 0, c; 254 int f = 0, c;
272 FPU_REG *st_ptr; 255 FPU_REG *st_ptr;
273 256
274 if ( !NOT_EMPTY(0) || !NOT_EMPTY(nr) ) 257 if (!NOT_EMPTY(0) || !NOT_EMPTY(nr)) {
275 { 258 setcc(SW_C3 | SW_C2 | SW_C0);
276 setcc(SW_C3 | SW_C2 | SW_C0); 259 /* Stack fault */
277 /* Stack fault */ 260 EXCEPTION(EX_StackUnder);
278 EXCEPTION(EX_StackUnder); 261 return !(control_word & CW_Invalid);
279 return !(control_word & CW_Invalid);
280 }
281
282 st_ptr = &st(nr);
283 c = compare(st_ptr, FPU_gettagi(nr));
284 if (c & COMP_NaN)
285 {
286 setcc(SW_C3 | SW_C2 | SW_C0);
287 if (c & COMP_SNaN) /* This is the only difference between
288 un-ordered and ordinary comparisons */
289 {
290 EXCEPTION(EX_Invalid);
291 return !(control_word & CW_Invalid);
292 } 262 }
293 return 0; 263
294 } 264 st_ptr = &st(nr);
295 else 265 c = compare(st_ptr, FPU_gettagi(nr));
296 switch (c & 7) 266 if (c & COMP_NaN) {
297 { 267 setcc(SW_C3 | SW_C2 | SW_C0);
298 case COMP_A_lt_B: 268 if (c & COMP_SNaN) { /* This is the only difference between
299 f = SW_C0; 269 un-ordered and ordinary comparisons */
300 break; 270 EXCEPTION(EX_Invalid);
301 case COMP_A_eq_B: 271 return !(control_word & CW_Invalid);
302 f = SW_C3; 272 }
303 break; 273 return 0;
304 case COMP_A_gt_B: 274 } else
305 f = 0; 275 switch (c & 7) {
306 break; 276 case COMP_A_lt_B:
307 case COMP_No_Comp: 277 f = SW_C0;
308 f = SW_C3 | SW_C2 | SW_C0; 278 break;
309 break; 279 case COMP_A_eq_B:
280 f = SW_C3;
281 break;
282 case COMP_A_gt_B:
283 f = 0;
284 break;
285 case COMP_No_Comp:
286 f = SW_C3 | SW_C2 | SW_C0;
287 break;
310#ifdef PARANOID 288#ifdef PARANOID
311 default: 289 default:
312 EXCEPTION(EX_INTERNAL|0x123); 290 EXCEPTION(EX_INTERNAL | 0x123);
313 f = SW_C3 | SW_C2 | SW_C0; 291 f = SW_C3 | SW_C2 | SW_C0;
314 break; 292 break;
315#endif /* PARANOID */ 293#endif /* PARANOID */
316 } 294 }
317 setcc(f); 295 setcc(f);
318 if (c & COMP_Denormal) 296 if (c & COMP_Denormal) {
319 { 297 return denormal_operand() < 0;
320 return denormal_operand() < 0; 298 }
321 } 299 return 0;
322 return 0;
323} 300}
324 301
325/*---------------------------------------------------------------------------*/ 302/*---------------------------------------------------------------------------*/
326 303
327void fcom_st(void) 304void fcom_st(void)
328{ 305{
329 /* fcom st(i) */ 306 /* fcom st(i) */
330 compare_st_st(FPU_rm); 307 compare_st_st(FPU_rm);
331} 308}
332 309
333
334void fcompst(void) 310void fcompst(void)
335{ 311{
336 /* fcomp st(i) */ 312 /* fcomp st(i) */
337 if ( !compare_st_st(FPU_rm) ) 313 if (!compare_st_st(FPU_rm))
338 FPU_pop(); 314 FPU_pop();
339} 315}
340 316
341
342void fcompp(void) 317void fcompp(void)
343{ 318{
344 /* fcompp */ 319 /* fcompp */
345 if (FPU_rm != 1) 320 if (FPU_rm != 1) {
346 { 321 FPU_illegal();
347 FPU_illegal(); 322 return;
348 return; 323 }
349 } 324 if (!compare_st_st(1))
350 if ( !compare_st_st(1) ) 325 poppop();
351 poppop();
352} 326}
353 327
354
355void fucom_(void) 328void fucom_(void)
356{ 329{
357 /* fucom st(i) */ 330 /* fucom st(i) */
358 compare_u_st_st(FPU_rm); 331 compare_u_st_st(FPU_rm);
359 332
360} 333}
361 334
362
363void fucomp(void) 335void fucomp(void)
364{ 336{
365 /* fucomp st(i) */ 337 /* fucomp st(i) */
366 if ( !compare_u_st_st(FPU_rm) ) 338 if (!compare_u_st_st(FPU_rm))
367 FPU_pop(); 339 FPU_pop();
368} 340}
369 341
370
371void fucompp(void) 342void fucompp(void)
372{ 343{
373 /* fucompp */ 344 /* fucompp */
374 if (FPU_rm == 1) 345 if (FPU_rm == 1) {
375 { 346 if (!compare_u_st_st(1))
376 if ( !compare_u_st_st(1) ) 347 poppop();
377 poppop(); 348 } else
378 } 349 FPU_illegal();
379 else
380 FPU_illegal();
381} 350}
diff --git a/arch/x86/math-emu/reg_constant.c b/arch/x86/math-emu/reg_constant.c
index a85015801969..04869e64b18e 100644
--- a/arch/x86/math-emu/reg_constant.c
+++ b/arch/x86/math-emu/reg_constant.c
@@ -16,29 +16,28 @@
16#include "reg_constant.h" 16#include "reg_constant.h"
17#include "control_w.h" 17#include "control_w.h"
18 18
19
20#define MAKE_REG(s,e,l,h) { l, h, \ 19#define MAKE_REG(s,e,l,h) { l, h, \
21 ((EXTENDED_Ebias+(e)) | ((SIGN_##s != 0)*0x8000)) } 20 ((EXTENDED_Ebias+(e)) | ((SIGN_##s != 0)*0x8000)) }
22 21
23FPU_REG const CONST_1 = MAKE_REG(POS, 0, 0x00000000, 0x80000000); 22FPU_REG const CONST_1 = MAKE_REG(POS, 0, 0x00000000, 0x80000000);
24#if 0 23#if 0
25FPU_REG const CONST_2 = MAKE_REG(POS, 1, 0x00000000, 0x80000000); 24FPU_REG const CONST_2 = MAKE_REG(POS, 1, 0x00000000, 0x80000000);
26FPU_REG const CONST_HALF = MAKE_REG(POS, -1, 0x00000000, 0x80000000); 25FPU_REG const CONST_HALF = MAKE_REG(POS, -1, 0x00000000, 0x80000000);
27#endif /* 0 */ 26#endif /* 0 */
28static FPU_REG const CONST_L2T = MAKE_REG(POS, 1, 0xcd1b8afe, 0xd49a784b); 27static FPU_REG const CONST_L2T = MAKE_REG(POS, 1, 0xcd1b8afe, 0xd49a784b);
29static FPU_REG const CONST_L2E = MAKE_REG(POS, 0, 0x5c17f0bc, 0xb8aa3b29); 28static FPU_REG const CONST_L2E = MAKE_REG(POS, 0, 0x5c17f0bc, 0xb8aa3b29);
30FPU_REG const CONST_PI = MAKE_REG(POS, 1, 0x2168c235, 0xc90fdaa2); 29FPU_REG const CONST_PI = MAKE_REG(POS, 1, 0x2168c235, 0xc90fdaa2);
31FPU_REG const CONST_PI2 = MAKE_REG(POS, 0, 0x2168c235, 0xc90fdaa2); 30FPU_REG const CONST_PI2 = MAKE_REG(POS, 0, 0x2168c235, 0xc90fdaa2);
32FPU_REG const CONST_PI4 = MAKE_REG(POS, -1, 0x2168c235, 0xc90fdaa2); 31FPU_REG const CONST_PI4 = MAKE_REG(POS, -1, 0x2168c235, 0xc90fdaa2);
33static FPU_REG const CONST_LG2 = MAKE_REG(POS, -2, 0xfbcff799, 0x9a209a84); 32static FPU_REG const CONST_LG2 = MAKE_REG(POS, -2, 0xfbcff799, 0x9a209a84);
34static FPU_REG const CONST_LN2 = MAKE_REG(POS, -1, 0xd1cf79ac, 0xb17217f7); 33static FPU_REG const CONST_LN2 = MAKE_REG(POS, -1, 0xd1cf79ac, 0xb17217f7);
35 34
36/* Extra bits to take pi/2 to more than 128 bits precision. */ 35/* Extra bits to take pi/2 to more than 128 bits precision. */
37FPU_REG const CONST_PI2extra = MAKE_REG(NEG, -66, 36FPU_REG const CONST_PI2extra = MAKE_REG(NEG, -66,
38 0xfc8f8cbb, 0xece675d1); 37 0xfc8f8cbb, 0xece675d1);
39 38
40/* Only the sign (and tag) is used in internal zeroes */ 39/* Only the sign (and tag) is used in internal zeroes */
41FPU_REG const CONST_Z = MAKE_REG(POS, EXP_UNDER, 0x0, 0x0); 40FPU_REG const CONST_Z = MAKE_REG(POS, EXP_UNDER, 0x0, 0x0);
42 41
43/* Only the sign and significand (and tag) are used in internal NaNs */ 42/* Only the sign and significand (and tag) are used in internal NaNs */
44/* The 80486 never generates one of these 43/* The 80486 never generates one of these
@@ -48,24 +47,22 @@ FPU_REG const CONST_SNAN = MAKE_REG(POS, EXP_OVER, 0x00000001, 0x80000000);
48FPU_REG const CONST_QNaN = MAKE_REG(NEG, EXP_OVER, 0x00000000, 0xC0000000); 47FPU_REG const CONST_QNaN = MAKE_REG(NEG, EXP_OVER, 0x00000000, 0xC0000000);
49 48
50/* Only the sign (and tag) is used in internal infinities */ 49/* Only the sign (and tag) is used in internal infinities */
51FPU_REG const CONST_INF = MAKE_REG(POS, EXP_OVER, 0x00000000, 0x80000000); 50FPU_REG const CONST_INF = MAKE_REG(POS, EXP_OVER, 0x00000000, 0x80000000);
52
53 51
54static void fld_const(FPU_REG const *c, int adj, u_char tag) 52static void fld_const(FPU_REG const *c, int adj, u_char tag)
55{ 53{
56 FPU_REG *st_new_ptr; 54 FPU_REG *st_new_ptr;
57 55
58 if ( STACK_OVERFLOW ) 56 if (STACK_OVERFLOW) {
59 { 57 FPU_stack_overflow();
60 FPU_stack_overflow(); 58 return;
61 return; 59 }
62 } 60 push();
63 push(); 61 reg_copy(c, st_new_ptr);
64 reg_copy(c, st_new_ptr); 62 st_new_ptr->sigl += adj; /* For all our fldxxx constants, we don't need to
65 st_new_ptr->sigl += adj; /* For all our fldxxx constants, we don't need to 63 borrow or carry. */
66 borrow or carry. */ 64 FPU_settag0(tag);
67 FPU_settag0(tag); 65 clear_C1();
68 clear_C1();
69} 66}
70 67
71/* A fast way to find out whether x is one of RC_DOWN or RC_CHOP 68/* A fast way to find out whether x is one of RC_DOWN or RC_CHOP
@@ -75,46 +72,46 @@ static void fld_const(FPU_REG const *c, int adj, u_char tag)
75 72
76static void fld1(int rc) 73static void fld1(int rc)
77{ 74{
78 fld_const(&CONST_1, 0, TAG_Valid); 75 fld_const(&CONST_1, 0, TAG_Valid);
79} 76}
80 77
81static void fldl2t(int rc) 78static void fldl2t(int rc)
82{ 79{
83 fld_const(&CONST_L2T, (rc == RC_UP) ? 1 : 0, TAG_Valid); 80 fld_const(&CONST_L2T, (rc == RC_UP) ? 1 : 0, TAG_Valid);
84} 81}
85 82
86static void fldl2e(int rc) 83static void fldl2e(int rc)
87{ 84{
88 fld_const(&CONST_L2E, DOWN_OR_CHOP(rc) ? -1 : 0, TAG_Valid); 85 fld_const(&CONST_L2E, DOWN_OR_CHOP(rc) ? -1 : 0, TAG_Valid);
89} 86}
90 87
91static void fldpi(int rc) 88static void fldpi(int rc)
92{ 89{
93 fld_const(&CONST_PI, DOWN_OR_CHOP(rc) ? -1 : 0, TAG_Valid); 90 fld_const(&CONST_PI, DOWN_OR_CHOP(rc) ? -1 : 0, TAG_Valid);
94} 91}
95 92
96static void fldlg2(int rc) 93static void fldlg2(int rc)
97{ 94{
98 fld_const(&CONST_LG2, DOWN_OR_CHOP(rc) ? -1 : 0, TAG_Valid); 95 fld_const(&CONST_LG2, DOWN_OR_CHOP(rc) ? -1 : 0, TAG_Valid);
99} 96}
100 97
101static void fldln2(int rc) 98static void fldln2(int rc)
102{ 99{
103 fld_const(&CONST_LN2, DOWN_OR_CHOP(rc) ? -1 : 0, TAG_Valid); 100 fld_const(&CONST_LN2, DOWN_OR_CHOP(rc) ? -1 : 0, TAG_Valid);
104} 101}
105 102
106static void fldz(int rc) 103static void fldz(int rc)
107{ 104{
108 fld_const(&CONST_Z, 0, TAG_Zero); 105 fld_const(&CONST_Z, 0, TAG_Zero);
109} 106}
110 107
111typedef void (*FUNC_RC)(int); 108typedef void (*FUNC_RC) (int);
112 109
113static FUNC_RC constants_table[] = { 110static FUNC_RC constants_table[] = {
114 fld1, fldl2t, fldl2e, fldpi, fldlg2, fldln2, fldz, (FUNC_RC)FPU_illegal 111 fld1, fldl2t, fldl2e, fldpi, fldlg2, fldln2, fldz, (FUNC_RC) FPU_illegal
115}; 112};
116 113
117void fconst(void) 114void fconst(void)
118{ 115{
119 (constants_table[FPU_rm])(control_word & CW_RC); 116 (constants_table[FPU_rm]) (control_word & CW_RC);
120} 117}
diff --git a/arch/x86/math-emu/reg_convert.c b/arch/x86/math-emu/reg_convert.c
index 45a258752703..108060779977 100644
--- a/arch/x86/math-emu/reg_convert.c
+++ b/arch/x86/math-emu/reg_convert.c
@@ -13,41 +13,34 @@
13#include "exception.h" 13#include "exception.h"
14#include "fpu_emu.h" 14#include "fpu_emu.h"
15 15
16
17int FPU_to_exp16(FPU_REG const *a, FPU_REG *x) 16int FPU_to_exp16(FPU_REG const *a, FPU_REG *x)
18{ 17{
19 int sign = getsign(a); 18 int sign = getsign(a);
20 19
21 *(long long *)&(x->sigl) = *(const long long *)&(a->sigl); 20 *(long long *)&(x->sigl) = *(const long long *)&(a->sigl);
22 21
23 /* Set up the exponent as a 16 bit quantity. */ 22 /* Set up the exponent as a 16 bit quantity. */
24 setexponent16(x, exponent(a)); 23 setexponent16(x, exponent(a));
25 24
26 if ( exponent16(x) == EXP_UNDER ) 25 if (exponent16(x) == EXP_UNDER) {
27 { 26 /* The number is a de-normal or pseudodenormal. */
28 /* The number is a de-normal or pseudodenormal. */ 27 /* We only deal with the significand and exponent. */
29 /* We only deal with the significand and exponent. */ 28
30 29 if (x->sigh & 0x80000000) {
31 if (x->sigh & 0x80000000) 30 /* Is a pseudodenormal. */
32 { 31 /* This is non-80486 behaviour because the number
33 /* Is a pseudodenormal. */ 32 loses its 'denormal' identity. */
34 /* This is non-80486 behaviour because the number 33 addexponent(x, 1);
35 loses its 'denormal' identity. */ 34 } else {
36 addexponent(x, 1); 35 /* Is a denormal. */
37 } 36 addexponent(x, 1);
38 else 37 FPU_normalize_nuo(x);
39 { 38 }
40 /* Is a denormal. */
41 addexponent(x, 1);
42 FPU_normalize_nuo(x);
43 } 39 }
44 }
45 40
46 if ( !(x->sigh & 0x80000000) ) 41 if (!(x->sigh & 0x80000000)) {
47 { 42 EXCEPTION(EX_INTERNAL | 0x180);
48 EXCEPTION(EX_INTERNAL | 0x180); 43 }
49 }
50 44
51 return sign; 45 return sign;
52} 46}
53
diff --git a/arch/x86/math-emu/reg_divide.c b/arch/x86/math-emu/reg_divide.c
index 5cee7ff920d9..6827012db341 100644
--- a/arch/x86/math-emu/reg_divide.c
+++ b/arch/x86/math-emu/reg_divide.c
@@ -26,182 +26,157 @@
26 */ 26 */
27int FPU_div(int flags, int rm, int control_w) 27int FPU_div(int flags, int rm, int control_w)
28{ 28{
29 FPU_REG x, y; 29 FPU_REG x, y;
30 FPU_REG const *a, *b, *st0_ptr, *st_ptr; 30 FPU_REG const *a, *b, *st0_ptr, *st_ptr;
31 FPU_REG *dest; 31 FPU_REG *dest;
32 u_char taga, tagb, signa, signb, sign, saved_sign; 32 u_char taga, tagb, signa, signb, sign, saved_sign;
33 int tag, deststnr; 33 int tag, deststnr;
34 34
35 if ( flags & DEST_RM ) 35 if (flags & DEST_RM)
36 deststnr = rm; 36 deststnr = rm;
37 else 37 else
38 deststnr = 0; 38 deststnr = 0;
39 39
40 if ( flags & REV ) 40 if (flags & REV) {
41 { 41 b = &st(0);
42 b = &st(0); 42 st0_ptr = b;
43 st0_ptr = b; 43 tagb = FPU_gettag0();
44 tagb = FPU_gettag0(); 44 if (flags & LOADED) {
45 if ( flags & LOADED ) 45 a = (FPU_REG *) rm;
46 { 46 taga = flags & 0x0f;
47 a = (FPU_REG *)rm; 47 } else {
48 taga = flags & 0x0f; 48 a = &st(rm);
49 st_ptr = a;
50 taga = FPU_gettagi(rm);
51 }
52 } else {
53 a = &st(0);
54 st0_ptr = a;
55 taga = FPU_gettag0();
56 if (flags & LOADED) {
57 b = (FPU_REG *) rm;
58 tagb = flags & 0x0f;
59 } else {
60 b = &st(rm);
61 st_ptr = b;
62 tagb = FPU_gettagi(rm);
63 }
49 } 64 }
50 else
51 {
52 a = &st(rm);
53 st_ptr = a;
54 taga = FPU_gettagi(rm);
55 }
56 }
57 else
58 {
59 a = &st(0);
60 st0_ptr = a;
61 taga = FPU_gettag0();
62 if ( flags & LOADED )
63 {
64 b = (FPU_REG *)rm;
65 tagb = flags & 0x0f;
66 }
67 else
68 {
69 b = &st(rm);
70 st_ptr = b;
71 tagb = FPU_gettagi(rm);
72 }
73 }
74 65
75 signa = getsign(a); 66 signa = getsign(a);
76 signb = getsign(b); 67 signb = getsign(b);
77 68
78 sign = signa ^ signb; 69 sign = signa ^ signb;
79 70
80 dest = &st(deststnr); 71 dest = &st(deststnr);
81 saved_sign = getsign(dest); 72 saved_sign = getsign(dest);
82 73
83 if ( !(taga | tagb) ) 74 if (!(taga | tagb)) {
84 { 75 /* Both regs Valid, this should be the most common case. */
85 /* Both regs Valid, this should be the most common case. */ 76 reg_copy(a, &x);
86 reg_copy(a, &x); 77 reg_copy(b, &y);
87 reg_copy(b, &y); 78 setpositive(&x);
88 setpositive(&x); 79 setpositive(&y);
89 setpositive(&y); 80 tag = FPU_u_div(&x, &y, dest, control_w, sign);
90 tag = FPU_u_div(&x, &y, dest, control_w, sign);
91 81
92 if ( tag < 0 ) 82 if (tag < 0)
93 return tag; 83 return tag;
94 84
95 FPU_settagi(deststnr, tag); 85 FPU_settagi(deststnr, tag);
96 return tag; 86 return tag;
97 } 87 }
98 88
99 if ( taga == TAG_Special ) 89 if (taga == TAG_Special)
100 taga = FPU_Special(a); 90 taga = FPU_Special(a);
101 if ( tagb == TAG_Special ) 91 if (tagb == TAG_Special)
102 tagb = FPU_Special(b); 92 tagb = FPU_Special(b);
103 93
104 if ( ((taga == TAG_Valid) && (tagb == TW_Denormal)) 94 if (((taga == TAG_Valid) && (tagb == TW_Denormal))
105 || ((taga == TW_Denormal) && (tagb == TAG_Valid)) 95 || ((taga == TW_Denormal) && (tagb == TAG_Valid))
106 || ((taga == TW_Denormal) && (tagb == TW_Denormal)) ) 96 || ((taga == TW_Denormal) && (tagb == TW_Denormal))) {
107 { 97 if (denormal_operand() < 0)
108 if ( denormal_operand() < 0 ) 98 return FPU_Exception;
109 return FPU_Exception; 99
110 100 FPU_to_exp16(a, &x);
111 FPU_to_exp16(a, &x); 101 FPU_to_exp16(b, &y);
112 FPU_to_exp16(b, &y); 102 tag = FPU_u_div(&x, &y, dest, control_w, sign);
113 tag = FPU_u_div(&x, &y, dest, control_w, sign); 103 if (tag < 0)
114 if ( tag < 0 ) 104 return tag;
115 return tag; 105
116 106 FPU_settagi(deststnr, tag);
117 FPU_settagi(deststnr, tag); 107 return tag;
118 return tag; 108 } else if ((taga <= TW_Denormal) && (tagb <= TW_Denormal)) {
119 } 109 if (tagb != TAG_Zero) {
120 else if ( (taga <= TW_Denormal) && (tagb <= TW_Denormal) ) 110 /* Want to find Zero/Valid */
121 { 111 if (tagb == TW_Denormal) {
122 if ( tagb != TAG_Zero ) 112 if (denormal_operand() < 0)
123 { 113 return FPU_Exception;
124 /* Want to find Zero/Valid */ 114 }
125 if ( tagb == TW_Denormal ) 115
126 { 116 /* The result is zero. */
127 if ( denormal_operand() < 0 ) 117 FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
128 return FPU_Exception; 118 setsign(dest, sign);
129 } 119 return TAG_Zero;
130 120 }
131 /* The result is zero. */ 121 /* We have an exception condition, either 0/0 or Valid/Zero. */
132 FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr); 122 if (taga == TAG_Zero) {
133 setsign(dest, sign); 123 /* 0/0 */
134 return TAG_Zero; 124 return arith_invalid(deststnr);
125 }
126 /* Valid/Zero */
127 return FPU_divide_by_zero(deststnr, sign);
135 } 128 }
136 /* We have an exception condition, either 0/0 or Valid/Zero. */ 129 /* Must have infinities, NaNs, etc */
137 if ( taga == TAG_Zero ) 130 else if ((taga == TW_NaN) || (tagb == TW_NaN)) {
138 { 131 if (flags & LOADED)
139 /* 0/0 */ 132 return real_2op_NaN((FPU_REG *) rm, flags & 0x0f, 0,
140 return arith_invalid(deststnr); 133 st0_ptr);
134
135 if (flags & DEST_RM) {
136 int tag;
137 tag = FPU_gettag0();
138 if (tag == TAG_Special)
139 tag = FPU_Special(st0_ptr);
140 return real_2op_NaN(st0_ptr, tag, rm,
141 (flags & REV) ? st0_ptr : &st(rm));
142 } else {
143 int tag;
144 tag = FPU_gettagi(rm);
145 if (tag == TAG_Special)
146 tag = FPU_Special(&st(rm));
147 return real_2op_NaN(&st(rm), tag, 0,
148 (flags & REV) ? st0_ptr : &st(rm));
149 }
150 } else if (taga == TW_Infinity) {
151 if (tagb == TW_Infinity) {
152 /* infinity/infinity */
153 return arith_invalid(deststnr);
154 } else {
155 /* tagb must be Valid or Zero */
156 if ((tagb == TW_Denormal) && (denormal_operand() < 0))
157 return FPU_Exception;
158
159 /* Infinity divided by Zero or Valid does
160 not raise and exception, but returns Infinity */
161 FPU_copy_to_regi(a, TAG_Special, deststnr);
162 setsign(dest, sign);
163 return taga;
164 }
165 } else if (tagb == TW_Infinity) {
166 if ((taga == TW_Denormal) && (denormal_operand() < 0))
167 return FPU_Exception;
168
169 /* The result is zero. */
170 FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
171 setsign(dest, sign);
172 return TAG_Zero;
141 } 173 }
142 /* Valid/Zero */
143 return FPU_divide_by_zero(deststnr, sign);
144 }
145 /* Must have infinities, NaNs, etc */
146 else if ( (taga == TW_NaN) || (tagb == TW_NaN) )
147 {
148 if ( flags & LOADED )
149 return real_2op_NaN((FPU_REG *)rm, flags & 0x0f, 0, st0_ptr);
150
151 if ( flags & DEST_RM )
152 {
153 int tag;
154 tag = FPU_gettag0();
155 if ( tag == TAG_Special )
156 tag = FPU_Special(st0_ptr);
157 return real_2op_NaN(st0_ptr, tag, rm, (flags & REV) ? st0_ptr : &st(rm));
158 }
159 else
160 {
161 int tag;
162 tag = FPU_gettagi(rm);
163 if ( tag == TAG_Special )
164 tag = FPU_Special(&st(rm));
165 return real_2op_NaN(&st(rm), tag, 0, (flags & REV) ? st0_ptr : &st(rm));
166 }
167 }
168 else if (taga == TW_Infinity)
169 {
170 if (tagb == TW_Infinity)
171 {
172 /* infinity/infinity */
173 return arith_invalid(deststnr);
174 }
175 else
176 {
177 /* tagb must be Valid or Zero */
178 if ( (tagb == TW_Denormal) && (denormal_operand() < 0) )
179 return FPU_Exception;
180
181 /* Infinity divided by Zero or Valid does
182 not raise and exception, but returns Infinity */
183 FPU_copy_to_regi(a, TAG_Special, deststnr);
184 setsign(dest, sign);
185 return taga;
186 }
187 }
188 else if (tagb == TW_Infinity)
189 {
190 if ( (taga == TW_Denormal) && (denormal_operand() < 0) )
191 return FPU_Exception;
192
193 /* The result is zero. */
194 FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
195 setsign(dest, sign);
196 return TAG_Zero;
197 }
198#ifdef PARANOID 174#ifdef PARANOID
199 else 175 else {
200 { 176 EXCEPTION(EX_INTERNAL | 0x102);
201 EXCEPTION(EX_INTERNAL|0x102); 177 return FPU_Exception;
202 return FPU_Exception; 178 }
203 } 179#endif /* PARANOID */
204#endif /* PARANOID */
205 180
206 return 0; 181 return 0;
207} 182}
diff --git a/arch/x86/math-emu/reg_ld_str.c b/arch/x86/math-emu/reg_ld_str.c
index e976caef6498..799d4af5be66 100644
--- a/arch/x86/math-emu/reg_ld_str.c
+++ b/arch/x86/math-emu/reg_ld_str.c
@@ -27,1084 +27,938 @@
27#include "control_w.h" 27#include "control_w.h"
28#include "status_w.h" 28#include "status_w.h"
29 29
30 30#define DOUBLE_Emax 1023 /* largest valid exponent */
31#define DOUBLE_Emax 1023 /* largest valid exponent */
32#define DOUBLE_Ebias 1023 31#define DOUBLE_Ebias 1023
33#define DOUBLE_Emin (-1022) /* smallest valid exponent */ 32#define DOUBLE_Emin (-1022) /* smallest valid exponent */
34 33
35#define SINGLE_Emax 127 /* largest valid exponent */ 34#define SINGLE_Emax 127 /* largest valid exponent */
36#define SINGLE_Ebias 127 35#define SINGLE_Ebias 127
37#define SINGLE_Emin (-126) /* smallest valid exponent */ 36#define SINGLE_Emin (-126) /* smallest valid exponent */
38
39 37
40static u_char normalize_no_excep(FPU_REG *r, int exp, int sign) 38static u_char normalize_no_excep(FPU_REG *r, int exp, int sign)
41{ 39{
42 u_char tag; 40 u_char tag;
43 41
44 setexponent16(r, exp); 42 setexponent16(r, exp);
45 43
46 tag = FPU_normalize_nuo(r); 44 tag = FPU_normalize_nuo(r);
47 stdexp(r); 45 stdexp(r);
48 if ( sign ) 46 if (sign)
49 setnegative(r); 47 setnegative(r);
50 48
51 return tag; 49 return tag;
52} 50}
53 51
54
55int FPU_tagof(FPU_REG *ptr) 52int FPU_tagof(FPU_REG *ptr)
56{ 53{
57 int exp; 54 int exp;
58 55
59 exp = exponent16(ptr) & 0x7fff; 56 exp = exponent16(ptr) & 0x7fff;
60 if ( exp == 0 ) 57 if (exp == 0) {
61 { 58 if (!(ptr->sigh | ptr->sigl)) {
62 if ( !(ptr->sigh | ptr->sigl) ) 59 return TAG_Zero;
63 { 60 }
64 return TAG_Zero; 61 /* The number is a de-normal or pseudodenormal. */
62 return TAG_Special;
63 }
64
65 if (exp == 0x7fff) {
66 /* Is an Infinity, a NaN, or an unsupported data type. */
67 return TAG_Special;
65 } 68 }
66 /* The number is a de-normal or pseudodenormal. */
67 return TAG_Special;
68 }
69
70 if ( exp == 0x7fff )
71 {
72 /* Is an Infinity, a NaN, or an unsupported data type. */
73 return TAG_Special;
74 }
75
76 if ( !(ptr->sigh & 0x80000000) )
77 {
78 /* Unsupported data type. */
79 /* Valid numbers have the ms bit set to 1. */
80 /* Unnormal. */
81 return TAG_Special;
82 }
83
84 return TAG_Valid;
85}
86 69
70 if (!(ptr->sigh & 0x80000000)) {
71 /* Unsupported data type. */
72 /* Valid numbers have the ms bit set to 1. */
73 /* Unnormal. */
74 return TAG_Special;
75 }
76
77 return TAG_Valid;
78}
87 79
88/* Get a long double from user memory */ 80/* Get a long double from user memory */
89int FPU_load_extended(long double __user *s, int stnr) 81int FPU_load_extended(long double __user *s, int stnr)
90{ 82{
91 FPU_REG *sti_ptr = &st(stnr); 83 FPU_REG *sti_ptr = &st(stnr);
92 84
93 RE_ENTRANT_CHECK_OFF; 85 RE_ENTRANT_CHECK_OFF;
94 FPU_access_ok(VERIFY_READ, s, 10); 86 FPU_access_ok(VERIFY_READ, s, 10);
95 __copy_from_user(sti_ptr, s, 10); 87 __copy_from_user(sti_ptr, s, 10);
96 RE_ENTRANT_CHECK_ON; 88 RE_ENTRANT_CHECK_ON;
97 89
98 return FPU_tagof(sti_ptr); 90 return FPU_tagof(sti_ptr);
99} 91}
100 92
101
102/* Get a double from user memory */ 93/* Get a double from user memory */
103int FPU_load_double(double __user *dfloat, FPU_REG *loaded_data) 94int FPU_load_double(double __user *dfloat, FPU_REG *loaded_data)
104{ 95{
105 int exp, tag, negative; 96 int exp, tag, negative;
106 unsigned m64, l64; 97 unsigned m64, l64;
107 98
108 RE_ENTRANT_CHECK_OFF; 99 RE_ENTRANT_CHECK_OFF;
109 FPU_access_ok(VERIFY_READ, dfloat, 8); 100 FPU_access_ok(VERIFY_READ, dfloat, 8);
110 FPU_get_user(m64, 1 + (unsigned long __user *) dfloat); 101 FPU_get_user(m64, 1 + (unsigned long __user *)dfloat);
111 FPU_get_user(l64, (unsigned long __user *) dfloat); 102 FPU_get_user(l64, (unsigned long __user *)dfloat);
112 RE_ENTRANT_CHECK_ON; 103 RE_ENTRANT_CHECK_ON;
113 104
114 negative = (m64 & 0x80000000) ? SIGN_Negative : SIGN_Positive; 105 negative = (m64 & 0x80000000) ? SIGN_Negative : SIGN_Positive;
115 exp = ((m64 & 0x7ff00000) >> 20) - DOUBLE_Ebias + EXTENDED_Ebias; 106 exp = ((m64 & 0x7ff00000) >> 20) - DOUBLE_Ebias + EXTENDED_Ebias;
116 m64 &= 0xfffff; 107 m64 &= 0xfffff;
117 if ( exp > DOUBLE_Emax + EXTENDED_Ebias ) 108 if (exp > DOUBLE_Emax + EXTENDED_Ebias) {
118 { 109 /* Infinity or NaN */
119 /* Infinity or NaN */ 110 if ((m64 == 0) && (l64 == 0)) {
120 if ((m64 == 0) && (l64 == 0)) 111 /* +- infinity */
121 { 112 loaded_data->sigh = 0x80000000;
122 /* +- infinity */ 113 loaded_data->sigl = 0x00000000;
123 loaded_data->sigh = 0x80000000; 114 exp = EXP_Infinity + EXTENDED_Ebias;
124 loaded_data->sigl = 0x00000000; 115 tag = TAG_Special;
125 exp = EXP_Infinity + EXTENDED_Ebias; 116 } else {
126 tag = TAG_Special; 117 /* Must be a signaling or quiet NaN */
127 } 118 exp = EXP_NaN + EXTENDED_Ebias;
128 else 119 loaded_data->sigh = (m64 << 11) | 0x80000000;
129 { 120 loaded_data->sigh |= l64 >> 21;
130 /* Must be a signaling or quiet NaN */ 121 loaded_data->sigl = l64 << 11;
131 exp = EXP_NaN + EXTENDED_Ebias; 122 tag = TAG_Special; /* The calling function must look for NaNs */
132 loaded_data->sigh = (m64 << 11) | 0x80000000; 123 }
133 loaded_data->sigh |= l64 >> 21; 124 } else if (exp < DOUBLE_Emin + EXTENDED_Ebias) {
134 loaded_data->sigl = l64 << 11; 125 /* Zero or de-normal */
135 tag = TAG_Special; /* The calling function must look for NaNs */ 126 if ((m64 == 0) && (l64 == 0)) {
136 } 127 /* Zero */
137 } 128 reg_copy(&CONST_Z, loaded_data);
138 else if ( exp < DOUBLE_Emin + EXTENDED_Ebias ) 129 exp = 0;
139 { 130 tag = TAG_Zero;
140 /* Zero or de-normal */ 131 } else {
141 if ((m64 == 0) && (l64 == 0)) 132 /* De-normal */
142 { 133 loaded_data->sigh = m64 << 11;
143 /* Zero */ 134 loaded_data->sigh |= l64 >> 21;
144 reg_copy(&CONST_Z, loaded_data); 135 loaded_data->sigl = l64 << 11;
145 exp = 0; 136
146 tag = TAG_Zero; 137 return normalize_no_excep(loaded_data, DOUBLE_Emin,
147 } 138 negative)
148 else 139 | (denormal_operand() < 0 ? FPU_Exception : 0);
149 { 140 }
150 /* De-normal */ 141 } else {
151 loaded_data->sigh = m64 << 11; 142 loaded_data->sigh = (m64 << 11) | 0x80000000;
152 loaded_data->sigh |= l64 >> 21; 143 loaded_data->sigh |= l64 >> 21;
153 loaded_data->sigl = l64 << 11; 144 loaded_data->sigl = l64 << 11;
154
155 return normalize_no_excep(loaded_data, DOUBLE_Emin, negative)
156 | (denormal_operand() < 0 ? FPU_Exception : 0);
157 }
158 }
159 else
160 {
161 loaded_data->sigh = (m64 << 11) | 0x80000000;
162 loaded_data->sigh |= l64 >> 21;
163 loaded_data->sigl = l64 << 11;
164 145
165 tag = TAG_Valid; 146 tag = TAG_Valid;
166 } 147 }
167 148
168 setexponent16(loaded_data, exp | negative); 149 setexponent16(loaded_data, exp | negative);
169 150
170 return tag; 151 return tag;
171} 152}
172 153
173
174/* Get a float from user memory */ 154/* Get a float from user memory */
175int FPU_load_single(float __user *single, FPU_REG *loaded_data) 155int FPU_load_single(float __user *single, FPU_REG *loaded_data)
176{ 156{
177 unsigned m32; 157 unsigned m32;
178 int exp, tag, negative; 158 int exp, tag, negative;
179 159
180 RE_ENTRANT_CHECK_OFF; 160 RE_ENTRANT_CHECK_OFF;
181 FPU_access_ok(VERIFY_READ, single, 4); 161 FPU_access_ok(VERIFY_READ, single, 4);
182 FPU_get_user(m32, (unsigned long __user *) single); 162 FPU_get_user(m32, (unsigned long __user *)single);
183 RE_ENTRANT_CHECK_ON; 163 RE_ENTRANT_CHECK_ON;
184 164
185 negative = (m32 & 0x80000000) ? SIGN_Negative : SIGN_Positive; 165 negative = (m32 & 0x80000000) ? SIGN_Negative : SIGN_Positive;
186 166
187 if (!(m32 & 0x7fffffff)) 167 if (!(m32 & 0x7fffffff)) {
188 { 168 /* Zero */
189 /* Zero */ 169 reg_copy(&CONST_Z, loaded_data);
190 reg_copy(&CONST_Z, loaded_data); 170 addexponent(loaded_data, negative);
191 addexponent(loaded_data, negative); 171 return TAG_Zero;
192 return TAG_Zero;
193 }
194 exp = ((m32 & 0x7f800000) >> 23) - SINGLE_Ebias + EXTENDED_Ebias;
195 m32 = (m32 & 0x7fffff) << 8;
196 if ( exp < SINGLE_Emin + EXTENDED_Ebias )
197 {
198 /* De-normals */
199 loaded_data->sigh = m32;
200 loaded_data->sigl = 0;
201
202 return normalize_no_excep(loaded_data, SINGLE_Emin, negative)
203 | (denormal_operand() < 0 ? FPU_Exception : 0);
204 }
205 else if ( exp > SINGLE_Emax + EXTENDED_Ebias )
206 {
207 /* Infinity or NaN */
208 if ( m32 == 0 )
209 {
210 /* +- infinity */
211 loaded_data->sigh = 0x80000000;
212 loaded_data->sigl = 0x00000000;
213 exp = EXP_Infinity + EXTENDED_Ebias;
214 tag = TAG_Special;
215 } 172 }
216 else 173 exp = ((m32 & 0x7f800000) >> 23) - SINGLE_Ebias + EXTENDED_Ebias;
217 { 174 m32 = (m32 & 0x7fffff) << 8;
218 /* Must be a signaling or quiet NaN */ 175 if (exp < SINGLE_Emin + EXTENDED_Ebias) {
219 exp = EXP_NaN + EXTENDED_Ebias; 176 /* De-normals */
220 loaded_data->sigh = m32 | 0x80000000; 177 loaded_data->sigh = m32;
221 loaded_data->sigl = 0; 178 loaded_data->sigl = 0;
222 tag = TAG_Special; /* The calling function must look for NaNs */ 179
180 return normalize_no_excep(loaded_data, SINGLE_Emin, negative)
181 | (denormal_operand() < 0 ? FPU_Exception : 0);
182 } else if (exp > SINGLE_Emax + EXTENDED_Ebias) {
183 /* Infinity or NaN */
184 if (m32 == 0) {
185 /* +- infinity */
186 loaded_data->sigh = 0x80000000;
187 loaded_data->sigl = 0x00000000;
188 exp = EXP_Infinity + EXTENDED_Ebias;
189 tag = TAG_Special;
190 } else {
191 /* Must be a signaling or quiet NaN */
192 exp = EXP_NaN + EXTENDED_Ebias;
193 loaded_data->sigh = m32 | 0x80000000;
194 loaded_data->sigl = 0;
195 tag = TAG_Special; /* The calling function must look for NaNs */
196 }
197 } else {
198 loaded_data->sigh = m32 | 0x80000000;
199 loaded_data->sigl = 0;
200 tag = TAG_Valid;
223 } 201 }
224 }
225 else
226 {
227 loaded_data->sigh = m32 | 0x80000000;
228 loaded_data->sigl = 0;
229 tag = TAG_Valid;
230 }
231 202
232 setexponent16(loaded_data, exp | negative); /* Set the sign. */ 203 setexponent16(loaded_data, exp | negative); /* Set the sign. */
233 204
234 return tag; 205 return tag;
235} 206}
236 207
237
238/* Get a long long from user memory */ 208/* Get a long long from user memory */
239int FPU_load_int64(long long __user *_s) 209int FPU_load_int64(long long __user *_s)
240{ 210{
241 long long s; 211 long long s;
242 int sign; 212 int sign;
243 FPU_REG *st0_ptr = &st(0); 213 FPU_REG *st0_ptr = &st(0);
244 214
245 RE_ENTRANT_CHECK_OFF; 215 RE_ENTRANT_CHECK_OFF;
246 FPU_access_ok(VERIFY_READ, _s, 8); 216 FPU_access_ok(VERIFY_READ, _s, 8);
247 if (copy_from_user(&s,_s,8)) 217 if (copy_from_user(&s, _s, 8))
248 FPU_abort; 218 FPU_abort;
249 RE_ENTRANT_CHECK_ON; 219 RE_ENTRANT_CHECK_ON;
250 220
251 if (s == 0) 221 if (s == 0) {
252 { 222 reg_copy(&CONST_Z, st0_ptr);
253 reg_copy(&CONST_Z, st0_ptr); 223 return TAG_Zero;
254 return TAG_Zero; 224 }
255 } 225
256 226 if (s > 0)
257 if (s > 0) 227 sign = SIGN_Positive;
258 sign = SIGN_Positive; 228 else {
259 else 229 s = -s;
260 { 230 sign = SIGN_Negative;
261 s = -s; 231 }
262 sign = SIGN_Negative;
263 }
264
265 significand(st0_ptr) = s;
266
267 return normalize_no_excep(st0_ptr, 63, sign);
268}
269 232
233 significand(st0_ptr) = s;
234
235 return normalize_no_excep(st0_ptr, 63, sign);
236}
270 237
271/* Get a long from user memory */ 238/* Get a long from user memory */
272int FPU_load_int32(long __user *_s, FPU_REG *loaded_data) 239int FPU_load_int32(long __user *_s, FPU_REG *loaded_data)
273{ 240{
274 long s; 241 long s;
275 int negative; 242 int negative;
276 243
277 RE_ENTRANT_CHECK_OFF; 244 RE_ENTRANT_CHECK_OFF;
278 FPU_access_ok(VERIFY_READ, _s, 4); 245 FPU_access_ok(VERIFY_READ, _s, 4);
279 FPU_get_user(s, _s); 246 FPU_get_user(s, _s);
280 RE_ENTRANT_CHECK_ON; 247 RE_ENTRANT_CHECK_ON;
281 248
282 if (s == 0) 249 if (s == 0) {
283 { reg_copy(&CONST_Z, loaded_data); return TAG_Zero; } 250 reg_copy(&CONST_Z, loaded_data);
251 return TAG_Zero;
252 }
284 253
285 if (s > 0) 254 if (s > 0)
286 negative = SIGN_Positive; 255 negative = SIGN_Positive;
287 else 256 else {
288 { 257 s = -s;
289 s = -s; 258 negative = SIGN_Negative;
290 negative = SIGN_Negative; 259 }
291 }
292 260
293 loaded_data->sigh = s; 261 loaded_data->sigh = s;
294 loaded_data->sigl = 0; 262 loaded_data->sigl = 0;
295 263
296 return normalize_no_excep(loaded_data, 31, negative); 264 return normalize_no_excep(loaded_data, 31, negative);
297} 265}
298 266
299
300/* Get a short from user memory */ 267/* Get a short from user memory */
301int FPU_load_int16(short __user *_s, FPU_REG *loaded_data) 268int FPU_load_int16(short __user *_s, FPU_REG *loaded_data)
302{ 269{
303 int s, negative; 270 int s, negative;
304 271
305 RE_ENTRANT_CHECK_OFF; 272 RE_ENTRANT_CHECK_OFF;
306 FPU_access_ok(VERIFY_READ, _s, 2); 273 FPU_access_ok(VERIFY_READ, _s, 2);
307 /* Cast as short to get the sign extended. */ 274 /* Cast as short to get the sign extended. */
308 FPU_get_user(s, _s); 275 FPU_get_user(s, _s);
309 RE_ENTRANT_CHECK_ON; 276 RE_ENTRANT_CHECK_ON;
310 277
311 if (s == 0) 278 if (s == 0) {
312 { reg_copy(&CONST_Z, loaded_data); return TAG_Zero; } 279 reg_copy(&CONST_Z, loaded_data);
280 return TAG_Zero;
281 }
313 282
314 if (s > 0) 283 if (s > 0)
315 negative = SIGN_Positive; 284 negative = SIGN_Positive;
316 else 285 else {
317 { 286 s = -s;
318 s = -s; 287 negative = SIGN_Negative;
319 negative = SIGN_Negative; 288 }
320 }
321 289
322 loaded_data->sigh = s << 16; 290 loaded_data->sigh = s << 16;
323 loaded_data->sigl = 0; 291 loaded_data->sigl = 0;
324 292
325 return normalize_no_excep(loaded_data, 15, negative); 293 return normalize_no_excep(loaded_data, 15, negative);
326} 294}
327 295
328
329/* Get a packed bcd array from user memory */ 296/* Get a packed bcd array from user memory */
330int FPU_load_bcd(u_char __user *s) 297int FPU_load_bcd(u_char __user *s)
331{ 298{
332 FPU_REG *st0_ptr = &st(0); 299 FPU_REG *st0_ptr = &st(0);
333 int pos; 300 int pos;
334 u_char bcd; 301 u_char bcd;
335 long long l=0; 302 long long l = 0;
336 int sign; 303 int sign;
337 304
338 RE_ENTRANT_CHECK_OFF; 305 RE_ENTRANT_CHECK_OFF;
339 FPU_access_ok(VERIFY_READ, s, 10); 306 FPU_access_ok(VERIFY_READ, s, 10);
340 RE_ENTRANT_CHECK_ON; 307 RE_ENTRANT_CHECK_ON;
341 for ( pos = 8; pos >= 0; pos--) 308 for (pos = 8; pos >= 0; pos--) {
342 { 309 l *= 10;
343 l *= 10; 310 RE_ENTRANT_CHECK_OFF;
344 RE_ENTRANT_CHECK_OFF; 311 FPU_get_user(bcd, s + pos);
345 FPU_get_user(bcd, s+pos); 312 RE_ENTRANT_CHECK_ON;
346 RE_ENTRANT_CHECK_ON; 313 l += bcd >> 4;
347 l += bcd >> 4; 314 l *= 10;
348 l *= 10; 315 l += bcd & 0x0f;
349 l += bcd & 0x0f; 316 }
350 } 317
351 318 RE_ENTRANT_CHECK_OFF;
352 RE_ENTRANT_CHECK_OFF; 319 FPU_get_user(sign, s + 9);
353 FPU_get_user(sign, s+9); 320 sign = sign & 0x80 ? SIGN_Negative : SIGN_Positive;
354 sign = sign & 0x80 ? SIGN_Negative : SIGN_Positive; 321 RE_ENTRANT_CHECK_ON;
355 RE_ENTRANT_CHECK_ON; 322
356 323 if (l == 0) {
357 if ( l == 0 ) 324 reg_copy(&CONST_Z, st0_ptr);
358 { 325 addexponent(st0_ptr, sign); /* Set the sign. */
359 reg_copy(&CONST_Z, st0_ptr); 326 return TAG_Zero;
360 addexponent(st0_ptr, sign); /* Set the sign. */ 327 } else {
361 return TAG_Zero; 328 significand(st0_ptr) = l;
362 } 329 return normalize_no_excep(st0_ptr, 63, sign);
363 else 330 }
364 {
365 significand(st0_ptr) = l;
366 return normalize_no_excep(st0_ptr, 63, sign);
367 }
368} 331}
369 332
370/*===========================================================================*/ 333/*===========================================================================*/
371 334
372/* Put a long double into user memory */ 335/* Put a long double into user memory */
373int FPU_store_extended(FPU_REG *st0_ptr, u_char st0_tag, long double __user *d) 336int FPU_store_extended(FPU_REG *st0_ptr, u_char st0_tag,
337 long double __user * d)
374{ 338{
375 /* 339 /*
376 The only exception raised by an attempt to store to an 340 The only exception raised by an attempt to store to an
377 extended format is the Invalid Stack exception, i.e. 341 extended format is the Invalid Stack exception, i.e.
378 attempting to store from an empty register. 342 attempting to store from an empty register.
379 */ 343 */
380 344
381 if ( st0_tag != TAG_Empty ) 345 if (st0_tag != TAG_Empty) {
382 { 346 RE_ENTRANT_CHECK_OFF;
383 RE_ENTRANT_CHECK_OFF; 347 FPU_access_ok(VERIFY_WRITE, d, 10);
384 FPU_access_ok(VERIFY_WRITE, d, 10); 348
385 349 FPU_put_user(st0_ptr->sigl, (unsigned long __user *)d);
386 FPU_put_user(st0_ptr->sigl, (unsigned long __user *) d); 350 FPU_put_user(st0_ptr->sigh,
387 FPU_put_user(st0_ptr->sigh, (unsigned long __user *) ((u_char __user *)d + 4)); 351 (unsigned long __user *)((u_char __user *) d + 4));
388 FPU_put_user(exponent16(st0_ptr), (unsigned short __user *) ((u_char __user *)d + 8)); 352 FPU_put_user(exponent16(st0_ptr),
389 RE_ENTRANT_CHECK_ON; 353 (unsigned short __user *)((u_char __user *) d +
390 354 8));
391 return 1; 355 RE_ENTRANT_CHECK_ON;
392 } 356
393 357 return 1;
394 /* Empty register (stack underflow) */ 358 }
395 EXCEPTION(EX_StackUnder);
396 if ( control_word & CW_Invalid )
397 {
398 /* The masked response */
399 /* Put out the QNaN indefinite */
400 RE_ENTRANT_CHECK_OFF;
401 FPU_access_ok(VERIFY_WRITE,d,10);
402 FPU_put_user(0, (unsigned long __user *) d);
403 FPU_put_user(0xc0000000, 1 + (unsigned long __user *) d);
404 FPU_put_user(0xffff, 4 + (short __user *) d);
405 RE_ENTRANT_CHECK_ON;
406 return 1;
407 }
408 else
409 return 0;
410 359
411} 360 /* Empty register (stack underflow) */
361 EXCEPTION(EX_StackUnder);
362 if (control_word & CW_Invalid) {
363 /* The masked response */
364 /* Put out the QNaN indefinite */
365 RE_ENTRANT_CHECK_OFF;
366 FPU_access_ok(VERIFY_WRITE, d, 10);
367 FPU_put_user(0, (unsigned long __user *)d);
368 FPU_put_user(0xc0000000, 1 + (unsigned long __user *)d);
369 FPU_put_user(0xffff, 4 + (short __user *)d);
370 RE_ENTRANT_CHECK_ON;
371 return 1;
372 } else
373 return 0;
412 374
375}
413 376
414/* Put a double into user memory */ 377/* Put a double into user memory */
415int FPU_store_double(FPU_REG *st0_ptr, u_char st0_tag, double __user *dfloat) 378int FPU_store_double(FPU_REG *st0_ptr, u_char st0_tag, double __user *dfloat)
416{ 379{
417 unsigned long l[2]; 380 unsigned long l[2];
418 unsigned long increment = 0; /* avoid gcc warnings */ 381 unsigned long increment = 0; /* avoid gcc warnings */
419 int precision_loss; 382 int precision_loss;
420 int exp; 383 int exp;
421 FPU_REG tmp; 384 FPU_REG tmp;
422 385
423 if ( st0_tag == TAG_Valid ) 386 if (st0_tag == TAG_Valid) {
424 { 387 reg_copy(st0_ptr, &tmp);
425 reg_copy(st0_ptr, &tmp); 388 exp = exponent(&tmp);
426 exp = exponent(&tmp);
427 389
428 if ( exp < DOUBLE_Emin ) /* It may be a denormal */ 390 if (exp < DOUBLE_Emin) { /* It may be a denormal */
429 { 391 addexponent(&tmp, -DOUBLE_Emin + 52); /* largest exp to be 51 */
430 addexponent(&tmp, -DOUBLE_Emin + 52); /* largest exp to be 51 */
431 392
432 denormal_arg: 393 denormal_arg:
433 394
434 if ( (precision_loss = FPU_round_to_int(&tmp, st0_tag)) ) 395 if ((precision_loss = FPU_round_to_int(&tmp, st0_tag))) {
435 {
436#ifdef PECULIAR_486 396#ifdef PECULIAR_486
437 /* Did it round to a non-denormal ? */ 397 /* Did it round to a non-denormal ? */
438 /* This behaviour might be regarded as peculiar, it appears 398 /* This behaviour might be regarded as peculiar, it appears
439 that the 80486 rounds to the dest precision, then 399 that the 80486 rounds to the dest precision, then
440 converts to decide underflow. */ 400 converts to decide underflow. */
441 if ( !((tmp.sigh == 0x00100000) && (tmp.sigl == 0) && 401 if (!
442 (st0_ptr->sigl & 0x000007ff)) ) 402 ((tmp.sigh == 0x00100000) && (tmp.sigl == 0)
403 && (st0_ptr->sigl & 0x000007ff)))
443#endif /* PECULIAR_486 */ 404#endif /* PECULIAR_486 */
444 { 405 {
445 EXCEPTION(EX_Underflow); 406 EXCEPTION(EX_Underflow);
446 /* This is a special case: see sec 16.2.5.1 of 407 /* This is a special case: see sec 16.2.5.1 of
447 the 80486 book */ 408 the 80486 book */
448 if ( !(control_word & CW_Underflow) ) 409 if (!(control_word & CW_Underflow))
449 return 0; 410 return 0;
450 } 411 }
451 EXCEPTION(precision_loss); 412 EXCEPTION(precision_loss);
452 if ( !(control_word & CW_Precision) ) 413 if (!(control_word & CW_Precision))
453 return 0; 414 return 0;
454 }
455 l[0] = tmp.sigl;
456 l[1] = tmp.sigh;
457 }
458 else
459 {
460 if ( tmp.sigl & 0x000007ff )
461 {
462 precision_loss = 1;
463 switch (control_word & CW_RC)
464 {
465 case RC_RND:
466 /* Rounding can get a little messy.. */
467 increment = ((tmp.sigl & 0x7ff) > 0x400) | /* nearest */
468 ((tmp.sigl & 0xc00) == 0xc00); /* odd -> even */
469 break;
470 case RC_DOWN: /* towards -infinity */
471 increment = signpositive(&tmp) ? 0 : tmp.sigl & 0x7ff;
472 break;
473 case RC_UP: /* towards +infinity */
474 increment = signpositive(&tmp) ? tmp.sigl & 0x7ff : 0;
475 break;
476 case RC_CHOP:
477 increment = 0;
478 break;
479 }
480
481 /* Truncate the mantissa */
482 tmp.sigl &= 0xfffff800;
483
484 if ( increment )
485 {
486 if ( tmp.sigl >= 0xfffff800 )
487 {
488 /* the sigl part overflows */
489 if ( tmp.sigh == 0xffffffff )
490 {
491 /* The sigh part overflows */
492 tmp.sigh = 0x80000000;
493 exp++;
494 if (exp >= EXP_OVER)
495 goto overflow;
496 } 415 }
497 else 416 l[0] = tmp.sigl;
498 { 417 l[1] = tmp.sigh;
499 tmp.sigh ++; 418 } else {
419 if (tmp.sigl & 0x000007ff) {
420 precision_loss = 1;
421 switch (control_word & CW_RC) {
422 case RC_RND:
423 /* Rounding can get a little messy.. */
424 increment = ((tmp.sigl & 0x7ff) > 0x400) | /* nearest */
425 ((tmp.sigl & 0xc00) == 0xc00); /* odd -> even */
426 break;
427 case RC_DOWN: /* towards -infinity */
428 increment =
429 signpositive(&tmp) ? 0 : tmp.
430 sigl & 0x7ff;
431 break;
432 case RC_UP: /* towards +infinity */
433 increment =
434 signpositive(&tmp) ? tmp.
435 sigl & 0x7ff : 0;
436 break;
437 case RC_CHOP:
438 increment = 0;
439 break;
440 }
441
442 /* Truncate the mantissa */
443 tmp.sigl &= 0xfffff800;
444
445 if (increment) {
446 if (tmp.sigl >= 0xfffff800) {
447 /* the sigl part overflows */
448 if (tmp.sigh == 0xffffffff) {
449 /* The sigh part overflows */
450 tmp.sigh = 0x80000000;
451 exp++;
452 if (exp >= EXP_OVER)
453 goto overflow;
454 } else {
455 tmp.sigh++;
456 }
457 tmp.sigl = 0x00000000;
458 } else {
459 /* We only need to increment sigl */
460 tmp.sigl += 0x00000800;
461 }
462 }
463 } else
464 precision_loss = 0;
465
466 l[0] = (tmp.sigl >> 11) | (tmp.sigh << 21);
467 l[1] = ((tmp.sigh >> 11) & 0xfffff);
468
469 if (exp > DOUBLE_Emax) {
470 overflow:
471 EXCEPTION(EX_Overflow);
472 if (!(control_word & CW_Overflow))
473 return 0;
474 set_precision_flag_up();
475 if (!(control_word & CW_Precision))
476 return 0;
477
478 /* This is a special case: see sec 16.2.5.1 of the 80486 book */
479 /* Overflow to infinity */
480 l[0] = 0x00000000; /* Set to */
481 l[1] = 0x7ff00000; /* + INF */
482 } else {
483 if (precision_loss) {
484 if (increment)
485 set_precision_flag_up();
486 else
487 set_precision_flag_down();
488 }
489 /* Add the exponent */
490 l[1] |= (((exp + DOUBLE_Ebias) & 0x7ff) << 20);
500 } 491 }
501 tmp.sigl = 0x00000000;
502 }
503 else
504 {
505 /* We only need to increment sigl */
506 tmp.sigl += 0x00000800;
507 }
508 }
509 }
510 else
511 precision_loss = 0;
512
513 l[0] = (tmp.sigl >> 11) | (tmp.sigh << 21);
514 l[1] = ((tmp.sigh >> 11) & 0xfffff);
515
516 if ( exp > DOUBLE_Emax )
517 {
518 overflow:
519 EXCEPTION(EX_Overflow);
520 if ( !(control_word & CW_Overflow) )
521 return 0;
522 set_precision_flag_up();
523 if ( !(control_word & CW_Precision) )
524 return 0;
525
526 /* This is a special case: see sec 16.2.5.1 of the 80486 book */
527 /* Overflow to infinity */
528 l[0] = 0x00000000; /* Set to */
529 l[1] = 0x7ff00000; /* + INF */
530 }
531 else
532 {
533 if ( precision_loss )
534 {
535 if ( increment )
536 set_precision_flag_up();
537 else
538 set_precision_flag_down();
539 } 492 }
540 /* Add the exponent */ 493 } else if (st0_tag == TAG_Zero) {
541 l[1] |= (((exp+DOUBLE_Ebias) & 0x7ff) << 20); 494 /* Number is zero */
542 } 495 l[0] = 0;
543 } 496 l[1] = 0;
544 } 497 } else if (st0_tag == TAG_Special) {
545 else if (st0_tag == TAG_Zero) 498 st0_tag = FPU_Special(st0_ptr);
546 { 499 if (st0_tag == TW_Denormal) {
547 /* Number is zero */ 500 /* A denormal will always underflow. */
548 l[0] = 0;
549 l[1] = 0;
550 }
551 else if ( st0_tag == TAG_Special )
552 {
553 st0_tag = FPU_Special(st0_ptr);
554 if ( st0_tag == TW_Denormal )
555 {
556 /* A denormal will always underflow. */
557#ifndef PECULIAR_486 501#ifndef PECULIAR_486
558 /* An 80486 is supposed to be able to generate 502 /* An 80486 is supposed to be able to generate
559 a denormal exception here, but... */ 503 a denormal exception here, but... */
560 /* Underflow has priority. */ 504 /* Underflow has priority. */
561 if ( control_word & CW_Underflow ) 505 if (control_word & CW_Underflow)
562 denormal_operand(); 506 denormal_operand();
563#endif /* PECULIAR_486 */ 507#endif /* PECULIAR_486 */
564 reg_copy(st0_ptr, &tmp); 508 reg_copy(st0_ptr, &tmp);
565 goto denormal_arg; 509 goto denormal_arg;
566 } 510 } else if (st0_tag == TW_Infinity) {
567 else if (st0_tag == TW_Infinity) 511 l[0] = 0;
568 { 512 l[1] = 0x7ff00000;
569 l[0] = 0; 513 } else if (st0_tag == TW_NaN) {
570 l[1] = 0x7ff00000; 514 /* Is it really a NaN ? */
571 } 515 if ((exponent(st0_ptr) == EXP_OVER)
572 else if (st0_tag == TW_NaN) 516 && (st0_ptr->sigh & 0x80000000)) {
573 { 517 /* See if we can get a valid NaN from the FPU_REG */
574 /* Is it really a NaN ? */ 518 l[0] =
575 if ( (exponent(st0_ptr) == EXP_OVER) 519 (st0_ptr->sigl >> 11) | (st0_ptr->
576 && (st0_ptr->sigh & 0x80000000) ) 520 sigh << 21);
577 { 521 l[1] = ((st0_ptr->sigh >> 11) & 0xfffff);
578 /* See if we can get a valid NaN from the FPU_REG */ 522 if (!(st0_ptr->sigh & 0x40000000)) {
579 l[0] = (st0_ptr->sigl >> 11) | (st0_ptr->sigh << 21); 523 /* It is a signalling NaN */
580 l[1] = ((st0_ptr->sigh >> 11) & 0xfffff); 524 EXCEPTION(EX_Invalid);
581 if ( !(st0_ptr->sigh & 0x40000000) ) 525 if (!(control_word & CW_Invalid))
582 { 526 return 0;
583 /* It is a signalling NaN */ 527 l[1] |= (0x40000000 >> 11);
584 EXCEPTION(EX_Invalid); 528 }
585 if ( !(control_word & CW_Invalid) ) 529 l[1] |= 0x7ff00000;
586 return 0; 530 } else {
587 l[1] |= (0x40000000 >> 11); 531 /* It is an unsupported data type */
532 EXCEPTION(EX_Invalid);
533 if (!(control_word & CW_Invalid))
534 return 0;
535 l[0] = 0;
536 l[1] = 0xfff80000;
537 }
588 } 538 }
589 l[1] |= 0x7ff00000; 539 } else if (st0_tag == TAG_Empty) {
590 } 540 /* Empty register (stack underflow) */
591 else 541 EXCEPTION(EX_StackUnder);
592 { 542 if (control_word & CW_Invalid) {
593 /* It is an unsupported data type */ 543 /* The masked response */
594 EXCEPTION(EX_Invalid); 544 /* Put out the QNaN indefinite */
595 if ( !(control_word & CW_Invalid) ) 545 RE_ENTRANT_CHECK_OFF;
596 return 0; 546 FPU_access_ok(VERIFY_WRITE, dfloat, 8);
597 l[0] = 0; 547 FPU_put_user(0, (unsigned long __user *)dfloat);
598 l[1] = 0xfff80000; 548 FPU_put_user(0xfff80000,
599 } 549 1 + (unsigned long __user *)dfloat);
550 RE_ENTRANT_CHECK_ON;
551 return 1;
552 } else
553 return 0;
600 } 554 }
601 } 555 if (getsign(st0_ptr))
602 else if ( st0_tag == TAG_Empty ) 556 l[1] |= 0x80000000;
603 {
604 /* Empty register (stack underflow) */
605 EXCEPTION(EX_StackUnder);
606 if ( control_word & CW_Invalid )
607 {
608 /* The masked response */
609 /* Put out the QNaN indefinite */
610 RE_ENTRANT_CHECK_OFF;
611 FPU_access_ok(VERIFY_WRITE,dfloat,8);
612 FPU_put_user(0, (unsigned long __user *) dfloat);
613 FPU_put_user(0xfff80000, 1 + (unsigned long __user *) dfloat);
614 RE_ENTRANT_CHECK_ON;
615 return 1;
616 }
617 else
618 return 0;
619 }
620 if ( getsign(st0_ptr) )
621 l[1] |= 0x80000000;
622
623 RE_ENTRANT_CHECK_OFF;
624 FPU_access_ok(VERIFY_WRITE,dfloat,8);
625 FPU_put_user(l[0], (unsigned long __user *)dfloat);
626 FPU_put_user(l[1], 1 + (unsigned long __user *)dfloat);
627 RE_ENTRANT_CHECK_ON;
628
629 return 1;
630}
631 557
558 RE_ENTRANT_CHECK_OFF;
559 FPU_access_ok(VERIFY_WRITE, dfloat, 8);
560 FPU_put_user(l[0], (unsigned long __user *)dfloat);
561 FPU_put_user(l[1], 1 + (unsigned long __user *)dfloat);
562 RE_ENTRANT_CHECK_ON;
563
564 return 1;
565}
632 566
633/* Put a float into user memory */ 567/* Put a float into user memory */
634int FPU_store_single(FPU_REG *st0_ptr, u_char st0_tag, float __user *single) 568int FPU_store_single(FPU_REG *st0_ptr, u_char st0_tag, float __user *single)
635{ 569{
636 long templ = 0; 570 long templ = 0;
637 unsigned long increment = 0; /* avoid gcc warnings */ 571 unsigned long increment = 0; /* avoid gcc warnings */
638 int precision_loss; 572 int precision_loss;
639 int exp; 573 int exp;
640 FPU_REG tmp; 574 FPU_REG tmp;
641 575
642 if ( st0_tag == TAG_Valid ) 576 if (st0_tag == TAG_Valid) {
643 {
644 577
645 reg_copy(st0_ptr, &tmp); 578 reg_copy(st0_ptr, &tmp);
646 exp = exponent(&tmp); 579 exp = exponent(&tmp);
647 580
648 if ( exp < SINGLE_Emin ) 581 if (exp < SINGLE_Emin) {
649 { 582 addexponent(&tmp, -SINGLE_Emin + 23); /* largest exp to be 22 */
650 addexponent(&tmp, -SINGLE_Emin + 23); /* largest exp to be 22 */
651 583
652 denormal_arg: 584 denormal_arg:
653 585
654 if ( (precision_loss = FPU_round_to_int(&tmp, st0_tag)) ) 586 if ((precision_loss = FPU_round_to_int(&tmp, st0_tag))) {
655 {
656#ifdef PECULIAR_486 587#ifdef PECULIAR_486
657 /* Did it round to a non-denormal ? */ 588 /* Did it round to a non-denormal ? */
658 /* This behaviour might be regarded as peculiar, it appears 589 /* This behaviour might be regarded as peculiar, it appears
659 that the 80486 rounds to the dest precision, then 590 that the 80486 rounds to the dest precision, then
660 converts to decide underflow. */ 591 converts to decide underflow. */
661 if ( !((tmp.sigl == 0x00800000) && 592 if (!((tmp.sigl == 0x00800000) &&
662 ((st0_ptr->sigh & 0x000000ff) || st0_ptr->sigl)) ) 593 ((st0_ptr->sigh & 0x000000ff)
594 || st0_ptr->sigl)))
663#endif /* PECULIAR_486 */ 595#endif /* PECULIAR_486 */
664 { 596 {
665 EXCEPTION(EX_Underflow); 597 EXCEPTION(EX_Underflow);
666 /* This is a special case: see sec 16.2.5.1 of 598 /* This is a special case: see sec 16.2.5.1 of
667 the 80486 book */ 599 the 80486 book */
668 if ( !(control_word & CW_Underflow) ) 600 if (!(control_word & CW_Underflow))
669 return 0; 601 return 0;
670 } 602 }
671 EXCEPTION(precision_loss); 603 EXCEPTION(precision_loss);
672 if ( !(control_word & CW_Precision) ) 604 if (!(control_word & CW_Precision))
673 return 0; 605 return 0;
674 } 606 }
675 templ = tmp.sigl; 607 templ = tmp.sigl;
676 } 608 } else {
677 else 609 if (tmp.sigl | (tmp.sigh & 0x000000ff)) {
678 { 610 unsigned long sigh = tmp.sigh;
679 if ( tmp.sigl | (tmp.sigh & 0x000000ff) ) 611 unsigned long sigl = tmp.sigl;
680 { 612
681 unsigned long sigh = tmp.sigh; 613 precision_loss = 1;
682 unsigned long sigl = tmp.sigl; 614 switch (control_word & CW_RC) {
683 615 case RC_RND:
684 precision_loss = 1; 616 increment = ((sigh & 0xff) > 0x80) /* more than half */
685 switch (control_word & CW_RC) 617 ||(((sigh & 0xff) == 0x80) && sigl) /* more than half */
686 { 618 ||((sigh & 0x180) == 0x180); /* round to even */
687 case RC_RND: 619 break;
688 increment = ((sigh & 0xff) > 0x80) /* more than half */ 620 case RC_DOWN: /* towards -infinity */
689 || (((sigh & 0xff) == 0x80) && sigl) /* more than half */ 621 increment = signpositive(&tmp)
690 || ((sigh & 0x180) == 0x180); /* round to even */ 622 ? 0 : (sigl | (sigh & 0xff));
691 break; 623 break;
692 case RC_DOWN: /* towards -infinity */ 624 case RC_UP: /* towards +infinity */
693 increment = signpositive(&tmp) 625 increment = signpositive(&tmp)
694 ? 0 : (sigl | (sigh & 0xff)); 626 ? (sigl | (sigh & 0xff)) : 0;
695 break; 627 break;
696 case RC_UP: /* towards +infinity */ 628 case RC_CHOP:
697 increment = signpositive(&tmp) 629 increment = 0;
698 ? (sigl | (sigh & 0xff)) : 0; 630 break;
699 break; 631 }
700 case RC_CHOP: 632
701 increment = 0; 633 /* Truncate part of the mantissa */
702 break; 634 tmp.sigl = 0;
703 } 635
704 636 if (increment) {
705 /* Truncate part of the mantissa */ 637 if (sigh >= 0xffffff00) {
706 tmp.sigl = 0; 638 /* The sigh part overflows */
707 639 tmp.sigh = 0x80000000;
708 if (increment) 640 exp++;
709 { 641 if (exp >= EXP_OVER)
710 if ( sigh >= 0xffffff00 ) 642 goto overflow;
711 { 643 } else {
712 /* The sigh part overflows */ 644 tmp.sigh &= 0xffffff00;
713 tmp.sigh = 0x80000000; 645 tmp.sigh += 0x100;
714 exp++; 646 }
715 if ( exp >= EXP_OVER ) 647 } else {
716 goto overflow; 648 tmp.sigh &= 0xffffff00; /* Finish the truncation */
717 } 649 }
718 else 650 } else
719 { 651 precision_loss = 0;
720 tmp.sigh &= 0xffffff00; 652
721 tmp.sigh += 0x100; 653 templ = (tmp.sigh >> 8) & 0x007fffff;
722 } 654
723 } 655 if (exp > SINGLE_Emax) {
724 else 656 overflow:
725 { 657 EXCEPTION(EX_Overflow);
726 tmp.sigh &= 0xffffff00; /* Finish the truncation */ 658 if (!(control_word & CW_Overflow))
727 } 659 return 0;
728 } 660 set_precision_flag_up();
729 else 661 if (!(control_word & CW_Precision))
730 precision_loss = 0; 662 return 0;
731 663
732 templ = (tmp.sigh >> 8) & 0x007fffff; 664 /* This is a special case: see sec 16.2.5.1 of the 80486 book. */
733 665 /* Masked response is overflow to infinity. */
734 if ( exp > SINGLE_Emax ) 666 templ = 0x7f800000;
735 { 667 } else {
736 overflow: 668 if (precision_loss) {
737 EXCEPTION(EX_Overflow); 669 if (increment)
738 if ( !(control_word & CW_Overflow) ) 670 set_precision_flag_up();
739 return 0; 671 else
740 set_precision_flag_up(); 672 set_precision_flag_down();
741 if ( !(control_word & CW_Precision) ) 673 }
742 return 0; 674 /* Add the exponent */
743 675 templ |= ((exp + SINGLE_Ebias) & 0xff) << 23;
744 /* This is a special case: see sec 16.2.5.1 of the 80486 book. */ 676 }
745 /* Masked response is overflow to infinity. */
746 templ = 0x7f800000;
747 }
748 else
749 {
750 if ( precision_loss )
751 {
752 if ( increment )
753 set_precision_flag_up();
754 else
755 set_precision_flag_down();
756 } 677 }
757 /* Add the exponent */ 678 } else if (st0_tag == TAG_Zero) {
758 templ |= ((exp+SINGLE_Ebias) & 0xff) << 23; 679 templ = 0;
759 } 680 } else if (st0_tag == TAG_Special) {
760 } 681 st0_tag = FPU_Special(st0_ptr);
761 } 682 if (st0_tag == TW_Denormal) {
762 else if (st0_tag == TAG_Zero) 683 reg_copy(st0_ptr, &tmp);
763 { 684
764 templ = 0; 685 /* A denormal will always underflow. */
765 }
766 else if ( st0_tag == TAG_Special )
767 {
768 st0_tag = FPU_Special(st0_ptr);
769 if (st0_tag == TW_Denormal)
770 {
771 reg_copy(st0_ptr, &tmp);
772
773 /* A denormal will always underflow. */
774#ifndef PECULIAR_486 686#ifndef PECULIAR_486
775 /* An 80486 is supposed to be able to generate 687 /* An 80486 is supposed to be able to generate
776 a denormal exception here, but... */ 688 a denormal exception here, but... */
777 /* Underflow has priority. */ 689 /* Underflow has priority. */
778 if ( control_word & CW_Underflow ) 690 if (control_word & CW_Underflow)
779 denormal_operand(); 691 denormal_operand();
780#endif /* PECULIAR_486 */ 692#endif /* PECULIAR_486 */
781 goto denormal_arg; 693 goto denormal_arg;
782 } 694 } else if (st0_tag == TW_Infinity) {
783 else if (st0_tag == TW_Infinity) 695 templ = 0x7f800000;
784 { 696 } else if (st0_tag == TW_NaN) {
785 templ = 0x7f800000; 697 /* Is it really a NaN ? */
786 } 698 if ((exponent(st0_ptr) == EXP_OVER)
787 else if (st0_tag == TW_NaN) 699 && (st0_ptr->sigh & 0x80000000)) {
788 { 700 /* See if we can get a valid NaN from the FPU_REG */
789 /* Is it really a NaN ? */ 701 templ = st0_ptr->sigh >> 8;
790 if ( (exponent(st0_ptr) == EXP_OVER) && (st0_ptr->sigh & 0x80000000) ) 702 if (!(st0_ptr->sigh & 0x40000000)) {
791 { 703 /* It is a signalling NaN */
792 /* See if we can get a valid NaN from the FPU_REG */ 704 EXCEPTION(EX_Invalid);
793 templ = st0_ptr->sigh >> 8; 705 if (!(control_word & CW_Invalid))
794 if ( !(st0_ptr->sigh & 0x40000000) ) 706 return 0;
795 { 707 templ |= (0x40000000 >> 8);
796 /* It is a signalling NaN */ 708 }
797 EXCEPTION(EX_Invalid); 709 templ |= 0x7f800000;
798 if ( !(control_word & CW_Invalid) ) 710 } else {
799 return 0; 711 /* It is an unsupported data type */
800 templ |= (0x40000000 >> 8); 712 EXCEPTION(EX_Invalid);
713 if (!(control_word & CW_Invalid))
714 return 0;
715 templ = 0xffc00000;
716 }
801 } 717 }
802 templ |= 0x7f800000;
803 }
804 else
805 {
806 /* It is an unsupported data type */
807 EXCEPTION(EX_Invalid);
808 if ( !(control_word & CW_Invalid) )
809 return 0;
810 templ = 0xffc00000;
811 }
812 }
813#ifdef PARANOID 718#ifdef PARANOID
814 else 719 else {
815 { 720 EXCEPTION(EX_INTERNAL | 0x164);
816 EXCEPTION(EX_INTERNAL|0x164); 721 return 0;
817 return 0; 722 }
818 }
819#endif 723#endif
820 } 724 } else if (st0_tag == TAG_Empty) {
821 else if ( st0_tag == TAG_Empty ) 725 /* Empty register (stack underflow) */
822 { 726 EXCEPTION(EX_StackUnder);
823 /* Empty register (stack underflow) */ 727 if (control_word & EX_Invalid) {
824 EXCEPTION(EX_StackUnder); 728 /* The masked response */
825 if ( control_word & EX_Invalid ) 729 /* Put out the QNaN indefinite */
826 { 730 RE_ENTRANT_CHECK_OFF;
827 /* The masked response */ 731 FPU_access_ok(VERIFY_WRITE, single, 4);
828 /* Put out the QNaN indefinite */ 732 FPU_put_user(0xffc00000,
829 RE_ENTRANT_CHECK_OFF; 733 (unsigned long __user *)single);
830 FPU_access_ok(VERIFY_WRITE,single,4); 734 RE_ENTRANT_CHECK_ON;
831 FPU_put_user(0xffc00000, (unsigned long __user *) single); 735 return 1;
832 RE_ENTRANT_CHECK_ON; 736 } else
833 return 1; 737 return 0;
834 } 738 }
835 else
836 return 0;
837 }
838#ifdef PARANOID 739#ifdef PARANOID
839 else 740 else {
840 { 741 EXCEPTION(EX_INTERNAL | 0x163);
841 EXCEPTION(EX_INTERNAL|0x163); 742 return 0;
842 return 0; 743 }
843 }
844#endif 744#endif
845 if ( getsign(st0_ptr) ) 745 if (getsign(st0_ptr))
846 templ |= 0x80000000; 746 templ |= 0x80000000;
847 747
848 RE_ENTRANT_CHECK_OFF; 748 RE_ENTRANT_CHECK_OFF;
849 FPU_access_ok(VERIFY_WRITE,single,4); 749 FPU_access_ok(VERIFY_WRITE, single, 4);
850 FPU_put_user(templ,(unsigned long __user *) single); 750 FPU_put_user(templ, (unsigned long __user *)single);
851 RE_ENTRANT_CHECK_ON; 751 RE_ENTRANT_CHECK_ON;
852 752
853 return 1; 753 return 1;
854} 754}
855 755
856
857/* Put a long long into user memory */ 756/* Put a long long into user memory */
858int FPU_store_int64(FPU_REG *st0_ptr, u_char st0_tag, long long __user *d) 757int FPU_store_int64(FPU_REG *st0_ptr, u_char st0_tag, long long __user *d)
859{ 758{
860 FPU_REG t; 759 FPU_REG t;
861 long long tll; 760 long long tll;
862 int precision_loss; 761 int precision_loss;
863 762
864 if ( st0_tag == TAG_Empty ) 763 if (st0_tag == TAG_Empty) {
865 { 764 /* Empty register (stack underflow) */
866 /* Empty register (stack underflow) */ 765 EXCEPTION(EX_StackUnder);
867 EXCEPTION(EX_StackUnder); 766 goto invalid_operand;
868 goto invalid_operand; 767 } else if (st0_tag == TAG_Special) {
869 } 768 st0_tag = FPU_Special(st0_ptr);
870 else if ( st0_tag == TAG_Special ) 769 if ((st0_tag == TW_Infinity) || (st0_tag == TW_NaN)) {
871 { 770 EXCEPTION(EX_Invalid);
872 st0_tag = FPU_Special(st0_ptr); 771 goto invalid_operand;
873 if ( (st0_tag == TW_Infinity) || 772 }
874 (st0_tag == TW_NaN) )
875 {
876 EXCEPTION(EX_Invalid);
877 goto invalid_operand;
878 } 773 }
879 } 774
880 775 reg_copy(st0_ptr, &t);
881 reg_copy(st0_ptr, &t); 776 precision_loss = FPU_round_to_int(&t, st0_tag);
882 precision_loss = FPU_round_to_int(&t, st0_tag); 777 ((long *)&tll)[0] = t.sigl;
883 ((long *)&tll)[0] = t.sigl; 778 ((long *)&tll)[1] = t.sigh;
884 ((long *)&tll)[1] = t.sigh; 779 if ((precision_loss == 1) ||
885 if ( (precision_loss == 1) || 780 ((t.sigh & 0x80000000) &&
886 ((t.sigh & 0x80000000) && 781 !((t.sigh == 0x80000000) && (t.sigl == 0) && signnegative(&t)))) {
887 !((t.sigh == 0x80000000) && (t.sigl == 0) && 782 EXCEPTION(EX_Invalid);
888 signnegative(&t))) ) 783 /* This is a special case: see sec 16.2.5.1 of the 80486 book */
889 { 784 invalid_operand:
890 EXCEPTION(EX_Invalid); 785 if (control_word & EX_Invalid) {
891 /* This is a special case: see sec 16.2.5.1 of the 80486 book */ 786 /* Produce something like QNaN "indefinite" */
892 invalid_operand: 787 tll = 0x8000000000000000LL;
893 if ( control_word & EX_Invalid ) 788 } else
894 { 789 return 0;
895 /* Produce something like QNaN "indefinite" */ 790 } else {
896 tll = 0x8000000000000000LL; 791 if (precision_loss)
792 set_precision_flag(precision_loss);
793 if (signnegative(&t))
794 tll = -tll;
897 } 795 }
898 else
899 return 0;
900 }
901 else
902 {
903 if ( precision_loss )
904 set_precision_flag(precision_loss);
905 if ( signnegative(&t) )
906 tll = - tll;
907 }
908
909 RE_ENTRANT_CHECK_OFF;
910 FPU_access_ok(VERIFY_WRITE,d,8);
911 if (copy_to_user(d, &tll, 8))
912 FPU_abort;
913 RE_ENTRANT_CHECK_ON;
914
915 return 1;
916}
917 796
797 RE_ENTRANT_CHECK_OFF;
798 FPU_access_ok(VERIFY_WRITE, d, 8);
799 if (copy_to_user(d, &tll, 8))
800 FPU_abort;
801 RE_ENTRANT_CHECK_ON;
802
803 return 1;
804}
918 805
919/* Put a long into user memory */ 806/* Put a long into user memory */
920int FPU_store_int32(FPU_REG *st0_ptr, u_char st0_tag, long __user *d) 807int FPU_store_int32(FPU_REG *st0_ptr, u_char st0_tag, long __user *d)
921{ 808{
922 FPU_REG t; 809 FPU_REG t;
923 int precision_loss; 810 int precision_loss;
924 811
925 if ( st0_tag == TAG_Empty ) 812 if (st0_tag == TAG_Empty) {
926 { 813 /* Empty register (stack underflow) */
927 /* Empty register (stack underflow) */ 814 EXCEPTION(EX_StackUnder);
928 EXCEPTION(EX_StackUnder); 815 goto invalid_operand;
929 goto invalid_operand; 816 } else if (st0_tag == TAG_Special) {
930 } 817 st0_tag = FPU_Special(st0_ptr);
931 else if ( st0_tag == TAG_Special ) 818 if ((st0_tag == TW_Infinity) || (st0_tag == TW_NaN)) {
932 { 819 EXCEPTION(EX_Invalid);
933 st0_tag = FPU_Special(st0_ptr); 820 goto invalid_operand;
934 if ( (st0_tag == TW_Infinity) || 821 }
935 (st0_tag == TW_NaN) )
936 {
937 EXCEPTION(EX_Invalid);
938 goto invalid_operand;
939 } 822 }
940 } 823
941 824 reg_copy(st0_ptr, &t);
942 reg_copy(st0_ptr, &t); 825 precision_loss = FPU_round_to_int(&t, st0_tag);
943 precision_loss = FPU_round_to_int(&t, st0_tag); 826 if (t.sigh ||
944 if (t.sigh || 827 ((t.sigl & 0x80000000) &&
945 ((t.sigl & 0x80000000) && 828 !((t.sigl == 0x80000000) && signnegative(&t)))) {
946 !((t.sigl == 0x80000000) && signnegative(&t))) ) 829 EXCEPTION(EX_Invalid);
947 { 830 /* This is a special case: see sec 16.2.5.1 of the 80486 book */
948 EXCEPTION(EX_Invalid); 831 invalid_operand:
949 /* This is a special case: see sec 16.2.5.1 of the 80486 book */ 832 if (control_word & EX_Invalid) {
950 invalid_operand: 833 /* Produce something like QNaN "indefinite" */
951 if ( control_word & EX_Invalid ) 834 t.sigl = 0x80000000;
952 { 835 } else
953 /* Produce something like QNaN "indefinite" */ 836 return 0;
954 t.sigl = 0x80000000; 837 } else {
838 if (precision_loss)
839 set_precision_flag(precision_loss);
840 if (signnegative(&t))
841 t.sigl = -(long)t.sigl;
955 } 842 }
956 else
957 return 0;
958 }
959 else
960 {
961 if ( precision_loss )
962 set_precision_flag(precision_loss);
963 if ( signnegative(&t) )
964 t.sigl = -(long)t.sigl;
965 }
966
967 RE_ENTRANT_CHECK_OFF;
968 FPU_access_ok(VERIFY_WRITE,d,4);
969 FPU_put_user(t.sigl, (unsigned long __user *) d);
970 RE_ENTRANT_CHECK_ON;
971
972 return 1;
973}
974 843
844 RE_ENTRANT_CHECK_OFF;
845 FPU_access_ok(VERIFY_WRITE, d, 4);
846 FPU_put_user(t.sigl, (unsigned long __user *)d);
847 RE_ENTRANT_CHECK_ON;
848
849 return 1;
850}
975 851
976/* Put a short into user memory */ 852/* Put a short into user memory */
977int FPU_store_int16(FPU_REG *st0_ptr, u_char st0_tag, short __user *d) 853int FPU_store_int16(FPU_REG *st0_ptr, u_char st0_tag, short __user *d)
978{ 854{
979 FPU_REG t; 855 FPU_REG t;
980 int precision_loss; 856 int precision_loss;
981 857
982 if ( st0_tag == TAG_Empty ) 858 if (st0_tag == TAG_Empty) {
983 { 859 /* Empty register (stack underflow) */
984 /* Empty register (stack underflow) */ 860 EXCEPTION(EX_StackUnder);
985 EXCEPTION(EX_StackUnder); 861 goto invalid_operand;
986 goto invalid_operand; 862 } else if (st0_tag == TAG_Special) {
987 } 863 st0_tag = FPU_Special(st0_ptr);
988 else if ( st0_tag == TAG_Special ) 864 if ((st0_tag == TW_Infinity) || (st0_tag == TW_NaN)) {
989 { 865 EXCEPTION(EX_Invalid);
990 st0_tag = FPU_Special(st0_ptr); 866 goto invalid_operand;
991 if ( (st0_tag == TW_Infinity) || 867 }
992 (st0_tag == TW_NaN) )
993 {
994 EXCEPTION(EX_Invalid);
995 goto invalid_operand;
996 } 868 }
997 } 869
998 870 reg_copy(st0_ptr, &t);
999 reg_copy(st0_ptr, &t); 871 precision_loss = FPU_round_to_int(&t, st0_tag);
1000 precision_loss = FPU_round_to_int(&t, st0_tag); 872 if (t.sigh ||
1001 if (t.sigh || 873 ((t.sigl & 0xffff8000) &&
1002 ((t.sigl & 0xffff8000) && 874 !((t.sigl == 0x8000) && signnegative(&t)))) {
1003 !((t.sigl == 0x8000) && signnegative(&t))) ) 875 EXCEPTION(EX_Invalid);
1004 { 876 /* This is a special case: see sec 16.2.5.1 of the 80486 book */
1005 EXCEPTION(EX_Invalid); 877 invalid_operand:
1006 /* This is a special case: see sec 16.2.5.1 of the 80486 book */ 878 if (control_word & EX_Invalid) {
1007 invalid_operand: 879 /* Produce something like QNaN "indefinite" */
1008 if ( control_word & EX_Invalid ) 880 t.sigl = 0x8000;
1009 { 881 } else
1010 /* Produce something like QNaN "indefinite" */ 882 return 0;
1011 t.sigl = 0x8000; 883 } else {
884 if (precision_loss)
885 set_precision_flag(precision_loss);
886 if (signnegative(&t))
887 t.sigl = -t.sigl;
1012 } 888 }
1013 else
1014 return 0;
1015 }
1016 else
1017 {
1018 if ( precision_loss )
1019 set_precision_flag(precision_loss);
1020 if ( signnegative(&t) )
1021 t.sigl = -t.sigl;
1022 }
1023
1024 RE_ENTRANT_CHECK_OFF;
1025 FPU_access_ok(VERIFY_WRITE,d,2);
1026 FPU_put_user((short)t.sigl, d);
1027 RE_ENTRANT_CHECK_ON;
1028
1029 return 1;
1030}
1031 889
890 RE_ENTRANT_CHECK_OFF;
891 FPU_access_ok(VERIFY_WRITE, d, 2);
892 FPU_put_user((short)t.sigl, d);
893 RE_ENTRANT_CHECK_ON;
894
895 return 1;
896}
1032 897
1033/* Put a packed bcd array into user memory */ 898/* Put a packed bcd array into user memory */
1034int FPU_store_bcd(FPU_REG *st0_ptr, u_char st0_tag, u_char __user *d) 899int FPU_store_bcd(FPU_REG *st0_ptr, u_char st0_tag, u_char __user *d)
1035{ 900{
1036 FPU_REG t; 901 FPU_REG t;
1037 unsigned long long ll; 902 unsigned long long ll;
1038 u_char b; 903 u_char b;
1039 int i, precision_loss; 904 int i, precision_loss;
1040 u_char sign = (getsign(st0_ptr) == SIGN_NEG) ? 0x80 : 0; 905 u_char sign = (getsign(st0_ptr) == SIGN_NEG) ? 0x80 : 0;
1041 906
1042 if ( st0_tag == TAG_Empty ) 907 if (st0_tag == TAG_Empty) {
1043 { 908 /* Empty register (stack underflow) */
1044 /* Empty register (stack underflow) */ 909 EXCEPTION(EX_StackUnder);
1045 EXCEPTION(EX_StackUnder); 910 goto invalid_operand;
1046 goto invalid_operand; 911 } else if (st0_tag == TAG_Special) {
1047 } 912 st0_tag = FPU_Special(st0_ptr);
1048 else if ( st0_tag == TAG_Special ) 913 if ((st0_tag == TW_Infinity) || (st0_tag == TW_NaN)) {
1049 { 914 EXCEPTION(EX_Invalid);
1050 st0_tag = FPU_Special(st0_ptr); 915 goto invalid_operand;
1051 if ( (st0_tag == TW_Infinity) || 916 }
1052 (st0_tag == TW_NaN) ) 917 }
1053 { 918
1054 EXCEPTION(EX_Invalid); 919 reg_copy(st0_ptr, &t);
1055 goto invalid_operand; 920 precision_loss = FPU_round_to_int(&t, st0_tag);
921 ll = significand(&t);
922
923 /* Check for overflow, by comparing with 999999999999999999 decimal. */
924 if ((t.sigh > 0x0de0b6b3) ||
925 ((t.sigh == 0x0de0b6b3) && (t.sigl > 0xa763ffff))) {
926 EXCEPTION(EX_Invalid);
927 /* This is a special case: see sec 16.2.5.1 of the 80486 book */
928 invalid_operand:
929 if (control_word & CW_Invalid) {
930 /* Produce the QNaN "indefinite" */
931 RE_ENTRANT_CHECK_OFF;
932 FPU_access_ok(VERIFY_WRITE, d, 10);
933 for (i = 0; i < 7; i++)
934 FPU_put_user(0, d + i); /* These bytes "undefined" */
935 FPU_put_user(0xc0, d + 7); /* This byte "undefined" */
936 FPU_put_user(0xff, d + 8);
937 FPU_put_user(0xff, d + 9);
938 RE_ENTRANT_CHECK_ON;
939 return 1;
940 } else
941 return 0;
942 } else if (precision_loss) {
943 /* Precision loss doesn't stop the data transfer */
944 set_precision_flag(precision_loss);
1056 } 945 }
1057 } 946
1058 947 RE_ENTRANT_CHECK_OFF;
1059 reg_copy(st0_ptr, &t); 948 FPU_access_ok(VERIFY_WRITE, d, 10);
1060 precision_loss = FPU_round_to_int(&t, st0_tag); 949 RE_ENTRANT_CHECK_ON;
1061 ll = significand(&t); 950 for (i = 0; i < 9; i++) {
1062 951 b = FPU_div_small(&ll, 10);
1063 /* Check for overflow, by comparing with 999999999999999999 decimal. */ 952 b |= (FPU_div_small(&ll, 10)) << 4;
1064 if ( (t.sigh > 0x0de0b6b3) || 953 RE_ENTRANT_CHECK_OFF;
1065 ((t.sigh == 0x0de0b6b3) && (t.sigl > 0xa763ffff)) ) 954 FPU_put_user(b, d + i);
1066 { 955 RE_ENTRANT_CHECK_ON;
1067 EXCEPTION(EX_Invalid);
1068 /* This is a special case: see sec 16.2.5.1 of the 80486 book */
1069 invalid_operand:
1070 if ( control_word & CW_Invalid )
1071 {
1072 /* Produce the QNaN "indefinite" */
1073 RE_ENTRANT_CHECK_OFF;
1074 FPU_access_ok(VERIFY_WRITE,d,10);
1075 for ( i = 0; i < 7; i++)
1076 FPU_put_user(0, d+i); /* These bytes "undefined" */
1077 FPU_put_user(0xc0, d+7); /* This byte "undefined" */
1078 FPU_put_user(0xff, d+8);
1079 FPU_put_user(0xff, d+9);
1080 RE_ENTRANT_CHECK_ON;
1081 return 1;
1082 } 956 }
1083 else 957 RE_ENTRANT_CHECK_OFF;
1084 return 0; 958 FPU_put_user(sign, d + 9);
1085 } 959 RE_ENTRANT_CHECK_ON;
1086 else if ( precision_loss ) 960
1087 { 961 return 1;
1088 /* Precision loss doesn't stop the data transfer */
1089 set_precision_flag(precision_loss);
1090 }
1091
1092 RE_ENTRANT_CHECK_OFF;
1093 FPU_access_ok(VERIFY_WRITE,d,10);
1094 RE_ENTRANT_CHECK_ON;
1095 for ( i = 0; i < 9; i++)
1096 {
1097 b = FPU_div_small(&ll, 10);
1098 b |= (FPU_div_small(&ll, 10)) << 4;
1099 RE_ENTRANT_CHECK_OFF;
1100 FPU_put_user(b, d+i);
1101 RE_ENTRANT_CHECK_ON;
1102 }
1103 RE_ENTRANT_CHECK_OFF;
1104 FPU_put_user(sign, d+9);
1105 RE_ENTRANT_CHECK_ON;
1106
1107 return 1;
1108} 962}
1109 963
1110/*===========================================================================*/ 964/*===========================================================================*/
@@ -1119,59 +973,56 @@ int FPU_store_bcd(FPU_REG *st0_ptr, u_char st0_tag, u_char __user *d)
1119 largest possible value */ 973 largest possible value */
1120int FPU_round_to_int(FPU_REG *r, u_char tag) 974int FPU_round_to_int(FPU_REG *r, u_char tag)
1121{ 975{
1122 u_char very_big; 976 u_char very_big;
1123 unsigned eax; 977 unsigned eax;
1124 978
1125 if (tag == TAG_Zero) 979 if (tag == TAG_Zero) {
1126 { 980 /* Make sure that zero is returned */
1127 /* Make sure that zero is returned */ 981 significand(r) = 0;
1128 significand(r) = 0; 982 return 0; /* o.k. */
1129 return 0; /* o.k. */ 983 }
1130 } 984
1131 985 if (exponent(r) > 63) {
1132 if (exponent(r) > 63) 986 r->sigl = r->sigh = ~0; /* The largest representable number */
1133 { 987 return 1; /* overflow */
1134 r->sigl = r->sigh = ~0; /* The largest representable number */ 988 }
1135 return 1; /* overflow */ 989
1136 } 990 eax = FPU_shrxs(&r->sigl, 63 - exponent(r));
1137 991 very_big = !(~(r->sigh) | ~(r->sigl)); /* test for 0xfff...fff */
1138 eax = FPU_shrxs(&r->sigl, 63 - exponent(r));
1139 very_big = !(~(r->sigh) | ~(r->sigl)); /* test for 0xfff...fff */
1140#define half_or_more (eax & 0x80000000) 992#define half_or_more (eax & 0x80000000)
1141#define frac_part (eax) 993#define frac_part (eax)
1142#define more_than_half ((eax & 0x80000001) == 0x80000001) 994#define more_than_half ((eax & 0x80000001) == 0x80000001)
1143 switch (control_word & CW_RC) 995 switch (control_word & CW_RC) {
1144 { 996 case RC_RND:
1145 case RC_RND: 997 if (more_than_half /* nearest */
1146 if ( more_than_half /* nearest */ 998 || (half_or_more && (r->sigl & 1))) { /* odd -> even */
1147 || (half_or_more && (r->sigl & 1)) ) /* odd -> even */ 999 if (very_big)
1148 { 1000 return 1; /* overflow */
1149 if ( very_big ) return 1; /* overflow */ 1001 significand(r)++;
1150 significand(r) ++; 1002 return PRECISION_LOST_UP;
1151 return PRECISION_LOST_UP; 1003 }
1152 } 1004 break;
1153 break; 1005 case RC_DOWN:
1154 case RC_DOWN: 1006 if (frac_part && getsign(r)) {
1155 if (frac_part && getsign(r)) 1007 if (very_big)
1156 { 1008 return 1; /* overflow */
1157 if ( very_big ) return 1; /* overflow */ 1009 significand(r)++;
1158 significand(r) ++; 1010 return PRECISION_LOST_UP;
1159 return PRECISION_LOST_UP; 1011 }
1160 } 1012 break;
1161 break; 1013 case RC_UP:
1162 case RC_UP: 1014 if (frac_part && !getsign(r)) {
1163 if (frac_part && !getsign(r)) 1015 if (very_big)
1164 { 1016 return 1; /* overflow */
1165 if ( very_big ) return 1; /* overflow */ 1017 significand(r)++;
1166 significand(r) ++; 1018 return PRECISION_LOST_UP;
1167 return PRECISION_LOST_UP; 1019 }
1020 break;
1021 case RC_CHOP:
1022 break;
1168 } 1023 }
1169 break;
1170 case RC_CHOP:
1171 break;
1172 }
1173 1024
1174 return eax ? PRECISION_LOST_DOWN : 0; 1025 return eax ? PRECISION_LOST_DOWN : 0;
1175 1026
1176} 1027}
1177 1028
@@ -1179,197 +1030,195 @@ int FPU_round_to_int(FPU_REG *r, u_char tag)
1179 1030
1180u_char __user *fldenv(fpu_addr_modes addr_modes, u_char __user *s) 1031u_char __user *fldenv(fpu_addr_modes addr_modes, u_char __user *s)
1181{ 1032{
1182 unsigned short tag_word = 0; 1033 unsigned short tag_word = 0;
1183 u_char tag; 1034 u_char tag;
1184 int i; 1035 int i;
1185 1036
1186 if ( (addr_modes.default_mode == VM86) || 1037 if ((addr_modes.default_mode == VM86) ||
1187 ((addr_modes.default_mode == PM16) 1038 ((addr_modes.default_mode == PM16)
1188 ^ (addr_modes.override.operand_size == OP_SIZE_PREFIX)) ) 1039 ^ (addr_modes.override.operand_size == OP_SIZE_PREFIX))) {
1189 { 1040 RE_ENTRANT_CHECK_OFF;
1190 RE_ENTRANT_CHECK_OFF; 1041 FPU_access_ok(VERIFY_READ, s, 0x0e);
1191 FPU_access_ok(VERIFY_READ, s, 0x0e); 1042 FPU_get_user(control_word, (unsigned short __user *)s);
1192 FPU_get_user(control_word, (unsigned short __user *) s); 1043 FPU_get_user(partial_status, (unsigned short __user *)(s + 2));
1193 FPU_get_user(partial_status, (unsigned short __user *) (s+2)); 1044 FPU_get_user(tag_word, (unsigned short __user *)(s + 4));
1194 FPU_get_user(tag_word, (unsigned short __user *) (s+4)); 1045 FPU_get_user(instruction_address.offset,
1195 FPU_get_user(instruction_address.offset, (unsigned short __user *) (s+6)); 1046 (unsigned short __user *)(s + 6));
1196 FPU_get_user(instruction_address.selector, (unsigned short __user *) (s+8)); 1047 FPU_get_user(instruction_address.selector,
1197 FPU_get_user(operand_address.offset, (unsigned short __user *) (s+0x0a)); 1048 (unsigned short __user *)(s + 8));
1198 FPU_get_user(operand_address.selector, (unsigned short __user *) (s+0x0c)); 1049 FPU_get_user(operand_address.offset,
1199 RE_ENTRANT_CHECK_ON; 1050 (unsigned short __user *)(s + 0x0a));
1200 s += 0x0e; 1051 FPU_get_user(operand_address.selector,
1201 if ( addr_modes.default_mode == VM86 ) 1052 (unsigned short __user *)(s + 0x0c));
1202 { 1053 RE_ENTRANT_CHECK_ON;
1203 instruction_address.offset 1054 s += 0x0e;
1204 += (instruction_address.selector & 0xf000) << 4; 1055 if (addr_modes.default_mode == VM86) {
1205 operand_address.offset += (operand_address.selector & 0xf000) << 4; 1056 instruction_address.offset
1057 += (instruction_address.selector & 0xf000) << 4;
1058 operand_address.offset +=
1059 (operand_address.selector & 0xf000) << 4;
1060 }
1061 } else {
1062 RE_ENTRANT_CHECK_OFF;
1063 FPU_access_ok(VERIFY_READ, s, 0x1c);
1064 FPU_get_user(control_word, (unsigned short __user *)s);
1065 FPU_get_user(partial_status, (unsigned short __user *)(s + 4));
1066 FPU_get_user(tag_word, (unsigned short __user *)(s + 8));
1067 FPU_get_user(instruction_address.offset,
1068 (unsigned long __user *)(s + 0x0c));
1069 FPU_get_user(instruction_address.selector,
1070 (unsigned short __user *)(s + 0x10));
1071 FPU_get_user(instruction_address.opcode,
1072 (unsigned short __user *)(s + 0x12));
1073 FPU_get_user(operand_address.offset,
1074 (unsigned long __user *)(s + 0x14));
1075 FPU_get_user(operand_address.selector,
1076 (unsigned long __user *)(s + 0x18));
1077 RE_ENTRANT_CHECK_ON;
1078 s += 0x1c;
1206 } 1079 }
1207 }
1208 else
1209 {
1210 RE_ENTRANT_CHECK_OFF;
1211 FPU_access_ok(VERIFY_READ, s, 0x1c);
1212 FPU_get_user(control_word, (unsigned short __user *) s);
1213 FPU_get_user(partial_status, (unsigned short __user *) (s+4));
1214 FPU_get_user(tag_word, (unsigned short __user *) (s+8));
1215 FPU_get_user(instruction_address.offset, (unsigned long __user *) (s+0x0c));
1216 FPU_get_user(instruction_address.selector, (unsigned short __user *) (s+0x10));
1217 FPU_get_user(instruction_address.opcode, (unsigned short __user *) (s+0x12));
1218 FPU_get_user(operand_address.offset, (unsigned long __user *) (s+0x14));
1219 FPU_get_user(operand_address.selector, (unsigned long __user *) (s+0x18));
1220 RE_ENTRANT_CHECK_ON;
1221 s += 0x1c;
1222 }
1223 1080
1224#ifdef PECULIAR_486 1081#ifdef PECULIAR_486
1225 control_word &= ~0xe080; 1082 control_word &= ~0xe080;
1226#endif /* PECULIAR_486 */ 1083#endif /* PECULIAR_486 */
1227 1084
1228 top = (partial_status >> SW_Top_Shift) & 7; 1085 top = (partial_status >> SW_Top_Shift) & 7;
1229 1086
1230 if ( partial_status & ~control_word & CW_Exceptions ) 1087 if (partial_status & ~control_word & CW_Exceptions)
1231 partial_status |= (SW_Summary | SW_Backward); 1088 partial_status |= (SW_Summary | SW_Backward);
1232 else 1089 else
1233 partial_status &= ~(SW_Summary | SW_Backward); 1090 partial_status &= ~(SW_Summary | SW_Backward);
1234 1091
1235 for ( i = 0; i < 8; i++ ) 1092 for (i = 0; i < 8; i++) {
1236 { 1093 tag = tag_word & 3;
1237 tag = tag_word & 3; 1094 tag_word >>= 2;
1238 tag_word >>= 2; 1095
1239 1096 if (tag == TAG_Empty)
1240 if ( tag == TAG_Empty ) 1097 /* New tag is empty. Accept it */
1241 /* New tag is empty. Accept it */ 1098 FPU_settag(i, TAG_Empty);
1242 FPU_settag(i, TAG_Empty); 1099 else if (FPU_gettag(i) == TAG_Empty) {
1243 else if ( FPU_gettag(i) == TAG_Empty ) 1100 /* Old tag is empty and new tag is not empty. New tag is determined
1244 { 1101 by old reg contents */
1245 /* Old tag is empty and new tag is not empty. New tag is determined 1102 if (exponent(&fpu_register(i)) == -EXTENDED_Ebias) {
1246 by old reg contents */ 1103 if (!
1247 if ( exponent(&fpu_register(i)) == - EXTENDED_Ebias ) 1104 (fpu_register(i).sigl | fpu_register(i).
1248 { 1105 sigh))
1249 if ( !(fpu_register(i).sigl | fpu_register(i).sigh) ) 1106 FPU_settag(i, TAG_Zero);
1250 FPU_settag(i, TAG_Zero); 1107 else
1251 else 1108 FPU_settag(i, TAG_Special);
1252 FPU_settag(i, TAG_Special); 1109 } else if (exponent(&fpu_register(i)) ==
1253 } 1110 0x7fff - EXTENDED_Ebias) {
1254 else if ( exponent(&fpu_register(i)) == 0x7fff - EXTENDED_Ebias ) 1111 FPU_settag(i, TAG_Special);
1255 { 1112 } else if (fpu_register(i).sigh & 0x80000000)
1256 FPU_settag(i, TAG_Special); 1113 FPU_settag(i, TAG_Valid);
1257 } 1114 else
1258 else if ( fpu_register(i).sigh & 0x80000000 ) 1115 FPU_settag(i, TAG_Special); /* An Un-normal */
1259 FPU_settag(i, TAG_Valid); 1116 }
1260 else 1117 /* Else old tag is not empty and new tag is not empty. Old tag
1261 FPU_settag(i, TAG_Special); /* An Un-normal */ 1118 remains correct */
1262 } 1119 }
1263 /* Else old tag is not empty and new tag is not empty. Old tag
1264 remains correct */
1265 }
1266
1267 return s;
1268}
1269 1120
1121 return s;
1122}
1270 1123
1271void frstor(fpu_addr_modes addr_modes, u_char __user *data_address) 1124void frstor(fpu_addr_modes addr_modes, u_char __user *data_address)
1272{ 1125{
1273 int i, regnr; 1126 int i, regnr;
1274 u_char __user *s = fldenv(addr_modes, data_address); 1127 u_char __user *s = fldenv(addr_modes, data_address);
1275 int offset = (top & 7) * 10, other = 80 - offset; 1128 int offset = (top & 7) * 10, other = 80 - offset;
1276 1129
1277 /* Copy all registers in stack order. */ 1130 /* Copy all registers in stack order. */
1278 RE_ENTRANT_CHECK_OFF; 1131 RE_ENTRANT_CHECK_OFF;
1279 FPU_access_ok(VERIFY_READ,s,80); 1132 FPU_access_ok(VERIFY_READ, s, 80);
1280 __copy_from_user(register_base+offset, s, other); 1133 __copy_from_user(register_base + offset, s, other);
1281 if ( offset ) 1134 if (offset)
1282 __copy_from_user(register_base, s+other, offset); 1135 __copy_from_user(register_base, s + other, offset);
1283 RE_ENTRANT_CHECK_ON; 1136 RE_ENTRANT_CHECK_ON;
1284 1137
1285 for ( i = 0; i < 8; i++ ) 1138 for (i = 0; i < 8; i++) {
1286 { 1139 regnr = (i + top) & 7;
1287 regnr = (i+top) & 7; 1140 if (FPU_gettag(regnr) != TAG_Empty)
1288 if ( FPU_gettag(regnr) != TAG_Empty ) 1141 /* The loaded data over-rides all other cases. */
1289 /* The loaded data over-rides all other cases. */ 1142 FPU_settag(regnr, FPU_tagof(&st(i)));
1290 FPU_settag(regnr, FPU_tagof(&st(i))); 1143 }
1291 }
1292 1144
1293} 1145}
1294 1146
1295
1296u_char __user *fstenv(fpu_addr_modes addr_modes, u_char __user *d) 1147u_char __user *fstenv(fpu_addr_modes addr_modes, u_char __user *d)
1297{ 1148{
1298 if ( (addr_modes.default_mode == VM86) || 1149 if ((addr_modes.default_mode == VM86) ||
1299 ((addr_modes.default_mode == PM16) 1150 ((addr_modes.default_mode == PM16)
1300 ^ (addr_modes.override.operand_size == OP_SIZE_PREFIX)) ) 1151 ^ (addr_modes.override.operand_size == OP_SIZE_PREFIX))) {
1301 { 1152 RE_ENTRANT_CHECK_OFF;
1302 RE_ENTRANT_CHECK_OFF; 1153 FPU_access_ok(VERIFY_WRITE, d, 14);
1303 FPU_access_ok(VERIFY_WRITE,d,14);
1304#ifdef PECULIAR_486 1154#ifdef PECULIAR_486
1305 FPU_put_user(control_word & ~0xe080, (unsigned long __user *) d); 1155 FPU_put_user(control_word & ~0xe080, (unsigned long __user *)d);
1306#else 1156#else
1307 FPU_put_user(control_word, (unsigned short __user *) d); 1157 FPU_put_user(control_word, (unsigned short __user *)d);
1308#endif /* PECULIAR_486 */ 1158#endif /* PECULIAR_486 */
1309 FPU_put_user(status_word(), (unsigned short __user *) (d+2)); 1159 FPU_put_user(status_word(), (unsigned short __user *)(d + 2));
1310 FPU_put_user(fpu_tag_word, (unsigned short __user *) (d+4)); 1160 FPU_put_user(fpu_tag_word, (unsigned short __user *)(d + 4));
1311 FPU_put_user(instruction_address.offset, (unsigned short __user *) (d+6)); 1161 FPU_put_user(instruction_address.offset,
1312 FPU_put_user(operand_address.offset, (unsigned short __user *) (d+0x0a)); 1162 (unsigned short __user *)(d + 6));
1313 if ( addr_modes.default_mode == VM86 ) 1163 FPU_put_user(operand_address.offset,
1314 { 1164 (unsigned short __user *)(d + 0x0a));
1315 FPU_put_user((instruction_address.offset & 0xf0000) >> 4, 1165 if (addr_modes.default_mode == VM86) {
1316 (unsigned short __user *) (d+8)); 1166 FPU_put_user((instruction_address.
1317 FPU_put_user((operand_address.offset & 0xf0000) >> 4, 1167 offset & 0xf0000) >> 4,
1318 (unsigned short __user *) (d+0x0c)); 1168 (unsigned short __user *)(d + 8));
1319 } 1169 FPU_put_user((operand_address.offset & 0xf0000) >> 4,
1320 else 1170 (unsigned short __user *)(d + 0x0c));
1321 { 1171 } else {
1322 FPU_put_user(instruction_address.selector, (unsigned short __user *) (d+8)); 1172 FPU_put_user(instruction_address.selector,
1323 FPU_put_user(operand_address.selector, (unsigned short __user *) (d+0x0c)); 1173 (unsigned short __user *)(d + 8));
1324 } 1174 FPU_put_user(operand_address.selector,
1325 RE_ENTRANT_CHECK_ON; 1175 (unsigned short __user *)(d + 0x0c));
1326 d += 0x0e; 1176 }
1327 } 1177 RE_ENTRANT_CHECK_ON;
1328 else 1178 d += 0x0e;
1329 { 1179 } else {
1330 RE_ENTRANT_CHECK_OFF; 1180 RE_ENTRANT_CHECK_OFF;
1331 FPU_access_ok(VERIFY_WRITE, d, 7*4); 1181 FPU_access_ok(VERIFY_WRITE, d, 7 * 4);
1332#ifdef PECULIAR_486 1182#ifdef PECULIAR_486
1333 control_word &= ~0xe080; 1183 control_word &= ~0xe080;
1334 /* An 80486 sets nearly all of the reserved bits to 1. */ 1184 /* An 80486 sets nearly all of the reserved bits to 1. */
1335 control_word |= 0xffff0040; 1185 control_word |= 0xffff0040;
1336 partial_status = status_word() | 0xffff0000; 1186 partial_status = status_word() | 0xffff0000;
1337 fpu_tag_word |= 0xffff0000; 1187 fpu_tag_word |= 0xffff0000;
1338 I387.soft.fcs &= ~0xf8000000; 1188 I387.soft.fcs &= ~0xf8000000;
1339 I387.soft.fos |= 0xffff0000; 1189 I387.soft.fos |= 0xffff0000;
1340#endif /* PECULIAR_486 */ 1190#endif /* PECULIAR_486 */
1341 if (__copy_to_user(d, &control_word, 7*4)) 1191 if (__copy_to_user(d, &control_word, 7 * 4))
1342 FPU_abort; 1192 FPU_abort;
1343 RE_ENTRANT_CHECK_ON; 1193 RE_ENTRANT_CHECK_ON;
1344 d += 0x1c; 1194 d += 0x1c;
1345 } 1195 }
1346
1347 control_word |= CW_Exceptions;
1348 partial_status &= ~(SW_Summary | SW_Backward);
1349
1350 return d;
1351}
1352 1196
1197 control_word |= CW_Exceptions;
1198 partial_status &= ~(SW_Summary | SW_Backward);
1199
1200 return d;
1201}
1353 1202
1354void fsave(fpu_addr_modes addr_modes, u_char __user *data_address) 1203void fsave(fpu_addr_modes addr_modes, u_char __user *data_address)
1355{ 1204{
1356 u_char __user *d; 1205 u_char __user *d;
1357 int offset = (top & 7) * 10, other = 80 - offset; 1206 int offset = (top & 7) * 10, other = 80 - offset;
1358 1207
1359 d = fstenv(addr_modes, data_address); 1208 d = fstenv(addr_modes, data_address);
1360 1209
1361 RE_ENTRANT_CHECK_OFF; 1210 RE_ENTRANT_CHECK_OFF;
1362 FPU_access_ok(VERIFY_WRITE,d,80); 1211 FPU_access_ok(VERIFY_WRITE, d, 80);
1363 1212
1364 /* Copy all registers in stack order. */ 1213 /* Copy all registers in stack order. */
1365 if (__copy_to_user(d, register_base+offset, other)) 1214 if (__copy_to_user(d, register_base + offset, other))
1366 FPU_abort; 1215 FPU_abort;
1367 if ( offset ) 1216 if (offset)
1368 if (__copy_to_user(d+other, register_base, offset)) 1217 if (__copy_to_user(d + other, register_base, offset))
1369 FPU_abort; 1218 FPU_abort;
1370 RE_ENTRANT_CHECK_ON; 1219 RE_ENTRANT_CHECK_ON;
1371 1220
1372 finit(); 1221 finit();
1373} 1222}
1374 1223
1375/*===========================================================================*/ 1224/*===========================================================================*/
diff --git a/arch/x86/math-emu/reg_mul.c b/arch/x86/math-emu/reg_mul.c
index 40f50b61bc67..36c37f71f713 100644
--- a/arch/x86/math-emu/reg_mul.c
+++ b/arch/x86/math-emu/reg_mul.c
@@ -20,7 +20,6 @@
20#include "reg_constant.h" 20#include "reg_constant.h"
21#include "fpu_system.h" 21#include "fpu_system.h"
22 22
23
24/* 23/*
25 Multiply two registers to give a register result. 24 Multiply two registers to give a register result.
26 The sources are st(deststnr) and (b,tagb,signb). 25 The sources are st(deststnr) and (b,tagb,signb).
@@ -29,104 +28,88 @@
29/* This routine must be called with non-empty source registers */ 28/* This routine must be called with non-empty source registers */
30int FPU_mul(FPU_REG const *b, u_char tagb, int deststnr, int control_w) 29int FPU_mul(FPU_REG const *b, u_char tagb, int deststnr, int control_w)
31{ 30{
32 FPU_REG *a = &st(deststnr); 31 FPU_REG *a = &st(deststnr);
33 FPU_REG *dest = a; 32 FPU_REG *dest = a;
34 u_char taga = FPU_gettagi(deststnr); 33 u_char taga = FPU_gettagi(deststnr);
35 u_char saved_sign = getsign(dest); 34 u_char saved_sign = getsign(dest);
36 u_char sign = (getsign(a) ^ getsign(b)); 35 u_char sign = (getsign(a) ^ getsign(b));
37 int tag; 36 int tag;
38
39 37
40 if ( !(taga | tagb) ) 38 if (!(taga | tagb)) {
41 { 39 /* Both regs Valid, this should be the most common case. */
42 /* Both regs Valid, this should be the most common case. */
43 40
44 tag = FPU_u_mul(a, b, dest, control_w, sign, exponent(a) + exponent(b)); 41 tag =
45 if ( tag < 0 ) 42 FPU_u_mul(a, b, dest, control_w, sign,
46 { 43 exponent(a) + exponent(b));
47 setsign(dest, saved_sign); 44 if (tag < 0) {
48 return tag; 45 setsign(dest, saved_sign);
46 return tag;
47 }
48 FPU_settagi(deststnr, tag);
49 return tag;
49 } 50 }
50 FPU_settagi(deststnr, tag);
51 return tag;
52 }
53 51
54 if ( taga == TAG_Special ) 52 if (taga == TAG_Special)
55 taga = FPU_Special(a); 53 taga = FPU_Special(a);
56 if ( tagb == TAG_Special ) 54 if (tagb == TAG_Special)
57 tagb = FPU_Special(b); 55 tagb = FPU_Special(b);
58 56
59 if ( ((taga == TAG_Valid) && (tagb == TW_Denormal)) 57 if (((taga == TAG_Valid) && (tagb == TW_Denormal))
60 || ((taga == TW_Denormal) && (tagb == TAG_Valid)) 58 || ((taga == TW_Denormal) && (tagb == TAG_Valid))
61 || ((taga == TW_Denormal) && (tagb == TW_Denormal)) ) 59 || ((taga == TW_Denormal) && (tagb == TW_Denormal))) {
62 { 60 FPU_REG x, y;
63 FPU_REG x, y; 61 if (denormal_operand() < 0)
64 if ( denormal_operand() < 0 ) 62 return FPU_Exception;
65 return FPU_Exception;
66
67 FPU_to_exp16(a, &x);
68 FPU_to_exp16(b, &y);
69 tag = FPU_u_mul(&x, &y, dest, control_w, sign,
70 exponent16(&x) + exponent16(&y));
71 if ( tag < 0 )
72 {
73 setsign(dest, saved_sign);
74 return tag;
75 }
76 FPU_settagi(deststnr, tag);
77 return tag;
78 }
79 else if ( (taga <= TW_Denormal) && (tagb <= TW_Denormal) )
80 {
81 if ( ((tagb == TW_Denormal) || (taga == TW_Denormal))
82 && (denormal_operand() < 0) )
83 return FPU_Exception;
84 63
85 /* Must have either both arguments == zero, or 64 FPU_to_exp16(a, &x);
86 one valid and the other zero. 65 FPU_to_exp16(b, &y);
87 The result is therefore zero. */ 66 tag = FPU_u_mul(&x, &y, dest, control_w, sign,
88 FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr); 67 exponent16(&x) + exponent16(&y));
89 /* The 80486 book says that the answer is +0, but a real 68 if (tag < 0) {
90 80486 behaves this way. 69 setsign(dest, saved_sign);
91 IEEE-754 apparently says it should be this way. */ 70 return tag;
92 setsign(dest, sign); 71 }
93 return TAG_Zero; 72 FPU_settagi(deststnr, tag);
94 } 73 return tag;
95 /* Must have infinities, NaNs, etc */ 74 } else if ((taga <= TW_Denormal) && (tagb <= TW_Denormal)) {
96 else if ( (taga == TW_NaN) || (tagb == TW_NaN) ) 75 if (((tagb == TW_Denormal) || (taga == TW_Denormal))
97 { 76 && (denormal_operand() < 0))
98 return real_2op_NaN(b, tagb, deststnr, &st(0)); 77 return FPU_Exception;
99 }
100 else if ( ((taga == TW_Infinity) && (tagb == TAG_Zero))
101 || ((tagb == TW_Infinity) && (taga == TAG_Zero)) )
102 {
103 return arith_invalid(deststnr); /* Zero*Infinity is invalid */
104 }
105 else if ( ((taga == TW_Denormal) || (tagb == TW_Denormal))
106 && (denormal_operand() < 0) )
107 {
108 return FPU_Exception;
109 }
110 else if (taga == TW_Infinity)
111 {
112 FPU_copy_to_regi(a, TAG_Special, deststnr);
113 setsign(dest, sign);
114 return TAG_Special;
115 }
116 else if (tagb == TW_Infinity)
117 {
118 FPU_copy_to_regi(b, TAG_Special, deststnr);
119 setsign(dest, sign);
120 return TAG_Special;
121 }
122 78
79 /* Must have either both arguments == zero, or
80 one valid and the other zero.
81 The result is therefore zero. */
82 FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
83 /* The 80486 book says that the answer is +0, but a real
84 80486 behaves this way.
85 IEEE-754 apparently says it should be this way. */
86 setsign(dest, sign);
87 return TAG_Zero;
88 }
89 /* Must have infinities, NaNs, etc */
90 else if ((taga == TW_NaN) || (tagb == TW_NaN)) {
91 return real_2op_NaN(b, tagb, deststnr, &st(0));
92 } else if (((taga == TW_Infinity) && (tagb == TAG_Zero))
93 || ((tagb == TW_Infinity) && (taga == TAG_Zero))) {
94 return arith_invalid(deststnr); /* Zero*Infinity is invalid */
95 } else if (((taga == TW_Denormal) || (tagb == TW_Denormal))
96 && (denormal_operand() < 0)) {
97 return FPU_Exception;
98 } else if (taga == TW_Infinity) {
99 FPU_copy_to_regi(a, TAG_Special, deststnr);
100 setsign(dest, sign);
101 return TAG_Special;
102 } else if (tagb == TW_Infinity) {
103 FPU_copy_to_regi(b, TAG_Special, deststnr);
104 setsign(dest, sign);
105 return TAG_Special;
106 }
123#ifdef PARANOID 107#ifdef PARANOID
124 else 108 else {
125 { 109 EXCEPTION(EX_INTERNAL | 0x102);
126 EXCEPTION(EX_INTERNAL|0x102); 110 return FPU_Exception;
127 return FPU_Exception; 111 }
128 } 112#endif /* PARANOID */
129#endif /* PARANOID */
130 113
131 return 0; 114 return 0;
132} 115}
diff --git a/arch/x86/math-emu/status_w.h b/arch/x86/math-emu/status_w.h
index 59e73302aa60..54a3f226982d 100644
--- a/arch/x86/math-emu/status_w.h
+++ b/arch/x86/math-emu/status_w.h
@@ -10,7 +10,7 @@
10#ifndef _STATUS_H_ 10#ifndef _STATUS_H_
11#define _STATUS_H_ 11#define _STATUS_H_
12 12
13#include "fpu_emu.h" /* for definition of PECULIAR_486 */ 13#include "fpu_emu.h" /* for definition of PECULIAR_486 */
14 14
15#ifdef __ASSEMBLY__ 15#ifdef __ASSEMBLY__
16#define Const__(x) $##x 16#define Const__(x) $##x
@@ -34,7 +34,7 @@
34#define SW_Denorm_Op Const__(0x0002) /* denormalized operand */ 34#define SW_Denorm_Op Const__(0x0002) /* denormalized operand */
35#define SW_Invalid Const__(0x0001) /* invalid operation */ 35#define SW_Invalid Const__(0x0001) /* invalid operation */
36 36
37#define SW_Exc_Mask Const__(0x27f) /* Status word exception bit mask */ 37#define SW_Exc_Mask Const__(0x27f) /* Status word exception bit mask */
38 38
39#ifndef __ASSEMBLY__ 39#ifndef __ASSEMBLY__
40 40
@@ -50,8 +50,8 @@
50 ((partial_status & ~SW_Top & 0xffff) | ((top << SW_Top_Shift) & SW_Top)) 50 ((partial_status & ~SW_Top & 0xffff) | ((top << SW_Top_Shift) & SW_Top))
51static inline void setcc(int cc) 51static inline void setcc(int cc)
52{ 52{
53 partial_status &= ~(SW_C0|SW_C1|SW_C2|SW_C3); 53 partial_status &= ~(SW_C0 | SW_C1 | SW_C2 | SW_C3);
54 partial_status |= (cc) & (SW_C0|SW_C1|SW_C2|SW_C3); 54 partial_status |= (cc) & (SW_C0 | SW_C1 | SW_C2 | SW_C3);
55} 55}
56 56
57#ifdef PECULIAR_486 57#ifdef PECULIAR_486
diff --git a/arch/x86/mm/Makefile_32 b/arch/x86/mm/Makefile_32
index 362b4ad082de..c36ae88bb543 100644
--- a/arch/x86/mm/Makefile_32
+++ b/arch/x86/mm/Makefile_32
@@ -2,9 +2,8 @@
2# Makefile for the linux i386-specific parts of the memory manager. 2# Makefile for the linux i386-specific parts of the memory manager.
3# 3#
4 4
5obj-y := init_32.o pgtable_32.o fault_32.o ioremap_32.o extable_32.o pageattr_32.o mmap_32.o 5obj-y := init_32.o pgtable_32.o fault.o ioremap.o extable.o pageattr.o mmap.o
6 6
7obj-$(CONFIG_NUMA) += discontig_32.o 7obj-$(CONFIG_NUMA) += discontig_32.o
8obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o 8obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
9obj-$(CONFIG_HIGHMEM) += highmem_32.o 9obj-$(CONFIG_HIGHMEM) += highmem_32.o
10obj-$(CONFIG_BOOT_IOREMAP) += boot_ioremap_32.o
diff --git a/arch/x86/mm/Makefile_64 b/arch/x86/mm/Makefile_64
index 6bcb47945b87..688c8c28ac8f 100644
--- a/arch/x86/mm/Makefile_64
+++ b/arch/x86/mm/Makefile_64
@@ -2,9 +2,8 @@
2# Makefile for the linux x86_64-specific parts of the memory manager. 2# Makefile for the linux x86_64-specific parts of the memory manager.
3# 3#
4 4
5obj-y := init_64.o fault_64.o ioremap_64.o extable_64.o pageattr_64.o mmap_64.o 5obj-y := init_64.o fault.o ioremap.o extable.o pageattr.o mmap.o
6obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o 6obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
7obj-$(CONFIG_NUMA) += numa_64.o 7obj-$(CONFIG_NUMA) += numa_64.o
8obj-$(CONFIG_K8_NUMA) += k8topology_64.o 8obj-$(CONFIG_K8_NUMA) += k8topology_64.o
9obj-$(CONFIG_ACPI_NUMA) += srat_64.o 9obj-$(CONFIG_ACPI_NUMA) += srat_64.o
10
diff --git a/arch/x86/mm/boot_ioremap_32.c b/arch/x86/mm/boot_ioremap_32.c
deleted file mode 100644
index f14da2a53ece..000000000000
--- a/arch/x86/mm/boot_ioremap_32.c
+++ /dev/null
@@ -1,100 +0,0 @@
1/*
2 * arch/i386/mm/boot_ioremap.c
3 *
4 * Re-map functions for early boot-time before paging_init() when the
5 * boot-time pagetables are still in use
6 *
7 * Written by Dave Hansen <haveblue@us.ibm.com>
8 */
9
10
11/*
12 * We need to use the 2-level pagetable functions, but CONFIG_X86_PAE
13 * keeps that from happening. If anyone has a better way, I'm listening.
14 *
15 * boot_pte_t is defined only if this all works correctly
16 */
17
18#undef CONFIG_X86_PAE
19#undef CONFIG_PARAVIRT
20#include <asm/page.h>
21#include <asm/pgtable.h>
22#include <asm/tlbflush.h>
23#include <linux/init.h>
24#include <linux/stddef.h>
25
26/*
27 * I'm cheating here. It is known that the two boot PTE pages are
28 * allocated next to each other. I'm pretending that they're just
29 * one big array.
30 */
31
32#define BOOT_PTE_PTRS (PTRS_PER_PTE*2)
33
34static unsigned long boot_pte_index(unsigned long vaddr)
35{
36 return __pa(vaddr) >> PAGE_SHIFT;
37}
38
39static inline boot_pte_t* boot_vaddr_to_pte(void *address)
40{
41 boot_pte_t* boot_pg = (boot_pte_t*)pg0;
42 return &boot_pg[boot_pte_index((unsigned long)address)];
43}
44
45/*
46 * This is only for a caller who is clever enough to page-align
47 * phys_addr and virtual_source, and who also has a preference
48 * about which virtual address from which to steal ptes
49 */
50static void __boot_ioremap(unsigned long phys_addr, unsigned long nrpages,
51 void* virtual_source)
52{
53 boot_pte_t* pte;
54 int i;
55 char *vaddr = virtual_source;
56
57 pte = boot_vaddr_to_pte(virtual_source);
58 for (i=0; i < nrpages; i++, phys_addr += PAGE_SIZE, pte++) {
59 set_pte(pte, pfn_pte(phys_addr>>PAGE_SHIFT, PAGE_KERNEL));
60 __flush_tlb_one(&vaddr[i*PAGE_SIZE]);
61 }
62}
63
64/* the virtual space we're going to remap comes from this array */
65#define BOOT_IOREMAP_PAGES 4
66#define BOOT_IOREMAP_SIZE (BOOT_IOREMAP_PAGES*PAGE_SIZE)
67static __initdata char boot_ioremap_space[BOOT_IOREMAP_SIZE]
68 __attribute__ ((aligned (PAGE_SIZE)));
69
70/*
71 * This only applies to things which need to ioremap before paging_init()
72 * bt_ioremap() and plain ioremap() are both useless at this point.
73 *
74 * When used, we're still using the boot-time pagetables, which only
75 * have 2 PTE pages mapping the first 8MB
76 *
77 * There is no unmap. The boot-time PTE pages aren't used after boot.
78 * If you really want the space back, just remap it yourself.
79 * boot_ioremap(&ioremap_space-PAGE_OFFSET, BOOT_IOREMAP_SIZE)
80 */
81__init void* boot_ioremap(unsigned long phys_addr, unsigned long size)
82{
83 unsigned long last_addr, offset;
84 unsigned int nrpages;
85
86 last_addr = phys_addr + size - 1;
87
88 /* page align the requested address */
89 offset = phys_addr & ~PAGE_MASK;
90 phys_addr &= PAGE_MASK;
91 size = PAGE_ALIGN(last_addr) - phys_addr;
92
93 nrpages = size >> PAGE_SHIFT;
94 if (nrpages > BOOT_IOREMAP_PAGES)
95 return NULL;
96
97 __boot_ioremap(phys_addr, nrpages, boot_ioremap_space);
98
99 return &boot_ioremap_space[offset];
100}
diff --git a/arch/x86/mm/discontig_32.c b/arch/x86/mm/discontig_32.c
index 13a474d3c6e9..04b1d20e2613 100644
--- a/arch/x86/mm/discontig_32.c
+++ b/arch/x86/mm/discontig_32.c
@@ -32,6 +32,7 @@
32#include <linux/kexec.h> 32#include <linux/kexec.h>
33#include <linux/pfn.h> 33#include <linux/pfn.h>
34#include <linux/swap.h> 34#include <linux/swap.h>
35#include <linux/acpi.h>
35 36
36#include <asm/e820.h> 37#include <asm/e820.h>
37#include <asm/setup.h> 38#include <asm/setup.h>
@@ -103,14 +104,10 @@ extern unsigned long highend_pfn, highstart_pfn;
103 104
104#define LARGE_PAGE_BYTES (PTRS_PER_PTE * PAGE_SIZE) 105#define LARGE_PAGE_BYTES (PTRS_PER_PTE * PAGE_SIZE)
105 106
106static unsigned long node_remap_start_pfn[MAX_NUMNODES];
107unsigned long node_remap_size[MAX_NUMNODES]; 107unsigned long node_remap_size[MAX_NUMNODES];
108static unsigned long node_remap_offset[MAX_NUMNODES];
109static void *node_remap_start_vaddr[MAX_NUMNODES]; 108static void *node_remap_start_vaddr[MAX_NUMNODES];
110void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags); 109void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags);
111 110
112static void *node_remap_end_vaddr[MAX_NUMNODES];
113static void *node_remap_alloc_vaddr[MAX_NUMNODES];
114static unsigned long kva_start_pfn; 111static unsigned long kva_start_pfn;
115static unsigned long kva_pages; 112static unsigned long kva_pages;
116/* 113/*
@@ -167,6 +164,22 @@ static void __init allocate_pgdat(int nid)
167 } 164 }
168} 165}
169 166
167#ifdef CONFIG_DISCONTIGMEM
168/*
169 * In the discontig memory model, a portion of the kernel virtual area (KVA)
170 * is reserved and portions of nodes are mapped using it. This is to allow
171 * node-local memory to be allocated for structures that would normally require
172 * ZONE_NORMAL. The memory is allocated with alloc_remap() and callers
173 * should be prepared to allocate from the bootmem allocator instead. This KVA
174 * mechanism is incompatible with SPARSEMEM as it makes assumptions about the
175 * layout of memory that are broken if alloc_remap() succeeds for some of the
176 * map and fails for others
177 */
178static unsigned long node_remap_start_pfn[MAX_NUMNODES];
179static void *node_remap_end_vaddr[MAX_NUMNODES];
180static void *node_remap_alloc_vaddr[MAX_NUMNODES];
181static unsigned long node_remap_offset[MAX_NUMNODES];
182
170void *alloc_remap(int nid, unsigned long size) 183void *alloc_remap(int nid, unsigned long size)
171{ 184{
172 void *allocation = node_remap_alloc_vaddr[nid]; 185 void *allocation = node_remap_alloc_vaddr[nid];
@@ -263,11 +276,46 @@ static unsigned long calculate_numa_remap_pages(void)
263 return reserve_pages; 276 return reserve_pages;
264} 277}
265 278
279static void init_remap_allocator(int nid)
280{
281 node_remap_start_vaddr[nid] = pfn_to_kaddr(
282 kva_start_pfn + node_remap_offset[nid]);
283 node_remap_end_vaddr[nid] = node_remap_start_vaddr[nid] +
284 (node_remap_size[nid] * PAGE_SIZE);
285 node_remap_alloc_vaddr[nid] = node_remap_start_vaddr[nid] +
286 ALIGN(sizeof(pg_data_t), PAGE_SIZE);
287
288 printk ("node %d will remap to vaddr %08lx - %08lx\n", nid,
289 (ulong) node_remap_start_vaddr[nid],
290 (ulong) pfn_to_kaddr(highstart_pfn
291 + node_remap_offset[nid] + node_remap_size[nid]));
292}
293#else
294void *alloc_remap(int nid, unsigned long size)
295{
296 return NULL;
297}
298
299static unsigned long calculate_numa_remap_pages(void)
300{
301 return 0;
302}
303
304static void init_remap_allocator(int nid)
305{
306}
307
308void __init remap_numa_kva(void)
309{
310}
311#endif /* CONFIG_DISCONTIGMEM */
312
266extern void setup_bootmem_allocator(void); 313extern void setup_bootmem_allocator(void);
267unsigned long __init setup_memory(void) 314unsigned long __init setup_memory(void)
268{ 315{
269 int nid; 316 int nid;
270 unsigned long system_start_pfn, system_max_low_pfn; 317 unsigned long system_start_pfn, system_max_low_pfn;
318 unsigned long wasted_pages;
271 319
272 /* 320 /*
273 * When mapping a NUMA machine we allocate the node_mem_map arrays 321 * When mapping a NUMA machine we allocate the node_mem_map arrays
@@ -288,11 +336,18 @@ unsigned long __init setup_memory(void)
288 336
289#ifdef CONFIG_BLK_DEV_INITRD 337#ifdef CONFIG_BLK_DEV_INITRD
290 /* Numa kva area is below the initrd */ 338 /* Numa kva area is below the initrd */
291 if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) 339 if (initrd_start)
292 kva_start_pfn = PFN_DOWN(boot_params.hdr.ramdisk_image) 340 kva_start_pfn = PFN_DOWN(initrd_start - PAGE_OFFSET)
293 - kva_pages; 341 - kva_pages;
294#endif 342#endif
295 kva_start_pfn -= kva_start_pfn & (PTRS_PER_PTE-1); 343
344 /*
345 * We waste pages past at the end of the KVA for no good reason other
346 * than how it is located. This is bad.
347 */
348 wasted_pages = kva_start_pfn & (PTRS_PER_PTE-1);
349 kva_start_pfn -= wasted_pages;
350 kva_pages += wasted_pages;
296 351
297 system_max_low_pfn = max_low_pfn = find_max_low_pfn(); 352 system_max_low_pfn = max_low_pfn = find_max_low_pfn();
298 printk("kva_start_pfn ~ %ld find_max_low_pfn() ~ %ld\n", 353 printk("kva_start_pfn ~ %ld find_max_low_pfn() ~ %ld\n",
@@ -318,19 +373,9 @@ unsigned long __init setup_memory(void)
318 printk("Low memory ends at vaddr %08lx\n", 373 printk("Low memory ends at vaddr %08lx\n",
319 (ulong) pfn_to_kaddr(max_low_pfn)); 374 (ulong) pfn_to_kaddr(max_low_pfn));
320 for_each_online_node(nid) { 375 for_each_online_node(nid) {
321 node_remap_start_vaddr[nid] = pfn_to_kaddr( 376 init_remap_allocator(nid);
322 kva_start_pfn + node_remap_offset[nid]);
323 /* Init the node remap allocator */
324 node_remap_end_vaddr[nid] = node_remap_start_vaddr[nid] +
325 (node_remap_size[nid] * PAGE_SIZE);
326 node_remap_alloc_vaddr[nid] = node_remap_start_vaddr[nid] +
327 ALIGN(sizeof(pg_data_t), PAGE_SIZE);
328 377
329 allocate_pgdat(nid); 378 allocate_pgdat(nid);
330 printk ("node %d will remap to vaddr %08lx - %08lx\n", nid,
331 (ulong) node_remap_start_vaddr[nid],
332 (ulong) pfn_to_kaddr(highstart_pfn
333 + node_remap_offset[nid] + node_remap_size[nid]));
334 } 379 }
335 printk("High memory starts at vaddr %08lx\n", 380 printk("High memory starts at vaddr %08lx\n",
336 (ulong) pfn_to_kaddr(highstart_pfn)); 381 (ulong) pfn_to_kaddr(highstart_pfn));
@@ -345,7 +390,8 @@ unsigned long __init setup_memory(void)
345 390
346void __init numa_kva_reserve(void) 391void __init numa_kva_reserve(void)
347{ 392{
348 reserve_bootmem(PFN_PHYS(kva_start_pfn),PFN_PHYS(kva_pages)); 393 if (kva_pages)
394 reserve_bootmem(PFN_PHYS(kva_start_pfn), PFN_PHYS(kva_pages));
349} 395}
350 396
351void __init zone_sizes_init(void) 397void __init zone_sizes_init(void)
@@ -430,3 +476,29 @@ int memory_add_physaddr_to_nid(u64 addr)
430 476
431EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid); 477EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid);
432#endif 478#endif
479
480#ifndef CONFIG_HAVE_ARCH_PARSE_SRAT
481/*
482 * XXX FIXME: Make SLIT table parsing available to 32-bit NUMA
483 *
484 * These stub functions are needed to compile 32-bit NUMA when SRAT is
485 * not set. There are functions in srat_64.c for parsing this table
486 * and it may be possible to make them common functions.
487 */
488void acpi_numa_slit_init (struct acpi_table_slit *slit)
489{
490 printk(KERN_INFO "ACPI: No support for parsing SLIT table\n");
491}
492
493void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa)
494{
495}
496
497void acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma)
498{
499}
500
501void acpi_numa_arch_fixup(void)
502{
503}
504#endif /* CONFIG_HAVE_ARCH_PARSE_SRAT */
diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c
new file mode 100644
index 000000000000..7e8db53528a7
--- /dev/null
+++ b/arch/x86/mm/extable.c
@@ -0,0 +1,62 @@
1#include <linux/module.h>
2#include <linux/spinlock.h>
3#include <asm/uaccess.h>
4
5
6int fixup_exception(struct pt_regs *regs)
7{
8 const struct exception_table_entry *fixup;
9
10#ifdef CONFIG_PNPBIOS
11 if (unlikely(SEGMENT_IS_PNP_CODE(regs->cs))) {
12 extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
13 extern u32 pnp_bios_is_utter_crap;
14 pnp_bios_is_utter_crap = 1;
15 printk(KERN_CRIT "PNPBIOS fault.. attempting recovery.\n");
16 __asm__ volatile(
17 "movl %0, %%esp\n\t"
18 "jmp *%1\n\t"
19 : : "g" (pnp_bios_fault_esp), "g" (pnp_bios_fault_eip));
20 panic("do_trap: can't hit this");
21 }
22#endif
23
24 fixup = search_exception_tables(regs->ip);
25 if (fixup) {
26 regs->ip = fixup->fixup;
27 return 1;
28 }
29
30 return 0;
31}
32
33#ifdef CONFIG_X86_64
34/*
35 * Need to defined our own search_extable on X86_64 to work around
36 * a B stepping K8 bug.
37 */
38const struct exception_table_entry *
39search_extable(const struct exception_table_entry *first,
40 const struct exception_table_entry *last,
41 unsigned long value)
42{
43 /* B stepping K8 bug */
44 if ((value >> 32) == 0)
45 value |= 0xffffffffUL << 32;
46
47 while (first <= last) {
48 const struct exception_table_entry *mid;
49 long diff;
50
51 mid = (last - first) / 2 + first;
52 diff = mid->insn - value;
53 if (diff == 0)
54 return mid;
55 else if (diff < 0)
56 first = mid+1;
57 else
58 last = mid-1;
59 }
60 return NULL;
61}
62#endif
diff --git a/arch/x86/mm/extable_32.c b/arch/x86/mm/extable_32.c
deleted file mode 100644
index 0ce4f22a2635..000000000000
--- a/arch/x86/mm/extable_32.c
+++ /dev/null
@@ -1,35 +0,0 @@
1/*
2 * linux/arch/i386/mm/extable.c
3 */
4
5#include <linux/module.h>
6#include <linux/spinlock.h>
7#include <asm/uaccess.h>
8
9int fixup_exception(struct pt_regs *regs)
10{
11 const struct exception_table_entry *fixup;
12
13#ifdef CONFIG_PNPBIOS
14 if (unlikely(SEGMENT_IS_PNP_CODE(regs->xcs)))
15 {
16 extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
17 extern u32 pnp_bios_is_utter_crap;
18 pnp_bios_is_utter_crap = 1;
19 printk(KERN_CRIT "PNPBIOS fault.. attempting recovery.\n");
20 __asm__ volatile(
21 "movl %0, %%esp\n\t"
22 "jmp *%1\n\t"
23 : : "g" (pnp_bios_fault_esp), "g" (pnp_bios_fault_eip));
24 panic("do_trap: can't hit this");
25 }
26#endif
27
28 fixup = search_exception_tables(regs->eip);
29 if (fixup) {
30 regs->eip = fixup->fixup;
31 return 1;
32 }
33
34 return 0;
35}
diff --git a/arch/x86/mm/extable_64.c b/arch/x86/mm/extable_64.c
deleted file mode 100644
index 79ac6e7100af..000000000000
--- a/arch/x86/mm/extable_64.c
+++ /dev/null
@@ -1,34 +0,0 @@
1/*
2 * linux/arch/x86_64/mm/extable.c
3 */
4
5#include <linux/module.h>
6#include <linux/spinlock.h>
7#include <linux/init.h>
8#include <asm/uaccess.h>
9
10/* Simple binary search */
11const struct exception_table_entry *
12search_extable(const struct exception_table_entry *first,
13 const struct exception_table_entry *last,
14 unsigned long value)
15{
16 /* Work around a B stepping K8 bug */
17 if ((value >> 32) == 0)
18 value |= 0xffffffffUL << 32;
19
20 while (first <= last) {
21 const struct exception_table_entry *mid;
22 long diff;
23
24 mid = (last - first) / 2 + first;
25 diff = mid->insn - value;
26 if (diff == 0)
27 return mid;
28 else if (diff < 0)
29 first = mid+1;
30 else
31 last = mid-1;
32 }
33 return NULL;
34}
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
new file mode 100644
index 000000000000..e28cc5277b16
--- /dev/null
+++ b/arch/x86/mm/fault.c
@@ -0,0 +1,986 @@
1/*
2 * Copyright (C) 1995 Linus Torvalds
3 * Copyright (C) 2001,2002 Andi Kleen, SuSE Labs.
4 */
5
6#include <linux/signal.h>
7#include <linux/sched.h>
8#include <linux/kernel.h>
9#include <linux/errno.h>
10#include <linux/string.h>
11#include <linux/types.h>
12#include <linux/ptrace.h>
13#include <linux/mman.h>
14#include <linux/mm.h>
15#include <linux/smp.h>
16#include <linux/interrupt.h>
17#include <linux/init.h>
18#include <linux/tty.h>
19#include <linux/vt_kern.h> /* For unblank_screen() */
20#include <linux/compiler.h>
21#include <linux/highmem.h>
22#include <linux/bootmem.h> /* for max_low_pfn */
23#include <linux/vmalloc.h>
24#include <linux/module.h>
25#include <linux/kprobes.h>
26#include <linux/uaccess.h>
27#include <linux/kdebug.h>
28
29#include <asm/system.h>
30#include <asm/desc.h>
31#include <asm/segment.h>
32#include <asm/pgalloc.h>
33#include <asm/smp.h>
34#include <asm/tlbflush.h>
35#include <asm/proto.h>
36#include <asm-generic/sections.h>
37
38/*
39 * Page fault error code bits
40 * bit 0 == 0 means no page found, 1 means protection fault
41 * bit 1 == 0 means read, 1 means write
42 * bit 2 == 0 means kernel, 1 means user-mode
43 * bit 3 == 1 means use of reserved bit detected
44 * bit 4 == 1 means fault was an instruction fetch
45 */
46#define PF_PROT (1<<0)
47#define PF_WRITE (1<<1)
48#define PF_USER (1<<2)
49#define PF_RSVD (1<<3)
50#define PF_INSTR (1<<4)
51
52static inline int notify_page_fault(struct pt_regs *regs)
53{
54#ifdef CONFIG_KPROBES
55 int ret = 0;
56
57 /* kprobe_running() needs smp_processor_id() */
58#ifdef CONFIG_X86_32
59 if (!user_mode_vm(regs)) {
60#else
61 if (!user_mode(regs)) {
62#endif
63 preempt_disable();
64 if (kprobe_running() && kprobe_fault_handler(regs, 14))
65 ret = 1;
66 preempt_enable();
67 }
68
69 return ret;
70#else
71 return 0;
72#endif
73}
74
75/*
76 * X86_32
77 * Sometimes AMD Athlon/Opteron CPUs report invalid exceptions on prefetch.
78 * Check that here and ignore it.
79 *
80 * X86_64
81 * Sometimes the CPU reports invalid exceptions on prefetch.
82 * Check that here and ignore it.
83 *
84 * Opcode checker based on code by Richard Brunner
85 */
86static int is_prefetch(struct pt_regs *regs, unsigned long addr,
87 unsigned long error_code)
88{
89 unsigned char *instr;
90 int scan_more = 1;
91 int prefetch = 0;
92 unsigned char *max_instr;
93
94#ifdef CONFIG_X86_32
95 if (!(__supported_pte_mask & _PAGE_NX))
96 return 0;
97#endif
98
99 /* If it was a exec fault on NX page, ignore */
100 if (error_code & PF_INSTR)
101 return 0;
102
103 instr = (unsigned char *)convert_ip_to_linear(current, regs);
104 max_instr = instr + 15;
105
106 if (user_mode(regs) && instr >= (unsigned char *)TASK_SIZE)
107 return 0;
108
109 while (scan_more && instr < max_instr) {
110 unsigned char opcode;
111 unsigned char instr_hi;
112 unsigned char instr_lo;
113
114 if (probe_kernel_address(instr, opcode))
115 break;
116
117 instr_hi = opcode & 0xf0;
118 instr_lo = opcode & 0x0f;
119 instr++;
120
121 switch (instr_hi) {
122 case 0x20:
123 case 0x30:
124 /*
125 * Values 0x26,0x2E,0x36,0x3E are valid x86 prefixes.
126 * In X86_64 long mode, the CPU will signal invalid
127 * opcode if some of these prefixes are present so
128 * X86_64 will never get here anyway
129 */
130 scan_more = ((instr_lo & 7) == 0x6);
131 break;
132#ifdef CONFIG_X86_64
133 case 0x40:
134 /*
135 * In AMD64 long mode 0x40..0x4F are valid REX prefixes
136 * Need to figure out under what instruction mode the
137 * instruction was issued. Could check the LDT for lm,
138 * but for now it's good enough to assume that long
139 * mode only uses well known segments or kernel.
140 */
141 scan_more = (!user_mode(regs)) || (regs->cs == __USER_CS);
142 break;
143#endif
144 case 0x60:
145 /* 0x64 thru 0x67 are valid prefixes in all modes. */
146 scan_more = (instr_lo & 0xC) == 0x4;
147 break;
148 case 0xF0:
149 /* 0xF0, 0xF2, 0xF3 are valid prefixes in all modes. */
150 scan_more = !instr_lo || (instr_lo>>1) == 1;
151 break;
152 case 0x00:
153 /* Prefetch instruction is 0x0F0D or 0x0F18 */
154 scan_more = 0;
155
156 if (probe_kernel_address(instr, opcode))
157 break;
158 prefetch = (instr_lo == 0xF) &&
159 (opcode == 0x0D || opcode == 0x18);
160 break;
161 default:
162 scan_more = 0;
163 break;
164 }
165 }
166 return prefetch;
167}
168
169static void force_sig_info_fault(int si_signo, int si_code,
170 unsigned long address, struct task_struct *tsk)
171{
172 siginfo_t info;
173
174 info.si_signo = si_signo;
175 info.si_errno = 0;
176 info.si_code = si_code;
177 info.si_addr = (void __user *)address;
178 force_sig_info(si_signo, &info, tsk);
179}
180
181#ifdef CONFIG_X86_64
182static int bad_address(void *p)
183{
184 unsigned long dummy;
185 return probe_kernel_address((unsigned long *)p, dummy);
186}
187#endif
188
189void dump_pagetable(unsigned long address)
190{
191#ifdef CONFIG_X86_32
192 __typeof__(pte_val(__pte(0))) page;
193
194 page = read_cr3();
195 page = ((__typeof__(page) *) __va(page))[address >> PGDIR_SHIFT];
196#ifdef CONFIG_X86_PAE
197 printk("*pdpt = %016Lx ", page);
198 if ((page >> PAGE_SHIFT) < max_low_pfn
199 && page & _PAGE_PRESENT) {
200 page &= PAGE_MASK;
201 page = ((__typeof__(page) *) __va(page))[(address >> PMD_SHIFT)
202 & (PTRS_PER_PMD - 1)];
203 printk(KERN_CONT "*pde = %016Lx ", page);
204 page &= ~_PAGE_NX;
205 }
206#else
207 printk("*pde = %08lx ", page);
208#endif
209
210 /*
211 * We must not directly access the pte in the highpte
212 * case if the page table is located in highmem.
213 * And let's rather not kmap-atomic the pte, just in case
214 * it's allocated already.
215 */
216 if ((page >> PAGE_SHIFT) < max_low_pfn
217 && (page & _PAGE_PRESENT)
218 && !(page & _PAGE_PSE)) {
219 page &= PAGE_MASK;
220 page = ((__typeof__(page) *) __va(page))[(address >> PAGE_SHIFT)
221 & (PTRS_PER_PTE - 1)];
222 printk("*pte = %0*Lx ", sizeof(page)*2, (u64)page);
223 }
224
225 printk("\n");
226#else /* CONFIG_X86_64 */
227 pgd_t *pgd;
228 pud_t *pud;
229 pmd_t *pmd;
230 pte_t *pte;
231
232 pgd = (pgd_t *)read_cr3();
233
234 pgd = __va((unsigned long)pgd & PHYSICAL_PAGE_MASK);
235 pgd += pgd_index(address);
236 if (bad_address(pgd)) goto bad;
237 printk("PGD %lx ", pgd_val(*pgd));
238 if (!pgd_present(*pgd)) goto ret;
239
240 pud = pud_offset(pgd, address);
241 if (bad_address(pud)) goto bad;
242 printk("PUD %lx ", pud_val(*pud));
243 if (!pud_present(*pud)) goto ret;
244
245 pmd = pmd_offset(pud, address);
246 if (bad_address(pmd)) goto bad;
247 printk("PMD %lx ", pmd_val(*pmd));
248 if (!pmd_present(*pmd) || pmd_large(*pmd)) goto ret;
249
250 pte = pte_offset_kernel(pmd, address);
251 if (bad_address(pte)) goto bad;
252 printk("PTE %lx", pte_val(*pte));
253ret:
254 printk("\n");
255 return;
256bad:
257 printk("BAD\n");
258#endif
259}
260
261#ifdef CONFIG_X86_32
262static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
263{
264 unsigned index = pgd_index(address);
265 pgd_t *pgd_k;
266 pud_t *pud, *pud_k;
267 pmd_t *pmd, *pmd_k;
268
269 pgd += index;
270 pgd_k = init_mm.pgd + index;
271
272 if (!pgd_present(*pgd_k))
273 return NULL;
274
275 /*
276 * set_pgd(pgd, *pgd_k); here would be useless on PAE
277 * and redundant with the set_pmd() on non-PAE. As would
278 * set_pud.
279 */
280
281 pud = pud_offset(pgd, address);
282 pud_k = pud_offset(pgd_k, address);
283 if (!pud_present(*pud_k))
284 return NULL;
285
286 pmd = pmd_offset(pud, address);
287 pmd_k = pmd_offset(pud_k, address);
288 if (!pmd_present(*pmd_k))
289 return NULL;
290 if (!pmd_present(*pmd)) {
291 set_pmd(pmd, *pmd_k);
292 arch_flush_lazy_mmu_mode();
293 } else
294 BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k));
295 return pmd_k;
296}
297#endif
298
299#ifdef CONFIG_X86_64
300static const char errata93_warning[] =
301KERN_ERR "******* Your BIOS seems to not contain a fix for K8 errata #93\n"
302KERN_ERR "******* Working around it, but it may cause SEGVs or burn power.\n"
303KERN_ERR "******* Please consider a BIOS update.\n"
304KERN_ERR "******* Disabling USB legacy in the BIOS may also help.\n";
305#endif
306
307/* Workaround for K8 erratum #93 & buggy BIOS.
308 BIOS SMM functions are required to use a specific workaround
309 to avoid corruption of the 64bit RIP register on C stepping K8.
310 A lot of BIOS that didn't get tested properly miss this.
311 The OS sees this as a page fault with the upper 32bits of RIP cleared.
312 Try to work around it here.
313 Note we only handle faults in kernel here.
314 Does nothing for X86_32
315 */
316static int is_errata93(struct pt_regs *regs, unsigned long address)
317{
318#ifdef CONFIG_X86_64
319 static int warned;
320 if (address != regs->ip)
321 return 0;
322 if ((address >> 32) != 0)
323 return 0;
324 address |= 0xffffffffUL << 32;
325 if ((address >= (u64)_stext && address <= (u64)_etext) ||
326 (address >= MODULES_VADDR && address <= MODULES_END)) {
327 if (!warned) {
328 printk(errata93_warning);
329 warned = 1;
330 }
331 regs->ip = address;
332 return 1;
333 }
334#endif
335 return 0;
336}
337
338/*
339 * Work around K8 erratum #100 K8 in compat mode occasionally jumps to illegal
340 * addresses >4GB. We catch this in the page fault handler because these
341 * addresses are not reachable. Just detect this case and return. Any code
342 * segment in LDT is compatibility mode.
343 */
344static int is_errata100(struct pt_regs *regs, unsigned long address)
345{
346#ifdef CONFIG_X86_64
347 if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) &&
348 (address >> 32))
349 return 1;
350#endif
351 return 0;
352}
353
354void do_invalid_op(struct pt_regs *, unsigned long);
355
356static int is_f00f_bug(struct pt_regs *regs, unsigned long address)
357{
358#ifdef CONFIG_X86_F00F_BUG
359 unsigned long nr;
360 /*
361 * Pentium F0 0F C7 C8 bug workaround.
362 */
363 if (boot_cpu_data.f00f_bug) {
364 nr = (address - idt_descr.address) >> 3;
365
366 if (nr == 6) {
367 do_invalid_op(regs, 0);
368 return 1;
369 }
370 }
371#endif
372 return 0;
373}
374
375static void show_fault_oops(struct pt_regs *regs, unsigned long error_code,
376 unsigned long address)
377{
378#ifdef CONFIG_X86_32
379 if (!oops_may_print())
380 return;
381#endif
382
383#ifdef CONFIG_X86_PAE
384 if (error_code & PF_INSTR) {
385 int level;
386 pte_t *pte = lookup_address(address, &level);
387
388 if (pte && pte_present(*pte) && !pte_exec(*pte))
389 printk(KERN_CRIT "kernel tried to execute "
390 "NX-protected page - exploit attempt? "
391 "(uid: %d)\n", current->uid);
392 }
393#endif
394
395 printk(KERN_ALERT "BUG: unable to handle kernel ");
396 if (address < PAGE_SIZE)
397 printk(KERN_CONT "NULL pointer dereference");
398 else
399 printk(KERN_CONT "paging request");
400#ifdef CONFIG_X86_32
401 printk(KERN_CONT " at %08lx\n", address);
402#else
403 printk(KERN_CONT " at %016lx\n", address);
404#endif
405 printk(KERN_ALERT "IP:");
406 printk_address(regs->ip, 1);
407 dump_pagetable(address);
408}
409
410#ifdef CONFIG_X86_64
411static noinline void pgtable_bad(unsigned long address, struct pt_regs *regs,
412 unsigned long error_code)
413{
414 unsigned long flags = oops_begin();
415 struct task_struct *tsk;
416
417 printk(KERN_ALERT "%s: Corrupted page table at address %lx\n",
418 current->comm, address);
419 dump_pagetable(address);
420 tsk = current;
421 tsk->thread.cr2 = address;
422 tsk->thread.trap_no = 14;
423 tsk->thread.error_code = error_code;
424 if (__die("Bad pagetable", regs, error_code))
425 regs = NULL;
426 oops_end(flags, regs, SIGKILL);
427}
428#endif
429
430/*
431 * Handle a spurious fault caused by a stale TLB entry. This allows
432 * us to lazily refresh the TLB when increasing the permissions of a
433 * kernel page (RO -> RW or NX -> X). Doing it eagerly is very
434 * expensive since that implies doing a full cross-processor TLB
435 * flush, even if no stale TLB entries exist on other processors.
436 * There are no security implications to leaving a stale TLB when
437 * increasing the permissions on a page.
438 */
439static int spurious_fault(unsigned long address,
440 unsigned long error_code)
441{
442 pgd_t *pgd;
443 pud_t *pud;
444 pmd_t *pmd;
445 pte_t *pte;
446
447 /* Reserved-bit violation or user access to kernel space? */
448 if (error_code & (PF_USER | PF_RSVD))
449 return 0;
450
451 pgd = init_mm.pgd + pgd_index(address);
452 if (!pgd_present(*pgd))
453 return 0;
454
455 pud = pud_offset(pgd, address);
456 if (!pud_present(*pud))
457 return 0;
458
459 pmd = pmd_offset(pud, address);
460 if (!pmd_present(*pmd))
461 return 0;
462
463 pte = pte_offset_kernel(pmd, address);
464 if (!pte_present(*pte))
465 return 0;
466
467 if ((error_code & PF_WRITE) && !pte_write(*pte))
468 return 0;
469 if ((error_code & PF_INSTR) && !pte_exec(*pte))
470 return 0;
471
472 return 1;
473}
474
475/*
476 * X86_32
477 * Handle a fault on the vmalloc or module mapping area
478 *
479 * X86_64
480 * Handle a fault on the vmalloc area
481 *
482 * This assumes no large pages in there.
483 */
484static int vmalloc_fault(unsigned long address)
485{
486#ifdef CONFIG_X86_32
487 unsigned long pgd_paddr;
488 pmd_t *pmd_k;
489 pte_t *pte_k;
490 /*
491 * Synchronize this task's top level page-table
492 * with the 'reference' page table.
493 *
494 * Do _not_ use "current" here. We might be inside
495 * an interrupt in the middle of a task switch..
496 */
497 pgd_paddr = read_cr3();
498 pmd_k = vmalloc_sync_one(__va(pgd_paddr), address);
499 if (!pmd_k)
500 return -1;
501 pte_k = pte_offset_kernel(pmd_k, address);
502 if (!pte_present(*pte_k))
503 return -1;
504 return 0;
505#else
506 pgd_t *pgd, *pgd_ref;
507 pud_t *pud, *pud_ref;
508 pmd_t *pmd, *pmd_ref;
509 pte_t *pte, *pte_ref;
510
511 /* Copy kernel mappings over when needed. This can also
512 happen within a race in page table update. In the later
513 case just flush. */
514
515 pgd = pgd_offset(current->mm ?: &init_mm, address);
516 pgd_ref = pgd_offset_k(address);
517 if (pgd_none(*pgd_ref))
518 return -1;
519 if (pgd_none(*pgd))
520 set_pgd(pgd, *pgd_ref);
521 else
522 BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref));
523
524 /* Below here mismatches are bugs because these lower tables
525 are shared */
526
527 pud = pud_offset(pgd, address);
528 pud_ref = pud_offset(pgd_ref, address);
529 if (pud_none(*pud_ref))
530 return -1;
531 if (pud_none(*pud) || pud_page_vaddr(*pud) != pud_page_vaddr(*pud_ref))
532 BUG();
533 pmd = pmd_offset(pud, address);
534 pmd_ref = pmd_offset(pud_ref, address);
535 if (pmd_none(*pmd_ref))
536 return -1;
537 if (pmd_none(*pmd) || pmd_page(*pmd) != pmd_page(*pmd_ref))
538 BUG();
539 pte_ref = pte_offset_kernel(pmd_ref, address);
540 if (!pte_present(*pte_ref))
541 return -1;
542 pte = pte_offset_kernel(pmd, address);
543 /* Don't use pte_page here, because the mappings can point
544 outside mem_map, and the NUMA hash lookup cannot handle
545 that. */
546 if (!pte_present(*pte) || pte_pfn(*pte) != pte_pfn(*pte_ref))
547 BUG();
548 return 0;
549#endif
550}
551
552int show_unhandled_signals = 1;
553
554/*
555 * This routine handles page faults. It determines the address,
556 * and the problem, and then passes it off to one of the appropriate
557 * routines.
558 */
559#ifdef CONFIG_X86_64
560asmlinkage
561#endif
562void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
563{
564 struct task_struct *tsk;
565 struct mm_struct *mm;
566 struct vm_area_struct *vma;
567 unsigned long address;
568 int write, si_code;
569 int fault;
570#ifdef CONFIG_X86_64
571 unsigned long flags;
572#endif
573
574 /*
575 * We can fault from pretty much anywhere, with unknown IRQ state.
576 */
577 trace_hardirqs_fixup();
578
579 tsk = current;
580 mm = tsk->mm;
581 prefetchw(&mm->mmap_sem);
582
583 /* get the address */
584 address = read_cr2();
585
586 si_code = SEGV_MAPERR;
587
588 if (notify_page_fault(regs))
589 return;
590
591 /*
592 * We fault-in kernel-space virtual memory on-demand. The
593 * 'reference' page table is init_mm.pgd.
594 *
595 * NOTE! We MUST NOT take any locks for this case. We may
596 * be in an interrupt or a critical region, and should
597 * only copy the information from the master page table,
598 * nothing more.
599 *
600 * This verifies that the fault happens in kernel space
601 * (error_code & 4) == 0, and that the fault was not a
602 * protection error (error_code & 9) == 0.
603 */
604#ifdef CONFIG_X86_32
605 if (unlikely(address >= TASK_SIZE)) {
606 if (!(error_code & (PF_RSVD|PF_USER|PF_PROT)) &&
607 vmalloc_fault(address) >= 0)
608 return;
609
610 /* Can handle a stale RO->RW TLB */
611 if (spurious_fault(address, error_code))
612 return;
613
614 /*
615 * Don't take the mm semaphore here. If we fixup a prefetch
616 * fault we could otherwise deadlock.
617 */
618 goto bad_area_nosemaphore;
619 }
620
621 /* It's safe to allow irq's after cr2 has been saved and the vmalloc
622 fault has been handled. */
623 if (regs->flags & (X86_EFLAGS_IF|VM_MASK))
624 local_irq_enable();
625
626 /*
627 * If we're in an interrupt, have no user context or are running in an
628 * atomic region then we must not take the fault.
629 */
630 if (in_atomic() || !mm)
631 goto bad_area_nosemaphore;
632#else /* CONFIG_X86_64 */
633 if (unlikely(address >= TASK_SIZE64)) {
634 /*
635 * Don't check for the module range here: its PML4
636 * is always initialized because it's shared with the main
637 * kernel text. Only vmalloc may need PML4 syncups.
638 */
639 if (!(error_code & (PF_RSVD|PF_USER|PF_PROT)) &&
640 ((address >= VMALLOC_START && address < VMALLOC_END))) {
641 if (vmalloc_fault(address) >= 0)
642 return;
643 }
644
645 /* Can handle a stale RO->RW TLB */
646 if (spurious_fault(address, error_code))
647 return;
648
649 /*
650 * Don't take the mm semaphore here. If we fixup a prefetch
651 * fault we could otherwise deadlock.
652 */
653 goto bad_area_nosemaphore;
654 }
655 if (likely(regs->flags & X86_EFLAGS_IF))
656 local_irq_enable();
657
658 if (unlikely(error_code & PF_RSVD))
659 pgtable_bad(address, regs, error_code);
660
661 /*
662 * If we're in an interrupt, have no user context or are running in an
663 * atomic region then we must not take the fault.
664 */
665 if (unlikely(in_atomic() || !mm))
666 goto bad_area_nosemaphore;
667
668 /*
669 * User-mode registers count as a user access even for any
670 * potential system fault or CPU buglet.
671 */
672 if (user_mode_vm(regs))
673 error_code |= PF_USER;
674again:
675#endif
676 /* When running in the kernel we expect faults to occur only to
677 * addresses in user space. All other faults represent errors in the
678 * kernel and should generate an OOPS. Unfortunately, in the case of an
679 * erroneous fault occurring in a code path which already holds mmap_sem
680 * we will deadlock attempting to validate the fault against the
681 * address space. Luckily the kernel only validly references user
682 * space from well defined areas of code, which are listed in the
683 * exceptions table.
684 *
685 * As the vast majority of faults will be valid we will only perform
686 * the source reference check when there is a possibility of a deadlock.
687 * Attempt to lock the address space, if we cannot we then validate the
688 * source. If this is invalid we can skip the address space check,
689 * thus avoiding the deadlock.
690 */
691 if (!down_read_trylock(&mm->mmap_sem)) {
692 if ((error_code & PF_USER) == 0 &&
693 !search_exception_tables(regs->ip))
694 goto bad_area_nosemaphore;
695 down_read(&mm->mmap_sem);
696 }
697
698 vma = find_vma(mm, address);
699 if (!vma)
700 goto bad_area;
701 if (vma->vm_start <= address)
702 goto good_area;
703 if (!(vma->vm_flags & VM_GROWSDOWN))
704 goto bad_area;
705 if (error_code & PF_USER) {
706 /*
707 * Accessing the stack below %sp is always a bug.
708 * The large cushion allows instructions like enter
709 * and pusha to work. ("enter $65535,$31" pushes
710 * 32 pointers and then decrements %sp by 65535.)
711 */
712 if (address + 65536 + 32 * sizeof(unsigned long) < regs->sp)
713 goto bad_area;
714 }
715 if (expand_stack(vma, address))
716 goto bad_area;
717/*
718 * Ok, we have a good vm_area for this memory access, so
719 * we can handle it..
720 */
721good_area:
722 si_code = SEGV_ACCERR;
723 write = 0;
724 switch (error_code & (PF_PROT|PF_WRITE)) {
725 default: /* 3: write, present */
726 /* fall through */
727 case PF_WRITE: /* write, not present */
728 if (!(vma->vm_flags & VM_WRITE))
729 goto bad_area;
730 write++;
731 break;
732 case PF_PROT: /* read, present */
733 goto bad_area;
734 case 0: /* read, not present */
735 if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
736 goto bad_area;
737 }
738
739#ifdef CONFIG_X86_32
740survive:
741#endif
742 /*
743 * If for any reason at all we couldn't handle the fault,
744 * make sure we exit gracefully rather than endlessly redo
745 * the fault.
746 */
747 fault = handle_mm_fault(mm, vma, address, write);
748 if (unlikely(fault & VM_FAULT_ERROR)) {
749 if (fault & VM_FAULT_OOM)
750 goto out_of_memory;
751 else if (fault & VM_FAULT_SIGBUS)
752 goto do_sigbus;
753 BUG();
754 }
755 if (fault & VM_FAULT_MAJOR)
756 tsk->maj_flt++;
757 else
758 tsk->min_flt++;
759
760#ifdef CONFIG_X86_32
761 /*
762 * Did it hit the DOS screen memory VA from vm86 mode?
763 */
764 if (v8086_mode(regs)) {
765 unsigned long bit = (address - 0xA0000) >> PAGE_SHIFT;
766 if (bit < 32)
767 tsk->thread.screen_bitmap |= 1 << bit;
768 }
769#endif
770 up_read(&mm->mmap_sem);
771 return;
772
773/*
774 * Something tried to access memory that isn't in our memory map..
775 * Fix it, but check if it's kernel or user first..
776 */
777bad_area:
778 up_read(&mm->mmap_sem);
779
780bad_area_nosemaphore:
781 /* User mode accesses just cause a SIGSEGV */
782 if (error_code & PF_USER) {
783 /*
784 * It's possible to have interrupts off here.
785 */
786 local_irq_enable();
787
788 /*
789 * Valid to do another page fault here because this one came
790 * from user space.
791 */
792 if (is_prefetch(regs, address, error_code))
793 return;
794
795 if (is_errata100(regs, address))
796 return;
797
798 if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
799 printk_ratelimit()) {
800 printk(
801#ifdef CONFIG_X86_32
802 "%s%s[%d]: segfault at %lx ip %08lx sp %08lx error %lx",
803#else
804 "%s%s[%d]: segfault at %lx ip %lx sp %lx error %lx",
805#endif
806 task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
807 tsk->comm, task_pid_nr(tsk), address, regs->ip,
808 regs->sp, error_code);
809 print_vma_addr(" in ", regs->ip);
810 printk("\n");
811 }
812
813 tsk->thread.cr2 = address;
814 /* Kernel addresses are always protection faults */
815 tsk->thread.error_code = error_code | (address >= TASK_SIZE);
816 tsk->thread.trap_no = 14;
817 force_sig_info_fault(SIGSEGV, si_code, address, tsk);
818 return;
819 }
820
821 if (is_f00f_bug(regs, address))
822 return;
823
824no_context:
825 /* Are we prepared to handle this kernel fault? */
826 if (fixup_exception(regs))
827 return;
828
829 /*
830 * X86_32
831 * Valid to do another page fault here, because if this fault
832 * had been triggered by is_prefetch fixup_exception would have
833 * handled it.
834 *
835 * X86_64
836 * Hall of shame of CPU/BIOS bugs.
837 */
838 if (is_prefetch(regs, address, error_code))
839 return;
840
841 if (is_errata93(regs, address))
842 return;
843
844/*
845 * Oops. The kernel tried to access some bad page. We'll have to
846 * terminate things with extreme prejudice.
847 */
848#ifdef CONFIG_X86_32
849 bust_spinlocks(1);
850#else
851 flags = oops_begin();
852#endif
853
854 show_fault_oops(regs, error_code, address);
855
856 tsk->thread.cr2 = address;
857 tsk->thread.trap_no = 14;
858 tsk->thread.error_code = error_code;
859
860#ifdef CONFIG_X86_32
861 die("Oops", regs, error_code);
862 bust_spinlocks(0);
863 do_exit(SIGKILL);
864#else
865 if (__die("Oops", regs, error_code))
866 regs = NULL;
867 /* Executive summary in case the body of the oops scrolled away */
868 printk(KERN_EMERG "CR2: %016lx\n", address);
869 oops_end(flags, regs, SIGKILL);
870#endif
871
872/*
873 * We ran out of memory, or some other thing happened to us that made
874 * us unable to handle the page fault gracefully.
875 */
876out_of_memory:
877 up_read(&mm->mmap_sem);
878 if (is_global_init(tsk)) {
879 yield();
880#ifdef CONFIG_X86_32
881 down_read(&mm->mmap_sem);
882 goto survive;
883#else
884 goto again;
885#endif
886 }
887
888 printk("VM: killing process %s\n", tsk->comm);
889 if (error_code & PF_USER)
890 do_group_exit(SIGKILL);
891 goto no_context;
892
893do_sigbus:
894 up_read(&mm->mmap_sem);
895
896 /* Kernel mode? Handle exceptions or die */
897 if (!(error_code & PF_USER))
898 goto no_context;
899#ifdef CONFIG_X86_32
900 /* User space => ok to do another page fault */
901 if (is_prefetch(regs, address, error_code))
902 return;
903#endif
904 tsk->thread.cr2 = address;
905 tsk->thread.error_code = error_code;
906 tsk->thread.trap_no = 14;
907 force_sig_info_fault(SIGBUS, BUS_ADRERR, address, tsk);
908}
909
910DEFINE_SPINLOCK(pgd_lock);
911LIST_HEAD(pgd_list);
912
913void vmalloc_sync_all(void)
914{
915#ifdef CONFIG_X86_32
916 /*
917 * Note that races in the updates of insync and start aren't
918 * problematic: insync can only get set bits added, and updates to
919 * start are only improving performance (without affecting correctness
920 * if undone).
921 */
922 static DECLARE_BITMAP(insync, PTRS_PER_PGD);
923 static unsigned long start = TASK_SIZE;
924 unsigned long address;
925
926 if (SHARED_KERNEL_PMD)
927 return;
928
929 BUILD_BUG_ON(TASK_SIZE & ~PGDIR_MASK);
930 for (address = start; address >= TASK_SIZE; address += PGDIR_SIZE) {
931 if (!test_bit(pgd_index(address), insync)) {
932 unsigned long flags;
933 struct page *page;
934
935 spin_lock_irqsave(&pgd_lock, flags);
936 list_for_each_entry(page, &pgd_list, lru) {
937 if (!vmalloc_sync_one(page_address(page),
938 address))
939 break;
940 }
941 spin_unlock_irqrestore(&pgd_lock, flags);
942 if (!page)
943 set_bit(pgd_index(address), insync);
944 }
945 if (address == start && test_bit(pgd_index(address), insync))
946 start = address + PGDIR_SIZE;
947 }
948#else /* CONFIG_X86_64 */
949 /*
950 * Note that races in the updates of insync and start aren't
951 * problematic: insync can only get set bits added, and updates to
952 * start are only improving performance (without affecting correctness
953 * if undone).
954 */
955 static DECLARE_BITMAP(insync, PTRS_PER_PGD);
956 static unsigned long start = VMALLOC_START & PGDIR_MASK;
957 unsigned long address;
958
959 for (address = start; address <= VMALLOC_END; address += PGDIR_SIZE) {
960 if (!test_bit(pgd_index(address), insync)) {
961 const pgd_t *pgd_ref = pgd_offset_k(address);
962 struct page *page;
963
964 if (pgd_none(*pgd_ref))
965 continue;
966 spin_lock(&pgd_lock);
967 list_for_each_entry(page, &pgd_list, lru) {
968 pgd_t *pgd;
969 pgd = (pgd_t *)page_address(page) + pgd_index(address);
970 if (pgd_none(*pgd))
971 set_pgd(pgd, *pgd_ref);
972 else
973 BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref));
974 }
975 spin_unlock(&pgd_lock);
976 set_bit(pgd_index(address), insync);
977 }
978 if (address == start)
979 start = address + PGDIR_SIZE;
980 }
981 /* Check that there is no need to do the same for the modules area. */
982 BUILD_BUG_ON(!(MODULES_VADDR > __START_KERNEL));
983 BUILD_BUG_ON(!(((MODULES_END - 1) & PGDIR_MASK) ==
984 (__START_KERNEL & PGDIR_MASK)));
985#endif
986}
diff --git a/arch/x86/mm/fault_32.c b/arch/x86/mm/fault_32.c
deleted file mode 100644
index a2273d44aa27..000000000000
--- a/arch/x86/mm/fault_32.c
+++ /dev/null
@@ -1,659 +0,0 @@
1/*
2 * linux/arch/i386/mm/fault.c
3 *
4 * Copyright (C) 1995 Linus Torvalds
5 */
6
7#include <linux/signal.h>
8#include <linux/sched.h>
9#include <linux/kernel.h>
10#include <linux/errno.h>
11#include <linux/string.h>
12#include <linux/types.h>
13#include <linux/ptrace.h>
14#include <linux/mman.h>
15#include <linux/mm.h>
16#include <linux/smp.h>
17#include <linux/interrupt.h>
18#include <linux/init.h>
19#include <linux/tty.h>
20#include <linux/vt_kern.h> /* For unblank_screen() */
21#include <linux/highmem.h>
22#include <linux/bootmem.h> /* for max_low_pfn */
23#include <linux/vmalloc.h>
24#include <linux/module.h>
25#include <linux/kprobes.h>
26#include <linux/uaccess.h>
27#include <linux/kdebug.h>
28#include <linux/kprobes.h>
29
30#include <asm/system.h>
31#include <asm/desc.h>
32#include <asm/segment.h>
33
34extern void die(const char *,struct pt_regs *,long);
35
36#ifdef CONFIG_KPROBES
37static inline int notify_page_fault(struct pt_regs *regs)
38{
39 int ret = 0;
40
41 /* kprobe_running() needs smp_processor_id() */
42 if (!user_mode_vm(regs)) {
43 preempt_disable();
44 if (kprobe_running() && kprobe_fault_handler(regs, 14))
45 ret = 1;
46 preempt_enable();
47 }
48
49 return ret;
50}
51#else
52static inline int notify_page_fault(struct pt_regs *regs)
53{
54 return 0;
55}
56#endif
57
58/*
59 * Return EIP plus the CS segment base. The segment limit is also
60 * adjusted, clamped to the kernel/user address space (whichever is
61 * appropriate), and returned in *eip_limit.
62 *
63 * The segment is checked, because it might have been changed by another
64 * task between the original faulting instruction and here.
65 *
66 * If CS is no longer a valid code segment, or if EIP is beyond the
67 * limit, or if it is a kernel address when CS is not a kernel segment,
68 * then the returned value will be greater than *eip_limit.
69 *
70 * This is slow, but is very rarely executed.
71 */
72static inline unsigned long get_segment_eip(struct pt_regs *regs,
73 unsigned long *eip_limit)
74{
75 unsigned long eip = regs->eip;
76 unsigned seg = regs->xcs & 0xffff;
77 u32 seg_ar, seg_limit, base, *desc;
78
79 /* Unlikely, but must come before segment checks. */
80 if (unlikely(regs->eflags & VM_MASK)) {
81 base = seg << 4;
82 *eip_limit = base + 0xffff;
83 return base + (eip & 0xffff);
84 }
85
86 /* The standard kernel/user address space limit. */
87 *eip_limit = user_mode(regs) ? USER_DS.seg : KERNEL_DS.seg;
88
89 /* By far the most common cases. */
90 if (likely(SEGMENT_IS_FLAT_CODE(seg)))
91 return eip;
92
93 /* Check the segment exists, is within the current LDT/GDT size,
94 that kernel/user (ring 0..3) has the appropriate privilege,
95 that it's a code segment, and get the limit. */
96 __asm__ ("larl %3,%0; lsll %3,%1"
97 : "=&r" (seg_ar), "=r" (seg_limit) : "0" (0), "rm" (seg));
98 if ((~seg_ar & 0x9800) || eip > seg_limit) {
99 *eip_limit = 0;
100 return 1; /* So that returned eip > *eip_limit. */
101 }
102
103 /* Get the GDT/LDT descriptor base.
104 When you look for races in this code remember that
105 LDT and other horrors are only used in user space. */
106 if (seg & (1<<2)) {
107 /* Must lock the LDT while reading it. */
108 mutex_lock(&current->mm->context.lock);
109 desc = current->mm->context.ldt;
110 desc = (void *)desc + (seg & ~7);
111 } else {
112 /* Must disable preemption while reading the GDT. */
113 desc = (u32 *)get_cpu_gdt_table(get_cpu());
114 desc = (void *)desc + (seg & ~7);
115 }
116
117 /* Decode the code segment base from the descriptor */
118 base = get_desc_base((unsigned long *)desc);
119
120 if (seg & (1<<2)) {
121 mutex_unlock(&current->mm->context.lock);
122 } else
123 put_cpu();
124
125 /* Adjust EIP and segment limit, and clamp at the kernel limit.
126 It's legitimate for segments to wrap at 0xffffffff. */
127 seg_limit += base;
128 if (seg_limit < *eip_limit && seg_limit >= base)
129 *eip_limit = seg_limit;
130 return eip + base;
131}
132
133/*
134 * Sometimes AMD Athlon/Opteron CPUs report invalid exceptions on prefetch.
135 * Check that here and ignore it.
136 */
137static int __is_prefetch(struct pt_regs *regs, unsigned long addr)
138{
139 unsigned long limit;
140 unsigned char *instr = (unsigned char *)get_segment_eip (regs, &limit);
141 int scan_more = 1;
142 int prefetch = 0;
143 int i;
144
145 for (i = 0; scan_more && i < 15; i++) {
146 unsigned char opcode;
147 unsigned char instr_hi;
148 unsigned char instr_lo;
149
150 if (instr > (unsigned char *)limit)
151 break;
152 if (probe_kernel_address(instr, opcode))
153 break;
154
155 instr_hi = opcode & 0xf0;
156 instr_lo = opcode & 0x0f;
157 instr++;
158
159 switch (instr_hi) {
160 case 0x20:
161 case 0x30:
162 /* Values 0x26,0x2E,0x36,0x3E are valid x86 prefixes. */
163 scan_more = ((instr_lo & 7) == 0x6);
164 break;
165
166 case 0x60:
167 /* 0x64 thru 0x67 are valid prefixes in all modes. */
168 scan_more = (instr_lo & 0xC) == 0x4;
169 break;
170 case 0xF0:
171 /* 0xF0, 0xF2, and 0xF3 are valid prefixes */
172 scan_more = !instr_lo || (instr_lo>>1) == 1;
173 break;
174 case 0x00:
175 /* Prefetch instruction is 0x0F0D or 0x0F18 */
176 scan_more = 0;
177 if (instr > (unsigned char *)limit)
178 break;
179 if (probe_kernel_address(instr, opcode))
180 break;
181 prefetch = (instr_lo == 0xF) &&
182 (opcode == 0x0D || opcode == 0x18);
183 break;
184 default:
185 scan_more = 0;
186 break;
187 }
188 }
189 return prefetch;
190}
191
192static inline int is_prefetch(struct pt_regs *regs, unsigned long addr,
193 unsigned long error_code)
194{
195 if (unlikely(boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
196 boot_cpu_data.x86 >= 6)) {
197 /* Catch an obscure case of prefetch inside an NX page. */
198 if (nx_enabled && (error_code & 16))
199 return 0;
200 return __is_prefetch(regs, addr);
201 }
202 return 0;
203}
204
205static noinline void force_sig_info_fault(int si_signo, int si_code,
206 unsigned long address, struct task_struct *tsk)
207{
208 siginfo_t info;
209
210 info.si_signo = si_signo;
211 info.si_errno = 0;
212 info.si_code = si_code;
213 info.si_addr = (void __user *)address;
214 force_sig_info(si_signo, &info, tsk);
215}
216
217fastcall void do_invalid_op(struct pt_regs *, unsigned long);
218
219static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
220{
221 unsigned index = pgd_index(address);
222 pgd_t *pgd_k;
223 pud_t *pud, *pud_k;
224 pmd_t *pmd, *pmd_k;
225
226 pgd += index;
227 pgd_k = init_mm.pgd + index;
228
229 if (!pgd_present(*pgd_k))
230 return NULL;
231
232 /*
233 * set_pgd(pgd, *pgd_k); here would be useless on PAE
234 * and redundant with the set_pmd() on non-PAE. As would
235 * set_pud.
236 */
237
238 pud = pud_offset(pgd, address);
239 pud_k = pud_offset(pgd_k, address);
240 if (!pud_present(*pud_k))
241 return NULL;
242
243 pmd = pmd_offset(pud, address);
244 pmd_k = pmd_offset(pud_k, address);
245 if (!pmd_present(*pmd_k))
246 return NULL;
247 if (!pmd_present(*pmd)) {
248 set_pmd(pmd, *pmd_k);
249 arch_flush_lazy_mmu_mode();
250 } else
251 BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k));
252 return pmd_k;
253}
254
255/*
256 * Handle a fault on the vmalloc or module mapping area
257 *
258 * This assumes no large pages in there.
259 */
260static inline int vmalloc_fault(unsigned long address)
261{
262 unsigned long pgd_paddr;
263 pmd_t *pmd_k;
264 pte_t *pte_k;
265 /*
266 * Synchronize this task's top level page-table
267 * with the 'reference' page table.
268 *
269 * Do _not_ use "current" here. We might be inside
270 * an interrupt in the middle of a task switch..
271 */
272 pgd_paddr = read_cr3();
273 pmd_k = vmalloc_sync_one(__va(pgd_paddr), address);
274 if (!pmd_k)
275 return -1;
276 pte_k = pte_offset_kernel(pmd_k, address);
277 if (!pte_present(*pte_k))
278 return -1;
279 return 0;
280}
281
282int show_unhandled_signals = 1;
283
284/*
285 * This routine handles page faults. It determines the address,
286 * and the problem, and then passes it off to one of the appropriate
287 * routines.
288 *
289 * error_code:
290 * bit 0 == 0 means no page found, 1 means protection fault
291 * bit 1 == 0 means read, 1 means write
292 * bit 2 == 0 means kernel, 1 means user-mode
293 * bit 3 == 1 means use of reserved bit detected
294 * bit 4 == 1 means fault was an instruction fetch
295 */
296fastcall void __kprobes do_page_fault(struct pt_regs *regs,
297 unsigned long error_code)
298{
299 struct task_struct *tsk;
300 struct mm_struct *mm;
301 struct vm_area_struct * vma;
302 unsigned long address;
303 int write, si_code;
304 int fault;
305
306 /*
307 * We can fault from pretty much anywhere, with unknown IRQ state.
308 */
309 trace_hardirqs_fixup();
310
311 /* get the address */
312 address = read_cr2();
313
314 tsk = current;
315
316 si_code = SEGV_MAPERR;
317
318 /*
319 * We fault-in kernel-space virtual memory on-demand. The
320 * 'reference' page table is init_mm.pgd.
321 *
322 * NOTE! We MUST NOT take any locks for this case. We may
323 * be in an interrupt or a critical region, and should
324 * only copy the information from the master page table,
325 * nothing more.
326 *
327 * This verifies that the fault happens in kernel space
328 * (error_code & 4) == 0, and that the fault was not a
329 * protection error (error_code & 9) == 0.
330 */
331 if (unlikely(address >= TASK_SIZE)) {
332 if (!(error_code & 0x0000000d) && vmalloc_fault(address) >= 0)
333 return;
334 if (notify_page_fault(regs))
335 return;
336 /*
337 * Don't take the mm semaphore here. If we fixup a prefetch
338 * fault we could otherwise deadlock.
339 */
340 goto bad_area_nosemaphore;
341 }
342
343 if (notify_page_fault(regs))
344 return;
345
346 /* It's safe to allow irq's after cr2 has been saved and the vmalloc
347 fault has been handled. */
348 if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
349 local_irq_enable();
350
351 mm = tsk->mm;
352
353 /*
354 * If we're in an interrupt, have no user context or are running in an
355 * atomic region then we must not take the fault..
356 */
357 if (in_atomic() || !mm)
358 goto bad_area_nosemaphore;
359
360 /* When running in the kernel we expect faults to occur only to
361 * addresses in user space. All other faults represent errors in the
362 * kernel and should generate an OOPS. Unfortunately, in the case of an
363 * erroneous fault occurring in a code path which already holds mmap_sem
364 * we will deadlock attempting to validate the fault against the
365 * address space. Luckily the kernel only validly references user
366 * space from well defined areas of code, which are listed in the
367 * exceptions table.
368 *
369 * As the vast majority of faults will be valid we will only perform
370 * the source reference check when there is a possibility of a deadlock.
371 * Attempt to lock the address space, if we cannot we then validate the
372 * source. If this is invalid we can skip the address space check,
373 * thus avoiding the deadlock.
374 */
375 if (!down_read_trylock(&mm->mmap_sem)) {
376 if ((error_code & 4) == 0 &&
377 !search_exception_tables(regs->eip))
378 goto bad_area_nosemaphore;
379 down_read(&mm->mmap_sem);
380 }
381
382 vma = find_vma(mm, address);
383 if (!vma)
384 goto bad_area;
385 if (vma->vm_start <= address)
386 goto good_area;
387 if (!(vma->vm_flags & VM_GROWSDOWN))
388 goto bad_area;
389 if (error_code & 4) {
390 /*
391 * Accessing the stack below %esp is always a bug.
392 * The large cushion allows instructions like enter
393 * and pusha to work. ("enter $65535,$31" pushes
394 * 32 pointers and then decrements %esp by 65535.)
395 */
396 if (address + 65536 + 32 * sizeof(unsigned long) < regs->esp)
397 goto bad_area;
398 }
399 if (expand_stack(vma, address))
400 goto bad_area;
401/*
402 * Ok, we have a good vm_area for this memory access, so
403 * we can handle it..
404 */
405good_area:
406 si_code = SEGV_ACCERR;
407 write = 0;
408 switch (error_code & 3) {
409 default: /* 3: write, present */
410 /* fall through */
411 case 2: /* write, not present */
412 if (!(vma->vm_flags & VM_WRITE))
413 goto bad_area;
414 write++;
415 break;
416 case 1: /* read, present */
417 goto bad_area;
418 case 0: /* read, not present */
419 if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
420 goto bad_area;
421 }
422
423 survive:
424 /*
425 * If for any reason at all we couldn't handle the fault,
426 * make sure we exit gracefully rather than endlessly redo
427 * the fault.
428 */
429 fault = handle_mm_fault(mm, vma, address, write);
430 if (unlikely(fault & VM_FAULT_ERROR)) {
431 if (fault & VM_FAULT_OOM)
432 goto out_of_memory;
433 else if (fault & VM_FAULT_SIGBUS)
434 goto do_sigbus;
435 BUG();
436 }
437 if (fault & VM_FAULT_MAJOR)
438 tsk->maj_flt++;
439 else
440 tsk->min_flt++;
441
442 /*
443 * Did it hit the DOS screen memory VA from vm86 mode?
444 */
445 if (regs->eflags & VM_MASK) {
446 unsigned long bit = (address - 0xA0000) >> PAGE_SHIFT;
447 if (bit < 32)
448 tsk->thread.screen_bitmap |= 1 << bit;
449 }
450 up_read(&mm->mmap_sem);
451 return;
452
453/*
454 * Something tried to access memory that isn't in our memory map..
455 * Fix it, but check if it's kernel or user first..
456 */
457bad_area:
458 up_read(&mm->mmap_sem);
459
460bad_area_nosemaphore:
461 /* User mode accesses just cause a SIGSEGV */
462 if (error_code & 4) {
463 /*
464 * It's possible to have interrupts off here.
465 */
466 local_irq_enable();
467
468 /*
469 * Valid to do another page fault here because this one came
470 * from user space.
471 */
472 if (is_prefetch(regs, address, error_code))
473 return;
474
475 if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
476 printk_ratelimit()) {
477 printk("%s%s[%d]: segfault at %08lx eip %08lx "
478 "esp %08lx error %lx\n",
479 task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
480 tsk->comm, task_pid_nr(tsk), address, regs->eip,
481 regs->esp, error_code);
482 }
483 tsk->thread.cr2 = address;
484 /* Kernel addresses are always protection faults */
485 tsk->thread.error_code = error_code | (address >= TASK_SIZE);
486 tsk->thread.trap_no = 14;
487 force_sig_info_fault(SIGSEGV, si_code, address, tsk);
488 return;
489 }
490
491#ifdef CONFIG_X86_F00F_BUG
492 /*
493 * Pentium F0 0F C7 C8 bug workaround.
494 */
495 if (boot_cpu_data.f00f_bug) {
496 unsigned long nr;
497
498 nr = (address - idt_descr.address) >> 3;
499
500 if (nr == 6) {
501 do_invalid_op(regs, 0);
502 return;
503 }
504 }
505#endif
506
507no_context:
508 /* Are we prepared to handle this kernel fault? */
509 if (fixup_exception(regs))
510 return;
511
512 /*
513 * Valid to do another page fault here, because if this fault
514 * had been triggered by is_prefetch fixup_exception would have
515 * handled it.
516 */
517 if (is_prefetch(regs, address, error_code))
518 return;
519
520/*
521 * Oops. The kernel tried to access some bad page. We'll have to
522 * terminate things with extreme prejudice.
523 */
524
525 bust_spinlocks(1);
526
527 if (oops_may_print()) {
528 __typeof__(pte_val(__pte(0))) page;
529
530#ifdef CONFIG_X86_PAE
531 if (error_code & 16) {
532 pte_t *pte = lookup_address(address);
533
534 if (pte && pte_present(*pte) && !pte_exec_kernel(*pte))
535 printk(KERN_CRIT "kernel tried to execute "
536 "NX-protected page - exploit attempt? "
537 "(uid: %d)\n", current->uid);
538 }
539#endif
540 if (address < PAGE_SIZE)
541 printk(KERN_ALERT "BUG: unable to handle kernel NULL "
542 "pointer dereference");
543 else
544 printk(KERN_ALERT "BUG: unable to handle kernel paging"
545 " request");
546 printk(" at virtual address %08lx\n",address);
547 printk(KERN_ALERT "printing eip: %08lx ", regs->eip);
548
549 page = read_cr3();
550 page = ((__typeof__(page) *) __va(page))[address >> PGDIR_SHIFT];
551#ifdef CONFIG_X86_PAE
552 printk("*pdpt = %016Lx ", page);
553 if ((page >> PAGE_SHIFT) < max_low_pfn
554 && page & _PAGE_PRESENT) {
555 page &= PAGE_MASK;
556 page = ((__typeof__(page) *) __va(page))[(address >> PMD_SHIFT)
557 & (PTRS_PER_PMD - 1)];
558 printk(KERN_CONT "*pde = %016Lx ", page);
559 page &= ~_PAGE_NX;
560 }
561#else
562 printk("*pde = %08lx ", page);
563#endif
564
565 /*
566 * We must not directly access the pte in the highpte
567 * case if the page table is located in highmem.
568 * And let's rather not kmap-atomic the pte, just in case
569 * it's allocated already.
570 */
571 if ((page >> PAGE_SHIFT) < max_low_pfn
572 && (page & _PAGE_PRESENT)
573 && !(page & _PAGE_PSE)) {
574 page &= PAGE_MASK;
575 page = ((__typeof__(page) *) __va(page))[(address >> PAGE_SHIFT)
576 & (PTRS_PER_PTE - 1)];
577 printk("*pte = %0*Lx ", sizeof(page)*2, (u64)page);
578 }
579
580 printk("\n");
581 }
582
583 tsk->thread.cr2 = address;
584 tsk->thread.trap_no = 14;
585 tsk->thread.error_code = error_code;
586 die("Oops", regs, error_code);
587 bust_spinlocks(0);
588 do_exit(SIGKILL);
589
590/*
591 * We ran out of memory, or some other thing happened to us that made
592 * us unable to handle the page fault gracefully.
593 */
594out_of_memory:
595 up_read(&mm->mmap_sem);
596 if (is_global_init(tsk)) {
597 yield();
598 down_read(&mm->mmap_sem);
599 goto survive;
600 }
601 printk("VM: killing process %s\n", tsk->comm);
602 if (error_code & 4)
603 do_group_exit(SIGKILL);
604 goto no_context;
605
606do_sigbus:
607 up_read(&mm->mmap_sem);
608
609 /* Kernel mode? Handle exceptions or die */
610 if (!(error_code & 4))
611 goto no_context;
612
613 /* User space => ok to do another page fault */
614 if (is_prefetch(regs, address, error_code))
615 return;
616
617 tsk->thread.cr2 = address;
618 tsk->thread.error_code = error_code;
619 tsk->thread.trap_no = 14;
620 force_sig_info_fault(SIGBUS, BUS_ADRERR, address, tsk);
621}
622
623void vmalloc_sync_all(void)
624{
625 /*
626 * Note that races in the updates of insync and start aren't
627 * problematic: insync can only get set bits added, and updates to
628 * start are only improving performance (without affecting correctness
629 * if undone).
630 */
631 static DECLARE_BITMAP(insync, PTRS_PER_PGD);
632 static unsigned long start = TASK_SIZE;
633 unsigned long address;
634
635 if (SHARED_KERNEL_PMD)
636 return;
637
638 BUILD_BUG_ON(TASK_SIZE & ~PGDIR_MASK);
639 for (address = start; address >= TASK_SIZE; address += PGDIR_SIZE) {
640 if (!test_bit(pgd_index(address), insync)) {
641 unsigned long flags;
642 struct page *page;
643
644 spin_lock_irqsave(&pgd_lock, flags);
645 for (page = pgd_list; page; page =
646 (struct page *)page->index)
647 if (!vmalloc_sync_one(page_address(page),
648 address)) {
649 BUG_ON(page != pgd_list);
650 break;
651 }
652 spin_unlock_irqrestore(&pgd_lock, flags);
653 if (!page)
654 set_bit(pgd_index(address), insync);
655 }
656 if (address == start && test_bit(pgd_index(address), insync))
657 start = address + PGDIR_SIZE;
658 }
659}
diff --git a/arch/x86/mm/fault_64.c b/arch/x86/mm/fault_64.c
deleted file mode 100644
index 0e26230669ca..000000000000
--- a/arch/x86/mm/fault_64.c
+++ /dev/null
@@ -1,623 +0,0 @@
1/*
2 * linux/arch/x86-64/mm/fault.c
3 *
4 * Copyright (C) 1995 Linus Torvalds
5 * Copyright (C) 2001,2002 Andi Kleen, SuSE Labs.
6 */
7
8#include <linux/signal.h>
9#include <linux/sched.h>
10#include <linux/kernel.h>
11#include <linux/errno.h>
12#include <linux/string.h>
13#include <linux/types.h>
14#include <linux/ptrace.h>
15#include <linux/mman.h>
16#include <linux/mm.h>
17#include <linux/smp.h>
18#include <linux/interrupt.h>
19#include <linux/init.h>
20#include <linux/tty.h>
21#include <linux/vt_kern.h> /* For unblank_screen() */
22#include <linux/compiler.h>
23#include <linux/vmalloc.h>
24#include <linux/module.h>
25#include <linux/kprobes.h>
26#include <linux/uaccess.h>
27#include <linux/kdebug.h>
28#include <linux/kprobes.h>
29
30#include <asm/system.h>
31#include <asm/pgalloc.h>
32#include <asm/smp.h>
33#include <asm/tlbflush.h>
34#include <asm/proto.h>
35#include <asm-generic/sections.h>
36
37/* Page fault error code bits */
38#define PF_PROT (1<<0) /* or no page found */
39#define PF_WRITE (1<<1)
40#define PF_USER (1<<2)
41#define PF_RSVD (1<<3)
42#define PF_INSTR (1<<4)
43
44#ifdef CONFIG_KPROBES
45static inline int notify_page_fault(struct pt_regs *regs)
46{
47 int ret = 0;
48
49 /* kprobe_running() needs smp_processor_id() */
50 if (!user_mode(regs)) {
51 preempt_disable();
52 if (kprobe_running() && kprobe_fault_handler(regs, 14))
53 ret = 1;
54 preempt_enable();
55 }
56
57 return ret;
58}
59#else
60static inline int notify_page_fault(struct pt_regs *regs)
61{
62 return 0;
63}
64#endif
65
66/* Sometimes the CPU reports invalid exceptions on prefetch.
67 Check that here and ignore.
68 Opcode checker based on code by Richard Brunner */
69static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr,
70 unsigned long error_code)
71{
72 unsigned char *instr;
73 int scan_more = 1;
74 int prefetch = 0;
75 unsigned char *max_instr;
76
77 /* If it was a exec fault ignore */
78 if (error_code & PF_INSTR)
79 return 0;
80
81 instr = (unsigned char __user *)convert_rip_to_linear(current, regs);
82 max_instr = instr + 15;
83
84 if (user_mode(regs) && instr >= (unsigned char *)TASK_SIZE)
85 return 0;
86
87 while (scan_more && instr < max_instr) {
88 unsigned char opcode;
89 unsigned char instr_hi;
90 unsigned char instr_lo;
91
92 if (probe_kernel_address(instr, opcode))
93 break;
94
95 instr_hi = opcode & 0xf0;
96 instr_lo = opcode & 0x0f;
97 instr++;
98
99 switch (instr_hi) {
100 case 0x20:
101 case 0x30:
102 /* Values 0x26,0x2E,0x36,0x3E are valid x86
103 prefixes. In long mode, the CPU will signal
104 invalid opcode if some of these prefixes are
105 present so we will never get here anyway */
106 scan_more = ((instr_lo & 7) == 0x6);
107 break;
108
109 case 0x40:
110 /* In AMD64 long mode, 0x40 to 0x4F are valid REX prefixes
111 Need to figure out under what instruction mode the
112 instruction was issued ... */
113 /* Could check the LDT for lm, but for now it's good
114 enough to assume that long mode only uses well known
115 segments or kernel. */
116 scan_more = (!user_mode(regs)) || (regs->cs == __USER_CS);
117 break;
118
119 case 0x60:
120 /* 0x64 thru 0x67 are valid prefixes in all modes. */
121 scan_more = (instr_lo & 0xC) == 0x4;
122 break;
123 case 0xF0:
124 /* 0xF0, 0xF2, and 0xF3 are valid prefixes in all modes. */
125 scan_more = !instr_lo || (instr_lo>>1) == 1;
126 break;
127 case 0x00:
128 /* Prefetch instruction is 0x0F0D or 0x0F18 */
129 scan_more = 0;
130 if (probe_kernel_address(instr, opcode))
131 break;
132 prefetch = (instr_lo == 0xF) &&
133 (opcode == 0x0D || opcode == 0x18);
134 break;
135 default:
136 scan_more = 0;
137 break;
138 }
139 }
140 return prefetch;
141}
142
143static int bad_address(void *p)
144{
145 unsigned long dummy;
146 return probe_kernel_address((unsigned long *)p, dummy);
147}
148
149void dump_pagetable(unsigned long address)
150{
151 pgd_t *pgd;
152 pud_t *pud;
153 pmd_t *pmd;
154 pte_t *pte;
155
156 pgd = (pgd_t *)read_cr3();
157
158 pgd = __va((unsigned long)pgd & PHYSICAL_PAGE_MASK);
159 pgd += pgd_index(address);
160 if (bad_address(pgd)) goto bad;
161 printk("PGD %lx ", pgd_val(*pgd));
162 if (!pgd_present(*pgd)) goto ret;
163
164 pud = pud_offset(pgd, address);
165 if (bad_address(pud)) goto bad;
166 printk("PUD %lx ", pud_val(*pud));
167 if (!pud_present(*pud)) goto ret;
168
169 pmd = pmd_offset(pud, address);
170 if (bad_address(pmd)) goto bad;
171 printk("PMD %lx ", pmd_val(*pmd));
172 if (!pmd_present(*pmd) || pmd_large(*pmd)) goto ret;
173
174 pte = pte_offset_kernel(pmd, address);
175 if (bad_address(pte)) goto bad;
176 printk("PTE %lx", pte_val(*pte));
177ret:
178 printk("\n");
179 return;
180bad:
181 printk("BAD\n");
182}
183
184static const char errata93_warning[] =
185KERN_ERR "******* Your BIOS seems to not contain a fix for K8 errata #93\n"
186KERN_ERR "******* Working around it, but it may cause SEGVs or burn power.\n"
187KERN_ERR "******* Please consider a BIOS update.\n"
188KERN_ERR "******* Disabling USB legacy in the BIOS may also help.\n";
189
190/* Workaround for K8 erratum #93 & buggy BIOS.
191 BIOS SMM functions are required to use a specific workaround
192 to avoid corruption of the 64bit RIP register on C stepping K8.
193 A lot of BIOS that didn't get tested properly miss this.
194 The OS sees this as a page fault with the upper 32bits of RIP cleared.
195 Try to work around it here.
196 Note we only handle faults in kernel here. */
197
198static int is_errata93(struct pt_regs *regs, unsigned long address)
199{
200 static int warned;
201 if (address != regs->rip)
202 return 0;
203 if ((address >> 32) != 0)
204 return 0;
205 address |= 0xffffffffUL << 32;
206 if ((address >= (u64)_stext && address <= (u64)_etext) ||
207 (address >= MODULES_VADDR && address <= MODULES_END)) {
208 if (!warned) {
209 printk(errata93_warning);
210 warned = 1;
211 }
212 regs->rip = address;
213 return 1;
214 }
215 return 0;
216}
217
218static noinline void pgtable_bad(unsigned long address, struct pt_regs *regs,
219 unsigned long error_code)
220{
221 unsigned long flags = oops_begin();
222 struct task_struct *tsk;
223
224 printk(KERN_ALERT "%s: Corrupted page table at address %lx\n",
225 current->comm, address);
226 dump_pagetable(address);
227 tsk = current;
228 tsk->thread.cr2 = address;
229 tsk->thread.trap_no = 14;
230 tsk->thread.error_code = error_code;
231 __die("Bad pagetable", regs, error_code);
232 oops_end(flags);
233 do_exit(SIGKILL);
234}
235
236/*
237 * Handle a fault on the vmalloc area
238 *
239 * This assumes no large pages in there.
240 */
241static int vmalloc_fault(unsigned long address)
242{
243 pgd_t *pgd, *pgd_ref;
244 pud_t *pud, *pud_ref;
245 pmd_t *pmd, *pmd_ref;
246 pte_t *pte, *pte_ref;
247
248 /* Copy kernel mappings over when needed. This can also
249 happen within a race in page table update. In the later
250 case just flush. */
251
252 pgd = pgd_offset(current->mm ?: &init_mm, address);
253 pgd_ref = pgd_offset_k(address);
254 if (pgd_none(*pgd_ref))
255 return -1;
256 if (pgd_none(*pgd))
257 set_pgd(pgd, *pgd_ref);
258 else
259 BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref));
260
261 /* Below here mismatches are bugs because these lower tables
262 are shared */
263
264 pud = pud_offset(pgd, address);
265 pud_ref = pud_offset(pgd_ref, address);
266 if (pud_none(*pud_ref))
267 return -1;
268 if (pud_none(*pud) || pud_page_vaddr(*pud) != pud_page_vaddr(*pud_ref))
269 BUG();
270 pmd = pmd_offset(pud, address);
271 pmd_ref = pmd_offset(pud_ref, address);
272 if (pmd_none(*pmd_ref))
273 return -1;
274 if (pmd_none(*pmd) || pmd_page(*pmd) != pmd_page(*pmd_ref))
275 BUG();
276 pte_ref = pte_offset_kernel(pmd_ref, address);
277 if (!pte_present(*pte_ref))
278 return -1;
279 pte = pte_offset_kernel(pmd, address);
280 /* Don't use pte_page here, because the mappings can point
281 outside mem_map, and the NUMA hash lookup cannot handle
282 that. */
283 if (!pte_present(*pte) || pte_pfn(*pte) != pte_pfn(*pte_ref))
284 BUG();
285 return 0;
286}
287
288int show_unhandled_signals = 1;
289
290/*
291 * This routine handles page faults. It determines the address,
292 * and the problem, and then passes it off to one of the appropriate
293 * routines.
294 */
295asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
296 unsigned long error_code)
297{
298 struct task_struct *tsk;
299 struct mm_struct *mm;
300 struct vm_area_struct * vma;
301 unsigned long address;
302 const struct exception_table_entry *fixup;
303 int write, fault;
304 unsigned long flags;
305 siginfo_t info;
306
307 /*
308 * We can fault from pretty much anywhere, with unknown IRQ state.
309 */
310 trace_hardirqs_fixup();
311
312 tsk = current;
313 mm = tsk->mm;
314 prefetchw(&mm->mmap_sem);
315
316 /* get the address */
317 address = read_cr2();
318
319 info.si_code = SEGV_MAPERR;
320
321
322 /*
323 * We fault-in kernel-space virtual memory on-demand. The
324 * 'reference' page table is init_mm.pgd.
325 *
326 * NOTE! We MUST NOT take any locks for this case. We may
327 * be in an interrupt or a critical region, and should
328 * only copy the information from the master page table,
329 * nothing more.
330 *
331 * This verifies that the fault happens in kernel space
332 * (error_code & 4) == 0, and that the fault was not a
333 * protection error (error_code & 9) == 0.
334 */
335 if (unlikely(address >= TASK_SIZE64)) {
336 /*
337 * Don't check for the module range here: its PML4
338 * is always initialized because it's shared with the main
339 * kernel text. Only vmalloc may need PML4 syncups.
340 */
341 if (!(error_code & (PF_RSVD|PF_USER|PF_PROT)) &&
342 ((address >= VMALLOC_START && address < VMALLOC_END))) {
343 if (vmalloc_fault(address) >= 0)
344 return;
345 }
346 if (notify_page_fault(regs))
347 return;
348 /*
349 * Don't take the mm semaphore here. If we fixup a prefetch
350 * fault we could otherwise deadlock.
351 */
352 goto bad_area_nosemaphore;
353 }
354
355 if (notify_page_fault(regs))
356 return;
357
358 if (likely(regs->eflags & X86_EFLAGS_IF))
359 local_irq_enable();
360
361 if (unlikely(error_code & PF_RSVD))
362 pgtable_bad(address, regs, error_code);
363
364 /*
365 * If we're in an interrupt or have no user
366 * context, we must not take the fault..
367 */
368 if (unlikely(in_atomic() || !mm))
369 goto bad_area_nosemaphore;
370
371 /*
372 * User-mode registers count as a user access even for any
373 * potential system fault or CPU buglet.
374 */
375 if (user_mode_vm(regs))
376 error_code |= PF_USER;
377
378 again:
379 /* When running in the kernel we expect faults to occur only to
380 * addresses in user space. All other faults represent errors in the
381 * kernel and should generate an OOPS. Unfortunately, in the case of an
382 * erroneous fault occurring in a code path which already holds mmap_sem
383 * we will deadlock attempting to validate the fault against the
384 * address space. Luckily the kernel only validly references user
385 * space from well defined areas of code, which are listed in the
386 * exceptions table.
387 *
388 * As the vast majority of faults will be valid we will only perform
389 * the source reference check when there is a possibility of a deadlock.
390 * Attempt to lock the address space, if we cannot we then validate the
391 * source. If this is invalid we can skip the address space check,
392 * thus avoiding the deadlock.
393 */
394 if (!down_read_trylock(&mm->mmap_sem)) {
395 if ((error_code & PF_USER) == 0 &&
396 !search_exception_tables(regs->rip))
397 goto bad_area_nosemaphore;
398 down_read(&mm->mmap_sem);
399 }
400
401 vma = find_vma(mm, address);
402 if (!vma)
403 goto bad_area;
404 if (likely(vma->vm_start <= address))
405 goto good_area;
406 if (!(vma->vm_flags & VM_GROWSDOWN))
407 goto bad_area;
408 if (error_code & 4) {
409 /* Allow userspace just enough access below the stack pointer
410 * to let the 'enter' instruction work.
411 */
412 if (address + 65536 + 32 * sizeof(unsigned long) < regs->rsp)
413 goto bad_area;
414 }
415 if (expand_stack(vma, address))
416 goto bad_area;
417/*
418 * Ok, we have a good vm_area for this memory access, so
419 * we can handle it..
420 */
421good_area:
422 info.si_code = SEGV_ACCERR;
423 write = 0;
424 switch (error_code & (PF_PROT|PF_WRITE)) {
425 default: /* 3: write, present */
426 /* fall through */
427 case PF_WRITE: /* write, not present */
428 if (!(vma->vm_flags & VM_WRITE))
429 goto bad_area;
430 write++;
431 break;
432 case PF_PROT: /* read, present */
433 goto bad_area;
434 case 0: /* read, not present */
435 if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
436 goto bad_area;
437 }
438
439 /*
440 * If for any reason at all we couldn't handle the fault,
441 * make sure we exit gracefully rather than endlessly redo
442 * the fault.
443 */
444 fault = handle_mm_fault(mm, vma, address, write);
445 if (unlikely(fault & VM_FAULT_ERROR)) {
446 if (fault & VM_FAULT_OOM)
447 goto out_of_memory;
448 else if (fault & VM_FAULT_SIGBUS)
449 goto do_sigbus;
450 BUG();
451 }
452 if (fault & VM_FAULT_MAJOR)
453 tsk->maj_flt++;
454 else
455 tsk->min_flt++;
456 up_read(&mm->mmap_sem);
457 return;
458
459/*
460 * Something tried to access memory that isn't in our memory map..
461 * Fix it, but check if it's kernel or user first..
462 */
463bad_area:
464 up_read(&mm->mmap_sem);
465
466bad_area_nosemaphore:
467 /* User mode accesses just cause a SIGSEGV */
468 if (error_code & PF_USER) {
469
470 /*
471 * It's possible to have interrupts off here.
472 */
473 local_irq_enable();
474
475 if (is_prefetch(regs, address, error_code))
476 return;
477
478 /* Work around K8 erratum #100 K8 in compat mode
479 occasionally jumps to illegal addresses >4GB. We
480 catch this here in the page fault handler because
481 these addresses are not reachable. Just detect this
482 case and return. Any code segment in LDT is
483 compatibility mode. */
484 if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) &&
485 (address >> 32))
486 return;
487
488 if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
489 printk_ratelimit()) {
490 printk(
491 "%s%s[%d]: segfault at %lx rip %lx rsp %lx error %lx\n",
492 tsk->pid > 1 ? KERN_INFO : KERN_EMERG,
493 tsk->comm, tsk->pid, address, regs->rip,
494 regs->rsp, error_code);
495 }
496
497 tsk->thread.cr2 = address;
498 /* Kernel addresses are always protection faults */
499 tsk->thread.error_code = error_code | (address >= TASK_SIZE);
500 tsk->thread.trap_no = 14;
501 info.si_signo = SIGSEGV;
502 info.si_errno = 0;
503 /* info.si_code has been set above */
504 info.si_addr = (void __user *)address;
505 force_sig_info(SIGSEGV, &info, tsk);
506 return;
507 }
508
509no_context:
510
511 /* Are we prepared to handle this kernel fault? */
512 fixup = search_exception_tables(regs->rip);
513 if (fixup) {
514 regs->rip = fixup->fixup;
515 return;
516 }
517
518 /*
519 * Hall of shame of CPU/BIOS bugs.
520 */
521
522 if (is_prefetch(regs, address, error_code))
523 return;
524
525 if (is_errata93(regs, address))
526 return;
527
528/*
529 * Oops. The kernel tried to access some bad page. We'll have to
530 * terminate things with extreme prejudice.
531 */
532
533 flags = oops_begin();
534
535 if (address < PAGE_SIZE)
536 printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
537 else
538 printk(KERN_ALERT "Unable to handle kernel paging request");
539 printk(" at %016lx RIP: \n" KERN_ALERT,address);
540 printk_address(regs->rip);
541 dump_pagetable(address);
542 tsk->thread.cr2 = address;
543 tsk->thread.trap_no = 14;
544 tsk->thread.error_code = error_code;
545 __die("Oops", regs, error_code);
546 /* Executive summary in case the body of the oops scrolled away */
547 printk(KERN_EMERG "CR2: %016lx\n", address);
548 oops_end(flags);
549 do_exit(SIGKILL);
550
551/*
552 * We ran out of memory, or some other thing happened to us that made
553 * us unable to handle the page fault gracefully.
554 */
555out_of_memory:
556 up_read(&mm->mmap_sem);
557 if (is_global_init(current)) {
558 yield();
559 goto again;
560 }
561 printk("VM: killing process %s\n", tsk->comm);
562 if (error_code & 4)
563 do_group_exit(SIGKILL);
564 goto no_context;
565
566do_sigbus:
567 up_read(&mm->mmap_sem);
568
569 /* Kernel mode? Handle exceptions or die */
570 if (!(error_code & PF_USER))
571 goto no_context;
572
573 tsk->thread.cr2 = address;
574 tsk->thread.error_code = error_code;
575 tsk->thread.trap_no = 14;
576 info.si_signo = SIGBUS;
577 info.si_errno = 0;
578 info.si_code = BUS_ADRERR;
579 info.si_addr = (void __user *)address;
580 force_sig_info(SIGBUS, &info, tsk);
581 return;
582}
583
584DEFINE_SPINLOCK(pgd_lock);
585LIST_HEAD(pgd_list);
586
587void vmalloc_sync_all(void)
588{
589 /* Note that races in the updates of insync and start aren't
590 problematic:
591 insync can only get set bits added, and updates to start are only
592 improving performance (without affecting correctness if undone). */
593 static DECLARE_BITMAP(insync, PTRS_PER_PGD);
594 static unsigned long start = VMALLOC_START & PGDIR_MASK;
595 unsigned long address;
596
597 for (address = start; address <= VMALLOC_END; address += PGDIR_SIZE) {
598 if (!test_bit(pgd_index(address), insync)) {
599 const pgd_t *pgd_ref = pgd_offset_k(address);
600 struct page *page;
601
602 if (pgd_none(*pgd_ref))
603 continue;
604 spin_lock(&pgd_lock);
605 list_for_each_entry(page, &pgd_list, lru) {
606 pgd_t *pgd;
607 pgd = (pgd_t *)page_address(page) + pgd_index(address);
608 if (pgd_none(*pgd))
609 set_pgd(pgd, *pgd_ref);
610 else
611 BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref));
612 }
613 spin_unlock(&pgd_lock);
614 set_bit(pgd_index(address), insync);
615 }
616 if (address == start)
617 start = address + PGDIR_SIZE;
618 }
619 /* Check that there is no need to do the same for the modules area. */
620 BUILD_BUG_ON(!(MODULES_VADDR > __START_KERNEL));
621 BUILD_BUG_ON(!(((MODULES_END - 1) & PGDIR_MASK) ==
622 (__START_KERNEL & PGDIR_MASK)));
623}
diff --git a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c
index 1c3bf95f7356..3d936f232704 100644
--- a/arch/x86/mm/highmem_32.c
+++ b/arch/x86/mm/highmem_32.c
@@ -18,6 +18,49 @@ void kunmap(struct page *page)
18 kunmap_high(page); 18 kunmap_high(page);
19} 19}
20 20
21static void debug_kmap_atomic_prot(enum km_type type)
22{
23#ifdef CONFIG_DEBUG_HIGHMEM
24 static unsigned warn_count = 10;
25
26 if (unlikely(warn_count == 0))
27 return;
28
29 if (unlikely(in_interrupt())) {
30 if (in_irq()) {
31 if (type != KM_IRQ0 && type != KM_IRQ1 &&
32 type != KM_BIO_SRC_IRQ && type != KM_BIO_DST_IRQ &&
33 type != KM_BOUNCE_READ) {
34 WARN_ON(1);
35 warn_count--;
36 }
37 } else if (!irqs_disabled()) { /* softirq */
38 if (type != KM_IRQ0 && type != KM_IRQ1 &&
39 type != KM_SOFTIRQ0 && type != KM_SOFTIRQ1 &&
40 type != KM_SKB_SUNRPC_DATA &&
41 type != KM_SKB_DATA_SOFTIRQ &&
42 type != KM_BOUNCE_READ) {
43 WARN_ON(1);
44 warn_count--;
45 }
46 }
47 }
48
49 if (type == KM_IRQ0 || type == KM_IRQ1 || type == KM_BOUNCE_READ ||
50 type == KM_BIO_SRC_IRQ || type == KM_BIO_DST_IRQ) {
51 if (!irqs_disabled()) {
52 WARN_ON(1);
53 warn_count--;
54 }
55 } else if (type == KM_SOFTIRQ0 || type == KM_SOFTIRQ1) {
56 if (irq_count() == 0 && !irqs_disabled()) {
57 WARN_ON(1);
58 warn_count--;
59 }
60 }
61#endif
62}
63
21/* 64/*
22 * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because 65 * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because
23 * no global lock is needed and because the kmap code must perform a global TLB 66 * no global lock is needed and because the kmap code must perform a global TLB
@@ -30,8 +73,10 @@ void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot)
30{ 73{
31 enum fixed_addresses idx; 74 enum fixed_addresses idx;
32 unsigned long vaddr; 75 unsigned long vaddr;
33
34 /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ 76 /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
77
78 debug_kmap_atomic_prot(type);
79
35 pagefault_disable(); 80 pagefault_disable();
36 81
37 if (!PageHighMem(page)) 82 if (!PageHighMem(page))
diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c
index 6c06d9c0488e..4fbafb4bc2f0 100644
--- a/arch/x86/mm/hugetlbpage.c
+++ b/arch/x86/mm/hugetlbpage.c
@@ -15,6 +15,7 @@
15#include <asm/mman.h> 15#include <asm/mman.h>
16#include <asm/tlb.h> 16#include <asm/tlb.h>
17#include <asm/tlbflush.h> 17#include <asm/tlbflush.h>
18#include <asm/pgalloc.h>
18 19
19static unsigned long page_table_shareable(struct vm_area_struct *svma, 20static unsigned long page_table_shareable(struct vm_area_struct *svma,
20 struct vm_area_struct *vma, 21 struct vm_area_struct *vma,
@@ -88,7 +89,7 @@ static void huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud)
88 89
89 spin_lock(&mm->page_table_lock); 90 spin_lock(&mm->page_table_lock);
90 if (pud_none(*pud)) 91 if (pud_none(*pud))
91 pud_populate(mm, pud, (unsigned long) spte & PAGE_MASK); 92 pud_populate(mm, pud, (pmd_t *)((unsigned long)spte & PAGE_MASK));
92 else 93 else
93 put_page(virt_to_page(spte)); 94 put_page(virt_to_page(spte));
94 spin_unlock(&mm->page_table_lock); 95 spin_unlock(&mm->page_table_lock);
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index 3c76d194fd2c..da524fb22422 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -27,7 +27,6 @@
27#include <linux/bootmem.h> 27#include <linux/bootmem.h>
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <linux/proc_fs.h> 29#include <linux/proc_fs.h>
30#include <linux/efi.h>
31#include <linux/memory_hotplug.h> 30#include <linux/memory_hotplug.h>
32#include <linux/initrd.h> 31#include <linux/initrd.h>
33#include <linux/cpumask.h> 32#include <linux/cpumask.h>
@@ -40,8 +39,10 @@
40#include <asm/fixmap.h> 39#include <asm/fixmap.h>
41#include <asm/e820.h> 40#include <asm/e820.h>
42#include <asm/apic.h> 41#include <asm/apic.h>
42#include <asm/bugs.h>
43#include <asm/tlb.h> 43#include <asm/tlb.h>
44#include <asm/tlbflush.h> 44#include <asm/tlbflush.h>
45#include <asm/pgalloc.h>
45#include <asm/sections.h> 46#include <asm/sections.h>
46#include <asm/paravirt.h> 47#include <asm/paravirt.h>
47 48
@@ -50,7 +51,7 @@ unsigned int __VMALLOC_RESERVE = 128 << 20;
50DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); 51DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
51unsigned long highstart_pfn, highend_pfn; 52unsigned long highstart_pfn, highend_pfn;
52 53
53static int noinline do_test_wp_bit(void); 54static noinline int do_test_wp_bit(void);
54 55
55/* 56/*
56 * Creates a middle page table and puts a pointer to it in the 57 * Creates a middle page table and puts a pointer to it in the
@@ -61,26 +62,26 @@ static pmd_t * __init one_md_table_init(pgd_t *pgd)
61{ 62{
62 pud_t *pud; 63 pud_t *pud;
63 pmd_t *pmd_table; 64 pmd_t *pmd_table;
64 65
65#ifdef CONFIG_X86_PAE 66#ifdef CONFIG_X86_PAE
66 if (!(pgd_val(*pgd) & _PAGE_PRESENT)) { 67 if (!(pgd_val(*pgd) & _PAGE_PRESENT)) {
67 pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE); 68 pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
68 69
69 paravirt_alloc_pd(__pa(pmd_table) >> PAGE_SHIFT); 70 paravirt_alloc_pd(&init_mm, __pa(pmd_table) >> PAGE_SHIFT);
70 set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT)); 71 set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
71 pud = pud_offset(pgd, 0); 72 pud = pud_offset(pgd, 0);
72 if (pmd_table != pmd_offset(pud, 0)) 73 BUG_ON(pmd_table != pmd_offset(pud, 0));
73 BUG();
74 } 74 }
75#endif 75#endif
76 pud = pud_offset(pgd, 0); 76 pud = pud_offset(pgd, 0);
77 pmd_table = pmd_offset(pud, 0); 77 pmd_table = pmd_offset(pud, 0);
78
78 return pmd_table; 79 return pmd_table;
79} 80}
80 81
81/* 82/*
82 * Create a page table and place a pointer to it in a middle page 83 * Create a page table and place a pointer to it in a middle page
83 * directory entry. 84 * directory entry:
84 */ 85 */
85static pte_t * __init one_page_table_init(pmd_t *pmd) 86static pte_t * __init one_page_table_init(pmd_t *pmd)
86{ 87{
@@ -90,9 +91,10 @@ static pte_t * __init one_page_table_init(pmd_t *pmd)
90#ifdef CONFIG_DEBUG_PAGEALLOC 91#ifdef CONFIG_DEBUG_PAGEALLOC
91 page_table = (pte_t *) alloc_bootmem_pages(PAGE_SIZE); 92 page_table = (pte_t *) alloc_bootmem_pages(PAGE_SIZE);
92#endif 93#endif
93 if (!page_table) 94 if (!page_table) {
94 page_table = 95 page_table =
95 (pte_t *)alloc_bootmem_low_pages(PAGE_SIZE); 96 (pte_t *)alloc_bootmem_low_pages(PAGE_SIZE);
97 }
96 98
97 paravirt_alloc_pt(&init_mm, __pa(page_table) >> PAGE_SHIFT); 99 paravirt_alloc_pt(&init_mm, __pa(page_table) >> PAGE_SHIFT);
98 set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE)); 100 set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
@@ -103,22 +105,21 @@ static pte_t * __init one_page_table_init(pmd_t *pmd)
103} 105}
104 106
105/* 107/*
106 * This function initializes a certain range of kernel virtual memory 108 * This function initializes a certain range of kernel virtual memory
107 * with new bootmem page tables, everywhere page tables are missing in 109 * with new bootmem page tables, everywhere page tables are missing in
108 * the given range. 110 * the given range.
109 */ 111 *
110 112 * NOTE: The pagetables are allocated contiguous on the physical space
111/* 113 * so we can cache the place of the first one and move around without
112 * NOTE: The pagetables are allocated contiguous on the physical space
113 * so we can cache the place of the first one and move around without
114 * checking the pgd every time. 114 * checking the pgd every time.
115 */ 115 */
116static void __init page_table_range_init (unsigned long start, unsigned long end, pgd_t *pgd_base) 116static void __init
117page_table_range_init(unsigned long start, unsigned long end, pgd_t *pgd_base)
117{ 118{
118 pgd_t *pgd;
119 pmd_t *pmd;
120 int pgd_idx, pmd_idx; 119 int pgd_idx, pmd_idx;
121 unsigned long vaddr; 120 unsigned long vaddr;
121 pgd_t *pgd;
122 pmd_t *pmd;
122 123
123 vaddr = start; 124 vaddr = start;
124 pgd_idx = pgd_index(vaddr); 125 pgd_idx = pgd_index(vaddr);
@@ -128,7 +129,8 @@ static void __init page_table_range_init (unsigned long start, unsigned long end
128 for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) { 129 for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
129 pmd = one_md_table_init(pgd); 130 pmd = one_md_table_init(pgd);
130 pmd = pmd + pmd_index(vaddr); 131 pmd = pmd + pmd_index(vaddr);
131 for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) { 132 for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end);
133 pmd++, pmd_idx++) {
132 one_page_table_init(pmd); 134 one_page_table_init(pmd);
133 135
134 vaddr += PMD_SIZE; 136 vaddr += PMD_SIZE;
@@ -145,17 +147,17 @@ static inline int is_kernel_text(unsigned long addr)
145} 147}
146 148
147/* 149/*
148 * This maps the physical memory to kernel virtual address space, a total 150 * This maps the physical memory to kernel virtual address space, a total
149 * of max_low_pfn pages, by creating page tables starting from address 151 * of max_low_pfn pages, by creating page tables starting from address
150 * PAGE_OFFSET. 152 * PAGE_OFFSET:
151 */ 153 */
152static void __init kernel_physical_mapping_init(pgd_t *pgd_base) 154static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
153{ 155{
156 int pgd_idx, pmd_idx, pte_ofs;
154 unsigned long pfn; 157 unsigned long pfn;
155 pgd_t *pgd; 158 pgd_t *pgd;
156 pmd_t *pmd; 159 pmd_t *pmd;
157 pte_t *pte; 160 pte_t *pte;
158 int pgd_idx, pmd_idx, pte_ofs;
159 161
160 pgd_idx = pgd_index(PAGE_OFFSET); 162 pgd_idx = pgd_index(PAGE_OFFSET);
161 pgd = pgd_base + pgd_idx; 163 pgd = pgd_base + pgd_idx;
@@ -165,29 +167,43 @@ static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
165 pmd = one_md_table_init(pgd); 167 pmd = one_md_table_init(pgd);
166 if (pfn >= max_low_pfn) 168 if (pfn >= max_low_pfn)
167 continue; 169 continue;
168 for (pmd_idx = 0; pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn; pmd++, pmd_idx++) {
169 unsigned int address = pfn * PAGE_SIZE + PAGE_OFFSET;
170 170
171 /* Map with big pages if possible, otherwise create normal page tables. */ 171 for (pmd_idx = 0;
172 pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn;
173 pmd++, pmd_idx++) {
174 unsigned int addr = pfn * PAGE_SIZE + PAGE_OFFSET;
175
176 /*
177 * Map with big pages if possible, otherwise
178 * create normal page tables:
179 */
172 if (cpu_has_pse) { 180 if (cpu_has_pse) {
173 unsigned int address2 = (pfn + PTRS_PER_PTE - 1) * PAGE_SIZE + PAGE_OFFSET + PAGE_SIZE-1; 181 unsigned int addr2;
174 if (is_kernel_text(address) || is_kernel_text(address2)) 182 pgprot_t prot = PAGE_KERNEL_LARGE;
175 set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE_EXEC)); 183
176 else 184 addr2 = (pfn + PTRS_PER_PTE-1) * PAGE_SIZE +
177 set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE)); 185 PAGE_OFFSET + PAGE_SIZE-1;
186
187 if (is_kernel_text(addr) ||
188 is_kernel_text(addr2))
189 prot = PAGE_KERNEL_LARGE_EXEC;
190
191 set_pmd(pmd, pfn_pmd(pfn, prot));
178 192
179 pfn += PTRS_PER_PTE; 193 pfn += PTRS_PER_PTE;
180 } else { 194 continue;
181 pte = one_page_table_init(pmd); 195 }
182 196 pte = one_page_table_init(pmd);
183 for (pte_ofs = 0; 197
184 pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn; 198 for (pte_ofs = 0;
185 pte++, pfn++, pte_ofs++, address += PAGE_SIZE) { 199 pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn;
186 if (is_kernel_text(address)) 200 pte++, pfn++, pte_ofs++, addr += PAGE_SIZE) {
187 set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC)); 201 pgprot_t prot = PAGE_KERNEL;
188 else 202
189 set_pte(pte, pfn_pte(pfn, PAGE_KERNEL)); 203 if (is_kernel_text(addr))
190 } 204 prot = PAGE_KERNEL_EXEC;
205
206 set_pte(pte, pfn_pte(pfn, prot));
191 } 207 }
192 } 208 }
193 } 209 }
@@ -200,57 +216,23 @@ static inline int page_kills_ppro(unsigned long pagenr)
200 return 0; 216 return 0;
201} 217}
202 218
203int page_is_ram(unsigned long pagenr)
204{
205 int i;
206 unsigned long addr, end;
207
208 if (efi_enabled) {
209 efi_memory_desc_t *md;
210 void *p;
211
212 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
213 md = p;
214 if (!is_available_memory(md))
215 continue;
216 addr = (md->phys_addr+PAGE_SIZE-1) >> PAGE_SHIFT;
217 end = (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) >> PAGE_SHIFT;
218
219 if ((pagenr >= addr) && (pagenr < end))
220 return 1;
221 }
222 return 0;
223 }
224
225 for (i = 0; i < e820.nr_map; i++) {
226
227 if (e820.map[i].type != E820_RAM) /* not usable memory */
228 continue;
229 /*
230 * !!!FIXME!!! Some BIOSen report areas as RAM that
231 * are not. Notably the 640->1Mb area. We need a sanity
232 * check here.
233 */
234 addr = (e820.map[i].addr+PAGE_SIZE-1) >> PAGE_SHIFT;
235 end = (e820.map[i].addr+e820.map[i].size) >> PAGE_SHIFT;
236 if ((pagenr >= addr) && (pagenr < end))
237 return 1;
238 }
239 return 0;
240}
241
242#ifdef CONFIG_HIGHMEM 219#ifdef CONFIG_HIGHMEM
243pte_t *kmap_pte; 220pte_t *kmap_pte;
244pgprot_t kmap_prot; 221pgprot_t kmap_prot;
245 222
246#define kmap_get_fixmap_pte(vaddr) \ 223static inline pte_t *kmap_get_fixmap_pte(unsigned long vaddr)
247 pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), vaddr), (vaddr)), (vaddr)) 224{
225 return pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr),
226 vaddr), vaddr), vaddr);
227}
248 228
249static void __init kmap_init(void) 229static void __init kmap_init(void)
250{ 230{
251 unsigned long kmap_vstart; 231 unsigned long kmap_vstart;
252 232
253 /* cache the first kmap pte */ 233 /*
234 * Cache the first kmap pte:
235 */
254 kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN); 236 kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
255 kmap_pte = kmap_get_fixmap_pte(kmap_vstart); 237 kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
256 238
@@ -259,11 +241,11 @@ static void __init kmap_init(void)
259 241
260static void __init permanent_kmaps_init(pgd_t *pgd_base) 242static void __init permanent_kmaps_init(pgd_t *pgd_base)
261{ 243{
244 unsigned long vaddr;
262 pgd_t *pgd; 245 pgd_t *pgd;
263 pud_t *pud; 246 pud_t *pud;
264 pmd_t *pmd; 247 pmd_t *pmd;
265 pte_t *pte; 248 pte_t *pte;
266 unsigned long vaddr;
267 249
268 vaddr = PKMAP_BASE; 250 vaddr = PKMAP_BASE;
269 page_table_range_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base); 251 page_table_range_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
@@ -272,7 +254,7 @@ static void __init permanent_kmaps_init(pgd_t *pgd_base)
272 pud = pud_offset(pgd, vaddr); 254 pud = pud_offset(pgd, vaddr);
273 pmd = pmd_offset(pud, vaddr); 255 pmd = pmd_offset(pud, vaddr);
274 pte = pte_offset_kernel(pmd, vaddr); 256 pte = pte_offset_kernel(pmd, vaddr);
275 pkmap_page_table = pte; 257 pkmap_page_table = pte;
276} 258}
277 259
278static void __meminit free_new_highpage(struct page *page) 260static void __meminit free_new_highpage(struct page *page)
@@ -291,7 +273,8 @@ void __init add_one_highpage_init(struct page *page, int pfn, int bad_ppro)
291 SetPageReserved(page); 273 SetPageReserved(page);
292} 274}
293 275
294static int __meminit add_one_highpage_hotplug(struct page *page, unsigned long pfn) 276static int __meminit
277add_one_highpage_hotplug(struct page *page, unsigned long pfn)
295{ 278{
296 free_new_highpage(page); 279 free_new_highpage(page);
297 totalram_pages++; 280 totalram_pages++;
@@ -299,6 +282,7 @@ static int __meminit add_one_highpage_hotplug(struct page *page, unsigned long p
299 max_mapnr = max(pfn, max_mapnr); 282 max_mapnr = max(pfn, max_mapnr);
300#endif 283#endif
301 num_physpages++; 284 num_physpages++;
285
302 return 0; 286 return 0;
303} 287}
304 288
@@ -306,7 +290,7 @@ static int __meminit add_one_highpage_hotplug(struct page *page, unsigned long p
306 * Not currently handling the NUMA case. 290 * Not currently handling the NUMA case.
307 * Assuming single node and all memory that 291 * Assuming single node and all memory that
308 * has been added dynamically that would be 292 * has been added dynamically that would be
309 * onlined here is in HIGHMEM 293 * onlined here is in HIGHMEM.
310 */ 294 */
311void __meminit online_page(struct page *page) 295void __meminit online_page(struct page *page)
312{ 296{
@@ -314,13 +298,11 @@ void __meminit online_page(struct page *page)
314 add_one_highpage_hotplug(page, page_to_pfn(page)); 298 add_one_highpage_hotplug(page, page_to_pfn(page));
315} 299}
316 300
317 301#ifndef CONFIG_NUMA
318#ifdef CONFIG_NUMA
319extern void set_highmem_pages_init(int);
320#else
321static void __init set_highmem_pages_init(int bad_ppro) 302static void __init set_highmem_pages_init(int bad_ppro)
322{ 303{
323 int pfn; 304 int pfn;
305
324 for (pfn = highstart_pfn; pfn < highend_pfn; pfn++) { 306 for (pfn = highstart_pfn; pfn < highend_pfn; pfn++) {
325 /* 307 /*
326 * Holes under sparsemem might not have no mem_map[]: 308 * Holes under sparsemem might not have no mem_map[]:
@@ -330,23 +312,18 @@ static void __init set_highmem_pages_init(int bad_ppro)
330 } 312 }
331 totalram_pages += totalhigh_pages; 313 totalram_pages += totalhigh_pages;
332} 314}
333#endif /* CONFIG_FLATMEM */ 315#endif /* !CONFIG_NUMA */
334 316
335#else 317#else
336#define kmap_init() do { } while (0) 318# define kmap_init() do { } while (0)
337#define permanent_kmaps_init(pgd_base) do { } while (0) 319# define permanent_kmaps_init(pgd_base) do { } while (0)
338#define set_highmem_pages_init(bad_ppro) do { } while (0) 320# define set_highmem_pages_init(bad_ppro) do { } while (0)
339#endif /* CONFIG_HIGHMEM */ 321#endif /* CONFIG_HIGHMEM */
340 322
341unsigned long long __PAGE_KERNEL = _PAGE_KERNEL; 323pteval_t __PAGE_KERNEL = _PAGE_KERNEL;
342EXPORT_SYMBOL(__PAGE_KERNEL); 324EXPORT_SYMBOL(__PAGE_KERNEL);
343unsigned long long __PAGE_KERNEL_EXEC = _PAGE_KERNEL_EXEC;
344 325
345#ifdef CONFIG_NUMA 326pteval_t __PAGE_KERNEL_EXEC = _PAGE_KERNEL_EXEC;
346extern void __init remap_numa_kva(void);
347#else
348#define remap_numa_kva() do {} while (0)
349#endif
350 327
351void __init native_pagetable_setup_start(pgd_t *base) 328void __init native_pagetable_setup_start(pgd_t *base)
352{ 329{
@@ -372,7 +349,7 @@ void __init native_pagetable_setup_start(pgd_t *base)
372 memset(&base[USER_PTRS_PER_PGD], 0, 349 memset(&base[USER_PTRS_PER_PGD], 0,
373 KERNEL_PGD_PTRS * sizeof(pgd_t)); 350 KERNEL_PGD_PTRS * sizeof(pgd_t));
374#else 351#else
375 paravirt_alloc_pd(__pa(swapper_pg_dir) >> PAGE_SHIFT); 352 paravirt_alloc_pd(&init_mm, __pa(base) >> PAGE_SHIFT);
376#endif 353#endif
377} 354}
378 355
@@ -410,10 +387,10 @@ void __init native_pagetable_setup_done(pgd_t *base)
410 * be partially populated, and so it avoids stomping on any existing 387 * be partially populated, and so it avoids stomping on any existing
411 * mappings. 388 * mappings.
412 */ 389 */
413static void __init pagetable_init (void) 390static void __init pagetable_init(void)
414{ 391{
415 unsigned long vaddr, end;
416 pgd_t *pgd_base = swapper_pg_dir; 392 pgd_t *pgd_base = swapper_pg_dir;
393 unsigned long vaddr, end;
417 394
418 paravirt_pagetable_setup_start(pgd_base); 395 paravirt_pagetable_setup_start(pgd_base);
419 396
@@ -435,9 +412,11 @@ static void __init pagetable_init (void)
435 * Fixed mappings, only the page table structure has to be 412 * Fixed mappings, only the page table structure has to be
436 * created - mappings will be set by set_fixmap(): 413 * created - mappings will be set by set_fixmap():
437 */ 414 */
415 early_ioremap_clear();
438 vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK; 416 vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
439 end = (FIXADDR_TOP + PMD_SIZE - 1) & PMD_MASK; 417 end = (FIXADDR_TOP + PMD_SIZE - 1) & PMD_MASK;
440 page_table_range_init(vaddr, end, pgd_base); 418 page_table_range_init(vaddr, end, pgd_base);
419 early_ioremap_reset();
441 420
442 permanent_kmaps_init(pgd_base); 421 permanent_kmaps_init(pgd_base);
443 422
@@ -450,7 +429,7 @@ static void __init pagetable_init (void)
450 * driver might have split up a kernel 4MB mapping. 429 * driver might have split up a kernel 4MB mapping.
451 */ 430 */
452char __nosavedata swsusp_pg_dir[PAGE_SIZE] 431char __nosavedata swsusp_pg_dir[PAGE_SIZE]
453 __attribute__ ((aligned (PAGE_SIZE))); 432 __attribute__ ((aligned(PAGE_SIZE)));
454 433
455static inline void save_pg_dir(void) 434static inline void save_pg_dir(void)
456{ 435{
@@ -462,7 +441,7 @@ static inline void save_pg_dir(void)
462} 441}
463#endif 442#endif
464 443
465void zap_low_mappings (void) 444void zap_low_mappings(void)
466{ 445{
467 int i; 446 int i;
468 447
@@ -474,22 +453,24 @@ void zap_low_mappings (void)
474 * Note that "pgd_clear()" doesn't do it for 453 * Note that "pgd_clear()" doesn't do it for
475 * us, because pgd_clear() is a no-op on i386. 454 * us, because pgd_clear() is a no-op on i386.
476 */ 455 */
477 for (i = 0; i < USER_PTRS_PER_PGD; i++) 456 for (i = 0; i < USER_PTRS_PER_PGD; i++) {
478#ifdef CONFIG_X86_PAE 457#ifdef CONFIG_X86_PAE
479 set_pgd(swapper_pg_dir+i, __pgd(1 + __pa(empty_zero_page))); 458 set_pgd(swapper_pg_dir+i, __pgd(1 + __pa(empty_zero_page)));
480#else 459#else
481 set_pgd(swapper_pg_dir+i, __pgd(0)); 460 set_pgd(swapper_pg_dir+i, __pgd(0));
482#endif 461#endif
462 }
483 flush_tlb_all(); 463 flush_tlb_all();
484} 464}
485 465
486int nx_enabled = 0; 466int nx_enabled;
467
468pteval_t __supported_pte_mask __read_mostly = ~_PAGE_NX;
469EXPORT_SYMBOL_GPL(__supported_pte_mask);
487 470
488#ifdef CONFIG_X86_PAE 471#ifdef CONFIG_X86_PAE
489 472
490static int disable_nx __initdata = 0; 473static int disable_nx __initdata;
491u64 __supported_pte_mask __read_mostly = ~_PAGE_NX;
492EXPORT_SYMBOL_GPL(__supported_pte_mask);
493 474
494/* 475/*
495 * noexec = on|off 476 * noexec = on|off
@@ -506,11 +487,14 @@ static int __init noexec_setup(char *str)
506 __supported_pte_mask |= _PAGE_NX; 487 __supported_pte_mask |= _PAGE_NX;
507 disable_nx = 0; 488 disable_nx = 0;
508 } 489 }
509 } else if (!strcmp(str,"off")) { 490 } else {
510 disable_nx = 1; 491 if (!strcmp(str, "off")) {
511 __supported_pte_mask &= ~_PAGE_NX; 492 disable_nx = 1;
512 } else 493 __supported_pte_mask &= ~_PAGE_NX;
513 return -EINVAL; 494 } else {
495 return -EINVAL;
496 }
497 }
514 498
515 return 0; 499 return 0;
516} 500}
@@ -522,6 +506,7 @@ static void __init set_nx(void)
522 506
523 if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) { 507 if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
524 cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]); 508 cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
509
525 if ((v[3] & (1 << 20)) && !disable_nx) { 510 if ((v[3] & (1 << 20)) && !disable_nx) {
526 rdmsr(MSR_EFER, l, h); 511 rdmsr(MSR_EFER, l, h);
527 l |= EFER_NX; 512 l |= EFER_NX;
@@ -531,35 +516,6 @@ static void __init set_nx(void)
531 } 516 }
532 } 517 }
533} 518}
534
535/*
536 * Enables/disables executability of a given kernel page and
537 * returns the previous setting.
538 */
539int __init set_kernel_exec(unsigned long vaddr, int enable)
540{
541 pte_t *pte;
542 int ret = 1;
543
544 if (!nx_enabled)
545 goto out;
546
547 pte = lookup_address(vaddr);
548 BUG_ON(!pte);
549
550 if (!pte_exec_kernel(*pte))
551 ret = 0;
552
553 if (enable)
554 pte->pte_high &= ~(1 << (_PAGE_BIT_NX - 32));
555 else
556 pte->pte_high |= 1 << (_PAGE_BIT_NX - 32);
557 pte_update_defer(&init_mm, vaddr, pte);
558 __flush_tlb_all();
559out:
560 return ret;
561}
562
563#endif 519#endif
564 520
565/* 521/*
@@ -574,9 +530,8 @@ void __init paging_init(void)
574#ifdef CONFIG_X86_PAE 530#ifdef CONFIG_X86_PAE
575 set_nx(); 531 set_nx();
576 if (nx_enabled) 532 if (nx_enabled)
577 printk("NX (Execute Disable) protection: active\n"); 533 printk(KERN_INFO "NX (Execute Disable) protection: active\n");
578#endif 534#endif
579
580 pagetable_init(); 535 pagetable_init();
581 536
582 load_cr3(swapper_pg_dir); 537 load_cr3(swapper_pg_dir);
@@ -600,10 +555,10 @@ void __init paging_init(void)
600 * used to involve black magic jumps to work around some nasty CPU bugs, 555 * used to involve black magic jumps to work around some nasty CPU bugs,
601 * but fortunately the switch to using exceptions got rid of all that. 556 * but fortunately the switch to using exceptions got rid of all that.
602 */ 557 */
603
604static void __init test_wp_bit(void) 558static void __init test_wp_bit(void)
605{ 559{
606 printk("Checking if this processor honours the WP bit even in supervisor mode... "); 560 printk(KERN_INFO
561 "Checking if this processor honours the WP bit even in supervisor mode...");
607 562
608 /* Any page-aligned address will do, the test is non-destructive */ 563 /* Any page-aligned address will do, the test is non-destructive */
609 __set_fixmap(FIX_WP_TEST, __pa(&swapper_pg_dir), PAGE_READONLY); 564 __set_fixmap(FIX_WP_TEST, __pa(&swapper_pg_dir), PAGE_READONLY);
@@ -611,47 +566,46 @@ static void __init test_wp_bit(void)
611 clear_fixmap(FIX_WP_TEST); 566 clear_fixmap(FIX_WP_TEST);
612 567
613 if (!boot_cpu_data.wp_works_ok) { 568 if (!boot_cpu_data.wp_works_ok) {
614 printk("No.\n"); 569 printk(KERN_CONT "No.\n");
615#ifdef CONFIG_X86_WP_WORKS_OK 570#ifdef CONFIG_X86_WP_WORKS_OK
616 panic("This kernel doesn't support CPU's with broken WP. Recompile it for a 386!"); 571 panic(
572 "This kernel doesn't support CPU's with broken WP. Recompile it for a 386!");
617#endif 573#endif
618 } else { 574 } else {
619 printk("Ok.\n"); 575 printk(KERN_CONT "Ok.\n");
620 } 576 }
621} 577}
622 578
623static struct kcore_list kcore_mem, kcore_vmalloc; 579static struct kcore_list kcore_mem, kcore_vmalloc;
624 580
625void __init mem_init(void) 581void __init mem_init(void)
626{ 582{
627 extern int ppro_with_ram_bug(void);
628 int codesize, reservedpages, datasize, initsize; 583 int codesize, reservedpages, datasize, initsize;
629 int tmp; 584 int tmp, bad_ppro;
630 int bad_ppro;
631 585
632#ifdef CONFIG_FLATMEM 586#ifdef CONFIG_FLATMEM
633 BUG_ON(!mem_map); 587 BUG_ON(!mem_map);
634#endif 588#endif
635
636 bad_ppro = ppro_with_ram_bug(); 589 bad_ppro = ppro_with_ram_bug();
637 590
638#ifdef CONFIG_HIGHMEM 591#ifdef CONFIG_HIGHMEM
639 /* check that fixmap and pkmap do not overlap */ 592 /* check that fixmap and pkmap do not overlap */
640 if (PKMAP_BASE+LAST_PKMAP*PAGE_SIZE >= FIXADDR_START) { 593 if (PKMAP_BASE + LAST_PKMAP*PAGE_SIZE >= FIXADDR_START) {
641 printk(KERN_ERR "fixmap and kmap areas overlap - this will crash\n"); 594 printk(KERN_ERR
595 "fixmap and kmap areas overlap - this will crash\n");
642 printk(KERN_ERR "pkstart: %lxh pkend: %lxh fixstart %lxh\n", 596 printk(KERN_ERR "pkstart: %lxh pkend: %lxh fixstart %lxh\n",
643 PKMAP_BASE, PKMAP_BASE+LAST_PKMAP*PAGE_SIZE, FIXADDR_START); 597 PKMAP_BASE, PKMAP_BASE + LAST_PKMAP*PAGE_SIZE,
598 FIXADDR_START);
644 BUG(); 599 BUG();
645 } 600 }
646#endif 601#endif
647
648 /* this will put all low memory onto the freelists */ 602 /* this will put all low memory onto the freelists */
649 totalram_pages += free_all_bootmem(); 603 totalram_pages += free_all_bootmem();
650 604
651 reservedpages = 0; 605 reservedpages = 0;
652 for (tmp = 0; tmp < max_low_pfn; tmp++) 606 for (tmp = 0; tmp < max_low_pfn; tmp++)
653 /* 607 /*
654 * Only count reserved RAM pages 608 * Only count reserved RAM pages:
655 */ 609 */
656 if (page_is_ram(tmp) && PageReserved(pfn_to_page(tmp))) 610 if (page_is_ram(tmp) && PageReserved(pfn_to_page(tmp)))
657 reservedpages++; 611 reservedpages++;
@@ -662,11 +616,12 @@ void __init mem_init(void)
662 datasize = (unsigned long) &_edata - (unsigned long) &_etext; 616 datasize = (unsigned long) &_edata - (unsigned long) &_etext;
663 initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; 617 initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
664 618
665 kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT); 619 kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
666 kclist_add(&kcore_vmalloc, (void *)VMALLOC_START, 620 kclist_add(&kcore_vmalloc, (void *)VMALLOC_START,
667 VMALLOC_END-VMALLOC_START); 621 VMALLOC_END-VMALLOC_START);
668 622
669 printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init, %ldk highmem)\n", 623 printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, "
624 "%dk reserved, %dk data, %dk init, %ldk highmem)\n",
670 (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), 625 (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
671 num_physpages << (PAGE_SHIFT-10), 626 num_physpages << (PAGE_SHIFT-10),
672 codesize >> 10, 627 codesize >> 10,
@@ -677,45 +632,46 @@ void __init mem_init(void)
677 ); 632 );
678 633
679#if 1 /* double-sanity-check paranoia */ 634#if 1 /* double-sanity-check paranoia */
680 printk("virtual kernel memory layout:\n" 635 printk(KERN_INFO "virtual kernel memory layout:\n"
681 " fixmap : 0x%08lx - 0x%08lx (%4ld kB)\n" 636 " fixmap : 0x%08lx - 0x%08lx (%4ld kB)\n"
682#ifdef CONFIG_HIGHMEM 637#ifdef CONFIG_HIGHMEM
683 " pkmap : 0x%08lx - 0x%08lx (%4ld kB)\n" 638 " pkmap : 0x%08lx - 0x%08lx (%4ld kB)\n"
684#endif 639#endif
685 " vmalloc : 0x%08lx - 0x%08lx (%4ld MB)\n" 640 " vmalloc : 0x%08lx - 0x%08lx (%4ld MB)\n"
686 " lowmem : 0x%08lx - 0x%08lx (%4ld MB)\n" 641 " lowmem : 0x%08lx - 0x%08lx (%4ld MB)\n"
687 " .init : 0x%08lx - 0x%08lx (%4ld kB)\n" 642 " .init : 0x%08lx - 0x%08lx (%4ld kB)\n"
688 " .data : 0x%08lx - 0x%08lx (%4ld kB)\n" 643 " .data : 0x%08lx - 0x%08lx (%4ld kB)\n"
689 " .text : 0x%08lx - 0x%08lx (%4ld kB)\n", 644 " .text : 0x%08lx - 0x%08lx (%4ld kB)\n",
690 FIXADDR_START, FIXADDR_TOP, 645 FIXADDR_START, FIXADDR_TOP,
691 (FIXADDR_TOP - FIXADDR_START) >> 10, 646 (FIXADDR_TOP - FIXADDR_START) >> 10,
692 647
693#ifdef CONFIG_HIGHMEM 648#ifdef CONFIG_HIGHMEM
694 PKMAP_BASE, PKMAP_BASE+LAST_PKMAP*PAGE_SIZE, 649 PKMAP_BASE, PKMAP_BASE+LAST_PKMAP*PAGE_SIZE,
695 (LAST_PKMAP*PAGE_SIZE) >> 10, 650 (LAST_PKMAP*PAGE_SIZE) >> 10,
696#endif 651#endif
697 652
698 VMALLOC_START, VMALLOC_END, 653 VMALLOC_START, VMALLOC_END,
699 (VMALLOC_END - VMALLOC_START) >> 20, 654 (VMALLOC_END - VMALLOC_START) >> 20,
700 655
701 (unsigned long)__va(0), (unsigned long)high_memory, 656 (unsigned long)__va(0), (unsigned long)high_memory,
702 ((unsigned long)high_memory - (unsigned long)__va(0)) >> 20, 657 ((unsigned long)high_memory - (unsigned long)__va(0)) >> 20,
703 658
704 (unsigned long)&__init_begin, (unsigned long)&__init_end, 659 (unsigned long)&__init_begin, (unsigned long)&__init_end,
705 ((unsigned long)&__init_end - (unsigned long)&__init_begin) >> 10, 660 ((unsigned long)&__init_end -
661 (unsigned long)&__init_begin) >> 10,
706 662
707 (unsigned long)&_etext, (unsigned long)&_edata, 663 (unsigned long)&_etext, (unsigned long)&_edata,
708 ((unsigned long)&_edata - (unsigned long)&_etext) >> 10, 664 ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
709 665
710 (unsigned long)&_text, (unsigned long)&_etext, 666 (unsigned long)&_text, (unsigned long)&_etext,
711 ((unsigned long)&_etext - (unsigned long)&_text) >> 10); 667 ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
712 668
713#ifdef CONFIG_HIGHMEM 669#ifdef CONFIG_HIGHMEM
714 BUG_ON(PKMAP_BASE+LAST_PKMAP*PAGE_SIZE > FIXADDR_START); 670 BUG_ON(PKMAP_BASE + LAST_PKMAP*PAGE_SIZE > FIXADDR_START);
715 BUG_ON(VMALLOC_END > PKMAP_BASE); 671 BUG_ON(VMALLOC_END > PKMAP_BASE);
716#endif 672#endif
717 BUG_ON(VMALLOC_START > VMALLOC_END); 673 BUG_ON(VMALLOC_START > VMALLOC_END);
718 BUG_ON((unsigned long)high_memory > VMALLOC_START); 674 BUG_ON((unsigned long)high_memory > VMALLOC_START);
719#endif /* double-sanity-check paranoia */ 675#endif /* double-sanity-check paranoia */
720 676
721#ifdef CONFIG_X86_PAE 677#ifdef CONFIG_X86_PAE
@@ -746,49 +702,38 @@ int arch_add_memory(int nid, u64 start, u64 size)
746 702
747 return __add_pages(zone, start_pfn, nr_pages); 703 return __add_pages(zone, start_pfn, nr_pages);
748} 704}
749
750#endif 705#endif
751 706
752struct kmem_cache *pmd_cache;
753
754void __init pgtable_cache_init(void)
755{
756 if (PTRS_PER_PMD > 1)
757 pmd_cache = kmem_cache_create("pmd",
758 PTRS_PER_PMD*sizeof(pmd_t),
759 PTRS_PER_PMD*sizeof(pmd_t),
760 SLAB_PANIC,
761 pmd_ctor);
762}
763
764/* 707/*
765 * This function cannot be __init, since exceptions don't work in that 708 * This function cannot be __init, since exceptions don't work in that
766 * section. Put this after the callers, so that it cannot be inlined. 709 * section. Put this after the callers, so that it cannot be inlined.
767 */ 710 */
768static int noinline do_test_wp_bit(void) 711static noinline int do_test_wp_bit(void)
769{ 712{
770 char tmp_reg; 713 char tmp_reg;
771 int flag; 714 int flag;
772 715
773 __asm__ __volatile__( 716 __asm__ __volatile__(
774 " movb %0,%1 \n" 717 " movb %0, %1 \n"
775 "1: movb %1,%0 \n" 718 "1: movb %1, %0 \n"
776 " xorl %2,%2 \n" 719 " xorl %2, %2 \n"
777 "2: \n" 720 "2: \n"
778 ".section __ex_table,\"a\"\n" 721 ".section __ex_table, \"a\"\n"
779 " .align 4 \n" 722 " .align 4 \n"
780 " .long 1b,2b \n" 723 " .long 1b, 2b \n"
781 ".previous \n" 724 ".previous \n"
782 :"=m" (*(char *)fix_to_virt(FIX_WP_TEST)), 725 :"=m" (*(char *)fix_to_virt(FIX_WP_TEST)),
783 "=q" (tmp_reg), 726 "=q" (tmp_reg),
784 "=r" (flag) 727 "=r" (flag)
785 :"2" (1) 728 :"2" (1)
786 :"memory"); 729 :"memory");
787 730
788 return flag; 731 return flag;
789} 732}
790 733
791#ifdef CONFIG_DEBUG_RODATA 734#ifdef CONFIG_DEBUG_RODATA
735const int rodata_test_data = 0xC3;
736EXPORT_SYMBOL_GPL(rodata_test_data);
792 737
793void mark_rodata_ro(void) 738void mark_rodata_ro(void)
794{ 739{
@@ -801,32 +746,58 @@ void mark_rodata_ro(void)
801 if (num_possible_cpus() <= 1) 746 if (num_possible_cpus() <= 1)
802#endif 747#endif
803 { 748 {
804 change_page_attr(virt_to_page(start), 749 set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT);
805 size >> PAGE_SHIFT, PAGE_KERNEL_RX); 750 printk(KERN_INFO "Write protecting the kernel text: %luk\n",
806 printk("Write protecting the kernel text: %luk\n", size >> 10); 751 size >> 10);
752
753#ifdef CONFIG_CPA_DEBUG
754 printk(KERN_INFO "Testing CPA: Reverting %lx-%lx\n",
755 start, start+size);
756 set_pages_rw(virt_to_page(start), size>>PAGE_SHIFT);
757
758 printk(KERN_INFO "Testing CPA: write protecting again\n");
759 set_pages_ro(virt_to_page(start), size>>PAGE_SHIFT);
760#endif
807 } 761 }
808#endif 762#endif
809 start += size; 763 start += size;
810 size = (unsigned long)__end_rodata - start; 764 size = (unsigned long)__end_rodata - start;
811 change_page_attr(virt_to_page(start), 765 set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT);
812 size >> PAGE_SHIFT, PAGE_KERNEL_RO); 766 printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n",
813 printk("Write protecting the kernel read-only data: %luk\n", 767 size >> 10);
814 size >> 10); 768 rodata_test();
815 769
816 /* 770#ifdef CONFIG_CPA_DEBUG
817 * change_page_attr() requires a global_flush_tlb() call after it. 771 printk(KERN_INFO "Testing CPA: undo %lx-%lx\n", start, start + size);
818 * We do this after the printk so that if something went wrong in the 772 set_pages_rw(virt_to_page(start), size >> PAGE_SHIFT);
819 * change, the printk gets out at least to give a better debug hint 773
820 * of who is the culprit. 774 printk(KERN_INFO "Testing CPA: write protecting again\n");
821 */ 775 set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT);
822 global_flush_tlb(); 776#endif
823} 777}
824#endif 778#endif
825 779
826void free_init_pages(char *what, unsigned long begin, unsigned long end) 780void free_init_pages(char *what, unsigned long begin, unsigned long end)
827{ 781{
782#ifdef CONFIG_DEBUG_PAGEALLOC
783 /*
784 * If debugging page accesses then do not free this memory but
785 * mark them not present - any buggy init-section access will
786 * create a kernel page fault:
787 */
788 printk(KERN_INFO "debug: unmapping init memory %08lx..%08lx\n",
789 begin, PAGE_ALIGN(end));
790 set_memory_np(begin, (end - begin) >> PAGE_SHIFT);
791#else
828 unsigned long addr; 792 unsigned long addr;
829 793
794 /*
795 * We just marked the kernel text read only above, now that
796 * we are going to free part of that, we need to make that
797 * writeable first.
798 */
799 set_memory_rw(begin, (end - begin) >> PAGE_SHIFT);
800
830 for (addr = begin; addr < end; addr += PAGE_SIZE) { 801 for (addr = begin; addr < end; addr += PAGE_SIZE) {
831 ClearPageReserved(virt_to_page(addr)); 802 ClearPageReserved(virt_to_page(addr));
832 init_page_count(virt_to_page(addr)); 803 init_page_count(virt_to_page(addr));
@@ -835,6 +806,7 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
835 totalram_pages++; 806 totalram_pages++;
836 } 807 }
837 printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10); 808 printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10);
809#endif
838} 810}
839 811
840void free_initmem(void) 812void free_initmem(void)
@@ -850,4 +822,3 @@ void free_initrd_mem(unsigned long start, unsigned long end)
850 free_init_pages("initrd memory", start, end); 822 free_init_pages("initrd memory", start, end);
851} 823}
852#endif 824#endif
853
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 0f9c8c890658..cc50a13ce8d9 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -43,12 +43,10 @@
43#include <asm/proto.h> 43#include <asm/proto.h>
44#include <asm/smp.h> 44#include <asm/smp.h>
45#include <asm/sections.h> 45#include <asm/sections.h>
46#include <asm/kdebug.h>
47#include <asm/numa.h>
46 48
47#ifndef Dprintk 49const struct dma_mapping_ops *dma_ops;
48#define Dprintk(x...)
49#endif
50
51const struct dma_mapping_ops* dma_ops;
52EXPORT_SYMBOL(dma_ops); 50EXPORT_SYMBOL(dma_ops);
53 51
54static unsigned long dma_reserve __initdata; 52static unsigned long dma_reserve __initdata;
@@ -65,22 +63,26 @@ void show_mem(void)
65{ 63{
66 long i, total = 0, reserved = 0; 64 long i, total = 0, reserved = 0;
67 long shared = 0, cached = 0; 65 long shared = 0, cached = 0;
68 pg_data_t *pgdat;
69 struct page *page; 66 struct page *page;
67 pg_data_t *pgdat;
70 68
71 printk(KERN_INFO "Mem-info:\n"); 69 printk(KERN_INFO "Mem-info:\n");
72 show_free_areas(); 70 show_free_areas();
73 printk(KERN_INFO "Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); 71 printk(KERN_INFO "Free swap: %6ldkB\n",
72 nr_swap_pages << (PAGE_SHIFT-10));
74 73
75 for_each_online_pgdat(pgdat) { 74 for_each_online_pgdat(pgdat) {
76 for (i = 0; i < pgdat->node_spanned_pages; ++i) { 75 for (i = 0; i < pgdat->node_spanned_pages; ++i) {
77 /* this loop can take a while with 256 GB and 4k pages 76 /*
78 so update the NMI watchdog */ 77 * This loop can take a while with 256 GB and
79 if (unlikely(i % MAX_ORDER_NR_PAGES == 0)) { 78 * 4k pages so defer the NMI watchdog:
79 */
80 if (unlikely(i % MAX_ORDER_NR_PAGES == 0))
80 touch_nmi_watchdog(); 81 touch_nmi_watchdog();
81 } 82
82 if (!pfn_valid(pgdat->node_start_pfn + i)) 83 if (!pfn_valid(pgdat->node_start_pfn + i))
83 continue; 84 continue;
85
84 page = pfn_to_page(pgdat->node_start_pfn + i); 86 page = pfn_to_page(pgdat->node_start_pfn + i);
85 total++; 87 total++;
86 if (PageReserved(page)) 88 if (PageReserved(page))
@@ -89,51 +91,58 @@ void show_mem(void)
89 cached++; 91 cached++;
90 else if (page_count(page)) 92 else if (page_count(page))
91 shared += page_count(page) - 1; 93 shared += page_count(page) - 1;
92 } 94 }
93 } 95 }
94 printk(KERN_INFO "%lu pages of RAM\n", total); 96 printk(KERN_INFO "%lu pages of RAM\n", total);
95 printk(KERN_INFO "%lu reserved pages\n",reserved); 97 printk(KERN_INFO "%lu reserved pages\n", reserved);
96 printk(KERN_INFO "%lu pages shared\n",shared); 98 printk(KERN_INFO "%lu pages shared\n", shared);
97 printk(KERN_INFO "%lu pages swap cached\n",cached); 99 printk(KERN_INFO "%lu pages swap cached\n", cached);
98} 100}
99 101
100int after_bootmem; 102int after_bootmem;
101 103
102static __init void *spp_getpage(void) 104static __init void *spp_getpage(void)
103{ 105{
104 void *ptr; 106 void *ptr;
107
105 if (after_bootmem) 108 if (after_bootmem)
106 ptr = (void *) get_zeroed_page(GFP_ATOMIC); 109 ptr = (void *) get_zeroed_page(GFP_ATOMIC);
107 else 110 else
108 ptr = alloc_bootmem_pages(PAGE_SIZE); 111 ptr = alloc_bootmem_pages(PAGE_SIZE);
109 if (!ptr || ((unsigned long)ptr & ~PAGE_MASK))
110 panic("set_pte_phys: cannot allocate page data %s\n", after_bootmem?"after bootmem":"");
111 112
112 Dprintk("spp_getpage %p\n", ptr); 113 if (!ptr || ((unsigned long)ptr & ~PAGE_MASK)) {
114 panic("set_pte_phys: cannot allocate page data %s\n",
115 after_bootmem ? "after bootmem" : "");
116 }
117
118 pr_debug("spp_getpage %p\n", ptr);
119
113 return ptr; 120 return ptr;
114} 121}
115 122
116static __init void set_pte_phys(unsigned long vaddr, 123static __init void
117 unsigned long phys, pgprot_t prot) 124set_pte_phys(unsigned long vaddr, unsigned long phys, pgprot_t prot)
118{ 125{
119 pgd_t *pgd; 126 pgd_t *pgd;
120 pud_t *pud; 127 pud_t *pud;
121 pmd_t *pmd; 128 pmd_t *pmd;
122 pte_t *pte, new_pte; 129 pte_t *pte, new_pte;
123 130
124 Dprintk("set_pte_phys %lx to %lx\n", vaddr, phys); 131 pr_debug("set_pte_phys %lx to %lx\n", vaddr, phys);
125 132
126 pgd = pgd_offset_k(vaddr); 133 pgd = pgd_offset_k(vaddr);
127 if (pgd_none(*pgd)) { 134 if (pgd_none(*pgd)) {
128 printk("PGD FIXMAP MISSING, it should be setup in head.S!\n"); 135 printk(KERN_ERR
136 "PGD FIXMAP MISSING, it should be setup in head.S!\n");
129 return; 137 return;
130 } 138 }
131 pud = pud_offset(pgd, vaddr); 139 pud = pud_offset(pgd, vaddr);
132 if (pud_none(*pud)) { 140 if (pud_none(*pud)) {
133 pmd = (pmd_t *) spp_getpage(); 141 pmd = (pmd_t *) spp_getpage();
134 set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER)); 142 set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
135 if (pmd != pmd_offset(pud, 0)) { 143 if (pmd != pmd_offset(pud, 0)) {
136 printk("PAGETABLE BUG #01! %p <-> %p\n", pmd, pmd_offset(pud,0)); 144 printk(KERN_ERR "PAGETABLE BUG #01! %p <-> %p\n",
145 pmd, pmd_offset(pud, 0));
137 return; 146 return;
138 } 147 }
139 } 148 }
@@ -142,7 +151,7 @@ static __init void set_pte_phys(unsigned long vaddr,
142 pte = (pte_t *) spp_getpage(); 151 pte = (pte_t *) spp_getpage();
143 set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER)); 152 set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
144 if (pte != pte_offset_kernel(pmd, 0)) { 153 if (pte != pte_offset_kernel(pmd, 0)) {
145 printk("PAGETABLE BUG #02!\n"); 154 printk(KERN_ERR "PAGETABLE BUG #02!\n");
146 return; 155 return;
147 } 156 }
148 } 157 }
@@ -162,33 +171,35 @@ static __init void set_pte_phys(unsigned long vaddr,
162} 171}
163 172
164/* NOTE: this is meant to be run only at boot */ 173/* NOTE: this is meant to be run only at boot */
165void __init 174void __init
166__set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t prot) 175__set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
167{ 176{
168 unsigned long address = __fix_to_virt(idx); 177 unsigned long address = __fix_to_virt(idx);
169 178
170 if (idx >= __end_of_fixed_addresses) { 179 if (idx >= __end_of_fixed_addresses) {
171 printk("Invalid __set_fixmap\n"); 180 printk(KERN_ERR "Invalid __set_fixmap\n");
172 return; 181 return;
173 } 182 }
174 set_pte_phys(address, phys, prot); 183 set_pte_phys(address, phys, prot);
175} 184}
176 185
177unsigned long __meminitdata table_start, table_end; 186static unsigned long __initdata table_start;
187static unsigned long __meminitdata table_end;
178 188
179static __meminit void *alloc_low_page(unsigned long *phys) 189static __meminit void *alloc_low_page(unsigned long *phys)
180{ 190{
181 unsigned long pfn = table_end++; 191 unsigned long pfn = table_end++;
182 void *adr; 192 void *adr;
183 193
184 if (after_bootmem) { 194 if (after_bootmem) {
185 adr = (void *)get_zeroed_page(GFP_ATOMIC); 195 adr = (void *)get_zeroed_page(GFP_ATOMIC);
186 *phys = __pa(adr); 196 *phys = __pa(adr);
197
187 return adr; 198 return adr;
188 } 199 }
189 200
190 if (pfn >= end_pfn) 201 if (pfn >= end_pfn)
191 panic("alloc_low_page: ran out of memory"); 202 panic("alloc_low_page: ran out of memory");
192 203
193 adr = early_ioremap(pfn * PAGE_SIZE, PAGE_SIZE); 204 adr = early_ioremap(pfn * PAGE_SIZE, PAGE_SIZE);
194 memset(adr, 0, PAGE_SIZE); 205 memset(adr, 0, PAGE_SIZE);
@@ -197,44 +208,49 @@ static __meminit void *alloc_low_page(unsigned long *phys)
197} 208}
198 209
199static __meminit void unmap_low_page(void *adr) 210static __meminit void unmap_low_page(void *adr)
200{ 211{
201
202 if (after_bootmem) 212 if (after_bootmem)
203 return; 213 return;
204 214
205 early_iounmap(adr, PAGE_SIZE); 215 early_iounmap(adr, PAGE_SIZE);
206} 216}
207 217
208/* Must run before zap_low_mappings */ 218/* Must run before zap_low_mappings */
209__meminit void *early_ioremap(unsigned long addr, unsigned long size) 219__meminit void *early_ioremap(unsigned long addr, unsigned long size)
210{ 220{
211 unsigned long vaddr;
212 pmd_t *pmd, *last_pmd; 221 pmd_t *pmd, *last_pmd;
222 unsigned long vaddr;
213 int i, pmds; 223 int i, pmds;
214 224
215 pmds = ((addr & ~PMD_MASK) + size + ~PMD_MASK) / PMD_SIZE; 225 pmds = ((addr & ~PMD_MASK) + size + ~PMD_MASK) / PMD_SIZE;
216 vaddr = __START_KERNEL_map; 226 vaddr = __START_KERNEL_map;
217 pmd = level2_kernel_pgt; 227 pmd = level2_kernel_pgt;
218 last_pmd = level2_kernel_pgt + PTRS_PER_PMD - 1; 228 last_pmd = level2_kernel_pgt + PTRS_PER_PMD - 1;
229
219 for (; pmd <= last_pmd; pmd++, vaddr += PMD_SIZE) { 230 for (; pmd <= last_pmd; pmd++, vaddr += PMD_SIZE) {
220 for (i = 0; i < pmds; i++) { 231 for (i = 0; i < pmds; i++) {
221 if (pmd_present(pmd[i])) 232 if (pmd_present(pmd[i]))
222 goto next; 233 goto continue_outer_loop;
223 } 234 }
224 vaddr += addr & ~PMD_MASK; 235 vaddr += addr & ~PMD_MASK;
225 addr &= PMD_MASK; 236 addr &= PMD_MASK;
237
226 for (i = 0; i < pmds; i++, addr += PMD_SIZE) 238 for (i = 0; i < pmds; i++, addr += PMD_SIZE)
227 set_pmd(pmd + i,__pmd(addr | _KERNPG_TABLE | _PAGE_PSE)); 239 set_pmd(pmd+i, __pmd(addr | __PAGE_KERNEL_LARGE_EXEC));
228 __flush_tlb(); 240 __flush_tlb_all();
241
229 return (void *)vaddr; 242 return (void *)vaddr;
230 next: 243continue_outer_loop:
231 ; 244 ;
232 } 245 }
233 printk("early_ioremap(0x%lx, %lu) failed\n", addr, size); 246 printk(KERN_ERR "early_ioremap(0x%lx, %lu) failed\n", addr, size);
247
234 return NULL; 248 return NULL;
235} 249}
236 250
237/* To avoid virtual aliases later */ 251/*
252 * To avoid virtual aliases later:
253 */
238__meminit void early_iounmap(void *addr, unsigned long size) 254__meminit void early_iounmap(void *addr, unsigned long size)
239{ 255{
240 unsigned long vaddr; 256 unsigned long vaddr;
@@ -244,9 +260,11 @@ __meminit void early_iounmap(void *addr, unsigned long size)
244 vaddr = (unsigned long)addr; 260 vaddr = (unsigned long)addr;
245 pmds = ((vaddr & ~PMD_MASK) + size + ~PMD_MASK) / PMD_SIZE; 261 pmds = ((vaddr & ~PMD_MASK) + size + ~PMD_MASK) / PMD_SIZE;
246 pmd = level2_kernel_pgt + pmd_index(vaddr); 262 pmd = level2_kernel_pgt + pmd_index(vaddr);
263
247 for (i = 0; i < pmds; i++) 264 for (i = 0; i < pmds; i++)
248 pmd_clear(pmd + i); 265 pmd_clear(pmd + i);
249 __flush_tlb(); 266
267 __flush_tlb_all();
250} 268}
251 269
252static void __meminit 270static void __meminit
@@ -259,16 +277,17 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end)
259 pmd_t *pmd = pmd_page + pmd_index(address); 277 pmd_t *pmd = pmd_page + pmd_index(address);
260 278
261 if (address >= end) { 279 if (address >= end) {
262 if (!after_bootmem) 280 if (!after_bootmem) {
263 for (; i < PTRS_PER_PMD; i++, pmd++) 281 for (; i < PTRS_PER_PMD; i++, pmd++)
264 set_pmd(pmd, __pmd(0)); 282 set_pmd(pmd, __pmd(0));
283 }
265 break; 284 break;
266 } 285 }
267 286
268 if (pmd_val(*pmd)) 287 if (pmd_val(*pmd))
269 continue; 288 continue;
270 289
271 entry = _PAGE_NX|_PAGE_PSE|_KERNPG_TABLE|_PAGE_GLOBAL|address; 290 entry = __PAGE_KERNEL_LARGE|_PAGE_GLOBAL|address;
272 entry &= __supported_pte_mask; 291 entry &= __supported_pte_mask;
273 set_pmd(pmd, __pmd(entry)); 292 set_pmd(pmd, __pmd(entry));
274 } 293 }
@@ -277,19 +296,19 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end)
277static void __meminit 296static void __meminit
278phys_pmd_update(pud_t *pud, unsigned long address, unsigned long end) 297phys_pmd_update(pud_t *pud, unsigned long address, unsigned long end)
279{ 298{
280 pmd_t *pmd = pmd_offset(pud,0); 299 pmd_t *pmd = pmd_offset(pud, 0);
281 spin_lock(&init_mm.page_table_lock); 300 spin_lock(&init_mm.page_table_lock);
282 phys_pmd_init(pmd, address, end); 301 phys_pmd_init(pmd, address, end);
283 spin_unlock(&init_mm.page_table_lock); 302 spin_unlock(&init_mm.page_table_lock);
284 __flush_tlb_all(); 303 __flush_tlb_all();
285} 304}
286 305
287static void __meminit phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end) 306static void __meminit
288{ 307phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end)
308{
289 int i = pud_index(addr); 309 int i = pud_index(addr);
290 310
291 311 for (; i < PTRS_PER_PUD; i++, addr = (addr & PUD_MASK) + PUD_SIZE) {
292 for (; i < PTRS_PER_PUD; i++, addr = (addr & PUD_MASK) + PUD_SIZE ) {
293 unsigned long pmd_phys; 312 unsigned long pmd_phys;
294 pud_t *pud = pud_page + pud_index(addr); 313 pud_t *pud = pud_page + pud_index(addr);
295 pmd_t *pmd; 314 pmd_t *pmd;
@@ -297,10 +316,11 @@ static void __meminit phys_pud_init(pud_t *pud_page, unsigned long addr, unsigne
297 if (addr >= end) 316 if (addr >= end)
298 break; 317 break;
299 318
300 if (!after_bootmem && !e820_any_mapped(addr,addr+PUD_SIZE,0)) { 319 if (!after_bootmem &&
301 set_pud(pud, __pud(0)); 320 !e820_any_mapped(addr, addr+PUD_SIZE, 0)) {
321 set_pud(pud, __pud(0));
302 continue; 322 continue;
303 } 323 }
304 324
305 if (pud_val(*pud)) { 325 if (pud_val(*pud)) {
306 phys_pmd_update(pud, addr, end); 326 phys_pmd_update(pud, addr, end);
@@ -308,14 +328,16 @@ static void __meminit phys_pud_init(pud_t *pud_page, unsigned long addr, unsigne
308 } 328 }
309 329
310 pmd = alloc_low_page(&pmd_phys); 330 pmd = alloc_low_page(&pmd_phys);
331
311 spin_lock(&init_mm.page_table_lock); 332 spin_lock(&init_mm.page_table_lock);
312 set_pud(pud, __pud(pmd_phys | _KERNPG_TABLE)); 333 set_pud(pud, __pud(pmd_phys | _KERNPG_TABLE));
313 phys_pmd_init(pmd, addr, end); 334 phys_pmd_init(pmd, addr, end);
314 spin_unlock(&init_mm.page_table_lock); 335 spin_unlock(&init_mm.page_table_lock);
336
315 unmap_low_page(pmd); 337 unmap_low_page(pmd);
316 } 338 }
317 __flush_tlb(); 339 __flush_tlb_all();
318} 340}
319 341
320static void __init find_early_table_space(unsigned long end) 342static void __init find_early_table_space(unsigned long end)
321{ 343{
@@ -326,14 +348,23 @@ static void __init find_early_table_space(unsigned long end)
326 tables = round_up(puds * sizeof(pud_t), PAGE_SIZE) + 348 tables = round_up(puds * sizeof(pud_t), PAGE_SIZE) +
327 round_up(pmds * sizeof(pmd_t), PAGE_SIZE); 349 round_up(pmds * sizeof(pmd_t), PAGE_SIZE);
328 350
329 /* RED-PEN putting page tables only on node 0 could 351 /*
330 cause a hotspot and fill up ZONE_DMA. The page tables 352 * RED-PEN putting page tables only on node 0 could
331 need roughly 0.5KB per GB. */ 353 * cause a hotspot and fill up ZONE_DMA. The page tables
332 start = 0x8000; 354 * need roughly 0.5KB per GB.
333 table_start = find_e820_area(start, end, tables); 355 */
356 start = 0x8000;
357 table_start = find_e820_area(start, end, tables);
334 if (table_start == -1UL) 358 if (table_start == -1UL)
335 panic("Cannot find space for the kernel page tables"); 359 panic("Cannot find space for the kernel page tables");
336 360
361 /*
362 * When you have a lot of RAM like 256GB, early_table will not fit
363 * into 0x8000 range, find_e820_area() will find area after kernel
364 * bss but the table_start is not page aligned, so need to round it
365 * up to avoid overlap with bss:
366 */
367 table_start = round_up(table_start, PAGE_SIZE);
337 table_start >>= PAGE_SHIFT; 368 table_start >>= PAGE_SHIFT;
338 table_end = table_start; 369 table_end = table_start;
339 370
@@ -342,20 +373,23 @@ static void __init find_early_table_space(unsigned long end)
342 (table_start << PAGE_SHIFT) + tables); 373 (table_start << PAGE_SHIFT) + tables);
343} 374}
344 375
345/* Setup the direct mapping of the physical memory at PAGE_OFFSET. 376/*
346 This runs before bootmem is initialized and gets pages directly from the 377 * Setup the direct mapping of the physical memory at PAGE_OFFSET.
347 physical memory. To access them they are temporarily mapped. */ 378 * This runs before bootmem is initialized and gets pages directly from
379 * the physical memory. To access them they are temporarily mapped.
380 */
348void __init_refok init_memory_mapping(unsigned long start, unsigned long end) 381void __init_refok init_memory_mapping(unsigned long start, unsigned long end)
349{ 382{
350 unsigned long next; 383 unsigned long next;
351 384
352 Dprintk("init_memory_mapping\n"); 385 pr_debug("init_memory_mapping\n");
353 386
354 /* 387 /*
355 * Find space for the kernel direct mapping tables. 388 * Find space for the kernel direct mapping tables.
356 * Later we should allocate these tables in the local node of the memory 389 *
357 * mapped. Unfortunately this is done currently before the nodes are 390 * Later we should allocate these tables in the local node of the
358 * discovered. 391 * memory mapped. Unfortunately this is done currently before the
392 * nodes are discovered.
359 */ 393 */
360 if (!after_bootmem) 394 if (!after_bootmem)
361 find_early_table_space(end); 395 find_early_table_space(end);
@@ -364,8 +398,8 @@ void __init_refok init_memory_mapping(unsigned long start, unsigned long end)
364 end = (unsigned long)__va(end); 398 end = (unsigned long)__va(end);
365 399
366 for (; start < end; start = next) { 400 for (; start < end; start = next) {
367 unsigned long pud_phys;
368 pgd_t *pgd = pgd_offset_k(start); 401 pgd_t *pgd = pgd_offset_k(start);
402 unsigned long pud_phys;
369 pud_t *pud; 403 pud_t *pud;
370 404
371 if (after_bootmem) 405 if (after_bootmem)
@@ -374,23 +408,26 @@ void __init_refok init_memory_mapping(unsigned long start, unsigned long end)
374 pud = alloc_low_page(&pud_phys); 408 pud = alloc_low_page(&pud_phys);
375 409
376 next = start + PGDIR_SIZE; 410 next = start + PGDIR_SIZE;
377 if (next > end) 411 if (next > end)
378 next = end; 412 next = end;
379 phys_pud_init(pud, __pa(start), __pa(next)); 413 phys_pud_init(pud, __pa(start), __pa(next));
380 if (!after_bootmem) 414 if (!after_bootmem)
381 set_pgd(pgd_offset_k(start), mk_kernel_pgd(pud_phys)); 415 set_pgd(pgd_offset_k(start), mk_kernel_pgd(pud_phys));
382 unmap_low_page(pud); 416 unmap_low_page(pud);
383 } 417 }
384 418
385 if (!after_bootmem) 419 if (!after_bootmem)
386 mmu_cr4_features = read_cr4(); 420 mmu_cr4_features = read_cr4();
387 __flush_tlb_all(); 421 __flush_tlb_all();
422
423 reserve_early(table_start << PAGE_SHIFT, table_end << PAGE_SHIFT);
388} 424}
389 425
390#ifndef CONFIG_NUMA 426#ifndef CONFIG_NUMA
391void __init paging_init(void) 427void __init paging_init(void)
392{ 428{
393 unsigned long max_zone_pfns[MAX_NR_ZONES]; 429 unsigned long max_zone_pfns[MAX_NR_ZONES];
430
394 memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); 431 memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
395 max_zone_pfns[ZONE_DMA] = MAX_DMA_PFN; 432 max_zone_pfns[ZONE_DMA] = MAX_DMA_PFN;
396 max_zone_pfns[ZONE_DMA32] = MAX_DMA32_PFN; 433 max_zone_pfns[ZONE_DMA32] = MAX_DMA32_PFN;
@@ -402,39 +439,48 @@ void __init paging_init(void)
402} 439}
403#endif 440#endif
404 441
405/* Unmap a kernel mapping if it exists. This is useful to avoid prefetches 442/*
406 from the CPU leading to inconsistent cache lines. address and size 443 * Unmap a kernel mapping if it exists. This is useful to avoid
407 must be aligned to 2MB boundaries. 444 * prefetches from the CPU leading to inconsistent cache lines.
408 Does nothing when the mapping doesn't exist. */ 445 * address and size must be aligned to 2MB boundaries.
409void __init clear_kernel_mapping(unsigned long address, unsigned long size) 446 * Does nothing when the mapping doesn't exist.
447 */
448void __init clear_kernel_mapping(unsigned long address, unsigned long size)
410{ 449{
411 unsigned long end = address + size; 450 unsigned long end = address + size;
412 451
413 BUG_ON(address & ~LARGE_PAGE_MASK); 452 BUG_ON(address & ~LARGE_PAGE_MASK);
414 BUG_ON(size & ~LARGE_PAGE_MASK); 453 BUG_ON(size & ~LARGE_PAGE_MASK);
415 454
416 for (; address < end; address += LARGE_PAGE_SIZE) { 455 for (; address < end; address += LARGE_PAGE_SIZE) {
417 pgd_t *pgd = pgd_offset_k(address); 456 pgd_t *pgd = pgd_offset_k(address);
418 pud_t *pud; 457 pud_t *pud;
419 pmd_t *pmd; 458 pmd_t *pmd;
459
420 if (pgd_none(*pgd)) 460 if (pgd_none(*pgd))
421 continue; 461 continue;
462
422 pud = pud_offset(pgd, address); 463 pud = pud_offset(pgd, address);
423 if (pud_none(*pud)) 464 if (pud_none(*pud))
424 continue; 465 continue;
466
425 pmd = pmd_offset(pud, address); 467 pmd = pmd_offset(pud, address);
426 if (!pmd || pmd_none(*pmd)) 468 if (!pmd || pmd_none(*pmd))
427 continue; 469 continue;
428 if (0 == (pmd_val(*pmd) & _PAGE_PSE)) { 470
429 /* Could handle this, but it should not happen currently. */ 471 if (!(pmd_val(*pmd) & _PAGE_PSE)) {
430 printk(KERN_ERR 472 /*
431 "clear_kernel_mapping: mapping has been split. will leak memory\n"); 473 * Could handle this, but it should not happen
432 pmd_ERROR(*pmd); 474 * currently:
475 */
476 printk(KERN_ERR "clear_kernel_mapping: "
477 "mapping has been split. will leak memory\n");
478 pmd_ERROR(*pmd);
433 } 479 }
434 set_pmd(pmd, __pmd(0)); 480 set_pmd(pmd, __pmd(0));
435 } 481 }
436 __flush_tlb_all(); 482 __flush_tlb_all();
437} 483}
438 484
439/* 485/*
440 * Memory hotplug specific functions 486 * Memory hotplug specific functions
@@ -461,16 +507,12 @@ int arch_add_memory(int nid, u64 start, u64 size)
461 unsigned long nr_pages = size >> PAGE_SHIFT; 507 unsigned long nr_pages = size >> PAGE_SHIFT;
462 int ret; 508 int ret;
463 509
464 init_memory_mapping(start, (start + size -1)); 510 init_memory_mapping(start, start + size-1);
465 511
466 ret = __add_pages(zone, start_pfn, nr_pages); 512 ret = __add_pages(zone, start_pfn, nr_pages);
467 if (ret) 513 WARN_ON(1);
468 goto error;
469 514
470 return ret; 515 return ret;
471error:
472 printk("%s: Problem encountered in __add_pages!\n", __func__);
473 return ret;
474} 516}
475EXPORT_SYMBOL_GPL(arch_add_memory); 517EXPORT_SYMBOL_GPL(arch_add_memory);
476 518
@@ -484,36 +526,8 @@ EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid);
484 526
485#endif /* CONFIG_MEMORY_HOTPLUG */ 527#endif /* CONFIG_MEMORY_HOTPLUG */
486 528
487#ifdef CONFIG_MEMORY_HOTPLUG_RESERVE 529static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel,
488/* 530 kcore_modules, kcore_vsyscall;
489 * Memory Hotadd without sparsemem. The mem_maps have been allocated in advance,
490 * just online the pages.
491 */
492int __add_pages(struct zone *z, unsigned long start_pfn, unsigned long nr_pages)
493{
494 int err = -EIO;
495 unsigned long pfn;
496 unsigned long total = 0, mem = 0;
497 for (pfn = start_pfn; pfn < start_pfn + nr_pages; pfn++) {
498 if (pfn_valid(pfn)) {
499 online_page(pfn_to_page(pfn));
500 err = 0;
501 mem++;
502 }
503 total++;
504 }
505 if (!err) {
506 z->spanned_pages += total;
507 z->present_pages += mem;
508 z->zone_pgdat->node_spanned_pages += total;
509 z->zone_pgdat->node_present_pages += mem;
510 }
511 return err;
512}
513#endif
514
515static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules,
516 kcore_vsyscall;
517 531
518void __init mem_init(void) 532void __init mem_init(void)
519{ 533{
@@ -521,8 +535,15 @@ void __init mem_init(void)
521 535
522 pci_iommu_alloc(); 536 pci_iommu_alloc();
523 537
524 /* clear the zero-page */ 538 /* clear_bss() already clear the empty_zero_page */
525 memset(empty_zero_page, 0, PAGE_SIZE); 539
540 /* temporary debugging - double check it's true: */
541 {
542 int i;
543
544 for (i = 0; i < 1024; i++)
545 WARN_ON_ONCE(empty_zero_page[i]);
546 }
526 547
527 reservedpages = 0; 548 reservedpages = 0;
528 549
@@ -534,7 +555,6 @@ void __init mem_init(void)
534#endif 555#endif
535 reservedpages = end_pfn - totalram_pages - 556 reservedpages = end_pfn - totalram_pages -
536 absent_pages_in_range(0, end_pfn); 557 absent_pages_in_range(0, end_pfn);
537
538 after_bootmem = 1; 558 after_bootmem = 1;
539 559
540 codesize = (unsigned long) &_etext - (unsigned long) &_text; 560 codesize = (unsigned long) &_etext - (unsigned long) &_text;
@@ -542,15 +562,16 @@ void __init mem_init(void)
542 initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; 562 initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
543 563
544 /* Register memory areas for /proc/kcore */ 564 /* Register memory areas for /proc/kcore */
545 kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT); 565 kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
546 kclist_add(&kcore_vmalloc, (void *)VMALLOC_START, 566 kclist_add(&kcore_vmalloc, (void *)VMALLOC_START,
547 VMALLOC_END-VMALLOC_START); 567 VMALLOC_END-VMALLOC_START);
548 kclist_add(&kcore_kernel, &_stext, _end - _stext); 568 kclist_add(&kcore_kernel, &_stext, _end - _stext);
549 kclist_add(&kcore_modules, (void *)MODULES_VADDR, MODULES_LEN); 569 kclist_add(&kcore_modules, (void *)MODULES_VADDR, MODULES_LEN);
550 kclist_add(&kcore_vsyscall, (void *)VSYSCALL_START, 570 kclist_add(&kcore_vsyscall, (void *)VSYSCALL_START,
551 VSYSCALL_END - VSYSCALL_START); 571 VSYSCALL_END - VSYSCALL_START);
552 572
553 printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, %ldk data, %ldk init)\n", 573 printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, "
574 "%ldk reserved, %ldk data, %ldk init)\n",
554 (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), 575 (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
555 end_pfn << (PAGE_SHIFT-10), 576 end_pfn << (PAGE_SHIFT-10),
556 codesize >> 10, 577 codesize >> 10,
@@ -566,19 +587,27 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
566 if (begin >= end) 587 if (begin >= end)
567 return; 588 return;
568 589
590 /*
591 * If debugging page accesses then do not free this memory but
592 * mark them not present - any buggy init-section access will
593 * create a kernel page fault:
594 */
595#ifdef CONFIG_DEBUG_PAGEALLOC
596 printk(KERN_INFO "debug: unmapping init memory %08lx..%08lx\n",
597 begin, PAGE_ALIGN(end));
598 set_memory_np(begin, (end - begin) >> PAGE_SHIFT);
599#else
569 printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10); 600 printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10);
601
570 for (addr = begin; addr < end; addr += PAGE_SIZE) { 602 for (addr = begin; addr < end; addr += PAGE_SIZE) {
571 ClearPageReserved(virt_to_page(addr)); 603 ClearPageReserved(virt_to_page(addr));
572 init_page_count(virt_to_page(addr)); 604 init_page_count(virt_to_page(addr));
573 memset((void *)(addr & ~(PAGE_SIZE-1)), 605 memset((void *)(addr & ~(PAGE_SIZE-1)),
574 POISON_FREE_INITMEM, PAGE_SIZE); 606 POISON_FREE_INITMEM, PAGE_SIZE);
575 if (addr >= __START_KERNEL_map)
576 change_page_attr_addr(addr, 1, __pgprot(0));
577 free_page(addr); 607 free_page(addr);
578 totalram_pages++; 608 totalram_pages++;
579 } 609 }
580 if (addr > __START_KERNEL_map) 610#endif
581 global_flush_tlb();
582} 611}
583 612
584void free_initmem(void) 613void free_initmem(void)
@@ -589,6 +618,8 @@ void free_initmem(void)
589} 618}
590 619
591#ifdef CONFIG_DEBUG_RODATA 620#ifdef CONFIG_DEBUG_RODATA
621const int rodata_test_data = 0xC3;
622EXPORT_SYMBOL_GPL(rodata_test_data);
592 623
593void mark_rodata_ro(void) 624void mark_rodata_ro(void)
594{ 625{
@@ -603,25 +634,27 @@ void mark_rodata_ro(void)
603#ifdef CONFIG_KPROBES 634#ifdef CONFIG_KPROBES
604 start = (unsigned long)__start_rodata; 635 start = (unsigned long)__start_rodata;
605#endif 636#endif
606 637
607 end = (unsigned long)__end_rodata; 638 end = (unsigned long)__end_rodata;
608 start = (start + PAGE_SIZE - 1) & PAGE_MASK; 639 start = (start + PAGE_SIZE - 1) & PAGE_MASK;
609 end &= PAGE_MASK; 640 end &= PAGE_MASK;
610 if (end <= start) 641 if (end <= start)
611 return; 642 return;
612 643
613 change_page_attr_addr(start, (end - start) >> PAGE_SHIFT, PAGE_KERNEL_RO); 644 set_memory_ro(start, (end - start) >> PAGE_SHIFT);
614 645
615 printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n", 646 printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n",
616 (end - start) >> 10); 647 (end - start) >> 10);
617 648
618 /* 649 rodata_test();
619 * change_page_attr_addr() requires a global_flush_tlb() call after it. 650
620 * We do this after the printk so that if something went wrong in the 651#ifdef CONFIG_CPA_DEBUG
621 * change, the printk gets out at least to give a better debug hint 652 printk(KERN_INFO "Testing CPA: undo %lx-%lx\n", start, end);
622 * of who is the culprit. 653 set_memory_rw(start, (end-start) >> PAGE_SHIFT);
623 */ 654
624 global_flush_tlb(); 655 printk(KERN_INFO "Testing CPA: again\n");
656 set_memory_ro(start, (end-start) >> PAGE_SHIFT);
657#endif
625} 658}
626#endif 659#endif
627 660
@@ -632,17 +665,21 @@ void free_initrd_mem(unsigned long start, unsigned long end)
632} 665}
633#endif 666#endif
634 667
635void __init reserve_bootmem_generic(unsigned long phys, unsigned len) 668void __init reserve_bootmem_generic(unsigned long phys, unsigned len)
636{ 669{
637#ifdef CONFIG_NUMA 670#ifdef CONFIG_NUMA
638 int nid = phys_to_nid(phys); 671 int nid = phys_to_nid(phys);
639#endif 672#endif
640 unsigned long pfn = phys >> PAGE_SHIFT; 673 unsigned long pfn = phys >> PAGE_SHIFT;
674
641 if (pfn >= end_pfn) { 675 if (pfn >= end_pfn) {
642 /* This can happen with kdump kernels when accessing firmware 676 /*
643 tables. */ 677 * This can happen with kdump kernels when accessing
678 * firmware tables:
679 */
644 if (pfn < end_pfn_map) 680 if (pfn < end_pfn_map)
645 return; 681 return;
682
646 printk(KERN_ERR "reserve_bootmem: illegal reserve %lx %u\n", 683 printk(KERN_ERR "reserve_bootmem: illegal reserve %lx %u\n",
647 phys, len); 684 phys, len);
648 return; 685 return;
@@ -650,9 +687,9 @@ void __init reserve_bootmem_generic(unsigned long phys, unsigned len)
650 687
651 /* Should check here against the e820 map to avoid double free */ 688 /* Should check here against the e820 map to avoid double free */
652#ifdef CONFIG_NUMA 689#ifdef CONFIG_NUMA
653 reserve_bootmem_node(NODE_DATA(nid), phys, len); 690 reserve_bootmem_node(NODE_DATA(nid), phys, len);
654#else 691#else
655 reserve_bootmem(phys, len); 692 reserve_bootmem(phys, len);
656#endif 693#endif
657 if (phys+len <= MAX_DMA_PFN*PAGE_SIZE) { 694 if (phys+len <= MAX_DMA_PFN*PAGE_SIZE) {
658 dma_reserve += len / PAGE_SIZE; 695 dma_reserve += len / PAGE_SIZE;
@@ -660,46 +697,49 @@ void __init reserve_bootmem_generic(unsigned long phys, unsigned len)
660 } 697 }
661} 698}
662 699
663int kern_addr_valid(unsigned long addr) 700int kern_addr_valid(unsigned long addr)
664{ 701{
665 unsigned long above = ((long)addr) >> __VIRTUAL_MASK_SHIFT; 702 unsigned long above = ((long)addr) >> __VIRTUAL_MASK_SHIFT;
666 pgd_t *pgd; 703 pgd_t *pgd;
667 pud_t *pud; 704 pud_t *pud;
668 pmd_t *pmd; 705 pmd_t *pmd;
669 pte_t *pte; 706 pte_t *pte;
670 707
671 if (above != 0 && above != -1UL) 708 if (above != 0 && above != -1UL)
672 return 0; 709 return 0;
673 710
674 pgd = pgd_offset_k(addr); 711 pgd = pgd_offset_k(addr);
675 if (pgd_none(*pgd)) 712 if (pgd_none(*pgd))
676 return 0; 713 return 0;
677 714
678 pud = pud_offset(pgd, addr); 715 pud = pud_offset(pgd, addr);
679 if (pud_none(*pud)) 716 if (pud_none(*pud))
680 return 0; 717 return 0;
681 718
682 pmd = pmd_offset(pud, addr); 719 pmd = pmd_offset(pud, addr);
683 if (pmd_none(*pmd)) 720 if (pmd_none(*pmd))
684 return 0; 721 return 0;
722
685 if (pmd_large(*pmd)) 723 if (pmd_large(*pmd))
686 return pfn_valid(pmd_pfn(*pmd)); 724 return pfn_valid(pmd_pfn(*pmd));
687 725
688 pte = pte_offset_kernel(pmd, addr); 726 pte = pte_offset_kernel(pmd, addr);
689 if (pte_none(*pte)) 727 if (pte_none(*pte))
690 return 0; 728 return 0;
729
691 return pfn_valid(pte_pfn(*pte)); 730 return pfn_valid(pte_pfn(*pte));
692} 731}
693 732
694/* A pseudo VMA to allow ptrace access for the vsyscall page. This only 733/*
695 covers the 64bit vsyscall page now. 32bit has a real VMA now and does 734 * A pseudo VMA to allow ptrace access for the vsyscall page. This only
696 not need special handling anymore. */ 735 * covers the 64bit vsyscall page now. 32bit has a real VMA now and does
697 736 * not need special handling anymore:
737 */
698static struct vm_area_struct gate_vma = { 738static struct vm_area_struct gate_vma = {
699 .vm_start = VSYSCALL_START, 739 .vm_start = VSYSCALL_START,
700 .vm_end = VSYSCALL_START + (VSYSCALL_MAPPED_PAGES << PAGE_SHIFT), 740 .vm_end = VSYSCALL_START + (VSYSCALL_MAPPED_PAGES * PAGE_SIZE),
701 .vm_page_prot = PAGE_READONLY_EXEC, 741 .vm_page_prot = PAGE_READONLY_EXEC,
702 .vm_flags = VM_READ | VM_EXEC 742 .vm_flags = VM_READ | VM_EXEC
703}; 743};
704 744
705struct vm_area_struct *get_gate_vma(struct task_struct *tsk) 745struct vm_area_struct *get_gate_vma(struct task_struct *tsk)
@@ -714,14 +754,17 @@ struct vm_area_struct *get_gate_vma(struct task_struct *tsk)
714int in_gate_area(struct task_struct *task, unsigned long addr) 754int in_gate_area(struct task_struct *task, unsigned long addr)
715{ 755{
716 struct vm_area_struct *vma = get_gate_vma(task); 756 struct vm_area_struct *vma = get_gate_vma(task);
757
717 if (!vma) 758 if (!vma)
718 return 0; 759 return 0;
760
719 return (addr >= vma->vm_start) && (addr < vma->vm_end); 761 return (addr >= vma->vm_start) && (addr < vma->vm_end);
720} 762}
721 763
722/* Use this when you have no reliable task/vma, typically from interrupt 764/*
723 * context. It is less reliable than using the task's vma and may give 765 * Use this when you have no reliable task/vma, typically from interrupt
724 * false positives. 766 * context. It is less reliable than using the task's vma and may give
767 * false positives:
725 */ 768 */
726int in_gate_area_no_task(unsigned long addr) 769int in_gate_area_no_task(unsigned long addr)
727{ 770{
@@ -741,8 +784,8 @@ const char *arch_vma_name(struct vm_area_struct *vma)
741/* 784/*
742 * Initialise the sparsemem vmemmap using huge-pages at the PMD level. 785 * Initialise the sparsemem vmemmap using huge-pages at the PMD level.
743 */ 786 */
744int __meminit vmemmap_populate(struct page *start_page, 787int __meminit
745 unsigned long size, int node) 788vmemmap_populate(struct page *start_page, unsigned long size, int node)
746{ 789{
747 unsigned long addr = (unsigned long)start_page; 790 unsigned long addr = (unsigned long)start_page;
748 unsigned long end = (unsigned long)(start_page + size); 791 unsigned long end = (unsigned long)(start_page + size);
@@ -757,6 +800,7 @@ int __meminit vmemmap_populate(struct page *start_page,
757 pgd = vmemmap_pgd_populate(addr, node); 800 pgd = vmemmap_pgd_populate(addr, node);
758 if (!pgd) 801 if (!pgd)
759 return -ENOMEM; 802 return -ENOMEM;
803
760 pud = vmemmap_pud_populate(pgd, addr, node); 804 pud = vmemmap_pud_populate(pgd, addr, node);
761 if (!pud) 805 if (!pud)
762 return -ENOMEM; 806 return -ENOMEM;
@@ -764,20 +808,22 @@ int __meminit vmemmap_populate(struct page *start_page,
764 pmd = pmd_offset(pud, addr); 808 pmd = pmd_offset(pud, addr);
765 if (pmd_none(*pmd)) { 809 if (pmd_none(*pmd)) {
766 pte_t entry; 810 pte_t entry;
767 void *p = vmemmap_alloc_block(PMD_SIZE, node); 811 void *p;
812
813 p = vmemmap_alloc_block(PMD_SIZE, node);
768 if (!p) 814 if (!p)
769 return -ENOMEM; 815 return -ENOMEM;
770 816
771 entry = pfn_pte(__pa(p) >> PAGE_SHIFT, PAGE_KERNEL); 817 entry = pfn_pte(__pa(p) >> PAGE_SHIFT,
772 mk_pte_huge(entry); 818 PAGE_KERNEL_LARGE);
773 set_pmd(pmd, __pmd(pte_val(entry))); 819 set_pmd(pmd, __pmd(pte_val(entry)));
774 820
775 printk(KERN_DEBUG " [%lx-%lx] PMD ->%p on node %d\n", 821 printk(KERN_DEBUG " [%lx-%lx] PMD ->%p on node %d\n",
776 addr, addr + PMD_SIZE - 1, p, node); 822 addr, addr + PMD_SIZE - 1, p, node);
777 } else 823 } else {
778 vmemmap_verify((pte_t *)pmd, node, addr, next); 824 vmemmap_verify((pte_t *)pmd, node, addr, next);
825 }
779 } 826 }
780
781 return 0; 827 return 0;
782} 828}
783#endif 829#endif
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
new file mode 100644
index 000000000000..ed795721ca8e
--- /dev/null
+++ b/arch/x86/mm/ioremap.c
@@ -0,0 +1,501 @@
1/*
2 * Re-map IO memory to kernel address space so that we can access it.
3 * This is needed for high PCI addresses that aren't mapped in the
4 * 640k-1MB IO memory area on PC's
5 *
6 * (C) Copyright 1995 1996 Linus Torvalds
7 */
8
9#include <linux/bootmem.h>
10#include <linux/init.h>
11#include <linux/io.h>
12#include <linux/module.h>
13#include <linux/slab.h>
14#include <linux/vmalloc.h>
15
16#include <asm/cacheflush.h>
17#include <asm/e820.h>
18#include <asm/fixmap.h>
19#include <asm/pgtable.h>
20#include <asm/tlbflush.h>
21#include <asm/pgalloc.h>
22
23enum ioremap_mode {
24 IOR_MODE_UNCACHED,
25 IOR_MODE_CACHED,
26};
27
28#ifdef CONFIG_X86_64
29
30unsigned long __phys_addr(unsigned long x)
31{
32 if (x >= __START_KERNEL_map)
33 return x - __START_KERNEL_map + phys_base;
34 return x - PAGE_OFFSET;
35}
36EXPORT_SYMBOL(__phys_addr);
37
38#endif
39
40int page_is_ram(unsigned long pagenr)
41{
42 unsigned long addr, end;
43 int i;
44
45 for (i = 0; i < e820.nr_map; i++) {
46 /*
47 * Not usable memory:
48 */
49 if (e820.map[i].type != E820_RAM)
50 continue;
51 addr = (e820.map[i].addr + PAGE_SIZE-1) >> PAGE_SHIFT;
52 end = (e820.map[i].addr + e820.map[i].size) >> PAGE_SHIFT;
53
54 /*
55 * Sanity check: Some BIOSen report areas as RAM that
56 * are not. Notably the 640->1Mb area, which is the
57 * PCI BIOS area.
58 */
59 if (addr >= (BIOS_BEGIN >> PAGE_SHIFT) &&
60 end < (BIOS_END >> PAGE_SHIFT))
61 continue;
62
63 if ((pagenr >= addr) && (pagenr < end))
64 return 1;
65 }
66 return 0;
67}
68
69/*
70 * Fix up the linear direct mapping of the kernel to avoid cache attribute
71 * conflicts.
72 */
73static int ioremap_change_attr(unsigned long paddr, unsigned long size,
74 enum ioremap_mode mode)
75{
76 unsigned long vaddr = (unsigned long)__va(paddr);
77 unsigned long nrpages = size >> PAGE_SHIFT;
78 int err, level;
79
80 /* No change for pages after the last mapping */
81 if ((paddr + size - 1) >= (max_pfn_mapped << PAGE_SHIFT))
82 return 0;
83
84 /*
85 * If there is no identity map for this address,
86 * change_page_attr_addr is unnecessary
87 */
88 if (!lookup_address(vaddr, &level))
89 return 0;
90
91 switch (mode) {
92 case IOR_MODE_UNCACHED:
93 default:
94 err = set_memory_uc(vaddr, nrpages);
95 break;
96 case IOR_MODE_CACHED:
97 err = set_memory_wb(vaddr, nrpages);
98 break;
99 }
100
101 return err;
102}
103
104/*
105 * Remap an arbitrary physical address space into the kernel virtual
106 * address space. Needed when the kernel wants to access high addresses
107 * directly.
108 *
109 * NOTE! We need to allow non-page-aligned mappings too: we will obviously
110 * have to convert them into an offset in a page-aligned mapping, but the
111 * caller shouldn't need to know that small detail.
112 */
113static void __iomem *__ioremap(unsigned long phys_addr, unsigned long size,
114 enum ioremap_mode mode)
115{
116 void __iomem *addr;
117 struct vm_struct *area;
118 unsigned long offset, last_addr;
119 pgprot_t prot;
120
121 /* Don't allow wraparound or zero size */
122 last_addr = phys_addr + size - 1;
123 if (!size || last_addr < phys_addr)
124 return NULL;
125
126 /*
127 * Don't remap the low PCI/ISA area, it's always mapped..
128 */
129 if (phys_addr >= ISA_START_ADDRESS && last_addr < ISA_END_ADDRESS)
130 return (__force void __iomem *)phys_to_virt(phys_addr);
131
132 /*
133 * Don't allow anybody to remap normal RAM that we're using..
134 */
135 for (offset = phys_addr >> PAGE_SHIFT; offset < max_pfn_mapped &&
136 (offset << PAGE_SHIFT) < last_addr; offset++) {
137 if (page_is_ram(offset))
138 return NULL;
139 }
140
141 switch (mode) {
142 case IOR_MODE_UNCACHED:
143 default:
144 prot = PAGE_KERNEL_NOCACHE;
145 break;
146 case IOR_MODE_CACHED:
147 prot = PAGE_KERNEL;
148 break;
149 }
150
151 /*
152 * Mappings have to be page-aligned
153 */
154 offset = phys_addr & ~PAGE_MASK;
155 phys_addr &= PAGE_MASK;
156 size = PAGE_ALIGN(last_addr+1) - phys_addr;
157
158 /*
159 * Ok, go for it..
160 */
161 area = get_vm_area(size, VM_IOREMAP);
162 if (!area)
163 return NULL;
164 area->phys_addr = phys_addr;
165 addr = (void __iomem *) area->addr;
166 if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size,
167 phys_addr, prot)) {
168 remove_vm_area((void *)(PAGE_MASK & (unsigned long) addr));
169 return NULL;
170 }
171
172 if (ioremap_change_attr(phys_addr, size, mode) < 0) {
173 vunmap(addr);
174 return NULL;
175 }
176
177 return (void __iomem *) (offset + (char __iomem *)addr);
178}
179
180/**
181 * ioremap_nocache - map bus memory into CPU space
182 * @offset: bus address of the memory
183 * @size: size of the resource to map
184 *
185 * ioremap_nocache performs a platform specific sequence of operations to
186 * make bus memory CPU accessible via the readb/readw/readl/writeb/
187 * writew/writel functions and the other mmio helpers. The returned
188 * address is not guaranteed to be usable directly as a virtual
189 * address.
190 *
191 * This version of ioremap ensures that the memory is marked uncachable
192 * on the CPU as well as honouring existing caching rules from things like
193 * the PCI bus. Note that there are other caches and buffers on many
194 * busses. In particular driver authors should read up on PCI writes
195 *
196 * It's useful if some control registers are in such an area and
197 * write combining or read caching is not desirable:
198 *
199 * Must be freed with iounmap.
200 */
201void __iomem *ioremap_nocache(unsigned long phys_addr, unsigned long size)
202{
203 return __ioremap(phys_addr, size, IOR_MODE_UNCACHED);
204}
205EXPORT_SYMBOL(ioremap_nocache);
206
207void __iomem *ioremap_cache(unsigned long phys_addr, unsigned long size)
208{
209 return __ioremap(phys_addr, size, IOR_MODE_CACHED);
210}
211EXPORT_SYMBOL(ioremap_cache);
212
213/**
214 * iounmap - Free a IO remapping
215 * @addr: virtual address from ioremap_*
216 *
217 * Caller must ensure there is only one unmapping for the same pointer.
218 */
219void iounmap(volatile void __iomem *addr)
220{
221 struct vm_struct *p, *o;
222
223 if ((void __force *)addr <= high_memory)
224 return;
225
226 /*
227 * __ioremap special-cases the PCI/ISA range by not instantiating a
228 * vm_area and by simply returning an address into the kernel mapping
229 * of ISA space. So handle that here.
230 */
231 if (addr >= phys_to_virt(ISA_START_ADDRESS) &&
232 addr < phys_to_virt(ISA_END_ADDRESS))
233 return;
234
235 addr = (volatile void __iomem *)
236 (PAGE_MASK & (unsigned long __force)addr);
237
238 /* Use the vm area unlocked, assuming the caller
239 ensures there isn't another iounmap for the same address
240 in parallel. Reuse of the virtual address is prevented by
241 leaving it in the global lists until we're done with it.
242 cpa takes care of the direct mappings. */
243 read_lock(&vmlist_lock);
244 for (p = vmlist; p; p = p->next) {
245 if (p->addr == addr)
246 break;
247 }
248 read_unlock(&vmlist_lock);
249
250 if (!p) {
251 printk(KERN_ERR "iounmap: bad address %p\n", addr);
252 dump_stack();
253 return;
254 }
255
256 /* Reset the direct mapping. Can block */
257 ioremap_change_attr(p->phys_addr, p->size, IOR_MODE_CACHED);
258
259 /* Finally remove it */
260 o = remove_vm_area((void *)addr);
261 BUG_ON(p != o || o == NULL);
262 kfree(p);
263}
264EXPORT_SYMBOL(iounmap);
265
266#ifdef CONFIG_X86_32
267
268int __initdata early_ioremap_debug;
269
270static int __init early_ioremap_debug_setup(char *str)
271{
272 early_ioremap_debug = 1;
273
274 return 0;
275}
276early_param("early_ioremap_debug", early_ioremap_debug_setup);
277
278static __initdata int after_paging_init;
279static __initdata unsigned long bm_pte[1024]
280 __attribute__((aligned(PAGE_SIZE)));
281
282static inline unsigned long * __init early_ioremap_pgd(unsigned long addr)
283{
284 return (unsigned long *)swapper_pg_dir + ((addr >> 22) & 1023);
285}
286
287static inline unsigned long * __init early_ioremap_pte(unsigned long addr)
288{
289 return bm_pte + ((addr >> PAGE_SHIFT) & 1023);
290}
291
292void __init early_ioremap_init(void)
293{
294 unsigned long *pgd;
295
296 if (early_ioremap_debug)
297 printk(KERN_INFO "early_ioremap_init()\n");
298
299 pgd = early_ioremap_pgd(fix_to_virt(FIX_BTMAP_BEGIN));
300 *pgd = __pa(bm_pte) | _PAGE_TABLE;
301 memset(bm_pte, 0, sizeof(bm_pte));
302 /*
303 * The boot-ioremap range spans multiple pgds, for which
304 * we are not prepared:
305 */
306 if (pgd != early_ioremap_pgd(fix_to_virt(FIX_BTMAP_END))) {
307 WARN_ON(1);
308 printk(KERN_WARNING "pgd %p != %p\n",
309 pgd, early_ioremap_pgd(fix_to_virt(FIX_BTMAP_END)));
310 printk(KERN_WARNING "fix_to_virt(FIX_BTMAP_BEGIN): %08lx\n",
311 fix_to_virt(FIX_BTMAP_BEGIN));
312 printk(KERN_WARNING "fix_to_virt(FIX_BTMAP_END): %08lx\n",
313 fix_to_virt(FIX_BTMAP_END));
314
315 printk(KERN_WARNING "FIX_BTMAP_END: %d\n", FIX_BTMAP_END);
316 printk(KERN_WARNING "FIX_BTMAP_BEGIN: %d\n",
317 FIX_BTMAP_BEGIN);
318 }
319}
320
321void __init early_ioremap_clear(void)
322{
323 unsigned long *pgd;
324
325 if (early_ioremap_debug)
326 printk(KERN_INFO "early_ioremap_clear()\n");
327
328 pgd = early_ioremap_pgd(fix_to_virt(FIX_BTMAP_BEGIN));
329 *pgd = 0;
330 paravirt_release_pt(__pa(pgd) >> PAGE_SHIFT);
331 __flush_tlb_all();
332}
333
334void __init early_ioremap_reset(void)
335{
336 enum fixed_addresses idx;
337 unsigned long *pte, phys, addr;
338
339 after_paging_init = 1;
340 for (idx = FIX_BTMAP_BEGIN; idx >= FIX_BTMAP_END; idx--) {
341 addr = fix_to_virt(idx);
342 pte = early_ioremap_pte(addr);
343 if (!*pte & _PAGE_PRESENT) {
344 phys = *pte & PAGE_MASK;
345 set_fixmap(idx, phys);
346 }
347 }
348}
349
350static void __init __early_set_fixmap(enum fixed_addresses idx,
351 unsigned long phys, pgprot_t flags)
352{
353 unsigned long *pte, addr = __fix_to_virt(idx);
354
355 if (idx >= __end_of_fixed_addresses) {
356 BUG();
357 return;
358 }
359 pte = early_ioremap_pte(addr);
360 if (pgprot_val(flags))
361 *pte = (phys & PAGE_MASK) | pgprot_val(flags);
362 else
363 *pte = 0;
364 __flush_tlb_one(addr);
365}
366
367static inline void __init early_set_fixmap(enum fixed_addresses idx,
368 unsigned long phys)
369{
370 if (after_paging_init)
371 set_fixmap(idx, phys);
372 else
373 __early_set_fixmap(idx, phys, PAGE_KERNEL);
374}
375
376static inline void __init early_clear_fixmap(enum fixed_addresses idx)
377{
378 if (after_paging_init)
379 clear_fixmap(idx);
380 else
381 __early_set_fixmap(idx, 0, __pgprot(0));
382}
383
384
385int __initdata early_ioremap_nested;
386
387static int __init check_early_ioremap_leak(void)
388{
389 if (!early_ioremap_nested)
390 return 0;
391
392 printk(KERN_WARNING
393 "Debug warning: early ioremap leak of %d areas detected.\n",
394 early_ioremap_nested);
395 printk(KERN_WARNING
396 "please boot with early_ioremap_debug and report the dmesg.\n");
397 WARN_ON(1);
398
399 return 1;
400}
401late_initcall(check_early_ioremap_leak);
402
403void __init *early_ioremap(unsigned long phys_addr, unsigned long size)
404{
405 unsigned long offset, last_addr;
406 unsigned int nrpages, nesting;
407 enum fixed_addresses idx0, idx;
408
409 WARN_ON(system_state != SYSTEM_BOOTING);
410
411 nesting = early_ioremap_nested;
412 if (early_ioremap_debug) {
413 printk(KERN_INFO "early_ioremap(%08lx, %08lx) [%d] => ",
414 phys_addr, size, nesting);
415 dump_stack();
416 }
417
418 /* Don't allow wraparound or zero size */
419 last_addr = phys_addr + size - 1;
420 if (!size || last_addr < phys_addr) {
421 WARN_ON(1);
422 return NULL;
423 }
424
425 if (nesting >= FIX_BTMAPS_NESTING) {
426 WARN_ON(1);
427 return NULL;
428 }
429 early_ioremap_nested++;
430 /*
431 * Mappings have to be page-aligned
432 */
433 offset = phys_addr & ~PAGE_MASK;
434 phys_addr &= PAGE_MASK;
435 size = PAGE_ALIGN(last_addr) - phys_addr;
436
437 /*
438 * Mappings have to fit in the FIX_BTMAP area.
439 */
440 nrpages = size >> PAGE_SHIFT;
441 if (nrpages > NR_FIX_BTMAPS) {
442 WARN_ON(1);
443 return NULL;
444 }
445
446 /*
447 * Ok, go for it..
448 */
449 idx0 = FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*nesting;
450 idx = idx0;
451 while (nrpages > 0) {
452 early_set_fixmap(idx, phys_addr);
453 phys_addr += PAGE_SIZE;
454 --idx;
455 --nrpages;
456 }
457 if (early_ioremap_debug)
458 printk(KERN_CONT "%08lx + %08lx\n", offset, fix_to_virt(idx0));
459
460 return (void *) (offset + fix_to_virt(idx0));
461}
462
463void __init early_iounmap(void *addr, unsigned long size)
464{
465 unsigned long virt_addr;
466 unsigned long offset;
467 unsigned int nrpages;
468 enum fixed_addresses idx;
469 unsigned int nesting;
470
471 nesting = --early_ioremap_nested;
472 WARN_ON(nesting < 0);
473
474 if (early_ioremap_debug) {
475 printk(KERN_INFO "early_iounmap(%p, %08lx) [%d]\n", addr,
476 size, nesting);
477 dump_stack();
478 }
479
480 virt_addr = (unsigned long)addr;
481 if (virt_addr < fix_to_virt(FIX_BTMAP_BEGIN)) {
482 WARN_ON(1);
483 return;
484 }
485 offset = virt_addr & ~PAGE_MASK;
486 nrpages = PAGE_ALIGN(offset + size - 1) >> PAGE_SHIFT;
487
488 idx = FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*nesting;
489 while (nrpages > 0) {
490 early_clear_fixmap(idx);
491 --idx;
492 --nrpages;
493 }
494}
495
496void __this_fixmap_does_not_exist(void)
497{
498 WARN_ON(1);
499}
500
501#endif /* CONFIG_X86_32 */
diff --git a/arch/x86/mm/ioremap_32.c b/arch/x86/mm/ioremap_32.c
deleted file mode 100644
index 0b278315d737..000000000000
--- a/arch/x86/mm/ioremap_32.c
+++ /dev/null
@@ -1,274 +0,0 @@
1/*
2 * arch/i386/mm/ioremap.c
3 *
4 * Re-map IO memory to kernel address space so that we can access it.
5 * This is needed for high PCI addresses that aren't mapped in the
6 * 640k-1MB IO memory area on PC's
7 *
8 * (C) Copyright 1995 1996 Linus Torvalds
9 */
10
11#include <linux/vmalloc.h>
12#include <linux/init.h>
13#include <linux/slab.h>
14#include <linux/module.h>
15#include <linux/io.h>
16#include <asm/fixmap.h>
17#include <asm/cacheflush.h>
18#include <asm/tlbflush.h>
19#include <asm/pgtable.h>
20
21#define ISA_START_ADDRESS 0xa0000
22#define ISA_END_ADDRESS 0x100000
23
24/*
25 * Generic mapping function (not visible outside):
26 */
27
28/*
29 * Remap an arbitrary physical address space into the kernel virtual
30 * address space. Needed when the kernel wants to access high addresses
31 * directly.
32 *
33 * NOTE! We need to allow non-page-aligned mappings too: we will obviously
34 * have to convert them into an offset in a page-aligned mapping, but the
35 * caller shouldn't need to know that small detail.
36 */
37void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
38{
39 void __iomem * addr;
40 struct vm_struct * area;
41 unsigned long offset, last_addr;
42 pgprot_t prot;
43
44 /* Don't allow wraparound or zero size */
45 last_addr = phys_addr + size - 1;
46 if (!size || last_addr < phys_addr)
47 return NULL;
48
49 /*
50 * Don't remap the low PCI/ISA area, it's always mapped..
51 */
52 if (phys_addr >= ISA_START_ADDRESS && last_addr < ISA_END_ADDRESS)
53 return (void __iomem *) phys_to_virt(phys_addr);
54
55 /*
56 * Don't allow anybody to remap normal RAM that we're using..
57 */
58 if (phys_addr <= virt_to_phys(high_memory - 1)) {
59 char *t_addr, *t_end;
60 struct page *page;
61
62 t_addr = __va(phys_addr);
63 t_end = t_addr + (size - 1);
64
65 for(page = virt_to_page(t_addr); page <= virt_to_page(t_end); page++)
66 if(!PageReserved(page))
67 return NULL;
68 }
69
70 prot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY
71 | _PAGE_ACCESSED | flags);
72
73 /*
74 * Mappings have to be page-aligned
75 */
76 offset = phys_addr & ~PAGE_MASK;
77 phys_addr &= PAGE_MASK;
78 size = PAGE_ALIGN(last_addr+1) - phys_addr;
79
80 /*
81 * Ok, go for it..
82 */
83 area = get_vm_area(size, VM_IOREMAP | (flags << 20));
84 if (!area)
85 return NULL;
86 area->phys_addr = phys_addr;
87 addr = (void __iomem *) area->addr;
88 if (ioremap_page_range((unsigned long) addr,
89 (unsigned long) addr + size, phys_addr, prot)) {
90 vunmap((void __force *) addr);
91 return NULL;
92 }
93 return (void __iomem *) (offset + (char __iomem *)addr);
94}
95EXPORT_SYMBOL(__ioremap);
96
97/**
98 * ioremap_nocache - map bus memory into CPU space
99 * @offset: bus address of the memory
100 * @size: size of the resource to map
101 *
102 * ioremap_nocache performs a platform specific sequence of operations to
103 * make bus memory CPU accessible via the readb/readw/readl/writeb/
104 * writew/writel functions and the other mmio helpers. The returned
105 * address is not guaranteed to be usable directly as a virtual
106 * address.
107 *
108 * This version of ioremap ensures that the memory is marked uncachable
109 * on the CPU as well as honouring existing caching rules from things like
110 * the PCI bus. Note that there are other caches and buffers on many
111 * busses. In particular driver authors should read up on PCI writes
112 *
113 * It's useful if some control registers are in such an area and
114 * write combining or read caching is not desirable:
115 *
116 * Must be freed with iounmap.
117 */
118
119void __iomem *ioremap_nocache (unsigned long phys_addr, unsigned long size)
120{
121 unsigned long last_addr;
122 void __iomem *p = __ioremap(phys_addr, size, _PAGE_PCD);
123 if (!p)
124 return p;
125
126 /* Guaranteed to be > phys_addr, as per __ioremap() */
127 last_addr = phys_addr + size - 1;
128
129 if (last_addr < virt_to_phys(high_memory) - 1) {
130 struct page *ppage = virt_to_page(__va(phys_addr));
131 unsigned long npages;
132
133 phys_addr &= PAGE_MASK;
134
135 /* This might overflow and become zero.. */
136 last_addr = PAGE_ALIGN(last_addr);
137
138 /* .. but that's ok, because modulo-2**n arithmetic will make
139 * the page-aligned "last - first" come out right.
140 */
141 npages = (last_addr - phys_addr) >> PAGE_SHIFT;
142
143 if (change_page_attr(ppage, npages, PAGE_KERNEL_NOCACHE) < 0) {
144 iounmap(p);
145 p = NULL;
146 }
147 global_flush_tlb();
148 }
149
150 return p;
151}
152EXPORT_SYMBOL(ioremap_nocache);
153
154/**
155 * iounmap - Free a IO remapping
156 * @addr: virtual address from ioremap_*
157 *
158 * Caller must ensure there is only one unmapping for the same pointer.
159 */
160void iounmap(volatile void __iomem *addr)
161{
162 struct vm_struct *p, *o;
163
164 if ((void __force *)addr <= high_memory)
165 return;
166
167 /*
168 * __ioremap special-cases the PCI/ISA range by not instantiating a
169 * vm_area and by simply returning an address into the kernel mapping
170 * of ISA space. So handle that here.
171 */
172 if (addr >= phys_to_virt(ISA_START_ADDRESS) &&
173 addr < phys_to_virt(ISA_END_ADDRESS))
174 return;
175
176 addr = (volatile void __iomem *)(PAGE_MASK & (unsigned long __force)addr);
177
178 /* Use the vm area unlocked, assuming the caller
179 ensures there isn't another iounmap for the same address
180 in parallel. Reuse of the virtual address is prevented by
181 leaving it in the global lists until we're done with it.
182 cpa takes care of the direct mappings. */
183 read_lock(&vmlist_lock);
184 for (p = vmlist; p; p = p->next) {
185 if (p->addr == addr)
186 break;
187 }
188 read_unlock(&vmlist_lock);
189
190 if (!p) {
191 printk("iounmap: bad address %p\n", addr);
192 dump_stack();
193 return;
194 }
195
196 /* Reset the direct mapping. Can block */
197 if ((p->flags >> 20) && p->phys_addr < virt_to_phys(high_memory) - 1) {
198 change_page_attr(virt_to_page(__va(p->phys_addr)),
199 get_vm_area_size(p) >> PAGE_SHIFT,
200 PAGE_KERNEL);
201 global_flush_tlb();
202 }
203
204 /* Finally remove it */
205 o = remove_vm_area((void *)addr);
206 BUG_ON(p != o || o == NULL);
207 kfree(p);
208}
209EXPORT_SYMBOL(iounmap);
210
211void __init *bt_ioremap(unsigned long phys_addr, unsigned long size)
212{
213 unsigned long offset, last_addr;
214 unsigned int nrpages;
215 enum fixed_addresses idx;
216
217 /* Don't allow wraparound or zero size */
218 last_addr = phys_addr + size - 1;
219 if (!size || last_addr < phys_addr)
220 return NULL;
221
222 /*
223 * Don't remap the low PCI/ISA area, it's always mapped..
224 */
225 if (phys_addr >= ISA_START_ADDRESS && last_addr < ISA_END_ADDRESS)
226 return phys_to_virt(phys_addr);
227
228 /*
229 * Mappings have to be page-aligned
230 */
231 offset = phys_addr & ~PAGE_MASK;
232 phys_addr &= PAGE_MASK;
233 size = PAGE_ALIGN(last_addr) - phys_addr;
234
235 /*
236 * Mappings have to fit in the FIX_BTMAP area.
237 */
238 nrpages = size >> PAGE_SHIFT;
239 if (nrpages > NR_FIX_BTMAPS)
240 return NULL;
241
242 /*
243 * Ok, go for it..
244 */
245 idx = FIX_BTMAP_BEGIN;
246 while (nrpages > 0) {
247 set_fixmap(idx, phys_addr);
248 phys_addr += PAGE_SIZE;
249 --idx;
250 --nrpages;
251 }
252 return (void*) (offset + fix_to_virt(FIX_BTMAP_BEGIN));
253}
254
255void __init bt_iounmap(void *addr, unsigned long size)
256{
257 unsigned long virt_addr;
258 unsigned long offset;
259 unsigned int nrpages;
260 enum fixed_addresses idx;
261
262 virt_addr = (unsigned long)addr;
263 if (virt_addr < fix_to_virt(FIX_BTMAP_BEGIN))
264 return;
265 offset = virt_addr & ~PAGE_MASK;
266 nrpages = PAGE_ALIGN(offset + size - 1) >> PAGE_SHIFT;
267
268 idx = FIX_BTMAP_BEGIN;
269 while (nrpages > 0) {
270 clear_fixmap(idx);
271 --idx;
272 --nrpages;
273 }
274}
diff --git a/arch/x86/mm/ioremap_64.c b/arch/x86/mm/ioremap_64.c
deleted file mode 100644
index 6cac90aa5032..000000000000
--- a/arch/x86/mm/ioremap_64.c
+++ /dev/null
@@ -1,210 +0,0 @@
1/*
2 * arch/x86_64/mm/ioremap.c
3 *
4 * Re-map IO memory to kernel address space so that we can access it.
5 * This is needed for high PCI addresses that aren't mapped in the
6 * 640k-1MB IO memory area on PC's
7 *
8 * (C) Copyright 1995 1996 Linus Torvalds
9 */
10
11#include <linux/vmalloc.h>
12#include <linux/init.h>
13#include <linux/slab.h>
14#include <linux/module.h>
15#include <linux/io.h>
16
17#include <asm/pgalloc.h>
18#include <asm/fixmap.h>
19#include <asm/tlbflush.h>
20#include <asm/cacheflush.h>
21#include <asm/proto.h>
22
23unsigned long __phys_addr(unsigned long x)
24{
25 if (x >= __START_KERNEL_map)
26 return x - __START_KERNEL_map + phys_base;
27 return x - PAGE_OFFSET;
28}
29EXPORT_SYMBOL(__phys_addr);
30
31#define ISA_START_ADDRESS 0xa0000
32#define ISA_END_ADDRESS 0x100000
33
34/*
35 * Fix up the linear direct mapping of the kernel to avoid cache attribute
36 * conflicts.
37 */
38static int
39ioremap_change_attr(unsigned long phys_addr, unsigned long size,
40 unsigned long flags)
41{
42 int err = 0;
43 if (phys_addr + size - 1 < (end_pfn_map << PAGE_SHIFT)) {
44 unsigned long npages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
45 unsigned long vaddr = (unsigned long) __va(phys_addr);
46
47 /*
48 * Must use a address here and not struct page because the phys addr
49 * can be a in hole between nodes and not have an memmap entry.
50 */
51 err = change_page_attr_addr(vaddr,npages,__pgprot(__PAGE_KERNEL|flags));
52 if (!err)
53 global_flush_tlb();
54 }
55 return err;
56}
57
58/*
59 * Generic mapping function
60 */
61
62/*
63 * Remap an arbitrary physical address space into the kernel virtual
64 * address space. Needed when the kernel wants to access high addresses
65 * directly.
66 *
67 * NOTE! We need to allow non-page-aligned mappings too: we will obviously
68 * have to convert them into an offset in a page-aligned mapping, but the
69 * caller shouldn't need to know that small detail.
70 */
71void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
72{
73 void * addr;
74 struct vm_struct * area;
75 unsigned long offset, last_addr;
76 pgprot_t pgprot;
77
78 /* Don't allow wraparound or zero size */
79 last_addr = phys_addr + size - 1;
80 if (!size || last_addr < phys_addr)
81 return NULL;
82
83 /*
84 * Don't remap the low PCI/ISA area, it's always mapped..
85 */
86 if (phys_addr >= ISA_START_ADDRESS && last_addr < ISA_END_ADDRESS)
87 return (__force void __iomem *)phys_to_virt(phys_addr);
88
89#ifdef CONFIG_FLATMEM
90 /*
91 * Don't allow anybody to remap normal RAM that we're using..
92 */
93 if (last_addr < virt_to_phys(high_memory)) {
94 char *t_addr, *t_end;
95 struct page *page;
96
97 t_addr = __va(phys_addr);
98 t_end = t_addr + (size - 1);
99
100 for(page = virt_to_page(t_addr); page <= virt_to_page(t_end); page++)
101 if(!PageReserved(page))
102 return NULL;
103 }
104#endif
105
106 pgprot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_GLOBAL
107 | _PAGE_DIRTY | _PAGE_ACCESSED | flags);
108 /*
109 * Mappings have to be page-aligned
110 */
111 offset = phys_addr & ~PAGE_MASK;
112 phys_addr &= PAGE_MASK;
113 size = PAGE_ALIGN(last_addr+1) - phys_addr;
114
115 /*
116 * Ok, go for it..
117 */
118 area = get_vm_area(size, VM_IOREMAP | (flags << 20));
119 if (!area)
120 return NULL;
121 area->phys_addr = phys_addr;
122 addr = area->addr;
123 if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size,
124 phys_addr, pgprot)) {
125 remove_vm_area((void *)(PAGE_MASK & (unsigned long) addr));
126 return NULL;
127 }
128 if (flags && ioremap_change_attr(phys_addr, size, flags) < 0) {
129 area->flags &= 0xffffff;
130 vunmap(addr);
131 return NULL;
132 }
133 return (__force void __iomem *) (offset + (char *)addr);
134}
135EXPORT_SYMBOL(__ioremap);
136
137/**
138 * ioremap_nocache - map bus memory into CPU space
139 * @offset: bus address of the memory
140 * @size: size of the resource to map
141 *
142 * ioremap_nocache performs a platform specific sequence of operations to
143 * make bus memory CPU accessible via the readb/readw/readl/writeb/
144 * writew/writel functions and the other mmio helpers. The returned
145 * address is not guaranteed to be usable directly as a virtual
146 * address.
147 *
148 * This version of ioremap ensures that the memory is marked uncachable
149 * on the CPU as well as honouring existing caching rules from things like
150 * the PCI bus. Note that there are other caches and buffers on many
151 * busses. In particular driver authors should read up on PCI writes
152 *
153 * It's useful if some control registers are in such an area and
154 * write combining or read caching is not desirable:
155 *
156 * Must be freed with iounmap.
157 */
158
159void __iomem *ioremap_nocache (unsigned long phys_addr, unsigned long size)
160{
161 return __ioremap(phys_addr, size, _PAGE_PCD);
162}
163EXPORT_SYMBOL(ioremap_nocache);
164
165/**
166 * iounmap - Free a IO remapping
167 * @addr: virtual address from ioremap_*
168 *
169 * Caller must ensure there is only one unmapping for the same pointer.
170 */
171void iounmap(volatile void __iomem *addr)
172{
173 struct vm_struct *p, *o;
174
175 if (addr <= high_memory)
176 return;
177 if (addr >= phys_to_virt(ISA_START_ADDRESS) &&
178 addr < phys_to_virt(ISA_END_ADDRESS))
179 return;
180
181 addr = (volatile void __iomem *)(PAGE_MASK & (unsigned long __force)addr);
182 /* Use the vm area unlocked, assuming the caller
183 ensures there isn't another iounmap for the same address
184 in parallel. Reuse of the virtual address is prevented by
185 leaving it in the global lists until we're done with it.
186 cpa takes care of the direct mappings. */
187 read_lock(&vmlist_lock);
188 for (p = vmlist; p; p = p->next) {
189 if (p->addr == addr)
190 break;
191 }
192 read_unlock(&vmlist_lock);
193
194 if (!p) {
195 printk("iounmap: bad address %p\n", addr);
196 dump_stack();
197 return;
198 }
199
200 /* Reset the direct mapping. Can block */
201 if (p->flags >> 20)
202 ioremap_change_attr(p->phys_addr, p->size, 0);
203
204 /* Finally remove it */
205 o = remove_vm_area((void *)addr);
206 BUG_ON(p != o || o == NULL);
207 kfree(p);
208}
209EXPORT_SYMBOL(iounmap);
210
diff --git a/arch/x86/mm/k8topology_64.c b/arch/x86/mm/k8topology_64.c
index a96006f7ae0c..7a2ebce87df5 100644
--- a/arch/x86/mm/k8topology_64.c
+++ b/arch/x86/mm/k8topology_64.c
@@ -1,9 +1,9 @@
1/* 1/*
2 * AMD K8 NUMA support. 2 * AMD K8 NUMA support.
3 * Discover the memory map and associated nodes. 3 * Discover the memory map and associated nodes.
4 * 4 *
5 * This version reads it directly from the K8 northbridge. 5 * This version reads it directly from the K8 northbridge.
6 * 6 *
7 * Copyright 2002,2003 Andi Kleen, SuSE Labs. 7 * Copyright 2002,2003 Andi Kleen, SuSE Labs.
8 */ 8 */
9#include <linux/kernel.h> 9#include <linux/kernel.h>
@@ -22,132 +22,135 @@
22 22
23static __init int find_northbridge(void) 23static __init int find_northbridge(void)
24{ 24{
25 int num; 25 int num;
26 26
27 for (num = 0; num < 32; num++) { 27 for (num = 0; num < 32; num++) {
28 u32 header; 28 u32 header;
29 29
30 header = read_pci_config(0, num, 0, 0x00); 30 header = read_pci_config(0, num, 0, 0x00);
31 if (header != (PCI_VENDOR_ID_AMD | (0x1100<<16))) 31 if (header != (PCI_VENDOR_ID_AMD | (0x1100<<16)) &&
32 continue; 32 header != (PCI_VENDOR_ID_AMD | (0x1200<<16)) &&
33 33 header != (PCI_VENDOR_ID_AMD | (0x1300<<16)))
34 header = read_pci_config(0, num, 1, 0x00); 34 continue;
35 if (header != (PCI_VENDOR_ID_AMD | (0x1101<<16))) 35
36 continue; 36 header = read_pci_config(0, num, 1, 0x00);
37 return num; 37 if (header != (PCI_VENDOR_ID_AMD | (0x1101<<16)) &&
38 } 38 header != (PCI_VENDOR_ID_AMD | (0x1201<<16)) &&
39 39 header != (PCI_VENDOR_ID_AMD | (0x1301<<16)))
40 return -1; 40 continue;
41 return num;
42 }
43
44 return -1;
41} 45}
42 46
43int __init k8_scan_nodes(unsigned long start, unsigned long end) 47int __init k8_scan_nodes(unsigned long start, unsigned long end)
44{ 48{
45 unsigned long prevbase; 49 unsigned long prevbase;
46 struct bootnode nodes[8]; 50 struct bootnode nodes[8];
47 int nodeid, i, j, nb; 51 int nodeid, i, nb;
48 unsigned char nodeids[8]; 52 unsigned char nodeids[8];
49 int found = 0; 53 int found = 0;
50 u32 reg; 54 u32 reg;
51 unsigned numnodes; 55 unsigned numnodes;
52 unsigned num_cores; 56 unsigned cores;
57 unsigned bits;
58 int j;
53 59
54 if (!early_pci_allowed()) 60 if (!early_pci_allowed())
55 return -1; 61 return -1;
56 62
57 nb = find_northbridge(); 63 nb = find_northbridge();
58 if (nb < 0) 64 if (nb < 0)
59 return nb; 65 return nb;
60 66
61 printk(KERN_INFO "Scanning NUMA topology in Northbridge %d\n", nb); 67 printk(KERN_INFO "Scanning NUMA topology in Northbridge %d\n", nb);
62
63 num_cores = (cpuid_ecx(0x80000008) & 0xff) + 1;
64 printk(KERN_INFO "CPU has %d num_cores\n", num_cores);
65 68
66 reg = read_pci_config(0, nb, 0, 0x60); 69 reg = read_pci_config(0, nb, 0, 0x60);
67 numnodes = ((reg >> 4) & 0xF) + 1; 70 numnodes = ((reg >> 4) & 0xF) + 1;
68 if (numnodes <= 1) 71 if (numnodes <= 1)
69 return -1; 72 return -1;
70 73
71 printk(KERN_INFO "Number of nodes %d\n", numnodes); 74 printk(KERN_INFO "Number of nodes %d\n", numnodes);
72 75
73 memset(&nodes,0,sizeof(nodes)); 76 memset(&nodes, 0, sizeof(nodes));
74 prevbase = 0; 77 prevbase = 0;
75 for (i = 0; i < 8; i++) { 78 for (i = 0; i < 8; i++) {
76 unsigned long base,limit; 79 unsigned long base, limit;
77 u32 nodeid; 80 u32 nodeid;
78 81
79 base = read_pci_config(0, nb, 1, 0x40 + i*8); 82 base = read_pci_config(0, nb, 1, 0x40 + i*8);
80 limit = read_pci_config(0, nb, 1, 0x44 + i*8); 83 limit = read_pci_config(0, nb, 1, 0x44 + i*8);
81 84
82 nodeid = limit & 7; 85 nodeid = limit & 7;
83 nodeids[i] = nodeid; 86 nodeids[i] = nodeid;
84 if ((base & 3) == 0) { 87 if ((base & 3) == 0) {
85 if (i < numnodes) 88 if (i < numnodes)
86 printk("Skipping disabled node %d\n", i); 89 printk("Skipping disabled node %d\n", i);
87 continue; 90 continue;
88 } 91 }
89 if (nodeid >= numnodes) { 92 if (nodeid >= numnodes) {
90 printk("Ignoring excess node %d (%lx:%lx)\n", nodeid, 93 printk("Ignoring excess node %d (%lx:%lx)\n", nodeid,
91 base, limit); 94 base, limit);
92 continue; 95 continue;
93 } 96 }
94 97
95 if (!limit) { 98 if (!limit) {
96 printk(KERN_INFO "Skipping node entry %d (base %lx)\n", i, 99 printk(KERN_INFO "Skipping node entry %d (base %lx)\n",
97 base); 100 i, base);
98 continue; 101 continue;
99 } 102 }
100 if ((base >> 8) & 3 || (limit >> 8) & 3) { 103 if ((base >> 8) & 3 || (limit >> 8) & 3) {
101 printk(KERN_ERR "Node %d using interleaving mode %lx/%lx\n", 104 printk(KERN_ERR "Node %d using interleaving mode %lx/%lx\n",
102 nodeid, (base>>8)&3, (limit>>8) & 3); 105 nodeid, (base>>8)&3, (limit>>8) & 3);
103 return -1; 106 return -1;
104 } 107 }
105 if (node_isset(nodeid, node_possible_map)) { 108 if (node_isset(nodeid, node_possible_map)) {
106 printk(KERN_INFO "Node %d already present. Skipping\n", 109 printk(KERN_INFO "Node %d already present. Skipping\n",
107 nodeid); 110 nodeid);
108 continue; 111 continue;
109 } 112 }
110 113
111 limit >>= 16; 114 limit >>= 16;
112 limit <<= 24; 115 limit <<= 24;
113 limit |= (1<<24)-1; 116 limit |= (1<<24)-1;
114 limit++; 117 limit++;
115 118
116 if (limit > end_pfn << PAGE_SHIFT) 119 if (limit > end_pfn << PAGE_SHIFT)
117 limit = end_pfn << PAGE_SHIFT; 120 limit = end_pfn << PAGE_SHIFT;
118 if (limit <= base) 121 if (limit <= base)
119 continue; 122 continue;
120 123
121 base >>= 16; 124 base >>= 16;
122 base <<= 24; 125 base <<= 24;
123 126
124 if (base < start) 127 if (base < start)
125 base = start; 128 base = start;
126 if (limit > end) 129 if (limit > end)
127 limit = end; 130 limit = end;
128 if (limit == base) { 131 if (limit == base) {
129 printk(KERN_ERR "Empty node %d\n", nodeid); 132 printk(KERN_ERR "Empty node %d\n", nodeid);
130 continue; 133 continue;
131 } 134 }
132 if (limit < base) { 135 if (limit < base) {
133 printk(KERN_ERR "Node %d bogus settings %lx-%lx.\n", 136 printk(KERN_ERR "Node %d bogus settings %lx-%lx.\n",
134 nodeid, base, limit); 137 nodeid, base, limit);
135 continue; 138 continue;
136 } 139 }
137 140
138 /* Could sort here, but pun for now. Should not happen anyroads. */ 141 /* Could sort here, but pun for now. Should not happen anyroads. */
139 if (prevbase > base) { 142 if (prevbase > base) {
140 printk(KERN_ERR "Node map not sorted %lx,%lx\n", 143 printk(KERN_ERR "Node map not sorted %lx,%lx\n",
141 prevbase,base); 144 prevbase, base);
142 return -1; 145 return -1;
143 } 146 }
144 147
145 printk(KERN_INFO "Node %d MemBase %016lx Limit %016lx\n", 148 printk(KERN_INFO "Node %d MemBase %016lx Limit %016lx\n",
146 nodeid, base, limit); 149 nodeid, base, limit);
147 150
148 found++; 151 found++;
149 152
150 nodes[nodeid].start = base; 153 nodes[nodeid].start = base;
151 nodes[nodeid].end = limit; 154 nodes[nodeid].end = limit;
152 e820_register_active_regions(nodeid, 155 e820_register_active_regions(nodeid,
153 nodes[nodeid].start >> PAGE_SHIFT, 156 nodes[nodeid].start >> PAGE_SHIFT,
@@ -156,27 +159,31 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end)
156 prevbase = base; 159 prevbase = base;
157 160
158 node_set(nodeid, node_possible_map); 161 node_set(nodeid, node_possible_map);
159 } 162 }
160 163
161 if (!found) 164 if (!found)
162 return -1; 165 return -1;
163 166
164 memnode_shift = compute_hash_shift(nodes, 8); 167 memnode_shift = compute_hash_shift(nodes, 8);
165 if (memnode_shift < 0) { 168 if (memnode_shift < 0) {
166 printk(KERN_ERR "No NUMA node hash function found. Contact maintainer\n"); 169 printk(KERN_ERR "No NUMA node hash function found. Contact maintainer\n");
167 return -1; 170 return -1;
168 } 171 }
169 printk(KERN_INFO "Using node hash shift of %d\n", memnode_shift); 172 printk(KERN_INFO "Using node hash shift of %d\n", memnode_shift);
173
174 /* use the coreid bits from early_identify_cpu */
175 bits = boot_cpu_data.x86_coreid_bits;
176 cores = (1<<bits);
170 177
171 for (i = 0; i < 8; i++) { 178 for (i = 0; i < 8; i++) {
172 if (nodes[i].start != nodes[i].end) { 179 if (nodes[i].start != nodes[i].end) {
173 nodeid = nodeids[i]; 180 nodeid = nodeids[i];
174 for (j = 0; j < num_cores; j++) 181 for (j = 0; j < cores; j++)
175 apicid_to_node[(nodeid * num_cores) + j] = i; 182 apicid_to_node[(nodeid << bits) + j] = i;
176 setup_node_bootmem(i, nodes[i].start, nodes[i].end); 183 setup_node_bootmem(i, nodes[i].start, nodes[i].end);
177 } 184 }
178 } 185 }
179 186
180 numa_init_array(); 187 numa_init_array();
181 return 0; 188 return 0;
182} 189}
diff --git a/arch/x86/mm/mmap_32.c b/arch/x86/mm/mmap.c
index 552e08473755..56fe7124fbec 100644
--- a/arch/x86/mm/mmap_32.c
+++ b/arch/x86/mm/mmap.c
@@ -1,10 +1,13 @@
1/* 1/*
2 * linux/arch/i386/mm/mmap.c 2 * Flexible mmap layout support
3 * 3 *
4 * flexible mmap layout support 4 * Based on code by Ingo Molnar and Andi Kleen, copyrighted
5 * as follows:
5 * 6 *
6 * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina. 7 * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
7 * All Rights Reserved. 8 * All Rights Reserved.
9 * Copyright 2005 Andi Kleen, SUSE Labs.
10 * Copyright 2007 Jiri Kosina, SUSE Labs.
8 * 11 *
9 * This program is free software; you can redistribute it and/or modify 12 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by 13 * it under the terms of the GNU General Public License as published by
@@ -19,14 +22,12 @@
19 * You should have received a copy of the GNU General Public License 22 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software 23 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 *
24 * Started by Ingo Molnar <mingo@elte.hu>
25 */ 25 */
26 26
27#include <linux/personality.h> 27#include <linux/personality.h>
28#include <linux/mm.h> 28#include <linux/mm.h>
29#include <linux/random.h> 29#include <linux/random.h>
30#include <linux/limits.h>
30#include <linux/sched.h> 31#include <linux/sched.h>
31 32
32/* 33/*
@@ -37,20 +38,71 @@
37#define MIN_GAP (128*1024*1024) 38#define MIN_GAP (128*1024*1024)
38#define MAX_GAP (TASK_SIZE/6*5) 39#define MAX_GAP (TASK_SIZE/6*5)
39 40
40static inline unsigned long mmap_base(struct mm_struct *mm) 41/*
42 * True on X86_32 or when emulating IA32 on X86_64
43 */
44static int mmap_is_ia32(void)
41{ 45{
42 unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur; 46#ifdef CONFIG_X86_32
43 unsigned long random_factor = 0; 47 return 1;
48#endif
49#ifdef CONFIG_IA32_EMULATION
50 if (test_thread_flag(TIF_IA32))
51 return 1;
52#endif
53 return 0;
54}
44 55
45 if (current->flags & PF_RANDOMIZE) 56static int mmap_is_legacy(void)
46 random_factor = get_random_int() % (1024*1024); 57{
58 if (current->personality & ADDR_COMPAT_LAYOUT)
59 return 1;
60
61 if (current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY)
62 return 1;
63
64 return sysctl_legacy_va_layout;
65}
66
67static unsigned long mmap_rnd(void)
68{
69 unsigned long rnd = 0;
70
71 /*
72 * 8 bits of randomness in 32bit mmaps, 20 address space bits
73 * 28 bits of randomness in 64bit mmaps, 40 address space bits
74 */
75 if (current->flags & PF_RANDOMIZE) {
76 if (mmap_is_ia32())
77 rnd = (long)get_random_int() % (1<<8);
78 else
79 rnd = (long)(get_random_int() % (1<<28));
80 }
81 return rnd << PAGE_SHIFT;
82}
83
84static unsigned long mmap_base(void)
85{
86 unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
47 87
48 if (gap < MIN_GAP) 88 if (gap < MIN_GAP)
49 gap = MIN_GAP; 89 gap = MIN_GAP;
50 else if (gap > MAX_GAP) 90 else if (gap > MAX_GAP)
51 gap = MAX_GAP; 91 gap = MAX_GAP;
52 92
53 return PAGE_ALIGN(TASK_SIZE - gap - random_factor); 93 return PAGE_ALIGN(TASK_SIZE - gap - mmap_rnd());
94}
95
96/*
97 * Bottom-up (legacy) layout on X86_32 did not support randomization, X86_64
98 * does, but not when emulating X86_32
99 */
100static unsigned long mmap_legacy_base(void)
101{
102 if (mmap_is_ia32())
103 return TASK_UNMAPPED_BASE;
104 else
105 return TASK_UNMAPPED_BASE + mmap_rnd();
54} 106}
55 107
56/* 108/*
@@ -59,18 +111,12 @@ static inline unsigned long mmap_base(struct mm_struct *mm)
59 */ 111 */
60void arch_pick_mmap_layout(struct mm_struct *mm) 112void arch_pick_mmap_layout(struct mm_struct *mm)
61{ 113{
62 /* 114 if (mmap_is_legacy()) {
63 * Fall back to the standard layout if the personality 115 mm->mmap_base = mmap_legacy_base();
64 * bit is set, or if the expected stack growth is unlimited:
65 */
66 if (sysctl_legacy_va_layout ||
67 (current->personality & ADDR_COMPAT_LAYOUT) ||
68 current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
69 mm->mmap_base = TASK_UNMAPPED_BASE;
70 mm->get_unmapped_area = arch_get_unmapped_area; 116 mm->get_unmapped_area = arch_get_unmapped_area;
71 mm->unmap_area = arch_unmap_area; 117 mm->unmap_area = arch_unmap_area;
72 } else { 118 } else {
73 mm->mmap_base = mmap_base(mm); 119 mm->mmap_base = mmap_base();
74 mm->get_unmapped_area = arch_get_unmapped_area_topdown; 120 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
75 mm->unmap_area = arch_unmap_area_topdown; 121 mm->unmap_area = arch_unmap_area_topdown;
76 } 122 }
diff --git a/arch/x86/mm/mmap_64.c b/arch/x86/mm/mmap_64.c
deleted file mode 100644
index 80bba0dc000e..000000000000
--- a/arch/x86/mm/mmap_64.c
+++ /dev/null
@@ -1,29 +0,0 @@
1/* Copyright 2005 Andi Kleen, SuSE Labs.
2 * Licensed under GPL, v.2
3 */
4#include <linux/mm.h>
5#include <linux/sched.h>
6#include <linux/random.h>
7#include <asm/ia32.h>
8
9/* Notebook: move the mmap code from sys_x86_64.c over here. */
10
11void arch_pick_mmap_layout(struct mm_struct *mm)
12{
13#ifdef CONFIG_IA32_EMULATION
14 if (current_thread_info()->flags & _TIF_IA32)
15 return ia32_pick_mmap_layout(mm);
16#endif
17 mm->mmap_base = TASK_UNMAPPED_BASE;
18 if (current->flags & PF_RANDOMIZE) {
19 /* Add 28bit randomness which is about 40bits of address space
20 because mmap base has to be page aligned.
21 or ~1/128 of the total user VM
22 (total user address space is 47bits) */
23 unsigned rnd = get_random_int() & 0xfffffff;
24 mm->mmap_base += ((unsigned long)rnd) << PAGE_SHIFT;
25 }
26 mm->get_unmapped_area = arch_get_unmapped_area;
27 mm->unmap_area = arch_unmap_area;
28}
29
diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c
index 3d6926ba8995..dc3b1f7e1451 100644
--- a/arch/x86/mm/numa_64.c
+++ b/arch/x86/mm/numa_64.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Generic VM initialization for x86-64 NUMA setups. 2 * Generic VM initialization for x86-64 NUMA setups.
3 * Copyright 2002,2003 Andi Kleen, SuSE Labs. 3 * Copyright 2002,2003 Andi Kleen, SuSE Labs.
4 */ 4 */
5#include <linux/kernel.h> 5#include <linux/kernel.h>
6#include <linux/mm.h> 6#include <linux/mm.h>
7#include <linux/string.h> 7#include <linux/string.h>
@@ -11,35 +11,45 @@
11#include <linux/ctype.h> 11#include <linux/ctype.h>
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/nodemask.h> 13#include <linux/nodemask.h>
14#include <linux/sched.h>
14 15
15#include <asm/e820.h> 16#include <asm/e820.h>
16#include <asm/proto.h> 17#include <asm/proto.h>
17#include <asm/dma.h> 18#include <asm/dma.h>
18#include <asm/numa.h> 19#include <asm/numa.h>
19#include <asm/acpi.h> 20#include <asm/acpi.h>
21#include <asm/k8.h>
20 22
21#ifndef Dprintk 23#ifndef Dprintk
22#define Dprintk(x...) 24#define Dprintk(x...)
23#endif 25#endif
24 26
25struct pglist_data *node_data[MAX_NUMNODES] __read_mostly; 27struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
28EXPORT_SYMBOL(node_data);
29
26bootmem_data_t plat_node_bdata[MAX_NUMNODES]; 30bootmem_data_t plat_node_bdata[MAX_NUMNODES];
27 31
28struct memnode memnode; 32struct memnode memnode;
29 33
30unsigned char cpu_to_node[NR_CPUS] __read_mostly = { 34int x86_cpu_to_node_map_init[NR_CPUS] = {
31 [0 ... NR_CPUS-1] = NUMA_NO_NODE 35 [0 ... NR_CPUS-1] = NUMA_NO_NODE
32}; 36};
33unsigned char apicid_to_node[MAX_LOCAL_APIC] __cpuinitdata = { 37void *x86_cpu_to_node_map_early_ptr;
34 [0 ... MAX_LOCAL_APIC-1] = NUMA_NO_NODE 38DEFINE_PER_CPU(int, x86_cpu_to_node_map) = NUMA_NO_NODE;
39EXPORT_PER_CPU_SYMBOL(x86_cpu_to_node_map);
40EXPORT_SYMBOL(x86_cpu_to_node_map_early_ptr);
41
42s16 apicid_to_node[MAX_LOCAL_APIC] __cpuinitdata = {
43 [0 ... MAX_LOCAL_APIC-1] = NUMA_NO_NODE
35}; 44};
36cpumask_t node_to_cpumask[MAX_NUMNODES] __read_mostly; 45
46cpumask_t node_to_cpumask_map[MAX_NUMNODES] __read_mostly;
47EXPORT_SYMBOL(node_to_cpumask_map);
37 48
38int numa_off __initdata; 49int numa_off __initdata;
39unsigned long __initdata nodemap_addr; 50unsigned long __initdata nodemap_addr;
40unsigned long __initdata nodemap_size; 51unsigned long __initdata nodemap_size;
41 52
42
43/* 53/*
44 * Given a shift value, try to populate memnodemap[] 54 * Given a shift value, try to populate memnodemap[]
45 * Returns : 55 * Returns :
@@ -47,14 +57,13 @@ unsigned long __initdata nodemap_size;
47 * 0 if memnodmap[] too small (of shift too small) 57 * 0 if memnodmap[] too small (of shift too small)
48 * -1 if node overlap or lost ram (shift too big) 58 * -1 if node overlap or lost ram (shift too big)
49 */ 59 */
50static int __init 60static int __init populate_memnodemap(const struct bootnode *nodes,
51populate_memnodemap(const struct bootnode *nodes, int numnodes, int shift) 61 int numnodes, int shift)
52{ 62{
53 int i;
54 int res = -1;
55 unsigned long addr, end; 63 unsigned long addr, end;
64 int i, res = -1;
56 65
57 memset(memnodemap, 0xff, memnodemapsize); 66 memset(memnodemap, 0xff, sizeof(s16)*memnodemapsize);
58 for (i = 0; i < numnodes; i++) { 67 for (i = 0; i < numnodes; i++) {
59 addr = nodes[i].start; 68 addr = nodes[i].start;
60 end = nodes[i].end; 69 end = nodes[i].end;
@@ -63,13 +72,13 @@ populate_memnodemap(const struct bootnode *nodes, int numnodes, int shift)
63 if ((end >> shift) >= memnodemapsize) 72 if ((end >> shift) >= memnodemapsize)
64 return 0; 73 return 0;
65 do { 74 do {
66 if (memnodemap[addr >> shift] != 0xff) 75 if (memnodemap[addr >> shift] != NUMA_NO_NODE)
67 return -1; 76 return -1;
68 memnodemap[addr >> shift] = i; 77 memnodemap[addr >> shift] = i;
69 addr += (1UL << shift); 78 addr += (1UL << shift);
70 } while (addr < end); 79 } while (addr < end);
71 res = 1; 80 res = 1;
72 } 81 }
73 return res; 82 return res;
74} 83}
75 84
@@ -78,12 +87,12 @@ static int __init allocate_cachealigned_memnodemap(void)
78 unsigned long pad, pad_addr; 87 unsigned long pad, pad_addr;
79 88
80 memnodemap = memnode.embedded_map; 89 memnodemap = memnode.embedded_map;
81 if (memnodemapsize <= 48) 90 if (memnodemapsize <= ARRAY_SIZE(memnode.embedded_map))
82 return 0; 91 return 0;
83 92
84 pad = L1_CACHE_BYTES - 1; 93 pad = L1_CACHE_BYTES - 1;
85 pad_addr = 0x8000; 94 pad_addr = 0x8000;
86 nodemap_size = pad + memnodemapsize; 95 nodemap_size = pad + sizeof(s16) * memnodemapsize;
87 nodemap_addr = find_e820_area(pad_addr, end_pfn<<PAGE_SHIFT, 96 nodemap_addr = find_e820_area(pad_addr, end_pfn<<PAGE_SHIFT,
88 nodemap_size); 97 nodemap_size);
89 if (nodemap_addr == -1UL) { 98 if (nodemap_addr == -1UL) {
@@ -94,6 +103,7 @@ static int __init allocate_cachealigned_memnodemap(void)
94 } 103 }
95 pad_addr = (nodemap_addr + pad) & ~pad; 104 pad_addr = (nodemap_addr + pad) & ~pad;
96 memnodemap = phys_to_virt(pad_addr); 105 memnodemap = phys_to_virt(pad_addr);
106 reserve_early(nodemap_addr, nodemap_addr + nodemap_size);
97 107
98 printk(KERN_DEBUG "NUMA: Allocated memnodemap from %lx - %lx\n", 108 printk(KERN_DEBUG "NUMA: Allocated memnodemap from %lx - %lx\n",
99 nodemap_addr, nodemap_addr + nodemap_size); 109 nodemap_addr, nodemap_addr + nodemap_size);
@@ -104,8 +114,8 @@ static int __init allocate_cachealigned_memnodemap(void)
104 * The LSB of all start and end addresses in the node map is the value of the 114 * The LSB of all start and end addresses in the node map is the value of the
105 * maximum possible shift. 115 * maximum possible shift.
106 */ 116 */
107static int __init 117static int __init extract_lsb_from_nodes(const struct bootnode *nodes,
108extract_lsb_from_nodes (const struct bootnode *nodes, int numnodes) 118 int numnodes)
109{ 119{
110 int i, nodes_used = 0; 120 int i, nodes_used = 0;
111 unsigned long start, end; 121 unsigned long start, end;
@@ -140,51 +150,50 @@ int __init compute_hash_shift(struct bootnode *nodes, int numnodes)
140 shift); 150 shift);
141 151
142 if (populate_memnodemap(nodes, numnodes, shift) != 1) { 152 if (populate_memnodemap(nodes, numnodes, shift) != 1) {
143 printk(KERN_INFO 153 printk(KERN_INFO "Your memory is not aligned you need to "
144 "Your memory is not aligned you need to rebuild your kernel " 154 "rebuild your kernel with a bigger NODEMAPSIZE "
145 "with a bigger NODEMAPSIZE shift=%d\n", 155 "shift=%d\n", shift);
146 shift);
147 return -1; 156 return -1;
148 } 157 }
149 return shift; 158 return shift;
150} 159}
151 160
152#ifdef CONFIG_SPARSEMEM
153int early_pfn_to_nid(unsigned long pfn) 161int early_pfn_to_nid(unsigned long pfn)
154{ 162{
155 return phys_to_nid(pfn << PAGE_SHIFT); 163 return phys_to_nid(pfn << PAGE_SHIFT);
156} 164}
157#endif
158 165
159static void * __init 166static void * __init early_node_mem(int nodeid, unsigned long start,
160early_node_mem(int nodeid, unsigned long start, unsigned long end, 167 unsigned long end, unsigned long size)
161 unsigned long size)
162{ 168{
163 unsigned long mem = find_e820_area(start, end, size); 169 unsigned long mem = find_e820_area(start, end, size);
164 void *ptr; 170 void *ptr;
171
165 if (mem != -1L) 172 if (mem != -1L)
166 return __va(mem); 173 return __va(mem);
167 ptr = __alloc_bootmem_nopanic(size, 174 ptr = __alloc_bootmem_nopanic(size,
168 SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS)); 175 SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS));
169 if (ptr == NULL) { 176 if (ptr == NULL) {
170 printk(KERN_ERR "Cannot find %lu bytes in node %d\n", 177 printk(KERN_ERR "Cannot find %lu bytes in node %d\n",
171 size, nodeid); 178 size, nodeid);
172 return NULL; 179 return NULL;
173 } 180 }
174 return ptr; 181 return ptr;
175} 182}
176 183
177/* Initialize bootmem allocator for a node */ 184/* Initialize bootmem allocator for a node */
178void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long end) 185void __init setup_node_bootmem(int nodeid, unsigned long start,
179{ 186 unsigned long end)
180 unsigned long start_pfn, end_pfn, bootmap_pages, bootmap_size, bootmap_start; 187{
181 unsigned long nodedata_phys; 188 unsigned long start_pfn, end_pfn, bootmap_pages, bootmap_size;
189 unsigned long bootmap_start, nodedata_phys;
182 void *bootmap; 190 void *bootmap;
183 const int pgdat_size = round_up(sizeof(pg_data_t), PAGE_SIZE); 191 const int pgdat_size = round_up(sizeof(pg_data_t), PAGE_SIZE);
184 192
185 start = round_up(start, ZONE_ALIGN); 193 start = round_up(start, ZONE_ALIGN);
186 194
187 printk(KERN_INFO "Bootmem setup node %d %016lx-%016lx\n", nodeid, start, end); 195 printk(KERN_INFO "Bootmem setup node %d %016lx-%016lx\n", nodeid,
196 start, end);
188 197
189 start_pfn = start >> PAGE_SHIFT; 198 start_pfn = start >> PAGE_SHIFT;
190 end_pfn = end >> PAGE_SHIFT; 199 end_pfn = end >> PAGE_SHIFT;
@@ -200,75 +209,55 @@ void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long en
200 NODE_DATA(nodeid)->node_spanned_pages = end_pfn - start_pfn; 209 NODE_DATA(nodeid)->node_spanned_pages = end_pfn - start_pfn;
201 210
202 /* Find a place for the bootmem map */ 211 /* Find a place for the bootmem map */
203 bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn); 212 bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn);
204 bootmap_start = round_up(nodedata_phys + pgdat_size, PAGE_SIZE); 213 bootmap_start = round_up(nodedata_phys + pgdat_size, PAGE_SIZE);
205 bootmap = early_node_mem(nodeid, bootmap_start, end, 214 bootmap = early_node_mem(nodeid, bootmap_start, end,
206 bootmap_pages<<PAGE_SHIFT); 215 bootmap_pages<<PAGE_SHIFT);
207 if (bootmap == NULL) { 216 if (bootmap == NULL) {
208 if (nodedata_phys < start || nodedata_phys >= end) 217 if (nodedata_phys < start || nodedata_phys >= end)
209 free_bootmem((unsigned long)node_data[nodeid],pgdat_size); 218 free_bootmem((unsigned long)node_data[nodeid],
219 pgdat_size);
210 node_data[nodeid] = NULL; 220 node_data[nodeid] = NULL;
211 return; 221 return;
212 } 222 }
213 bootmap_start = __pa(bootmap); 223 bootmap_start = __pa(bootmap);
214 Dprintk("bootmap start %lu pages %lu\n", bootmap_start, bootmap_pages); 224 Dprintk("bootmap start %lu pages %lu\n", bootmap_start, bootmap_pages);
215 225
216 bootmap_size = init_bootmem_node(NODE_DATA(nodeid), 226 bootmap_size = init_bootmem_node(NODE_DATA(nodeid),
217 bootmap_start >> PAGE_SHIFT, 227 bootmap_start >> PAGE_SHIFT,
218 start_pfn, end_pfn); 228 start_pfn, end_pfn);
219 229
220 free_bootmem_with_active_regions(nodeid, end); 230 free_bootmem_with_active_regions(nodeid, end);
221 231
222 reserve_bootmem_node(NODE_DATA(nodeid), nodedata_phys, pgdat_size); 232 reserve_bootmem_node(NODE_DATA(nodeid), nodedata_phys, pgdat_size);
223 reserve_bootmem_node(NODE_DATA(nodeid), bootmap_start, bootmap_pages<<PAGE_SHIFT); 233 reserve_bootmem_node(NODE_DATA(nodeid), bootmap_start,
234 bootmap_pages<<PAGE_SHIFT);
224#ifdef CONFIG_ACPI_NUMA 235#ifdef CONFIG_ACPI_NUMA
225 srat_reserve_add_area(nodeid); 236 srat_reserve_add_area(nodeid);
226#endif 237#endif
227 node_set_online(nodeid); 238 node_set_online(nodeid);
228} 239}
229
230/* Initialize final allocator for a zone */
231void __init setup_node_zones(int nodeid)
232{
233 unsigned long start_pfn, end_pfn, memmapsize, limit;
234
235 start_pfn = node_start_pfn(nodeid);
236 end_pfn = node_end_pfn(nodeid);
237
238 Dprintk(KERN_INFO "Setting up memmap for node %d %lx-%lx\n",
239 nodeid, start_pfn, end_pfn);
240
241 /* Try to allocate mem_map at end to not fill up precious <4GB
242 memory. */
243 memmapsize = sizeof(struct page) * (end_pfn-start_pfn);
244 limit = end_pfn << PAGE_SHIFT;
245#ifdef CONFIG_FLAT_NODE_MEM_MAP
246 NODE_DATA(nodeid)->node_mem_map =
247 __alloc_bootmem_core(NODE_DATA(nodeid)->bdata,
248 memmapsize, SMP_CACHE_BYTES,
249 round_down(limit - memmapsize, PAGE_SIZE),
250 limit);
251#endif
252}
253 240
241/*
242 * There are unfortunately some poorly designed mainboards around that
243 * only connect memory to a single CPU. This breaks the 1:1 cpu->node
244 * mapping. To avoid this fill in the mapping for all possible CPUs,
245 * as the number of CPUs is not known yet. We round robin the existing
246 * nodes.
247 */
254void __init numa_init_array(void) 248void __init numa_init_array(void)
255{ 249{
256 int rr, i; 250 int rr, i;
257 /* There are unfortunately some poorly designed mainboards around 251
258 that only connect memory to a single CPU. This breaks the 1:1 cpu->node
259 mapping. To avoid this fill in the mapping for all possible
260 CPUs, as the number of CPUs is not known yet.
261 We round robin the existing nodes. */
262 rr = first_node(node_online_map); 252 rr = first_node(node_online_map);
263 for (i = 0; i < NR_CPUS; i++) { 253 for (i = 0; i < NR_CPUS; i++) {
264 if (cpu_to_node(i) != NUMA_NO_NODE) 254 if (early_cpu_to_node(i) != NUMA_NO_NODE)
265 continue; 255 continue;
266 numa_set_node(i, rr); 256 numa_set_node(i, rr);
267 rr = next_node(rr, node_online_map); 257 rr = next_node(rr, node_online_map);
268 if (rr == MAX_NUMNODES) 258 if (rr == MAX_NUMNODES)
269 rr = first_node(node_online_map); 259 rr = first_node(node_online_map);
270 } 260 }
271
272} 261}
273 262
274#ifdef CONFIG_NUMA_EMU 263#ifdef CONFIG_NUMA_EMU
@@ -276,15 +265,17 @@ void __init numa_init_array(void)
276char *cmdline __initdata; 265char *cmdline __initdata;
277 266
278/* 267/*
279 * Setups up nid to range from addr to addr + size. If the end boundary is 268 * Setups up nid to range from addr to addr + size. If the end
280 * greater than max_addr, then max_addr is used instead. The return value is 0 269 * boundary is greater than max_addr, then max_addr is used instead.
281 * if there is additional memory left for allocation past addr and -1 otherwise. 270 * The return value is 0 if there is additional memory left for
282 * addr is adjusted to be at the end of the node. 271 * allocation past addr and -1 otherwise. addr is adjusted to be at
272 * the end of the node.
283 */ 273 */
284static int __init setup_node_range(int nid, struct bootnode *nodes, u64 *addr, 274static int __init setup_node_range(int nid, struct bootnode *nodes, u64 *addr,
285 u64 size, u64 max_addr) 275 u64 size, u64 max_addr)
286{ 276{
287 int ret = 0; 277 int ret = 0;
278
288 nodes[nid].start = *addr; 279 nodes[nid].start = *addr;
289 *addr += size; 280 *addr += size;
290 if (*addr >= max_addr) { 281 if (*addr >= max_addr) {
@@ -335,6 +326,7 @@ static int __init split_nodes_equally(struct bootnode *nodes, u64 *addr,
335 326
336 for (i = node_start; i < num_nodes + node_start; i++) { 327 for (i = node_start; i < num_nodes + node_start; i++) {
337 u64 end = *addr + size; 328 u64 end = *addr + size;
329
338 if (i < big) 330 if (i < big)
339 end += FAKE_NODE_MIN_SIZE; 331 end += FAKE_NODE_MIN_SIZE;
340 /* 332 /*
@@ -380,14 +372,9 @@ static int __init split_nodes_by_size(struct bootnode *nodes, u64 *addr,
380static int __init numa_emulation(unsigned long start_pfn, unsigned long end_pfn) 372static int __init numa_emulation(unsigned long start_pfn, unsigned long end_pfn)
381{ 373{
382 struct bootnode nodes[MAX_NUMNODES]; 374 struct bootnode nodes[MAX_NUMNODES];
383 u64 addr = start_pfn << PAGE_SHIFT; 375 u64 size, addr = start_pfn << PAGE_SHIFT;
384 u64 max_addr = end_pfn << PAGE_SHIFT; 376 u64 max_addr = end_pfn << PAGE_SHIFT;
385 int num_nodes = 0; 377 int num_nodes = 0, num = 0, coeff_flag, coeff = -1, i;
386 int coeff_flag;
387 int coeff = -1;
388 int num = 0;
389 u64 size;
390 int i;
391 378
392 memset(&nodes, 0, sizeof(nodes)); 379 memset(&nodes, 0, sizeof(nodes));
393 /* 380 /*
@@ -395,8 +382,9 @@ static int __init numa_emulation(unsigned long start_pfn, unsigned long end_pfn)
395 * system RAM into N fake nodes. 382 * system RAM into N fake nodes.
396 */ 383 */
397 if (!strchr(cmdline, '*') && !strchr(cmdline, ',')) { 384 if (!strchr(cmdline, '*') && !strchr(cmdline, ',')) {
398 num_nodes = split_nodes_equally(nodes, &addr, max_addr, 0, 385 long n = simple_strtol(cmdline, NULL, 0);
399 simple_strtol(cmdline, NULL, 0)); 386
387 num_nodes = split_nodes_equally(nodes, &addr, max_addr, 0, n);
400 if (num_nodes < 0) 388 if (num_nodes < 0)
401 return num_nodes; 389 return num_nodes;
402 goto out; 390 goto out;
@@ -483,46 +471,47 @@ out:
483 for_each_node_mask(i, node_possible_map) { 471 for_each_node_mask(i, node_possible_map) {
484 e820_register_active_regions(i, nodes[i].start >> PAGE_SHIFT, 472 e820_register_active_regions(i, nodes[i].start >> PAGE_SHIFT,
485 nodes[i].end >> PAGE_SHIFT); 473 nodes[i].end >> PAGE_SHIFT);
486 setup_node_bootmem(i, nodes[i].start, nodes[i].end); 474 setup_node_bootmem(i, nodes[i].start, nodes[i].end);
487 } 475 }
488 acpi_fake_nodes(nodes, num_nodes); 476 acpi_fake_nodes(nodes, num_nodes);
489 numa_init_array(); 477 numa_init_array();
490 return 0; 478 return 0;
491} 479}
492#endif /* CONFIG_NUMA_EMU */ 480#endif /* CONFIG_NUMA_EMU */
493 481
494void __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn) 482void __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
495{ 483{
496 int i; 484 int i;
497 485
498 nodes_clear(node_possible_map); 486 nodes_clear(node_possible_map);
499 487
500#ifdef CONFIG_NUMA_EMU 488#ifdef CONFIG_NUMA_EMU
501 if (cmdline && !numa_emulation(start_pfn, end_pfn)) 489 if (cmdline && !numa_emulation(start_pfn, end_pfn))
502 return; 490 return;
503 nodes_clear(node_possible_map); 491 nodes_clear(node_possible_map);
504#endif 492#endif
505 493
506#ifdef CONFIG_ACPI_NUMA 494#ifdef CONFIG_ACPI_NUMA
507 if (!numa_off && !acpi_scan_nodes(start_pfn << PAGE_SHIFT, 495 if (!numa_off && !acpi_scan_nodes(start_pfn << PAGE_SHIFT,
508 end_pfn << PAGE_SHIFT)) 496 end_pfn << PAGE_SHIFT))
509 return; 497 return;
510 nodes_clear(node_possible_map); 498 nodes_clear(node_possible_map);
511#endif 499#endif
512 500
513#ifdef CONFIG_K8_NUMA 501#ifdef CONFIG_K8_NUMA
514 if (!numa_off && !k8_scan_nodes(start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT)) 502 if (!numa_off && !k8_scan_nodes(start_pfn<<PAGE_SHIFT,
503 end_pfn<<PAGE_SHIFT))
515 return; 504 return;
516 nodes_clear(node_possible_map); 505 nodes_clear(node_possible_map);
517#endif 506#endif
518 printk(KERN_INFO "%s\n", 507 printk(KERN_INFO "%s\n",
519 numa_off ? "NUMA turned off" : "No NUMA configuration found"); 508 numa_off ? "NUMA turned off" : "No NUMA configuration found");
520 509
521 printk(KERN_INFO "Faking a node at %016lx-%016lx\n", 510 printk(KERN_INFO "Faking a node at %016lx-%016lx\n",
522 start_pfn << PAGE_SHIFT, 511 start_pfn << PAGE_SHIFT,
523 end_pfn << PAGE_SHIFT); 512 end_pfn << PAGE_SHIFT);
524 /* setup dummy node covering all memory */ 513 /* setup dummy node covering all memory */
525 memnode_shift = 63; 514 memnode_shift = 63;
526 memnodemap = memnode.embedded_map; 515 memnodemap = memnode.embedded_map;
527 memnodemap[0] = 0; 516 memnodemap[0] = 0;
528 nodes_clear(node_online_map); 517 nodes_clear(node_online_map);
@@ -530,36 +519,48 @@ void __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
530 node_set(0, node_possible_map); 519 node_set(0, node_possible_map);
531 for (i = 0; i < NR_CPUS; i++) 520 for (i = 0; i < NR_CPUS; i++)
532 numa_set_node(i, 0); 521 numa_set_node(i, 0);
533 node_to_cpumask[0] = cpumask_of_cpu(0); 522 /* cpumask_of_cpu() may not be available during early startup */
523 memset(&node_to_cpumask_map[0], 0, sizeof(node_to_cpumask_map[0]));
524 cpu_set(0, node_to_cpumask_map[0]);
534 e820_register_active_regions(0, start_pfn, end_pfn); 525 e820_register_active_regions(0, start_pfn, end_pfn);
535 setup_node_bootmem(0, start_pfn << PAGE_SHIFT, end_pfn << PAGE_SHIFT); 526 setup_node_bootmem(0, start_pfn << PAGE_SHIFT, end_pfn << PAGE_SHIFT);
536} 527}
537 528
538__cpuinit void numa_add_cpu(int cpu) 529__cpuinit void numa_add_cpu(int cpu)
539{ 530{
540 set_bit(cpu, &node_to_cpumask[cpu_to_node(cpu)]); 531 set_bit(cpu,
541} 532 (unsigned long *)&node_to_cpumask_map[early_cpu_to_node(cpu)]);
533}
542 534
543void __cpuinit numa_set_node(int cpu, int node) 535void __cpuinit numa_set_node(int cpu, int node)
544{ 536{
537 int *cpu_to_node_map = x86_cpu_to_node_map_early_ptr;
538
545 cpu_pda(cpu)->nodenumber = node; 539 cpu_pda(cpu)->nodenumber = node;
546 cpu_to_node(cpu) = node; 540
541 if(cpu_to_node_map)
542 cpu_to_node_map[cpu] = node;
543 else if(per_cpu_offset(cpu))
544 per_cpu(x86_cpu_to_node_map, cpu) = node;
545 else
546 Dprintk(KERN_INFO "Setting node for non-present cpu %d\n", cpu);
547} 547}
548 548
549unsigned long __init numa_free_all_bootmem(void) 549unsigned long __init numa_free_all_bootmem(void)
550{ 550{
551 int i;
552 unsigned long pages = 0; 551 unsigned long pages = 0;
553 for_each_online_node(i) { 552 int i;
553
554 for_each_online_node(i)
554 pages += free_all_bootmem_node(NODE_DATA(i)); 555 pages += free_all_bootmem_node(NODE_DATA(i));
555 } 556
556 return pages; 557 return pages;
557} 558}
558 559
559void __init paging_init(void) 560void __init paging_init(void)
560{ 561{
561 int i;
562 unsigned long max_zone_pfns[MAX_NR_ZONES]; 562 unsigned long max_zone_pfns[MAX_NR_ZONES];
563
563 memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); 564 memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
564 max_zone_pfns[ZONE_DMA] = MAX_DMA_PFN; 565 max_zone_pfns[ZONE_DMA] = MAX_DMA_PFN;
565 max_zone_pfns[ZONE_DMA32] = MAX_DMA32_PFN; 566 max_zone_pfns[ZONE_DMA32] = MAX_DMA32_PFN;
@@ -568,32 +569,27 @@ void __init paging_init(void)
568 sparse_memory_present_with_active_regions(MAX_NUMNODES); 569 sparse_memory_present_with_active_regions(MAX_NUMNODES);
569 sparse_init(); 570 sparse_init();
570 571
571 for_each_online_node(i) {
572 setup_node_zones(i);
573 }
574
575 free_area_init_nodes(max_zone_pfns); 572 free_area_init_nodes(max_zone_pfns);
576} 573}
577 574
578static __init int numa_setup(char *opt) 575static __init int numa_setup(char *opt)
579{ 576{
580 if (!opt) 577 if (!opt)
581 return -EINVAL; 578 return -EINVAL;
582 if (!strncmp(opt,"off",3)) 579 if (!strncmp(opt, "off", 3))
583 numa_off = 1; 580 numa_off = 1;
584#ifdef CONFIG_NUMA_EMU 581#ifdef CONFIG_NUMA_EMU
585 if (!strncmp(opt, "fake=", 5)) 582 if (!strncmp(opt, "fake=", 5))
586 cmdline = opt + 5; 583 cmdline = opt + 5;
587#endif 584#endif
588#ifdef CONFIG_ACPI_NUMA 585#ifdef CONFIG_ACPI_NUMA
589 if (!strncmp(opt,"noacpi",6)) 586 if (!strncmp(opt, "noacpi", 6))
590 acpi_numa = -1; 587 acpi_numa = -1;
591 if (!strncmp(opt,"hotadd=", 7)) 588 if (!strncmp(opt, "hotadd=", 7))
592 hotadd_percent = simple_strtoul(opt+7, NULL, 10); 589 hotadd_percent = simple_strtoul(opt+7, NULL, 10);
593#endif 590#endif
594 return 0; 591 return 0;
595} 592}
596
597early_param("numa", numa_setup); 593early_param("numa", numa_setup);
598 594
599/* 595/*
@@ -611,38 +607,16 @@ early_param("numa", numa_setup);
611void __init init_cpu_to_node(void) 607void __init init_cpu_to_node(void)
612{ 608{
613 int i; 609 int i;
614 for (i = 0; i < NR_CPUS; i++) { 610
615 u8 apicid = x86_cpu_to_apicid_init[i]; 611 for (i = 0; i < NR_CPUS; i++) {
612 u16 apicid = x86_cpu_to_apicid_init[i];
613
616 if (apicid == BAD_APICID) 614 if (apicid == BAD_APICID)
617 continue; 615 continue;
618 if (apicid_to_node[apicid] == NUMA_NO_NODE) 616 if (apicid_to_node[apicid] == NUMA_NO_NODE)
619 continue; 617 continue;
620 numa_set_node(i,apicid_to_node[apicid]); 618 numa_set_node(i, apicid_to_node[apicid]);
621 } 619 }
622} 620}
623 621
624EXPORT_SYMBOL(cpu_to_node);
625EXPORT_SYMBOL(node_to_cpumask);
626EXPORT_SYMBOL(memnode);
627EXPORT_SYMBOL(node_data);
628
629#ifdef CONFIG_DISCONTIGMEM
630/*
631 * Functions to convert PFNs from/to per node page addresses.
632 * These are out of line because they are quite big.
633 * They could be all tuned by pre caching more state.
634 * Should do that.
635 */
636 622
637int pfn_valid(unsigned long pfn)
638{
639 unsigned nid;
640 if (pfn >= num_physpages)
641 return 0;
642 nid = pfn_to_nid(pfn);
643 if (nid == 0xff)
644 return 0;
645 return pfn >= node_start_pfn(nid) && (pfn) < node_end_pfn(nid);
646}
647EXPORT_SYMBOL(pfn_valid);
648#endif
diff --git a/arch/x86/mm/pageattr-test.c b/arch/x86/mm/pageattr-test.c
new file mode 100644
index 000000000000..06353d43f72e
--- /dev/null
+++ b/arch/x86/mm/pageattr-test.c
@@ -0,0 +1,224 @@
1/*
2 * self test for change_page_attr.
3 *
4 * Clears the global bit on random pages in the direct mapping, then reverts
5 * and compares page tables forwards and afterwards.
6 */
7#include <linux/bootmem.h>
8#include <linux/random.h>
9#include <linux/kernel.h>
10#include <linux/init.h>
11#include <linux/mm.h>
12
13#include <asm/cacheflush.h>
14#include <asm/pgtable.h>
15#include <asm/kdebug.h>
16
17enum {
18 NTEST = 4000,
19#ifdef CONFIG_X86_64
20 LPS = (1 << PMD_SHIFT),
21#elif defined(CONFIG_X86_PAE)
22 LPS = (1 << PMD_SHIFT),
23#else
24 LPS = (1 << 22),
25#endif
26 GPS = (1<<30)
27};
28
29struct split_state {
30 long lpg, gpg, spg, exec;
31 long min_exec, max_exec;
32};
33
34static __init int print_split(struct split_state *s)
35{
36 long i, expected, missed = 0;
37 int printed = 0;
38 int err = 0;
39
40 s->lpg = s->gpg = s->spg = s->exec = 0;
41 s->min_exec = ~0UL;
42 s->max_exec = 0;
43 for (i = 0; i < max_pfn_mapped; ) {
44 unsigned long addr = (unsigned long)__va(i << PAGE_SHIFT);
45 int level;
46 pte_t *pte;
47
48 pte = lookup_address(addr, &level);
49 if (!pte) {
50 if (!printed) {
51 dump_pagetable(addr);
52 printk(KERN_INFO "CPA %lx no pte level %d\n",
53 addr, level);
54 printed = 1;
55 }
56 missed++;
57 i++;
58 continue;
59 }
60
61 if (level == PG_LEVEL_1G && sizeof(long) == 8) {
62 s->gpg++;
63 i += GPS/PAGE_SIZE;
64 } else if (level == PG_LEVEL_2M) {
65 if (!(pte_val(*pte) & _PAGE_PSE)) {
66 printk(KERN_ERR
67 "%lx level %d but not PSE %Lx\n",
68 addr, level, (u64)pte_val(*pte));
69 err = 1;
70 }
71 s->lpg++;
72 i += LPS/PAGE_SIZE;
73 } else {
74 s->spg++;
75 i++;
76 }
77 if (!(pte_val(*pte) & _PAGE_NX)) {
78 s->exec++;
79 if (addr < s->min_exec)
80 s->min_exec = addr;
81 if (addr > s->max_exec)
82 s->max_exec = addr;
83 }
84 }
85 printk(KERN_INFO
86 "CPA mapping 4k %lu large %lu gb %lu x %lu[%lx-%lx] miss %lu\n",
87 s->spg, s->lpg, s->gpg, s->exec,
88 s->min_exec != ~0UL ? s->min_exec : 0, s->max_exec, missed);
89
90 expected = (s->gpg*GPS + s->lpg*LPS)/PAGE_SIZE + s->spg + missed;
91 if (expected != i) {
92 printk(KERN_ERR "CPA max_pfn_mapped %lu but expected %lu\n",
93 max_pfn_mapped, expected);
94 return 1;
95 }
96 return err;
97}
98
99static unsigned long __initdata addr[NTEST];
100static unsigned int __initdata len[NTEST];
101
102/* Change the global bit on random pages in the direct mapping */
103static __init int exercise_pageattr(void)
104{
105 struct split_state sa, sb, sc;
106 unsigned long *bm;
107 pte_t *pte, pte0;
108 int failed = 0;
109 int level;
110 int i, k;
111 int err;
112
113 printk(KERN_INFO "CPA exercising pageattr\n");
114
115 bm = vmalloc((max_pfn_mapped + 7) / 8);
116 if (!bm) {
117 printk(KERN_ERR "CPA Cannot vmalloc bitmap\n");
118 return -ENOMEM;
119 }
120 memset(bm, 0, (max_pfn_mapped + 7) / 8);
121
122 failed += print_split(&sa);
123 srandom32(100);
124
125 for (i = 0; i < NTEST; i++) {
126 unsigned long pfn = random32() % max_pfn_mapped;
127
128 addr[i] = (unsigned long)__va(pfn << PAGE_SHIFT);
129 len[i] = random32() % 100;
130 len[i] = min_t(unsigned long, len[i], max_pfn_mapped - pfn - 1);
131
132 if (len[i] == 0)
133 len[i] = 1;
134
135 pte = NULL;
136 pte0 = pfn_pte(0, __pgprot(0)); /* shut gcc up */
137
138 for (k = 0; k < len[i]; k++) {
139 pte = lookup_address(addr[i] + k*PAGE_SIZE, &level);
140 if (!pte || pgprot_val(pte_pgprot(*pte)) == 0) {
141 addr[i] = 0;
142 break;
143 }
144 if (k == 0) {
145 pte0 = *pte;
146 } else {
147 if (pgprot_val(pte_pgprot(*pte)) !=
148 pgprot_val(pte_pgprot(pte0))) {
149 len[i] = k;
150 break;
151 }
152 }
153 if (test_bit(pfn + k, bm)) {
154 len[i] = k;
155 break;
156 }
157 __set_bit(pfn + k, bm);
158 }
159 if (!addr[i] || !pte || !k) {
160 addr[i] = 0;
161 continue;
162 }
163
164 err = change_page_attr_clear(addr[i], len[i],
165 __pgprot(_PAGE_GLOBAL));
166 if (err < 0) {
167 printk(KERN_ERR "CPA %d failed %d\n", i, err);
168 failed++;
169 }
170
171 pte = lookup_address(addr[i], &level);
172 if (!pte || pte_global(*pte) || pte_huge(*pte)) {
173 printk(KERN_ERR "CPA %lx: bad pte %Lx\n", addr[i],
174 pte ? (u64)pte_val(*pte) : 0ULL);
175 failed++;
176 }
177 if (level != PG_LEVEL_4K) {
178 printk(KERN_ERR "CPA %lx: unexpected level %d\n",
179 addr[i], level);
180 failed++;
181 }
182
183 }
184 vfree(bm);
185
186 failed += print_split(&sb);
187
188 printk(KERN_INFO "CPA reverting everything\n");
189 for (i = 0; i < NTEST; i++) {
190 if (!addr[i])
191 continue;
192 pte = lookup_address(addr[i], &level);
193 if (!pte) {
194 printk(KERN_ERR "CPA lookup of %lx failed\n", addr[i]);
195 failed++;
196 continue;
197 }
198 err = change_page_attr_set(addr[i], len[i],
199 __pgprot(_PAGE_GLOBAL));
200 if (err < 0) {
201 printk(KERN_ERR "CPA reverting failed: %d\n", err);
202 failed++;
203 }
204 pte = lookup_address(addr[i], &level);
205 if (!pte || !pte_global(*pte)) {
206 printk(KERN_ERR "CPA %lx: bad pte after revert %Lx\n",
207 addr[i], pte ? (u64)pte_val(*pte) : 0ULL);
208 failed++;
209 }
210
211 }
212
213 failed += print_split(&sc);
214
215 if (failed) {
216 printk(KERN_ERR "CPA selftests NOT PASSED. Please report.\n");
217 WARN_ON(1);
218 } else {
219 printk(KERN_INFO "CPA selftests PASSED\n");
220 }
221
222 return 0;
223}
224module_init(exercise_pageattr);
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
new file mode 100644
index 000000000000..1cc6607eacb0
--- /dev/null
+++ b/arch/x86/mm/pageattr.c
@@ -0,0 +1,564 @@
1/*
2 * Copyright 2002 Andi Kleen, SuSE Labs.
3 * Thanks to Ben LaHaise for precious feedback.
4 */
5#include <linux/highmem.h>
6#include <linux/bootmem.h>
7#include <linux/module.h>
8#include <linux/sched.h>
9#include <linux/slab.h>
10#include <linux/mm.h>
11
12#include <asm/e820.h>
13#include <asm/processor.h>
14#include <asm/tlbflush.h>
15#include <asm/sections.h>
16#include <asm/uaccess.h>
17#include <asm/pgalloc.h>
18
19static inline int
20within(unsigned long addr, unsigned long start, unsigned long end)
21{
22 return addr >= start && addr < end;
23}
24
25/*
26 * Flushing functions
27 */
28
29/**
30 * clflush_cache_range - flush a cache range with clflush
31 * @addr: virtual start address
32 * @size: number of bytes to flush
33 *
34 * clflush is an unordered instruction which needs fencing with mfence
35 * to avoid ordering issues.
36 */
37void clflush_cache_range(void *vaddr, unsigned int size)
38{
39 void *vend = vaddr + size - 1;
40
41 mb();
42
43 for (; vaddr < vend; vaddr += boot_cpu_data.x86_clflush_size)
44 clflush(vaddr);
45 /*
46 * Flush any possible final partial cacheline:
47 */
48 clflush(vend);
49
50 mb();
51}
52
53static void __cpa_flush_all(void *arg)
54{
55 /*
56 * Flush all to work around Errata in early athlons regarding
57 * large page flushing.
58 */
59 __flush_tlb_all();
60
61 if (boot_cpu_data.x86_model >= 4)
62 wbinvd();
63}
64
65static void cpa_flush_all(void)
66{
67 BUG_ON(irqs_disabled());
68
69 on_each_cpu(__cpa_flush_all, NULL, 1, 1);
70}
71
72static void __cpa_flush_range(void *arg)
73{
74 /*
75 * We could optimize that further and do individual per page
76 * tlb invalidates for a low number of pages. Caveat: we must
77 * flush the high aliases on 64bit as well.
78 */
79 __flush_tlb_all();
80}
81
82static void cpa_flush_range(unsigned long start, int numpages)
83{
84 unsigned int i, level;
85 unsigned long addr;
86
87 BUG_ON(irqs_disabled());
88 WARN_ON(PAGE_ALIGN(start) != start);
89
90 on_each_cpu(__cpa_flush_range, NULL, 1, 1);
91
92 /*
93 * We only need to flush on one CPU,
94 * clflush is a MESI-coherent instruction that
95 * will cause all other CPUs to flush the same
96 * cachelines:
97 */
98 for (i = 0, addr = start; i < numpages; i++, addr += PAGE_SIZE) {
99 pte_t *pte = lookup_address(addr, &level);
100
101 /*
102 * Only flush present addresses:
103 */
104 if (pte && pte_present(*pte))
105 clflush_cache_range((void *) addr, PAGE_SIZE);
106 }
107}
108
109/*
110 * Certain areas of memory on x86 require very specific protection flags,
111 * for example the BIOS area or kernel text. Callers don't always get this
112 * right (again, ioremap() on BIOS memory is not uncommon) so this function
113 * checks and fixes these known static required protection bits.
114 */
115static inline pgprot_t static_protections(pgprot_t prot, unsigned long address)
116{
117 pgprot_t forbidden = __pgprot(0);
118
119 /*
120 * The BIOS area between 640k and 1Mb needs to be executable for
121 * PCI BIOS based config access (CONFIG_PCI_GOBIOS) support.
122 */
123 if (within(__pa(address), BIOS_BEGIN, BIOS_END))
124 pgprot_val(forbidden) |= _PAGE_NX;
125
126 /*
127 * The kernel text needs to be executable for obvious reasons
128 * Does not cover __inittext since that is gone later on
129 */
130 if (within(address, (unsigned long)_text, (unsigned long)_etext))
131 pgprot_val(forbidden) |= _PAGE_NX;
132
133#ifdef CONFIG_DEBUG_RODATA
134 /* The .rodata section needs to be read-only */
135 if (within(address, (unsigned long)__start_rodata,
136 (unsigned long)__end_rodata))
137 pgprot_val(forbidden) |= _PAGE_RW;
138#endif
139
140 prot = __pgprot(pgprot_val(prot) & ~pgprot_val(forbidden));
141
142 return prot;
143}
144
145pte_t *lookup_address(unsigned long address, int *level)
146{
147 pgd_t *pgd = pgd_offset_k(address);
148 pud_t *pud;
149 pmd_t *pmd;
150
151 *level = PG_LEVEL_NONE;
152
153 if (pgd_none(*pgd))
154 return NULL;
155 pud = pud_offset(pgd, address);
156 if (pud_none(*pud))
157 return NULL;
158 pmd = pmd_offset(pud, address);
159 if (pmd_none(*pmd))
160 return NULL;
161
162 *level = PG_LEVEL_2M;
163 if (pmd_large(*pmd))
164 return (pte_t *)pmd;
165
166 *level = PG_LEVEL_4K;
167 return pte_offset_kernel(pmd, address);
168}
169
170static void __set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte)
171{
172 /* change init_mm */
173 set_pte_atomic(kpte, pte);
174#ifdef CONFIG_X86_32
175 if (!SHARED_KERNEL_PMD) {
176 struct page *page;
177
178 list_for_each_entry(page, &pgd_list, lru) {
179 pgd_t *pgd;
180 pud_t *pud;
181 pmd_t *pmd;
182
183 pgd = (pgd_t *)page_address(page) + pgd_index(address);
184 pud = pud_offset(pgd, address);
185 pmd = pmd_offset(pud, address);
186 set_pte_atomic((pte_t *)pmd, pte);
187 }
188 }
189#endif
190}
191
192static int split_large_page(pte_t *kpte, unsigned long address)
193{
194 pgprot_t ref_prot = pte_pgprot(pte_clrhuge(*kpte));
195 gfp_t gfp_flags = GFP_KERNEL;
196 unsigned long flags;
197 unsigned long addr;
198 pte_t *pbase, *tmp;
199 struct page *base;
200 unsigned int i, level;
201
202#ifdef CONFIG_DEBUG_PAGEALLOC
203 gfp_flags = __GFP_HIGH | __GFP_NOFAIL | __GFP_NOWARN;
204 gfp_flags = GFP_ATOMIC | __GFP_NOWARN;
205#endif
206 base = alloc_pages(gfp_flags, 0);
207 if (!base)
208 return -ENOMEM;
209
210 spin_lock_irqsave(&pgd_lock, flags);
211 /*
212 * Check for races, another CPU might have split this page
213 * up for us already:
214 */
215 tmp = lookup_address(address, &level);
216 if (tmp != kpte) {
217 WARN_ON_ONCE(1);
218 goto out_unlock;
219 }
220
221 address = __pa(address);
222 addr = address & LARGE_PAGE_MASK;
223 pbase = (pte_t *)page_address(base);
224#ifdef CONFIG_X86_32
225 paravirt_alloc_pt(&init_mm, page_to_pfn(base));
226#endif
227
228 pgprot_val(ref_prot) &= ~_PAGE_NX;
229 for (i = 0; i < PTRS_PER_PTE; i++, addr += PAGE_SIZE)
230 set_pte(&pbase[i], pfn_pte(addr >> PAGE_SHIFT, ref_prot));
231
232 /*
233 * Install the new, split up pagetable. Important detail here:
234 *
235 * On Intel the NX bit of all levels must be cleared to make a
236 * page executable. See section 4.13.2 of Intel 64 and IA-32
237 * Architectures Software Developer's Manual).
238 */
239 ref_prot = pte_pgprot(pte_mkexec(pte_clrhuge(*kpte)));
240 __set_pmd_pte(kpte, address, mk_pte(base, ref_prot));
241 base = NULL;
242
243out_unlock:
244 spin_unlock_irqrestore(&pgd_lock, flags);
245
246 if (base)
247 __free_pages(base, 0);
248
249 return 0;
250}
251
252static int
253__change_page_attr(unsigned long address, unsigned long pfn,
254 pgprot_t mask_set, pgprot_t mask_clr)
255{
256 struct page *kpte_page;
257 int level, err = 0;
258 pte_t *kpte;
259
260#ifdef CONFIG_X86_32
261 BUG_ON(pfn > max_low_pfn);
262#endif
263
264repeat:
265 kpte = lookup_address(address, &level);
266 if (!kpte)
267 return -EINVAL;
268
269 kpte_page = virt_to_page(kpte);
270 BUG_ON(PageLRU(kpte_page));
271 BUG_ON(PageCompound(kpte_page));
272
273 if (level == PG_LEVEL_4K) {
274 pgprot_t new_prot = pte_pgprot(*kpte);
275 pte_t new_pte, old_pte = *kpte;
276
277 pgprot_val(new_prot) &= ~pgprot_val(mask_clr);
278 pgprot_val(new_prot) |= pgprot_val(mask_set);
279
280 new_prot = static_protections(new_prot, address);
281
282 new_pte = pfn_pte(pfn, canon_pgprot(new_prot));
283 BUG_ON(pte_pfn(new_pte) != pte_pfn(old_pte));
284
285 set_pte_atomic(kpte, new_pte);
286 } else {
287 err = split_large_page(kpte, address);
288 if (!err)
289 goto repeat;
290 }
291 return err;
292}
293
294/**
295 * change_page_attr_addr - Change page table attributes in linear mapping
296 * @address: Virtual address in linear mapping.
297 * @prot: New page table attribute (PAGE_*)
298 *
299 * Change page attributes of a page in the direct mapping. This is a variant
300 * of change_page_attr() that also works on memory holes that do not have
301 * mem_map entry (pfn_valid() is false).
302 *
303 * See change_page_attr() documentation for more details.
304 *
305 * Modules and drivers should use the set_memory_* APIs instead.
306 */
307
308#define HIGH_MAP_START __START_KERNEL_map
309#define HIGH_MAP_END (__START_KERNEL_map + KERNEL_TEXT_SIZE)
310
311static int
312change_page_attr_addr(unsigned long address, pgprot_t mask_set,
313 pgprot_t mask_clr)
314{
315 unsigned long phys_addr = __pa(address);
316 unsigned long pfn = phys_addr >> PAGE_SHIFT;
317 int err;
318
319#ifdef CONFIG_X86_64
320 /*
321 * If we are inside the high mapped kernel range, then we
322 * fixup the low mapping first. __va() returns the virtual
323 * address in the linear mapping:
324 */
325 if (within(address, HIGH_MAP_START, HIGH_MAP_END))
326 address = (unsigned long) __va(phys_addr);
327#endif
328
329 err = __change_page_attr(address, pfn, mask_set, mask_clr);
330 if (err)
331 return err;
332
333#ifdef CONFIG_X86_64
334 /*
335 * If the physical address is inside the kernel map, we need
336 * to touch the high mapped kernel as well:
337 */
338 if (within(phys_addr, 0, KERNEL_TEXT_SIZE)) {
339 /*
340 * Calc the high mapping address. See __phys_addr()
341 * for the non obvious details.
342 */
343 address = phys_addr + HIGH_MAP_START - phys_base;
344 /* Make sure the kernel mappings stay executable */
345 pgprot_val(mask_clr) |= _PAGE_NX;
346
347 /*
348 * Our high aliases are imprecise, because we check
349 * everything between 0 and KERNEL_TEXT_SIZE, so do
350 * not propagate lookup failures back to users:
351 */
352 __change_page_attr(address, pfn, mask_set, mask_clr);
353 }
354#endif
355 return err;
356}
357
358static int __change_page_attr_set_clr(unsigned long addr, int numpages,
359 pgprot_t mask_set, pgprot_t mask_clr)
360{
361 unsigned int i;
362 int ret;
363
364 for (i = 0; i < numpages ; i++, addr += PAGE_SIZE) {
365 ret = change_page_attr_addr(addr, mask_set, mask_clr);
366 if (ret)
367 return ret;
368 }
369
370 return 0;
371}
372
373static int change_page_attr_set_clr(unsigned long addr, int numpages,
374 pgprot_t mask_set, pgprot_t mask_clr)
375{
376 int ret = __change_page_attr_set_clr(addr, numpages, mask_set,
377 mask_clr);
378
379 /*
380 * On success we use clflush, when the CPU supports it to
381 * avoid the wbindv. If the CPU does not support it and in the
382 * error case we fall back to cpa_flush_all (which uses
383 * wbindv):
384 */
385 if (!ret && cpu_has_clflush)
386 cpa_flush_range(addr, numpages);
387 else
388 cpa_flush_all();
389
390 return ret;
391}
392
393static inline int change_page_attr_set(unsigned long addr, int numpages,
394 pgprot_t mask)
395{
396 return change_page_attr_set_clr(addr, numpages, mask, __pgprot(0));
397}
398
399static inline int change_page_attr_clear(unsigned long addr, int numpages,
400 pgprot_t mask)
401{
402 return __change_page_attr_set_clr(addr, numpages, __pgprot(0), mask);
403
404}
405
406int set_memory_uc(unsigned long addr, int numpages)
407{
408 return change_page_attr_set(addr, numpages,
409 __pgprot(_PAGE_PCD | _PAGE_PWT));
410}
411EXPORT_SYMBOL(set_memory_uc);
412
413int set_memory_wb(unsigned long addr, int numpages)
414{
415 return change_page_attr_clear(addr, numpages,
416 __pgprot(_PAGE_PCD | _PAGE_PWT));
417}
418EXPORT_SYMBOL(set_memory_wb);
419
420int set_memory_x(unsigned long addr, int numpages)
421{
422 return change_page_attr_clear(addr, numpages, __pgprot(_PAGE_NX));
423}
424EXPORT_SYMBOL(set_memory_x);
425
426int set_memory_nx(unsigned long addr, int numpages)
427{
428 return change_page_attr_set(addr, numpages, __pgprot(_PAGE_NX));
429}
430EXPORT_SYMBOL(set_memory_nx);
431
432int set_memory_ro(unsigned long addr, int numpages)
433{
434 return change_page_attr_clear(addr, numpages, __pgprot(_PAGE_RW));
435}
436
437int set_memory_rw(unsigned long addr, int numpages)
438{
439 return change_page_attr_set(addr, numpages, __pgprot(_PAGE_RW));
440}
441
442int set_memory_np(unsigned long addr, int numpages)
443{
444 return change_page_attr_clear(addr, numpages, __pgprot(_PAGE_PRESENT));
445}
446
447int set_pages_uc(struct page *page, int numpages)
448{
449 unsigned long addr = (unsigned long)page_address(page);
450
451 return set_memory_uc(addr, numpages);
452}
453EXPORT_SYMBOL(set_pages_uc);
454
455int set_pages_wb(struct page *page, int numpages)
456{
457 unsigned long addr = (unsigned long)page_address(page);
458
459 return set_memory_wb(addr, numpages);
460}
461EXPORT_SYMBOL(set_pages_wb);
462
463int set_pages_x(struct page *page, int numpages)
464{
465 unsigned long addr = (unsigned long)page_address(page);
466
467 return set_memory_x(addr, numpages);
468}
469EXPORT_SYMBOL(set_pages_x);
470
471int set_pages_nx(struct page *page, int numpages)
472{
473 unsigned long addr = (unsigned long)page_address(page);
474
475 return set_memory_nx(addr, numpages);
476}
477EXPORT_SYMBOL(set_pages_nx);
478
479int set_pages_ro(struct page *page, int numpages)
480{
481 unsigned long addr = (unsigned long)page_address(page);
482
483 return set_memory_ro(addr, numpages);
484}
485
486int set_pages_rw(struct page *page, int numpages)
487{
488 unsigned long addr = (unsigned long)page_address(page);
489
490 return set_memory_rw(addr, numpages);
491}
492
493
494#if defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_CPA_DEBUG)
495static inline int __change_page_attr_set(unsigned long addr, int numpages,
496 pgprot_t mask)
497{
498 return __change_page_attr_set_clr(addr, numpages, mask, __pgprot(0));
499}
500
501static inline int __change_page_attr_clear(unsigned long addr, int numpages,
502 pgprot_t mask)
503{
504 return __change_page_attr_set_clr(addr, numpages, __pgprot(0), mask);
505}
506#endif
507
508#ifdef CONFIG_DEBUG_PAGEALLOC
509
510static int __set_pages_p(struct page *page, int numpages)
511{
512 unsigned long addr = (unsigned long)page_address(page);
513
514 return __change_page_attr_set(addr, numpages,
515 __pgprot(_PAGE_PRESENT | _PAGE_RW));
516}
517
518static int __set_pages_np(struct page *page, int numpages)
519{
520 unsigned long addr = (unsigned long)page_address(page);
521
522 return __change_page_attr_clear(addr, numpages,
523 __pgprot(_PAGE_PRESENT));
524}
525
526void kernel_map_pages(struct page *page, int numpages, int enable)
527{
528 if (PageHighMem(page))
529 return;
530 if (!enable) {
531 debug_check_no_locks_freed(page_address(page),
532 numpages * PAGE_SIZE);
533 }
534
535 /*
536 * If page allocator is not up yet then do not call c_p_a():
537 */
538 if (!debug_pagealloc_enabled)
539 return;
540
541 /*
542 * The return value is ignored - the calls cannot fail,
543 * large pages are disabled at boot time:
544 */
545 if (enable)
546 __set_pages_p(page, numpages);
547 else
548 __set_pages_np(page, numpages);
549
550 /*
551 * We should perform an IPI and flush all tlbs,
552 * but that can deadlock->flush only current cpu:
553 */
554 __flush_tlb_all();
555}
556#endif
557
558/*
559 * The testcases use internal knowledge of the implementation that shouldn't
560 * be exposed to the rest of the kernel. Include these directly here.
561 */
562#ifdef CONFIG_CPA_DEBUG
563#include "pageattr-test.c"
564#endif
diff --git a/arch/x86/mm/pageattr_32.c b/arch/x86/mm/pageattr_32.c
deleted file mode 100644
index 260073c07600..000000000000
--- a/arch/x86/mm/pageattr_32.c
+++ /dev/null
@@ -1,278 +0,0 @@
1/*
2 * Copyright 2002 Andi Kleen, SuSE Labs.
3 * Thanks to Ben LaHaise for precious feedback.
4 */
5
6#include <linux/mm.h>
7#include <linux/sched.h>
8#include <linux/highmem.h>
9#include <linux/module.h>
10#include <linux/slab.h>
11#include <asm/uaccess.h>
12#include <asm/processor.h>
13#include <asm/tlbflush.h>
14#include <asm/pgalloc.h>
15#include <asm/sections.h>
16
17static DEFINE_SPINLOCK(cpa_lock);
18static struct list_head df_list = LIST_HEAD_INIT(df_list);
19
20
21pte_t *lookup_address(unsigned long address)
22{
23 pgd_t *pgd = pgd_offset_k(address);
24 pud_t *pud;
25 pmd_t *pmd;
26 if (pgd_none(*pgd))
27 return NULL;
28 pud = pud_offset(pgd, address);
29 if (pud_none(*pud))
30 return NULL;
31 pmd = pmd_offset(pud, address);
32 if (pmd_none(*pmd))
33 return NULL;
34 if (pmd_large(*pmd))
35 return (pte_t *)pmd;
36 return pte_offset_kernel(pmd, address);
37}
38
39static struct page *split_large_page(unsigned long address, pgprot_t prot,
40 pgprot_t ref_prot)
41{
42 int i;
43 unsigned long addr;
44 struct page *base;
45 pte_t *pbase;
46
47 spin_unlock_irq(&cpa_lock);
48 base = alloc_pages(GFP_KERNEL, 0);
49 spin_lock_irq(&cpa_lock);
50 if (!base)
51 return NULL;
52
53 /*
54 * page_private is used to track the number of entries in
55 * the page table page that have non standard attributes.
56 */
57 SetPagePrivate(base);
58 page_private(base) = 0;
59
60 address = __pa(address);
61 addr = address & LARGE_PAGE_MASK;
62 pbase = (pte_t *)page_address(base);
63 paravirt_alloc_pt(&init_mm, page_to_pfn(base));
64 for (i = 0; i < PTRS_PER_PTE; i++, addr += PAGE_SIZE) {
65 set_pte(&pbase[i], pfn_pte(addr >> PAGE_SHIFT,
66 addr == address ? prot : ref_prot));
67 }
68 return base;
69}
70
71static void cache_flush_page(struct page *p)
72{
73 void *adr = page_address(p);
74 int i;
75 for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size)
76 clflush(adr+i);
77}
78
79static void flush_kernel_map(void *arg)
80{
81 struct list_head *lh = (struct list_head *)arg;
82 struct page *p;
83
84 /* High level code is not ready for clflush yet */
85 if (0 && cpu_has_clflush) {
86 list_for_each_entry (p, lh, lru)
87 cache_flush_page(p);
88 } else if (boot_cpu_data.x86_model >= 4)
89 wbinvd();
90
91 /* Flush all to work around Errata in early athlons regarding
92 * large page flushing.
93 */
94 __flush_tlb_all();
95}
96
97static void set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte)
98{
99 struct page *page;
100 unsigned long flags;
101
102 set_pte_atomic(kpte, pte); /* change init_mm */
103 if (SHARED_KERNEL_PMD)
104 return;
105
106 spin_lock_irqsave(&pgd_lock, flags);
107 for (page = pgd_list; page; page = (struct page *)page->index) {
108 pgd_t *pgd;
109 pud_t *pud;
110 pmd_t *pmd;
111 pgd = (pgd_t *)page_address(page) + pgd_index(address);
112 pud = pud_offset(pgd, address);
113 pmd = pmd_offset(pud, address);
114 set_pte_atomic((pte_t *)pmd, pte);
115 }
116 spin_unlock_irqrestore(&pgd_lock, flags);
117}
118
119/*
120 * No more special protections in this 2/4MB area - revert to a
121 * large page again.
122 */
123static inline void revert_page(struct page *kpte_page, unsigned long address)
124{
125 pgprot_t ref_prot;
126 pte_t *linear;
127
128 ref_prot =
129 ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
130 ? PAGE_KERNEL_LARGE_EXEC : PAGE_KERNEL_LARGE;
131
132 linear = (pte_t *)
133 pmd_offset(pud_offset(pgd_offset_k(address), address), address);
134 set_pmd_pte(linear, address,
135 pfn_pte((__pa(address) & LARGE_PAGE_MASK) >> PAGE_SHIFT,
136 ref_prot));
137}
138
139static inline void save_page(struct page *kpte_page)
140{
141 if (!test_and_set_bit(PG_arch_1, &kpte_page->flags))
142 list_add(&kpte_page->lru, &df_list);
143}
144
145static int
146__change_page_attr(struct page *page, pgprot_t prot)
147{
148 pte_t *kpte;
149 unsigned long address;
150 struct page *kpte_page;
151
152 BUG_ON(PageHighMem(page));
153 address = (unsigned long)page_address(page);
154
155 kpte = lookup_address(address);
156 if (!kpte)
157 return -EINVAL;
158 kpte_page = virt_to_page(kpte);
159 BUG_ON(PageLRU(kpte_page));
160 BUG_ON(PageCompound(kpte_page));
161
162 if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) {
163 if (!pte_huge(*kpte)) {
164 set_pte_atomic(kpte, mk_pte(page, prot));
165 } else {
166 pgprot_t ref_prot;
167 struct page *split;
168
169 ref_prot =
170 ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
171 ? PAGE_KERNEL_EXEC : PAGE_KERNEL;
172 split = split_large_page(address, prot, ref_prot);
173 if (!split)
174 return -ENOMEM;
175 set_pmd_pte(kpte,address,mk_pte(split, ref_prot));
176 kpte_page = split;
177 }
178 page_private(kpte_page)++;
179 } else if (!pte_huge(*kpte)) {
180 set_pte_atomic(kpte, mk_pte(page, PAGE_KERNEL));
181 BUG_ON(page_private(kpte_page) == 0);
182 page_private(kpte_page)--;
183 } else
184 BUG();
185
186 /*
187 * If the pte was reserved, it means it was created at boot
188 * time (not via split_large_page) and in turn we must not
189 * replace it with a largepage.
190 */
191
192 save_page(kpte_page);
193 if (!PageReserved(kpte_page)) {
194 if (cpu_has_pse && (page_private(kpte_page) == 0)) {
195 paravirt_release_pt(page_to_pfn(kpte_page));
196 revert_page(kpte_page, address);
197 }
198 }
199 return 0;
200}
201
202static inline void flush_map(struct list_head *l)
203{
204 on_each_cpu(flush_kernel_map, l, 1, 1);
205}
206
207/*
208 * Change the page attributes of an page in the linear mapping.
209 *
210 * This should be used when a page is mapped with a different caching policy
211 * than write-back somewhere - some CPUs do not like it when mappings with
212 * different caching policies exist. This changes the page attributes of the
213 * in kernel linear mapping too.
214 *
215 * The caller needs to ensure that there are no conflicting mappings elsewhere.
216 * This function only deals with the kernel linear map.
217 *
218 * Caller must call global_flush_tlb() after this.
219 */
220int change_page_attr(struct page *page, int numpages, pgprot_t prot)
221{
222 int err = 0;
223 int i;
224 unsigned long flags;
225
226 spin_lock_irqsave(&cpa_lock, flags);
227 for (i = 0; i < numpages; i++, page++) {
228 err = __change_page_attr(page, prot);
229 if (err)
230 break;
231 }
232 spin_unlock_irqrestore(&cpa_lock, flags);
233 return err;
234}
235
236void global_flush_tlb(void)
237{
238 struct list_head l;
239 struct page *pg, *next;
240
241 BUG_ON(irqs_disabled());
242
243 spin_lock_irq(&cpa_lock);
244 list_replace_init(&df_list, &l);
245 spin_unlock_irq(&cpa_lock);
246 flush_map(&l);
247 list_for_each_entry_safe(pg, next, &l, lru) {
248 list_del(&pg->lru);
249 clear_bit(PG_arch_1, &pg->flags);
250 if (PageReserved(pg) || !cpu_has_pse || page_private(pg) != 0)
251 continue;
252 ClearPagePrivate(pg);
253 __free_page(pg);
254 }
255}
256
257#ifdef CONFIG_DEBUG_PAGEALLOC
258void kernel_map_pages(struct page *page, int numpages, int enable)
259{
260 if (PageHighMem(page))
261 return;
262 if (!enable)
263 debug_check_no_locks_freed(page_address(page),
264 numpages * PAGE_SIZE);
265
266 /* the return value is ignored - the calls cannot fail,
267 * large pages are disabled at boot time.
268 */
269 change_page_attr(page, numpages, enable ? PAGE_KERNEL : __pgprot(0));
270 /* we should perform an IPI and flush all tlbs,
271 * but that can deadlock->flush only current cpu.
272 */
273 __flush_tlb_all();
274}
275#endif
276
277EXPORT_SYMBOL(change_page_attr);
278EXPORT_SYMBOL(global_flush_tlb);
diff --git a/arch/x86/mm/pageattr_64.c b/arch/x86/mm/pageattr_64.c
deleted file mode 100644
index c40afbaaf93d..000000000000
--- a/arch/x86/mm/pageattr_64.c
+++ /dev/null
@@ -1,255 +0,0 @@
1/*
2 * Copyright 2002 Andi Kleen, SuSE Labs.
3 * Thanks to Ben LaHaise for precious feedback.
4 */
5
6#include <linux/mm.h>
7#include <linux/sched.h>
8#include <linux/highmem.h>
9#include <linux/module.h>
10#include <linux/slab.h>
11#include <asm/uaccess.h>
12#include <asm/processor.h>
13#include <asm/tlbflush.h>
14#include <asm/io.h>
15
16pte_t *lookup_address(unsigned long address)
17{
18 pgd_t *pgd = pgd_offset_k(address);
19 pud_t *pud;
20 pmd_t *pmd;
21 pte_t *pte;
22 if (pgd_none(*pgd))
23 return NULL;
24 pud = pud_offset(pgd, address);
25 if (!pud_present(*pud))
26 return NULL;
27 pmd = pmd_offset(pud, address);
28 if (!pmd_present(*pmd))
29 return NULL;
30 if (pmd_large(*pmd))
31 return (pte_t *)pmd;
32 pte = pte_offset_kernel(pmd, address);
33 if (pte && !pte_present(*pte))
34 pte = NULL;
35 return pte;
36}
37
38static struct page *split_large_page(unsigned long address, pgprot_t prot,
39 pgprot_t ref_prot)
40{
41 int i;
42 unsigned long addr;
43 struct page *base = alloc_pages(GFP_KERNEL, 0);
44 pte_t *pbase;
45 if (!base)
46 return NULL;
47 /*
48 * page_private is used to track the number of entries in
49 * the page table page have non standard attributes.
50 */
51 SetPagePrivate(base);
52 page_private(base) = 0;
53
54 address = __pa(address);
55 addr = address & LARGE_PAGE_MASK;
56 pbase = (pte_t *)page_address(base);
57 for (i = 0; i < PTRS_PER_PTE; i++, addr += PAGE_SIZE) {
58 pbase[i] = pfn_pte(addr >> PAGE_SHIFT,
59 addr == address ? prot : ref_prot);
60 }
61 return base;
62}
63
64void clflush_cache_range(void *adr, int size)
65{
66 int i;
67 for (i = 0; i < size; i += boot_cpu_data.x86_clflush_size)
68 clflush(adr+i);
69}
70
71static void flush_kernel_map(void *arg)
72{
73 struct list_head *l = (struct list_head *)arg;
74 struct page *pg;
75
76 /* When clflush is available always use it because it is
77 much cheaper than WBINVD. */
78 /* clflush is still broken. Disable for now. */
79 if (1 || !cpu_has_clflush)
80 asm volatile("wbinvd" ::: "memory");
81 else list_for_each_entry(pg, l, lru) {
82 void *adr = page_address(pg);
83 clflush_cache_range(adr, PAGE_SIZE);
84 }
85 __flush_tlb_all();
86}
87
88static inline void flush_map(struct list_head *l)
89{
90 on_each_cpu(flush_kernel_map, l, 1, 1);
91}
92
93static LIST_HEAD(deferred_pages); /* protected by init_mm.mmap_sem */
94
95static inline void save_page(struct page *fpage)
96{
97 if (!test_and_set_bit(PG_arch_1, &fpage->flags))
98 list_add(&fpage->lru, &deferred_pages);
99}
100
101/*
102 * No more special protections in this 2/4MB area - revert to a
103 * large page again.
104 */
105static void revert_page(unsigned long address, pgprot_t ref_prot)
106{
107 pgd_t *pgd;
108 pud_t *pud;
109 pmd_t *pmd;
110 pte_t large_pte;
111 unsigned long pfn;
112
113 pgd = pgd_offset_k(address);
114 BUG_ON(pgd_none(*pgd));
115 pud = pud_offset(pgd,address);
116 BUG_ON(pud_none(*pud));
117 pmd = pmd_offset(pud, address);
118 BUG_ON(pmd_val(*pmd) & _PAGE_PSE);
119 pfn = (__pa(address) & LARGE_PAGE_MASK) >> PAGE_SHIFT;
120 large_pte = pfn_pte(pfn, ref_prot);
121 large_pte = pte_mkhuge(large_pte);
122 set_pte((pte_t *)pmd, large_pte);
123}
124
125static int
126__change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot,
127 pgprot_t ref_prot)
128{
129 pte_t *kpte;
130 struct page *kpte_page;
131 pgprot_t ref_prot2;
132
133 kpte = lookup_address(address);
134 if (!kpte) return 0;
135 kpte_page = virt_to_page(((unsigned long)kpte) & PAGE_MASK);
136 BUG_ON(PageLRU(kpte_page));
137 BUG_ON(PageCompound(kpte_page));
138 if (pgprot_val(prot) != pgprot_val(ref_prot)) {
139 if (!pte_huge(*kpte)) {
140 set_pte(kpte, pfn_pte(pfn, prot));
141 } else {
142 /*
143 * split_large_page will take the reference for this
144 * change_page_attr on the split page.
145 */
146 struct page *split;
147 ref_prot2 = pte_pgprot(pte_clrhuge(*kpte));
148 split = split_large_page(address, prot, ref_prot2);
149 if (!split)
150 return -ENOMEM;
151 pgprot_val(ref_prot2) &= ~_PAGE_NX;
152 set_pte(kpte, mk_pte(split, ref_prot2));
153 kpte_page = split;
154 }
155 page_private(kpte_page)++;
156 } else if (!pte_huge(*kpte)) {
157 set_pte(kpte, pfn_pte(pfn, ref_prot));
158 BUG_ON(page_private(kpte_page) == 0);
159 page_private(kpte_page)--;
160 } else
161 BUG();
162
163 /* on x86-64 the direct mapping set at boot is not using 4k pages */
164 BUG_ON(PageReserved(kpte_page));
165
166 save_page(kpte_page);
167 if (page_private(kpte_page) == 0)
168 revert_page(address, ref_prot);
169 return 0;
170}
171
172/*
173 * Change the page attributes of an page in the linear mapping.
174 *
175 * This should be used when a page is mapped with a different caching policy
176 * than write-back somewhere - some CPUs do not like it when mappings with
177 * different caching policies exist. This changes the page attributes of the
178 * in kernel linear mapping too.
179 *
180 * The caller needs to ensure that there are no conflicting mappings elsewhere.
181 * This function only deals with the kernel linear map.
182 *
183 * Caller must call global_flush_tlb() after this.
184 */
185int change_page_attr_addr(unsigned long address, int numpages, pgprot_t prot)
186{
187 int err = 0, kernel_map = 0;
188 int i;
189
190 if (address >= __START_KERNEL_map
191 && address < __START_KERNEL_map + KERNEL_TEXT_SIZE) {
192 address = (unsigned long)__va(__pa(address));
193 kernel_map = 1;
194 }
195
196 down_write(&init_mm.mmap_sem);
197 for (i = 0; i < numpages; i++, address += PAGE_SIZE) {
198 unsigned long pfn = __pa(address) >> PAGE_SHIFT;
199
200 if (!kernel_map || pte_present(pfn_pte(0, prot))) {
201 err = __change_page_attr(address, pfn, prot, PAGE_KERNEL);
202 if (err)
203 break;
204 }
205 /* Handle kernel mapping too which aliases part of the
206 * lowmem */
207 if (__pa(address) < KERNEL_TEXT_SIZE) {
208 unsigned long addr2;
209 pgprot_t prot2;
210 addr2 = __START_KERNEL_map + __pa(address);
211 /* Make sure the kernel mappings stay executable */
212 prot2 = pte_pgprot(pte_mkexec(pfn_pte(0, prot)));
213 err = __change_page_attr(addr2, pfn, prot2,
214 PAGE_KERNEL_EXEC);
215 }
216 }
217 up_write(&init_mm.mmap_sem);
218 return err;
219}
220
221/* Don't call this for MMIO areas that may not have a mem_map entry */
222int change_page_attr(struct page *page, int numpages, pgprot_t prot)
223{
224 unsigned long addr = (unsigned long)page_address(page);
225 return change_page_attr_addr(addr, numpages, prot);
226}
227
228void global_flush_tlb(void)
229{
230 struct page *pg, *next;
231 struct list_head l;
232
233 /*
234 * Write-protect the semaphore, to exclude two contexts
235 * doing a list_replace_init() call in parallel and to
236 * exclude new additions to the deferred_pages list:
237 */
238 down_write(&init_mm.mmap_sem);
239 list_replace_init(&deferred_pages, &l);
240 up_write(&init_mm.mmap_sem);
241
242 flush_map(&l);
243
244 list_for_each_entry_safe(pg, next, &l, lru) {
245 list_del(&pg->lru);
246 clear_bit(PG_arch_1, &pg->flags);
247 if (page_private(pg) != 0)
248 continue;
249 ClearPagePrivate(pg);
250 __free_page(pg);
251 }
252}
253
254EXPORT_SYMBOL(change_page_attr);
255EXPORT_SYMBOL(global_flush_tlb);
diff --git a/arch/x86/mm/pgtable_32.c b/arch/x86/mm/pgtable_32.c
index be61a1d845a4..2ae5999a795a 100644
--- a/arch/x86/mm/pgtable_32.c
+++ b/arch/x86/mm/pgtable_32.c
@@ -195,11 +195,6 @@ struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
195 return pte; 195 return pte;
196} 196}
197 197
198void pmd_ctor(struct kmem_cache *cache, void *pmd)
199{
200 memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t));
201}
202
203/* 198/*
204 * List of all pgd's needed for non-PAE so it can invalidate entries 199 * List of all pgd's needed for non-PAE so it can invalidate entries
205 * in both cached and uncached pgd's; not needed for PAE since the 200 * in both cached and uncached pgd's; not needed for PAE since the
@@ -210,27 +205,18 @@ void pmd_ctor(struct kmem_cache *cache, void *pmd)
210 * vmalloc faults work because attached pagetables are never freed. 205 * vmalloc faults work because attached pagetables are never freed.
211 * -- wli 206 * -- wli
212 */ 207 */
213DEFINE_SPINLOCK(pgd_lock);
214struct page *pgd_list;
215
216static inline void pgd_list_add(pgd_t *pgd) 208static inline void pgd_list_add(pgd_t *pgd)
217{ 209{
218 struct page *page = virt_to_page(pgd); 210 struct page *page = virt_to_page(pgd);
219 page->index = (unsigned long)pgd_list; 211
220 if (pgd_list) 212 list_add(&page->lru, &pgd_list);
221 set_page_private(pgd_list, (unsigned long)&page->index);
222 pgd_list = page;
223 set_page_private(page, (unsigned long)&pgd_list);
224} 213}
225 214
226static inline void pgd_list_del(pgd_t *pgd) 215static inline void pgd_list_del(pgd_t *pgd)
227{ 216{
228 struct page *next, **pprev, *page = virt_to_page(pgd); 217 struct page *page = virt_to_page(pgd);
229 next = (struct page *)page->index; 218
230 pprev = (struct page **)page_private(page); 219 list_del(&page->lru);
231 *pprev = next;
232 if (next)
233 set_page_private(next, (unsigned long)pprev);
234} 220}
235 221
236 222
@@ -285,7 +271,6 @@ static void pgd_dtor(void *pgd)
285 if (SHARED_KERNEL_PMD) 271 if (SHARED_KERNEL_PMD)
286 return; 272 return;
287 273
288 paravirt_release_pd(__pa(pgd) >> PAGE_SHIFT);
289 spin_lock_irqsave(&pgd_lock, flags); 274 spin_lock_irqsave(&pgd_lock, flags);
290 pgd_list_del(pgd); 275 pgd_list_del(pgd);
291 spin_unlock_irqrestore(&pgd_lock, flags); 276 spin_unlock_irqrestore(&pgd_lock, flags);
@@ -294,77 +279,96 @@ static void pgd_dtor(void *pgd)
294#define UNSHARED_PTRS_PER_PGD \ 279#define UNSHARED_PTRS_PER_PGD \
295 (SHARED_KERNEL_PMD ? USER_PTRS_PER_PGD : PTRS_PER_PGD) 280 (SHARED_KERNEL_PMD ? USER_PTRS_PER_PGD : PTRS_PER_PGD)
296 281
297/* If we allocate a pmd for part of the kernel address space, then 282#ifdef CONFIG_X86_PAE
298 make sure its initialized with the appropriate kernel mappings. 283/*
299 Otherwise use a cached zeroed pmd. */ 284 * Mop up any pmd pages which may still be attached to the pgd.
300static pmd_t *pmd_cache_alloc(int idx) 285 * Normally they will be freed by munmap/exit_mmap, but any pmd we
286 * preallocate which never got a corresponding vma will need to be
287 * freed manually.
288 */
289static void pgd_mop_up_pmds(pgd_t *pgdp)
301{ 290{
302 pmd_t *pmd; 291 int i;
303 292
304 if (idx >= USER_PTRS_PER_PGD) { 293 for(i = 0; i < UNSHARED_PTRS_PER_PGD; i++) {
305 pmd = (pmd_t *)__get_free_page(GFP_KERNEL); 294 pgd_t pgd = pgdp[i];
306 295
307 if (pmd) 296 if (pgd_val(pgd) != 0) {
308 memcpy(pmd, 297 pmd_t *pmd = (pmd_t *)pgd_page_vaddr(pgd);
309 (void *)pgd_page_vaddr(swapper_pg_dir[idx]), 298
299 pgdp[i] = native_make_pgd(0);
300
301 paravirt_release_pd(pgd_val(pgd) >> PAGE_SHIFT);
302 pmd_free(pmd);
303 }
304 }
305}
306
307/*
308 * In PAE mode, we need to do a cr3 reload (=tlb flush) when
309 * updating the top-level pagetable entries to guarantee the
310 * processor notices the update. Since this is expensive, and
311 * all 4 top-level entries are used almost immediately in a
312 * new process's life, we just pre-populate them here.
313 *
314 * Also, if we're in a paravirt environment where the kernel pmd is
315 * not shared between pagetables (!SHARED_KERNEL_PMDS), we allocate
316 * and initialize the kernel pmds here.
317 */
318static int pgd_prepopulate_pmd(struct mm_struct *mm, pgd_t *pgd)
319{
320 pud_t *pud;
321 unsigned long addr;
322 int i;
323
324 pud = pud_offset(pgd, 0);
325 for (addr = i = 0; i < UNSHARED_PTRS_PER_PGD;
326 i++, pud++, addr += PUD_SIZE) {
327 pmd_t *pmd = pmd_alloc_one(mm, addr);
328
329 if (!pmd) {
330 pgd_mop_up_pmds(pgd);
331 return 0;
332 }
333
334 if (i >= USER_PTRS_PER_PGD)
335 memcpy(pmd, (pmd_t *)pgd_page_vaddr(swapper_pg_dir[i]),
310 sizeof(pmd_t) * PTRS_PER_PMD); 336 sizeof(pmd_t) * PTRS_PER_PMD);
311 } else
312 pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL);
313 337
314 return pmd; 338 pud_populate(mm, pud, pmd);
339 }
340
341 return 1;
342}
343#else /* !CONFIG_X86_PAE */
344/* No need to prepopulate any pagetable entries in non-PAE modes. */
345static int pgd_prepopulate_pmd(struct mm_struct *mm, pgd_t *pgd)
346{
347 return 1;
315} 348}
316 349
317static void pmd_cache_free(pmd_t *pmd, int idx) 350static void pgd_mop_up_pmds(pgd_t *pgd)
318{ 351{
319 if (idx >= USER_PTRS_PER_PGD)
320 free_page((unsigned long)pmd);
321 else
322 kmem_cache_free(pmd_cache, pmd);
323} 352}
353#endif /* CONFIG_X86_PAE */
324 354
325pgd_t *pgd_alloc(struct mm_struct *mm) 355pgd_t *pgd_alloc(struct mm_struct *mm)
326{ 356{
327 int i;
328 pgd_t *pgd = quicklist_alloc(0, GFP_KERNEL, pgd_ctor); 357 pgd_t *pgd = quicklist_alloc(0, GFP_KERNEL, pgd_ctor);
329 358
330 if (PTRS_PER_PMD == 1 || !pgd) 359 mm->pgd = pgd; /* so that alloc_pd can use it */
331 return pgd;
332 360
333 for (i = 0; i < UNSHARED_PTRS_PER_PGD; ++i) { 361 if (pgd && !pgd_prepopulate_pmd(mm, pgd)) {
334 pmd_t *pmd = pmd_cache_alloc(i); 362 quicklist_free(0, pgd_dtor, pgd);
335 363 pgd = NULL;
336 if (!pmd)
337 goto out_oom;
338
339 paravirt_alloc_pd(__pa(pmd) >> PAGE_SHIFT);
340 set_pgd(&pgd[i], __pgd(1 + __pa(pmd)));
341 } 364 }
342 return pgd;
343 365
344out_oom: 366 return pgd;
345 for (i--; i >= 0; i--) {
346 pgd_t pgdent = pgd[i];
347 void* pmd = (void *)__va(pgd_val(pgdent)-1);
348 paravirt_release_pd(__pa(pmd) >> PAGE_SHIFT);
349 pmd_cache_free(pmd, i);
350 }
351 quicklist_free(0, pgd_dtor, pgd);
352 return NULL;
353} 367}
354 368
355void pgd_free(pgd_t *pgd) 369void pgd_free(pgd_t *pgd)
356{ 370{
357 int i; 371 pgd_mop_up_pmds(pgd);
358
359 /* in the PAE case user pgd entries are overwritten before usage */
360 if (PTRS_PER_PMD > 1)
361 for (i = 0; i < UNSHARED_PTRS_PER_PGD; ++i) {
362 pgd_t pgdent = pgd[i];
363 void* pmd = (void *)__va(pgd_val(pgdent)-1);
364 paravirt_release_pd(__pa(pmd) >> PAGE_SHIFT);
365 pmd_cache_free(pmd, i);
366 }
367 /* in the non-PAE case, free_pgtables() clears user pgd entries */
368 quicklist_free(0, pgd_dtor, pgd); 372 quicklist_free(0, pgd_dtor, pgd);
369} 373}
370 374
@@ -372,4 +376,3 @@ void check_pgt_cache(void)
372{ 376{
373 quicklist_trim(0, pgd_dtor, 25, 16); 377 quicklist_trim(0, pgd_dtor, 25, 16);
374} 378}
375
diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c
index ea85172fc0cc..65416f843e59 100644
--- a/arch/x86/mm/srat_64.c
+++ b/arch/x86/mm/srat_64.c
@@ -130,6 +130,9 @@ void __init
130acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa) 130acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa)
131{ 131{
132 int pxm, node; 132 int pxm, node;
133 int apic_id;
134
135 apic_id = pa->apic_id;
133 if (srat_disabled()) 136 if (srat_disabled())
134 return; 137 return;
135 if (pa->header.length != sizeof(struct acpi_srat_cpu_affinity)) { 138 if (pa->header.length != sizeof(struct acpi_srat_cpu_affinity)) {
@@ -145,68 +148,12 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa)
145 bad_srat(); 148 bad_srat();
146 return; 149 return;
147 } 150 }
148 apicid_to_node[pa->apic_id] = node; 151 apicid_to_node[apic_id] = node;
149 acpi_numa = 1; 152 acpi_numa = 1;
150 printk(KERN_INFO "SRAT: PXM %u -> APIC %u -> Node %u\n", 153 printk(KERN_INFO "SRAT: PXM %u -> APIC %u -> Node %u\n",
151 pxm, pa->apic_id, node); 154 pxm, apic_id, node);
152}
153
154#ifdef CONFIG_MEMORY_HOTPLUG_RESERVE
155/*
156 * Protect against too large hotadd areas that would fill up memory.
157 */
158static int hotadd_enough_memory(struct bootnode *nd)
159{
160 static unsigned long allocated;
161 static unsigned long last_area_end;
162 unsigned long pages = (nd->end - nd->start) >> PAGE_SHIFT;
163 long mem = pages * sizeof(struct page);
164 unsigned long addr;
165 unsigned long allowed;
166 unsigned long oldpages = pages;
167
168 if (mem < 0)
169 return 0;
170 allowed = (end_pfn - absent_pages_in_range(0, end_pfn)) * PAGE_SIZE;
171 allowed = (allowed / 100) * hotadd_percent;
172 if (allocated + mem > allowed) {
173 unsigned long range;
174 /* Give them at least part of their hotadd memory upto hotadd_percent
175 It would be better to spread the limit out
176 over multiple hotplug areas, but that is too complicated
177 right now */
178 if (allocated >= allowed)
179 return 0;
180 range = allowed - allocated;
181 pages = (range / PAGE_SIZE);
182 mem = pages * sizeof(struct page);
183 nd->end = nd->start + range;
184 }
185 /* Not completely fool proof, but a good sanity check */
186 addr = find_e820_area(last_area_end, end_pfn<<PAGE_SHIFT, mem);
187 if (addr == -1UL)
188 return 0;
189 if (pages != oldpages)
190 printk(KERN_NOTICE "SRAT: Hotadd area limited to %lu bytes\n",
191 pages << PAGE_SHIFT);
192 last_area_end = addr + mem;
193 allocated += mem;
194 return 1;
195}
196
197static int update_end_of_memory(unsigned long end)
198{
199 found_add_area = 1;
200 if ((end >> PAGE_SHIFT) > end_pfn)
201 end_pfn = end >> PAGE_SHIFT;
202 return 1;
203} 155}
204 156
205static inline int save_add_info(void)
206{
207 return hotadd_percent > 0;
208}
209#else
210int update_end_of_memory(unsigned long end) {return -1;} 157int update_end_of_memory(unsigned long end) {return -1;}
211static int hotadd_enough_memory(struct bootnode *nd) {return 1;} 158static int hotadd_enough_memory(struct bootnode *nd) {return 1;}
212#ifdef CONFIG_MEMORY_HOTPLUG_SPARSE 159#ifdef CONFIG_MEMORY_HOTPLUG_SPARSE
@@ -214,10 +161,9 @@ static inline int save_add_info(void) {return 1;}
214#else 161#else
215static inline int save_add_info(void) {return 0;} 162static inline int save_add_info(void) {return 0;}
216#endif 163#endif
217#endif
218/* 164/*
219 * Update nodes_add and decide if to include add are in the zone. 165 * Update nodes_add and decide if to include add are in the zone.
220 * Both SPARSE and RESERVE need nodes_add infomation. 166 * Both SPARSE and RESERVE need nodes_add information.
221 * This code supports one contiguous hot add area per node. 167 * This code supports one contiguous hot add area per node.
222 */ 168 */
223static int reserve_hotadd(int node, unsigned long start, unsigned long end) 169static int reserve_hotadd(int node, unsigned long start, unsigned long end)
@@ -377,7 +323,7 @@ static int __init nodes_cover_memory(const struct bootnode *nodes)
377 return 1; 323 return 1;
378} 324}
379 325
380static void unparse_node(int node) 326static void __init unparse_node(int node)
381{ 327{
382 int i; 328 int i;
383 node_clear(node, nodes_parsed); 329 node_clear(node, nodes_parsed);
@@ -400,7 +346,12 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end)
400 /* First clean up the node list */ 346 /* First clean up the node list */
401 for (i = 0; i < MAX_NUMNODES; i++) { 347 for (i = 0; i < MAX_NUMNODES; i++) {
402 cutoff_node(i, start, end); 348 cutoff_node(i, start, end);
403 if ((nodes[i].end - nodes[i].start) < NODE_MIN_SIZE) { 349 /*
350 * don't confuse VM with a node that doesn't have the
351 * minimum memory.
352 */
353 if (nodes[i].end &&
354 (nodes[i].end - nodes[i].start) < NODE_MIN_SIZE) {
404 unparse_node(i); 355 unparse_node(i);
405 node_set_offline(i); 356 node_set_offline(i);
406 } 357 }
@@ -431,9 +382,11 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end)
431 setup_node_bootmem(i, nodes[i].start, nodes[i].end); 382 setup_node_bootmem(i, nodes[i].start, nodes[i].end);
432 383
433 for (i = 0; i < NR_CPUS; i++) { 384 for (i = 0; i < NR_CPUS; i++) {
434 if (cpu_to_node(i) == NUMA_NO_NODE) 385 int node = early_cpu_to_node(i);
386
387 if (node == NUMA_NO_NODE)
435 continue; 388 continue;
436 if (!node_isset(cpu_to_node(i), node_possible_map)) 389 if (!node_isset(node, node_possible_map))
437 numa_set_node(i, NUMA_NO_NODE); 390 numa_set_node(i, NUMA_NO_NODE);
438 } 391 }
439 numa_init_array(); 392 numa_init_array();
@@ -441,6 +394,12 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end)
441} 394}
442 395
443#ifdef CONFIG_NUMA_EMU 396#ifdef CONFIG_NUMA_EMU
397static int fake_node_to_pxm_map[MAX_NUMNODES] __initdata = {
398 [0 ... MAX_NUMNODES-1] = PXM_INVAL
399};
400static s16 fake_apicid_to_node[MAX_LOCAL_APIC] __initdata = {
401 [0 ... MAX_LOCAL_APIC-1] = NUMA_NO_NODE
402};
444static int __init find_node_by_addr(unsigned long addr) 403static int __init find_node_by_addr(unsigned long addr)
445{ 404{
446 int ret = NUMA_NO_NODE; 405 int ret = NUMA_NO_NODE;
@@ -457,7 +416,7 @@ static int __init find_node_by_addr(unsigned long addr)
457 break; 416 break;
458 } 417 }
459 } 418 }
460 return i; 419 return ret;
461} 420}
462 421
463/* 422/*
@@ -471,12 +430,6 @@ static int __init find_node_by_addr(unsigned long addr)
471void __init acpi_fake_nodes(const struct bootnode *fake_nodes, int num_nodes) 430void __init acpi_fake_nodes(const struct bootnode *fake_nodes, int num_nodes)
472{ 431{
473 int i, j; 432 int i, j;
474 int fake_node_to_pxm_map[MAX_NUMNODES] = {
475 [0 ... MAX_NUMNODES-1] = PXM_INVAL
476 };
477 unsigned char fake_apicid_to_node[MAX_LOCAL_APIC] = {
478 [0 ... MAX_LOCAL_APIC-1] = NUMA_NO_NODE
479 };
480 433
481 printk(KERN_INFO "Faking PXM affinity for fake nodes on real " 434 printk(KERN_INFO "Faking PXM affinity for fake nodes on real "
482 "topology.\n"); 435 "topology.\n");
diff --git a/arch/x86/oprofile/backtrace.c b/arch/x86/oprofile/backtrace.c
index 0ed046a187f7..e2095cba409f 100644
--- a/arch/x86/oprofile/backtrace.c
+++ b/arch/x86/oprofile/backtrace.c
@@ -32,7 +32,7 @@ static int backtrace_stack(void *data, char *name)
32 return 0; 32 return 0;
33} 33}
34 34
35static void backtrace_address(void *data, unsigned long addr) 35static void backtrace_address(void *data, unsigned long addr, int reliable)
36{ 36{
37 unsigned int *depth = data; 37 unsigned int *depth = data;
38 38
@@ -48,7 +48,7 @@ static struct stacktrace_ops backtrace_ops = {
48}; 48};
49 49
50struct frame_head { 50struct frame_head {
51 struct frame_head *ebp; 51 struct frame_head *bp;
52 unsigned long ret; 52 unsigned long ret;
53} __attribute__((packed)); 53} __attribute__((packed));
54 54
@@ -67,21 +67,21 @@ dump_user_backtrace(struct frame_head * head)
67 67
68 /* frame pointers should strictly progress back up the stack 68 /* frame pointers should strictly progress back up the stack
69 * (towards higher addresses) */ 69 * (towards higher addresses) */
70 if (head >= bufhead[0].ebp) 70 if (head >= bufhead[0].bp)
71 return NULL; 71 return NULL;
72 72
73 return bufhead[0].ebp; 73 return bufhead[0].bp;
74} 74}
75 75
76void 76void
77x86_backtrace(struct pt_regs * const regs, unsigned int depth) 77x86_backtrace(struct pt_regs * const regs, unsigned int depth)
78{ 78{
79 struct frame_head *head = (struct frame_head *)frame_pointer(regs); 79 struct frame_head *head = (struct frame_head *)frame_pointer(regs);
80 unsigned long stack = stack_pointer(regs); 80 unsigned long stack = kernel_trap_sp(regs);
81 81
82 if (!user_mode_vm(regs)) { 82 if (!user_mode_vm(regs)) {
83 if (depth) 83 if (depth)
84 dump_trace(NULL, regs, (unsigned long *)stack, 84 dump_trace(NULL, regs, (unsigned long *)stack, 0,
85 &backtrace_ops, &depth); 85 &backtrace_ops, &depth);
86 return; 86 return;
87 } 87 }
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c
index 944bbcdd2b8d..1f11cf0a307f 100644
--- a/arch/x86/oprofile/nmi_int.c
+++ b/arch/x86/oprofile/nmi_int.c
@@ -18,11 +18,11 @@
18#include <asm/nmi.h> 18#include <asm/nmi.h>
19#include <asm/msr.h> 19#include <asm/msr.h>
20#include <asm/apic.h> 20#include <asm/apic.h>
21 21
22#include "op_counter.h" 22#include "op_counter.h"
23#include "op_x86_model.h" 23#include "op_x86_model.h"
24 24
25static struct op_x86_model_spec const * model; 25static struct op_x86_model_spec const *model;
26static struct op_msrs cpu_msrs[NR_CPUS]; 26static struct op_msrs cpu_msrs[NR_CPUS];
27static unsigned long saved_lvtpc[NR_CPUS]; 27static unsigned long saved_lvtpc[NR_CPUS];
28 28
@@ -41,7 +41,6 @@ static int nmi_suspend(struct sys_device *dev, pm_message_t state)
41 return 0; 41 return 0;
42} 42}
43 43
44
45static int nmi_resume(struct sys_device *dev) 44static int nmi_resume(struct sys_device *dev)
46{ 45{
47 if (nmi_enabled == 1) 46 if (nmi_enabled == 1)
@@ -49,29 +48,27 @@ static int nmi_resume(struct sys_device *dev)
49 return 0; 48 return 0;
50} 49}
51 50
52
53static struct sysdev_class oprofile_sysclass = { 51static struct sysdev_class oprofile_sysclass = {
54 set_kset_name("oprofile"), 52 .name = "oprofile",
55 .resume = nmi_resume, 53 .resume = nmi_resume,
56 .suspend = nmi_suspend, 54 .suspend = nmi_suspend,
57}; 55};
58 56
59
60static struct sys_device device_oprofile = { 57static struct sys_device device_oprofile = {
61 .id = 0, 58 .id = 0,
62 .cls = &oprofile_sysclass, 59 .cls = &oprofile_sysclass,
63}; 60};
64 61
65
66static int __init init_sysfs(void) 62static int __init init_sysfs(void)
67{ 63{
68 int error; 64 int error;
69 if (!(error = sysdev_class_register(&oprofile_sysclass))) 65
66 error = sysdev_class_register(&oprofile_sysclass);
67 if (!error)
70 error = sysdev_register(&device_oprofile); 68 error = sysdev_register(&device_oprofile);
71 return error; 69 return error;
72} 70}
73 71
74
75static void exit_sysfs(void) 72static void exit_sysfs(void)
76{ 73{
77 sysdev_unregister(&device_oprofile); 74 sysdev_unregister(&device_oprofile);
@@ -90,7 +87,7 @@ static int profile_exceptions_notify(struct notifier_block *self,
90 int ret = NOTIFY_DONE; 87 int ret = NOTIFY_DONE;
91 int cpu = smp_processor_id(); 88 int cpu = smp_processor_id();
92 89
93 switch(val) { 90 switch (val) {
94 case DIE_NMI: 91 case DIE_NMI:
95 if (model->check_ctrs(args->regs, &cpu_msrs[cpu])) 92 if (model->check_ctrs(args->regs, &cpu_msrs[cpu]))
96 ret = NOTIFY_STOP; 93 ret = NOTIFY_STOP;
@@ -101,24 +98,24 @@ static int profile_exceptions_notify(struct notifier_block *self,
101 return ret; 98 return ret;
102} 99}
103 100
104static void nmi_cpu_save_registers(struct op_msrs * msrs) 101static void nmi_cpu_save_registers(struct op_msrs *msrs)
105{ 102{
106 unsigned int const nr_ctrs = model->num_counters; 103 unsigned int const nr_ctrs = model->num_counters;
107 unsigned int const nr_ctrls = model->num_controls; 104 unsigned int const nr_ctrls = model->num_controls;
108 struct op_msr * counters = msrs->counters; 105 struct op_msr *counters = msrs->counters;
109 struct op_msr * controls = msrs->controls; 106 struct op_msr *controls = msrs->controls;
110 unsigned int i; 107 unsigned int i;
111 108
112 for (i = 0; i < nr_ctrs; ++i) { 109 for (i = 0; i < nr_ctrs; ++i) {
113 if (counters[i].addr){ 110 if (counters[i].addr) {
114 rdmsr(counters[i].addr, 111 rdmsr(counters[i].addr,
115 counters[i].saved.low, 112 counters[i].saved.low,
116 counters[i].saved.high); 113 counters[i].saved.high);
117 } 114 }
118 } 115 }
119 116
120 for (i = 0; i < nr_ctrls; ++i) { 117 for (i = 0; i < nr_ctrls; ++i) {
121 if (controls[i].addr){ 118 if (controls[i].addr) {
122 rdmsr(controls[i].addr, 119 rdmsr(controls[i].addr,
123 controls[i].saved.low, 120 controls[i].saved.low,
124 controls[i].saved.high); 121 controls[i].saved.high);
@@ -126,15 +123,13 @@ static void nmi_cpu_save_registers(struct op_msrs * msrs)
126 } 123 }
127} 124}
128 125
129 126static void nmi_save_registers(void *dummy)
130static void nmi_save_registers(void * dummy)
131{ 127{
132 int cpu = smp_processor_id(); 128 int cpu = smp_processor_id();
133 struct op_msrs * msrs = &cpu_msrs[cpu]; 129 struct op_msrs *msrs = &cpu_msrs[cpu];
134 nmi_cpu_save_registers(msrs); 130 nmi_cpu_save_registers(msrs);
135} 131}
136 132
137
138static void free_msrs(void) 133static void free_msrs(void)
139{ 134{
140 int i; 135 int i;
@@ -146,7 +141,6 @@ static void free_msrs(void)
146 } 141 }
147} 142}
148 143
149
150static int allocate_msrs(void) 144static int allocate_msrs(void)
151{ 145{
152 int success = 1; 146 int success = 1;
@@ -173,11 +167,10 @@ static int allocate_msrs(void)
173 return success; 167 return success;
174} 168}
175 169
176 170static void nmi_cpu_setup(void *dummy)
177static void nmi_cpu_setup(void * dummy)
178{ 171{
179 int cpu = smp_processor_id(); 172 int cpu = smp_processor_id();
180 struct op_msrs * msrs = &cpu_msrs[cpu]; 173 struct op_msrs *msrs = &cpu_msrs[cpu];
181 spin_lock(&oprofilefs_lock); 174 spin_lock(&oprofilefs_lock);
182 model->setup_ctrs(msrs); 175 model->setup_ctrs(msrs);
183 spin_unlock(&oprofilefs_lock); 176 spin_unlock(&oprofilefs_lock);
@@ -193,13 +186,14 @@ static struct notifier_block profile_exceptions_nb = {
193 186
194static int nmi_setup(void) 187static int nmi_setup(void)
195{ 188{
196 int err=0; 189 int err = 0;
197 int cpu; 190 int cpu;
198 191
199 if (!allocate_msrs()) 192 if (!allocate_msrs())
200 return -ENOMEM; 193 return -ENOMEM;
201 194
202 if ((err = register_die_notifier(&profile_exceptions_nb))){ 195 err = register_die_notifier(&profile_exceptions_nb);
196 if (err) {
203 free_msrs(); 197 free_msrs();
204 return err; 198 return err;
205 } 199 }
@@ -210,7 +204,7 @@ static int nmi_setup(void)
210 204
211 /* Assume saved/restored counters are the same on all CPUs */ 205 /* Assume saved/restored counters are the same on all CPUs */
212 model->fill_in_addresses(&cpu_msrs[0]); 206 model->fill_in_addresses(&cpu_msrs[0]);
213 for_each_possible_cpu (cpu) { 207 for_each_possible_cpu(cpu) {
214 if (cpu != 0) { 208 if (cpu != 0) {
215 memcpy(cpu_msrs[cpu].counters, cpu_msrs[0].counters, 209 memcpy(cpu_msrs[cpu].counters, cpu_msrs[0].counters,
216 sizeof(struct op_msr) * model->num_counters); 210 sizeof(struct op_msr) * model->num_counters);
@@ -226,39 +220,37 @@ static int nmi_setup(void)
226 return 0; 220 return 0;
227} 221}
228 222
229 223static void nmi_restore_registers(struct op_msrs *msrs)
230static void nmi_restore_registers(struct op_msrs * msrs)
231{ 224{
232 unsigned int const nr_ctrs = model->num_counters; 225 unsigned int const nr_ctrs = model->num_counters;
233 unsigned int const nr_ctrls = model->num_controls; 226 unsigned int const nr_ctrls = model->num_controls;
234 struct op_msr * counters = msrs->counters; 227 struct op_msr *counters = msrs->counters;
235 struct op_msr * controls = msrs->controls; 228 struct op_msr *controls = msrs->controls;
236 unsigned int i; 229 unsigned int i;
237 230
238 for (i = 0; i < nr_ctrls; ++i) { 231 for (i = 0; i < nr_ctrls; ++i) {
239 if (controls[i].addr){ 232 if (controls[i].addr) {
240 wrmsr(controls[i].addr, 233 wrmsr(controls[i].addr,
241 controls[i].saved.low, 234 controls[i].saved.low,
242 controls[i].saved.high); 235 controls[i].saved.high);
243 } 236 }
244 } 237 }
245 238
246 for (i = 0; i < nr_ctrs; ++i) { 239 for (i = 0; i < nr_ctrs; ++i) {
247 if (counters[i].addr){ 240 if (counters[i].addr) {
248 wrmsr(counters[i].addr, 241 wrmsr(counters[i].addr,
249 counters[i].saved.low, 242 counters[i].saved.low,
250 counters[i].saved.high); 243 counters[i].saved.high);
251 } 244 }
252 } 245 }
253} 246}
254
255 247
256static void nmi_cpu_shutdown(void * dummy) 248static void nmi_cpu_shutdown(void *dummy)
257{ 249{
258 unsigned int v; 250 unsigned int v;
259 int cpu = smp_processor_id(); 251 int cpu = smp_processor_id();
260 struct op_msrs * msrs = &cpu_msrs[cpu]; 252 struct op_msrs *msrs = &cpu_msrs[cpu];
261 253
262 /* restoring APIC_LVTPC can trigger an apic error because the delivery 254 /* restoring APIC_LVTPC can trigger an apic error because the delivery
263 * mode and vector nr combination can be illegal. That's by design: on 255 * mode and vector nr combination can be illegal. That's by design: on
264 * power on apic lvt contain a zero vector nr which are legal only for 256 * power on apic lvt contain a zero vector nr which are legal only for
@@ -271,7 +263,6 @@ static void nmi_cpu_shutdown(void * dummy)
271 nmi_restore_registers(msrs); 263 nmi_restore_registers(msrs);
272} 264}
273 265
274
275static void nmi_shutdown(void) 266static void nmi_shutdown(void)
276{ 267{
277 nmi_enabled = 0; 268 nmi_enabled = 0;
@@ -281,45 +272,40 @@ static void nmi_shutdown(void)
281 free_msrs(); 272 free_msrs();
282} 273}
283 274
284 275static void nmi_cpu_start(void *dummy)
285static void nmi_cpu_start(void * dummy)
286{ 276{
287 struct op_msrs const * msrs = &cpu_msrs[smp_processor_id()]; 277 struct op_msrs const *msrs = &cpu_msrs[smp_processor_id()];
288 model->start(msrs); 278 model->start(msrs);
289} 279}
290
291 280
292static int nmi_start(void) 281static int nmi_start(void)
293{ 282{
294 on_each_cpu(nmi_cpu_start, NULL, 0, 1); 283 on_each_cpu(nmi_cpu_start, NULL, 0, 1);
295 return 0; 284 return 0;
296} 285}
297 286
298 287static void nmi_cpu_stop(void *dummy)
299static void nmi_cpu_stop(void * dummy)
300{ 288{
301 struct op_msrs const * msrs = &cpu_msrs[smp_processor_id()]; 289 struct op_msrs const *msrs = &cpu_msrs[smp_processor_id()];
302 model->stop(msrs); 290 model->stop(msrs);
303} 291}
304 292
305
306static void nmi_stop(void) 293static void nmi_stop(void)
307{ 294{
308 on_each_cpu(nmi_cpu_stop, NULL, 0, 1); 295 on_each_cpu(nmi_cpu_stop, NULL, 0, 1);
309} 296}
310 297
311
312struct op_counter_config counter_config[OP_MAX_COUNTER]; 298struct op_counter_config counter_config[OP_MAX_COUNTER];
313 299
314static int nmi_create_files(struct super_block * sb, struct dentry * root) 300static int nmi_create_files(struct super_block *sb, struct dentry *root)
315{ 301{
316 unsigned int i; 302 unsigned int i;
317 303
318 for (i = 0; i < model->num_counters; ++i) { 304 for (i = 0; i < model->num_counters; ++i) {
319 struct dentry * dir; 305 struct dentry *dir;
320 char buf[4]; 306 char buf[4];
321 307
322 /* quick little hack to _not_ expose a counter if it is not 308 /* quick little hack to _not_ expose a counter if it is not
323 * available for use. This should protect userspace app. 309 * available for use. This should protect userspace app.
324 * NOTE: assumes 1:1 mapping here (that counters are organized 310 * NOTE: assumes 1:1 mapping here (that counters are organized
325 * sequentially in their struct assignment). 311 * sequentially in their struct assignment).
@@ -329,21 +315,21 @@ static int nmi_create_files(struct super_block * sb, struct dentry * root)
329 315
330 snprintf(buf, sizeof(buf), "%d", i); 316 snprintf(buf, sizeof(buf), "%d", i);
331 dir = oprofilefs_mkdir(sb, root, buf); 317 dir = oprofilefs_mkdir(sb, root, buf);
332 oprofilefs_create_ulong(sb, dir, "enabled", &counter_config[i].enabled); 318 oprofilefs_create_ulong(sb, dir, "enabled", &counter_config[i].enabled);
333 oprofilefs_create_ulong(sb, dir, "event", &counter_config[i].event); 319 oprofilefs_create_ulong(sb, dir, "event", &counter_config[i].event);
334 oprofilefs_create_ulong(sb, dir, "count", &counter_config[i].count); 320 oprofilefs_create_ulong(sb, dir, "count", &counter_config[i].count);
335 oprofilefs_create_ulong(sb, dir, "unit_mask", &counter_config[i].unit_mask); 321 oprofilefs_create_ulong(sb, dir, "unit_mask", &counter_config[i].unit_mask);
336 oprofilefs_create_ulong(sb, dir, "kernel", &counter_config[i].kernel); 322 oprofilefs_create_ulong(sb, dir, "kernel", &counter_config[i].kernel);
337 oprofilefs_create_ulong(sb, dir, "user", &counter_config[i].user); 323 oprofilefs_create_ulong(sb, dir, "user", &counter_config[i].user);
338 } 324 }
339 325
340 return 0; 326 return 0;
341} 327}
342 328
343static int p4force; 329static int p4force;
344module_param(p4force, int, 0); 330module_param(p4force, int, 0);
345 331
346static int __init p4_init(char ** cpu_type) 332static int __init p4_init(char **cpu_type)
347{ 333{
348 __u8 cpu_model = boot_cpu_data.x86_model; 334 __u8 cpu_model = boot_cpu_data.x86_model;
349 335
@@ -356,15 +342,15 @@ static int __init p4_init(char ** cpu_type)
356 return 1; 342 return 1;
357#else 343#else
358 switch (smp_num_siblings) { 344 switch (smp_num_siblings) {
359 case 1: 345 case 1:
360 *cpu_type = "i386/p4"; 346 *cpu_type = "i386/p4";
361 model = &op_p4_spec; 347 model = &op_p4_spec;
362 return 1; 348 return 1;
363 349
364 case 2: 350 case 2:
365 *cpu_type = "i386/p4-ht"; 351 *cpu_type = "i386/p4-ht";
366 model = &op_p4_ht2_spec; 352 model = &op_p4_ht2_spec;
367 return 1; 353 return 1;
368 } 354 }
369#endif 355#endif
370 356
@@ -373,8 +359,7 @@ static int __init p4_init(char ** cpu_type)
373 return 0; 359 return 0;
374} 360}
375 361
376 362static int __init ppro_init(char **cpu_type)
377static int __init ppro_init(char ** cpu_type)
378{ 363{
379 __u8 cpu_model = boot_cpu_data.x86_model; 364 __u8 cpu_model = boot_cpu_data.x86_model;
380 365
@@ -409,52 +394,52 @@ int __init op_nmi_init(struct oprofile_operations *ops)
409 394
410 if (!cpu_has_apic) 395 if (!cpu_has_apic)
411 return -ENODEV; 396 return -ENODEV;
412 397
413 switch (vendor) { 398 switch (vendor) {
414 case X86_VENDOR_AMD: 399 case X86_VENDOR_AMD:
415 /* Needs to be at least an Athlon (or hammer in 32bit mode) */ 400 /* Needs to be at least an Athlon (or hammer in 32bit mode) */
416 401
417 switch (family) { 402 switch (family) {
418 default: 403 default:
404 return -ENODEV;
405 case 6:
406 model = &op_athlon_spec;
407 cpu_type = "i386/athlon";
408 break;
409 case 0xf:
410 model = &op_athlon_spec;
411 /* Actually it could be i386/hammer too, but give
412 user space an consistent name. */
413 cpu_type = "x86-64/hammer";
414 break;
415 case 0x10:
416 model = &op_athlon_spec;
417 cpu_type = "x86-64/family10";
418 break;
419 }
420 break;
421
422 case X86_VENDOR_INTEL:
423 switch (family) {
424 /* Pentium IV */
425 case 0xf:
426 if (!p4_init(&cpu_type))
419 return -ENODEV; 427 return -ENODEV;
420 case 6:
421 model = &op_athlon_spec;
422 cpu_type = "i386/athlon";
423 break;
424 case 0xf:
425 model = &op_athlon_spec;
426 /* Actually it could be i386/hammer too, but give
427 user space an consistent name. */
428 cpu_type = "x86-64/hammer";
429 break;
430 case 0x10:
431 model = &op_athlon_spec;
432 cpu_type = "x86-64/family10";
433 break;
434 }
435 break; 428 break;
436 429
437 case X86_VENDOR_INTEL: 430 /* A P6-class processor */
438 switch (family) { 431 case 6:
439 /* Pentium IV */ 432 if (!ppro_init(&cpu_type))
440 case 0xf: 433 return -ENODEV;
441 if (!p4_init(&cpu_type))
442 return -ENODEV;
443 break;
444
445 /* A P6-class processor */
446 case 6:
447 if (!ppro_init(&cpu_type))
448 return -ENODEV;
449 break;
450
451 default:
452 return -ENODEV;
453 }
454 break; 434 break;
455 435
456 default: 436 default:
457 return -ENODEV; 437 return -ENODEV;
438 }
439 break;
440
441 default:
442 return -ENODEV;
458 } 443 }
459 444
460 init_sysfs(); 445 init_sysfs();
@@ -469,7 +454,6 @@ int __init op_nmi_init(struct oprofile_operations *ops)
469 return 0; 454 return 0;
470} 455}
471 456
472
473void op_nmi_exit(void) 457void op_nmi_exit(void)
474{ 458{
475 if (using_nmi) 459 if (using_nmi)
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 862746390666..52deabc72a6f 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -109,6 +109,19 @@ static void __devinit pcibios_fixup_ghosts(struct pci_bus *b)
109 } 109 }
110} 110}
111 111
112static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
113{
114 struct resource *rom_r = &dev->resource[PCI_ROM_RESOURCE];
115
116 if (rom_r->parent)
117 return;
118 if (rom_r->start)
119 /* we deal with BIOS assigned ROM later */
120 return;
121 if (!(pci_probe & PCI_ASSIGN_ROMS))
122 rom_r->start = rom_r->end = rom_r->flags = 0;
123}
124
112/* 125/*
113 * Called after each bus is probed, but before its children 126 * Called after each bus is probed, but before its children
114 * are examined. 127 * are examined.
@@ -116,8 +129,12 @@ static void __devinit pcibios_fixup_ghosts(struct pci_bus *b)
116 129
117void __devinit pcibios_fixup_bus(struct pci_bus *b) 130void __devinit pcibios_fixup_bus(struct pci_bus *b)
118{ 131{
132 struct pci_dev *dev;
133
119 pcibios_fixup_ghosts(b); 134 pcibios_fixup_ghosts(b);
120 pci_read_bridge_bases(b); 135 pci_read_bridge_bases(b);
136 list_for_each_entry(dev, &b->devices, bus_list)
137 pcibios_fixup_device_resources(dev);
121} 138}
122 139
123/* 140/*
diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c
index 6cff66dd0c91..cb63007e20b2 100644
--- a/arch/x86/pci/fixup.c
+++ b/arch/x86/pci/fixup.c
@@ -19,7 +19,7 @@ static void __devinit pci_fixup_i450nx(struct pci_dev *d)
19 19
20 printk(KERN_WARNING "PCI: Searching for i450NX host bridges on %s\n", pci_name(d)); 20 printk(KERN_WARNING "PCI: Searching for i450NX host bridges on %s\n", pci_name(d));
21 reg = 0xd0; 21 reg = 0xd0;
22 for(pxb=0; pxb<2; pxb++) { 22 for(pxb = 0; pxb < 2; pxb++) {
23 pci_read_config_byte(d, reg++, &busno); 23 pci_read_config_byte(d, reg++, &busno);
24 pci_read_config_byte(d, reg++, &suba); 24 pci_read_config_byte(d, reg++, &suba);
25 pci_read_config_byte(d, reg++, &subb); 25 pci_read_config_byte(d, reg++, &subb);
@@ -56,7 +56,7 @@ static void __devinit pci_fixup_umc_ide(struct pci_dev *d)
56 int i; 56 int i;
57 57
58 printk(KERN_WARNING "PCI: Fixing base address flags for device %s\n", pci_name(d)); 58 printk(KERN_WARNING "PCI: Fixing base address flags for device %s\n", pci_name(d));
59 for(i=0; i<4; i++) 59 for(i = 0; i < 4; i++)
60 d->resource[i].flags |= PCI_BASE_ADDRESS_SPACE_IO; 60 d->resource[i].flags |= PCI_BASE_ADDRESS_SPACE_IO;
61} 61}
62DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886BF, pci_fixup_umc_ide); 62DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886BF, pci_fixup_umc_ide);
@@ -127,7 +127,7 @@ static void pci_fixup_via_northbridge_bug(struct pci_dev *d)
127 NB latency to zero */ 127 NB latency to zero */
128 pci_write_config_byte(d, PCI_LATENCY_TIMER, 0); 128 pci_write_config_byte(d, PCI_LATENCY_TIMER, 0);
129 129
130 where = 0x95; /* the memory write queue timer register is 130 where = 0x95; /* the memory write queue timer register is
131 different for the KT266x's: 0x95 not 0x55 */ 131 different for the KT266x's: 0x95 not 0x55 */
132 } else if (d->device == PCI_DEVICE_ID_VIA_8363_0 && 132 } else if (d->device == PCI_DEVICE_ID_VIA_8363_0 &&
133 (d->revision == VIA_8363_KL133_REVISION_ID || 133 (d->revision == VIA_8363_KL133_REVISION_ID ||
@@ -230,7 +230,7 @@ static int quirk_pcie_aspm_write(struct pci_bus *bus, unsigned int devfn, int wh
230 230
231 if ((offset) && (where == offset)) 231 if ((offset) && (where == offset))
232 value = value & 0xfffffffc; 232 value = value & 0xfffffffc;
233 233
234 return raw_pci_ops->write(0, bus->number, devfn, where, size, value); 234 return raw_pci_ops->write(0, bus->number, devfn, where, size, value);
235} 235}
236 236
@@ -271,8 +271,8 @@ static void pcie_rootport_aspm_quirk(struct pci_dev *pdev)
271 * after hot-remove, the pbus->devices is empty and this code 271 * after hot-remove, the pbus->devices is empty and this code
272 * will set the offsets to zero and the bus ops to parent's bus 272 * will set the offsets to zero and the bus ops to parent's bus
273 * ops, which is unmodified. 273 * ops, which is unmodified.
274 */ 274 */
275 for (i= GET_INDEX(pdev->device, 0); i <= GET_INDEX(pdev->device, 7); ++i) 275 for (i = GET_INDEX(pdev->device, 0); i <= GET_INDEX(pdev->device, 7); ++i)
276 quirk_aspm_offset[i] = 0; 276 quirk_aspm_offset[i] = 0;
277 277
278 pbus->ops = pbus->parent->ops; 278 pbus->ops = pbus->parent->ops;
@@ -286,17 +286,17 @@ static void pcie_rootport_aspm_quirk(struct pci_dev *pdev)
286 list_for_each_entry(dev, &pbus->devices, bus_list) { 286 list_for_each_entry(dev, &pbus->devices, bus_list) {
287 /* There are 0 to 8 devices attached to this bus */ 287 /* There are 0 to 8 devices attached to this bus */
288 cap_base = pci_find_capability(dev, PCI_CAP_ID_EXP); 288 cap_base = pci_find_capability(dev, PCI_CAP_ID_EXP);
289 quirk_aspm_offset[GET_INDEX(pdev->device, dev->devfn)]= cap_base + 0x10; 289 quirk_aspm_offset[GET_INDEX(pdev->device, dev->devfn)] = cap_base + 0x10;
290 } 290 }
291 pbus->ops = &quirk_pcie_aspm_ops; 291 pbus->ops = &quirk_pcie_aspm_ops;
292 } 292 }
293} 293}
294DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PA, pcie_rootport_aspm_quirk ); 294DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PA, pcie_rootport_aspm_quirk);
295DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PA1, pcie_rootport_aspm_quirk ); 295DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PA1, pcie_rootport_aspm_quirk);
296DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PB, pcie_rootport_aspm_quirk ); 296DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PB, pcie_rootport_aspm_quirk);
297DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PB1, pcie_rootport_aspm_quirk ); 297DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PB1, pcie_rootport_aspm_quirk);
298DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PC, pcie_rootport_aspm_quirk ); 298DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PC, pcie_rootport_aspm_quirk);
299DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PC1, pcie_rootport_aspm_quirk ); 299DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PC1, pcie_rootport_aspm_quirk);
300 300
301/* 301/*
302 * Fixup to mark boot BIOS video selected by BIOS before it changes 302 * Fixup to mark boot BIOS video selected by BIOS before it changes
@@ -336,8 +336,8 @@ static void __devinit pci_fixup_video(struct pci_dev *pdev)
336 * PCI header type NORMAL. 336 * PCI header type NORMAL.
337 */ 337 */
338 if (bridge 338 if (bridge
339 &&((bridge->hdr_type == PCI_HEADER_TYPE_BRIDGE) 339 && ((bridge->hdr_type == PCI_HEADER_TYPE_BRIDGE)
340 ||(bridge->hdr_type == PCI_HEADER_TYPE_CARDBUS))) { 340 || (bridge->hdr_type == PCI_HEADER_TYPE_CARDBUS))) {
341 pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, 341 pci_read_config_word(bridge, PCI_BRIDGE_CONTROL,
342 &config); 342 &config);
343 if (!(config & PCI_BRIDGE_CTL_VGA)) 343 if (!(config & PCI_BRIDGE_CTL_VGA))
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
index 88d8f5c0ecb5..ed07ce6c171b 100644
--- a/arch/x86/pci/irq.c
+++ b/arch/x86/pci/irq.c
@@ -200,6 +200,7 @@ static int pirq_ali_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
200{ 200{
201 static const unsigned char irqmap[16] = { 0, 9, 3, 10, 4, 5, 7, 6, 1, 11, 0, 12, 0, 14, 0, 15 }; 201 static const unsigned char irqmap[16] = { 0, 9, 3, 10, 4, 5, 7, 6, 1, 11, 0, 12, 0, 14, 0, 15 };
202 202
203 WARN_ON_ONCE(pirq >= 16);
203 return irqmap[read_config_nybble(router, 0x48, pirq-1)]; 204 return irqmap[read_config_nybble(router, 0x48, pirq-1)];
204} 205}
205 206
@@ -207,7 +208,8 @@ static int pirq_ali_set(struct pci_dev *router, struct pci_dev *dev, int pirq, i
207{ 208{
208 static const unsigned char irqmap[16] = { 0, 8, 0, 2, 4, 5, 7, 6, 0, 1, 3, 9, 11, 0, 13, 15 }; 209 static const unsigned char irqmap[16] = { 0, 8, 0, 2, 4, 5, 7, 6, 0, 1, 3, 9, 11, 0, 13, 15 };
209 unsigned int val = irqmap[irq]; 210 unsigned int val = irqmap[irq];
210 211
212 WARN_ON_ONCE(pirq >= 16);
211 if (val) { 213 if (val) {
212 write_config_nybble(router, 0x48, pirq-1, val); 214 write_config_nybble(router, 0x48, pirq-1, val);
213 return 1; 215 return 1;
@@ -257,12 +259,16 @@ static int pirq_via_set(struct pci_dev *router, struct pci_dev *dev, int pirq, i
257static int pirq_via586_get(struct pci_dev *router, struct pci_dev *dev, int pirq) 259static int pirq_via586_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
258{ 260{
259 static const unsigned int pirqmap[5] = { 3, 2, 5, 1, 1 }; 261 static const unsigned int pirqmap[5] = { 3, 2, 5, 1, 1 };
262
263 WARN_ON_ONCE(pirq >= 5);
260 return read_config_nybble(router, 0x55, pirqmap[pirq-1]); 264 return read_config_nybble(router, 0x55, pirqmap[pirq-1]);
261} 265}
262 266
263static int pirq_via586_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) 267static int pirq_via586_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
264{ 268{
265 static const unsigned int pirqmap[5] = { 3, 2, 5, 1, 1 }; 269 static const unsigned int pirqmap[5] = { 3, 2, 5, 1, 1 };
270
271 WARN_ON_ONCE(pirq >= 5);
266 write_config_nybble(router, 0x55, pirqmap[pirq-1], irq); 272 write_config_nybble(router, 0x55, pirqmap[pirq-1], irq);
267 return 1; 273 return 1;
268} 274}
@@ -275,12 +281,16 @@ static int pirq_via586_set(struct pci_dev *router, struct pci_dev *dev, int pirq
275static int pirq_ite_get(struct pci_dev *router, struct pci_dev *dev, int pirq) 281static int pirq_ite_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
276{ 282{
277 static const unsigned char pirqmap[4] = { 1, 0, 2, 3 }; 283 static const unsigned char pirqmap[4] = { 1, 0, 2, 3 };
284
285 WARN_ON_ONCE(pirq >= 4);
278 return read_config_nybble(router,0x43, pirqmap[pirq-1]); 286 return read_config_nybble(router,0x43, pirqmap[pirq-1]);
279} 287}
280 288
281static int pirq_ite_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) 289static int pirq_ite_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
282{ 290{
283 static const unsigned char pirqmap[4] = { 1, 0, 2, 3 }; 291 static const unsigned char pirqmap[4] = { 1, 0, 2, 3 };
292
293 WARN_ON_ONCE(pirq >= 4);
284 write_config_nybble(router, 0x43, pirqmap[pirq-1], irq); 294 write_config_nybble(router, 0x43, pirqmap[pirq-1], irq);
285 return 1; 295 return 1;
286} 296}
@@ -419,6 +429,7 @@ static int pirq_sis_set(struct pci_dev *router, struct pci_dev *dev, int pirq, i
419 429
420static int pirq_vlsi_get(struct pci_dev *router, struct pci_dev *dev, int pirq) 430static int pirq_vlsi_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
421{ 431{
432 WARN_ON_ONCE(pirq >= 9);
422 if (pirq > 8) { 433 if (pirq > 8) {
423 printk(KERN_INFO "VLSI router pirq escape (%d)\n", pirq); 434 printk(KERN_INFO "VLSI router pirq escape (%d)\n", pirq);
424 return 0; 435 return 0;
@@ -428,6 +439,7 @@ static int pirq_vlsi_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
428 439
429static int pirq_vlsi_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) 440static int pirq_vlsi_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
430{ 441{
442 WARN_ON_ONCE(pirq >= 9);
431 if (pirq > 8) { 443 if (pirq > 8) {
432 printk(KERN_INFO "VLSI router pirq escape (%d)\n", pirq); 444 printk(KERN_INFO "VLSI router pirq escape (%d)\n", pirq);
433 return 0; 445 return 0;
@@ -449,14 +461,14 @@ static int pirq_vlsi_set(struct pci_dev *router, struct pci_dev *dev, int pirq,
449 */ 461 */
450static int pirq_serverworks_get(struct pci_dev *router, struct pci_dev *dev, int pirq) 462static int pirq_serverworks_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
451{ 463{
452 outb_p(pirq, 0xc00); 464 outb(pirq, 0xc00);
453 return inb(0xc01) & 0xf; 465 return inb(0xc01) & 0xf;
454} 466}
455 467
456static int pirq_serverworks_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) 468static int pirq_serverworks_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
457{ 469{
458 outb_p(pirq, 0xc00); 470 outb(pirq, 0xc00);
459 outb_p(irq, 0xc01); 471 outb(irq, 0xc01);
460 return 1; 472 return 1;
461} 473}
462 474
diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c
index 998fd3ec0d68..efcf620d1439 100644
--- a/arch/x86/power/cpu.c
+++ b/arch/x86/power/cpu.c
@@ -19,7 +19,7 @@ unsigned long saved_context_esp, saved_context_ebp;
19unsigned long saved_context_esi, saved_context_edi; 19unsigned long saved_context_esi, saved_context_edi;
20unsigned long saved_context_eflags; 20unsigned long saved_context_eflags;
21 21
22void __save_processor_state(struct saved_context *ctxt) 22static void __save_processor_state(struct saved_context *ctxt)
23{ 23{
24 mtrr_save_fixed_ranges(NULL); 24 mtrr_save_fixed_ranges(NULL);
25 kernel_fpu_begin(); 25 kernel_fpu_begin();
@@ -74,19 +74,19 @@ static void fix_processor_context(void)
74 /* 74 /*
75 * Now maybe reload the debug registers 75 * Now maybe reload the debug registers
76 */ 76 */
77 if (current->thread.debugreg[7]){ 77 if (current->thread.debugreg7) {
78 set_debugreg(current->thread.debugreg[0], 0); 78 set_debugreg(current->thread.debugreg0, 0);
79 set_debugreg(current->thread.debugreg[1], 1); 79 set_debugreg(current->thread.debugreg1, 1);
80 set_debugreg(current->thread.debugreg[2], 2); 80 set_debugreg(current->thread.debugreg2, 2);
81 set_debugreg(current->thread.debugreg[3], 3); 81 set_debugreg(current->thread.debugreg3, 3);
82 /* no 4 and 5 */ 82 /* no 4 and 5 */
83 set_debugreg(current->thread.debugreg[6], 6); 83 set_debugreg(current->thread.debugreg6, 6);
84 set_debugreg(current->thread.debugreg[7], 7); 84 set_debugreg(current->thread.debugreg7, 7);
85 } 85 }
86 86
87} 87}
88 88
89void __restore_processor_state(struct saved_context *ctxt) 89static void __restore_processor_state(struct saved_context *ctxt)
90{ 90{
91 /* 91 /*
92 * control registers 92 * control registers
diff --git a/arch/x86/vdso/.gitignore b/arch/x86/vdso/.gitignore
index f8b69d84238e..60274d5746e1 100644
--- a/arch/x86/vdso/.gitignore
+++ b/arch/x86/vdso/.gitignore
@@ -1 +1,6 @@
1vdso.lds 1vdso.lds
2vdso-syms.lds
3vdso32-syms.lds
4vdso32-syscall-syms.lds
5vdso32-sysenter-syms.lds
6vdso32-int80-syms.lds
diff --git a/arch/x86/vdso/Makefile b/arch/x86/vdso/Makefile
index e7bff0fbac23..d28dda574700 100644
--- a/arch/x86/vdso/Makefile
+++ b/arch/x86/vdso/Makefile
@@ -1,39 +1,37 @@
1# 1#
2# x86-64 vDSO. 2# Building vDSO images for x86.
3# 3#
4 4
5VDSO64-$(CONFIG_X86_64) := y
6VDSO32-$(CONFIG_X86_32) := y
7VDSO32-$(CONFIG_COMPAT) := y
8
9vdso-install-$(VDSO64-y) += vdso.so
10vdso-install-$(VDSO32-y) += $(vdso32-y:=.so)
11
12
5# files to link into the vdso 13# files to link into the vdso
6# vdso-start.o has to be first 14vobjs-y := vdso-note.o vclock_gettime.o vgetcpu.o vvar.o
7vobjs-y := vdso-start.o vdso-note.o vclock_gettime.o vgetcpu.o vvar.o
8 15
9# files to link into kernel 16# files to link into kernel
10obj-y := vma.o vdso.o vdso-syms.o 17obj-$(VDSO64-y) += vma.o vdso.o
18obj-$(VDSO32-y) += vdso32.o vdso32-setup.o
11 19
12vobjs := $(foreach F,$(vobjs-y),$(obj)/$F) 20vobjs := $(foreach F,$(vobjs-y),$(obj)/$F)
13 21
14$(obj)/vdso.o: $(obj)/vdso.so 22$(obj)/vdso.o: $(obj)/vdso.so
15 23
16targets += vdso.so vdso.so.dbg vdso.lds $(vobjs-y) vdso-syms.o 24targets += vdso.so vdso.so.dbg vdso.lds $(vobjs-y)
17
18# The DSO images are built using a special linker script.
19quiet_cmd_syscall = SYSCALL $@
20 cmd_syscall = $(CC) -m elf_x86_64 -nostdlib $(SYSCFLAGS_$(@F)) \
21 -Wl,-T,$(filter-out FORCE,$^) -o $@
22 25
23export CPPFLAGS_vdso.lds += -P -C 26export CPPFLAGS_vdso.lds += -P -C
24 27
25vdso-flags = -fPIC -shared -Wl,-soname=linux-vdso.so.1 \ 28VDSO_LDFLAGS_vdso.lds = -m elf_x86_64 -Wl,-soname=linux-vdso.so.1 \
26 $(call ld-option, -Wl$(comma)--hash-style=sysv) \ 29 -Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096
27 -Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096
28SYSCFLAGS_vdso.so = $(vdso-flags)
29SYSCFLAGS_vdso.so.dbg = $(vdso-flags)
30 30
31$(obj)/vdso.o: $(src)/vdso.S $(obj)/vdso.so 31$(obj)/vdso.o: $(src)/vdso.S $(obj)/vdso.so
32 32
33$(obj)/vdso.so: $(src)/vdso.lds $(vobjs) FORCE
34
35$(obj)/vdso.so.dbg: $(src)/vdso.lds $(vobjs) FORCE 33$(obj)/vdso.so.dbg: $(src)/vdso.lds $(vobjs) FORCE
36 $(call if_changed,syscall) 34 $(call if_changed,vdso)
37 35
38$(obj)/%.so: OBJCOPYFLAGS := -S 36$(obj)/%.so: OBJCOPYFLAGS := -S
39$(obj)/%.so: $(obj)/%.so.dbg FORCE 37$(obj)/%.so: $(obj)/%.so.dbg FORCE
@@ -41,24 +39,96 @@ $(obj)/%.so: $(obj)/%.so.dbg FORCE
41 39
42CFL := $(PROFILING) -mcmodel=small -fPIC -g0 -O2 -fasynchronous-unwind-tables -m64 40CFL := $(PROFILING) -mcmodel=small -fPIC -g0 -O2 -fasynchronous-unwind-tables -m64
43 41
44$(obj)/vclock_gettime.o: KBUILD_CFLAGS = $(CFL) 42$(vobjs): KBUILD_CFLAGS = $(CFL)
45$(obj)/vgetcpu.o: KBUILD_CFLAGS = $(CFL) 43
44targets += vdso-syms.lds
45obj-$(VDSO64-y) += vdso-syms.lds
46
47#
48# Match symbols in the DSO that look like VDSO*; produce a file of constants.
49#
50sed-vdsosym := -e 's/^00*/0/' \
51 -e 's/^\([0-9a-fA-F]*\) . \(VDSO[a-zA-Z0-9_]*\)$$/\2 = 0x\1;/p'
52quiet_cmd_vdsosym = VDSOSYM $@
53 cmd_vdsosym = $(NM) $< | sed -n $(sed-vdsosym) | LC_ALL=C sort > $@
54
55$(obj)/%-syms.lds: $(obj)/%.so.dbg FORCE
56 $(call if_changed,vdsosym)
57
58#
59# Build multiple 32-bit vDSO images to choose from at boot time.
60#
61obj-$(VDSO32-y) += vdso32-syms.lds
62vdso32.so-$(CONFIG_X86_32) += int80
63vdso32.so-$(CONFIG_COMPAT) += syscall
64vdso32.so-$(VDSO32-y) += sysenter
65
66CPPFLAGS_vdso32.lds = $(CPPFLAGS_vdso.lds)
67VDSO_LDFLAGS_vdso32.lds = -m elf_i386 -Wl,-soname=linux-gate.so.1
68
69# This makes sure the $(obj) subdirectory exists even though vdso32/
70# is not a kbuild sub-make subdirectory.
71override obj-dirs = $(dir $(obj)) $(obj)/vdso32/
46 72
47# We also create a special relocatable object that should mirror the symbol 73targets += vdso32/vdso32.lds
48# table and layout of the linked DSO. With ld -R we can then refer to 74targets += $(vdso32.so-y:%=vdso32-%.so.dbg) $(vdso32.so-y:%=vdso32-%.so)
49# these symbols in the kernel code rather than hand-coded addresses. 75targets += vdso32/note.o $(vdso32.so-y:%=vdso32/%.o)
50extra-y += vdso-syms.o
51$(obj)/built-in.o: $(obj)/vdso-syms.o
52$(obj)/built-in.o: ld_flags += -R $(obj)/vdso-syms.o
53 76
54SYSCFLAGS_vdso-syms.o = -r -d 77extra-y += $(vdso32.so-y:%=vdso32-%.so)
55$(obj)/vdso-syms.o: $(src)/vdso.lds $(vobjs) FORCE
56 $(call if_changed,syscall)
57 78
79$(obj)/vdso32.o: $(vdso32.so-y:%=$(obj)/vdso32-%.so)
80
81KBUILD_AFLAGS_32 := $(filter-out -m64,$(KBUILD_AFLAGS))
82$(vdso32.so-y:%=$(obj)/vdso32-%.so.dbg): KBUILD_AFLAGS = $(KBUILD_AFLAGS_32)
83$(vdso32.so-y:%=$(obj)/vdso32-%.so.dbg): asflags-$(CONFIG_X86_64) += -m32
84
85$(vdso32.so-y:%=$(obj)/vdso32-%.so.dbg): $(obj)/vdso32-%.so.dbg: FORCE \
86 $(obj)/vdso32/vdso32.lds \
87 $(obj)/vdso32/note.o \
88 $(obj)/vdso32/%.o
89 $(call if_changed,vdso)
90
91# Make vdso32-*-syms.lds from each image, and then make sure they match.
92# The only difference should be that some do not define VDSO32_SYSENTER_RETURN.
93
94targets += vdso32-syms.lds $(vdso32.so-y:%=vdso32-%-syms.lds)
95
96quiet_cmd_vdso32sym = VDSOSYM $@
97define cmd_vdso32sym
98 if LC_ALL=C sort -u $(filter-out FORCE,$^) > $(@D)/.tmp_$(@F) && \
99 $(foreach H,$(filter-out FORCE,$^),\
100 if grep -q VDSO32_SYSENTER_RETURN $H; \
101 then diff -u $(@D)/.tmp_$(@F) $H; \
102 else sed /VDSO32_SYSENTER_RETURN/d $(@D)/.tmp_$(@F) | \
103 diff -u - $H; fi &&) : ;\
104 then mv -f $(@D)/.tmp_$(@F) $@; \
105 else rm -f $(@D)/.tmp_$(@F); exit 1; \
106 fi
107endef
108
109$(obj)/vdso32-syms.lds: $(vdso32.so-y:%=$(obj)/vdso32-%-syms.lds) FORCE
110 $(call if_changed,vdso32sym)
111
112#
113# The DSO images are built using a special linker script.
114#
115quiet_cmd_vdso = VDSO $@
116 cmd_vdso = $(CC) -nostdlib -o $@ \
117 $(VDSO_LDFLAGS) $(VDSO_LDFLAGS_$(filter %.lds,$(^F))) \
118 -Wl,-T,$(filter %.lds,$^) $(filter %.o,$^)
119
120VDSO_LDFLAGS = -fPIC -shared $(call ld-option, -Wl$(comma)--hash-style=sysv)
121
122#
123# Install the unstripped copy of vdso*.so listed in $(vdso-install-y).
124#
58quiet_cmd_vdso_install = INSTALL $@ 125quiet_cmd_vdso_install = INSTALL $@
59 cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@ 126 cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@
60vdso.so: 127$(vdso-install-y): %.so: $(obj)/%.so.dbg FORCE
61 @mkdir -p $(MODLIB)/vdso 128 @mkdir -p $(MODLIB)/vdso
62 $(call cmd,vdso_install) 129 $(call cmd,vdso_install)
63 130
64vdso_install: vdso.so 131PHONY += vdso_install $(vdso-install-y)
132vdso_install: $(vdso-install-y)
133
134clean-files := vdso32-syscall* vdso32-sysenter* vdso32-int80*
diff --git a/arch/x86/vdso/vclock_gettime.c b/arch/x86/vdso/vclock_gettime.c
index 5b54cdfb2b07..23476c2ebfc4 100644
--- a/arch/x86/vdso/vclock_gettime.c
+++ b/arch/x86/vdso/vclock_gettime.c
@@ -19,7 +19,6 @@
19#include <asm/hpet.h> 19#include <asm/hpet.h>
20#include <asm/unistd.h> 20#include <asm/unistd.h>
21#include <asm/io.h> 21#include <asm/io.h>
22#include <asm/vgtod.h>
23#include "vextern.h" 22#include "vextern.h"
24 23
25#define gtod vdso_vsyscall_gtod_data 24#define gtod vdso_vsyscall_gtod_data
diff --git a/arch/x86/vdso/vdso-layout.lds.S b/arch/x86/vdso/vdso-layout.lds.S
new file mode 100644
index 000000000000..634a2cf62046
--- /dev/null
+++ b/arch/x86/vdso/vdso-layout.lds.S
@@ -0,0 +1,64 @@
1/*
2 * Linker script for vDSO. This is an ELF shared object prelinked to
3 * its virtual address, and with only one read-only segment.
4 * This script controls its layout.
5 */
6
7SECTIONS
8{
9 . = VDSO_PRELINK + SIZEOF_HEADERS;
10
11 .hash : { *(.hash) } :text
12 .gnu.hash : { *(.gnu.hash) }
13 .dynsym : { *(.dynsym) }
14 .dynstr : { *(.dynstr) }
15 .gnu.version : { *(.gnu.version) }
16 .gnu.version_d : { *(.gnu.version_d) }
17 .gnu.version_r : { *(.gnu.version_r) }
18
19 .note : { *(.note.*) } :text :note
20
21 .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
22 .eh_frame : { KEEP (*(.eh_frame)) } :text
23
24 .dynamic : { *(.dynamic) } :text :dynamic
25
26 .rodata : { *(.rodata*) } :text
27 .data : {
28 *(.data*)
29 *(.sdata*)
30 *(.got.plt) *(.got)
31 *(.gnu.linkonce.d.*)
32 *(.bss*)
33 *(.dynbss*)
34 *(.gnu.linkonce.b.*)
35 }
36
37 .altinstructions : { *(.altinstructions) }
38 .altinstr_replacement : { *(.altinstr_replacement) }
39
40 /*
41 * Align the actual code well away from the non-instruction data.
42 * This is the best thing for the I-cache.
43 */
44 . = ALIGN(0x100);
45
46 .text : { *(.text*) } :text =0x90909090
47}
48
49/*
50 * Very old versions of ld do not recognize this name token; use the constant.
51 */
52#define PT_GNU_EH_FRAME 0x6474e550
53
54/*
55 * We must supply the ELF program headers explicitly to get just one
56 * PT_LOAD segment, and set the flags explicitly to make segments read-only.
57 */
58PHDRS
59{
60 text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */
61 dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
62 note PT_NOTE FLAGS(4); /* PF_R */
63 eh_frame_hdr PT_GNU_EH_FRAME;
64}
diff --git a/arch/x86/vdso/vdso-start.S b/arch/x86/vdso/vdso-start.S
deleted file mode 100644
index 2dc2cdb84d67..000000000000
--- a/arch/x86/vdso/vdso-start.S
+++ /dev/null
@@ -1,2 +0,0 @@
1 .globl vdso_kernel_start
2vdso_kernel_start:
diff --git a/arch/x86/vdso/vdso.lds.S b/arch/x86/vdso/vdso.lds.S
index 667d3245d972..4e5dd3b4de7f 100644
--- a/arch/x86/vdso/vdso.lds.S
+++ b/arch/x86/vdso/vdso.lds.S
@@ -1,79 +1,37 @@
1/* 1/*
2 * Linker script for vsyscall DSO. The vsyscall page is an ELF shared 2 * Linker script for 64-bit vDSO.
3 * object prelinked to its virtual address, and with only one read-only 3 * We #include the file to define the layout details.
4 * segment (that fits in one page). This script controls its layout. 4 * Here we only choose the prelinked virtual address.
5 *
6 * This file defines the version script giving the user-exported symbols in
7 * the DSO. We can define local symbols here called VDSO* to make their
8 * values visible using the asm-x86/vdso.h macros from the kernel proper.
5 */ 9 */
6#include <asm/asm-offsets.h>
7#include "voffset.h"
8 10
9#define VDSO_PRELINK 0xffffffffff700000 11#define VDSO_PRELINK 0xffffffffff700000
10 12#include "vdso-layout.lds.S"
11SECTIONS
12{
13 . = VDSO_PRELINK + SIZEOF_HEADERS;
14
15 .hash : { *(.hash) } :text
16 .gnu.hash : { *(.gnu.hash) }
17 .dynsym : { *(.dynsym) }
18 .dynstr : { *(.dynstr) }
19 .gnu.version : { *(.gnu.version) }
20 .gnu.version_d : { *(.gnu.version_d) }
21 .gnu.version_r : { *(.gnu.version_r) }
22
23 /* This linker script is used both with -r and with -shared.
24 For the layouts to match, we need to skip more than enough
25 space for the dynamic symbol table et al. If this amount
26 is insufficient, ld -shared will barf. Just increase it here. */
27 . = VDSO_PRELINK + VDSO_TEXT_OFFSET;
28
29 .text : { *(.text*) } :text
30 .rodata : { *(.rodata*) } :text
31 .data : {
32 *(.data*)
33 *(.sdata*)
34 *(.bss*)
35 *(.dynbss*)
36 } :text
37
38 .altinstructions : { *(.altinstructions) } :text
39 .altinstr_replacement : { *(.altinstr_replacement) } :text
40
41 .note : { *(.note.*) } :text :note
42 .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
43 .eh_frame : { KEEP (*(.eh_frame)) } :text
44 .dynamic : { *(.dynamic) } :text :dynamic
45 .useless : {
46 *(.got.plt) *(.got)
47 *(.gnu.linkonce.d.*)
48 *(.gnu.linkonce.b.*)
49 } :text
50}
51 13
52/* 14/*
53 * We must supply the ELF program headers explicitly to get just one 15 * This controls what userland symbols we export from the vDSO.
54 * PT_LOAD segment, and set the flags explicitly to make segments read-only.
55 */ 16 */
56PHDRS 17VERSION {
57{ 18 LINUX_2.6 {
58 text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */ 19 global:
59 dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ 20 clock_gettime;
60 note PT_NOTE FLAGS(4); /* PF_R */ 21 __vdso_clock_gettime;
61 eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */ 22 gettimeofday;
23 __vdso_gettimeofday;
24 getcpu;
25 __vdso_getcpu;
26 local: *;
27 };
62} 28}
63 29
30VDSO64_PRELINK = VDSO_PRELINK;
31
64/* 32/*
65 * This controls what symbols we export from the DSO. 33 * Define VDSO64_x for each VEXTERN(x), for use via VDSO64_SYMBOL.
66 */ 34 */
67VERSION 35#define VEXTERN(x) VDSO64_ ## x = vdso_ ## x;
68{ 36#include "vextern.h"
69 LINUX_2.6 { 37#undef VEXTERN
70 global:
71 clock_gettime;
72 __vdso_clock_gettime;
73 gettimeofday;
74 __vdso_gettimeofday;
75 getcpu;
76 __vdso_getcpu;
77 local: *;
78 };
79}
diff --git a/arch/x86/kernel/sysenter_32.c b/arch/x86/vdso/vdso32-setup.c
index 5a2d951e2608..348f1341e1c8 100644
--- a/arch/x86/kernel/sysenter_32.c
+++ b/arch/x86/vdso/vdso32-setup.c
@@ -23,6 +23,8 @@
23#include <asm/unistd.h> 23#include <asm/unistd.h>
24#include <asm/elf.h> 24#include <asm/elf.h>
25#include <asm/tlbflush.h> 25#include <asm/tlbflush.h>
26#include <asm/vdso.h>
27#include <asm/proto.h>
26 28
27enum { 29enum {
28 VDSO_DISABLED = 0, 30 VDSO_DISABLED = 0,
@@ -36,14 +38,24 @@ enum {
36#define VDSO_DEFAULT VDSO_ENABLED 38#define VDSO_DEFAULT VDSO_ENABLED
37#endif 39#endif
38 40
41#ifdef CONFIG_X86_64
42#define vdso_enabled sysctl_vsyscall32
43#define arch_setup_additional_pages syscall32_setup_pages
44#endif
45
46/*
47 * This is the difference between the prelinked addresses in the vDSO images
48 * and the VDSO_HIGH_BASE address where CONFIG_COMPAT_VDSO places the vDSO
49 * in the user address space.
50 */
51#define VDSO_ADDR_ADJUST (VDSO_HIGH_BASE - (unsigned long)VDSO32_PRELINK)
52
39/* 53/*
40 * Should the kernel map a VDSO page into processes and pass its 54 * Should the kernel map a VDSO page into processes and pass its
41 * address down to glibc upon exec()? 55 * address down to glibc upon exec()?
42 */ 56 */
43unsigned int __read_mostly vdso_enabled = VDSO_DEFAULT; 57unsigned int __read_mostly vdso_enabled = VDSO_DEFAULT;
44 58
45EXPORT_SYMBOL_GPL(vdso_enabled);
46
47static int __init vdso_setup(char *s) 59static int __init vdso_setup(char *s)
48{ 60{
49 vdso_enabled = simple_strtoul(s, NULL, 0); 61 vdso_enabled = simple_strtoul(s, NULL, 0);
@@ -51,9 +63,18 @@ static int __init vdso_setup(char *s)
51 return 1; 63 return 1;
52} 64}
53 65
54__setup("vdso=", vdso_setup); 66/*
67 * For consistency, the argument vdso32=[012] affects the 32-bit vDSO
68 * behavior on both 64-bit and 32-bit kernels.
69 * On 32-bit kernels, vdso=[012] means the same thing.
70 */
71__setup("vdso32=", vdso_setup);
72
73#ifdef CONFIG_X86_32
74__setup_param("vdso=", vdso32_setup, vdso_setup, 0);
55 75
56extern asmlinkage void sysenter_entry(void); 76EXPORT_SYMBOL_GPL(vdso_enabled);
77#endif
57 78
58static __init void reloc_symtab(Elf32_Ehdr *ehdr, 79static __init void reloc_symtab(Elf32_Ehdr *ehdr,
59 unsigned offset, unsigned size) 80 unsigned offset, unsigned size)
@@ -78,7 +99,7 @@ static __init void reloc_symtab(Elf32_Ehdr *ehdr,
78 case STT_FUNC: 99 case STT_FUNC:
79 case STT_SECTION: 100 case STT_SECTION:
80 case STT_FILE: 101 case STT_FILE:
81 sym->st_value += VDSO_HIGH_BASE; 102 sym->st_value += VDSO_ADDR_ADJUST;
82 } 103 }
83 } 104 }
84} 105}
@@ -104,7 +125,7 @@ static __init void reloc_dyn(Elf32_Ehdr *ehdr, unsigned offset)
104 case DT_VERNEED: 125 case DT_VERNEED:
105 case DT_ADDRRNGLO ... DT_ADDRRNGHI: 126 case DT_ADDRRNGLO ... DT_ADDRRNGHI:
106 /* definitely pointers needing relocation */ 127 /* definitely pointers needing relocation */
107 dyn->d_un.d_ptr += VDSO_HIGH_BASE; 128 dyn->d_un.d_ptr += VDSO_ADDR_ADJUST;
108 break; 129 break;
109 130
110 case DT_ENCODING ... OLD_DT_LOOS-1: 131 case DT_ENCODING ... OLD_DT_LOOS-1:
@@ -113,7 +134,7 @@ static __init void reloc_dyn(Elf32_Ehdr *ehdr, unsigned offset)
113 they're even */ 134 they're even */
114 if (dyn->d_tag >= DT_ENCODING && 135 if (dyn->d_tag >= DT_ENCODING &&
115 (dyn->d_tag & 1) == 0) 136 (dyn->d_tag & 1) == 0)
116 dyn->d_un.d_ptr += VDSO_HIGH_BASE; 137 dyn->d_un.d_ptr += VDSO_ADDR_ADJUST;
117 break; 138 break;
118 139
119 case DT_VERDEFNUM: 140 case DT_VERDEFNUM:
@@ -142,15 +163,15 @@ static __init void relocate_vdso(Elf32_Ehdr *ehdr)
142 int i; 163 int i;
143 164
144 BUG_ON(memcmp(ehdr->e_ident, ELFMAG, 4) != 0 || 165 BUG_ON(memcmp(ehdr->e_ident, ELFMAG, 4) != 0 ||
145 !elf_check_arch(ehdr) || 166 !elf_check_arch_ia32(ehdr) ||
146 ehdr->e_type != ET_DYN); 167 ehdr->e_type != ET_DYN);
147 168
148 ehdr->e_entry += VDSO_HIGH_BASE; 169 ehdr->e_entry += VDSO_ADDR_ADJUST;
149 170
150 /* rebase phdrs */ 171 /* rebase phdrs */
151 phdr = (void *)ehdr + ehdr->e_phoff; 172 phdr = (void *)ehdr + ehdr->e_phoff;
152 for (i = 0; i < ehdr->e_phnum; i++) { 173 for (i = 0; i < ehdr->e_phnum; i++) {
153 phdr[i].p_vaddr += VDSO_HIGH_BASE; 174 phdr[i].p_vaddr += VDSO_ADDR_ADJUST;
154 175
155 /* relocate dynamic stuff */ 176 /* relocate dynamic stuff */
156 if (phdr[i].p_type == PT_DYNAMIC) 177 if (phdr[i].p_type == PT_DYNAMIC)
@@ -163,7 +184,7 @@ static __init void relocate_vdso(Elf32_Ehdr *ehdr)
163 if (!(shdr[i].sh_flags & SHF_ALLOC)) 184 if (!(shdr[i].sh_flags & SHF_ALLOC))
164 continue; 185 continue;
165 186
166 shdr[i].sh_addr += VDSO_HIGH_BASE; 187 shdr[i].sh_addr += VDSO_ADDR_ADJUST;
167 188
168 if (shdr[i].sh_type == SHT_SYMTAB || 189 if (shdr[i].sh_type == SHT_SYMTAB ||
169 shdr[i].sh_type == SHT_DYNSYM) 190 shdr[i].sh_type == SHT_DYNSYM)
@@ -172,6 +193,45 @@ static __init void relocate_vdso(Elf32_Ehdr *ehdr)
172 } 193 }
173} 194}
174 195
196/*
197 * These symbols are defined by vdso32.S to mark the bounds
198 * of the ELF DSO images included therein.
199 */
200extern const char vdso32_default_start, vdso32_default_end;
201extern const char vdso32_sysenter_start, vdso32_sysenter_end;
202static struct page *vdso32_pages[1];
203
204#ifdef CONFIG_X86_64
205
206static int use_sysenter __read_mostly = -1;
207
208#define vdso32_sysenter() (use_sysenter > 0)
209
210/* May not be __init: called during resume */
211void syscall32_cpu_init(void)
212{
213 if (use_sysenter < 0)
214 use_sysenter = (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL);
215
216 /* Load these always in case some future AMD CPU supports
217 SYSENTER from compat mode too. */
218 checking_wrmsrl(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS);
219 checking_wrmsrl(MSR_IA32_SYSENTER_ESP, 0ULL);
220 checking_wrmsrl(MSR_IA32_SYSENTER_EIP, (u64)ia32_sysenter_target);
221
222 wrmsrl(MSR_CSTAR, ia32_cstar_target);
223}
224
225#define compat_uses_vma 1
226
227static inline void map_compat_vdso(int map)
228{
229}
230
231#else /* CONFIG_X86_32 */
232
233#define vdso32_sysenter() (boot_cpu_has(X86_FEATURE_SEP))
234
175void enable_sep_cpu(void) 235void enable_sep_cpu(void)
176{ 236{
177 int cpu = get_cpu(); 237 int cpu = get_cpu();
@@ -183,10 +243,10 @@ void enable_sep_cpu(void)
183 } 243 }
184 244
185 tss->x86_tss.ss1 = __KERNEL_CS; 245 tss->x86_tss.ss1 = __KERNEL_CS;
186 tss->x86_tss.esp1 = sizeof(struct tss_struct) + (unsigned long) tss; 246 tss->x86_tss.sp1 = sizeof(struct tss_struct) + (unsigned long) tss;
187 wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0); 247 wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);
188 wrmsr(MSR_IA32_SYSENTER_ESP, tss->x86_tss.esp1, 0); 248 wrmsr(MSR_IA32_SYSENTER_ESP, tss->x86_tss.sp1, 0);
189 wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long) sysenter_entry, 0); 249 wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long) ia32_sysenter_target, 0);
190 put_cpu(); 250 put_cpu();
191} 251}
192 252
@@ -209,13 +269,7 @@ static int __init gate_vma_init(void)
209 return 0; 269 return 0;
210} 270}
211 271
212/* 272#define compat_uses_vma 0
213 * These symbols are defined by vsyscall.o to mark the bounds
214 * of the ELF DSO images included therein.
215 */
216extern const char vsyscall_int80_start, vsyscall_int80_end;
217extern const char vsyscall_sysenter_start, vsyscall_sysenter_end;
218static struct page *syscall_pages[1];
219 273
220static void map_compat_vdso(int map) 274static void map_compat_vdso(int map)
221{ 275{
@@ -226,31 +280,35 @@ static void map_compat_vdso(int map)
226 280
227 vdso_mapped = map; 281 vdso_mapped = map;
228 282
229 __set_fixmap(FIX_VDSO, page_to_pfn(syscall_pages[0]) << PAGE_SHIFT, 283 __set_fixmap(FIX_VDSO, page_to_pfn(vdso32_pages[0]) << PAGE_SHIFT,
230 map ? PAGE_READONLY_EXEC : PAGE_NONE); 284 map ? PAGE_READONLY_EXEC : PAGE_NONE);
231 285
232 /* flush stray tlbs */ 286 /* flush stray tlbs */
233 flush_tlb_all(); 287 flush_tlb_all();
234} 288}
235 289
290#endif /* CONFIG_X86_64 */
291
236int __init sysenter_setup(void) 292int __init sysenter_setup(void)
237{ 293{
238 void *syscall_page = (void *)get_zeroed_page(GFP_ATOMIC); 294 void *syscall_page = (void *)get_zeroed_page(GFP_ATOMIC);
239 const void *vsyscall; 295 const void *vsyscall;
240 size_t vsyscall_len; 296 size_t vsyscall_len;
241 297
242 syscall_pages[0] = virt_to_page(syscall_page); 298 vdso32_pages[0] = virt_to_page(syscall_page);
243 299
300#ifdef CONFIG_X86_32
244 gate_vma_init(); 301 gate_vma_init();
245 302
246 printk("Compat vDSO mapped to %08lx.\n", __fix_to_virt(FIX_VDSO)); 303 printk("Compat vDSO mapped to %08lx.\n", __fix_to_virt(FIX_VDSO));
304#endif
247 305
248 if (!boot_cpu_has(X86_FEATURE_SEP)) { 306 if (!vdso32_sysenter()) {
249 vsyscall = &vsyscall_int80_start; 307 vsyscall = &vdso32_default_start;
250 vsyscall_len = &vsyscall_int80_end - &vsyscall_int80_start; 308 vsyscall_len = &vdso32_default_end - &vdso32_default_start;
251 } else { 309 } else {
252 vsyscall = &vsyscall_sysenter_start; 310 vsyscall = &vdso32_sysenter_start;
253 vsyscall_len = &vsyscall_sysenter_end - &vsyscall_sysenter_start; 311 vsyscall_len = &vdso32_sysenter_end - &vdso32_sysenter_start;
254 } 312 }
255 313
256 memcpy(syscall_page, vsyscall, vsyscall_len); 314 memcpy(syscall_page, vsyscall, vsyscall_len);
@@ -259,9 +317,6 @@ int __init sysenter_setup(void)
259 return 0; 317 return 0;
260} 318}
261 319
262/* Defined in vsyscall-sysenter.S */
263extern void SYSENTER_RETURN;
264
265/* Setup a VMA at program startup for the vsyscall page */ 320/* Setup a VMA at program startup for the vsyscall page */
266int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack) 321int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack)
267{ 322{
@@ -286,7 +341,9 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack)
286 ret = addr; 341 ret = addr;
287 goto up_fail; 342 goto up_fail;
288 } 343 }
344 }
289 345
346 if (compat_uses_vma || !compat) {
290 /* 347 /*
291 * MAYWRITE to allow gdb to COW and set breakpoints 348 * MAYWRITE to allow gdb to COW and set breakpoints
292 * 349 *
@@ -300,7 +357,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack)
300 VM_READ|VM_EXEC| 357 VM_READ|VM_EXEC|
301 VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC| 358 VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
302 VM_ALWAYSDUMP, 359 VM_ALWAYSDUMP,
303 syscall_pages); 360 vdso32_pages);
304 361
305 if (ret) 362 if (ret)
306 goto up_fail; 363 goto up_fail;
@@ -308,7 +365,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack)
308 365
309 current->mm->context.vdso = (void *)addr; 366 current->mm->context.vdso = (void *)addr;
310 current_thread_info()->sysenter_return = 367 current_thread_info()->sysenter_return =
311 (void *)VDSO_SYM(&SYSENTER_RETURN); 368 VDSO32_SYMBOL(addr, SYSENTER_RETURN);
312 369
313 up_fail: 370 up_fail:
314 up_write(&mm->mmap_sem); 371 up_write(&mm->mmap_sem);
@@ -316,6 +373,45 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack)
316 return ret; 373 return ret;
317} 374}
318 375
376#ifdef CONFIG_X86_64
377
378__initcall(sysenter_setup);
379
380#ifdef CONFIG_SYSCTL
381/* Register vsyscall32 into the ABI table */
382#include <linux/sysctl.h>
383
384static ctl_table abi_table2[] = {
385 {
386 .procname = "vsyscall32",
387 .data = &sysctl_vsyscall32,
388 .maxlen = sizeof(int),
389 .mode = 0644,
390 .proc_handler = proc_dointvec
391 },
392 {}
393};
394
395static ctl_table abi_root_table2[] = {
396 {
397 .ctl_name = CTL_ABI,
398 .procname = "abi",
399 .mode = 0555,
400 .child = abi_table2
401 },
402 {}
403};
404
405static __init int ia32_binfmt_init(void)
406{
407 register_sysctl_table(abi_root_table2);
408 return 0;
409}
410__initcall(ia32_binfmt_init);
411#endif
412
413#else /* CONFIG_X86_32 */
414
319const char *arch_vma_name(struct vm_area_struct *vma) 415const char *arch_vma_name(struct vm_area_struct *vma)
320{ 416{
321 if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) 417 if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
@@ -344,3 +440,5 @@ int in_gate_area_no_task(unsigned long addr)
344{ 440{
345 return 0; 441 return 0;
346} 442}
443
444#endif /* CONFIG_X86_64 */
diff --git a/arch/x86/vdso/vdso32.S b/arch/x86/vdso/vdso32.S
new file mode 100644
index 000000000000..1e36f72cab86
--- /dev/null
+++ b/arch/x86/vdso/vdso32.S
@@ -0,0 +1,19 @@
1#include <linux/init.h>
2
3__INITDATA
4
5 .globl vdso32_default_start, vdso32_default_end
6vdso32_default_start:
7#ifdef CONFIG_X86_32
8 .incbin "arch/x86/vdso/vdso32-int80.so"
9#else
10 .incbin "arch/x86/vdso/vdso32-syscall.so"
11#endif
12vdso32_default_end:
13
14 .globl vdso32_sysenter_start, vdso32_sysenter_end
15vdso32_sysenter_start:
16 .incbin "arch/x86/vdso/vdso32-sysenter.so"
17vdso32_sysenter_end:
18
19__FINIT
diff --git a/arch/x86/vdso/vdso32/.gitignore b/arch/x86/vdso/vdso32/.gitignore
new file mode 100644
index 000000000000..e45fba9d0ced
--- /dev/null
+++ b/arch/x86/vdso/vdso32/.gitignore
@@ -0,0 +1 @@
vdso32.lds
diff --git a/arch/x86/kernel/vsyscall-int80_32.S b/arch/x86/vdso/vdso32/int80.S
index 103cab6aa7c0..b15b7c01aedb 100644
--- a/arch/x86/kernel/vsyscall-int80_32.S
+++ b/arch/x86/vdso/vdso32/int80.S
@@ -1,15 +1,15 @@
1/* 1/*
2 * Code for the vsyscall page. This version uses the old int $0x80 method. 2 * Code for the vDSO. This version uses the old int $0x80 method.
3 * 3 *
4 * NOTE: 4 * First get the common code for the sigreturn entry points.
5 * 1) __kernel_vsyscall _must_ be first in this page. 5 * This must come first.
6 * 2) there are alignment constraints on this stub, see vsyscall-sigreturn.S
7 * for details.
8 */ 6 */
7#include "sigreturn.S"
9 8
10 .text 9 .text
11 .globl __kernel_vsyscall 10 .globl __kernel_vsyscall
12 .type __kernel_vsyscall,@function 11 .type __kernel_vsyscall,@function
12 ALIGN
13__kernel_vsyscall: 13__kernel_vsyscall:
14.LSTART_vsyscall: 14.LSTART_vsyscall:
15 int $0x80 15 int $0x80
@@ -47,7 +47,10 @@ __kernel_vsyscall:
47.LENDFDEDLSI: 47.LENDFDEDLSI:
48 .previous 48 .previous
49 49
50/* 50 /*
51 * Get the common code for the sigreturn entry points. 51 * Pad out the segment to match the size of the sysenter.S version.
52 */ 52 */
53#include "vsyscall-sigreturn_32.S" 53VDSO32_vsyscall_eh_frame_size = 0x40
54 .section .data,"aw",@progbits
55 .space VDSO32_vsyscall_eh_frame_size-(.LENDFDEDLSI-.LSTARTFRAMEDLSI), 0
56 .previous
diff --git a/arch/x86/kernel/vsyscall-note_32.S b/arch/x86/vdso/vdso32/note.S
index fcf376a37f79..c83f25734696 100644
--- a/arch/x86/kernel/vsyscall-note_32.S
+++ b/arch/x86/vdso/vdso32/note.S
@@ -33,12 +33,11 @@ ELFNOTE_END
33 * at boot time we set VDSO_NOTE_NONEGSEG_BIT if running under Xen. 33 * at boot time we set VDSO_NOTE_NONEGSEG_BIT if running under Xen.
34 */ 34 */
35 35
36#include "../../x86/xen/vdso.h" /* Defines VDSO_NOTE_NONEGSEG_BIT. */ 36#include "../../xen/vdso.h" /* Defines VDSO_NOTE_NONEGSEG_BIT. */
37 37
38 .globl VDSO_NOTE_MASK
39ELFNOTE_START(GNU, 2, "a") 38ELFNOTE_START(GNU, 2, "a")
40 .long 1 /* ncaps */ 39 .long 1 /* ncaps */
41VDSO_NOTE_MASK: 40VDSO32_NOTE_MASK: /* Symbol used by arch/x86/xen/setup.c */
42 .long 0 /* mask */ 41 .long 0 /* mask */
43 .byte VDSO_NOTE_NONEGSEG_BIT; .asciz "nosegneg" /* bit, name */ 42 .byte VDSO_NOTE_NONEGSEG_BIT; .asciz "nosegneg" /* bit, name */
44ELFNOTE_END 43ELFNOTE_END
diff --git a/arch/x86/kernel/vsyscall-sigreturn_32.S b/arch/x86/vdso/vdso32/sigreturn.S
index a92262f41659..31776d0efc8c 100644
--- a/arch/x86/kernel/vsyscall-sigreturn_32.S
+++ b/arch/x86/vdso/vdso32/sigreturn.S
@@ -1,41 +1,42 @@
1/* 1/*
2 * Common code for the sigreturn entry points on the vsyscall page. 2 * Common code for the sigreturn entry points in vDSO images.
3 * So far this code is the same for both int80 and sysenter versions. 3 * So far this code is the same for both int80 and sysenter versions.
4 * This file is #include'd by vsyscall-*.S to define them after the 4 * This file is #include'd by int80.S et al to define them first thing.
5 * vsyscall entry point. The kernel assumes that the addresses of these 5 * The kernel assumes that the addresses of these routines are constant
6 * routines are constant for all vsyscall implementations. 6 * for all vDSO implementations.
7 */ 7 */
8 8
9#include <asm/unistd.h> 9#include <linux/linkage.h>
10#include <asm/unistd_32.h>
10#include <asm/asm-offsets.h> 11#include <asm/asm-offsets.h>
11 12
12 13#ifndef SYSCALL_ENTER_KERNEL
13/* XXX 14#define SYSCALL_ENTER_KERNEL int $0x80
14 Should these be named "_sigtramp" or something? 15#endif
15*/
16 16
17 .text 17 .text
18 .org __kernel_vsyscall+32,0x90
19 .globl __kernel_sigreturn 18 .globl __kernel_sigreturn
20 .type __kernel_sigreturn,@function 19 .type __kernel_sigreturn,@function
20 ALIGN
21__kernel_sigreturn: 21__kernel_sigreturn:
22.LSTART_sigreturn: 22.LSTART_sigreturn:
23 popl %eax /* XXX does this mean it needs unwind info? */ 23 popl %eax /* XXX does this mean it needs unwind info? */
24 movl $__NR_sigreturn, %eax 24 movl $__NR_sigreturn, %eax
25 int $0x80 25 SYSCALL_ENTER_KERNEL
26.LEND_sigreturn: 26.LEND_sigreturn:
27 nop
27 .size __kernel_sigreturn,.-.LSTART_sigreturn 28 .size __kernel_sigreturn,.-.LSTART_sigreturn
28 29
29 .balign 32
30 .globl __kernel_rt_sigreturn 30 .globl __kernel_rt_sigreturn
31 .type __kernel_rt_sigreturn,@function 31 .type __kernel_rt_sigreturn,@function
32 ALIGN
32__kernel_rt_sigreturn: 33__kernel_rt_sigreturn:
33.LSTART_rt_sigreturn: 34.LSTART_rt_sigreturn:
34 movl $__NR_rt_sigreturn, %eax 35 movl $__NR_rt_sigreturn, %eax
35 int $0x80 36 SYSCALL_ENTER_KERNEL
36.LEND_rt_sigreturn: 37.LEND_rt_sigreturn:
38 nop
37 .size __kernel_rt_sigreturn,.-.LSTART_rt_sigreturn 39 .size __kernel_rt_sigreturn,.-.LSTART_rt_sigreturn
38 .balign 32
39 .previous 40 .previous
40 41
41 .section .eh_frame,"a",@progbits 42 .section .eh_frame,"a",@progbits
@@ -70,9 +71,9 @@ __kernel_rt_sigreturn:
70 be the value of the stack pointer in the caller. This means 71 be the value of the stack pointer in the caller. This means
71 that we must define the CFA of this body of code to be the 72 that we must define the CFA of this body of code to be the
72 saved value of the stack pointer in the sigcontext. Which 73 saved value of the stack pointer in the sigcontext. Which
73 also means that there is no fixed relation to the other 74 also means that there is no fixed relation to the other
74 saved registers, which means that we must use DW_CFA_expression 75 saved registers, which means that we must use DW_CFA_expression
75 to compute their addresses. It also means that when we 76 to compute their addresses. It also means that when we
76 adjust the stack with the popl, we have to do it all over again. */ 77 adjust the stack with the popl, we have to do it all over again. */
77 78
78#define do_cfa_expr(offset) \ 79#define do_cfa_expr(offset) \
@@ -91,27 +92,27 @@ __kernel_rt_sigreturn:
91 .sleb128 offset; /* offset */ \ 92 .sleb128 offset; /* offset */ \
921: 931:
93 94
94 do_cfa_expr(SIGCONTEXT_esp+4) 95 do_cfa_expr(IA32_SIGCONTEXT_sp+4)
95 do_expr(0, SIGCONTEXT_eax+4) 96 do_expr(0, IA32_SIGCONTEXT_ax+4)
96 do_expr(1, SIGCONTEXT_ecx+4) 97 do_expr(1, IA32_SIGCONTEXT_cx+4)
97 do_expr(2, SIGCONTEXT_edx+4) 98 do_expr(2, IA32_SIGCONTEXT_dx+4)
98 do_expr(3, SIGCONTEXT_ebx+4) 99 do_expr(3, IA32_SIGCONTEXT_bx+4)
99 do_expr(5, SIGCONTEXT_ebp+4) 100 do_expr(5, IA32_SIGCONTEXT_bp+4)
100 do_expr(6, SIGCONTEXT_esi+4) 101 do_expr(6, IA32_SIGCONTEXT_si+4)
101 do_expr(7, SIGCONTEXT_edi+4) 102 do_expr(7, IA32_SIGCONTEXT_di+4)
102 do_expr(8, SIGCONTEXT_eip+4) 103 do_expr(8, IA32_SIGCONTEXT_ip+4)
103 104
104 .byte 0x42 /* DW_CFA_advance_loc 2 -- nop; popl eax. */ 105 .byte 0x42 /* DW_CFA_advance_loc 2 -- nop; popl eax. */
105 106
106 do_cfa_expr(SIGCONTEXT_esp) 107 do_cfa_expr(IA32_SIGCONTEXT_sp)
107 do_expr(0, SIGCONTEXT_eax) 108 do_expr(0, IA32_SIGCONTEXT_ax)
108 do_expr(1, SIGCONTEXT_ecx) 109 do_expr(1, IA32_SIGCONTEXT_cx)
109 do_expr(2, SIGCONTEXT_edx) 110 do_expr(2, IA32_SIGCONTEXT_dx)
110 do_expr(3, SIGCONTEXT_ebx) 111 do_expr(3, IA32_SIGCONTEXT_bx)
111 do_expr(5, SIGCONTEXT_ebp) 112 do_expr(5, IA32_SIGCONTEXT_bp)
112 do_expr(6, SIGCONTEXT_esi) 113 do_expr(6, IA32_SIGCONTEXT_si)
113 do_expr(7, SIGCONTEXT_edi) 114 do_expr(7, IA32_SIGCONTEXT_di)
114 do_expr(8, SIGCONTEXT_eip) 115 do_expr(8, IA32_SIGCONTEXT_ip)
115 116
116 .align 4 117 .align 4
117.LENDFDEDLSI1: 118.LENDFDEDLSI1:
@@ -128,15 +129,15 @@ __kernel_rt_sigreturn:
128 slightly less complicated than the above, since we don't 129 slightly less complicated than the above, since we don't
129 modify the stack pointer in the process. */ 130 modify the stack pointer in the process. */
130 131
131 do_cfa_expr(RT_SIGFRAME_sigcontext-4 + SIGCONTEXT_esp) 132 do_cfa_expr(IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_sp)
132 do_expr(0, RT_SIGFRAME_sigcontext-4 + SIGCONTEXT_eax) 133 do_expr(0, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ax)
133 do_expr(1, RT_SIGFRAME_sigcontext-4 + SIGCONTEXT_ecx) 134 do_expr(1, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_cx)
134 do_expr(2, RT_SIGFRAME_sigcontext-4 + SIGCONTEXT_edx) 135 do_expr(2, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_dx)
135 do_expr(3, RT_SIGFRAME_sigcontext-4 + SIGCONTEXT_ebx) 136 do_expr(3, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_bx)
136 do_expr(5, RT_SIGFRAME_sigcontext-4 + SIGCONTEXT_ebp) 137 do_expr(5, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_bp)
137 do_expr(6, RT_SIGFRAME_sigcontext-4 + SIGCONTEXT_esi) 138 do_expr(6, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_si)
138 do_expr(7, RT_SIGFRAME_sigcontext-4 + SIGCONTEXT_edi) 139 do_expr(7, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_di)
139 do_expr(8, RT_SIGFRAME_sigcontext-4 + SIGCONTEXT_eip) 140 do_expr(8, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ip)
140 141
141 .align 4 142 .align 4
142.LENDFDEDLSI2: 143.LENDFDEDLSI2:
diff --git a/arch/x86/ia32/vsyscall-syscall.S b/arch/x86/vdso/vdso32/syscall.S
index cf9ef678de3e..5415b5613d55 100644
--- a/arch/x86/ia32/vsyscall-syscall.S
+++ b/arch/x86/vdso/vdso32/syscall.S
@@ -1,16 +1,18 @@
1/* 1/*
2 * Code for the vsyscall page. This version uses the syscall instruction. 2 * Code for the vDSO. This version uses the syscall instruction.
3 *
4 * First get the common code for the sigreturn entry points.
5 * This must come first.
3 */ 6 */
7#define SYSCALL_ENTER_KERNEL syscall
8#include "sigreturn.S"
4 9
5#include <asm/ia32_unistd.h>
6#include <asm/asm-offsets.h>
7#include <asm/segment.h> 10#include <asm/segment.h>
8 11
9 .code32
10 .text 12 .text
11 .section .text.vsyscall,"ax"
12 .globl __kernel_vsyscall 13 .globl __kernel_vsyscall
13 .type __kernel_vsyscall,@function 14 .type __kernel_vsyscall,@function
15 ALIGN
14__kernel_vsyscall: 16__kernel_vsyscall:
15.LSTART_vsyscall: 17.LSTART_vsyscall:
16 push %ebp 18 push %ebp
@@ -64,6 +66,12 @@ __kernel_vsyscall:
64 .uleb128 4 66 .uleb128 4
65 .align 4 67 .align 4
66.LENDFDE1: 68.LENDFDE1:
69 .previous
67 70
68#define SYSCALL_ENTER_KERNEL syscall 71 /*
69#include "vsyscall-sigreturn.S" 72 * Pad out the segment to match the size of the sysenter.S version.
73 */
74VDSO32_vsyscall_eh_frame_size = 0x40
75 .section .data,"aw",@progbits
76 .space VDSO32_vsyscall_eh_frame_size-(.LENDFDE1-.LSTARTFRAME), 0
77 .previous
diff --git a/arch/x86/kernel/vsyscall-sysenter_32.S b/arch/x86/vdso/vdso32/sysenter.S
index ed879bf42995..e2800affa754 100644
--- a/arch/x86/kernel/vsyscall-sysenter_32.S
+++ b/arch/x86/vdso/vdso32/sysenter.S
@@ -1,11 +1,10 @@
1/* 1/*
2 * Code for the vsyscall page. This version uses the sysenter instruction. 2 * Code for the vDSO. This version uses the sysenter instruction.
3 * 3 *
4 * NOTE: 4 * First get the common code for the sigreturn entry points.
5 * 1) __kernel_vsyscall _must_ be first in this page. 5 * This must come first.
6 * 2) there are alignment constraints on this stub, see vsyscall-sigreturn.S
7 * for details.
8 */ 6 */
7#include "sigreturn.S"
9 8
10/* 9/*
11 * The caller puts arg2 in %ecx, which gets pushed. The kernel will use 10 * The caller puts arg2 in %ecx, which gets pushed. The kernel will use
@@ -23,11 +22,12 @@
23 * arg6 from the stack. 22 * arg6 from the stack.
24 * 23 *
25 * You can not use this vsyscall for the clone() syscall because the 24 * You can not use this vsyscall for the clone() syscall because the
26 * three dwords on the parent stack do not get copied to the child. 25 * three words on the parent stack do not get copied to the child.
27 */ 26 */
28 .text 27 .text
29 .globl __kernel_vsyscall 28 .globl __kernel_vsyscall
30 .type __kernel_vsyscall,@function 29 .type __kernel_vsyscall,@function
30 ALIGN
31__kernel_vsyscall: 31__kernel_vsyscall:
32.LSTART_vsyscall: 32.LSTART_vsyscall:
33 push %ecx 33 push %ecx
@@ -45,8 +45,7 @@ __kernel_vsyscall:
45 /* 14: System call restart point is here! (SYSENTER_RETURN-2) */ 45 /* 14: System call restart point is here! (SYSENTER_RETURN-2) */
46 jmp .Lenter_kernel 46 jmp .Lenter_kernel
47 /* 16: System call normal return point is here! */ 47 /* 16: System call normal return point is here! */
48 .globl SYSENTER_RETURN /* Symbol used by sysenter.c */ 48VDSO32_SYSENTER_RETURN: /* Symbol used by sysenter.c via vdso32-syms.h */
49SYSENTER_RETURN:
50 pop %ebp 49 pop %ebp
51.Lpop_ebp: 50.Lpop_ebp:
52 pop %edx 51 pop %edx
@@ -85,38 +84,33 @@ SYSENTER_RETURN:
85 .uleb128 0 84 .uleb128 0
86 /* What follows are the instructions for the table generation. 85 /* What follows are the instructions for the table generation.
87 We have to record all changes of the stack pointer. */ 86 We have to record all changes of the stack pointer. */
88 .byte 0x04 /* DW_CFA_advance_loc4 */ 87 .byte 0x40 + (.Lpush_ecx-.LSTART_vsyscall) /* DW_CFA_advance_loc */
89 .long .Lpush_ecx-.LSTART_vsyscall
90 .byte 0x0e /* DW_CFA_def_cfa_offset */ 88 .byte 0x0e /* DW_CFA_def_cfa_offset */
91 .byte 0x08 /* RA at offset 8 now */ 89 .byte 0x08 /* RA at offset 8 now */
92 .byte 0x04 /* DW_CFA_advance_loc4 */ 90 .byte 0x40 + (.Lpush_edx-.Lpush_ecx) /* DW_CFA_advance_loc */
93 .long .Lpush_edx-.Lpush_ecx
94 .byte 0x0e /* DW_CFA_def_cfa_offset */ 91 .byte 0x0e /* DW_CFA_def_cfa_offset */
95 .byte 0x0c /* RA at offset 12 now */ 92 .byte 0x0c /* RA at offset 12 now */
96 .byte 0x04 /* DW_CFA_advance_loc4 */ 93 .byte 0x40 + (.Lenter_kernel-.Lpush_edx) /* DW_CFA_advance_loc */
97 .long .Lenter_kernel-.Lpush_edx
98 .byte 0x0e /* DW_CFA_def_cfa_offset */ 94 .byte 0x0e /* DW_CFA_def_cfa_offset */
99 .byte 0x10 /* RA at offset 16 now */ 95 .byte 0x10 /* RA at offset 16 now */
100 .byte 0x85, 0x04 /* DW_CFA_offset %ebp -16 */ 96 .byte 0x85, 0x04 /* DW_CFA_offset %ebp -16 */
101 /* Finally the epilogue. */ 97 /* Finally the epilogue. */
102 .byte 0x04 /* DW_CFA_advance_loc4 */ 98 .byte 0x40 + (.Lpop_ebp-.Lenter_kernel) /* DW_CFA_advance_loc */
103 .long .Lpop_ebp-.Lenter_kernel
104 .byte 0x0e /* DW_CFA_def_cfa_offset */ 99 .byte 0x0e /* DW_CFA_def_cfa_offset */
105 .byte 0x0c /* RA at offset 12 now */ 100 .byte 0x0c /* RA at offset 12 now */
106 .byte 0xc5 /* DW_CFA_restore %ebp */ 101 .byte 0xc5 /* DW_CFA_restore %ebp */
107 .byte 0x04 /* DW_CFA_advance_loc4 */ 102 .byte 0x40 + (.Lpop_edx-.Lpop_ebp) /* DW_CFA_advance_loc */
108 .long .Lpop_edx-.Lpop_ebp
109 .byte 0x0e /* DW_CFA_def_cfa_offset */ 103 .byte 0x0e /* DW_CFA_def_cfa_offset */
110 .byte 0x08 /* RA at offset 8 now */ 104 .byte 0x08 /* RA at offset 8 now */
111 .byte 0x04 /* DW_CFA_advance_loc4 */ 105 .byte 0x40 + (.Lpop_ecx-.Lpop_edx) /* DW_CFA_advance_loc */
112 .long .Lpop_ecx-.Lpop_edx
113 .byte 0x0e /* DW_CFA_def_cfa_offset */ 106 .byte 0x0e /* DW_CFA_def_cfa_offset */
114 .byte 0x04 /* RA at offset 4 now */ 107 .byte 0x04 /* RA at offset 4 now */
115 .align 4 108 .align 4
116.LENDFDEDLSI: 109.LENDFDEDLSI:
117 .previous 110 .previous
118 111
119/* 112 /*
120 * Get the common code for the sigreturn entry points. 113 * Emit a symbol with the size of this .eh_frame data,
121 */ 114 * to verify it matches the other versions.
122#include "vsyscall-sigreturn_32.S" 115 */
116VDSO32_vsyscall_eh_frame_size = (.LENDFDEDLSI-.LSTARTFRAMEDLSI)
diff --git a/arch/x86/vdso/vdso32/vdso32.lds.S b/arch/x86/vdso/vdso32/vdso32.lds.S
new file mode 100644
index 000000000000..976124bb5f92
--- /dev/null
+++ b/arch/x86/vdso/vdso32/vdso32.lds.S
@@ -0,0 +1,37 @@
1/*
2 * Linker script for 32-bit vDSO.
3 * We #include the file to define the layout details.
4 * Here we only choose the prelinked virtual address.
5 *
6 * This file defines the version script giving the user-exported symbols in
7 * the DSO. We can define local symbols here called VDSO* to make their
8 * values visible using the asm-x86/vdso.h macros from the kernel proper.
9 */
10
11#define VDSO_PRELINK 0
12#include "../vdso-layout.lds.S"
13
14/* The ELF entry point can be used to set the AT_SYSINFO value. */
15ENTRY(__kernel_vsyscall);
16
17/*
18 * This controls what userland symbols we export from the vDSO.
19 */
20VERSION
21{
22 LINUX_2.5 {
23 global:
24 __kernel_vsyscall;
25 __kernel_sigreturn;
26 __kernel_rt_sigreturn;
27 local: *;
28 };
29}
30
31/*
32 * Symbols we define here called VDSO* get their values into vdso32-syms.h.
33 */
34VDSO32_PRELINK = VDSO_PRELINK;
35VDSO32_vsyscall = __kernel_vsyscall;
36VDSO32_sigreturn = __kernel_sigreturn;
37VDSO32_rt_sigreturn = __kernel_rt_sigreturn;
diff --git a/arch/x86/vdso/vgetcpu.c b/arch/x86/vdso/vgetcpu.c
index 3b1ae1abfba9..c8097f17f8a9 100644
--- a/arch/x86/vdso/vgetcpu.c
+++ b/arch/x86/vdso/vgetcpu.c
@@ -15,11 +15,11 @@
15 15
16long __vdso_getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *unused) 16long __vdso_getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *unused)
17{ 17{
18 unsigned int dummy, p; 18 unsigned int p;
19 19
20 if (*vdso_vgetcpu_mode == VGETCPU_RDTSCP) { 20 if (*vdso_vgetcpu_mode == VGETCPU_RDTSCP) {
21 /* Load per CPU data from RDTSCP */ 21 /* Load per CPU data from RDTSCP */
22 rdtscp(dummy, dummy, p); 22 native_read_tscp(&p);
23 } else { 23 } else {
24 /* Load per CPU data from GDT */ 24 /* Load per CPU data from GDT */
25 asm("lsl %1,%0" : "=r" (p) : "r" (__PER_CPU_SEG)); 25 asm("lsl %1,%0" : "=r" (p) : "r" (__PER_CPU_SEG));
diff --git a/arch/x86/vdso/vma.c b/arch/x86/vdso/vma.c
index ff9333e5fb08..3fdd51497a83 100644
--- a/arch/x86/vdso/vma.c
+++ b/arch/x86/vdso/vma.c
@@ -11,23 +11,20 @@
11#include <asm/vsyscall.h> 11#include <asm/vsyscall.h>
12#include <asm/vgtod.h> 12#include <asm/vgtod.h>
13#include <asm/proto.h> 13#include <asm/proto.h>
14#include "voffset.h" 14#include <asm/vdso.h>
15 15
16int vdso_enabled = 1; 16#include "vextern.h" /* Just for VMAGIC. */
17
18#define VEXTERN(x) extern typeof(__ ## x) *vdso_ ## x;
19#include "vextern.h"
20#undef VEXTERN 17#undef VEXTERN
21 18
22extern char vdso_kernel_start[], vdso_start[], vdso_end[]; 19int vdso_enabled = 1;
20
21extern char vdso_start[], vdso_end[];
23extern unsigned short vdso_sync_cpuid; 22extern unsigned short vdso_sync_cpuid;
24 23
25struct page **vdso_pages; 24struct page **vdso_pages;
26 25
27static inline void *var_ref(void *vbase, char *var, char *name) 26static inline void *var_ref(void *p, char *name)
28{ 27{
29 unsigned offset = var - &vdso_kernel_start[0] + VDSO_TEXT_OFFSET;
30 void *p = vbase + offset;
31 if (*(void **)p != (void *)VMAGIC) { 28 if (*(void **)p != (void *)VMAGIC) {
32 printk("VDSO: variable %s broken\n", name); 29 printk("VDSO: variable %s broken\n", name);
33 vdso_enabled = 0; 30 vdso_enabled = 0;
@@ -62,9 +59,8 @@ static int __init init_vdso_vars(void)
62 vdso_enabled = 0; 59 vdso_enabled = 0;
63 } 60 }
64 61
65#define V(x) *(typeof(x) *) var_ref(vbase, (char *)RELOC_HIDE(&x, 0), #x)
66#define VEXTERN(x) \ 62#define VEXTERN(x) \
67 V(vdso_ ## x) = &__ ## x; 63 *(typeof(__ ## x) **) var_ref(VDSO64_SYMBOL(vbase, x), #x) = &__ ## x;
68#include "vextern.h" 64#include "vextern.h"
69#undef VEXTERN 65#undef VEXTERN
70 return 0; 66 return 0;
diff --git a/arch/x86/vdso/voffset.h b/arch/x86/vdso/voffset.h
deleted file mode 100644
index 4af67c79085f..000000000000
--- a/arch/x86/vdso/voffset.h
+++ /dev/null
@@ -1 +0,0 @@
1#define VDSO_TEXT_OFFSET 0x600
diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig
index fbfa55ce0d55..4d5f2649bee4 100644
--- a/arch/x86/xen/Kconfig
+++ b/arch/x86/xen/Kconfig
@@ -5,6 +5,7 @@
5config XEN 5config XEN
6 bool "Xen guest support" 6 bool "Xen guest support"
7 select PARAVIRT 7 select PARAVIRT
8 depends on X86_32
8 depends on X86_CMPXCHG && X86_TSC && !NEED_MULTIPLE_NODES && !(X86_VISWS || X86_VOYAGER) 9 depends on X86_CMPXCHG && X86_TSC && !NEED_MULTIPLE_NODES && !(X86_VISWS || X86_VOYAGER)
9 help 10 help
10 This is the Linux Xen port. Enabling this will allow the 11 This is the Linux Xen port. Enabling this will allow the
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index b6af3ea43c73..de647bc6e74d 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -95,7 +95,7 @@ struct shared_info *HYPERVISOR_shared_info = (void *)&dummy_shared_info;
95 * 95 *
96 * 0: not available, 1: available 96 * 0: not available, 1: available
97 */ 97 */
98static int have_vcpu_info_placement = 1; 98static int have_vcpu_info_placement = 0;
99 99
100static void __init xen_vcpu_setup(int cpu) 100static void __init xen_vcpu_setup(int cpu)
101{ 101{
@@ -141,8 +141,8 @@ static void __init xen_banner(void)
141 printk(KERN_INFO "Hypervisor signature: %s\n", xen_start_info->magic); 141 printk(KERN_INFO "Hypervisor signature: %s\n", xen_start_info->magic);
142} 142}
143 143
144static void xen_cpuid(unsigned int *eax, unsigned int *ebx, 144static void xen_cpuid(unsigned int *ax, unsigned int *bx,
145 unsigned int *ecx, unsigned int *edx) 145 unsigned int *cx, unsigned int *dx)
146{ 146{
147 unsigned maskedx = ~0; 147 unsigned maskedx = ~0;
148 148
@@ -150,18 +150,18 @@ static void xen_cpuid(unsigned int *eax, unsigned int *ebx,
150 * Mask out inconvenient features, to try and disable as many 150 * Mask out inconvenient features, to try and disable as many
151 * unsupported kernel subsystems as possible. 151 * unsupported kernel subsystems as possible.
152 */ 152 */
153 if (*eax == 1) 153 if (*ax == 1)
154 maskedx = ~((1 << X86_FEATURE_APIC) | /* disable APIC */ 154 maskedx = ~((1 << X86_FEATURE_APIC) | /* disable APIC */
155 (1 << X86_FEATURE_ACPI) | /* disable ACPI */ 155 (1 << X86_FEATURE_ACPI) | /* disable ACPI */
156 (1 << X86_FEATURE_ACC)); /* thermal monitoring */ 156 (1 << X86_FEATURE_ACC)); /* thermal monitoring */
157 157
158 asm(XEN_EMULATE_PREFIX "cpuid" 158 asm(XEN_EMULATE_PREFIX "cpuid"
159 : "=a" (*eax), 159 : "=a" (*ax),
160 "=b" (*ebx), 160 "=b" (*bx),
161 "=c" (*ecx), 161 "=c" (*cx),
162 "=d" (*edx) 162 "=d" (*dx)
163 : "0" (*eax), "2" (*ecx)); 163 : "0" (*ax), "2" (*cx));
164 *edx &= maskedx; 164 *dx &= maskedx;
165} 165}
166 166
167static void xen_set_debugreg(int reg, unsigned long val) 167static void xen_set_debugreg(int reg, unsigned long val)
@@ -275,19 +275,12 @@ static unsigned long xen_store_tr(void)
275 275
276static void xen_set_ldt(const void *addr, unsigned entries) 276static void xen_set_ldt(const void *addr, unsigned entries)
277{ 277{
278 unsigned long linear_addr = (unsigned long)addr;
279 struct mmuext_op *op; 278 struct mmuext_op *op;
280 struct multicall_space mcs = xen_mc_entry(sizeof(*op)); 279 struct multicall_space mcs = xen_mc_entry(sizeof(*op));
281 280
282 op = mcs.args; 281 op = mcs.args;
283 op->cmd = MMUEXT_SET_LDT; 282 op->cmd = MMUEXT_SET_LDT;
284 if (linear_addr) { 283 op->arg1.linear_addr = (unsigned long)addr;
285 /* ldt my be vmalloced, use arbitrary_virt_to_machine */
286 xmaddr_t maddr;
287 maddr = arbitrary_virt_to_machine((unsigned long)addr);
288 linear_addr = (unsigned long)maddr.maddr;
289 }
290 op->arg1.linear_addr = linear_addr;
291 op->arg2.nr_ents = entries; 284 op->arg2.nr_ents = entries;
292 285
293 MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF); 286 MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
@@ -295,7 +288,7 @@ static void xen_set_ldt(const void *addr, unsigned entries)
295 xen_mc_issue(PARAVIRT_LAZY_CPU); 288 xen_mc_issue(PARAVIRT_LAZY_CPU);
296} 289}
297 290
298static void xen_load_gdt(const struct Xgt_desc_struct *dtr) 291static void xen_load_gdt(const struct desc_ptr *dtr)
299{ 292{
300 unsigned long *frames; 293 unsigned long *frames;
301 unsigned long va = dtr->address; 294 unsigned long va = dtr->address;
@@ -357,11 +350,11 @@ static void xen_load_tls(struct thread_struct *t, unsigned int cpu)
357} 350}
358 351
359static void xen_write_ldt_entry(struct desc_struct *dt, int entrynum, 352static void xen_write_ldt_entry(struct desc_struct *dt, int entrynum,
360 u32 low, u32 high) 353 const void *ptr)
361{ 354{
362 unsigned long lp = (unsigned long)&dt[entrynum]; 355 unsigned long lp = (unsigned long)&dt[entrynum];
363 xmaddr_t mach_lp = virt_to_machine(lp); 356 xmaddr_t mach_lp = virt_to_machine(lp);
364 u64 entry = (u64)high << 32 | low; 357 u64 entry = *(u64 *)ptr;
365 358
366 preempt_disable(); 359 preempt_disable();
367 360
@@ -395,12 +388,11 @@ static int cvt_gate_to_trap(int vector, u32 low, u32 high,
395} 388}
396 389
397/* Locations of each CPU's IDT */ 390/* Locations of each CPU's IDT */
398static DEFINE_PER_CPU(struct Xgt_desc_struct, idt_desc); 391static DEFINE_PER_CPU(struct desc_ptr, idt_desc);
399 392
400/* Set an IDT entry. If the entry is part of the current IDT, then 393/* Set an IDT entry. If the entry is part of the current IDT, then
401 also update Xen. */ 394 also update Xen. */
402static void xen_write_idt_entry(struct desc_struct *dt, int entrynum, 395static void xen_write_idt_entry(gate_desc *dt, int entrynum, const gate_desc *g)
403 u32 low, u32 high)
404{ 396{
405 unsigned long p = (unsigned long)&dt[entrynum]; 397 unsigned long p = (unsigned long)&dt[entrynum];
406 unsigned long start, end; 398 unsigned long start, end;
@@ -412,14 +404,15 @@ static void xen_write_idt_entry(struct desc_struct *dt, int entrynum,
412 404
413 xen_mc_flush(); 405 xen_mc_flush();
414 406
415 write_dt_entry(dt, entrynum, low, high); 407 native_write_idt_entry(dt, entrynum, g);
416 408
417 if (p >= start && (p + 8) <= end) { 409 if (p >= start && (p + 8) <= end) {
418 struct trap_info info[2]; 410 struct trap_info info[2];
411 u32 *desc = (u32 *)g;
419 412
420 info[1].address = 0; 413 info[1].address = 0;
421 414
422 if (cvt_gate_to_trap(entrynum, low, high, &info[0])) 415 if (cvt_gate_to_trap(entrynum, desc[0], desc[1], &info[0]))
423 if (HYPERVISOR_set_trap_table(info)) 416 if (HYPERVISOR_set_trap_table(info))
424 BUG(); 417 BUG();
425 } 418 }
@@ -427,7 +420,7 @@ static void xen_write_idt_entry(struct desc_struct *dt, int entrynum,
427 preempt_enable(); 420 preempt_enable();
428} 421}
429 422
430static void xen_convert_trap_info(const struct Xgt_desc_struct *desc, 423static void xen_convert_trap_info(const struct desc_ptr *desc,
431 struct trap_info *traps) 424 struct trap_info *traps)
432{ 425{
433 unsigned in, out, count; 426 unsigned in, out, count;
@@ -446,7 +439,7 @@ static void xen_convert_trap_info(const struct Xgt_desc_struct *desc,
446 439
447void xen_copy_trap_info(struct trap_info *traps) 440void xen_copy_trap_info(struct trap_info *traps)
448{ 441{
449 const struct Xgt_desc_struct *desc = &__get_cpu_var(idt_desc); 442 const struct desc_ptr *desc = &__get_cpu_var(idt_desc);
450 443
451 xen_convert_trap_info(desc, traps); 444 xen_convert_trap_info(desc, traps);
452} 445}
@@ -454,7 +447,7 @@ void xen_copy_trap_info(struct trap_info *traps)
454/* Load a new IDT into Xen. In principle this can be per-CPU, so we 447/* Load a new IDT into Xen. In principle this can be per-CPU, so we
455 hold a spinlock to protect the static traps[] array (static because 448 hold a spinlock to protect the static traps[] array (static because
456 it avoids allocation, and saves stack space). */ 449 it avoids allocation, and saves stack space). */
457static void xen_load_idt(const struct Xgt_desc_struct *desc) 450static void xen_load_idt(const struct desc_ptr *desc)
458{ 451{
459 static DEFINE_SPINLOCK(lock); 452 static DEFINE_SPINLOCK(lock);
460 static struct trap_info traps[257]; 453 static struct trap_info traps[257];
@@ -475,22 +468,21 @@ static void xen_load_idt(const struct Xgt_desc_struct *desc)
475/* Write a GDT descriptor entry. Ignore LDT descriptors, since 468/* Write a GDT descriptor entry. Ignore LDT descriptors, since
476 they're handled differently. */ 469 they're handled differently. */
477static void xen_write_gdt_entry(struct desc_struct *dt, int entry, 470static void xen_write_gdt_entry(struct desc_struct *dt, int entry,
478 u32 low, u32 high) 471 const void *desc, int type)
479{ 472{
480 preempt_disable(); 473 preempt_disable();
481 474
482 switch ((high >> 8) & 0xff) { 475 switch (type) {
483 case DESCTYPE_LDT: 476 case DESC_LDT:
484 case DESCTYPE_TSS: 477 case DESC_TSS:
485 /* ignore */ 478 /* ignore */
486 break; 479 break;
487 480
488 default: { 481 default: {
489 xmaddr_t maddr = virt_to_machine(&dt[entry]); 482 xmaddr_t maddr = virt_to_machine(&dt[entry]);
490 u64 desc = (u64)high << 32 | low;
491 483
492 xen_mc_flush(); 484 xen_mc_flush();
493 if (HYPERVISOR_update_descriptor(maddr.maddr, desc)) 485 if (HYPERVISOR_update_descriptor(maddr.maddr, *(u64 *)desc))
494 BUG(); 486 BUG();
495 } 487 }
496 488
@@ -499,11 +491,11 @@ static void xen_write_gdt_entry(struct desc_struct *dt, int entry,
499 preempt_enable(); 491 preempt_enable();
500} 492}
501 493
502static void xen_load_esp0(struct tss_struct *tss, 494static void xen_load_sp0(struct tss_struct *tss,
503 struct thread_struct *thread) 495 struct thread_struct *thread)
504{ 496{
505 struct multicall_space mcs = xen_mc_entry(0); 497 struct multicall_space mcs = xen_mc_entry(0);
506 MULTI_stack_switch(mcs.mc, __KERNEL_DS, thread->esp0); 498 MULTI_stack_switch(mcs.mc, __KERNEL_DS, thread->sp0);
507 xen_mc_issue(PARAVIRT_LAZY_CPU); 499 xen_mc_issue(PARAVIRT_LAZY_CPU);
508} 500}
509 501
@@ -521,12 +513,12 @@ static void xen_io_delay(void)
521} 513}
522 514
523#ifdef CONFIG_X86_LOCAL_APIC 515#ifdef CONFIG_X86_LOCAL_APIC
524static unsigned long xen_apic_read(unsigned long reg) 516static u32 xen_apic_read(unsigned long reg)
525{ 517{
526 return 0; 518 return 0;
527} 519}
528 520
529static void xen_apic_write(unsigned long reg, unsigned long val) 521static void xen_apic_write(unsigned long reg, u32 val)
530{ 522{
531 /* Warn to see if there's any stray references */ 523 /* Warn to see if there's any stray references */
532 WARN_ON(1); 524 WARN_ON(1);
@@ -666,6 +658,13 @@ static __init void xen_alloc_pt_init(struct mm_struct *mm, u32 pfn)
666 make_lowmem_page_readonly(__va(PFN_PHYS(pfn))); 658 make_lowmem_page_readonly(__va(PFN_PHYS(pfn)));
667} 659}
668 660
661/* Early release_pt assumes that all pts are pinned, since there's
662 only init_mm and anything attached to that is pinned. */
663static void xen_release_pt_init(u32 pfn)
664{
665 make_lowmem_page_readwrite(__va(PFN_PHYS(pfn)));
666}
667
669static void pin_pagetable_pfn(unsigned level, unsigned long pfn) 668static void pin_pagetable_pfn(unsigned level, unsigned long pfn)
670{ 669{
671 struct mmuext_op op; 670 struct mmuext_op op;
@@ -677,7 +676,7 @@ static void pin_pagetable_pfn(unsigned level, unsigned long pfn)
677 676
678/* This needs to make sure the new pte page is pinned iff its being 677/* This needs to make sure the new pte page is pinned iff its being
679 attached to a pinned pagetable. */ 678 attached to a pinned pagetable. */
680static void xen_alloc_pt(struct mm_struct *mm, u32 pfn) 679static void xen_alloc_ptpage(struct mm_struct *mm, u32 pfn, unsigned level)
681{ 680{
682 struct page *page = pfn_to_page(pfn); 681 struct page *page = pfn_to_page(pfn);
683 682
@@ -686,7 +685,7 @@ static void xen_alloc_pt(struct mm_struct *mm, u32 pfn)
686 685
687 if (!PageHighMem(page)) { 686 if (!PageHighMem(page)) {
688 make_lowmem_page_readonly(__va(PFN_PHYS(pfn))); 687 make_lowmem_page_readonly(__va(PFN_PHYS(pfn)));
689 pin_pagetable_pfn(MMUEXT_PIN_L1_TABLE, pfn); 688 pin_pagetable_pfn(level, pfn);
690 } else 689 } else
691 /* make sure there are no stray mappings of 690 /* make sure there are no stray mappings of
692 this page */ 691 this page */
@@ -694,6 +693,16 @@ static void xen_alloc_pt(struct mm_struct *mm, u32 pfn)
694 } 693 }
695} 694}
696 695
696static void xen_alloc_pt(struct mm_struct *mm, u32 pfn)
697{
698 xen_alloc_ptpage(mm, pfn, MMUEXT_PIN_L1_TABLE);
699}
700
701static void xen_alloc_pd(struct mm_struct *mm, u32 pfn)
702{
703 xen_alloc_ptpage(mm, pfn, MMUEXT_PIN_L2_TABLE);
704}
705
697/* This should never happen until we're OK to use struct page */ 706/* This should never happen until we're OK to use struct page */
698static void xen_release_pt(u32 pfn) 707static void xen_release_pt(u32 pfn)
699{ 708{
@@ -796,6 +805,9 @@ static __init void xen_pagetable_setup_done(pgd_t *base)
796 /* This will work as long as patching hasn't happened yet 805 /* This will work as long as patching hasn't happened yet
797 (which it hasn't) */ 806 (which it hasn't) */
798 pv_mmu_ops.alloc_pt = xen_alloc_pt; 807 pv_mmu_ops.alloc_pt = xen_alloc_pt;
808 pv_mmu_ops.alloc_pd = xen_alloc_pd;
809 pv_mmu_ops.release_pt = xen_release_pt;
810 pv_mmu_ops.release_pd = xen_release_pt;
799 pv_mmu_ops.set_pte = xen_set_pte; 811 pv_mmu_ops.set_pte = xen_set_pte;
800 812
801 if (!xen_feature(XENFEAT_auto_translated_physmap)) { 813 if (!xen_feature(XENFEAT_auto_translated_physmap)) {
@@ -953,7 +965,7 @@ static const struct pv_cpu_ops xen_cpu_ops __initdata = {
953 .read_pmc = native_read_pmc, 965 .read_pmc = native_read_pmc,
954 966
955 .iret = (void *)&hypercall_page[__HYPERVISOR_iret], 967 .iret = (void *)&hypercall_page[__HYPERVISOR_iret],
956 .irq_enable_sysexit = NULL, /* never called */ 968 .irq_enable_syscall_ret = NULL, /* never called */
957 969
958 .load_tr_desc = paravirt_nop, 970 .load_tr_desc = paravirt_nop,
959 .set_ldt = xen_set_ldt, 971 .set_ldt = xen_set_ldt,
@@ -968,7 +980,7 @@ static const struct pv_cpu_ops xen_cpu_ops __initdata = {
968 .write_ldt_entry = xen_write_ldt_entry, 980 .write_ldt_entry = xen_write_ldt_entry,
969 .write_gdt_entry = xen_write_gdt_entry, 981 .write_gdt_entry = xen_write_gdt_entry,
970 .write_idt_entry = xen_write_idt_entry, 982 .write_idt_entry = xen_write_idt_entry,
971 .load_esp0 = xen_load_esp0, 983 .load_sp0 = xen_load_sp0,
972 984
973 .set_iopl_mask = xen_set_iopl_mask, 985 .set_iopl_mask = xen_set_iopl_mask,
974 .io_delay = xen_io_delay, 986 .io_delay = xen_io_delay,
@@ -1019,10 +1031,10 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = {
1019 .pte_update_defer = paravirt_nop, 1031 .pte_update_defer = paravirt_nop,
1020 1032
1021 .alloc_pt = xen_alloc_pt_init, 1033 .alloc_pt = xen_alloc_pt_init,
1022 .release_pt = xen_release_pt, 1034 .release_pt = xen_release_pt_init,
1023 .alloc_pd = paravirt_nop, 1035 .alloc_pd = xen_alloc_pt_init,
1024 .alloc_pd_clone = paravirt_nop, 1036 .alloc_pd_clone = paravirt_nop,
1025 .release_pd = paravirt_nop, 1037 .release_pd = xen_release_pt_init,
1026 1038
1027#ifdef CONFIG_HIGHPTE 1039#ifdef CONFIG_HIGHPTE
1028 .kmap_atomic_pte = xen_kmap_atomic_pte, 1040 .kmap_atomic_pte = xen_kmap_atomic_pte,
diff --git a/arch/x86/xen/events.c b/arch/x86/xen/events.c
index 6d1da5809e6f..dcf613e17581 100644
--- a/arch/x86/xen/events.c
+++ b/arch/x86/xen/events.c
@@ -465,7 +465,7 @@ void xen_send_IPI_one(unsigned int cpu, enum ipi_vector vector)
465 * a bitset of words which contain pending event bits. The second 465 * a bitset of words which contain pending event bits. The second
466 * level is a bitset of pending events themselves. 466 * level is a bitset of pending events themselves.
467 */ 467 */
468fastcall void xen_evtchn_do_upcall(struct pt_regs *regs) 468void xen_evtchn_do_upcall(struct pt_regs *regs)
469{ 469{
470 int cpu = get_cpu(); 470 int cpu = get_cpu();
471 struct shared_info *s = HYPERVISOR_shared_info; 471 struct shared_info *s = HYPERVISOR_shared_info;
@@ -487,7 +487,7 @@ fastcall void xen_evtchn_do_upcall(struct pt_regs *regs)
487 int irq = evtchn_to_irq[port]; 487 int irq = evtchn_to_irq[port];
488 488
489 if (irq != -1) { 489 if (irq != -1) {
490 regs->orig_eax = ~irq; 490 regs->orig_ax = ~irq;
491 do_IRQ(regs); 491 do_IRQ(regs);
492 } 492 }
493 } 493 }
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 0ac6c5dc49ba..45aa771e73a9 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -58,7 +58,8 @@
58 58
59xmaddr_t arbitrary_virt_to_machine(unsigned long address) 59xmaddr_t arbitrary_virt_to_machine(unsigned long address)
60{ 60{
61 pte_t *pte = lookup_address(address); 61 int level;
62 pte_t *pte = lookup_address(address, &level);
62 unsigned offset = address & PAGE_MASK; 63 unsigned offset = address & PAGE_MASK;
63 64
64 BUG_ON(pte == NULL); 65 BUG_ON(pte == NULL);
@@ -70,8 +71,9 @@ void make_lowmem_page_readonly(void *vaddr)
70{ 71{
71 pte_t *pte, ptev; 72 pte_t *pte, ptev;
72 unsigned long address = (unsigned long)vaddr; 73 unsigned long address = (unsigned long)vaddr;
74 int level;
73 75
74 pte = lookup_address(address); 76 pte = lookup_address(address, &level);
75 BUG_ON(pte == NULL); 77 BUG_ON(pte == NULL);
76 78
77 ptev = pte_wrprotect(*pte); 79 ptev = pte_wrprotect(*pte);
@@ -84,8 +86,9 @@ void make_lowmem_page_readwrite(void *vaddr)
84{ 86{
85 pte_t *pte, ptev; 87 pte_t *pte, ptev;
86 unsigned long address = (unsigned long)vaddr; 88 unsigned long address = (unsigned long)vaddr;
89 int level;
87 90
88 pte = lookup_address(address); 91 pte = lookup_address(address, &level);
89 BUG_ON(pte == NULL); 92 BUG_ON(pte == NULL);
90 93
91 ptev = pte_mkwrite(*pte); 94 ptev = pte_mkwrite(*pte);
@@ -241,12 +244,12 @@ unsigned long long xen_pgd_val(pgd_t pgd)
241 244
242pte_t xen_make_pte(unsigned long long pte) 245pte_t xen_make_pte(unsigned long long pte)
243{ 246{
244 if (pte & 1) 247 if (pte & _PAGE_PRESENT) {
245 pte = phys_to_machine(XPADDR(pte)).maddr; 248 pte = phys_to_machine(XPADDR(pte)).maddr;
249 pte &= ~(_PAGE_PCD | _PAGE_PWT);
250 }
246 251
247 pte &= ~_PAGE_PCD; 252 return (pte_t){ .pte = pte };
248
249 return (pte_t){ pte, pte >> 32 };
250} 253}
251 254
252pmd_t xen_make_pmd(unsigned long long pmd) 255pmd_t xen_make_pmd(unsigned long long pmd)
@@ -290,10 +293,10 @@ unsigned long xen_pgd_val(pgd_t pgd)
290 293
291pte_t xen_make_pte(unsigned long pte) 294pte_t xen_make_pte(unsigned long pte)
292{ 295{
293 if (pte & _PAGE_PRESENT) 296 if (pte & _PAGE_PRESENT) {
294 pte = phys_to_machine(XPADDR(pte)).maddr; 297 pte = phys_to_machine(XPADDR(pte)).maddr;
295 298 pte &= ~(_PAGE_PCD | _PAGE_PWT);
296 pte &= ~_PAGE_PCD; 299 }
297 300
298 return (pte_t){ pte }; 301 return (pte_t){ pte };
299} 302}
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index f84e77226646..3bad4773a2f3 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -10,6 +10,7 @@
10#include <linux/pm.h> 10#include <linux/pm.h>
11 11
12#include <asm/elf.h> 12#include <asm/elf.h>
13#include <asm/vdso.h>
13#include <asm/e820.h> 14#include <asm/e820.h>
14#include <asm/setup.h> 15#include <asm/setup.h>
15#include <asm/xen/hypervisor.h> 16#include <asm/xen/hypervisor.h>
@@ -59,12 +60,10 @@ static void xen_idle(void)
59/* 60/*
60 * Set the bit indicating "nosegneg" library variants should be used. 61 * Set the bit indicating "nosegneg" library variants should be used.
61 */ 62 */
62static void fiddle_vdso(void) 63static void __init fiddle_vdso(void)
63{ 64{
64 extern u32 VDSO_NOTE_MASK; /* See ../kernel/vsyscall-note.S. */ 65 extern const char vdso32_default_start;
65 extern char vsyscall_int80_start; 66 u32 *mask = VDSO32_SYMBOL(&vdso32_default_start, NOTE_MASK);
66 u32 *mask = (u32 *) ((unsigned long) &VDSO_NOTE_MASK - VDSO_PRELINK +
67 &vsyscall_int80_start);
68 *mask |= 1 << VDSO_NOTE_NONEGSEG_BIT; 67 *mask |= 1 << VDSO_NOTE_NONEGSEG_BIT;
69} 68}
70 69
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index c1b131bcdcbe..aafc54437403 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -146,7 +146,7 @@ void __init xen_smp_prepare_boot_cpu(void)
146 old memory can be recycled */ 146 old memory can be recycled */
147 make_lowmem_page_readwrite(&per_cpu__gdt_page); 147 make_lowmem_page_readwrite(&per_cpu__gdt_page);
148 148
149 for (cpu = 0; cpu < NR_CPUS; cpu++) { 149 for_each_possible_cpu(cpu) {
150 cpus_clear(per_cpu(cpu_sibling_map, cpu)); 150 cpus_clear(per_cpu(cpu_sibling_map, cpu));
151 /* 151 /*
152 * cpu_core_map lives in a per cpu area that is cleared 152 * cpu_core_map lives in a per cpu area that is cleared
@@ -163,7 +163,7 @@ void __init xen_smp_prepare_cpus(unsigned int max_cpus)
163{ 163{
164 unsigned cpu; 164 unsigned cpu;
165 165
166 for (cpu = 0; cpu < NR_CPUS; cpu++) { 166 for_each_possible_cpu(cpu) {
167 cpus_clear(per_cpu(cpu_sibling_map, cpu)); 167 cpus_clear(per_cpu(cpu_sibling_map, cpu));
168 /* 168 /*
169 * cpu_core_ map will be zeroed when the per 169 * cpu_core_ map will be zeroed when the per
@@ -239,10 +239,10 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
239 ctxt->gdt_ents = ARRAY_SIZE(gdt->gdt); 239 ctxt->gdt_ents = ARRAY_SIZE(gdt->gdt);
240 240
241 ctxt->user_regs.cs = __KERNEL_CS; 241 ctxt->user_regs.cs = __KERNEL_CS;
242 ctxt->user_regs.esp = idle->thread.esp0 - sizeof(struct pt_regs); 242 ctxt->user_regs.esp = idle->thread.sp0 - sizeof(struct pt_regs);
243 243
244 ctxt->kernel_ss = __KERNEL_DS; 244 ctxt->kernel_ss = __KERNEL_DS;
245 ctxt->kernel_sp = idle->thread.esp0; 245 ctxt->kernel_sp = idle->thread.sp0;
246 246
247 ctxt->event_callback_cs = __KERNEL_CS; 247 ctxt->event_callback_cs = __KERNEL_CS;
248 ctxt->event_callback_eip = (unsigned long)xen_hypervisor_callback; 248 ctxt->event_callback_eip = (unsigned long)xen_hypervisor_callback;
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c
index d083ff5ef088..b3721fd6877b 100644
--- a/arch/x86/xen/time.c
+++ b/arch/x86/xen/time.c
@@ -592,7 +592,7 @@ __init void xen_time_init(void)
592 set_normalized_timespec(&wall_to_monotonic, 592 set_normalized_timespec(&wall_to_monotonic,
593 -xtime.tv_sec, -xtime.tv_nsec); 593 -xtime.tv_sec, -xtime.tv_nsec);
594 594
595 tsc_disable = 0; 595 setup_force_cpu_cap(X86_FEATURE_TSC);
596 596
597 xen_setup_timer(cpu); 597 xen_setup_timer(cpu);
598 xen_setup_cpu_clockevents(); 598 xen_setup_cpu_clockevents();
diff --git a/arch/x86/xen/xen-head.S b/arch/x86/xen/xen-head.S
index f8d6937db2ec..288d587ce73c 100644
--- a/arch/x86/xen/xen-head.S
+++ b/arch/x86/xen/xen-head.S
@@ -4,16 +4,18 @@
4#ifdef CONFIG_XEN 4#ifdef CONFIG_XEN
5 5
6#include <linux/elfnote.h> 6#include <linux/elfnote.h>
7#include <linux/init.h>
7#include <asm/boot.h> 8#include <asm/boot.h>
8#include <xen/interface/elfnote.h> 9#include <xen/interface/elfnote.h>
9 10
10.pushsection .init.text 11 __INIT
11ENTRY(startup_xen) 12ENTRY(startup_xen)
12 movl %esi,xen_start_info 13 movl %esi,xen_start_info
13 cld 14 cld
14 movl $(init_thread_union+THREAD_SIZE),%esp 15 movl $(init_thread_union+THREAD_SIZE),%esp
15 jmp xen_start_kernel 16 jmp xen_start_kernel
16.popsection 17
18 __FINIT
17 19
18.pushsection .bss.page_aligned 20.pushsection .bss.page_aligned
19 .align PAGE_SIZE_asm 21 .align PAGE_SIZE_asm
diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S
index ac4ed52034db..7d0f55a4982d 100644
--- a/arch/xtensa/kernel/vmlinux.lds.S
+++ b/arch/xtensa/kernel/vmlinux.lds.S
@@ -136,13 +136,13 @@ SECTIONS
136 __init_begin = .; 136 __init_begin = .;
137 .init.text : { 137 .init.text : {
138 _sinittext = .; 138 _sinittext = .;
139 *(.init.literal) *(.init.text) 139 *(.init.literal) INIT_TEXT
140 _einittext = .; 140 _einittext = .;
141 } 141 }
142 142
143 .init.data : 143 .init.data :
144 { 144 {
145 *(.init.data) 145 INIT_DATA
146 . = ALIGN(0x4); 146 . = ALIGN(0x4);
147 __tagtable_begin = .; 147 __tagtable_begin = .;
148 *(.taglist) 148 *(.taglist)
@@ -278,8 +278,9 @@ SECTIONS
278 /* Sections to be discarded */ 278 /* Sections to be discarded */
279 /DISCARD/ : 279 /DISCARD/ :
280 { 280 {
281 *(.exit.literal .exit.text) 281 *(.exit.literal)
282 *(.exit.data) 282 EXIT_TEXT
283 EXIT_DATA
283 *(.exitcall.exit) 284 *(.exitcall.exit)
284 } 285 }
285 286
diff --git a/arch/xtensa/mm/Makefile b/arch/xtensa/mm/Makefile
index 10aec22a8f98..64e304a2f884 100644
--- a/arch/xtensa/mm/Makefile
+++ b/arch/xtensa/mm/Makefile
@@ -1,9 +1,5 @@
1# 1#
2# Makefile for the Linux/Xtensa-specific parts of the memory manager. 2# Makefile for the Linux/Xtensa-specific parts of the memory manager.
3# 3#
4# Note! Dependencies are done automagically by 'make dep', which also
5# removes any old dependencies. DON'T put your own dependencies here
6# unless it's something special (ie not a .c file).
7#
8 4
9obj-y := init.o fault.o tlb.o misc.o cache.o 5obj-y := init.o fault.o tlb.o misc.o cache.o
diff --git a/arch/xtensa/platform-iss/Makefile b/arch/xtensa/platform-iss/Makefile
index 5b394e9620e5..af96e314d71f 100644
--- a/arch/xtensa/platform-iss/Makefile
+++ b/arch/xtensa/platform-iss/Makefile
@@ -3,11 +3,6 @@
3# Makefile for the Xtensa Instruction Set Simulator (ISS) 3# Makefile for the Xtensa Instruction Set Simulator (ISS)
4# "prom monitor" library routines under Linux. 4# "prom monitor" library routines under Linux.
5# 5#
6# Note! Dependencies are done automagically by 'make dep', which also
7# removes any old dependencies. DON'T put your own dependencies here
8# unless it's something special (ie not a .c file).
9#
10# Note 2! The CFLAGS definitions are in the main makefile...
11 6
12obj-y = io.o console.o setup.o network.o 7obj-y = io.o console.o setup.o network.o
13 8