From bab384bdbe279efd7acc2146ef13b0b0395b2a42 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 3 Jun 2003 17:04:10 +0000 Subject: [PATCH] Merge with Linux 2.5.59. --- Documentation/Changes | 2 +- Documentation/crypto/api-intro.txt | 12 +- Documentation/driver-model/bus.txt | 4 +- Documentation/driver-model/driver.txt | 32 +- Documentation/driver-model/overview.txt | 4 +- Documentation/filesystems/sysfs.txt | 10 +- MAINTAINERS | 6 +- Makefile | 13 +- arch/alpha/Kconfig | 38 +- arch/alpha/Makefile | 4 + arch/alpha/boot/Makefile | 7 +- arch/alpha/kernel/Makefile | 22 +- arch/alpha/kernel/alpha_ksyms.c | 13 +- arch/alpha/kernel/core_marvel.c | 1121 +++++++++++++ arch/alpha/kernel/core_titan.c | 532 ++++-- arch/alpha/kernel/core_tsunami.c | 1 - arch/alpha/kernel/core_wildfire.c | 27 + arch/alpha/kernel/err_impl.h | 14 + arch/alpha/kernel/err_marvel.c | 57 + arch/alpha/kernel/err_titan.c | 747 +++++++++ arch/alpha/kernel/gct.c | 48 + arch/alpha/kernel/irq.c | 38 +- arch/alpha/kernel/machvec_impl.h | 15 +- arch/alpha/kernel/osf_sys.c | 11 +- arch/alpha/kernel/pci.c | 39 +- arch/alpha/kernel/pci_impl.h | 7 + arch/alpha/kernel/pci_iommu.c | 38 +- arch/alpha/kernel/proto.h | 30 + arch/alpha/kernel/setup.c | 53 +- arch/alpha/kernel/smp.c | 117 +- arch/alpha/kernel/sys_marvel.c | 500 ++++++ arch/alpha/kernel/sys_titan.c | 810 ++++----- arch/alpha/kernel/sys_wildfire.c | 5 + arch/alpha/kernel/traps.c | 2 +- arch/alpha/lib/callback_srm.S | 2 + arch/alpha/mm/Makefile | 2 +- arch/alpha/mm/numa.c | 101 +- arch/alpha/mm/remap.c | 90 + arch/alpha/vmlinux.lds.S | 162 +- arch/arm/kernel/bios32.c | 2 +- arch/arm/kernel/calls.S | 20 +- arch/arm/kernel/process.c | 3 +- arch/arm/mach-integrator/cpu.c | 2 +- arch/arm/mach-sa1100/cpu-sa1100.c | 2 +- arch/arm/mach-sa1100/cpu-sa1110.c | 2 +- arch/arm/tools/mach-types | 12 +- arch/arm/vmlinux-armo.lds.in | 17 +- arch/arm/vmlinux-armv.lds.in | 23 +- arch/cris/vmlinux.lds.S | 14 +- arch/i386/Kconfig | 2 + arch/i386/Makefile | 4 + arch/i386/defconfig | 10 +- arch/i386/kernel/acpi.c | 8 +- arch/i386/kernel/cpu/amd.c | 2 +- arch/i386/kernel/cpu/cpufreq/gx-suspmod.c | 1 + arch/i386/kernel/cpu/proc.c | 2 +- arch/i386/kernel/entry.S | 14 +- arch/i386/kernel/io_apic.c | 16 +- arch/i386/kernel/mpparse.c | 6 +- arch/i386/kernel/smp.c | 1 + arch/i386/kernel/smpboot.c | 4 +- arch/i386/vmlinux.lds.S | 19 +- arch/ia64/defconfig | 10 +- arch/ia64/vmlinux.lds.S | 26 +- arch/m68k/Kconfig | 25 + arch/m68k/atari/stram.c | 4 +- arch/m68k/kernel/m68k_defs.c | 2 +- arch/m68k/kernel/m68k_ksyms.c | 3 + arch/m68k/kernel/setup.c | 1 + arch/m68k/mm/extable.c | 94 +- arch/m68k/mm/fault.c | 7 +- arch/m68k/q40/config.c | 44 + arch/m68k/q40/q40ints.c | 221 +-- arch/m68k/vmlinux-std.lds | 13 +- arch/m68k/vmlinux-sun3.lds | 15 +- arch/m68knommu/kernel/Makefile | 5 +- arch/m68knommu/platform/5307/entry.S | 834 ++++------ arch/m68knommu/platform/68328/entry.S | 309 +--- arch/m68knommu/platform/68360/entry.S | 215 +-- arch/m68knommu/platform/68EZ328/ucsimm/crt0_ram.S | 11 +- arch/m68knommu/platform/68VZ328/de2/himem.ld | 11 - arch/m68knommu/platform/68VZ328/ucdimm/crt0_ram.S | 11 +- arch/m68knommu/vmlinux.lds.S | 10 +- arch/mips/Kconfig-shared | 2 + arch/mips/defconfig | 7 +- arch/mips/defconfig-atlas | 6 - arch/mips/defconfig-capcella | 6 - arch/mips/defconfig-cobalt | 6 - arch/mips/defconfig-ddb5476 | 7 +- arch/mips/defconfig-ddb5477 | 16 +- arch/mips/defconfig-decstation | 6 - arch/mips/defconfig-e55 | 7 +- arch/mips/defconfig-eagle | 7 +- arch/mips/defconfig-ev64120 | 6 - arch/mips/defconfig-ev96100 | 6 - arch/mips/defconfig-hp-lj | 6 - arch/mips/defconfig-ip22 | 7 +- arch/mips/defconfig-it8172 | 16 +- arch/mips/defconfig-ivr | 6 - arch/mips/defconfig-jmr3927 | 6 - arch/mips/defconfig-lasat200 | 6 - arch/mips/defconfig-malta | 6 - arch/mips/defconfig-mpc30x | 7 +- arch/mips/defconfig-nino | 6 - arch/mips/defconfig-ocelot | 6 - arch/mips/defconfig-osprey | 6 - arch/mips/defconfig-pb1000 | 14 +- arch/mips/defconfig-pb1100 | 14 +- arch/mips/defconfig-pb1500 | 7 +- arch/mips/defconfig-rm200 | 7 +- arch/mips/defconfig-sb1250-swarm | 7 +- arch/mips/defconfig-sead | 6 - arch/mips/defconfig-tb0226 | 14 +- arch/mips/defconfig-tb0229 | 6 - arch/mips/defconfig-workpad | 7 +- arch/mips/vmlinux.lds.S | 17 +- arch/mips64/defconfig | 6 - arch/mips64/defconfig-atlas | 6 - arch/mips64/defconfig-decstation | 6 - arch/mips64/defconfig-ip22 | 7 +- arch/mips64/defconfig-ip27 | 6 - arch/mips64/defconfig-ip32 | 6 - arch/mips64/defconfig-malta | 6 - arch/mips64/defconfig-rm200 | 7 +- arch/mips64/defconfig-sb1250-swarm | 7 +- arch/mips64/defconfig-sead | 6 - arch/mips64/kernel/scall_o32.S | 4 +- arch/mips64/kernel/signal32.c | 81 +- arch/mips64/vmlinux.lds.S | 17 +- arch/parisc/defconfig | 8 +- arch/parisc/vmlinux.lds.S | 27 +- arch/ppc/Makefile | 1 + arch/ppc/boot/common/cpc700_memory.c | 10 +- arch/ppc/boot/common/misc-common.c | 25 +- arch/ppc/boot/common/mpc10x_memory.c | 10 +- arch/ppc/boot/common/util.S | 10 +- arch/ppc/boot/include/mpc10x.h | 10 +- arch/ppc/boot/ld.script | 2 +- arch/ppc/boot/simple/Makefile | 10 +- arch/ppc/boot/simple/gt64260_tty.c | 10 +- arch/ppc/boot/simple/head.S | 10 +- arch/ppc/boot/simple/misc-ev64260.S | 10 +- arch/ppc/boot/simple/misc-spruce.c | 25 +- arch/ppc/boot/simple/misc.c | 10 +- arch/ppc/boot/simple/relocate.S | 10 +- arch/ppc/boot/utils/mkbugboot.c | 10 +- arch/ppc/kernel/asm-offsets.c | 5 + arch/ppc/kernel/entry.S | 192 ++- arch/ppc/kernel/head.S | 2 - arch/ppc/kernel/head_4xx.S | 169 +- arch/ppc/kernel/ptrace.c | 21 +- arch/ppc/kernel/smp.c | 10 +- arch/ppc/kernel/traps.c | 22 +- arch/ppc/ocp/Makefile | 14 + arch/ppc/ocp/ocp-driver.c | 195 +++ arch/ppc/ocp/ocp-probe.c | 114 ++ arch/ppc/ocp/ocp.c | 109 ++ arch/ppc/platforms/4xx/ash.c | 12 +- arch/ppc/platforms/4xx/ash.h | 18 +- arch/ppc/platforms/4xx/cedar.c | 11 +- arch/ppc/platforms/4xx/cedar.h | 18 +- arch/ppc/platforms/4xx/ep405.c | 12 +- arch/ppc/platforms/4xx/ep405.h | 14 +- arch/ppc/platforms/4xx/ibm405gp.c | 73 +- arch/ppc/platforms/4xx/ibm405gp.h | 35 +- arch/ppc/platforms/4xx/ibm405gpr.c | 74 +- arch/ppc/platforms/4xx/ibm405gpr.h | 33 +- arch/ppc/platforms/4xx/ibmnp405h.c | 33 +- arch/ppc/platforms/4xx/ibmnp405h.h | 35 +- arch/ppc/platforms/4xx/ibmnp405l.c | 83 +- arch/ppc/platforms/4xx/ibmnp405l.h | 35 +- arch/ppc/platforms/4xx/ibmnp4gs.c | 63 +- arch/ppc/platforms/4xx/ibmnp4gs.h | 31 +- arch/ppc/platforms/4xx/ibmstb3.c | 69 +- arch/ppc/platforms/4xx/ibmstb3.h | 37 +- arch/ppc/platforms/4xx/ibmstb4.c | 75 +- arch/ppc/platforms/4xx/ibmstb4.h | 35 +- arch/ppc/platforms/4xx/ibmstbx25.c | 81 +- arch/ppc/platforms/4xx/ibmstbx25.h | 33 +- arch/ppc/platforms/4xx/redwood.c | 12 +- arch/ppc/platforms/4xx/redwood.h | 17 +- arch/ppc/platforms/4xx/redwood5.c | 14 +- arch/ppc/platforms/4xx/redwood5.h | 17 +- arch/ppc/platforms/4xx/redwood6.c | 33 +- arch/ppc/platforms/4xx/redwood6.h | 38 +- arch/ppc/platforms/4xx/sycamore.c | 16 +- arch/ppc/platforms/4xx/sycamore.h | 20 +- arch/ppc/platforms/4xx/walnut.c | 22 +- arch/ppc/platforms/4xx/walnut.h | 26 +- arch/ppc/platforms/ev64260.h | 10 +- arch/ppc/platforms/ev64260_setup.c | 10 +- arch/ppc/platforms/k2.h | 10 +- arch/ppc/platforms/k2_pci.c | 10 +- arch/ppc/platforms/k2_setup.c | 10 +- arch/ppc/platforms/lopec_pci.c | 10 +- arch/ppc/platforms/lopec_serial.h | 10 +- arch/ppc/platforms/lopec_setup.c | 10 +- arch/ppc/platforms/mcpn765.h | 10 +- arch/ppc/platforms/mcpn765_pci.c | 10 +- arch/ppc/platforms/mcpn765_serial.h | 10 +- arch/ppc/platforms/mcpn765_setup.c | 10 +- arch/ppc/platforms/menf1.h | 10 +- arch/ppc/platforms/menf1_pci.c | 10 +- arch/ppc/platforms/menf1_setup.c | 12 +- arch/ppc/platforms/mvme5100.h | 10 +- arch/ppc/platforms/mvme5100_pci.c | 10 +- arch/ppc/platforms/mvme5100_serial.h | 10 +- arch/ppc/platforms/mvme5100_setup.c | 10 +- arch/ppc/platforms/pal4.h | 10 +- arch/ppc/platforms/pal4_pci.c | 10 +- arch/ppc/platforms/pal4_serial.h | 10 +- arch/ppc/platforms/pal4_setup.c | 10 +- arch/ppc/platforms/pcore.h | 10 +- arch/ppc/platforms/pcore_pci.c | 10 +- arch/ppc/platforms/pcore_setup.c | 10 +- arch/ppc/platforms/powerpmc250.c | 10 +- arch/ppc/platforms/powerpmc250.h | 10 +- arch/ppc/platforms/powerpmc250_serial.h | 10 +- arch/ppc/platforms/pplus_pci.c | 14 +- arch/ppc/platforms/pplus_setup.c | 14 +- arch/ppc/platforms/prpmc750_pci.c | 10 +- arch/ppc/platforms/prpmc750_serial.h | 10 +- arch/ppc/platforms/prpmc750_setup.c | 10 +- arch/ppc/platforms/prpmc800.h | 10 +- arch/ppc/platforms/prpmc800_pci.c | 10 +- arch/ppc/platforms/prpmc800_serial.h | 12 +- arch/ppc/platforms/prpmc800_setup.c | 10 +- arch/ppc/platforms/sandpoint.h | 10 +- arch/ppc/platforms/sandpoint_pci.c | 10 +- arch/ppc/platforms/sandpoint_serial.h | 10 +- arch/ppc/platforms/sandpoint_setup.c | 10 +- arch/ppc/platforms/spruce.h | 25 +- arch/ppc/platforms/spruce_pci.c | 25 +- arch/ppc/platforms/spruce_serial.h | 25 +- arch/ppc/platforms/spruce_setup.c | 25 +- arch/ppc/platforms/zx4500.h | 10 +- arch/ppc/platforms/zx4500_pci.c | 10 +- arch/ppc/platforms/zx4500_serial.h | 12 +- arch/ppc/platforms/zx4500_setup.c | 10 +- arch/ppc/syslib/cpc700.h | 27 +- arch/ppc/syslib/cpc700_pic.c | 27 +- arch/ppc/syslib/cpc710.h | 12 +- arch/ppc/syslib/gt64260_common.c | 12 +- arch/ppc/syslib/gt64260_pic.c | 12 +- arch/ppc/syslib/harrier.c | 12 +- arch/ppc/syslib/mpc10x_common.c | 13 +- arch/ppc/syslib/pci_auto.c | 12 +- arch/ppc/syslib/ppc405_pci.c | 37 +- arch/ppc/syslib/ppc4xx_dma.c | 33 +- arch/ppc/syslib/ppc4xx_pm.c | 122 +- arch/ppc/syslib/ppc4xx_serial.c | 35 +- arch/ppc/syslib/pplus_common.c | 12 +- arch/ppc/syslib/todc_time.c | 12 +- arch/ppc/vmlinux.lds.S | 23 +- arch/ppc64/boot/zImage.lds | 1 + arch/ppc64/kernel/Makefile | 3 +- arch/ppc64/kernel/entry.S | 15 +- arch/ppc64/kernel/ioctl32.c | 3 +- arch/ppc64/kernel/misc.S | 26 +- arch/ppc64/kernel/module.c | 464 ++++++ arch/ppc64/kernel/ppc_ksyms.c | 13 +- arch/ppc64/kernel/process.c | 6 + arch/ppc64/kernel/signal.c | 182 +-- arch/ppc64/kernel/signal32.c | 40 +- arch/ppc64/kernel/sys32.S | 279 ++-- arch/ppc64/kernel/sys_ppc32.c | 413 +---- arch/ppc64/mm/extable.c | 7 +- arch/ppc64/vmlinux.lds.S | 22 +- arch/s390/vmlinux.lds.S | 15 +- arch/s390x/kernel/entry.S | 4 +- arch/s390x/kernel/linux32.c | 52 +- arch/s390x/kernel/linux32.h | 15 +- arch/s390x/kernel/signal32.c | 15 +- arch/s390x/kernel/wrapper32.S | 18 +- arch/s390x/vmlinux.lds.S | 15 +- arch/sh/vmlinux.lds.S | 16 +- arch/sparc/vmlinux.lds.S | 19 +- arch/sparc64/Kconfig | 33 + arch/sparc64/defconfig | 20 +- arch/sparc64/kernel/Makefile | 1 + arch/sparc64/kernel/setup.c | 19 + arch/sparc64/kernel/sys_sparc32.c | 25 +- arch/sparc64/kernel/us3_cpufreq.c | 319 ++++ arch/sparc64/vmlinux.lds.S | 19 +- arch/um/uml.lds.S | 11 +- arch/v850/vmlinux.lds.S | 11 +- arch/x86_64/Kconfig | 77 +- arch/x86_64/Makefile | 34 +- arch/x86_64/boot/Makefile | 10 +- arch/x86_64/boot/compressed/Makefile | 2 +- arch/x86_64/defconfig | 41 +- arch/x86_64/ia32/fpu32.c | 6 +- arch/x86_64/ia32/ia32_signal.c | 70 +- arch/x86_64/ia32/ia32entry.S | 6 +- arch/x86_64/ia32/sys_ia32.c | 52 - arch/x86_64/ia32/syscall32.c | 30 +- arch/x86_64/kernel/Makefile | 3 +- arch/x86_64/kernel/apic.c | 13 +- arch/x86_64/kernel/entry.S | 4 +- arch/x86_64/kernel/head.S | 31 +- arch/x86_64/kernel/module.c | 108 +- arch/x86_64/kernel/process.c | 26 +- arch/x86_64/kernel/ptrace.c | 19 + arch/x86_64/kernel/setup64.c | 2 +- arch/x86_64/kernel/smpboot.c | 8 - arch/x86_64/kernel/traps.c | 6 +- arch/x86_64/lib/Makefile | 15 +- arch/x86_64/lib/usercopy.c | 21 +- arch/x86_64/mm/Makefile | 2 +- arch/x86_64/mm/init.c | 3 - arch/x86_64/mm/modutil.c | 127 -- arch/x86_64/pci/Makefile | 18 +- arch/x86_64/vmlinux.lds.S | 27 +- crypto/Kconfig | 12 + crypto/Makefile | 1 + crypto/des.c | 4 +- crypto/sha512.c | 373 +++++ crypto/tcrypt.c | 116 +- crypto/tcrypt.h | 109 ++ drivers/Makefile | 1 + drivers/acorn/block/fd1772.c | 38 +- drivers/atm/nicstar.c | 3 - drivers/base/bus.c | 36 +- drivers/base/node.c | 4 +- drivers/block/elevator.c | 8 +- drivers/char/Kconfig | 2 +- drivers/char/agp/agp.h | 58 +- drivers/char/agp/ali-agp.c | 10 +- drivers/char/agp/amd-k7-agp.c | 14 +- drivers/char/agp/amd-k8-agp.c | 82 +- drivers/char/agp/backend.c | 41 +- drivers/char/agp/frontend.c | 4 +- drivers/char/agp/generic.c | 161 +- drivers/char/agp/hp-agp.c | 9 +- drivers/char/agp/i460-agp.c | 9 +- drivers/char/agp/i7x05-agp.c | 10 +- drivers/char/agp/intel-agp.c | 14 +- drivers/char/agp/sis-agp.c | 10 +- drivers/char/agp/sworks-agp.c | 121 +- drivers/char/agp/via-agp.c | 10 +- drivers/char/agp/via-kt400.c | 10 +- drivers/char/i8k.c | 8 +- drivers/char/pcmcia/synclink_cs.c | 10 +- drivers/char/synclink.c | 11 +- drivers/char/synclinkmp.c | 10 +- drivers/char/tty_io.c | 14 +- drivers/char/watchdog/acquirewdt.c | 14 +- drivers/char/watchdog/advantechwdt.c | 210 +-- drivers/char/watchdog/alim7101_wdt.c | 14 +- drivers/char/watchdog/eurotechwdt.c | 156 +- drivers/char/watchdog/i810-tco.c | 3 - drivers/char/watchdog/ib700wdt.c | 73 +- drivers/char/watchdog/indydog.c | 2 +- drivers/char/watchdog/machzwd.c | 12 +- drivers/char/watchdog/mixcomwd.c | 4 - drivers/char/watchdog/pcwd.c | 10 - drivers/char/watchdog/sa1100_wdt.c | 1 - drivers/char/watchdog/sbc60xxwdt.c | 13 +- drivers/char/watchdog/sc1200wdt.c | 9 +- drivers/char/watchdog/sc520_wdt.c | 14 +- drivers/char/watchdog/scx200_wdt.c | 6 +- drivers/char/watchdog/shwdt.c | 1 - drivers/char/watchdog/softdog.c | 57 +- drivers/char/watchdog/w83877f_wdt.c | 16 +- drivers/char/watchdog/wafer5823wdt.c | 5 +- drivers/char/watchdog/wdt.c | 44 +- drivers/char/watchdog/wdt285.c | 23 +- drivers/char/watchdog/wdt977.c | 1 - drivers/char/watchdog/wdt_pci.c | 133 +- drivers/eisa/Kconfig | 20 + drivers/eisa/Makefile | 18 + drivers/eisa/eisa-bus.c | 218 +++ drivers/eisa/eisa.ids | 1155 +++++++++++++ drivers/hotplug/acpiphp_glue.c | 45 +- drivers/ide/Kconfig | 2 +- drivers/input/keyboard/amikbd.c | 2 +- drivers/input/serio/q40kbd.c | 16 +- drivers/isdn/hisax/config.c | 2 +- drivers/isdn/hisax/hisax_fcpcipnp.c | 2 +- drivers/isdn/i4l/isdn_ppp_ccp.c | 2 +- drivers/media/video/cpia.h | 26 +- drivers/media/video/cpia_pp.c | 22 +- drivers/media/video/cpia_usb.c | 11 +- drivers/net/3c501.c | 4 - drivers/net/3c509.c | 336 ++-- drivers/net/3c515.c | 1 - drivers/net/3c527.c | 1 - drivers/net/3c59x.c | 259 +-- drivers/net/Space.c | 4 - drivers/net/appletalk/cops.c | 1 - drivers/net/hamachi.c | 1 - drivers/net/isa-skeleton.c | 1 - drivers/net/myri_sbus.c | 1 - drivers/net/pcnet32.c | 1 - drivers/net/ptifddi.c | 1 - drivers/net/seeq8005.c | 4 - drivers/net/sk_mca.c | 5 - drivers/net/smc9194.c | 1 - drivers/net/sundance.c | 1 - drivers/net/tc35815.c | 1 - drivers/net/tulip/winbond-840.c | 1 - drivers/net/via-rhine.c | 6 + drivers/net/wan/sbni.c | 1 - drivers/parisc/Kconfig | 2 + drivers/pcmcia/cardbus.c | 16 +- drivers/s390/cio/chsc.c | 8 +- drivers/s390/net/ctcmain.c | 10 +- drivers/s390/net/cu3088.c | 6 +- drivers/s390/net/netiucv.c | 4 +- drivers/sbus/char/display7seg.c | 13 +- drivers/scsi/mac_scsi.c | 1266 +++++++------- drivers/scsi/mac_scsi.h | 32 +- drivers/scsi/pcmcia/aha152x_stub.c | 3 + drivers/scsi/pcmcia/fdomain_stub.c | 3 + drivers/scsi/pcmcia/qlogic_stub.c | 3 + drivers/scsi/scsi_debug.c | 52 +- drivers/serial/sunsab.c | 2 +- drivers/usb/class/bluetty.c | 7 +- drivers/usb/class/cdc-acm.c | 4 +- drivers/usb/core/hcd.c | 2 +- drivers/usb/core/hcd.h | 3 - drivers/usb/core/usb.c | 1 + drivers/usb/misc/speedtouch.c | 45 +- drivers/usb/serial/bus.c | 13 + drivers/usb/serial/usb-serial.c | 1 + drivers/usb/storage/scsiglue.c | 4 + drivers/video/Kconfig | 2 +- drivers/video/Makefile | 15 +- drivers/video/acornfb.c | 594 ++----- drivers/video/aty/atyfb.h | 1 + drivers/video/aty/atyfb_base.c | 92 +- drivers/video/aty/mach64_accel.c | 12 + drivers/video/cfbcopyarea.c | 85 +- drivers/video/cfbfillrect.c | 22 +- drivers/video/cfbimgblt.c | 146 +- drivers/video/console/Kconfig | 14 +- drivers/video/console/fbcon.c | 91 +- drivers/video/console/sticon.c | 101 +- drivers/video/console/sticore.c | 171 +- drivers/video/fbmem.c | 17 +- drivers/video/fbmon.c | 383 +++++ drivers/video/i810/i810.h | 2 - drivers/video/i810/i810_accel.c | 11 +- drivers/video/i810/i810_dvt.c | 2 +- drivers/video/i810/i810_main.c | 51 +- drivers/video/i810/i810_main.h | 79 +- drivers/video/riva/Makefile | 2 +- drivers/video/riva/fbdev.c | 1720 ++++++++++---------- drivers/video/riva/nv_driver.c | 212 +++ drivers/video/riva/riva_hw.c | 350 +++- drivers/video/riva/rivafb.h | 15 +- drivers/video/sa1100fb.h | 4 +- drivers/video/sstfb.c | 705 ++++---- drivers/video/sstfb.h | 31 +- drivers/video/sticore.h | 54 +- drivers/video/stifb.c | 103 +- drivers/video/tdfxfb.c | 12 +- drivers/video/tridentfb.c | 1215 +++++++------- fs/block_dev.c | 57 +- fs/devfs/Makefile | 44 +- fs/devfs/base.c | 18 +- fs/devfs/internal.h | 3 + fs/devfs/util.c | 224 +-- fs/devpts/inode.c | 2 +- fs/exec.c | 2 + fs/ext3/ialloc.c | 28 +- fs/ext3/inode.c | 36 +- fs/ext3/namei.c | 16 +- fs/hugetlbfs/inode.c | 3 - fs/intermezzo/vfs.c | 11 +- fs/jbd/checkpoint.c | 1 - fs/jbd/commit.c | 33 - fs/jbd/transaction.c | 38 +- fs/partitions/sgi.c | 40 +- fs/proc/Makefile | 6 + fs/proc/array.c | 260 +-- fs/proc/base.c | 6 - fs/proc/inode.c | 7 +- fs/proc/proc_misc.c | 3 +- fs/proc/task_mmu.c | 247 +++ fs/proc/task_nommu.c | 107 ++ fs/quota.c | 54 +- fs/xfs/linux/xfs_linux.h | 2 +- fs/xfs/linux/xfs_lrw.c | 7 +- fs/xfs/linux/xfs_vnode.h | 3 +- fs/xfs/pagebuf/page_buf.c | 6 +- fs/xfs/support/debug.c | 38 +- fs/xfs/xfs_dir.c | 6 - fs/xfs/xfs_dir2.c | 8 +- fs/xfs/xfs_inode.h | 7 +- fs/xfs/xfs_log_recover.c | 10 +- fs/xfs/xfs_rename.c | 53 +- fs/xfs/xfs_utils.c | 4 +- fs/xfs/xfs_vfsops.c | 4 +- fs/xfs/xfs_vnodeops.c | 59 +- include/asm-alpha/agp.h | 2 + include/asm-alpha/agp_backend.h | 43 + include/asm-alpha/console.h | 5 + include/asm-alpha/core_marvel.h | 579 +++++++ include/asm-alpha/core_titan.h | 18 +- include/asm-alpha/gct.h | 58 + include/asm-alpha/hardirq.h | 8 +- include/asm-alpha/hwrpb.h | 1 + include/asm-alpha/ide.h | 2 +- include/asm-alpha/io.h | 26 +- include/asm-alpha/irq.h | 5 +- include/asm-alpha/machvec.h | 10 + include/asm-alpha/mmzone.h | 247 +-- include/asm-alpha/numnodes.h | 8 +- include/asm-alpha/pci.h | 2 + include/asm-alpha/pgalloc.h | 3 +- include/asm-alpha/pgtable.h | 32 +- include/asm-alpha/smp.h | 15 +- include/asm-alpha/system.h | 2 +- include/asm-alpha/topology.h | 65 +- include/asm-arm/arch-integrator/memory.h | 6 +- include/asm-arm/ide.h | 2 - include/asm-arm/unistd.h | 64 +- include/asm-generic/topology.h | 5 + include/asm-generic/vmlinux.lds.h | 33 + include/asm-i386/apicdef.h | 9 +- include/asm-i386/mach-bigsmp/mach_apic.h | 15 +- include/asm-i386/mach-default/mach_apic.h | 10 + include/asm-i386/mach-default/mach_mpparse.h | 6 + include/asm-i386/mach-numaq/mach_apic.h | 11 + include/asm-i386/mach-numaq/mach_mpparse.h | 5 + include/asm-i386/mach-summit/mach_apic.h | 59 +- include/asm-i386/mach-summit/mach_mpparse.h | 10 +- include/asm-i386/module.h | 44 + include/asm-i386/mpspec.h | 6 +- include/asm-i386/smp.h | 12 - include/asm-i386/topology.h | 3 + include/asm-ia64/topology.h | 3 + include/asm-m68k/machdep.h | 1 + include/asm-m68k/mmu_context.h | 2 + include/asm-m68k/q40ints.h | 24 +- include/asm-m68k/rtc.h | 17 +- include/asm-m68k/uaccess.h | 3 - include/asm-m68knommu/bug.h | 12 + include/asm-m68knommu/entry.h | 317 ++-- include/asm-m68knommu/page.h | 22 - include/asm-mips64/compat.h | 7 + include/asm-mips64/signal.h | 9 - include/asm-ppc/gt64260.h | 10 +- include/asm-ppc/gt64260_defs.h | 10 +- include/asm-ppc/harrier.h | 12 +- include/asm-ppc/ibm403.h | 35 +- include/asm-ppc/ibm405.h | 34 +- include/asm-ppc/ibm_ocp_pci.h | 88 +- include/asm-ppc/mpc10x.h | 10 +- include/asm-ppc/ppc405_dma.h | 18 +- include/asm-ppc/pplus.h | 12 +- include/asm-ppc/processor.h | 9 + include/asm-ppc/rtc.h | 10 +- include/asm-ppc/todc.h | 10 +- include/asm-ppc64/bug.h | 33 + include/asm-ppc64/module.h | 40 +- include/asm-ppc64/page.h | 23 - include/asm-ppc64/topology.h | 3 + include/asm-s390x/compat.h | 9 +- include/asm-sparc64/bug.h | 3 + include/asm-x86_64/bug.h | 24 + include/asm-x86_64/compat.h | 13 + include/asm-x86_64/ia32.h | 13 - include/asm-x86_64/mmu_context.h | 5 +- include/asm-x86_64/page.h | 16 +- include/asm-x86_64/proto.h | 6 + include/asm-x86_64/ptrace.h | 4 + include/asm-x86_64/segment.h | 2 +- include/asm-x86_64/uaccess.h | 2 +- include/linux/compat.h | 6 + include/linux/cpufreq.h | 2 +- include/linux/devfs_fs_kernel.h | 30 - include/linux/eisa.h | 60 + include/linux/ext3_fs.h | 2 +- include/linux/ext3_jbd.h | 12 - include/linux/fb.h | 13 + include/linux/font.h | 30 +- include/linux/fs.h | 6 +- include/linux/i2c.h | 8 - include/linux/jbd.h | 28 +- include/linux/kobject.h | 2 +- include/linux/miscdevice.h | 1 + include/linux/mm.h | 7 +- include/linux/mmzone.h | 3 +- include/linux/module.h | 27 +- include/linux/netdevice.h | 1 + include/linux/sched.h | 11 + include/linux/tty_driver.h | 1 + include/linux/usb.h | 4 +- include/linux/xattr.h | 2 +- include/video/font.h | 24 - .../video/tridentfb.h => include/video/trident.h | 30 +- init/Kconfig | 57 +- init/Makefile | 3 +- init/main.c | 1 + init/vermagic.c | 22 + kernel/compat.c | 44 +- kernel/exit.c | 19 +- kernel/fork.c | 16 + kernel/kallsyms.c | 11 +- kernel/module.c | 28 +- kernel/sched.c | 186 ++- lib/kobject.c | 4 +- mm/mmap.c | 8 +- mm/page_alloc.c | 8 +- mm/readahead.c | 5 +- net/atm/mpc.c | 4 - net/core/dev.c | 12 + net/core/rtnetlink.c | 17 +- net/netsyms.c | 2 + net/sunrpc/rpc_pipe.c | 15 +- scripts/Makefile.build | 13 +- scripts/kallsyms.c | 2 +- scripts/per-cpu-check.awk | 2 +- sound/Kconfig | 26 +- sound/oss/soundcard.c | 3 - 617 files changed, 17883 insertions(+), 12050 deletions(-) create mode 100644 arch/alpha/kernel/core_marvel.c create mode 100644 arch/alpha/kernel/err_marvel.c create mode 100644 arch/alpha/kernel/err_titan.c create mode 100644 arch/alpha/kernel/gct.c create mode 100644 arch/alpha/kernel/sys_marvel.c rewrite arch/alpha/kernel/sys_titan.c (61%) create mode 100644 arch/alpha/mm/remap.c rewrite arch/m68k/mm/extable.c (64%) rewrite arch/m68knommu/platform/5307/entry.S (77%) delete mode 100644 arch/m68knommu/platform/68VZ328/de2/himem.ld create mode 100644 arch/ppc/ocp/Makefile create mode 100644 arch/ppc/ocp/ocp-driver.c create mode 100644 arch/ppc/ocp/ocp-probe.c create mode 100644 arch/ppc/ocp/ocp.c rewrite arch/ppc/platforms/4xx/ibm405gp.c (67%) rewrite arch/ppc/platforms/4xx/ibm405gpr.c (67%) rewrite arch/ppc/platforms/4xx/ibmnp405l.c (68%) rewrite arch/ppc/platforms/4xx/ibmnp4gs.c (84%) rewrite arch/ppc/platforms/4xx/ibmstb3.c (78%) rewrite arch/ppc/platforms/4xx/ibmstb4.c (71%) rewrite arch/ppc/platforms/4xx/ibmstbx25.c (61%) rewrite arch/ppc/syslib/ppc4xx_pm.c (75%) create mode 100644 arch/ppc64/kernel/module.c create mode 100644 arch/sparc64/kernel/us3_cpufreq.c delete mode 100644 arch/x86_64/mm/modutil.c create mode 100644 crypto/sha512.c create mode 100644 drivers/eisa/Kconfig create mode 100644 drivers/eisa/Makefile create mode 100644 drivers/eisa/eisa-bus.c create mode 100644 drivers/eisa/eisa.ids rewrite drivers/scsi/mac_scsi.c (63%) create mode 100644 drivers/video/riva/nv_driver.c rewrite fs/devfs/Makefile (82%) create mode 100644 fs/devfs/internal.h create mode 100644 fs/proc/task_mmu.c create mode 100644 fs/proc/task_nommu.c create mode 100644 include/asm-alpha/agp_backend.h create mode 100644 include/asm-alpha/core_marvel.h create mode 100644 include/asm-alpha/gct.h rewrite include/asm-alpha/mmzone.h (63%) rewrite include/asm-alpha/topology.h (73%) create mode 100644 include/asm-generic/vmlinux.lds.h create mode 100644 include/asm-m68knommu/bug.h rewrite include/asm-m68knommu/entry.h (71%) rewrite include/asm-ppc/ibm_ocp_pci.h (80%) create mode 100644 include/asm-ppc64/bug.h rewrite include/asm-ppc64/module.h (84%) create mode 100644 include/asm-x86_64/bug.h create mode 100644 include/linux/eisa.h delete mode 100644 include/video/font.h rename drivers/video/tridentfb.h => include/video/trident.h (84%) create mode 100644 init/vermagic.c diff --git a/Documentation/Changes b/Documentation/Changes index 8df1075acfe..df23c8f1833 100644 --- a/Documentation/Changes +++ b/Documentation/Changes @@ -52,7 +52,7 @@ o Gnu C 2.95.3 # gcc --version o Gnu make 3.78 # make --version o binutils 2.9.5.0.25 # ld -v o util-linux 2.10o # fdformat --version -o module-init-tools 0.9 # rmmod -V +o module-init-tools 0.9.8 # rmmod -V o e2fsprogs 1.29 # tune2fs o jfsutils 1.0.14 # fsck.jfs -V o reiserfsprogs 3.6.3 # reiserfsck -V 2>&1|grep reiserfsprogs diff --git a/Documentation/crypto/api-intro.txt b/Documentation/crypto/api-intro.txt index d2e805565bd..f6abc861c27 100644 --- a/Documentation/crypto/api-intro.txt +++ b/Documentation/crypto/api-intro.txt @@ -80,6 +80,10 @@ should also be added: alias digest_null crypto_null alias compress_null crypto_null +The SHA384 algorithm shares code within the SHA512 module, so you'll +also need: + alias sha384 sha512 + DEVELOPER NOTES @@ -182,7 +186,7 @@ Original developers of the crypto algorithms: Andrew Tridgell and Steve French (MD4) Colin Plumb (MD5) Steve Reid (SHA1) - Jean-Luc Cooke (SHA256) + Jean-Luc Cooke (SHA256, SHA384, SHA512) Kazunori Miyazawa / USAGI (HMAC) Matthew Skala (Twofish) Dag Arne Osvik (Serpent) @@ -201,9 +205,11 @@ Twofish algorithm contributors: Werner Koch Marc Mutz -SHA256 algorithm contributors: +SHA256/384/512 algorithm contributors: Andrew McDonald - + Kyle McMartin + Herbert Valerio Riedel + AES algorithm contributors: Alexander Kjeldaas Herbert Valerio Riedel diff --git a/Documentation/driver-model/bus.txt b/Documentation/driver-model/bus.txt index 59efde89a12..7ecb8301622 100644 --- a/Documentation/driver-model/bus.txt +++ b/Documentation/driver-model/bus.txt @@ -32,8 +32,8 @@ object of this type. They must initialize the name field, and may optionally initialize the match callback. struct bus_type pci_bus_type = { - name: "pci", - match: pci_bus_match, + .name = "pci", + .match = pci_bus_match, }; The structure should be exported to drivers in a header file: diff --git a/Documentation/driver-model/driver.txt b/Documentation/driver-model/driver.txt index 335bceb16d1..7d3f2a63c40 100644 --- a/Documentation/driver-model/driver.txt +++ b/Documentation/driver-model/driver.txt @@ -49,14 +49,14 @@ driver. This declaration is hypothetical only; it relies on the driver being converted completely to the new model. static struct device_driver eepro100_driver = { - name: "eepro100", - bus: &pci_bus_type, - devclass: ðernet_devclass, /* when it's implemented */ + .name = "eepro100", + .bus = &pci_bus_type, + .devclass = ðernet_devclass, /* when it's implemented */ - probe: eepro100_probe, - remove: eepro100_remove, - suspend: eepro100_suspend, - resume: eepro100_resume, + .probe = eepro100_probe, + .remove = eepro100_remove, + .suspend = eepro100_suspend, + .resume = eepro100_resume, }; Most drivers will not be able to be converted completely to the new @@ -81,15 +81,15 @@ A definition that included bus-specific fields would look something like (using the eepro100 driver again): static struct pci_driver eepro100_driver = { - id_table: eepro100_pci_tbl, - driver: { - name: "eepro100", - bus: &pci_bus_type, - devclass: ðernet_devclass, /* when it's implemented */ - probe: eepro100_probe, - remove: eepro100_remove, - suspend: eepro100_suspend, - resume: eepro100_resume, + .id_table = eepro100_pci_tbl, + .driver = { + .name = "eepro100", + .bus = &pci_bus_type, + .devclass = ðernet_devclass, /* when it's implemented */ + .probe = eepro100_probe, + .remove = eepro100_remove, + .suspend = eepro100_suspend, + .resume = eepro100_resume, }, }; diff --git a/Documentation/driver-model/overview.txt b/Documentation/driver-model/overview.txt index fb03153bf82..8d8d089e485 100644 --- a/Documentation/driver-model/overview.txt +++ b/Documentation/driver-model/overview.txt @@ -86,11 +86,11 @@ whole sysfs filesystem anywhere in userspace. This can be done permanently by providing the following entry into the /etc/fstab (under the provision that the mount point does exist, of course): -none /devices sysfs defaults 0 0 +none /sys sysfs defaults 0 0 Or by hand on the command line: -~: mount -t sysfs none /devices +# mount -t sysfs sysfs /devices Whenever a device is inserted into the tree, a directory is created for it. This directory may be populated at each layer of discovery - the global layer, diff --git a/Documentation/filesystems/sysfs.txt b/Documentation/filesystems/sysfs.txt index 328762afa86..9b9c223c270 100644 --- a/Documentation/filesystems/sysfs.txt +++ b/Documentation/filesystems/sysfs.txt @@ -6,12 +6,6 @@ Patrick Mochel 10 January 2003 -Note (17 Oct 2002): the name has just been changed from sysfs to -sysfs. Updates to the documentation will come soon; after the -conversion to use it is completely finished. - - - What it is: ~~~~~~~~~~~ @@ -271,8 +265,8 @@ for devices on that particular bus (this assmumes that drivers do not span multiple bus types). -More information can device-model specific features can be found in -Documentation/device-model/. +More information can driver-model specific features can be found in +Documentation/driver-model/. TODO: Finish this section. diff --git a/MAINTAINERS b/MAINTAINERS index efc3cbb4292..60525ebfa4c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1908,11 +1908,11 @@ W: http://pegasus2.sourceforge.net/ S: Maintained USB SCANNER DRIVER -P: Brian Beattie -M: beattie@beattie-home.net +P: Henning Meier-Geinitz +M: henning@meier-geinitz.de L: linux-usb-users@lists.sourceforge.net L: linux-usb-devel@lists.sourceforge.net -W: http://www.beattie-home.net/linux +W: http://www.meier-geinitz.de/kernel/ S: Maintained USB SE401 DRIVER diff --git a/Makefile b/Makefile index 9d2c4c8d86e..87687ecfb13 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 5 -SUBLEVEL = 58 +SUBLEVEL = 59 EXTRAVERSION = # *DOCUMENTATION* @@ -394,6 +394,17 @@ $(SUBDIRS): .hdepend prepare prepare: include/linux/version.h include/asm include/config/MARKER @echo ' Starting the build. KBUILD_BUILTIN=$(KBUILD_BUILTIN) KBUILD_MODULES=$(KBUILD_MODULES)' +# We need to build init/vermagic.o before descending since all modules +# (*.ko) need it already + +ifdef CONFIG_MODULES + +prepare: init/vermagic.o + +init/vermagic.o: include/linux/version.h + +endif + # This can be used by arch/$ARCH/Makefile to preprocess # their vmlinux.lds.S file diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index e01bb0f3cfd..f8a3ad80f5c 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig @@ -65,6 +65,7 @@ choice LX164 AlphaPC164-LX Miata Personal Workstation 433a, 433au, 500a, 500au, 600a, or 600au + Marvel AlphaServer ES47 / ES80 / GS1280 Mikasa AS 1000 Noname AXPpci33, UDB (Multia) Noritake AS 1000A, AS 600A, AS 800 @@ -75,7 +76,7 @@ choice Sable AS 2000, AS 2100 Shark DS 20L Takara Takara - Titan Privateer + Titan AlphaServer ES45 / DS25 Wildfire AlphaServer GS 40/80/160/320 If you don't know what to do, choose "generic". @@ -172,6 +173,11 @@ config ALPHA_LX164 A technical overview of this board is available at . +config ALPHA_MARVEL + bool "Marvel" + help + AlphaServer ES47 / ES80 / GS1280 based on EV7. + config ALPHA_MIATA bool "Miata" help @@ -238,6 +244,8 @@ config ALPHA_TAKARA config ALPHA_TITAN bool "Titan" + help + AlphaServer ES45/DS25 SMP based on EV68 and Titan chipset. config ALPHA_WILDFIRE bool "Wildfire" @@ -301,6 +309,11 @@ config PCI information about which PCI hardware does work under Linux and which doesn't. +config ALPHA_CORE_AGP + bool + depends on ALPHA_GENERIC || ALPHA_TITAN || ALPHA_MARVEL + default y + config ALPHA_NONAME bool depends on ALPHA_BOOK1 || ALPHA_NONAME_CH @@ -387,7 +400,7 @@ config ALPHA_PYXIS config ALPHA_EV6 bool - depends on ALPHA_NAUTILUS || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_SHARK || ALPHA_DP264 || ALPHA_EIGER + depends on ALPHA_NAUTILUS || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_SHARK || ALPHA_DP264 || ALPHA_EIGER || ALPHA_MARVEL default y config ALPHA_TSUNAMI @@ -397,11 +410,16 @@ config ALPHA_TSUNAMI config ALPHA_EV67 bool "EV67 (or later) CPU (speed > 600MHz)?" if ALPHA_DP264 || ALPHA_EIGER - default y if ALPHA_NAUTILUS || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_SHARK + default y if ALPHA_NAUTILUS || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_SHARK || ALPHA_MARVEL help Is this a machine based on the EV67 core? If in doubt, select N here and the machine will be treated as an EV6. +config ALPHA_EV7 + bool + depends on ALPHA_MARVEL + default y + config ALPHA_MCPCIA bool depends on ALPHA_RAWHIDE @@ -419,7 +437,7 @@ config ALPHA_IRONGATE config ALPHA_SRM bool "Use SRM as bootloader" if ALPHA_CABRIOLET || ALPHA_AVANTI_CH || ALPHA_EB64P || ALPHA_PC164 || ALPHA_TAKARA || ALPHA_EB164 || ALPHA_ALCOR || ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_NAUTILUS || ALPHA_NONAME - default y if ALPHA_JENSEN || ALPHA_MIKASA || ALPHA_SABLE || ALPHA_NORITAKE || ALPHA_DP264 || ALPHA_RAWHIDE || ALPHA_EIGER || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_SHARK + default y if ALPHA_JENSEN || ALPHA_MIKASA || ALPHA_SABLE || ALPHA_NORITAKE || ALPHA_DP264 || ALPHA_RAWHIDE || ALPHA_EIGER || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_SHARK || ALPHA_MARVEL ---help--- There are two different types of booting firmware on Alphas: SRM, which is command line driven, and ARC, which uses menus and arrow @@ -461,7 +479,7 @@ config ALPHA_BROKEN_IRQ_MASK config SMP bool "Symmetric multi-processing support" - depends on ALPHA_SABLE || ALPHA_RAWHIDE || ALPHA_DP264 || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_GENERIC || ALPHA_SHARK + depends on ALPHA_SABLE || ALPHA_RAWHIDE || ALPHA_DP264 || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_GENERIC || ALPHA_SHARK || ALPHA_MARVEL ---help--- This enables support for systems with more than one CPU. If you have a system with only one CPU, like most personal computers, say N. If @@ -535,6 +553,7 @@ config VERBOSE_MCHECK bool "Verbose Machine Checks" source "drivers/pci/Kconfig" +source "drivers/eisa/Kconfig" config HOTPLUG bool "Support for hot-pluggable devices" @@ -772,6 +791,15 @@ config IDE If unsure, say Y. +config IDE_MAX_HWIFS + int "Max IDE interfaces" + depends on IDE + default 4 + help + This is the maximum number of IDE hardware interfaces that will + be supported by the driver. Make sure it is at least as high as + the number IDE interfaces in your system. + source "drivers/ide/Kconfig" endmenu diff --git a/arch/alpha/Makefile b/arch/alpha/Makefile index d2fadd634e4..e7b10749f57 100644 --- a/arch/alpha/Makefile +++ b/arch/alpha/Makefile @@ -96,6 +96,10 @@ core-y += arch/alpha/kernel/ arch/alpha/mm/ core-$(CONFIG_MATHEMU) += arch/alpha/math-emu/ libs-y += arch/alpha/lib/ +# export what is needed by arch/alpha/boot/Makefile +LIBS_Y := $(patsubst %/, %/lib.a, $(libs-y)) +export LIBS_Y + boot := arch/alpha/boot #Default target when executing make with no arguments diff --git a/arch/alpha/boot/Makefile b/arch/alpha/boot/Makefile index ff36b472038..0529f4269cc 100644 --- a/arch/alpha/boot/Makefile +++ b/arch/alpha/boot/Makefile @@ -72,8 +72,11 @@ $(obj)/tools/bootph: $(obj)/bootpheader $(OBJSTRIP) FORCE LDFLAGS_bootloader := -static -uvsprintf -T #-N -relax LDFLAGS_bootpheader := -static -uvsprintf -T #-N -relax -$(obj)/bootloader: $(obj)/bootloader.lds $(obj)/head.o $(obj)/main.o FORCE +OBJ_bootlx := $(obj)/head.o $(obj)/main.o +OBJ_bootph := $(obj)/head.o $(obj)/bootp.o + +$(obj)/bootloader: $(obj)/bootloader.lds $(OBJ_bootlx) FORCE $(call if_changed,ld) -$(obj)/bootpheader: $(obj)/bootloader.lds $(obj)/head.o $(obj)/bootp.o FORCE +$(obj)/bootpheader: $(obj)/bootloader.lds $(OBJ_bootph) $(LIBS_Y) FORCE $(call if_changed,ld) diff --git a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile index d9523688bf6..ebabe031d41 100644 --- a/arch/alpha/kernel/Makefile +++ b/arch/alpha/kernel/Makefile @@ -6,7 +6,7 @@ EXTRA_TARGETS := head.o EXTRA_AFLAGS := $(CFLAGS) -export-objs := alpha_ksyms.o +export-objs := alpha_ksyms.o core_marvel.o core_titan.o obj-y := entry.o traps.o process.o init_task.o osf_sys.o irq.o \ irq_alpha.o signal.o setup.o ptrace.o time.o semaphore.o \ @@ -21,18 +21,19 @@ obj-$(CONFIG_MODULES) += module.o ifdef CONFIG_ALPHA_GENERIC obj-y += core_apecs.o core_cia.o core_irongate.o core_lca.o \ - core_mcpcia.o core_polaris.o core_t2.o core_tsunami.o \ - core_titan.o core_wildfire.o + core_marvel.o core_mcpcia.o core_polaris.o core_t2.o \ + core_tsunami.o core_titan.o core_wildfire.o obj-y += sys_alcor.o sys_cabriolet.o sys_dp264.o sys_eb64p.o sys_eiger.o \ - sys_jensen.o sys_miata.o sys_mikasa.o sys_nautilus.o sys_titan.o \ - sys_noritake.o sys_rawhide.o sys_ruffian.o sys_rx164.o \ - sys_sable.o sys_sio.o sys_sx164.o sys_takara.o \ - sys_wildfire.o + sys_jensen.o sys_marvel.o sys_miata.o sys_mikasa.o sys_nautilus.o \ + sys_titan.o sys_noritake.o sys_rawhide.o sys_ruffian.o sys_rx164.o \ + sys_sable.o sys_sio.o sys_sx164.o sys_takara.o sys_wildfire.o obj-y += irq_pyxis.o irq_i8259.o irq_srm.o -obj-y += es1888.o smc37c669.o smc37c93x.o ns87312.o +obj-y += err_titan.o err_marvel.o + +obj-y += es1888.o smc37c669.o smc37c93x.o ns87312.o gct.o else @@ -41,6 +42,7 @@ obj-$(CONFIG_ALPHA_APECS) += core_apecs.o obj-$(CONFIG_ALPHA_CIA) += core_cia.o obj-$(CONFIG_ALPHA_IRONGATE) += core_irongate.o obj-$(CONFIG_ALPHA_LCA) += core_lca.o +obj-$(CONFIG_ALPHA_MARVEL) += core_marvel.o gct.o obj-$(CONFIG_ALPHA_MCPCIA) += core_mcpcia.o obj-$(CONFIG_ALPHA_POLARIS) += core_polaris.o obj-$(CONFIG_ALPHA_T2) += core_t2.o @@ -62,11 +64,13 @@ obj-$(CONFIG_ALPHA_PC164) += sys_cabriolet.o irq_i8259.o irq_srm.o \ smc37c93x.o obj-$(CONFIG_ALPHA_DP264) += sys_dp264.o irq_i8259.o es1888.o smc37c669.o obj-$(CONFIG_ALPHA_SHARK) += sys_dp264.o irq_i8259.o es1888.o smc37c669.o -obj-$(CONFIG_ALPHA_TITAN) += sys_titan.o irq_i8259.o smc37c669.o +obj-$(CONFIG_ALPHA_TITAN) += sys_titan.o irq_i8259.o smc37c669.o \ + err_titan.o obj-$(CONFIG_ALPHA_EB64P) += sys_eb64p.o irq_i8259.o obj-$(CONFIG_ALPHA_EB66) += sys_eb64p.o irq_i8259.o obj-$(CONFIG_ALPHA_EIGER) += sys_eiger.o irq_i8259.o obj-$(CONFIG_ALPHA_JENSEN) += sys_jensen.o pci-noop.o irq_i8259.o +obj-$(CONFIG_ALPHA_MARVEL) += sys_marvel.o err_marvel.o obj-$(CONFIG_ALPHA_MIATA) += sys_miata.o irq_pyxis.o irq_i8259.o \ es1888.o smc37c669.o obj-$(CONFIG_ALPHA_MIKASA) += sys_mikasa.o irq_i8259.o irq_srm.o diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c index d571cc2877a..0689cfcca9d 100644 --- a/arch/alpha/kernel/alpha_ksyms.c +++ b/arch/alpha/kernel/alpha_ksyms.c @@ -217,17 +217,24 @@ EXPORT_SYMBOL(smp_call_function); EXPORT_SYMBOL(smp_call_function_on_cpu); EXPORT_SYMBOL(atomic_dec_and_lock); #ifdef CONFIG_DEBUG_SPINLOCK -EXPORT_SYMBOL(spin_unlock); +EXPORT_SYMBOL(_raw_spin_unlock); EXPORT_SYMBOL(debug_spin_lock); EXPORT_SYMBOL(debug_spin_trylock); #endif #ifdef CONFIG_DEBUG_RWLOCK -EXPORT_SYMBOL(write_lock); -EXPORT_SYMBOL(read_lock); +EXPORT_SYMBOL(_raw_write_lock); +EXPORT_SYMBOL(_raw_read_lock); #endif EXPORT_SYMBOL(cpu_present_mask); #endif /* CONFIG_SMP */ +/* + * NUMA specific symbols + */ +#ifdef CONFIG_DISCONTIGMEM +EXPORT_SYMBOL(node_data); +#endif /* CONFIG_DISCONTIGMEM */ + EXPORT_SYMBOL(rtc_lock); /* diff --git a/arch/alpha/kernel/core_marvel.c b/arch/alpha/kernel/core_marvel.c new file mode 100644 index 00000000000..075ed763112 --- /dev/null +++ b/arch/alpha/kernel/core_marvel.c @@ -0,0 +1,1121 @@ +/* + * linux/arch/alpha/kernel/core_marvel.c + * + * Code common to all Marvel based systems. + */ + +#include + +#define __EXTERN_INLINE inline +#include +#include +#undef __EXTERN_INLINE + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "proto.h" +#include "pci_impl.h" + + +/* + * Debug helpers + */ +#define DEBUG_CONFIG 0 + +#if DEBUG_CONFIG +# define DBG_CFG(args) printk args +#else +# define DBG_CFG(args) +#endif + + +/* + * Private data + */ +static struct io7 *io7_head = NULL; + + +/* + * Helper functions + */ +static unsigned long __attribute__ ((unused)) +read_ev7_csr(int pe, unsigned long offset) +{ + ev7_csr *ev7csr = EV7_CSR_KERN(pe, offset); + unsigned long q; + + mb(); + q = ev7csr->csr; + mb(); + + return q; +} + +static void __attribute__ ((unused)) +write_ev7_csr(int pe, unsigned long offset, unsigned long q) +{ + ev7_csr *ev7csr = EV7_CSR_KERN(pe, offset); + + mb(); + ev7csr->csr = q; + mb(); +} + +static char * __init +mk_resource_name(int pe, int port, char *str) +{ + char tmp[80]; + char *name; + + sprintf(tmp, "PCI %s PE %d PORT %d", str, pe, port); + name = alloc_bootmem(strlen(tmp) + 1); + strcpy(name, tmp); + + return name; +} + +inline struct io7 * +marvel_next_io7(struct io7 *prev) +{ + return (prev ? prev->next : io7_head); +} + +struct io7 * +marvel_find_io7(int pe) +{ + struct io7 *io7; + + for (io7 = io7_head; io7 && io7->pe != pe; io7 = io7->next) + continue; + + return io7; +} + +static struct io7 * __init +alloc_io7(unsigned int pe) +{ + struct io7 *io7; + struct io7 *insp; + int h; + + if (marvel_find_io7(pe)) { + printk(KERN_WARNING "IO7 at PE %d already allocated!\n", pe); + return NULL; + } + + io7 = alloc_bootmem(sizeof(*io7)); + io7->pe = pe; + io7->irq_lock = SPIN_LOCK_UNLOCKED; + + for (h = 0; h < 4; h++) { + io7->ports[h].io7 = io7; + io7->ports[h].port = h; + io7->ports[h].enabled = 0; /* default to disabled */ + } + + /* + * Insert in pe sorted order. + */ + if (NULL == io7_head) /* empty list */ + io7_head = io7; + else if (io7_head->pe > io7->pe) { /* insert at head */ + io7->next = io7_head; + io7_head = io7; + } else { /* insert at position */ + for (insp = io7_head; insp; insp = insp->next) { + if (insp->pe == io7->pe) { + printk(KERN_ERR "Too many IO7s at PE %d\n", + io7->pe); + return NULL; + } + + if (NULL == insp->next || + insp->next->pe > io7->pe) { /* insert here */ + io7->next = insp->next; + insp->next = io7; + break; + } + } + + if (NULL == insp) { /* couldn't insert ?!? */ + printk(KERN_WARNING "Failed to insert IO7 at PE %d " + " - adding at head of list\n", io7->pe); + io7->next = io7_head; + io7_head = io7; + } + } + + return io7; +} + +void +io7_clear_errors(struct io7 *io7) +{ + io7_port7_csrs *p7csrs; + io7_ioport_csrs *csrs; + int port; + + + /* + * First the IO ports. + */ + for (port = 0; port < 4; port++) { + csrs = IO7_CSRS_KERN(io7->pe, port); + + csrs->POx_ERR_SUM.csr = -1UL; + csrs->POx_TLB_ERR.csr = -1UL; + csrs->POx_SPL_COMPLT.csr = -1UL; + csrs->POx_TRANS_SUM.csr = -1UL; + } + + /* + * Then the common ones. + */ + p7csrs = IO7_PORT7_CSRS_KERN(io7->pe); + + p7csrs->PO7_ERROR_SUM.csr = -1UL; + p7csrs->PO7_UNCRR_SYM.csr = -1UL; + p7csrs->PO7_CRRCT_SYM.csr = -1UL; +} + + +/* + * IO7 PCI, PCI/X, AGP configuration. + */ +static void __init +io7_init_hose(struct io7 *io7, int port) +{ + static int hose_index = 0; + + struct pci_controller *hose = alloc_pci_controller(); + struct io7_port *io7_port = &io7->ports[port]; + io7_ioport_csrs *csrs = IO7_CSRS_KERN(io7->pe, port); + int i; + + hose->index = hose_index++; /* arbitrary */ + + /* + * We don't have an isa or legacy hose, but glibc expects to be + * able to use the bus == 0 / dev == 0 form of the iobase syscall + * to determine information about the i/o system. Since XFree86 + * relies on glibc's determination to tell whether or not to use + * sparse access, we need to point the pci_isa_hose at a real hose + * so at least that determination is correct. + */ + if (hose->index == 0) + pci_isa_hose = hose; + + io7_port->csrs = csrs; + io7_port->hose = hose; + hose->sysdata = io7_port; + + hose->io_space = alloc_resource(); + hose->mem_space = alloc_resource(); + + /* + * Base addresses for userland consumption. Since these are going + * to be mapped, they are pure physical addresses. + */ + hose->sparse_mem_base = hose->sparse_io_base = 0; + hose->dense_mem_base = IO7_MEM_PHYS(io7->pe, port); + hose->dense_io_base = IO7_IO_PHYS(io7->pe, port); + + /* + * Base addresses and resource ranges for kernel consumption. + */ + hose->config_space_base = (unsigned long)IO7_CONF_KERN(io7->pe, port); + + hose->io_space->start = (unsigned long)IO7_IO_KERN(io7->pe, port); + hose->io_space->end = hose->io_space->start + IO7_IO_SPACE - 1; + hose->io_space->name = mk_resource_name(io7->pe, port, "IO"); + hose->io_space->flags = IORESOURCE_IO; + + hose->mem_space->start = (unsigned long)IO7_MEM_KERN(io7->pe, port); + hose->mem_space->end = hose->mem_space->start + IO7_MEM_SPACE - 1; + hose->mem_space->name = mk_resource_name(io7->pe, port, "MEM"); + hose->mem_space->flags = IORESOURCE_MEM; + + if (request_resource(&ioport_resource, hose->io_space) < 0) + printk(KERN_ERR "Failed to request IO on hose %d\n", + hose->index); + if (request_resource(&iomem_resource, hose->mem_space) < 0) + printk(KERN_ERR "Failed to request MEM on hose %d\n", + hose->index); + + /* + * Save the existing DMA window settings for later restoration. + */ + for (i = 0; i < 4; i++) { + io7_port->saved_wbase[i] = csrs->POx_WBASE[i].csr; + io7_port->saved_wmask[i] = csrs->POx_WMASK[i].csr; + io7_port->saved_tbase[i] = csrs->POx_TBASE[i].csr; + } + + /* + * Set up the PCI to main memory translation windows. + * + * Window 0 is scatter-gather 8MB at 8MB + * Window 1 is direct access 1GB at 2GB + * Window 2 is scatter-gather (up-to) 1GB at 3GB + * Window 3 is disabled + */ + + /* + * TBIA before modifying windows. + */ + marvel_pci_tbi(hose, 0, -1); + + /* + * Set up window 0 for scatter-gather 8MB at 8MB. + */ + hose->sg_isa = iommu_arena_new_node(marvel_cpuid_to_nid(io7->pe), + hose, 0x00800000, 0x00800000, 0); + hose->sg_isa->align_entry = 8; /* cache line boundary */ + csrs->POx_WBASE[0].csr = + hose->sg_isa->dma_base | wbase_m_ena | wbase_m_sg; + csrs->POx_WMASK[0].csr = (hose->sg_isa->size - 1) & wbase_m_addr; + csrs->POx_TBASE[0].csr = virt_to_phys(hose->sg_isa->ptes); + + /* + * Set up window 1 for direct-mapped 1GB at 2GB. + */ + csrs->POx_WBASE[1].csr = __direct_map_base | wbase_m_ena; + csrs->POx_WMASK[1].csr = (__direct_map_size - 1) & wbase_m_addr; + csrs->POx_TBASE[1].csr = 0; + + /* + * Set up window 2 for scatter-gather (up-to) 1GB at 3GB. + */ + hose->sg_pci = iommu_arena_new_node(marvel_cpuid_to_nid(io7->pe), + hose, 0xc0000000, 0x40000000, 0); + hose->sg_pci->align_entry = 8; /* cache line boundary */ + csrs->POx_WBASE[2].csr = + hose->sg_pci->dma_base | wbase_m_ena | wbase_m_sg; + csrs->POx_WMASK[2].csr = (hose->sg_pci->size - 1) & wbase_m_addr; + csrs->POx_TBASE[2].csr = virt_to_phys(hose->sg_pci->ptes); + + /* + * Disable window 3. + */ + csrs->POx_WBASE[3].csr = 0; + + /* + * Make sure that the AGP Monster Window is disabled. + */ + csrs->POx_CTRL.csr &= ~(1UL << 61); + +#if 1 + printk("FIXME: disabling master aborts\n"); + csrs->POx_MSK_HEI.csr &= ~(3UL << 14); +#endif + /* + * TBIA after modifying windows. + */ + marvel_pci_tbi(hose, 0, -1); +} + +static void __init +marvel_init_io7(struct io7 *io7) +{ + int i; + + printk("Initializing IO7 at PID %d\n", io7->pe); + + /* + * Get the Port 7 CSR pointer. + */ + io7->csrs = IO7_PORT7_CSRS_KERN(io7->pe); + + /* + * Init this IO7's hoses. + */ + for (i = 0; i < IO7_NUM_PORTS; i++) { + io7_ioport_csrs *csrs = IO7_CSRS_KERN(io7->pe, i); + if (csrs->POx_CACHE_CTL.csr == 8) { + io7->ports[i].enabled = 1; + io7_init_hose(io7, i); + } + } +} + +void +marvel_io7_present(gct6_node *node) +{ + int pe; + + if (node->type != GCT_TYPE_HOSE || + node->subtype != GCT_SUBTYPE_IO_PORT_MODULE) + return; + + pe = (node->id >> 8) & 0xff; + printk("Found an IO7 at PID %d\n", pe); + + alloc_io7(pe); +} + +static void __init +marvel_init_vga_hose(void) +{ +#ifdef CONFIG_VGA_HOSE + u64 *pu64 = (u64 *)((u64)hwrpb + hwrpb->ctbt_offset); + + if (pu64[7] == 3) { /* TERM_TYPE == graphics */ + struct pci_controller *hose = NULL; + int h = (pu64[30] >> 24) & 0xff; /* TERM_OUT_LOC, hose # */ + struct io7 *io7; + int pid, port; + + /* FIXME - encoding is going to have to change for Marvel + * since hose will be able to overflow a byte... + * need to fix this decode when the console + * changes its encoding + */ + printk("console graphics is on hose %d (console)\n", h); + + /* + * The console's hose numbering is: + * + * hose: PID + * hose<1:0>: PORT + * + * We need to find the hose at that pid and port + */ + pid = h >> 2; + port = h & 3; + if ((io7 = marvel_find_io7(pid))) + hose = io7->ports[port].hose; + + if (hose) { + printk("Console graphics on hose %d\n", hose->index); + pci_vga_hose = hose; + } + } +#endif /* CONFIG_VGA_HOSE */ +} + +gct6_search_struct gct_wanted_node_list[] = { + { GCT_TYPE_HOSE, GCT_SUBTYPE_IO_PORT_MODULE, marvel_io7_present }, + { 0, 0, NULL } +}; + +/* + * In case the GCT is not complete, let the user specify PIDs with IO7s + * at boot time. Syntax is 'io7=a,b,c,...,n' where a-n are the PIDs (decimal) + * where IO7s are connected + */ +static int __init +marvel_specify_io7(char *str) +{ + unsigned long pid; + struct io7 *io7; + char *pchar; + + do { + pid = simple_strtoul(str, &pchar, 0); + if (pchar != str) { + printk("User-specified IO7 at PID %lu\n", pid); + io7 = alloc_io7(pid); + if (io7) marvel_init_io7(io7); + } + + if (pchar == str) pchar++; + str = pchar; + } while(*str); + + return 0; +} +__setup("io7=", marvel_specify_io7); + +void __init +marvel_init_arch(void) +{ + struct io7 *io7; + + /* With multiple PCI busses, we play with I/O as physical addrs. */ + ioport_resource.end = ~0UL; + iomem_resource.end = ~0UL; + + /* PCI DMA Direct Mapping is 1GB at 2GB. */ + __direct_map_base = 0x80000000; + __direct_map_size = 0x40000000; + + /* Parse the config tree. */ + gct6_find_nodes(GCT_NODE_PTR(0), gct_wanted_node_list); + + /* Init the io7s. */ + for (io7 = NULL; NULL != (io7 = marvel_next_io7(io7)); ) + marvel_init_io7(io7); + + /* Check for graphic console location (if any). */ + marvel_init_vga_hose(); +} + +void +marvel_kill_arch(int mode) +{ +} + + +/* + * PCI Configuration Space access functions + * + * Configuration space addresses have the following format: + * + * |2 2 2 2|1 1 1 1|1 1 1 1|1 1 + * |3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|R|R| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * n:24 reserved for hose base + * 23:16 bus number (8 bits = 128 possible buses) + * 15:11 Device number (5 bits) + * 10:8 function number + * 7:2 register number + * + * Notes: + * IO7 determines whether to use a type 0 or type 1 config cycle + * based on the bus number. Therefore the bus number must be set + * to 0 for the root bus on any hose. + * + * The function number selects which function of a multi-function device + * (e.g., SCSI and Ethernet). + * + */ + +static inline unsigned long +build_conf_addr(struct pci_controller *hose, u8 bus, + unsigned int devfn, int where) +{ + return (hose->config_space_base | (bus << 16) | (devfn << 8) | where); +} + +static unsigned long +mk_conf_addr(struct pci_bus *pbus, unsigned int devfn, int where) +{ + struct pci_controller *hose = pbus->sysdata; + struct io7_port *io7_port; + unsigned long addr = 0; + u8 bus = pbus->number; + + if (!hose) + return addr; + + /* Check for enabled. */ + io7_port = hose->sysdata; + if (!io7_port->enabled) + return addr; + + if (hose->first_busno == bus) { + /* Don't support idsel > 20 on primary bus. */ + if (devfn >= PCI_DEVFN(21, 0)) + return addr; + bus = 0; + } + + addr = build_conf_addr(hose, bus, devfn, where); + + DBG_CFG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr)); + return addr; +} + +static int +marvel_read_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 *value) +{ + unsigned long addr; + + if (0 == (addr = mk_conf_addr(bus, devfn, where))) + return PCIBIOS_DEVICE_NOT_FOUND; + + switch(size) { + case 1: + *value = __kernel_ldbu(*(vucp)addr); + break; + case 2: + *value = __kernel_ldwu(*(vusp)addr); + break; + case 4: + *value = *(vuip)addr; + break; + default: + return PCIBIOS_FUNC_NOT_SUPPORTED; + } + + return PCIBIOS_SUCCESSFUL; +} + +static int +marvel_write_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 value) +{ + unsigned long addr; + + if (0 == (addr = mk_conf_addr(bus, devfn, where))) + return PCIBIOS_DEVICE_NOT_FOUND; + + switch (size) { + case 1: + __kernel_stb(value, *(vucp)addr); + mb(); + __kernel_ldbu(*(vucp)addr); + break; + case 2: + __kernel_stw(value, *(vusp)addr); + mb(); + __kernel_ldwu(*(vusp)addr); + break; + case 4: + *(vuip)addr = value; + mb(); + *(vuip)addr; + break; + default: + return PCIBIOS_FUNC_NOT_SUPPORTED; + } + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops marvel_pci_ops = +{ + .read = marvel_read_config, + .write = marvel_write_config, +}; + + +/* + * Other PCI helper functions. + */ +void +marvel_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end) +{ + io7_ioport_csrs *csrs = ((struct io7_port *)hose->sysdata)->csrs; + + wmb(); + csrs->POx_SG_TBIA.csr = 0; + mb(); + csrs->POx_SG_TBIA.csr; +} + + +/* + * IO map support. + */ +unsigned long +marvel_ioremap(unsigned long addr, unsigned long size) +{ + struct pci_controller *hose; + unsigned long baddr, last; + struct vm_struct *area; + unsigned long vaddr; + unsigned long *ptes; + unsigned long pfn; + + /* + * Adjust the addr. + */ +#ifdef CONFIG_VGA_HOSE + if (pci_vga_hose && __marvel_is_mem_vga(addr)) { + addr += pci_vga_hose->mem_space->start; + } +#endif + + if (!marvel_is_ioaddr(addr)) return 0UL; + + /* + * Find the hose. + */ + for (hose = hose_head; hose; hose = hose->next) { + if ((addr >> 32) == (hose->mem_space->start >> 32)) + break; + } + if (!hose) + return 0UL; + + /* + * We have the hose - calculate the bus limits. + */ + baddr = addr - hose->mem_space->start; + last = baddr + size - 1; + + /* + * Is it direct-mapped? + */ + if ((baddr >= __direct_map_base) && + ((baddr + size - 1) < __direct_map_base + __direct_map_size)) + return IDENT_ADDR | (baddr - __direct_map_base); + + /* + * Check the scatter-gather arena. + */ + if (hose->sg_pci && + baddr >= (unsigned long)hose->sg_pci->dma_base && + last < (unsigned long)hose->sg_pci->dma_base + hose->sg_pci->size){ + + /* + * Adjust the limits (mappings must be page aligned) + */ + baddr -= hose->sg_pci->dma_base; + last -= hose->sg_pci->dma_base; + baddr &= PAGE_MASK; + size = PAGE_ALIGN(last) - baddr; + + /* + * Map it. + */ + area = get_vm_area(size, VM_IOREMAP); + if (!area) return (unsigned long)NULL; + ptes = hose->sg_pci->ptes; + for (vaddr = (unsigned long)area->addr; + baddr <= last; + baddr += PAGE_SIZE, vaddr += PAGE_SIZE) { + pfn = ptes[baddr >> PAGE_SHIFT]; + if (!(pfn & 1)) { + printk("ioremap failed... pte not valid...\n"); + vfree(area->addr); + return 0UL; + } + pfn >>= 1; /* make it a true pfn */ + + if (__alpha_remap_area_pages(VMALLOC_VMADDR(vaddr), + pfn << PAGE_SHIFT, + PAGE_SIZE, 0)) { + printk("FAILED to map...\n"); + vfree(area->addr); + return 0UL; + } + } + + flush_tlb_all(); + + vaddr = (unsigned long)area->addr + (addr & ~PAGE_MASK); + + return vaddr; + } + + /* + * Not found - assume legacy ioremap. + */ + return addr; +} + +void +marvel_iounmap(unsigned long addr) +{ + if (((long)addr >> 41) == -2) + return; /* kseg map, nothing to do */ + if (addr) + return vfree((void *)(PAGE_MASK & addr)); +} + +#ifndef CONFIG_ALPHA_GENERIC +EXPORT_SYMBOL(marvel_ioremap); +EXPORT_SYMBOL(marvel_iounmap); +#endif + +/* + * SRMCons support + * + * Marvel doesn't have a real serial console -- it's either graphics or + * server management based. If we're running on the server management based + * console, allow the srmcons callback driver to be a console device. + */ +int +marvel_srmcons_allowed(void) +{ + u64 *pu64 = (u64 *)((u64)hwrpb + hwrpb->ctbt_offset); + + return (pu64[7] == 2); +} + + +/* + * RTC Support + */ +struct marvel_rtc_access_info { + unsigned long function; + unsigned long index; + unsigned long data; +}; + +static void +__marvel_access_rtc(void *info) +{ + struct marvel_rtc_access_info *rtc_access = info; + + register unsigned long __r0 __asm__("$0"); + register unsigned long __r16 __asm__("$16") = rtc_access->function; + register unsigned long __r17 __asm__("$17") = rtc_access->index; + register unsigned long __r18 __asm__("$18") = rtc_access->data; + + __asm__ __volatile__( + "call_pal %4 # cserve rtc" + : "=r"(__r16), "=r"(__r17), "=r"(__r18), "=r"(__r0) + : "i"(PAL_cserve), "0"(__r16), "1"(__r17), "2"(__r18) + : "$1", "$22", "$23", "$24", "$25"); + + rtc_access->data = __r0; +} + +u8 +__marvel_rtc_io(int write, u8 b, unsigned long addr) +{ + struct marvel_rtc_access_info rtc_access = {0, }; + static u8 index = 0; + u8 ret = 0; + + switch(addr) { + case 0x70: /* RTC_PORT(0) */ + if (write) index = b; + ret = index; + break; + + case 0x71: /* RTC_PORT(1) */ + rtc_access.index = index; + rtc_access.data = BCD_TO_BIN(b); + rtc_access.function = 0x49; /* GET_TOY */ + if (write) rtc_access.function = 0x48; /* PUT_TOY */ + +#if CONFIG_SMP + if (smp_processor_id() != boot_cpuid) + smp_call_function_on_cpu(__marvel_access_rtc, + &rtc_access, + 1, /* retry */ + 1, /* wait */ + 1UL << boot_cpuid); + else + __marvel_access_rtc(&rtc_access); +#else + __marvel_access_rtc(&rtc_access); +#endif + ret = BIN_TO_BCD(rtc_access.data); + + break; + + default: + printk(KERN_WARNING "Illegal RTC port %lx\n", addr); + break; + } + + return ret; +} + + +/* + * NUMA Support + */ +/********** + * FIXME - for now each cpu is a node by itself + * -- no real support for striped mode + ********** + */ +int +marvel_pa_to_nid(unsigned long pa) +{ + int cpuid; + + if ((pa >> 43) & 1) /* I/O */ + cpuid = (~(pa >> 35) & 0xff); + else /* mem */ + cpuid = ((pa >> 34) & 0x3) | ((pa >> (37 - 2)) & (0x1f << 2)); + + return marvel_cpuid_to_nid(cpuid); +} + +int +marvel_cpuid_to_nid(int cpuid) +{ + return cpuid; +} + +unsigned long +marvel_node_mem_start(int nid) +{ + unsigned long pa; + + pa = (nid & 0x3) | ((nid & (0x1f << 2)) << 1); + pa <<= 34; + + return pa; +} + +unsigned long +marvel_node_mem_size(int nid) +{ + return 16UL * 1024 * 1024 * 1024; /* 16GB */ +} + + +/* + * AGP GART Support. + */ +#include +#include +#include +#include + +#define MARVEL_AGP_APER_SIZE (64 * 1024 * 1024) + +struct marvel_agp_aperture { + struct pci_iommu_arena *arena; + long pg_start; + long pg_count; +}; + +static int +marvel_agp_setup(alpha_agp_info *agp) +{ + struct marvel_agp_aperture *aper; + + aper = kmalloc(sizeof(*aper), GFP_KERNEL); + if (aper == NULL) return -ENOMEM; + + aper->arena = agp->hose->sg_pci; + aper->pg_count = MARVEL_AGP_APER_SIZE / PAGE_SIZE; + aper->pg_start = iommu_reserve(aper->arena, aper->pg_count, + aper->pg_count - 1); + + if (aper->pg_start < 0) { + printk(KERN_ERR "Failed to reserve AGP memory\n"); + kfree(aper); + return -ENOMEM; + } + + agp->aperture.bus_base = + aper->arena->dma_base + aper->pg_start * PAGE_SIZE; + agp->aperture.size = aper->pg_count * PAGE_SIZE; + agp->aperture.sysdata = aper; + + return 0; +} + +static void +marvel_agp_cleanup(alpha_agp_info *agp) +{ + struct marvel_agp_aperture *aper = agp->aperture.sysdata; + int status; + + status = iommu_release(aper->arena, aper->pg_start, aper->pg_count); + if (status == -EBUSY) { + printk(KERN_WARNING + "Attempted to release bound AGP memory - unbinding\n"); + iommu_unbind(aper->arena, aper->pg_start, aper->pg_count); + status = iommu_release(aper->arena, aper->pg_start, + aper->pg_count); + } + if (status < 0) + printk(KERN_ERR "Failed to release AGP memory\n"); + + kfree(aper); + kfree(agp); +} + +static int +marvel_agp_configure(alpha_agp_info *agp) +{ + io7_ioport_csrs *csrs = ((struct io7_port *)agp->hose->sysdata)->csrs; + struct io7 *io7 = ((struct io7_port *)agp->hose->sysdata)->io7; + unsigned int new_rate = 0; + unsigned long agp_pll; + + /* + * Check the requested mode against the PLL setting. + * The agpgart_be code has not programmed the card yet, + * so we can still tweak mode here. + */ + agp_pll = io7->csrs->POx_RST[IO7_AGP_PORT].csr; + switch(IO7_PLL_RNGB(agp_pll)) { + case 0x4: /* 2x only */ + /* + * The PLL is only programmed for 2x, so adjust the + * rate to 2x, if necessary. + */ + if (agp->mode.bits.rate != 2) + new_rate = 2; + break; + + case 0x6: /* 1x / 4x */ + /* + * The PLL is programmed for 1x or 4x. Don't go faster + * than requested, so if the requested rate is 2x, use 1x. + */ + if (agp->mode.bits.rate == 2) + new_rate = 1; + break; + + default: /* ??????? */ + /* + * Don't know what this PLL setting is, take the requested + * rate, but warn the user. + */ + printk("%s: unknown PLL setting RNGB=%lx (PLL6_CTL=%016lx)\n", + __FUNCTION__, IO7_PLL_RNGB(agp_pll), agp_pll); + break; + } + + /* + * Set the new rate, if necessary. + */ + if (new_rate) { + printk("Requested AGP Rate %dX not compatible " + "with PLL setting - using %dX\n", + agp->mode.bits.rate, + new_rate); + + agp->mode.bits.rate = new_rate; + } + + printk("Enabling AGP on hose %d: %dX%s RQ %d\n", + agp->hose->index, agp->mode.bits.rate, + agp->mode.bits.sba ? " - SBA" : "", agp->mode.bits.rq); + + csrs->AGP_CMD.csr = agp->mode.lw; + + return 0; +} + +static int +marvel_agp_bind_memory(alpha_agp_info *agp, off_t pg_start, agp_memory *mem) +{ + struct marvel_agp_aperture *aper = agp->aperture.sysdata; + return iommu_bind(aper->arena, aper->pg_start + pg_start, + mem->page_count, mem->memory); +} + +static int +marvel_agp_unbind_memory(alpha_agp_info *agp, off_t pg_start, agp_memory *mem) +{ + struct marvel_agp_aperture *aper = agp->aperture.sysdata; + return iommu_unbind(aper->arena, aper->pg_start + pg_start, + mem->page_count); +} + +static unsigned long +marvel_agp_translate(alpha_agp_info *agp, dma_addr_t addr) +{ + struct marvel_agp_aperture *aper = agp->aperture.sysdata; + unsigned long baddr = addr - aper->arena->dma_base; + unsigned long pte; + + if (addr < agp->aperture.bus_base || + addr >= agp->aperture.bus_base + agp->aperture.size) { + printk("%s: addr out of range\n", __FUNCTION__); + return -EINVAL; + } + + pte = aper->arena->ptes[baddr >> PAGE_SHIFT]; + if (!(pte & 1)) { + printk("%s: pte not valid\n", __FUNCTION__); + return -EINVAL; + } + return (pte >> 1) << PAGE_SHIFT; +} + +struct alpha_agp_ops marvel_agp_ops = +{ + .setup = marvel_agp_setup, + .cleanup = marvel_agp_cleanup, + .configure = marvel_agp_configure, + .bind = marvel_agp_bind_memory, + .unbind = marvel_agp_unbind_memory, + .translate = marvel_agp_translate +}; + +alpha_agp_info * +marvel_agp_info(void) +{ + struct pci_controller *hose; + io7_ioport_csrs *csrs; + alpha_agp_info *agp; + struct io7 *io7; + + /* + * Find the first IO7 with an AGP card. + * + * FIXME -- there should be a better way (we want to be able to + * specify and what if the agp card is not video???) + */ + hose = NULL; + for (io7 = NULL; (io7 = marvel_next_io7(io7)) != NULL; ) { + struct pci_controller *h; + vuip addr; + + if (!io7->ports[IO7_AGP_PORT].enabled) + continue; + + h = io7->ports[IO7_AGP_PORT].hose; + addr = (vuip)build_conf_addr(h, 0, PCI_DEVFN(5, 0), 0); + + if (*addr != 0xffffffffu) { + hose = h; + break; + } + } + + printk("MARVEL - using hose %d as AGP\n", hose->index); + + if (!hose || !hose->sg_pci) + return NULL; + + /* + * Get the csrs from the hose. + */ + csrs = ((struct io7_port *)hose->sysdata)->csrs; + + /* + * Allocate the info structure. + */ + agp = kmalloc(sizeof(*agp), GFP_KERNEL); + + /* + * Fill it in. + */ + agp->type = 0 /* FIXME: ALPHA_CORE_AGP */; + agp->hose = hose; + agp->private = NULL; + agp->ops = &marvel_agp_ops; + + /* + * Aperture - not configured until ops.setup(). + */ + agp->aperture.bus_base = 0; + agp->aperture.size = 0; + agp->aperture.sysdata = NULL; + + /* + * Capabilities. + * + * NOTE: IO7 reports through AGP_STAT that it can support a read queue + * depth of 17 (rq = 0x10). It actually only supports a depth of + * 16 (rq = 0xf). + */ + agp->capability.lw = csrs->AGP_STAT.csr; + agp->capability.bits.rq = 0xf; + + /* + * Mode. + */ + agp->mode.lw = csrs->AGP_CMD.csr; + + return agp; +} diff --git a/arch/alpha/kernel/core_titan.c b/arch/alpha/kernel/core_titan.c index b90d64c3c90..d5619bbc4ad 100644 --- a/arch/alpha/kernel/core_titan.c +++ b/arch/alpha/kernel/core_titan.c @@ -5,15 +5,20 @@ */ #include +#include #include #include #include #include #include +#include +#include #include #include #include +#include +#include #define __EXTERN_INLINE inline #include @@ -25,8 +30,6 @@ #include "proto.h" #include "pci_impl.h" -unsigned TITAN_agp = 0; - /* Save Titan configuration data as the console had it set up. */ struct @@ -49,6 +52,31 @@ struct # define DBG_CFG(args) #endif + +/* + * Routines to access TIG registers. + */ +static inline volatile unsigned long * +mk_tig_addr(int offset) +{ + return (volatile unsigned long *)(TITAN_TIG_SPACE + (offset << 6)); +} + +static inline u8 +titan_read_tig(int offset, u8 value) +{ + volatile unsigned long *tig_addr = mk_tig_addr(offset); + return (u8)(*tig_addr & 0xff); +} + +static inline void +titan_write_tig(int offset, u8 value) +{ + volatile unsigned long *tig_addr = mk_tig_addr(offset); + *tig_addr = (unsigned long)value; +} + + /* * Given a bus, device, and function number, compute resulting * configuration space address @@ -179,13 +207,16 @@ titan_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end) volatile unsigned long *csr; unsigned long value; - /* Get the right hose */ + /* Get the right hose. */ port = &pachip->g_port; if (hose->index & 2) port = &pachip->a_port; /* We can invalidate up to 8 tlb entries in a go. The flush - matches against <31:16> in the pci address. */ + matches against <31:16> in the pci address. + Note that gtlbi* and atlbi* are in the same place in the g_port + and a_port, respectively, so the g_port offset can be used + even if hose is an a_port */ csr = &port->port_specific.g.gtlbia.csr; if (((start ^ end) & 0xffff0000) == 0) csr = &port->port_specific.g.gtlbiv.csr; @@ -200,9 +231,7 @@ titan_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end) *csr; } -#define FN __FUNCTION__ - -static int __init +static int titan_query_agp(titan_pachip_port *port) { union TPAchipPCTL pctl; @@ -213,36 +242,6 @@ titan_query_agp(titan_pachip_port *port) return pctl.pctl_r_bits.apctl_v_agp_present; } -static void __init -titan_init_agp(titan_pachip_port *port, struct pci_controller *hose) -{ - union TPAchipPCTL pctl; - - if (!titan_query_agp(port)) - return; - - printk("AGP present on hose %d\n", hose->index); - - /* get APCTL */ - pctl.pctl_q_whole = port->pctl.csr; - - - pctl.pctl_r_bits.apctl_v_agp_en = 1; /* enable AGP */ - pctl.pctl_r_bits.apctl_v_agp_lp_rd = 0; - pctl.pctl_r_bits.apctl_v_agp_hp_rd = 0; - - port->pctl.csr = pctl.pctl_q_whole; - - TITAN_agp |= 1 << hose->index; - -#ifdef CONFIG_VGA_HOSE - /* is a graphics card on the AGP? (always device 5) */ - if (hose != NULL && - __kernel_ldwu(*(vusp)(hose->config_space_base + 0x280a)) == - PCI_CLASS_DISPLAY_VGA) - set_vga_hose(hose); -#endif -} static void __init titan_init_one_pachip_port(titan_pachip_port *port, int index) @@ -255,10 +254,13 @@ titan_init_one_pachip_port(titan_pachip_port *port, int index) hose->io_space = alloc_resource(); hose->mem_space = alloc_resource(); - /* This is for userland consumption. For some reason, the 40-bit - PIO bias that we use in the kernel through KSEG didn't work for - the page table based user mappings. So make sure we get the - 43-bit PIO bias. */ + /* + * This is for userland consumption. The 40-bit PIO bias that we + * use in the kernel through KSEG doesn't work in the page table + * based user mappings. (43-bit KSEG sign extends the physical + * address from bit 40 to hit the I/O bit - mapped addresses don't). + * So make sure we get the 43-bit PIO bias. + */ hose->sparse_mem_base = 0; hose->sparse_io_base = 0; hose->dense_mem_base @@ -284,9 +286,6 @@ titan_init_one_pachip_port(titan_pachip_port *port, int index) if (request_resource(&iomem_resource, hose->mem_space) < 0) printk(KERN_ERR "Failed to request MEM on hose %d\n", index); - /* It's safe to call this for both G-Ports and A-Ports */ - titan_init_agp(port, hose); - /* * Save the existing PCI window translations. SRM will * need them when we go to reboot. @@ -310,39 +309,41 @@ titan_init_one_pachip_port(titan_pachip_port *port, int index) /* * Set up the PCI to main memory translation windows. * - * Note: Window 3 on Titan is Scatter-Gather ONLY + * Note: Window 3 on Titan is Scatter-Gather ONLY. * * Window 0 is scatter-gather 8MB at 8MB (for isa) - * Window 1 is scatter-gather (up to) 1GB at 1GB - * Window 2 is direct access 2GB at 2GB + * Window 1 is direct access 1GB at 2GB + * Window 2 is scatter-gather 1GB at 3GB */ hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0); hose->sg_isa->align_entry = 8; /* 64KB for ISA */ - hose->sg_pci = iommu_arena_new(hose, 0x40000000, - size_for_memory(0x40000000), 0); + hose->sg_pci = iommu_arena_new(hose, 0xc0000000, 0x40000000, 0); hose->sg_pci->align_entry = 4; /* Titan caches 4 PTEs at a time */ - __direct_map_base = 0x80000000; - __direct_map_size = 0x80000000; - port->wsba[0].csr = hose->sg_isa->dma_base | 3; port->wsm[0].csr = (hose->sg_isa->size - 1) & 0xfff00000; port->tba[0].csr = virt_to_phys(hose->sg_isa->ptes); - port->wsba[1].csr = hose->sg_pci->dma_base | 3; - port->wsm[1].csr = (hose->sg_pci->size - 1) & 0xfff00000; - port->tba[1].csr = virt_to_phys(hose->sg_pci->ptes); + port->wsba[1].csr = __direct_map_base | 1; + port->wsm[1].csr = (__direct_map_size - 1) & 0xfff00000; + port->tba[1].csr = 0; - port->wsba[2].csr = 0x80000000 | 1; - port->wsm[2].csr = (0x80000000 - 1) & 0xfff00000; - port->tba[2].csr = 0; + port->wsba[2].csr = hose->sg_pci->dma_base | 3; + port->wsm[2].csr = (hose->sg_pci->size - 1) & 0xfff00000; + port->tba[2].csr = virt_to_phys(hose->sg_pci->ptes); port->wsba[3].csr = 0; - /* Enable the Monster Window to make DAC pci64 possible. */ + /* Enable the Monster Window to make DAC pci64 possible. */ port->pctl.csr |= pctl_m_mwin; + /* + * If it's an AGP port, initialize agplastwr. + */ + if (titan_query_agp(port)) + port->port_specific.a.agplastwr.csr = __direct_map_base; + titan_pci_tbi(hose, 0, -1); } @@ -360,25 +361,51 @@ titan_init_pachips(titan_pachip *pachip0, titan_pachip *pachip1) titan_init_one_pachip_port(&pachip1->a_port, 3);/* hose 3 */ } +static void __init +titan_init_vga_hose(void) +{ +#ifdef CONFIG_VGA_HOSE + u64 *pu64 = (u64 *)((u64)hwrpb + hwrpb->ctbt_offset); + + if (pu64[7] == 3) { /* TERM_TYPE == graphics */ + struct pci_controller *hose; + int h = (pu64[30] >> 24) & 0xff; /* console hose # */ + + /* + * Our hose numbering matches the console's, so just find + * the right one... + */ + for (hose = hose_head; hose; hose = hose->next) { + if (hose->index == h) break; + } + + if (hose) { + printk("Console graphics on hose %d\n", hose->index); + pci_vga_hose = hose; + } + } +#endif /* CONFIG_VGA_HOSE */ +} + void __init titan_init_arch(void) { #if 0 - printk("%s: titan_init_arch()\n", FN); - printk("%s: CChip registers:\n", FN); - printk("%s: CSR_CSC 0x%lx\n", FN, TITAN_cchip->csc.csr); - printk("%s: CSR_MTR 0x%lx\n", FN, TITAN_cchip->mtr.csr); - printk("%s: CSR_MISC 0x%lx\n", FN, TITAN_cchip->misc.csr); - printk("%s: CSR_DIM0 0x%lx\n", FN, TITAN_cchip->dim0.csr); - printk("%s: CSR_DIM1 0x%lx\n", FN, TITAN_cchip->dim1.csr); - printk("%s: CSR_DIR0 0x%lx\n", FN, TITAN_cchip->dir0.csr); - printk("%s: CSR_DIR1 0x%lx\n", FN, TITAN_cchip->dir1.csr); - printk("%s: CSR_DRIR 0x%lx\n", FN, TITAN_cchip->drir.csr); - - printk("%s: DChip registers:\n", FN); - printk("%s: CSR_DSC 0x%lx\n", FN, TITAN_dchip->dsc.csr); - printk("%s: CSR_STR 0x%lx\n", FN, TITAN_dchip->str.csr); - printk("%s: CSR_DREV 0x%lx\n", FN, TITAN_dchip->drev.csr); + printk("%s: titan_init_arch()\n", __FUNCTION__); + printk("%s: CChip registers:\n", __FUNCTION__); + printk("%s: CSR_CSC 0x%lx\n", __FUNCTION__, TITAN_cchip->csc.csr); + printk("%s: CSR_MTR 0x%lx\n", __FUNCTION__, TITAN_cchip->mtr.csr); + printk("%s: CSR_MISC 0x%lx\n", __FUNCTION__, TITAN_cchip->misc.csr); + printk("%s: CSR_DIM0 0x%lx\n", __FUNCTION__, TITAN_cchip->dim0.csr); + printk("%s: CSR_DIM1 0x%lx\n", __FUNCTION__, TITAN_cchip->dim1.csr); + printk("%s: CSR_DIR0 0x%lx\n", __FUNCTION__, TITAN_cchip->dir0.csr); + printk("%s: CSR_DIR1 0x%lx\n", __FUNCTION__, TITAN_cchip->dir1.csr); + printk("%s: CSR_DRIR 0x%lx\n", __FUNCTION__, TITAN_cchip->drir.csr); + + printk("%s: DChip registers:\n", __FUNCTION__); + printk("%s: CSR_DSC 0x%lx\n", __FUNCTION__, TITAN_dchip->dsc.csr); + printk("%s: CSR_STR 0x%lx\n", __FUNCTION__, TITAN_dchip->str.csr); + printk("%s: CSR_DREV 0x%lx\n", __FUNCTION__, TITAN_dchip->drev.csr); #endif boot_cpuid = __hard_smp_processor_id(); @@ -387,8 +414,15 @@ titan_init_arch(void) ioport_resource.end = ~0UL; iomem_resource.end = ~0UL; - /* Init the PA chip(s) */ + /* PCI DMA Direct Mapping is 1GB at 2GB. */ + __direct_map_base = 0x80000000; + __direct_map_size = 0x40000000; + + /* Init the PA chip(s). */ titan_init_pachips(TITAN_pachip0, TITAN_pachip1); + + /* Check for graphic console location (if any). */ + titan_init_vga_hose(); } static void @@ -417,8 +451,8 @@ titan_kill_pachips(titan_pachip *pachip0, titan_pachip *pachip1) int pchip1_present = TITAN_cchip->csc.csr & 1L<<14; if (pchip1_present) { - titan_kill_one_pachip_port(&pachip0->g_port, 1); - titan_kill_one_pachip_port(&pachip0->a_port, 3); + titan_kill_one_pachip_port(&pachip1->g_port, 1); + titan_kill_one_pachip_port(&pachip1->a_port, 3); } titan_kill_one_pachip_port(&pachip0->g_port, 0); titan_kill_one_pachip_port(&pachip0->a_port, 2); @@ -430,38 +464,336 @@ titan_kill_arch(int mode) titan_kill_pachips(TITAN_pachip0, TITAN_pachip1); } -static inline void -titan_pci_clr_err_1(titan_pachip *pachip) + +/* + * IO map support. + */ +unsigned long +titan_ioremap(unsigned long addr, unsigned long size) { - unsigned int jd; + int h = (addr & TITAN_HOSE_MASK) >> TITAN_HOSE_SHIFT; + unsigned long baddr = addr & ~TITAN_HOSE_MASK; + unsigned long last = baddr + size - 1; + struct pci_controller *hose; + struct vm_struct *area; + unsigned long vaddr; + unsigned long *ptes; + unsigned long pfn; + + /* + * Adjust the addr. + */ +#ifdef CONFIG_VGA_HOSE + if (pci_vga_hose && __titan_is_mem_vga(addr)) { + h = pci_vga_hose->index; + addr += pci_vga_hose->mem_space->start; + } +#endif + + /* + * Find the hose. + */ + for (hose = hose_head; hose; hose = hose->next) + if (hose->index == h) break; + if (!hose) return (unsigned long)NULL; + + /* + * Is it direct-mapped? + */ + if ((baddr >= __direct_map_base) && + ((baddr + size - 1) < __direct_map_base + __direct_map_size)) + return addr - __direct_map_base + TITAN_MEM_BIAS; + + /* + * Check the scatter-gather arena. + */ + if (hose->sg_pci && + baddr >= (unsigned long)hose->sg_pci->dma_base && + last < (unsigned long)hose->sg_pci->dma_base + hose->sg_pci->size){ + + /* + * Adjust the limits (mappings must be page aligned) + */ + baddr -= hose->sg_pci->dma_base; + last -= hose->sg_pci->dma_base; + baddr &= PAGE_MASK; + size = PAGE_ALIGN(last) - baddr; + + /* + * Map it + */ + area = get_vm_area(size, VM_IOREMAP); + if (!area) return (unsigned long)NULL; + ptes = hose->sg_pci->ptes; + for (vaddr = (unsigned long)area->addr; + baddr <= last; + baddr += PAGE_SIZE, vaddr += PAGE_SIZE) { + pfn = ptes[baddr >> PAGE_SHIFT]; + if (!(pfn & 1)) { + printk("ioremap failed... pte not valid...\n"); + vfree(area->addr); + return (unsigned long)NULL; + } + pfn >>= 1; /* make it a true pfn */ + + if (__alpha_remap_area_pages(VMALLOC_VMADDR(vaddr), + pfn << PAGE_SHIFT, + PAGE_SIZE, 0)) { + printk("FAILED to map...\n"); + vfree(area->addr); + return (unsigned long)NULL; + } + } + + flush_tlb_all(); + + vaddr = (unsigned long)area->addr + (addr & ~PAGE_MASK); + return vaddr; + } + + /* + * Not found - assume legacy ioremap. + */ + return addr + TITAN_MEM_BIAS; - jd = pachip->g_port.port_specific.g.gperror.csr; - pachip->g_port.port_specific.g.gperror.csr = jd; - mb(); - pachip->g_port.port_specific.g.gperror.csr; } -static inline void -titan_pci_clr_err(void) +void +titan_iounmap(unsigned long addr) { - titan_pci_clr_err_1(TITAN_pachip0); + if (((long)addr >> 41) == -2) + return; /* kseg map, nothing to do */ + if (addr) + vfree((void *)(PAGE_MASK & addr)); +} - if (TITAN_cchip->csc.csr & 1L<<14) - titan_pci_clr_err_1(TITAN_pachip1); +#ifndef CONFIG_ALPHA_GENERIC +EXPORT_SYMBOL(titan_ioremap); +EXPORT_SYMBOL(titan_iounmap); +#endif + +/* + * AGP GART Support. + */ +#include +#include +#include +#include + +#define TITAN_AGP_APER_SIZE (64 * 1024 * 1024) + +struct titan_agp_aperture { + struct pci_iommu_arena *arena; + long pg_start; + long pg_count; +}; + +static int +titan_agp_setup(alpha_agp_info *agp) +{ + struct titan_agp_aperture *aper; + + aper = kmalloc(sizeof(struct titan_agp_aperture), GFP_KERNEL); + if (aper == NULL) + return -ENOMEM; + + aper->arena = agp->hose->sg_pci; + aper->pg_count = TITAN_AGP_APER_SIZE / PAGE_SIZE; + aper->pg_start = iommu_reserve(aper->arena, aper->pg_count, + aper->pg_count - 1); + if (aper->pg_start < 0) { + printk(KERN_ERR "Failed to reserve AGP memory\n"); + kfree(aper); + return -ENOMEM; + } + + agp->aperture.bus_base = + aper->arena->dma_base + aper->pg_start * PAGE_SIZE; + agp->aperture.size = aper->pg_count * PAGE_SIZE; + agp->aperture.sysdata = aper; + + return 0; } -void -titan_machine_check(unsigned long vector, unsigned long la_ptr, - struct pt_regs * regs) +static void +titan_agp_cleanup(alpha_agp_info *agp) { - /* clear error before any reporting. */ - mb(); - draina(); - titan_pci_clr_err(); - wrmces(0x7); - mb(); + struct titan_agp_aperture *aper = agp->aperture.sysdata; + int status; + + status = iommu_release(aper->arena, aper->pg_start, aper->pg_count); + if (status == -EBUSY) { + printk(KERN_WARNING + "Attempted to release bound AGP memory - unbinding\n"); + iommu_unbind(aper->arena, aper->pg_start, aper->pg_count); + status = iommu_release(aper->arena, aper->pg_start, + aper->pg_count); + } + if (status < 0) + printk(KERN_ERR "Failed to release AGP memory\n"); + + kfree(aper); + kfree(agp); +} + +static int +titan_agp_configure(alpha_agp_info *agp) +{ + union TPAchipPCTL pctl; + titan_pachip_port *port = agp->private; + pctl.pctl_q_whole = port->pctl.csr; - process_mcheck_info(vector, la_ptr, regs, "TITAN", - mcheck_expected(smp_processor_id())); + /* Side-Band Addressing? */ + pctl.pctl_r_bits.apctl_v_agp_sba_en = agp->mode.bits.sba; + + /* AGP Rate? */ + pctl.pctl_r_bits.apctl_v_agp_rate = 0; /* 1x */ + if (agp->mode.bits.rate & 2) + pctl.pctl_r_bits.apctl_v_agp_rate = 1; /* 2x */ +#if 0 + if (agp->mode.bits.rate & 4) + pctl.pctl_r_bits.apctl_v_agp_rate = 2; /* 4x */ +#endif + + /* RQ Depth? */ + pctl.pctl_r_bits.apctl_v_agp_hp_rd = 2; + pctl.pctl_r_bits.apctl_v_agp_lp_rd = 7; + + /* + * AGP Enable. + */ + pctl.pctl_r_bits.apctl_v_agp_en = agp->mode.bits.enable; + + /* Tell the user. */ + printk("Enabling AGP: %dX%s\n", + 1 << pctl.pctl_r_bits.apctl_v_agp_rate, + pctl.pctl_r_bits.apctl_v_agp_sba_en ? " - SBA" : ""); + + /* Write it. */ + port->pctl.csr = pctl.pctl_q_whole; + + /* And wait at least 5000 66MHz cycles (per Titan spec). */ + udelay(100); + + return 0; } +static int +titan_agp_bind_memory(alpha_agp_info *agp, off_t pg_start, agp_memory *mem) +{ + struct titan_agp_aperture *aper = agp->aperture.sysdata; + return iommu_bind(aper->arena, aper->pg_start + pg_start, + mem->page_count, mem->memory); +} + +static int +titan_agp_unbind_memory(alpha_agp_info *agp, off_t pg_start, agp_memory *mem) +{ + struct titan_agp_aperture *aper = agp->aperture.sysdata; + return iommu_unbind(aper->arena, aper->pg_start + pg_start, + mem->page_count); +} + +static unsigned long +titan_agp_translate(alpha_agp_info *agp, dma_addr_t addr) +{ + struct titan_agp_aperture *aper = agp->aperture.sysdata; + unsigned long baddr = addr - aper->arena->dma_base; + unsigned long pte; + + if (addr < agp->aperture.bus_base || + addr >= agp->aperture.bus_base + agp->aperture.size) { + printk("%s: addr out of range\n", __FUNCTION__); + return -EINVAL; + } + + pte = aper->arena->ptes[baddr >> PAGE_SHIFT]; + if (!(pte & 1)) { + printk("%s: pte not valid\n", __FUNCTION__); + return -EINVAL; + } + + return (pte >> 1) << PAGE_SHIFT; +} + +struct alpha_agp_ops titan_agp_ops = +{ + setup: titan_agp_setup, + cleanup: titan_agp_cleanup, + configure: titan_agp_configure, + bind: titan_agp_bind_memory, + unbind: titan_agp_unbind_memory, + translate: titan_agp_translate +}; + +alpha_agp_info * +titan_agp_info(void) +{ + alpha_agp_info *agp; + struct pci_controller *hose; + titan_pachip_port *port; + int hosenum = -1; + union TPAchipPCTL pctl; + + /* + * Find the AGP port. + */ + port = &TITAN_pachip0->a_port; + if (titan_query_agp(port)) + hosenum = 2; + if (hosenum < 0 && + titan_query_agp(port = &TITAN_pachip1->a_port)) + hosenum = 3; + + /* + * Find the hose the port is on. + */ + for (hose = hose_head; hose; hose = hose->next) + if (hose->index == hosenum) + break; + + if (!hose || !hose->sg_pci) + return NULL; + + /* + * Allocate the info structure. + */ + agp = kmalloc(sizeof(*agp), GFP_KERNEL); + + /* + * Fill it in. + */ + agp->type = 0 /* FIXME: ALPHA_CORE_AGP */; + agp->hose = hose; + agp->private = port; + agp->ops = &titan_agp_ops; + + /* + * Aperture - not configured until ops.setup(). + * + * FIXME - should we go ahead and allocate it here? + */ + agp->aperture.bus_base = 0; + agp->aperture.size = 0; + agp->aperture.sysdata = NULL; + + /* + * Capabilities. + */ + agp->capability.lw = 0; + agp->capability.bits.rate = 3; /* 2x, 1x */ + agp->capability.bits.sba = 1; + agp->capability.bits.rq = 7; /* 8 - 1 */ + + /* + * Mode. + */ + pctl.pctl_q_whole = port->pctl.csr; + agp->mode.lw = 0; + agp->mode.bits.rate = 1 << pctl.pctl_r_bits.apctl_v_agp_rate; + agp->mode.bits.sba = pctl.pctl_r_bits.apctl_v_agp_sba_en; + agp->mode.bits.rq = 7; /* RQ Depth? */ + agp->mode.bits.enable = pctl.pctl_r_bits.apctl_v_agp_en; + + return agp; +} diff --git a/arch/alpha/kernel/core_tsunami.c b/arch/alpha/kernel/core_tsunami.c index 23bcd4c426e..2fc49a239d8 100644 --- a/arch/alpha/kernel/core_tsunami.c +++ b/arch/alpha/kernel/core_tsunami.c @@ -357,7 +357,6 @@ void __init tsunami_init_arch(void) { #ifdef NXM_MACHINE_CHECKS_ON_TSUNAMI - extern asmlinkage void entInt(void); unsigned long tmp; /* Ho hum.. init_arch is called before init_IRQ, but we need to be diff --git a/arch/alpha/kernel/core_wildfire.c b/arch/alpha/kernel/core_wildfire.c index 10b77131e08..6f7ff467d49 100644 --- a/arch/alpha/kernel/core_wildfire.c +++ b/arch/alpha/kernel/core_wildfire.c @@ -442,6 +442,33 @@ struct pci_ops wildfire_pci_ops = .write = wildfire_write_config, }; + +/* + * NUMA Support + */ +int wildfire_pa_to_nid(unsigned long pa) +{ + return pa >> 36; +} + +int wildfire_cpuid_to_nid(int cpuid) +{ + /* assume 4 CPUs per node */ + return cpuid >> 2; +} + +unsigned long wildfire_node_mem_start(int nid) +{ + /* 64GB per node */ + return (unsigned long)nid * (64UL * 1024 * 1024 * 1024); +} + +unsigned long wildfire_node_mem_size(int nid) +{ + /* 64GB per node */ + return 64UL * 1024 * 1024 * 1024; +} + #if DEBUG_DUMP_REGS static void __init diff --git a/arch/alpha/kernel/err_impl.h b/arch/alpha/kernel/err_impl.h index 2154a1a790e..32c709ab75c 100644 --- a/arch/alpha/kernel/err_impl.h +++ b/arch/alpha/kernel/err_impl.h @@ -146,3 +146,17 @@ extern void cdl_check_console_data_log(void); extern int cdl_register_subpacket_annotation(struct el_subpacket_annotation *); extern int cdl_register_subpacket_handler(struct el_subpacket_handler *); +/* + * err_marvel.c + */ +extern void marvel_machine_check(u64, u64, struct pt_regs *); +extern void marvel_register_error_handlers(void); + +/* + * err_titan.c + */ +extern int titan_process_logout_frame(struct el_common *, int); +extern void titan_machine_check(u64, u64, struct pt_regs *); +extern void titan_register_error_handlers(void); +extern int privateer_process_logout_frame(struct el_common *, int); +extern void privateer_machine_check(u64, u64, struct pt_regs *); diff --git a/arch/alpha/kernel/err_marvel.c b/arch/alpha/kernel/err_marvel.c new file mode 100644 index 00000000000..2fc563d8983 --- /dev/null +++ b/arch/alpha/kernel/err_marvel.c @@ -0,0 +1,57 @@ +/* + * linux/arch/alpha/kernel/err_marvel.c + * + * Copyright (C) 2001 Jeff Wiedemeier (Compaq Computer Corporation) + * + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "err_impl.h" +#include "proto.h" + + +void +marvel_machine_check(u64 vector, u64 la_ptr, struct pt_regs *regs) +{ + struct el_subpacket *el_ptr = (struct el_subpacket *)la_ptr; + + /* + * Sync the processor + */ + mb(); + draina(); + + el_process_subpacket(el_ptr); + + switch(vector) { + case SCB_Q_SYSEVENT: + printk(KERN_CRIT "MARVEL SYSEVENT %ld\n", vector); + break; + case SCB_Q_SYSMCHK: + case SCB_Q_SYSERR: + printk(KERN_CRIT "MARVEL SYSMCHK/ERR %ld\n", vector); + break; + default: + /* Don't know it - pass it up. */ + return ev7_machine_check(vector, la_ptr, regs); + } + + /* Release the logout frame. */ + wrmces(0x7); + mb(); +} + +void +marvel_register_error_handlers(void) +{ + ev7_register_error_handlers(); +} diff --git a/arch/alpha/kernel/err_titan.c b/arch/alpha/kernel/err_titan.c new file mode 100644 index 00000000000..f5cbb6b97b9 --- /dev/null +++ b/arch/alpha/kernel/err_titan.c @@ -0,0 +1,747 @@ +/* + * linux/arch/alpha/kernel/err_titan.c + * + * Copyright (C) 2000 Jeff Wiedemeier (Compaq Computer Corporation) + * + * Error handling code supporting TITAN systems + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include "err_impl.h" +#include "proto.h" + + +static int +titan_parse_c_misc(u64 c_misc, int print) +{ + char *src; + int nxs = 0; + int status = MCHK_DISPOSITION_REPORT; + +#define TITAN__CCHIP_MISC__NXM (1UL << 28) +#define TITAN__CCHIP_MISC__NXS__S (29) +#define TITAN__CCHIP_MISC__NXS__M (0x7) + + if (!(c_misc & TITAN__CCHIP_MISC__NXM)) + return MCHK_DISPOSITION_UNKNOWN_ERROR; + +#ifdef CONFIG_VERBOSE_MCHECK + if (!print) + return status; + + nxs = EXTRACT(c_misc, TITAN__CCHIP_MISC__NXS); + switch(nxs) { + case 0: /* CPU 0 */ + case 1: /* CPU 1 */ + case 2: /* CPU 2 */ + case 3: /* CPU 3 */ + src = "CPU"; + /* num is already the CPU number */ + break; + case 4: /* Pchip 0 */ + case 5: /* Pchip 1 */ + src = "Pchip"; + nxs -= 4; + break; + default:/* reserved */ + src = "Unknown, NXS ="; + /* leave num untouched */ + break; + } + + printk("%s Non-existent memory access from: %s %d\n", + err_print_prefix, src, nxs); +#endif /* CONFIG_VERBOSE_MCHECK */ + + return status; +} + +static int +titan_parse_p_serror(int which, u64 serror, int print) +{ + int status = MCHK_DISPOSITION_REPORT; + +#ifdef CONFIG_VERBOSE_MCHECK + char *serror_src[] = {"GPCI", "APCI", "AGP HP", "AGP LP"}; + char *serror_cmd[] = {"DMA Read", "DMA RMW", "SGTE Read", "Reserved"}; +#endif /* CONFIG_VERBOSE_MCHECK */ + +#define TITAN__PCHIP_SERROR__LOST_UECC (1UL << 0) +#define TITAN__PCHIP_SERROR__UECC (1UL << 1) +#define TITAN__PCHIP_SERROR__CRE (1UL << 2) +#define TITAN__PCHIP_SERROR__NXIO (1UL << 3) +#define TITAN__PCHIP_SERROR__LOST_CRE (1UL << 4) +#define TITAN__PCHIP_SERROR__ECCMASK (TITAN__PCHIP_SERROR__UECC | \ + TITAN__PCHIP_SERROR__CRE) +#define TITAN__PCHIP_SERROR__ERRMASK (TITAN__PCHIP_SERROR__LOST_UECC | \ + TITAN__PCHIP_SERROR__UECC | \ + TITAN__PCHIP_SERROR__CRE | \ + TITAN__PCHIP_SERROR__NXIO | \ + TITAN__PCHIP_SERROR__LOST_CRE) +#define TITAN__PCHIP_SERROR__SRC__S (52) +#define TITAN__PCHIP_SERROR__SRC__M (0x3) +#define TITAN__PCHIP_SERROR__CMD__S (54) +#define TITAN__PCHIP_SERROR__CMD__M (0x3) +#define TITAN__PCHIP_SERROR__SYN__S (56) +#define TITAN__PCHIP_SERROR__SYN__M (0xff) +#define TITAN__PCHIP_SERROR__ADDR__S (15) +#define TITAN__PCHIP_SERROR__ADDR__M (0xffffffffUL) + + if (!(serror & TITAN__PCHIP_SERROR__ERRMASK)) + return MCHK_DISPOSITION_UNKNOWN_ERROR; + +#ifdef CONFIG_VERBOSE_MCHECK + if (!print) + return status; + + printk("%s PChip %d SERROR: %016lx\n", + err_print_prefix, which, serror); + if (serror & TITAN__PCHIP_SERROR__ECCMASK) { + printk("%s %sorrectable ECC Error:\n" + " Source: %-6s Command: %-8s Syndrome: 0x%08x\n" + " Address: 0x%lx\n", + err_print_prefix, + (serror & TITAN__PCHIP_SERROR__UECC) ? "Unc" : "C", + serror_src[EXTRACT(serror, TITAN__PCHIP_SERROR__SRC)], + serror_cmd[EXTRACT(serror, TITAN__PCHIP_SERROR__CMD)], + (unsigned)EXTRACT(serror, TITAN__PCHIP_SERROR__SYN), + EXTRACT(serror, TITAN__PCHIP_SERROR__ADDR)); + } + if (serror & TITAN__PCHIP_SERROR__NXIO) + printk("%s Non Existent I/O Error\n", err_print_prefix); + if (serror & TITAN__PCHIP_SERROR__LOST_UECC) + printk("%s Lost Uncorrectable ECC Error\n", + err_print_prefix); + if (serror & TITAN__PCHIP_SERROR__LOST_CRE) + printk("%s Lost Correctable ECC Error\n", err_print_prefix); +#endif /* CONFIG_VERBOSE_MCHECK */ + + return status; +} + +static int +titan_parse_p_perror(int which, int port, u64 perror, int print) +{ + int cmd; + unsigned long addr; + int status = MCHK_DISPOSITION_REPORT; + +#ifdef CONFIG_VERBOSE_MCHECK + char *perror_cmd[] = { "Interrupt Acknowledge", "Special Cycle", + "I/O Read", "I/O Write", + "Reserved", "Reserved", + "Memory Read", "Memory Write", + "Reserved", "Reserved", + "Configuration Read", "Configuration Write", + "Memory Read Multiple", "Dual Address Cycle", + "Memory Read Line","Memory Write and Invalidate" + }; +#endif /* CONFIG_VERBOSE_MCHECK */ + +#define TITAN__PCHIP_PERROR__LOST (1UL << 0) +#define TITAN__PCHIP_PERROR__SERR (1UL << 1) +#define TITAN__PCHIP_PERROR__PERR (1UL << 2) +#define TITAN__PCHIP_PERROR__DCRTO (1UL << 3) +#define TITAN__PCHIP_PERROR__SGE (1UL << 4) +#define TITAN__PCHIP_PERROR__APE (1UL << 5) +#define TITAN__PCHIP_PERROR__TA (1UL << 6) +#define TITAN__PCHIP_PERROR__DPE (1UL << 7) +#define TITAN__PCHIP_PERROR__NDS (1UL << 8) +#define TITAN__PCHIP_PERROR__IPTPR (1UL << 9) +#define TITAN__PCHIP_PERROR__IPTPW (1UL << 10) +#define TITAN__PCHIP_PERROR__ERRMASK (TITAN__PCHIP_PERROR__LOST | \ + TITAN__PCHIP_PERROR__SERR | \ + TITAN__PCHIP_PERROR__PERR | \ + TITAN__PCHIP_PERROR__DCRTO | \ + TITAN__PCHIP_PERROR__SGE | \ + TITAN__PCHIP_PERROR__APE | \ + TITAN__PCHIP_PERROR__TA | \ + TITAN__PCHIP_PERROR__DPE | \ + TITAN__PCHIP_PERROR__NDS | \ + TITAN__PCHIP_PERROR__IPTPR | \ + TITAN__PCHIP_PERROR__IPTPW) +#define TITAN__PCHIP_PERROR__DAC (1UL << 47) +#define TITAN__PCHIP_PERROR__MWIN (1UL << 48) +#define TITAN__PCHIP_PERROR__CMD__S (52) +#define TITAN__PCHIP_PERROR__CMD__M (0x0f) +#define TITAN__PCHIP_PERROR__ADDR__S (14) +#define TITAN__PCHIP_PERROR__ADDR__M (0x1ffffffff) + + if (!(perror & TITAN__PCHIP_PERROR__ERRMASK)) + return MCHK_DISPOSITION_UNKNOWN_ERROR; + + cmd = EXTRACT(perror, TITAN__PCHIP_PERROR__CMD); + addr = EXTRACT(perror, TITAN__PCHIP_PERROR__ADDR) << 2; + + /* + * Initializing the BIOS on a video card on a bus without + * a south bridge (subtractive decode agent) can result in + * master aborts as the BIOS probes the capabilities of the + * card. XFree86 does such initialization. If the error + * is a master abort (No DevSel as PCI Master) and the command + * is an I/O read or write below the address where we start + * assigning PCI I/O spaces (SRM uses 0x1000), then mark the + * error as dismissable so starting XFree86 doesn't result + * in a series of uncorrectable errors being reported. Also + * dismiss master aborts to VGA frame buffer space + * (0xA0000 - 0xC0000) and legacy BIOS space (0xC0000 - 0x100000) + * for the same reason. + * + * Also mark the error dismissible if it looks like the right + * error but only the Lost bit is set. Since the BIOS initialization + * can cause multiple master aborts and the error interrupt can + * be handled on a different CPU than the BIOS code is run on, + * it is possible for a second master abort to occur between the + * time the PALcode reads PERROR and the time it writes PERROR + * to acknowledge the error. If this timing happens, a second + * error will be signalled after the first, and if no additional + * errors occur, will look like a Lost error with no additional + * errors on the same transaction as the previous error. + */ + if (((perror & TITAN__PCHIP_PERROR__NDS) || + ((perror & TITAN__PCHIP_PERROR__ERRMASK) == + TITAN__PCHIP_PERROR__LOST)) && + ((((cmd & 0xE) == 2) && (addr < 0x1000)) || + (((cmd & 0xE) == 6) && (addr >= 0xA0000) && (addr < 0x100000)))) { + status = MCHK_DISPOSITION_DISMISS; + } + +#ifdef CONFIG_VERBOSE_MCHECK + if (!print) + return status; + + printk("%s PChip %d %cPERROR: %016lx\n", + err_print_prefix, which, + port ? 'A' : 'G', perror); + if (perror & TITAN__PCHIP_PERROR__IPTPW) + printk("%s Invalid Peer-to-Peer Write\n", err_print_prefix); + if (perror & TITAN__PCHIP_PERROR__IPTPR) + printk("%s Invalid Peer-to-Peer Read\n", err_print_prefix); + if (perror & TITAN__PCHIP_PERROR__NDS) + printk("%s No DEVSEL as PCI Master [Master Abort]\n", + err_print_prefix); + if (perror & TITAN__PCHIP_PERROR__DPE) + printk("%s Data Parity Error\n", err_print_prefix); + if (perror & TITAN__PCHIP_PERROR__TA) + printk("%s Target Abort\n", err_print_prefix); + if (perror & TITAN__PCHIP_PERROR__APE) + printk("%s Address Parity Error\n", err_print_prefix); + if (perror & TITAN__PCHIP_PERROR__SGE) + printk("%s Scatter-Gather Error, Invalid PTE\n", + err_print_prefix); + if (perror & TITAN__PCHIP_PERROR__DCRTO) + printk("%s Delayed-Completion Retry Timeout\n", + err_print_prefix); + if (perror & TITAN__PCHIP_PERROR__PERR) + printk("%s PERR Asserted\n", err_print_prefix); + if (perror & TITAN__PCHIP_PERROR__SERR) + printk("%s SERR Asserted\n", err_print_prefix); + if (perror & TITAN__PCHIP_PERROR__LOST) + printk("%s Lost Error\n", err_print_prefix); + printk("%s Command: 0x%x - %s\n" + " Address: 0x%lx\n", + err_print_prefix, + cmd, perror_cmd[cmd], + addr); + if (perror & TITAN__PCHIP_PERROR__DAC) + printk("%s Dual Address Cycle\n", err_print_prefix); + if (perror & TITAN__PCHIP_PERROR__MWIN) + printk("%s Hit in Monster Window\n", err_print_prefix); +#endif /* CONFIG_VERBOSE_MCHECK */ + + return status; +} + +static int +titan_parse_p_agperror(int which, u64 agperror, int print) +{ + int cmd, len; + unsigned long addr; + int status = MCHK_DISPOSITION_REPORT; + +#ifdef CONFIG_VERBOSE_MCHECK + char *agperror_cmd[] = { "Read (low-priority)", "Read (high-priority)", + "Write (low-priority)", + "Write (high-priority)", + "Reserved", "Reserved", + "Flush", "Fence" + }; +#endif /* CONFIG_VERBOSE_MCHECK */ + +#define TITAN__PCHIP_AGPERROR__LOST (1UL << 0) +#define TITAN__PCHIP_AGPERROR__LPQFULL (1UL << 1) +#define TITAN__PCHIP_AGPERROR__HPQFULL (1UL << 2) +#define TITAN__PCHIP_AGPERROR__RESCMD (1UL << 3) +#define TITAN__PCHIP_AGPERROR__IPTE (1UL << 4) +#define TITAN__PCHIP_AGPERROR__PTP (1UL << 5) +#define TITAN__PCHIP_AGPERROR__NOWINDOW (1UL << 6) +#define TITAN__PCHIP_AGPERROR__ERRMASK (TITAN__PCHIP_AGPERROR__LOST | \ + TITAN__PCHIP_AGPERROR__LPQFULL | \ + TITAN__PCHIP_AGPERROR__HPQFULL | \ + TITAN__PCHIP_AGPERROR__RESCMD | \ + TITAN__PCHIP_AGPERROR__IPTE | \ + TITAN__PCHIP_AGPERROR__PTP | \ + TITAN__PCHIP_AGPERROR__NOWINDOW) +#define TITAN__PCHIP_AGPERROR__DAC (1UL << 48) +#define TITAN__PCHIP_AGPERROR__MWIN (1UL << 49) +#define TITAN__PCHIP_AGPERROR__FENCE (1UL << 59) +#define TITAN__PCHIP_AGPERROR__CMD__S (50) +#define TITAN__PCHIP_AGPERROR__CMD__M (0x07) +#define TITAN__PCHIP_AGPERROR__ADDR__S (15) +#define TITAN__PCHIP_AGPERROR__ADDR__M (0xffffffffUL) +#define TITAN__PCHIP_AGPERROR__LEN__S (53) +#define TITAN__PCHIP_AGPERROR__LEN__M (0x3f) + + if (!(agperror & TITAN__PCHIP_AGPERROR__ERRMASK)) + return MCHK_DISPOSITION_UNKNOWN_ERROR; + +#ifdef CONFIG_VERBOSE_MCHECK + if (!print) + return status; + + cmd = EXTRACT(agperror, TITAN__PCHIP_AGPERROR__CMD); + addr = EXTRACT(agperror, TITAN__PCHIP_AGPERROR__ADDR) << 3; + len = EXTRACT(agperror, TITAN__PCHIP_AGPERROR__LEN); + + printk("%s PChip %d AGPERROR: %016lx\n", err_print_prefix, + which, agperror); + if (agperror & TITAN__PCHIP_AGPERROR__NOWINDOW) + printk("%s No Window\n", err_print_prefix); + if (agperror & TITAN__PCHIP_AGPERROR__PTP) + printk("%s Peer-to-Peer set\n", err_print_prefix); + if (agperror & TITAN__PCHIP_AGPERROR__IPTE) + printk("%s Invalid PTE\n", err_print_prefix); + if (agperror & TITAN__PCHIP_AGPERROR__RESCMD) + printk("%s Reserved Command\n", err_print_prefix); + if (agperror & TITAN__PCHIP_AGPERROR__HPQFULL) + printk("%s HP Transaction Received while Queue Full\n", + err_print_prefix); + if (agperror & TITAN__PCHIP_AGPERROR__LPQFULL) + printk("%s LP Transaction Received while Queue Full\n", + err_print_prefix); + if (agperror & TITAN__PCHIP_AGPERROR__LOST) + printk("%s Lost Error\n", err_print_prefix); + printk("%s Command: 0x%x - %s, %d Quadwords%s\n" + " Address: 0x%lx\n", + err_print_prefix, cmd, agperror_cmd[cmd], len, + (agperror & TITAN__PCHIP_AGPERROR__FENCE) ? ", FENCE" : "", + addr); + if (agperror & TITAN__PCHIP_AGPERROR__DAC) + printk("%s Dual Address Cycle\n", err_print_prefix); + if (agperror & TITAN__PCHIP_AGPERROR__MWIN) + printk("%s Hit in Monster Window\n", err_print_prefix); +#endif /* CONFIG_VERBOSE_MCHECK */ + + return status; +} + +static int +titan_parse_p_chip(int which, u64 serror, u64 gperror, + u64 aperror, u64 agperror, int print) +{ + int status = MCHK_DISPOSITION_UNKNOWN_ERROR; + status |= titan_parse_p_serror(which, serror, print); + status |= titan_parse_p_perror(which, 0, gperror, print); + status |= titan_parse_p_perror(which, 1, aperror, print); + status |= titan_parse_p_agperror(which, agperror, print); + return status; +} + +int +titan_process_logout_frame(struct el_common *mchk_header, int print) +{ + struct el_TITAN_sysdata_mcheck *tmchk = + (struct el_TITAN_sysdata_mcheck *) + ((unsigned long)mchk_header + mchk_header->sys_offset); + int status = MCHK_DISPOSITION_UNKNOWN_ERROR; + + status |= titan_parse_c_misc(tmchk->c_misc, print); + status |= titan_parse_p_chip(0, tmchk->p0_serror, tmchk->p0_gperror, + tmchk->p0_aperror, tmchk->p0_agperror, + print); + status |= titan_parse_p_chip(1, tmchk->p1_serror, tmchk->p1_gperror, + tmchk->p1_aperror, tmchk->p1_agperror, + print); + + return status; +} + +void +titan_machine_check(u64 vector, u64 la_ptr, struct pt_regs *regs) +{ + struct el_common *mchk_header = (struct el_common *)la_ptr; + struct el_TITAN_sysdata_mcheck *tmchk = + (struct el_TITAN_sysdata_mcheck *) + ((unsigned long)mchk_header + mchk_header->sys_offset); + u64 irqmask; + + /* + * Mask of Titan interrupt sources which are reported as machine checks + * + * 63 - CChip Error + * 62 - PChip 0 H_Error + * 61 - PChip 1 H_Error + * 60 - PChip 0 C_Error + * 59 - PChip 1 C_Error + */ +#define TITAN_MCHECK_INTERRUPT_MASK 0xF800000000000000UL + + /* + * Sync the processor + */ + mb(); + draina(); + + /* + * Only handle system errors here + */ + if ((vector != SCB_Q_SYSMCHK) && (vector != SCB_Q_SYSERR)) + return ev6_machine_check(vector, la_ptr, regs); + + /* + * It's a system error, handle it here + * + * The PALcode has already cleared the error, so just parse it + */ + + /* + * Parse the logout frame without printing first. If the only error(s) + * found are classified as "dismissable", then just dismiss them and + * don't print any message + */ + if (titan_process_logout_frame(mchk_header, 0) != + MCHK_DISPOSITION_DISMISS) { + char *saved_err_prefix = err_print_prefix; + err_print_prefix = KERN_CRIT; + + /* + * Either a nondismissable error was detected or no + * recognized error was detected in the logout frame + * -- report the error in either case + */ + printk("%s" + "*System %s Error (Vector 0x%x) reported on CPU %d:\n", + err_print_prefix, + (vector == SCB_Q_SYSERR)?"Correctable":"Uncorrectable", + (unsigned int)vector, (int)smp_processor_id()); + +#ifdef CONFIG_VERBOSE_MCHECK + titan_process_logout_frame(mchk_header, 1); + dik_show_regs(regs, NULL); +#endif /* CONFIG_VERBOSE_MCHECK */ + + err_print_prefix = saved_err_prefix; + + /* + * Convert any pending interrupts which report as system + * machine checks to interrupts + */ + irqmask = tmchk->c_dirx & TITAN_MCHECK_INTERRUPT_MASK; + titan_dispatch_irqs(irqmask, regs); + } + + + /* + * Release the logout frame + */ + wrmces(0x7); + mb(); +} + +/* + * Subpacket Annotations + */ +static char *el_titan_pchip0_extended_annotation[] = { + "Subpacket Header", "P0_SCTL", "P0_SERREN", + "P0_APCTL", "P0_APERREN", "P0_AGPERREN", + "P0_ASPRST", "P0_AWSBA0", "P0_AWSBA1", + "P0_AWSBA2", "P0_AWSBA3", "P0_AWSM0", + "P0_AWSM1", "P0_AWSM2", "P0_AWSM3", + "P0_ATBA0", "P0_ATBA1", "P0_ATBA2", + "P0_ATBA3", "P0_GPCTL", "P0_GPERREN", + "P0_GSPRST", "P0_GWSBA0", "P0_GWSBA1", + "P0_GWSBA2", "P0_GWSBA3", "P0_GWSM0", + "P0_GWSM1", "P0_GWSM2", "P0_GWSM3", + "P0_GTBA0", "P0_GTBA1", "P0_GTBA2", + "P0_GTBA3", NULL +}; +static char *el_titan_pchip1_extended_annotation[] = { + "Subpacket Header", "P1_SCTL", "P1_SERREN", + "P1_APCTL", "P1_APERREN", "P1_AGPERREN", + "P1_ASPRST", "P1_AWSBA0", "P1_AWSBA1", + "P1_AWSBA2", "P1_AWSBA3", "P1_AWSM0", + "P1_AWSM1", "P1_AWSM2", "P1_AWSM3", + "P1_ATBA0", "P1_ATBA1", "P1_ATBA2", + "P1_ATBA3", "P1_GPCTL", "P1_GPERREN", + "P1_GSPRST", "P1_GWSBA0", "P1_GWSBA1", + "P1_GWSBA2", "P1_GWSBA3", "P1_GWSM0", + "P1_GWSM1", "P1_GWSM2", "P1_GWSM3", + "P1_GTBA0", "P1_GTBA1", "P1_GTBA2", + "P1_GTBA3", NULL +}; +static char *el_titan_memory_extended_annotation[] = { + "Subpacket Header", "AAR0", "AAR1", + "AAR2", "AAR3", "P0_SCTL", + "P0_GPCTL", "P0_APCTL", "P1_SCTL", + "P1_GPCTL", "P1_SCTL", NULL +}; + +static struct el_subpacket_annotation el_titan_annotations[] = { + SUBPACKET_ANNOTATION(EL_CLASS__REGATTA_FAMILY, + EL_TYPE__REGATTA__TITAN_PCHIP0_EXTENDED, + 1, + "Titan PChip 0 Extended Frame", + el_titan_pchip0_extended_annotation), + SUBPACKET_ANNOTATION(EL_CLASS__REGATTA_FAMILY, + EL_TYPE__REGATTA__TITAN_PCHIP1_EXTENDED, + 1, + "Titan PChip 1 Extended Frame", + el_titan_pchip1_extended_annotation), + SUBPACKET_ANNOTATION(EL_CLASS__REGATTA_FAMILY, + EL_TYPE__REGATTA__TITAN_MEMORY_EXTENDED, + 1, + "Titan Memory Extended Frame", + el_titan_memory_extended_annotation), + SUBPACKET_ANNOTATION(EL_CLASS__REGATTA_FAMILY, + EL_TYPE__TERMINATION__TERMINATION, + 1, + "Termination Subpacket", + NULL) +}; + +static struct el_subpacket * +el_process_regatta_subpacket(struct el_subpacket *header) +{ + int status; + + if (header->class != EL_CLASS__REGATTA_FAMILY) { + printk("%s ** Unexpected header CLASS %d TYPE %d, aborting\n", + err_print_prefix, + header->class, header->type); + return NULL; + } + + switch(header->type) { + case EL_TYPE__REGATTA__PROCESSOR_ERROR_FRAME: + case EL_TYPE__REGATTA__SYSTEM_ERROR_FRAME: + case EL_TYPE__REGATTA__ENVIRONMENTAL_FRAME: + case EL_TYPE__REGATTA__PROCESSOR_DBL_ERROR_HALT: + case EL_TYPE__REGATTA__SYSTEM_DBL_ERROR_HALT: + printk("%s ** Occurred on CPU %d:\n", + err_print_prefix, + (int)header->by_type.regatta_frame.cpuid); + status = privateer_process_logout_frame((struct el_common *) + header->by_type.regatta_frame.data_start, 1); + break; + default: + printk("%s ** REGATTA TYPE %d SUBPACKET\n", + err_print_prefix, header->type); + el_annotate_subpacket(header); + break; + } + + + return (struct el_subpacket *)((unsigned long)header + header->length); +} + +static struct el_subpacket_handler titan_subpacket_handler = + SUBPACKET_HANDLER_INIT(EL_CLASS__REGATTA_FAMILY, + el_process_regatta_subpacket); + +void +titan_register_error_handlers(void) +{ + size_t i; + + for (i = 0; i < ARRAY_SIZE (el_titan_annotations); i++) + cdl_register_subpacket_annotation(&el_titan_annotations[i]); + + cdl_register_subpacket_handler(&titan_subpacket_handler); +} + + +/* + * Privateer + */ + +static int +privateer_process_680_frame(struct el_common *mchk_header, int print) +{ + struct el_PRIVATEER_envdata_mcheck *emchk = + (struct el_PRIVATEER_envdata_mcheck *) + ((unsigned long)mchk_header + mchk_header->sys_offset); + int status = MCHK_DISPOSITION_UNKNOWN_ERROR; + + /* TODO - catagorize errors, for now, no error */ + +#ifdef CONFIG_VERBOSE_MCHECK + if (!print) + return status; + + /* TODO - decode instead of just dumping... */ + printk("%s Summary Flags: %016lx\n" + " CChip DIRx: %016lx\n" + " System Management IR: %016lx\n" + " CPU IR: %016lx\n" + " Power Supply IR: %016lx\n" + " LM78 Fault Status: %016lx\n" + " System Doors: %016lx\n" + " Temperature Warning: %016lx\n" + " Fan Control: %016lx\n" + " Fatal Power Down Code: %016lx\n", + err_print_prefix, + emchk->summary, + emchk->c_dirx, + emchk->smir, + emchk->cpuir, + emchk->psir, + emchk->fault, + emchk->sys_doors, + emchk->temp_warn, + emchk->fan_ctrl, + emchk->code); +#endif /* CONFIG_VERBOSE_MCHECK */ + + return status; +} + +int +privateer_process_logout_frame(struct el_common *mchk_header, int print) +{ + struct el_common_EV6_mcheck *ev6mchk = + (struct el_common_EV6_mcheck *)mchk_header; + int status = MCHK_DISPOSITION_UNKNOWN_ERROR; + + /* + * Machine check codes + */ +#define PRIVATEER_MCHK__CORR_ECC 0x86 /* 630 */ +#define PRIVATEER_MCHK__DC_TAG_PERR 0x9E /* 630 */ +#define PRIVATEER_MCHK__PAL_BUGCHECK 0x8E /* 670 */ +#define PRIVATEER_MCHK__OS_BUGCHECK 0x90 /* 670 */ +#define PRIVATEER_MCHK__PROC_HRD_ERR 0x98 /* 670 */ +#define PRIVATEER_MCHK__ISTREAM_CMOV_PRX 0xA0 /* 670 */ +#define PRIVATEER_MCHK__ISTREAM_CMOV_FLT 0xA2 /* 670 */ +#define PRIVATEER_MCHK__SYS_HRD_ERR 0x202 /* 660 */ +#define PRIVATEER_MCHK__SYS_CORR_ERR 0x204 /* 620 */ +#define PRIVATEER_MCHK__SYS_ENVIRON 0x206 /* 680 */ + + switch(ev6mchk->MCHK_Code) { + /* + * Vector 630 - Processor, Correctable + */ + case PRIVATEER_MCHK__CORR_ECC: + case PRIVATEER_MCHK__DC_TAG_PERR: + /* + * Fall through to vector 670 for processing... + */ + /* + * Vector 670 - Processor, Uncorrectable + */ + case PRIVATEER_MCHK__PAL_BUGCHECK: + case PRIVATEER_MCHK__OS_BUGCHECK: + case PRIVATEER_MCHK__PROC_HRD_ERR: + case PRIVATEER_MCHK__ISTREAM_CMOV_PRX: + case PRIVATEER_MCHK__ISTREAM_CMOV_FLT: + status |= ev6_process_logout_frame(mchk_header, print); + break; + + /* + * Vector 620 - System, Correctable + */ + case PRIVATEER_MCHK__SYS_CORR_ERR: + /* + * Fall through to vector 660 for processing... + */ + /* + * Vector 660 - System, Uncorrectable + */ + case PRIVATEER_MCHK__SYS_HRD_ERR: + status |= titan_process_logout_frame(mchk_header, print); + break; + + /* + * Vector 680 - System, Environmental + */ + case PRIVATEER_MCHK__SYS_ENVIRON: /* System, Environmental */ + status |= privateer_process_680_frame(mchk_header, print); + break; + + /* + * Unknown + */ + default: + status |= MCHK_DISPOSITION_REPORT; + if (print) { + printk("%s** Unknown Error, frame follows\n", + err_print_prefix); + mchk_dump_logout_frame(mchk_header); + } + + } + + return status; +} + +void +privateer_machine_check(u64 vector, u64 la_ptr, struct pt_regs *regs) +{ + struct el_common *mchk_header = (struct el_common *)la_ptr; + struct el_TITAN_sysdata_mcheck *tmchk = + (struct el_TITAN_sysdata_mcheck *) + (la_ptr + mchk_header->sys_offset); + u64 irqmask; + char *saved_err_prefix = err_print_prefix; + +#define PRIVATEER_680_INTERRUPT_MASK (0xE00UL) +#define PRIVATEER_HOTPLUG_INTERRUPT_MASK (0xE00UL) + + /* + * Sync the processor. + */ + mb(); + draina(); + + /* + * Only handle system events here. + */ + if (vector != SCB_Q_SYSEVENT) + return titan_machine_check(vector, la_ptr, regs); + + /* + * Report the event - System Events should be reported even if no + * error is indicated since the event could indicate the return + * to normal status. + */ + err_print_prefix = KERN_CRIT; + printk("%s*System Event (Vector 0x%x) reported on CPU %d:\n", + err_print_prefix, + (unsigned int)vector, (int)smp_processor_id()); + privateer_process_680_frame(mchk_header, 1); + err_print_prefix = saved_err_prefix; + + /* + * Convert any pending interrupts which report as 680 machine + * checks to interrupts. + */ + irqmask = tmchk->c_dirx & PRIVATEER_680_INTERRUPT_MASK; + + /* + * Dispatch the interrupt(s). + */ + titan_dispatch_irqs(irqmask, regs); + + /* + * Release the logout frame. + */ + wrmces(0x7); + mb(); +} diff --git a/arch/alpha/kernel/gct.c b/arch/alpha/kernel/gct.c new file mode 100644 index 00000000000..8827687b9f8 --- /dev/null +++ b/arch/alpha/kernel/gct.c @@ -0,0 +1,48 @@ +/* + * linux/arch/alpha/kernel/gct.c + */ + +#include +#include +#include +#include + +#include +#include + +int +gct6_find_nodes(gct6_node *node, gct6_search_struct *search) +{ + gct6_search_struct *wanted; + int status = 0; + + /* First check the magic number. */ + if (node->magic != GCT_NODE_MAGIC) { + printk(KERN_ERR "GCT Node MAGIC incorrect - GCT invalid\n"); + return -EINVAL; + } + + /* Check against the search struct. */ + for (wanted = search; + wanted && (wanted->type | wanted->subtype); + wanted++) { + if (node->type != wanted->type) + continue; + if (node->subtype != wanted->subtype) + continue; + + /* Found it -- call out. */ + if (wanted->callout) + wanted->callout(node); + } + + /* Now walk the tree, siblings first. */ + if (node->next) + status |= gct6_find_nodes(GCT_NODE_PTR(node->next), search); + + /* Then the children. */ + if (node->child) + status |= gct6_find_nodes(GCT_NODE_PTR(node->child), search); + + return status; +} diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c index 8903861e08f..cd9d6454c6d 100644 --- a/arch/alpha/kernel/irq.c +++ b/arch/alpha/kernel/irq.c @@ -213,7 +213,7 @@ setup_irq(unsigned int irq, struct irqaction * new) static struct proc_dir_entry * root_irq_dir; static struct proc_dir_entry * irq_dir[NR_IRQS]; -#ifdef CONFIG_SMP +#ifdef CONFIG_SMP static struct proc_dir_entry * smp_affinity_entry[NR_IRQS]; static char irq_user_affinity[NR_IRQS]; static unsigned long irq_affinity[NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL }; @@ -361,16 +361,18 @@ register_irq_proc (unsigned int irq) /* create /proc/irq/1234 */ irq_dir[irq] = proc_mkdir(name, root_irq_dir); -#ifdef CONFIG_SMP - /* create /proc/irq/1234/smp_affinity */ - entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]); +#ifdef CONFIG_SMP + if (irq_desc[irq].handler->set_affinity) { + /* create /proc/irq/1234/smp_affinity */ + entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]); - entry->nlink = 1; - entry->data = (void *)(long)irq; - entry->read_proc = irq_affinity_read_proc; - entry->write_proc = irq_affinity_write_proc; + entry->nlink = 1; + entry->data = (void *)(long)irq; + entry->read_proc = irq_affinity_read_proc; + entry->write_proc = irq_affinity_write_proc; - smp_affinity_entry[irq] = entry; + smp_affinity_entry[irq] = entry; + } #endif } @@ -387,7 +389,7 @@ init_irq_proc (void) /* create /proc/irq */ root_irq_dir = proc_mkdir("irq", 0); -#ifdef CONFIG_SMP +#ifdef CONFIG_SMP /* create /proc/irq/prof_cpu_mask */ entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir); @@ -398,12 +400,16 @@ init_irq_proc (void) #endif /* - * Create entries for all existing IRQs. + * Create entries for all existing IRQs. If the number of IRQs + * is greater the 1/4 the total dynamic inode space for /proc, + * don't pollute the inode space */ - for (i = 0; i < NR_IRQS; i++) { - if (irq_desc[i].handler == &no_irq_type) - continue; - register_irq_proc(i); + if (ACTUAL_NR_IRQS < (PROC_NDYNAMIC / 4)) { + for (i = 0; i < ACTUAL_NR_IRQS; i++) { + if (irq_desc[i].handler == &no_irq_type) + continue; + register_irq_proc(i); + } } } @@ -518,7 +524,7 @@ show_interrupts(struct seq_file *p, void *v) seq_putc(p, '\n'); #endif - for (i = 0; i < NR_IRQS; i++) { + for (i = 0; i < ACTUAL_NR_IRQS; i++) { action = irq_desc[i].action; if (!action) continue; diff --git a/arch/alpha/kernel/machvec_impl.h b/arch/alpha/kernel/machvec_impl.h index c02365ee0b3..f9832ce76bd 100644 --- a/arch/alpha/kernel/machvec_impl.h +++ b/arch/alpha/kernel/machvec_impl.h @@ -9,10 +9,12 @@ #include #include -/* Whee. IRONGATE, POLARIS, TSUNAMI, TITAN, and WILDFIRE don't have an HAE. +/* Whee. These systems don't have an HAE: + IRONGATE, MARVEL, POLARIS, TSUNAMI, TITAN, WILDFIRE Fix things up for the GENERIC kernel by defining the HAE address to be that of the cache. Now we can read and write it as we like. ;-) */ #define IRONGATE_HAE_ADDRESS (&alpha_mv.hae_cache) +#define MARVEL_HAE_ADDRESS (&alpha_mv.hae_cache) #define POLARIS_HAE_ADDRESS (&alpha_mv.hae_cache) #define TSUNAMI_HAE_ADDRESS (&alpha_mv.hae_cache) #define TITAN_HAE_ADDRESS (&alpha_mv.hae_cache) @@ -32,7 +34,6 @@ #define T2_IACK_SC 1 #define WILDFIRE_IACK_SC 1 /* FIXME */ - /* * Some helpful macros for filling in the blanks. */ @@ -63,6 +64,13 @@ mv_flush_tlb_current: ev5_flush_tlb_current, \ mv_flush_tlb_current_page: ev5_flush_tlb_current_page +#define DO_EV7_MMU \ + max_asn: EV6_MAX_ASN, \ + mv_switch_mm: ev5_switch_mm, \ + mv_activate_mm: ev5_activate_mm, \ + mv_flush_tlb_current: ev5_flush_tlb_current, \ + mv_flush_tlb_current_page: ev5_flush_tlb_current_page + #define IO_LITE(UP,low) \ hae_register: (unsigned long *) CAT(UP,_HAE_ADDRESS), \ iack_sc: CAT(UP,_IACK_SC), \ @@ -91,6 +99,7 @@ #define DO_CIA_IO IO(CIA,cia) #define DO_IRONGATE_IO IO(IRONGATE,irongate) #define DO_LCA_IO IO(LCA,lca) +#define DO_MARVEL_IO IO(MARVEL,marvel) #define DO_MCPCIA_IO IO(MCPCIA,mcpcia) #define DO_POLARIS_IO IO(POLARIS,polaris) #define DO_T2_IO IO(T2,t2) @@ -109,6 +118,7 @@ #define DO_CIA_BUS BUS(cia) #define DO_IRONGATE_BUS BUS(irongate) #define DO_LCA_BUS BUS(lca) +#define DO_MARVEL_BUS BUS(marvel) #define DO_MCPCIA_BUS BUS(mcpcia) #define DO_POLARIS_BUS BUS(polaris) #define DO_T2_BUS BUS(t2) @@ -116,7 +126,6 @@ #define DO_TITAN_BUS BUS(titan) #define DO_WILDFIRE_BUS BUS(wildfire) - /* * In a GENERIC kernel, we have lots of these vectors floating about, * all but one of which we want to go away. In a non-GENERIC kernel, diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index bb14b26258c..75f5aa0e6a9 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -465,18 +465,13 @@ osf_shmat(int shmid, void *shmaddr, int shmflg) unsigned long raddr; long err; - lock_kernel(); err = sys_shmat(shmid, shmaddr, shmflg, &raddr); - if (err) - goto out; + /* * This works because all user-level addresses are * non-negative longs! */ - err = raddr; - out: - unlock_kernel(); - return err; + return err ? err : (long)raddr; } @@ -830,7 +825,7 @@ extern struct timezone sys_tz; extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz); extern int do_getitimer(int which, struct itimerval *value); extern int do_setitimer(int which, struct itimerval *, struct itimerval *); -asmlinkage int sys_utimes(char *, struct timeval *); +extern asmlinkage int sys_utimes(char *, struct timeval *); extern int do_adjtimex(struct timex *); struct timeval32 diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c index 01786622349..c658ba7bf7d 100644 --- a/arch/alpha/kernel/pci.c +++ b/arch/alpha/kernel/pci.c @@ -42,6 +42,8 @@ const char *const pci_mem_names[] = { const char pci_hae0_name[] = "HAE0"; +/* Indicate whether we respect the PCI setup left by console. */ +int __initdata pci_probe_only; /* * The PCI controller list. @@ -270,7 +272,11 @@ pcibios_fixup_bus(struct pci_bus *bus) end = hose->mem_space->start + pci_mem_end; if (hose->mem_space->end > end) hose->mem_space->end = end; - } + } else if (pci_probe_only && + (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { + pci_read_bridge_bases(bus); + pcibios_fixup_device_resources(dev, bus); + } for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) { struct pci_dev *dev = pci_dev_b(ln); @@ -407,6 +413,30 @@ pcibios_set_master(struct pci_dev *dev) pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64); } +static void __init +pcibios_claim_console_setup(void) +{ + struct list_head *lb; + + for(lb = pci_root_buses.next; lb != &pci_root_buses; lb = lb->next) { + struct pci_bus *b = pci_bus_b(lb); + struct list_head *ld; + + for (ld = b->devices.next; ld != &b->devices; ld = ld->next) { + struct pci_dev *dev = pci_dev_b(ld); + int i; + + for (i = 0; i < PCI_NUM_RESOURCES; i++) { + struct resource *r = &dev->resource[i]; + + if (r->parent || !r->start || !r->flags) + continue; + pci_claim_resource(dev, i); + } + } + } +} + void __init common_init_pci(void) { @@ -424,7 +454,12 @@ common_init_pci(void) next_busno += 1; } - pci_assign_unassigned_resources(); + if (pci_probe_only) + pcibios_claim_console_setup(); + else /* FIXME: `else' will be removed when + pci_assign_unassigned_resources() is able to work + correctly with [partially] allocated PCI tree. */ + pci_assign_unassigned_resources(); pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq); } diff --git a/arch/alpha/kernel/pci_impl.h b/arch/alpha/kernel/pci_impl.h index 7139e6c2da7..eadf7784870 100644 --- a/arch/alpha/kernel/pci_impl.h +++ b/arch/alpha/kernel/pci_impl.h @@ -150,11 +150,18 @@ struct pci_iommu_arena extern struct pci_controller *hose_head, **hose_tail; extern struct pci_controller *pci_isa_hose; +/* Indicate that we trust the console to configure things properly. */ +extern int pci_probe_only; + extern void common_init_pci(void); extern u8 common_swizzle(struct pci_dev *, u8 *); extern struct pci_controller *alloc_pci_controller(void); extern struct resource *alloc_resource(void); +extern struct pci_iommu_arena *iommu_arena_new_node(int, + struct pci_controller *, + dma_addr_t, unsigned long, + unsigned long); extern struct pci_iommu_arena *iommu_arena_new(struct pci_controller *, dma_addr_t, unsigned long, unsigned long); diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c index 4276b64a9bc..436502888e1 100644 --- a/arch/alpha/kernel/pci_iommu.c +++ b/arch/alpha/kernel/pci_iommu.c @@ -58,8 +58,8 @@ size_for_memory(unsigned long max) } struct pci_iommu_arena * -iommu_arena_new(struct pci_controller *hose, dma_addr_t base, - unsigned long window_size, unsigned long align) +iommu_arena_new_node(int nid, struct pci_controller *hose, dma_addr_t base, + unsigned long window_size, unsigned long align) { unsigned long mem_size; struct pci_iommu_arena *arena; @@ -73,9 +73,36 @@ iommu_arena_new(struct pci_controller *hose, dma_addr_t base, if (align < mem_size) align = mem_size; + +#ifdef CONFIG_DISCONTIGMEM + + if (!NODE_DATA(nid) || + (NULL == (arena = alloc_bootmem_node(NODE_DATA(nid), + sizeof(*arena))))) { + printk("%s: couldn't allocate arena from node %d\n" + " falling back to system-wide allocation\n", + __FUNCTION__, nid); + arena = alloc_bootmem(sizeof(*arena)); + } + + if (!NODE_DATA(nid) || + (NULL == (arena->ptes = __alloc_bootmem_node(NODE_DATA(nid), + mem_size, + align, + 0)))) { + printk("%s: couldn't allocate arena ptes from node %d\n" + " falling back to system-wide allocation\n", + __FUNCTION__, nid); + arena->ptes = __alloc_bootmem(mem_size, align, 0); + } + +#else /* CONFIG_DISCONTIGMEM */ + arena = alloc_bootmem(sizeof(*arena)); arena->ptes = __alloc_bootmem(mem_size, align, 0); +#endif /* CONFIG_DISCONTIGMEM */ + spin_lock_init(&arena->lock); arena->hose = hose; arena->dma_base = base; @@ -89,6 +116,13 @@ iommu_arena_new(struct pci_controller *hose, dma_addr_t base, return arena; } +struct pci_iommu_arena * +iommu_arena_new(struct pci_controller *hose, dma_addr_t base, + unsigned long window_size, unsigned long align) +{ + return iommu_arena_new_node(0, hose, base, window_size, align); +} + /* Must be called with the arena lock held */ static long iommu_arena_find_pages(struct pci_iommu_arena *arena, long n, long mask) diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h index 62ba3f89553..bb0adcbcb31 100644 --- a/arch/alpha/kernel/proto.h +++ b/arch/alpha/kernel/proto.h @@ -1,4 +1,6 @@ #include + + /* Prototypes of functions used across modules here in this directory. */ #define vucp volatile unsigned char * @@ -41,6 +43,22 @@ extern void lca_init_arch(void); extern void lca_machine_check(u64, u64, struct pt_regs *); extern void lca_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); +/* core_marvel.c */ +extern struct pci_ops marvel_pci_ops; +extern void marvel_init_arch(void); +extern void marvel_kill_arch(int); +extern void marvel_machine_check(u64, u64, struct pt_regs *); +extern void marvel_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); +extern int marvel_pa_to_nid(unsigned long); +extern int marvel_cpuid_to_nid(int); +extern unsigned long marvel_node_mem_start(int); +extern unsigned long marvel_node_mem_size(int); +extern int marvel_srmcons_allowed(void); +extern struct _alpha_agp_info *marvel_agp_info(void); +struct io7 *marvel_find_io7(int pe); +struct io7 *marvel_next_io7(struct io7 *prev); +void io7_clear_errors(struct io7 *io7); + /* core_mcpcia.c */ extern struct pci_ops mcpcia_pci_ops; extern void mcpcia_init_arch(void); @@ -68,6 +86,7 @@ extern void titan_init_arch(void); extern void titan_kill_arch(int); extern void titan_machine_check(u64, u64, struct pt_regs *); extern void titan_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); +extern struct _alpha_agp_info *titan_agp_info(void); /* core_tsunami.c */ extern struct pci_ops tsunami_pci_ops; @@ -82,6 +101,10 @@ extern void wildfire_init_arch(void); extern void wildfire_kill_arch(int); extern void wildfire_machine_check(u64, u64, struct pt_regs *); extern void wildfire_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); +extern int wildfire_pa_to_nid(unsigned long); +extern int wildfire_cpuid_to_nid(int); +extern unsigned long wildfire_node_mem_start(int); +extern unsigned long wildfire_node_mem_size(int); /* setup.c */ extern unsigned long srm_hae; @@ -145,10 +168,17 @@ extern int ptrace_cancel_bpt (struct task_struct *child); extern void dik_show_regs(struct pt_regs *regs, unsigned long *r9_15); extern void die_if_kernel(char *, struct pt_regs *, long, unsigned long *); +/* sys_titan.c */ +extern void titan_dispatch_irqs(u64, struct pt_regs *); + /* ../mm/init.c */ extern void switch_to_system_map(void); extern void srm_paging_stop(void); +/* ../mm/remap.c */ +extern int __alpha_remap_area_pages(unsigned long, unsigned long, + unsigned long, unsigned long); + /* irq.c */ #ifdef CONFIG_SMP diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index 6c9e86da2a9..e8719e35606 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c @@ -155,6 +155,7 @@ WEAK(eb66p_mv); WEAK(eiger_mv); WEAK(jensen_mv); WEAK(lx164_mv); +WEAK(marvel_ev7_mv); WEAK(miata_mv); WEAK(mikasa_mv); WEAK(mikasa_primo_mv); @@ -174,6 +175,7 @@ WEAK(sable_gamma_mv); WEAK(shark_mv); WEAK(sx164_mv); WEAK(takara_mv); +WEAK(titan_mv); WEAK(webbrick_mv); WEAK(wildfire_mv); WEAK(xl_mv); @@ -288,7 +290,7 @@ setup_memory(void *kernel_end) (hwrpb->mddt_offset + (unsigned long) hwrpb); for_each_mem_cluster(memdesc, cluster, i) { - printk("memcluster %d, usage %01lx, start %8lu, end %8lu\n", + printk("memcluster %lu, usage %01lx, start %8lu, end %8lu\n", i, cluster->usage, cluster->start_pfn, cluster->start_pfn + cluster->numpages); @@ -303,6 +305,24 @@ setup_memory(void *kernel_end) max_low_pfn = end; } + /* + * Except for the NUMA systems (wildfire, marvel) all of the + * Alpha systems we run on support 32GB of memory or less. + * Since the NUMA systems introduce large holes in memory addressing, + * we can get into a situation where there is not enough contiguous + * memory for the memory map. + * + * Limit memory to the first 32GB to limit the NUMA systems to + * memory on their first node (wildfire) or 2 (marvel) to avoid + * not being able to produce the memory map. In order to access + * all of the memory on the NUMA systems, build with discontiguous + * memory support. + * + * If the user specified a memory limit, let that memory limit stand. + */ + if (!mem_size_limit) + mem_size_limit = (32ul * 1024 * 1024 * 1024) >> PAGE_SHIFT; + if (mem_size_limit && max_low_pfn >= mem_size_limit) { printk("setup: forcing memory size to %ldK (from %ldK).\n", @@ -677,7 +697,7 @@ static char systype_names[][16] = { "Mikasa", "EB64", "EB66", "EB64+", "AlphaBook1", "Rawhide", "K2", "Lynx", "XL", "EB164", "Noritake", "Cortex", "29", "Miata", "XXM", "Takara", "Yukon", - "Tsunami", "Wildfire", "CUSCO", "Eiger", "Titan" + "Tsunami", "Wildfire", "CUSCO", "Eiger", "Titan", "Marvel" }; static char unofficial_names[][8] = {"100", "Ruffian"}; @@ -696,15 +716,20 @@ static int eb64p_indices[] = {0,0,1,2}; static char eb66_names[][8] = {"EB66", "EB66+"}; static int eb66_indices[] = {0,0,1}; +static char marvel_names[][16] = { + "Marvel/EV7" +}; +static int marvel_indices[] = { 0 }; + static char rawhide_names[][16] = { "Dodge", "Wrangler", "Durango", "Tincup", "DaVinci" }; static int rawhide_indices[] = {0,0,0,1,1,2,2,3,3,4,4}; static char titan_names[][16] = { - "0", "Privateer" + "DEFAULT", "Privateer", "Falcon", "Granite" }; -static int titan_indices[] = {0,1}; +static int titan_indices[] = {0,1,2,2,3}; static char tsunami_names[][16] = { "0", "DP264", "Warhol", "Windjammer", "Monet", "Clipper", @@ -757,6 +782,7 @@ get_sysvec(unsigned long type, unsigned long variation, unsigned long cpu) NULL, /* CUSCO */ &eiger_mv, /* Eiger */ NULL, /* Titan */ + NULL, /* Marvel */ }; static struct alpha_machine_vector *unofficial_vecs[] __initdata = @@ -794,10 +820,17 @@ get_sysvec(unsigned long type, unsigned long variation, unsigned long cpu) &eb66p_mv }; + static struct alpha_machine_vector *marvel_vecs[] __initdata = + { + &marvel_ev7_mv, + }; + static struct alpha_machine_vector *titan_vecs[] __initdata = { - NULL, + &titan_mv, /* default */ &privateer_mv, /* privateer */ + &titan_mv, /* falcon */ + &privateer_mv, /* granite */ }; static struct alpha_machine_vector *tsunami_vecs[] __initdata = @@ -862,7 +895,12 @@ get_sysvec(unsigned long type, unsigned long variation, unsigned long cpu) if (member < N(eb66_indices)) vec = eb66_vecs[eb66_indices[member]]; break; + case ST_DEC_MARVEL: + if (member < N(marvel_indices)) + vec = marvel_vecs[marvel_indices[member]]; + break; case ST_DEC_TITAN: + vec = titan_vecs[0]; /* default */ if (member < N(titan_indices)) vec = titan_vecs[titan_indices[member]]; break; @@ -1001,11 +1039,16 @@ get_sysnames(unsigned long type, unsigned long variation, unsigned long cpu, if (member < N(eb66_indices)) *variation_name = eb66_names[eb66_indices[member]]; break; + case ST_DEC_MARVEL: + if (member < N(marvel_indices)) + *variation_name = marvel_names[marvel_indices[member]]; + break; case ST_DEC_RAWHIDE: if (member < N(rawhide_indices)) *variation_name = rawhide_names[rawhide_indices[member]]; break; case ST_DEC_TITAN: + *variation_name = titan_names[0]; /* default */ if (member < N(titan_indices)) *variation_name = titan_names[titan_indices[member]]; break; diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c index 148aaaf310f..46eff5eeb85 100644 --- a/arch/alpha/kernel/smp.c +++ b/arch/alpha/kernel/smp.c @@ -72,37 +72,19 @@ static int smp_secondary_alive __initdata = 0; /* Which cpus ids came online. */ unsigned long cpu_present_mask; +volatile unsigned long cpu_online_map; /* cpus reported in the hwrpb */ static unsigned long hwrpb_cpu_present_mask __initdata = 0; -static int max_cpus = -1; /* Command-line limitation. */ int smp_num_probed; /* Internal processor count */ int smp_num_cpus = 1; /* Number that came online. */ -int smp_threads_ready; /* True once the per process idle is forked. */ cycles_t cacheflush_time; unsigned long cache_decay_ticks; extern void calibrate_delay(void); -extern asmlinkage void entInt(void); -static int __init nosmp(char *str) -{ - max_cpus = 0; - return 1; -} - -__setup("nosmp", nosmp); - -static int __init maxcpus(char *str) -{ - get_option(&str, &max_cpus); - return 1; -} - -__setup("maxcpus", maxcpus); - /* * Called by both boot and secondaries to move global data into @@ -151,6 +133,11 @@ smp_callin(void) { int cpuid = hard_smp_processor_id(); + if (test_and_set_bit(cpuid, &cpu_online_map)) { + printk("??, cpu 0x%x already present??\n", cpuid); + BUG(); + } + /* Turn on machine checks. */ wrmces(7); @@ -163,6 +150,9 @@ smp_callin(void) /* Get our local ticker going. */ smp_setup_percpu_timer(cpuid); + /* Call platform-specific callin, if specified */ + if (alpha_mv.smp_callin) alpha_mv.smp_callin(); + /* All kernel threads share the same mm context. */ atomic_inc(&init_mm.mm_count); current->active_mm = &init_mm; @@ -181,10 +171,6 @@ smp_callin(void) wmb(); smp_secondary_alive = 1; - /* Wait for the go code. */ - while (!smp_threads_ready) - barrier(); - DBGS(("smp_callin: commencing CPU %d current %p active_mm %p\n", cpuid, current, current->active_mm)); @@ -432,7 +418,7 @@ fork_by_hand(void) /* Don't care about the contents of regs since we'll never reschedule the forked task. */ struct pt_regs regs; - return do_fork(CLONE_VM|CLONE_IDLETASK, 0, ®s, 0, NULL); + return do_fork(CLONE_VM|CLONE_IDLETASK, 0, ®s, 0, NULL, NULL); } /* @@ -542,13 +528,12 @@ setup_smp(void) } /* - * Called by smp_init bring all the secondaries online and hold them. + * Called by smp_init prepare the secondaries */ void __init -smp_boot_cpus(void) +smp_prepare_cpus(unsigned int max_cpus) { int cpu_count, i; - unsigned long bogosum; /* Take care of some initial bookkeeping. */ memset(ipi_data, 0, sizeof(ipi_data)); @@ -559,6 +544,9 @@ smp_boot_cpus(void) smp_tune_scheduling(boot_cpuid); smp_setup_percpu_timer(boot_cpuid); + /* We have already have the boot CPU online.. */ + set_bit(boot_cpuid, &cpu_online_map); + /* Nothing to do on a UP box, or when told not to. */ if (smp_num_probed == 1 || max_cpus == 0) { cpu_present_mask = 1UL << boot_cpuid; @@ -569,44 +557,20 @@ smp_boot_cpus(void) printk(KERN_INFO "SMP starting up secondaries.\n"); cpu_count = 1; - for (i = 0; i < NR_CPUS; i++) { + for (i = 0; (i < NR_CPUS) && (cpu_count < max_cpus); i++) { if (i == boot_cpuid) continue; if (((hwrpb_cpu_present_mask >> i) & 1) == 0) continue; - if (smp_boot_one_cpu(i)) - continue; - cpu_present_mask |= 1UL << i; cpu_count++; } - if (cpu_count == 1) { - printk(KERN_ERR "SMP: Only one lonely processor alive.\n"); - return; - } - - bogosum = 0; - for (i = 0; i < NR_CPUS; i++) { - if (cpu_present_mask & (1UL << i)) - bogosum += cpu_data[i].loops_per_jiffy; - } - printk(KERN_INFO "SMP: Total of %d processors activated " - "(%lu.%02lu BogoMIPS).\n", - cpu_count, (bogosum + 2500) / (500000/HZ), - ((bogosum + 2500) / (5000/HZ)) % 100); - smp_num_cpus = cpu_count; } -void __init -smp_prepare_cpus(unsigned int max_cpus) -{ - smp_boot_cpus(); -} - void __devinit smp_prepare_boot_cpu(void) { @@ -616,14 +580,26 @@ smp_prepare_boot_cpu(void) int __devinit __cpu_up(unsigned int cpu) { + smp_boot_one_cpu(cpu); + return cpu_online(cpu) ? 0 : -ENOSYS; } void __init smp_cpus_done(unsigned int max_cpus) { - smp_threads_ready = 1; - mb(); + int cpu; + unsigned long bogosum = 0; + + for(cpu = 0; cpu < NR_CPUS; cpu++) + if (cpu_online(cpu)) + bogosum += cpu_data[cpu].loops_per_jiffy; + + printk(KERN_INFO "SMP: Total of %d processors activated " + "(%lu.%02lu BogoMIPS).\n", + num_online_cpus(), + (bogosum + 2500) / (500000/HZ), + ((bogosum + 2500) / (5000/HZ)) % 100); } @@ -865,11 +841,36 @@ smp_call_function_on_cpu (void (*func) (void *info), void *info, int retry, && time_before (jiffies, timeout)) barrier(); - /* We either got one or timed out -- clear the lock. */ + /* If there's no response yet, log a message but allow a longer + * timeout period -- if we get a response this time, log + * a message saying when we got it.. + */ + if (atomic_read(&data.unstarted_count) > 0) { + long start_time = jiffies; + printk(KERN_ERR "%s: initial timeout -- trying long wait\n", + __FUNCTION__); + timeout = jiffies + 30 * HZ; + while (atomic_read(&data.unstarted_count) > 0 + && time_before(jiffies, timeout)) + barrier(); + if (atomic_read(&data.unstarted_count) <= 0) { + long delta = jiffies - start_time; + printk(KERN_ERR + "%s: response %ld.%ld seconds into long wait\n", + __FUNCTION__, delta / HZ, + (100 * (delta - ((delta / HZ) * HZ))) / HZ); + } + } + + /* We either got one or timed out -- clear the lock. */ mb(); smp_call_function_data = 0; - if (atomic_read (&data.unstarted_count) > 0) - return -ETIMEDOUT; + + /* + * If after both the initial and long timeout periods we still don't + * have a response, something is very wrong... + */ + BUG_ON(atomic_read (&data.unstarted_count) > 0); /* Wait for a complete response, if needed. */ if (wait) { @@ -884,7 +885,7 @@ int smp_call_function (void (*func) (void *info), void *info, int retry, int wait) { return smp_call_function_on_cpu (func, info, retry, wait, - cpu_present_mask); + cpu_online_map); } static void diff --git a/arch/alpha/kernel/sys_marvel.c b/arch/alpha/kernel/sys_marvel.c new file mode 100644 index 00000000000..212213effa2 --- /dev/null +++ b/arch/alpha/kernel/sys_marvel.c @@ -0,0 +1,500 @@ +/* + * linux/arch/alpha/kernel/sys_marvel.c + * + * Marvel / IO7 support + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "proto.h" +#include "err_impl.h" +#include "irq_impl.h" +#include "pci_impl.h" +#include "machvec_impl.h" + +#if NR_IRQS < MARVEL_NR_IRQS +# error NR_IRQS < MARVEL_NR_IRQS !!! +#endif + + +/* + * Interrupt handling. + */ +static void +io7_device_interrupt(unsigned long vector, struct pt_regs * regs) +{ + unsigned int pid; + unsigned int irq; + + /* + * Vector is 0x800 + (interrupt) + * + * where (interrupt) is: + * + * ...16|15 14|13 4|3 0 + * -----+-----+--------+--- + * PE | 0 | irq | 0 + * + * where (irq) is + * + * 0x0800 - 0x0ff0 - 0x0800 + (LSI id << 4) + * 0x1000 - 0x2ff0 - 0x1000 + (MSI_DAT<8:0> << 4) + */ + pid = vector >> 16; + irq = ((vector & 0xffff) - 0x800) >> 4; + + irq += 16; /* offset for legacy */ + irq &= MARVEL_IRQ_VEC_IRQ_MASK; /* not too many bits */ + irq |= pid << MARVEL_IRQ_VEC_PE_SHIFT; /* merge the pid */ + + handle_irq(irq, regs); +} + +static volatile unsigned long * +io7_get_irq_ctl(unsigned int irq, struct io7 **pio7) +{ + volatile unsigned long *ctl; + unsigned int pid; + struct io7 *io7; + + pid = irq >> MARVEL_IRQ_VEC_PE_SHIFT; + + if (!(io7 = marvel_find_io7(pid))) { + printk(KERN_ERR + "%s for nonexistent io7 -- vec %x, pid %d\n", + __FUNCTION__, irq, pid); + return NULL; + } + + irq &= MARVEL_IRQ_VEC_IRQ_MASK; /* isolate the vector */ + irq -= 16; /* subtract legacy bias */ + + if (irq >= 0x180) { + printk(KERN_ERR + "%s for invalid irq -- pid %d adjusted irq %x\n", + __FUNCTION__, pid, irq); + return NULL; + } + + ctl = &io7->csrs->PO7_LSI_CTL[irq & 0xff].csr; /* assume LSI */ + if (irq >= 0x80) /* MSI */ + ctl = &io7->csrs->PO7_MSI_CTL[((irq - 0x80) >> 5) & 0x0f].csr; + + if (pio7) *pio7 = io7; + return ctl; +} + +static void +io7_enable_irq(unsigned int irq) +{ + volatile unsigned long *ctl; + struct io7 *io7; + + ctl = io7_get_irq_ctl(irq, &io7); + if (!ctl || !io7) { + printk(KERN_ERR "%s: get_ctl failed for irq %x\n", + __FUNCTION__, irq); + return; + } + + spin_lock(&io7->irq_lock); + *ctl |= 1UL << 24; + mb(); + *ctl; + spin_unlock(&io7->irq_lock); +} + +static void +io7_disable_irq(unsigned int irq) +{ + volatile unsigned long *ctl; + struct io7 *io7; + + ctl = io7_get_irq_ctl(irq, &io7); + if (!ctl || !io7) { + printk(KERN_ERR "%s: get_ctl failed for irq %x\n", + __FUNCTION__, irq); + return; + } + + spin_lock(&io7->irq_lock); + *ctl &= ~(1UL << 24); + mb(); + *ctl; + spin_unlock(&io7->irq_lock); +} + +static unsigned int +io7_startup_irq(unsigned int irq) +{ + io7_enable_irq(irq); + return 0; /* never anything pending */ +} + +static void +io7_end_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + io7_enable_irq(irq); +} + +static void +marvel_irq_noop(unsigned int irq) +{ + return; +} + +static unsigned int +marvel_irq_noop_return(unsigned int irq) +{ + return 0; +} + +static struct hw_interrupt_type marvel_legacy_irq_type = { + .typename = "LEGACY", + .startup = marvel_irq_noop_return, + .shutdown = marvel_irq_noop, + .enable = marvel_irq_noop, + .disable = marvel_irq_noop, + .ack = marvel_irq_noop, + .end = marvel_irq_noop, +}; + +static struct hw_interrupt_type io7_lsi_irq_type = { + .typename = "LSI", + .startup = io7_startup_irq, + .shutdown = io7_disable_irq, + .enable = io7_enable_irq, + .disable = io7_disable_irq, + .ack = io7_disable_irq, + .end = io7_end_irq, +}; + +static struct hw_interrupt_type io7_msi_irq_type = { + .typename = "MSI", + .startup = io7_startup_irq, + .shutdown = io7_disable_irq, + .enable = io7_enable_irq, + .disable = io7_disable_irq, + .ack = marvel_irq_noop, + .end = io7_end_irq, +}; + +static void +io7_redirect_irq(struct io7 *io7, + volatile unsigned long *csr, + unsigned int where) +{ + unsigned long val; + + val = *csr; + val &= ~(0x1ffUL << 24); /* clear the target pid */ + val |= ((unsigned long)where << 24); /* set the new target pid */ + + *csr = val; + mb(); + *csr; +} + +static void +io7_redirect_one_lsi(struct io7 *io7, unsigned int which, unsigned int where) +{ + unsigned long val; + + /* + * LSI_CTL has target PID @ 14 + */ + val = io7->csrs->PO7_LSI_CTL[which].csr; + val &= ~(0x1ffUL << 14); /* clear the target pid */ + val |= ((unsigned long)where << 14); /* set teh new target pid */ + + io7->csrs->PO7_LSI_CTL[which].csr = val; + mb(); + io7->csrs->PO7_LSI_CTL[which].csr; +} + +static void +io7_redirect_one_msi(struct io7 *io7, unsigned int which, unsigned int where) +{ + unsigned long val; + + /* + * MSI_CTL has target PID @ 14 + */ + val = io7->csrs->PO7_MSI_CTL[which].csr; + val &= ~(0x1ffUL << 14); /* clear the target pid */ + val |= ((unsigned long)where << 14); /* set teh new target pid */ + + io7->csrs->PO7_MSI_CTL[which].csr = val; + mb(); + io7->csrs->PO7_MSI_CTL[which].csr; +} + +static void __init +init_one_io7_lsi(struct io7 *io7, unsigned int which, unsigned int where) +{ + /* + * LSI_CTL has target PID @ 14 + */ + io7->csrs->PO7_LSI_CTL[which].csr = ((unsigned long)where << 14); + mb(); + io7->csrs->PO7_LSI_CTL[which].csr; +} + +static void __init +init_one_io7_msi(struct io7 *io7, unsigned int which, unsigned int where) +{ + /* + * MSI_CTL has target PID @ 14 + */ + io7->csrs->PO7_MSI_CTL[which].csr = ((unsigned long)where << 14); + mb(); + io7->csrs->PO7_MSI_CTL[which].csr; +} + +static void __init +init_io7_irqs(struct io7 *io7, + struct hw_interrupt_type *lsi_ops, + struct hw_interrupt_type *msi_ops) +{ + long base = (io7->pe << MARVEL_IRQ_VEC_PE_SHIFT) + 16; + long i; + + printk("Initializing interrupts for IO7 at PE %u - base %lx\n", + io7->pe, base); + + /* + * Where should interrupts from this IO7 go? + * + * They really should be sent to the local CPU to avoid having to + * traverse the mesh, but if it's not an SMP kernel, they have to + * go to the boot CPU. Send them all to the boot CPU for now, + * as each secondary starts, it can redirect it's local device + * interrupts. + */ + printk(" Interrupts reported to CPU at PE %u\n", boot_cpuid); + + spin_lock(&io7->irq_lock); + + /* set up the error irqs */ + io7_redirect_irq(io7, &io7->csrs->HLT_CTL.csr, boot_cpuid); + io7_redirect_irq(io7, &io7->csrs->HPI_CTL.csr, boot_cpuid); + io7_redirect_irq(io7, &io7->csrs->CRD_CTL.csr, boot_cpuid); + io7_redirect_irq(io7, &io7->csrs->STV_CTL.csr, boot_cpuid); + io7_redirect_irq(io7, &io7->csrs->HEI_CTL.csr, boot_cpuid); + + /* Set up the lsi irqs. */ + for (i = 0; i < 128; ++i) { + irq_desc[base + i].status = IRQ_DISABLED | IRQ_LEVEL; + irq_desc[base + i].handler = lsi_ops; + } + + /* Disable the implemented irqs in hardware. */ + for (i = 0; i < 0x60; ++i) + init_one_io7_lsi(io7, i, boot_cpuid); + + init_one_io7_lsi(io7, 0x74, boot_cpuid); + init_one_io7_lsi(io7, 0x75, boot_cpuid); + + + /* Set up the msi irqs. */ + for (i = 128; i < (128 + 512); ++i) { + irq_desc[base + i].status = IRQ_DISABLED | IRQ_LEVEL; + irq_desc[base + i].handler = msi_ops; + } + + for (i = 0; i < 16; ++i) + init_one_io7_msi(io7, i, boot_cpuid); + + spin_unlock(&io7->irq_lock); +} + +static void __init +marvel_init_irq(void) +{ + int i; + struct io7 *io7 = NULL; + + /* Reserve the legacy irqs. */ + for (i = 0; i < 16; ++i) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].handler = &marvel_legacy_irq_type; + } + + /* Init the io7 irqs. */ + for (io7 = NULL; (io7 = marvel_next_io7(io7)) != NULL; ) + init_io7_irqs(io7, &io7_lsi_irq_type, &io7_msi_irq_type); +} + +static int +marvel_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + struct pci_controller *hose = dev->sysdata; + struct io7_port *io7_port = hose->sysdata; + struct io7 *io7 = io7_port->io7; + int msi_loc, msi_data_off; + u16 msg_ctl; + u16 msg_dat; + u8 intline; + int irq; + + pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &intline); + irq = intline; + + msi_loc = pci_find_capability(dev, PCI_CAP_ID_MSI); + msg_ctl = 0; + if (msi_loc) + pci_read_config_word(dev, msi_loc + PCI_MSI_FLAGS, &msg_ctl); + + if (msg_ctl & PCI_MSI_FLAGS_ENABLE) { + msi_data_off = PCI_MSI_DATA_32; + if (msg_ctl & PCI_MSI_FLAGS_64BIT) + msi_data_off = PCI_MSI_DATA_64; + pci_read_config_word(dev, msi_loc + msi_data_off, &msg_dat); + + irq = msg_dat & 0x1ff; /* we use msg_data<8:0> */ + irq += 0x80; /* offset for lsi */ + +#if 1 + printk("PCI:%d:%d:%d (hose %d) [%s] is using MSI\n", + dev->bus->number, + PCI_SLOT(dev->devfn), + PCI_FUNC(dev->devfn), + hose->index, + dev->dev.name); + printk(" %d message(s) from 0x%04x\n", + 1 << ((msg_ctl & PCI_MSI_FLAGS_QSIZE) >> 4), + msg_dat); + printk(" reporting on %d IRQ(s) from %d (0x%x)\n", + 1 << ((msg_ctl & PCI_MSI_FLAGS_QSIZE) >> 4), + (irq + 16) | (io7->pe << MARVEL_IRQ_VEC_PE_SHIFT), + (irq + 16) | (io7->pe << MARVEL_IRQ_VEC_PE_SHIFT)); +#endif + +#if 0 + pci_write_config_word(dev, msi_loc + PCI_MSI_FLAGS, + msg_ctl & ~PCI_MSI_FLAGS_ENABLE); + pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &intline); + irq = intline; + + printk(" forcing LSI interrupt on irq %d [0x%x]\n", irq, irq); +#endif + } + + irq += 16; /* offset for legacy */ + irq |= io7->pe << MARVEL_IRQ_VEC_PE_SHIFT; /* merge the pid */ + + return irq; +} + +static void __init +marvel_init_pci(void) +{ + struct io7 *io7; + + marvel_register_error_handlers(); + + pci_probe_only = 1; + common_init_pci(); + +#ifdef CONFIG_VGA_HOSE + locate_and_init_vga(NULL); +#endif + + /* Clear any io7 errors. */ + for (io7 = NULL; (io7 = marvel_next_io7(io7)) != NULL; ) + io7_clear_errors(io7); +} + +static void +marvel_init_rtc(void) +{ + init_rtc_irq(); +} + +static void +marvel_smp_callin(void) +{ + int cpuid = hard_smp_processor_id(); + struct io7 *io7 = marvel_find_io7(cpuid); + unsigned int i; + + if (!io7) + return; + + /* + * There is a local IO7 - redirect all of it's interrupts here. + */ + printk("Redirecting IO7 interrupts to local CPU at PE %u\n", cpuid); + + /* Redirect the error IRQS here. */ + io7_redirect_irq(io7, &io7->csrs->HLT_CTL.csr, cpuid); + io7_redirect_irq(io7, &io7->csrs->HPI_CTL.csr, cpuid); + io7_redirect_irq(io7, &io7->csrs->CRD_CTL.csr, cpuid); + io7_redirect_irq(io7, &io7->csrs->STV_CTL.csr, cpuid); + io7_redirect_irq(io7, &io7->csrs->HEI_CTL.csr, cpuid); + + /* Redirect the implemented LSIs here. */ + for (i = 0; i < 0x60; ++i) + io7_redirect_one_lsi(io7, i, cpuid); + + io7_redirect_one_lsi(io7, 0x74, cpuid); + io7_redirect_one_lsi(io7, 0x75, cpuid); + + /* Redirect the MSIs here. */ + for (i = 0; i < 16; ++i) + io7_redirect_one_msi(io7, i, cpuid); +} + +/* + * System Vectors + */ +struct alpha_machine_vector marvel_ev7_mv __initmv = { + .vector_name = "MARVEL/EV7", + DO_EV7_MMU, + DO_DEFAULT_RTC, + DO_MARVEL_IO, + DO_MARVEL_BUS, + .machine_check = marvel_machine_check, + .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS, + .min_io_address = DEFAULT_IO_BASE, + .min_mem_address = DEFAULT_MEM_BASE, + .pci_dac_offset = IO7_DAC_OFFSET, + + .nr_irqs = MARVEL_NR_IRQS, + .device_interrupt = io7_device_interrupt, + + .agp_info = marvel_agp_info, + + .smp_callin = marvel_smp_callin, + .init_arch = marvel_init_arch, + .init_irq = marvel_init_irq, + .init_rtc = marvel_init_rtc, + .init_pci = marvel_init_pci, + .kill_arch = marvel_kill_arch, + .pci_map_irq = marvel_map_irq, + .pci_swizzle = common_swizzle, + + .pa_to_nid = marvel_pa_to_nid, + .cpuid_to_nid = marvel_cpuid_to_nid, + .node_mem_start = marvel_node_mem_start, + .node_mem_size = marvel_node_mem_size, +}; +ALIAS_MV(marvel_ev7) diff --git a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c dissimilarity index 61% index 9fe6e89f89e..79f72209654 100644 --- a/arch/alpha/kernel/sys_titan.c +++ b/arch/alpha/kernel/sys_titan.c @@ -1,389 +1,421 @@ -/* - * linux/arch/alpha/kernel/sys_titan.c - * - * Copyright (C) 1995 David A Rusling - * Copyright (C) 1996, 1999 Jay A Estabrook - * Copyright (C) 1998, 1999 Richard Henderson - * Copyright (C) 1999, 2000 Jeff Wiedemeier - * - * Code supporting TITAN systems (EV6+TITAN), currently: - * Privateer - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "proto.h" -#include "irq_impl.h" -#include "pci_impl.h" -#include "machvec_impl.h" - -/* Note mask bit is true for ENABLED irqs. */ -static unsigned long cached_irq_mask; -/* Titan boards handle at most four CPUs. */ -static unsigned long cpu_irq_affinity[4] = { ~0UL, ~0UL, ~0UL, ~0UL }; - -spinlock_t titan_irq_lock = SPIN_LOCK_UNLOCKED; - -static void -titan_update_irq_hw(unsigned long mask) -{ - register titan_cchip *cchip = TITAN_cchip; - unsigned long isa_enable = 1UL << 55; - register int bcpu = boot_cpuid; - -#ifdef CONFIG_SMP - register unsigned long cpm = cpu_present_mask; - volatile unsigned long *dim0, *dim1, *dim2, *dim3; - unsigned long mask0, mask1, mask2, mask3, dummy; - - mask &= ~isa_enable; - mask0 = mask & cpu_irq_affinity[0]; - mask1 = mask & cpu_irq_affinity[1]; - mask2 = mask & cpu_irq_affinity[2]; - mask3 = mask & cpu_irq_affinity[3]; - - if (bcpu == 0) mask0 |= isa_enable; - else if (bcpu == 1) mask1 |= isa_enable; - else if (bcpu == 2) mask2 |= isa_enable; - else mask3 |= isa_enable; - - dim0 = &cchip->dim0.csr; - dim1 = &cchip->dim1.csr; - dim2 = &cchip->dim2.csr; - dim3 = &cchip->dim3.csr; - if ((cpm & 1) == 0) dim0 = &dummy; - if ((cpm & 2) == 0) dim1 = &dummy; - if ((cpm & 4) == 0) dim2 = &dummy; - if ((cpm & 8) == 0) dim3 = &dummy; - - *dim0 = mask0; - *dim1 = mask1; - *dim2 = mask2; - *dim3 = mask3; - mb(); - *dim0; - *dim1; - *dim2; - *dim3; -#else - volatile unsigned long *dimB; - dimB = &cchip->dim0.csr; - if (bcpu == 1) dimB = &cchip->dim1.csr; - else if (bcpu == 2) dimB = &cchip->dim2.csr; - else if (bcpu == 3) dimB = &cchip->dim3.csr; - - *dimB = mask | isa_enable; - mb(); - *dimB; -#endif -} - -static inline void -privateer_enable_irq(unsigned int irq) -{ - spin_lock(&titan_irq_lock); - cached_irq_mask |= 1UL << (irq - 16); - titan_update_irq_hw(cached_irq_mask); - spin_unlock(&titan_irq_lock); -} - -static inline void -privateer_disable_irq(unsigned int irq) -{ - spin_lock(&titan_irq_lock); - cached_irq_mask &= ~(1UL << (irq - 16)); - titan_update_irq_hw(cached_irq_mask); - spin_unlock(&titan_irq_lock); -} - -static unsigned int -privateer_startup_irq(unsigned int irq) -{ - privateer_enable_irq(irq); - return 0; /* never anything pending */ -} - -static void -privateer_end_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - privateer_enable_irq(irq); -} - -static void -cpu_set_irq_affinity(unsigned int irq, unsigned long affinity) -{ - int cpu; - - for (cpu = 0; cpu < 4; cpu++) { - if (affinity & (1UL << cpu)) - cpu_irq_affinity[cpu] |= 1UL << irq; - else - cpu_irq_affinity[cpu] &= ~(1UL << irq); - } - -} - -static void -privateer_set_affinity(unsigned int irq, unsigned long affinity) -{ - spin_lock(&titan_irq_lock); - cpu_set_irq_affinity(irq - 16, affinity); - titan_update_irq_hw(cached_irq_mask); - spin_unlock(&titan_irq_lock); -} - -static struct hw_interrupt_type privateer_irq_type = { - .typename = "PRIVATEER", - .startup = privateer_startup_irq, - .shutdown = privateer_disable_irq, - .enable = privateer_enable_irq, - .disable = privateer_disable_irq, - .ack = privateer_disable_irq, - .end = privateer_end_irq, - .set_affinity = privateer_set_affinity, -}; - -static void -privateer_device_interrupt(unsigned long vector, struct pt_regs * regs) -{ - printk("privateer_device_interrupt: NOT IMPLEMENTED YET!! \n"); -} - -static void -privateer_srm_device_interrupt(unsigned long vector, struct pt_regs * regs) -{ - int irq; - - irq = (vector - 0x800) >> 4; - handle_irq(irq, regs); -} - - -static void __init -init_titan_irqs(struct hw_interrupt_type * ops, int imin, int imax) -{ - long i; - for(i = imin; i <= imax; ++i) { - irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].handler = ops; - } -} - -static void __init -privateer_init_irq(void) -{ - outb(0, DMA1_RESET_REG); - outb(0, DMA2_RESET_REG); - outb(DMA_MODE_CASCADE, DMA2_MODE_REG); - outb(0, DMA2_MASK_REG); - - if (alpha_using_srm) - alpha_mv.device_interrupt = privateer_srm_device_interrupt; - - titan_update_irq_hw(0UL); - - init_i8259a_irqs(); - init_titan_irqs(&privateer_irq_type, 16, 63 + 16); -} - -/* - * Privateer PCI Fixup configuration. - * - * PCHIP 0 BUS 0 (Hose 0) - * - * IDSEL Dev What - * ----- --- ---- - * 18 7 Embedded Southbridge - * 19 8 Slot 0 - * 20 9 Slot 1 - * 21 10 Slot 2 - * 22 11 Slot 3 - * 23 12 Embedded HotPlug controller - * 27 16 Embedded Southbridge IDE - * 29 18 Embedded Southbridge PMU - * 31 20 Embedded Southbridge USB - * - * PCHIP 1 BUS 0 (Hose 1) - * - * IDSEL Dev What - * ----- --- ---- - * 12 1 Slot 0 - * 13 2 Slot 1 - * 17 6 Embedded hotPlug controller - * - * PCHIP 0 BUS 1 (Hose 2) - * - * IDSEL What - * ----- ---- - * NONE AGP - * - * PCHIP 1 BUS 1 (Hose 3) - * - * IDSEL Dev What - * ----- --- ---- - * 12 1 Slot 0 - * 13 2 Slot 1 - * 17 6 Embedded hotPlug controller - * - * Summary @ TITAN_CSR_DIM0: - * Bit Meaning - * 0-7 Unused - * 8 PCHIP 0 BUS 1 YUKON (if present) - * 9 PCHIP 1 BUS 1 YUKON - * 10 PCHIP 1 BUS 0 YUKON - * 11 PCHIP 0 BUS 0 YUKON - * 12 PCHIP 0 BUS 0 SLOT 2 INT A - * 13 PCHIP 0 BUS 0 SLOT 2 INT B - * 14 PCHIP 0 BUS 0 SLOT 2 INT C - * 15 PCHIP 0 BUS 0 SLOT 2 INT D - * 16 PCHIP 0 BUS 0 SLOT 3 INT A - * 17 PCHIP 0 BUS 0 SLOT 3 INT B - * 18 PCHIP 0 BUS 0 SLOT 3 INT C - * 19 PCHIP 0 BUS 0 SLOT 3 INT D - * 20 PCHIP 0 BUS 0 SLOT 0 INT A - * 21 PCHIP 0 BUS 0 SLOT 0 INT B - * 22 PCHIP 0 BUS 0 SLOT 0 INT C - * 23 PCHIP 0 BUS 0 SLOT 0 INT D - * 24 PCHIP 0 BUS 0 SLOT 1 INT A - * 25 PCHIP 0 BUS 0 SLOT 1 INT B - * 26 PCHIP 0 BUS 0 SLOT 1 INT C - * 27 PCHIP 0 BUS 0 SLOT 1 INT D - * 28 PCHIP 1 BUS 0 SLOT 0 INT A - * 29 PCHIP 1 BUS 0 SLOT 0 INT B - * 30 PCHIP 1 BUS 0 SLOT 0 INT C - * 31 PCHIP 1 BUS 0 SLOT 0 INT D - * 32 PCHIP 1 BUS 0 SLOT 1 INT A - * 33 PCHIP 1 BUS 0 SLOT 1 INT B - * 34 PCHIP 1 BUS 0 SLOT 1 INT C - * 35 PCHIP 1 BUS 0 SLOT 1 INT D - * 36 PCHIP 1 BUS 1 SLOT 0 INT A - * 37 PCHIP 1 BUS 1 SLOT 0 INT B - * 38 PCHIP 1 BUS 1 SLOT 0 INT C - * 39 PCHIP 1 BUS 1 SLOT 0 INT D - * 40 PCHIP 1 BUS 1 SLOT 1 INT A - * 41 PCHIP 1 BUS 1 SLOT 1 INT B - * 42 PCHIP 1 BUS 1 SLOT 1 INT C - * 43 PCHIP 1 BUS 1 SLOT 1 INT D - * 44 AGP INT A - * 45 AGP INT B - * 46-47 Unused - * 49 Reserved for Sleep mode - * 50 Temperature Warning (optional) - * 51 Power Warning (optional) - * 52 Reserved - * 53 South Bridge NMI - * 54 South Bridge SMI INT - * 55 South Bridge ISA Interrupt - * 56-58 Unused - * 59 PCHIP1_C_ERROR - * 60 PCHIP0_C_ERROR - * 61 PCHIP1_H_ERROR - * 62 PCHIP0_H_ERROR - * 63 Reserved - * - */ -static int __init -privateer_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ - u8 irq; - - pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); - - /* is it routed through ISA? */ - if ((irq & 0xF0) == 0xE0) - return (int)irq; - - return (int)irq + 16; /* HACK -- this better only be called once */ -} - -#ifdef CONFIG_VGA_HOSE -static struct pci_controller * __init -privateer_vga_hose_select(struct pci_controller *h1, struct pci_controller *h2) -{ - struct pci_controller *hose = h1; - int agp1, agp2; - - /* which hose(s) are agp? */ - agp1 = (0 != (TITAN_agp & (1 << h1->index))); - agp2 = (0 != (TITAN_agp & (1 << h2->index))); - - hose = h1; /* default to h1 */ - if (agp1 ^ agp2) { - if (agp2) hose = h2; /* take agp if only one */ - } else if (h2->index < h1->index) - hose = h2; /* first hose if 2xpci or 2xagp */ - - return hose; -} -#endif - -static void __init -privateer_init_pci(void) -{ - common_init_pci(); - SMC669_Init(0); -#ifdef CONFIG_VGA_HOSE - locate_and_init_vga(privateer_vga_hose_select); -#endif -} - -void -privateer_machine_check(unsigned long vector, unsigned long la_ptr, - struct pt_regs * regs) -{ - /* only handle system events here */ - if (vector != SCB_Q_SYSEVENT) - return titan_machine_check(vector, la_ptr, regs); - - /* it's a system event, handle it here */ - printk("PRIVATEER 680 Machine Check on CPU %d\n", smp_processor_id()); -} - - -/* - * The System Vectors - */ - -struct alpha_machine_vector privateer_mv __initmv = { - .vector_name = "PRIVATEER", - DO_EV6_MMU, - DO_DEFAULT_RTC, - DO_TITAN_IO, - DO_TITAN_BUS, - .machine_check = privateer_machine_check, - .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS, - .min_io_address = DEFAULT_IO_BASE, - .min_mem_address = DEFAULT_MEM_BASE, - .pci_dac_offset = TITAN_DAC_OFFSET, - - .nr_irqs = 80, /* 64 + 16 */ - .device_interrupt = privateer_device_interrupt, - - .init_arch = titan_init_arch, - .init_irq = privateer_init_irq, - .init_rtc = common_init_rtc, - .init_pci = privateer_init_pci, - .kill_arch = titan_kill_arch, - .pci_map_irq = privateer_map_irq, - .pci_swizzle = common_swizzle, -}; -ALIAS_MV(privateer) +/* + * linux/arch/alpha/kernel/sys_titan.c + * + * Copyright (C) 1995 David A Rusling + * Copyright (C) 1996, 1999 Jay A Estabrook + * Copyright (C) 1998, 1999 Richard Henderson + * Copyright (C) 1999, 2000 Jeff Wiedemeier + * + * Code supporting TITAN systems (EV6+TITAN), currently: + * Privateer + * Falcon + * Granite + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "proto.h" +#include "irq_impl.h" +#include "pci_impl.h" +#include "machvec_impl.h" +#include "err_impl.h" + + +/* + * Titan generic + */ + +/* + * Titan supports up to 4 CPUs + */ +static unsigned long titan_cpu_irq_affinity[4] = { ~0UL, ~0UL, ~0UL, ~0UL }; + +/* + * Mask is set (1) if enabled + */ +static unsigned long titan_cached_irq_mask; + +/* + * Need SMP-safe access to interrupt CSRs + */ +spinlock_t titan_irq_lock = SPIN_LOCK_UNLOCKED; + +static void +titan_update_irq_hw(unsigned long mask) +{ + register titan_cchip *cchip = TITAN_cchip; + unsigned long isa_enable = 1UL << 55; + register int bcpu = boot_cpuid; + +#ifdef CONFIG_SMP + register unsigned long cpm = cpu_present_mask; + volatile unsigned long *dim0, *dim1, *dim2, *dim3; + unsigned long mask0, mask1, mask2, mask3, dummy; + + mask &= ~isa_enable; + mask0 = mask & titan_cpu_irq_affinity[0]; + mask1 = mask & titan_cpu_irq_affinity[1]; + mask2 = mask & titan_cpu_irq_affinity[2]; + mask3 = mask & titan_cpu_irq_affinity[3]; + + if (bcpu == 0) mask0 |= isa_enable; + else if (bcpu == 1) mask1 |= isa_enable; + else if (bcpu == 2) mask2 |= isa_enable; + else mask3 |= isa_enable; + + dim0 = &cchip->dim0.csr; + dim1 = &cchip->dim1.csr; + dim2 = &cchip->dim2.csr; + dim3 = &cchip->dim3.csr; + if ((cpm & 1) == 0) dim0 = &dummy; + if ((cpm & 2) == 0) dim1 = &dummy; + if ((cpm & 4) == 0) dim2 = &dummy; + if ((cpm & 8) == 0) dim3 = &dummy; + + *dim0 = mask0; + *dim1 = mask1; + *dim2 = mask2; + *dim3 = mask3; + mb(); + *dim0; + *dim1; + *dim2; + *dim3; +#else + volatile unsigned long *dimB; + dimB = &cchip->dim0.csr; + if (bcpu == 1) dimB = &cchip->dim1.csr; + else if (bcpu == 2) dimB = &cchip->dim2.csr; + else if (bcpu == 3) dimB = &cchip->dim3.csr; + + *dimB = mask | isa_enable; + mb(); + *dimB; +#endif +} + +static inline void +titan_enable_irq(unsigned int irq) +{ + spin_lock(&titan_irq_lock); + titan_cached_irq_mask |= 1UL << (irq - 16); + titan_update_irq_hw(titan_cached_irq_mask); + spin_unlock(&titan_irq_lock); +} + +static inline void +titan_disable_irq(unsigned int irq) +{ + spin_lock(&titan_irq_lock); + titan_cached_irq_mask &= ~(1UL << (irq - 16)); + titan_update_irq_hw(titan_cached_irq_mask); + spin_unlock(&titan_irq_lock); +} + +static unsigned int +titan_startup_irq(unsigned int irq) +{ + titan_enable_irq(irq); + return 0; /* never anything pending */ +} + +static void +titan_end_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + titan_enable_irq(irq); +} + +static void +titan_cpu_set_irq_affinity(unsigned int irq, unsigned long affinity) +{ + int cpu; + + for (cpu = 0; cpu < 4; cpu++) { + if (affinity & (1UL << cpu)) + titan_cpu_irq_affinity[cpu] |= 1UL << irq; + else + titan_cpu_irq_affinity[cpu] &= ~(1UL << irq); + } + +} + +static void +titan_set_irq_affinity(unsigned int irq, unsigned long affinity) +{ + spin_lock(&titan_irq_lock); + titan_cpu_set_irq_affinity(irq - 16, affinity); + titan_update_irq_hw(titan_cached_irq_mask); + spin_unlock(&titan_irq_lock); +} + +static void +titan_device_interrupt(unsigned long vector, struct pt_regs * regs) +{ + printk("titan_device_interrupt: NOT IMPLEMENTED YET!! \n"); +} + +static void +titan_srm_device_interrupt(unsigned long vector, struct pt_regs * regs) +{ + int irq; + + irq = (vector - 0x800) >> 4; + handle_irq(irq, regs); +} + + +static void __init +init_titan_irqs(struct hw_interrupt_type * ops, int imin, int imax) +{ + long i; + for (i = imin; i <= imax; ++i) { + irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; + irq_desc[i].handler = ops; + } +} + +static struct hw_interrupt_type titan_irq_type = { + .typename = "TITAN", + .startup = titan_startup_irq, + .shutdown = titan_disable_irq, + .enable = titan_enable_irq, + .disable = titan_disable_irq, + .ack = titan_disable_irq, + .end = titan_end_irq, + .set_affinity = titan_set_irq_affinity, +}; + +static void +titan_intr_nop(int irq, void *dev_id, struct pt_regs *regs) +{ + /* + * This is a NOP interrupt handler for the purposes of + * event counting -- just return. + */ +} + +static void __init +titan_init_irq(void) +{ + if (alpha_using_srm && !alpha_mv.device_interrupt) + alpha_mv.device_interrupt = titan_srm_device_interrupt; + if (!alpha_mv.device_interrupt) + alpha_mv.device_interrupt = titan_device_interrupt; + + titan_update_irq_hw(0); + + init_titan_irqs(&titan_irq_type, 16, 63 + 16); +} + +static void __init +titan_legacy_init_irq(void) +{ + /* init the legacy dma controller */ + outb(0, DMA1_RESET_REG); + outb(0, DMA2_RESET_REG); + outb(DMA_MODE_CASCADE, DMA2_MODE_REG); + outb(0, DMA2_MASK_REG); + + /* init the legacy irq controller */ + init_i8259a_irqs(); + + /* init the titan irqs */ + titan_init_irq(); +} + +void +titan_dispatch_irqs(u64 mask, struct pt_regs *regs) +{ + unsigned long vector; + + /* + * Mask down to those interrupts which are enable on this processor + */ + mask &= titan_cpu_irq_affinity[smp_processor_id()]; + + /* + * Dispatch all requested interrupts + */ + while (mask) { + /* convert to SRM vector... priority is <63> -> <0> */ + __asm__("ctlz %1, %0" : "=r"(vector) : "r"(mask)); + vector = 63 - vector; + mask &= ~(1UL << vector); /* clear it out */ + vector = 0x900 + (vector << 4); /* convert to SRM vector */ + + /* dispatch it */ + alpha_mv.device_interrupt(vector, regs); + } +} + + +/* + * Titan Family + */ +static void __init +titan_late_init(void) +{ + /* + * Enable the system error interrupts. These interrupts are + * all reported to the kernel as machine checks, so the handler + * is a nop so it can be called to count the individual events. + */ + request_irq(63+16, titan_intr_nop, SA_INTERRUPT, + "CChip Error", NULL); + request_irq(62+16, titan_intr_nop, SA_INTERRUPT, + "PChip 0 H_Error", NULL); + request_irq(61+16, titan_intr_nop, SA_INTERRUPT, + "PChip 1 H_Error", NULL); + request_irq(60+16, titan_intr_nop, SA_INTERRUPT, + "PChip 0 C_Error", NULL); + request_irq(59+16, titan_intr_nop, SA_INTERRUPT, + "PChip 1 C_Error", NULL); + + /* + * Register our error handlers. + */ + titan_register_error_handlers(); + + /* + * Check if the console left us any error logs. + */ + cdl_check_console_data_log(); + +} + +static int __devinit +titan_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + u8 intline; + int irq; + + /* Get the current intline. */ + pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &intline); + irq = intline; + + /* Is it explicitly routed through ISA? */ + if ((irq & 0xF0) == 0xE0) + return irq; + + /* Offset by 16 to make room for ISA interrupts 0 - 15. */ + return irq + 16; +} + +static void __init +titan_init_pci(void) +{ + /* + * This isn't really the right place, but there's some init + * that needs to be done after everything is basically up. + */ + titan_late_init(); + + pci_probe_only = 1; + common_init_pci(); + SMC669_Init(0); +#ifdef CONFIG_VGA_HOSE + locate_and_init_vga(NULL); +#endif +} + + +/* + * Privateer + */ +static void __init +privateer_init_pci(void) +{ + /* + * Hook a couple of extra err interrupts that the + * common titan code won't. + */ + request_irq(53+16, titan_intr_nop, SA_INTERRUPT, + "NMI", NULL); + request_irq(50+16, titan_intr_nop, SA_INTERRUPT, + "Temperature Warning", NULL); + + /* + * Finish with the common version. + */ + return titan_init_pci(); +} + + +/* + * The System Vectors. + */ +struct alpha_machine_vector titan_mv __initmv = { + .vector_name = "TITAN", + DO_EV6_MMU, + DO_DEFAULT_RTC, + DO_TITAN_IO, + DO_TITAN_BUS, + .machine_check = titan_machine_check, + .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS, + .min_io_address = DEFAULT_IO_BASE, + .min_mem_address = DEFAULT_MEM_BASE, + .pci_dac_offset = TITAN_DAC_OFFSET, + + .nr_irqs = 80, /* 64 + 16 */ + /* device_interrupt will be filled in by titan_init_irq */ + + .agp_info = titan_agp_info, + + .init_arch = titan_init_arch, + .init_irq = titan_legacy_init_irq, + .init_rtc = common_init_rtc, + .init_pci = titan_init_pci, + + .kill_arch = titan_kill_arch, + .pci_map_irq = titan_map_irq, + .pci_swizzle = common_swizzle, +}; +ALIAS_MV(titan) + +struct alpha_machine_vector privateer_mv __initmv = { + .vector_name = "PRIVATEER", + DO_EV6_MMU, + DO_DEFAULT_RTC, + DO_TITAN_IO, + DO_TITAN_BUS, + .machine_check = privateer_machine_check, + .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS, + .min_io_address = DEFAULT_IO_BASE, + .min_mem_address = DEFAULT_MEM_BASE, + .pci_dac_offset = TITAN_DAC_OFFSET, + + .nr_irqs = 80, /* 64 + 16 */ + /* device_interrupt will be filled in by titan_init_irq */ + + .agp_info = titan_agp_info, + + .init_arch = titan_init_arch, + .init_irq = titan_legacy_init_irq, + .init_rtc = common_init_rtc, + .init_pci = privateer_init_pci, + + .kill_arch = titan_kill_arch, + .pci_map_irq = titan_map_irq, + .pci_swizzle = common_swizzle, +}; +/* No alpha_mv alias for privateer since we compile it + in unconditionally with titan; setup_arch knows how to cope. */ diff --git a/arch/alpha/kernel/sys_wildfire.c b/arch/alpha/kernel/sys_wildfire.c index 0e8fa5959ee..2169c5249d5 100644 --- a/arch/alpha/kernel/sys_wildfire.c +++ b/arch/alpha/kernel/sys_wildfire.c @@ -353,5 +353,10 @@ struct alpha_machine_vector wildfire_mv __initmv = { .kill_arch = wildfire_kill_arch, .pci_map_irq = wildfire_map_irq, .pci_swizzle = common_swizzle, + + .pa_to_nid = wildfire_pa_to_nid, + .cpuid_to_nid = wildfire_cpuid_to_nid, + .node_mem_start = wildfire_node_mem_start, + .node_mem_size = wildfire_node_mem_size, }; ALIAS_MV(wildfire) diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c index 4963bab746a..9803b8ca067 100644 --- a/arch/alpha/kernel/traps.c +++ b/arch/alpha/kernel/traps.c @@ -118,7 +118,7 @@ dik_show_trace(unsigned long *sp) long i = 0; printk("Trace:"); while (0x1ff8 & (unsigned long) sp) { - extern unsigned long _stext, _etext; + extern char _stext[], _etext[]; unsigned long tmp = *sp; sp++; if (tmp < (unsigned long) &_stext) diff --git a/arch/alpha/lib/callback_srm.S b/arch/alpha/lib/callback_srm.S index de2edebb1b2..0528acd0d9a 100644 --- a/arch/alpha/lib/callback_srm.S +++ b/arch/alpha/lib/callback_srm.S @@ -78,6 +78,8 @@ CALLBACK(puts, CCB_PUTS, 4) CALLBACK(open, CCB_OPEN, 3) CALLBACK(close, CCB_CLOSE, 2) CALLBACK(read, CCB_READ, 5) +CALLBACK(open_console, CCB_OPEN_CONSOLE, 1) +CALLBACK(close_console, CCB_CLOSE_CONSOLE, 1) CALLBACK(getenv, CCB_GET_ENV, 4) CALLBACK(setenv, CCB_SET_ENV, 4) CALLBACK(getc, CCB_GETC, 2) diff --git a/arch/alpha/mm/Makefile b/arch/alpha/mm/Makefile index ec693be931a..1b423a5a7aa 100644 --- a/arch/alpha/mm/Makefile +++ b/arch/alpha/mm/Makefile @@ -2,6 +2,6 @@ # Makefile for the linux alpha-specific parts of the memory manager. # -obj-y := init.o fault.o extable.o +obj-y := init.o fault.o extable.o remap.o obj-$(CONFIG_DISCONTIGMEM) += numa.o diff --git a/arch/alpha/mm/numa.c b/arch/alpha/mm/numa.c index 1375e90f809..99680b5c247 100644 --- a/arch/alpha/mm/numa.c +++ b/arch/alpha/mm/numa.c @@ -19,8 +19,8 @@ #include #include -plat_pg_data_t *plat_node_data[MAX_NUMNODES]; -bootmem_data_t plat_node_bdata[MAX_NUMNODES]; +pg_data_t node_data[MAX_NUMNODES]; +bootmem_data_t node_bdata[MAX_NUMNODES]; #undef DEBUG_DISCONTIG #ifdef DEBUG_DISCONTIG @@ -65,12 +65,12 @@ setup_memory_node(int nid, void *kernel_end) unsigned long start, end; unsigned long node_pfn_start, node_pfn_end; int i; - unsigned long node_datasz = PFN_UP(sizeof(plat_pg_data_t)); + unsigned long node_datasz = PFN_UP(sizeof(pg_data_t)); int show_init = 0; /* Find the bounds of current node */ - node_pfn_start = (nid * NODE_MAX_MEM_SIZE) >> PAGE_SHIFT; - node_pfn_end = node_pfn_start + (NODE_MAX_MEM_SIZE >> PAGE_SHIFT); + node_pfn_start = (node_mem_start(nid)) >> PAGE_SHIFT; + node_pfn_end = node_pfn_start + (node_mem_size(nid) >> PAGE_SHIFT); /* Find free clusters, and init and free the bootmem accordingly. */ memdesc = (struct memdesc_struct *) @@ -93,7 +93,7 @@ setup_memory_node(int nid, void *kernel_end) if (!show_init) { show_init = 1; - printk("Initialing bootmem allocator on Node ID %d\n", nid); + printk("Initializing bootmem allocator on Node ID %d\n", nid); } printk(" memcluster %2d, usage %1lx, start %8lu, end %8lu\n", i, cluster->usage, cluster->start_pfn, @@ -107,13 +107,17 @@ setup_memory_node(int nid, void *kernel_end) if (start < min_low_pfn) min_low_pfn = start; if (end > max_low_pfn) - max_low_pfn = end; + max_pfn = max_low_pfn = end; } - if (mem_size_limit && max_low_pfn >= mem_size_limit) { - printk("setup: forcing memory size to %ldK (from %ldK).\n", - mem_size_limit << (PAGE_SHIFT - 10), - max_low_pfn << (PAGE_SHIFT - 10)); + if (mem_size_limit && max_low_pfn > mem_size_limit) { + static int msg_shown = 0; + if (!msg_shown) { + msg_shown = 1; + printk("setup: forcing memory size to %ldK (from %ldK).\n", + mem_size_limit << (PAGE_SHIFT - 10), + max_low_pfn << (PAGE_SHIFT - 10)); + } max_low_pfn = mem_size_limit; } @@ -122,20 +126,22 @@ setup_memory_node(int nid, void *kernel_end) num_physpages += max_low_pfn - min_low_pfn; +#if 0 /* we'll try this one again in a little while */ /* Cute trick to make sure our local node data is on local memory */ - PLAT_NODE_DATA(nid) = (plat_pg_data_t *)(__va(min_low_pfn << PAGE_SHIFT)); - /* Quasi-mark the plat_pg_data_t as in-use */ + node_data[nid] = (pg_data_t *)(__va(min_low_pfn << PAGE_SHIFT)); +#endif + /* Quasi-mark the pg_data_t as in-use */ min_low_pfn += node_datasz; if (min_low_pfn >= max_low_pfn) { - printk(" not enough mem to reserve PLAT_NODE_DATA"); + printk(" not enough mem to reserve NODE_DATA"); return; } - NODE_DATA(nid)->bdata = &plat_node_bdata[nid]; + NODE_DATA(nid)->bdata = &node_bdata[nid]; printk(" Detected node memory: start %8lu, end %8lu\n", min_low_pfn, max_low_pfn); - DBGDCONT(" DISCONTIG: plat_node_data[%d] is at 0x%p\n", nid, PLAT_NODE_DATA(nid)); + DBGDCONT(" DISCONTIG: node_data[%d] is at 0x%p\n", nid, NODE_DATA(nid)); DBGDCONT(" DISCONTIG: NODE_DATA(%d)->bdata is at 0x%p\n", nid, NODE_DATA(nid)->bdata); /* Find the bounds of kernel memory. */ @@ -286,8 +292,8 @@ void __init paging_init(void) dma_local_pfn = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; for (nid = 0; nid < numnodes; nid++) { - unsigned long start_pfn = plat_node_bdata[nid].node_boot_start >> PAGE_SHIFT; - unsigned long end_pfn = plat_node_bdata[nid].node_low_pfn; + unsigned long start_pfn = node_bdata[nid].node_boot_start >> PAGE_SHIFT; + unsigned long end_pfn = node_bdata[nid].node_low_pfn; if (dma_local_pfn >= end_pfn - start_pfn) zones_size[ZONE_DMA] = end_pfn - start_pfn; @@ -302,52 +308,6 @@ void __init paging_init(void) memset((void *)ZERO_PGE, 0, PAGE_SIZE); } -#define printkdot() \ -do { \ - if (!(i++ % ((100UL*1024*1024)>>PAGE_SHIFT))) \ - printk("."); \ -} while(0) - -#define clobber(p, size) memset((p)->virtual, 0xaa, (size)) - -void __init mem_stress(void) -{ - LIST_HEAD(x); - LIST_HEAD(xx); - struct page * p; - unsigned long i = 0; - - printk("starting memstress"); - while ((p = alloc_pages(GFP_ATOMIC, 1))) { - clobber(p, PAGE_SIZE*2); - list_add(&p->list, &x); - printkdot(); - } - while ((p = alloc_page(GFP_ATOMIC))) { - clobber(p, PAGE_SIZE); - list_add(&p->list, &xx); - printkdot(); - } - while (!list_empty(&x)) { - p = list_entry(x.next, struct page, list); - clobber(p, PAGE_SIZE*2); - list_del(x.next); - __free_pages(p, 1); - printkdot(); - } - while (!list_empty(&xx)) { - p = list_entry(xx.next, struct page, list); - clobber(p, PAGE_SIZE); - list_del(xx.next); - __free_pages(p, 0); - printkdot(); - } - printk("I'm still alive duh!\n"); -} - -#undef printkdot -#undef clobber - void __init mem_init(void) { unsigned long codesize, reservedpages, datasize, initsize, pfn; @@ -355,9 +315,9 @@ void __init mem_init(void) extern char _text, _etext, _data, _edata; extern char __init_begin, __init_end; unsigned long nid, i; - mem_map_t * lmem_map; + struct page * lmem_map; - high_memory = (void *) __va(max_mapnr <node_start_pfn; - for (i = 0; i < PLAT_NODE_DATA_SIZE(nid); i++, pfn++) + for (i = 0; i < node_size(nid); i++, pfn++) if (page_is_ram(pfn) && PageReserved(lmem_map+i)) reservedpages++; } @@ -401,8 +361,8 @@ show_mem(void) show_free_areas(); printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); for (nid = 0; nid < numnodes; nid++) { - mem_map_t * lmem_map = NODE_MEM_MAP(nid); - i = PLAT_NODE_DATA_SIZE(nid); + struct page * lmem_map = node_mem_map(nid); + i = node_size(nid); while (i-- > 0) { total++; if (PageReserved(lmem_map+i)) @@ -420,5 +380,4 @@ show_mem(void) printk("%ld reserved pages\n",reserved); printk("%ld pages shared\n",shared); printk("%ld pages swap cached\n",cached); - printk("%ld pages in page table cache\n",pgtable_cache_size); } diff --git a/arch/alpha/mm/remap.c b/arch/alpha/mm/remap.c new file mode 100644 index 00000000000..19817ad3d89 --- /dev/null +++ b/arch/alpha/mm/remap.c @@ -0,0 +1,90 @@ +#include +#include +#include + +/* called with the page_table_lock held */ +static inline void +remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, + unsigned long phys_addr, unsigned long flags) +{ + unsigned long end; + unsigned long pfn; + + address &= ~PMD_MASK; + end = address + size; + if (end > PMD_SIZE) + end = PMD_SIZE; + if (address >= end) + BUG(); + pfn = phys_addr >> PAGE_SHIFT; + do { + if (!pte_none(*pte)) { + printk("remap_area_pte: page already exists\n"); + BUG(); + } + set_pte(pte, pfn_pte(pfn, + __pgprot(_PAGE_VALID | _PAGE_ASM | + _PAGE_KRE | _PAGE_KWE | flags))); + address += PAGE_SIZE; + pfn++; + pte++; + } while (address && (address < end)); +} + +/* called with the page_table_lock held */ +static inline int +remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, + unsigned long phys_addr, unsigned long flags) +{ + unsigned long end; + + address &= ~PGDIR_MASK; + end = address + size; + if (end > PGDIR_SIZE) + end = PGDIR_SIZE; + phys_addr -= address; + if (address >= end) + BUG(); + do { + pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address); + if (!pte) + return -ENOMEM; + remap_area_pte(pte, address, end - address, + address + phys_addr, flags); + address = (address + PMD_SIZE) & PMD_MASK; + pmd++; + } while (address && (address < end)); + return 0; +} + +int +__alpha_remap_area_pages(unsigned long address, unsigned long phys_addr, + unsigned long size, unsigned long flags) +{ + pgd_t * dir; + int error = 0; + unsigned long end = address + size; + + phys_addr -= address; + dir = pgd_offset(&init_mm, address); + flush_cache_all(); + if (address >= end) + BUG(); + spin_lock(&init_mm.page_table_lock); + do { + pmd_t *pmd; + pmd = pmd_alloc(&init_mm, dir, address); + error = -ENOMEM; + if (!pmd) + break; + if (remap_area_pmd(pmd, address, end - address, + phys_addr + address, flags)) + break; + error = 0; + address = (address + PGDIR_SIZE) & PGDIR_MASK; + dir++; + } while (address && (address < end)); + spin_unlock(&init_mm.page_table_lock); + return error; +} + diff --git a/arch/alpha/vmlinux.lds.S b/arch/alpha/vmlinux.lds.S index 20f7cadffed..abceb48a669 100644 --- a/arch/alpha/vmlinux.lds.S +++ b/arch/alpha/vmlinux.lds.S @@ -1,6 +1,8 @@ #include +#include OUTPUT_FORMAT("elf64-alpha") +OUTPUT_ARCH(alpha) ENTRY(__start) PHDRS { kernel PT_LOAD ; } jiffies = jiffies_64; @@ -9,67 +11,43 @@ SECTIONS #ifdef CONFIG_ALPHA_LEGACY_START_ADDRESS . = 0xfffffc0000310000; #else - . = 0xfffffc0000810000; + . = 0xfffffc0001010000; #endif - .text : { - _text = .; - *(.text) - _etext = .; + _text = .; /* Text and read-only data */ + .text : { + *(.text) + *(.fixup) + *(.gnu.warning) } :kernel + _etext = .; /* End of text section */ - /* Exception table */ - __ex_table ALIGN(16) : { - __start___ex_table = .; - *(__ex_table) - __stop___ex_table = .; - } - - /* Kernel symbol table */ - __ksymtab ALIGN(8) : { - __start___ksymtab = .; - *(__ksymtab) - __stop___ksymtab = .; - } - - /* Kernel symbol table: GPL only */ - __gpl_ksymtab ALIGN(8) : { - __start___gpl_ksymtab = .; - *(__gpl_ksymtab) - __stop___gpl_ksymtab = .; - } - - /* All kernel symbols */ - __kallsyms ALIGN(8) : { - __start___kallsyms = .; - *(__kallsyms) - __stop___kallsyms = .; - } + . = ALIGN(16); + __start___ex_table = .; /* Exception table */ + __ex_table : { *(__ex_table) } + __stop___ex_table = .; - .kstrtab : { *(.kstrtab) } - .rodata : { *(.rodata) *(.rodata.*) } + RODATA - /* Startup code */ - .init.text ALIGN(8192) : { - __init_begin = .; - *(.init.text) - } + /* Will be freed after init */ + . = ALIGN(8192); /* Init code and data */ + __init_begin = .; + .init.text : { *(.init.text) } .init.data : { *(.init.data) } - .init.setup ALIGN(16): { - __setup_start = .; - *(.init.setup) - __setup_end = .; - } + . = ALIGN(16); + __setup_start = .; + .init.setup : { *(.init.setup) } + __setup_end = .; - __param ALIGN(8): { - __start___param = .; - *(__param) - __stop___param = .; - } + . = ALIGN(8); + __start___param = .; + __param : { *(__param) } + __stop___param = .; - .initcall.init ALIGN(8): { - __initcall_start = .; + . = ALIGN(8); + __initcall_start = .; + .initcall.init : { *(.initcall1.init) *(.initcall2.init) *(.initcall3.init) @@ -77,54 +55,64 @@ SECTIONS *(.initcall5.init) *(.initcall6.init) *(.initcall7.init) - __initcall_end = .; } + __initcall_end = .; - .init.ramfs ALIGN(8192): { - __initramfs_start = .; - *(.init.ramfs) - __initramfs_end = .; - } + . = ALIGN(8192); + __initramfs_start = .; + .init.ramfs : { *(.init.ramfs) } + __initramfs_end = .; - .data.percpu ALIGN(64): { - __per_cpu_start = .; - *(.data.percpu) - __per_cpu_end = .; - } + . = ALIGN(64); + __per_cpu_start = .; + .data.percpu : { *(.data.percpu) } + __per_cpu_end = .; - /* The initial task and kernel stack */ - .data.init_thread ALIGN(2*8192) : { - __init_end = .; - *(.data.init_thread) - } + . = ALIGN(2*8192); + __init_end = .; + /* Freed after init ends here */ - /* Global data */ - .data.page_aligned ALIGN(8192) : { - _data = .; - *(.data.page_aligned) - } + /* Note 2 page alignment above. */ + .data.init_thread : { *(.data.init_thread) } + + . = ALIGN(8192); + .data.page_aligned : { *(.data.page_aligned) } + + . = ALIGN(64); .data.cacheline_aligned : { *(.data.cacheline_aligned) } - .data : { *(.data) CONSTRUCTORS } - .got : { *(.got) } - .sdata : { - *(.sdata) - _edata = .; - } - .sbss : { - __bss_start = .; - *(.sbss) *(.scommon) - } - .bss : { - *(.bss) *(COMMON) - __bss_stop = .; - _end = .; + _data = .; + .data : { /* Data */ + *(.data) + CONSTRUCTORS } + .got : { *(.got) } + .sdata : { *(.sdata) } + + _edata = .; /* End of data section */ + + __bss_start = .; + .sbss : { *(.sbss) *(.scommon) } + .bss : { *(.bss) *(COMMON) } + __bss_stop = .; + + _end = .; + + /* Sections to be discarded */ + /DISCARD/ : { *(.exit.text) *(.exit.data) *(.exitcall.exit) } + .mdebug 0 : { *(.mdebug) } .note 0 : { *(.note) } .comment 0 : { *(.comment) } + /* Stabs debugging sections */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } /* DWARF 1 */ .debug 0 : { *(.debug) } .line 0 : { *(.line) } @@ -147,6 +135,4 @@ SECTIONS .debug_funcnames 0 : { *(.debug_funcnames) } .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } - - /DISCARD/ : { *(.exit.text) *(.exit.data) *(.exitcall.exit) } } diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index 198558dd920..ccc4be1e64e 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -11,7 +11,7 @@ #include #include -#include /* for BUG() */ +#include #include #include #include diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index 7e6df7d5f2d..58e4c2d4b23 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S @@ -10,7 +10,7 @@ * This file is included twice in entry-common.S */ #ifndef NR_syscalls -#define NR_syscalls 256 +#define NR_syscalls 288 #else __syscall_start: @@ -253,6 +253,24 @@ __syscall_start: .long sys_lremovexattr .long sys_fremovexattr .long sys_tkill + .long sys_sendfile64 +/* 240 */ .long sys_futex + .long sys_sched_setaffinity + .long sys_sched_getaffinity + .long sys_io_setup + .long sys_io_destroy +/* 245 */ .long sys_io_getevents + .long sys_io_submit + .long sys_io_cancel + .long sys_exit_group + .long sys_lookup_dcookie +/* 250 */ .long sys_epoll_create + .long sys_epoll_ctl + .long sys_epoll_wait + .long sys_remap_file_pages + .long sys_ni_syscall /* sys_set_thread_area */ +/* 255 */ .long sys_ni_syscall /* sys_get_thread_area */ + .long sys_ni_syscall /* sys_set_tid_address */ __syscall_end: .rept NR_syscalls - (__syscall_end - __syscall_start) / 4 diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index b5bcb9e5275..6f482ff3936 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -91,15 +91,16 @@ void default_idle(void) void cpu_idle(void) { /* endless idle loop with no priority at all */ - preempt_disable(); while (1) { void (*idle)(void) = pm_idle; if (!idle) idle = default_idle; + preempt_disable(); leds_event(led_idle_start); while (!need_resched()) idle(); leds_event(led_idle_end); + preempt_enable(); schedule(); } } diff --git a/arch/arm/mach-integrator/cpu.c b/arch/arm/mach-integrator/cpu.c index 2d71baa7635..9a55cfdb6cb 100644 --- a/arch/arm/mach-integrator/cpu.c +++ b/arch/arm/mach-integrator/cpu.c @@ -228,4 +228,4 @@ static int __init integrator_cpu_init(void) return 0; } -core_initcall(integrator_cpu_init); +arch_initcall(integrator_cpu_init); diff --git a/arch/arm/mach-sa1100/cpu-sa1100.c b/arch/arm/mach-sa1100/cpu-sa1100.c index b4226692b90..9c1c4ba81c4 100644 --- a/arch/arm/mach-sa1100/cpu-sa1100.c +++ b/arch/arm/mach-sa1100/cpu-sa1100.c @@ -232,4 +232,4 @@ static int __init sa1100_dram_init(void) return ret; } -core_initcall(sa1100_dram_init); +arch_initcall(sa1100_dram_init); diff --git a/arch/arm/mach-sa1100/cpu-sa1110.c b/arch/arm/mach-sa1100/cpu-sa1110.c index 2ab03f867d8..ecfc2c113a7 100644 --- a/arch/arm/mach-sa1100/cpu-sa1110.c +++ b/arch/arm/mach-sa1100/cpu-sa1110.c @@ -345,4 +345,4 @@ static int __init sa1110_clk_init(void) return 0; } -core_initcall(sa1110_clk_init); +arch_initcall(sa1110_clk_init); diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index 22b0d6a1d19..3c38df1ee88 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types @@ -6,7 +6,7 @@ # To add an entry into this database, please see Documentation/arm/README, # or contact rmk@arm.linux.org.uk # -# Last update: Mon Dec 23 18:49:04 2002 +# Last update: Mon Jan 13 22:55:16 2003 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # @@ -198,7 +198,7 @@ omaha ARCH_OMAHA OMAHA 186 ta7 ARCH_TA7 TA7 187 nova SA1100_NOVA NOVA 188 hmk ARCH_HMK HMK 189 -inphinity ARCH_INPHINITY INPHINITY 190 +karo ARCH_KARO KARO 190 fester SA1100_FESTER FESTER 191 gpi ARCH_GPI GPI 192 smdk2410 ARCH_SMDK2410 SMDK2410 193 @@ -273,3 +273,11 @@ prpmc1100 ARCH_PRPMC1100 PRPMC1100 261 at91rm9200dk ARCH_AT91RM9200DK AT91RM9200DK 262 armstick ARCH_ARMSTICK ARMSTICK 263 armonie ARCH_ARMONIE ARMONIE 264 +mport1 ARCH_MPORT1 MPORT1 265 +s3c5410 ARCH_S3C5410 S3C5410 266 +zcp320a ARCH_ZCP320A ZCP320A 267 +i_box ARCH_I_BOX I_BOX 268 +stlc1502 ARCH_STLC1502 STLC1502 269 +siren ARCH_SIREN SIREN 270 +greenlake ARCH_GREENLAKE GREENLAKE 271 +argus ARCH_ARGUS ARGUS 272 diff --git a/arch/arm/vmlinux-armo.lds.in b/arch/arm/vmlinux-armo.lds.in index ce2b98b67fd..c1c3cd10756 100644 --- a/arch/arm/vmlinux-armo.lds.in +++ b/arch/arm/vmlinux-armo.lds.in @@ -2,6 +2,9 @@ * taken from the i386 version by Russell King * Written by Martin Mares */ + +#include + OUTPUT_ARCH(arm) ENTRY(stext) jiffies = jiffies_64; @@ -63,8 +66,6 @@ SECTIONS _etext = .; /* End of text section */ } - .kstrtab : { *(.kstrtab) } - . = ALIGN(16); __ex_table : { /* Exception table */ __start___ex_table = .; @@ -72,17 +73,7 @@ SECTIONS __stop___ex_table = .; } - __ksymtab : { /* Kernel symbol table */ - __start___ksymtab = .; - *(__ksymtab) - __stop___ksymtab = .; - } - - __gpl_ksymtab : { /* Kernel symbol table: GPL-only */ - __start___gpl_ksymtab = .; - *(__gpl_ksymtab) - __stop___gpl_ksymtab = .; - } + RODATA .data : { /* diff --git a/arch/arm/vmlinux-armv.lds.in b/arch/arm/vmlinux-armv.lds.in index 2f358b7a6a6..572fb352470 100644 --- a/arch/arm/vmlinux-armv.lds.in +++ b/arch/arm/vmlinux-armv.lds.in @@ -2,6 +2,9 @@ * taken from the i386 version by Russell King * Written by Martin Mares */ + +#include + OUTPUT_ARCH(arm) ENTRY(stext) jiffies = jiffies_64; @@ -66,8 +69,6 @@ SECTIONS _etext = .; /* End of text section */ } - .kstrtab : { *(.kstrtab) } - . = ALIGN(16); __ex_table : { /* Exception table */ __start___ex_table = .; @@ -75,23 +76,7 @@ SECTIONS __stop___ex_table = .; } - __gpl_ksymtab : { /* GPL Kernel symbol table */ - __start___gpl_ksymtab = .; - *(__gpl_ksymtab) - __stop___gpl_ksymtab = .; - } - - __ksymtab : { /* Kernel symbol table */ - __start___ksymtab = .; - *(__ksymtab) - __stop___ksymtab = .; - } - - __kallsyms : { /* All kernel symbols */ - __start___kallsyms = .; - *(__kallsyms) - __stop___kallsyms = .; - } + RODATA . = ALIGN(8192); diff --git a/arch/cris/vmlinux.lds.S b/arch/cris/vmlinux.lds.S index bc3231c2c3b..e033c81f19a 100644 --- a/arch/cris/vmlinux.lds.S +++ b/arch/cris/vmlinux.lds.S @@ -9,7 +9,8 @@ */ #include - +#include + jiffies = jiffies_64; SECTIONS { @@ -31,21 +32,12 @@ SECTIONS _etext = . ; /* End of text section */ __etext = .; - .rodata : { *(.rodata) *(.rodata.__*) } - .kstrtab : { *(.kstrtab) } - . = ALIGN(4); /* Exception table */ __start___ex_table = .; __ex_table : { *(__ex_table) } __stop___ex_table = .; - __start___ksymtab = .; /* Kernel symbol table */ - __ksymtab : { *(__ksymtab) } - __stop___ksymtab = .; - - __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only */ - __gpl_ksymtab : { *(__gpl_ksymtab) } - __stop___gpl_ksymtab = .; + RODATA . = ALIGN (4); ___data_start = . ; diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index dffda495f39..3ec0e526430 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -1181,6 +1181,8 @@ config EISA Otherwise, say N. +source "drivers/eisa/Kconfig" + config MCA bool "MCA support" depends on !(X86_VISWS || X86_VOYAGER) diff --git a/arch/i386/Makefile b/arch/i386/Makefile index fe0b05d847b..dfa5ced00a7 100644 --- a/arch/i386/Makefile +++ b/arch/i386/Makefile @@ -69,6 +69,10 @@ mcore-$(CONFIG_X86_NUMAQ) := mach-default mflags-$(CONFIG_X86_BIGSMP) := -Iinclude/asm-i386/mach-bigsmp mcore-$(CONFIG_X86_BIGSMP) := mach-default +#Summit subarch support +mflags-$(CONFIG_X86_SUMMIT) := -Iinclude/asm-i386/mach-summit +mcore-$(CONFIG_X86_SUMMIT) := mach-default + # default subarch .h files mflags-y += -Iinclude/asm-i386/mach-default diff --git a/arch/i386/defconfig b/arch/i386/defconfig index 869f19867f7..8cae61a843a 100644 --- a/arch/i386/defconfig +++ b/arch/i386/defconfig @@ -839,11 +839,6 @@ CONFIG_DUMMY_CONSOLE=y CONFIG_SOUND=y # -# Open Sound System -# -# CONFIG_SOUND_PRIME is not set - -# # Advanced Linux Sound Architecture # CONFIG_SND=y @@ -924,6 +919,11 @@ CONFIG_SND_INTEL8X0=y # CONFIG_SND_USB_AUDIO is not set # +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set + +# # USB support # CONFIG_USB=y diff --git a/arch/i386/kernel/acpi.c b/arch/i386/kernel/acpi.c index 6aa07dcba63..e0ce1ceccca 100644 --- a/arch/i386/kernel/acpi.c +++ b/arch/i386/kernel/acpi.c @@ -44,6 +44,8 @@ #include #include +#include +#include #define PREFIX "ACPI: " @@ -126,6 +128,8 @@ acpi_parse_madt ( printk(KERN_INFO PREFIX "Local APIC address 0x%08x\n", madt->lapic_address); + acpi_madt_oem_check(madt->header.oem_id, madt->header.oem_table_id); + return 0; } @@ -430,8 +434,10 @@ acpi_boot_init ( #endif /*CONFIG_X86_IO_APIC*/ #ifdef CONFIG_X86_LOCAL_APIC - if (acpi_lapic && acpi_ioapic) + if (acpi_lapic && acpi_ioapic) { smp_found_config = 1; + clustered_apic_check(); + } #endif return 0; diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c index d0272733c39..762a1a8d8c0 100644 --- a/arch/i386/kernel/cpu/amd.c +++ b/arch/i386/kernel/cpu/amd.c @@ -56,7 +56,7 @@ static void __init init_amd(struct cpuinfo_x86 *c) if (inl (CBAR) & CBAR_ENB) outl (0 | CBAR_KEY, CBAR); } - + break; case 5: if( c->x86_model < 6 ) { diff --git a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c index b0d322e7a93..fac3f907163 100644 --- a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c +++ b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c @@ -482,6 +482,7 @@ static int __init cpufreq_gx_init(void) driver->policy[0].cpuinfo.transition_latency = CPUFREQ_ETERNAL; driver->verify = &cpufreq_gx_verify; driver->setpolicy = &cpufreq_gx_setpolicy; + strncpy(driver->name, "gx-suspmod", CPUFREQ_NAME_LEN); gx_driver = driver; diff --git a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c index af05636fe86..722d29cc1b3 100644 --- a/arch/i386/kernel/cpu/proc.c +++ b/arch/i386/kernel/cpu/proc.c @@ -22,7 +22,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce", "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov", "pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx", - "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", NULL, + "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe", /* AMD-defined */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index ead9bab311b..09954f83b48 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -126,7 +126,8 @@ VM_MASK = 0x00020000 addl $4, %esp; \ 1: iret; \ .section .fixup,"ax"; \ -2: movl $(__USER_DS), %edx; \ +2: sti; \ + movl $(__USER_DS), %edx; \ movl %edx, %ds; \ movl %edx, %es; \ pushl $11; \ @@ -154,17 +155,6 @@ do_lcall: movl %eax,EFLAGS(%ebp) # movl %edx,EIP(%ebp) # Now we move them to their "normal" places movl %ecx,CS(%ebp) # - - # - # Call gates don't clear TF and NT in eflags like - # traps do, so we need to do it ourselves. - # %eax already contains eflags (but it may have - # DF set, clear that also) - # - andl $~(DF_MASK | TF_MASK | NT_MASK),%eax - pushl %eax - popfl - andl $-8192, %ebp # GET_THREAD_INFO movl TI_EXEC_DOMAIN(%ebp), %edx # Get the execution domain call *4(%edx) # Call the lcall7 handler for the domain diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 1e4be4e4f05..9d1a99a6ffe 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -278,7 +278,7 @@ static inline void balance_irq(int irq) new_cpu = move(entry->cpu, allowed_mask, now, random_number); if (entry->cpu != new_cpu) { entry->cpu = new_cpu; - set_ioapic_affinity(irq, 1 << new_cpu); + set_ioapic_affinity(irq, cpu_to_logical_apicid(new_cpu)); } } } @@ -719,8 +719,8 @@ void __init setup_IO_APIC_irqs(void) */ memset(&entry,0,sizeof(entry)); - entry.delivery_mode = dest_LowestPrio; - entry.dest_mode = INT_DELIVERY_MODE; + entry.delivery_mode = INT_DELIVERY_MODE; + entry.dest_mode = INT_DEST_MODE; entry.mask = 0; /* enable IRQ */ entry.dest.logical.logical_dest = TARGET_CPUS; @@ -799,10 +799,10 @@ void __init setup_ExtINT_IRQ0_pin(unsigned int pin, int vector) * We use logical delivery to get the timer IRQ * to the first CPU. */ - entry.dest_mode = INT_DELIVERY_MODE; + entry.dest_mode = INT_DEST_MODE; entry.mask = 0; /* unmask IRQ now */ entry.dest.logical.logical_dest = TARGET_CPUS; - entry.delivery_mode = dest_LowestPrio; + entry.delivery_mode = INT_DELIVERY_MODE; entry.polarity = 0; entry.trigger = 0; entry.vector = vector; @@ -1763,7 +1763,7 @@ late_initcall(io_apic_bug_finalize); #ifdef CONFIG_ACPI_BOOT -#define IO_APIC_MAX_ID 15 +#define IO_APIC_MAX_ID APIC_BROADCAST_ID int __init io_apic_get_unique_id (int ioapic, int apic_id) { @@ -1880,8 +1880,8 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq) memset(&entry,0,sizeof(entry)); - entry.delivery_mode = dest_LowestPrio; - entry.dest_mode = INT_DELIVERY_MODE; + entry.delivery_mode = INT_DELIVERY_MODE; + entry.dest_mode = INT_DEST_MODE; entry.dest.logical.logical_dest = TARGET_CPUS; entry.mask = 1; /* Disabled (masked) */ entry.trigger = 1; /* Level sensitive */ diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c index f41b3f2304f..3333811397b 100644 --- a/arch/i386/kernel/mpparse.c +++ b/arch/i386/kernel/mpparse.c @@ -72,8 +72,8 @@ static unsigned int __initdata num_processors; /* Bitmask of physically existing CPUs */ unsigned long phys_cpu_present_map; -int summit_x86 = 0; -u8 raw_phys_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID }; +int x86_summit = 0; +u8 bios_cpu_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID }; /* * Intel MP BIOS table parsing routines: @@ -186,7 +186,7 @@ void __init MP_processor_info (struct mpc_config_processor *m) ver = 0x10; } apic_version[m->mpc_apicid] = ver; - raw_phys_apicid[num_processors - 1] = m->mpc_apicid; + bios_cpu_apicid[num_processors - 1] = m->mpc_apicid; } static void __init MP_bus_info (struct mpc_config_bus *m) diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c index 4a77837cca8..2a3f3f057f7 100644 --- a/arch/i386/kernel/smp.c +++ b/arch/i386/kernel/smp.c @@ -24,6 +24,7 @@ #include #include #include +#include /* * Some notes on x86 processor bugs affecting SMP operation: diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index c393236ad8e..0d1158c3607 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -1045,10 +1045,10 @@ static void __init smp_boot_cpus(unsigned int max_cpus) /* * Don't even attempt to start the boot CPU! */ - if (apicid == boot_cpu_apicid) + if ((apicid == boot_cpu_apicid) || (apicid == BAD_APICID)) continue; - if (!(phys_cpu_present_map & (1 << bit))) + if (!check_apicid_present(bit)) continue; if (max_cpus <= cpucount+1) continue; diff --git a/arch/i386/vmlinux.lds.S b/arch/i386/vmlinux.lds.S index 222deebc9e6..cb0584239a3 100644 --- a/arch/i386/vmlinux.lds.S +++ b/arch/i386/vmlinux.lds.S @@ -1,6 +1,9 @@ /* ld script to make i386 Linux kernel * Written by Martin Mares ; */ + +#include + OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") OUTPUT_ARCH(i386) ENTRY(_start) @@ -18,26 +21,12 @@ SECTIONS _etext = .; /* End of text section */ - .rodata : { *(.rodata) *(.rodata.*) } - .kstrtab : { *(.kstrtab) } - . = ALIGN(16); /* Exception table */ __start___ex_table = .; __ex_table : { *(__ex_table) } __stop___ex_table = .; - . = ALIGN(64); - __start___ksymtab = .; /* Kernel symbol table */ - __ksymtab : { *(__ksymtab) } - __stop___ksymtab = .; - - __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only symbols */ - __gpl_ksymtab : { *(__gpl_ksymtab) } - __stop___gpl_ksymtab = .; - - __start___kallsyms = .; /* All kernel symbols */ - __kallsyms : { *(__kallsyms) } - __stop___kallsyms = .; + RODATA /* writeable */ .data : { /* Data */ diff --git a/arch/ia64/defconfig b/arch/ia64/defconfig index 7c4f8c633ed..e239ef34b35 100644 --- a/arch/ia64/defconfig +++ b/arch/ia64/defconfig @@ -657,6 +657,11 @@ CONFIG_VGA_CONSOLE=y CONFIG_SOUND=y # +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# # Open Sound System # CONFIG_SOUND_PRIME=y @@ -681,11 +686,6 @@ CONFIG_SOUND_CS4281=y # CONFIG_SOUND_TVMIXER is not set # -# Advanced Linux Sound Architecture -# -# CONFIG_SND is not set - -# # USB support # CONFIG_USB=y diff --git a/arch/ia64/vmlinux.lds.S b/arch/ia64/vmlinux.lds.S index 04a2fdf300d..37a65b7fb9a 100644 --- a/arch/ia64/vmlinux.lds.S +++ b/arch/ia64/vmlinux.lds.S @@ -4,6 +4,9 @@ #include #include +#define LOAD_OFFSET PAGE_OFFSET +#include + OUTPUT_FORMAT("elf64-ia64-little") OUTPUT_ARCH(ia64) ENTRY(phys_start) @@ -60,23 +63,6 @@ SECTIONS machvec_end = .; #endif - __start___ksymtab = .; /* Kernel symbol table */ - __ksymtab : AT(ADDR(__ksymtab) - PAGE_OFFSET) - { *(__ksymtab) } - __stop___ksymtab = .; - - __start___gpl_ksymtab = .; /* Kernel symbol table: GPL only */ - __gpl_ksymtab : AT(ADDR(__gpl_ksymtab) - PAGE_OFFSET) - { *(__gpl_ksymtab) } - __stop___gpl_ksymtab = .; - - __kallsyms : AT(ADDR(__kallsyms) - PAGE_OFFSET) - { - __start___kallsyms = .; /* All kernel symbols */ - *(__kallsyms) - __stop___kallsyms = .; - } - /* Unwind info & table: */ . = ALIGN(8); .IA_64.unwind_info : AT(ADDR(.IA_64.unwind_info) - PAGE_OFFSET) @@ -86,10 +72,8 @@ SECTIONS { *(.IA_64.unwind*) } ia64_unw_end = .; - .rodata : AT(ADDR(.rodata) - PAGE_OFFSET) - { *(.rodata) *(.rodata.*) } - .kstrtab : AT(ADDR(.kstrtab) - PAGE_OFFSET) - { *(.kstrtab) } + RODATA + .opd : AT(ADDR(.opd) - PAGE_OFFSET) { *(.opd) } diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 657e5f9afb9..cabe93920be 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -1720,6 +1720,31 @@ config GEN_RTC tristate "Generic /dev/rtc emulation" if !SUN3 depends on !ATARI default y if SUN3 + ---help--- + If you say Y here and create a character special file /dev/rtc with + major number 10 and minor number 135 using mknod ("man mknod"), you + will get access to the real time clock (or hardware clock) built + into your computer. + + It reports status information via the file /proc/driver/rtc and its + behaviour is set by various ioctls on /dev/rtc. If you enable the + "extended RTC operation" below it will also provide an emulation + for RTC_UIE which is required by some programs and may improve + precision in some cases. + + This driver is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module is called genrtc.o. If you want to compile it as a module, + say M here and read . To load the + module automatically add 'alias char-major-10-135 genrtc' to your + /etc/modules.conf + +config GEN_RTC_X + bool "Extended RTC operation" + depends on GEN_RTC + help + Provides an emulation for RTC_UIE which is required by some programs + and may improve precision of the generic RTC support in some cases. config UNIX98_PTYS bool "Unix98 PTY support" diff --git a/arch/m68k/atari/stram.c b/arch/m68k/atari/stram.c index cc1586d8784..0e73a273850 100644 --- a/arch/m68k/atari/stram.c +++ b/arch/m68k/atari/stram.c @@ -540,7 +540,6 @@ static int __init swap_init(void *start_mem, void *swap_data) p->flags = SWP_USED; p->swap_file = &fake_dentry; p->swap_vfsmnt = &fake_vfsmnt; - p->swap_device = 0; p->swap_map = swap_data; p->cluster_nr = 0; p->next = -1; @@ -549,8 +548,7 @@ static int __init swap_init(void *start_mem, void *swap_data) /* call stram_open() directly, avoids at least the overhead in * constructing a dummy file structure... */ - p->swap_device = MKDEV( STRAM_MAJOR, STRAM_MINOR ); - swap_inode.i_rdev = p->swap_device; + swap_inode.i_rdev = MKDEV( STRAM_MAJOR, STRAM_MINOR ); stram_open( &swap_inode, MAGIC_FILE_P ); p->max = SWAP_NR(swap_end); diff --git a/arch/m68k/kernel/m68k_defs.c b/arch/m68k/kernel/m68k_defs.c index 4dd235d15b2..78d01dc971c 100644 --- a/arch/m68k/kernel/m68k_defs.c +++ b/arch/m68k/kernel/m68k_defs.c @@ -14,7 +14,7 @@ #include #include #include -#include