diff options
Diffstat (limited to 'arch')
484 files changed, 11869 insertions, 10873 deletions
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index c5739d6309df..083c5df42d35 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig @@ -596,6 +596,8 @@ source "fs/Kconfig.binfmt" endmenu +source "net/Kconfig" + source "drivers/Kconfig" source "fs/Kconfig" diff --git a/arch/alpha/kernel/irq_alpha.c b/arch/alpha/kernel/irq_alpha.c index e6ded33c6e22..9d34ce26e5ef 100644 --- a/arch/alpha/kernel/irq_alpha.c +++ b/arch/alpha/kernel/irq_alpha.c @@ -55,6 +55,8 @@ do_entInt(unsigned long type, unsigned long vector, #ifdef CONFIG_SMP { long cpu; + + local_irq_disable(); smp_percpu_timer_interrupt(regs); cpu = smp_processor_id(); if (cpu != boot_cpuid) { diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c index fd7bd17cc960..6f509a644bdd 100644 --- a/arch/alpha/kernel/traps.c +++ b/arch/alpha/kernel/traps.c @@ -240,7 +240,7 @@ do_entIF(unsigned long type, struct pt_regs *regs) siginfo_t info; int signo, code; - if (regs->ps == 0) { + if ((regs->ps & ~IPL_MAX) == 0) { if (type == 1) { const unsigned int *data = (const unsigned int *) regs->pc; diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c8d94dcd8ef7..7bc4a583f4e1 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -223,7 +223,9 @@ source "arch/arm/mach-pxa/Kconfig" source "arch/arm/mach-sa1100/Kconfig" -source "arch/arm/mach-omap/Kconfig" +source "arch/arm/plat-omap/Kconfig" + +source "arch/arm/mach-omap1/Kconfig" source "arch/arm/mach-s3c2410/Kconfig" @@ -361,6 +363,11 @@ config NO_IDLE_HZ Alternatively, if you want dynamic tick automatically enabled during boot, pass "dyntick=enable" via the kernel command string. + Please note that dynamic tick may affect the accuracy of + timekeeping on some platforms depending on the implementation. + Currently at least OMAP platform is known to have accurate + timekeeping with dynamic tick. + config ARCH_DISCONTIGMEM_ENABLE bool default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM) @@ -509,7 +516,7 @@ config XIP_PHYS_ADDR endmenu -if (ARCH_SA1100 || ARCH_INTEGRATOR) +if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP1) menu "CPU Frequency scaling" @@ -693,6 +700,8 @@ config APM endmenu +source "net/Kconfig" + menu "Device Drivers" source "drivers/base/Kconfig" @@ -725,7 +734,7 @@ source "drivers/ieee1394/Kconfig" source "drivers/message/i2o/Kconfig" -source "net/Kconfig" +source "drivers/net/Kconfig" source "drivers/isdn/Kconfig" @@ -737,6 +746,8 @@ source "drivers/char/Kconfig" source "drivers/i2c/Kconfig" +source "drivers/hwmon/Kconfig" + #source "drivers/l3/Kconfig" source "drivers/misc/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 8330495e2448..67f1453ade05 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -56,7 +56,7 @@ tune-$(CONFIG_CPU_XSCALE) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) tune-$(CONFIG_CPU_V6) :=-mtune=strongarm # Need -Uarm for gcc < 3.x -CFLAGS_ABI :=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) +CFLAGS_ABI :=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) $(call cc-option,-mno-thumb-interwork,) CFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm AFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) -msoft-float @@ -91,7 +91,8 @@ textaddr-$(CONFIG_ARCH_FORTUNET) := 0xc0008000 machine-$(CONFIG_ARCH_IOP3XX) := iop3xx machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx machine-$(CONFIG_ARCH_IXP2000) := ixp2000 - machine-$(CONFIG_ARCH_OMAP) := omap + machine-$(CONFIG_ARCH_OMAP1) := omap1 + incdir-$(CONFIG_ARCH_OMAP) := omap machine-$(CONFIG_ARCH_S3C2410) := s3c2410 machine-$(CONFIG_ARCH_LH7A40X) := lh7a40x machine-$(CONFIG_ARCH_VERSATILE) := versatile @@ -142,6 +143,9 @@ core-$(CONFIG_FPE_NWFPE) += arch/arm/nwfpe/ core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ) core-$(CONFIG_VFP) += arch/arm/vfp/ +# If we have a common platform directory, then include it in the build. +core-$(CONFIG_ARCH_OMAP) += arch/arm/plat-omap/ + drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/ drivers-$(CONFIG_ARCH_CLPS7500) += drivers/acorn/char/ drivers-$(CONFIG_ARCH_L7200) += drivers/acorn/char/ diff --git a/arch/arm/boot/compressed/head-shark.S b/arch/arm/boot/compressed/head-shark.S index 848f60e5429b..089c560e07f1 100644 --- a/arch/arm/boot/compressed/head-shark.S +++ b/arch/arm/boot/compressed/head-shark.S @@ -63,8 +63,8 @@ __beginning: mov r4, r0 @ save the entry to the firmware mov pc, r2 -__copy_target: .long 0x08508000 -__copy_end: .long 0x08608000 +__copy_target: .long 0x08507FFC +__copy_end: .long 0x08607FFC .word _start .word __bss_start @@ -73,9 +73,10 @@ __copy_end: .long 0x08608000 __temp_stack: .space 128 __mmu_off: - adr r0, __ofw_data + adr r0, __ofw_data @ read the 1. entry of the memory map ldr r0, [r0, #4] orr r0, r0, #0x00600000 + sub r0, r0, #4 ldr r1, __copy_end ldr r3, __copy_target @@ -89,20 +90,43 @@ __mmu_off: * from 0x08500000 to 0x08508000 if we have only 8MB */ +/* As we get more 2.6-kernels it gets more and more + * uncomfortable to be bound to kernel images of 1MB only. + * So we add a loop here, to be able to copy some more. + * Alexander Schulz 2005-07-17 + */ + + mov r4, #3 @ How many megabytes to copy + + +__MoveCode: sub r4, r4, #1 __Copy: ldr r2, [r0], #-4 str r2, [r1], #-4 teq r1, r3 bne __Copy + + /* The firmware maps us in blocks of 1 MB, the next block is + _below_ the last one. So our decrementing source pointer + ist right here, but the destination pointer must be increased + by 2 MB */ + add r1, r1, #0x00200000 + add r3, r3, #0x00100000 + + teq r4, #0 + bne __MoveCode + + /* and jump to it */ - adr r2, __go_on - adr r0, __ofw_data + adr r2, __go_on @ where we want to jump + adr r0, __ofw_data @ read the 1. entry of the memory map ldr r0, [r0, #4] - sub r2, r2, r0 - sub r2, r2, #0x00500000 - ldr r0, __copy_target + sub r2, r2, r0 @ we are mapped add 0e50 now, sub that (-0e00) + sub r2, r2, #0x00500000 @ -0050 + ldr r0, __copy_target @ and add 0850 8000 instead + add r0, r0, #4 add r2, r2, r0 - mov pc, r2 + mov pc, r2 @ and jump there __go_on: adr sp, __temp_stack diff --git a/arch/arm/configs/bast_defconfig b/arch/arm/configs/bast_defconfig index 2d985e9611cd..35e3a99bcbb6 100644 --- a/arch/arm/configs/bast_defconfig +++ b/arch/arm/configs/bast_defconfig @@ -561,7 +561,6 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_SERIAL_S3C2410=y CONFIG_SERIAL_S3C2410_CONSOLE=y -CONFIG_SERIAL_BAST_SIO=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y diff --git a/arch/arm/configs/enp2611_defconfig b/arch/arm/configs/enp2611_defconfig index b8c51ee7f1bb..f67ca01b4982 100644 --- a/arch/arm/configs/enp2611_defconfig +++ b/arch/arm/configs/enp2611_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-git6 -# Sat Jun 25 00:57:29 2005 +# Linux kernel version: 2.6.13-rc2 +# Thu Jul 7 16:41:21 2005 # CONFIG_ARM=y CONFIG_MMU=y @@ -137,6 +137,7 @@ CONFIG_PCI_NAMES=y # # CONFIG_SMP is not set # CONFIG_PREEMPT is not set +# CONFIG_NO_IDLE_HZ is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y @@ -345,10 +346,9 @@ CONFIG_PACKET_MMAP=y CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y -CONFIG_IP_FIB_HASH=y -# CONFIG_IP_FIB_TRIE is not set # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y @@ -363,17 +363,8 @@ CONFIG_SYN_COOKIES=y # CONFIG_INET_TUNNEL is not set # CONFIG_IP_TCPDIAG is not set # CONFIG_IP_TCPDIAG_IPV6 is not set - -# -# TCP congestion control -# +# CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_BIC=y -CONFIG_TCP_CONG_WESTWOOD=m -CONFIG_TCP_CONG_HTCP=m -# CONFIG_TCP_CONG_HSTCP is not set -# CONFIG_TCP_CONG_HYBLA is not set -# CONFIG_TCP_CONG_VEGAS is not set -# CONFIG_TCP_CONG_SCALABLE is not set # CONFIG_IPV6 is not set # CONFIG_NETFILTER is not set @@ -931,4 +922,3 @@ CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y -# CONFIG_TEXTSEARCH is not set diff --git a/arch/arm/configs/ixdp2400_defconfig b/arch/arm/configs/ixdp2400_defconfig index 3cfbe2ec29ca..5c6c928215d0 100644 --- a/arch/arm/configs/ixdp2400_defconfig +++ b/arch/arm/configs/ixdp2400_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-git6 -# Sat Jun 25 00:58:38 2005 +# Linux kernel version: 2.6.13-rc2 +# Thu Jul 7 16:49:01 2005 # CONFIG_ARM=y CONFIG_MMU=y @@ -138,6 +138,7 @@ CONFIG_PCI_NAMES=y # # CONFIG_SMP is not set # CONFIG_PREEMPT is not set +# CONFIG_NO_IDLE_HZ is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y @@ -346,10 +347,9 @@ CONFIG_PACKET_MMAP=y CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y -CONFIG_IP_FIB_HASH=y -# CONFIG_IP_FIB_TRIE is not set # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y @@ -364,17 +364,8 @@ CONFIG_SYN_COOKIES=y # CONFIG_INET_TUNNEL is not set # CONFIG_IP_TCPDIAG is not set # CONFIG_IP_TCPDIAG_IPV6 is not set - -# -# TCP congestion control -# +# CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_BIC=y -CONFIG_TCP_CONG_WESTWOOD=m -CONFIG_TCP_CONG_HTCP=m -# CONFIG_TCP_CONG_HSTCP is not set -# CONFIG_TCP_CONG_HYBLA is not set -# CONFIG_TCP_CONG_VEGAS is not set -# CONFIG_TCP_CONG_SCALABLE is not set # CONFIG_IPV6 is not set # CONFIG_NETFILTER is not set @@ -932,4 +923,3 @@ CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y -# CONFIG_TEXTSEARCH is not set diff --git a/arch/arm/configs/ixdp2401_defconfig b/arch/arm/configs/ixdp2401_defconfig index 5c87e8e6969b..6dc40f6be0ef 100644 --- a/arch/arm/configs/ixdp2401_defconfig +++ b/arch/arm/configs/ixdp2401_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-git6 -# Sat Jun 25 00:59:35 2005 +# Linux kernel version: 2.6.13-rc2 +# Thu Jul 7 16:49:08 2005 # CONFIG_ARM=y CONFIG_MMU=y @@ -138,6 +138,7 @@ CONFIG_PCI_NAMES=y # # CONFIG_SMP is not set # CONFIG_PREEMPT is not set +# CONFIG_NO_IDLE_HZ is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y @@ -346,10 +347,9 @@ CONFIG_PACKET_MMAP=y CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y -CONFIG_IP_FIB_HASH=y -# CONFIG_IP_FIB_TRIE is not set # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y @@ -364,17 +364,8 @@ CONFIG_SYN_COOKIES=y # CONFIG_INET_TUNNEL is not set CONFIG_IP_TCPDIAG=y # CONFIG_IP_TCPDIAG_IPV6 is not set - -# -# TCP congestion control -# +# CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_BIC=y -CONFIG_TCP_CONG_WESTWOOD=m -CONFIG_TCP_CONG_HTCP=m -# CONFIG_TCP_CONG_HSTCP is not set -# CONFIG_TCP_CONG_HYBLA is not set -# CONFIG_TCP_CONG_VEGAS is not set -# CONFIG_TCP_CONG_SCALABLE is not set # CONFIG_IPV6 is not set # CONFIG_NETFILTER is not set @@ -933,4 +924,3 @@ CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y -# CONFIG_TEXTSEARCH is not set diff --git a/arch/arm/configs/ixdp2800_defconfig b/arch/arm/configs/ixdp2800_defconfig index 3cb561a551cb..d2bb0b7153fe 100644 --- a/arch/arm/configs/ixdp2800_defconfig +++ b/arch/arm/configs/ixdp2800_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-git6 -# Sat Jun 25 01:00:27 2005 +# Linux kernel version: 2.6.13-rc2 +# Thu Jul 7 16:49:20 2005 # CONFIG_ARM=y CONFIG_MMU=y @@ -138,6 +138,7 @@ CONFIG_PCI_NAMES=y # # CONFIG_SMP is not set # CONFIG_PREEMPT is not set +# CONFIG_NO_IDLE_HZ is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y @@ -346,10 +347,9 @@ CONFIG_PACKET_MMAP=y CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y -CONFIG_IP_FIB_HASH=y -# CONFIG_IP_FIB_TRIE is not set # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y @@ -364,17 +364,8 @@ CONFIG_SYN_COOKIES=y # CONFIG_INET_TUNNEL is not set # CONFIG_IP_TCPDIAG is not set # CONFIG_IP_TCPDIAG_IPV6 is not set - -# -# TCP congestion control -# +# CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_BIC=y -CONFIG_TCP_CONG_WESTWOOD=m -CONFIG_TCP_CONG_HTCP=m -# CONFIG_TCP_CONG_HSTCP is not set -# CONFIG_TCP_CONG_HYBLA is not set -# CONFIG_TCP_CONG_VEGAS is not set -# CONFIG_TCP_CONG_SCALABLE is not set # CONFIG_IPV6 is not set # CONFIG_NETFILTER is not set @@ -932,4 +923,3 @@ CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y -# CONFIG_TEXTSEARCH is not set diff --git a/arch/arm/configs/ixdp2801_defconfig b/arch/arm/configs/ixdp2801_defconfig index b1e162f29cb9..2d6f960e3395 100644 --- a/arch/arm/configs/ixdp2801_defconfig +++ b/arch/arm/configs/ixdp2801_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-git6 -# Sat Jun 25 01:01:18 2005 +# Linux kernel version: 2.6.13-rc2 +# Thu Jul 7 16:49:13 2005 # CONFIG_ARM=y CONFIG_MMU=y @@ -138,6 +138,7 @@ CONFIG_PCI_NAMES=y # # CONFIG_SMP is not set # CONFIG_PREEMPT is not set +# CONFIG_NO_IDLE_HZ is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y @@ -346,10 +347,9 @@ CONFIG_PACKET_MMAP=y CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y -CONFIG_IP_FIB_HASH=y -# CONFIG_IP_FIB_TRIE is not set # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y @@ -364,17 +364,8 @@ CONFIG_SYN_COOKIES=y # CONFIG_INET_TUNNEL is not set # CONFIG_IP_TCPDIAG is not set # CONFIG_IP_TCPDIAG_IPV6 is not set - -# -# TCP congestion control -# +# CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_BIC=y -CONFIG_TCP_CONG_WESTWOOD=m -CONFIG_TCP_CONG_HTCP=m -# CONFIG_TCP_CONG_HSTCP is not set -# CONFIG_TCP_CONG_HYBLA is not set -# CONFIG_TCP_CONG_VEGAS is not set -# CONFIG_TCP_CONG_SCALABLE is not set # CONFIG_IPV6 is not set # CONFIG_NETFILTER is not set @@ -933,4 +924,3 @@ CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y -# CONFIG_TEXTSEARCH is not set diff --git a/arch/arm/configs/omap_h2_1610_defconfig b/arch/arm/configs/omap_h2_1610_defconfig index 4e58d9341bce..24955263b096 100644 --- a/arch/arm/configs/omap_h2_1610_defconfig +++ b/arch/arm/configs/omap_h2_1610_defconfig @@ -1,14 +1,13 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc1-bk2 -# Sun Mar 27 17:52:41 2005 +# Linux kernel version: 2.6.13-rc2 +# Fri Jul 8 04:49:34 2005 # CONFIG_ARM=y CONFIG_MMU=y CONFIG_UID16=y CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_IOMAP=y # # Code maturity level options @@ -17,6 +16,7 @@ CONFIG_EXPERIMENTAL=y CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup @@ -33,8 +33,9 @@ CONFIG_KOBJECT_UEVENT=y # CONFIG_IKCONFIG is not set # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -82,10 +83,28 @@ CONFIG_ARCH_OMAP=y # CONFIG_ARCH_VERSATILE is not set # CONFIG_ARCH_IMX is not set # CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_AAEC2000 is not set # # TI OMAP Implementations # +CONFIG_ARCH_OMAP_OTG=y +CONFIG_ARCH_OMAP1=y +# CONFIG_ARCH_OMAP2 is not set + +# +# OMAP Feature Selections +# +# CONFIG_OMAP_RESET_CLOCKS is not set +CONFIG_OMAP_MUX=y +# CONFIG_OMAP_MUX_DEBUG is not set +CONFIG_OMAP_MUX_WARNINGS=y +# CONFIG_OMAP_MPU_TIMER is not set +CONFIG_OMAP_32K_TIMER=y +CONFIG_OMAP_32K_TIMER_HZ=128 +CONFIG_OMAP_LL_DEBUG_UART1=y +# CONFIG_OMAP_LL_DEBUG_UART2 is not set +# CONFIG_OMAP_LL_DEBUG_UART3 is not set # # OMAP Core Type @@ -93,7 +112,6 @@ CONFIG_ARCH_OMAP=y # CONFIG_ARCH_OMAP730 is not set # CONFIG_ARCH_OMAP1510 is not set CONFIG_ARCH_OMAP16XX=y -CONFIG_ARCH_OMAP_OTG=y # # OMAP Board Type @@ -101,21 +119,14 @@ CONFIG_ARCH_OMAP_OTG=y # CONFIG_MACH_OMAP_INNOVATOR is not set CONFIG_MACH_OMAP_H2=y # CONFIG_MACH_OMAP_H3 is not set -# CONFIG_MACH_OMAP_H4 is not set # CONFIG_MACH_OMAP_OSK is not set # CONFIG_MACH_OMAP_GENERIC is not set # -# OMAP Feature Selections +# OMAP CPU Speed # -CONFIG_OMAP_MUX=y -# CONFIG_OMAP_MUX_DEBUG is not set -CONFIG_OMAP_MUX_WARNINGS=y -CONFIG_OMAP_MPU_TIMER=y -# CONFIG_OMAP_32K_TIMER is not set -CONFIG_OMAP_LL_DEBUG_UART1=y -# CONFIG_OMAP_LL_DEBUG_UART2 is not set -# CONFIG_OMAP_LL_DEBUG_UART3 is not set +# CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER is not set +# CONFIG_OMAP_ARM_216MHZ is not set CONFIG_OMAP_ARM_192MHZ=y # CONFIG_OMAP_ARM_168MHZ is not set # CONFIG_OMAP_ARM_120MHZ is not set @@ -145,6 +156,7 @@ CONFIG_ARM_THUMB=y # # Bus support # +CONFIG_ISA_DMA_API=y # # PCCARD (PCMCIA/CardBus) support @@ -154,7 +166,16 @@ CONFIG_ARM_THUMB=y # # Kernel Features # +# CONFIG_SMP is not set CONFIG_PREEMPT=y +CONFIG_NO_IDLE_HZ=y +# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_LEDS is not set CONFIG_ALIGNMENT_TRAP=y @@ -167,6 +188,22 @@ CONFIG_CMDLINE="mem=32M console=ttyS0,115200n8 root=0801 ro init=/bin/sh" # CONFIG_XIP_KERNEL is not set # +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +CONFIG_CPU_FREQ_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set + +# # Floating point emulation # @@ -202,7 +239,6 @@ CONFIG_PM=y CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set -CONFIG_DEBUG_DRIVER=y # # Memory Technology Devices (MTD) @@ -292,7 +328,6 @@ CONFIG_MTD_CFI_UTIL=y # # Block devices # -# CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set @@ -327,6 +362,7 @@ CONFIG_SCSI_PROC_FS=y # CONFIG_CHR_DEV_OSST is not set # CONFIG_BLK_DEV_SR is not set # CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs @@ -356,6 +392,7 @@ CONFIG_SCSI_PROC_FS=y # # Fusion MPT device support # +# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -375,12 +412,12 @@ CONFIG_NET=y # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK_DEV is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y @@ -395,6 +432,8 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_TUNNEL is not set CONFIG_IP_TCPDIAG=y # CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y # CONFIG_IPV6 is not set # CONFIG_NETFILTER is not set @@ -442,6 +481,7 @@ CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_MII=y CONFIG_SMC91X=y +# CONFIG_DM9000 is not set # # Ethernet (1000 Mbit) @@ -518,7 +558,6 @@ CONFIG_SERIO=y CONFIG_SERIO_SERPORT=y # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # # Character devices @@ -567,13 +606,11 @@ CONFIG_WATCHDOG_NOWAYOUT=y # # Ftape, the floppy tape device driver # -# CONFIG_DRM is not set # CONFIG_RAW_DRIVER is not set # # TPM devices # -# CONFIG_TCG_TPM is not set # # I2C support @@ -604,7 +641,9 @@ CONFIG_I2C_CHARDEV=y # CONFIG_SENSORS_ADM1025 is not set # CONFIG_SENSORS_ADM1026 is not set # CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set # CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_FSCHER is not set # CONFIG_SENSORS_FSCPOS is not set @@ -620,6 +659,7 @@ CONFIG_I2C_CHARDEV=y # CONFIG_SENSORS_LM85 is not set # CONFIG_SENSORS_LM87 is not set # CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_SMSC47B397 is not set @@ -627,15 +667,21 @@ CONFIG_I2C_CHARDEV=y # CONFIG_SENSORS_W83781D is not set # CONFIG_SENSORS_W83L785TS is not set # CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set # # Other I2C Chip support # +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set # CONFIG_SENSORS_EEPROM is not set # CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set # CONFIG_SENSORS_PCF8591 is not set # CONFIG_SENSORS_RTC8564 is not set CONFIG_ISP1301_OMAP=y +CONFIG_TPS65010=y +# CONFIG_SENSORS_MAX6875 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set @@ -663,8 +709,10 @@ CONFIG_FB=y # CONFIG_FB_CFB_COPYAREA is not set # CONFIG_FB_CFB_IMAGEBLIT is not set # CONFIG_FB_SOFT_CURSOR is not set +# CONFIG_FB_MACMODES is not set CONFIG_FB_MODE_HELPERS=y # CONFIG_FB_TILEBLITTING is not set +# CONFIG_FB_S1D13XXX is not set # CONFIG_FB_VIRTUAL is not set # @@ -677,11 +725,13 @@ CONFIG_FONTS=y CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y # CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set # CONFIG_FONT_PEARL_8x8 is not set # CONFIG_FONT_ACORN_8x8 is not set # CONFIG_FONT_MINI_4x6 is not set # CONFIG_FONT_SUN8x16 is not set # CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set # # Logo configuration @@ -729,14 +779,14 @@ CONFIG_USB_ARCH_HAS_OHCI=y # CONFIG_USB_GADGET=y # CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_SELECTED=y # CONFIG_USB_GADGET_NET2280 is not set # CONFIG_USB_GADGET_PXA2XX is not set # CONFIG_USB_GADGET_GOKU is not set -# CONFIG_USB_GADGET_SA1100 is not set # CONFIG_USB_GADGET_LH7A40X is not set -# CONFIG_USB_GADGET_DUMMY_HCD is not set CONFIG_USB_GADGET_OMAP=y CONFIG_USB_OMAP=y +# CONFIG_USB_GADGET_DUMMY_HCD is not set # CONFIG_USB_GADGET_DUALSPEED is not set # CONFIG_USB_ZERO is not set CONFIG_USB_ETH=y @@ -755,6 +805,7 @@ CONFIG_USB_ETH_RNDIS=y # CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set # CONFIG_JBD is not set # CONFIG_REISERFS_FS is not set @@ -791,7 +842,6 @@ CONFIG_FAT_DEFAULT_CODEPAGE=437 # CONFIG_PROC_FS=y CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set # CONFIG_DEVPTS_FS_XATTR is not set # CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set @@ -828,12 +878,14 @@ CONFIG_CRAMFS=y # CONFIG_NFS_FS=y CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set CONFIG_NFS_V4=y # CONFIG_NFS_DIRECTIO is not set # CONFIG_NFSD is not set CONFIG_ROOT_NFS=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y CONFIG_SUNRPC_GSS=y CONFIG_RPCSEC_GSS_KRB5=y @@ -903,24 +955,11 @@ CONFIG_NLS_DEFAULT="iso8859-1" # Kernel hacking # # CONFIG_PRINTK_TIME is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_DEBUG_KERNEL is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_SCHEDSTATS is not set -# CONFIG_DEBUG_SLAB is not set -CONFIG_DEBUG_PREEMPT=y -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_INFO=y -# CONFIG_DEBUG_FS is not set CONFIG_FRAME_POINTER=y -CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set -CONFIG_DEBUG_ERRORS=y -CONFIG_DEBUG_LL=y -# CONFIG_DEBUG_ICEDCC is not set +# CONFIG_DEBUG_USER is not set # # Security options diff --git a/arch/arm/configs/omnimeter_defconfig b/arch/arm/configs/omnimeter_defconfig deleted file mode 100644 index 78fdb4a428b1..000000000000 --- a/arch/arm/configs/omnimeter_defconfig +++ /dev/null @@ -1,803 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc1-bk2 -# Sun Mar 27 21:31:45 2005 -# -CONFIG_ARM=y -CONFIG_MMU=y -CONFIG_UID16=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_IOMAP=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y -CONFIG_BROKEN_ON_SMP=y - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set -CONFIG_HOTPLUG=y -CONFIG_KOBJECT_UEVENT=y -# CONFIG_IKCONFIG is not set -# CONFIG_EMBEDDED is not set -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 - -# -# Loadable module support -# -CONFIG_MODULES=y -# CONFIG_MODULE_UNLOAD is not set -CONFIG_OBSOLETE_MODPARM=y -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y - -# -# System Type -# -# CONFIG_ARCH_CLPS7500 is not set -# CONFIG_ARCH_CLPS711X is not set -# CONFIG_ARCH_CO285 is not set -# CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_CAMELOT is not set -# CONFIG_ARCH_FOOTBRIDGE is not set -# CONFIG_ARCH_INTEGRATOR is not set -# CONFIG_ARCH_IOP3XX is not set -# CONFIG_ARCH_IXP4XX is not set -# CONFIG_ARCH_IXP2000 is not set -# CONFIG_ARCH_L7200 is not set -# CONFIG_ARCH_PXA is not set -# CONFIG_ARCH_RPC is not set -CONFIG_ARCH_SA1100=y -# CONFIG_ARCH_S3C2410 is not set -# CONFIG_ARCH_SHARK is not set -# CONFIG_ARCH_LH7A40X is not set -# CONFIG_ARCH_OMAP is not set -# CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_IMX is not set -# CONFIG_ARCH_H720X is not set - -# -# SA11x0 Implementations -# -# CONFIG_SA1100_ASSABET is not set -# CONFIG_SA1100_CERF is not set -# CONFIG_SA1100_COLLIE is not set -# CONFIG_SA1100_H3100 is not set -# CONFIG_SA1100_H3600 is not set -# CONFIG_SA1100_H3800 is not set -# CONFIG_SA1100_BADGE4 is not set -# CONFIG_SA1100_JORNADA720 is not set -# CONFIG_SA1100_HACKKIT is not set -# CONFIG_SA1100_LART is not set -# CONFIG_SA1100_PLEB is not set -# CONFIG_SA1100_SHANNON is not set -# CONFIG_SA1100_SIMPAD is not set -# CONFIG_SA1100_SSP is not set - -# -# Processor Type -# -CONFIG_CPU_32=y -CONFIG_CPU_SA1100=y -CONFIG_CPU_32v4=y -CONFIG_CPU_ABRT_EV4=y -CONFIG_CPU_CACHE_V4WB=y -CONFIG_CPU_CACHE_VIVT=y -CONFIG_CPU_TLB_V4WB=y -CONFIG_CPU_MINICACHE=y - -# -# Processor Features -# - -# -# Bus support -# -CONFIG_ISA=y - -# -# PCCARD (PCMCIA/CardBus) support -# -CONFIG_PCCARD=y -# CONFIG_PCMCIA_DEBUG is not set -CONFIG_PCMCIA=y - -# -# PC-card bridges -# -CONFIG_I82365=y -# CONFIG_TCIC is not set -CONFIG_PCMCIA_SA1100=y -CONFIG_PCCARD_NONSTATIC=y - -# -# Kernel Features -# -# CONFIG_PREEMPT is not set -CONFIG_DISCONTIGMEM=y -# CONFIG_LEDS is not set -CONFIG_ALIGNMENT_TRAP=y - -# -# Boot options -# -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="keepinitrd mem=16M root=/dev/ram ramdisk=8192 initrd=0xd0000000,4M" -# CONFIG_XIP_KERNEL is not set - -# -# CPU Frequency scaling -# -# CONFIG_CPU_FREQ is not set - -# -# Floating point emulation -# - -# -# At least one emulation must be selected -# -# CONFIG_FPE_NWFPE is not set -# CONFIG_FPE_FASTFPE is not set - -# -# Userspace binary formats -# -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_AOUT=y -# CONFIG_BINFMT_MISC is not set -# CONFIG_ARTHUR is not set - -# -# Power management options -# -# CONFIG_PM is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# -# CONFIG_PNP is not set - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_XD is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=m -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -CONFIG_BLK_DEV_NBD=m -# CONFIG_BLK_DEV_RAM is not set -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CDROM_PKTCDVD is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -# CONFIG_ATA_OVER_ETH is not set - -# -# ATA/ATAPI/MFM/RLL support -# -CONFIG_IDE=y -CONFIG_BLK_DEV_IDE=y - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_IDE_SATA is not set -CONFIG_BLK_DEV_IDEDISK=y -# CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_BLK_DEV_IDECS is not set -# CONFIG_BLK_DEV_IDECD is not set -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set -# CONFIG_IDE_TASK_IOCTL is not set - -# -# IDE chipset support/bugfixes -# -CONFIG_IDE_GENERIC=y -# CONFIG_IDE_ARM is not set -# CONFIG_IDE_CHIPSETS is not set -# CONFIG_BLK_DEV_IDEDMA is not set -# CONFIG_IDEDMA_AUTO is not set -# CONFIG_BLK_DEV_HD is not set - -# -# SCSI device support -# -# CONFIG_SCSI is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# - -# -# IEEE 1394 (FireWire) support -# - -# -# I2O device support -# - -# -# Networking support -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -# CONFIG_NETLINK_DEV is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_IP_TCPDIAG=y -# CONFIG_IP_TCPDIAG_IPV6 is not set - -# -# IP: Virtual Server Configuration -# -# CONFIG_IP_VS is not set -# CONFIG_IPV6 is not set -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set - -# -# IP: Netfilter Configuration -# -# CONFIG_IP_NF_CONNTRACK is not set -# CONFIG_IP_NF_CONNTRACK_MARK is not set -# CONFIG_IP_NF_QUEUE is not set -# CONFIG_IP_NF_IPTABLES is not set -# CONFIG_IP_NF_ARPTABLES is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set -# CONFIG_NET_CLS_ROUTE is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -# CONFIG_MII is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_SMC91X is not set -# CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_AT1700 is not set -# CONFIG_DEPCA is not set -# CONFIG_HP100 is not set -# CONFIG_NET_ISA is not set -# CONFIG_NET_PCI is not set -# CONFIG_NET_POCKET is not set - -# -# Ethernet (1000 Mbit) -# - -# -# Ethernet (10000 Mbit) -# - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN (non-hamradio) -# -CONFIG_NET_RADIO=y - -# -# Obsolete Wireless cards support (pre-802.11) -# -# CONFIG_STRIP is not set -# CONFIG_ARLAN is not set -# CONFIG_WAVELAN is not set -CONFIG_PCMCIA_WAVELAN=y -# CONFIG_PCMCIA_NETWAVE is not set - -# -# Wireless 802.11 Frequency Hopping cards support -# -# CONFIG_PCMCIA_RAYCS is not set - -# -# Wireless 802.11b ISA/PCI cards support -# -# CONFIG_HERMES is not set -# CONFIG_ATMEL is not set - -# -# Wireless 802.11b Pcmcia/Cardbus cards support -# -CONFIG_AIRO_CS=y -CONFIG_PCMCIA_WL3501=y -CONFIG_NET_WIRELESS=y - -# -# PCMCIA network device support -# -CONFIG_NET_PCMCIA=y -CONFIG_PCMCIA_3C589=y -# CONFIG_PCMCIA_3C574 is not set -# CONFIG_PCMCIA_FMVJ18X is not set -CONFIG_PCMCIA_PCNET=y -# CONFIG_PCMCIA_NMCLAN is not set -# CONFIG_PCMCIA_SMC91C92 is not set -# CONFIG_PCMCIA_XIRC2PS is not set -# CONFIG_PCMCIA_AXNET is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Input device support -# -CONFIG_INPUT=y - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -CONFIG_INPUT_KEYBOARD=y -CONFIG_KEYBOARD_ATKBD=y -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYBOARD_NEWTON is not set -CONFIG_INPUT_MOUSE=y -CONFIG_MOUSE_PS2=y -# CONFIG_MOUSE_SERIAL is not set -# CONFIG_MOUSE_INPORT is not set -# CONFIG_MOUSE_LOGIBM is not set -# CONFIG_MOUSE_PC110PAD is not set -# CONFIG_MOUSE_VSXXXAA is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -CONFIG_SERIO=y -CONFIG_SERIO_SERPORT=y -CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_SA1100=y -CONFIG_SERIAL_SA1100_CONSOLE=y -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_NVRAM is not set -# CONFIG_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_DRM is not set - -# -# PCMCIA character devices -# -# CONFIG_SYNCLINK_CS is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# Misc devices -# - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -CONFIG_FB=y -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_IMAGEBLIT=y -CONFIG_FB_SOFT_CURSOR=y -# CONFIG_FB_MODE_HELPERS is not set -# CONFIG_FB_TILEBLITTING is not set -CONFIG_FB_SA1100=y -# CONFIG_FB_VIRTUAL is not set - -# -# Console display driver support -# -# CONFIG_VGA_CONSOLE is not set -# CONFIG_MDA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_FONTS=y -CONFIG_FONT_8x8=y -# CONFIG_FONT_8x16 is not set -# CONFIG_FONT_6x11 is not set -# CONFIG_FONT_PEARL_8x8 is not set -# CONFIG_FONT_ACORN_8x8 is not set -# CONFIG_FONT_MINI_4x6 is not set -# CONFIG_FONT_SUN8x16 is not set -# CONFIG_FONT_SUN12x22 is not set - -# -# Logo configuration -# -# CONFIG_LOGO is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB is not set - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set - -# -# XFS support -# -# CONFIG_XFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -# CONFIG_VFAT_FS is not set -CONFIG_FAT_DEFAULT_CODEPAGE=437 -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVPTS_FS_XATTR is not set -# CONFIG_TMPFS is not set -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -# CONFIG_NFSD is not set -CONFIG_LOCKD=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -# CONFIG_NLS_CODEPAGE_437 is not set -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -# CONFIG_NLS_ISO8859_1 is not set -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set - -# -# Profiling support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -# CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_FRAME_POINTER=y -# CONFIG_DEBUG_USER is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Hardware crypto devices -# - -# -# Library routines -# -# CONFIG_CRC_CCITT is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig index 98b72ff38832..96a794d8de84 100644 --- a/arch/arm/configs/s3c2410_defconfig +++ b/arch/arm/configs/s3c2410_defconfig @@ -570,7 +570,6 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_SERIAL_S3C2410=y CONFIG_SERIAL_S3C2410_CONSOLE=y -CONFIG_SERIAL_BAST_SIO=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y diff --git a/arch/arm/configs/shark_defconfig b/arch/arm/configs/shark_defconfig index 1d9bcbbc8dfc..271823f0d708 100644 --- a/arch/arm/configs/shark_defconfig +++ b/arch/arm/configs/shark_defconfig @@ -1,22 +1,21 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc1-bk2 -# Sun Mar 27 23:59:14 2005 +# Linux kernel version: 2.6.12-git3 +# Sat Jul 16 15:21:47 2005 # CONFIG_ARM=y CONFIG_MMU=y CONFIG_UID16=y CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_IOMAP=y # # Code maturity level options # CONFIG_EXPERIMENTAL=y -# CONFIG_CLEAN_COMPILE is not set -CONFIG_BROKEN=y +CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup @@ -33,7 +32,10 @@ CONFIG_KOBJECT_UEVENT=y # CONFIG_IKCONFIG is not set # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -81,6 +83,7 @@ CONFIG_ARCH_SHARK=y # CONFIG_ARCH_VERSATILE is not set # CONFIG_ARCH_IMX is not set # CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_AAEC2000 is not set # # Processor Type @@ -103,10 +106,12 @@ CONFIG_CPU_TLB_V4WB=y # CONFIG_ISA=y CONFIG_ISA_DMA=y +CONFIG_ISA_DMA_API=y CONFIG_PCI=y CONFIG_PCI_HOST_VIA82C505=y CONFIG_PCI_LEGACY_PROC=y # CONFIG_PCI_NAMES is not set +# CONFIG_PCI_DEBUG is not set # # PCCARD (PCMCIA/CardBus) support @@ -116,7 +121,9 @@ CONFIG_PCI_LEGACY_PROC=y # # Kernel Features # +# CONFIG_SMP is not set # CONFIG_PREEMPT is not set +# CONFIG_DISCONTIGMEM is not set CONFIG_LEDS=y CONFIG_LEDS_TIMER=y # CONFIG_LEDS_CPU is not set @@ -163,6 +170,7 @@ CONFIG_BINFMT_ELF=y # CONFIG_STANDALONE is not set CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set # # Memory Technology Devices (MTD) @@ -172,8 +180,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # # Parallel port support # -CONFIG_PARPORT=y -CONFIG_PARPORT_PC=y +CONFIG_PARPORT=m +CONFIG_PARPORT_PC=m # CONFIG_PARPORT_SERIAL is not set # CONFIG_PARPORT_PC_FIFO is not set # CONFIG_PARPORT_PC_SUPERIO is not set @@ -189,7 +197,6 @@ CONFIG_PARPORT_PC=y # # Block devices # -# CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set @@ -229,7 +236,7 @@ CONFIG_BLK_DEV_IDE=y # CONFIG_BLK_DEV_IDE_SATA is not set CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -CONFIG_BLK_DEV_IDECD=y +CONFIG_BLK_DEV_IDECD=m # CONFIG_BLK_DEV_IDETAPE is not set CONFIG_BLK_DEV_IDEFLOPPY=y # CONFIG_BLK_DEV_IDESCSI is not set @@ -261,6 +268,7 @@ CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=m # CONFIG_BLK_DEV_SR_VENDOR is not set CONFIG_CHR_DEV_SG=m +# CONFIG_CHR_DEV_SCH is not set # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs @@ -290,17 +298,14 @@ CONFIG_CHR_DEV_SG=m # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_IN2000 is not set # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set # CONFIG_SCSI_SATA is not set # CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_DTC3280 is not set # CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_GENERIC_NCR5380 is not set @@ -314,11 +319,8 @@ CONFIG_CHR_DEV_SG=m # CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_IPR is not set # CONFIG_SCSI_PAS16 is not set -# CONFIG_SCSI_PCI2000 is not set -# CONFIG_SCSI_PCI2220I is not set # CONFIG_SCSI_PSI240I is not set # CONFIG_SCSI_QLOGIC_FAS is not set -# CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set CONFIG_SCSI_QLA2XXX=m @@ -327,6 +329,7 @@ CONFIG_SCSI_QLA2XXX=m # CONFIG_SCSI_QLA2300 is not set # CONFIG_SCSI_QLA2322 is not set # CONFIG_SCSI_QLA6312 is not set +# CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set @@ -344,6 +347,8 @@ CONFIG_SCSI_QLA2XXX=m # Fusion MPT device support # # CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set # # IEEE 1394 (FireWire) support @@ -365,7 +370,6 @@ CONFIG_NET=y # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK_DEV is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -380,7 +384,7 @@ CONFIG_INET=y # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set # CONFIG_INET_TUNNEL is not set -# CONFIG_IP_TCPDIAG is not set +CONFIG_IP_TCPDIAG=y # CONFIG_IP_TCPDIAG_IPV6 is not set # CONFIG_IPV6 is not set # CONFIG_NETFILTER is not set @@ -439,6 +443,7 @@ CONFIG_NET_ETHERNET=y # CONFIG_LANCE is not set # CONFIG_NET_VENDOR_SMC is not set # CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set # CONFIG_NET_VENDOR_RACAL is not set # @@ -483,9 +488,11 @@ CONFIG_CS89x0=y # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set # CONFIG_R8169 is not set +# CONFIG_SKGE is not set # CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set # CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set # # Ethernet (10000 Mbit) @@ -569,7 +576,6 @@ CONFIG_SERIO_I8042=y CONFIG_SERIO_LIBPS2=y # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # # Character devices @@ -592,6 +598,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4 # CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -653,6 +660,7 @@ CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y CONFIG_FB_SOFT_CURSOR=y +# CONFIG_FB_MACMODES is not set # CONFIG_FB_MODE_HELPERS is not set # CONFIG_FB_TILEBLITTING is not set # CONFIG_FB_CIRRUS is not set @@ -674,7 +682,7 @@ CONFIG_FB_CYBER2000=y # CONFIG_FB_3DFX is not set # CONFIG_FB_VOODOO1 is not set # CONFIG_FB_TRIDENT is not set -# CONFIG_FB_PM3 is not set +# CONFIG_FB_S1D13XXX is not set # CONFIG_FB_VIRTUAL is not set # @@ -808,7 +816,7 @@ CONFIG_DNOTIFY=y # # CD-ROM/DVD Filesystems # -CONFIG_ISO9660_FS=y +CONFIG_ISO9660_FS=m CONFIG_JOLIET=y # CONFIG_ZISOFS is not set # CONFIG_UDF_FS is not set @@ -816,9 +824,9 @@ CONFIG_JOLIET=y # # DOS/FAT/NT Filesystems # -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m CONFIG_FAT_DEFAULT_CODEPAGE=437 CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # CONFIG_NTFS_FS is not set @@ -833,7 +841,6 @@ CONFIG_DEVFS_MOUNT=y # CONFIG_DEVFS_DEBUG is not set # CONFIG_DEVPTS_FS_XATTR is not set # CONFIG_TMPFS is not set -# CONFIG_HUGETLBFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y @@ -857,13 +864,14 @@ CONFIG_RAMFS=y # # Network File Systems # -CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y # CONFIG_NFS_V4 is not set # CONFIG_NFS_DIRECTIO is not set # CONFIG_NFSD is not set -CONFIG_LOCKD=y -CONFIG_SUNRPC=y +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_SUNRPC=m # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set @@ -895,12 +903,12 @@ CONFIG_MSDOS_PARTITION=y # # Native Language Support # -CONFIG_NLS=y +CONFIG_NLS=m CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_437=m # CONFIG_NLS_CODEPAGE_737 is not set # CONFIG_NLS_CODEPAGE_775 is not set -CONFIG_NLS_CODEPAGE_850=y +CONFIG_NLS_CODEPAGE_850=m # CONFIG_NLS_CODEPAGE_852 is not set # CONFIG_NLS_CODEPAGE_855 is not set # CONFIG_NLS_CODEPAGE_857 is not set @@ -921,7 +929,7 @@ CONFIG_NLS_CODEPAGE_850=y # CONFIG_NLS_CODEPAGE_1250 is not set # CONFIG_NLS_CODEPAGE_1251 is not set # CONFIG_NLS_ASCII is not set -CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_ISO8859_1=m # CONFIG_NLS_ISO8859_2 is not set # CONFIG_NLS_ISO8859_3 is not set # CONFIG_NLS_ISO8859_4 is not set @@ -945,11 +953,22 @@ CONFIG_NLS_ISO8859_1=y # Kernel hacking # # CONFIG_PRINTK_TIME is not set -# CONFIG_DEBUG_KERNEL is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_MAGIC_SYSRQ is not set CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set CONFIG_FRAME_POINTER=y CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +# CONFIG_DEBUG_ERRORS is not set +# CONFIG_DEBUG_LL is not set # # Security options diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index 4c38bd8bc298..835d450797a1 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c @@ -30,9 +30,6 @@ extern void __lshrdi3(void); extern void __modsi3(void); extern void __muldi3(void); extern void __ucmpdi2(void); -extern void __udivdi3(void); -extern void __umoddi3(void); -extern void __udivmoddi4(void); extern void __udivsi3(void); extern void __umodsi3(void); extern void __do_div64(void); @@ -44,7 +41,10 @@ extern void fp_enter(void); * This has a special calling convention; it doesn't * modify any of the usual registers, except for LR. */ +#define EXPORT_CRC_ALIAS(sym) __CRC_SYMBOL(sym, "") + #define EXPORT_SYMBOL_ALIAS(sym,orig) \ + EXPORT_CRC_ALIAS(sym) \ const struct kernel_symbol __ksymtab_##sym \ __attribute__((section("__ksymtab"))) = \ { (unsigned long)&orig, #sym }; @@ -134,9 +134,6 @@ EXPORT_SYMBOL(__lshrdi3); EXPORT_SYMBOL(__modsi3); EXPORT_SYMBOL(__muldi3); EXPORT_SYMBOL(__ucmpdi2); -EXPORT_SYMBOL(__udivdi3); -EXPORT_SYMBOL(__umoddi3); -EXPORT_SYMBOL(__udivmoddi4); EXPORT_SYMBOL(__udivsi3); EXPORT_SYMBOL(__umodsi3); EXPORT_SYMBOL(__do_div64); diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index bd4823c74645..1155cf07c871 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -344,9 +344,9 @@ __create_page_tables: str r6, [r0] #endif +#ifdef CONFIG_DEBUG_LL bic r7, r7, #0x0c @ turn off cacheable @ and bufferable bits -#ifdef CONFIG_DEBUG_LL /* * Map in IO space for serial debugging. * This allows debug messages to be output @@ -372,28 +372,24 @@ __create_page_tables: teq r1, #MACH_TYPE_NETWINDER teqne r1, #MACH_TYPE_CATS bne 1f - add r0, r4, #0x3fc0 @ ff000000 - mov r3, #0x7c000000 - orr r3, r3, r7 - str r3, [r0], #4 - add r3, r3, #1 << 20 - str r3, [r0], #4 + add r0, r4, #0xff000000 >> 18 + orr r3, r7, #0x7c000000 + str r3, [r0] 1: #endif -#endif #ifdef CONFIG_ARCH_RPC /* * Map in screen at 0x02000000 & SCREEN2_BASE * Similar reasons here - for debug. This is * only for Acorn RiscPC architectures. */ - add r0, r4, #0x80 @ 02000000 - mov r3, #0x02000000 - orr r3, r3, r7 + add r0, r4, #0x02000000 >> 18 + orr r3, r7, #0x02000000 str r3, [r0] - add r0, r4, #0x3600 @ d8000000 + add r0, r4, #0xd8000000 >> 18 str r3, [r0] #endif +#endif mov pc, lr .ltorg diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 8f146a4b4752..bbea636ff687 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -32,6 +32,7 @@ #include <asm/leds.h> #include <asm/processor.h> #include <asm/uaccess.h> +#include <asm/mach/time.h> extern const char *processor_modes[]; extern void setup_mm_for_reboot(char mode); @@ -85,8 +86,10 @@ EXPORT_SYMBOL(pm_power_off); void default_idle(void) { local_irq_disable(); - if (!need_resched() && !hlt_counter) + if (!need_resched() && !hlt_counter) { + timer_dyn_reprogram(); arch_idle(); + } local_irq_enable(); } diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 8cf733daa800..c9b69771f92e 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -359,7 +359,8 @@ void cpu_init(void) "I" (offsetof(struct stack, abt[0])), "I" (PSR_F_BIT | PSR_I_BIT | UND_MODE), "I" (offsetof(struct stack, und[0])), - "I" (PSR_F_BIT | PSR_I_BIT | SVC_MODE)); + "I" (PSR_F_BIT | PSR_I_BIT | SVC_MODE) + : "r14"); } static struct machine_desc * __init setup_machine(unsigned int nr) @@ -736,8 +737,8 @@ void __init setup_arch(char **cmdline_p) if (mdesc->soft_reboot) reboot_setup("s"); - if (mdesc->param_offset) - tags = phys_to_virt(mdesc->param_offset); + if (mdesc->boot_params) + tags = phys_to_virt(mdesc->boot_params); /* * If we have the old style parameters, convert them to diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 07ddeed61766..5e435e42dacd 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -697,7 +697,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) if (!user_mode(regs)) return 0; - if (try_to_freeze(0)) + if (try_to_freeze()) goto no_signal; if (current->ptrace & PT_SINGLESTEP) diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 34892758f098..295e0a8379cf 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -36,7 +36,7 @@ * The present bitmask indicates that the CPU is physically present. * The online bitmask indicates that the CPU is up and running. */ -cpumask_t cpu_present_mask; +cpumask_t cpu_possible_map; cpumask_t cpu_online_map; /* @@ -78,7 +78,7 @@ struct smp_call_struct { static struct smp_call_struct * volatile smp_call_function_data; static DEFINE_SPINLOCK(smp_call_function_lock); -int __init __cpu_up(unsigned int cpu) +int __cpuinit __cpu_up(unsigned int cpu) { struct task_struct *idle; pgd_t *pgd; @@ -159,7 +159,7 @@ int __init __cpu_up(unsigned int cpu) * This is the secondary CPU boot entry. We're using this CPUs * idle thread stack, but a set of temporary page tables. */ -asmlinkage void __init secondary_start_kernel(void) +asmlinkage void __cpuinit secondary_start_kernel(void) { struct mm_struct *mm = &init_mm; unsigned int cpu = smp_processor_id(); @@ -209,7 +209,7 @@ asmlinkage void __init secondary_start_kernel(void) * Called by both boot and secondaries to move global data into * per-processor storage. */ -void __init smp_store_cpu_info(unsigned int cpuid) +void __cpuinit smp_store_cpu_info(unsigned int cpuid) { struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid); @@ -235,7 +235,8 @@ void __init smp_prepare_boot_cpu(void) { unsigned int cpu = smp_processor_id(); - cpu_set(cpu, cpu_present_mask); + cpu_set(cpu, cpu_possible_map); + cpu_set(cpu, cpu_present_map); cpu_set(cpu, cpu_online_map); } @@ -355,7 +356,7 @@ void show_ipi_list(struct seq_file *p) seq_puts(p, "IPI:"); - for_each_online_cpu(cpu) + for_each_present_cpu(cpu) seq_printf(p, " %10lu", per_cpu(ipi_data, cpu).ipi_count); seq_putc(p, '\n'); @@ -502,3 +503,126 @@ int __init setup_profiling_timer(unsigned int multiplier) { return -EINVAL; } + +static int +on_each_cpu_mask(void (*func)(void *), void *info, int retry, int wait, + cpumask_t mask) +{ + int ret = 0; + + preempt_disable(); + + ret = smp_call_function_on_cpu(func, info, retry, wait, mask); + if (cpu_isset(smp_processor_id(), mask)) + func(info); + + preempt_enable(); + + return ret; +} + +/**********************************************************************/ + +/* + * TLB operations + */ +struct tlb_args { + struct vm_area_struct *ta_vma; + unsigned long ta_start; + unsigned long ta_end; +}; + +static inline void ipi_flush_tlb_all(void *ignored) +{ + local_flush_tlb_all(); +} + +static inline void ipi_flush_tlb_mm(void *arg) +{ + struct mm_struct *mm = (struct mm_struct *)arg; + + local_flush_tlb_mm(mm); +} + +static inline void ipi_flush_tlb_page(void *arg) +{ + struct tlb_args *ta = (struct tlb_args *)arg; + + local_flush_tlb_page(ta->ta_vma, ta->ta_start); +} + +static inline void ipi_flush_tlb_kernel_page(void *arg) +{ + struct tlb_args *ta = (struct tlb_args *)arg; + + local_flush_tlb_kernel_page(ta->ta_start); +} + +static inline void ipi_flush_tlb_range(void *arg) +{ + struct tlb_args *ta = (struct tlb_args *)arg; + + local_flush_tlb_range(ta->ta_vma, ta->ta_start, ta->ta_end); +} + +static inline void ipi_flush_tlb_kernel_range(void *arg) +{ + struct tlb_args *ta = (struct tlb_args *)arg; + + local_flush_tlb_kernel_range(ta->ta_start, ta->ta_end); +} + +void flush_tlb_all(void) +{ + on_each_cpu(ipi_flush_tlb_all, NULL, 1, 1); +} + +void flush_tlb_mm(struct mm_struct *mm) +{ + cpumask_t mask = mm->cpu_vm_mask; + + on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, 1, mask); +} + +void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) +{ + cpumask_t mask = vma->vm_mm->cpu_vm_mask; + struct tlb_args ta; + + ta.ta_vma = vma; + ta.ta_start = uaddr; + + on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, 1, mask); +} + +void flush_tlb_kernel_page(unsigned long kaddr) +{ + struct tlb_args ta; + + ta.ta_start = kaddr; + + on_each_cpu(ipi_flush_tlb_kernel_page, &ta, 1, 1); +} + +void flush_tlb_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end) +{ + cpumask_t mask = vma->vm_mm->cpu_vm_mask; + struct tlb_args ta; + + ta.ta_vma = vma; + ta.ta_start = start; + ta.ta_end = end; + + on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, 1, mask); +} + +void flush_tlb_kernel_range(unsigned long start, unsigned long end) +{ + struct tlb_args ta; + + ta.ta_start = start; + ta.ta_end = end; + + on_each_cpu(ipi_flush_tlb_kernel_range, &ta, 1, 1); +} diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index 06054c9ba074..1b7fcd50c3e2 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c @@ -424,15 +424,19 @@ static int timer_dyn_tick_disable(void) return ret; } +/* + * Reprogram the system timer for at least the calculated time interval. + * This function should be called from the idle thread with IRQs disabled, + * immediately before sleeping. + */ void timer_dyn_reprogram(void) { struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick; - unsigned long flags; - write_seqlock_irqsave(&xtime_lock, flags); + write_seqlock(&xtime_lock); if (dyn_tick->state & DYN_TICK_ENABLED) dyn_tick->reprogram(next_timer_interrupt() - jiffies); - write_sequnlock_irqrestore(&xtime_lock, flags); + write_sequnlock(&xtime_lock); } static ssize_t timer_show_dyn_tick(struct sys_device *dev, char *buf) diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 2fb0a4cfb37a..d571c37ac30c 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -230,16 +230,8 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err) do_exit(SIGSEGV); } -void die_if_kernel(const char *str, struct pt_regs *regs, int err) -{ - if (user_mode(regs)) - return; - - die(str, regs, err); -} - -static void notify_die(const char *str, struct pt_regs *regs, siginfo_t *info, - unsigned long err, unsigned long trap) +void notify_die(const char *str, struct pt_regs *regs, struct siginfo *info, + unsigned long err, unsigned long trap) { if (user_mode(regs)) { current->thread.error_code = err; @@ -256,16 +248,20 @@ static DEFINE_SPINLOCK(undef_lock); void register_undef_hook(struct undef_hook *hook) { - spin_lock_irq(&undef_lock); + unsigned long flags; + + spin_lock_irqsave(&undef_lock, flags); list_add(&hook->node, &undef_hook); - spin_unlock_irq(&undef_lock); + spin_unlock_irqrestore(&undef_lock, flags); } void unregister_undef_hook(struct undef_hook *hook) { - spin_lock_irq(&undef_lock); + unsigned long flags; + + spin_lock_irqsave(&undef_lock, flags); list_del(&hook->node); - spin_unlock_irq(&undef_lock); + spin_unlock_irqrestore(&undef_lock, flags); } asmlinkage void do_undefinstr(struct pt_regs *regs) diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index c0e65833ffc4..8725d63e4219 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -11,7 +11,7 @@ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \ strnlen_user.o strchr.o strrchr.o testchangebit.o \ testclearbit.o testsetbit.o uaccess.o getuser.o \ putuser.o ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ - ucmpdi2.o udivdi3.o lib1funcs.o div64.o \ + ucmpdi2.o lib1funcs.o div64.o \ io-readsb.o io-writesb.o io-readsl.o io-writesl.o ifeq ($(CONFIG_CPU_32v3),y) diff --git a/arch/arm/lib/bitops.h b/arch/arm/lib/bitops.h index 4a83ab6cd565..6976e60e47cb 100644 --- a/arch/arm/lib/bitops.h +++ b/arch/arm/lib/bitops.h @@ -1,3 +1,33 @@ +#if __LINUX_ARM_ARCH__ >= 6 + .macro bitop, instr + mov r2, #1 + and r3, r0, #7 @ Get bit offset + add r1, r1, r0, lsr #3 @ Get byte offset + mov r3, r2, lsl r3 +1: ldrexb r2, [r1] + \instr r2, r2, r3 + strexb r0, r2, [r1] + cmpne r0, #0 + bne 1b + mov pc, lr + .endm + + .macro testop, instr, store + and r3, r0, #7 @ Get bit offset + mov r2, #1 + add r1, r1, r0, lsr #3 @ Get byte offset + mov r3, r2, lsl r3 @ create mask +1: ldrexb r2, [r1] + ands r0, r2, r3 @ save old value of bit + \instr ip, r2, r3 @ toggle bit + strexb r2, ip, [r1] + cmp r2, #0 + bne 1b + cmp r0, #0 + movne r0, #1 +2: mov pc, lr + .endm +#else .macro bitop, instr and r2, r0, #7 mov r3, #1 @@ -31,3 +61,4 @@ moveq r0, #0 mov pc, lr .endm +#endif diff --git a/arch/arm/lib/io-shark.c b/arch/arm/lib/io-shark.c index 108d4573e970..824253948f51 100644 --- a/arch/arm/lib/io-shark.c +++ b/arch/arm/lib/io-shark.c @@ -11,73 +11,3 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#include <linux/kernel.h> - -#include <asm/io.h> - -void print_warning(void) -{ - printk(KERN_WARNING "ins?/outs? not implemented on this architecture\n"); -} - -void insl(unsigned int port, void *to, int len) -{ - print_warning(); -} - -void insb(unsigned int port, void *to, int len) -{ - print_warning(); -} - -void outsl(unsigned int port, const void *from, int len) -{ - print_warning(); -} - -void outsb(unsigned int port, const void *from, int len) -{ - print_warning(); -} - -/* these should be in assembler again */ - -/* - * Purpose: read a block of data from a hardware register to memory. - * Proto : insw(int from_port, void *to, int len_in_words); - * Proto : inswb(int from_port, void *to, int len_in_bytes); - * Notes : increment to - */ - -void insw(unsigned int port, void *to, int len) -{ - int i; - - for (i = 0; i < len; i++) - ((unsigned short *) to)[i] = inw(port); -} - -void inswb(unsigned int port, void *to, int len) -{ - insw(port, to, len >> 2); -} - -/* - * Purpose: write a block of data from memory to a hardware register. - * Proto : outsw(int to_reg, void *from, int len_in_words); - * Proto : outswb(int to_reg, void *from, int len_in_bytes); - * Notes : increments from - */ - -void outsw(unsigned int port, const void *from, int len) -{ - int i; - - for (i = 0; i < len; i++) - outw(((unsigned short *) from)[i], port); -} - -void outswb(unsigned int port, const void *from, int len) -{ - outsw(port, from, len >> 2); -} diff --git a/arch/arm/lib/longlong.h b/arch/arm/lib/longlong.h deleted file mode 100644 index 90ae647e4d76..000000000000 --- a/arch/arm/lib/longlong.h +++ /dev/null @@ -1,183 +0,0 @@ -/* longlong.h -- based on code from gcc-2.95.3 - - definitions for mixed size 32/64 bit arithmetic. - Copyright (C) 1991, 92, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc. - - This definition file is free software; you can redistribute it - and/or modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2, or (at your option) any later version. - - This definition file is distributed in the hope that it will be - useful, but WITHOUT ANY WARRANTY; without even the implied - warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* Borrowed from GCC 2.95.3, I Molton 29/07/01 */ - -#ifndef SI_TYPE_SIZE -#define SI_TYPE_SIZE 32 -#endif - -#define __BITS4 (SI_TYPE_SIZE / 4) -#define __ll_B (1L << (SI_TYPE_SIZE / 2)) -#define __ll_lowpart(t) ((u32) (t) % __ll_B) -#define __ll_highpart(t) ((u32) (t) / __ll_B) - -/* Define auxiliary asm macros. - - 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand) - multiplies two u32 integers MULTIPLER and MULTIPLICAND, - and generates a two-part u32 product in HIGH_PROD and - LOW_PROD. - - 2) __umulsidi3(a,b) multiplies two u32 integers A and B, - and returns a u64 product. This is just a variant of umul_ppmm. - - 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator, - denominator) divides a two-word unsigned integer, composed by the - integers HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and - places the quotient in QUOTIENT and the remainder in REMAINDER. - HIGH_NUMERATOR must be less than DENOMINATOR for correct operation. - If, in addition, the most significant bit of DENOMINATOR must be 1, - then the pre-processor symbol UDIV_NEEDS_NORMALIZATION is defined to 1. - - 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator, - denominator). Like udiv_qrnnd but the numbers are signed. The - quotient is rounded towards 0. - - 5) count_leading_zeros(count, x) counts the number of zero-bits from - the msb to the first non-zero bit. This is the number of steps X - needs to be shifted left to set the msb. Undefined for X == 0. - - 6) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1, - high_addend_2, low_addend_2) adds two two-word unsigned integers, - composed by HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and - LOW_ADDEND_2 respectively. The result is placed in HIGH_SUM and - LOW_SUM. Overflow (i.e. carry out) is not stored anywhere, and is - lost. - - 7) sub_ddmmss(high_difference, low_difference, high_minuend, - low_minuend, high_subtrahend, low_subtrahend) subtracts two - two-word unsigned integers, composed by HIGH_MINUEND_1 and - LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and LOW_SUBTRAHEND_2 - respectively. The result is placed in HIGH_DIFFERENCE and - LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere, - and is lost. - - If any of these macros are left undefined for a particular CPU, - C macros are used. */ - -#if defined (__arm__) -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ("adds %1, %4, %5 \n\ - adc %0, %2, %3" \ - : "=r" ((u32) (sh)), \ - "=&r" ((u32) (sl)) \ - : "%r" ((u32) (ah)), \ - "rI" ((u32) (bh)), \ - "%r" ((u32) (al)), \ - "rI" ((u32) (bl))) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("subs %1, %4, %5 \n\ - sbc %0, %2, %3" \ - : "=r" ((u32) (sh)), \ - "=&r" ((u32) (sl)) \ - : "r" ((u32) (ah)), \ - "rI" ((u32) (bh)), \ - "r" ((u32) (al)), \ - "rI" ((u32) (bl))) -#define umul_ppmm(xh, xl, a, b) \ -{register u32 __t0, __t1, __t2; \ - __asm__ ("%@ Inlined umul_ppmm \n\ - mov %2, %5, lsr #16 \n\ - mov %0, %6, lsr #16 \n\ - bic %3, %5, %2, lsl #16 \n\ - bic %4, %6, %0, lsl #16 \n\ - mul %1, %3, %4 \n\ - mul %4, %2, %4 \n\ - mul %3, %0, %3 \n\ - mul %0, %2, %0 \n\ - adds %3, %4, %3 \n\ - addcs %0, %0, #65536 \n\ - adds %1, %1, %3, lsl #16 \n\ - adc %0, %0, %3, lsr #16" \ - : "=&r" ((u32) (xh)), \ - "=r" ((u32) (xl)), \ - "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \ - : "r" ((u32) (a)), \ - "r" ((u32) (b)));} -#define UMUL_TIME 20 -#define UDIV_TIME 100 -#endif /* __arm__ */ - -#define __umulsidi3(u, v) \ - ({DIunion __w; \ - umul_ppmm (__w.s.high, __w.s.low, u, v); \ - __w.ll; }) - -#define __udiv_qrnnd_c(q, r, n1, n0, d) \ - do { \ - u32 __d1, __d0, __q1, __q0; \ - u32 __r1, __r0, __m; \ - __d1 = __ll_highpart (d); \ - __d0 = __ll_lowpart (d); \ - \ - __r1 = (n1) % __d1; \ - __q1 = (n1) / __d1; \ - __m = (u32) __q1 * __d0; \ - __r1 = __r1 * __ll_B | __ll_highpart (n0); \ - if (__r1 < __m) \ - { \ - __q1--, __r1 += (d); \ - if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\ - if (__r1 < __m) \ - __q1--, __r1 += (d); \ - } \ - __r1 -= __m; \ - \ - __r0 = __r1 % __d1; \ - __q0 = __r1 / __d1; \ - __m = (u32) __q0 * __d0; \ - __r0 = __r0 * __ll_B | __ll_lowpart (n0); \ - if (__r0 < __m) \ - { \ - __q0--, __r0 += (d); \ - if (__r0 >= (d)) \ - if (__r0 < __m) \ - __q0--, __r0 += (d); \ - } \ - __r0 -= __m; \ - \ - (q) = (u32) __q1 * __ll_B | __q0; \ - (r) = __r0; \ - } while (0) - -#define UDIV_NEEDS_NORMALIZATION 1 -#define udiv_qrnnd __udiv_qrnnd_c - -#define count_leading_zeros(count, x) \ - do { \ - u32 __xr = (x); \ - u32 __a; \ - \ - if (SI_TYPE_SIZE <= 32) \ - { \ - __a = __xr < ((u32)1<<2*__BITS4) \ - ? (__xr < ((u32)1<<__BITS4) ? 0 : __BITS4) \ - : (__xr < ((u32)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \ - } \ - else \ - { \ - for (__a = SI_TYPE_SIZE - 8; __a > 0; __a -= 8) \ - if (((__xr >> __a) & 0xff) != 0) \ - break; \ - } \ - \ - (count) = SI_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \ - } while (0) diff --git a/arch/arm/lib/udivdi3.c b/arch/arm/lib/udivdi3.c deleted file mode 100644 index e343be4c6642..000000000000 --- a/arch/arm/lib/udivdi3.c +++ /dev/null @@ -1,222 +0,0 @@ -/* More subroutines needed by GCC output code on some machines. */ -/* Compile this one with gcc. */ -/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with other files, - some of which are compiled with GCC, to produce an executable, - this library does not by itself cause the resulting executable - to be covered by the GNU General Public License. - This exception does not however invalidate any other reasons why - the executable file might be covered by the GNU General Public License. - */ -/* support functions required by the kernel. based on code from gcc-2.95.3 */ -/* I Molton 29/07/01 */ - -#include "gcclib.h" -#include "longlong.h" - -static const u8 __clz_tab[] = { - 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, -}; - -u64 __udivmoddi4(u64 n, u64 d, u64 * rp) -{ - DIunion ww; - DIunion nn, dd; - DIunion rr; - u32 d0, d1, n0, n1, n2; - u32 q0, q1; - u32 b, bm; - - nn.ll = n; - dd.ll = d; - - d0 = dd.s.low; - d1 = dd.s.high; - n0 = nn.s.low; - n1 = nn.s.high; - - if (d1 == 0) { - if (d0 > n1) { - /* 0q = nn / 0D */ - - count_leading_zeros(bm, d0); - - if (bm != 0) { - /* Normalize, i.e. make the most significant bit of the - denominator set. */ - - d0 = d0 << bm; - n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm)); - n0 = n0 << bm; - } - - udiv_qrnnd(q0, n0, n1, n0, d0); - q1 = 0; - - /* Remainder in n0 >> bm. */ - } else { - /* qq = NN / 0d */ - - if (d0 == 0) - d0 = 1 / d0; /* Divide intentionally by zero. */ - - count_leading_zeros(bm, d0); - - if (bm == 0) { - /* From (n1 >= d0) /\ (the most significant bit of d0 is set), - conclude (the most significant bit of n1 is set) /\ (the - leading quotient digit q1 = 1). - - This special case is necessary, not an optimization. - (Shifts counts of SI_TYPE_SIZE are undefined.) */ - - n1 -= d0; - q1 = 1; - } else { - /* Normalize. */ - - b = SI_TYPE_SIZE - bm; - - d0 = d0 << bm; - n2 = n1 >> b; - n1 = (n1 << bm) | (n0 >> b); - n0 = n0 << bm; - - udiv_qrnnd(q1, n1, n2, n1, d0); - } - - /* n1 != d0... */ - - udiv_qrnnd(q0, n0, n1, n0, d0); - - /* Remainder in n0 >> bm. */ - } - - if (rp != 0) { - rr.s.low = n0 >> bm; - rr.s.high = 0; - *rp = rr.ll; - } - } else { - if (d1 > n1) { - /* 00 = nn / DD */ - - q0 = 0; - q1 = 0; - - /* Remainder in n1n0. */ - if (rp != 0) { - rr.s.low = n0; - rr.s.high = n1; - *rp = rr.ll; - } - } else { - /* 0q = NN / dd */ - - count_leading_zeros(bm, d1); - if (bm == 0) { - /* From (n1 >= d1) /\ (the most significant bit of d1 is set), - conclude (the most significant bit of n1 is set) /\ (the - quotient digit q0 = 0 or 1). - - This special case is necessary, not an optimization. */ - - /* The condition on the next line takes advantage of that - n1 >= d1 (true due to program flow). */ - if (n1 > d1 || n0 >= d0) { - q0 = 1; - sub_ddmmss(n1, n0, n1, n0, d1, d0); - } else - q0 = 0; - - q1 = 0; - - if (rp != 0) { - rr.s.low = n0; - rr.s.high = n1; - *rp = rr.ll; - } - } else { - u32 m1, m0; - /* Normalize. */ - - b = SI_TYPE_SIZE - bm; - - d1 = (d1 << bm) | (d0 >> b); - d0 = d0 << bm; - n2 = n1 >> b; - n1 = (n1 << bm) | (n0 >> b); - n0 = n0 << bm; - - udiv_qrnnd(q0, n1, n2, n1, d1); - umul_ppmm(m1, m0, q0, d0); - - if (m1 > n1 || (m1 == n1 && m0 > n0)) { - q0--; - sub_ddmmss(m1, m0, m1, m0, d1, d0); - } - - q1 = 0; - - /* Remainder in (n1n0 - m1m0) >> bm. */ - if (rp != 0) { - sub_ddmmss(n1, n0, n1, n0, m1, m0); - rr.s.low = (n1 << b) | (n0 >> bm); - rr.s.high = n1 >> bm; - *rp = rr.ll; - } - } - } - } - - ww.s.low = q0; - ww.s.high = q1; - return ww.ll; -} - -u64 __udivdi3(u64 n, u64 d) -{ - return __udivmoddi4(n, d, (u64 *) 0); -} - -u64 __umoddi3(u64 u, u64 v) -{ - u64 w; - - (void)__udivmoddi4(u, v, &w); - - return w; -} diff --git a/arch/arm/mach-aaec2000/Makefile.boot b/arch/arm/mach-aaec2000/Makefile.boot new file mode 100644 index 000000000000..8f5a8b7c53c7 --- /dev/null +++ b/arch/arm/mach-aaec2000/Makefile.boot @@ -0,0 +1 @@ + zreladdr-y := 0xf0008000 diff --git a/arch/arm/mach-aaec2000/aaed2000.c b/arch/arm/mach-aaec2000/aaed2000.c index 5417ca3f4621..c9d899886648 100644 --- a/arch/arm/mach-aaec2000/aaed2000.c +++ b/arch/arm/mach-aaec2000/aaed2000.c @@ -40,9 +40,11 @@ static void __init aaed2000_map_io(void) } MACHINE_START(AAED2000, "Agilent AAED-2000 Development Platform") - MAINTAINER("Nicolas Bellido Y Ortega") - BOOT_MEM(0xf0000000, PIO_BASE, VIO_BASE) - MAPIO(aaed2000_map_io) - INITIRQ(aaed2000_init_irq) + /* Maintainer: Nicolas Bellido Y Ortega */ + .phys_ram = 0xf0000000, + .phys_io = PIO_BASE, + .io_pg_offst = ((VIO_BASE) >> 18) & 0xfffc, + .map_io = aaed2000_map_io, + .init_irq = aaed2000_init_irq, .timer = &aaec2000_timer, MACHINE_END diff --git a/arch/arm/mach-aaec2000/core.c b/arch/arm/mach-aaec2000/core.c index fc145b3768fa..aece0cd4f0a3 100644 --- a/arch/arm/mach-aaec2000/core.c +++ b/arch/arm/mach-aaec2000/core.c @@ -128,8 +128,8 @@ aaec2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction aaec2000_timer_irq = { .name = "AAEC-2000 Timer Tick", - .flags = SA_INTERRUPT, - .handler = aaec2000_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = aaec2000_timer_interrupt, }; static void __init aaec2000_timer_init(void) diff --git a/arch/arm/mach-clps711x/autcpu12.c b/arch/arm/mach-clps711x/autcpu12.c index c106704a2c34..dc73feb1ffb0 100644 --- a/arch/arm/mach-clps711x/autcpu12.c +++ b/arch/arm/mach-clps711x/autcpu12.c @@ -59,11 +59,13 @@ void __init autcpu12_map_io(void) } MACHINE_START(AUTCPU12, "autronix autcpu12") - MAINTAINER("Thomas Gleixner") - BOOT_MEM(0xc0000000, 0x80000000, 0xff000000) - BOOT_PARAMS(0xc0020000) - MAPIO(autcpu12_map_io) - INITIRQ(clps711x_init_irq) + /* Maintainer: Thomas Gleixner */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xff000000) >> 18) & 0xfffc, + .boot_params = 0xc0020000, + .map_io = autcpu12_map_io, + .init_irq = clps711x_init_irq, .timer = &clps711x_timer, MACHINE_END diff --git a/arch/arm/mach-clps711x/cdb89712.c b/arch/arm/mach-clps711x/cdb89712.c index 7664f9cf83b8..a46c82cd2711 100644 --- a/arch/arm/mach-clps711x/cdb89712.c +++ b/arch/arm/mach-clps711x/cdb89712.c @@ -49,10 +49,12 @@ static void __init cdb89712_map_io(void) } MACHINE_START(CDB89712, "Cirrus-CDB89712") - MAINTAINER("Ray Lehtiniemi") - BOOT_MEM(0xc0000000, 0x80000000, 0xff000000) - BOOT_PARAMS(0xc0000100) - MAPIO(cdb89712_map_io) - INITIRQ(clps711x_init_irq) + /* Maintainer: Ray Lehtiniemi */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xff000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = cdb89712_map_io, + .init_irq = clps711x_init_irq, .timer = &clps711x_timer, MACHINE_END diff --git a/arch/arm/mach-clps711x/ceiva.c b/arch/arm/mach-clps711x/ceiva.c index e4093be3c4cb..780d91805984 100644 --- a/arch/arm/mach-clps711x/ceiva.c +++ b/arch/arm/mach-clps711x/ceiva.c @@ -53,10 +53,12 @@ static void __init ceiva_map_io(void) MACHINE_START(CEIVA, "CEIVA/Polaroid Photo MAX Digital Picture Frame") - MAINTAINER("Rob Scott") - BOOT_MEM(0xc0000000, 0x80000000, 0xff000000) - BOOT_PARAMS(0xc0000100) - MAPIO(ceiva_map_io) - INITIRQ(clps711x_init_irq) + /* Maintainer: Rob Scott */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xff000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = ceiva_map_io, + .init_irq = clps711x_init_irq, .timer = &clps711x_timer, MACHINE_END diff --git a/arch/arm/mach-clps711x/clep7312.c b/arch/arm/mach-clps711x/clep7312.c index 9ca21cb481ba..c83f3fd68fcd 100644 --- a/arch/arm/mach-clps711x/clep7312.c +++ b/arch/arm/mach-clps711x/clep7312.c @@ -37,12 +37,14 @@ fixup_clep7312(struct machine_desc *desc, struct tag *tags, MACHINE_START(CLEP7212, "Cirrus Logic 7212/7312") - MAINTAINER("Nobody") - BOOT_MEM(0xc0000000, 0x80000000, 0xff000000) - BOOT_PARAMS(0xc0000100) - FIXUP(fixup_clep7312) - MAPIO(clps711x_map_io) - INITIRQ(clps711x_init_irq) + /* Maintainer: Nobody */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xff000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .fixup = fixup_clep7312, + .map_io = clps711x_map_io, + .init_irq = clps711x_init_irq, .timer = &clps711x_timer, MACHINE_END diff --git a/arch/arm/mach-clps711x/edb7211-arch.c b/arch/arm/mach-clps711x/edb7211-arch.c index c6c46324a2e3..255c98b63e15 100644 --- a/arch/arm/mach-clps711x/edb7211-arch.c +++ b/arch/arm/mach-clps711x/edb7211-arch.c @@ -51,11 +51,13 @@ fixup_edb7211(struct machine_desc *desc, struct tag *tags, } MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)") - MAINTAINER("Jon McClintock") - BOOT_MEM(0xc0000000, 0x80000000, 0xff000000) - BOOT_PARAMS(0xc0020100) /* 0xc0000000 - 0xc001ffff can be video RAM */ - FIXUP(fixup_edb7211) - MAPIO(edb7211_map_io) - INITIRQ(clps711x_init_irq) + /* Maintainer: Jon McClintock */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xff000000) >> 18) & 0xfffc, + .boot_params = 0xc0020100, /* 0xc0000000 - 0xc001ffff can be video RAM */ + .fixup = fixup_edb7211, + .map_io = edb7211_map_io, + .init_irq = clps711x_init_irq, .timer = &clps711x_timer, MACHINE_END diff --git a/arch/arm/mach-clps711x/fortunet.c b/arch/arm/mach-clps711x/fortunet.c index c1c5b8e01549..f83a59761e02 100644 --- a/arch/arm/mach-clps711x/fortunet.c +++ b/arch/arm/mach-clps711x/fortunet.c @@ -75,11 +75,13 @@ fortunet_fixup(struct machine_desc *desc, struct tag *tags, } MACHINE_START(FORTUNET, "ARM-FortuNet") - MAINTAINER("FortuNet Inc.") - BOOT_MEM(0xc0000000, 0x80000000, 0xf0000000) - BOOT_PARAMS(0x00000000) - FIXUP(fortunet_fixup) - MAPIO(clps711x_map_io) - INITIRQ(clps711x_init_irq) + /* Maintainer: FortuNet Inc. */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf0000000) >> 18) & 0xfffc, + .boot_params = 0x00000000, + .fixup = fortunet_fixup, + .map_io = clps711x_map_io, + .init_irq = clps711x_init_irq, .timer = &clps711x_timer, MACHINE_END diff --git a/arch/arm/mach-clps711x/p720t.c b/arch/arm/mach-clps711x/p720t.c index 29269df054f5..5bdb90edf992 100644 --- a/arch/arm/mach-clps711x/p720t.c +++ b/arch/arm/mach-clps711x/p720t.c @@ -79,12 +79,14 @@ static void __init p720t_map_io(void) } MACHINE_START(P720T, "ARM-Prospector720T") - MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd") - BOOT_MEM(0xc0000000, 0x80000000, 0xff000000) - BOOT_PARAMS(0xc0000100) - FIXUP(fixup_p720t) - MAPIO(p720t_map_io) - INITIRQ(clps711x_init_irq) + /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xff000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .fixup = fixup_p720t, + .map_io = p720t_map_io, + .init_irq = clps711x_init_irq, .timer = &clps711x_timer, MACHINE_END diff --git a/arch/arm/mach-clps711x/time.c b/arch/arm/mach-clps711x/time.c index 383d4e0c6e35..1a23f0dcd4b8 100644 --- a/arch/arm/mach-clps711x/time.c +++ b/arch/arm/mach-clps711x/time.c @@ -57,8 +57,8 @@ p720t_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction clps711x_timer_irq = { .name = "CLPS711x Timer Tick", - .flags = SA_INTERRUPT, - .handler = p720t_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = p720t_timer_interrupt, }; static void __init clps711x_timer_init(void) diff --git a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c index 0bc7da488612..112f1d68fb2b 100644 --- a/arch/arm/mach-clps7500/core.c +++ b/arch/arm/mach-clps7500/core.c @@ -298,8 +298,8 @@ clps7500_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction clps7500_timer_irq = { .name = "CLPS7500 Timer Tick", - .flags = SA_INTERRUPT, - .handler = clps7500_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = clps7500_timer_interrupt, }; /* @@ -366,11 +366,13 @@ static void __init clps7500_init(void) } MACHINE_START(CLPS7500, "CL-PS7500") - MAINTAINER("Philip Blundell") - BOOT_MEM(0x10000000, 0x03000000, 0xe0000000) - MAPIO(clps7500_map_io) - INITIRQ(clps7500_init_irq) - .init_machine = clps7500_init, - .timer = &clps7500_timer, + /* Maintainer: Philip Blundell */ + .phys_ram = 0x10000000, + .phys_io = 0x03000000, + .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc, + .map_io = clps7500_map_io, + .init_irq = clps7500_init_irq, + .init_machine = clps7500_init, + .timer = &clps7500_timer, MACHINE_END diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c index ef362d44949d..23c4da10101b 100644 --- a/arch/arm/mach-ebsa110/core.c +++ b/arch/arm/mach-ebsa110/core.c @@ -173,8 +173,8 @@ ebsa110_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction ebsa110_timer_irq = { .name = "EBSA110 Timer Tick", - .flags = SA_INTERRUPT, - .handler = ebsa110_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = ebsa110_timer_interrupt, }; /* @@ -233,13 +233,15 @@ static int __init ebsa110_init(void) arch_initcall(ebsa110_init); MACHINE_START(EBSA110, "EBSA110") - MAINTAINER("Russell King") - BOOT_MEM(0x00000000, 0xe0000000, 0xe0000000) - BOOT_PARAMS(0x00000400) - DISABLE_PARPORT(0) - DISABLE_PARPORT(2) - SOFT_REBOOT - MAPIO(ebsa110_map_io) - INITIRQ(ebsa110_init_irq) + /* Maintainer: Russell King */ + .phys_ram = 0x00000000, + .phys_io = 0xe0000000, + .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc, + .boot_params = 0x00000400, + .reserve_lp0 = 1, + .reserve_lp2 = 1, + .soft_reboot = 1, + .map_io = ebsa110_map_io, + .init_irq = ebsa110_init_irq, .timer = &ebsa110_timer, MACHINE_END diff --git a/arch/arm/mach-epxa10db/arch.c b/arch/arm/mach-epxa10db/arch.c index 1b40340e8a21..7daa021676d0 100644 --- a/arch/arm/mach-epxa10db/arch.c +++ b/arch/arm/mach-epxa10db/arch.c @@ -63,10 +63,12 @@ extern void epxa10db_init_irq(void); extern struct sys_timer epxa10db_timer; MACHINE_START(CAMELOT, "Altera Epxa10db") - MAINTAINER("Altera Corporation") - BOOT_MEM(0x00000000, 0x7fffc000, 0xffffc000) - MAPIO(epxa10db_map_io) - INITIRQ(epxa10db_init_irq) + /* Maintainer: Altera Corporation */ + .phys_ram = 0x00000000, + .phys_io = 0x7fffc000, + .io_pg_offst = ((0xffffc000) >> 18) & 0xfffc, + .map_io = epxa10db_map_io, + .init_irq = epxa10db_init_irq, .timer = &epxa10db_timer, MACHINE_END diff --git a/arch/arm/mach-epxa10db/time.c b/arch/arm/mach-epxa10db/time.c index 1b991f3cc3c6..4b1084dde8dd 100644 --- a/arch/arm/mach-epxa10db/time.c +++ b/arch/arm/mach-epxa10db/time.c @@ -56,8 +56,8 @@ epxa10db_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction epxa10db_timer_irq = { .name = "Excalibur Timer Tick", - .flags = SA_INTERRUPT, - .handler = epxa10db_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = epxa10db_timer_interrupt, }; /* diff --git a/arch/arm/mach-footbridge/cats-hw.c b/arch/arm/mach-footbridge/cats-hw.c index d1ced86c379c..49b898af0032 100644 --- a/arch/arm/mach-footbridge/cats-hw.c +++ b/arch/arm/mach-footbridge/cats-hw.c @@ -84,12 +84,14 @@ fixup_cats(struct machine_desc *desc, struct tag *tags, } MACHINE_START(CATS, "Chalice-CATS") - MAINTAINER("Philip Blundell") - BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000) - BOOT_PARAMS(0x00000100) - SOFT_REBOOT - FIXUP(fixup_cats) - MAPIO(footbridge_map_io) - INITIRQ(footbridge_init_irq) + /* Maintainer: Philip Blundell */ + .phys_ram = 0x00000000, + .phys_io = DC21285_ARMCSR_BASE, + .io_pg_offst = ((0xfe000000) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .soft_reboot = 1, + .fixup = fixup_cats, + .map_io = footbridge_map_io, + .init_irq = footbridge_init_irq, .timer = &isa_timer, MACHINE_END diff --git a/arch/arm/mach-footbridge/co285.c b/arch/arm/mach-footbridge/co285.c index e1541914fdcd..548a79081688 100644 --- a/arch/arm/mach-footbridge/co285.c +++ b/arch/arm/mach-footbridge/co285.c @@ -28,11 +28,13 @@ fixup_coebsa285(struct machine_desc *desc, struct tag *tags, } MACHINE_START(CO285, "co-EBSA285") - MAINTAINER("Mark van Doesburg") - BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0x7cf00000) - FIXUP(fixup_coebsa285) - MAPIO(footbridge_map_io) - INITIRQ(footbridge_init_irq) + /* Maintainer: Mark van Doesburg */ + .phys_ram = 0x00000000, + .phys_io = DC21285_ARMCSR_BASE, + .io_pg_offst = ((0x7cf00000) >> 18) & 0xfffc, + .fixup = fixup_coebsa285, + .map_io = footbridge_map_io, + .init_irq = footbridge_init_irq, .timer = &footbridge_timer, MACHINE_END diff --git a/arch/arm/mach-footbridge/dc21285-timer.c b/arch/arm/mach-footbridge/dc21285-timer.c index da5b9b7623ca..14a62d6008fe 100644 --- a/arch/arm/mach-footbridge/dc21285-timer.c +++ b/arch/arm/mach-footbridge/dc21285-timer.c @@ -43,7 +43,7 @@ timer1_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction footbridge_timer_irq = { .name = "Timer1 timer tick", .handler = timer1_interrupt, - .flags = SA_INTERRUPT, + .flags = SA_INTERRUPT | SA_TIMER, }; /* diff --git a/arch/arm/mach-footbridge/ebsa285.c b/arch/arm/mach-footbridge/ebsa285.c index d0931f5a63c8..1c37605268d5 100644 --- a/arch/arm/mach-footbridge/ebsa285.c +++ b/arch/arm/mach-footbridge/ebsa285.c @@ -13,12 +13,15 @@ #include "common.h" MACHINE_START(EBSA285, "EBSA285") - MAINTAINER("Russell King") - BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000) - BOOT_PARAMS(0x00000100) - VIDEO(0x000a0000, 0x000bffff) - MAPIO(footbridge_map_io) - INITIRQ(footbridge_init_irq) + /* Maintainer: Russell King */ + .phys_ram = 0x00000000, + .phys_io = DC21285_ARMCSR_BASE, + .io_pg_offst = ((0xfe000000) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .video_start = 0x000a0000, + .video_end = 0x000bffff, + .map_io = footbridge_map_io, + .init_irq = footbridge_init_irq, .timer = &footbridge_timer, MACHINE_END diff --git a/arch/arm/mach-footbridge/isa-timer.c b/arch/arm/mach-footbridge/isa-timer.c index a4fefa0bb5a1..c1d74f7ab669 100644 --- a/arch/arm/mach-footbridge/isa-timer.c +++ b/arch/arm/mach-footbridge/isa-timer.c @@ -72,7 +72,7 @@ isa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction isa_timer_irq = { .name = "ISA timer tick", .handler = isa_timer_interrupt, - .flags = SA_INTERRUPT, + .flags = SA_INTERRUPT | SA_TIMER, }; static void __init isa_timer_init(void) diff --git a/arch/arm/mach-footbridge/netwinder-hw.c b/arch/arm/mach-footbridge/netwinder-hw.c index 1e1dfd79f4fe..775f85fc8513 100644 --- a/arch/arm/mach-footbridge/netwinder-hw.c +++ b/arch/arm/mach-footbridge/netwinder-hw.c @@ -647,14 +647,17 @@ fixup_netwinder(struct machine_desc *desc, struct tag *tags, } MACHINE_START(NETWINDER, "Rebel-NetWinder") - MAINTAINER("Russell King/Rebel.com") - BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000) - BOOT_PARAMS(0x00000100) - VIDEO(0x000a0000, 0x000bffff) - DISABLE_PARPORT(0) - DISABLE_PARPORT(2) - FIXUP(fixup_netwinder) - MAPIO(footbridge_map_io) - INITIRQ(footbridge_init_irq) + /* Maintainer: Russell King/Rebel.com */ + .phys_ram = 0x00000000, + .phys_io = DC21285_ARMCSR_BASE, + .io_pg_offst = ((0xfe000000) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .video_start = 0x000a0000, + .video_end = 0x000bffff, + .reserve_lp0 = 1, + .reserve_lp2 = 1, + .fixup = fixup_netwinder, + .map_io = footbridge_map_io, + .init_irq = footbridge_init_irq, .timer = &isa_timer, MACHINE_END diff --git a/arch/arm/mach-footbridge/personal.c b/arch/arm/mach-footbridge/personal.c index 415086d7bbee..0146b8bb59da 100644 --- a/arch/arm/mach-footbridge/personal.c +++ b/arch/arm/mach-footbridge/personal.c @@ -13,11 +13,13 @@ #include "common.h" MACHINE_START(PERSONAL_SERVER, "Compaq-PersonalServer") - MAINTAINER("Jamey Hicks / George France") - BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000) - BOOT_PARAMS(0x00000100) - MAPIO(footbridge_map_io) - INITIRQ(footbridge_init_irq) + /* Maintainer: Jamey Hicks / George France */ + .phys_ram = 0x00000000, + .phys_io = DC21285_ARMCSR_BASE, + .io_pg_offst = ((0xfe000000) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = footbridge_map_io, + .init_irq = footbridge_init_irq, .timer = &footbridge_timer, MACHINE_END diff --git a/arch/arm/mach-h720x/cpu-h7201.c b/arch/arm/mach-h720x/cpu-h7201.c index 743656881ed6..af9e4a5d5ea7 100644 --- a/arch/arm/mach-h720x/cpu-h7201.c +++ b/arch/arm/mach-h720x/cpu-h7201.c @@ -41,8 +41,8 @@ h7201_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction h7201_timer_irq = { .name = "h7201 Timer Tick", - .flags = SA_INTERRUPT, - .handler = h7201_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = h7201_timer_interrupt, }; /* diff --git a/arch/arm/mach-h720x/cpu-h7202.c b/arch/arm/mach-h720x/cpu-h7202.c index 21b8fb6122cd..593b6a2a30e1 100644 --- a/arch/arm/mach-h720x/cpu-h7202.c +++ b/arch/arm/mach-h720x/cpu-h7202.c @@ -171,8 +171,8 @@ static struct irqchip h7202_timerx_chip = { static struct irqaction h7202_timer_irq = { .name = "h7202 Timer Tick", - .flags = SA_INTERRUPT, - .handler = h7202_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = h7202_timer_interrupt, }; /* diff --git a/arch/arm/mach-h720x/h7201-eval.c b/arch/arm/mach-h720x/h7201-eval.c index 9b24b9b0db15..fa59e9e2a5c8 100644 --- a/arch/arm/mach-h720x/h7201-eval.c +++ b/arch/arm/mach-h720x/h7201-eval.c @@ -30,10 +30,12 @@ #include "common.h" MACHINE_START(H7201, "Hynix GMS30C7201") - MAINTAINER("Robert Schwebel, Pengutronix") - BOOT_MEM(0x40000000, 0x80000000, 0xf0000000) - BOOT_PARAMS(0xc0001000) - MAPIO(h720x_map_io) - INITIRQ(h720x_init_irq) - .timer = &h7201_timer, + /* Maintainer: Robert Schwebel, Pengutronix */ + .phys_ram = 0x40000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf0000000) >> 18) & 0xfffc, + .boot_params = 0xc0001000, + .map_io = h720x_map_io, + .init_irq = h720x_init_irq, + .timer = &h7201_timer, MACHINE_END diff --git a/arch/arm/mach-h720x/h7202-eval.c b/arch/arm/mach-h720x/h7202-eval.c index 3456a00d5f5c..db9078ad008c 100644 --- a/arch/arm/mach-h720x/h7202-eval.c +++ b/arch/arm/mach-h720x/h7202-eval.c @@ -71,11 +71,13 @@ static void __init init_eval_h7202(void) } MACHINE_START(H7202, "Hynix HMS30C7202") - MAINTAINER("Robert Schwebel, Pengutronix") - BOOT_MEM(0x40000000, 0x80000000, 0xf0000000) - BOOT_PARAMS(0x40000100) - MAPIO(h720x_map_io) - INITIRQ(h7202_init_irq) - .timer = &h7202_timer, - INIT_MACHINE(init_eval_h7202) + /* Maintainer: Robert Schwebel, Pengutronix */ + .phys_ram = 0x40000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf0000000) >> 18) & 0xfffc, + .boot_params = 0x40000100, + .map_io = h720x_map_io, + .init_irq = h7202_init_irq, + .timer = &h7202_timer, + .init_machine = init_eval_h7202, MACHINE_END diff --git a/arch/arm/mach-imx/mx1ads.c b/arch/arm/mach-imx/mx1ads.c index 625dd01c2578..5d25434d332c 100644 --- a/arch/arm/mach-imx/mx1ads.c +++ b/arch/arm/mach-imx/mx1ads.c @@ -78,11 +78,13 @@ mx1ads_map_io(void) } MACHINE_START(MX1ADS, "Motorola MX1ADS") - MAINTAINER("Sascha Hauer, Pengutronix") - BOOT_MEM(0x08000000, 0x00200000, 0xe0200000) - BOOT_PARAMS(0x08000100) - MAPIO(mx1ads_map_io) - INITIRQ(imx_init_irq) + /* Maintainer: Sascha Hauer, Pengutronix */ + .phys_ram = 0x08000000, + .phys_io = 0x00200000, + .io_pg_offst = ((0xe0200000) >> 18) & 0xfffc, + .boot_params = 0x08000100, + .map_io = mx1ads_map_io, + .init_irq = imx_init_irq, .timer = &imx_timer, - INIT_MACHINE(mx1ads_init) + .init_machine = mx1ads_init, MACHINE_END diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c index 11f1e56c36bc..ea805bfa5e54 100644 --- a/arch/arm/mach-imx/time.c +++ b/arch/arm/mach-imx/time.c @@ -72,8 +72,8 @@ imx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction imx_timer_irq = { .name = "i.MX Timer Tick", - .flags = SA_INTERRUPT, - .handler = imx_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = imx_timer_interrupt, }; /* diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index bd1e5e3c9d34..dacbf504dae2 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -20,6 +20,7 @@ #include <asm/irq.h> #include <asm/io.h> #include <asm/hardware/amba.h> +#include <asm/hardware/arm_timer.h> #include <asm/arch/cm.h> #include <asm/system.h> #include <asm/leds.h> @@ -156,16 +157,6 @@ EXPORT_SYMBOL(cm_control); #define TICKS2USECS(x) ((x) / TICKS_PER_uSEC) #endif -/* - * What does it look like? - */ -typedef struct TimerStruct { - unsigned long TimerLoad; - unsigned long TimerValue; - unsigned long TimerControl; - unsigned long TimerClear; -} TimerStruct_t; - static unsigned long timer_reload; /* @@ -174,7 +165,6 @@ static unsigned long timer_reload; */ unsigned long integrator_gettimeoffset(void) { - volatile TimerStruct_t *timer1 = (TimerStruct_t *)TIMER1_VA_BASE; unsigned long ticks1, ticks2, status; /* @@ -183,11 +173,11 @@ unsigned long integrator_gettimeoffset(void) * an interrupt. We get around this by ensuring that the * counter has not reloaded between our two reads. */ - ticks2 = timer1->TimerValue & 0xffff; + ticks2 = readl(TIMER1_VA_BASE + TIMER_VALUE) & 0xffff; do { ticks1 = ticks2; status = __raw_readl(VA_IC_BASE + IRQ_RAW_STATUS); - ticks2 = timer1->TimerValue & 0xffff; + ticks2 = readl(TIMER1_VA_BASE + TIMER_VALUE) & 0xffff; } while (ticks2 > ticks1); /* @@ -213,14 +203,12 @@ unsigned long integrator_gettimeoffset(void) static irqreturn_t integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE; - write_seqlock(&xtime_lock); /* * clear the interrupt */ - timer1->TimerClear = 1; + writel(1, TIMER1_VA_BASE + TIMER_INTCLR); /* * the clock tick routines are only processed on the @@ -247,8 +235,8 @@ integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction integrator_timer_irq = { .name = "Integrator Timer Tick", - .flags = SA_INTERRUPT, - .handler = integrator_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = integrator_timer_interrupt, }; /* @@ -256,32 +244,29 @@ static struct irqaction integrator_timer_irq = { */ void __init integrator_time_init(unsigned long reload, unsigned int ctrl) { - volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE; - volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE; - volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE; - unsigned int timer_ctrl = 0x80 | 0x40; /* periodic */ + unsigned int timer_ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC; timer_reload = reload; timer_ctrl |= ctrl; if (timer_reload > 0x100000) { timer_reload >>= 8; - timer_ctrl |= 0x08; /* /256 */ + timer_ctrl |= TIMER_CTRL_DIV256; } else if (timer_reload > 0x010000) { timer_reload >>= 4; - timer_ctrl |= 0x04; /* /16 */ + timer_ctrl |= TIMER_CTRL_DIV16; } /* * Initialise to a known state (all timers off) */ - timer0->TimerControl = 0; - timer1->TimerControl = 0; - timer2->TimerControl = 0; + writel(0, TIMER0_VA_BASE + TIMER_CTRL); + writel(0, TIMER1_VA_BASE + TIMER_CTRL); + writel(0, TIMER2_VA_BASE + TIMER_CTRL); - timer1->TimerLoad = timer_reload; - timer1->TimerValue = timer_reload; - timer1->TimerControl = timer_ctrl; + writel(timer_reload, TIMER1_VA_BASE + TIMER_LOAD); + writel(timer_reload, TIMER1_VA_BASE + TIMER_VALUE); + writel(timer_ctrl, TIMER1_VA_BASE + TIMER_CTRL); /* * Make irqs happen for the system timer diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index 91ba9fd79c87..36e2b6eb67b7 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -292,11 +292,13 @@ static struct sys_timer ap_timer = { }; MACHINE_START(INTEGRATOR, "ARM-Integrator") - MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd") - BOOT_MEM(0x00000000, 0x16000000, 0xf1600000) - BOOT_PARAMS(0x00000100) - MAPIO(ap_map_io) - INITIRQ(ap_init_irq) + /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ + .phys_ram = 0x00000000, + .phys_io = 0x16000000, + .io_pg_offst = ((0xf1600000) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = ap_map_io, + .init_irq = ap_init_irq, .timer = &ap_timer, - INIT_MACHINE(ap_init) + .init_machine = ap_init, MACHINE_END diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index e0a01eef0993..569f328c479d 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -532,11 +532,13 @@ static struct sys_timer cp_timer = { }; MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP") - MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd") - BOOT_MEM(0x00000000, 0x16000000, 0xf1600000) - BOOT_PARAMS(0x00000100) - MAPIO(intcp_map_io) - INITIRQ(intcp_init_irq) + /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ + .phys_ram = 0x00000000, + .phys_io = 0x16000000, + .io_pg_offst = ((0xf1600000) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = intcp_map_io, + .init_irq = intcp_init_irq, .timer = &cp_timer, - INIT_MACHINE(intcp_init) + .init_machine = intcp_init, MACHINE_END diff --git a/arch/arm/mach-integrator/platsmp.c b/arch/arm/mach-integrator/platsmp.c index ead15dfcb53d..aecf47ba033a 100644 --- a/arch/arm/mach-integrator/platsmp.c +++ b/arch/arm/mach-integrator/platsmp.c @@ -27,12 +27,12 @@ extern void integrator_secondary_startup(void); * control for which core is the next to come out of the secondary * boot "holding pen" */ -volatile int __initdata pen_release = -1; -unsigned long __initdata phys_pen_release = 0; +volatile int __cpuinitdata pen_release = -1; +unsigned long __cpuinitdata phys_pen_release = 0; static DEFINE_SPINLOCK(boot_lock); -void __init platform_secondary_init(unsigned int cpu) +void __cpuinit platform_secondary_init(unsigned int cpu) { /* * the primary core may have used a "cross call" soft interrupt @@ -61,7 +61,7 @@ void __init platform_secondary_init(unsigned int cpu) spin_unlock(&boot_lock); } -int __init boot_secondary(unsigned int cpu, struct task_struct *idle) +int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) { unsigned long timeout; @@ -174,11 +174,13 @@ void __init smp_prepare_cpus(unsigned int max_cpus) max_cpus = ncores; /* - * Initialise the present mask - this tells us which CPUs should - * be present. + * Initialise the possible/present maps. + * cpu_possible_map describes the set of CPUs which may be present + * cpu_present_map describes the set of CPUs populated */ for (i = 0; i < max_cpus; i++) { - cpu_set(i, cpu_present_mask); + cpu_set(i, cpu_possible_map); + cpu_set(i, cpu_present_map); } /* diff --git a/arch/arm/mach-iop3xx/iop321-setup.c b/arch/arm/mach-iop3xx/iop321-setup.c index bf23e0fd2843..0f921ba2750c 100644 --- a/arch/arm/mach-iop3xx/iop321-setup.c +++ b/arch/arm/mach-iop3xx/iop321-setup.c @@ -146,23 +146,27 @@ extern void iop321_init_time(void); #if defined(CONFIG_ARCH_IQ80321) MACHINE_START(IQ80321, "Intel IQ80321") - MAINTAINER("Intel Corporation") - BOOT_MEM(PHYS_OFFSET, IQ80321_UART, IQ80321_UART) - MAPIO(iq80321_map_io) - INITIRQ(iop321_init_irq) + /* Maintainer: Intel Corporation */ + .phys_ram = PHYS_OFFSET, + .phys_io = IQ80321_UART, + .io_pg_offst = ((IQ80321_UART) >> 18) & 0xfffc, + .map_io = iq80321_map_io, + .init_irq = iop321_init_irq, .timer = &iop321_timer, - BOOT_PARAMS(0xa0000100) - INIT_MACHINE(iop32x_init) + .boot_params = 0xa0000100, + .init_machine = iop32x_init, MACHINE_END #elif defined(CONFIG_ARCH_IQ31244) MACHINE_START(IQ31244, "Intel IQ31244") - MAINTAINER("Intel Corp.") - BOOT_MEM(PHYS_OFFSET, IQ31244_UART, IQ31244_UART) - MAPIO(iq31244_map_io) - INITIRQ(iop321_init_irq) + /* Maintainer: Intel Corp. */ + .phys_ram = PHYS_OFFSET, + .phys_io = IQ31244_UART, + .io_pg_offst = ((IQ31244_UART) >> 18) & 0xfffc, + .map_io = iq31244_map_io, + .init_irq = iop321_init_irq, .timer = &iop321_timer, - BOOT_PARAMS(0xa0000100) - INIT_MACHINE(iop32x_init) + .boot_params = 0xa0000100, + .init_machine = iop32x_init, MACHINE_END #else #error No machine descriptor defined for this IOP3XX implementation diff --git a/arch/arm/mach-iop3xx/iop321-time.c b/arch/arm/mach-iop3xx/iop321-time.c index 9b7dd64d1b8f..d53af1669502 100644 --- a/arch/arm/mach-iop3xx/iop321-time.c +++ b/arch/arm/mach-iop3xx/iop321-time.c @@ -86,7 +86,7 @@ iop321_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction iop321_timer_irq = { .name = "IOP321 Timer Tick", .handler = iop321_timer_interrupt, - .flags = SA_INTERRUPT + .flags = SA_INTERRUPT | SA_TIMER, }; static void __init iop321_timer_init(void) diff --git a/arch/arm/mach-iop3xx/iop331-setup.c b/arch/arm/mach-iop3xx/iop331-setup.c index 622e7914819a..fc74b722f72f 100644 --- a/arch/arm/mach-iop3xx/iop331-setup.c +++ b/arch/arm/mach-iop3xx/iop331-setup.c @@ -148,26 +148,28 @@ extern void iq80332_map_io(void); #if defined(CONFIG_ARCH_IQ80331) MACHINE_START(IQ80331, "Intel IQ80331") - MAINTAINER("Intel Corp.") - BOOT_MEM(PHYS_OFFSET, 0xfefff000, 0xfffff000) // virtual, physical - //BOOT_MEM(PHYS_OFFSET, IOP331_UART0_VIRT, IOP331_UART0_PHYS) - MAPIO(iq80331_map_io) - INITIRQ(iop331_init_irq) + /* Maintainer: Intel Corp. */ + .phys_ram = PHYS_OFFSET, + .phys_io = 0xfefff000, + .io_pg_offst = ((0xfffff000) >> 18) & 0xfffc, // virtual, physical + .map_io = iq80331_map_io, + .init_irq = iop331_init_irq, .timer = &iop331_timer, - BOOT_PARAMS(0x0100) - INIT_MACHINE(iop33x_init) + .boot_params = 0x0100, + .init_machine = iop33x_init, MACHINE_END #elif defined(CONFIG_MACH_IQ80332) MACHINE_START(IQ80332, "Intel IQ80332") - MAINTAINER("Intel Corp.") - BOOT_MEM(PHYS_OFFSET, 0xfefff000, 0xfffff000) // virtual, physical - //BOOT_MEM(PHYS_OFFSET, IOP331_UART0_VIRT, IOP331_UART0_PHYS) - MAPIO(iq80332_map_io) - INITIRQ(iop331_init_irq) + /* Maintainer: Intel Corp. */ + .phys_ram = PHYS_OFFSET, + .phys_io = 0xfefff000, + .io_pg_offst = ((0xfffff000) >> 18) & 0xfffc, // virtual, physical + .map_io = iq80332_map_io, + .init_irq = iop331_init_irq, .timer = &iop331_timer, - BOOT_PARAMS(0x0100) - INIT_MACHINE(iop33x_init) + .boot_params = 0x0100, + .init_machine = iop33x_init, MACHINE_END #else diff --git a/arch/arm/mach-iop3xx/iop331-time.c b/arch/arm/mach-iop3xx/iop331-time.c index e01696769263..1a6d9d661e4b 100644 --- a/arch/arm/mach-iop3xx/iop331-time.c +++ b/arch/arm/mach-iop3xx/iop331-time.c @@ -83,7 +83,7 @@ iop331_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction iop331_timer_irq = { .name = "IOP331 Timer Tick", .handler = iop331_timer_interrupt, - .flags = SA_INTERRUPT + .flags = SA_INTERRUPT | SA_TIMER, }; static void __init iop331_timer_init(void) diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c index 0ee34acb8d7b..45b18658499f 100644 --- a/arch/arm/mach-ixp2000/core.c +++ b/arch/arm/mach-ixp2000/core.c @@ -23,7 +23,7 @@ #include <linux/serial.h> #include <linux/tty.h> #include <linux/bitops.h> -#include <linux/serial_core.h> +#include <linux/serial_8250.h> #include <linux/mm.h> #include <asm/types.h> @@ -103,6 +103,11 @@ static struct map_desc ixp2000_io_desc[] __initdata = { .length = IXP2000_PCI_CSR_SIZE, .type = MT_DEVICE }, { + .virtual = IXP2000_MSF_VIRT_BASE, + .physical = IXP2000_MSF_PHYS_BASE, + .length = IXP2000_MSF_SIZE, + .type = MT_DEVICE + }, { .virtual = IXP2000_PCI_IO_VIRT_BASE, .physical = IXP2000_PCI_IO_PHYS_BASE, .length = IXP2000_PCI_IO_SIZE, @@ -120,19 +125,6 @@ static struct map_desc ixp2000_io_desc[] __initdata = { } }; -static struct uart_port ixp2000_serial_port = { - .membase = (char *)(IXP2000_UART_VIRT_BASE + 3), - .mapbase = IXP2000_UART_PHYS_BASE + 3, - .irq = IRQ_IXP2000_UART, - .flags = UPF_SKIP_TEST, - .iotype = UPIO_MEM, - .regshift = 2, - .uartclk = 50000000, - .line = 0, - .type = PORT_XSCALE, - .fifosize = 16 -}; - void __init ixp2000_map_io(void) { extern unsigned int processor_id; @@ -152,12 +144,50 @@ void __init ixp2000_map_io(void) } iotable_init(ixp2000_io_desc, ARRAY_SIZE(ixp2000_io_desc)); - early_serial_setup(&ixp2000_serial_port); /* Set slowport to 8-bit mode. */ ixp2000_reg_write(IXP2000_SLOWPORT_FRM, 1); } + +/************************************************************************* + * Serial port support for IXP2000 + *************************************************************************/ +static struct plat_serial8250_port ixp2000_serial_port[] = { + { + .mapbase = IXP2000_UART_PHYS_BASE, + .membase = (char *)(IXP2000_UART_VIRT_BASE + 3), + .irq = IRQ_IXP2000_UART, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = 50000000, + }, + { }, +}; + +static struct resource ixp2000_uart_resource = { + .start = IXP2000_UART_PHYS_BASE, + .end = IXP2000_UART_PHYS_BASE + 0xffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device ixp2000_serial_device = { + .name = "serial8250", + .id = 0, + .dev = { + .platform_data = ixp2000_serial_port, + }, + .num_resources = 1, + .resource = &ixp2000_uart_resource, +}; + +void __init ixp2000_uart_init(void) +{ + platform_device_register(&ixp2000_serial_device); +} + + /************************************************************************* * Timer-tick functions for IXP2000 *************************************************************************/ @@ -194,8 +224,8 @@ static int ixp2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction ixp2000_timer_irq = { .name = "IXP2000 Timer Tick", - .flags = SA_INTERRUPT, - .handler = ixp2000_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = ixp2000_timer_interrupt, }; void __init ixp2000_init_time(unsigned long tick_rate) diff --git a/arch/arm/mach-ixp2000/enp2611.c b/arch/arm/mach-ixp2000/enp2611.c index f3a291b6a9fb..9aa54de44740 100644 --- a/arch/arm/mach-ixp2000/enp2611.c +++ b/arch/arm/mach-ixp2000/enp2611.c @@ -219,17 +219,20 @@ static struct platform_device *enp2611_devices[] __initdata = { static void __init enp2611_init_machine(void) { platform_add_devices(enp2611_devices, ARRAY_SIZE(enp2611_devices)); + ixp2000_uart_init(); } MACHINE_START(ENP2611, "Radisys ENP-2611 PCI network processor board") - MAINTAINER("Lennert Buytenhek <buytenh@wantstofly.org>") - BOOT_MEM(0x00000000, IXP2000_UART_PHYS_BASE, IXP2000_UART_VIRT_BASE) - BOOT_PARAMS(0x00000100) - MAPIO(ixp2000_map_io) - INITIRQ(ixp2000_init_irq) + /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */ + .phys_ram = 0x00000000, + .phys_io = IXP2000_UART_PHYS_BASE, + .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = ixp2000_map_io, + .init_irq = ixp2000_init_irq, .timer = &enp2611_timer, - INIT_MACHINE(enp2611_init_machine) + .init_machine = enp2611_init_machine, MACHINE_END diff --git a/arch/arm/mach-ixp2000/ixdp2400.c b/arch/arm/mach-ixp2000/ixdp2400.c index df3ff26c8cdd..fd280a93637e 100644 --- a/arch/arm/mach-ixp2000/ixdp2400.c +++ b/arch/arm/mach-ixp2000/ixdp2400.c @@ -168,12 +168,14 @@ void ixdp2400_init_irq(void) } MACHINE_START(IXDP2400, "Intel IXDP2400 Development Platform") - MAINTAINER("MontaVista Software, Inc.") - BOOT_MEM(0x00000000, IXP2000_UART_PHYS_BASE, IXP2000_UART_VIRT_BASE) - BOOT_PARAMS(0x00000100) - MAPIO(ixdp2x00_map_io) - INITIRQ(ixdp2400_init_irq) + /* Maintainer: MontaVista Software, Inc. */ + .phys_ram = 0x00000000, + .phys_io = IXP2000_UART_PHYS_BASE, + .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = ixdp2x00_map_io, + .init_irq = ixdp2400_init_irq, .timer = &ixdp2400_timer, - INIT_MACHINE(ixdp2x00_init_machine) + .init_machine = ixdp2x00_init_machine, MACHINE_END diff --git a/arch/arm/mach-ixp2000/ixdp2800.c b/arch/arm/mach-ixp2000/ixdp2800.c index aec13c7108a9..f9073aa28615 100644 --- a/arch/arm/mach-ixp2000/ixdp2800.c +++ b/arch/arm/mach-ixp2000/ixdp2800.c @@ -42,12 +42,6 @@ #include <asm/mach/flash.h> #include <asm/mach/arch.h> - -void ixdp2400_init_irq(void) -{ - ixdp2x00_init_irq(IXDP2800_CPLD_INT_STAT, IXDP2800_CPLD_INT_MASK, IXDP2400_NR_IRQS); -} - /************************************************************************* * IXDP2800 timer tick *************************************************************************/ @@ -290,12 +284,14 @@ void ixdp2800_init_irq(void) } MACHINE_START(IXDP2800, "Intel IXDP2800 Development Platform") - MAINTAINER("MontaVista Software, Inc.") - BOOT_MEM(0x00000000, IXP2000_UART_PHYS_BASE, IXP2000_UART_VIRT_BASE) - BOOT_PARAMS(0x00000100) - MAPIO(ixdp2x00_map_io) - INITIRQ(ixdp2800_init_irq) + /* Maintainer: MontaVista Software, Inc. */ + .phys_ram = 0x00000000, + .phys_io = IXP2000_UART_PHYS_BASE, + .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = ixdp2x00_map_io, + .init_irq = ixdp2800_init_irq, .timer = &ixdp2800_timer, - INIT_MACHINE(ixdp2x00_init_machine) + .init_machine = ixdp2x00_init_machine, MACHINE_END diff --git a/arch/arm/mach-ixp2000/ixdp2x00.c b/arch/arm/mach-ixp2000/ixdp2x00.c index 5e4380747b53..a43369ad876c 100644 --- a/arch/arm/mach-ixp2000/ixdp2x00.c +++ b/arch/arm/mach-ixp2000/ixdp2x00.c @@ -303,5 +303,6 @@ void __init ixdp2x00_init_machine(void) gpio_line_config(IXDP2X00_GPIO_I2C_ENABLE, GPIO_OUT); platform_add_devices(ixdp2x00_devices, ARRAY_SIZE(ixdp2x00_devices)); + ixp2000_uart_init(); } diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c index e94dace3d412..43447dad1657 100644 --- a/arch/arm/mach-ixp2000/ixdp2x01.c +++ b/arch/arm/mach-ixp2000/ixdp2x01.c @@ -370,30 +370,35 @@ static void __init ixdp2x01_init_machine(void) ((*IXDP2X01_CPLD_FLASH_REG & IXDP2X01_CPLD_FLASH_BANK_MASK) + 1); platform_add_devices(ixdp2x01_devices, ARRAY_SIZE(ixdp2x01_devices)); + ixp2000_uart_init(); } #ifdef CONFIG_ARCH_IXDP2401 MACHINE_START(IXDP2401, "Intel IXDP2401 Development Platform") - MAINTAINER("MontaVista Software, Inc.") - BOOT_MEM(0x00000000, IXP2000_UART_PHYS_BASE, IXP2000_UART_VIRT_BASE) - BOOT_PARAMS(0x00000100) - MAPIO(ixdp2x01_map_io) - INITIRQ(ixdp2x01_init_irq) + /* Maintainer: MontaVista Software, Inc. */ + .phys_ram = 0x00000000, + .phys_io = IXP2000_UART_PHYS_BASE, + .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = ixdp2x01_map_io, + .init_irq = ixdp2x01_init_irq, .timer = &ixdp2x01_timer, - INIT_MACHINE(ixdp2x01_init_machine) + .init_machine = ixdp2x01_init_machine, MACHINE_END #endif #ifdef CONFIG_ARCH_IXDP2801 MACHINE_START(IXDP2801, "Intel IXDP2801 Development Platform") - MAINTAINER("MontaVista Software, Inc.") - BOOT_MEM(0x00000000, IXP2000_UART_PHYS_BASE, IXP2000_UART_VIRT_BASE) - BOOT_PARAMS(0x00000100) - MAPIO(ixdp2x01_map_io) - INITIRQ(ixdp2x01_init_irq) + /* Maintainer: MontaVista Software, Inc. */ + .phys_ram = 0x00000000, + .phys_io = IXP2000_UART_PHYS_BASE, + .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = ixdp2x01_map_io, + .init_irq = ixdp2x01_init_irq, .timer = &ixdp2x01_timer, - INIT_MACHINE(ixdp2x01_init_machine) + .init_machine = ixdp2x01_init_machine, MACHINE_END #endif diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c index aa92e3708838..2b544363c078 100644 --- a/arch/arm/mach-ixp4xx/common-pci.c +++ b/arch/arm/mach-ixp4xx/common-pci.c @@ -453,8 +453,8 @@ int ixp4xx_setup(int nr, struct pci_sys_data *sys) local_write_config(PCI_COMMAND, 2, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); res[0].name = "PCI I/O Space"; - res[0].start = 0x00001000; - res[0].end = 0xffff0000; + res[0].start = 0x00000000; + res[0].end = 0x0000ffff; res[0].flags = IORESOURCE_IO; res[1].name = "PCI Memory Space"; diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index f39e8408488f..04490a9f8f6e 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -298,8 +298,8 @@ static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id, struct pt_regs static struct irqaction ixp4xx_timer_irq = { .name = "IXP4xx Timer Tick", - .flags = SA_INTERRUPT, - .handler = ixp4xx_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = ixp4xx_timer_interrupt, }; static void __init ixp4xx_timer_init(void) diff --git a/arch/arm/mach-ixp4xx/coyote-setup.c b/arch/arm/mach-ixp4xx/coyote-setup.c index 8a05a1227e5f..4ff4393ef0ea 100644 --- a/arch/arm/mach-ixp4xx/coyote-setup.c +++ b/arch/arm/mach-ixp4xx/coyote-setup.c @@ -56,21 +56,24 @@ static struct resource coyote_uart_resource = { .flags = IORESOURCE_MEM, }; -static struct plat_serial8250_port coyote_uart_data = { - .mapbase = IXP4XX_UART2_BASE_PHYS, - .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, - .irq = IRQ_IXP4XX_UART2, - .flags = UPF_BOOT_AUTOCONF, - .iotype = UPIO_MEM, - .regshift = 2, - .uartclk = IXP4XX_UART_XTAL, +static struct plat_serial8250_port coyote_uart_data[] = { + { + .mapbase = IXP4XX_UART2_BASE_PHYS, + .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, + .irq = IRQ_IXP4XX_UART2, + .flags = UPF_BOOT_AUTOCONF, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = IXP4XX_UART_XTAL, + }, + { }, }; static struct platform_device coyote_uart = { .name = "serial8250", .id = 0, .dev = { - .platform_data = &coyote_uart_data, + .platform_data = coyote_uart_data, }, .num_resources = 1, .resource = &coyote_uart_resource, @@ -87,10 +90,10 @@ static void __init coyote_init(void) *IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0; if (machine_is_ixdpg425()) { - coyote_uart_data.membase = + coyote_uart_data[0].membase = (char*)(IXP4XX_UART1_BASE_VIRT + REG_OFFSET); - coyote_uart_data.mapbase = IXP4XX_UART1_BASE_PHYS; - coyote_uart_data.irq = IRQ_IXP4XX_UART1; + coyote_uart_data[0].mapbase = IXP4XX_UART1_BASE_PHYS; + coyote_uart_data[0].irq = IRQ_IXP4XX_UART1; } @@ -100,14 +103,15 @@ static void __init coyote_init(void) #ifdef CONFIG_ARCH_ADI_COYOTE MACHINE_START(ADI_COYOTE, "ADI Engineering Coyote") - MAINTAINER("MontaVista Software, Inc.") - BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS, - IXP4XX_PERIPHERAL_BASE_VIRT) - MAPIO(coyote_map_io) - INITIRQ(ixp4xx_init_irq) + /* Maintainer: MontaVista Software, Inc. */ + .phys_ram = PHYS_OFFSET, + .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, + .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, + .map_io = coyote_map_io, + .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, - BOOT_PARAMS(0x0100) - INIT_MACHINE(coyote_init) + .boot_params = 0x0100, + .init_machine = coyote_init, MACHINE_END #endif @@ -117,14 +121,15 @@ MACHINE_END */ #ifdef CONFIG_MACH_IXDPG425 MACHINE_START(IXDPG425, "Intel IXDPG425") - MAINTAINER("MontaVista Software, Inc.") - BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS, - IXP4XX_PERIPHERAL_BASE_VIRT) - MAPIO(coyote_map_io) - INITIRQ(ixp4xx_init_irq) + /* Maintainer: MontaVista Software, Inc. */ + .phys_ram = PHYS_OFFSET, + .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, + .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, + .map_io = coyote_map_io, + .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, - BOOT_PARAMS(0x0100) - INIT_MACHINE(coyote_init) + .boot_params = 0x0100, + .init_machine = coyote_init, MACHINE_END #endif diff --git a/arch/arm/mach-ixp4xx/gtwx5715-setup.c b/arch/arm/mach-ixp4xx/gtwx5715-setup.c index e77c86efd21d..8ba1cd9406e7 100644 --- a/arch/arm/mach-ixp4xx/gtwx5715-setup.c +++ b/arch/arm/mach-ixp4xx/gtwx5715-setup.c @@ -140,14 +140,15 @@ static void __init gtwx5715_init(void) MACHINE_START(GTWX5715, "Gemtek GTWX5715 (Linksys WRV54G)") - MAINTAINER("George Joseph") - BOOT_MEM(PHYS_OFFSET, IXP4XX_UART2_BASE_PHYS, - IXP4XX_UART2_BASE_VIRT) - MAPIO(gtwx5715_map_io) - INITIRQ(ixp4xx_init_irq) - .timer = &ixp4xx_timer, - BOOT_PARAMS(0x0100) - INIT_MACHINE(gtwx5715_init) + /* Maintainer: George Joseph */ + .phys_ram = PHYS_OFFSET, + .phys_io = IXP4XX_UART2_BASE_PHYS, + .io_pg_offst = ((IXP4XX_UART2_BASE_VIRT) >> 18) & 0xfffc, + .map_io = gtwx5715_map_io, + .init_irq = ixp4xx_init_irq, + .timer = &ixp4xx_timer, + .boot_params = 0x0100, + .init_machine = gtwx5715_init, MACHINE_END diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c index 77346c1f676b..c2ba759e9946 100644 --- a/arch/arm/mach-ixp4xx/ixdp425-setup.c +++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c @@ -95,7 +95,8 @@ static struct plat_serial8250_port ixdp425_uart_data[] = { .iotype = UPIO_MEM, .regshift = 2, .uartclk = IXP4XX_UART_XTAL, - } + }, + { }, }; static struct platform_device ixdp425_uart = { @@ -128,36 +129,39 @@ static void __init ixdp425_init(void) } MACHINE_START(IXDP425, "Intel IXDP425 Development Platform") - MAINTAINER("MontaVista Software, Inc.") - BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS, - IXP4XX_PERIPHERAL_BASE_VIRT) - MAPIO(ixdp425_map_io) - INITIRQ(ixp4xx_init_irq) + /* Maintainer: MontaVista Software, Inc. */ + .phys_ram = PHYS_OFFSET, + .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, + .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, + .map_io = ixdp425_map_io, + .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, - BOOT_PARAMS(0x0100) - INIT_MACHINE(ixdp425_init) + .boot_params = 0x0100, + .init_machine = ixdp425_init, MACHINE_END MACHINE_START(IXDP465, "Intel IXDP465 Development Platform") - MAINTAINER("MontaVista Software, Inc.") - BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS, - IXP4XX_PERIPHERAL_BASE_VIRT) - MAPIO(ixdp425_map_io) - INITIRQ(ixp4xx_init_irq) + /* Maintainer: MontaVista Software, Inc. */ + .phys_ram = PHYS_OFFSET, + .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, + .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, + .map_io = ixdp425_map_io, + .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, - BOOT_PARAMS(0x0100) - INIT_MACHINE(ixdp425_init) + .boot_params = 0x0100, + .init_machine = ixdp425_init, MACHINE_END MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform") - MAINTAINER("MontaVista Software, Inc.") - BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS, - IXP4XX_PERIPHERAL_BASE_VIRT) - MAPIO(ixdp425_map_io) - INITIRQ(ixp4xx_init_irq) + /* Maintainer: MontaVista Software, Inc. */ + .phys_ram = PHYS_OFFSET, + .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, + .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, + .map_io = ixdp425_map_io, + .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, - BOOT_PARAMS(0x0100) - INIT_MACHINE(ixdp425_init) + .boot_params = 0x0100, + .init_machine = ixdp425_init, MACHINE_END /* @@ -168,14 +172,15 @@ MACHINE_END */ #ifdef CONFIG_ARCH_AVILA MACHINE_START(AVILA, "Gateworks Avila Network Platform") - MAINTAINER("Deepak Saxena <dsaxena@plexity.net>") - BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS, - IXP4XX_PERIPHERAL_BASE_VIRT) - MAPIO(ixdp425_map_io) - INITIRQ(ixp4xx_init_irq) + /* Maintainer: Deepak Saxena <dsaxena@plexity.net> */ + .phys_ram = PHYS_OFFSET, + .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, + .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, + .map_io = ixdp425_map_io, + .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, - BOOT_PARAMS(0x0100) - INIT_MACHINE(ixdp425_init) + .boot_params = 0x0100, + .init_machine = ixdp425_init, MACHINE_END #endif diff --git a/arch/arm/mach-l7200/core.c b/arch/arm/mach-l7200/core.c index 606ca95f8217..2a7fee2a7635 100644 --- a/arch/arm/mach-l7200/core.c +++ b/arch/arm/mach-l7200/core.c @@ -81,9 +81,11 @@ static void __init l7200_map_io(void) } MACHINE_START(L7200, "LinkUp Systems L7200") - MAINTAINER("Steve Hill / Scott McConnell") - BOOT_MEM(0xf0000000, 0x80040000, 0xd0000000) - MAPIO(l7200_map_io) - INITIRQ(l7200_init_irq) + /* Maintainer: Steve Hill / Scott McConnell */ + .phys_ram = 0xf0000000, + .phys_io = 0x80040000, + .io_pg_offst = ((0xd0000000) >> 18) & 0xfffc, + .map_io = l7200_map_io, + .init_irq = l7200_init_irq, MACHINE_END diff --git a/arch/arm/mach-lh7a40x/arch-kev7a400.c b/arch/arm/mach-lh7a40x/arch-kev7a400.c index be5d17fe9dcb..cb3dcd3bd00a 100644 --- a/arch/arm/mach-lh7a40x/arch-kev7a400.c +++ b/arch/arm/mach-lh7a40x/arch-kev7a400.c @@ -102,10 +102,12 @@ void __init lh7a40x_init_board_irq (void) } MACHINE_START (KEV7A400, "Sharp KEV7a400") - MAINTAINER ("Marc Singer") - BOOT_MEM (0xc0000000, 0x80000000, io_p2v (0x80000000)) - BOOT_PARAMS (0xc0000100) - MAPIO (kev7a400_map_io) - INITIRQ (lh7a400_init_irq) + /* Maintainer: Marc Singer */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = kev7a400_map_io, + .init_irq = lh7a400_init_irq, .timer = &lh7a40x_timer, MACHINE_END diff --git a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c index c823447a150f..6eb61a17c63b 100644 --- a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c +++ b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c @@ -260,13 +260,15 @@ lpd7a400_map_io(void) #ifdef CONFIG_MACH_LPD7A400 MACHINE_START (LPD7A400, "Logic Product Development LPD7A400-10") - MAINTAINER ("Marc Singer") - BOOT_MEM (0xc0000000, 0x80000000, io_p2v (0x80000000)) - BOOT_PARAMS (0xc0000100) - MAPIO (lpd7a400_map_io) - INITIRQ (lh7a400_init_irq) + /* Maintainer: Marc Singer */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = lpd7a400_map_io, + .init_irq = lh7a400_init_irq, .timer = &lh7a40x_timer, - INIT_MACHINE (lpd7a40x_init) + .init_machine = lpd7a40x_init, MACHINE_END #endif @@ -274,13 +276,15 @@ MACHINE_END #ifdef CONFIG_MACH_LPD7A404 MACHINE_START (LPD7A404, "Logic Product Development LPD7A404-10") - MAINTAINER ("Marc Singer") - BOOT_MEM (0xc0000000, 0x80000000, io_p2v (0x80000000)) - BOOT_PARAMS (0xc0000100) - MAPIO (lpd7a400_map_io) - INITIRQ (lh7a404_init_irq) + /* Maintainer: Marc Singer */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = lpd7a400_map_io, + .init_irq = lh7a404_init_irq, .timer = &lh7a40x_timer, - INIT_MACHINE (lpd7a40x_init) + .init_machine = lpd7a40x_init, MACHINE_END #endif diff --git a/arch/arm/mach-lh7a40x/time.c b/arch/arm/mach-lh7a40x/time.c index 51e1c814b400..be377e331f25 100644 --- a/arch/arm/mach-lh7a40x/time.c +++ b/arch/arm/mach-lh7a40x/time.c @@ -53,8 +53,8 @@ lh7a40x_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction lh7a40x_timer_irq = { .name = "LHA740x Timer Tick", - .flags = SA_INTERRUPT, - .handler = lh7a40x_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = lh7a40x_timer_interrupt, }; static void __init lh7a40x_timer_init(void) diff --git a/arch/arm/mach-omap/Kconfig b/arch/arm/mach-omap/Kconfig deleted file mode 100644 index 9e42efa66b2b..000000000000 --- a/arch/arm/mach-omap/Kconfig +++ /dev/null @@ -1,221 +0,0 @@ -if ARCH_OMAP - -menu "TI OMAP Implementations" - -comment "OMAP Core Type" - -config ARCH_OMAP730 - depends on ARCH_OMAP - bool "OMAP730 Based System" - select ARCH_OMAP_OTG - -config ARCH_OMAP1510 - depends on ARCH_OMAP - default y - bool "OMAP1510 Based System" - -config ARCH_OMAP16XX - depends on ARCH_OMAP - bool "OMAP16XX Based System" - select ARCH_OMAP_OTG - -config ARCH_OMAP_OTG - bool - -comment "OMAP Board Type" - -config MACH_OMAP_INNOVATOR - bool "TI Innovator" - depends on ARCH_OMAP1510 || ARCH_OMAP16XX - help - TI OMAP 1510 or 1610 Innovator board support. Say Y here if you - have such a board. - -config MACH_OMAP_H2 - bool "TI H2 Support" - depends on ARCH_OMAP16XX - help - TI OMAP 1610/1611B H2 board support. Say Y here if you have such - a board. - -config MACH_OMAP_H3 - bool "TI H3 Support" - depends on ARCH_OMAP16XX - help - TI OMAP 1710 H3 board support. Say Y here if you have such - a board. - -config MACH_OMAP_H4 - bool "TI H4 Support" - depends on ARCH_OMAP16XX - help - TI OMAP 1610 H4 board support. Say Y here if you have such - a board. - -config MACH_OMAP_OSK - bool "TI OSK Support" - depends on ARCH_OMAP16XX - help - TI OMAP 5912 OSK (OMAP Starter Kit) board support. Say Y here - if you have such a board. - -config MACH_OMAP_PERSEUS2 - bool "TI Perseus2" - depends on ARCH_OMAP730 - help - Support for TI OMAP 730 Perseus2 board. Say Y here if you have such - a board. - -config MACH_VOICEBLUE - bool "Voiceblue" - depends on ARCH_OMAP1510 - help - Support for Voiceblue GSM/VoIP gateway. Say Y here if you have such - board. - -config MACH_NETSTAR - bool "NetStar" - depends on ARCH_OMAP1510 - help - Support for NetStar PBX. Say Y here if you have such a board. - -config MACH_OMAP_GENERIC - bool "Generic OMAP board" - depends on ARCH_OMAP1510 || ARCH_OMAP16XX - help - Support for generic OMAP-1510, 1610 or 1710 board with - no FPGA. Can be used as template for porting Linux to - custom OMAP boards. Say Y here if you have a custom - board. - -comment "OMAP Feature Selections" - -#config OMAP_BOOT_TAG -# bool "OMAP bootloader information passing" -# depends on ARCH_OMAP -# default n -# help -# Say Y, if you have a bootloader which passes information -# about your board and its peripheral configuration. - -config OMAP_MUX - bool "OMAP multiplexing support" - depends on ARCH_OMAP - default y - help - Pin multiplexing support for OMAP boards. If your bootloader - sets the multiplexing correctly, say N. Otherwise, or if unsure, - say Y. - -config OMAP_MUX_DEBUG - bool "Multiplexing debug output" - depends on OMAP_MUX - default n - help - Makes the multiplexing functions print out a lot of debug info. - This is useful if you want to find out the correct values of the - multiplexing registers. - -config OMAP_MUX_WARNINGS - bool "Warn about pins the bootloader didn't set up" - depends on OMAP_MUX - default y - help - Choose Y here to warn whenever driver initialization logic needs - to change the pin multiplexing setup. When there are no warnings - printed, it's safe to deselect OMAP_MUX for your product. - -choice - prompt "System timer" - default OMAP_MPU_TIMER - -config OMAP_MPU_TIMER - bool "Use mpu timer" - help - Select this option if you want to use the OMAP mpu timer. This - timer provides more intra-tick resolution than the 32KHz timer, - but consumes more power. - -config OMAP_32K_TIMER - bool "Use 32KHz timer" - depends on ARCH_OMAP16XX - help - Select this option if you want to enable the OMAP 32KHz timer. - This timer saves power compared to the OMAP_MPU_TIMER, and has - support for no tick during idle. The 32KHz timer provides less - intra-tick resolution than OMAP_MPU_TIMER. The 32KHz timer is - currently only available for OMAP-16xx. - -endchoice - -config OMAP_32K_TIMER_HZ - int "Kernel internal timer frequency for 32KHz timer" - range 32 1024 - depends on OMAP_32K_TIMER - default "128" - help - Kernel internal timer frequency should be a divisor of 32768, - such as 64 or 128. - -choice - prompt "Low-level debug console UART" - depends on ARCH_OMAP - default OMAP_LL_DEBUG_UART1 - -config OMAP_LL_DEBUG_UART1 - bool "UART1" - -config OMAP_LL_DEBUG_UART2 - bool "UART2" - -config OMAP_LL_DEBUG_UART3 - bool "UART3" - -endchoice - -config OMAP_ARM_195MHZ - bool "OMAP ARM 195 MHz CPU" - depends on ARCH_OMAP730 - help - Enable 195MHz clock for OMAP CPU. If unsure, say N. - -config OMAP_ARM_192MHZ - bool "OMAP ARM 192 MHz CPU" - depends on ARCH_OMAP16XX - help - Enable 192MHz clock for OMAP CPU. If unsure, say N. - -config OMAP_ARM_182MHZ - bool "OMAP ARM 182 MHz CPU" - depends on ARCH_OMAP730 - help - Enable 182MHz clock for OMAP CPU. If unsure, say N. - -config OMAP_ARM_168MHZ - bool "OMAP ARM 168 MHz CPU" - depends on ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730 - help - Enable 168MHz clock for OMAP CPU. If unsure, say N. - -config OMAP_ARM_120MHZ - bool "OMAP ARM 120 MHz CPU" - depends on ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730 - help - Enable 120MHz clock for OMAP CPU. If unsure, say N. - -config OMAP_ARM_60MHZ - bool "OMAP ARM 60 MHz CPU" - depends on ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730 - default y - help - Enable 60MHz clock for OMAP CPU. If unsure, say Y. - -config OMAP_ARM_30MHZ - bool "OMAP ARM 30 MHz CPU" - depends on ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730 - help - Enable 30MHz clock for OMAP CPU. If unsure, say N. - -endmenu - -endif diff --git a/arch/arm/mach-omap/Makefile b/arch/arm/mach-omap/Makefile deleted file mode 100644 index 4cafb11d2c02..000000000000 --- a/arch/arm/mach-omap/Makefile +++ /dev/null @@ -1,40 +0,0 @@ -# -# Makefile for the linux kernel. -# - -# Common support -obj-y := common.o time.o irq.o dma.o clock.o mux.o gpio.o mcbsp.o usb.o -obj-m := -obj-n := -obj- := -led-y := leds.o - -# Specific board support -obj-$(CONFIG_MACH_OMAP_H2) += board-h2.o -obj-$(CONFIG_MACH_OMAP_INNOVATOR) += board-innovator.o -obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o -obj-$(CONFIG_MACH_OMAP_PERSEUS2) += board-perseus2.o -obj-$(CONFIG_MACH_OMAP_OSK) += board-osk.o -obj-$(CONFIG_MACH_OMAP_H3) += board-h3.o -obj-$(CONFIG_MACH_VOICEBLUE) += board-voiceblue.o -obj-$(CONFIG_MACH_NETSTAR) += board-netstar.o - -# OCPI interconnect support for 1710, 1610 and 5912 -obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o - -# LEDs support -led-$(CONFIG_MACH_OMAP_H2) += leds-h2p2-debug.o -led-$(CONFIG_MACH_OMAP_INNOVATOR) += leds-innovator.o -led-$(CONFIG_MACH_OMAP_PERSEUS2) += leds-h2p2-debug.o -obj-$(CONFIG_LEDS) += $(led-y) - -# Power Management -obj-$(CONFIG_PM) += pm.o sleep.o - -ifeq ($(CONFIG_ARCH_OMAP1510),y) -# Innovator-1510 FPGA -obj-$(CONFIG_MACH_OMAP_INNOVATOR) += fpga.o -endif - -# kgdb support -obj-$(CONFIG_KGDB_SERIAL) += kgdb-serial.o diff --git a/arch/arm/mach-omap/common.c b/arch/arm/mach-omap/common.c deleted file mode 100644 index 265cde48586f..000000000000 --- a/arch/arm/mach-omap/common.c +++ /dev/null @@ -1,549 +0,0 @@ -/* - * linux/arch/arm/mach-omap/common.c - * - * Code common to all OMAP machines. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/config.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/pm.h> -#include <linux/console.h> -#include <linux/serial.h> -#include <linux/tty.h> -#include <linux/serial_8250.h> -#include <linux/serial_reg.h> - -#include <asm/hardware.h> -#include <asm/system.h> -#include <asm/pgtable.h> -#include <asm/mach/map.h> -#include <asm/hardware/clock.h> -#include <asm/io.h> -#include <asm/mach-types.h> - -#include <asm/arch/board.h> -#include <asm/arch/mux.h> -#include <asm/arch/fpga.h> - -#include "clock.h" - -#define DEBUG 1 - -struct omap_id { - u16 jtag_id; /* Used to determine OMAP type */ - u8 die_rev; /* Processor revision */ - u32 omap_id; /* OMAP revision */ - u32 type; /* Cpu id bits [31:08], cpu class bits [07:00] */ -}; - -/* Register values to detect the OMAP version */ -static struct omap_id omap_ids[] __initdata = { - { .jtag_id = 0x355f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300100}, - { .jtag_id = 0xb55f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300300}, - { .jtag_id = 0xb470, .die_rev = 0x0, .omap_id = 0x03310100, .type = 0x15100000}, - { .jtag_id = 0xb576, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x16100000}, - { .jtag_id = 0xb576, .die_rev = 0x2, .omap_id = 0x03320100, .type = 0x16110000}, - { .jtag_id = 0xb576, .die_rev = 0x3, .omap_id = 0x03320100, .type = 0x16100c00}, - { .jtag_id = 0xb576, .die_rev = 0x0, .omap_id = 0x03320200, .type = 0x16100d00}, - { .jtag_id = 0xb613, .die_rev = 0x0, .omap_id = 0x03320300, .type = 0x1610ef00}, - { .jtag_id = 0xb613, .die_rev = 0x0, .omap_id = 0x03320300, .type = 0x1610ef00}, - { .jtag_id = 0xb576, .die_rev = 0x1, .omap_id = 0x03320100, .type = 0x16110000}, - { .jtag_id = 0xb58c, .die_rev = 0x2, .omap_id = 0x03320200, .type = 0x16110b00}, - { .jtag_id = 0xb58c, .die_rev = 0x3, .omap_id = 0x03320200, .type = 0x16110c00}, - { .jtag_id = 0xb65f, .die_rev = 0x0, .omap_id = 0x03320400, .type = 0x16212300}, - { .jtag_id = 0xb65f, .die_rev = 0x1, .omap_id = 0x03320400, .type = 0x16212300}, - { .jtag_id = 0xb65f, .die_rev = 0x1, .omap_id = 0x03320500, .type = 0x16212300}, - { .jtag_id = 0xb5f7, .die_rev = 0x0, .omap_id = 0x03330000, .type = 0x17100000}, - { .jtag_id = 0xb5f7, .die_rev = 0x1, .omap_id = 0x03330100, .type = 0x17100000}, - { .jtag_id = 0xb5f7, .die_rev = 0x2, .omap_id = 0x03330100, .type = 0x17100000}, -}; - -/* - * Get OMAP type from PROD_ID. - * 1710 has the PROD_ID in bits 15:00, not in 16:01 as documented in TRM. - * 1510 PROD_ID is empty, and 1610 PROD_ID does not make sense. - * Undocumented register in TEST BLOCK is used as fallback; This seems to - * work on 1510, 1610 & 1710. The official way hopefully will work in future - * processors. - */ -static u16 __init omap_get_jtag_id(void) -{ - u32 prod_id, omap_id; - - prod_id = omap_readl(OMAP_PRODUCTION_ID_1); - omap_id = omap_readl(OMAP32_ID_1); - - /* Check for unusable OMAP_PRODUCTION_ID_1 on 1611B/5912 and 730 */ - if (((prod_id >> 20) == 0) || (prod_id == omap_id)) - prod_id = 0; - else - prod_id &= 0xffff; - - if (prod_id) - return prod_id; - - /* Use OMAP32_ID_1 as fallback */ - prod_id = ((omap_id >> 12) & 0xffff); - - return prod_id; -} - -/* - * Get OMAP revision from DIE_REV. - * Early 1710 processors may have broken OMAP_DIE_ID, it contains PROD_ID. - * Undocumented register in the TEST BLOCK is used as fallback. - * REVISIT: This does not seem to work on 1510 - */ -static u8 __init omap_get_die_rev(void) -{ - u32 die_rev; - - die_rev = omap_readl(OMAP_DIE_ID_1); - - /* Check for broken OMAP_DIE_ID on early 1710 */ - if (((die_rev >> 12) & 0xffff) == omap_get_jtag_id()) - die_rev = 0; - - die_rev = (die_rev >> 17) & 0xf; - if (die_rev) - return die_rev; - - die_rev = (omap_readl(OMAP32_ID_1) >> 28) & 0xf; - - return die_rev; -} - -static void __init omap_check_revision(void) -{ - int i; - u16 jtag_id; - u8 die_rev; - u32 omap_id; - u8 cpu_type; - - jtag_id = omap_get_jtag_id(); - die_rev = omap_get_die_rev(); - omap_id = omap_readl(OMAP32_ID_0); - -#ifdef DEBUG - printk("OMAP_DIE_ID_0: 0x%08x\n", omap_readl(OMAP_DIE_ID_0)); - printk("OMAP_DIE_ID_1: 0x%08x DIE_REV: %i\n", - omap_readl(OMAP_DIE_ID_1), - (omap_readl(OMAP_DIE_ID_1) >> 17) & 0xf); - printk("OMAP_PRODUCTION_ID_0: 0x%08x\n", omap_readl(OMAP_PRODUCTION_ID_0)); - printk("OMAP_PRODUCTION_ID_1: 0x%08x JTAG_ID: 0x%04x\n", - omap_readl(OMAP_PRODUCTION_ID_1), - omap_readl(OMAP_PRODUCTION_ID_1) & 0xffff); - printk("OMAP32_ID_0: 0x%08x\n", omap_readl(OMAP32_ID_0)); - printk("OMAP32_ID_1: 0x%08x\n", omap_readl(OMAP32_ID_1)); - printk("JTAG_ID: 0x%04x DIE_REV: %i\n", jtag_id, die_rev); -#endif - - system_serial_high = omap_readl(OMAP_DIE_ID_0); - system_serial_low = omap_readl(OMAP_DIE_ID_1); - - /* First check only the major version in a safe way */ - for (i = 0; i < ARRAY_SIZE(omap_ids); i++) { - if (jtag_id == (omap_ids[i].jtag_id)) { - system_rev = omap_ids[i].type; - break; - } - } - - /* Check if we can find the die revision */ - for (i = 0; i < ARRAY_SIZE(omap_ids); i++) { - if (jtag_id == omap_ids[i].jtag_id && die_rev == omap_ids[i].die_rev) { - system_rev = omap_ids[i].type; - break; - } - } - - /* Finally check also the omap_id */ - for (i = 0; i < ARRAY_SIZE(omap_ids); i++) { - if (jtag_id == omap_ids[i].jtag_id - && die_rev == omap_ids[i].die_rev - && omap_id == omap_ids[i].omap_id) { - system_rev = omap_ids[i].type; - break; - } - } - - /* Add the cpu class info (7xx, 15xx, 16xx, 24xx) */ - cpu_type = system_rev >> 24; - - switch (cpu_type) { - case 0x07: - system_rev |= 0x07; - break; - case 0x15: - system_rev |= 0x15; - break; - case 0x16: - case 0x17: - system_rev |= 0x16; - break; - case 0x24: - system_rev |= 0x24; - break; - default: - printk("Unknown OMAP cpu type: 0x%02x\n", cpu_type); - } - - printk("OMAP%04x", system_rev >> 16); - if ((system_rev >> 8) & 0xff) - printk("%x", (system_rev >> 8) & 0xff); - printk(" revision %i handled as %02xxx id: %08x%08x\n", - die_rev, system_rev & 0xff, system_serial_low, - system_serial_high); -} - -/* - * ---------------------------------------------------------------------------- - * OMAP I/O mapping - * - * The machine specific code may provide the extra mapping besides the - * default mapping provided here. - * ---------------------------------------------------------------------------- - */ - -static struct map_desc omap_io_desc[] __initdata = { - { IO_VIRT, IO_PHYS, IO_SIZE, MT_DEVICE }, -}; - -#ifdef CONFIG_ARCH_OMAP730 -static struct map_desc omap730_io_desc[] __initdata = { - { OMAP730_DSP_BASE, OMAP730_DSP_START, OMAP730_DSP_SIZE, MT_DEVICE }, - { OMAP730_DSPREG_BASE, OMAP730_DSPREG_START, OMAP730_DSPREG_SIZE, MT_DEVICE }, - { OMAP730_SRAM_BASE, OMAP730_SRAM_START, OMAP730_SRAM_SIZE, MT_DEVICE } -}; -#endif - -#ifdef CONFIG_ARCH_OMAP1510 -static struct map_desc omap1510_io_desc[] __initdata = { - { OMAP1510_DSP_BASE, OMAP1510_DSP_START, OMAP1510_DSP_SIZE, MT_DEVICE }, - { OMAP1510_DSPREG_BASE, OMAP1510_DSPREG_START, OMAP1510_DSPREG_SIZE, MT_DEVICE }, - { OMAP1510_SRAM_BASE, OMAP1510_SRAM_START, OMAP1510_SRAM_SIZE, MT_DEVICE } -}; -#endif - -#if defined(CONFIG_ARCH_OMAP16XX) -static struct map_desc omap1610_io_desc[] __initdata = { - { OMAP16XX_DSP_BASE, OMAP16XX_DSP_START, OMAP16XX_DSP_SIZE, MT_DEVICE }, - { OMAP16XX_DSPREG_BASE, OMAP16XX_DSPREG_START, OMAP16XX_DSPREG_SIZE, MT_DEVICE }, - { OMAP16XX_SRAM_BASE, OMAP16XX_SRAM_START, OMAP1610_SRAM_SIZE, MT_DEVICE } -}; - -static struct map_desc omap5912_io_desc[] __initdata = { - { OMAP16XX_DSP_BASE, OMAP16XX_DSP_START, OMAP16XX_DSP_SIZE, MT_DEVICE }, - { OMAP16XX_DSPREG_BASE, OMAP16XX_DSPREG_START, OMAP16XX_DSPREG_SIZE, MT_DEVICE }, -/* - * The OMAP5912 has 250kByte internal SRAM. Because the mapping is baseed on page - * size (4kByte), it seems that the last 2kByte (=0x800) of the 250kByte are not mapped. - * Add additional 2kByte (0x800) so that the last page is mapped and the last 2kByte - * can be used. - */ - { OMAP16XX_SRAM_BASE, OMAP16XX_SRAM_START, OMAP5912_SRAM_SIZE + 0x800, MT_DEVICE } -}; -#endif - -static int initialized = 0; - -static void __init _omap_map_io(void) -{ - initialized = 1; - - /* We have to initialize the IO space mapping before we can run - * cpu_is_omapxxx() macros. */ - iotable_init(omap_io_desc, ARRAY_SIZE(omap_io_desc)); - omap_check_revision(); - -#ifdef CONFIG_ARCH_OMAP730 - if (cpu_is_omap730()) { - iotable_init(omap730_io_desc, ARRAY_SIZE(omap730_io_desc)); - } -#endif -#ifdef CONFIG_ARCH_OMAP1510 - if (cpu_is_omap1510()) { - iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc)); - } -#endif -#if defined(CONFIG_ARCH_OMAP16XX) - if (cpu_is_omap1610() || cpu_is_omap1710()) { - iotable_init(omap1610_io_desc, ARRAY_SIZE(omap1610_io_desc)); - } - if (cpu_is_omap5912()) { - iotable_init(omap5912_io_desc, ARRAY_SIZE(omap5912_io_desc)); - } -#endif - - /* REVISIT: Refer to OMAP5910 Errata, Advisory SYS_1: "Timeout Abort - * on a Posted Write in the TIPB Bridge". - */ - omap_writew(0x0, MPU_PUBLIC_TIPB_CNTL); - omap_writew(0x0, MPU_PRIVATE_TIPB_CNTL); - - /* Must init clocks early to assure that timer interrupt works - */ - clk_init(); -} - -/* - * This should only get called from board specific init - */ -void omap_map_io(void) -{ - if (!initialized) - _omap_map_io(); -} - -static inline unsigned int omap_serial_in(struct plat_serial8250_port *up, - int offset) -{ - offset <<= up->regshift; - return (unsigned int)__raw_readb(up->membase + offset); -} - -static inline void omap_serial_outp(struct plat_serial8250_port *p, int offset, - int value) -{ - offset <<= p->regshift; - __raw_writeb(value, p->membase + offset); -} - -/* - * Internal UARTs need to be initialized for the 8250 autoconfig to work - * properly. Note that the TX watermark initialization may not be needed - * once the 8250.c watermark handling code is merged. - */ -static void __init omap_serial_reset(struct plat_serial8250_port *p) -{ - omap_serial_outp(p, UART_OMAP_MDR1, 0x07); /* disable UART */ - omap_serial_outp(p, UART_OMAP_SCR, 0x08); /* TX watermark */ - omap_serial_outp(p, UART_OMAP_MDR1, 0x00); /* enable UART */ - - if (!cpu_is_omap1510()) { - omap_serial_outp(p, UART_OMAP_SYSC, 0x01); - while (!(omap_serial_in(p, UART_OMAP_SYSC) & 0x01)); - } -} - -static struct plat_serial8250_port serial_platform_data[] = { - { - .membase = (char*)IO_ADDRESS(OMAP_UART1_BASE), - .mapbase = (unsigned long)OMAP_UART1_BASE, - .irq = INT_UART1, - .flags = UPF_BOOT_AUTOCONF, - .iotype = UPIO_MEM, - .regshift = 2, - .uartclk = OMAP16XX_BASE_BAUD * 16, - }, - { - .membase = (char*)IO_ADDRESS(OMAP_UART2_BASE), - .mapbase = (unsigned long)OMAP_UART2_BASE, - .irq = INT_UART2, - .flags = UPF_BOOT_AUTOCONF, - .iotype = UPIO_MEM, - .regshift = 2, - .uartclk = OMAP16XX_BASE_BAUD * 16, - }, - { - .membase = (char*)IO_ADDRESS(OMAP_UART3_BASE), - .mapbase = (unsigned long)OMAP_UART3_BASE, - .irq = INT_UART3, - .flags = UPF_BOOT_AUTOCONF, - .iotype = UPIO_MEM, - .regshift = 2, - .uartclk = OMAP16XX_BASE_BAUD * 16, - }, - { }, -}; - -static struct platform_device serial_device = { - .name = "serial8250", - .id = 0, - .dev = { - .platform_data = serial_platform_data, - }, -}; - -/* - * Note that on Innovator-1510 UART2 pins conflict with USB2. - * By default UART2 does not work on Innovator-1510 if you have - * USB OHCI enabled. To use UART2, you must disable USB2 first. - */ -void __init omap_serial_init(int ports[OMAP_MAX_NR_PORTS]) -{ - int i; - - if (cpu_is_omap730()) { - serial_platform_data[0].regshift = 0; - serial_platform_data[1].regshift = 0; - serial_platform_data[0].irq = INT_730_UART_MODEM_1; - serial_platform_data[1].irq = INT_730_UART_MODEM_IRDA_2; - } - - if (cpu_is_omap1510()) { - serial_platform_data[0].uartclk = OMAP1510_BASE_BAUD * 16; - serial_platform_data[1].uartclk = OMAP1510_BASE_BAUD * 16; - serial_platform_data[2].uartclk = OMAP1510_BASE_BAUD * 16; - } - - for (i = 0; i < OMAP_MAX_NR_PORTS; i++) { - unsigned char reg; - - if (ports[i] == 0) { - serial_platform_data[i].membase = 0; - serial_platform_data[i].mapbase = 0; - continue; - } - - switch (i) { - case 0: - if (cpu_is_omap1510()) { - omap_cfg_reg(UART1_TX); - omap_cfg_reg(UART1_RTS); - if (machine_is_omap_innovator()) { - reg = fpga_read(OMAP1510_FPGA_POWER); - reg |= OMAP1510_FPGA_PCR_COM1_EN; - fpga_write(reg, OMAP1510_FPGA_POWER); - udelay(10); - } - } - break; - case 1: - if (cpu_is_omap1510()) { - omap_cfg_reg(UART2_TX); - omap_cfg_reg(UART2_RTS); - if (machine_is_omap_innovator()) { - reg = fpga_read(OMAP1510_FPGA_POWER); - reg |= OMAP1510_FPGA_PCR_COM2_EN; - fpga_write(reg, OMAP1510_FPGA_POWER); - udelay(10); - } - } - break; - case 2: - if (cpu_is_omap1510()) { - omap_cfg_reg(UART3_TX); - omap_cfg_reg(UART3_RX); - } - if (cpu_is_omap1710()) { - clk_enable(clk_get(0, "uart3_ck")); - } - break; - } - omap_serial_reset(&serial_platform_data[i]); - } -} - -static int __init omap_init(void) -{ - return platform_device_register(&serial_device); -} -arch_initcall(omap_init); - -#define NO_LENGTH_CHECK 0xffffffff - -extern int omap_bootloader_tag_len; -extern u8 omap_bootloader_tag[]; - -struct omap_board_config_kernel *omap_board_config; -int omap_board_config_size = 0; - -static const void *get_config(u16 tag, size_t len, int skip, size_t *len_out) -{ - struct omap_board_config_kernel *kinfo = NULL; - int i; - -#ifdef CONFIG_OMAP_BOOT_TAG - struct omap_board_config_entry *info = NULL; - - if (omap_bootloader_tag_len > 4) - info = (struct omap_board_config_entry *) omap_bootloader_tag; - while (info != NULL) { - u8 *next; - - if (info->tag == tag) { - if (skip == 0) - break; - skip--; - } - - if ((info->len & 0x03) != 0) { - /* We bail out to avoid an alignment fault */ - printk(KERN_ERR "OMAP peripheral config: Length (%d) not word-aligned (tag %04x)\n", - info->len, info->tag); - return NULL; - } - next = (u8 *) info + sizeof(*info) + info->len; - if (next >= omap_bootloader_tag + omap_bootloader_tag_len) - info = NULL; - else - info = (struct omap_board_config_entry *) next; - } - if (info != NULL) { - /* Check the length as a lame attempt to check for - * binary inconsistancy. */ - if (len != NO_LENGTH_CHECK) { - /* Word-align len */ - if (len & 0x03) - len = (len + 3) & ~0x03; - if (info->len != len) { - printk(KERN_ERR "OMAP peripheral config: Length mismatch with tag %x (want %d, got %d)\n", - tag, len, info->len); - return NULL; - } - } - if (len_out != NULL) - *len_out = info->len; - return info->data; - } -#endif - /* Try to find the config from the board-specific structures - * in the kernel. */ - for (i = 0; i < omap_board_config_size; i++) { - if (omap_board_config[i].tag == tag) { - kinfo = &omap_board_config[i]; - break; - } - } - if (kinfo == NULL) - return NULL; - return kinfo->data; -} - -const void *__omap_get_config(u16 tag, size_t len, int nr) -{ - return get_config(tag, len, nr, NULL); -} -EXPORT_SYMBOL(__omap_get_config); - -const void *omap_get_var_config(u16 tag, size_t *len) -{ - return get_config(tag, NO_LENGTH_CHECK, 0, len); -} -EXPORT_SYMBOL(omap_get_var_config); - -static int __init omap_add_serial_console(void) -{ - const struct omap_uart_config *info; - - info = omap_get_config(OMAP_TAG_UART, struct omap_uart_config); - if (info != NULL && info->console_uart) { - static char speed[11], *opt = NULL; - - if (info->console_speed) { - snprintf(speed, sizeof(speed), "%u", info->console_speed); - opt = speed; - } - return add_preferred_console("ttyS", info->console_uart - 1, opt); - } - return 0; -} -console_initcall(omap_add_serial_console); diff --git a/arch/arm/mach-omap/common.h b/arch/arm/mach-omap/common.h deleted file mode 100644 index 9f62858c0df4..000000000000 --- a/arch/arm/mach-omap/common.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * linux/arch/arm/mach-omap/common.h - * - * Header for code common to all OMAP machines. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __ARCH_ARM_MACH_OMAP_COMMON_H -#define __ARCH_ARM_MACH_OMAP_COMMON_H - -struct sys_timer; - -extern void omap_map_io(void); -extern struct sys_timer omap_timer; -extern void omap_serial_init(int ports[]); - -#endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */ diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig new file mode 100644 index 000000000000..7408ac94f771 --- /dev/null +++ b/arch/arm/mach-omap1/Kconfig @@ -0,0 +1,144 @@ +comment "OMAP Core Type" + depends on ARCH_OMAP1 + +config ARCH_OMAP730 + depends on ARCH_OMAP1 + bool "OMAP730 Based System" + select ARCH_OMAP_OTG + +config ARCH_OMAP1510 + depends on ARCH_OMAP1 + default y + bool "OMAP1510 Based System" + +config ARCH_OMAP16XX + depends on ARCH_OMAP1 + bool "OMAP16xx Based System" + select ARCH_OMAP_OTG + +comment "OMAP Board Type" + depends on ARCH_OMAP1 + +config MACH_OMAP_INNOVATOR + bool "TI Innovator" + depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX) + help + TI OMAP 1510 or 1610 Innovator board support. Say Y here if you + have such a board. + +config MACH_OMAP_H2 + bool "TI H2 Support" + depends on ARCH_OMAP1 && ARCH_OMAP16XX + help + TI OMAP 1610/1611B H2 board support. Say Y here if you have such + a board. + +config MACH_OMAP_H3 + bool "TI H3 Support" + depends on ARCH_OMAP1 && ARCH_OMAP16XX + help + TI OMAP 1710 H3 board support. Say Y here if you have such + a board. + +config MACH_OMAP_OSK + bool "TI OSK Support" + depends on ARCH_OMAP1 && ARCH_OMAP16XX + help + TI OMAP 5912 OSK (OMAP Starter Kit) board support. Say Y here + if you have such a board. + +config MACH_OMAP_PERSEUS2 + bool "TI Perseus2" + depends on ARCH_OMAP1 && ARCH_OMAP730 + help + Support for TI OMAP 730 Perseus2 board. Say Y here if you have such + a board. + +config MACH_VOICEBLUE + bool "Voiceblue" + depends on ARCH_OMAP1 && ARCH_OMAP1510 + help + Support for Voiceblue GSM/VoIP gateway. Say Y here if you have + such a board. + +config MACH_NETSTAR + bool "NetStar" + depends on ARCH_OMAP1 && ARCH_OMAP1510 + help + Support for NetStar PBX. Say Y here if you have such a board. + +config MACH_OMAP_GENERIC + bool "Generic OMAP board" + depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX) + help + Support for generic OMAP-1510, 1610 or 1710 board with + no FPGA. Can be used as template for porting Linux to + custom OMAP boards. Say Y here if you have a custom + board. + +comment "OMAP CPU Speed" + depends on ARCH_OMAP1 + +config OMAP_CLOCKS_SET_BY_BOOTLOADER + bool "OMAP clocks set by bootloader" + depends on ARCH_OMAP1 + help + Enable this option to prevent the kernel from overriding the clock + frequencies programmed by bootloader for MPU, DSP, MMUs, TC, + internal LCD controller and MPU peripherals. + +config OMAP_ARM_216MHZ + bool "OMAP ARM 216 MHz CPU (1710 only)" + depends on ARCH_OMAP1 && ARCH_OMAP16XX + help + Enable 216 MHz clock for OMAP1710 CPU. If unsure, say N. + +config OMAP_ARM_195MHZ + bool "OMAP ARM 195 MHz CPU" + depends on ARCH_OMAP1 && ARCH_OMAP730 + help + Enable 195MHz clock for OMAP CPU. If unsure, say N. + +config OMAP_ARM_192MHZ + bool "OMAP ARM 192 MHz CPU" + depends on ARCH_OMAP1 && ARCH_OMAP16XX + help + Enable 192MHz clock for OMAP CPU. If unsure, say N. + +config OMAP_ARM_182MHZ + bool "OMAP ARM 182 MHz CPU" + depends on ARCH_OMAP1 && ARCH_OMAP730 + help + Enable 182MHz clock for OMAP CPU. If unsure, say N. + +config OMAP_ARM_168MHZ + bool "OMAP ARM 168 MHz CPU" + depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730) + help + Enable 168MHz clock for OMAP CPU. If unsure, say N. + +config OMAP_ARM_150MHZ + bool "OMAP ARM 150 MHz CPU" + depends on ARCH_OMAP1 && ARCH_OMAP1510 + help + Enable 150MHz clock for OMAP CPU. If unsure, say N. + +config OMAP_ARM_120MHZ + bool "OMAP ARM 120 MHz CPU" + depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730) + help + Enable 120MHz clock for OMAP CPU. If unsure, say N. + +config OMAP_ARM_60MHZ + bool "OMAP ARM 60 MHz CPU" + depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730) + default y + help + Enable 60MHz clock for OMAP CPU. If unsure, say Y. + +config OMAP_ARM_30MHZ + bool "OMAP ARM 30 MHz CPU" + depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730) + help + Enable 30MHz clock for OMAP CPU. If unsure, say N. + diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile new file mode 100644 index 000000000000..d386fd913f0c --- /dev/null +++ b/arch/arm/mach-omap1/Makefile @@ -0,0 +1,30 @@ +# +# Makefile for the linux kernel. +# + +# Common support +obj-y := io.o id.o irq.o time.o serial.o +led-y := leds.o + +# Specific board support +obj-$(CONFIG_MACH_OMAP_H2) += board-h2.o +obj-$(CONFIG_MACH_OMAP_INNOVATOR) += board-innovator.o +obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o +obj-$(CONFIG_MACH_OMAP_PERSEUS2) += board-perseus2.o +obj-$(CONFIG_MACH_OMAP_OSK) += board-osk.o +obj-$(CONFIG_MACH_OMAP_H3) += board-h3.o +obj-$(CONFIG_MACH_VOICEBLUE) += board-voiceblue.o +obj-$(CONFIG_MACH_NETSTAR) += board-netstar.o + +ifeq ($(CONFIG_ARCH_OMAP1510),y) +# Innovator-1510 FPGA +obj-$(CONFIG_MACH_OMAP_INNOVATOR) += fpga.o +endif + +# LEDs support +led-$(CONFIG_MACH_OMAP_H2) += leds-h2p2-debug.o +led-$(CONFIG_MACH_OMAP_INNOVATOR) += leds-innovator.o +led-$(CONFIG_MACH_OMAP_PERSEUS2) += leds-h2p2-debug.o +led-$(CONFIG_MACH_OMAP_OSK) += leds-osk.o +obj-$(CONFIG_LEDS) += $(led-y) + diff --git a/arch/arm/mach-omap/Makefile.boot b/arch/arm/mach-omap1/Makefile.boot index fee1a6a15b54..292d56c5a888 100644 --- a/arch/arm/mach-omap/Makefile.boot +++ b/arch/arm/mach-omap1/Makefile.boot @@ -1,4 +1,3 @@ zreladdr-y := 0x10008000 params_phys-y := 0x10000100 initrd_phys-y := 0x10800000 - diff --git a/arch/arm/mach-omap/board-generic.c b/arch/arm/mach-omap1/board-generic.c index 2102a2cd1013..122796ebe8f5 100644 --- a/arch/arm/mach-omap/board-generic.c +++ b/arch/arm/mach-omap1/board-generic.c @@ -1,5 +1,5 @@ /* - * linux/arch/arm/mach-omap/board-generic.c + * linux/arch/arm/mach-omap1/board-generic.c * * Modified from board-innovator1510.c * @@ -26,8 +26,7 @@ #include <asm/arch/mux.h> #include <asm/arch/usb.h> #include <asm/arch/board.h> - -#include "common.h" +#include <asm/arch/common.h> static int __initdata generic_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1}; @@ -84,15 +83,17 @@ static void __init omap_generic_init(void) static void __init omap_generic_map_io(void) { - omap_map_io(); + omap_map_common_io() } MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710") - MAINTAINER("Tony Lindgren <tony@atomide.com>") - BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) - BOOT_PARAMS(0x10000100) - MAPIO(omap_generic_map_io) - INITIRQ(omap_generic_init_irq) - INIT_MACHINE(omap_generic_init) + /* Maintainer: Tony Lindgren <tony@atomide.com> */ + .phys_ram = 0x10000000, + .phys_io = 0xfff00000, + .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, + .boot_params = 0x10000100, + .map_io = omap_generic_map_io, + .init_irq = omap_generic_init_irq, + .init_machine = omap_generic_init, .timer = &omap_timer, MACHINE_END diff --git a/arch/arm/mach-omap/board-h2.c b/arch/arm/mach-omap1/board-h2.c index 1f067830d1fc..f4983ee95ab4 100644 --- a/arch/arm/mach-omap/board-h2.c +++ b/arch/arm/mach-omap1/board-h2.c @@ -1,5 +1,5 @@ /* - * linux/arch/arm/mach-omap/board-h2.c + * linux/arch/arm/mach-omap1/board-h2.c * * Board specific inits for OMAP-1610 H2 * @@ -35,8 +35,7 @@ #include <asm/arch/gpio.h> #include <asm/arch/tc.h> #include <asm/arch/usb.h> - -#include "common.h" +#include <asm/arch/common.h> extern int omap_gpio_init(void); @@ -172,16 +171,18 @@ static void __init h2_init(void) static void __init h2_map_io(void) { - omap_map_io(); + omap_map_common_io(); omap_serial_init(h2_serial_ports); } MACHINE_START(OMAP_H2, "TI-H2") - MAINTAINER("Imre Deak <imre.deak@nokia.com>") - BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) - BOOT_PARAMS(0x10000100) - MAPIO(h2_map_io) - INITIRQ(h2_init_irq) - INIT_MACHINE(h2_init) + /* Maintainer: Imre Deak <imre.deak@nokia.com> */ + .phys_ram = 0x10000000, + .phys_io = 0xfff00000, + .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, + .boot_params = 0x10000100, + .map_io = h2_map_io, + .init_irq = h2_init_irq, + .init_machine = h2_init, .timer = &omap_timer, MACHINE_END diff --git a/arch/arm/mach-omap/board-h3.c b/arch/arm/mach-omap1/board-h3.c index 486a5a006c9a..7cd419d61b40 100644 --- a/arch/arm/mach-omap/board-h3.c +++ b/arch/arm/mach-omap1/board-h3.c @@ -1,5 +1,5 @@ /* - * linux/arch/arm/mach-omap/board-h3.c + * linux/arch/arm/mach-omap1/board-h3.c * * This file contains OMAP1710 H3 specific code. * @@ -37,8 +37,7 @@ #include <asm/arch/mux.h> #include <asm/arch/tc.h> #include <asm/arch/usb.h> - -#include "common.h" +#include <asm/arch/common.h> extern int omap_gpio_init(void); @@ -190,16 +189,18 @@ void h3_init_irq(void) static void __init h3_map_io(void) { - omap_map_io(); + omap_map_common_io(); omap_serial_init(h3_serial_ports); } MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board") - MAINTAINER("Texas Instruments, Inc.") - BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) - BOOT_PARAMS(0x10000100) - MAPIO(h3_map_io) - INITIRQ(h3_init_irq) - INIT_MACHINE(h3_init) + /* Maintainer: Texas Instruments, Inc. */ + .phys_ram = 0x10000000, + .phys_io = 0xfff00000, + .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, + .boot_params = 0x10000100, + .map_io = h3_map_io, + .init_irq = h3_init_irq, + .init_machine = h3_init, .timer = &omap_timer, MACHINE_END diff --git a/arch/arm/mach-omap/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c index 57cf4da88d55..91de60a91ef8 100644 --- a/arch/arm/mach-omap/board-innovator.c +++ b/arch/arm/mach-omap1/board-innovator.c @@ -1,5 +1,5 @@ /* - * linux/arch/arm/mach-omap/board-innovator.c + * linux/arch/arm/mach-omap1/board-innovator.c * * Board specific inits for OMAP-1510 and OMAP-1610 Innovator * @@ -33,8 +33,7 @@ #include <asm/arch/gpio.h> #include <asm/arch/tc.h> #include <asm/arch/usb.h> - -#include "common.h" +#include <asm/arch/common.h> static int __initdata innovator_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1}; @@ -252,7 +251,7 @@ static void __init innovator_init(void) static void __init innovator_map_io(void) { - omap_map_io(); + omap_map_common_io(); #ifdef CONFIG_ARCH_OMAP1510 if (cpu_is_omap1510()) { @@ -270,11 +269,13 @@ static void __init innovator_map_io(void) } MACHINE_START(OMAP_INNOVATOR, "TI-Innovator") - MAINTAINER("MontaVista Software, Inc.") - BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) - BOOT_PARAMS(0x10000100) - MAPIO(innovator_map_io) - INITIRQ(innovator_init_irq) - INIT_MACHINE(innovator_init) + /* Maintainer: MontaVista Software, Inc. */ + .phys_ram = 0x10000000, + .phys_io = 0xfff00000, + .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, + .boot_params = 0x10000100, + .map_io = innovator_map_io, + .init_irq = innovator_init_irq, + .init_machine = innovator_init, .timer = &omap_timer, MACHINE_END diff --git a/arch/arm/mach-omap/board-netstar.c b/arch/arm/mach-omap1/board-netstar.c index 54acbd215c4b..6750b2014092 100644 --- a/arch/arm/mach-omap/board-netstar.c +++ b/arch/arm/mach-omap1/board-netstar.c @@ -26,8 +26,7 @@ #include <asm/arch/gpio.h> #include <asm/arch/mux.h> #include <asm/arch/usb.h> - -#include "common.h" +#include <asm/arch/common.h> extern void __init omap_init_time(void); extern int omap_gpio_init(void); @@ -100,7 +99,7 @@ static int __initdata omap_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1}; static void __init netstar_map_io(void) { - omap_map_io(); + omap_map_common_io(); omap_serial_init(omap_serial_ports); } @@ -141,11 +140,13 @@ static int __init netstar_late_init(void) postcore_initcall(netstar_late_init); MACHINE_START(NETSTAR, "NetStar OMAP5910") - MAINTAINER("Ladislav Michl <michl@2n.cz>") - BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) - BOOT_PARAMS(0x10000100) - MAPIO(netstar_map_io) - INITIRQ(netstar_init_irq) - INIT_MACHINE(netstar_init) - .timer = &omap_timer, + /* Maintainer: Ladislav Michl <michl@2n.cz> */ + .phys_ram = 0x10000000, + .phys_io = 0xfff00000, + .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, + .boot_params = 0x10000100, + .map_io = netstar_map_io, + .init_irq = netstar_init_irq, + .init_machine = netstar_init, + .timer = &omap_timer, MACHINE_END diff --git a/arch/arm/mach-omap/board-osk.c b/arch/arm/mach-omap1/board-osk.c index a951fc82459b..6844e536c698 100644 --- a/arch/arm/mach-omap/board-osk.c +++ b/arch/arm/mach-omap1/board-osk.c @@ -1,5 +1,5 @@ /* - * linux/arch/arm/mach-omap/board-osk.c + * linux/arch/arm/mach-omap1/board-osk.c * * Board specific init for OMAP5912 OSK * @@ -39,8 +39,7 @@ #include <asm/arch/usb.h> #include <asm/arch/mux.h> #include <asm/arch/tc.h> - -#include "common.h" +#include <asm/arch/common.h> static struct map_desc osk5912_io_desc[] __initdata = { { OMAP_OSK_NOR_FLASH_BASE, OMAP_OSK_NOR_FLASH_START, OMAP_OSK_NOR_FLASH_SIZE, @@ -153,17 +152,19 @@ static void __init osk_init(void) static void __init osk_map_io(void) { - omap_map_io(); + omap_map_common_io(); iotable_init(osk5912_io_desc, ARRAY_SIZE(osk5912_io_desc)); omap_serial_init(osk_serial_ports); } MACHINE_START(OMAP_OSK, "TI-OSK") - MAINTAINER("Dirk Behme <dirk.behme@de.bosch.com>") - BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) - BOOT_PARAMS(0x10000100) - MAPIO(osk_map_io) - INITIRQ(osk_init_irq) - INIT_MACHINE(osk_init) + /* Maintainer: Dirk Behme <dirk.behme@de.bosch.com> */ + .phys_ram = 0x10000000, + .phys_io = 0xfff00000, + .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, + .boot_params = 0x10000100, + .map_io = osk_map_io, + .init_irq = osk_init_irq, + .init_machine = osk_init, .timer = &omap_timer, MACHINE_END diff --git a/arch/arm/mach-omap/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c index 64515aeb49cf..213317392d9b 100644 --- a/arch/arm/mach-omap/board-perseus2.c +++ b/arch/arm/mach-omap1/board-perseus2.c @@ -1,5 +1,5 @@ /* - * linux/arch/arm/mach-omap/board-perseus2.c + * linux/arch/arm/mach-omap1/board-perseus2.c * * Modified from board-generic.c * @@ -27,8 +27,7 @@ #include <asm/arch/gpio.h> #include <asm/arch/mux.h> #include <asm/arch/fpga.h> - -#include "common.h" +#include <asm/arch/common.h> static struct resource smc91x_resources[] = { [0] = { @@ -140,7 +139,7 @@ static struct map_desc omap_perseus2_io_desc[] __initdata = { static void __init omap_perseus2_map_io(void) { - omap_map_io(); + omap_map_common_io(); iotable_init(omap_perseus2_io_desc, ARRAY_SIZE(omap_perseus2_io_desc)); @@ -179,11 +178,13 @@ static void __init omap_perseus2_map_io(void) } MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2") - MAINTAINER("Kevin Hilman <kjh@hilman.org>") - BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) - BOOT_PARAMS(0x10000100) - MAPIO(omap_perseus2_map_io) - INITIRQ(omap_perseus2_init_irq) - INIT_MACHINE(omap_perseus2_init) + /* Maintainer: Kevin Hilman <kjh@hilman.org> */ + .phys_ram = 0x10000000, + .phys_io = 0xfff00000, + .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, + .boot_params = 0x10000100, + .map_io = omap_perseus2_map_io, + .init_irq = omap_perseus2_init_irq, + .init_machine = omap_perseus2_init, .timer = &omap_timer, MACHINE_END diff --git a/arch/arm/mach-omap/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c index f1a5bffac666..e42281988990 100644 --- a/arch/arm/mach-omap/board-voiceblue.c +++ b/arch/arm/mach-omap1/board-voiceblue.c @@ -1,5 +1,5 @@ /* - * linux/arch/arm/mach-omap/board-voiceblue.c + * linux/arch/arm/mach-omap1/board-voiceblue.c * * Modified from board-generic.c * @@ -31,8 +31,7 @@ #include <asm/arch/tc.h> #include <asm/arch/mux.h> #include <asm/arch/usb.h> - -#include "common.h" +#include <asm/arch/common.h> extern void omap_init_time(void); extern int omap_gpio_init(void); @@ -170,7 +169,7 @@ static int __initdata omap_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1}; static void __init voiceblue_map_io(void) { - omap_map_io(); + omap_map_common_io(); omap_serial_init(omap_serial_ports); } @@ -246,11 +245,13 @@ EXPORT_SYMBOL(voiceblue_wdt_disable); EXPORT_SYMBOL(voiceblue_wdt_ping); MACHINE_START(VOICEBLUE, "VoiceBlue OMAP5910") - MAINTAINER("Ladislav Michl <michl@2n.cz>") - BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) - BOOT_PARAMS(0x10000100) - MAPIO(voiceblue_map_io) - INITIRQ(voiceblue_init_irq) - INIT_MACHINE(voiceblue_init) - .timer = &omap_timer, + /* Maintainer: Ladislav Michl <michl@2n.cz> */ + .phys_ram = 0x10000000, + .phys_io = 0xfff00000, + .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, + .boot_params = 0x10000100, + .map_io = voiceblue_map_io, + .init_irq = voiceblue_init_irq, + .init_machine = voiceblue_init, + .timer = &omap_timer, MACHINE_END diff --git a/arch/arm/mach-omap/fpga.c b/arch/arm/mach-omap1/fpga.c index 7c08f6c2e1d0..7c08f6c2e1d0 100644 --- a/arch/arm/mach-omap/fpga.c +++ b/arch/arm/mach-omap1/fpga.c diff --git a/arch/arm/mach-omap1/id.c b/arch/arm/mach-omap1/id.c new file mode 100644 index 000000000000..986c3b7e09bb --- /dev/null +++ b/arch/arm/mach-omap1/id.c @@ -0,0 +1,188 @@ +/* + * linux/arch/arm/mach-omap1/id.c + * + * OMAP1 CPU identification code + * + * Copyright (C) 2004 Nokia Corporation + * Written by Tony Lindgren <tony@atomide.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/io.h> + +struct omap_id { + u16 jtag_id; /* Used to determine OMAP type */ + u8 die_rev; /* Processor revision */ + u32 omap_id; /* OMAP revision */ + u32 type; /* Cpu id bits [31:08], cpu class bits [07:00] */ +}; + +/* Register values to detect the OMAP version */ +static struct omap_id omap_ids[] __initdata = { + { .jtag_id = 0x355f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300100}, + { .jtag_id = 0xb55f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300300}, + { .jtag_id = 0xb470, .die_rev = 0x0, .omap_id = 0x03310100, .type = 0x15100000}, + { .jtag_id = 0xb576, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x16100000}, + { .jtag_id = 0xb576, .die_rev = 0x2, .omap_id = 0x03320100, .type = 0x16110000}, + { .jtag_id = 0xb576, .die_rev = 0x3, .omap_id = 0x03320100, .type = 0x16100c00}, + { .jtag_id = 0xb576, .die_rev = 0x0, .omap_id = 0x03320200, .type = 0x16100d00}, + { .jtag_id = 0xb613, .die_rev = 0x0, .omap_id = 0x03320300, .type = 0x1610ef00}, + { .jtag_id = 0xb613, .die_rev = 0x0, .omap_id = 0x03320300, .type = 0x1610ef00}, + { .jtag_id = 0xb576, .die_rev = 0x1, .omap_id = 0x03320100, .type = 0x16110000}, + { .jtag_id = 0xb58c, .die_rev = 0x2, .omap_id = 0x03320200, .type = 0x16110b00}, + { .jtag_id = 0xb58c, .die_rev = 0x3, .omap_id = 0x03320200, .type = 0x16110c00}, + { .jtag_id = 0xb65f, .die_rev = 0x0, .omap_id = 0x03320400, .type = 0x16212300}, + { .jtag_id = 0xb65f, .die_rev = 0x1, .omap_id = 0x03320400, .type = 0x16212300}, + { .jtag_id = 0xb65f, .die_rev = 0x1, .omap_id = 0x03320500, .type = 0x16212300}, + { .jtag_id = 0xb5f7, .die_rev = 0x0, .omap_id = 0x03330000, .type = 0x17100000}, + { .jtag_id = 0xb5f7, .die_rev = 0x1, .omap_id = 0x03330100, .type = 0x17100000}, + { .jtag_id = 0xb5f7, .die_rev = 0x2, .omap_id = 0x03330100, .type = 0x17100000}, +}; + +/* + * Get OMAP type from PROD_ID. + * 1710 has the PROD_ID in bits 15:00, not in 16:01 as documented in TRM. + * 1510 PROD_ID is empty, and 1610 PROD_ID does not make sense. + * Undocumented register in TEST BLOCK is used as fallback; This seems to + * work on 1510, 1610 & 1710. The official way hopefully will work in future + * processors. + */ +static u16 __init omap_get_jtag_id(void) +{ + u32 prod_id, omap_id; + + prod_id = omap_readl(OMAP_PRODUCTION_ID_1); + omap_id = omap_readl(OMAP32_ID_1); + + /* Check for unusable OMAP_PRODUCTION_ID_1 on 1611B/5912 and 730 */ + if (((prod_id >> 20) == 0) || (prod_id == omap_id)) + prod_id = 0; + else + prod_id &= 0xffff; + + if (prod_id) + return prod_id; + + /* Use OMAP32_ID_1 as fallback */ + prod_id = ((omap_id >> 12) & 0xffff); + + return prod_id; +} + +/* + * Get OMAP revision from DIE_REV. + * Early 1710 processors may have broken OMAP_DIE_ID, it contains PROD_ID. + * Undocumented register in the TEST BLOCK is used as fallback. + * REVISIT: This does not seem to work on 1510 + */ +static u8 __init omap_get_die_rev(void) +{ + u32 die_rev; + + die_rev = omap_readl(OMAP_DIE_ID_1); + + /* Check for broken OMAP_DIE_ID on early 1710 */ + if (((die_rev >> 12) & 0xffff) == omap_get_jtag_id()) + die_rev = 0; + + die_rev = (die_rev >> 17) & 0xf; + if (die_rev) + return die_rev; + + die_rev = (omap_readl(OMAP32_ID_1) >> 28) & 0xf; + + return die_rev; +} + +void __init omap_check_revision(void) +{ + int i; + u16 jtag_id; + u8 die_rev; + u32 omap_id; + u8 cpu_type; + + jtag_id = omap_get_jtag_id(); + die_rev = omap_get_die_rev(); + omap_id = omap_readl(OMAP32_ID_0); + +#ifdef DEBUG + printk("OMAP_DIE_ID_0: 0x%08x\n", omap_readl(OMAP_DIE_ID_0)); + printk("OMAP_DIE_ID_1: 0x%08x DIE_REV: %i\n", + omap_readl(OMAP_DIE_ID_1), + (omap_readl(OMAP_DIE_ID_1) >> 17) & 0xf); + printk("OMAP_PRODUCTION_ID_0: 0x%08x\n", omap_readl(OMAP_PRODUCTION_ID_0)); + printk("OMAP_PRODUCTION_ID_1: 0x%08x JTAG_ID: 0x%04x\n", + omap_readl(OMAP_PRODUCTION_ID_1), + omap_readl(OMAP_PRODUCTION_ID_1) & 0xffff); + printk("OMAP32_ID_0: 0x%08x\n", omap_readl(OMAP32_ID_0)); + printk("OMAP32_ID_1: 0x%08x\n", omap_readl(OMAP32_ID_1)); + printk("JTAG_ID: 0x%04x DIE_REV: %i\n", jtag_id, die_rev); +#endif + + system_serial_high = omap_readl(OMAP_DIE_ID_0); + system_serial_low = omap_readl(OMAP_DIE_ID_1); + + /* First check only the major version in a safe way */ + for (i = 0; i < ARRAY_SIZE(omap_ids); i++) { + if (jtag_id == (omap_ids[i].jtag_id)) { + system_rev = omap_ids[i].type; + break; + } + } + + /* Check if we can find the die revision */ + for (i = 0; i < ARRAY_SIZE(omap_ids); i++) { + if (jtag_id == omap_ids[i].jtag_id && die_rev == omap_ids[i].die_rev) { + system_rev = omap_ids[i].type; + break; + } + } + + /* Finally check also the omap_id */ + for (i = 0; i < ARRAY_SIZE(omap_ids); i++) { + if (jtag_id == omap_ids[i].jtag_id + && die_rev == omap_ids[i].die_rev + && omap_id == omap_ids[i].omap_id) { + system_rev = omap_ids[i].type; + break; + } + } + + /* Add the cpu class info (7xx, 15xx, 16xx, 24xx) */ + cpu_type = system_rev >> 24; + + switch (cpu_type) { + case 0x07: + system_rev |= 0x07; + break; + case 0x15: + system_rev |= 0x15; + break; + case 0x16: + case 0x17: + system_rev |= 0x16; + break; + case 0x24: + system_rev |= 0x24; + break; + default: + printk("Unknown OMAP cpu type: 0x%02x\n", cpu_type); + } + + printk("OMAP%04x", system_rev >> 16); + if ((system_rev >> 8) & 0xff) + printk("%x", (system_rev >> 8) & 0xff); + printk(" revision %i handled as %02xxx id: %08x%08x\n", + die_rev, system_rev & 0xff, system_serial_low, + system_serial_high); +} + diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c new file mode 100644 index 000000000000..207df0fe934d --- /dev/null +++ b/arch/arm/mach-omap1/io.c @@ -0,0 +1,115 @@ +/* + * linux/arch/arm/mach-omap1/io.c + * + * OMAP1 I/O mapping code + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/mach/map.h> +#include <asm/io.h> +#include <asm/arch/tc.h> + +extern int clk_init(void); +extern void omap_check_revision(void); + +/* + * The machine specific code may provide the extra mapping besides the + * default mapping provided here. + */ +static struct map_desc omap_io_desc[] __initdata = { + { IO_VIRT, IO_PHYS, IO_SIZE, MT_DEVICE }, +}; + +#ifdef CONFIG_ARCH_OMAP730 +static struct map_desc omap730_io_desc[] __initdata = { + { OMAP730_DSP_BASE, OMAP730_DSP_START, OMAP730_DSP_SIZE, MT_DEVICE }, + { OMAP730_DSPREG_BASE, OMAP730_DSPREG_START, OMAP730_DSPREG_SIZE, MT_DEVICE }, + { OMAP730_SRAM_BASE, OMAP730_SRAM_START, OMAP730_SRAM_SIZE, MT_DEVICE } +}; +#endif + +#ifdef CONFIG_ARCH_OMAP1510 +static struct map_desc omap1510_io_desc[] __initdata = { + { OMAP1510_DSP_BASE, OMAP1510_DSP_START, OMAP1510_DSP_SIZE, MT_DEVICE }, + { OMAP1510_DSPREG_BASE, OMAP1510_DSPREG_START, OMAP1510_DSPREG_SIZE, MT_DEVICE }, + { OMAP1510_SRAM_BASE, OMAP1510_SRAM_START, OMAP1510_SRAM_SIZE, MT_DEVICE } +}; +#endif + +#if defined(CONFIG_ARCH_OMAP16XX) +static struct map_desc omap1610_io_desc[] __initdata = { + { OMAP16XX_DSP_BASE, OMAP16XX_DSP_START, OMAP16XX_DSP_SIZE, MT_DEVICE }, + { OMAP16XX_DSPREG_BASE, OMAP16XX_DSPREG_START, OMAP16XX_DSPREG_SIZE, MT_DEVICE }, + { OMAP16XX_SRAM_BASE, OMAP16XX_SRAM_START, OMAP1610_SRAM_SIZE, MT_DEVICE } +}; + +static struct map_desc omap5912_io_desc[] __initdata = { + { OMAP16XX_DSP_BASE, OMAP16XX_DSP_START, OMAP16XX_DSP_SIZE, MT_DEVICE }, + { OMAP16XX_DSPREG_BASE, OMAP16XX_DSPREG_START, OMAP16XX_DSPREG_SIZE, MT_DEVICE }, +/* + * The OMAP5912 has 250kByte internal SRAM. Because the mapping is baseed on page + * size (4kByte), it seems that the last 2kByte (=0x800) of the 250kByte are not mapped. + * Add additional 2kByte (0x800) so that the last page is mapped and the last 2kByte + * can be used. + */ + { OMAP16XX_SRAM_BASE, OMAP16XX_SRAM_START, OMAP5912_SRAM_SIZE + 0x800, MT_DEVICE } +}; +#endif + +static int initialized = 0; + +static void __init _omap_map_io(void) +{ + initialized = 1; + + /* We have to initialize the IO space mapping before we can run + * cpu_is_omapxxx() macros. */ + iotable_init(omap_io_desc, ARRAY_SIZE(omap_io_desc)); + omap_check_revision(); + +#ifdef CONFIG_ARCH_OMAP730 + if (cpu_is_omap730()) { + iotable_init(omap730_io_desc, ARRAY_SIZE(omap730_io_desc)); + } +#endif +#ifdef CONFIG_ARCH_OMAP1510 + if (cpu_is_omap1510()) { + iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc)); + } +#endif +#if defined(CONFIG_ARCH_OMAP16XX) + if (cpu_is_omap1610() || cpu_is_omap1710()) { + iotable_init(omap1610_io_desc, ARRAY_SIZE(omap1610_io_desc)); + } + if (cpu_is_omap5912()) { + iotable_init(omap5912_io_desc, ARRAY_SIZE(omap5912_io_desc)); + } +#endif + + /* REVISIT: Refer to OMAP5910 Errata, Advisory SYS_1: "Timeout Abort + * on a Posted Write in the TIPB Bridge". + */ + omap_writew(0x0, MPU_PUBLIC_TIPB_CNTL); + omap_writew(0x0, MPU_PRIVATE_TIPB_CNTL); + + /* Must init clocks early to assure that timer interrupt works + */ + clk_init(); +} + +/* + * This should only get called from board specific init + */ +void omap_map_common_io(void) +{ + if (!initialized) + _omap_map_io(); +} diff --git a/arch/arm/mach-omap/irq.c b/arch/arm/mach-omap1/irq.c index f01c99266a86..a11b6d807352 100644 --- a/arch/arm/mach-omap/irq.c +++ b/arch/arm/mach-omap1/irq.c @@ -56,6 +56,7 @@ struct omap_irq_bank { unsigned long base_reg; unsigned long trigger_map; + unsigned long wake_enable; }; static unsigned int irq_bank_count = 0; @@ -105,6 +106,19 @@ static void omap_mask_ack_irq(unsigned int irq) omap_ack_irq(irq); } +static int omap_wake_irq(unsigned int irq, unsigned int enable) +{ + int bank = IRQ_BANK(irq); + + if (enable) + irq_banks[bank].wake_enable |= IRQ_BIT(irq); + else + irq_banks[bank].wake_enable &= ~IRQ_BIT(irq); + + return 0; +} + + /* * Allows tuning the IRQ type and priority * @@ -145,7 +159,7 @@ static struct omap_irq_bank omap1510_irq_banks[] = { static struct omap_irq_bank omap1610_irq_banks[] = { { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3fefe8f }, { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xfdb7c1fd }, - { .base_reg = OMAP_IH2_BASE + 0x100, .trigger_map = 0xfffff7ff }, + { .base_reg = OMAP_IH2_BASE + 0x100, .trigger_map = 0xffffb7ff }, { .base_reg = OMAP_IH2_BASE + 0x200, .trigger_map = 0xffffffff }, }; #endif @@ -154,6 +168,7 @@ static struct irqchip omap_irq_chip = { .ack = omap_mask_ack_irq, .mask = omap_mask_irq, .unmask = omap_unmask_irq, + .wake = omap_wake_irq, }; void __init omap_init_irq(void) diff --git a/arch/arm/mach-omap/leds-h2p2-debug.c b/arch/arm/mach-omap1/leds-h2p2-debug.c index 6e98290cca5c..ec0d8285f243 100644 --- a/arch/arm/mach-omap/leds-h2p2-debug.c +++ b/arch/arm/mach-omap1/leds-h2p2-debug.c @@ -13,7 +13,6 @@ #include <linux/init.h> #include <linux/kernel_stat.h> #include <linux/sched.h> -#include <linux/version.h> #include <asm/io.h> #include <asm/hardware.h> diff --git a/arch/arm/mach-omap/leds-innovator.c b/arch/arm/mach-omap1/leds-innovator.c index 8043b7d0f66e..8043b7d0f66e 100644 --- a/arch/arm/mach-omap/leds-innovator.c +++ b/arch/arm/mach-omap1/leds-innovator.c diff --git a/arch/arm/mach-omap/leds-osk.c b/arch/arm/mach-omap1/leds-osk.c index f5177f430793..4a0e8b9d4fc3 100644 --- a/arch/arm/mach-omap/leds-osk.c +++ b/arch/arm/mach-omap1/leds-osk.c @@ -129,14 +129,11 @@ void osk_leds_event(led_event_t evt) #ifdef CONFIG_FB_OMAP -#ifdef CONFIG_LEDS_TIMER case led_timer: hw_led_state ^= TIMER_LED; mistral_setled(); break; -#endif -#ifdef CONFIG_LEDS_CPU case led_idle_start: hw_led_state |= IDLE_LED; mistral_setled(); @@ -146,7 +143,6 @@ void osk_leds_event(led_event_t evt) hw_led_state &= ~IDLE_LED; mistral_setled(); break; -#endif #endif /* CONFIG_FB_OMAP */ diff --git a/arch/arm/mach-omap/leds.c b/arch/arm/mach-omap1/leds.c index 8ab21fe98e1b..8ab21fe98e1b 100644 --- a/arch/arm/mach-omap/leds.c +++ b/arch/arm/mach-omap1/leds.c diff --git a/arch/arm/mach-omap/leds.h b/arch/arm/mach-omap1/leds.h index a1e9fedc376c..a1e9fedc376c 100644 --- a/arch/arm/mach-omap/leds.h +++ b/arch/arm/mach-omap1/leds.h diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c new file mode 100644 index 000000000000..214e5d17c8b5 --- /dev/null +++ b/arch/arm/mach-omap1/serial.c @@ -0,0 +1,200 @@ +/* + * linux/arch/arm/mach-omap1/id.c + * + * OMAP1 CPU identification code + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/serial.h> +#include <linux/tty.h> +#include <linux/serial_8250.h> +#include <linux/serial_reg.h> + +#include <asm/io.h> +#include <asm/mach-types.h> +#include <asm/hardware/clock.h> + +#include <asm/arch/board.h> +#include <asm/arch/mux.h> +#include <asm/arch/fpga.h> + +static struct clk * uart1_ck = NULL; +static struct clk * uart2_ck = NULL; +static struct clk * uart3_ck = NULL; + +static inline unsigned int omap_serial_in(struct plat_serial8250_port *up, + int offset) +{ + offset <<= up->regshift; + return (unsigned int)__raw_readb(up->membase + offset); +} + +static inline void omap_serial_outp(struct plat_serial8250_port *p, int offset, + int value) +{ + offset <<= p->regshift; + __raw_writeb(value, p->membase + offset); +} + +/* + * Internal UARTs need to be initialized for the 8250 autoconfig to work + * properly. Note that the TX watermark initialization may not be needed + * once the 8250.c watermark handling code is merged. + */ +static void __init omap_serial_reset(struct plat_serial8250_port *p) +{ + omap_serial_outp(p, UART_OMAP_MDR1, 0x07); /* disable UART */ + omap_serial_outp(p, UART_OMAP_SCR, 0x08); /* TX watermark */ + omap_serial_outp(p, UART_OMAP_MDR1, 0x00); /* enable UART */ + + if (!cpu_is_omap1510()) { + omap_serial_outp(p, UART_OMAP_SYSC, 0x01); + while (!(omap_serial_in(p, UART_OMAP_SYSC) & 0x01)); + } +} + +static struct plat_serial8250_port serial_platform_data[] = { + { + .membase = (char*)IO_ADDRESS(OMAP_UART1_BASE), + .mapbase = (unsigned long)OMAP_UART1_BASE, + .irq = INT_UART1, + .flags = UPF_BOOT_AUTOCONF, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = OMAP16XX_BASE_BAUD * 16, + }, + { + .membase = (char*)IO_ADDRESS(OMAP_UART2_BASE), + .mapbase = (unsigned long)OMAP_UART2_BASE, + .irq = INT_UART2, + .flags = UPF_BOOT_AUTOCONF, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = OMAP16XX_BASE_BAUD * 16, + }, + { + .membase = (char*)IO_ADDRESS(OMAP_UART3_BASE), + .mapbase = (unsigned long)OMAP_UART3_BASE, + .irq = INT_UART3, + .flags = UPF_BOOT_AUTOCONF, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = OMAP16XX_BASE_BAUD * 16, + }, + { }, +}; + +static struct platform_device serial_device = { + .name = "serial8250", + .id = 0, + .dev = { + .platform_data = serial_platform_data, + }, +}; + +/* + * Note that on Innovator-1510 UART2 pins conflict with USB2. + * By default UART2 does not work on Innovator-1510 if you have + * USB OHCI enabled. To use UART2, you must disable USB2 first. + */ +void __init omap_serial_init(int ports[OMAP_MAX_NR_PORTS]) +{ + int i; + + if (cpu_is_omap730()) { + serial_platform_data[0].regshift = 0; + serial_platform_data[1].regshift = 0; + serial_platform_data[0].irq = INT_730_UART_MODEM_1; + serial_platform_data[1].irq = INT_730_UART_MODEM_IRDA_2; + } + + if (cpu_is_omap1510()) { + serial_platform_data[0].uartclk = OMAP1510_BASE_BAUD * 16; + serial_platform_data[1].uartclk = OMAP1510_BASE_BAUD * 16; + serial_platform_data[2].uartclk = OMAP1510_BASE_BAUD * 16; + } + + for (i = 0; i < OMAP_MAX_NR_PORTS; i++) { + unsigned char reg; + + if (ports[i] == 0) { + serial_platform_data[i].membase = NULL; + serial_platform_data[i].mapbase = 0; + continue; + } + + switch (i) { + case 0: + uart1_ck = clk_get(NULL, "uart1_ck"); + if (IS_ERR(uart1_ck)) + printk("Could not get uart1_ck\n"); + else { + clk_use(uart1_ck); + if (cpu_is_omap1510()) + clk_set_rate(uart1_ck, 12000000); + } + if (cpu_is_omap1510()) { + omap_cfg_reg(UART1_TX); + omap_cfg_reg(UART1_RTS); + if (machine_is_omap_innovator()) { + reg = fpga_read(OMAP1510_FPGA_POWER); + reg |= OMAP1510_FPGA_PCR_COM1_EN; + fpga_write(reg, OMAP1510_FPGA_POWER); + udelay(10); + } + } + break; + case 1: + uart2_ck = clk_get(NULL, "uart2_ck"); + if (IS_ERR(uart2_ck)) + printk("Could not get uart2_ck\n"); + else { + clk_use(uart2_ck); + if (cpu_is_omap1510()) + clk_set_rate(uart2_ck, 12000000); + else + clk_set_rate(uart2_ck, 48000000); + } + if (cpu_is_omap1510()) { + omap_cfg_reg(UART2_TX); + omap_cfg_reg(UART2_RTS); + if (machine_is_omap_innovator()) { + reg = fpga_read(OMAP1510_FPGA_POWER); + reg |= OMAP1510_FPGA_PCR_COM2_EN; + fpga_write(reg, OMAP1510_FPGA_POWER); + udelay(10); + } + } + break; + case 2: + uart3_ck = clk_get(NULL, "uart3_ck"); + if (IS_ERR(uart3_ck)) + printk("Could not get uart3_ck\n"); + else { + clk_use(uart3_ck); + if (cpu_is_omap1510()) + clk_set_rate(uart3_ck, 12000000); + } + if (cpu_is_omap1510()) { + omap_cfg_reg(UART3_TX); + omap_cfg_reg(UART3_RX); + } + break; + } + omap_serial_reset(&serial_platform_data[i]); + } +} + +static int __init omap_init(void) +{ + return platform_device_register(&serial_device); +} +arch_initcall(omap_init); diff --git a/arch/arm/mach-omap/time.c b/arch/arm/mach-omap1/time.c index 4205fdcb632c..d540539c9bbb 100644 --- a/arch/arm/mach-omap/time.c +++ b/arch/arm/mach-omap1/time.c @@ -1,10 +1,10 @@ /* - * linux/arch/arm/mach-omap/time.c + * linux/arch/arm/mach-omap1/time.c * * OMAP Timers * * Copyright (C) 2004 Nokia Corporation - * Partial timer rewrite and additional VST timer support by + * Partial timer rewrite and additional dynamic tick timer support by * Tony Lindgen <tony@atomide.com> and * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> * @@ -58,17 +58,9 @@ struct sys_timer omap_timer; * MPU timer * --------------------------------------------------------------------------- */ -#define OMAP_MPU_TIMER1_BASE (0xfffec500) -#define OMAP_MPU_TIMER2_BASE (0xfffec600) -#define OMAP_MPU_TIMER3_BASE (0xfffec700) #define OMAP_MPU_TIMER_BASE OMAP_MPU_TIMER1_BASE #define OMAP_MPU_TIMER_OFFSET 0x100 -#define MPU_TIMER_FREE (1 << 6) -#define MPU_TIMER_CLOCK_ENABLE (1 << 5) -#define MPU_TIMER_AR (1 << 1) -#define MPU_TIMER_ST (1 << 0) - /* cycles to nsec conversions taken from arch/i386/kernel/timers/timer_tsc.c, * converted to use kHz by Kevin Hilman */ /* convert from cycles(64bits) => nanoseconds (64bits) @@ -188,8 +180,8 @@ static irqreturn_t omap_mpu_timer_interrupt(int irq, void *dev_id, static struct irqaction omap_mpu_timer_irq = { .name = "mpu timer", - .flags = SA_INTERRUPT, - .handler = omap_mpu_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = omap_mpu_timer_interrupt, }; static unsigned long omap_mpu_timer1_overflows; @@ -203,7 +195,7 @@ static irqreturn_t omap_mpu_timer1_interrupt(int irq, void *dev_id, static struct irqaction omap_mpu_timer1_irq = { .name = "mpu timer1 overflow", .flags = SA_INTERRUPT, - .handler = omap_mpu_timer1_interrupt + .handler = omap_mpu_timer1_interrupt, }; static __init void omap_init_mpu_timer(void) @@ -255,13 +247,19 @@ unsigned long long sched_clock(void) #define OMAP_32K_TIMER_TCR 0x04 #define OMAP_32K_TICKS_PER_HZ (32768 / HZ) +#if (32768 % HZ) != 0 +/* We cannot ignore modulo. + * Potential error can be as high as several percent. + */ +#define OMAP_32K_TICK_MODULO (32768 % HZ) +static unsigned modulo_count = 0; /* Counts 1/HZ units */ +#endif /* * TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1 * so with HZ = 100, TVR = 327.68. */ #define OMAP_32K_TIMER_TICK_PERIOD ((32768 / HZ) - 1) -#define MAX_SKIP_JIFFIES 25 #define TIMER_32K_SYNCHRONIZED 0xfffbc410 #define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate) \ @@ -332,6 +330,19 @@ static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, now = omap_32k_sync_timer_read(); while (now - omap_32k_last_tick >= OMAP_32K_TICKS_PER_HZ) { +#ifdef OMAP_32K_TICK_MODULO + /* Modulo addition may put omap_32k_last_tick ahead of now + * and cause unwanted repetition of the while loop. + */ + if (unlikely(now - omap_32k_last_tick == ~0)) + break; + + modulo_count += OMAP_32K_TICK_MODULO; + if (modulo_count > HZ) { + ++omap_32k_last_tick; + modulo_count -= HZ; + } +#endif omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ; timer_tick(regs); } @@ -347,14 +358,55 @@ static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, return IRQ_HANDLED; } +#ifdef CONFIG_NO_IDLE_HZ +/* + * Programs the next timer interrupt needed. Called when dynamic tick is + * enabled, and to reprogram the ticks to skip from pm_idle. Note that + * we can keep the timer continuous, and don't need to set it to run in + * one-shot mode. This is because the timer will get reprogrammed again + * after next interrupt. + */ +void omap_32k_timer_reprogram(unsigned long next_tick) +{ + omap_32k_timer_start(JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1); +} + +static struct irqaction omap_32k_timer_irq; +extern struct timer_update_handler timer_update; + +static int omap_32k_timer_enable_dyn_tick(void) +{ + /* No need to reprogram timer, just use the next interrupt */ + return 0; +} + +static int omap_32k_timer_disable_dyn_tick(void) +{ + omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD); + return 0; +} + +static struct dyn_tick_timer omap_dyn_tick_timer = { + .enable = omap_32k_timer_enable_dyn_tick, + .disable = omap_32k_timer_disable_dyn_tick, + .reprogram = omap_32k_timer_reprogram, + .handler = omap_32k_timer_interrupt, +}; +#endif /* CONFIG_NO_IDLE_HZ */ + static struct irqaction omap_32k_timer_irq = { .name = "32KHz timer", - .flags = SA_INTERRUPT, - .handler = omap_32k_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = omap_32k_timer_interrupt, }; static __init void omap_init_32k_timer(void) { + +#ifdef CONFIG_NO_IDLE_HZ + omap_timer.dyn_tick = &omap_dyn_tick_timer; +#endif + setup_irq(INT_OS_TIMER, &omap_32k_timer_irq); omap_timer.offset = omap_32k_timer_gettimeoffset; omap_32k_last_tick = omap_32k_sync_timer_read(); @@ -367,7 +419,7 @@ static __init void omap_init_32k_timer(void) * Timer initialization * --------------------------------------------------------------------------- */ -void __init omap_timer_init(void) +static void __init omap_timer_init(void) { #if defined(CONFIG_OMAP_MPU_TIMER) omap_init_mpu_timer(); diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index c4e6d2523585..efc2f657184e 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -24,3 +24,7 @@ obj-$(CONFIG_LEDS) += $(led-y) # Misc features obj-$(CONFIG_PM) += pm.o sleep.o + +ifeq ($(CONFIG_PXA27x),y) +obj-$(CONFIG_PM) += standby.o +endif diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index f691cf77d390..86b862f56e7e 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c @@ -287,34 +287,40 @@ static void __init corgi_map_io(void) #ifdef CONFIG_MACH_CORGI MACHINE_START(CORGI, "SHARP Corgi") - BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000)) - FIXUP(fixup_corgi) - MAPIO(corgi_map_io) - INITIRQ(corgi_init_irq) - .init_machine = corgi_init, - .timer = &pxa_timer, + .phys_ram = 0xa0000000, + .phys_io = 0x40000000, + .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, + .fixup = fixup_corgi, + .map_io = corgi_map_io, + .init_irq = corgi_init_irq, + .init_machine = corgi_init, + .timer = &pxa_timer, MACHINE_END #endif #ifdef CONFIG_MACH_SHEPHERD MACHINE_START(SHEPHERD, "SHARP Shepherd") - BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000)) - FIXUP(fixup_corgi) - MAPIO(corgi_map_io) - INITIRQ(corgi_init_irq) - .init_machine = corgi_init, - .timer = &pxa_timer, + .phys_ram = 0xa0000000, + .phys_io = 0x40000000, + .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, + .fixup = fixup_corgi, + .map_io = corgi_map_io, + .init_irq = corgi_init_irq, + .init_machine = corgi_init, + .timer = &pxa_timer, MACHINE_END #endif #ifdef CONFIG_MACH_HUSKY MACHINE_START(HUSKY, "SHARP Husky") - BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000)) - FIXUP(fixup_corgi) - MAPIO(corgi_map_io) - INITIRQ(corgi_init_irq) - .init_machine = corgi_init, - .timer = &pxa_timer, + .phys_ram = 0xa0000000, + .phys_io = 0x40000000, + .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, + .fixup = fixup_corgi, + .map_io = corgi_map_io, + .init_irq = corgi_init_irq, + .init_machine = corgi_init, + .timer = &pxa_timer, MACHINE_END #endif diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c index c5a66bf4d3d5..386e107b53cc 100644 --- a/arch/arm/mach-pxa/idp.c +++ b/arch/arm/mach-pxa/idp.c @@ -181,10 +181,12 @@ static void __init idp_map_io(void) MACHINE_START(PXA_IDP, "Vibren PXA255 IDP") - MAINTAINER("Vibren Technologies") - BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000)) - MAPIO(idp_map_io) - INITIRQ(idp_init_irq) + /* Maintainer: Vibren Technologies */ + .phys_ram = 0xa0000000, + .phys_io = 0x40000000, + .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, + .map_io = idp_map_io, + .init_irq = idp_init_irq, .timer = &pxa_timer, - INIT_MACHINE(idp_init) + .init_machine = idp_init, MACHINE_END diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index f2c9e0d2b24b..6309853b59be 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -268,10 +268,12 @@ static void __init lubbock_map_io(void) } MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Platform (aka Lubbock)") - MAINTAINER("MontaVista Software Inc.") - BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000)) - MAPIO(lubbock_map_io) - INITIRQ(lubbock_init_irq) + /* Maintainer: MontaVista Software Inc. */ + .phys_ram = 0xa0000000, + .phys_io = 0x40000000, + .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, + .map_io = lubbock_map_io, + .init_irq = lubbock_init_irq, .timer = &pxa_timer, - INIT_MACHINE(lubbock_init) + .init_machine = lubbock_init, MACHINE_END diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index 9896afca751f..827b7b5a5be8 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -345,10 +345,12 @@ static void __init mainstone_map_io(void) } MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)") - MAINTAINER("MontaVista Software Inc.") - BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000)) - MAPIO(mainstone_map_io) - INITIRQ(mainstone_init_irq) + /* Maintainer: MontaVista Software Inc. */ + .phys_ram = 0xa0000000, + .phys_io = 0x40000000, + .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, + .map_io = mainstone_map_io, + .init_irq = mainstone_init_irq, .timer = &pxa_timer, - INIT_MACHINE(mainstone_init) + .init_machine = mainstone_init, MACHINE_END diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index b6c746ea3830..0e4f6fab100a 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c @@ -180,10 +180,12 @@ static void __init poodle_map_io(void) } MACHINE_START(POODLE, "SHARP Poodle") - BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000)) - FIXUP(fixup_poodle) - MAPIO(poodle_map_io) - INITIRQ(pxa_init_irq) - .timer = &pxa_timer, - .init_machine = poodle_init, + .phys_ram = 0xa0000000, + .phys_io = 0x40000000, + .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, + .fixup = fixup_poodle, + .map_io = poodle_map_io, + .init_irq = pxa_init_irq, + .timer = &pxa_timer, + .init_machine = poodle_init, MACHINE_END diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 893964fb9659..9a791b07118d 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -126,6 +126,7 @@ int pxa_cpu_pm_prepare(suspend_state_t state) { switch (state) { case PM_SUSPEND_MEM: + case PM_SUSPEND_STANDBY: return 0; default: return -EINVAL; @@ -138,7 +139,10 @@ void pxa_cpu_pm_enter(suspend_state_t state) extern void pxa_cpu_suspend(unsigned int); extern void pxa_cpu_resume(void); - CKEN = CKEN22_MEMC | CKEN9_OSTIMER; + if (state == PM_SUSPEND_STANDBY) + CKEN = CKEN22_MEMC | CKEN9_OSTIMER | CKEN16_LCD |CKEN0_PWM0; + else + CKEN = CKEN22_MEMC | CKEN9_OSTIMER; /* ensure voltage-change sequencer not initiated, which hangs */ PCFR &= ~PCFR_FVC; @@ -147,6 +151,9 @@ void pxa_cpu_pm_enter(suspend_state_t state) PEDR = 0xDF12FE1B; switch (state) { + case PM_SUSPEND_STANDBY: + pxa_cpu_standby(); + break; case PM_SUSPEND_MEM: /* set resume return address */ PSPR = virt_to_phys(pxa_cpu_resume); diff --git a/arch/arm/mach-pxa/standby.S b/arch/arm/mach-pxa/standby.S new file mode 100644 index 000000000000..8a3f27b76784 --- /dev/null +++ b/arch/arm/mach-pxa/standby.S @@ -0,0 +1,32 @@ +/* + * PXA27x standby mode + * + * Author: David Burrage + * + * 2005 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ + +#include <linux/config.h> +#include <linux/linkage.h> +#include <asm/assembler.h> +#include <asm/hardware.h> + +#include <asm/arch/pxa-regs.h> + + .text + +ENTRY(pxa_cpu_standby) + ldr r0, =PSSR + mov r1, #(PSSR_PH | PSSR_STS) + mov r2, #2 + mov r3, #UNCACHED_PHYS_0 @ Read mem context in. + ldr ip, [r3] + b 1f + + .align 5 +1: mcr p14, 0, r2, c7, c0, 0 @ put the system into Standby + str r1, [r0] @ make sure PSSR_PH/STS are clear + mov pc, lr diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c index 473fb6173f72..6e5202154f91 100644 --- a/arch/arm/mach-pxa/time.c +++ b/arch/arm/mach-pxa/time.c @@ -105,8 +105,8 @@ pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction pxa_timer_irq = { .name = "PXA Timer Tick", - .flags = SA_INTERRUPT, - .handler = pxa_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = pxa_timer_interrupt, }; static void __init pxa_timer_init(void) diff --git a/arch/arm/mach-rpc/riscpc.c b/arch/arm/mach-rpc/riscpc.c index 437106881436..a10268618f74 100644 --- a/arch/arm/mach-rpc/riscpc.c +++ b/arch/arm/mach-rpc/riscpc.c @@ -163,12 +163,14 @@ arch_initcall(rpc_init); extern struct sys_timer ioc_timer; MACHINE_START(RISCPC, "Acorn-RiscPC") - MAINTAINER("Russell King") - BOOT_MEM(0x10000000, 0x03000000, 0xe0000000) - BOOT_PARAMS(0x10000100) - DISABLE_PARPORT(0) - DISABLE_PARPORT(1) - MAPIO(rpc_map_io) - INITIRQ(rpc_init_irq) + /* Maintainer: Russell King */ + .phys_ram = 0x10000000, + .phys_io = 0x03000000, + .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc, + .boot_params = 0x10000100, + .reserve_lp0 = 1, + .reserve_lp1 = 1, + .map_io = rpc_map_io, + .init_irq = rpc_init_irq, .timer = &ioc_timer, MACHINE_END diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig index 534df0c6c770..d4d03d0daaec 100644 --- a/arch/arm/mach-s3c2410/Kconfig +++ b/arch/arm/mach-s3c2410/Kconfig @@ -154,6 +154,11 @@ config S3C2410_PM_CHECK_CHUNKSIZE the CRC data block will take more memory, but wil identify any faults with better precision. +config PM_SIMTEC + bool + depends on PM && (ARCH_BAST || MACH_VR1000) + default y + config S3C2410_LOWLEVEL_UART_PORT int "S3C2410 UART to use for low-level messages" default 0 diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile index 7c379aad5d62..f99b689e4392 100644 --- a/arch/arm/mach-s3c2410/Makefile +++ b/arch/arm/mach-s3c2410/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_S3C2410_DMA) += dma.o # Power Management support obj-$(CONFIG_PM) += pm.o sleep.o +obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o # S3C2440 support diff --git a/arch/arm/mach-s3c2410/devs.c b/arch/arm/mach-s3c2410/devs.c index 64792f678668..4664bd11adc1 100644 --- a/arch/arm/mach-s3c2410/devs.c +++ b/arch/arm/mach-s3c2410/devs.c @@ -96,8 +96,8 @@ struct platform_device s3c_device_lcd = { .num_resources = ARRAY_SIZE(s3c_lcd_resource), .resource = s3c_lcd_resource, .dev = { - .dma_mask = &s3c_device_lcd_dmamask, - .coherent_dma_mask = 0xffffffffUL + .dma_mask = &s3c_device_lcd_dmamask, + .coherent_dma_mask = 0xffffffffUL } }; diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c index c7c28890d406..65feaf20d23e 100644 --- a/arch/arm/mach-s3c2410/dma.c +++ b/arch/arm/mach-s3c2410/dma.c @@ -436,7 +436,7 @@ int s3c2410_dma_enqueue(unsigned int channel, void *id, buf = kmem_cache_alloc(dma_kmem, GFP_ATOMIC); if (buf == NULL) { - pr_debug("%s: out of memory (%d alloc)\n", + pr_debug("%s: out of memory (%ld alloc)\n", __FUNCTION__, sizeof(*buf)); return -ENOMEM; } diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c index b668c48f4399..cf9f46d88061 100644 --- a/arch/arm/mach-s3c2410/irq.c +++ b/arch/arm/mach-s3c2410/irq.c @@ -40,8 +40,11 @@ * 04-Nov-2004 Ben Dooks * Fix standard IRQ wake for EINT0..4 and RTC * - * 22-Feb-2004 Ben Dooks + * 22-Feb-2005 Ben Dooks * Fixed edge-triggering on ADC IRQ + * + * 28-Jun-2005 Ben Dooks + * Mark IRQ_LCD valid */ #include <linux/init.h> @@ -366,7 +369,6 @@ static struct irqchip s3c_irq_eint0t4 = { #define INTMSK_UART1 (1UL << (IRQ_UART1 - IRQ_EINT0)) #define INTMSK_UART2 (1UL << (IRQ_UART2 - IRQ_EINT0)) #define INTMSK_ADCPARENT (1UL << (IRQ_ADCPARENT - IRQ_EINT0)) -#define INTMSK_LCD (1UL << (IRQ_LCD - IRQ_EINT0)) static inline void s3c_irqsub_mask(unsigned int irqno, unsigned int parentbit, @@ -716,7 +718,6 @@ void __init s3c24xx_init_irq(void) case IRQ_UART0: case IRQ_UART1: case IRQ_UART2: - case IRQ_LCD: case IRQ_ADCPARENT: set_irq_chip(irqno, &s3c_irq_level_chip); set_irq_handler(irqno, do_level_IRQ); diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c index f3e970039b65..206778ebfce7 100644 --- a/arch/arm/mach-s3c2410/mach-bast.c +++ b/arch/arm/mach-s3c2410/mach-bast.c @@ -27,6 +27,8 @@ * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA * 14-Mar-2006 BJD Updated for __iomem changes * 22-Jun-2006 BJD Added DM9000 platform information + * 28-Jun-2006 BJD Moved pm functionality out to common code + * 17-Jul-2006 BJD Changed to platform device for SuperIO 16550s */ #include <linux/kernel.h> @@ -63,11 +65,12 @@ #include <linux/mtd/nand_ecc.h> #include <linux/mtd/partitions.h> +#include <linux/serial_8250.h> + #include "clock.h" #include "devs.h" #include "cpu.h" #include "usb-simtec.h" -#include "pm.h" #define COPYRIGHT ", (c) 2004-2005 Simtec Electronics" @@ -351,6 +354,39 @@ static struct platform_device bast_device_dm9k = { } }; +/* serial devices */ + +#define SERIAL_BASE (S3C2410_CS2 + BAST_PA_SUPERIO) +#define SERIAL_FLAGS (UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_SHARE_IRQ) +#define SERIAL_CLK (1843200) + +static struct plat_serial8250_port bast_sio_data[] = { + [0] = { + .mapbase = SERIAL_BASE + 0x2f8, + .irq = IRQ_PCSERIAL1, + .flags = SERIAL_FLAGS, + .iotype = UPIO_MEM, + .regshift = 0, + .uartclk = SERIAL_CLK, + }, + [1] = { + .mapbase = SERIAL_BASE + 0x3f8, + .irq = IRQ_PCSERIAL2, + .flags = SERIAL_FLAGS, + .iotype = UPIO_MEM, + .regshift = 0, + .uartclk = SERIAL_CLK, + }, + { } +}; + +static struct platform_device bast_sio = { + .name = "serial8250", + .id = 0, + .dev = { + .platform_data = &bast_sio_data, + }, +}; /* Standard BAST devices */ @@ -364,6 +400,7 @@ static struct platform_device *bast_devices[] __initdata = { &s3c_device_nand, &bast_device_nor, &bast_device_dm9k, + &bast_sio, }; static struct clk *bast_clocks[] = { @@ -405,44 +442,14 @@ void __init bast_map_io(void) usb_simtec_init(); } -void __init bast_init_irq(void) -{ - s3c24xx_init_irq(); -} - -#ifdef CONFIG_PM - -/* bast_init_machine - * - * enable the power management functions for the EB2410ITX -*/ - -static __init void bast_init_machine(void) -{ - unsigned long gstatus4; - - printk(KERN_INFO "BAST Power Manangement" COPYRIGHT "\n"); - - gstatus4 = (__raw_readl(S3C2410_BANKCON7) & 0x3) << 30; - gstatus4 |= (__raw_readl(S3C2410_BANKCON6) & 0x3) << 28; - gstatus4 |= (__raw_readl(S3C2410_BANKSIZE) & S3C2410_BANKSIZE_MASK); - - __raw_writel(gstatus4, S3C2410_GSTATUS4); - - s3c2410_pm_init(); -} - -#else -#define bast_init_machine NULL -#endif - MACHINE_START(BAST, "Simtec-BAST") - MAINTAINER("Ben Dooks <ben@simtec.co.uk>") - BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) - BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) - MAPIO(bast_map_io) - INITIRQ(bast_init_irq) - .init_machine = bast_init_machine, + /* Maintainer: Ben Dooks <ben@simtec.co.uk> */ + .phys_ram = S3C2410_SDRAM_PA, + .phys_io = S3C2410_PA_UART, + .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, + .boot_params = S3C2410_SDRAM_PA + 0x100, + .map_io = bast_map_io, + .init_irq = s3c24xx_init_irq, .timer = &s3c24xx_timer, MACHINE_END diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c index 2924afc068a4..ea4fb1a97a50 100644 --- a/arch/arm/mach-s3c2410/mach-h1940.c +++ b/arch/arm/mach-s3c2410/mach-h1940.c @@ -117,10 +117,12 @@ void __init h1940_init_irq(void) } MACHINE_START(H1940, "IPAQ-H1940") - MAINTAINER("Ben Dooks <ben@fluff.org>") - BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) - BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) - MAPIO(h1940_map_io) - INITIRQ(h1940_init_irq) + /* Maintainer: Ben Dooks <ben@fluff.org> */ + .phys_ram = S3C2410_SDRAM_PA, + .phys_io = S3C2410_PA_UART, + .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, + .boot_params = S3C2410_SDRAM_PA + 0x100, + .map_io = h1940_map_io, + .init_irq = h1940_init_irq, .timer = &s3c24xx_timer, MACHINE_END diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index bd15998c129b..79044d9bce38 100644 --- a/arch/arm/mach-s3c2410/mach-n30.c +++ b/arch/arm/mach-s3c2410/mach-n30.c @@ -137,10 +137,11 @@ void __init n30_init(void) } MACHINE_START(N30, "Acer-N30") - MAINTAINER("Christer Weinigel <christer@weinigel.se>, Ben Dooks <ben-linux@fluff.org>") - BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) - BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) - + /* Maintainer: Christer Weinigel <christer@weinigel.se>, Ben Dooks <ben-linux@fluff.org> */ + .phys_ram = S3C2410_SDRAM_PA, + .phys_io = S3C2410_PA_UART, + .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, + .boot_params = S3C2410_SDRAM_PA + 0x100, .timer = &s3c24xx_timer, .init_machine = n30_init, .init_irq = n30_init_irq, diff --git a/arch/arm/mach-s3c2410/mach-nexcoder.c b/arch/arm/mach-s3c2410/mach-nexcoder.c index 70487bf4b71e..d24c242414ca 100644 --- a/arch/arm/mach-s3c2410/mach-nexcoder.c +++ b/arch/arm/mach-s3c2410/mach-nexcoder.c @@ -147,9 +147,11 @@ void __init nexcoder_map_io(void) MACHINE_START(NEXCODER_2440, "NexVision - Nexcoder 2440") - MAINTAINER("Guillaume GOURAT <guillaume.gourat@nexvision.tv>") - BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) - BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) + /* Maintainer: Guillaume GOURAT <guillaume.gourat@nexvision.tv> */ + .phys_ram = S3C2410_SDRAM_PA, + .phys_io = S3C2410_PA_UART, + .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, + .boot_params = S3C2410_SDRAM_PA + 0x100, .map_io = nexcoder_map_io, .init_irq = s3c24xx_init_irq, .timer = &s3c24xx_timer, diff --git a/arch/arm/mach-s3c2410/mach-otom.c b/arch/arm/mach-s3c2410/mach-otom.c index 67d8ce8fb00f..d901ed492ff5 100644 --- a/arch/arm/mach-s3c2410/mach-otom.c +++ b/arch/arm/mach-s3c2410/mach-otom.c @@ -115,9 +115,11 @@ void __init otom11_map_io(void) MACHINE_START(OTOM, "Nex Vision - Otom 1.1") - MAINTAINER("Guillaume GOURAT <guillaume.gourat@nexvision.tv>") - BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) - BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) + /* Maintainer: Guillaume GOURAT <guillaume.gourat@nexvision.tv> */ + .phys_ram = S3C2410_SDRAM_PA, + .phys_io = S3C2410_PA_UART, + .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, + .boot_params = S3C2410_SDRAM_PA + 0x100, .map_io = otom11_map_io, .init_irq = s3c24xx_init_irq, .timer = &s3c24xx_timer, diff --git a/arch/arm/mach-s3c2410/mach-rx3715.c b/arch/arm/mach-s3c2410/mach-rx3715.c index f8d3a9784e71..a73d61c1de46 100644 --- a/arch/arm/mach-s3c2410/mach-rx3715.c +++ b/arch/arm/mach-s3c2410/mach-rx3715.c @@ -131,11 +131,13 @@ static void __init rx3715_init_machine(void) #endif MACHINE_START(RX3715, "IPAQ-RX3715") - MAINTAINER("Ben Dooks <ben@fluff.org>") - BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) - BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) - MAPIO(rx3715_map_io) - INITIRQ(rx3715_init_irq) - INIT_MACHINE(rx3715_init_machine) + /* Maintainer: Ben Dooks <ben@fluff.org> */ + .phys_ram = S3C2410_SDRAM_PA, + .phys_io = S3C2410_PA_UART, + .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, + .boot_params = S3C2410_SDRAM_PA + 0x100, + .map_io = rx3715_map_io, + .init_irq = rx3715_init_irq, + .init_machine = rx3715_init_machine, .timer = &s3c24xx_timer, MACHINE_END diff --git a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c index c1a4a1420ea0..67e903a700d3 100644 --- a/arch/arm/mach-s3c2410/mach-smdk2410.c +++ b/arch/arm/mach-s3c2410/mach-smdk2410.c @@ -112,11 +112,13 @@ void __init smdk2410_init_irq(void) MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch * to SMDK2410 */ - MAINTAINER("Jonas Dietsche") - BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) - BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) - MAPIO(smdk2410_map_io) - INITIRQ(smdk2410_init_irq) + /* Maintainer: Jonas Dietsche */ + .phys_ram = S3C2410_SDRAM_PA, + .phys_io = S3C2410_PA_UART, + .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, + .boot_params = S3C2410_SDRAM_PA + 0x100, + .map_io = smdk2410_map_io, + .init_irq = smdk2410_init_irq, .timer = &s3c24xx_timer, MACHINE_END diff --git a/arch/arm/mach-s3c2410/mach-smdk2440.c b/arch/arm/mach-s3c2410/mach-smdk2440.c index 7857176d9bcb..357522106f68 100644 --- a/arch/arm/mach-s3c2410/mach-smdk2440.c +++ b/arch/arm/mach-s3c2410/mach-smdk2440.c @@ -124,9 +124,11 @@ void __init smdk2440_machine_init(void) } MACHINE_START(S3C2440, "SMDK2440") - MAINTAINER("Ben Dooks <ben@fluff.org>") - BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) - BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) + /* Maintainer: Ben Dooks <ben@fluff.org> */ + .phys_ram = S3C2410_SDRAM_PA, + .phys_io = S3C2410_PA_UART, + .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, + .boot_params = S3C2410_SDRAM_PA + 0x100, .init_irq = s3c24xx_init_irq, .map_io = smdk2440_map_io, diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c index 76be074944a0..924e8464c212 100644 --- a/arch/arm/mach-s3c2410/mach-vr1000.c +++ b/arch/arm/mach-s3c2410/mach-vr1000.c @@ -371,16 +371,14 @@ void __init vr1000_map_io(void) usb_simtec_init(); } -void __init vr1000_init_irq(void) -{ - s3c24xx_init_irq(); -} MACHINE_START(VR1000, "Thorcom-VR1000") - MAINTAINER("Ben Dooks <ben@simtec.co.uk>") - BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) - BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) - MAPIO(vr1000_map_io) - INITIRQ(vr1000_init_irq) + /* Maintainer: Ben Dooks <ben@simtec.co.uk> */ + .phys_ram = S3C2410_SDRAM_PA, + .phys_io = S3C2410_PA_UART, + .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, + .boot_params = S3C2410_SDRAM_PA + 0x100, + .map_io = vr1000_map_io, + .init_irq = s3c24xx_init_irq, .timer = &s3c24xx_timer, MACHINE_END diff --git a/arch/arm/mach-s3c2410/pm-simtec.c b/arch/arm/mach-s3c2410/pm-simtec.c new file mode 100644 index 000000000000..2cb798832223 --- /dev/null +++ b/arch/arm/mach-s3c2410/pm-simtec.c @@ -0,0 +1,65 @@ +/* linux/arch/arm/mach-s3c2410/pm-simtec.c + * + * Copyright (c) 2004 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * http://armlinux.simtec.co.uk/ + * + * Power Management helpers for Simtec S3C24XX implementations + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/list.h> +#include <linux/timer.h> +#include <linux/init.h> +#include <linux/device.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <asm/hardware.h> +#include <asm/io.h> + +#include <asm/arch/map.h> +#include <asm/arch/regs-serial.h> +#include <asm/arch/regs-gpio.h> +#include <asm/arch/regs-mem.h> + +#include <asm/mach-types.h> + +#include "pm.h" + +#define COPYRIGHT ", (c) 2005 Simtec Electronics" + +/* pm_simtec_init + * + * enable the power management functions +*/ + +static __init int pm_simtec_init(void) +{ + unsigned long gstatus4; + + /* check which machine we are running on */ + + if (!machine_is_bast() && !machine_is_vr1000()) + return 0; + + printk(KERN_INFO "Simtec Board Power Manangement" COPYRIGHT "\n"); + + gstatus4 = (__raw_readl(S3C2410_BANKCON7) & 0x3) << 30; + gstatus4 |= (__raw_readl(S3C2410_BANKCON6) & 0x3) << 28; + gstatus4 |= (__raw_readl(S3C2410_BANKSIZE) & S3C2410_BANKSIZE_MASK); + + __raw_writel(gstatus4, S3C2410_GSTATUS4); + + return s3c2410_pm_init(); +} + +arch_initcall(pm_simtec_init); diff --git a/arch/arm/mach-s3c2410/time.c b/arch/arm/mach-s3c2410/time.c index 179f0e031af4..765a3a9ae032 100644 --- a/arch/arm/mach-s3c2410/time.c +++ b/arch/arm/mach-s3c2410/time.c @@ -137,8 +137,8 @@ s3c2410_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction s3c2410_timer_irq = { .name = "S3C2410 Timer Tick", - .flags = SA_INTERRUPT, - .handler = s3c2410_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = s3c2410_timer_interrupt, }; /* diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c index bedf88fafe08..4d4d303ee3a8 100644 --- a/arch/arm/mach-sa1100/assabet.c +++ b/arch/arm/mach-sa1100/assabet.c @@ -431,11 +431,13 @@ static void __init assabet_map_io(void) MACHINE_START(ASSABET, "Intel-Assabet") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - BOOT_PARAMS(0xc0000100) - FIXUP(fixup_assabet) - MAPIO(assabet_map_io) - INITIRQ(sa1100_init_irq) + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .fixup = fixup_assabet, + .map_io = assabet_map_io, + .init_irq = sa1100_init_irq, .timer = &sa1100_timer, .init_machine = assabet_init, MACHINE_END diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c index 6a60b497ab42..b6169cb09196 100644 --- a/arch/arm/mach-sa1100/badge4.c +++ b/arch/arm/mach-sa1100/badge4.c @@ -285,9 +285,11 @@ static void __init badge4_map_io(void) } MACHINE_START(BADGE4, "Hewlett-Packard Laboratories BadgePAD 4") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - BOOT_PARAMS(0xc0000100) - MAPIO(badge4_map_io) - INITIRQ(sa1100_init_irq) + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = badge4_map_io, + .init_irq = sa1100_init_irq, .timer = &sa1100_timer, MACHINE_END diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c index f8edde5e7cbf..0aa918e24c31 100644 --- a/arch/arm/mach-sa1100/cerf.c +++ b/arch/arm/mach-sa1100/cerf.c @@ -123,10 +123,12 @@ static void __init cerf_init(void) } MACHINE_START(CERF, "Intrinsyc CerfBoard/CerfCube") - MAINTAINER("support@intrinsyc.com") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - MAPIO(cerf_map_io) - INITIRQ(cerf_init_irq) + /* Maintainer: support@intrinsyc.com */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .map_io = cerf_map_io, + .init_irq = cerf_init_irq, .timer = &sa1100_timer, .init_machine = cerf_init, MACHINE_END diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c index 99287890d396..8cb69113a57c 100644 --- a/arch/arm/mach-sa1100/collie.c +++ b/arch/arm/mach-sa1100/collie.c @@ -184,9 +184,11 @@ static void __init collie_map_io(void) } MACHINE_START(COLLIE, "Sharp-Collie") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - MAPIO(collie_map_io) - INITIRQ(sa1100_init_irq) + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .map_io = collie_map_io, + .init_irq = sa1100_init_irq, .timer = &sa1100_timer, .init_machine = collie_init, MACHINE_END diff --git a/arch/arm/mach-sa1100/cpu-sa1110.c b/arch/arm/mach-sa1100/cpu-sa1110.c index 8d2a89a2ea01..04c94ab6c18b 100644 --- a/arch/arm/mach-sa1100/cpu-sa1110.c +++ b/arch/arm/mach-sa1100/cpu-sa1110.c @@ -271,8 +271,7 @@ static int sa1110_target(struct cpufreq_policy *policy, */ sdram_set_refresh(2); if (!irqs_disabled()) { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(20 * HZ / 1000); + msleep(20); } else { mdelay(20); } diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c index 84c86543501a..e7aa2681ca64 100644 --- a/arch/arm/mach-sa1100/h3600.c +++ b/arch/arm/mach-sa1100/h3600.c @@ -380,10 +380,12 @@ static void __init h3100_map_io(void) } MACHINE_START(H3100, "Compaq iPAQ H3100") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - BOOT_PARAMS(0xc0000100) - MAPIO(h3100_map_io) - INITIRQ(sa1100_init_irq) + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = h3100_map_io, + .init_irq = sa1100_init_irq, .timer = &sa1100_timer, .init_machine = h3xxx_mach_init, MACHINE_END @@ -496,10 +498,12 @@ static void __init h3600_map_io(void) } MACHINE_START(H3600, "Compaq iPAQ H3600") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - BOOT_PARAMS(0xc0000100) - MAPIO(h3600_map_io) - INITIRQ(sa1100_init_irq) + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = h3600_map_io, + .init_irq = sa1100_init_irq, .timer = &sa1100_timer, .init_machine = h3xxx_mach_init, MACHINE_END @@ -727,7 +731,7 @@ static void h3800_IRQ_demux(unsigned int irq, struct irqdesc *desc, struct pt_re static struct irqaction h3800_irq = { .name = "h3800_asic", .handler = h3800_IRQ_demux, - .flags = SA_INTERRUPT, + .flags = SA_INTERRUPT | SA_TIMER, }; u32 kpio_int_shadow = 0; @@ -881,10 +885,12 @@ static void __init h3800_map_io(void) } MACHINE_START(H3800, "Compaq iPAQ H3800") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - BOOT_PARAMS(0xc0000100) - MAPIO(h3800_map_io) - INITIRQ(h3800_init_irq) + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = h3800_map_io, + .init_irq = h3800_init_irq, .timer = &sa1100_timer, .init_machine = h3xxx_mach_init, MACHINE_END diff --git a/arch/arm/mach-sa1100/hackkit.c b/arch/arm/mach-sa1100/hackkit.c index 570841779714..502d65cfe654 100644 --- a/arch/arm/mach-sa1100/hackkit.c +++ b/arch/arm/mach-sa1100/hackkit.c @@ -191,10 +191,12 @@ static void __init hackkit_init(void) */ MACHINE_START(HACKKIT, "HackKit Cpu Board") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - BOOT_PARAMS(0xc0000100) - MAPIO(hackkit_map_io) - INITIRQ(sa1100_init_irq) + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = hackkit_map_io, + .init_irq = sa1100_init_irq, .timer = &sa1100_timer, .init_machine = hackkit_init, MACHINE_END diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c index 6be78291a878..eee3cbc5ec4f 100644 --- a/arch/arm/mach-sa1100/jornada720.c +++ b/arch/arm/mach-sa1100/jornada720.c @@ -97,9 +97,11 @@ static void __init jornada720_map_io(void) } MACHINE_START(JORNADA720, "HP Jornada 720") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - BOOT_PARAMS(0xc0000100) - MAPIO(jornada720_map_io) - INITIRQ(sa1100_init_irq) + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = jornada720_map_io, + .init_irq = sa1100_init_irq, .timer = &sa1100_timer, MACHINE_END diff --git a/arch/arm/mach-sa1100/lart.c b/arch/arm/mach-sa1100/lart.c index 51c08ccfb8db..870b488aeda4 100644 --- a/arch/arm/mach-sa1100/lart.c +++ b/arch/arm/mach-sa1100/lart.c @@ -41,9 +41,11 @@ static void __init lart_map_io(void) } MACHINE_START(LART, "LART") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - BOOT_PARAMS(0xc0000100) - MAPIO(lart_map_io) - INITIRQ(sa1100_init_irq) + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = lart_map_io, + .init_irq = sa1100_init_irq, .timer = &sa1100_timer, MACHINE_END diff --git a/arch/arm/mach-sa1100/pleb.c b/arch/arm/mach-sa1100/pleb.c index 5606bd71b024..e17b58fb9c9c 100644 --- a/arch/arm/mach-sa1100/pleb.c +++ b/arch/arm/mach-sa1100/pleb.c @@ -146,9 +146,11 @@ static void __init pleb_map_io(void) } MACHINE_START(PLEB, "PLEB") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - MAPIO(pleb_map_io) - INITIRQ(sa1100_init_irq) + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .map_io = pleb_map_io, + .init_irq = sa1100_init_irq, .timer = &sa1100_timer, .init_machine = pleb_init, MACHINE_END diff --git a/arch/arm/mach-sa1100/shannon.c b/arch/arm/mach-sa1100/shannon.c index edddd559be02..43a00359fcdd 100644 --- a/arch/arm/mach-sa1100/shannon.c +++ b/arch/arm/mach-sa1100/shannon.c @@ -76,10 +76,12 @@ static void __init shannon_map_io(void) } MACHINE_START(SHANNON, "Shannon (AKA: Tuxscreen)") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - BOOT_PARAMS(0xc0000100) - MAPIO(shannon_map_io) - INITIRQ(sa1100_init_irq) + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = shannon_map_io, + .init_irq = sa1100_init_irq, .timer = &sa1100_timer, .init_machine = shannon_init, MACHINE_END diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c index 8d113d629867..77978586b126 100644 --- a/arch/arm/mach-sa1100/simpad.c +++ b/arch/arm/mach-sa1100/simpad.c @@ -215,10 +215,12 @@ arch_initcall(simpad_init); MACHINE_START(SIMPAD, "Simpad") - MAINTAINER("Holger Freyther") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - BOOT_PARAMS(0xc0000100) - MAPIO(simpad_map_io) - INITIRQ(sa1100_init_irq) + /* Maintainer: Holger Freyther */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = simpad_map_io, + .init_irq = sa1100_init_irq, .timer = &sa1100_timer, MACHINE_END diff --git a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c index 19b0c0fd6377..0eeb3616ffea 100644 --- a/arch/arm/mach-sa1100/time.c +++ b/arch/arm/mach-sa1100/time.c @@ -99,8 +99,8 @@ sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction sa1100_timer_irq = { .name = "SA11xx Timer Tick", - .flags = SA_INTERRUPT, - .handler = sa1100_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = sa1100_timer_interrupt, }; static void __init sa1100_timer_init(void) diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c index a9bc5d0dbd85..e737eae4521f 100644 --- a/arch/arm/mach-shark/core.c +++ b/arch/arm/mach-shark/core.c @@ -24,7 +24,7 @@ static struct plat_serial8250_port serial_platform_data[] = { .iobase = 0x3f8, .irq = 4, .uartclk = 1843200, - .regshift = 2, + .regshift = 0, .iotype = UPIO_PORT, .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, }, @@ -32,7 +32,7 @@ static struct plat_serial8250_port serial_platform_data[] = { .iobase = 0x2f8, .irq = 3, .uartclk = 1843200, - .regshift = 2, + .regshift = 0, .iotype = UPIO_PORT, .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, }, @@ -84,8 +84,8 @@ shark_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction shark_timer_irq = { .name = "Shark Timer Tick", - .flags = SA_INTERRUPT, - .handler = shark_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = shark_timer_interrupt, }; /* @@ -105,10 +105,12 @@ static struct sys_timer shark_timer = { }; MACHINE_START(SHARK, "Shark") - MAINTAINER("Alexander Schulz") - BOOT_MEM(0x08000000, 0x40000000, 0xe0000000) - BOOT_PARAMS(0x08003000) - MAPIO(shark_map_io) - INITIRQ(shark_init_irq) + /* Maintainer: Alexander Schulz */ + .phys_ram = 0x08000000, + .phys_io = 0x40000000, + .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc, + .boot_params = 0x08003000, + .map_io = shark_map_io, + .init_irq = shark_init_irq, .timer = &shark_timer, MACHINE_END diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 6a7cbea5e098..f01c0f8a2bb3 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -33,6 +33,7 @@ #include <asm/mach-types.h> #include <asm/hardware/amba.h> #include <asm/hardware/amba_clcd.h> +#include <asm/hardware/arm_timer.h> #include <asm/hardware/icst307.h> #include <asm/mach/arch.h> @@ -788,38 +789,25 @@ void __init versatile_init(void) */ #define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10) #if TIMER_INTERVAL >= 0x100000 -#define TIMER_RELOAD (TIMER_INTERVAL >> 8) /* Divide by 256 */ -#define TIMER_CTRL 0x88 /* Enable, Clock / 256 */ +#define TIMER_RELOAD (TIMER_INTERVAL >> 8) +#define TIMER_DIVISOR (TIMER_CTRL_DIV256) #define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC) #elif TIMER_INTERVAL >= 0x10000 #define TIMER_RELOAD (TIMER_INTERVAL >> 4) /* Divide by 16 */ -#define TIMER_CTRL 0x84 /* Enable, Clock / 16 */ +#define TIMER_DIVISOR (TIMER_CTRL_DIV16) #define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC) #else #define TIMER_RELOAD (TIMER_INTERVAL) -#define TIMER_CTRL 0x80 /* Enable */ +#define TIMER_DIVISOR (TIMER_CTRL_DIV1) #define TICKS2USECS(x) ((x) / TICKS_PER_uSEC) #endif -#define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable */ - -/* - * What does it look like? - */ -typedef struct TimerStruct { - unsigned long TimerLoad; - unsigned long TimerValue; - unsigned long TimerControl; - unsigned long TimerClear; -} TimerStruct_t; - /* * Returns number of ms since last clock interrupt. Note that interrupts * will have been disabled by do_gettimeoffset() */ static unsigned long versatile_gettimeoffset(void) { - volatile TimerStruct_t *timer0 = (TimerStruct_t *)TIMER0_VA_BASE; unsigned long ticks1, ticks2, status; /* @@ -828,11 +816,11 @@ static unsigned long versatile_gettimeoffset(void) * an interrupt. We get around this by ensuring that the * counter has not reloaded between our two reads. */ - ticks2 = timer0->TimerValue & 0xffff; + ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff; do { ticks1 = ticks2; status = __raw_readl(VA_IC_BASE + VIC_IRQ_RAW_STATUS); - ticks2 = timer0->TimerValue & 0xffff; + ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff; } while (ticks2 > ticks1); /* @@ -859,12 +847,10 @@ static unsigned long versatile_gettimeoffset(void) */ static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE; - write_seqlock(&xtime_lock); // ...clear the interrupt - timer0->TimerClear = 1; + writel(1, TIMER0_VA_BASE + TIMER_INTCLR); timer_tick(regs); @@ -875,8 +861,8 @@ static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id, struct pt_re static struct irqaction versatile_timer_irq = { .name = "Versatile Timer Tick", - .flags = SA_INTERRUPT, - .handler = versatile_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = versatile_timer_interrupt, }; /* @@ -884,31 +870,32 @@ static struct irqaction versatile_timer_irq = { */ static void __init versatile_timer_init(void) { - volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE; - volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE; - volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE; - volatile TimerStruct_t *timer3 = (volatile TimerStruct_t *)TIMER3_VA_BASE; + u32 val; /* * set clock frequency: * VERSATILE_REFCLK is 32KHz * VERSATILE_TIMCLK is 1MHz */ - *(volatile unsigned int *)IO_ADDRESS(VERSATILE_SCTL_BASE) |= - ((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) | - (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel)); + val = readl(IO_ADDRESS(VERSATILE_SCTL_BASE)); + writel((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) | + (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) | + (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) | + (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel) | val, + IO_ADDRESS(VERSATILE_SCTL_BASE)); /* * Initialise to a known state (all timers off) */ - timer0->TimerControl = 0; - timer1->TimerControl = 0; - timer2->TimerControl = 0; - timer3->TimerControl = 0; - - timer0->TimerLoad = TIMER_RELOAD; - timer0->TimerValue = TIMER_RELOAD; - timer0->TimerControl = TIMER_CTRL | 0x40 | TIMER_CTRL_IE; /* periodic + IE */ + writel(0, TIMER0_VA_BASE + TIMER_CTRL); + writel(0, TIMER1_VA_BASE + TIMER_CTRL); + writel(0, TIMER2_VA_BASE + TIMER_CTRL); + writel(0, TIMER3_VA_BASE + TIMER_CTRL); + + writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD); + writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_VALUE); + writel(TIMER_DIVISOR | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC | + TIMER_CTRL_IE, TIMER0_VA_BASE + TIMER_CTRL); /* * Make irqs happen for the system timer diff --git a/arch/arm/mach-versatile/versatile_ab.c b/arch/arm/mach-versatile/versatile_ab.c index d332084586cf..8b0b3bef24ae 100644 --- a/arch/arm/mach-versatile/versatile_ab.c +++ b/arch/arm/mach-versatile/versatile_ab.c @@ -35,11 +35,13 @@ #include "core.h" MACHINE_START(VERSATILE_AB, "ARM-Versatile AB") - MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd") - BOOT_MEM(0x00000000, 0x101f1000, 0xf11f1000) - BOOT_PARAMS(0x00000100) - MAPIO(versatile_map_io) - INITIRQ(versatile_init_irq) + /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ + .phys_ram = 0x00000000, + .phys_io = 0x101f1000, + .io_pg_offst = ((0xf11f1000) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = versatile_map_io, + .init_irq = versatile_init_irq, .timer = &versatile_timer, - INIT_MACHINE(versatile_init) + .init_machine = versatile_init, MACHINE_END diff --git a/arch/arm/mach-versatile/versatile_pb.c b/arch/arm/mach-versatile/versatile_pb.c index 2702099a68f3..7c3078c38916 100644 --- a/arch/arm/mach-versatile/versatile_pb.c +++ b/arch/arm/mach-versatile/versatile_pb.c @@ -99,11 +99,13 @@ static int __init versatile_pb_init(void) arch_initcall(versatile_pb_init); MACHINE_START(VERSATILE_PB, "ARM-Versatile PB") - MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd") - BOOT_MEM(0x00000000, 0x101f1000, 0xf11f1000) - BOOT_PARAMS(0x00000100) - MAPIO(versatile_map_io) - INITIRQ(versatile_init_irq) + /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ + .phys_ram = 0x00000000, + .phys_io = 0x101f1000, + .io_pg_offst = ((0xf11f1000) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = versatile_map_io, + .init_irq = versatile_init_irq, .timer = &versatile_timer, - INIT_MACHINE(versatile_init) + .init_machine = versatile_init, MACHINE_END diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 95606b4a3ba6..afbbeb6f4658 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -101,7 +101,7 @@ config CPU_ARM922T # ARM925T config CPU_ARM925T - bool "Support ARM925T processor" if ARCH_OMAP + bool "Support ARM925T processor" if ARCH_OMAP1 depends on ARCH_OMAP1510 default y if ARCH_OMAP1510 select CPU_32v4 diff --git a/arch/arm/mm/blockops.c b/arch/arm/mm/blockops.c index 806c6eeb1b0c..4f5ee2d08996 100644 --- a/arch/arm/mm/blockops.c +++ b/arch/arm/mm/blockops.c @@ -25,13 +25,14 @@ blk_flush_kern_dcache_page(void *kaddr) { asm( "add r1, r0, %0 \n\ + sub r1, r1, %1 \n\ 1: .word 0xec401f0e @ mcrr p15, 0, r0, r1, c14, 0 @ blocking \n\ mov r0, #0 \n\ mcr p15, 0, r0, c7, c5, 0 \n\ mcr p15, 0, r0, c7, c10, 4 \n\ mov pc, lr" : - : "I" (PAGE_SIZE)); + : "I" (PAGE_SIZE), "I" (L1_CACHE_BYTES)); } /* diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index e25b4fd8412c..65bfe84b6d67 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -372,49 +372,50 @@ do_bad(unsigned long addr, unsigned int fsr, struct pt_regs *regs) static struct fsr_info { int (*fn)(unsigned long addr, unsigned int fsr, struct pt_regs *regs); int sig; + int code; const char *name; } fsr_info[] = { /* * The following are the standard ARMv3 and ARMv4 aborts. ARMv5 * defines these to be "precise" aborts. */ - { do_bad, SIGSEGV, "vector exception" }, - { do_bad, SIGILL, "alignment exception" }, - { do_bad, SIGKILL, "terminal exception" }, - { do_bad, SIGILL, "alignment exception" }, - { do_bad, SIGBUS, "external abort on linefetch" }, - { do_translation_fault, SIGSEGV, "section translation fault" }, - { do_bad, SIGBUS, "external abort on linefetch" }, - { do_page_fault, SIGSEGV, "page translation fault" }, - { do_bad, SIGBUS, "external abort on non-linefetch" }, - { do_bad, SIGSEGV, "section domain fault" }, - { do_bad, SIGBUS, "external abort on non-linefetch" }, - { do_bad, SIGSEGV, "page domain fault" }, - { do_bad, SIGBUS, "external abort on translation" }, - { do_sect_fault, SIGSEGV, "section permission fault" }, - { do_bad, SIGBUS, "external abort on translation" }, - { do_page_fault, SIGSEGV, "page permission fault" }, + { do_bad, SIGSEGV, 0, "vector exception" }, + { do_bad, SIGILL, BUS_ADRALN, "alignment exception" }, + { do_bad, SIGKILL, 0, "terminal exception" }, + { do_bad, SIGILL, BUS_ADRALN, "alignment exception" }, + { do_bad, SIGBUS, 0, "external abort on linefetch" }, + { do_translation_fault, SIGSEGV, SEGV_MAPERR, "section translation fault" }, + { do_bad, SIGBUS, 0, "external abort on linefetch" }, + { do_page_fault, SIGSEGV, SEGV_MAPERR, "page translation fault" }, + { do_bad, SIGBUS, 0, "external abort on non-linefetch" }, + { do_bad, SIGSEGV, SEGV_ACCERR, "section domain fault" }, + { do_bad, SIGBUS, 0, "external abort on non-linefetch" }, + { do_bad, SIGSEGV, SEGV_ACCERR, "page domain fault" }, + { do_bad, SIGBUS, 0, "external abort on translation" }, + { do_sect_fault, SIGSEGV, SEGV_ACCERR, "section permission fault" }, + { do_bad, SIGBUS, 0, "external abort on translation" }, + { do_page_fault, SIGSEGV, SEGV_ACCERR, "page permission fault" }, /* * The following are "imprecise" aborts, which are signalled by bit * 10 of the FSR, and may not be recoverable. These are only * supported if the CPU abort handler supports bit 10. */ - { do_bad, SIGBUS, "unknown 16" }, - { do_bad, SIGBUS, "unknown 17" }, - { do_bad, SIGBUS, "unknown 18" }, - { do_bad, SIGBUS, "unknown 19" }, - { do_bad, SIGBUS, "lock abort" }, /* xscale */ - { do_bad, SIGBUS, "unknown 21" }, - { do_bad, SIGBUS, "imprecise external abort" }, /* xscale */ - { do_bad, SIGBUS, "unknown 23" }, - { do_bad, SIGBUS, "dcache parity error" }, /* xscale */ - { do_bad, SIGBUS, "unknown 25" }, - { do_bad, SIGBUS, "unknown 26" }, - { do_bad, SIGBUS, "unknown 27" }, - { do_bad, SIGBUS, "unknown 28" }, - { do_bad, SIGBUS, "unknown 29" }, - { do_bad, SIGBUS, "unknown 30" }, - { do_bad, SIGBUS, "unknown 31" } + { do_bad, SIGBUS, 0, "unknown 16" }, + { do_bad, SIGBUS, 0, "unknown 17" }, + { do_bad, SIGBUS, 0, "unknown 18" }, + { do_bad, SIGBUS, 0, "unknown 19" }, + { do_bad, SIGBUS, 0, "lock abort" }, /* xscale */ + { do_bad, SIGBUS, 0, "unknown 21" }, + { do_bad, SIGBUS, BUS_OBJERR, "imprecise external abort" }, /* xscale */ + { do_bad, SIGBUS, 0, "unknown 23" }, + { do_bad, SIGBUS, 0, "dcache parity error" }, /* xscale */ + { do_bad, SIGBUS, 0, "unknown 25" }, + { do_bad, SIGBUS, 0, "unknown 26" }, + { do_bad, SIGBUS, 0, "unknown 27" }, + { do_bad, SIGBUS, 0, "unknown 28" }, + { do_bad, SIGBUS, 0, "unknown 29" }, + { do_bad, SIGBUS, 0, "unknown 30" }, + { do_bad, SIGBUS, 0, "unknown 31" } }; void __init @@ -435,15 +436,19 @@ asmlinkage void do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { const struct fsr_info *inf = fsr_info + (fsr & 15) + ((fsr & (1 << 10)) >> 6); + struct siginfo info; if (!inf->fn(addr, fsr, regs)) return; printk(KERN_ALERT "Unhandled fault: %s (0x%03x) at 0x%08lx\n", inf->name, fsr, addr); - force_sig(inf->sig, current); - show_pte(current->mm, addr); - die_if_kernel("Oops", regs, 0); + + info.si_signo = inf->sig; + info.si_errno = 0; + info.si_code = inf->code; + info.si_addr = (void __user *)addr; + notify_die("", regs, &info, fsr, 0); } asmlinkage void diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index c08710b1ff02..edffa47a4b2a 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -437,7 +437,7 @@ void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc) memtable_init(mi); if (mdesc->map_io) mdesc->map_io(); - flush_tlb_all(); + local_flush_tlb_all(); /* * initialise the zones within each node @@ -522,6 +522,69 @@ static inline void free_area(unsigned long addr, unsigned long end, char *s) printk(KERN_INFO "Freeing %s memory: %dK\n", s, size); } +static inline void +free_memmap(int node, unsigned long start_pfn, unsigned long end_pfn) +{ + struct page *start_pg, *end_pg; + unsigned long pg, pgend; + + /* + * Convert start_pfn/end_pfn to a struct page pointer. + */ + start_pg = pfn_to_page(start_pfn); + end_pg = pfn_to_page(end_pfn); + + /* + * Convert to physical addresses, and + * round start upwards and end downwards. + */ + pg = PAGE_ALIGN(__pa(start_pg)); + pgend = __pa(end_pg) & PAGE_MASK; + + /* + * If there are free pages between these, + * free the section of the memmap array. + */ + if (pg < pgend) + free_bootmem_node(NODE_DATA(node), pg, pgend - pg); +} + +/* + * The mem_map array can get very big. Free the unused area of the memory map. + */ +static void __init free_unused_memmap_node(int node, struct meminfo *mi) +{ + unsigned long bank_start, prev_bank_end = 0; + unsigned int i; + + /* + * [FIXME] This relies on each bank being in address order. This + * may not be the case, especially if the user has provided the + * information on the command line. + */ + for (i = 0; i < mi->nr_banks; i++) { + if (mi->bank[i].size == 0 || mi->bank[i].node != node) + continue; + + bank_start = mi->bank[i].start >> PAGE_SHIFT; + if (bank_start < prev_bank_end) { + printk(KERN_ERR "MEM: unordered memory banks. " + "Not freeing memmap.\n"); + break; + } + + /* + * If we had a previous bank, and there is a space + * between the current bank and the previous, free it. + */ + if (prev_bank_end && prev_bank_end != bank_start) + free_memmap(node, prev_bank_end, bank_start); + + prev_bank_end = (mi->bank[i].start + + mi->bank[i].size) >> PAGE_SHIFT; + } +} + /* * mem_init() marks the free areas in the mem_map and tells us how much * memory is free. This is done after various parts of the system have @@ -540,16 +603,12 @@ void __init mem_init(void) max_mapnr = virt_to_page(high_memory) - mem_map; #endif - /* - * We may have non-contiguous memory. - */ - if (meminfo.nr_banks != 1) - create_memmap_holes(&meminfo); - /* this will put all unused low memory onto the freelists */ for_each_online_node(node) { pg_data_t *pgdat = NODE_DATA(node); + free_unused_memmap_node(node, &meminfo); + if (pgdat->node_spanned_pages != 0) totalram_pages += free_all_bootmem_node(pgdat); } diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c index 2c2b93d77d43..b19f00e99a21 100644 --- a/arch/arm/mm/mm-armv.c +++ b/arch/arm/mm/mm-armv.c @@ -169,7 +169,14 @@ pgd_t *get_pgd_slow(struct mm_struct *mm) memzero(new_pgd, FIRST_KERNEL_PGD_NR * sizeof(pgd_t)); + /* + * Copy over the kernel and IO PGD entries + */ init_pgd = pgd_offset_k(0); + memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR, + (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t)); + + clean_dcache_area(new_pgd, PTRS_PER_PGD * sizeof(pgd_t)); if (!vectors_high()) { /* @@ -198,14 +205,6 @@ pgd_t *get_pgd_slow(struct mm_struct *mm) spin_unlock(&mm->page_table_lock); } - /* - * Copy over the kernel and IO PGD entries - */ - memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR, - (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t)); - - clean_dcache_area(new_pgd, PTRS_PER_PGD * sizeof(pgd_t)); - return new_pgd; no_pte: @@ -400,7 +399,7 @@ static void __init build_mem_type_table(void) ecc_mask = 0; } - if (cpu_arch <= CPU_ARCH_ARMv5) { + if (cpu_arch <= CPU_ARCH_ARMv5TEJ) { for (i = 0; i < ARRAY_SIZE(mem_types); i++) { if (mem_types[i].prot_l1) mem_types[i].prot_l1 |= PMD_BIT4; @@ -585,7 +584,7 @@ void setup_mm_for_reboot(char mode) pmdval = (i << PGDIR_SHIFT) | PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT; - if (cpu_arch <= CPU_ARCH_ARMv5) + if (cpu_arch <= CPU_ARCH_ARMv5TEJ) pmdval |= PMD_BIT4; pmd = pmd_off(pgd, i << PGDIR_SHIFT); pmd[0] = __pmd(pmdval); @@ -683,7 +682,7 @@ void __init memtable_init(struct meminfo *mi) } flush_cache_all(); - flush_tlb_all(); + local_flush_tlb_all(); top_pmd = pmd_off_k(0xffff0000); } @@ -698,75 +697,3 @@ void __init iotable_init(struct map_desc *io_desc, int nr) for (i = 0; i < nr; i++) create_mapping(io_desc + i); } - -static inline void -free_memmap(int node, unsigned long start_pfn, unsigned long end_pfn) -{ - struct page *start_pg, *end_pg; - unsigned long pg, pgend; - - /* - * Convert start_pfn/end_pfn to a struct page pointer. - */ - start_pg = pfn_to_page(start_pfn); - end_pg = pfn_to_page(end_pfn); - - /* - * Convert to physical addresses, and - * round start upwards and end downwards. - */ - pg = PAGE_ALIGN(__pa(start_pg)); - pgend = __pa(end_pg) & PAGE_MASK; - - /* - * If there are free pages between these, - * free the section of the memmap array. - */ - if (pg < pgend) - free_bootmem_node(NODE_DATA(node), pg, pgend - pg); -} - -static inline void free_unused_memmap_node(int node, struct meminfo *mi) -{ - unsigned long bank_start, prev_bank_end = 0; - unsigned int i; - - /* - * [FIXME] This relies on each bank being in address order. This - * may not be the case, especially if the user has provided the - * information on the command line. - */ - for (i = 0; i < mi->nr_banks; i++) { - if (mi->bank[i].size == 0 || mi->bank[i].node != node) - continue; - - bank_start = mi->bank[i].start >> PAGE_SHIFT; - if (bank_start < prev_bank_end) { - printk(KERN_ERR "MEM: unordered memory banks. " - "Not freeing memmap.\n"); - break; - } - - /* - * If we had a previous bank, and there is a space - * between the current bank and the previous, free it. - */ - if (prev_bank_end && prev_bank_end != bank_start) - free_memmap(node, prev_bank_end, bank_start); - - prev_bank_end = PAGE_ALIGN(mi->bank[i].start + - mi->bank[i].size) >> PAGE_SHIFT; - } -} - -/* - * The mem_map array can get very big. Free - * the unused area of the memory map. - */ -void __init create_memmap_holes(struct meminfo *mi) -{ - int node; - - for_each_online_node(node) - free_unused_memmap_node(node, mi); -} diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S index 1f325231b9e4..5c0ae5260d1c 100644 --- a/arch/arm/mm/proc-arm1020.S +++ b/arch/arm/mm/proc-arm1020.S @@ -445,14 +445,14 @@ __arm1020_setup: /* * R * .RVI ZFRS BLDP WCAM - * .0.1 1001 ..11 0101 /* FIXME: why no V bit? */ + * .011 1001 ..11 0101 */ .type arm1020_cr1_clear, #object .type arm1020_cr1_set, #object arm1020_cr1_clear: .word 0x593f arm1020_cr1_set: - .word 0x1935 + .word 0x3935 __INITDATA diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S index 142a2c2d6f0b..d69389c4d4ba 100644 --- a/arch/arm/mm/proc-arm1020e.S +++ b/arch/arm/mm/proc-arm1020e.S @@ -427,14 +427,14 @@ __arm1020e_setup: /* * R * .RVI ZFRS BLDP WCAM - * .0.1 1001 ..11 0101 /* FIXME: why no V bit? */ + * .011 1001 ..11 0101 */ .type arm1020e_cr1_clear, #object .type arm1020e_cr1_set, #object arm1020e_cr1_clear: .word 0x5f3f arm1020e_cr1_set: - .word 0x1935 + .word 0x3935 __INITDATA diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index e3d8510f4340..352db98ee269 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S @@ -200,7 +200,7 @@ __v6_setup: mcr p15, 0, r4, c2, c0, 1 @ load TTB1 #ifdef CONFIG_VFP mrc p15, 0, r0, c1, c0, 2 - orr r0, r0, #(3 << 20) + orr r0, r0, #(0xf << 20) mcr p15, 0, r0, c1, c0, 2 @ Enable full access to VFP #endif mrc p15, 0, r0, c1, c0, 0 @ read control register diff --git a/arch/arm/nwfpe/fpa11.h b/arch/arm/nwfpe/fpa11.h index 45cc65426a22..e4a61aea534b 100644 --- a/arch/arm/nwfpe/fpa11.h +++ b/arch/arm/nwfpe/fpa11.h @@ -29,9 +29,7 @@ * stack+task struct. Use the same method as 'current' uses to * reach them. */ -register unsigned long *user_registers asm("sl"); - -#define GET_USERREG() (user_registers) +#define GET_USERREG() ((struct pt_regs *)(THREAD_START_SP + (unsigned long)current_thread_info()) - 1) #include <linux/config.h> #include <linux/thread_info.h> diff --git a/arch/arm/nwfpe/fpmodule.c b/arch/arm/nwfpe/fpmodule.c index a806fea5c3ed..12885f31d347 100644 --- a/arch/arm/nwfpe/fpmodule.c +++ b/arch/arm/nwfpe/fpmodule.c @@ -24,7 +24,6 @@ #include "fpa11.h" #include <linux/module.h> -#include <linux/version.h> #include <linux/config.h> /* XXX */ @@ -133,7 +132,7 @@ void float_raise(signed char flags) printk(KERN_DEBUG "NWFPE: %s[%d] takes exception %08x at %p from %08lx\n", current->comm, current->pid, flags, - __builtin_return_address(0), GET_USERREG()[15]); + __builtin_return_address(0), GET_USERREG()->ARM_pc); #endif /* Keep SoftFloat exception flags up to date. */ diff --git a/arch/arm/nwfpe/fpmodule.inl b/arch/arm/nwfpe/fpmodule.inl index e5f59e9a3022..2c39ad408f22 100644 --- a/arch/arm/nwfpe/fpmodule.inl +++ b/arch/arm/nwfpe/fpmodule.inl @@ -28,8 +28,8 @@ static inline unsigned long readRegister(const unsigned int nReg) for this in this routine. LDF/STF instructions with Rn = PC depend on the PC being correct, as they use PC+8 in their address calculations. */ - unsigned long *userRegisters = GET_USERREG(); - unsigned int val = userRegisters[nReg]; + struct pt_regs *regs = GET_USERREG(); + unsigned int val = regs->uregs[nReg]; if (REG_PC == nReg) val -= 4; return val; @@ -38,8 +38,8 @@ static inline unsigned long readRegister(const unsigned int nReg) static inline void writeRegister(const unsigned int nReg, const unsigned long val) { - unsigned long *userRegisters = GET_USERREG(); - userRegisters[nReg] = val; + struct pt_regs *regs = GET_USERREG(); + regs->uregs[nReg] = val; } static inline unsigned long readCPSR(void) @@ -63,12 +63,12 @@ static inline unsigned long readConditionCodes(void) static inline void writeConditionCodes(const unsigned long val) { - unsigned long *userRegisters = GET_USERREG(); + struct pt_regs *regs = GET_USERREG(); unsigned long rval; /* * Operate directly on userRegisters since * the CPSR may be the PC register itself. */ - rval = userRegisters[REG_CPSR] & ~CC_MASK; - userRegisters[REG_CPSR] = rval | (val & CC_MASK); + rval = regs->ARM_cpsr & ~CC_MASK; + regs->ARM_cpsr = rval | (val & CC_MASK); } diff --git a/arch/arm/oprofile/Makefile b/arch/arm/oprofile/Makefile index ba1a6e9f2b28..8ffb523e6c77 100644 --- a/arch/arm/oprofile/Makefile +++ b/arch/arm/oprofile/Makefile @@ -6,6 +6,6 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ oprofilefs.o oprofile_stats.o \ timer_int.o ) -oprofile-y := $(DRIVER_OBJS) init.o +oprofile-y := $(DRIVER_OBJS) init.o backtrace.o oprofile-$(CONFIG_CPU_XSCALE) += common.o op_model_xscale.o diff --git a/arch/arm/oprofile/backtrace.c b/arch/arm/oprofile/backtrace.c new file mode 100644 index 000000000000..ec58d3e2eb8b --- /dev/null +++ b/arch/arm/oprofile/backtrace.c @@ -0,0 +1,144 @@ +/* + * Arm specific backtracing code for oprofile + * + * Copyright 2005 Openedhand Ltd. + * + * Author: Richard Purdie <rpurdie@openedhand.com> + * + * Based on i386 oprofile backtrace code by John Levon, David Smith + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include <linux/oprofile.h> +#include <linux/sched.h> +#include <linux/mm.h> +#include <asm/ptrace.h> +#include <asm/uaccess.h> + + +/* + * The registers we're interested in are at the end of the variable + * length saved register structure. The fp points at the end of this + * structure so the address of this struct is: + * (struct frame_tail *)(xxx->fp)-1 + */ +struct frame_tail { + struct frame_tail *fp; + unsigned long sp; + unsigned long lr; +} __attribute__((packed)); + + +#ifdef CONFIG_FRAME_POINTER +static struct frame_tail* kernel_backtrace(struct frame_tail *tail) +{ + oprofile_add_trace(tail->lr); + + /* frame pointers should strictly progress back up the stack + * (towards higher addresses) */ + if (tail >= tail->fp) + return NULL; + + return tail->fp-1; +} +#endif + +static struct frame_tail* user_backtrace(struct frame_tail *tail) +{ + struct frame_tail buftail; + + /* hardware pte might not be valid due to dirty/accessed bit emulation + * so we use copy_from_user and benefit from exception fixups */ + if (copy_from_user(&buftail, tail, sizeof(struct frame_tail))) + return NULL; + + oprofile_add_trace(buftail.lr); + + /* frame pointers should strictly progress back up the stack + * (towards higher addresses) */ + if (tail >= buftail.fp) + return NULL; + + return buftail.fp-1; +} + +/* Compare two addresses and see if they're on the same page */ +#define CMP_ADDR_EQUAL(x,y,offset) ((((unsigned long) x) >> PAGE_SHIFT) \ + == ((((unsigned long) y) + offset) >> PAGE_SHIFT)) + +/* check that the page(s) containing the frame tail are present */ +static int pages_present(struct frame_tail *tail) +{ + struct mm_struct * mm = current->mm; + + if (!check_user_page_readable(mm, (unsigned long)tail)) + return 0; + + if (CMP_ADDR_EQUAL(tail, tail, 8)) + return 1; + + if (!check_user_page_readable(mm, ((unsigned long)tail) + 8)) + return 0; + + return 1; +} + +/* + * | | /\ Higher addresses + * | | + * --------------- stack base (address of current_thread_info) + * | thread info | + * . . + * | stack | + * --------------- saved regs->ARM_fp value if valid (frame_tail address) + * . . + * --------------- struct pt_regs stored on stack (struct pt_regs *) + * | | + * . . + * | | + * --------------- %esp + * | | + * | | \/ Lower addresses + * + * Thus, &pt_regs <-> stack base restricts the valid(ish) fp values + */ +static int valid_kernel_stack(struct frame_tail *tail, struct pt_regs *regs) +{ + unsigned long tailaddr = (unsigned long)tail; + unsigned long stack = (unsigned long)regs; + unsigned long stack_base = (stack & ~(THREAD_SIZE - 1)) + THREAD_SIZE; + + return (tailaddr > stack) && (tailaddr < stack_base); +} + +void arm_backtrace(struct pt_regs const *regs, unsigned int depth) +{ + struct frame_tail *tail; + unsigned long last_address = 0; + + tail = ((struct frame_tail *) regs->ARM_fp) - 1; + + if (!user_mode(regs)) { + +#ifdef CONFIG_FRAME_POINTER + while (depth-- && tail && valid_kernel_stack(tail, regs)) { + tail = kernel_backtrace(tail); + } +#endif + return; + } + + while (depth-- && tail && !((unsigned long) tail & 3)) { + if ((!CMP_ADDR_EQUAL(last_address, tail, 0) + || !CMP_ADDR_EQUAL(last_address, tail, 8)) + && !pages_present(tail)) + return; + last_address = (unsigned long) tail; + tail = user_backtrace(tail); + } +} + diff --git a/arch/arm/oprofile/init.c b/arch/arm/oprofile/init.c index cce3d3015eb7..d315a3a86c86 100644 --- a/arch/arm/oprofile/init.c +++ b/arch/arm/oprofile/init.c @@ -20,6 +20,8 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) ret = pmu_init(ops, &op_xscale_spec); #endif + ops->backtrace = arm_backtrace; + return ret; } diff --git a/arch/arm/oprofile/op_arm_model.h b/arch/arm/oprofile/op_arm_model.h index 2d4caf4781ad..2148d07484b7 100644 --- a/arch/arm/oprofile/op_arm_model.h +++ b/arch/arm/oprofile/op_arm_model.h @@ -24,6 +24,8 @@ struct op_arm_model_spec { extern struct op_arm_model_spec op_xscale_spec; #endif +extern void arm_backtrace(struct pt_regs * const regs, unsigned int depth); + extern int __init pmu_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec); extern void pmu_exit(void); #endif /* OP_ARM_MODEL_H */ diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig new file mode 100644 index 000000000000..345365852f8c --- /dev/null +++ b/arch/arm/plat-omap/Kconfig @@ -0,0 +1,112 @@ +if ARCH_OMAP + +menu "TI OMAP Implementations" + +config ARCH_OMAP_OTG + bool + +choice + prompt "OMAP System Type" + default ARCH_OMAP1 + +config ARCH_OMAP1 + bool "TI OMAP1" + +config ARCH_OMAP2 + bool "TI OMAP2" + +endchoice + +comment "OMAP Feature Selections" + +config OMAP_RESET_CLOCKS + bool "Reset unused clocks during boot" + depends on ARCH_OMAP + default n + help + Say Y if you want to reset unused clocks during boot. + This option saves power, but assumes all drivers are + using the clock framework. Broken drivers that do not + yet use clock framework may not work with this option. + If you are booting from another operating system, you + probably do not want this option enabled until your + device drivers work properly. + +config OMAP_MUX + bool "OMAP multiplexing support" + depends on ARCH_OMAP + default y + help + Pin multiplexing support for OMAP boards. If your bootloader + sets the multiplexing correctly, say N. Otherwise, or if unsure, + say Y. + +config OMAP_MUX_DEBUG + bool "Multiplexing debug output" + depends on OMAP_MUX + default n + help + Makes the multiplexing functions print out a lot of debug info. + This is useful if you want to find out the correct values of the + multiplexing registers. + +config OMAP_MUX_WARNINGS + bool "Warn about pins the bootloader didn't set up" + depends on OMAP_MUX + default y + help + Choose Y here to warn whenever driver initialization logic needs + to change the pin multiplexing setup. When there are no warnings + printed, it's safe to deselect OMAP_MUX for your product. + +choice + prompt "System timer" + default OMAP_MPU_TIMER + +config OMAP_MPU_TIMER + bool "Use mpu timer" + help + Select this option if you want to use the OMAP mpu timer. This + timer provides more intra-tick resolution than the 32KHz timer, + but consumes more power. + +config OMAP_32K_TIMER + bool "Use 32KHz timer" + depends on ARCH_OMAP16XX + help + Select this option if you want to enable the OMAP 32KHz timer. + This timer saves power compared to the OMAP_MPU_TIMER, and has + support for no tick during idle. The 32KHz timer provides less + intra-tick resolution than OMAP_MPU_TIMER. The 32KHz timer is + currently only available for OMAP-16xx. + +endchoice + +config OMAP_32K_TIMER_HZ + int "Kernel internal timer frequency for 32KHz timer" + range 32 1024 + depends on OMAP_32K_TIMER + default "128" + help + Kernel internal timer frequency should be a divisor of 32768, + such as 64 or 128. + +choice + prompt "Low-level debug console UART" + depends on ARCH_OMAP + default OMAP_LL_DEBUG_UART1 + +config OMAP_LL_DEBUG_UART1 + bool "UART1" + +config OMAP_LL_DEBUG_UART2 + bool "UART2" + +config OMAP_LL_DEBUG_UART3 + bool "UART3" + +endchoice + +endmenu + +endif diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile new file mode 100644 index 000000000000..531e11af54d4 --- /dev/null +++ b/arch/arm/plat-omap/Makefile @@ -0,0 +1,17 @@ +# +# Makefile for the linux kernel. +# + +# Common support +obj-y := common.o dma.o clock.o mux.o gpio.o mcbsp.o usb.o +obj-m := +obj-n := +obj- := + +# OCPI interconnect support for 1710, 1610 and 5912 +obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o + +# Power Management +obj-$(CONFIG_PM) += pm.o sleep.o + +obj-$(CONFIG_CPU_FREQ) += cpu-omap.o diff --git a/arch/arm/mach-omap/clock.c b/arch/arm/plat-omap/clock.c index e91186b5341a..59d91b3262ba 100644 --- a/arch/arm/mach-omap/clock.c +++ b/arch/arm/plat-omap/clock.c @@ -1,5 +1,5 @@ /* - * linux/arch/arm/mach-omap/clock.c + * linux/arch/arm/plat-omap/clock.c * * Copyright (C) 2004 Nokia corporation * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> @@ -14,6 +14,7 @@ #include <linux/errno.h> #include <linux/err.h> +#include <asm/io.h> #include <asm/semaphore.h> #include <asm/hardware/clock.h> #include <asm/arch/board.h> @@ -25,6 +26,8 @@ static LIST_HEAD(clocks); static DECLARE_MUTEX(clocks_sem); static DEFINE_SPINLOCK(clockfw_lock); static void propagate_rate(struct clk * clk); +/* UART clock function */ +static int set_uart_rate(struct clk * clk, unsigned long rate); /* External clock (MCLK & BCLK) functions */ static int set_ext_clk_rate(struct clk * clk, unsigned long rate); static long round_ext_clk_rate(struct clk * clk, unsigned long rate); @@ -34,7 +37,7 @@ static int select_table_rate(struct clk * clk, unsigned long rate); static long round_to_table_rate(struct clk * clk, unsigned long rate); void clk_setdpll(__u16, __u16); -struct mpu_rate rate_table[] = { +static struct mpu_rate rate_table[] = { /* MPU MHz, xtal MHz, dpll1 MHz, CKCTL, DPLL_CTL * armdiv, dspdiv, dspmmu, tcdiv, perdiv, lcddiv */ @@ -48,7 +51,7 @@ struct mpu_rate rate_table[] = { { 192000000, 19200000, 192000000, 0x050f, 0x2510 }, /* 1/1/2/2/8/8 */ { 192000000, 12000000, 192000000, 0x050f, 0x2810 }, /* 1/1/2/2/8/8 */ { 96000000, 12000000, 192000000, 0x055f, 0x2810 }, /* 2/2/2/2/8/8 */ - { 48000000, 12000000, 192000000, 0x0ccf, 0x2810 }, /* 4/4/4/4/8/8 */ + { 48000000, 12000000, 192000000, 0x0baf, 0x2810 }, /* 4/8/4/4/8/8 */ { 24000000, 12000000, 192000000, 0x0fff, 0x2810 }, /* 8/8/8/8/8/8 */ #endif #if defined(CONFIG_OMAP_ARM_182MHZ) @@ -58,7 +61,7 @@ struct mpu_rate rate_table[] = { { 168000000, 12000000, 168000000, 0x010f, 0x2710 }, /* 1/1/1/2/8/8 */ #endif #if defined(CONFIG_OMAP_ARM_150MHZ) - { 150000000, 12000000, 150000000, 0x150a, 0x2cb0 }, /* 0/0/1/1/2/2 */ + { 150000000, 12000000, 150000000, 0x010a, 0x2cb0 }, /* 1/1/1/2/4/4 */ #endif #if defined(CONFIG_OMAP_ARM_120MHZ) { 120000000, 12000000, 120000000, 0x010a, 0x2510 }, /* 1/1/1/2/4/4 */ @@ -76,19 +79,11 @@ struct mpu_rate rate_table[] = { }; -static void ckctl_recalc(struct clk * clk) -{ - int dsor; - - /* Calculate divisor encoded as 2-bit exponent */ - dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset)); - if (unlikely(clk->rate == clk->parent->rate / dsor)) - return; /* No change, quick exit */ - clk->rate = clk->parent->rate / dsor; - - if (unlikely(clk->flags & RATE_PROPAGATES)) - propagate_rate(clk); -} +static void ckctl_recalc(struct clk * clk); +int __clk_enable(struct clk *clk); +void __clk_disable(struct clk *clk); +void __clk_unuse(struct clk *clk); +int __clk_use(struct clk *clk); static void followparent_recalc(struct clk * clk) @@ -102,6 +97,14 @@ static void watchdog_recalc(struct clk * clk) clk->rate = clk->parent->rate / 14; } +static void uart_recalc(struct clk * clk) +{ + unsigned int val = omap_readl(clk->enable_reg); + if (val & clk->enable_bit) + clk->rate = 48000000; + else + clk->rate = 12000000; +} static struct clk ck_ref = { .name = "ck_ref", @@ -138,7 +141,7 @@ static struct clk arm_ck = { static struct clk armper_ck = { .name = "armper_ck", .parent = &ck_dpll1, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + .flags = CLOCK_IN_OMAP730 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | RATE_CKCTL, .enable_reg = ARM_IDLECT2, .enable_bit = EN_PERCK, @@ -185,7 +188,7 @@ static struct clk armwdt_ck = { static struct clk arminth_ck16xx = { .name = "arminth_ck", .parent = &arm_ck, - .flags = CLOCK_IN_OMAP16XX, + .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED, .recalc = &followparent_recalc, /* Note: On 16xx the frequency can be divided by 2 by programming * ARM_CKCTL:ARM_INTHCK_SEL(14) to 1 @@ -214,6 +217,38 @@ static struct clk dspmmu_ck = { .recalc = &ckctl_recalc, }; +static struct clk dspper_ck = { + .name = "dspper_ck", + .parent = &ck_dpll1, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + RATE_CKCTL | DSP_DOMAIN_CLOCK | VIRTUAL_IO_ADDRESS, + .enable_reg = DSP_IDLECT2, + .enable_bit = EN_PERCK, + .rate_offset = CKCTL_PERDIV_OFFSET, + .recalc = &followparent_recalc, + //.recalc = &ckctl_recalc, +}; + +static struct clk dspxor_ck = { + .name = "dspxor_ck", + .parent = &ck_ref, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + DSP_DOMAIN_CLOCK | VIRTUAL_IO_ADDRESS, + .enable_reg = DSP_IDLECT2, + .enable_bit = EN_XORPCK, + .recalc = &followparent_recalc, +}; + +static struct clk dsptim_ck = { + .name = "dsptim_ck", + .parent = &ck_ref, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + DSP_DOMAIN_CLOCK | VIRTUAL_IO_ADDRESS, + .enable_reg = DSP_IDLECT2, + .enable_bit = EN_DSPTIMCK, + .recalc = &followparent_recalc, +}; + static struct clk tc_ck = { .name = "tc_ck", .parent = &ck_dpll1, @@ -226,7 +261,7 @@ static struct clk tc_ck = { static struct clk arminth_ck1510 = { .name = "arminth_ck", .parent = &tc_ck, - .flags = CLOCK_IN_OMAP1510, + .flags = CLOCK_IN_OMAP1510 | ALWAYS_ENABLED, .recalc = &followparent_recalc, /* Note: On 1510 the frequency follows TC_CK * @@ -237,7 +272,7 @@ static struct clk arminth_ck1510 = { static struct clk tipb_ck = { .name = "tibp_ck", .parent = &tc_ck, - .flags = CLOCK_IN_OMAP1510, + .flags = CLOCK_IN_OMAP1510 | ALWAYS_ENABLED, .recalc = &followparent_recalc, }; @@ -271,14 +306,15 @@ static struct clk tc2_ck = { static struct clk dma_ck = { .name = "dma_ck", .parent = &tc_ck, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + ALWAYS_ENABLED, .recalc = &followparent_recalc, }; static struct clk dma_lcdfree_ck = { .name = "dma_lcdfree_ck", .parent = &tc_ck, - .flags = CLOCK_IN_OMAP16XX, + .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED, .recalc = &followparent_recalc, }; @@ -303,14 +339,14 @@ static struct clk lb_ck = { static struct clk rhea1_ck = { .name = "rhea1_ck", .parent = &tc_ck, - .flags = CLOCK_IN_OMAP16XX, + .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED, .recalc = &followparent_recalc, }; static struct clk rhea2_ck = { .name = "rhea2_ck", .parent = &tc_ck, - .flags = CLOCK_IN_OMAP16XX, + .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED, .recalc = &followparent_recalc, }; @@ -325,43 +361,55 @@ static struct clk lcd_ck = { .recalc = &ckctl_recalc, }; -static struct clk uart1_ck = { +static struct clk uart1_1510 = { + .name = "uart1_ck", + /* Direct from ULPD, no parent */ + .rate = 12000000, + .flags = CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT | ALWAYS_ENABLED, + .enable_reg = MOD_CONF_CTRL_0, + .enable_bit = 29, /* Chooses between 12MHz and 48MHz */ + .set_rate = &set_uart_rate, + .recalc = &uart_recalc, +}; + +static struct clk uart1_16xx = { .name = "uart1_ck", /* Direct from ULPD, no parent */ .rate = 48000000, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | - RATE_FIXED | ENABLE_REG_32BIT, + .flags = CLOCK_IN_OMAP16XX | RATE_FIXED | ENABLE_REG_32BIT, .enable_reg = MOD_CONF_CTRL_0, .enable_bit = 29, - /* (Only on 1510) - * The "enable bit" actually chooses between 48MHz and 12MHz. - */ }; static struct clk uart2_ck = { .name = "uart2_ck", /* Direct from ULPD, no parent */ - .rate = 48000000, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | - RATE_FIXED | ENABLE_REG_32BIT, + .rate = 12000000, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | ENABLE_REG_32BIT, .enable_reg = MOD_CONF_CTRL_0, - .enable_bit = 30, - /* (for both 1510 and 16xx) - * The "enable bit" actually chooses between 48MHz and 12MHz/32kHz. - */ + .enable_bit = 30, /* Chooses between 12MHz and 48MHz */ + .set_rate = &set_uart_rate, + .recalc = &uart_recalc, }; -static struct clk uart3_ck = { +static struct clk uart3_1510 = { + .name = "uart3_ck", + /* Direct from ULPD, no parent */ + .rate = 12000000, + .flags = CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT | ALWAYS_ENABLED, + .enable_reg = MOD_CONF_CTRL_0, + .enable_bit = 31, /* Chooses between 12MHz and 48MHz */ + .set_rate = &set_uart_rate, + .recalc = &uart_recalc, +}; + +static struct clk uart3_16xx = { .name = "uart3_ck", /* Direct from ULPD, no parent */ .rate = 48000000, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | - RATE_FIXED | ENABLE_REG_32BIT, + .flags = CLOCK_IN_OMAP16XX | RATE_FIXED | ENABLE_REG_32BIT, .enable_reg = MOD_CONF_CTRL_0, .enable_bit = 31, - /* (Only on 1510) - * The "enable bit" actually chooses between 48MHz and 12MHz. - */ }; static struct clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */ @@ -480,6 +528,9 @@ static struct clk * onchip_clks[] = { /* CK_GEN2 clocks */ &dsp_ck, &dspmmu_ck, + &dspper_ck, + &dspxor_ck, + &dsptim_ck, /* CK_GEN3 clocks */ &tc_ck, &tipb_ck, @@ -494,9 +545,11 @@ static struct clk * onchip_clks[] = { &rhea2_ck, &lcd_ck, /* ULPD clocks */ - &uart1_ck, + &uart1_1510, + &uart1_16xx, &uart2_ck, - &uart3_ck, + &uart3_1510, + &uart3_16xx, &usb_clko, &usb_hhc_ck1510, &usb_hhc_ck16xx, &mclk_1510, &mclk_16xx, @@ -547,14 +600,34 @@ int __clk_enable(struct clk *clk) return 0; } + if (clk->flags & DSP_DOMAIN_CLOCK) { + __clk_use(&api_ck); + } + if (clk->flags & ENABLE_REG_32BIT) { - regval32 = omap_readl(clk->enable_reg); - regval32 |= (1 << clk->enable_bit); - omap_writel(regval32, clk->enable_reg); + if (clk->flags & VIRTUAL_IO_ADDRESS) { + regval32 = __raw_readl(clk->enable_reg); + regval32 |= (1 << clk->enable_bit); + __raw_writel(regval32, clk->enable_reg); + } else { + regval32 = omap_readl(clk->enable_reg); + regval32 |= (1 << clk->enable_bit); + omap_writel(regval32, clk->enable_reg); + } } else { - regval16 = omap_readw(clk->enable_reg); - regval16 |= (1 << clk->enable_bit); - omap_writew(regval16, clk->enable_reg); + if (clk->flags & VIRTUAL_IO_ADDRESS) { + regval16 = __raw_readw(clk->enable_reg); + regval16 |= (1 << clk->enable_bit); + __raw_writew(regval16, clk->enable_reg); + } else { + regval16 = omap_readw(clk->enable_reg); + regval16 |= (1 << clk->enable_bit); + omap_writew(regval16, clk->enable_reg); + } + } + + if (clk->flags & DSP_DOMAIN_CLOCK) { + __clk_unuse(&api_ck); } return 0; @@ -569,14 +642,34 @@ void __clk_disable(struct clk *clk) if (clk->enable_reg == 0) return; + if (clk->flags & DSP_DOMAIN_CLOCK) { + __clk_use(&api_ck); + } + if (clk->flags & ENABLE_REG_32BIT) { - regval32 = omap_readl(clk->enable_reg); - regval32 &= ~(1 << clk->enable_bit); - omap_writel(regval32, clk->enable_reg); + if (clk->flags & VIRTUAL_IO_ADDRESS) { + regval32 = __raw_readl(clk->enable_reg); + regval32 &= ~(1 << clk->enable_bit); + __raw_writel(regval32, clk->enable_reg); + } else { + regval32 = omap_readl(clk->enable_reg); + regval32 &= ~(1 << clk->enable_bit); + omap_writel(regval32, clk->enable_reg); + } } else { - regval16 = omap_readw(clk->enable_reg); - regval16 &= ~(1 << clk->enable_bit); - omap_writew(regval16, clk->enable_reg); + if (clk->flags & VIRTUAL_IO_ADDRESS) { + regval16 = __raw_readw(clk->enable_reg); + regval16 &= ~(1 << clk->enable_bit); + __raw_writew(regval16, clk->enable_reg); + } else { + regval16 = omap_readw(clk->enable_reg); + regval16 &= ~(1 << clk->enable_bit); + omap_writew(regval16, clk->enable_reg); + } + } + + if (clk->flags & DSP_DOMAIN_CLOCK) { + __clk_unuse(&api_ck); } } @@ -766,6 +859,33 @@ static int calc_dsor_exp(struct clk *clk, unsigned long rate) return dsor_exp; } + +static void ckctl_recalc(struct clk * clk) +{ + int dsor; + + /* Calculate divisor encoded as 2-bit exponent */ + if (clk->flags & DSP_DOMAIN_CLOCK) { + /* The clock control bits are in DSP domain, + * so api_ck is needed for access. + * Note that DSP_CKCTL virt addr = phys addr, so + * we must use __raw_readw() instead of omap_readw(). + */ + __clk_use(&api_ck); + dsor = 1 << (3 & (__raw_readw(DSP_CKCTL) >> clk->rate_offset)); + __clk_unuse(&api_ck); + } else { + dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset)); + } + if (unlikely(clk->rate == clk->parent->rate / dsor)) + return; /* No change, quick exit */ + clk->rate = clk->parent->rate / dsor; + + if (unlikely(clk->flags & RATE_PROPAGATES)) + propagate_rate(clk); +} + + long clk_round_rate(struct clk *clk, unsigned long rate) { int dsor_exp; @@ -826,6 +946,9 @@ static int select_table_rate(struct clk * clk, unsigned long rate) if (!ptr->rate) return -EINVAL; + if (!ptr->rate) + return -EINVAL; + if (unlikely(ck_dpll1.rate == 0)) { omap_writew(ptr->dpllctl_val, DPLL_CTL); ck_dpll1.rate = ptr->pll_rate; @@ -921,6 +1044,23 @@ static unsigned calc_ext_dsor(unsigned long rate) return dsor; } +/* Only needed on 1510 */ +static int set_uart_rate(struct clk * clk, unsigned long rate) +{ + unsigned int val; + + val = omap_readl(clk->enable_reg); + if (rate == 12000000) + val &= ~(1 << clk->enable_bit); + else if (rate == 48000000) + val |= (1 << clk->enable_bit); + else + return -EINVAL; + omap_writel(val, clk->enable_reg); + clk->rate = rate; + + return 0; +} static int set_ext_clk_rate(struct clk * clk, unsigned long rate) { @@ -985,7 +1125,18 @@ void clk_unregister(struct clk *clk) } EXPORT_SYMBOL(clk_unregister); - +#ifdef CONFIG_OMAP_RESET_CLOCKS +/* + * Resets some clocks that may be left on from bootloader, + * but leaves serial clocks on. See also omap_late_clk_reset(). + */ +static inline void omap_early_clk_reset(void) +{ + //omap_writel(0x3 << 29, MOD_CONF_CTRL_0); +} +#else +#define omap_early_clk_reset() {} +#endif int __init clk_init(void) { @@ -993,6 +1144,8 @@ int __init clk_init(void) const struct omap_clock_config *info; int crystal_type = 0; /* Default 12 MHz */ + omap_early_clk_reset(); + for (clkp = onchip_clks; clkp < onchip_clks+ARRAY_SIZE(onchip_clks); clkp++) { if (((*clkp)->flags &CLOCK_IN_OMAP1510) && cpu_is_omap1510()) { clk_register(*clkp); @@ -1023,9 +1176,42 @@ int __init clk_init(void) ck_ref.rate = 19200000; #endif + printk("Clocks: ARM_SYSST: 0x%04x DPLL_CTL: 0x%04x ARM_CKCTL: 0x%04x\n", + omap_readw(ARM_SYSST), omap_readw(DPLL_CTL), + omap_readw(ARM_CKCTL)); + /* We want to be in syncronous scalable mode */ omap_writew(0x1000, ARM_SYSST); +#ifdef CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER + /* Use values set by bootloader. Determine PLL rate and recalculate + * dependent clocks as if kernel had changed PLL or divisors. + */ + { + unsigned pll_ctl_val = omap_readw(DPLL_CTL); + + ck_dpll1.rate = ck_ref.rate; /* Base xtal rate */ + if (pll_ctl_val & 0x10) { + /* PLL enabled, apply multiplier and divisor */ + if (pll_ctl_val & 0xf80) + ck_dpll1.rate *= (pll_ctl_val & 0xf80) >> 7; + ck_dpll1.rate /= ((pll_ctl_val & 0x60) >> 5) + 1; + } else { + /* PLL disabled, apply bypass divisor */ + switch (pll_ctl_val & 0xc) { + case 0: + break; + case 0x4: + ck_dpll1.rate /= 2; + break; + default: + ck_dpll1.rate /= 4; + break; + } + } + } + propagate_rate(&ck_dpll1); +#else /* Find the highest supported frequency and enable it */ if (select_table_rate(&virtual_ck_mpu, ~0)) { printk(KERN_ERR "System frequencies not set. Check your config.\n"); @@ -1034,12 +1220,13 @@ int __init clk_init(void) omap_writew(0x1005, ARM_CKCTL); ck_dpll1.rate = 60000000; propagate_rate(&ck_dpll1); - printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): %ld/%ld/%ld\n", - ck_ref.rate, ck_dpll1.rate, arm_ck.rate); } - +#endif /* Cache rates for clocks connected to ck_ref (not dpll1) */ propagate_rate(&ck_ref); + printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): %ld.%01ld/%ld/%ld MHz\n", + ck_ref.rate / 1000000, (ck_ref.rate / 100000) % 10, + ck_dpll1.rate, arm_ck.rate); #ifdef CONFIG_MACH_OMAP_PERSEUS2 /* Select slicer output as OMAP input clock */ @@ -1074,3 +1261,63 @@ int __init clk_init(void) return 0; } + + +#ifdef CONFIG_OMAP_RESET_CLOCKS + +static int __init omap_late_clk_reset(void) +{ + /* Turn off all unused clocks */ + struct clk *p; + __u32 regval32; + + omap_writew(0, SOFT_REQ_REG); + omap_writew(0, SOFT_REQ_REG2); + + list_for_each_entry(p, &clocks, node) { + if (p->usecount > 0 || (p->flags & ALWAYS_ENABLED) || + p->enable_reg == 0) + continue; + + /* Assume no DSP clocks have been activated by bootloader */ + if (p->flags & DSP_DOMAIN_CLOCK) + continue; + + /* Is the clock already disabled? */ + if (p->flags & ENABLE_REG_32BIT) { + if (p->flags & VIRTUAL_IO_ADDRESS) + regval32 = __raw_readl(p->enable_reg); + else + regval32 = omap_readl(p->enable_reg); + } else { + if (p->flags & VIRTUAL_IO_ADDRESS) + regval32 = __raw_readw(p->enable_reg); + else + regval32 = omap_readw(p->enable_reg); + } + + if ((regval32 & (1 << p->enable_bit)) == 0) + continue; + + /* FIXME: This clock seems to be necessary but no-one + * has asked for its activation. */ + if (p == &tc2_ck // FIX: pm.c (SRAM), CCP, Camera + || p == &ck_dpll1out // FIX: SoSSI, SSR + || p == &arm_gpio_ck // FIX: GPIO code for 1510 + ) { + printk(KERN_INFO "FIXME: Clock \"%s\" seems unused\n", + p->name); + continue; + } + + printk(KERN_INFO "Disabling unused clock \"%s\"... ", p->name); + __clk_disable(p); + printk(" done\n"); + } + + return 0; +} + +late_initcall(omap_late_clk_reset); + +#endif diff --git a/arch/arm/mach-omap/clock.h b/arch/arm/plat-omap/clock.h index 08c0ddde1835..a89e1e8c2519 100644 --- a/arch/arm/mach-omap/clock.h +++ b/arch/arm/plat-omap/clock.h @@ -1,5 +1,5 @@ /* - * linux/arch/arm/mach-omap/clock.h + * linux/arch/arm/plat-omap/clock.h * * Copyright (C) 2004 Nokia corporation * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> @@ -52,6 +52,8 @@ struct mpu_rate { #define CLOCK_IN_OMAP16XX 64 #define CLOCK_IN_OMAP1510 128 #define CLOCK_IN_OMAP730 256 +#define DSP_DOMAIN_CLOCK 512 +#define VIRTUAL_IO_ADDRESS 1024 /* ARM_CKCTL bit shifts */ #define CKCTL_PERDIV_OFFSET 0 @@ -63,6 +65,8 @@ struct mpu_rate { /*#define ARM_TIMXO 12*/ #define EN_DSPCK 13 /*#define ARM_INTHCK_SEL 14*/ /* Divide-by-2 for mpu inth_ck */ +/* DSP_CKCTL bit shifts */ +#define CKCTL_DSPPERDIV_OFFSET 0 /* ARM_IDLECT1 bit shifts */ /*#define IDLWDT_ARM 0*/ @@ -96,6 +100,9 @@ struct mpu_rate { #define EN_TC1_CK 2 #define EN_TC2_CK 4 +/* DSP_IDLECT2 bit shifts (0,1,2 are same as for ARM_IDLECT2) */ +#define EN_DSPTIMCK 5 + /* Various register defines for clock controls scattered around OMAP chip */ #define USB_MCLK_EN_BIT 4 /* In ULPD_CLKC_CTRL */ #define USB_HOST_HHC_UHOST_EN 9 /* In MOD_CONF_CTRL_0 */ @@ -103,7 +110,8 @@ struct mpu_rate { #define COM_ULPD_PLL_CLK_REQ 1 /* In COM_CLK_DIV_CTRL_SEL */ #define SWD_CLK_DIV_CTRL_SEL 0xfffe0874 #define COM_CLK_DIV_CTRL_SEL 0xfffe0878 - +#define SOFT_REQ_REG 0xfffe0834 +#define SOFT_REQ_REG2 0xfffe0880 int clk_register(struct clk *clk); void clk_unregister(struct clk *clk); diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c new file mode 100644 index 000000000000..ea967a8f6ce5 --- /dev/null +++ b/arch/arm/plat-omap/common.c @@ -0,0 +1,135 @@ +/* + * linux/arch/arm/plat-omap/common.c + * + * Code common to all OMAP machines. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/config.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/pm.h> +#include <linux/console.h> +#include <linux/serial.h> +#include <linux/tty.h> +#include <linux/serial_8250.h> +#include <linux/serial_reg.h> + +#include <asm/hardware.h> +#include <asm/system.h> +#include <asm/pgtable.h> +#include <asm/mach/map.h> +#include <asm/hardware/clock.h> +#include <asm/io.h> +#include <asm/mach-types.h> + +#include <asm/arch/board.h> +#include <asm/arch/mux.h> +#include <asm/arch/fpga.h> + +#include "clock.h" + +#define NO_LENGTH_CHECK 0xffffffff + +extern int omap_bootloader_tag_len; +extern u8 omap_bootloader_tag[]; + +struct omap_board_config_kernel *omap_board_config; +int omap_board_config_size = 0; + +static const void *get_config(u16 tag, size_t len, int skip, size_t *len_out) +{ + struct omap_board_config_kernel *kinfo = NULL; + int i; + +#ifdef CONFIG_OMAP_BOOT_TAG + struct omap_board_config_entry *info = NULL; + + if (omap_bootloader_tag_len > 4) + info = (struct omap_board_config_entry *) omap_bootloader_tag; + while (info != NULL) { + u8 *next; + + if (info->tag == tag) { + if (skip == 0) + break; + skip--; + } + + if ((info->len & 0x03) != 0) { + /* We bail out to avoid an alignment fault */ + printk(KERN_ERR "OMAP peripheral config: Length (%d) not word-aligned (tag %04x)\n", + info->len, info->tag); + return NULL; + } + next = (u8 *) info + sizeof(*info) + info->len; + if (next >= omap_bootloader_tag + omap_bootloader_tag_len) + info = NULL; + else + info = (struct omap_board_config_entry *) next; + } + if (info != NULL) { + /* Check the length as a lame attempt to check for + * binary inconsistancy. */ + if (len != NO_LENGTH_CHECK) { + /* Word-align len */ + if (len & 0x03) + len = (len + 3) & ~0x03; + if (info->len != len) { + printk(KERN_ERR "OMAP peripheral config: Length mismatch with tag %x (want %d, got %d)\n", + tag, len, info->len); + return NULL; + } + } + if (len_out != NULL) + *len_out = info->len; + return info->data; + } +#endif + /* Try to find the config from the board-specific structures + * in the kernel. */ + for (i = 0; i < omap_board_config_size; i++) { + if (omap_board_config[i].tag == tag) { + kinfo = &omap_board_config[i]; + break; + } + } + if (kinfo == NULL) + return NULL; + return kinfo->data; +} + +const void *__omap_get_config(u16 tag, size_t len, int nr) +{ + return get_config(tag, len, nr, NULL); +} +EXPORT_SYMBOL(__omap_get_config); + +const void *omap_get_var_config(u16 tag, size_t *len) +{ + return get_config(tag, NO_LENGTH_CHECK, 0, len); +} +EXPORT_SYMBOL(omap_get_var_config); + +static int __init omap_add_serial_console(void) +{ + const struct omap_serial_console_config *info; + + info = omap_get_config(OMAP_TAG_SERIAL_CONSOLE, + struct omap_serial_console_config); + if (info != NULL && info->console_uart) { + static char speed[11], *opt = NULL; + + if (info->console_speed) { + snprintf(speed, sizeof(speed), "%u", info->console_speed); + opt = speed; + } + return add_preferred_console("ttyS", info->console_uart - 1, opt); + } + return 0; +} +console_initcall(omap_add_serial_console); diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c new file mode 100644 index 000000000000..409aac2c4b9d --- /dev/null +++ b/arch/arm/plat-omap/cpu-omap.c @@ -0,0 +1,128 @@ +/* + * linux/arch/arm/plat-omap/cpu-omap.c + * + * CPU frequency scaling for OMAP + * + * Copyright (C) 2005 Nokia Corporation + * Written by Tony Lindgren <tony@atomide.com> + * + * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/cpufreq.h> +#include <linux/delay.h> +#include <linux/init.h> +#include <linux/err.h> + +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/io.h> +#include <asm/system.h> + +#include <asm/hardware/clock.h> + +/* TODO: Add support for SDRAM timing changes */ + +int omap_verify_speed(struct cpufreq_policy *policy) +{ + struct clk * mpu_clk; + + if (policy->cpu) + return -EINVAL; + + cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, + policy->cpuinfo.max_freq); + mpu_clk = clk_get(NULL, "mpu"); + if (IS_ERR(mpu_clk)) + return PTR_ERR(mpu_clk); + policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000; + policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000; + cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, + policy->cpuinfo.max_freq); + clk_put(mpu_clk); + + return 0; +} + +unsigned int omap_getspeed(unsigned int cpu) +{ + struct clk * mpu_clk; + unsigned long rate; + + if (cpu) + return 0; + + mpu_clk = clk_get(NULL, "mpu"); + if (IS_ERR(mpu_clk)) + return 0; + rate = clk_get_rate(mpu_clk) / 1000; + clk_put(mpu_clk); + + return rate; +} + +static int omap_target(struct cpufreq_policy *policy, + unsigned int target_freq, + unsigned int relation) +{ + struct clk * mpu_clk; + struct cpufreq_freqs freqs; + int ret = 0; + + mpu_clk = clk_get(NULL, "mpu"); + if (IS_ERR(mpu_clk)) + return PTR_ERR(mpu_clk); + + freqs.old = omap_getspeed(0); + freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000; + freqs.cpu = 0; + + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + ret = clk_set_rate(mpu_clk, target_freq * 1000); + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + clk_put(mpu_clk); + + return ret; +} + +static int __init omap_cpu_init(struct cpufreq_policy *policy) +{ + struct clk * mpu_clk; + + mpu_clk = clk_get(NULL, "mpu"); + if (IS_ERR(mpu_clk)) + return PTR_ERR(mpu_clk); + + if (policy->cpu != 0) + return -EINVAL; + policy->cur = policy->min = policy->max = omap_getspeed(0); + policy->governor = CPUFREQ_DEFAULT_GOVERNOR; + policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000; + policy->cpuinfo.max_freq = clk_round_rate(mpu_clk, 216000000) / 1000; + policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; + clk_put(mpu_clk); + + return 0; +} + +static struct cpufreq_driver omap_driver = { + .flags = CPUFREQ_STICKY, + .verify = omap_verify_speed, + .target = omap_target, + .get = omap_getspeed, + .init = omap_cpu_init, + .name = "omap", +}; + +static int __init omap_cpufreq_init(void) +{ + return cpufreq_register_driver(&omap_driver); +} + +arch_initcall(omap_cpufreq_init); diff --git a/arch/arm/mach-omap/dma.c b/arch/arm/plat-omap/dma.c index 7a9ebe80d6f8..c0a5c2fa42bd 100644 --- a/arch/arm/mach-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -1,5 +1,5 @@ /* - * linux/arch/arm/omap/dma.c + * linux/arch/arm/plat-omap/dma.c * * Copyright (C) 2003 Nokia Corporation * Author: Juha Yrjölä <juha.yrjola@nokia.com> @@ -794,10 +794,6 @@ static void set_b1_regs(void) w = omap_readw(OMAP1610_DMA_LCD_CTRL); /* Always set the source port as SDRAM for now*/ w &= ~(0x03 << 6); - if (lcd_dma.ext_ctrl) - w |= 1 << 8; - else - w &= ~(1 << 8); if (lcd_dma.callback != NULL) w |= 1 << 1; /* Block interrupt enable */ else @@ -889,9 +885,15 @@ void omap_enable_lcd_dma(void) */ if (enable_1510_mode || !lcd_dma.ext_ctrl) return; + + w = omap_readw(OMAP1610_DMA_LCD_CTRL); + w |= 1 << 8; + omap_writew(w, OMAP1610_DMA_LCD_CTRL); + w = omap_readw(OMAP1610_DMA_LCD_CCR); w |= 1 << 7; omap_writew(w, OMAP1610_DMA_LCD_CCR); + lcd_dma.active = 1; } @@ -922,10 +924,19 @@ void omap_setup_lcd_dma(void) void omap_stop_lcd_dma(void) { + u16 w; + lcd_dma.active = 0; - if (!enable_1510_mode && lcd_dma.ext_ctrl) - omap_writew(omap_readw(OMAP1610_DMA_LCD_CCR) & ~(1 << 7), - OMAP1610_DMA_LCD_CCR); + if (enable_1510_mode || !lcd_dma.ext_ctrl) + return; + + w = omap_readw(OMAP1610_DMA_LCD_CCR); + w &= ~(1 << 7); + omap_writew(w, OMAP1610_DMA_LCD_CCR); + + w = omap_readw(OMAP1610_DMA_LCD_CTRL); + w &= ~(1 << 8); + omap_writew(w, OMAP1610_DMA_LCD_CTRL); } /* @@ -972,6 +983,25 @@ dma_addr_t omap_get_dma_dst_pos(int lch) (OMAP_DMA_CDSA_U(lch) << 16)); } +int omap_dma_running(void) +{ + int lch; + + /* Check if LCD DMA is running */ + if (cpu_is_omap16xx()) + if (omap_readw(OMAP1610_DMA_LCD_CCR) & OMAP_DMA_CCR_EN) + return 1; + + for (lch = 0; lch < dma_chan_count; lch++) { + u16 w; + + w = omap_readw(OMAP_DMA_CCR(lch)); + if (w & OMAP_DMA_CCR_EN) + return 1; + } + return 0; +} + static int __init omap_init_dma(void) { int ch, r; diff --git a/arch/arm/mach-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 9045dfd469ad..1c85b4e536c2 100644 --- a/arch/arm/mach-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -1,5 +1,5 @@ /* - * linux/arch/arm/mach-omap/gpio.c + * linux/arch/arm/plat-omap/gpio.c * * Support functions for OMAP GPIO * diff --git a/arch/arm/mach-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index 7c4ad7713091..43567d5edddb 100644 --- a/arch/arm/mach-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c @@ -1,5 +1,5 @@ /* - * linux/arch/arm/omap/mcbsp.c + * linux/arch/arm/plat-omap/mcbsp.c * * Copyright (C) 2004 Nokia Corporation * Author: Samuel Ortiz <samuel.ortiz@nokia.com> @@ -66,6 +66,7 @@ struct omap_mcbsp { static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT]; static struct clk *mcbsp_dsp_ck = 0; static struct clk *mcbsp_api_ck = 0; +static struct clk *mcbsp_dspxor_ck = 0; static void omap_mcbsp_dump_reg(u8 id) @@ -175,7 +176,7 @@ static int omap_mcbsp_check(unsigned int id) return 0; } - if (cpu_is_omap1510() || cpu_is_omap1610() || cpu_is_omap1710()) { + if (cpu_is_omap1510() || cpu_is_omap16xx()) { if (id > OMAP_MAX_MCBSP_COUNT) { printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1); return -1; @@ -191,15 +192,12 @@ static int omap_mcbsp_check(unsigned int id) static void omap_mcbsp_dsp_request(void) { - if (cpu_is_omap1510() || cpu_is_omap1610() || cpu_is_omap1710()) { - omap_writew((omap_readw(ARM_RSTCT1) | (1 << 1) | (1 << 2)), - ARM_RSTCT1); - clk_enable(mcbsp_dsp_ck); - clk_enable(mcbsp_api_ck); + if (cpu_is_omap1510() || cpu_is_omap16xx()) { + clk_use(mcbsp_dsp_ck); + clk_use(mcbsp_api_ck); /* enable 12MHz clock to mcbsp 1 & 3 */ - __raw_writew(__raw_readw(DSP_IDLECT2) | (1 << EN_XORPCK), - DSP_IDLECT2); + clk_use(mcbsp_dspxor_ck); __raw_writew(__raw_readw(DSP_RSTCT2) | 1 | 1 << 1, DSP_RSTCT2); } @@ -207,10 +205,13 @@ static void omap_mcbsp_dsp_request(void) static void omap_mcbsp_dsp_free(void) { - /* Useless for now */ + if (cpu_is_omap1510() || cpu_is_omap16xx()) { + clk_unuse(mcbsp_dspxor_ck); + clk_unuse(mcbsp_dsp_ck); + clk_unuse(mcbsp_api_ck); + } } - int omap_mcbsp_request(unsigned int id) { int err; @@ -350,6 +351,73 @@ void omap_mcbsp_stop(unsigned int id) } +/* polled mcbsp i/o operations */ +int omap_mcbsp_pollwrite(unsigned int id, u16 buf) +{ + u32 base = mcbsp[id].io_base; + writew(buf, base + OMAP_MCBSP_REG_DXR1); + /* if frame sync error - clear the error */ + if (readw(base + OMAP_MCBSP_REG_SPCR2) & XSYNC_ERR) { + /* clear error */ + writew(readw(base + OMAP_MCBSP_REG_SPCR2) & (~XSYNC_ERR), + base + OMAP_MCBSP_REG_SPCR2); + /* resend */ + return -1; + } else { + /* wait for transmit confirmation */ + int attemps = 0; + while (!(readw(base + OMAP_MCBSP_REG_SPCR2) & XRDY)) { + if (attemps++ > 1000) { + writew(readw(base + OMAP_MCBSP_REG_SPCR2) & + (~XRST), + base + OMAP_MCBSP_REG_SPCR2); + udelay(10); + writew(readw(base + OMAP_MCBSP_REG_SPCR2) | + (XRST), + base + OMAP_MCBSP_REG_SPCR2); + udelay(10); + printk(KERN_ERR + " Could not write to McBSP Register\n"); + return -2; + } + } + } + return 0; +} + +int omap_mcbsp_pollread(unsigned int id, u16 * buf) +{ + u32 base = mcbsp[id].io_base; + /* if frame sync error - clear the error */ + if (readw(base + OMAP_MCBSP_REG_SPCR1) & RSYNC_ERR) { + /* clear error */ + writew(readw(base + OMAP_MCBSP_REG_SPCR1) & (~RSYNC_ERR), + base + OMAP_MCBSP_REG_SPCR1); + /* resend */ + return -1; + } else { + /* wait for recieve confirmation */ + int attemps = 0; + while (!(readw(base + OMAP_MCBSP_REG_SPCR1) & RRDY)) { + if (attemps++ > 1000) { + writew(readw(base + OMAP_MCBSP_REG_SPCR1) & + (~RRST), + base + OMAP_MCBSP_REG_SPCR1); + udelay(10); + writew(readw(base + OMAP_MCBSP_REG_SPCR1) | + (RRST), + base + OMAP_MCBSP_REG_SPCR1); + udelay(10); + printk(KERN_ERR + " Could not read from McBSP Register\n"); + return -2; + } + } + } + *buf = readw(base + OMAP_MCBSP_REG_DRR1); + return 0; +} + /* * IRQ based word transmission. */ @@ -625,10 +693,15 @@ static int __init omap_mcbsp_init(void) return PTR_ERR(mcbsp_dsp_ck); } mcbsp_api_ck = clk_get(0, "api_ck"); - if (IS_ERR(mcbsp_dsp_ck)) { + if (IS_ERR(mcbsp_api_ck)) { printk(KERN_ERR "mcbsp: could not acquire api_ck handle.\n"); return PTR_ERR(mcbsp_api_ck); } + mcbsp_dspxor_ck = clk_get(0, "dspxor_ck"); + if (IS_ERR(mcbsp_dspxor_ck)) { + printk(KERN_ERR "mcbsp: could not acquire dspxor_ck handle.\n"); + return PTR_ERR(mcbsp_dspxor_ck); + } #ifdef CONFIG_ARCH_OMAP730 if (cpu_is_omap730()) { @@ -643,7 +716,7 @@ static int __init omap_mcbsp_init(void) } #endif #if defined(CONFIG_ARCH_OMAP16XX) - if (cpu_is_omap1610() || cpu_is_omap1710()) { + if (cpu_is_omap16xx()) { mcbsp_info = mcbsp_1610; mcbsp_count = ARRAY_SIZE(mcbsp_1610); } diff --git a/arch/arm/mach-omap/mux.c b/arch/arm/plat-omap/mux.c index bcf3c6e5ecd0..ea7b955b9c81 100644 --- a/arch/arm/mach-omap/mux.c +++ b/arch/arm/plat-omap/mux.c @@ -1,5 +1,5 @@ /* - * linux/arch/arm/mach-omap/mux.c + * linux/arch/arm/plat-omap/mux.c * * Utility to set the Omap MUX and PULL_DWN registers from a table in mux.h * @@ -53,19 +53,13 @@ omap_cfg_reg(const reg_cfg_t reg_cfg) return -EINVAL; } - cfg = ®_cfg_table[reg_cfg]; - - /* - * We do a pretty long section here with lock on, but pin muxing - * should only happen on driver init for each driver, so it's not time - * critical. - */ - spin_lock_irqsave(&mux_spin_lock, flags); + cfg = (reg_cfg_set *)®_cfg_table[reg_cfg]; /* Check the mux register in question */ if (cfg->mux_reg) { unsigned tmp1, tmp2; + spin_lock_irqsave(&mux_spin_lock, flags); reg_orig = omap_readl(cfg->mux_reg); /* The mux registers always seem to be 3 bits long */ @@ -80,11 +74,13 @@ omap_cfg_reg(const reg_cfg_t reg_cfg) warn = 1; omap_writel(reg, cfg->mux_reg); + spin_unlock_irqrestore(&mux_spin_lock, flags); } /* Check for pull up or pull down selection on 1610 */ if (!cpu_is_omap1510()) { if (cfg->pu_pd_reg && cfg->pull_val) { + spin_lock_irqsave(&mux_spin_lock, flags); pu_pd_orig = omap_readl(cfg->pu_pd_reg); mask = 1 << cfg->pull_bit; @@ -100,11 +96,13 @@ omap_cfg_reg(const reg_cfg_t reg_cfg) pu_pd = pu_pd_orig & ~mask; } omap_writel(pu_pd, cfg->pu_pd_reg); + spin_unlock_irqrestore(&mux_spin_lock, flags); } } /* Check for an associated pull down register */ if (cfg->pull_reg) { + spin_lock_irqsave(&mux_spin_lock, flags); pull_orig = omap_readl(cfg->pull_reg); mask = 1 << cfg->pull_bit; @@ -121,6 +119,7 @@ omap_cfg_reg(const reg_cfg_t reg_cfg) } omap_writel(pull, cfg->pull_reg); + spin_unlock_irqrestore(&mux_spin_lock, flags); } if (warn) { @@ -149,8 +148,6 @@ omap_cfg_reg(const reg_cfg_t reg_cfg) } #endif - spin_unlock_irqrestore(&mux_spin_lock, flags); - #ifdef CONFIG_OMAP_MUX_ERRORS return warn ? -ETXTBSY : 0; #else diff --git a/arch/arm/mach-omap/ocpi.c b/arch/arm/plat-omap/ocpi.c index c9ced134a75d..2ede2ee8cae4 100644 --- a/arch/arm/mach-omap/ocpi.c +++ b/arch/arm/plat-omap/ocpi.c @@ -1,5 +1,5 @@ /* - * linux/arch/arm/mach-omap/ocpi.c + * linux/arch/arm/plat-omap/ocpi.c * * Minimal OCP bus support for omap16xx * @@ -25,7 +25,6 @@ #include <linux/config.h> #include <linux/module.h> -#include <linux/version.h> #include <linux/types.h> #include <linux/errno.h> #include <linux/kernel.h> diff --git a/arch/arm/mach-omap/pm.c b/arch/arm/plat-omap/pm.c index 00fac155df2a..e6536b16c385 100644 --- a/arch/arm/mach-omap/pm.c +++ b/arch/arm/plat-omap/pm.c @@ -1,5 +1,5 @@ /* - * linux/arch/arm/mach-omap/pm.c + * linux/arch/arm/plat-omap/pm.c * * OMAP Power Management Routines * @@ -41,7 +41,9 @@ #include <linux/pm.h> #include <asm/io.h> +#include <asm/mach/time.h> #include <asm/mach-types.h> + #include <asm/arch/omap16xx.h> #include <asm/arch/pm.h> #include <asm/arch/mux.h> @@ -80,13 +82,13 @@ void omap_pm_idle(void) return; } mask32 = omap_readl(ARM_SYSST); - local_fiq_enable(); - local_irq_enable(); -#if defined(CONFIG_OMAP_32K_TIMER) && defined(CONFIG_NO_IDLE_HZ) - /* Override timer to use VST for the next cycle */ - omap_32k_timer_next_vst_interrupt(); -#endif + /* + * Since an interrupt may set up a timer, we don't want to + * reprogram the hardware timer with interrupts enabled. + * Re-enable interrupts only after returning from idle. + */ + timer_dyn_reprogram(); if ((mask32 & DSP_IDLE) == 0) { __asm__ volatile ("mcr p15, 0, r0, c7, c0, 4"); @@ -102,6 +104,8 @@ void omap_pm_idle(void) func_ptr(); } + local_fiq_enable(); + local_irq_enable(); } /* diff --git a/arch/arm/mach-omap/sleep.S b/arch/arm/plat-omap/sleep.S index 4d426d105828..279490ce772b 100644 --- a/arch/arm/mach-omap/sleep.S +++ b/arch/arm/plat-omap/sleep.S @@ -1,5 +1,5 @@ /* - * linux/arch/arm/mach-omap/sleep.S + * linux/arch/arm/plat-omap/sleep.S * * Low-level OMAP1510/1610 sleep/wakeUp support * diff --git a/arch/arm/mach-omap/usb.c b/arch/arm/plat-omap/usb.c index 6e805d451d0e..25bc4a8dd763 100644 --- a/arch/arm/mach-omap/usb.c +++ b/arch/arm/plat-omap/usb.c @@ -1,5 +1,5 @@ /* - * arch/arm/mach-omap/usb.c -- platform level USB initialization + * arch/arm/plat-omap/usb.c -- platform level USB initialization * * Copyright (C) 2004 Texas Instruments, Inc. * @@ -41,7 +41,6 @@ /* These routines should handle the standard chip-specific modes * for usb0/1/2 ports, covering basic mux and transceiver setup. - * Call omap_usb_init() once, from INIT_MACHINE(). * * Some board-*.c files will need to set up additional mux options, * like for suspend handling, vbus sensing, GPIOs, and the D+ pullup. @@ -288,8 +287,8 @@ static void usb_release(struct device *dev) static struct resource udc_resources[] = { /* order is significant! */ { /* registers */ - .start = IO_ADDRESS(UDC_BASE), - .end = IO_ADDRESS(UDC_BASE + 0xff), + .start = UDC_BASE, + .end = UDC_BASE + 0xff, .flags = IORESOURCE_MEM, }, { /* general IRQ */ .start = IH2_BASE + 20, @@ -327,7 +326,7 @@ static u64 ohci_dmamask = ~(u32)0; static struct resource ohci_resources[] = { { .start = OMAP_OHCI_BASE, - .end = OMAP_OHCI_BASE + 4096, + .end = OMAP_OHCI_BASE + 4096 - 1, .flags = IORESOURCE_MEM, }, { @@ -355,8 +354,8 @@ static struct platform_device ohci_device = { static struct resource otg_resources[] = { /* order is significant! */ { - .start = IO_ADDRESS(OTG_BASE), - .end = IO_ADDRESS(OTG_BASE + 0xff), + .start = OTG_BASE, + .end = OTG_BASE + 0xff, .flags = IORESOURCE_MEM, }, { .start = IH2_BASE + 8, diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index 30c1dfbb052f..6d3a79e5fef8 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: Thu Mar 24 14:34:50 2005 +# Last update: Thu Jun 23 20:19:33 2005 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # @@ -243,7 +243,7 @@ yoho ARCH_YOHO YOHO 231 jasper ARCH_JASPER JASPER 232 dsc25 ARCH_DSC25 DSC25 233 omap_innovator MACH_OMAP_INNOVATOR OMAP_INNOVATOR 234 -ramses ARCH_RAMSES RAMSES 235 +mnci ARCH_RAMSES RAMSES 235 s28x ARCH_S28X S28X 236 mport3 ARCH_MPORT3 MPORT3 237 pxa_eagle250 ARCH_PXA_EAGLE250 PXA_EAGLE250 238 @@ -323,7 +323,7 @@ nimbra29x ARCH_NIMBRA29X NIMBRA29X 311 nimbra210 ARCH_NIMBRA210 NIMBRA210 312 hhp_d95xx ARCH_HHP_D95XX HHP_D95XX 313 labarm ARCH_LABARM LABARM 314 -m825xx ARCH_M825XX M825XX 315 +comcerto ARCH_M825XX M825XX 315 m7100 SA1100_M7100 M7100 316 nipc2 ARCH_NIPC2 NIPC2 317 fu7202 ARCH_FU7202 FU7202 318 @@ -724,3 +724,66 @@ lpc22xx MACH_LPC22XX LPC22XX 715 omap_comet3 MACH_COMET3 COMET3 716 omap_comet4 MACH_COMET4 COMET4 717 csb625 MACH_CSB625 CSB625 718 +fortunet2 MACH_FORTUNET2 FORTUNET2 719 +s5h2200 MACH_S5H2200 S5H2200 720 +optorm920 MACH_OPTORM920 OPTORM920 721 +adsbitsyxb MACH_ADSBITSYXB ADSBITSYXB 722 +adssphere MACH_ADSSPHERE ADSSPHERE 723 +adsportal MACH_ADSPORTAL ADSPORTAL 724 +ln2410sbc MACH_LN2410SBC LN2410SBC 725 +cb3rufc MACH_CB3RUFC CB3RUFC 726 +mp2usb MACH_MP2USB MP2USB 727 +ntnp425c MACH_NTNP425C NTNP425C 728 +colibri MACH_COLIBRI COLIBRI 729 +pcm7220 MACH_PCM7220 PCM7220 730 +gateway7001 MACH_GATEWAY7001 GATEWAY7001 731 +pcm027 MACH_PCM027 PCM027 732 +cmpxa MACH_CMPXA CMPXA 733 +anubis MACH_ANUBIS ANUBIS 734 +ite8152 MACH_ITE8152 ITE8152 735 +lpc3xxx MACH_LPC3XXX LPC3XXX 736 +puppeteer MACH_PUPPETEER PUPPETEER 737 +vt001 MACH_MACH_VADATECH MACH_VADATECH 738 +e570 MACH_E570 E570 739 +x50 MACH_X50 X50 740 +recon MACH_RECON RECON 741 +xboardgp8 MACH_XBOARDGP8 XBOARDGP8 742 +fpic2 MACH_FPIC2 FPIC2 743 +akita MACH_AKITA AKITA 744 +a81 MACH_A81 A81 745 +svm_sc25x MACH_SVM_SC25X SVM_SC25X 746 +vt020 MACH_VADATECH020 VADATECH020 747 +tli MACH_TLI TLI 748 +edb9315lc MACH_EDB9315LC EDB9315LC 749 +passec MACH_PASSEC PASSEC 750 +ds_tiger MACH_DS_TIGER DS_TIGER 751 +e310 MACH_E310 E310 752 +e330 MACH_E330 E330 753 +rt3000 MACH_RT3000 RT3000 754 +nokia770 MACH_NOKIA770 NOKIA770 755 +pnx0106 MACH_PNX0106 PNX0106 756 +hx21xx MACH_HX21XX HX21XX 757 +faraday MACH_FARADAY FARADAY 758 +sbc9312 MACH_SBC9312 SBC9312 759 +batman MACH_BATMAN BATMAN 760 +jpd201 MACH_JPD201 JPD201 761 +mipsa MACH_MIPSA MIPSA 762 +kacom MACH_KACOM KACOM 763 +swarcocpu MACH_SWARCOCPU SWARCOCPU 764 +swarcodsl MACH_SWARCODSL SWARCODSL 765 +blueangel MACH_BLUEANGEL BLUEANGEL 766 +hairygrama MACH_HAIRYGRAMA HAIRYGRAMA 767 +banff MACH_BANFF BANFF 768 +carmeva MACH_CARMEVA CARMEVA 769 +sam255 MACH_SAM255 SAM255 770 +ppm10 MACH_PPM10 PPM10 771 +edb9315a MACH_EDB9315A EDB9315A 772 +sunset MACH_SUNSET SUNSET 773 +stargate2 MACH_STARGATE2 STARGATE2 774 +intelmote2 MACH_INTELMOTE2 INTELMOTE2 775 +trizeps4 MACH_TRIZEPS4 TRIZEPS4 776 +mainstone2 MACH_MAINSTONE2 MAINSTONE2 777 +ez_ixp42x MACH_EZ_IXP42X EZ_IXP42X 778 +tapwave_zodiac MACH_TAPWAVE_ZODIAC TAPWAVE_ZODIAC 779 +universalmeter MACH_UNIVERSALMETER UNIVERSALMETER 780 +hicoarm9 MACH_HICOARM9 HICOARM9 781 diff --git a/arch/arm/vfp/vfp.h b/arch/arm/vfp/vfp.h index 55a02bc994a3..4b97950984e9 100644 --- a/arch/arm/vfp/vfp.h +++ b/arch/arm/vfp/vfp.h @@ -117,7 +117,13 @@ static inline u64 vfp_estimate_div128to64(u64 nh, u64 nl, u64 m) if (nh >= m) return ~0ULL; mh = m >> 32; - z = (mh << 32 <= nh) ? 0xffffffff00000000ULL : (nh / mh) << 32; + if (mh << 32 <= nh) { + z = 0xffffffff00000000ULL; + } else { + z = nh; + do_div(z, mh); + z <<= 32; + } mul64to128(&termh, &terml, m, z); sub128(&remh, &reml, nh, nl, termh, terml); ml = m << 32; @@ -126,7 +132,12 @@ static inline u64 vfp_estimate_div128to64(u64 nh, u64 nl, u64 m) add128(&remh, &reml, remh, reml, mh, ml); } remh = (remh << 32) | (reml >> 32); - z |= (mh << 32 <= remh) ? 0xffffffff : remh / mh; + if (mh << 32 <= remh) { + z |= 0xffffffff; + } else { + do_div(remh, mh); + z |= remh; + } return z; } diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c index fa3053e84db5..b801cd66b6ea 100644 --- a/arch/arm/vfp/vfpdouble.c +++ b/arch/arm/vfp/vfpdouble.c @@ -32,6 +32,8 @@ */ #include <linux/kernel.h> #include <linux/bitops.h> + +#include <asm/div64.h> #include <asm/ptrace.h> #include <asm/vfp.h> diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 3aeedd2afc70..22f3da4e0829 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -89,7 +89,7 @@ void vfp_raise_sigfpe(unsigned int sicode, struct pt_regs *regs) current->thread.error_code = 0; current->thread.trap_no = 6; - force_sig_info(SIGFPE, &info, current); + send_sig_info(SIGFPE, &info, current); } static void vfp_panic(char *reason) diff --git a/arch/arm/vfp/vfpsingle.c b/arch/arm/vfp/vfpsingle.c index 6849fe35cb2e..14dd696ddeb1 100644 --- a/arch/arm/vfp/vfpsingle.c +++ b/arch/arm/vfp/vfpsingle.c @@ -32,6 +32,8 @@ */ #include <linux/kernel.h> #include <linux/bitops.h> + +#include <asm/div64.h> #include <asm/ptrace.h> #include <asm/vfp.h> @@ -303,7 +305,11 @@ u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand) if (z <= a) return (s32)a >> 1; } - return (u32)(((u64)a << 31) / z) + (z >> 1); + { + u64 v = (u64)a << 31; + do_div(v, z); + return v + (z >> 1); + } } static u32 vfp_single_fsqrt(int sd, int unused, s32 m, u32 fpscr) @@ -1107,7 +1113,11 @@ static u32 vfp_single_fdiv(int sd, int sn, s32 m, u32 fpscr) vsn.significand >>= 1; vsd.exponent++; } - vsd.significand = ((u64)vsn.significand << 32) / vsm.significand; + { + u64 significand = (u64)vsn.significand << 32; + do_div(significand, vsm.significand); + vsd.significand = significand; + } if ((vsd.significand & 0x3f) == 0) vsd.significand |= ((u64)vsm.significand * vsd.significand != (u64)vsn.significand << 32); diff --git a/arch/arm26/Kconfig b/arch/arm26/Kconfig index dc0c1936969b..1f0373267306 100644 --- a/arch/arm26/Kconfig +++ b/arch/arm26/Kconfig @@ -183,6 +183,8 @@ source "mm/Kconfig" endmenu +source "net/Kconfig" + source "drivers/base/Kconfig" source "drivers/parport/Kconfig" @@ -193,7 +195,7 @@ source "drivers/block/Kconfig" source "drivers/md/Kconfig" -source "net/Kconfig" +source "drivers/net/Kconfig" source "drivers/ide/Kconfig" diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig index f848e3761491..e5979d68e352 100644 --- a/arch/cris/Kconfig +++ b/arch/cris/Kconfig @@ -122,6 +122,8 @@ source arch/cris/arch-v10/Kconfig endmenu +source "net/Kconfig" + # bring in ETRAX built-in drivers menu "Drivers for built-in interfaces" source arch/cris/arch-v10/drivers/Kconfig @@ -149,7 +151,7 @@ source "drivers/ieee1394/Kconfig" source "drivers/message/i2o/Kconfig" -source "net/Kconfig" +source "drivers/net/Kconfig" source "drivers/isdn/Kconfig" diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig index c93f95146cc2..ec85c0d6c6da 100644 --- a/arch/frv/Kconfig +++ b/arch/frv/Kconfig @@ -346,6 +346,8 @@ source "fs/Kconfig.binfmt" endmenu +source "net/Kconfig" + source "drivers/Kconfig" source "fs/Kconfig" diff --git a/arch/frv/defconfig b/arch/frv/defconfig new file mode 100644 index 000000000000..b6e4ca5efb59 --- /dev/null +++ b/arch/frv/defconfig @@ -0,0 +1,627 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.11.8 +# Fri May 13 17:16:03 2005 +# +CONFIG_FRV=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +# CONFIG_GENERIC_CALIBRATE_DELAY is not set +# CONFIG_GENERIC_HARDIRQS is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +# CONFIG_KOBJECT_UEVENT is not set +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# Fujitsu FR-V system setup +# +CONFIG_MMU=y +CONFIG_FRV_OUTOFLINE_ATOMIC_OPS=y +CONFIG_HIGHMEM=y +CONFIG_HIGHPTE=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_FRV_DEFL_CACHE_WBACK is not set +# CONFIG_FRV_DEFL_CACHE_WBEHIND is not set +CONFIG_FRV_DEFL_CACHE_WTHRU=y +# CONFIG_FRV_DEFL_CACHE_DISABLED is not set + +# +# CPU core support +# +CONFIG_CPU_FR451=y +CONFIG_CPU_FR451_COMPILE=y +CONFIG_FRV_L1_CACHE_SHIFT=5 +CONFIG_MB93091_VDK=y +# CONFIG_MB93093_PDK is not set +CONFIG_MB93090_MB00=y +# CONFIG_MB93091_NO_MB is not set +# CONFIG_GPREL_DATA_8 is not set +CONFIG_GPREL_DATA_4=y +# CONFIG_GPREL_DATA_NONE is not set +CONFIG_PCI=y +# CONFIG_PCI_LEGACY_PROC is not set +# CONFIG_PCI_NAMES is not set +# CONFIG_PCI_DEBUG is not set +# CONFIG_PCMCIA is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Executable formats +# +# CONFIG_BINFMT_ELF is not set +CONFIG_BINFMT_ELF_FDPIC=y +# CONFIG_BINFMT_MISC is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +# CONFIG_STANDALONE is not set +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set +# CONFIG_FORK_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_RAM is not set +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_IP_TCPDIAG is not set +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_KGDBOE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NETPOLL_RX is not set +# CONFIG_NETPOLL_TRAP is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_DGRS is not set +# CONFIG_EEPRO100 is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +CONFIG_NE2K_PCI=y +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SKGE is not set +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_CHELSIO_T1 is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=1 +CONFIG_SERIAL_8250_EXTENDED=y +# CONFIG_SERIAL_8250_MANY_PORTS is not set +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_MULTIPORT is not set +# CONFIG_SERIAL_8250_RSA is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISER4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_PROC_KCORE is not set +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_RELAYFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_MAGIC_SYSRQ is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_HIGHMEM is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_FRAME_POINTER is not set +# CONFIG_EARLY_PRINTK is not set +CONFIG_DEBUG_STACKOVERFLOW=y +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_GDBSTUB is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set diff --git a/arch/frv/mb93090-mb00/pci-irq.c b/arch/frv/mb93090-mb00/pci-irq.c index 24622d89b1ca..af981bda015c 100644 --- a/arch/frv/mb93090-mb00/pci-irq.c +++ b/arch/frv/mb93090-mb00/pci-irq.c @@ -60,7 +60,7 @@ void __init pcibios_fixup_irqs(void) } } -void __init pcibios_penalize_isa_irq(int irq) +void __init pcibios_penalize_isa_irq(int irq, int active) { } diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig index 62a89e812e3e..26698a49f153 100644 --- a/arch/h8300/Kconfig +++ b/arch/h8300/Kconfig @@ -55,6 +55,8 @@ source "fs/Kconfig.binfmt" endmenu +source "net/Kconfig" + source "drivers/base/Kconfig" source "drivers/mtd/Kconfig" @@ -65,7 +67,7 @@ source "drivers/ide/Kconfig" source "arch/h8300/Kconfig.ide" -source "net/Kconfig" +source "drivers/net/Kconfig" # # input - input/joystick depends on it. As does USB. @@ -179,6 +181,8 @@ source "drivers/serial/Kconfig" source "drivers/i2c/Kconfig" +source "drivers/hwmon/Kconfig" + source "drivers/usb/Kconfig" endmenu diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index 6c02336fe2e4..a801d9d48606 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -1285,6 +1285,8 @@ source "fs/Kconfig.binfmt" endmenu +source "net/Kconfig" + source "drivers/Kconfig" source "fs/Kconfig" diff --git a/arch/i386/boot/tools/build.c b/arch/i386/boot/tools/build.c index 4a17956512e1..6835f6d47c31 100644 --- a/arch/i386/boot/tools/build.c +++ b/arch/i386/boot/tools/build.c @@ -70,7 +70,8 @@ void usage(void) int main(int argc, char ** argv) { - unsigned int i, c, sz, setup_sectors; + unsigned int i, sz, setup_sectors; + int c; u32 sys_size; byte major_root, minor_root; struct stat sb; diff --git a/arch/i386/kernel/acpi/Makefile b/arch/i386/kernel/acpi/Makefile index ee75cb286cfe..5e291a20c03d 100644 --- a/arch/i386/kernel/acpi/Makefile +++ b/arch/i386/kernel/acpi/Makefile @@ -2,3 +2,7 @@ obj-$(CONFIG_ACPI_BOOT) := boot.o obj-$(CONFIG_X86_IO_APIC) += earlyquirk.o obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup.o +ifneq ($(CONFIG_ACPI_PROCESSOR),) +obj-y += cstate.o +endif + diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index 9f63ae0f404b..b7808a89d945 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c @@ -159,9 +159,15 @@ char *__acpi_map_table(unsigned long phys, unsigned long size) #endif #ifdef CONFIG_PCI_MMCONFIG -static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) +/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ +struct acpi_table_mcfg_config *pci_mmcfg_config; +int pci_mmcfg_config_num; + +int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) { struct acpi_table_mcfg *mcfg; + unsigned long i; + int config_size; if (!phys_addr || !size) return -EINVAL; @@ -172,18 +178,38 @@ static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) return -ENODEV; } - if (mcfg->base_reserved) { - printk(KERN_ERR PREFIX "MMCONFIG not in low 4GB of memory\n"); + /* how many config structures do we have */ + pci_mmcfg_config_num = 0; + i = size - sizeof(struct acpi_table_mcfg); + while (i >= sizeof(struct acpi_table_mcfg_config)) { + ++pci_mmcfg_config_num; + i -= sizeof(struct acpi_table_mcfg_config); + }; + if (pci_mmcfg_config_num == 0) { + printk(KERN_ERR PREFIX "MMCONFIG has no entries\n"); return -ENODEV; } - pci_mmcfg_base_addr = mcfg->base_address; + config_size = pci_mmcfg_config_num * sizeof(*pci_mmcfg_config); + pci_mmcfg_config = kmalloc(config_size, GFP_KERNEL); + if (!pci_mmcfg_config) { + printk(KERN_WARNING PREFIX + "No memory for MCFG config tables\n"); + return -ENOMEM; + } + + memcpy(pci_mmcfg_config, &mcfg->config, config_size); + for (i = 0; i < pci_mmcfg_config_num; ++i) { + if (mcfg->config[i].base_reserved) { + printk(KERN_ERR PREFIX + "MMCONFIG not in low 4GB of memory\n"); + return -ENODEV; + } + } return 0; } -#else -#define acpi_parse_mcfg NULL -#endif /* !CONFIG_PCI_MMCONFIG */ +#endif /* CONFIG_PCI_MMCONFIG */ #ifdef CONFIG_X86_LOCAL_APIC static int __init @@ -507,6 +533,22 @@ acpi_unmap_lsapic(int cpu) EXPORT_SYMBOL(acpi_unmap_lsapic); #endif /* CONFIG_ACPI_HOTPLUG_CPU */ +int +acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base) +{ + /* TBD */ + return -EINVAL; +} +EXPORT_SYMBOL(acpi_register_ioapic); + +int +acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base) +{ + /* TBD */ + return -EINVAL; +} +EXPORT_SYMBOL(acpi_unregister_ioapic); + static unsigned long __init acpi_scan_rsdp ( unsigned long start, @@ -1123,7 +1165,6 @@ int __init acpi_boot_init(void) acpi_process_madt(); acpi_table_parse(ACPI_HPET, acpi_parse_hpet); - acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); return 0; } diff --git a/arch/i386/kernel/acpi/cstate.c b/arch/i386/kernel/acpi/cstate.c new file mode 100644 index 000000000000..4c3036ba65df --- /dev/null +++ b/arch/i386/kernel/acpi/cstate.c @@ -0,0 +1,103 @@ +/* + * arch/i386/kernel/acpi/cstate.c + * + * Copyright (C) 2005 Intel Corporation + * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> + * - Added _PDC for SMP C-states on Intel CPUs + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/acpi.h> + +#include <acpi/processor.h> +#include <asm/acpi.h> + +static void acpi_processor_power_init_intel_pdc(struct acpi_processor_power + *pow) +{ + struct acpi_object_list *obj_list; + union acpi_object *obj; + u32 *buf; + + /* allocate and initialize pdc. It will be used later. */ + obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL); + if (!obj_list) { + printk(KERN_ERR "Memory allocation error\n"); + return; + } + + obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL); + if (!obj) { + printk(KERN_ERR "Memory allocation error\n"); + kfree(obj_list); + return; + } + + buf = kmalloc(12, GFP_KERNEL); + if (!buf) { + printk(KERN_ERR "Memory allocation error\n"); + kfree(obj); + kfree(obj_list); + return; + } + + buf[0] = ACPI_PDC_REVISION_ID; + buf[1] = 1; + buf[2] = ACPI_PDC_C_CAPABILITY_SMP; + + obj->type = ACPI_TYPE_BUFFER; + obj->buffer.length = 12; + obj->buffer.pointer = (u8 *) buf; + obj_list->count = 1; + obj_list->pointer = obj; + pow->pdc = obj_list; + + return; +} + +/* Initialize _PDC data based on the CPU vendor */ +void acpi_processor_power_init_pdc(struct acpi_processor_power *pow, + unsigned int cpu) +{ + struct cpuinfo_x86 *c = cpu_data + cpu; + + pow->pdc = NULL; + if (c->x86_vendor == X86_VENDOR_INTEL) + acpi_processor_power_init_intel_pdc(pow); + + return; +} + +EXPORT_SYMBOL(acpi_processor_power_init_pdc); + +/* + * Initialize bm_flags based on the CPU cache properties + * On SMP it depends on cache configuration + * - When cache is not shared among all CPUs, we flush cache + * before entering C3. + * - When cache is shared among all CPUs, we use bm_check + * mechanism as in UP case + * + * This routine is called only after all the CPUs are online + */ +void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags, + unsigned int cpu) +{ + struct cpuinfo_x86 *c = cpu_data + cpu; + + flags->bm_check = 0; + if (num_online_cpus() == 1) + flags->bm_check = 1; + else if (c->x86_vendor == X86_VENDOR_INTEL) { + /* + * Today all CPUs that support C3 share cache. + * TBD: This needs to look at cache shared map, once + * multi-core detection patch makes to the base. + */ + flags->bm_check = 1; + } +} + +EXPORT_SYMBOL(acpi_processor_power_init_bm_check); diff --git a/arch/i386/kernel/acpi/wakeup.S b/arch/i386/kernel/acpi/wakeup.S index 39d32484f6f5..44d886c745ec 100644 --- a/arch/i386/kernel/acpi/wakeup.S +++ b/arch/i386/kernel/acpi/wakeup.S @@ -74,8 +74,9 @@ wakeup_code: movw %ax,%fs movw $0x0e00 + 'i', %fs:(0x12) - # need a gdt - lgdt real_save_gdt - wakeup_code + # need a gdt -- use lgdtl to force 32-bit operands, in case + # the GDT is located past 16 megabytes. + lgdtl real_save_gdt - wakeup_code movl real_save_cr0 - wakeup_code, %eax movl %eax, %cr0 diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index 93df90bbb87e..bd1dbf3bd223 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c @@ -35,6 +35,7 @@ #include <asm/desc.h> #include <asm/arch_hooks.h> #include <asm/hpet.h> +#include <asm/i8253.h> #include <mach_apic.h> @@ -879,7 +880,6 @@ fake_ioapic_page: */ static unsigned int __devinit get_8254_timer_count(void) { - extern spinlock_t i8253_lock; unsigned long flags; unsigned int count; diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index d48ce9290963..064211d5f41b 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c @@ -228,10 +228,10 @@ #include <asm/system.h> #include <asm/uaccess.h> #include <asm/desc.h> +#include <asm/i8253.h> #include "io_ports.h" -extern spinlock_t i8253_lock; extern unsigned long get_cmos_time(void); extern void machine_real_restart(unsigned char *, int); @@ -1168,8 +1168,7 @@ static void get_time_diff(void) static void reinit_timer(void) { #ifdef INIT_TIMER_AFTER_SUSPEND - unsigned long flags; - extern spinlock_t i8253_lock; + unsigned long flags; spin_lock_irqsave(&i8253_lock, flags); /* set the clock to 100 Hz */ diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index 2203a9d20212..4553ffd94b1f 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c @@ -435,6 +435,11 @@ void __devinit identify_cpu(struct cpuinfo_x86 *c) if (c == &boot_cpu_data) sysenter_setup(); enable_sep_cpu(); + + if (c == &boot_cpu_data) + mtrr_bp_init(); + else + mtrr_ap_init(); } #ifdef CONFIG_X86_HT diff --git a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c index 1a49adb1f4a6..e86ea486c311 100644 --- a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c +++ b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c @@ -190,7 +190,7 @@ static __init struct pci_dev *gx_detect_chipset(void) /* detect which companion chip is used */ while ((gx_pci = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, gx_pci)) != NULL) { - if ((pci_match_device (gx_chipset_tbl, gx_pci)) != NULL) { + if ((pci_match_id(gx_chipset_tbl, gx_pci)) != NULL) { return gx_pci; } } diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c index 7dcbf70fc16f..327a55d4d1c6 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c @@ -375,7 +375,7 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy) arg0.buffer.pointer = (u8 *) arg0_buf; arg0_buf[0] = ACPI_PDC_REVISION_ID; arg0_buf[1] = 1; - arg0_buf[2] = ACPI_PDC_EST_CAPABILITY_SMP | ACPI_PDC_EST_CAPABILITY_MSR; + arg0_buf[2] = ACPI_PDC_EST_CAPABILITY_SMP_MSR; p.pdc = &arg_list; diff --git a/arch/i386/kernel/cpu/intel.c b/arch/i386/kernel/cpu/intel.c index 96a75d045835..a2c33c1a46c5 100644 --- a/arch/i386/kernel/cpu/intel.c +++ b/arch/i386/kernel/cpu/intel.c @@ -25,7 +25,7 @@ extern int trap_init_f00f_bug(void); /* * Alignment at which movsl is preferred for bulk memory copies. */ -struct movsl_mask movsl_mask; +struct movsl_mask movsl_mask __read_mostly; #endif void __devinit early_intel_workaround(struct cpuinfo_x86 *c) diff --git a/arch/i386/kernel/cpu/mtrr/generic.c b/arch/i386/kernel/cpu/mtrr/generic.c index 64d91f73a0a4..169ac8e0db68 100644 --- a/arch/i386/kernel/cpu/mtrr/generic.c +++ b/arch/i386/kernel/cpu/mtrr/generic.c @@ -67,13 +67,6 @@ void __init get_mtrr_state(void) mtrr_state.enabled = (lo & 0xc00) >> 10; } -/* Free resources associated with a struct mtrr_state */ -void __init finalize_mtrr_state(void) -{ - kfree(mtrr_state.var_ranges); - mtrr_state.var_ranges = NULL; -} - /* Some BIOS's are fucked and don't set all MTRRs the same! */ void __init mtrr_state_warn(void) { @@ -334,6 +327,9 @@ static void generic_set_mtrr(unsigned int reg, unsigned long base, */ { unsigned long flags; + struct mtrr_var_range *vr; + + vr = &mtrr_state.var_ranges[reg]; local_irq_save(flags); prepare_set(); @@ -342,11 +338,15 @@ static void generic_set_mtrr(unsigned int reg, unsigned long base, /* The invalid bit is kept in the mask, so we simply clear the relevant mask register to disable a range. */ mtrr_wrmsr(MTRRphysMask_MSR(reg), 0, 0); + memset(vr, 0, sizeof(struct mtrr_var_range)); } else { - mtrr_wrmsr(MTRRphysBase_MSR(reg), base << PAGE_SHIFT | type, - (base & size_and_mask) >> (32 - PAGE_SHIFT)); - mtrr_wrmsr(MTRRphysMask_MSR(reg), -size << PAGE_SHIFT | 0x800, - (-size & size_and_mask) >> (32 - PAGE_SHIFT)); + vr->base_lo = base << PAGE_SHIFT | type; + vr->base_hi = (base & size_and_mask) >> (32 - PAGE_SHIFT); + vr->mask_lo = -size << PAGE_SHIFT | 0x800; + vr->mask_hi = (-size & size_and_mask) >> (32 - PAGE_SHIFT); + + mtrr_wrmsr(MTRRphysBase_MSR(reg), vr->base_lo, vr->base_hi); + mtrr_wrmsr(MTRRphysMask_MSR(reg), vr->mask_lo, vr->mask_hi); } post_set(); diff --git a/arch/i386/kernel/cpu/mtrr/main.c b/arch/i386/kernel/cpu/mtrr/main.c index d66b09e0c820..764cac64e211 100644 --- a/arch/i386/kernel/cpu/mtrr/main.c +++ b/arch/i386/kernel/cpu/mtrr/main.c @@ -332,6 +332,8 @@ int mtrr_add_page(unsigned long base, unsigned long size, error = -EINVAL; + /* No CPU hotplug when we change MTRR entries */ + lock_cpu_hotplug(); /* Search for existing MTRR */ down(&main_lock); for (i = 0; i < num_var_ranges; ++i) { @@ -372,6 +374,7 @@ int mtrr_add_page(unsigned long base, unsigned long size, error = i; out: up(&main_lock); + unlock_cpu_hotplug(); return error; } @@ -461,6 +464,8 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size) return -ENXIO; max = num_var_ranges; + /* No CPU hotplug when we change MTRR entries */ + lock_cpu_hotplug(); down(&main_lock); if (reg < 0) { /* Search for existing MTRR */ @@ -501,6 +506,7 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size) error = reg; out: up(&main_lock); + unlock_cpu_hotplug(); return error; } /** @@ -544,21 +550,9 @@ static void __init init_ifs(void) centaur_init_mtrr(); } -static void __init init_other_cpus(void) -{ - if (use_intel()) - get_mtrr_state(); - - /* bring up the other processors */ - set_mtrr(~0U,0,0,0); - - if (use_intel()) { - finalize_mtrr_state(); - mtrr_state_warn(); - } -} - - +/* The suspend/resume methods are only for CPU without MTRR. CPU using generic + * MTRR driver doesn't require this + */ struct mtrr_value { mtrr_type ltype; unsigned long lbase; @@ -611,13 +605,13 @@ static struct sysdev_driver mtrr_sysdev_driver = { /** - * mtrr_init - initialize mtrrs on the boot CPU + * mtrr_bp_init - initialize mtrrs on the boot CPU * * This needs to be called early; before any of the other CPUs are * initialized (i.e. before smp_init()). * */ -static int __init mtrr_init(void) +void __init mtrr_bp_init(void) { init_ifs(); @@ -674,12 +668,48 @@ static int __init mtrr_init(void) if (mtrr_if) { set_num_var_ranges(); init_table(); - init_other_cpus(); - - return sysdev_driver_register(&cpu_sysdev_class, - &mtrr_sysdev_driver); + if (use_intel()) + get_mtrr_state(); } - return -ENXIO; } -subsys_initcall(mtrr_init); +void mtrr_ap_init(void) +{ + unsigned long flags; + + if (!mtrr_if || !use_intel()) + return; + /* + * Ideally we should hold main_lock here to avoid mtrr entries changed, + * but this routine will be called in cpu boot time, holding the lock + * breaks it. This routine is called in two cases: 1.very earily time + * of software resume, when there absolutely isn't mtrr entry changes; + * 2.cpu hotadd time. We let mtrr_add/del_page hold cpuhotplug lock to + * prevent mtrr entry changes + */ + local_irq_save(flags); + + mtrr_if->set_all(); + + local_irq_restore(flags); +} + +static int __init mtrr_init_finialize(void) +{ + if (!mtrr_if) + return 0; + if (use_intel()) + mtrr_state_warn(); + else { + /* The CPUs haven't MTRR and seemes not support SMP. They have + * specific drivers, we use a tricky method to support + * suspend/resume for them. + * TBD: is there any system with such CPU which supports + * suspend/resume? if no, we should remove the code. + */ + sysdev_driver_register(&cpu_sysdev_class, + &mtrr_sysdev_driver); + } + return 0; +} +subsys_initcall(mtrr_init_finialize); diff --git a/arch/i386/kernel/cpu/mtrr/mtrr.h b/arch/i386/kernel/cpu/mtrr/mtrr.h index de1351245599..99c9f2682041 100644 --- a/arch/i386/kernel/cpu/mtrr/mtrr.h +++ b/arch/i386/kernel/cpu/mtrr/mtrr.h @@ -91,7 +91,6 @@ extern struct mtrr_ops * mtrr_if; extern unsigned int num_var_ranges; -void finalize_mtrr_state(void); void mtrr_state_warn(void); char *mtrr_attrib_to_str(int x); void mtrr_wrmsr(unsigned, unsigned, unsigned); diff --git a/arch/i386/kernel/i387.c b/arch/i386/kernel/i387.c index b817168d9c62..d75524758daf 100644 --- a/arch/i386/kernel/i387.c +++ b/arch/i386/kernel/i387.c @@ -82,17 +82,6 @@ void kernel_fpu_begin(void) } EXPORT_SYMBOL_GPL(kernel_fpu_begin); -void restore_fpu( struct task_struct *tsk ) -{ - if ( cpu_has_fxsr ) { - asm volatile( "fxrstor %0" - : : "m" (tsk->thread.i387.fxsave) ); - } else { - asm volatile( "frstor %0" - : : "m" (tsk->thread.i387.fsave) ); - } -} - /* * FPU tag word conversions. */ diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 35eb8e29c485..6578f40bd501 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -37,6 +37,7 @@ #include <asm/smp.h> #include <asm/desc.h> #include <asm/timer.h> +#include <asm/i8259.h> #include <mach_apic.h> @@ -1566,7 +1567,6 @@ void print_all_local_APICs (void) void /*__init*/ print_PIC(void) { - extern spinlock_t i8259A_lock; unsigned int v; unsigned long flags; diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c index 3762f6b35ab2..a6d8c45961d3 100644 --- a/arch/i386/kernel/kprobes.c +++ b/arch/i386/kernel/kprobes.c @@ -127,48 +127,23 @@ static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) regs->eip = (unsigned long)&p->ainsn.insn; } -struct task_struct *arch_get_kprobe_task(void *ptr) -{ - return ((struct thread_info *) (((unsigned long) ptr) & - (~(THREAD_SIZE -1))))->task; -} - void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs) { unsigned long *sara = (unsigned long *)®s->esp; - struct kretprobe_instance *ri; - static void *orig_ret_addr; + struct kretprobe_instance *ri; + + if ((ri = get_free_rp_inst(rp)) != NULL) { + ri->rp = rp; + ri->task = current; + ri->ret_addr = (kprobe_opcode_t *) *sara; - /* - * Save the return address when the return probe hits - * the first time, and use it to populate the (krprobe - * instance)->ret_addr for subsequent return probes at - * the same addrress since stack address would have - * the kretprobe_trampoline by then. - */ - if (((void*) *sara) != kretprobe_trampoline) - orig_ret_addr = (void*) *sara; - - if ((ri = get_free_rp_inst(rp)) != NULL) { - ri->rp = rp; - ri->stack_addr = sara; - ri->ret_addr = orig_ret_addr; - add_rp_inst(ri); /* Replace the return addr with trampoline addr */ *sara = (unsigned long) &kretprobe_trampoline; - } else { - rp->nmissed++; - } -} -void arch_kprobe_flush_task(struct task_struct *tk) -{ - struct kretprobe_instance *ri; - while ((ri = get_rp_inst_tsk(tk)) != NULL) { - *((unsigned long *)(ri->stack_addr)) = - (unsigned long) ri->ret_addr; - recycle_rp_inst(ri); - } + add_rp_inst(ri); + } else { + rp->nmissed++; + } } /* @@ -286,36 +261,59 @@ no_kprobe: */ int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) { - struct task_struct *tsk; - struct kretprobe_instance *ri; - struct hlist_head *head; - struct hlist_node *node; - unsigned long *sara = ((unsigned long *) ®s->esp) - 1; - - tsk = arch_get_kprobe_task(sara); - head = kretprobe_inst_table_head(tsk); - - hlist_for_each_entry(ri, node, head, hlist) { - if (ri->stack_addr == sara && ri->rp) { - if (ri->rp->handler) - ri->rp->handler(ri, regs); - } - } - return 0; -} + struct kretprobe_instance *ri = NULL; + struct hlist_head *head; + struct hlist_node *node, *tmp; + unsigned long orig_ret_address = 0; + unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline; -void trampoline_post_handler(struct kprobe *p, struct pt_regs *regs, - unsigned long flags) -{ - struct kretprobe_instance *ri; - /* RA already popped */ - unsigned long *sara = ((unsigned long *)®s->esp) - 1; + head = kretprobe_inst_table_head(current); - while ((ri = get_rp_inst(sara))) { - regs->eip = (unsigned long)ri->ret_addr; + /* + * It is possible to have multiple instances associated with a given + * task either because an multiple functions in the call path + * have a return probe installed on them, and/or more then one return + * return probe was registered for a target function. + * + * We can handle this because: + * - instances are always inserted at the head of the list + * - when multiple return probes are registered for the same + * function, the first instance's ret_addr will point to the + * real return address, and all the rest will point to + * kretprobe_trampoline + */ + hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { + if (ri->task != current) + /* another task is sharing our hash bucket */ + continue; + + if (ri->rp && ri->rp->handler) + ri->rp->handler(ri, regs); + + orig_ret_address = (unsigned long)ri->ret_addr; recycle_rp_inst(ri); + + if (orig_ret_address != trampoline_address) + /* + * This is the real return address. Any other + * instances associated with this task are for + * other calls deeper on the call stack + */ + break; } - regs->eflags &= ~TF_MASK; + + BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address)); + regs->eip = orig_ret_address; + + unlock_kprobes(); + preempt_enable_no_resched(); + + /* + * By returning a non-zero value, we are telling + * kprobe_handler() that we have handled unlocking + * and re-enabling preemption. + */ + return 1; } /* @@ -403,8 +401,7 @@ static inline int post_kprobe_handler(struct pt_regs *regs) current_kprobe->post_handler(current_kprobe, regs, 0); } - if (current_kprobe->post_handler != trampoline_post_handler) - resume_execution(current_kprobe, regs); + resume_execution(current_kprobe, regs); regs->eflags |= kprobe_saved_eflags; /*Restore back the original saved kprobes variables and continue. */ @@ -534,3 +531,13 @@ int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) } return 0; } + +static struct kprobe trampoline_p = { + .addr = (kprobe_opcode_t *) &kretprobe_trampoline, + .pre_handler = trampoline_probe_handler +}; + +int __init arch_init_kprobes(void) +{ + return register_kprobe(&trampoline_p); +} diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index 5f8cfa6b7940..d9492058aaf3 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c @@ -617,6 +617,33 @@ handle_io_bitmap(struct thread_struct *next, struct tss_struct *tss) } /* + * This function selects if the context switch from prev to next + * has to tweak the TSC disable bit in the cr4. + */ +static inline void disable_tsc(struct task_struct *prev_p, + struct task_struct *next_p) +{ + struct thread_info *prev, *next; + + /* + * gcc should eliminate the ->thread_info dereference if + * has_secure_computing returns 0 at compile time (SECCOMP=n). + */ + prev = prev_p->thread_info; + next = next_p->thread_info; + + if (has_secure_computing(prev) || has_secure_computing(next)) { + /* slow path here */ + if (has_secure_computing(prev) && + !has_secure_computing(next)) { + write_cr4(read_cr4() & ~X86_CR4_TSD); + } else if (!has_secure_computing(prev) && + has_secure_computing(next)) + write_cr4(read_cr4() | X86_CR4_TSD); + } +} + +/* * switch_to(x,yn) should switch tasks from x to y. * * We fsave/fwait so that an exception goes off at the right time @@ -673,28 +700,34 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas /* * Restore %fs and %gs if needed. + * + * Glibc normally makes %fs be zero, and %gs is one of + * the TLS segments. */ - if (unlikely(prev->fs | prev->gs | next->fs | next->gs)) { + if (unlikely(prev->fs | next->fs)) loadsegment(fs, next->fs); + + if (prev->gs | next->gs) loadsegment(gs, next->gs); - } /* * Now maybe reload the debug registers */ if (unlikely(next->debugreg[7])) { - set_debugreg(current->thread.debugreg[0], 0); - set_debugreg(current->thread.debugreg[1], 1); - set_debugreg(current->thread.debugreg[2], 2); - set_debugreg(current->thread.debugreg[3], 3); + set_debugreg(next->debugreg[0], 0); + set_debugreg(next->debugreg[1], 1); + set_debugreg(next->debugreg[2], 2); + set_debugreg(next->debugreg[3], 3); /* no 4 and 5 */ - set_debugreg(current->thread.debugreg[6], 6); - set_debugreg(current->thread.debugreg[7], 7); + set_debugreg(next->debugreg[6], 6); + set_debugreg(next->debugreg[7], 7); } if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) handle_io_bitmap(next, tss); + disable_tsc(prev_p, next_p); + return prev_p; } diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 7306353c520e..af4de58cab54 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -1414,7 +1414,7 @@ static struct nop { This runs before SMP is initialized to avoid SMP problems with self modifying code. This implies that assymetric systems where APs have less capabilities than the boot processor are not handled. - In this case boot with "noreplacement". */ + Tough. Make sure you disable such features by hand. */ void apply_alternatives(void *start, void *end) { struct alt_instr *a; @@ -1442,24 +1442,12 @@ void apply_alternatives(void *start, void *end) } } -static int no_replacement __initdata = 0; - void __init alternative_instructions(void) { extern struct alt_instr __alt_instructions[], __alt_instructions_end[]; - if (no_replacement) - return; apply_alternatives(__alt_instructions, __alt_instructions_end); } -static int __init noreplacement_setup(char *s) -{ - no_replacement = 1; - return 0; -} - -__setup("noreplacement", noreplacement_setup); - static char * __init machine_specific_memory_setup(void); #ifdef CONFIG_MCA diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index d66bf489a2e9..8ac8e9fd5614 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -68,21 +68,21 @@ EXPORT_SYMBOL(smp_num_siblings); #endif /* Package ID of each logical CPU */ -int phys_proc_id[NR_CPUS] = {[0 ... NR_CPUS-1] = BAD_APICID}; +int phys_proc_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID}; EXPORT_SYMBOL(phys_proc_id); /* Core ID of each logical CPU */ -int cpu_core_id[NR_CPUS] = {[0 ... NR_CPUS-1] = BAD_APICID}; +int cpu_core_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID}; EXPORT_SYMBOL(cpu_core_id); -cpumask_t cpu_sibling_map[NR_CPUS]; +cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly; EXPORT_SYMBOL(cpu_sibling_map); -cpumask_t cpu_core_map[NR_CPUS]; +cpumask_t cpu_core_map[NR_CPUS] __read_mostly; EXPORT_SYMBOL(cpu_core_map); /* bitmap of online cpus */ -cpumask_t cpu_online_map; +cpumask_t cpu_online_map __read_mostly; EXPORT_SYMBOL(cpu_online_map); cpumask_t cpu_callin_map; @@ -100,7 +100,7 @@ static int __devinitdata tsc_sync_disabled; struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; EXPORT_SYMBOL(cpu_data); -u8 x86_cpu_to_apicid[NR_CPUS] = +u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = 0xff }; EXPORT_SYMBOL(x86_cpu_to_apicid); @@ -550,10 +550,10 @@ extern struct { #ifdef CONFIG_NUMA /* which logical CPUs are on which nodes */ -cpumask_t node_2_cpu_mask[MAX_NUMNODES] = +cpumask_t node_2_cpu_mask[MAX_NUMNODES] __read_mostly = { [0 ... MAX_NUMNODES-1] = CPU_MASK_NONE }; /* which node each logical CPU is on */ -int cpu_2_node[NR_CPUS] = { [0 ... NR_CPUS-1] = 0 }; +int cpu_2_node[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = 0 }; EXPORT_SYMBOL(cpu_2_node); /* set up a mapping between cpu and node. */ @@ -581,7 +581,7 @@ static inline void unmap_cpu_to_node(int cpu) #endif /* CONFIG_NUMA */ -u8 cpu_2_logical_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID }; +u8 cpu_2_logical_apicid[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID }; static void map_cpu_to_logical_apicid(void) { diff --git a/arch/i386/kernel/syscall_table.S b/arch/i386/kernel/syscall_table.S index 442a6e937b19..468500a7e894 100644 --- a/arch/i386/kernel/syscall_table.S +++ b/arch/i386/kernel/syscall_table.S @@ -289,3 +289,8 @@ ENTRY(sys_call_table) .long sys_add_key .long sys_request_key .long sys_keyctl + .long sys_ioprio_set + .long sys_ioprio_get /* 290 */ + .long sys_inotify_init + .long sys_inotify_add_watch + .long sys_inotify_rm_watch diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c index e68d9fdb0759..0ee9dee8af06 100644 --- a/arch/i386/kernel/time.c +++ b/arch/i386/kernel/time.c @@ -68,7 +68,8 @@ #include "io_ports.h" -extern spinlock_t i8259A_lock; +#include <asm/i8259.h> + int pit_latch_buggy; /* extern */ #include "do_timer.h" @@ -85,10 +86,12 @@ extern unsigned long wall_jiffies; DEFINE_SPINLOCK(rtc_lock); EXPORT_SYMBOL(rtc_lock); +#include <asm/i8253.h> + DEFINE_SPINLOCK(i8253_lock); EXPORT_SYMBOL(i8253_lock); -struct timer_opts *cur_timer = &timer_none; +struct timer_opts *cur_timer __read_mostly = &timer_none; /* * This is a special lock that is owned by the CPU and holds the index diff --git a/arch/i386/kernel/timers/timer_cyclone.c b/arch/i386/kernel/timers/timer_cyclone.c index f6f1206a11bb..13892a65c941 100644 --- a/arch/i386/kernel/timers/timer_cyclone.c +++ b/arch/i386/kernel/timers/timer_cyclone.c @@ -17,9 +17,9 @@ #include <asm/io.h> #include <asm/pgtable.h> #include <asm/fixmap.h> -#include "io_ports.h" +#include <asm/i8253.h> -extern spinlock_t i8253_lock; +#include "io_ports.h" /* Number of usecs that the last interrupt was delayed */ static int delay_at_last_interrupt; diff --git a/arch/i386/kernel/timers/timer_hpet.c b/arch/i386/kernel/timers/timer_hpet.c index d766e0963ac1..ef8dac5dd33b 100644 --- a/arch/i386/kernel/timers/timer_hpet.c +++ b/arch/i386/kernel/timers/timer_hpet.c @@ -18,7 +18,7 @@ #include "mach_timer.h" #include <asm/hpet.h> -static unsigned long hpet_usec_quotient; /* convert hpet clks to usec */ +static unsigned long __read_mostly hpet_usec_quotient; /* convert hpet clks to usec */ static unsigned long tsc_hpet_quotient; /* convert tsc to hpet clks */ static unsigned long hpet_last; /* hpet counter value at last tick*/ static unsigned long last_tsc_low; /* lsb 32 bits of Time Stamp Counter */ @@ -180,7 +180,7 @@ static int __init init_hpet(char* override) /************************************************************/ /* tsc timer_opts struct */ -static struct timer_opts timer_hpet = { +static struct timer_opts timer_hpet __read_mostly = { .name = "hpet", .mark_offset = mark_offset_hpet, .get_offset = get_offset_hpet, diff --git a/arch/i386/kernel/timers/timer_pit.c b/arch/i386/kernel/timers/timer_pit.c index 967d5453cd0e..06de036a820c 100644 --- a/arch/i386/kernel/timers/timer_pit.c +++ b/arch/i386/kernel/timers/timer_pit.c @@ -15,9 +15,8 @@ #include <asm/smp.h> #include <asm/io.h> #include <asm/arch_hooks.h> +#include <asm/i8253.h> -extern spinlock_t i8259A_lock; -extern spinlock_t i8253_lock; #include "do_timer.h" #include "io_ports.h" @@ -166,7 +165,6 @@ struct init_timer_opts __initdata timer_pit_init = { void setup_pit_timer(void) { - extern spinlock_t i8253_lock; unsigned long flags; spin_lock_irqsave(&i8253_lock, flags); diff --git a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c index f46e625bab67..8f4e4d5bc560 100644 --- a/arch/i386/kernel/timers/timer_tsc.c +++ b/arch/i386/kernel/timers/timer_tsc.c @@ -24,6 +24,7 @@ #include "mach_timer.h" #include <asm/hpet.h> +#include <asm/i8253.h> #ifdef CONFIG_HPET_TIMER static unsigned long hpet_usec_quotient; @@ -35,8 +36,6 @@ static inline void cpufreq_delayed_get(void); int tsc_disable __devinitdata = 0; -extern spinlock_t i8253_lock; - static int use_tsc; /* Number of usecs that the last interrupt was delayed */ static int delay_at_last_interrupt; diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S index 7e01a528a83a..761972f8cb6c 100644 --- a/arch/i386/kernel/vmlinux.lds.S +++ b/arch/i386/kernel/vmlinux.lds.S @@ -57,6 +57,9 @@ SECTIONS *(.data.cacheline_aligned) } + /* rarely changed data like cpu maps */ + . = ALIGN(32); + .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { *(.data.read_mostly) } _edata = .; /* End of data section */ . = ALIGN(THREAD_SIZE); /* init_task */ diff --git a/arch/i386/mach-visws/reboot.c b/arch/i386/mach-visws/reboot.c index 3a81e904a7b8..95e4676594e1 100644 --- a/arch/i386/mach-visws/reboot.c +++ b/arch/i386/mach-visws/reboot.c @@ -7,6 +7,7 @@ #include "piix4.h" void (*pm_power_off)(void); +EXPORT_SYMBOL(pm_power_off); void machine_restart(char * __unused) { diff --git a/arch/i386/mach-voyager/voyager_basic.c b/arch/i386/mach-voyager/voyager_basic.c index 602aea240e9b..8680080a6a89 100644 --- a/arch/i386/mach-voyager/voyager_basic.c +++ b/arch/i386/mach-voyager/voyager_basic.c @@ -30,11 +30,13 @@ #include <linux/irq.h> #include <asm/tlbflush.h> #include <asm/arch_hooks.h> +#include <asm/i8253.h> /* * Power off function, if any */ void (*pm_power_off)(void); +EXPORT_SYMBOL(pm_power_off); int voyager_level = 0; @@ -182,7 +184,6 @@ voyager_timer_interrupt(struct pt_regs *regs) * and swiftly introduce it to something sharp and * pointy. */ __u16 val; - extern spinlock_t i8253_lock; spin_lock(&i8253_lock); diff --git a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c index 8c8527593da0..0e1f4208b07c 100644 --- a/arch/i386/mach-voyager/voyager_smp.c +++ b/arch/i386/mach-voyager/voyager_smp.c @@ -10,6 +10,7 @@ * the voyager hal to provide the functionality */ #include <linux/config.h> +#include <linux/module.h> #include <linux/mm.h> #include <linux/kernel_stat.h> #include <linux/delay.h> @@ -40,6 +41,7 @@ static unsigned long cpu_irq_affinity[NR_CPUS] __cacheline_aligned = { [0 ... NR /* per CPU data structure (for /proc/cpuinfo et al), visible externally * indexed physically */ struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; +EXPORT_SYMBOL(cpu_data); /* physical ID of the CPU used to boot the system */ unsigned char boot_cpu_id; @@ -72,6 +74,7 @@ static volatile unsigned long smp_invalidate_needed; /* Bitmask of currently online CPUs - used by setup.c for /proc/cpuinfo, visible externally but still physical */ cpumask_t cpu_online_map = CPU_MASK_NONE; +EXPORT_SYMBOL(cpu_online_map); /* Bitmask of CPUs present in the system - exported by i386_syms.c, used * by scheduler but indexed physically */ @@ -238,6 +241,7 @@ static cpumask_t smp_commenced_mask = CPU_MASK_NONE; /* This is for the new dynamic CPU boot code */ cpumask_t cpu_callin_map = CPU_MASK_NONE; cpumask_t cpu_callout_map = CPU_MASK_NONE; +EXPORT_SYMBOL(cpu_callout_map); /* The per processor IRQ masks (these are usually kept in sync) */ static __u16 vic_irq_mask[NR_CPUS] __cacheline_aligned; @@ -978,6 +982,7 @@ void flush_tlb_page(struct vm_area_struct * vma, unsigned long va) preempt_enable(); } +EXPORT_SYMBOL(flush_tlb_page); /* enable the requested IRQs */ static void @@ -1109,6 +1114,7 @@ smp_call_function (void (*func) (void *info), void *info, int retry, return 0; } +EXPORT_SYMBOL(smp_call_function); /* Sorry about the name. In an APIC based system, the APICs * themselves are programmed to send a timer interrupt. This is used diff --git a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c index 6b25afc933b6..f379b8d67558 100644 --- a/arch/i386/mm/ioremap.c +++ b/arch/i386/mm/ioremap.c @@ -228,7 +228,8 @@ EXPORT_SYMBOL(ioremap_nocache); void iounmap(volatile void __iomem *addr) { struct vm_struct *p; - if ((void __force *) addr <= high_memory) + + if ((void __force *)addr <= high_memory) return; /* @@ -241,9 +242,10 @@ void iounmap(volatile void __iomem *addr) return; write_lock(&vmlist_lock); - p = __remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr)); + p = __remove_vm_area((void *)(PAGE_MASK & (unsigned long __force)addr)); if (!p) { printk(KERN_WARNING "iounmap: bad address %p\n", addr); + dump_stack(); goto out_unlock; } diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c index 720975e1af50..70bcd53451f6 100644 --- a/arch/i386/pci/common.c +++ b/arch/i386/pci/common.c @@ -25,7 +25,8 @@ unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | int pci_routeirq; int pcibios_last_bus = -1; -struct pci_bus *pci_root_bus = NULL; +unsigned long pirq_table_addr; +struct pci_bus *pci_root_bus; struct pci_raw_ops *raw_pci_ops; static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) @@ -133,7 +134,7 @@ struct pci_bus * __devinit pcibios_scan_root(int busnum) printk("PCI: Probing PCI hardware (bus %02x)\n", busnum); - return pci_scan_bus(busnum, &pci_root_ops, NULL); + return pci_scan_bus_parented(NULL, busnum, &pci_root_ops, NULL); } extern u8 pci_cache_line_size; @@ -164,6 +165,7 @@ static int __init pcibios_init(void) if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT)) pcibios_sort(); #endif + pci_assign_unassigned_resources(); return 0; } @@ -188,6 +190,9 @@ char * __devinit pcibios_setup(char *str) } else if (!strcmp(str, "biosirq")) { pci_probe |= PCI_BIOS_IRQ_SCAN; return NULL; + } else if (!strncmp(str, "pirqaddr=", 9)) { + pirq_table_addr = simple_strtoul(str+9, NULL, 0); + return NULL; } #endif #ifdef CONFIG_PCI_DIRECT diff --git a/arch/i386/pci/i386.c b/arch/i386/pci/i386.c index c205ea7e233b..93a364c82150 100644 --- a/arch/i386/pci/i386.c +++ b/arch/i386/pci/i386.c @@ -106,11 +106,16 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) if ((dev = bus->self)) { for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) { r = &dev->resource[idx]; - if (!r->start) + if (!r->flags) continue; pr = pci_find_parent_resource(dev, r); - if (!pr || request_resource(pr, r) < 0) + if (!r->start || !pr || request_resource(pr, r) < 0) { printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, pci_name(dev)); + /* Something is wrong with the region. + Invalidate the resource to prevent child + resource allocations in this range. */ + r->flags = 0; + } } } pcibios_allocate_bus_resources(&bus->children); @@ -227,7 +232,7 @@ int pcibios_enable_resources(struct pci_dev *dev, int mask) pci_read_config_word(dev, PCI_COMMAND, &cmd); old_cmd = cmd; - for(idx=0; idx<6; idx++) { + for(idx = 0; idx < PCI_NUM_RESOURCES; idx++) { /* Only set up the requested stuff */ if (!(mask & (1<<idx))) continue; diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c index 83458f81e661..766b104ac1a1 100644 --- a/arch/i386/pci/irq.c +++ b/arch/i386/pci/irq.c @@ -58,6 +58,35 @@ struct irq_router_handler { int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL; /* + * Check passed address for the PCI IRQ Routing Table signature + * and perform checksum verification. + */ + +static inline struct irq_routing_table * pirq_check_routing_table(u8 *addr) +{ + struct irq_routing_table *rt; + int i; + u8 sum; + + rt = (struct irq_routing_table *) addr; + if (rt->signature != PIRQ_SIGNATURE || + rt->version != PIRQ_VERSION || + rt->size % 16 || + rt->size < sizeof(struct irq_routing_table)) + return NULL; + sum = 0; + for (i=0; i < rt->size; i++) + sum += addr[i]; + if (!sum) { + DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt); + return rt; + } + return NULL; +} + + + +/* * Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table. */ @@ -65,23 +94,17 @@ static struct irq_routing_table * __init pirq_find_routing_table(void) { u8 *addr; struct irq_routing_table *rt; - int i; - u8 sum; + if (pirq_table_addr) { + rt = pirq_check_routing_table((u8 *) __va(pirq_table_addr)); + if (rt) + return rt; + printk(KERN_WARNING "PCI: PIRQ table NOT found at pirqaddr\n"); + } for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) { - rt = (struct irq_routing_table *) addr; - if (rt->signature != PIRQ_SIGNATURE || - rt->version != PIRQ_VERSION || - rt->size % 16 || - rt->size < sizeof(struct irq_routing_table)) - continue; - sum = 0; - for(i=0; i<rt->size; i++) - sum += addr[i]; - if (!sum) { - DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt); + rt = pirq_check_routing_table(addr); + if (rt) return rt; - } } return NULL; } @@ -1028,24 +1051,28 @@ static int __init pcibios_irq_init(void) subsys_initcall(pcibios_irq_init); -static void pirq_penalize_isa_irq(int irq) +static void pirq_penalize_isa_irq(int irq, int active) { /* * If any ISAPnP device reports an IRQ in its list of possible * IRQ's, we try to avoid assigning it to PCI devices. */ - if (irq < 16) - pirq_penalty[irq] += 100; + if (irq < 16) { + if (active) + pirq_penalty[irq] += 1000; + else + pirq_penalty[irq] += 100; + } } -void pcibios_penalize_isa_irq(int irq) +void pcibios_penalize_isa_irq(int irq, int active) { #ifdef CONFIG_ACPI_PCI if (!acpi_noirq) - acpi_penalize_isa_irq(irq); + acpi_penalize_isa_irq(irq, active); else #endif - pirq_penalize_isa_irq(irq); + pirq_penalize_isa_irq(irq, active); } static int pirq_enable_irq(struct pci_dev *dev) diff --git a/arch/i386/pci/legacy.c b/arch/i386/pci/legacy.c index 1492e3753869..149a9588c256 100644 --- a/arch/i386/pci/legacy.c +++ b/arch/i386/pci/legacy.c @@ -45,6 +45,8 @@ static int __init pci_legacy_init(void) printk("PCI: Probing PCI hardware\n"); pci_root_bus = pcibios_scan_root(0); + if (pci_root_bus) + pci_bus_add_devices(pci_root_bus); pcibios_fixup_peer_bridges(); diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index 021a50aa51f4..60f0e7a1162a 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c @@ -11,11 +11,9 @@ #include <linux/pci.h> #include <linux/init.h> +#include <linux/acpi.h> #include "pci.h" -/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ -u32 pci_mmcfg_base_addr; - #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG)) /* The base address of the last MMCONFIG device accessed */ @@ -24,10 +22,31 @@ static u32 mmcfg_last_accessed_device; /* * Functions for accessing PCI configuration space with MMCONFIG accesses */ +static u32 get_base_addr(unsigned int seg, int bus) +{ + int cfg_num = -1; + struct acpi_table_mcfg_config *cfg; + + while (1) { + ++cfg_num; + if (cfg_num >= pci_mmcfg_config_num) { + /* something bad is going on, no cfg table is found. */ + /* so we fall back to the old way we used to do this */ + /* and just rely on the first entry to be correct. */ + return pci_mmcfg_config[0].base_address; + } + cfg = &pci_mmcfg_config[cfg_num]; + if (cfg->pci_segment_group_number != seg) + continue; + if ((cfg->start_bus_number <= bus) && + (cfg->end_bus_number >= bus)) + return cfg->base_address; + } +} -static inline void pci_exp_set_dev_base(int bus, int devfn) +static inline void pci_exp_set_dev_base(unsigned int seg, int bus, int devfn) { - u32 dev_base = pci_mmcfg_base_addr | (bus << 20) | (devfn << 12); + u32 dev_base = get_base_addr(seg, bus) | (bus << 20) | (devfn << 12); if (dev_base != mmcfg_last_accessed_device) { mmcfg_last_accessed_device = dev_base; set_fixmap_nocache(FIX_PCIE_MCFG, dev_base); @@ -44,7 +63,7 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus, spin_lock_irqsave(&pci_config_lock, flags); - pci_exp_set_dev_base(bus, devfn); + pci_exp_set_dev_base(seg, bus, devfn); switch (len) { case 1: @@ -73,7 +92,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, spin_lock_irqsave(&pci_config_lock, flags); - pci_exp_set_dev_base(bus, devfn); + pci_exp_set_dev_base(seg, bus, devfn); switch (len) { case 1: @@ -101,7 +120,11 @@ static int __init pci_mmcfg_init(void) { if ((pci_probe & PCI_PROBE_MMCONF) == 0) goto out; - if (!pci_mmcfg_base_addr) + + acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); + if ((pci_mmcfg_config_num == 0) || + (pci_mmcfg_config == NULL) || + (pci_mmcfg_config[0].base_address == 0)) goto out; /* Kludge for now. Don't use mmconfig on AMD systems because diff --git a/arch/i386/pci/numa.c b/arch/i386/pci/numa.c index 9e3695461899..adbe17a38f6f 100644 --- a/arch/i386/pci/numa.c +++ b/arch/i386/pci/numa.c @@ -115,6 +115,8 @@ static int __init pci_numa_init(void) return 0; pci_root_bus = pcibios_scan_root(0); + if (pci_root_bus) + pci_bus_add_devices(pci_root_bus); if (num_online_nodes() > 1) for_each_online_node(quad) { if (quad == 0) diff --git a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h index a8fc80ca69f3..a80f0f55ff51 100644 --- a/arch/i386/pci/pci.h +++ b/arch/i386/pci/pci.h @@ -27,6 +27,7 @@ #define PCI_ASSIGN_ALL_BUSSES 0x4000 extern unsigned int pci_probe; +extern unsigned long pirq_table_addr; /* pci-i386.c */ diff --git a/arch/i386/pci/visws.c b/arch/i386/pci/visws.c index 6a9248784439..314c933b6b8e 100644 --- a/arch/i386/pci/visws.c +++ b/arch/i386/pci/visws.c @@ -21,7 +21,7 @@ static int pci_visws_enable_irq(struct pci_dev *dev) { return 0; } int (*pcibios_enable_irq)(struct pci_dev *dev) = &pci_visws_enable_irq; -void __init pcibios_penalize_isa_irq(int irq) {} +void __init pcibios_penalize_isa_irq(int irq, int active) {} unsigned int pci_bus0, pci_bus1; diff --git a/arch/i386/power/cpu.c b/arch/i386/power/cpu.c index 0e6b45b61251..c547c1af6fa1 100644 --- a/arch/i386/power/cpu.c +++ b/arch/i386/power/cpu.c @@ -137,6 +137,7 @@ void __restore_processor_state(struct saved_context *ctxt) fix_processor_context(); do_fpu_end(); + mtrr_ap_init(); } void restore_processor_state(void) diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 01b78e7f992e..cbb3e0cef93a 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -220,13 +220,6 @@ config IOSAPIC depends on !IA64_HP_SIM default y -config IA64_SGI_SN_SIM - bool "SGI Medusa Simulator Support" - depends on IA64_SGI_SN2 || IA64_GENERIC - help - If you are compiling a kernel that will run under SGI's IA-64 - simulator (Medusa) then say Y, otherwise say N. - config IA64_SGI_SN_XP tristate "Support communication between SGI SSIs" select IA64_UNCACHED_ALLOCATOR @@ -423,6 +416,8 @@ endmenu endif +source "net/Kconfig" + source "drivers/Kconfig" source "fs/Kconfig" diff --git a/arch/ia64/configs/sn2_defconfig b/arch/ia64/configs/sn2_defconfig index 487d2e36b0a6..04d0b00a2b8c 100644 --- a/arch/ia64/configs/sn2_defconfig +++ b/arch/ia64/configs/sn2_defconfig @@ -81,7 +81,6 @@ CONFIG_HOLES_IN_ZONE=y CONFIG_ARCH_DISCONTIGMEM_ENABLE=y # CONFIG_IA64_CYCLONE is not set CONFIG_IOSAPIC=y -CONFIG_IA64_SGI_SN_SIM=y CONFIG_FORCE_MAX_ZONEORDER=18 CONFIG_SMP=y CONFIG_NR_CPUS=512 @@ -99,7 +98,7 @@ CONFIG_ACPI_DEALLOCATE_IRQ=y # Firmware Drivers # CONFIG_EFI_VARS=y -# CONFIG_EFI_PCDP is not set +CONFIG_EFI_PCDP=y CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set @@ -650,7 +649,7 @@ CONFIG_MMTIMER=y # # Console display driver support # -# CONFIG_VGA_CONSOLE is not set +CONFIG_VGA_CONSOLE=y CONFIG_DUMMY_CONSOLE=y # diff --git a/arch/ia64/configs/tiger_defconfig b/arch/ia64/configs/tiger_defconfig index 47f45341ac62..73454eee26f1 100644 --- a/arch/ia64/configs/tiger_defconfig +++ b/arch/ia64/configs/tiger_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-20050621 -# Tue Jun 21 14:03:24 2005 +# Linux kernel version: 2.6.13-rc1-20050629 +# Wed Jun 29 15:28:12 2005 # # @@ -80,18 +80,29 @@ CONFIG_MCKINLEY=y # CONFIG_IA64_PAGE_SIZE_8KB is not set CONFIG_IA64_PAGE_SIZE_16KB=y # CONFIG_IA64_PAGE_SIZE_64KB is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 CONFIG_IA64_L1_CACHE_SHIFT=7 # CONFIG_NUMA is not set CONFIG_VIRTUAL_MEM_MAP=y CONFIG_HOLES_IN_ZONE=y CONFIG_IA64_CYCLONE=y CONFIG_IOSAPIC=y +# CONFIG_IA64_SGI_SN_XP is not set CONFIG_FORCE_MAX_ZONEORDER=18 CONFIG_SMP=y CONFIG_NR_CPUS=4 CONFIG_HOTPLUG_CPU=y # CONFIG_SCHED_SMT is not set # CONFIG_PREEMPT is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_HAVE_DEC_LOCK=y CONFIG_IA32_SUPPORT=y CONFIG_COMPAT=y @@ -257,6 +268,7 @@ CONFIG_BLK_DEV_CMD64X=y # CONFIG_BLK_DEV_HPT366 is not set # CONFIG_BLK_DEV_SC1200 is not set CONFIG_BLK_DEV_PIIX=y +# CONFIG_BLK_DEV_IT821X is not set # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_PDC202XX_OLD is not set # CONFIG_BLK_DEV_PDC202XX_NEW is not set @@ -395,6 +407,7 @@ CONFIG_UNIX=y CONFIG_INET=y CONFIG_IP_MULTICAST=y # CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y # CONFIG_IP_PNP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set @@ -407,6 +420,8 @@ CONFIG_SYN_COOKIES=y # CONFIG_INET_TUNNEL is not set CONFIG_IP_TCPDIAG=y # CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y # CONFIG_IPV6 is not set # CONFIG_NETFILTER is not set @@ -598,9 +613,7 @@ CONFIG_GAMEPORT=m # CONFIG_GAMEPORT_NS558 is not set # CONFIG_GAMEPORT_L4 is not set # CONFIG_GAMEPORT_EMU10K1 is not set -# CONFIG_GAMEPORT_VORTEX is not set # CONFIG_GAMEPORT_FM801 is not set -# CONFIG_GAMEPORT_CS461X is not set # # Character devices @@ -629,7 +642,6 @@ CONFIG_SERIAL_8250_NR_UARTS=6 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_SERIAL_8250_DETECT_IRQ is not set -# CONFIG_SERIAL_8250_MULTIPORT is not set # CONFIG_SERIAL_8250_RSA is not set # @@ -743,6 +755,7 @@ CONFIG_USB_DEVICEFS=y CONFIG_USB_EHCI_HCD=m # CONFIG_USB_EHCI_SPLIT_ISO is not set # CONFIG_USB_EHCI_ROOT_HUB_TT is not set +# CONFIG_USB_ISP116X_HCD is not set CONFIG_USB_OHCI_HCD=m # CONFIG_USB_OHCI_BIG_ENDIAN is not set CONFIG_USB_OHCI_LITTLE_ENDIAN=y @@ -779,9 +792,11 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_HIDDEV is not set # CONFIG_USB_AIPTEK is not set # CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set # CONFIG_USB_KBTAB is not set # CONFIG_USB_POWERMATE is not set # CONFIG_USB_MTOUCH is not set +# CONFIG_USB_ITMTOUCH is not set # CONFIG_USB_EGALAX is not set # CONFIG_USB_XPAD is not set # CONFIG_USB_ATI_REMOTE is not set @@ -838,7 +853,7 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_TEST is not set # -# USB ATM/DSL drivers +# USB DSL modem support # # @@ -857,12 +872,17 @@ CONFIG_USB_HIDINPUT=y # CONFIG_INFINIBAND is not set # +# SN Devices +# + +# # File systems # CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y CONFIG_EXT3_FS_POSIX_ACL=y @@ -922,7 +942,6 @@ CONFIG_NTFS_FS=m CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set # CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y CONFIG_TMPFS_XATTR=y @@ -953,15 +972,18 @@ CONFIG_RAMFS=y # CONFIG_NFS_FS=m CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set CONFIG_NFS_V4=y CONFIG_NFS_DIRECTIO=y CONFIG_NFSD=m CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set CONFIG_NFSD_V4=y CONFIG_NFSD_TCP=y CONFIG_LOCKD=m CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=y +CONFIG_NFS_COMMON=y CONFIG_SUNRPC=m CONFIG_SUNRPC_GSS=m CONFIG_RPCSEC_GSS_KRB5=m @@ -1069,6 +1091,7 @@ CONFIG_LOG_BUF_SHIFT=20 # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_FS is not set +# CONFIG_KPROBES is not set CONFIG_IA64_GRANULE_16MB=y # CONFIG_IA64_GRANULE_64MB is not set # CONFIG_IA64_PRINT_HAZARDS is not set @@ -1090,7 +1113,7 @@ CONFIG_CRYPTO=y # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_MD4 is not set -CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_SHA1 is not set # CONFIG_CRYPTO_SHA256 is not set # CONFIG_CRYPTO_SHA512 is not set diff --git a/arch/ia64/configs/zx1_defconfig b/arch/ia64/configs/zx1_defconfig index 21d6f9bab5e9..b7755e4436d2 100644 --- a/arch/ia64/configs/zx1_defconfig +++ b/arch/ia64/configs/zx1_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.10 -# Wed Dec 29 09:05:48 2004 +# Linux kernel version: 2.6.13-rc1-20050629 +# Wed Jun 29 15:31:11 2005 # # @@ -12,6 +12,7 @@ CONFIG_EXPERIMENTAL=y CONFIG_BROKEN=y CONFIG_BROKEN_ON_SMP=y CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup @@ -24,23 +25,26 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set -CONFIG_LOG_BUF_SHIFT=17 CONFIG_HOTPLUG=y CONFIG_KOBJECT_UEVENT=y # CONFIG_IKCONFIG is not set +# CONFIG_CPUSETS is not set # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SHMEM=y CONFIG_CC_ALIGN_FUNCTIONS=0 CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 # # Loadable module support @@ -59,12 +63,15 @@ CONFIG_IA64=y CONFIG_64BIT=y CONFIG_MMU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_TIME_INTERPOLATION=y CONFIG_EFI=y CONFIG_GENERIC_IOMAP=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y # CONFIG_IA64_GENERIC is not set # CONFIG_IA64_DIG is not set CONFIG_IA64_HP_ZX1=y +# CONFIG_IA64_HP_ZX1_SWIOTLB is not set # CONFIG_IA64_SGI_SN2 is not set # CONFIG_IA64_HP_SIM is not set # CONFIG_ITANIUM is not set @@ -73,22 +80,36 @@ CONFIG_MCKINLEY=y # CONFIG_IA64_PAGE_SIZE_8KB is not set CONFIG_IA64_PAGE_SIZE_16KB=y # CONFIG_IA64_PAGE_SIZE_64KB is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 CONFIG_IA64_L1_CACHE_SHIFT=7 # CONFIG_NUMA is not set CONFIG_VIRTUAL_MEM_MAP=y +CONFIG_HOLES_IN_ZONE=y # CONFIG_IA64_CYCLONE is not set CONFIG_IOSAPIC=y +# CONFIG_IA64_SGI_SN_XP is not set CONFIG_FORCE_MAX_ZONEORDER=18 CONFIG_SMP=y CONFIG_NR_CPUS=16 # CONFIG_HOTPLUG_CPU is not set +# CONFIG_SCHED_SMT is not set # CONFIG_PREEMPT is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_HAVE_DEC_LOCK=y CONFIG_IA32_SUPPORT=y CONFIG_COMPAT=y CONFIG_IA64_MCA_RECOVERY=y CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y +CONFIG_ACPI_DEALLOCATE_IRQ=y # # Firmware Drivers @@ -120,6 +141,7 @@ CONFIG_ACPI_BUS=y CONFIG_ACPI_POWER=y CONFIG_ACPI_PCI=y CONFIG_ACPI_SYSTEM=y +# CONFIG_ACPI_CONTAINER is not set # # Bus options (PCI, PCMCIA) @@ -129,6 +151,7 @@ CONFIG_PCI_DOMAINS=y # CONFIG_PCI_MSI is not set CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y +# CONFIG_PCI_DEBUG is not set # # PCI Hotplug Support @@ -138,7 +161,6 @@ CONFIG_HOTPLUG_PCI=y CONFIG_HOTPLUG_PCI_ACPI=y # CONFIG_HOTPLUG_PCI_ACPI_IBM is not set # CONFIG_HOTPLUG_PCI_CPCI is not set -# CONFIG_HOTPLUG_PCI_PCIE is not set # CONFIG_HOTPLUG_PCI_SHPC is not set # @@ -147,10 +169,6 @@ CONFIG_HOTPLUG_PCI_ACPI=y # CONFIG_PCCARD is not set # -# PC-card bridges -# - -# # Device Drivers # @@ -184,6 +202,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set # CONFIG_BLK_DEV_NBD is not set @@ -203,6 +222,7 @@ CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set # # ATA/ATAPI/MFM/RLL support @@ -246,6 +266,7 @@ CONFIG_BLK_DEV_CMD64X=y # CONFIG_BLK_DEV_HPT366 is not set # CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_IT821X is not set # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_PDC202XX_OLD is not set # CONFIG_BLK_DEV_PDC202XX_NEW is not set @@ -275,6 +296,7 @@ CONFIG_CHR_DEV_OSST=y CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y +# CONFIG_CHR_DEV_SCH is not set # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs @@ -288,6 +310,7 @@ CONFIG_SCSI_LOGGING=y # CONFIG_SCSI_SPI_ATTRS=y # CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set # # SCSI low-level drivers @@ -303,13 +326,10 @@ CONFIG_SCSI_SPI_ATTRS=y # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set # CONFIG_SCSI_SATA is not set -# CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_EATA is not set # CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set @@ -319,8 +339,6 @@ CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 # CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set # CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_PCI2000 is not set -# CONFIG_SCSI_PCI2220I is not set # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set CONFIG_SCSI_QLOGIC_1280=y @@ -331,7 +349,7 @@ CONFIG_SCSI_QLA2XXX=y # CONFIG_SCSI_QLA2300 is not set # CONFIG_SCSI_QLA2322 is not set # CONFIG_SCSI_QLA6312 is not set -# CONFIG_SCSI_QLA6322 is not set +# CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_DEBUG is not set @@ -344,9 +362,9 @@ CONFIG_SCSI_QLA2XXX=y # # Fusion MPT device support # -CONFIG_FUSION=y -CONFIG_FUSION_MAX_SGE=40 -# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set # # IEEE 1394 (FireWire) support @@ -368,12 +386,12 @@ CONFIG_NET=y # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK_DEV is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y # CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y # CONFIG_IP_PNP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set @@ -386,6 +404,8 @@ CONFIG_IP_MULTICAST=y # CONFIG_INET_TUNNEL is not set # CONFIG_IP_TCPDIAG is not set # CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y # # IP: Virtual Server Configuration @@ -405,8 +425,6 @@ CONFIG_NETFILTER=y CONFIG_IP_NF_ARPTABLES=y # CONFIG_IP_NF_ARPFILTER is not set # CONFIG_IP_NF_ARP_MANGLE is not set -# CONFIG_IP_NF_COMPAT_IPCHAINS is not set -# CONFIG_IP_NF_COMPAT_IPFWADM is not set # # SCTP Configuration (EXPERIMENTAL) @@ -483,7 +501,6 @@ CONFIG_NET_PCI=y # CONFIG_DGRS is not set # CONFIG_EEPRO100 is not set CONFIG_E100=y -# CONFIG_E100_NAPI is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set @@ -505,9 +522,11 @@ CONFIG_E1000=y # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set # CONFIG_R8169 is not set +# CONFIG_SKGE is not set # CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set CONFIG_TIGON3=y +# CONFIG_BNX2 is not set # # Ethernet (10000 Mbit) @@ -565,18 +584,6 @@ CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_EVBUG is not set # -# Input I/O drivers -# -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y -CONFIG_SERIO=y -# CONFIG_SERIO_I8042 is not set -# CONFIG_SERIO_SERPORT is not set -# CONFIG_SERIO_CT82C710 is not set -# CONFIG_SERIO_PCIPS2 is not set -# CONFIG_SERIO_RAW is not set - -# # Input Device Drivers # # CONFIG_INPUT_KEYBOARD is not set @@ -586,6 +593,16 @@ CONFIG_SERIO=y # CONFIG_INPUT_MISC is not set # +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_PCIPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# # Character devices # CONFIG_VT=y @@ -603,7 +620,6 @@ CONFIG_SERIAL_8250_NR_UARTS=8 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_SERIAL_8250_DETECT_IRQ is not set -# CONFIG_SERIAL_8250_MULTIPORT is not set # CONFIG_SERIAL_8250_RSA is not set # @@ -611,6 +627,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -644,6 +661,12 @@ CONFIG_DRM_RADEON=y # CONFIG_DRM_SIS is not set # CONFIG_RAW_DRIVER is not set # CONFIG_HPET is not set +# CONFIG_HANGCHECK_TIMER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set # # I2C support @@ -668,6 +691,7 @@ CONFIG_I2C_ALGOPCF=y # CONFIG_I2C_AMD8111 is not set # CONFIG_I2C_I801 is not set # CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set # CONFIG_I2C_ISA is not set # CONFIG_I2C_NFORCE2 is not set # CONFIG_I2C_PARPORT_LIGHT is not set @@ -691,10 +715,14 @@ CONFIG_I2C_ALGOPCF=y # CONFIG_SENSORS_ADM1025 is not set # CONFIG_SENSORS_ADM1026 is not set # CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set # CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set # CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_IT87 is not set # CONFIG_SENSORS_LM63 is not set # CONFIG_SENSORS_LM75 is not set @@ -705,21 +733,29 @@ CONFIG_I2C_ALGOPCF=y # CONFIG_SENSORS_LM85 is not set # CONFIG_SENSORS_LM87 is not set # CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SIS5595 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_VIA686A is not set # CONFIG_SENSORS_W83781D is not set # CONFIG_SENSORS_W83L785TS is not set # CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set # # Other I2C Chip support # +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set # CONFIG_SENSORS_EEPROM is not set # CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set # CONFIG_SENSORS_PCF8591 is not set # CONFIG_SENSORS_RTC8564 is not set +# CONFIG_SENSORS_MAX6875 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set @@ -746,6 +782,7 @@ CONFIG_VIDEO_DEV=y # # Video Adapters # +# CONFIG_TUNER_MULTI_I2C is not set # CONFIG_VIDEO_BT848 is not set # CONFIG_VIDEO_CPIA is not set # CONFIG_VIDEO_SAA5246A is not set @@ -778,6 +815,11 @@ CONFIG_VIDEO_DEV=y # Graphics support # CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y +# CONFIG_FB_MACMODES is not set CONFIG_FB_MODE_HELPERS=y # CONFIG_FB_TILEBLITTING is not set # CONFIG_FB_CIRRUS is not set @@ -785,6 +827,7 @@ CONFIG_FB_MODE_HELPERS=y # CONFIG_FB_CYBER2000 is not set # CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set +# CONFIG_FB_NVIDIA is not set # CONFIG_FB_RIVA is not set # CONFIG_FB_MATROX is not set # CONFIG_FB_RADEON_OLD is not set @@ -801,6 +844,7 @@ CONFIG_FB_RADEON_DEBUG=y # CONFIG_FB_VOODOO1 is not set # CONFIG_FB_TRIDENT is not set # CONFIG_FB_PM3 is not set +# CONFIG_FB_S1D13XXX is not set # CONFIG_FB_VIRTUAL is not set # @@ -820,6 +864,7 @@ CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -869,6 +914,8 @@ CONFIG_SND_AC97_CODEC=y # CONFIG_SND_CS46XX is not set # CONFIG_SND_CS4281 is not set # CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_CA0106 is not set # CONFIG_SND_KORG1212 is not set # CONFIG_SND_MIXART is not set # CONFIG_SND_NM256 is not set @@ -876,6 +923,7 @@ CONFIG_SND_AC97_CODEC=y # CONFIG_SND_RME96 is not set # CONFIG_SND_RME9652 is not set # CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set # CONFIG_SND_TRIDENT is not set # CONFIG_SND_YMFPCI is not set # CONFIG_SND_ALS4000 is not set @@ -893,13 +941,14 @@ CONFIG_SND_FM801_TEA575X=y # CONFIG_SND_INTEL8X0M is not set # CONFIG_SND_SONICVIBES is not set # CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set # CONFIG_SND_VX222 is not set +# CONFIG_SND_HDA_INTEL is not set # # USB devices # # CONFIG_SND_USB_AUDIO is not set -# CONFIG_SND_USB_USX2Y is not set # # Open Sound System @@ -909,6 +958,8 @@ CONFIG_SND_FM801_TEA575X=y # # USB support # +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB=y # CONFIG_USB_DEBUG is not set @@ -920,8 +971,6 @@ CONFIG_USB_BANDWIDTH=y # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_SUSPEND is not set # CONFIG_USB_OTG is not set -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y # # USB Host Controller Drivers @@ -929,7 +978,10 @@ CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB_EHCI_HCD=y # CONFIG_USB_EHCI_SPLIT_ISO is not set # CONFIG_USB_EHCI_ROOT_HUB_TT is not set +# CONFIG_USB_ISP116X_HCD is not set CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y CONFIG_USB_UHCI_HCD=y # CONFIG_USB_SL811_HCD is not set @@ -947,12 +999,11 @@ CONFIG_USB_UHCI_HCD=y # CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_RW_DETECT is not set # CONFIG_USB_STORAGE_DATAFAB is not set # CONFIG_USB_STORAGE_FREECOM is not set # CONFIG_USB_STORAGE_ISD200 is not set # CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_USBAT is not set # CONFIG_USB_STORAGE_SDDR09 is not set # CONFIG_USB_STORAGE_SDDR55 is not set # CONFIG_USB_STORAGE_JUMPSHOT is not set @@ -966,9 +1017,11 @@ CONFIG_USB_HIDINPUT=y CONFIG_USB_HIDDEV=y # CONFIG_USB_AIPTEK is not set # CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set # CONFIG_USB_KBTAB is not set # CONFIG_USB_POWERMATE is not set # CONFIG_USB_MTOUCH is not set +# CONFIG_USB_ITMTOUCH is not set # CONFIG_USB_EGALAX is not set # CONFIG_USB_XPAD is not set # CONFIG_USB_ATI_REMOTE is not set @@ -978,7 +1031,6 @@ CONFIG_USB_HIDDEV=y # # CONFIG_USB_MDC800 is not set # CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set # # USB Multimedia devices @@ -992,6 +1044,7 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_SE401 is not set # CONFIG_USB_SN9C102 is not set # CONFIG_USB_STV680 is not set +# CONFIG_USB_PWC is not set # # USB Network Adapters @@ -1001,6 +1054,7 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set +CONFIG_USB_MON=y # # USB port drivers @@ -1016,7 +1070,6 @@ CONFIG_USB_HIDDEV=y # # CONFIG_USB_EMI62 is not set # CONFIG_USB_EMI26 is not set -# CONFIG_USB_TIGL is not set # CONFIG_USB_AUERSWALD is not set # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set @@ -1025,9 +1078,11 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_CYTHERM is not set # CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_SISUSBVGA is not set # -# USB ATM/DSL drivers +# USB DSL modem support # # @@ -1041,12 +1096,22 @@ CONFIG_USB_HIDDEV=y # CONFIG_MMC is not set # +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# SN Devices +# + +# # File systems # CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y # CONFIG_EXT2_FS_POSIX_ACL is not set # CONFIG_EXT2_FS_SECURITY is not set +# CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set @@ -1056,6 +1121,10 @@ CONFIG_JBD=y CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set + +# +# XFS support +# # CONFIG_XFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set @@ -1089,7 +1158,6 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set # CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y CONFIG_TMPFS_XATTR=y @@ -1120,15 +1188,18 @@ CONFIG_RAMFS=y # CONFIG_NFS_FS=y CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set CONFIG_NFS_V4=y # CONFIG_NFS_DIRECTIO is not set CONFIG_NFSD=y CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set # CONFIG_NFSD_V4 is not set # CONFIG_NFSD_TCP is not set CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=y +CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y CONFIG_SUNRPC_GSS=y CONFIG_RPCSEC_GSS_KRB5=y @@ -1209,6 +1280,8 @@ CONFIG_NLS_UTF8=y # CONFIG_CRC_CCITT is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y # # Profiling support @@ -1218,14 +1291,18 @@ CONFIG_CRC32=y # # Kernel hacking # +# CONFIG_PRINTK_TIME is not set CONFIG_DEBUG_KERNEL=y CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=17 # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +CONFIG_KPROBES=y CONFIG_IA64_GRANULE_16MB=y # CONFIG_IA64_GRANULE_64MB is not set CONFIG_IA64_PRINT_HAZARDS=y @@ -1252,6 +1329,7 @@ CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_SHA256 is not set # CONFIG_CRYPTO_SHA512 is not set # CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_TWOFISH is not set diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index b8db6e3e5e81..11957598a8b9 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c @@ -156,10 +156,13 @@ */ #define DELAYED_RESOURCE_CNT 64 +#define PCI_DEVICE_ID_HP_SX2000_IOC 0x12ec + #define ZX1_IOC_ID ((PCI_DEVICE_ID_HP_ZX1_IOC << 16) | PCI_VENDOR_ID_HP) #define ZX2_IOC_ID ((PCI_DEVICE_ID_HP_ZX2_IOC << 16) | PCI_VENDOR_ID_HP) #define REO_IOC_ID ((PCI_DEVICE_ID_HP_REO_IOC << 16) | PCI_VENDOR_ID_HP) #define SX1000_IOC_ID ((PCI_DEVICE_ID_HP_SX1000_IOC << 16) | PCI_VENDOR_ID_HP) +#define SX2000_IOC_ID ((PCI_DEVICE_ID_HP_SX2000_IOC << 16) | PCI_VENDOR_ID_HP) #define ZX1_IOC_OFFSET 0x1000 /* ACPI reports SBA, we want IOC */ @@ -1726,6 +1729,7 @@ static struct ioc_iommu ioc_iommu_info[] __initdata = { { ZX1_IOC_ID, "zx1", ioc_zx1_init }, { ZX2_IOC_ID, "zx2", NULL }, { SX1000_IOC_ID, "sx1000", NULL }, + { SX2000_IOC_ID, "sx2000", NULL }, }; static struct ioc * __init diff --git a/arch/ia64/hp/sim/simeth.c b/arch/ia64/hp/sim/simeth.c index ae84a1018a89..0639ec0ed015 100644 --- a/arch/ia64/hp/sim/simeth.c +++ b/arch/ia64/hp/sim/simeth.c @@ -191,7 +191,7 @@ simeth_probe1(void) unsigned char mac_addr[ETH_ALEN]; struct simeth_local *local; struct net_device *dev; - int fd, i, err; + int fd, i, err, rc; /* * XXX Fix me @@ -228,7 +228,9 @@ simeth_probe1(void) return err; } - dev->irq = assign_irq_vector(AUTO_ASSIGN); + if ((rc = assign_irq_vector(AUTO_ASSIGN)) < 0) + panic("%s: out of interrupt vectors!\n", __FUNCTION__); + dev->irq = rc; /* * attach the interrupt in the simulator, this does enable interrupts diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index 786e70718ce4..7dcb8582ae0d 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c @@ -30,6 +30,7 @@ #include <linux/module.h> #include <linux/serial.h> #include <linux/serialP.h> +#include <linux/sysrq.h> #include <asm/irq.h> #include <asm/hw_irq.h> @@ -149,12 +150,17 @@ static void receive_chars(struct tty_struct *tty, struct pt_regs *regs) seen_esc = 2; continue; } else if ( seen_esc == 2 ) { - if ( ch == 'P' ) show_state(); /* F1 key */ -#ifdef CONFIG_KDB - if ( ch == 'S' ) - kdb(KDB_REASON_KEYBOARD, 0, (kdb_eframe_t) regs); + if ( ch == 'P' ) /* F1 */ + show_state(); +#ifdef CONFIG_MAGIC_SYSRQ + if ( ch == 'S' ) { /* F4 */ + do + ch = ia64_ssc(0, 0, 0, 0, + SSC_GETCHAR); + while (!ch); + handle_sysrq(ch, regs, NULL); + } #endif - seen_esc = 0; continue; } @@ -976,7 +982,7 @@ static struct tty_operations hp_ops = { static int __init simrs_init (void) { - int i; + int i, rc; struct serial_state *state; if (!ia64_platform_is("hpsim")) @@ -1011,7 +1017,10 @@ simrs_init (void) if (state->type == PORT_UNKNOWN) continue; if (!state->irq) { - state->irq = assign_irq_vector(AUTO_ASSIGN); + if ((rc = assign_irq_vector(AUTO_ASSIGN)) < 0) + panic("%s: out of interrupt vectors!\n", + __FUNCTION__); + state->irq = rc; ia64_ssc_connect_irq(KEYBOARD_INTR, state->irq); } diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile index b2e2f6509eb0..e1fb68ddec26 100644 --- a/arch/ia64/kernel/Makefile +++ b/arch/ia64/kernel/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_IA64_PALINFO) += palinfo.o obj-$(CONFIG_IOSAPIC) += iosapic.o obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_SMP) += smp.o smpboot.o domain.o +obj-$(CONFIG_NUMA) += numa.o obj-$(CONFIG_PERFMON) += perfmon_default_smpl.o obj-$(CONFIG_IA64_CYCLONE) += cyclone.o obj-$(CONFIG_IA64_MCA_RECOVERY) += mca_recovery.o diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 72dfd9e7de0f..9609f243e5d0 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -11,6 +11,7 @@ * Copyright (C) 2001 Jenna Hall <jenna.s.hall@intel.com> * Copyright (C) 2001 Takayoshi Kochi <t-kochi@bq.jp.nec.com> * Copyright (C) 2002 Erich Focht <efocht@ess.nec.de> + * Copyright (C) 2004 Ashok Raj <ashok.raj@intel.com> * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * @@ -67,6 +68,11 @@ EXPORT_SYMBOL(pm_power_off); unsigned char acpi_kbd_controller_present = 1; unsigned char acpi_legacy_devices; +static unsigned int __initdata acpi_madt_rev; + +unsigned int acpi_cpei_override; +unsigned int acpi_cpei_phys_cpuid; + #define MAX_SAPICS 256 u16 ia64_acpiid_to_sapicid[MAX_SAPICS] = { [0 ... MAX_SAPICS - 1] = -1 }; @@ -236,9 +242,7 @@ acpi_parse_iosapic (acpi_table_entry_header *header, const unsigned long end) if (BAD_MADT_ENTRY(iosapic, end)) return -EINVAL; - iosapic_init(iosapic->address, iosapic->global_irq_base); - - return 0; + return iosapic_init(iosapic->address, iosapic->global_irq_base); } @@ -267,10 +271,56 @@ acpi_parse_plat_int_src ( (plintsrc->flags.trigger == 1) ? IOSAPIC_EDGE : IOSAPIC_LEVEL); platform_intr_list[plintsrc->type] = vector; + if (acpi_madt_rev > 1) { + acpi_cpei_override = plintsrc->plint_flags.cpei_override_flag; + } + + /* + * Save the physical id, so we can check when its being removed + */ + acpi_cpei_phys_cpuid = ((plintsrc->id << 8) | (plintsrc->eid)) & 0xffff; + return 0; } +unsigned int can_cpei_retarget(void) +{ + extern int cpe_vector; + + /* + * Only if CPEI is supported and the override flag + * is present, otherwise return that its re-targettable + * if we are in polling mode. + */ + if (cpe_vector > 0 && !acpi_cpei_override) + return 0; + else + return 1; +} + +unsigned int is_cpu_cpei_target(unsigned int cpu) +{ + unsigned int logical_id; + + logical_id = cpu_logical_id(acpi_cpei_phys_cpuid); + + if (logical_id == cpu) + return 1; + else + return 0; +} + +void set_cpei_target_cpu(unsigned int cpu) +{ + acpi_cpei_phys_cpuid = cpu_physical_id(cpu); +} + +unsigned int get_cpei_target_cpu(void) +{ + return acpi_cpei_phys_cpuid; +} + static int __init acpi_parse_int_src_ovr ( acpi_table_entry_header *header, const unsigned long end) @@ -328,6 +378,8 @@ acpi_parse_madt (unsigned long phys_addr, unsigned long size) acpi_madt = (struct acpi_table_madt *) __va(phys_addr); + acpi_madt_rev = acpi_madt->header.revision; + /* remember the value for reference after free_initmem() */ #ifdef CONFIG_ITANIUM has_8259 = 1; /* Firmware on old Itanium systems is broken */ @@ -642,9 +694,11 @@ acpi_boot_init (void) if (smp_boot_data.cpu_phys_id[cpu] != hard_smp_processor_id()) node_cpuid[i++].phys_id = smp_boot_data.cpu_phys_id[cpu]; } - build_cpu_to_node_map(); # endif #endif +#ifdef CONFIG_ACPI_NUMA + build_cpu_to_node_map(); +#endif /* Make boot-up look pretty */ printk(KERN_INFO "%d CPUs available, %d CPUs total\n", available_cpus, total_cpus); return 0; @@ -772,7 +826,7 @@ EXPORT_SYMBOL(acpi_unmap_lsapic); #ifdef CONFIG_ACPI_NUMA -acpi_status __init +acpi_status __devinit acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret) { struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; @@ -825,4 +879,28 @@ acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret) return AE_OK; } #endif /* CONFIG_NUMA */ + +int +acpi_register_ioapic (acpi_handle handle, u64 phys_addr, u32 gsi_base) +{ + int err; + + if ((err = iosapic_init(phys_addr, gsi_base))) + return err; + +#if CONFIG_ACPI_NUMA + acpi_map_iosapic(handle, 0, NULL, NULL); +#endif /* CONFIG_ACPI_NUMA */ + + return 0; +} +EXPORT_SYMBOL(acpi_register_ioapic); + +int +acpi_unregister_ioapic (acpi_handle handle, u32 gsi_base) +{ + return iosapic_remove(gsi_base); +} +EXPORT_SYMBOL(acpi_unregister_ioapic); + #endif /* CONFIG_ACPI_BOOT */ diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index b1d5d3d5276c..bb9a506deb78 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -470,18 +470,6 @@ ENTRY(load_switch_stack) br.cond.sptk.many b7 END(load_switch_stack) -GLOBAL_ENTRY(__ia64_syscall) - .regstk 6,0,0,0 - mov r15=in5 // put syscall number in place - break __BREAK_SYSCALL - movl r2=errno - cmp.eq p6,p7=-1,r10 - ;; -(p6) st4 [r2]=r8 -(p6) mov r8=-1 - br.ret.sptk.many rp -END(__ia64_syscall) - GLOBAL_ENTRY(execve) mov r15=__NR_execve // put syscall number in place break __BREAK_SYSCALL @@ -637,7 +625,7 @@ END(ia64_ret_from_syscall) * r8-r11: restored (syscall return value(s)) * r12: restored (user-level stack pointer) * r13: restored (user-level thread pointer) - * r14: cleared + * r14: set to __kernel_syscall_via_epc * r15: restored (syscall #) * r16-r17: cleared * r18: user-level b6 @@ -658,7 +646,7 @@ END(ia64_ret_from_syscall) * pr: restored (user-level pr) * b0: restored (user-level rp) * b6: restored - * b7: cleared + * b7: set to __kernel_syscall_via_epc * ar.unat: restored (user-level ar.unat) * ar.pfs: restored (user-level ar.pfs) * ar.rsc: restored (user-level ar.rsc) @@ -704,72 +692,79 @@ ENTRY(ia64_leave_syscall) ;; (p6) ld4 r31=[r18] // load current_thread_info()->flags ld8 r19=[r2],PT(B6)-PT(LOADRS) // load ar.rsc value for "loadrs" - mov b7=r0 // clear b7 + nop.i 0 ;; - ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE) // load ar.bspstore (may be garbage) + mov r16=ar.bsp // M2 get existing backing store pointer ld8 r18=[r2],PT(R9)-PT(B6) // load b6 (p6) and r15=TIF_WORK_MASK,r31 // any work other than TIF_SYSCALL_TRACE? ;; - mov r16=ar.bsp // M2 get existing backing store pointer + ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE) // load ar.bspstore (may be garbage) (p6) cmp4.ne.unc p6,p0=r15, r0 // any special work pending? (p6) br.cond.spnt .work_pending_syscall ;; // start restoring the state saved on the kernel stack (struct pt_regs): ld8 r9=[r2],PT(CR_IPSR)-PT(R9) ld8 r11=[r3],PT(CR_IIP)-PT(R11) - mov f6=f0 // clear f6 +(pNonSys) break 0 // bug check: we shouldn't be here if pNonSys is TRUE! ;; invala // M0|1 invalidate ALAT - rsm psr.i | psr.ic // M2 initiate turning off of interrupt and interruption collection - mov f9=f0 // clear f9 + rsm psr.i | psr.ic // M2 turn off interrupts and interruption collection + cmp.eq p9,p0=r0,r0 // A set p9 to indicate that we should restore cr.ifs - ld8 r29=[r2],16 // load cr.ipsr - ld8 r28=[r3],16 // load cr.iip - mov f8=f0 // clear f8 + ld8 r29=[r2],16 // M0|1 load cr.ipsr + ld8 r28=[r3],16 // M0|1 load cr.iip + mov r22=r0 // A clear r22 ;; ld8 r30=[r2],16 // M0|1 load cr.ifs ld8 r25=[r3],16 // M0|1 load ar.unat - cmp.eq p9,p0=r0,r0 // set p9 to indicate that we should restore cr.ifs +(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13 ;; ld8 r26=[r2],PT(B0)-PT(AR_PFS) // M0|1 load ar.pfs -(pKStk) mov r22=psr // M2 read PSR now that interrupts are disabled - mov f10=f0 // clear f10 +(pKStk) mov r22=psr // M2 read PSR now that interrupts are disabled + nop 0 ;; - ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // load b0 - ld8 r27=[r3],PT(PR)-PT(AR_RSC) // load ar.rsc - mov f11=f0 // clear f11 + ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // M0|1 load b0 + ld8 r27=[r3],PT(PR)-PT(AR_RSC) // M0|1 load ar.rsc + mov f6=f0 // F clear f6 ;; - ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT) // load ar.rnat (may be garbage) - ld8 r31=[r3],PT(R1)-PT(PR) // load predicates -(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13 + ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT) // M0|1 load ar.rnat (may be garbage) + ld8 r31=[r3],PT(R1)-PT(PR) // M0|1 load predicates + mov f7=f0 // F clear f7 ;; - ld8 r20=[r2],PT(R12)-PT(AR_FPSR) // load ar.fpsr - ld8.fill r1=[r3],16 // load r1 -(pUStk) mov r17=1 + ld8 r20=[r2],PT(R12)-PT(AR_FPSR) // M0|1 load ar.fpsr + ld8.fill r1=[r3],16 // M0|1 load r1 +(pUStk) mov r17=1 // A ;; - srlz.d // M0 ensure interruption collection is off - ld8.fill r13=[r3],16 - mov f7=f0 // clear f7 +(pUStk) st1 [r14]=r17 // M2|3 + ld8.fill r13=[r3],16 // M0|1 + mov f8=f0 // F clear f8 ;; - ld8.fill r12=[r2] // restore r12 (sp) - mov.m ar.ssd=r0 // M2 clear ar.ssd - mov r22=r0 // clear r22 + ld8.fill r12=[r2] // M0|1 restore r12 (sp) + ld8.fill r15=[r3] // M0|1 restore r15 + mov b6=r18 // I0 restore b6 - ld8.fill r15=[r3] // restore r15 -(pUStk) st1 [r14]=r17 - addl r3=THIS_CPU(ia64_phys_stacked_size_p8),r0 + addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0 // A + mov f9=f0 // F clear f9 +(pKStk) br.cond.dpnt.many skip_rbs_switch // B + + srlz.d // M0 ensure interruption collection is off (for cover) + shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition + cover // B add current frame into dirty partition & set cr.ifs ;; -(pUStk) ld4 r17=[r3] // r17 = cpu_data->phys_stacked_size_p8 - mov.m ar.csd=r0 // M2 clear ar.csd - mov b6=r18 // I0 restore b6 +(pUStk) ld4 r17=[r17] // M0|1 r17 = cpu_data->phys_stacked_size_p8 + mov r19=ar.bsp // M2 get new backing store pointer + mov f10=f0 // F clear f10 + + nop.m 0 + movl r14=__kernel_syscall_via_epc // X ;; - mov r14=r0 // clear r14 - shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition -(pKStk) br.cond.dpnt.many skip_rbs_switch + mov.m ar.csd=r0 // M2 clear ar.csd + mov.m ar.ccv=r0 // M2 clear ar.ccv + mov b7=r14 // I0 clear b7 (hint with __kernel_syscall_via_epc) - mov.m ar.ccv=r0 // clear ar.ccv -(pNonSys) br.cond.dpnt.many dont_preserve_current_frame - br.cond.sptk.many rbs_switch + mov.m ar.ssd=r0 // M2 clear ar.ssd + mov f11=f0 // F clear f11 + br.cond.sptk.many rbs_switch // B END(ia64_leave_syscall) #ifdef CONFIG_IA32_SUPPORT @@ -885,7 +880,7 @@ GLOBAL_ENTRY(ia64_leave_kernel) ldf.fill f7=[r2],PT(F11)-PT(F7) ldf.fill f8=[r3],32 ;; - srlz.i // ensure interruption collection is off + srlz.d // ensure that inter. collection is off (VHPT is don't care, since text is pinned) mov ar.ccv=r15 ;; ldf.fill f11=[r2] @@ -945,11 +940,10 @@ GLOBAL_ENTRY(ia64_leave_kernel) * NOTE: alloc, loadrs, and cover can't be predicated. */ (pNonSys) br.cond.dpnt dont_preserve_current_frame - -rbs_switch: cover // add current frame into dirty partition and set cr.ifs ;; mov r19=ar.bsp // get new backing store pointer +rbs_switch: sub r16=r16,r18 // krbs = old bsp - size of dirty partition cmp.ne p9,p0=r0,r0 // clear p9 to skip restore of cr.ifs ;; @@ -1024,14 +1018,14 @@ rse_clear_invalid: mov loc5=0 mov loc6=0 mov loc7=0 -(pRecurse) br.call.sptk.few b0=rse_clear_invalid +(pRecurse) br.call.dptk.few b0=rse_clear_invalid ;; mov loc8=0 mov loc9=0 cmp.ne pReturn,p0=r0,in1 // if recursion count != 0, we need to do a br.ret mov loc10=0 mov loc11=0 -(pReturn) br.ret.sptk.many b0 +(pReturn) br.ret.dptk.many b0 #endif /* !CONFIG_ITANIUM */ # undef pRecurse # undef pReturn @@ -1255,7 +1249,7 @@ ENTRY(sys_rt_sigreturn) stf.spill [r17]=f11 adds out0=16,sp // out0 = &sigscratch br.call.sptk.many rp=ia64_rt_sigreturn -.ret19: .restore sp 0 +.ret19: .restore sp,0 adds sp=16,sp ;; ld8 r9=[sp] // load new ar.unat @@ -1577,8 +1571,8 @@ sys_call_table: data8 sys_add_key data8 sys_request_key data8 sys_keyctl - data8 sys_ni_syscall - data8 sys_ni_syscall // 1275 + data8 sys_ioprio_set + data8 sys_ioprio_get // 1275 data8 sys_set_zone_reclaim data8 sys_ni_syscall data8 sys_ni_syscall diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S index 962b6c4e32b5..7d7684a369d3 100644 --- a/arch/ia64/kernel/fsys.S +++ b/arch/ia64/kernel/fsys.S @@ -531,93 +531,114 @@ GLOBAL_ENTRY(fsys_bubble_down) .altrp b6 .body /* - * We get here for syscalls that don't have a lightweight handler. For those, we - * need to bubble down into the kernel and that requires setting up a minimal - * pt_regs structure, and initializing the CPU state more or less as if an - * interruption had occurred. To make syscall-restarts work, we setup pt_regs - * such that cr_iip points to the second instruction in syscall_via_break. - * Decrementing the IP hence will restart the syscall via break and not - * decrementing IP will return us to the caller, as usual. Note that we preserve - * the value of psr.pp rather than initializing it from dcr.pp. This makes it - * possible to distinguish fsyscall execution from other privileged execution. + * We get here for syscalls that don't have a lightweight + * handler. For those, we need to bubble down into the kernel + * and that requires setting up a minimal pt_regs structure, + * and initializing the CPU state more or less as if an + * interruption had occurred. To make syscall-restarts work, + * we setup pt_regs such that cr_iip points to the second + * instruction in syscall_via_break. Decrementing the IP + * hence will restart the syscall via break and not + * decrementing IP will return us to the caller, as usual. + * Note that we preserve the value of psr.pp rather than + * initializing it from dcr.pp. This makes it possible to + * distinguish fsyscall execution from other privileged + * execution. * * On entry: - * - normal fsyscall handler register usage, except that we also have: + * - normal fsyscall handler register usage, except + * that we also have: * - r18: address of syscall entry point * - r21: ar.fpsr * - r26: ar.pfs * - r27: ar.rsc * - r29: psr + * + * We used to clear some PSR bits here but that requires slow + * serialization. Fortuntely, that isn't really necessary. + * The rationale is as follows: we used to clear bits + * ~PSR_PRESERVED_BITS in PSR.L. Since + * PSR_PRESERVED_BITS==PSR.{UP,MFL,MFH,PK,DT,PP,SP,RT,IC}, we + * ended up clearing PSR.{BE,AC,I,DFL,DFH,DI,DB,SI,TB}. + * However, + * + * PSR.BE : already is turned off in __kernel_syscall_via_epc() + * PSR.AC : don't care (kernel normally turns PSR.AC on) + * PSR.I : already turned off by the time fsys_bubble_down gets + * invoked + * PSR.DFL: always 0 (kernel never turns it on) + * PSR.DFH: don't care --- kernel never touches f32-f127 on its own + * initiative + * PSR.DI : always 0 (kernel never turns it on) + * PSR.SI : always 0 (kernel never turns it on) + * PSR.DB : don't care --- kernel never enables kernel-level + * breakpoints + * PSR.TB : must be 0 already; if it wasn't zero on entry to + * __kernel_syscall_via_epc, the branch to fsys_bubble_down + * will trigger a taken branch; the taken-trap-handler then + * converts the syscall into a break-based system-call. */ -# define PSR_PRESERVED_BITS (IA64_PSR_UP | IA64_PSR_MFL | IA64_PSR_MFH | IA64_PSR_PK \ - | IA64_PSR_DT | IA64_PSR_PP | IA64_PSR_SP | IA64_PSR_RT \ - | IA64_PSR_IC) /* - * Reading psr.l gives us only bits 0-31, psr.it, and psr.mc. The rest we have - * to synthesize. + * Reading psr.l gives us only bits 0-31, psr.it, and psr.mc. + * The rest we have to synthesize. */ -# define PSR_ONE_BITS ((3 << IA64_PSR_CPL0_BIT) | (0x1 << IA64_PSR_RI_BIT) \ +# define PSR_ONE_BITS ((3 << IA64_PSR_CPL0_BIT) \ + | (0x1 << IA64_PSR_RI_BIT) \ | IA64_PSR_BN | IA64_PSR_I) - invala - movl r8=PSR_ONE_BITS + invala // M0|1 + movl r14=ia64_ret_from_syscall // X - mov r25=ar.unat // save ar.unat (5 cyc) - movl r9=PSR_PRESERVED_BITS + nop.m 0 + movl r28=__kernel_syscall_via_break // X create cr.iip + ;; - mov ar.rsc=0 // set enforced lazy mode, pl 0, little-endian, loadrs=0 - movl r28=__kernel_syscall_via_break + mov r2=r16 // A get task addr to addl-addressable register + adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 // A + mov r31=pr // I0 save pr (2 cyc) ;; - mov r23=ar.bspstore // save ar.bspstore (12 cyc) - mov r31=pr // save pr (2 cyc) - mov r20=r1 // save caller's gp in r20 + st1 [r16]=r0 // M2|3 clear current->thread.on_ustack flag + addl r22=IA64_RBS_OFFSET,r2 // A compute base of RBS + add r3=TI_FLAGS+IA64_TASK_SIZE,r2 // A ;; - mov r2=r16 // copy current task addr to addl-addressable register - and r9=r9,r29 - mov r19=b6 // save b6 (2 cyc) + ld4 r3=[r3] // M0|1 r3 = current_thread_info()->flags + lfetch.fault.excl.nt1 [r22] // M0|1 prefetch register backing-store + nop.i 0 ;; - mov psr.l=r9 // slam the door (17 cyc to srlz.i) - or r29=r8,r29 // construct cr.ipsr value to save - addl r22=IA64_RBS_OFFSET,r2 // compute base of RBS + mov ar.rsc=0 // M2 set enforced lazy mode, pl 0, LE, loadrs=0 + nop.m 0 + nop.i 0 ;; - // GAS reports a spurious RAW hazard on the read of ar.rnat because it thinks - // we may be reading ar.itc after writing to psr.l. Avoid that message with - // this directive: - dv_serialize_data - mov.m r24=ar.rnat // read ar.rnat (5 cyc lat) - lfetch.fault.excl.nt1 [r22] - adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r2 - - // ensure previous insn group is issued before we stall for srlz.i: + mov r23=ar.bspstore // M2 (12 cyc) save ar.bspstore + mov.m r24=ar.rnat // M2 (5 cyc) read ar.rnat (dual-issues!) + nop.i 0 ;; - srlz.i // ensure new psr.l has been established - ///////////////////////////////////////////////////////////////////////////// - ////////// from this point on, execution is not interruptible anymore - ///////////////////////////////////////////////////////////////////////////// - addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2 // compute base of memory stack - cmp.ne pKStk,pUStk=r0,r0 // set pKStk <- 0, pUStk <- 1 + mov ar.bspstore=r22 // M2 (6 cyc) switch to kernel RBS + movl r8=PSR_ONE_BITS // X ;; - st1 [r16]=r0 // clear current->thread.on_ustack flag - mov ar.bspstore=r22 // switch to kernel RBS - mov b6=r18 // copy syscall entry-point to b6 (7 cyc) - add r3=TI_FLAGS+IA64_TASK_SIZE,r2 + mov r25=ar.unat // M2 (5 cyc) save ar.unat + mov r19=b6 // I0 save b6 (2 cyc) + mov r20=r1 // A save caller's gp in r20 ;; - ld4 r3=[r3] // r2 = current_thread_info()->flags - mov r18=ar.bsp // save (kernel) ar.bsp (12 cyc) - mov ar.rsc=0x3 // set eager mode, pl 0, little-endian, loadrs=0 - br.call.sptk.many b7=ia64_syscall_setup - ;; - ssm psr.i - movl r2=ia64_ret_from_syscall + or r29=r8,r29 // A construct cr.ipsr value to save + mov b6=r18 // I0 copy syscall entry-point to b6 (7 cyc) + addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2 // A compute base of memory stack + + mov r18=ar.bsp // M2 save (kernel) ar.bsp (12 cyc) + cmp.ne pKStk,pUStk=r0,r0 // A set pKStk <- 0, pUStk <- 1 + br.call.sptk.many b7=ia64_syscall_setup // B ;; - mov rp=r2 // set the real return addr - and r3=_TIF_SYSCALL_TRACEAUDIT,r3 + mov ar.rsc=0x3 // M2 set eager mode, pl 0, LE, loadrs=0 + mov rp=r14 // I0 set the real return addr + and r3=_TIF_SYSCALL_TRACEAUDIT,r3 // A ;; - cmp.eq p8,p0=r3,r0 + ssm psr.i // M2 we're on kernel stacks now, reenable irqs + cmp.eq p8,p0=r3,r0 // A +(p10) br.cond.spnt.many ia64_ret_from_syscall // B return if bad call-frame or r15 is a NaT -(p10) br.cond.spnt.many ia64_ret_from_syscall // p10==true means out registers are more than 8 -(p8) br.call.sptk.many b6=b6 // ignore this return addr - br.cond.sptk ia64_trace_syscall + nop.m 0 +(p8) br.call.sptk.many b6=b6 // B (ignore return address) + br.cond.spnt ia64_trace_syscall // B END(fsys_bubble_down) .rodata diff --git a/arch/ia64/kernel/gate.S b/arch/ia64/kernel/gate.S index facf75acdc85..86948ce63e43 100644 --- a/arch/ia64/kernel/gate.S +++ b/arch/ia64/kernel/gate.S @@ -72,38 +72,40 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc) * bundle get executed. The remaining code must be safe even if * they do not get executed. */ - adds r17=-1024,r15 - mov r10=0 // default to successful syscall execution - epc + adds r17=-1024,r15 // A + mov r10=0 // A default to successful syscall execution + epc // B causes split-issue } ;; - rsm psr.be // note: on McKinley "rsm psr.be/srlz.d" is slightly faster than "rum psr.be" - LOAD_FSYSCALL_TABLE(r14) - - mov r16=IA64_KR(CURRENT) // 12 cycle read latency - tnat.nz p10,p9=r15 - mov r19=NR_syscalls-1 + rsm psr.be | psr.i // M2 (5 cyc to srlz.d) + LOAD_FSYSCALL_TABLE(r14) // X ;; - shladd r18=r17,3,r14 - - srlz.d - cmp.ne p8,p0=r0,r0 // p8 <- FALSE - /* Note: if r17 is a NaT, p6 will be set to zero. */ - cmp.geu p6,p7=r19,r17 // (syscall > 0 && syscall < 1024+NR_syscalls)? - ;; -(p6) ld8 r18=[r18] - mov r21=ar.fpsr - add r14=-8,r14 // r14 <- addr of fsys_bubble_down entry - ;; -(p6) mov b7=r18 -(p6) tbit.z p8,p0=r18,0 -(p8) br.dptk.many b7 - -(p6) rsm psr.i - mov r27=ar.rsc - mov r26=ar.pfs + mov r16=IA64_KR(CURRENT) // M2 (12 cyc) + shladd r18=r17,3,r14 // A + mov r19=NR_syscalls-1 // A + ;; + lfetch [r18] // M0|1 + mov r29=psr // M2 (12 cyc) + // If r17 is a NaT, p6 will be zero + cmp.geu p6,p7=r19,r17 // A (sysnr > 0 && sysnr < 1024+NR_syscalls)? + ;; + mov r21=ar.fpsr // M2 (12 cyc) + tnat.nz p10,p9=r15 // I0 + mov.i r26=ar.pfs // I0 (would stall anyhow due to srlz.d...) + ;; + srlz.d // M0 (forces split-issue) ensure PSR.BE==0 +(p6) ld8 r18=[r18] // M0|1 + nop.i 0 + ;; + nop.m 0 +(p6) tbit.z.unc p8,p0=r18,0 // I0 (dual-issues with "mov b7=r18"!) + nop.i 0 ;; - mov r29=psr // read psr (12 cyc load latency) +(p8) ssm psr.i +(p6) mov b7=r18 // I0 +(p8) br.dptk.many b7 // B + + mov r27=ar.rsc // M2 (12 cyc) /* * brl.cond doesn't work as intended because the linker would convert this branch * into a branch to a PLT. Perhaps there will be a way to avoid this with some @@ -111,6 +113,8 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc) * instead. */ #ifdef CONFIG_ITANIUM +(p6) add r14=-8,r14 // r14 <- addr of fsys_bubble_down entry + ;; (p6) ld8 r14=[r14] // r14 <- fsys_bubble_down ;; (p6) mov b7=r14 @@ -118,7 +122,7 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc) #else BRL_COND_FSYS_BUBBLE_DOWN(p6) #endif - + ssm psr.i mov r10=-1 (p10) mov r8=EINVAL (p9) mov r8=ENOSYS diff --git a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c index 7bbf019c9867..01572814abe4 100644 --- a/arch/ia64/kernel/ia64_ksyms.c +++ b/arch/ia64/kernel/ia64_ksyms.c @@ -58,9 +58,6 @@ EXPORT_SYMBOL(__strlen_user); EXPORT_SYMBOL(__strncpy_from_user); EXPORT_SYMBOL(__strnlen_user); -#include <asm/unistd.h> -EXPORT_SYMBOL(__ia64_syscall); - /* from arch/ia64/lib */ extern void __divsi3(void); extern void __udivsi3(void); diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index 88b014381df5..7936b62f7a2e 100644 --- a/arch/ia64/kernel/iosapic.c +++ b/arch/ia64/kernel/iosapic.c @@ -129,14 +129,13 @@ static struct iosapic { char __iomem *addr; /* base address of IOSAPIC */ unsigned int gsi_base; /* first GSI assigned to this IOSAPIC */ unsigned short num_rte; /* number of RTE in this IOSAPIC */ + int rtes_inuse; /* # of RTEs in use on this IOSAPIC */ #ifdef CONFIG_NUMA unsigned short node; /* numa node association via pxm */ #endif } iosapic_lists[NR_IOSAPICS]; -static int num_iosapic; - -static unsigned char pcat_compat __initdata; /* 8259 compatibility flag */ +static unsigned char pcat_compat __devinitdata; /* 8259 compatibility flag */ static int iosapic_kmalloc_ok; static LIST_HEAD(free_rte_list); @@ -149,7 +148,7 @@ find_iosapic (unsigned int gsi) { int i; - for (i = 0; i < num_iosapic; i++) { + for (i = 0; i < NR_IOSAPICS; i++) { if ((unsigned) (gsi - iosapic_lists[i].gsi_base) < iosapic_lists[i].num_rte) return i; } @@ -490,8 +489,6 @@ static int iosapic_find_sharable_vector (unsigned long trigger, unsigned long po } } } - if (vector < 0) - panic("%s: out of interrupt vectors!\n", __FUNCTION__); return vector; } @@ -507,6 +504,8 @@ iosapic_reassign_vector (int vector) if (!list_empty(&iosapic_intr_info[vector].rtes)) { new_vector = assign_irq_vector(AUTO_ASSIGN); + if (new_vector < 0) + panic("%s: out of interrupt vectors!\n", __FUNCTION__); printk(KERN_INFO "Reassigning vector %d to %d\n", vector, new_vector); memcpy(&iosapic_intr_info[new_vector], &iosapic_intr_info[vector], sizeof(struct iosapic_intr_info)); @@ -598,6 +597,7 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery, rte->refcnt++; list_add_tail(&rte->rte_list, &iosapic_intr_info[vector].rtes); iosapic_intr_info[vector].count++; + iosapic_lists[index].rtes_inuse++; } else if (vector_is_shared(vector)) { struct iosapic_intr_info *info = &iosapic_intr_info[vector]; @@ -734,9 +734,12 @@ again: spin_unlock_irqrestore(&iosapic_lock, flags); /* If vector is running out, we try to find a sharable vector */ - vector = assign_irq_vector_nopanic(AUTO_ASSIGN); - if (vector < 0) + vector = assign_irq_vector(AUTO_ASSIGN); + if (vector < 0) { vector = iosapic_find_sharable_vector(trigger, polarity); + if (vector < 0) + panic("%s: out of interrupt vectors!\n", __FUNCTION__); + } spin_lock_irqsave(&irq_descp(vector)->lock, flags); spin_lock(&iosapic_lock); @@ -778,7 +781,7 @@ void iosapic_unregister_intr (unsigned int gsi) { unsigned long flags; - int irq, vector; + int irq, vector, index; irq_desc_t *idesc; u32 low32; unsigned long trigger, polarity; @@ -819,6 +822,9 @@ iosapic_unregister_intr (unsigned int gsi) list_del(&rte->rte_list); iosapic_intr_info[vector].count--; iosapic_free_rte(rte); + index = find_iosapic(gsi); + iosapic_lists[index].rtes_inuse--; + WARN_ON(iosapic_lists[index].rtes_inuse < 0); trigger = iosapic_intr_info[vector].trigger; polarity = iosapic_intr_info[vector].polarity; @@ -881,6 +887,8 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi, break; case ACPI_INTERRUPT_INIT: vector = assign_irq_vector(AUTO_ASSIGN); + if (vector < 0) + panic("%s: out of interrupt vectors!\n", __FUNCTION__); delivery = IOSAPIC_INIT; break; case ACPI_INTERRUPT_CPEI: @@ -952,30 +960,86 @@ iosapic_system_init (int system_pcat_compat) } } -void __init +static inline int +iosapic_alloc (void) +{ + int index; + + for (index = 0; index < NR_IOSAPICS; index++) + if (!iosapic_lists[index].addr) + return index; + + printk(KERN_WARNING "%s: failed to allocate iosapic\n", __FUNCTION__); + return -1; +} + +static inline void +iosapic_free (int index) +{ + memset(&iosapic_lists[index], 0, sizeof(iosapic_lists[0])); +} + +static inline int +iosapic_check_gsi_range (unsigned int gsi_base, unsigned int ver) +{ + int index; + unsigned int gsi_end, base, end; + + /* check gsi range */ + gsi_end = gsi_base + ((ver >> 16) & 0xff); + for (index = 0; index < NR_IOSAPICS; index++) { + if (!iosapic_lists[index].addr) + continue; + + base = iosapic_lists[index].gsi_base; + end = base + iosapic_lists[index].num_rte - 1; + + if (gsi_base < base && gsi_end < base) + continue;/* OK */ + + if (gsi_base > end && gsi_end > end) + continue; /* OK */ + + return -EBUSY; + } + return 0; +} + +int __devinit iosapic_init (unsigned long phys_addr, unsigned int gsi_base) { - int num_rte; + int num_rte, err, index; unsigned int isa_irq, ver; char __iomem *addr; + unsigned long flags; - addr = ioremap(phys_addr, 0); - ver = iosapic_version(addr); + spin_lock_irqsave(&iosapic_lock, flags); + { + addr = ioremap(phys_addr, 0); + ver = iosapic_version(addr); - /* - * The MAX_REDIR register holds the highest input pin - * number (starting from 0). - * We add 1 so that we can use it for number of pins (= RTEs) - */ - num_rte = ((ver >> 16) & 0xff) + 1; + if ((err = iosapic_check_gsi_range(gsi_base, ver))) { + iounmap(addr); + spin_unlock_irqrestore(&iosapic_lock, flags); + return err; + } + + /* + * The MAX_REDIR register holds the highest input pin + * number (starting from 0). + * We add 1 so that we can use it for number of pins (= RTEs) + */ + num_rte = ((ver >> 16) & 0xff) + 1; - iosapic_lists[num_iosapic].addr = addr; - iosapic_lists[num_iosapic].gsi_base = gsi_base; - iosapic_lists[num_iosapic].num_rte = num_rte; + index = iosapic_alloc(); + iosapic_lists[index].addr = addr; + iosapic_lists[index].gsi_base = gsi_base; + iosapic_lists[index].num_rte = num_rte; #ifdef CONFIG_NUMA - iosapic_lists[num_iosapic].node = MAX_NUMNODES; + iosapic_lists[index].node = MAX_NUMNODES; #endif - num_iosapic++; + } + spin_unlock_irqrestore(&iosapic_lock, flags); if ((gsi_base == 0) && pcat_compat) { /* @@ -986,10 +1050,43 @@ iosapic_init (unsigned long phys_addr, unsigned int gsi_base) for (isa_irq = 0; isa_irq < 16; ++isa_irq) iosapic_override_isa_irq(isa_irq, isa_irq, IOSAPIC_POL_HIGH, IOSAPIC_EDGE); } + return 0; +} + +#ifdef CONFIG_HOTPLUG +int +iosapic_remove (unsigned int gsi_base) +{ + int index, err = 0; + unsigned long flags; + + spin_lock_irqsave(&iosapic_lock, flags); + { + index = find_iosapic(gsi_base); + if (index < 0) { + printk(KERN_WARNING "%s: No IOSAPIC for GSI base %u\n", + __FUNCTION__, gsi_base); + goto out; + } + + if (iosapic_lists[index].rtes_inuse) { + err = -EBUSY; + printk(KERN_WARNING "%s: IOSAPIC for GSI base %u is busy\n", + __FUNCTION__, gsi_base); + goto out; + } + + iounmap(iosapic_lists[index].addr); + iosapic_free(index); + } + out: + spin_unlock_irqrestore(&iosapic_lock, flags); + return err; } +#endif /* CONFIG_HOTPLUG */ #ifdef CONFIG_NUMA -void __init +void __devinit map_iosapic_to_node(unsigned int gsi_base, int node) { int index; diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index 4fe60c7a2e90..6c4d59fd0364 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c @@ -63,30 +63,19 @@ EXPORT_SYMBOL(isa_irq_to_vector_map); static unsigned long ia64_vector_mask[BITS_TO_LONGS(IA64_NUM_DEVICE_VECTORS)]; int -assign_irq_vector_nopanic (int irq) +assign_irq_vector (int irq) { int pos, vector; again: pos = find_first_zero_bit(ia64_vector_mask, IA64_NUM_DEVICE_VECTORS); vector = IA64_FIRST_DEVICE_VECTOR + pos; if (vector > IA64_LAST_DEVICE_VECTOR) - return -1; + return -ENOSPC; if (test_and_set_bit(pos, ia64_vector_mask)) goto again; return vector; } -int -assign_irq_vector (int irq) -{ - int vector = assign_irq_vector_nopanic(irq); - - if (vector < 0) - panic("assign_irq_vector: out of interrupt vectors!"); - - return vector; -} - void free_irq_vector (int vector) { diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S index 2bc085a73e30..3bb3a13c4047 100644 --- a/arch/ia64/kernel/ivt.S +++ b/arch/ia64/kernel/ivt.S @@ -1,7 +1,7 @@ /* * arch/ia64/kernel/ivt.S * - * Copyright (C) 1998-2001, 2003 Hewlett-Packard Co + * Copyright (C) 1998-2001, 2003, 2005 Hewlett-Packard Co * Stephane Eranian <eranian@hpl.hp.com> * David Mosberger <davidm@hpl.hp.com> * Copyright (C) 2000, 2002-2003 Intel Co @@ -692,82 +692,118 @@ ENTRY(break_fault) * to prevent leaking bits from kernel to user level. */ DBG_FAULT(11) - mov r16=IA64_KR(CURRENT) // r16 = current task; 12 cycle read lat. - mov r17=cr.iim - mov r18=__IA64_BREAK_SYSCALL - mov r21=ar.fpsr - mov r29=cr.ipsr - mov r19=b6 - mov r25=ar.unat - mov r27=ar.rsc - mov r26=ar.pfs - mov r28=cr.iip - mov r31=pr // prepare to save predicates - mov r20=r1 - ;; + mov.m r16=IA64_KR(CURRENT) // M2 r16 <- current task (12 cyc) + mov r29=cr.ipsr // M2 (12 cyc) + mov r31=pr // I0 (2 cyc) + + mov r17=cr.iim // M2 (2 cyc) + mov.m r27=ar.rsc // M2 (12 cyc) + mov r18=__IA64_BREAK_SYSCALL // A + + mov.m ar.rsc=0 // M2 + mov.m r21=ar.fpsr // M2 (12 cyc) + mov r19=b6 // I0 (2 cyc) + ;; + mov.m r23=ar.bspstore // M2 (12 cyc) + mov.m r24=ar.rnat // M2 (5 cyc) + mov.i r26=ar.pfs // I0 (2 cyc) + + invala // M0|1 + nop.m 0 // M + mov r20=r1 // A save r1 + + nop.m 0 + movl r30=sys_call_table // X + + mov r28=cr.iip // M2 (2 cyc) + cmp.eq p0,p7=r18,r17 // I0 is this a system call? +(p7) br.cond.spnt non_syscall // B no -> + // + // From this point on, we are definitely on the syscall-path + // and we can use (non-banked) scratch registers. + // +/////////////////////////////////////////////////////////////////////// + mov r1=r16 // A move task-pointer to "addl"-addressable reg + mov r2=r16 // A setup r2 for ia64_syscall_setup + add r9=TI_FLAGS+IA64_TASK_SIZE,r16 // A r9 = ¤t_thread_info()->flags + adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 - cmp.eq p0,p7=r18,r17 // is this a system call? (p7 <- false, if so) -(p7) br.cond.spnt non_syscall + adds r15=-1024,r15 // A subtract 1024 from syscall number + mov r3=NR_syscalls - 1 ;; - ld1 r17=[r16] // load current->thread.on_ustack flag - st1 [r16]=r0 // clear current->thread.on_ustack flag - add r1=-IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 // set r1 for MINSTATE_START_SAVE_MIN_VIRT + ld1.bias r17=[r16] // M0|1 r17 = current->thread.on_ustack flag + ld4 r9=[r9] // M0|1 r9 = current_thread_info()->flags + extr.u r8=r29,41,2 // I0 extract ei field from cr.ipsr + + shladd r30=r15,3,r30 // A r30 = sys_call_table + 8*(syscall-1024) + addl r22=IA64_RBS_OFFSET,r1 // A compute base of RBS + cmp.leu p6,p7=r15,r3 // A syscall number in range? ;; - invala - /* adjust return address so we skip over the break instruction: */ + lfetch.fault.excl.nt1 [r22] // M0|1 prefetch RBS +(p6) ld8 r30=[r30] // M0|1 load address of syscall entry point + tnat.nz.or p7,p0=r15 // I0 is syscall nr a NaT? - extr.u r8=r29,41,2 // extract ei field from cr.ipsr - ;; - cmp.eq p6,p7=2,r8 // isr.ei==2? - mov r2=r1 // setup r2 for ia64_syscall_setup - ;; -(p6) mov r8=0 // clear ei to 0 -(p6) adds r28=16,r28 // switch cr.iip to next bundle cr.ipsr.ei wrapped -(p7) adds r8=1,r8 // increment ei to next slot - ;; - cmp.eq pKStk,pUStk=r0,r17 // are we in kernel mode already? - dep r29=r8,r29,41,2 // insert new ei into cr.ipsr + mov.m ar.bspstore=r22 // M2 switch to kernel RBS + cmp.eq p8,p9=2,r8 // A isr.ei==2? ;; - // switch from user to kernel RBS: - MINSTATE_START_SAVE_MIN_VIRT - br.call.sptk.many b7=ia64_syscall_setup - ;; - MINSTATE_END_SAVE_MIN_VIRT // switch to bank 1 - ssm psr.ic | PSR_DEFAULT_BITS - ;; - srlz.i // guarantee that interruption collection is on - mov r3=NR_syscalls - 1 - ;; -(p15) ssm psr.i // restore psr.i - // p10==true means out registers are more than 8 or r15's Nat is true -(p10) br.cond.spnt.many ia64_ret_from_syscall - ;; - movl r16=sys_call_table +(p8) mov r8=0 // A clear ei to 0 +(p7) movl r30=sys_ni_syscall // X - adds r15=-1024,r15 // r15 contains the syscall number---subtract 1024 - movl r2=ia64_ret_from_syscall - ;; - shladd r20=r15,3,r16 // r20 = sys_call_table + 8*(syscall-1024) - cmp.leu p6,p7=r15,r3 // (syscall > 0 && syscall < 1024 + NR_syscalls) ? - mov rp=r2 // set the real return addr +(p8) adds r28=16,r28 // A switch cr.iip to next bundle +(p9) adds r8=1,r8 // A increment ei to next slot + nop.i 0 ;; -(p6) ld8 r20=[r20] // load address of syscall entry point -(p7) movl r20=sys_ni_syscall - add r2=TI_FLAGS+IA64_TASK_SIZE,r13 - ;; - ld4 r2=[r2] // r2 = current_thread_info()->flags - ;; - and r2=_TIF_SYSCALL_TRACEAUDIT,r2 // mask trace or audit + mov.m r25=ar.unat // M2 (5 cyc) + dep r29=r8,r29,41,2 // I0 insert new ei into cr.ipsr + adds r15=1024,r15 // A restore original syscall number + // + // If any of the above loads miss in L1D, we'll stall here until + // the data arrives. + // +/////////////////////////////////////////////////////////////////////// + st1 [r16]=r0 // M2|3 clear current->thread.on_ustack flag + mov b6=r30 // I0 setup syscall handler branch reg early + cmp.eq pKStk,pUStk=r0,r17 // A were we on kernel stacks already? + + and r9=_TIF_SYSCALL_TRACEAUDIT,r9 // A mask trace or audit + mov r18=ar.bsp // M2 (12 cyc) +(pKStk) br.cond.spnt .break_fixup // B we're already in kernel-mode -- fix up RBS + ;; +.back_from_break_fixup: +(pUStk) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1 // A compute base of memory stack + cmp.eq p14,p0=r9,r0 // A are syscalls being traced/audited? + br.call.sptk.many b7=ia64_syscall_setup // B +1: + mov ar.rsc=0x3 // M2 set eager mode, pl 0, LE, loadrs=0 + nop 0 + bsw.1 // B (6 cyc) regs are saved, switch to bank 1 ;; - cmp.eq p8,p0=r2,r0 - mov b6=r20 + + ssm psr.ic | PSR_DEFAULT_BITS // M2 now it's safe to re-enable intr.-collection + movl r3=ia64_ret_from_syscall // X ;; -(p8) br.call.sptk.many b6=b6 // ignore this return addr - br.cond.sptk ia64_trace_syscall + + srlz.i // M0 ensure interruption collection is on + mov rp=r3 // I0 set the real return addr +(p10) br.cond.spnt.many ia64_ret_from_syscall // B return if bad call-frame or r15 is a NaT + +(p15) ssm psr.i // M2 restore psr.i +(p14) br.call.sptk.many b6=b6 // B invoke syscall-handker (ignore return addr) + br.cond.spnt.many ia64_trace_syscall // B do syscall-tracing thingamagic // NOT REACHED +/////////////////////////////////////////////////////////////////////// + // On entry, we optimistically assumed that we're coming from user-space. + // For the rare cases where a system-call is done from within the kernel, + // we fix things up at this point: +.break_fixup: + add r1=-IA64_PT_REGS_SIZE,sp // A allocate space for pt_regs structure + mov ar.rnat=r24 // M2 restore kernel's AR.RNAT + ;; + mov ar.bspstore=r23 // M2 restore kernel's AR.BSPSTORE + br.cond.sptk .back_from_break_fixup END(break_fault) .org ia64_ivt+0x3000 @@ -842,8 +878,6 @@ END(interrupt) * - r31: saved pr * - b0: original contents (to be saved) * On exit: - * - executing on bank 1 registers - * - psr.ic enabled, interrupts restored * - p10: TRUE if syscall is invoked with more than 8 out * registers or r15's Nat is true * - r1: kernel's gp @@ -851,8 +885,11 @@ END(interrupt) * - r8: -EINVAL if p10 is true * - r12: points to kernel stack * - r13: points to current task + * - r14: preserved (same as on entry) + * - p13: preserved * - p15: TRUE if interrupts need to be re-enabled * - ar.fpsr: set to kernel settings + * - b6: preserved (same as on entry) */ GLOBAL_ENTRY(ia64_syscall_setup) #if PT(B6) != 0 @@ -920,10 +957,10 @@ GLOBAL_ENTRY(ia64_syscall_setup) (p13) mov in5=-1 ;; st8 [r16]=r21,PT(R8)-PT(AR_FPSR) // save ar.fpsr - tnat.nz p14,p0=in6 + tnat.nz p13,p0=in6 cmp.lt p10,p9=r11,r8 // frame size can't be more than local+8 ;; - stf8 [r16]=f1 // ensure pt_regs.r8 != 0 (see handle_syscall_error) + mov r8=1 (p9) tnat.nz p10,p0=r15 adds r12=-16,r1 // switch to kernel memory stack (with 16 bytes of scratch) @@ -934,9 +971,9 @@ GLOBAL_ENTRY(ia64_syscall_setup) mov r13=r2 // establish `current' movl r1=__gp // establish kernel global pointer ;; -(p14) mov in6=-1 + st8 [r16]=r8 // ensure pt_regs.r8 != 0 (see handle_syscall_error) +(p13) mov in6=-1 (p8) mov in7=-1 - nop.i 0 cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0 movl r17=FPSR_DEFAULT @@ -1007,6 +1044,8 @@ END(dispatch_illegal_op_fault) FAULT(17) ENTRY(non_syscall) + mov ar.rsc=r27 // restore ar.rsc before SAVE_MIN_WITH_COVER + ;; SAVE_MIN_WITH_COVER // There is no particular reason for this code to be here, other than that @@ -1204,6 +1243,25 @@ END(disabled_fp_reg) // 0x5600 Entry 26 (size 16 bundles) Nat Consumption (11,23,37,50) ENTRY(nat_consumption) DBG_FAULT(26) + + mov r16=cr.ipsr + mov r17=cr.isr + mov r31=pr // save PR + ;; + and r18=0xf,r17 // r18 = cr.ipsr.code{3:0} + tbit.z p6,p0=r17,IA64_ISR_NA_BIT + ;; + cmp.ne.or p6,p0=IA64_ISR_CODE_LFETCH,r18 + dep r16=-1,r16,IA64_PSR_ED_BIT,1 +(p6) br.cond.spnt 1f // branch if (cr.ispr.na == 0 || cr.ipsr.code{3:0} != LFETCH) + ;; + mov cr.ipsr=r16 // set cr.ipsr.na + mov pr=r31,-1 + ;; + rfi + +1: mov pr=r31,-1 + ;; FAULT(26) END(nat_consumption) diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c index 5978823d5c63..884f5cd27d8a 100644 --- a/arch/ia64/kernel/kprobes.c +++ b/arch/ia64/kernel/kprobes.c @@ -34,6 +34,7 @@ #include <asm/pgtable.h> #include <asm/kdebug.h> +#include <asm/sections.h> extern void jprobe_inst_return(void); @@ -263,13 +264,33 @@ static inline void get_kprobe_inst(bundle_t *bundle, uint slot, } } +/* Returns non-zero if the addr is in the Interrupt Vector Table */ +static inline int in_ivt_functions(unsigned long addr) +{ + return (addr >= (unsigned long)__start_ivt_text + && addr < (unsigned long)__end_ivt_text); +} + static int valid_kprobe_addr(int template, int slot, unsigned long addr) { if ((slot > 2) || ((bundle_encoding[template][1] == L) && slot > 1)) { - printk(KERN_WARNING "Attempting to insert unaligned kprobe at 0x%lx\n", - addr); + printk(KERN_WARNING "Attempting to insert unaligned kprobe " + "at 0x%lx\n", addr); return -EINVAL; } + + if (in_ivt_functions(addr)) { + printk(KERN_WARNING "Kprobes can't be inserted inside " + "IVT functions at 0x%lx\n", addr); + return -EINVAL; + } + + if (slot == 1 && bundle_encoding[template][1] != L) { + printk(KERN_WARNING "Inserting kprobes on slot #1 " + "is not supported\n"); + return -EINVAL; + } + return 0; } @@ -290,6 +311,94 @@ static inline void set_current_kprobe(struct kprobe *p) current_kprobe = p; } +static void kretprobe_trampoline(void) +{ +} + +/* + * At this point the target function has been tricked into + * returning into our trampoline. Lookup the associated instance + * and then: + * - call the handler function + * - cleanup by marking the instance as unused + * - long jump back to the original return address + */ +int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) +{ + struct kretprobe_instance *ri = NULL; + struct hlist_head *head; + struct hlist_node *node, *tmp; + unsigned long orig_ret_address = 0; + unsigned long trampoline_address = + ((struct fnptr *)kretprobe_trampoline)->ip; + + head = kretprobe_inst_table_head(current); + + /* + * It is possible to have multiple instances associated with a given + * task either because an multiple functions in the call path + * have a return probe installed on them, and/or more then one return + * return probe was registered for a target function. + * + * We can handle this because: + * - instances are always inserted at the head of the list + * - when multiple return probes are registered for the same + * function, the first instance's ret_addr will point to the + * real return address, and all the rest will point to + * kretprobe_trampoline + */ + hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { + if (ri->task != current) + /* another task is sharing our hash bucket */ + continue; + + if (ri->rp && ri->rp->handler) + ri->rp->handler(ri, regs); + + orig_ret_address = (unsigned long)ri->ret_addr; + recycle_rp_inst(ri); + + if (orig_ret_address != trampoline_address) + /* + * This is the real return address. Any other + * instances associated with this task are for + * other calls deeper on the call stack + */ + break; + } + + BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address)); + regs->cr_iip = orig_ret_address; + + unlock_kprobes(); + preempt_enable_no_resched(); + + /* + * By returning a non-zero value, we are telling + * kprobe_handler() that we have handled unlocking + * and re-enabling preemption. + */ + return 1; +} + +void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs) +{ + struct kretprobe_instance *ri; + + if ((ri = get_free_rp_inst(rp)) != NULL) { + ri->rp = rp; + ri->task = current; + ri->ret_addr = (kprobe_opcode_t *)regs->b0; + + /* Replace the return addr with trampoline addr */ + regs->b0 = ((struct fnptr *)kretprobe_trampoline)->ip; + + add_rp_inst(ri); + } else { + rp->nmissed++; + } +} + int arch_prepare_kprobe(struct kprobe *p) { unsigned long addr = (unsigned long) p->addr; @@ -492,8 +601,8 @@ static int pre_kprobes_handler(struct die_args *args) if (p->pre_handler && p->pre_handler(p, regs)) /* * Our pre-handler is specifically requesting that we just - * do a return. This is handling the case where the - * pre-handler is really our special jprobe pre-handler. + * do a return. This is used for both the jprobe pre-handler + * and the kretprobe trampoline */ return 1; @@ -599,3 +708,14 @@ int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) *regs = jprobe_saved_regs; return 1; } + +static struct kprobe trampoline_p = { + .pre_handler = trampoline_probe_handler +}; + +int __init arch_init_kprobes(void) +{ + trampoline_p.addr = + (kprobe_opcode_t *)((struct fnptr *)kretprobe_trampoline)->ip; + return register_kprobe(&trampoline_p); +} diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 736e328b5e61..4ebbf3974381 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c @@ -271,7 +271,7 @@ ia64_mca_log_sal_error_record(int sal_info_type) #ifdef CONFIG_ACPI -static int cpe_vector = -1; +int cpe_vector = -1; static irqreturn_t ia64_mca_cpe_int_handler (int cpe_irq, void *arg, struct pt_regs *ptregs) diff --git a/arch/ia64/kernel/numa.c b/arch/ia64/kernel/numa.c new file mode 100644 index 000000000000..a68ce6678092 --- /dev/null +++ b/arch/ia64/kernel/numa.c @@ -0,0 +1,57 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * ia64 kernel NUMA specific stuff + * + * Copyright (C) 2002 Erich Focht <efocht@ess.nec.de> + * Copyright (C) 2004 Silicon Graphics, Inc. + * Jesse Barnes <jbarnes@sgi.com> + */ +#include <linux/config.h> +#include <linux/topology.h> +#include <linux/module.h> +#include <asm/processor.h> +#include <asm/smp.h> + +u8 cpu_to_node_map[NR_CPUS] __cacheline_aligned; +EXPORT_SYMBOL(cpu_to_node_map); + +cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned; + +/** + * build_cpu_to_node_map - setup cpu to node and node to cpumask arrays + * + * Build cpu to node mapping and initialize the per node cpu masks using + * info from the node_cpuid array handed to us by ACPI. + */ +void __init build_cpu_to_node_map(void) +{ + int cpu, i, node; + + for(node=0; node < MAX_NUMNODES; node++) + cpus_clear(node_to_cpu_mask[node]); + + for(cpu = 0; cpu < NR_CPUS; ++cpu) { + node = -1; + for (i = 0; i < NR_CPUS; ++i) + if (cpu_physical_id(cpu) == node_cpuid[i].phys_id) { + node = node_cpuid[i].nid; + break; + } + cpu_to_node_map[cpu] = (node >= 0) ? node : 0; + if (node >= 0) + cpu_set(cpu, node_to_cpu_mask[node]); + } +} diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index 6407bff6bfd7..b8ebb8e427ef 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c @@ -37,7 +37,6 @@ #include <linux/vfs.h> #include <linux/pagemap.h> #include <linux/mount.h> -#include <linux/version.h> #include <linux/bitops.h> #include <asm/errno.h> diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index ebb71f3d6d19..e484910246ad 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c @@ -27,6 +27,7 @@ #include <linux/efi.h> #include <linux/interrupt.h> #include <linux/delay.h> +#include <linux/kprobes.h> #include <asm/cpu.h> #include <asm/delay.h> @@ -195,6 +196,7 @@ update_pal_halt_status(int status) void default_idle (void) { + local_irq_enable(); while (!need_resched()) if (can_do_pal_halt) safe_halt(); @@ -707,6 +709,13 @@ kernel_thread_helper (int (*fn)(void *), void *arg) void flush_thread (void) { + /* + * Remove function-return probe instances associated with this task + * and put them back on the free list. Do not insert an exit probe for + * this function, it will be disabled by kprobe_flush_task if you do. + */ + kprobe_flush_task(current); + /* drop floating-point and debug-register state if it exists: */ current->thread.flags &= ~(IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID); ia64_drop_fpu(current); @@ -721,6 +730,14 @@ flush_thread (void) void exit_thread (void) { + + /* + * Remove function-return probe instances associated with this task + * and put them back on the free list. Do not insert an exit probe for + * this function, it will be disabled by kprobe_flush_task if you do. + */ + kprobe_flush_task(current); + ia64_drop_fpu(current); #ifdef CONFIG_PERFMON /* if needed, stop monitoring and flush state to perfmon context */ diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c index 6d57aebad485..bbb8bc7c0552 100644 --- a/arch/ia64/kernel/ptrace.c +++ b/arch/ia64/kernel/ptrace.c @@ -725,12 +725,32 @@ convert_to_non_syscall (struct task_struct *child, struct pt_regs *pt, break; } + /* + * Note: at the time of this call, the target task is blocked + * in notify_resume_user() and by clearling PRED_LEAVE_SYSCALL + * (aka, "pLvSys") we redirect execution from + * .work_pending_syscall_end to .work_processed_kernel. + */ unw_get_pr(&prev_info, &pr); - pr &= ~(1UL << PRED_SYSCALL); + pr &= ~((1UL << PRED_SYSCALL) | (1UL << PRED_LEAVE_SYSCALL)); pr |= (1UL << PRED_NON_SYSCALL); unw_set_pr(&prev_info, pr); pt->cr_ifs = (1UL << 63) | cfm; + /* + * Clear the memory that is NOT written on syscall-entry to + * ensure we do not leak kernel-state to user when execution + * resumes. + */ + pt->r2 = 0; + pt->r3 = 0; + pt->r14 = 0; + memset(&pt->r16, 0, 16*8); /* clear r16-r31 */ + memset(&pt->f6, 0, 6*16); /* clear f6-f11 */ + pt->b7 = 0; + pt->ar_ccv = 0; + pt->ar_csd = 0; + pt->ar_ssd = 0; } static int diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index d14692e0920a..84f89da7c640 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -20,6 +20,7 @@ * 02/01/00 R.Seth fixed get_cpuinfo for SMP * 01/07/99 S.Eranian added the support for command line argument * 06/24/99 W.Drummond added boot_cpu_data. + * 05/28/05 Z. Menyhart Dynamic stride size for "flush_icache_range()" */ #include <linux/config.h> #include <linux/module.h> @@ -40,6 +41,8 @@ #include <linux/serial_core.h> #include <linux/efi.h> #include <linux/initrd.h> +#include <linux/platform.h> +#include <linux/pm.h> #include <asm/ia32.h> #include <asm/machvec.h> @@ -72,6 +75,8 @@ DEFINE_PER_CPU(unsigned long, ia64_phys_stacked_size_p8); unsigned long ia64_cycles_per_usec; struct ia64_boot_param *ia64_boot_param; struct screen_info screen_info; +unsigned long vga_console_iobase; +unsigned long vga_console_membase; unsigned long ia64_max_cacheline_size; unsigned long ia64_iobase; /* virtual address for I/O accesses */ @@ -81,6 +86,13 @@ EXPORT_SYMBOL(io_space); unsigned int num_io_spaces; /* + * "flush_icache_range()" needs to know what processor dependent stride size to use + * when it makes i-cache(s) coherent with d-caches. + */ +#define I_CACHE_STRIDE_SHIFT 5 /* Safest way to go: 32 bytes by 32 bytes */ +unsigned long ia64_i_cache_stride_shift = ~0; + +/* * The merge_mask variable needs to be set to (max(iommu_page_size(iommu)) - 1). This * mask specifies a mask of address bits that must be 0 in order for two buffers to be * mergeable by the I/O MMU (i.e., the end address of the first buffer and the start @@ -273,23 +285,25 @@ io_port_init (void) static inline int __init early_console_setup (char *cmdline) { + int earlycons = 0; + #ifdef CONFIG_SERIAL_SGI_L1_CONSOLE { extern int sn_serial_console_early_setup(void); if (!sn_serial_console_early_setup()) - return 0; + earlycons++; } #endif #ifdef CONFIG_EFI_PCDP if (!efi_setup_pcdp_console(cmdline)) - return 0; + earlycons++; #endif #ifdef CONFIG_SERIAL_8250_CONSOLE if (!early_serial_console_init(cmdline)) - return 0; + earlycons++; #endif - return -1; + return (earlycons) ? 0 : -1; } static inline void @@ -622,6 +636,12 @@ setup_per_cpu_areas (void) /* start_kernel() requires this... */ } +/* + * Calculate the max. cache line size. + * + * In addition, the minimum of the i-cache stride sizes is calculated for + * "flush_icache_range()". + */ static void get_max_cacheline_size (void) { @@ -635,6 +655,8 @@ get_max_cacheline_size (void) printk(KERN_ERR "%s: ia64_pal_cache_summary() failed (status=%ld)\n", __FUNCTION__, status); max = SMP_CACHE_BYTES; + /* Safest setup for "flush_icache_range()" */ + ia64_i_cache_stride_shift = I_CACHE_STRIDE_SHIFT; goto out; } @@ -643,14 +665,31 @@ get_max_cacheline_size (void) &cci); if (status != 0) { printk(KERN_ERR - "%s: ia64_pal_cache_config_info(l=%lu) failed (status=%ld)\n", + "%s: ia64_pal_cache_config_info(l=%lu, 2) failed (status=%ld)\n", __FUNCTION__, l, status); max = SMP_CACHE_BYTES; + /* The safest setup for "flush_icache_range()" */ + cci.pcci_stride = I_CACHE_STRIDE_SHIFT; + cci.pcci_unified = 1; } line_size = 1 << cci.pcci_line_size; if (line_size > max) max = line_size; - } + if (!cci.pcci_unified) { + status = ia64_pal_cache_config_info(l, + /* cache_type (instruction)= */ 1, + &cci); + if (status != 0) { + printk(KERN_ERR + "%s: ia64_pal_cache_config_info(l=%lu, 1) failed (status=%ld)\n", + __FUNCTION__, l, status); + /* The safest setup for "flush_icache_range()" */ + cci.pcci_stride = I_CACHE_STRIDE_SHIFT; + } + } + if (cci.pcci_stride < ia64_i_cache_stride_shift) + ia64_i_cache_stride_shift = cci.pcci_stride; + } out: if (max > ia64_max_cacheline_size) ia64_max_cacheline_size = max; @@ -779,6 +818,7 @@ cpu_init (void) /* size of physical stacked register partition plus 8 bytes: */ __get_cpu_var(ia64_phys_stacked_size_p8) = num_phys_stacked*8 + 8; platform_cpu_init(); + pm_idle = default_idle; } void diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c index edd9f07860b2..b8a0a7d257a9 100644 --- a/arch/ia64/kernel/signal.c +++ b/arch/ia64/kernel/signal.c @@ -143,6 +143,7 @@ restore_sigcontext (struct sigcontext __user *sc, struct sigscratch *scr) __copy_from_user(current->thread.fph, &sc->sc_fr[32], 96*16); psr->mfh = 0; /* drop signal handler's fph contents... */ + preempt_disable(); if (psr->dfh) ia64_drop_fpu(current); else { @@ -150,6 +151,7 @@ restore_sigcontext (struct sigcontext __user *sc, struct sigscratch *scr) __ia64_load_fpu(current->thread.fph); ia64_set_local_fpu_owner(current); } + preempt_enable(); } return err; } diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c index b49d4ddaab93..0166a9847095 100644 --- a/arch/ia64/kernel/smp.c +++ b/arch/ia64/kernel/smp.c @@ -231,13 +231,16 @@ smp_flush_tlb_all (void) void smp_flush_tlb_mm (struct mm_struct *mm) { + preempt_disable(); /* this happens for the common case of a single-threaded fork(): */ if (likely(mm == current->active_mm && atomic_read(&mm->mm_users) == 1)) { local_finish_flush_tlb_mm(mm); + preempt_enable(); return; } + preempt_enable(); /* * We could optimize this further by using mm->cpu_vm_mask to track which CPUs * have been running in the address space. It's not clear that this is worth the diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index 623b0a546709..7d72c0d872b3 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c @@ -525,47 +525,6 @@ smp_build_cpu_map (void) } } -#ifdef CONFIG_NUMA - -/* on which node is each logical CPU (one cacheline even for 64 CPUs) */ -u8 cpu_to_node_map[NR_CPUS] __cacheline_aligned; -EXPORT_SYMBOL(cpu_to_node_map); -/* which logical CPUs are on which nodes */ -cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned; - -/* - * Build cpu to node mapping and initialize the per node cpu masks. - */ -void __init -build_cpu_to_node_map (void) -{ - int cpu, i, node; - - for(node=0; node<MAX_NUMNODES; node++) - cpus_clear(node_to_cpu_mask[node]); - for(cpu = 0; cpu < NR_CPUS; ++cpu) { - /* - * All Itanium NUMA platforms I know use ACPI, so maybe we - * can drop this ifdef completely. [EF] - */ -#ifdef CONFIG_ACPI_NUMA - node = -1; - for (i = 0; i < NR_CPUS; ++i) - if (cpu_physical_id(cpu) == node_cpuid[i].phys_id) { - node = node_cpuid[i].nid; - break; - } -#else -# error Fixme: Dunno how to build CPU-to-node map. -#endif - cpu_to_node_map[cpu] = (node >= 0) ? node : 0; - if (node >= 0) - cpu_set(cpu, node_to_cpu_mask[node]); - } -} - -#endif /* CONFIG_NUMA */ - /* * Cycle through the APs sending Wakeup IPIs to boot each. */ diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c index f1aafd4c05f9..92ff46ad21e2 100644 --- a/arch/ia64/kernel/topology.c +++ b/arch/ia64/kernel/topology.c @@ -36,6 +36,15 @@ int arch_register_cpu(int num) parent = &sysfs_nodes[cpu_to_node(num)]; #endif /* CONFIG_NUMA */ +#ifdef CONFIG_ACPI_BOOT + /* + * If CPEI cannot be re-targetted, and this is + * CPEI target, then dont create the control file + */ + if (!can_cpei_retarget() && is_cpu_cpei_target(num)) + sysfs_cpus[num].cpu.no_control = 1; +#endif + return register_cpu(&sysfs_cpus[num].cpu, num, parent); } diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c index e7e520d90f03..4440c8343fa4 100644 --- a/arch/ia64/kernel/traps.c +++ b/arch/ia64/kernel/traps.c @@ -90,14 +90,16 @@ die (const char *str, struct pt_regs *regs, long err) .lock_owner_depth = 0 }; static int die_counter; + int cpu = get_cpu(); - if (die.lock_owner != smp_processor_id()) { + if (die.lock_owner != cpu) { console_verbose(); spin_lock_irq(&die.lock); - die.lock_owner = smp_processor_id(); + die.lock_owner = cpu; die.lock_owner_depth = 0; bust_spinlocks(1); } + put_cpu(); if (++die.lock_owner_depth < 3) { printk("%s[%d]: %s %ld [%d]\n", diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S index b9f0db4c1b04..a676e79e0681 100644 --- a/arch/ia64/kernel/vmlinux.lds.S +++ b/arch/ia64/kernel/vmlinux.lds.S @@ -8,6 +8,11 @@ #define LOAD_OFFSET (KERNEL_START - KERNEL_TR_PAGE_SIZE) #include <asm-generic/vmlinux.lds.h> +#define IVT_TEXT \ + VMLINUX_SYMBOL(__start_ivt_text) = .; \ + *(.text.ivt) \ + VMLINUX_SYMBOL(__end_ivt_text) = .; + OUTPUT_FORMAT("elf64-ia64-little") OUTPUT_ARCH(ia64) ENTRY(phys_start) @@ -39,7 +44,7 @@ SECTIONS .text : AT(ADDR(.text) - LOAD_OFFSET) { - *(.text.ivt) + IVT_TEXT *(.text) SCHED_TEXT LOCK_TEXT diff --git a/arch/ia64/lib/flush.S b/arch/ia64/lib/flush.S index a1af9146cfdb..3e2cfa2c6d39 100644 --- a/arch/ia64/lib/flush.S +++ b/arch/ia64/lib/flush.S @@ -3,37 +3,59 @@ * * Copyright (C) 1999-2001, 2005 Hewlett-Packard Co * David Mosberger-Tang <davidm@hpl.hp.com> + * + * 05/28/05 Zoltan Menyhart Dynamic stride size */ + #include <asm/asmmacro.h> -#include <asm/page.h> + /* * flush_icache_range(start,end) - * Must flush range from start to end-1 but nothing else (need to + * + * Make i-cache(s) coherent with d-caches. + * + * Must deal with range from start to end-1 but nothing else (need to * be careful not to touch addresses that may be unmapped). + * + * Note: "in0" and "in1" are preserved for debugging purposes. */ GLOBAL_ENTRY(flush_icache_range) + .prologue - alloc r2=ar.pfs,2,0,0,0 - sub r8=in1,in0,1 + alloc r2=ar.pfs,2,0,0,0 + movl r3=ia64_i_cache_stride_shift + mov r21=1 + ;; + ld8 r20=[r3] // r20: stride shift + sub r22=in1,r0,1 // last byte address ;; - shr.u r8=r8,5 // we flush 32 bytes per iteration - .save ar.lc, r3 - mov r3=ar.lc // save ar.lc + shr.u r23=in0,r20 // start / (stride size) + shr.u r22=r22,r20 // (last byte address) / (stride size) + shl r21=r21,r20 // r21: stride size of the i-cache(s) + ;; + sub r8=r22,r23 // number of strides - 1 + shl r24=r23,r20 // r24: addresses for "fc.i" = + // "start" rounded down to stride boundary + .save ar.lc,r3 + mov r3=ar.lc // save ar.lc ;; .body - - mov ar.lc=r8 + mov ar.lc=r8 ;; -.Loop: fc.i in0 // issuable on M2 only - add in0=32,in0 + /* + * 32 byte aligned loop, even number of (actually 2) bundles + */ +.Loop: fc.i r24 // issuable on M0 only + add r24=r21,r24 // we flush "stride size" bytes per iteration + nop.i 0 br.cloop.sptk.few .Loop ;; sync.i ;; srlz.i ;; - mov ar.lc=r3 // restore ar.lc + mov ar.lc=r3 // restore ar.lc br.ret.sptk.many rp END(flush_icache_range) diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c index f3fd528ead3b..b5c90e548195 100644 --- a/arch/ia64/mm/discontig.c +++ b/arch/ia64/mm/discontig.c @@ -44,150 +44,7 @@ struct early_node_data { }; static struct early_node_data mem_data[MAX_NUMNODES] __initdata; - -/** - * reassign_cpu_only_nodes - called from find_memory to move CPU-only nodes to a memory node - * - * This function will move nodes with only CPUs (no memory) - * to a node with memory which is at the minimum numa_slit distance. - * Any reassigments will result in the compression of the nodes - * and renumbering the nid values where appropriate. - * The static declarations below are to avoid large stack size which - * makes the code not re-entrant. - */ -static void __init reassign_cpu_only_nodes(void) -{ - struct node_memblk_s *p; - int i, j, k, nnode, nid, cpu, cpunid, pxm; - u8 cslit, slit; - static DECLARE_BITMAP(nodes_with_mem, MAX_NUMNODES) __initdata; - static u8 numa_slit_fix[MAX_NUMNODES * MAX_NUMNODES] __initdata; - static int node_flip[MAX_NUMNODES] __initdata; - static int old_nid_map[NR_CPUS] __initdata; - - for (nnode = 0, p = &node_memblk[0]; p < &node_memblk[num_node_memblks]; p++) - if (!test_bit(p->nid, (void *) nodes_with_mem)) { - set_bit(p->nid, (void *) nodes_with_mem); - nnode++; - } - - /* - * All nids with memory. - */ - if (nnode == num_online_nodes()) - return; - - /* - * Change nids and attempt to migrate CPU-only nodes - * to the best numa_slit (closest neighbor) possible. - * For reassigned CPU nodes a nid can't be arrived at - * until after this loop because the target nid's new - * identity might not have been established yet. So - * new nid values are fabricated above num_online_nodes() and - * mapped back later to their true value. - */ - /* MCD - This code is a bit complicated, but may be unnecessary now. - * We can now handle much more interesting node-numbering. - * The old requirement that 0 <= nid <= numnodes <= MAX_NUMNODES - * and that there be no holes in the numbering 0..numnodes - * has become simply 0 <= nid <= MAX_NUMNODES. - */ - nid = 0; - for_each_online_node(i) { - if (test_bit(i, (void *) nodes_with_mem)) { - /* - * Save original nid value for numa_slit - * fixup and node_cpuid reassignments. - */ - node_flip[nid] = i; - - if (i == nid) { - nid++; - continue; - } - - for (p = &node_memblk[0]; p < &node_memblk[num_node_memblks]; p++) - if (p->nid == i) - p->nid = nid; - - cpunid = nid; - nid++; - } else - cpunid = MAX_NUMNODES; - - for (cpu = 0; cpu < NR_CPUS; cpu++) - if (node_cpuid[cpu].nid == i) { - /* - * For nodes not being reassigned just - * fix the cpu's nid and reverse pxm map - */ - if (cpunid < MAX_NUMNODES) { - pxm = nid_to_pxm_map[i]; - pxm_to_nid_map[pxm] = - node_cpuid[cpu].nid = cpunid; - continue; - } - - /* - * For nodes being reassigned, find best node by - * numa_slit information and then make a temporary - * nid value based on current nid and num_online_nodes(). - */ - slit = 0xff; - k = 2*num_online_nodes(); - for_each_online_node(j) { - if (i == j) - continue; - else if (test_bit(j, (void *) nodes_with_mem)) { - cslit = numa_slit[i * num_online_nodes() + j]; - if (cslit < slit) { - k = num_online_nodes() + j; - slit = cslit; - } - } - } - - /* save old nid map so we can update the pxm */ - old_nid_map[cpu] = node_cpuid[cpu].nid; - node_cpuid[cpu].nid = k; - } - } - - /* - * Fixup temporary nid values for CPU-only nodes. - */ - for (cpu = 0; cpu < NR_CPUS; cpu++) - if (node_cpuid[cpu].nid == (2*num_online_nodes())) { - pxm = nid_to_pxm_map[old_nid_map[cpu]]; - pxm_to_nid_map[pxm] = node_cpuid[cpu].nid = nnode - 1; - } else { - for (i = 0; i < nnode; i++) { - if (node_flip[i] != (node_cpuid[cpu].nid - num_online_nodes())) - continue; - - pxm = nid_to_pxm_map[old_nid_map[cpu]]; - pxm_to_nid_map[pxm] = node_cpuid[cpu].nid = i; - break; - } - } - - /* - * Fix numa_slit by compressing from larger - * nid array to reduced nid array. - */ - for (i = 0; i < nnode; i++) - for (j = 0; j < nnode; j++) - numa_slit_fix[i * nnode + j] = - numa_slit[node_flip[i] * num_online_nodes() + node_flip[j]]; - - memcpy(numa_slit, numa_slit_fix, sizeof (numa_slit)); - - nodes_clear(node_online_map); - for (i = 0; i < nnode; i++) - node_set_online(i); - - return; -} +static nodemask_t memory_less_mask __initdata; /* * To prevent cache aliasing effects, align per-node structures so that they @@ -233,44 +90,101 @@ static int __init build_node_maps(unsigned long start, unsigned long len, } /** - * early_nr_phys_cpus_node - return number of physical cpus on a given node + * early_nr_cpus_node - return number of cpus on a given node * @node: node to check * - * Count the number of physical cpus on @node. These are cpus that actually - * exist. We can't use nr_cpus_node() yet because + * Count the number of cpus on @node. We can't use nr_cpus_node() yet because * acpi_boot_init() (which builds the node_to_cpu_mask array) hasn't been - * called yet. + * called yet. Note that node 0 will also count all non-existent cpus. */ -static int early_nr_phys_cpus_node(int node) +static int __init early_nr_cpus_node(int node) { int cpu, n = 0; for (cpu = 0; cpu < NR_CPUS; cpu++) if (node == node_cpuid[cpu].nid) - if ((cpu == 0) || node_cpuid[cpu].phys_id) - n++; + n++; return n; } +/** + * compute_pernodesize - compute size of pernode data + * @node: the node id. + */ +static unsigned long __init compute_pernodesize(int node) +{ + unsigned long pernodesize = 0, cpus; + + cpus = early_nr_cpus_node(node); + pernodesize += PERCPU_PAGE_SIZE * cpus; + pernodesize += node * L1_CACHE_BYTES; + pernodesize += L1_CACHE_ALIGN(sizeof(pg_data_t)); + pernodesize += L1_CACHE_ALIGN(sizeof(struct ia64_node_data)); + pernodesize = PAGE_ALIGN(pernodesize); + return pernodesize; +} /** - * early_nr_cpus_node - return number of cpus on a given node - * @node: node to check + * per_cpu_node_setup - setup per-cpu areas on each node + * @cpu_data: per-cpu area on this node + * @node: node to setup * - * Count the number of cpus on @node. We can't use nr_cpus_node() yet because - * acpi_boot_init() (which builds the node_to_cpu_mask array) hasn't been - * called yet. Note that node 0 will also count all non-existent cpus. + * Copy the static per-cpu data into the region we just set aside and then + * setup __per_cpu_offset for each CPU on this node. Return a pointer to + * the end of the area. */ -static int early_nr_cpus_node(int node) +static void *per_cpu_node_setup(void *cpu_data, int node) { - int cpu, n = 0; +#ifdef CONFIG_SMP + int cpu; - for (cpu = 0; cpu < NR_CPUS; cpu++) - if (node == node_cpuid[cpu].nid) - n++; + for (cpu = 0; cpu < NR_CPUS; cpu++) { + if (node == node_cpuid[cpu].nid) { + memcpy(__va(cpu_data), __phys_per_cpu_start, + __per_cpu_end - __per_cpu_start); + __per_cpu_offset[cpu] = (char*)__va(cpu_data) - + __per_cpu_start; + cpu_data += PERCPU_PAGE_SIZE; + } + } +#endif + return cpu_data; +} - return n; +/** + * fill_pernode - initialize pernode data. + * @node: the node id. + * @pernode: physical address of pernode data + * @pernodesize: size of the pernode data + */ +static void __init fill_pernode(int node, unsigned long pernode, + unsigned long pernodesize) +{ + void *cpu_data; + int cpus = early_nr_cpus_node(node); + struct bootmem_data *bdp = &mem_data[node].bootmem_data; + + mem_data[node].pernode_addr = pernode; + mem_data[node].pernode_size = pernodesize; + memset(__va(pernode), 0, pernodesize); + + cpu_data = (void *)pernode; + pernode += PERCPU_PAGE_SIZE * cpus; + pernode += node * L1_CACHE_BYTES; + + mem_data[node].pgdat = __va(pernode); + pernode += L1_CACHE_ALIGN(sizeof(pg_data_t)); + + mem_data[node].node_data = __va(pernode); + pernode += L1_CACHE_ALIGN(sizeof(struct ia64_node_data)); + + mem_data[node].pgdat->bdata = bdp; + pernode += L1_CACHE_ALIGN(sizeof(pg_data_t)); + + cpu_data = per_cpu_node_setup(cpu_data, node); + + return; } /** @@ -304,9 +218,8 @@ static int early_nr_cpus_node(int node) static int __init find_pernode_space(unsigned long start, unsigned long len, int node) { - unsigned long epfn, cpu, cpus, phys_cpus; + unsigned long epfn; unsigned long pernodesize = 0, pernode, pages, mapsize; - void *cpu_data; struct bootmem_data *bdp = &mem_data[node].bootmem_data; epfn = (start + len) >> PAGE_SHIFT; @@ -329,49 +242,12 @@ static int __init find_pernode_space(unsigned long start, unsigned long len, * Calculate total size needed, incl. what's necessary * for good alignment and alias prevention. */ - cpus = early_nr_cpus_node(node); - phys_cpus = early_nr_phys_cpus_node(node); - pernodesize += PERCPU_PAGE_SIZE * cpus; - pernodesize += node * L1_CACHE_BYTES; - pernodesize += L1_CACHE_ALIGN(sizeof(pg_data_t)); - pernodesize += L1_CACHE_ALIGN(sizeof(struct ia64_node_data)); - pernodesize = PAGE_ALIGN(pernodesize); + pernodesize = compute_pernodesize(node); pernode = NODEDATA_ALIGN(start, node); /* Is this range big enough for what we want to store here? */ - if (start + len > (pernode + pernodesize + mapsize)) { - mem_data[node].pernode_addr = pernode; - mem_data[node].pernode_size = pernodesize; - memset(__va(pernode), 0, pernodesize); - - cpu_data = (void *)pernode; - pernode += PERCPU_PAGE_SIZE * cpus; - pernode += node * L1_CACHE_BYTES; - - mem_data[node].pgdat = __va(pernode); - pernode += L1_CACHE_ALIGN(sizeof(pg_data_t)); - - mem_data[node].node_data = __va(pernode); - pernode += L1_CACHE_ALIGN(sizeof(struct ia64_node_data)); - - mem_data[node].pgdat->bdata = bdp; - pernode += L1_CACHE_ALIGN(sizeof(pg_data_t)); - - /* - * Copy the static per-cpu data into the region we - * just set aside and then setup __per_cpu_offset - * for each CPU on this node. - */ - for (cpu = 0; cpu < NR_CPUS; cpu++) { - if (node == node_cpuid[cpu].nid) { - memcpy(__va(cpu_data), __phys_per_cpu_start, - __per_cpu_end - __per_cpu_start); - __per_cpu_offset[cpu] = (char*)__va(cpu_data) - - __per_cpu_start; - cpu_data += PERCPU_PAGE_SIZE; - } - } - } + if (start + len > (pernode + pernodesize + mapsize)) + fill_pernode(node, pernode, pernodesize); return 0; } @@ -411,6 +287,9 @@ static void __init reserve_pernode_space(void) for_each_online_node(node) { pg_data_t *pdp = mem_data[node].pgdat; + if (node_isset(node, memory_less_mask)) + continue; + bdp = pdp->bdata; /* First the bootmem_map itself */ @@ -436,8 +315,8 @@ static void __init reserve_pernode_space(void) */ static void __init initialize_pernode_data(void) { - int cpu, node; pg_data_t *pgdat_list[MAX_NUMNODES]; + int cpu, node; for_each_online_node(node) pgdat_list[node] = mem_data[node].pgdat; @@ -447,12 +326,99 @@ static void __init initialize_pernode_data(void) memcpy(mem_data[node].node_data->pg_data_ptrs, pgdat_list, sizeof(pgdat_list)); } - +#ifdef CONFIG_SMP /* Set the node_data pointer for each per-cpu struct */ for (cpu = 0; cpu < NR_CPUS; cpu++) { node = node_cpuid[cpu].nid; per_cpu(cpu_info, cpu).node_data = mem_data[node].node_data; } +#else + { + struct cpuinfo_ia64 *cpu0_cpu_info; + cpu = 0; + node = node_cpuid[cpu].nid; + cpu0_cpu_info = (struct cpuinfo_ia64 *)(__phys_per_cpu_start + + ((char *)&per_cpu__cpu_info - __per_cpu_start)); + cpu0_cpu_info->node_data = mem_data[node].node_data; + } +#endif /* CONFIG_SMP */ +} + +/** + * memory_less_node_alloc - * attempt to allocate memory on the best NUMA slit + * node but fall back to any other node when __alloc_bootmem_node fails + * for best. + * @nid: node id + * @pernodesize: size of this node's pernode data + * @align: alignment to use for this node's pernode data + */ +static void __init *memory_less_node_alloc(int nid, unsigned long pernodesize, + unsigned long align) +{ + void *ptr = NULL; + u8 best = 0xff; + int bestnode = -1, node; + + for_each_online_node(node) { + if (node_isset(node, memory_less_mask)) + continue; + else if (node_distance(nid, node) < best) { + best = node_distance(nid, node); + bestnode = node; + } + } + + ptr = __alloc_bootmem_node(mem_data[bestnode].pgdat, + pernodesize, align, __pa(MAX_DMA_ADDRESS)); + + if (!ptr) + panic("NO memory for memory less node\n"); + return ptr; +} + +/** + * pgdat_insert - insert the pgdat into global pgdat_list + * @pgdat: the pgdat for a node. + */ +static void __init pgdat_insert(pg_data_t *pgdat) +{ + pg_data_t *prev = NULL, *next; + + for_each_pgdat(next) + if (pgdat->node_id < next->node_id) + break; + else + prev = next; + + if (prev) { + prev->pgdat_next = pgdat; + pgdat->pgdat_next = next; + } else { + pgdat->pgdat_next = pgdat_list; + pgdat_list = pgdat; + } + + return; +} + +/** + * memory_less_nodes - allocate and initialize CPU only nodes pernode + * information. + */ +static void __init memory_less_nodes(void) +{ + unsigned long pernodesize; + void *pernode; + int node; + + for_each_node_mask(node, memory_less_mask) { + pernodesize = compute_pernodesize(node); + pernode = memory_less_node_alloc(node, pernodesize, + (node) ? (node * PERCPU_PAGE_SIZE) : (1024*1024)); + fill_pernode(node, __pa(pernode), pernodesize); + } + + return; } /** @@ -472,16 +438,19 @@ void __init find_memory(void) node_set_online(0); } + nodes_or(memory_less_mask, memory_less_mask, node_online_map); min_low_pfn = -1; max_low_pfn = 0; - if (num_online_nodes() > 1) - reassign_cpu_only_nodes(); - /* These actually end up getting called by call_pernode_memory() */ efi_memmap_walk(filter_rsvd_memory, build_node_maps); efi_memmap_walk(filter_rsvd_memory, find_pernode_space); + for_each_online_node(node) + if (mem_data[node].bootmem_data.node_low_pfn) { + node_clear(node, memory_less_mask); + mem_data[node].min_pfn = ~0UL; + } /* * Initialize the boot memory maps in reverse order since that's * what the bootmem allocator expects @@ -492,17 +461,14 @@ void __init find_memory(void) if (!node_online(node)) continue; + else if (node_isset(node, memory_less_mask)) + continue; bdp = &mem_data[node].bootmem_data; pernode = mem_data[node].pernode_addr; pernodesize = mem_data[node].pernode_size; map = pernode + pernodesize; - /* Sanity check... */ - if (!pernode) - panic("pernode space for node %d " - "could not be allocated!", node); - init_bootmem_node(mem_data[node].pgdat, map>>PAGE_SHIFT, bdp->node_boot_start>>PAGE_SHIFT, @@ -512,6 +478,7 @@ void __init find_memory(void) efi_memmap_walk(filter_rsvd_memory, free_node_bootmem); reserve_pernode_space(); + memory_less_nodes(); initialize_pernode_data(); max_pfn = max_low_pfn; @@ -519,6 +486,7 @@ void __init find_memory(void) find_initrd(); } +#ifdef CONFIG_SMP /** * per_cpu_init - setup per-cpu variables * @@ -529,15 +497,15 @@ void *per_cpu_init(void) { int cpu; - if (smp_processor_id() == 0) { - for (cpu = 0; cpu < NR_CPUS; cpu++) { - per_cpu(local_per_cpu_offset, cpu) = - __per_cpu_offset[cpu]; - } - } + if (smp_processor_id() != 0) + return __per_cpu_start + __per_cpu_offset[smp_processor_id()]; + + for (cpu = 0; cpu < NR_CPUS; cpu++) + per_cpu(local_per_cpu_offset, cpu) = __per_cpu_offset[cpu]; return __per_cpu_start + __per_cpu_offset[smp_processor_id()]; } +#endif /* CONFIG_SMP */ /** * show_mem - give short summary of memory stats @@ -680,12 +648,13 @@ void __init paging_init(void) max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT; - /* so min() will work in count_node_pages */ - for_each_online_node(node) - mem_data[node].min_pfn = ~0UL; - efi_memmap_walk(filter_rsvd_memory, count_node_pages); + vmalloc_end -= PAGE_ALIGN(max_low_pfn * sizeof(struct page)); + vmem_map = (struct page *) vmalloc_end; + efi_memmap_walk(create_mem_map_page_table, NULL); + printk("Virtual mem_map starts at 0x%p\n", vmem_map); + for_each_online_node(node) { memset(zones_size, 0, sizeof(zones_size)); memset(zholes_size, 0, sizeof(zholes_size)); @@ -719,15 +688,6 @@ void __init paging_init(void) mem_data[node].num_dma_physpages); } - if (node == 0) { - vmalloc_end -= - PAGE_ALIGN(max_low_pfn * sizeof(struct page)); - vmem_map = (struct page *) vmalloc_end; - - efi_memmap_walk(create_mem_map_page_table, NULL); - printk("Virtual mem_map starts at 0x%p\n", vmem_map); - } - pfn_offset = mem_data[node].min_pfn; NODE_DATA(node)->node_mem_map = vmem_map + pfn_offset; @@ -735,5 +695,11 @@ void __init paging_init(void) pfn_offset, zholes_size); } + /* + * Make memory less nodes become a member of the known nodes. + */ + for_each_node_mask(node, memory_less_mask) + pgdat_insert(mem_data[node].pgdat); + zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page)); } diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index 4eb2f52b87a1..65f9958db9f0 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -597,7 +597,8 @@ mem_init (void) kclist_add(&kcore_kernel, _stext, _end - _stext); for_each_pgdat(pgdat) - totalram_pages += free_all_bootmem_node(pgdat); + if (pgdat->bdata->node_bootmem_map) + totalram_pages += free_all_bootmem_node(pgdat); reserved_pages = 0; efi_memmap_walk(count_reserved_pages, &reserved_pages); diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index e3fc4edea113..54d9ed444e4a 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -157,6 +157,7 @@ alloc_pci_controller (int seg) memset(controller, 0, sizeof(*controller)); controller->segment = seg; + controller->node = -1; return controller; } @@ -288,6 +289,7 @@ pci_acpi_scan_root(struct acpi_device *device, int domain, int bus) unsigned int windows = 0; struct pci_bus *pbus; char *name; + int pxm; controller = alloc_pci_controller(domain); if (!controller) @@ -295,10 +297,16 @@ pci_acpi_scan_root(struct acpi_device *device, int domain, int bus) controller->acpi_handle = device->handle; + pxm = acpi_get_pxm(controller->acpi_handle); +#ifdef CONFIG_NUMA + if (pxm >= 0) + controller->node = pxm_to_nid_map[pxm]; +#endif + acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window, &windows); - controller->window = kmalloc(sizeof(*controller->window) * windows, - GFP_KERNEL); + controller->window = kmalloc_node(sizeof(*controller->window) * windows, + GFP_KERNEL, controller->node); if (!controller->window) goto out2; @@ -312,7 +320,7 @@ pci_acpi_scan_root(struct acpi_device *device, int domain, int bus) acpi_walk_resources(device->handle, METHOD_NAME__CRS, add_window, &info); - pbus = pci_scan_bus(bus, &pci_root_ops, controller); + pbus = pci_scan_bus_parented(NULL, bus, &pci_root_ops, controller); if (pbus) pcibios_setup_root_windows(pbus, controller); @@ -373,6 +381,25 @@ void pcibios_bus_to_resource(struct pci_dev *dev, res->end = region->end + offset; } +static int __devinit is_valid_resource(struct pci_dev *dev, int idx) +{ + unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM; + struct resource *devr = &dev->resource[idx]; + + if (!dev->bus) + return 0; + for (i=0; i<PCI_BUS_NUM_RESOURCES; i++) { + struct resource *busr = dev->bus->resource[i]; + + if (!busr || ((busr->flags ^ devr->flags) & type_mask)) + continue; + if ((devr->start) && (devr->start >= busr->start) && + (devr->end <= busr->end)) + return 1; + } + return 0; +} + static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) { struct pci_bus_region region; @@ -386,7 +413,8 @@ static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) region.start = dev->resource[i].start; region.end = dev->resource[i].end; pcibios_bus_to_resource(dev, &dev->resource[i], ®ion); - pci_claim_resource(dev, i); + if ((is_valid_resource(dev, i))) + pci_claim_resource(dev, i); } } @@ -398,6 +426,10 @@ pcibios_fixup_bus (struct pci_bus *b) { struct pci_dev *dev; + if (b->self) { + pci_read_bridge_bases(b); + pcibios_fixup_device_resources(b->self); + } list_for_each_entry(dev, &b->devices, bus_list) pcibios_fixup_device_resources(dev); @@ -418,18 +450,24 @@ pcibios_enable_resources (struct pci_dev *dev, int mask) u16 cmd, old_cmd; int idx; struct resource *r; + unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM; if (!dev) return -EINVAL; pci_read_config_word(dev, PCI_COMMAND, &cmd); old_cmd = cmd; - for (idx=0; idx<6; idx++) { + for (idx=0; idx<PCI_NUM_RESOURCES; idx++) { /* Only set up the desired resources. */ if (!(mask & (1 << idx))) continue; r = &dev->resource[idx]; + if (!(r->flags & type_mask)) + continue; + if ((idx == PCI_ROM_RESOURCE) && + (!(r->flags & IORESOURCE_ROM_ENABLE))) + continue; if (!r->start && r->end) { printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", @@ -441,8 +479,6 @@ pcibios_enable_resources (struct pci_dev *dev, int mask) if (r->flags & IORESOURCE_MEM) cmd |= PCI_COMMAND_MEMORY; } - if (dev->resource[PCI_ROM_RESOURCE].start) - cmd |= PCI_COMMAND_MEMORY; if (cmd != old_cmd) { printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd); pci_write_config_word(dev, PCI_COMMAND, cmd); diff --git a/arch/ia64/sn/include/pci/pcibr_provider.h b/arch/ia64/sn/include/pci/pcibr_provider.h deleted file mode 100644 index 1cd291d8badd..000000000000 --- a/arch/ia64/sn/include/pci/pcibr_provider.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992-1997,2000-2004 Silicon Graphics, Inc. All rights reserved. - */ -#ifndef _ASM_IA64_SN_PCI_PCIBR_PROVIDER_H -#define _ASM_IA64_SN_PCI_PCIBR_PROVIDER_H - -/* Workarounds */ -#define PV907516 (1 << 1) /* TIOCP: Don't write the write buffer flush reg */ - -#define BUSTYPE_MASK 0x1 - -/* Macros given a pcibus structure */ -#define IS_PCIX(ps) ((ps)->pbi_bridge_mode & BUSTYPE_MASK) -#define IS_PCI_BRIDGE_ASIC(asic) (asic == PCIIO_ASIC_TYPE_PIC || \ - asic == PCIIO_ASIC_TYPE_TIOCP) -#define IS_PIC_SOFT(ps) (ps->pbi_bridge_type == PCIBR_BRIDGETYPE_PIC) - - -/* - * The different PCI Bridge types supported on the SGI Altix platforms - */ -#define PCIBR_BRIDGETYPE_UNKNOWN -1 -#define PCIBR_BRIDGETYPE_PIC 2 -#define PCIBR_BRIDGETYPE_TIOCP 3 - -/* - * Bridge 64bit Direct Map Attributes - */ -#define PCI64_ATTR_PREF (1ull << 59) -#define PCI64_ATTR_PREC (1ull << 58) -#define PCI64_ATTR_VIRTUAL (1ull << 57) -#define PCI64_ATTR_BAR (1ull << 56) -#define PCI64_ATTR_SWAP (1ull << 55) -#define PCI64_ATTR_VIRTUAL1 (1ull << 54) - -#define PCI32_LOCAL_BASE 0 -#define PCI32_MAPPED_BASE 0x40000000 -#define PCI32_DIRECT_BASE 0x80000000 - -#define IS_PCI32_MAPPED(x) ((uint64_t)(x) < PCI32_DIRECT_BASE && \ - (uint64_t)(x) >= PCI32_MAPPED_BASE) -#define IS_PCI32_DIRECT(x) ((uint64_t)(x) >= PCI32_MAPPED_BASE) - - -/* - * Bridge PMU Address Transaltion Entry Attibutes - */ -#define PCI32_ATE_V (0x1 << 0) -#define PCI32_ATE_CO (0x1 << 1) -#define PCI32_ATE_PREC (0x1 << 2) -#define PCI32_ATE_PREF (0x1 << 3) -#define PCI32_ATE_BAR (0x1 << 4) -#define PCI32_ATE_ADDR_SHFT 12 - -#define MINIMAL_ATES_REQUIRED(addr, size) \ - (IOPG(IOPGOFF(addr) + (size) - 1) == IOPG((size) - 1)) - -#define MINIMAL_ATE_FLAG(addr, size) \ - (MINIMAL_ATES_REQUIRED((uint64_t)addr, size) ? 1 : 0) - -/* bit 29 of the pci address is the SWAP bit */ -#define ATE_SWAPSHIFT 29 -#define ATE_SWAP_ON(x) ((x) |= (1 << ATE_SWAPSHIFT)) -#define ATE_SWAP_OFF(x) ((x) &= ~(1 << ATE_SWAPSHIFT)) - -/* - * I/O page size - */ -#if PAGE_SIZE < 16384 -#define IOPFNSHIFT 12 /* 4K per mapped page */ -#else -#define IOPFNSHIFT 14 /* 16K per mapped page */ -#endif - -#define IOPGSIZE (1 << IOPFNSHIFT) -#define IOPG(x) ((x) >> IOPFNSHIFT) -#define IOPGOFF(x) ((x) & (IOPGSIZE-1)) - -#define PCIBR_DEV_SWAP_DIR (1ull << 19) -#define PCIBR_CTRL_PAGE_SIZE (0x1 << 21) - -/* - * PMU resources. - */ -struct ate_resource{ - uint64_t *ate; - uint64_t num_ate; - uint64_t lowest_free_index; -}; - -struct pcibus_info { - struct pcibus_bussoft pbi_buscommon; /* common header */ - uint32_t pbi_moduleid; - short pbi_bridge_type; - short pbi_bridge_mode; - - struct ate_resource pbi_int_ate_resource; - uint64_t pbi_int_ate_size; - - uint64_t pbi_dir_xbase; - char pbi_hub_xid; - - uint64_t pbi_devreg[8]; - spinlock_t pbi_lock; - - uint32_t pbi_valid_devices; - uint32_t pbi_enabled_devices; -}; - -/* - * pcibus_info structure locking macros - */ -inline static unsigned long -pcibr_lock(struct pcibus_info *pcibus_info) -{ - unsigned long flag; - spin_lock_irqsave(&pcibus_info->pbi_lock, flag); - return(flag); -} -#define pcibr_unlock(pcibus_info, flag) spin_unlock_irqrestore(&pcibus_info->pbi_lock, flag) - -extern int pcibr_init_provider(void); -extern void *pcibr_bus_fixup(struct pcibus_bussoft *); -extern dma_addr_t pcibr_dma_map(struct pci_dev *, unsigned long, size_t); -extern dma_addr_t pcibr_dma_map_consistent(struct pci_dev *, unsigned long, size_t); -extern void pcibr_dma_unmap(struct pci_dev *, dma_addr_t, int); - -/* - * prototypes for the bridge asic register access routines in pcibr_reg.c - */ -extern void pcireg_control_bit_clr(struct pcibus_info *, uint64_t); -extern void pcireg_control_bit_set(struct pcibus_info *, uint64_t); -extern uint64_t pcireg_tflush_get(struct pcibus_info *); -extern uint64_t pcireg_intr_status_get(struct pcibus_info *); -extern void pcireg_intr_enable_bit_clr(struct pcibus_info *, uint64_t); -extern void pcireg_intr_enable_bit_set(struct pcibus_info *, uint64_t); -extern void pcireg_intr_addr_addr_set(struct pcibus_info *, int, uint64_t); -extern void pcireg_force_intr_set(struct pcibus_info *, int); -extern uint64_t pcireg_wrb_flush_get(struct pcibus_info *, int); -extern void pcireg_int_ate_set(struct pcibus_info *, int, uint64_t); -extern uint64_t * pcireg_int_ate_addr(struct pcibus_info *, int); -extern void pcibr_force_interrupt(struct sn_irq_info *sn_irq_info); -extern void pcibr_change_devices_irq(struct sn_irq_info *sn_irq_info); -extern int pcibr_ate_alloc(struct pcibus_info *, int); -extern void pcibr_ate_free(struct pcibus_info *, int); -extern void ate_write(struct pcibus_info *, int, int, uint64_t); -#endif diff --git a/arch/ia64/sn/include/pci/pic.h b/arch/ia64/sn/include/pci/pic.h deleted file mode 100644 index fd18acecb1e6..000000000000 --- a/arch/ia64/sn/include/pci/pic.h +++ /dev/null @@ -1,261 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved. - */ -#ifndef _ASM_IA64_SN_PCI_PIC_H -#define _ASM_IA64_SN_PCI_PIC_H - -/* - * PIC AS DEVICE ZERO - * ------------------ - * - * PIC handles PCI/X busses. PCI/X requires that the 'bridge' (i.e. PIC) - * be designated as 'device 0'. That is a departure from earlier SGI - * PCI bridges. Because of that we use config space 1 to access the - * config space of the first actual PCI device on the bus. - * Here's what the PIC manual says: - * - * The current PCI-X bus specification now defines that the parent - * hosts bus bridge (PIC for example) must be device 0 on bus 0. PIC - * reduced the total number of devices from 8 to 4 and removed the - * device registers and windows, now only supporting devices 0,1,2, and - * 3. PIC did leave all 8 configuration space windows. The reason was - * there was nothing to gain by removing them. Here in lies the problem. - * The device numbering we do using 0 through 3 is unrelated to the device - * numbering which PCI-X requires in configuration space. In the past we - * correlated Configs pace and our device space 0 <-> 0, 1 <-> 1, etc. - * PCI-X requires we start a 1, not 0 and currently the PX brick - * does associate our: - * - * device 0 with configuration space window 1, - * device 1 with configuration space window 2, - * device 2 with configuration space window 3, - * device 3 with configuration space window 4. - * - * The net effect is that all config space access are off-by-one with - * relation to other per-slot accesses on the PIC. - * Here is a table that shows some of that: - * - * Internal Slot# - * | - * | 0 1 2 3 - * ----------|--------------------------------------- - * config | 0x21000 0x22000 0x23000 0x24000 - * | - * even rrb | 0[0] n/a 1[0] n/a [] == implied even/odd - * | - * odd rrb | n/a 0[1] n/a 1[1] - * | - * int dev | 00 01 10 11 - * | - * ext slot# | 1 2 3 4 - * ----------|--------------------------------------- - */ - -#define PIC_ATE_TARGETID_SHFT 8 -#define PIC_HOST_INTR_ADDR 0x0000FFFFFFFFFFFFUL -#define PIC_PCI64_ATTR_TARG_SHFT 60 - - -/***************************************************************************** - *********************** PIC MMR structure mapping *************************** - *****************************************************************************/ - -/* NOTE: PIC WAR. PV#854697. PIC does not allow writes just to [31:0] - * of a 64-bit register. When writing PIC registers, always write the - * entire 64 bits. - */ - -struct pic { - - /* 0x000000-0x00FFFF -- Local Registers */ - - /* 0x000000-0x000057 -- Standard Widget Configuration */ - uint64_t p_wid_id; /* 0x000000 */ - uint64_t p_wid_stat; /* 0x000008 */ - uint64_t p_wid_err_upper; /* 0x000010 */ - uint64_t p_wid_err_lower; /* 0x000018 */ - #define p_wid_err p_wid_err_lower - uint64_t p_wid_control; /* 0x000020 */ - uint64_t p_wid_req_timeout; /* 0x000028 */ - uint64_t p_wid_int_upper; /* 0x000030 */ - uint64_t p_wid_int_lower; /* 0x000038 */ - #define p_wid_int p_wid_int_lower - uint64_t p_wid_err_cmdword; /* 0x000040 */ - uint64_t p_wid_llp; /* 0x000048 */ - uint64_t p_wid_tflush; /* 0x000050 */ - - /* 0x000058-0x00007F -- Bridge-specific Widget Configuration */ - uint64_t p_wid_aux_err; /* 0x000058 */ - uint64_t p_wid_resp_upper; /* 0x000060 */ - uint64_t p_wid_resp_lower; /* 0x000068 */ - #define p_wid_resp p_wid_resp_lower - uint64_t p_wid_tst_pin_ctrl; /* 0x000070 */ - uint64_t p_wid_addr_lkerr; /* 0x000078 */ - - /* 0x000080-0x00008F -- PMU & MAP */ - uint64_t p_dir_map; /* 0x000080 */ - uint64_t _pad_000088; /* 0x000088 */ - - /* 0x000090-0x00009F -- SSRAM */ - uint64_t p_map_fault; /* 0x000090 */ - uint64_t _pad_000098; /* 0x000098 */ - - /* 0x0000A0-0x0000AF -- Arbitration */ - uint64_t p_arb; /* 0x0000A0 */ - uint64_t _pad_0000A8; /* 0x0000A8 */ - - /* 0x0000B0-0x0000BF -- Number In A Can or ATE Parity Error */ - uint64_t p_ate_parity_err; /* 0x0000B0 */ - uint64_t _pad_0000B8; /* 0x0000B8 */ - - /* 0x0000C0-0x0000FF -- PCI/GIO */ - uint64_t p_bus_timeout; /* 0x0000C0 */ - uint64_t p_pci_cfg; /* 0x0000C8 */ - uint64_t p_pci_err_upper; /* 0x0000D0 */ - uint64_t p_pci_err_lower; /* 0x0000D8 */ - #define p_pci_err p_pci_err_lower - uint64_t _pad_0000E0[4]; /* 0x0000{E0..F8} */ - - /* 0x000100-0x0001FF -- Interrupt */ - uint64_t p_int_status; /* 0x000100 */ - uint64_t p_int_enable; /* 0x000108 */ - uint64_t p_int_rst_stat; /* 0x000110 */ - uint64_t p_int_mode; /* 0x000118 */ - uint64_t p_int_device; /* 0x000120 */ - uint64_t p_int_host_err; /* 0x000128 */ - uint64_t p_int_addr[8]; /* 0x0001{30,,,68} */ - uint64_t p_err_int_view; /* 0x000170 */ - uint64_t p_mult_int; /* 0x000178 */ - uint64_t p_force_always[8]; /* 0x0001{80,,,B8} */ - uint64_t p_force_pin[8]; /* 0x0001{C0,,,F8} */ - - /* 0x000200-0x000298 -- Device */ - uint64_t p_device[4]; /* 0x0002{00,,,18} */ - uint64_t _pad_000220[4]; /* 0x0002{20,,,38} */ - uint64_t p_wr_req_buf[4]; /* 0x0002{40,,,58} */ - uint64_t _pad_000260[4]; /* 0x0002{60,,,78} */ - uint64_t p_rrb_map[2]; /* 0x0002{80,,,88} */ - #define p_even_resp p_rrb_map[0] /* 0x000280 */ - #define p_odd_resp p_rrb_map[1] /* 0x000288 */ - uint64_t p_resp_status; /* 0x000290 */ - uint64_t p_resp_clear; /* 0x000298 */ - - uint64_t _pad_0002A0[12]; /* 0x0002{A0..F8} */ - - /* 0x000300-0x0003F8 -- Buffer Address Match Registers */ - struct { - uint64_t upper; /* 0x0003{00,,,F0} */ - uint64_t lower; /* 0x0003{08,,,F8} */ - } p_buf_addr_match[16]; - - /* 0x000400-0x0005FF -- Performance Monitor Registers (even only) */ - struct { - uint64_t flush_w_touch; /* 0x000{400,,,5C0} */ - uint64_t flush_wo_touch; /* 0x000{408,,,5C8} */ - uint64_t inflight; /* 0x000{410,,,5D0} */ - uint64_t prefetch; /* 0x000{418,,,5D8} */ - uint64_t total_pci_retry; /* 0x000{420,,,5E0} */ - uint64_t max_pci_retry; /* 0x000{428,,,5E8} */ - uint64_t max_latency; /* 0x000{430,,,5F0} */ - uint64_t clear_all; /* 0x000{438,,,5F8} */ - } p_buf_count[8]; - - - /* 0x000600-0x0009FF -- PCI/X registers */ - uint64_t p_pcix_bus_err_addr; /* 0x000600 */ - uint64_t p_pcix_bus_err_attr; /* 0x000608 */ - uint64_t p_pcix_bus_err_data; /* 0x000610 */ - uint64_t p_pcix_pio_split_addr; /* 0x000618 */ - uint64_t p_pcix_pio_split_attr; /* 0x000620 */ - uint64_t p_pcix_dma_req_err_attr; /* 0x000628 */ - uint64_t p_pcix_dma_req_err_addr; /* 0x000630 */ - uint64_t p_pcix_timeout; /* 0x000638 */ - - uint64_t _pad_000640[120]; /* 0x000{640,,,9F8} */ - - /* 0x000A00-0x000BFF -- PCI/X Read&Write Buffer */ - struct { - uint64_t p_buf_addr; /* 0x000{A00,,,AF0} */ - uint64_t p_buf_attr; /* 0X000{A08,,,AF8} */ - } p_pcix_read_buf_64[16]; - - struct { - uint64_t p_buf_addr; /* 0x000{B00,,,BE0} */ - uint64_t p_buf_attr; /* 0x000{B08,,,BE8} */ - uint64_t p_buf_valid; /* 0x000{B10,,,BF0} */ - uint64_t __pad1; /* 0x000{B18,,,BF8} */ - } p_pcix_write_buf_64[8]; - - /* End of Local Registers -- Start of Address Map space */ - - char _pad_000c00[0x010000 - 0x000c00]; - - /* 0x010000-0x011fff -- Internal ATE RAM (Auto Parity Generation) */ - uint64_t p_int_ate_ram[1024]; /* 0x010000-0x011fff */ - - /* 0x012000-0x013fff -- Internal ATE RAM (Manual Parity Generation) */ - uint64_t p_int_ate_ram_mp[1024]; /* 0x012000-0x013fff */ - - char _pad_014000[0x18000 - 0x014000]; - - /* 0x18000-0x197F8 -- PIC Write Request Ram */ - uint64_t p_wr_req_lower[256]; /* 0x18000 - 0x187F8 */ - uint64_t p_wr_req_upper[256]; /* 0x18800 - 0x18FF8 */ - uint64_t p_wr_req_parity[256]; /* 0x19000 - 0x197F8 */ - - char _pad_019800[0x20000 - 0x019800]; - - /* 0x020000-0x027FFF -- PCI Device Configuration Spaces */ - union { - uint8_t c[0x1000 / 1]; /* 0x02{0000,,,7FFF} */ - uint16_t s[0x1000 / 2]; /* 0x02{0000,,,7FFF} */ - uint32_t l[0x1000 / 4]; /* 0x02{0000,,,7FFF} */ - uint64_t d[0x1000 / 8]; /* 0x02{0000,,,7FFF} */ - union { - uint8_t c[0x100 / 1]; - uint16_t s[0x100 / 2]; - uint32_t l[0x100 / 4]; - uint64_t d[0x100 / 8]; - } f[8]; - } p_type0_cfg_dev[8]; /* 0x02{0000,,,7FFF} */ - - /* 0x028000-0x028FFF -- PCI Type 1 Configuration Space */ - union { - uint8_t c[0x1000 / 1]; /* 0x028000-0x029000 */ - uint16_t s[0x1000 / 2]; /* 0x028000-0x029000 */ - uint32_t l[0x1000 / 4]; /* 0x028000-0x029000 */ - uint64_t d[0x1000 / 8]; /* 0x028000-0x029000 */ - union { - uint8_t c[0x100 / 1]; - uint16_t s[0x100 / 2]; - uint32_t l[0x100 / 4]; - uint64_t d[0x100 / 8]; - } f[8]; - } p_type1_cfg; /* 0x028000-0x029000 */ - - char _pad_029000[0x030000-0x029000]; - - /* 0x030000-0x030007 -- PCI Interrupt Acknowledge Cycle */ - union { - uint8_t c[8 / 1]; - uint16_t s[8 / 2]; - uint32_t l[8 / 4]; - uint64_t d[8 / 8]; - } p_pci_iack; /* 0x030000-0x030007 */ - - char _pad_030007[0x040000-0x030008]; - - /* 0x040000-0x030007 -- PCIX Special Cycle */ - union { - uint8_t c[8 / 1]; - uint16_t s[8 / 2]; - uint32_t l[8 / 4]; - uint64_t d[8 / 8]; - } p_pcix_cycle; /* 0x040000-0x040007 */ -}; - -#endif /* _ASM_IA64_SN_PCI_PIC_H */ diff --git a/arch/ia64/sn/include/pci/tiocp.h b/arch/ia64/sn/include/pci/tiocp.h deleted file mode 100644 index f07c83b2bf6e..000000000000 --- a/arch/ia64/sn/include/pci/tiocp.h +++ /dev/null @@ -1,256 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2003-2004 Silicon Graphics, Inc. All rights reserved. - */ -#ifndef _ASM_IA64_SN_PCI_TIOCP_H -#define _ASM_IA64_SN_PCI_TIOCP_H - -#define TIOCP_HOST_INTR_ADDR 0x003FFFFFFFFFFFFFUL -#define TIOCP_PCI64_CMDTYPE_MEM (0x1ull << 60) - - -/***************************************************************************** - *********************** TIOCP MMR structure mapping *************************** - *****************************************************************************/ - -struct tiocp{ - - /* 0x000000-0x00FFFF -- Local Registers */ - - /* 0x000000-0x000057 -- (Legacy Widget Space) Configuration */ - uint64_t cp_id; /* 0x000000 */ - uint64_t cp_stat; /* 0x000008 */ - uint64_t cp_err_upper; /* 0x000010 */ - uint64_t cp_err_lower; /* 0x000018 */ - #define cp_err cp_err_lower - uint64_t cp_control; /* 0x000020 */ - uint64_t cp_req_timeout; /* 0x000028 */ - uint64_t cp_intr_upper; /* 0x000030 */ - uint64_t cp_intr_lower; /* 0x000038 */ - #define cp_intr cp_intr_lower - uint64_t cp_err_cmdword; /* 0x000040 */ - uint64_t _pad_000048; /* 0x000048 */ - uint64_t cp_tflush; /* 0x000050 */ - - /* 0x000058-0x00007F -- Bridge-specific Configuration */ - uint64_t cp_aux_err; /* 0x000058 */ - uint64_t cp_resp_upper; /* 0x000060 */ - uint64_t cp_resp_lower; /* 0x000068 */ - #define cp_resp cp_resp_lower - uint64_t cp_tst_pin_ctrl; /* 0x000070 */ - uint64_t cp_addr_lkerr; /* 0x000078 */ - - /* 0x000080-0x00008F -- PMU & MAP */ - uint64_t cp_dir_map; /* 0x000080 */ - uint64_t _pad_000088; /* 0x000088 */ - - /* 0x000090-0x00009F -- SSRAM */ - uint64_t cp_map_fault; /* 0x000090 */ - uint64_t _pad_000098; /* 0x000098 */ - - /* 0x0000A0-0x0000AF -- Arbitration */ - uint64_t cp_arb; /* 0x0000A0 */ - uint64_t _pad_0000A8; /* 0x0000A8 */ - - /* 0x0000B0-0x0000BF -- Number In A Can or ATE Parity Error */ - uint64_t cp_ate_parity_err; /* 0x0000B0 */ - uint64_t _pad_0000B8; /* 0x0000B8 */ - - /* 0x0000C0-0x0000FF -- PCI/GIO */ - uint64_t cp_bus_timeout; /* 0x0000C0 */ - uint64_t cp_pci_cfg; /* 0x0000C8 */ - uint64_t cp_pci_err_upper; /* 0x0000D0 */ - uint64_t cp_pci_err_lower; /* 0x0000D8 */ - #define cp_pci_err cp_pci_err_lower - uint64_t _pad_0000E0[4]; /* 0x0000{E0..F8} */ - - /* 0x000100-0x0001FF -- Interrupt */ - uint64_t cp_int_status; /* 0x000100 */ - uint64_t cp_int_enable; /* 0x000108 */ - uint64_t cp_int_rst_stat; /* 0x000110 */ - uint64_t cp_int_mode; /* 0x000118 */ - uint64_t cp_int_device; /* 0x000120 */ - uint64_t cp_int_host_err; /* 0x000128 */ - uint64_t cp_int_addr[8]; /* 0x0001{30,,,68} */ - uint64_t cp_err_int_view; /* 0x000170 */ - uint64_t cp_mult_int; /* 0x000178 */ - uint64_t cp_force_always[8]; /* 0x0001{80,,,B8} */ - uint64_t cp_force_pin[8]; /* 0x0001{C0,,,F8} */ - - /* 0x000200-0x000298 -- Device */ - uint64_t cp_device[4]; /* 0x0002{00,,,18} */ - uint64_t _pad_000220[4]; /* 0x0002{20,,,38} */ - uint64_t cp_wr_req_buf[4]; /* 0x0002{40,,,58} */ - uint64_t _pad_000260[4]; /* 0x0002{60,,,78} */ - uint64_t cp_rrb_map[2]; /* 0x0002{80,,,88} */ - #define cp_even_resp cp_rrb_map[0] /* 0x000280 */ - #define cp_odd_resp cp_rrb_map[1] /* 0x000288 */ - uint64_t cp_resp_status; /* 0x000290 */ - uint64_t cp_resp_clear; /* 0x000298 */ - - uint64_t _pad_0002A0[12]; /* 0x0002{A0..F8} */ - - /* 0x000300-0x0003F8 -- Buffer Address Match Registers */ - struct { - uint64_t upper; /* 0x0003{00,,,F0} */ - uint64_t lower; /* 0x0003{08,,,F8} */ - } cp_buf_addr_match[16]; - - /* 0x000400-0x0005FF -- Performance Monitor Registers (even only) */ - struct { - uint64_t flush_w_touch; /* 0x000{400,,,5C0} */ - uint64_t flush_wo_touch; /* 0x000{408,,,5C8} */ - uint64_t inflight; /* 0x000{410,,,5D0} */ - uint64_t prefetch; /* 0x000{418,,,5D8} */ - uint64_t total_pci_retry; /* 0x000{420,,,5E0} */ - uint64_t max_pci_retry; /* 0x000{428,,,5E8} */ - uint64_t max_latency; /* 0x000{430,,,5F0} */ - uint64_t clear_all; /* 0x000{438,,,5F8} */ - } cp_buf_count[8]; - - - /* 0x000600-0x0009FF -- PCI/X registers */ - uint64_t cp_pcix_bus_err_addr; /* 0x000600 */ - uint64_t cp_pcix_bus_err_attr; /* 0x000608 */ - uint64_t cp_pcix_bus_err_data; /* 0x000610 */ - uint64_t cp_pcix_pio_split_addr; /* 0x000618 */ - uint64_t cp_pcix_pio_split_attr; /* 0x000620 */ - uint64_t cp_pcix_dma_req_err_attr; /* 0x000628 */ - uint64_t cp_pcix_dma_req_err_addr; /* 0x000630 */ - uint64_t cp_pcix_timeout; /* 0x000638 */ - - uint64_t _pad_000640[24]; /* 0x000{640,,,6F8} */ - - /* 0x000700-0x000737 -- Debug Registers */ - uint64_t cp_ct_debug_ctl; /* 0x000700 */ - uint64_t cp_br_debug_ctl; /* 0x000708 */ - uint64_t cp_mux3_debug_ctl; /* 0x000710 */ - uint64_t cp_mux4_debug_ctl; /* 0x000718 */ - uint64_t cp_mux5_debug_ctl; /* 0x000720 */ - uint64_t cp_mux6_debug_ctl; /* 0x000728 */ - uint64_t cp_mux7_debug_ctl; /* 0x000730 */ - - uint64_t _pad_000738[89]; /* 0x000{738,,,9F8} */ - - /* 0x000A00-0x000BFF -- PCI/X Read&Write Buffer */ - struct { - uint64_t cp_buf_addr; /* 0x000{A00,,,AF0} */ - uint64_t cp_buf_attr; /* 0X000{A08,,,AF8} */ - } cp_pcix_read_buf_64[16]; - - struct { - uint64_t cp_buf_addr; /* 0x000{B00,,,BE0} */ - uint64_t cp_buf_attr; /* 0x000{B08,,,BE8} */ - uint64_t cp_buf_valid; /* 0x000{B10,,,BF0} */ - uint64_t __pad1; /* 0x000{B18,,,BF8} */ - } cp_pcix_write_buf_64[8]; - - /* End of Local Registers -- Start of Address Map space */ - - char _pad_000c00[0x010000 - 0x000c00]; - - /* 0x010000-0x011FF8 -- Internal ATE RAM (Auto Parity Generation) */ - uint64_t cp_int_ate_ram[1024]; /* 0x010000-0x011FF8 */ - - char _pad_012000[0x14000 - 0x012000]; - - /* 0x014000-0x015FF8 -- Internal ATE RAM (Manual Parity Generation) */ - uint64_t cp_int_ate_ram_mp[1024]; /* 0x014000-0x015FF8 */ - - char _pad_016000[0x18000 - 0x016000]; - - /* 0x18000-0x197F8 -- TIOCP Write Request Ram */ - uint64_t cp_wr_req_lower[256]; /* 0x18000 - 0x187F8 */ - uint64_t cp_wr_req_upper[256]; /* 0x18800 - 0x18FF8 */ - uint64_t cp_wr_req_parity[256]; /* 0x19000 - 0x197F8 */ - - char _pad_019800[0x1C000 - 0x019800]; - - /* 0x1C000-0x1EFF8 -- TIOCP Read Response Ram */ - uint64_t cp_rd_resp_lower[512]; /* 0x1C000 - 0x1CFF8 */ - uint64_t cp_rd_resp_upper[512]; /* 0x1D000 - 0x1DFF8 */ - uint64_t cp_rd_resp_parity[512]; /* 0x1E000 - 0x1EFF8 */ - - char _pad_01F000[0x20000 - 0x01F000]; - - /* 0x020000-0x021FFF -- Host Device (CP) Configuration Space (not used) */ - char _pad_020000[0x021000 - 0x20000]; - - /* 0x021000-0x027FFF -- PCI Device Configuration Spaces */ - union { - uint8_t c[0x1000 / 1]; /* 0x02{0000,,,7FFF} */ - uint16_t s[0x1000 / 2]; /* 0x02{0000,,,7FFF} */ - uint32_t l[0x1000 / 4]; /* 0x02{0000,,,7FFF} */ - uint64_t d[0x1000 / 8]; /* 0x02{0000,,,7FFF} */ - union { - uint8_t c[0x100 / 1]; - uint16_t s[0x100 / 2]; - uint32_t l[0x100 / 4]; - uint64_t d[0x100 / 8]; - } f[8]; - } cp_type0_cfg_dev[7]; /* 0x02{1000,,,7FFF} */ - - /* 0x028000-0x028FFF -- PCI Type 1 Configuration Space */ - union { - uint8_t c[0x1000 / 1]; /* 0x028000-0x029000 */ - uint16_t s[0x1000 / 2]; /* 0x028000-0x029000 */ - uint32_t l[0x1000 / 4]; /* 0x028000-0x029000 */ - uint64_t d[0x1000 / 8]; /* 0x028000-0x029000 */ - union { - uint8_t c[0x100 / 1]; - uint16_t s[0x100 / 2]; - uint32_t l[0x100 / 4]; - uint64_t d[0x100 / 8]; - } f[8]; - } cp_type1_cfg; /* 0x028000-0x029000 */ - - char _pad_029000[0x030000-0x029000]; - - /* 0x030000-0x030007 -- PCI Interrupt Acknowledge Cycle */ - union { - uint8_t c[8 / 1]; - uint16_t s[8 / 2]; - uint32_t l[8 / 4]; - uint64_t d[8 / 8]; - } cp_pci_iack; /* 0x030000-0x030007 */ - - char _pad_030007[0x040000-0x030008]; - - /* 0x040000-0x040007 -- PCIX Special Cycle */ - union { - uint8_t c[8 / 1]; - uint16_t s[8 / 2]; - uint32_t l[8 / 4]; - uint64_t d[8 / 8]; - } cp_pcix_cycle; /* 0x040000-0x040007 */ - - char _pad_040007[0x200000-0x040008]; - - /* 0x200000-0x7FFFFF -- PCI/GIO Device Spaces */ - union { - uint8_t c[0x100000 / 1]; - uint16_t s[0x100000 / 2]; - uint32_t l[0x100000 / 4]; - uint64_t d[0x100000 / 8]; - } cp_devio_raw[6]; /* 0x200000-0x7FFFFF */ - - #define cp_devio(n) cp_devio_raw[((n)<2)?(n*2):(n+2)] - - char _pad_800000[0xA00000-0x800000]; - - /* 0xA00000-0xBFFFFF -- PCI/GIO Device Spaces w/flush */ - union { - uint8_t c[0x100000 / 1]; - uint16_t s[0x100000 / 2]; - uint32_t l[0x100000 / 4]; - uint64_t d[0x100000 / 8]; - } cp_devio_raw_flush[6]; /* 0xA00000-0xBFFFFF */ - - #define cp_devio_flush(n) cp_devio_raw_flush[((n)<2)?(n*2):(n+2)] - -}; - -#endif /* _ASM_IA64_SN_PCI_TIOCP_H */ diff --git a/arch/ia64/sn/include/xtalk/hubdev.h b/arch/ia64/sn/include/xtalk/hubdev.h index 868e7ecae84b..580a1c0403a7 100644 --- a/arch/ia64/sn/include/xtalk/hubdev.h +++ b/arch/ia64/sn/include/xtalk/hubdev.h @@ -8,6 +8,8 @@ #ifndef _ASM_IA64_SN_XTALK_HUBDEV_H #define _ASM_IA64_SN_XTALK_HUBDEV_H +#include "xtalk/xwidgetdev.h" + #define HUB_WIDGET_ID_MAX 0xf #define DEV_PER_WIDGET (2*2*8) #define IIO_ITTE_WIDGET_BITS 4 /* size of widget field */ diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index 9e07f5463f21..a6649baf629a 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c @@ -9,21 +9,28 @@ #include <linux/bootmem.h> #include <linux/nodemask.h> #include <asm/sn/types.h> -#include <asm/sn/sn_sal.h> #include <asm/sn/addrs.h> -#include <asm/sn/pcibus_provider_defs.h> -#include <asm/sn/pcidev.h> -#include "pci/pcibr_provider.h" -#include "xtalk/xwidgetdev.h" #include <asm/sn/geo.h> -#include "xtalk/hubdev.h" #include <asm/sn/io.h> +#include <asm/sn/pcibr_provider.h> +#include <asm/sn/pcibus_provider_defs.h> +#include <asm/sn/pcidev.h> #include <asm/sn/simulator.h> +#include <asm/sn/sn_sal.h> #include <asm/sn/tioca_provider.h> +#include "xtalk/hubdev.h" +#include "xtalk/xwidgetdev.h" -char master_baseio_wid; nasid_t master_nasid = INVALID_NASID; /* Partition Master */ +static struct list_head sn_sysdata_list; + +/* sysdata list struct */ +struct sysdata_el { + struct list_head entry; + void *sysdata; +}; + struct slab_info { struct hubdev_info hubdev; }; @@ -54,7 +61,7 @@ sn_default_pci_unmap(struct pci_dev *pdev, dma_addr_t addr, int direction) } static void * -sn_default_pci_bus_fixup(struct pcibus_bussoft *soft) +sn_default_pci_bus_fixup(struct pcibus_bussoft *soft, struct pci_controller *controller) { return NULL; } @@ -138,23 +145,6 @@ sal_get_pcidev_info(u64 segment, u64 bus_number, u64 devfn, u64 pci_dev, } /* - * sn_alloc_pci_sysdata() - This routine allocates a pci controller - * which is expected as the pci_dev and pci_bus sysdata by the Linux - * PCI infrastructure. - */ -static inline struct pci_controller *sn_alloc_pci_sysdata(void) -{ - struct pci_controller *pci_sysdata; - - pci_sysdata = kmalloc(sizeof(*pci_sysdata), GFP_KERNEL); - if (!pci_sysdata) - BUG(); - - memset(pci_sysdata, 0, sizeof(*pci_sysdata)); - return pci_sysdata; -} - -/* * sn_fixup_ionodes() - This routine initializes the HUB data strcuture for * each node in the system. */ @@ -221,22 +211,34 @@ static void sn_fixup_ionodes(void) } +void sn_pci_unfixup_slot(struct pci_dev *dev) +{ + struct pci_dev *host_pci_dev = SN_PCIDEV_INFO(dev)->host_pci_dev; + + sn_irq_unfixup(dev); + pci_dev_put(host_pci_dev); + pci_dev_put(dev); +} + /* * sn_pci_fixup_slot() - This routine sets up a slot's resources * consistent with the Linux PCI abstraction layer. Resources acquired * from our PCI provider include PIO maps to BAR space and interrupt * objects. */ -static void sn_pci_fixup_slot(struct pci_dev *dev) +void sn_pci_fixup_slot(struct pci_dev *dev) { int idx; int segment = 0; - uint64_t size; - struct sn_irq_info *sn_irq_info; - struct pci_dev *host_pci_dev; int status = 0; struct pcibus_bussoft *bs; + struct pci_bus *host_pci_bus; + struct pci_dev *host_pci_dev; + struct sn_irq_info *sn_irq_info; + unsigned long size; + unsigned int bus_no, devfn; + pci_dev_get(dev); /* for the sysdata pointer */ dev->sysdata = kmalloc(sizeof(struct pcidev_info), GFP_KERNEL); if (SN_PCIDEV_INFO(dev) <= 0) BUG(); /* Cannot afford to run out of memory */ @@ -253,7 +255,7 @@ static void sn_pci_fixup_slot(struct pci_dev *dev) (u64) __pa(SN_PCIDEV_INFO(dev)), (u64) __pa(sn_irq_info)); if (status) - BUG(); /* Cannot get platform pci device information information */ + BUG(); /* Cannot get platform pci device information */ /* Copy over PIO Mapped Addresses */ for (idx = 0; idx <= PCI_ROM_RESOURCE; idx++) { @@ -275,15 +277,21 @@ static void sn_pci_fixup_slot(struct pci_dev *dev) dev->resource[idx].parent = &iomem_resource; } - /* set up host bus linkages */ - bs = SN_PCIBUS_BUSSOFT(dev->bus); - host_pci_dev = - pci_find_slot(SN_PCIDEV_INFO(dev)->pdi_slot_host_handle >> 32, - SN_PCIDEV_INFO(dev)-> - pdi_slot_host_handle & 0xffffffff); + /* + * Using the PROMs values for the PCI host bus, get the Linux + * PCI host_pci_dev struct and set up host bus linkages + */ + + bus_no = SN_PCIDEV_INFO(dev)->pdi_slot_host_handle >> 32; + devfn = SN_PCIDEV_INFO(dev)->pdi_slot_host_handle & 0xffffffff; + host_pci_bus = pci_find_bus(pci_domain_nr(dev->bus), bus_no); + host_pci_dev = pci_get_slot(host_pci_bus, devfn); + + SN_PCIDEV_INFO(dev)->host_pci_dev = host_pci_dev; SN_PCIDEV_INFO(dev)->pdi_host_pcidev_info = - SN_PCIDEV_INFO(host_pci_dev); + SN_PCIDEV_INFO(host_pci_dev); SN_PCIDEV_INFO(dev)->pdi_linux_pcidev = dev; + bs = SN_PCIBUS_BUSSOFT(dev->bus); SN_PCIDEV_INFO(dev)->pdi_pcibus_info = bs; if (bs && bs->bs_asic_type < PCIIO_ASIC_MAX_TYPES) { @@ -297,6 +305,9 @@ static void sn_pci_fixup_slot(struct pci_dev *dev) SN_PCIDEV_INFO(dev)->pdi_sn_irq_info = sn_irq_info; dev->irq = SN_PCIDEV_INFO(dev)->pdi_sn_irq_info->irq_irq; sn_irq_fixup(dev, sn_irq_info); + } else { + SN_PCIDEV_INFO(dev)->pdi_sn_irq_info = NULL; + kfree(sn_irq_info); } } @@ -304,55 +315,57 @@ static void sn_pci_fixup_slot(struct pci_dev *dev) * sn_pci_controller_fixup() - This routine sets up a bus's resources * consistent with the Linux PCI abstraction layer. */ -static void sn_pci_controller_fixup(int segment, int busnum) +void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) { int status = 0; int nasid, cnode; - struct pci_bus *bus; struct pci_controller *controller; struct pcibus_bussoft *prom_bussoft_ptr; struct hubdev_info *hubdev_info; void *provider_soft; struct sn_pcibus_provider *provider; - status = - sal_get_pcibus_info((u64) segment, (u64) busnum, - (u64) ia64_tpa(&prom_bussoft_ptr)); - if (status > 0) { - return; /* bus # does not exist */ - } - + status = sal_get_pcibus_info((u64) segment, (u64) busnum, + (u64) ia64_tpa(&prom_bussoft_ptr)); + if (status > 0) + return; /*bus # does not exist */ prom_bussoft_ptr = __va(prom_bussoft_ptr); - controller = sn_alloc_pci_sysdata(); - /* controller non-zero is BUG'd in sn_alloc_pci_sysdata */ - bus = pci_scan_bus(busnum, &pci_root_ops, controller); + controller = kcalloc(1,sizeof(struct pci_controller), GFP_KERNEL); + if (!controller) + BUG(); + if (bus == NULL) { - return; /* error, or bus already scanned */ + bus = pci_scan_bus(busnum, &pci_root_ops, controller); + if (bus == NULL) + return; /* error, or bus already scanned */ + bus->sysdata = NULL; } + if (bus->sysdata) + goto error_return; /* sysdata already alloc'd */ + /* * Per-provider fixup. Copies the contents from prom to local * area and links SN_PCIBUS_BUSSOFT(). */ - if (prom_bussoft_ptr->bs_asic_type >= PCIIO_ASIC_MAX_TYPES) { + if (prom_bussoft_ptr->bs_asic_type >= PCIIO_ASIC_MAX_TYPES) return; /* unsupported asic type */ - } + + if (prom_bussoft_ptr->bs_asic_type == PCIIO_ASIC_TYPE_PPB) + goto error_return; /* no further fixup necessary */ provider = sn_pci_provider[prom_bussoft_ptr->bs_asic_type]; - if (provider == NULL) { + if (provider == NULL) return; /* no provider registerd for this asic */ - } provider_soft = NULL; - if (provider->bus_fixup) { - provider_soft = (*provider->bus_fixup) (prom_bussoft_ptr); - } + if (provider->bus_fixup) + provider_soft = (*provider->bus_fixup) (prom_bussoft_ptr, controller); - if (provider_soft == NULL) { + if (provider_soft == NULL) return; /* fixup failed or not applicable */ - } /* * Generic bus fixup goes here. Don't reference prom_bussoft_ptr @@ -361,12 +374,63 @@ static void sn_pci_controller_fixup(int segment, int busnum) bus->sysdata = controller; PCI_CONTROLLER(bus)->platform_data = provider_soft; - nasid = NASID_GET(SN_PCIBUS_BUSSOFT(bus)->bs_base); cnode = nasid_to_cnodeid(nasid); hubdev_info = (struct hubdev_info *)(NODEPDA(cnode)->pdinfo); SN_PCIBUS_BUSSOFT(bus)->bs_xwidget_info = &(hubdev_info->hdi_xwidget_info[SN_PCIBUS_BUSSOFT(bus)->bs_xid]); + + /* + * If the node information we obtained during the fixup phase is invalid + * then set controller->node to -1 (undetermined) + */ + if (controller->node >= num_online_nodes()) { + struct pcibus_bussoft *b = SN_PCIBUS_BUSSOFT(bus); + + printk(KERN_WARNING "Device ASIC=%u XID=%u PBUSNUM=%lu" + "L_IO=%lx L_MEM=%lx BASE=%lx\n", + b->bs_asic_type, b->bs_xid, b->bs_persist_busnum, + b->bs_legacy_io, b->bs_legacy_mem, b->bs_base); + printk(KERN_WARNING "on node %d but only %d nodes online." + "Association set to undetermined.\n", + controller->node, num_online_nodes()); + controller->node = -1; + } + return; + +error_return: + + kfree(controller); + return; +} + +void sn_bus_store_sysdata(struct pci_dev *dev) +{ + struct sysdata_el *element; + + element = kcalloc(1, sizeof(struct sysdata_el), GFP_KERNEL); + if (!element) { + dev_dbg(dev, "%s: out of memory!\n", __FUNCTION__); + return; + } + element->sysdata = dev->sysdata; + list_add(&element->entry, &sn_sysdata_list); +} + +void sn_bus_free_sysdata(void) +{ + struct sysdata_el *element; + struct list_head *list; + +sn_sysdata_free_start: + list_for_each(list, &sn_sysdata_list) { + element = list_entry(list, struct sysdata_el, entry); + list_del(&element->entry); + kfree(element->sysdata); + kfree(element); + goto sn_sysdata_free_start; + } + return; } /* @@ -384,7 +448,7 @@ static int __init sn_pci_init(void) extern void register_sn_procfs(void); #endif - if (!ia64_platform_is("sn2") || IS_RUNNING_ON_SIMULATOR()) + if (!ia64_platform_is("sn2") || IS_RUNNING_ON_FAKE_PROM()) return 0; /* @@ -403,20 +467,17 @@ static int __init sn_pci_init(void) */ ia64_max_iommu_merge_mask = ~PAGE_MASK; sn_fixup_ionodes(); - sn_irq = kmalloc(sizeof(struct sn_irq_info *) * NR_IRQS, GFP_KERNEL); - if (sn_irq <= 0) - BUG(); /* Canno afford to run out of memory. */ - memset(sn_irq, 0, sizeof(struct sn_irq_info *) * NR_IRQS); - + sn_irq_lh_init(); + INIT_LIST_HEAD(&sn_sysdata_list); sn_init_cpei_timer(); #ifdef CONFIG_PROC_FS register_sn_procfs(); #endif - for (i = 0; i < PCI_BUSES_TO_SCAN; i++) { - sn_pci_controller_fixup(0, i); - } + /* busses are not known yet ... */ + for (i = 0; i < PCI_BUSES_TO_SCAN; i++) + sn_pci_controller_fixup(0, i, NULL); /* * Generic Linux PCI Layer has created the pci_bus and pci_dev @@ -425,9 +486,8 @@ static int __init sn_pci_init(void) */ while ((pci_dev = - pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) != NULL) { + pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) != NULL) sn_pci_fixup_slot(pci_dev); - } sn_ioif_inited = 1; /* sn I/O infrastructure now initialized */ @@ -469,3 +529,8 @@ cnodeid_get_geoid(cnodeid_t cnode) } subsys_initcall(sn_pci_init); +EXPORT_SYMBOL(sn_pci_fixup_slot); +EXPORT_SYMBOL(sn_pci_unfixup_slot); +EXPORT_SYMBOL(sn_pci_controller_fixup); +EXPORT_SYMBOL(sn_bus_store_sysdata); +EXPORT_SYMBOL(sn_bus_free_sysdata); diff --git a/arch/ia64/sn/kernel/iomv.c b/arch/ia64/sn/kernel/iomv.c index fec6d8b8237b..7ce3cdad627b 100644 --- a/arch/ia64/sn/kernel/iomv.c +++ b/arch/ia64/sn/kernel/iomv.c @@ -9,12 +9,16 @@ #include <linux/module.h> #include <asm/io.h> #include <asm/delay.h> +#include <asm/vga.h> #include <asm/sn/nodepda.h> #include <asm/sn/simulator.h> #include <asm/sn/pda.h> #include <asm/sn/sn_cpuid.h> #include <asm/sn/shub_mmr.h> +#define IS_LEGACY_VGA_IOPORT(p) \ + (((p) >= 0x3b0 && (p) <= 0x3bb) || ((p) >= 0x3c0 && (p) <= 0x3df)) + /** * sn_io_addr - convert an in/out port to an i/o address * @port: port to convert @@ -26,6 +30,8 @@ void *sn_io_addr(unsigned long port) { if (!IS_RUNNING_ON_SIMULATOR()) { + if (IS_LEGACY_VGA_IOPORT(port)) + port += vga_console_iobase; /* On sn2, legacy I/O ports don't point at anything */ if (port < (64 * 1024)) return NULL; diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c index 0f4e8138658f..84d276a14ecb 100644 --- a/arch/ia64/sn/kernel/irq.c +++ b/arch/ia64/sn/kernel/irq.c @@ -9,13 +9,13 @@ */ #include <linux/irq.h> -#include <asm/sn/intr.h> +#include <linux/spinlock.h> #include <asm/sn/addrs.h> #include <asm/sn/arch.h> -#include "xtalk/xwidgetdev.h" +#include <asm/sn/intr.h> +#include <asm/sn/pcibr_provider.h> #include <asm/sn/pcibus_provider_defs.h> #include <asm/sn/pcidev.h> -#include "pci/pcibr_provider.h" #include <asm/sn/shub_mmr.h> #include <asm/sn/sn_sal.h> @@ -25,7 +25,8 @@ static void unregister_intr_pda(struct sn_irq_info *sn_irq_info); extern int sn_force_interrupt_flag; extern int sn_ioif_inited; -struct sn_irq_info **sn_irq; +static struct list_head **sn_irq_lh; +static spinlock_t sn_irq_info_lock = SPIN_LOCK_UNLOCKED; /* non-IRQ lock */ static inline uint64_t sn_intr_alloc(nasid_t local_nasid, int local_widget, u64 sn_irq_info, @@ -101,7 +102,7 @@ static void sn_end_irq(unsigned int irq) nasid = get_nasid(); event_occurred = HUB_L((uint64_t *) GLOBAL_MMR_ADDR (nasid, SH_EVENT_OCCURRED)); - /* If the UART bit is set here, we may have received an + /* If the UART bit is set here, we may have received an * interrupt from the UART that the driver missed. To * make sure, we IPI ourselves to force us to look again. */ @@ -115,82 +116,84 @@ static void sn_end_irq(unsigned int irq) force_interrupt(irq); } +static void sn_irq_info_free(struct rcu_head *head); + static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask) { - struct sn_irq_info *sn_irq_info = sn_irq[irq]; - struct sn_irq_info *tmp_sn_irq_info; + struct sn_irq_info *sn_irq_info, *sn_irq_info_safe; int cpuid, cpuphys; - nasid_t t_nasid; /* nasid to target */ - int t_slice; /* slice to target */ - - /* allocate a temp sn_irq_info struct to get new target info */ - tmp_sn_irq_info = kmalloc(sizeof(*tmp_sn_irq_info), GFP_KERNEL); - if (!tmp_sn_irq_info) - return; cpuid = first_cpu(mask); cpuphys = cpu_physical_id(cpuid); - t_nasid = cpuid_to_nasid(cpuid); - t_slice = cpuid_to_slice(cpuid); - while (sn_irq_info) { - int status; - int local_widget; - uint64_t bridge = (uint64_t) sn_irq_info->irq_bridge; - nasid_t local_nasid = NASID_GET(bridge); + list_for_each_entry_safe(sn_irq_info, sn_irq_info_safe, + sn_irq_lh[irq], list) { + uint64_t bridge; + int local_widget, status; + nasid_t local_nasid; + struct sn_irq_info *new_irq_info; + + new_irq_info = kmalloc(sizeof(struct sn_irq_info), GFP_ATOMIC); + if (new_irq_info == NULL) + break; + memcpy(new_irq_info, sn_irq_info, sizeof(struct sn_irq_info)); + + bridge = (uint64_t) new_irq_info->irq_bridge; + if (!bridge) { + kfree(new_irq_info); + break; /* irq is not a device interrupt */ + } - if (!bridge) - break; /* irq is not a device interrupt */ + local_nasid = NASID_GET(bridge); if (local_nasid & 1) local_widget = TIO_SWIN_WIDGETNUM(bridge); else local_widget = SWIN_WIDGETNUM(bridge); - /* Free the old PROM sn_irq_info structure */ - sn_intr_free(local_nasid, local_widget, sn_irq_info); + /* Free the old PROM new_irq_info structure */ + sn_intr_free(local_nasid, local_widget, new_irq_info); + /* Update kernels new_irq_info with new target info */ + unregister_intr_pda(new_irq_info); - /* allocate a new PROM sn_irq_info struct */ + /* allocate a new PROM new_irq_info struct */ status = sn_intr_alloc(local_nasid, local_widget, - __pa(tmp_sn_irq_info), irq, t_nasid, - t_slice); - - if (status == 0) { - /* Update kernels sn_irq_info with new target info */ - unregister_intr_pda(sn_irq_info); - sn_irq_info->irq_cpuid = cpuid; - sn_irq_info->irq_nasid = t_nasid; - sn_irq_info->irq_slice = t_slice; - sn_irq_info->irq_xtalkaddr = - tmp_sn_irq_info->irq_xtalkaddr; - sn_irq_info->irq_cookie = tmp_sn_irq_info->irq_cookie; - register_intr_pda(sn_irq_info); - - if (IS_PCI_BRIDGE_ASIC(sn_irq_info->irq_bridge_type)) { - pcibr_change_devices_irq(sn_irq_info); - } + __pa(new_irq_info), irq, + cpuid_to_nasid(cpuid), + cpuid_to_slice(cpuid)); + + /* SAL call failed */ + if (status) { + kfree(new_irq_info); + break; + } + + new_irq_info->irq_cpuid = cpuid; + register_intr_pda(new_irq_info); + + if (IS_PCI_BRIDGE_ASIC(new_irq_info->irq_bridge_type)) + pcibr_change_devices_irq(new_irq_info); - sn_irq_info = sn_irq_info->irq_next; + spin_lock(&sn_irq_info_lock); + list_replace_rcu(&sn_irq_info->list, &new_irq_info->list); + spin_unlock(&sn_irq_info_lock); + call_rcu(&sn_irq_info->rcu, sn_irq_info_free); #ifdef CONFIG_SMP - set_irq_affinity_info((irq & 0xff), cpuphys, 0); + set_irq_affinity_info((irq & 0xff), cpuphys, 0); #endif - } else { - break; /* snp_affinity failed the intr_alloc */ - } } - kfree(tmp_sn_irq_info); } struct hw_interrupt_type irq_type_sn = { - "SN hub", - sn_startup_irq, - sn_shutdown_irq, - sn_enable_irq, - sn_disable_irq, - sn_ack_irq, - sn_end_irq, - sn_set_affinity_irq + .typename = "SN hub", + .startup = sn_startup_irq, + .shutdown = sn_shutdown_irq, + .enable = sn_enable_irq, + .disable = sn_disable_irq, + .ack = sn_ack_irq, + .end = sn_end_irq, + .set_affinity = sn_set_affinity_irq }; unsigned int sn_local_vector_to_irq(u8 vector) @@ -231,19 +234,18 @@ static void unregister_intr_pda(struct sn_irq_info *sn_irq_info) struct sn_irq_info *tmp_irq_info; int i, foundmatch; + rcu_read_lock(); if (pdacpu(cpu)->sn_last_irq == irq) { foundmatch = 0; - for (i = pdacpu(cpu)->sn_last_irq - 1; i; i--) { - tmp_irq_info = sn_irq[i]; - while (tmp_irq_info) { + for (i = pdacpu(cpu)->sn_last_irq - 1; + i && !foundmatch; i--) { + list_for_each_entry_rcu(tmp_irq_info, + sn_irq_lh[i], + list) { if (tmp_irq_info->irq_cpuid == cpu) { - foundmatch++; + foundmatch = 1; break; } - tmp_irq_info = tmp_irq_info->irq_next; - } - if (foundmatch) { - break; } } pdacpu(cpu)->sn_last_irq = i; @@ -251,60 +253,27 @@ static void unregister_intr_pda(struct sn_irq_info *sn_irq_info) if (pdacpu(cpu)->sn_first_irq == irq) { foundmatch = 0; - for (i = pdacpu(cpu)->sn_first_irq + 1; i < NR_IRQS; i++) { - tmp_irq_info = sn_irq[i]; - while (tmp_irq_info) { + for (i = pdacpu(cpu)->sn_first_irq + 1; + i < NR_IRQS && !foundmatch; i++) { + list_for_each_entry_rcu(tmp_irq_info, + sn_irq_lh[i], + list) { if (tmp_irq_info->irq_cpuid == cpu) { - foundmatch++; + foundmatch = 1; break; } - tmp_irq_info = tmp_irq_info->irq_next; - } - if (foundmatch) { - break; } } pdacpu(cpu)->sn_first_irq = ((i == NR_IRQS) ? 0 : i); } + rcu_read_unlock(); } -struct sn_irq_info *sn_irq_alloc(nasid_t local_nasid, int local_widget, int irq, - nasid_t nasid, int slice) +static void sn_irq_info_free(struct rcu_head *head) { struct sn_irq_info *sn_irq_info; - int status; - - sn_irq_info = kmalloc(sizeof(*sn_irq_info), GFP_KERNEL); - if (sn_irq_info == NULL) - return NULL; - - memset(sn_irq_info, 0x0, sizeof(*sn_irq_info)); - - status = - sn_intr_alloc(local_nasid, local_widget, __pa(sn_irq_info), irq, - nasid, slice); - - if (status) { - kfree(sn_irq_info); - return NULL; - } else { - return sn_irq_info; - } -} - -void sn_irq_free(struct sn_irq_info *sn_irq_info) -{ - uint64_t bridge = (uint64_t) sn_irq_info->irq_bridge; - nasid_t local_nasid = NASID_GET(bridge); - int local_widget; - - if (local_nasid & 1) /* tio check */ - local_widget = TIO_SWIN_WIDGETNUM(bridge); - else - local_widget = SWIN_WIDGETNUM(bridge); - - sn_intr_free(local_nasid, local_widget, sn_irq_info); + sn_irq_info = container_of(head, struct sn_irq_info, rcu); kfree(sn_irq_info); } @@ -314,30 +283,54 @@ void sn_irq_fixup(struct pci_dev *pci_dev, struct sn_irq_info *sn_irq_info) int slice = sn_irq_info->irq_slice; int cpu = nasid_slice_to_cpuid(nasid, slice); + pci_dev_get(pci_dev); sn_irq_info->irq_cpuid = cpu; sn_irq_info->irq_pciioinfo = SN_PCIDEV_INFO(pci_dev); /* link it into the sn_irq[irq] list */ - sn_irq_info->irq_next = sn_irq[sn_irq_info->irq_irq]; - sn_irq[sn_irq_info->irq_irq] = sn_irq_info; + spin_lock(&sn_irq_info_lock); + list_add_rcu(&sn_irq_info->list, sn_irq_lh[sn_irq_info->irq_irq]); + spin_unlock(&sn_irq_info_lock); (void)register_intr_pda(sn_irq_info); } +void sn_irq_unfixup(struct pci_dev *pci_dev) +{ + struct sn_irq_info *sn_irq_info; + + /* Only cleanup IRQ stuff if this device has a host bus context */ + if (!SN_PCIDEV_BUSSOFT(pci_dev)) + return; + + sn_irq_info = SN_PCIDEV_INFO(pci_dev)->pdi_sn_irq_info; + if (!sn_irq_info || !sn_irq_info->irq_irq) { + kfree(sn_irq_info); + return; + } + + unregister_intr_pda(sn_irq_info); + spin_lock(&sn_irq_info_lock); + list_del_rcu(&sn_irq_info->list); + spin_unlock(&sn_irq_info_lock); + call_rcu(&sn_irq_info->rcu, sn_irq_info_free); + pci_dev_put(pci_dev); +} + static void force_interrupt(int irq) { struct sn_irq_info *sn_irq_info; if (!sn_ioif_inited) return; - sn_irq_info = sn_irq[irq]; - while (sn_irq_info) { + + rcu_read_lock(); + list_for_each_entry_rcu(sn_irq_info, sn_irq_lh[irq], list) { if (IS_PCI_BRIDGE_ASIC(sn_irq_info->irq_bridge_type) && - (sn_irq_info->irq_bridge != NULL)) { + (sn_irq_info->irq_bridge != NULL)) pcibr_force_interrupt(sn_irq_info); - } - sn_irq_info = sn_irq_info->irq_next; } + rcu_read_unlock(); } /* @@ -402,19 +395,41 @@ static void sn_check_intr(int irq, struct sn_irq_info *sn_irq_info) void sn_lb_int_war_check(void) { + struct sn_irq_info *sn_irq_info; int i; if (!sn_ioif_inited || pda->sn_first_irq == 0) return; + + rcu_read_lock(); for (i = pda->sn_first_irq; i <= pda->sn_last_irq; i++) { - struct sn_irq_info *sn_irq_info = sn_irq[i]; - while (sn_irq_info) { - /* Only call for PCI bridges that are fully initialized. */ + list_for_each_entry_rcu(sn_irq_info, sn_irq_lh[i], list) { + /* + * Only call for PCI bridges that are fully + * initialized. + */ if (IS_PCI_BRIDGE_ASIC(sn_irq_info->irq_bridge_type) && - (sn_irq_info->irq_bridge != NULL)) { + (sn_irq_info->irq_bridge != NULL)) sn_check_intr(i, sn_irq_info); - } - sn_irq_info = sn_irq_info->irq_next; } } + rcu_read_unlock(); +} + +void sn_irq_lh_init(void) +{ + int i; + + sn_irq_lh = kmalloc(sizeof(struct list_head *) * NR_IRQS, GFP_KERNEL); + if (!sn_irq_lh) + panic("SN PCI INIT: Failed to allocate memory for PCI init\n"); + + for (i = 0; i < NR_IRQS; i++) { + sn_irq_lh[i] = kmalloc(sizeof(struct list_head), GFP_KERNEL); + if (!sn_irq_lh[i]) + panic("SN PCI INIT: Failed IRQ memory allocation\n"); + + INIT_LIST_HEAD(sn_irq_lh[i]); + } + } diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c index 44bfc7f318cb..7c7fe441d623 100644 --- a/arch/ia64/sn/kernel/setup.c +++ b/arch/ia64/sn/kernel/setup.c @@ -36,6 +36,7 @@ #include <asm/machvec.h> #include <asm/system.h> #include <asm/processor.h> +#include <asm/vga.h> #include <asm/sn/arch.h> #include <asm/sn/addrs.h> #include <asm/sn/pda.h> @@ -95,6 +96,7 @@ u8 sn_coherency_id; EXPORT_SYMBOL(sn_coherency_id); u8 sn_region_size; EXPORT_SYMBOL(sn_region_size); +int sn_prom_type; /* 0=hardware, 1=medusa/realprom, 2=medusa/fakeprom */ short physical_node_map[MAX_PHYSNODE_ID]; @@ -268,19 +270,22 @@ void __init sn_setup(char **cmdline_p) { long status, ticks_per_sec, drift; int pxm; - int major = sn_sal_rev_major(), minor = sn_sal_rev_minor(); + u32 version = sn_sal_rev(); extern void sn_cpu_init(void); ia64_sn_plat_set_error_handling_features(); +#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) /* - * If the generic code has enabled vga console support - lets - * get rid of it again. This is a kludge for the fact that ACPI - * currtently has no way of informing us if legacy VGA is available - * or not. + * If there was a primary vga adapter identified through the + * EFI PCDP table, make it the preferred console. Otherwise + * zero out conswitchp. */ -#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) - if (conswitchp == &vga_con) { + + if (vga_console_membase) { + /* usable vga ... make tty0 the preferred default console */ + add_preferred_console("tty", 0, NULL); + } else { printk(KERN_DEBUG "SGI: Disabling VGA console\n"); #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; @@ -303,22 +308,21 @@ void __init sn_setup(char **cmdline_p) * support here so we don't have to listen to failed keyboard probe * messages. */ - if ((major < 2 || (major == 2 && minor <= 9)) && - acpi_kbd_controller_present) { + if (version <= 0x0209 && acpi_kbd_controller_present) { printk(KERN_INFO "Disabling legacy keyboard support as prom " "is too old and doesn't provide FADT\n"); acpi_kbd_controller_present = 0; } - printk("SGI SAL version %x.%02x\n", major, minor); + printk("SGI SAL version %x.%02x\n", version >> 8, version & 0x00FF); /* * Confirm the SAL we're running on is recent enough... */ - if ((major < SN_SAL_MIN_MAJOR) || (major == SN_SAL_MIN_MAJOR && - minor < SN_SAL_MIN_MINOR)) { + if (version < SN_SAL_MIN_VERSION) { printk(KERN_ERR "This kernel needs SGI SAL version >= " - "%x.%02x\n", SN_SAL_MIN_MAJOR, SN_SAL_MIN_MINOR); + "%x.%02x\n", SN_SAL_MIN_VERSION >> 8, + SN_SAL_MIN_VERSION & 0x00FF); panic("PROM version too old\n"); } @@ -350,7 +354,7 @@ void __init sn_setup(char **cmdline_p) ia64_mark_idle = &snidle; - /* + /* * For the bootcpu, we do this here. All other cpus will make the * call as part of cpu_init in slave cpu initialization. */ @@ -397,7 +401,7 @@ static void __init sn_init_pdas(char **cmdline_p) nodepdaindr[cnode] = alloc_bootmem_node(NODE_DATA(cnode), sizeof(nodepda_t)); memset(nodepdaindr[cnode], 0, sizeof(nodepda_t)); - memset(nodepdaindr[cnode]->phys_cpuid, -1, + memset(nodepdaindr[cnode]->phys_cpuid, -1, sizeof(nodepdaindr[cnode]->phys_cpuid)); } @@ -427,7 +431,7 @@ static void __init sn_init_pdas(char **cmdline_p) } /* - * Initialize the per node hubdev. This includes IO Nodes and + * Initialize the per node hubdev. This includes IO Nodes and * headless/memless nodes. */ for (cnode = 0; cnode < numionodes; cnode++) { @@ -455,6 +459,14 @@ void __init sn_cpu_init(void) int i; static int wars_have_been_checked; + if (smp_processor_id() == 0 && IS_MEDUSA()) { + if (ia64_sn_is_fake_prom()) + sn_prom_type = 2; + else + sn_prom_type = 1; + printk("Running on medusa with %s PROM\n", (sn_prom_type == 1) ? "real" : "fake"); + } + memset(pda, 0, sizeof(pda)); if (ia64_sn_get_sn_info(0, &sn_hub_info->shub2, &sn_hub_info->nasid_bitmask, &sn_hub_info->nasid_shift, &sn_system_size, &sn_sharing_domain_size, &sn_partition_id, @@ -520,7 +532,7 @@ void __init sn_cpu_init(void) */ { u64 pio1[] = {SH1_PIO_WRITE_STATUS_0, 0, SH1_PIO_WRITE_STATUS_1, 0}; - u64 pio2[] = {SH2_PIO_WRITE_STATUS_0, SH2_PIO_WRITE_STATUS_1, + u64 pio2[] = {SH2_PIO_WRITE_STATUS_0, SH2_PIO_WRITE_STATUS_1, SH2_PIO_WRITE_STATUS_2, SH2_PIO_WRITE_STATUS_3}; u64 *pio; pio = is_shub1() ? pio1 : pio2; @@ -552,6 +564,10 @@ static void __init scan_for_ionodes(void) int nasid = 0; lboard_t *brd; + /* fakeprom does not support klgraph */ + if (IS_RUNNING_ON_FAKE_PROM()) + return; + /* Setup ionodes with memory */ for (nasid = 0; nasid < MAX_PHYSNODE_ID; nasid += 2) { char *klgraph_header; @@ -563,8 +579,6 @@ static void __init scan_for_ionodes(void) cnodeid = -1; klgraph_header = __va(ia64_sn_get_klconfig_addr(nasid)); if (!klgraph_header) { - if (IS_RUNNING_ON_SIMULATOR()) - continue; BUG(); /* All nodes must have klconfig tables! */ } cnodeid = nasid_to_cnodeid(nasid); @@ -630,8 +644,8 @@ int nasid_slice_to_cpuid(int nasid, int slice) { long cpu; - - for (cpu=0; cpu < NR_CPUS; cpu++) + + for (cpu=0; cpu < NR_CPUS; cpu++) if (cpuid_to_nasid(cpu) == nasid && cpuid_to_slice(cpu) == slice) return cpu; diff --git a/arch/ia64/sn/kernel/sn2/ptc_deadlock.S b/arch/ia64/sn/kernel/sn2/ptc_deadlock.S index 7947312801ec..96cb71d15682 100644 --- a/arch/ia64/sn/kernel/sn2/ptc_deadlock.S +++ b/arch/ia64/sn/kernel/sn2/ptc_deadlock.S @@ -6,6 +6,7 @@ * Copyright (C) 2000-2004 Silicon Graphics, Inc. All rights reserved. */ +#include <asm/types.h> #include <asm/sn/shub_mmr.h> #define DEADLOCKBIT SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_SHFT diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c index a087b274847e..254fe15c064b 100644 --- a/arch/ia64/sn/kernel/tiocx.c +++ b/arch/ia64/sn/kernel/tiocx.c @@ -8,12 +8,12 @@ #include <linux/module.h> #include <linux/kernel.h> -#include <linux/version.h> #include <linux/slab.h> #include <linux/spinlock.h> #include <linux/proc_fs.h> #include <linux/device.h> #include <linux/delay.h> +#include <asm/system.h> #include <asm/uaccess.h> #include <asm/sn/sn_sal.h> #include <asm/sn/addrs.h> @@ -204,8 +204,8 @@ cx_device_register(nasid_t nasid, int part_num, int mfg_num, cx_dev->dev.parent = NULL; cx_dev->dev.bus = &tiocx_bus_type; cx_dev->dev.release = tiocx_bus_release; - snprintf(cx_dev->dev.bus_id, BUS_ID_SIZE, "%d.0x%x", - cx_dev->cx_id.nasid, cx_dev->cx_id.part_num); + snprintf(cx_dev->dev.bus_id, BUS_ID_SIZE, "%d", + cx_dev->cx_id.nasid); device_register(&cx_dev->dev); get_device(&cx_dev->dev); @@ -236,7 +236,6 @@ int cx_device_unregister(struct cx_dev *cx_dev) */ static int cx_device_reload(struct cx_dev *cx_dev) { - device_remove_file(&cx_dev->dev, &dev_attr_cxdev_control); cx_device_unregister(cx_dev); return cx_device_register(cx_dev->cx_id.nasid, cx_dev->cx_id.part_num, cx_dev->cx_id.mfg_num, cx_dev->hubdev); @@ -383,6 +382,7 @@ static int is_fpga_brick(int nasid) switch (tiocx_btchar_get(nasid)) { case L1_BRICKTYPE_SA: case L1_BRICKTYPE_ATHENA: + case L1_BRICKTYPE_DAYTONA: return 1; } return 0; @@ -409,7 +409,7 @@ static int tiocx_reload(struct cx_dev *cx_dev) uint64_t cx_id; cx_id = - *(volatile int32_t *)(TIO_SWIN_BASE(nasid, TIOCX_CORELET) + + *(volatile uint64_t *)(TIO_SWIN_BASE(nasid, TIOCX_CORELET) + WIDGET_ID); part_num = XWIDGET_PART_NUM(cx_id); mfg_num = XWIDGET_MFG_NUM(cx_id); @@ -458,6 +458,10 @@ static ssize_t store_cxdev_control(struct device *dev, struct device_attribute * switch (n) { case 1: + tio_corelet_reset(cx_dev->cx_id.nasid, TIOCX_CORELET); + tiocx_reload(cx_dev); + break; + case 2: tiocx_reload(cx_dev); break; case 3: @@ -477,6 +481,9 @@ static int __init tiocx_init(void) cnodeid_t cnodeid; int found_tiocx_device = 0; + if (!ia64_platform_is("sn2")) + return -ENODEV; + bus_register(&tiocx_bus_type); for (cnodeid = 0; cnodeid < MAX_COMPACT_NODES; cnodeid++) { @@ -537,7 +544,7 @@ static void __exit tiocx_exit(void) bus_unregister(&tiocx_bus_type); } -module_init(tiocx_init); +subsys_initcall(tiocx_init); module_exit(tiocx_exit); /************************************************************************ diff --git a/arch/ia64/sn/kernel/xpc_channel.c b/arch/ia64/sn/kernel/xpc_channel.c index 6d02dac8056f..94698bea7be0 100644 --- a/arch/ia64/sn/kernel/xpc_channel.c +++ b/arch/ia64/sn/kernel/xpc_channel.c @@ -72,7 +72,7 @@ xpc_initialize_channels(struct xpc_partition *part, partid_t partid) enum xpc_retval xpc_setup_infrastructure(struct xpc_partition *part) { - int ret; + int ret, cpuid; struct timer_list *timer; partid_t partid = XPC_PARTID(part); @@ -223,9 +223,9 @@ xpc_setup_infrastructure(struct xpc_partition *part) xpc_vars_part[partid].openclose_args_pa = __pa(part->local_openclose_args); xpc_vars_part[partid].IPI_amo_pa = __pa(part->local_IPI_amo_va); - xpc_vars_part[partid].IPI_nasid = cpuid_to_nasid(smp_processor_id()); - xpc_vars_part[partid].IPI_phys_cpuid = - cpu_physical_id(smp_processor_id()); + cpuid = raw_smp_processor_id(); /* any CPU in this partition will do */ + xpc_vars_part[partid].IPI_nasid = cpuid_to_nasid(cpuid); + xpc_vars_part[partid].IPI_phys_cpuid = cpu_physical_id(cpuid); xpc_vars_part[partid].nchannels = part->nchannels; xpc_vars_part[partid].magic = XPC_VP_MAGIC1; diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c index 177ddb748ebe..d580adcad927 100644 --- a/arch/ia64/sn/kernel/xpc_main.c +++ b/arch/ia64/sn/kernel/xpc_main.c @@ -53,6 +53,7 @@ #include <linux/cache.h> #include <linux/interrupt.h> #include <linux/slab.h> +#include <linux/delay.h> #include <asm/sn/intr.h> #include <asm/sn/sn_sal.h> #include <asm/uaccess.h> @@ -308,8 +309,7 @@ xpc_make_first_contact(struct xpc_partition *part) "partition %d\n", XPC_PARTID(part)); /* wait a 1/4 of a second or so */ - set_current_state(TASK_INTERRUPTIBLE); - (void) schedule_timeout(0.25 * HZ); + msleep_interruptible(250); if (part->act_state == XPC_P_DEACTIVATING) { return part->reason; @@ -841,9 +841,7 @@ xpc_do_exit(void) down(&xpc_discovery_exited); - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(0.3 * HZ); - set_current_state(TASK_RUNNING); + msleep_interruptible(300); /* wait for all partitions to become inactive */ @@ -860,12 +858,8 @@ xpc_do_exit(void) } } - if (active_part_count) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(0.3 * HZ); - set_current_state(TASK_RUNNING); - } - + if (active_part_count) + msleep_interruptible(300); } while (active_part_count > 0); diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c index 5da9bdbde7cb..0e4b9ad9ef02 100644 --- a/arch/ia64/sn/pci/pci_dma.c +++ b/arch/ia64/sn/pci/pci_dma.c @@ -11,9 +11,10 @@ #include <linux/module.h> #include <asm/dma.h> -#include <asm/sn/sn_sal.h> +#include <asm/sn/pcibr_provider.h> #include <asm/sn/pcibus_provider_defs.h> #include <asm/sn/pcidev.h> +#include <asm/sn/sn_sal.h> #define SG_ENT_VIRT_ADDRESS(sg) (page_address((sg)->page) + (sg)->offset) #define SG_ENT_PHYS_ADDRESS(SG) virt_to_phys(SG_ENT_VIRT_ADDRESS(SG)) @@ -78,6 +79,7 @@ void *sn_dma_alloc_coherent(struct device *dev, size_t size, { void *cpuaddr; unsigned long phys_addr; + int node; struct pci_dev *pdev = to_pci_dev(dev); struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); @@ -85,10 +87,19 @@ void *sn_dma_alloc_coherent(struct device *dev, size_t size, /* * Allocate the memory. - * FIXME: We should be doing alloc_pages_node for the node closest - * to the PCI device. */ - if (!(cpuaddr = (void *)__get_free_pages(GFP_ATOMIC, get_order(size)))) + node = pcibus_to_node(pdev->bus); + if (likely(node >=0)) { + struct page *p = alloc_pages_node(node, GFP_ATOMIC, get_order(size)); + + if (likely(p)) + cpuaddr = page_address(p); + else + return NULL; + } else + cpuaddr = (void *)__get_free_pages(GFP_ATOMIC, get_order(size)); + + if (unlikely(!cpuaddr)) return NULL; memset(cpuaddr, 0x0, size); diff --git a/arch/ia64/sn/pci/pcibr/pcibr_ate.c b/arch/ia64/sn/pci/pcibr/pcibr_ate.c index 0e47bce85f2d..d1647b863e61 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_ate.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_ate.c @@ -8,9 +8,9 @@ #include <linux/types.h> #include <asm/sn/sn_sal.h> +#include <asm/sn/pcibr_provider.h> #include <asm/sn/pcibus_provider_defs.h> #include <asm/sn/pcidev.h> -#include "pci/pcibr_provider.h" int pcibr_invalidate_ate = 0; /* by default don't invalidate ATE on free */ diff --git a/arch/ia64/sn/pci/pcibr/pcibr_dma.c b/arch/ia64/sn/pci/pcibr/pcibr_dma.c index 64af2b2c1787..b058dc2a0b9d 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_dma.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_dma.c @@ -8,18 +8,17 @@ #include <linux/types.h> #include <linux/pci.h> -#include <asm/sn/sn_sal.h> +#include <asm/sn/addrs.h> #include <asm/sn/geo.h> -#include "xtalk/xwidgetdev.h" -#include "xtalk/hubdev.h" +#include <asm/sn/pcibr_provider.h> #include <asm/sn/pcibus_provider_defs.h> #include <asm/sn/pcidev.h> -#include "pci/tiocp.h" -#include "pci/pic.h" -#include "pci/pcibr_provider.h" -#include "pci/tiocp.h" +#include <asm/sn/pic.h> +#include <asm/sn/sn_sal.h> +#include <asm/sn/tiocp.h> #include "tio.h" -#include <asm/sn/addrs.h> +#include "xtalk/xwidgetdev.h" +#include "xtalk/hubdev.h" extern int sn_ioif_inited; diff --git a/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/arch/ia64/sn/pci/pcibr/pcibr_provider.c index 3893999d23d8..b95e928636a1 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_provider.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_provider.c @@ -6,18 +6,51 @@ * Copyright (C) 2001-2004 Silicon Graphics, Inc. All rights reserved. */ -#include <linux/types.h> #include <linux/interrupt.h> +#include <linux/types.h> #include <linux/pci.h> -#include <asm/sn/sn_sal.h> -#include "xtalk/xwidgetdev.h" +#include <asm/sn/addrs.h> #include <asm/sn/geo.h> -#include "xtalk/hubdev.h" +#include <asm/sn/pcibr_provider.h> #include <asm/sn/pcibus_provider_defs.h> #include <asm/sn/pcidev.h> -#include "pci/pcibr_provider.h" -#include <asm/sn/addrs.h> +#include <asm/sn/sn_sal.h> +#include "xtalk/xwidgetdev.h" +#include "xtalk/hubdev.h" + +int +sal_pcibr_slot_enable(struct pcibus_info *soft, int device, void *resp) +{ + struct ia64_sal_retval ret_stuff; + uint64_t busnum; + + ret_stuff.status = 0; + ret_stuff.v0 = 0; + busnum = soft->pbi_buscommon.bs_persist_busnum; + SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_SLOT_ENABLE, (u64) busnum, + (u64) device, (u64) resp, 0, 0, 0, 0); + + return (int)ret_stuff.v0; +} + +int +sal_pcibr_slot_disable(struct pcibus_info *soft, int device, int action, + void *resp) +{ + struct ia64_sal_retval ret_stuff; + uint64_t busnum; + + ret_stuff.status = 0; + ret_stuff.v0 = 0; + + busnum = soft->pbi_buscommon.bs_persist_busnum; + SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_SLOT_DISABLE, + (u64) busnum, (u64) device, (u64) action, + (u64) resp, 0, 0, 0); + + return (int)ret_stuff.v0; +} static int sal_pcibr_error_interrupt(struct pcibus_info *soft) { @@ -52,7 +85,7 @@ pcibr_error_intr_handler(int irq, void *arg, struct pt_regs *regs) } void * -pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft) +pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *controller) { int nasid, cnode, j; struct hubdev_info *hubdev_info; @@ -125,6 +158,14 @@ pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft) memset(soft->pbi_int_ate_resource.ate, 0, (soft->pbi_int_ate_size * sizeof(uint64_t))); + if (prom_bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCP) + /* + * TIO PCI Bridge with no closest node information. + * FIXME: Find another way to determine the closest node + */ + controller->node = -1; + else + controller->node = cnode; return soft; } @@ -188,3 +229,6 @@ pcibr_init_provider(void) return 0; } + +EXPORT_SYMBOL_GPL(sal_pcibr_slot_enable); +EXPORT_SYMBOL_GPL(sal_pcibr_slot_disable); diff --git a/arch/ia64/sn/pci/pcibr/pcibr_reg.c b/arch/ia64/sn/pci/pcibr/pcibr_reg.c index 865c11c3b50a..21426d02fbe6 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_reg.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_reg.c @@ -6,13 +6,13 @@ * Copyright (C) 2004 Silicon Graphics, Inc. All rights reserved. */ -#include <linux/types.h> #include <linux/interrupt.h> +#include <linux/types.h> +#include <asm/sn/pcibr_provider.h> #include <asm/sn/pcibus_provider_defs.h> #include <asm/sn/pcidev.h> -#include "pci/tiocp.h" -#include "pci/pic.h" -#include "pci/pcibr_provider.h" +#include <asm/sn/pic.h> +#include <asm/sn/tiocp.h> union br_ptr { struct tiocp tio; diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c index 8dae9eb45456..5d76a7581465 100644 --- a/arch/ia64/sn/pci/tioca_provider.c +++ b/arch/ia64/sn/pci/tioca_provider.c @@ -336,7 +336,7 @@ tioca_dma_d48(struct pci_dev *pdev, uint64_t paddr) if (!ct_addr) return 0; - bus_addr = (dma_addr_t) (ct_addr & 0xffffffffffff); + bus_addr = (dma_addr_t) (ct_addr & 0xffffffffffffUL); node_upper = ct_addr >> 48; if (node_upper > 64) { @@ -464,7 +464,7 @@ map_return: * For mappings created using the direct modes (64 or 48) there are no * resources to release. */ -void +static void tioca_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir) { int i, entry; @@ -514,7 +514,7 @@ tioca_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir) * The mapping mode used is based on the devices dma_mask. As a last resort * use the GART mapped mode. */ -uint64_t +static uint64_t tioca_dma_map(struct pci_dev *pdev, uint64_t paddr, size_t byte_count) { uint64_t mapaddr; @@ -580,8 +580,8 @@ tioca_error_intr_handler(int irq, void *arg, struct pt_regs *pt) * On successful setup, returns the kernel version of tioca_common back to * the caller. */ -void * -tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft) +static void * +tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *controller) { struct tioca_common *tioca_common; struct tioca_kernel *tioca_kern; @@ -589,8 +589,7 @@ tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft) /* sanity check prom rev */ - if (sn_sal_rev_major() < 4 || - (sn_sal_rev_major() == 4 && sn_sal_rev_minor() < 6)) { + if (sn_sal_rev() < 0x0406) { printk (KERN_ERR "%s: SGI prom rev 4.06 or greater required " "for tioca support\n", __FUNCTION__); @@ -647,6 +646,8 @@ tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft) __FUNCTION__, SGI_TIOCA_ERROR, (int)tioca_common->ca_common.bs_persist_busnum); + /* Setup locality information */ + controller->node = tioca_kern->ca_closest_node; return tioca_common; } diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig index 42ca8a39798d..7772951df313 100644 --- a/arch/m32r/Kconfig +++ b/arch/m32r/Kconfig @@ -359,6 +359,8 @@ source "fs/Kconfig.binfmt" endmenu +source "net/Kconfig" + source "drivers/Kconfig" source "fs/Kconfig" diff --git a/arch/m32r/kernel/setup_m32700ut.c b/arch/m32r/kernel/setup_m32700ut.c index b014e2c1e524..a146b24a556b 100644 --- a/arch/m32r/kernel/setup_m32700ut.c +++ b/arch/m32r/kernel/setup_m32700ut.c @@ -3,8 +3,8 @@ * * Setup routines for Renesas M32700UT Board * - * Copyright (c) 2002 Hiroyuki Kondo, Hirokazu Takata, - * Hitoshi Yamamoto, Takeo Takahashi + * Copyright (c) 2002-2005 Hiroyuki Kondo, Hirokazu Takata, + * Hitoshi Yamamoto, Takeo Takahashi * * This file is subject to the terms and conditions of the GNU General * Public License. See the file "COPYING" in the main directory of this @@ -435,7 +435,7 @@ void __init init_IRQ(void) icu_data[M32R_IRQ_INT2].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01; enable_m32700ut_irq(M32R_IRQ_INT2); -//#if defined(CONFIG_VIDEO_M32R_AR) +#if defined(CONFIG_VIDEO_M32R_AR) /* * INT3# is used for AR */ @@ -445,9 +445,11 @@ void __init init_IRQ(void) irq_desc[M32R_IRQ_INT3].depth = 1; icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; disable_m32700ut_irq(M32R_IRQ_INT3); -//#endif /* CONFIG_VIDEO_M32R_AR */ +#endif /* CONFIG_VIDEO_M32R_AR */ } +#if defined(CONFIG_SMC91X) + #define LAN_IOSTART 0x300 #define LAN_IOEND 0x320 static struct resource smc91x_resources[] = { @@ -469,10 +471,55 @@ static struct platform_device smc91x_device = { .num_resources = ARRAY_SIZE(smc91x_resources), .resource = smc91x_resources, }; +#endif + +#if defined(CONFIG_FB_S1D13XXX) + +#include <video/s1d13xxxfb.h> +#include <asm/s1d13806.h> + +static struct s1d13xxxfb_pdata s1d13xxxfb_data = { + .initregs = s1d13xxxfb_initregs, + .initregssize = ARRAY_SIZE(s1d13xxxfb_initregs), + .platform_init_video = NULL, +#ifdef CONFIG_PM + .platform_suspend_video = NULL, + .platform_resume_video = NULL, +#endif +}; + +static struct resource s1d13xxxfb_resources[] = { + [0] = { + .start = 0x10600000UL, + .end = 0x1073FFFFUL, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 0x10400000UL, + .end = 0x104001FFUL, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device s1d13xxxfb_device = { + .name = S1D_DEVICENAME, + .id = 0, + .dev = { + .platform_data = &s1d13xxxfb_data, + }, + .num_resources = ARRAY_SIZE(s1d13xxxfb_resources), + .resource = s1d13xxxfb_resources, +}; +#endif static int __init platform_init(void) { +#if defined(CONFIG_SMC91X) platform_device_register(&smc91x_device); +#endif +#if defined(CONFIG_FB_S1D13XXX) + platform_device_register(&s1d13xxxfb_device); +#endif return 0; } arch_initcall(platform_init); diff --git a/arch/m32r/kernel/setup_mappi.c b/arch/m32r/kernel/setup_mappi.c index aaf8e569b930..4e709809efc5 100644 --- a/arch/m32r/kernel/setup_mappi.c +++ b/arch/m32r/kernel/setup_mappi.c @@ -3,14 +3,15 @@ * * Setup routines for Renesas MAPPI Board * - * Copyright (c) 2001, 2002 Hiroyuki Kondo, Hirokazu Takata, - * Hitoshi Yamamoto + * Copyright (c) 2001-2005 Hiroyuki Kondo, Hirokazu Takata, + * Hitoshi Yamamoto */ #include <linux/config.h> #include <linux/irq.h> #include <linux/kernel.h> #include <linux/init.h> +#include <linux/device.h> #include <asm/system.h> #include <asm/m32r.h> @@ -158,3 +159,49 @@ void __init init_IRQ(void) disable_mappi_irq(M32R_IRQ_INT2); #endif /* CONFIG_M32RPCC */ } + +#if defined(CONFIG_FB_S1D13XXX) + +#include <video/s1d13xxxfb.h> +#include <asm/s1d13806.h> + +static struct s1d13xxxfb_pdata s1d13xxxfb_data = { + .initregs = s1d13xxxfb_initregs, + .initregssize = ARRAY_SIZE(s1d13xxxfb_initregs), + .platform_init_video = NULL, +#ifdef CONFIG_PM + .platform_suspend_video = NULL, + .platform_resume_video = NULL, +#endif +}; + +static struct resource s1d13xxxfb_resources[] = { + [0] = { + .start = 0x10200000UL, + .end = 0x1033FFFFUL, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 0x10000000UL, + .end = 0x100001FFUL, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device s1d13xxxfb_device = { + .name = S1D_DEVICENAME, + .id = 0, + .dev = { + .platform_data = &s1d13xxxfb_data, + }, + .num_resources = ARRAY_SIZE(s1d13xxxfb_resources), + .resource = s1d13xxxfb_resources, +}; + +static int __init platform_init(void) +{ + platform_device_register(&s1d13xxxfb_device); + return 0; +} +arch_initcall(platform_init); +#endif diff --git a/arch/m32r/kernel/setup_mappi2.c b/arch/m32r/kernel/setup_mappi2.c index 38d5e9a41427..a1d801598aa4 100644 --- a/arch/m32r/kernel/setup_mappi2.c +++ b/arch/m32r/kernel/setup_mappi2.c @@ -3,8 +3,8 @@ * * Setup routines for Renesas MAPPI-II(M3A-ZA36) Board * - * Copyright (c) 2001, 2002 Hiroyuki Kondo, Hirokazu Takata, - * Hitoshi Yamamoto, Mamoru Sakugawa + * Copyright (c) 2001-2005 Hiroyuki Kondo, Hirokazu Takata, + * Hitoshi Yamamoto, Mamoru Sakugawa */ #include <linux/config.h> diff --git a/arch/m32r/kernel/setup_mappi3.c b/arch/m32r/kernel/setup_mappi3.c index 3d60a85aaec5..a76412e883e8 100644 --- a/arch/m32r/kernel/setup_mappi3.c +++ b/arch/m32r/kernel/setup_mappi3.c @@ -3,8 +3,8 @@ * * Setup routines for Renesas MAPPI-III(M3A-2170) Board * - * Copyright (c) 2001-2005 Hiroyuki Kondo, Hirokazu Takata, - * Hitoshi Yamamoto, Mamoru Sakugawa + * Copyright (c) 2001-2005 Hiroyuki Kondo, Hirokazu Takata, + * Hitoshi Yamamoto, Mamoru Sakugawa */ #include <linux/config.h> @@ -178,6 +178,8 @@ void __init init_IRQ(void) #endif /* CONFIG_M32R_CFC */ } +#if defined(CONFIG_SMC91X) + #define LAN_IOSTART 0x300 #define LAN_IOEND 0x320 static struct resource smc91x_resources[] = { @@ -200,9 +202,55 @@ static struct platform_device smc91x_device = { .resource = smc91x_resources, }; +#endif + +#if defined(CONFIG_FB_S1D13XXX) + +#include <video/s1d13xxxfb.h> +#include <asm/s1d13806.h> + +static struct s1d13xxxfb_pdata s1d13xxxfb_data = { + .initregs = s1d13xxxfb_initregs, + .initregssize = ARRAY_SIZE(s1d13xxxfb_initregs), + .platform_init_video = NULL, +#ifdef CONFIG_PM + .platform_suspend_video = NULL, + .platform_resume_video = NULL, +#endif +}; + +static struct resource s1d13xxxfb_resources[] = { + [0] = { + .start = 0x1d600000UL, + .end = 0x1d73FFFFUL, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 0x1d400000UL, + .end = 0x1d4001FFUL, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device s1d13xxxfb_device = { + .name = S1D_DEVICENAME, + .id = 0, + .dev = { + .platform_data = &s1d13xxxfb_data, + }, + .num_resources = ARRAY_SIZE(s1d13xxxfb_resources), + .resource = s1d13xxxfb_resources, +}; +#endif + static int __init platform_init(void) { +#if defined(CONFIG_SMC91X) platform_device_register(&smc91x_device); +#endif +#if defined(CONFIG_FB_S1D13XXX) + platform_device_register(&s1d13xxxfb_device); +#endif return 0; } arch_initcall(platform_init); diff --git a/arch/m32r/kernel/setup_oaks32r.c b/arch/m32r/kernel/setup_oaks32r.c index d656640badc9..45add5b76f19 100644 --- a/arch/m32r/kernel/setup_oaks32r.c +++ b/arch/m32r/kernel/setup_oaks32r.c @@ -3,8 +3,8 @@ * * Setup routines for OAKS32R Board * - * Copyright (c) 2002-2004 Hiroyuki Kondo, Hirokazu Takata, - * Hitoshi Yamamoto, Mamoru Sakugawa + * Copyright (c) 2002-2005 Hiroyuki Kondo, Hirokazu Takata, + * Hitoshi Yamamoto, Mamoru Sakugawa */ #include <linux/config.h> @@ -139,5 +139,4 @@ void __init init_IRQ(void) icu_data[M32R_IRQ_SIO1_S].icucr = 0; disable_oaks32r_irq(M32R_IRQ_SIO1_S); #endif /* CONFIG_SERIAL_M32R_SIO */ - } diff --git a/arch/m32r/kernel/setup_opsput.c b/arch/m32r/kernel/setup_opsput.c index 86f4cf2a86c3..f0301f58bcce 100644 --- a/arch/m32r/kernel/setup_opsput.c +++ b/arch/m32r/kernel/setup_opsput.c @@ -3,7 +3,7 @@ * * Setup routines for Renesas OPSPUT Board * - * Copyright (c) 2002-2004 + * Copyright (c) 2002-2005 * Hiroyuki Kondo, Hirokazu Takata, * Hitoshi Yamamoto, Takeo Takahashi, Mamoru Sakugawa * @@ -439,7 +439,7 @@ void __init init_IRQ(void) icu_data[M32R_IRQ_INT2].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01; enable_opsput_irq(M32R_IRQ_INT2); -//#if defined(CONFIG_VIDEO_M32R_AR) +#if defined(CONFIG_VIDEO_M32R_AR) /* * INT3# is used for AR */ @@ -449,9 +449,11 @@ void __init init_IRQ(void) irq_desc[M32R_IRQ_INT3].depth = 1; icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; disable_opsput_irq(M32R_IRQ_INT3); -//#endif /* CONFIG_VIDEO_M32R_AR */ +#endif /* CONFIG_VIDEO_M32R_AR */ } +#if defined(CONFIG_SMC91X) + #define LAN_IOSTART 0x300 #define LAN_IOEND 0x320 static struct resource smc91x_resources[] = { @@ -473,10 +475,55 @@ static struct platform_device smc91x_device = { .num_resources = ARRAY_SIZE(smc91x_resources), .resource = smc91x_resources, }; +#endif + +#if defined(CONFIG_FB_S1D13XXX) + +#include <video/s1d13xxxfb.h> +#include <asm/s1d13806.h> + +static struct s1d13xxxfb_pdata s1d13xxxfb_data = { + .initregs = s1d13xxxfb_initregs, + .initregssize = ARRAY_SIZE(s1d13xxxfb_initregs), + .platform_init_video = NULL, +#ifdef CONFIG_PM + .platform_suspend_video = NULL, + .platform_resume_video = NULL, +#endif +}; + +static struct resource s1d13xxxfb_resources[] = { + [0] = { + .start = 0x10600000UL, + .end = 0x1073FFFFUL, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 0x10400000UL, + .end = 0x104001FFUL, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device s1d13xxxfb_device = { + .name = S1D_DEVICENAME, + .id = 0, + .dev = { + .platform_data = &s1d13xxxfb_data, + }, + .num_resources = ARRAY_SIZE(s1d13xxxfb_resources), + .resource = s1d13xxxfb_resources, +}; +#endif static int __init platform_init(void) { +#if defined(CONFIG_SMC91X) platform_device_register(&smc91x_device); +#endif +#if defined(CONFIG_FB_S1D13XXX) + platform_device_register(&s1d13xxxfb_device); +#endif return 0; } arch_initcall(platform_init); diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 691a2469ff36..178c4a3fbb72 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -450,6 +450,8 @@ source "drivers/zorro/Kconfig" endmenu +source "net/Kconfig" + source "drivers/Kconfig" menu "Character devices" diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig index dbfcdc8e6087..117f183f0b43 100644 --- a/arch/m68knommu/Kconfig +++ b/arch/m68knommu/Kconfig @@ -575,6 +575,8 @@ config PM endmenu +source "net/Kconfig" + source "drivers/Kconfig" source "fs/Kconfig" diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index bd9de7b00c0a..b578239146b5 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1640,6 +1640,8 @@ config PM endmenu +source "net/Kconfig" + source "drivers/Kconfig" source "fs/Kconfig" diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index 508026ae5842..65ee15396ffd 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c @@ -457,7 +457,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs) if (!user_mode(regs)) return 1; - if (try_to_freeze(0)) + if (try_to_freeze()) goto no_signal; if (!oldset) diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index ce327c799b44..1c2d87435233 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -190,6 +190,8 @@ source "fs/Kconfig.binfmt" endmenu +source "net/Kconfig" + source "drivers/Kconfig" source "fs/Kconfig" diff --git a/arch/parisc/configs/712_defconfig b/arch/parisc/configs/712_defconfig index 872085dea8a8..6efaa9293eef 100644 --- a/arch/parisc/configs/712_defconfig +++ b/arch/parisc/configs/712_defconfig @@ -506,7 +506,7 @@ CONFIG_HW_CONSOLE=y # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=8 +CONFIG_SERIAL_8250_NR_UARTS=17 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y diff --git a/arch/parisc/configs/a500_defconfig b/arch/parisc/configs/a500_defconfig index d28ebfa1070d..30fc03ed0cfb 100644 --- a/arch/parisc/configs/a500_defconfig +++ b/arch/parisc/configs/a500_defconfig @@ -662,7 +662,7 @@ CONFIG_HW_CONSOLE=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_CS=m -CONFIG_SERIAL_8250_NR_UARTS=8 +CONFIG_SERIAL_8250_NR_UARTS=17 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y diff --git a/arch/parisc/configs/b180_defconfig b/arch/parisc/configs/b180_defconfig index 1700d7aec686..46c9511f3229 100644 --- a/arch/parisc/configs/b180_defconfig +++ b/arch/parisc/configs/b180_defconfig @@ -514,7 +514,7 @@ CONFIG_HW_CONSOLE=y # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_NR_UARTS=13 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y diff --git a/arch/parisc/configs/c3000_defconfig b/arch/parisc/configs/c3000_defconfig index b27980161c31..67aca6ccc9b0 100644 --- a/arch/parisc/configs/c3000_defconfig +++ b/arch/parisc/configs/c3000_defconfig @@ -661,7 +661,7 @@ CONFIG_HW_CONSOLE=y # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_NR_UARTS=13 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y diff --git a/arch/parisc/defconfig b/arch/parisc/defconfig index ebd6301aa599..fdae21c503d7 100644 --- a/arch/parisc/defconfig +++ b/arch/parisc/defconfig @@ -517,7 +517,7 @@ CONFIG_HW_CONSOLE=y # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_NR_UARTS=13 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y diff --git a/arch/ppc/8xx_io/enet.c b/arch/ppc/8xx_io/enet.c index 4ea7158e5062..ece6a9fbe09b 100644 --- a/arch/ppc/8xx_io/enet.c +++ b/arch/ppc/8xx_io/enet.c @@ -714,16 +714,24 @@ static int __init scc_enet_init(void) immap->im_ioport.iop_pcdat &= ~PC_ENET_LBK; /* Disable Loopback */ #endif /* PC_ENET_LBK */ - /* Configure port C pins to enable CLSN and RENA. +#ifdef PE_ENET_TCLK + /* Configure port E for TCLK and RCLK. */ - immap->im_ioport.iop_pcpar &= ~(PC_ENET_CLSN | PC_ENET_RENA); - immap->im_ioport.iop_pcdir &= ~(PC_ENET_CLSN | PC_ENET_RENA); - immap->im_ioport.iop_pcso |= (PC_ENET_CLSN | PC_ENET_RENA); - + cp->cp_pepar |= (PE_ENET_TCLK | PE_ENET_RCLK); + cp->cp_pedir &= ~(PE_ENET_TCLK | PE_ENET_RCLK); + cp->cp_peso &= ~(PE_ENET_TCLK | PE_ENET_RCLK); +#else /* Configure port A for TCLK and RCLK. */ immap->im_ioport.iop_papar |= (PA_ENET_TCLK | PA_ENET_RCLK); immap->im_ioport.iop_padir &= ~(PA_ENET_TCLK | PA_ENET_RCLK); +#endif + + /* Configure port C pins to enable CLSN and RENA. + */ + immap->im_ioport.iop_pcpar &= ~(PC_ENET_CLSN | PC_ENET_RENA); + immap->im_ioport.iop_pcdir &= ~(PC_ENET_CLSN | PC_ENET_RENA); + immap->im_ioport.iop_pcso |= (PC_ENET_CLSN | PC_ENET_RENA); /* Configure Serial Interface clock routing. * First, clear all SCC bits to zero, then set the ones we want. @@ -896,14 +904,18 @@ static int __init scc_enet_init(void) /* It is now OK to enable the Ethernet transmitter. * Unfortunately, there are board implementation differences here. */ -#if (!defined (PB_ENET_TENA) && defined (PC_ENET_TENA)) +#if (!defined (PB_ENET_TENA) && defined (PC_ENET_TENA) && !defined (PE_ENET_TENA)) immap->im_ioport.iop_pcpar |= PC_ENET_TENA; immap->im_ioport.iop_pcdir &= ~PC_ENET_TENA; -#elif ( defined (PB_ENET_TENA) && !defined (PC_ENET_TENA)) +#elif ( defined (PB_ENET_TENA) && !defined (PC_ENET_TENA) && !defined (PE_ENET_TENA)) cp->cp_pbpar |= PB_ENET_TENA; cp->cp_pbdir |= PB_ENET_TENA; +#elif ( !defined (PB_ENET_TENA) && !defined (PC_ENET_TENA) && defined (PE_ENET_TENA)) + cp->cp_pepar |= PE_ENET_TENA; + cp->cp_pedir &= ~PE_ENET_TENA; + cp->cp_peso |= PE_ENET_TENA; #else -#error Configuration Error: define exactly ONE of PB_ENET_TENA, PC_ENET_TENA +#error Configuration Error: define exactly ONE of PB_ENET_TENA, PC_ENET_TENA, PE_ENET_TENA #endif #if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) @@ -936,6 +948,29 @@ static int __init scc_enet_init(void) *((volatile uint *)BCSR1) &= ~BCSR1_ETHEN; #endif +#ifdef CONFIG_MPC885ADS + + /* Deassert PHY reset and enable the PHY. + */ + { + volatile uint __iomem *bcsr = ioremap(BCSR_ADDR, BCSR_SIZE); + uint tmp; + + tmp = in_be32(bcsr + 1 /* BCSR1 */); + tmp |= BCSR1_ETHEN; + out_be32(bcsr + 1, tmp); + tmp = in_be32(bcsr + 4 /* BCSR4 */); + tmp |= BCSR4_ETH10_RST; + out_be32(bcsr + 4, tmp); + iounmap(bcsr); + } + + /* On MPC885ADS SCC ethernet PHY defaults to the full duplex mode + * upon reset. SCC is set to half duplex by default. So this + * inconsistency should be better fixed by the software. + */ +#endif + dev->base_addr = (unsigned long)ep; #if 0 dev->name = "CPM_ENET"; @@ -969,3 +1004,4 @@ static int __init scc_enet_init(void) } module_init(scc_enet_init); + diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig index a7835cd3f51f..b833cbcd77f0 100644 --- a/arch/ppc/Kconfig +++ b/arch/ppc/Kconfig @@ -284,6 +284,9 @@ endmenu menu "Platform options" +config FADS + bool + choice prompt "8xx Machine Type" depends on 8xx @@ -399,8 +402,25 @@ config BSEIP 26MB DRAM, 4MB flash, Ethernet, a 16K-gate FPGA, USB, an LCD/video controller, and two RS232 ports. -config FADS +config MPC8XXFADS bool "FADS" + select FADS + +config MPC86XADS + bool "MPC86XADS" + help + MPC86x Application Development System by Freescale Semiconductor. + The MPC86xADS is meant to serve as a platform for s/w and h/w + development around the MPC86X processor families. + select FADS + +config MPC885ADS + bool "MPC885ADS" + help + Freescale Semiconductor MPC885 Application Development System (ADS). + Also known as DUET. + The MPC885ADS is meant to serve as a platform for s/w and h/w + development around the MPC885 processor family. config TQM823L bool "TQM823L" @@ -1335,6 +1355,8 @@ config PIN_TLB depends on ADVANCED_OPTIONS && 8xx endmenu +source "net/Kconfig" + source "drivers/Kconfig" source "fs/Kconfig" diff --git a/arch/ppc/boot/images/Makefile b/arch/ppc/boot/images/Makefile index c9ac5f5fa9e4..532e7ef1edb6 100644 --- a/arch/ppc/boot/images/Makefile +++ b/arch/ppc/boot/images/Makefile @@ -6,12 +6,17 @@ MKIMAGE := $(srctree)/scripts/mkuboot.sh extra-y := vmlinux.bin vmlinux.gz +# two make processes may write to vmlinux.gz at the same time with make -j +quiet_cmd_mygzip = GZIP $@ +cmd_mygzip = gzip -f -9 < $< > $@.$$$$ && mv $@.$$$$ $@ + + OBJCOPYFLAGS_vmlinux.bin := -O binary $(obj)/vmlinux.bin: vmlinux FORCE $(call if_changed,objcopy) $(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE - $(call if_changed,gzip) + $(call if_changed,mygzip) quiet_cmd_uimage = UIMAGE $@ cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A ppc -O linux -T kernel \ diff --git a/arch/ppc/configs/mpc86x_ads_defconfig b/arch/ppc/configs/mpc86x_ads_defconfig new file mode 100644 index 000000000000..f63c6f59d68a --- /dev/null +++ b/arch/ppc/configs/mpc86x_ads_defconfig @@ -0,0 +1,633 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc4 +# Tue Jun 14 13:36:35 2005 +# +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_HAVE_DEC_LOCK=y +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_GENERIC_NVRAM=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +# CONFIG_CLEAN_COMPILE is not set +CONFIG_BROKEN=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +# CONFIG_KALLSYMS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +# CONFIG_BASE_FULL is not set +CONFIG_FUTEX=y +# CONFIG_EPOLL is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +# CONFIG_SHMEM is not set +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +CONFIG_TINY_SHMEM=y +CONFIG_BASE_SMALL=1 + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODULE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_KMOD is not set + +# +# Processor +# +# CONFIG_6xx is not set +# CONFIG_40x is not set +# CONFIG_44x is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set +CONFIG_8xx=y +# CONFIG_E500 is not set +# CONFIG_MATH_EMULATION is not set +# CONFIG_CPU_FREQ is not set +CONFIG_EMBEDDEDBOOT=y +# CONFIG_PM is not set +CONFIG_NOT_COHERENT_CACHE=y + +# +# Platform options +# +CONFIG_FADS=y +# CONFIG_RPXLITE is not set +# CONFIG_RPXCLASSIC is not set +# CONFIG_BSEIP is not set +# CONFIG_MPC8XXFADS is not set +CONFIG_MPC86XADS=y +# CONFIG_TQM823L is not set +# CONFIG_TQM850L is not set +# CONFIG_TQM855L is not set +# CONFIG_TQM860L is not set +# CONFIG_FPS850L is not set +# CONFIG_SPD823TS is not set +# CONFIG_IVMS8 is not set +# CONFIG_IVML24 is not set +# CONFIG_SM850 is not set +# CONFIG_HERMES_PRO is not set +# CONFIG_IP860 is not set +# CONFIG_LWMON is not set +# CONFIG_PCU_E is not set +# CONFIG_CCM is not set +# CONFIG_LANTEC is not set +# CONFIG_MBX is not set +# CONFIG_WINCEPT is not set +# CONFIG_SMP is not set +# CONFIG_PREEMPT is not set +# CONFIG_HIGHMEM is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_CMDLINE_BOOL is not set +CONFIG_ISA_DMA_API=y + +# +# Bus options +# +# CONFIG_PCI is not set +# CONFIG_PCI_DOMAINS is not set +# CONFIG_PCI_QSPAN is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Advanced setup +# +# CONFIG_ADVANCED_OPTIONS is not set + +# +# Default settings for advanced configuration options are used +# +CONFIG_HIGHMEM_START=0xfe000000 +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_KERNEL_START=0xc0000000 +CONFIG_TASK_SIZE=0x80000000 +CONFIG_CONSISTENT_START=0xff100000 +CONFIG_CONSISTENT_SIZE=0x00200000 +CONFIG_BOOT_LOAD=0x00400000 + +# +# Device Drivers +# + +# +# Generic Driver Options +# +# CONFIG_STANDALONE is not set +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_LBD is not set +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# + +# +# Macintosh device drivers +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +CONFIG_IPV6=m +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_OAKNET is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_CPM=y +CONFIG_SERIAL_CPM_CONSOLE=y +# CONFIG_SERIAL_CPM_SCC1 is not set +# CONFIG_SERIAL_CPM_SCC2 is not set +# CONFIG_SERIAL_CPM_SCC3 is not set +# CONFIG_SERIAL_CPM_SCC4 is not set +CONFIG_SERIAL_CPM_SMC1=y +# CONFIG_SERIAL_CPM_SMC2 is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB_ARCH_HAS_HCD is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_FS_XATTR is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_DNOTIFY is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +CONFIG_NFS_V4=y +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# MPC8xx CPM Options +# +CONFIG_SCC_ENET=y +CONFIG_SCC1_ENET=y +# CONFIG_SCC2_ENET is not set +# CONFIG_SCC3_ENET is not set +# CONFIG_FEC_ENET is not set +# CONFIG_ENET_BIG_BUFFERS is not set + +# +# Generic MPC8xx Options +# +# CONFIG_8xx_COPYBACK is not set +# CONFIG_8xx_CPU6 is not set +CONFIG_NO_UCODE_PATCH=y +# CONFIG_USB_SOF_UCODE_PATCH is not set +# CONFIG_I2C_SPI_UCODE_PATCH is not set +# CONFIG_I2C_SPI_SMC1_UCODE_PATCH is not set + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# diff --git a/arch/ppc/configs/mpc885ads_defconfig b/arch/ppc/configs/mpc885ads_defconfig new file mode 100644 index 000000000000..016f94d9325f --- /dev/null +++ b/arch/ppc/configs/mpc885ads_defconfig @@ -0,0 +1,622 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc6 +# Thu Jun 9 21:17:29 2005 +# +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_HAVE_DEC_LOCK=y +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_GENERIC_NVRAM=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +# CONFIG_CLEAN_COMPILE is not set +CONFIG_BROKEN=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_HOTPLUG=y +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +# CONFIG_KALLSYMS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +# CONFIG_EPOLL is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# Processor +# +# CONFIG_6xx is not set +# CONFIG_40x is not set +# CONFIG_44x is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set +CONFIG_8xx=y +# CONFIG_E500 is not set +# CONFIG_MATH_EMULATION is not set +# CONFIG_CPU_FREQ is not set +CONFIG_EMBEDDEDBOOT=y +# CONFIG_PM is not set +CONFIG_NOT_COHERENT_CACHE=y + +# +# Platform options +# +# CONFIG_RPXLITE is not set +# CONFIG_RPXCLASSIC is not set +# CONFIG_BSEIP is not set +# CONFIG_FADS is not set +CONFIG_MPC885ADS=y +# CONFIG_TQM823L is not set +# CONFIG_TQM850L is not set +# CONFIG_TQM855L is not set +# CONFIG_TQM860L is not set +# CONFIG_FPS850L is not set +# CONFIG_SPD823TS is not set +# CONFIG_IVMS8 is not set +# CONFIG_IVML24 is not set +# CONFIG_SM850 is not set +# CONFIG_HERMES_PRO is not set +# CONFIG_IP860 is not set +# CONFIG_LWMON is not set +# CONFIG_PCU_E is not set +# CONFIG_CCM is not set +# CONFIG_LANTEC is not set +# CONFIG_MBX is not set +# CONFIG_WINCEPT is not set +# CONFIG_SMP is not set +# CONFIG_PREEMPT is not set +# CONFIG_HIGHMEM is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_CMDLINE_BOOL is not set +CONFIG_ISA_DMA_API=y + +# +# Bus options +# +# CONFIG_PCI is not set +# CONFIG_PCI_DOMAINS is not set +# CONFIG_PCI_QSPAN is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Advanced setup +# +# CONFIG_ADVANCED_OPTIONS is not set + +# +# Default settings for advanced configuration options are used +# +CONFIG_HIGHMEM_START=0xfe000000 +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_KERNEL_START=0xc0000000 +CONFIG_TASK_SIZE=0x80000000 +CONFIG_CONSISTENT_START=0xff100000 +CONFIG_CONSISTENT_SIZE=0x00200000 +CONFIG_BOOT_LOAD=0x00400000 + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_LBD is not set +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# + +# +# Macintosh device drivers +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_OAKNET is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +CONFIG_PPP=y +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=y +CONFIG_PPP_SYNC_TTY=y +CONFIG_PPP_DEFLATE=y +# CONFIG_PPP_BSDCOMP is not set +# CONFIG_PPPOE is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_CPM=y +CONFIG_SERIAL_CPM_CONSOLE=y +# CONFIG_SERIAL_CPM_SCC1 is not set +# CONFIG_SERIAL_CPM_SCC2 is not set +# CONFIG_SERIAL_CPM_SCC3 is not set +# CONFIG_SERIAL_CPM_SCC4 is not set +CONFIG_SERIAL_CPM_SMC1=y +CONFIG_SERIAL_CPM_SMC2=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB_ARCH_HAS_HCD is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +# CONFIG_EXT2_FS_SECURITY is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_DNOTIFY is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_PROC_KCORE is not set +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# MPC8xx CPM Options +# +CONFIG_SCC_ENET=y +# CONFIG_SCC1_ENET is not set +# CONFIG_SCC2_ENET is not set +CONFIG_SCC3_ENET=y +# CONFIG_FEC_ENET is not set +# CONFIG_ENET_BIG_BUFFERS is not set + +# +# Generic MPC8xx Options +# +CONFIG_8xx_COPYBACK=y +CONFIG_8xx_CPU6=y +CONFIG_NO_UCODE_PATCH=y +# CONFIG_USB_SOF_UCODE_PATCH is not set +# CONFIG_I2C_SPI_UCODE_PATCH is not set +# CONFIG_I2C_SPI_SMC1_UCODE_PATCH is not set + +# +# Library routines +# +CONFIG_CRC_CCITT=y +# CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# diff --git a/arch/ppc/kernel/machine_kexec.c b/arch/ppc/kernel/machine_kexec.c index 84d65a87191e..a72787747df7 100644 --- a/arch/ppc/kernel/machine_kexec.c +++ b/arch/ppc/kernel/machine_kexec.c @@ -28,6 +28,12 @@ typedef NORET_TYPE void (*relocate_new_kernel_t)( const extern unsigned char relocate_new_kernel[]; const extern unsigned int relocate_new_kernel_size; +/* + * Provide a dummy crash_notes definition while crash dump arrives to ppc. + * This prevents breakage of crash_notes attribute in kernel/ksysfs.c. + */ +void *crash_notes = NULL; + void machine_shutdown(void) { if (ppc_md.machine_shutdown) diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index b6a63a49a232..191a8def3bdb 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S @@ -1449,3 +1449,5 @@ _GLOBAL(sys_call_table) .long sys_request_key /* 270 */ .long sys_keyctl .long sys_waitid + .long sys_ioprio_set + .long sys_ioprio_get diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c index 6d7b92d72458..70cfb6ffd877 100644 --- a/arch/ppc/kernel/pci.c +++ b/arch/ppc/kernel/pci.c @@ -1495,7 +1495,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, *offset += hose->pci_mem_offset; res_bit = IORESOURCE_MEM; } else { - io_offset = (unsigned long)hose->io_base_virt; + io_offset = hose->io_base_virt - ___IO_BASE; *offset += io_offset; res_bit = IORESOURCE_IO; } @@ -1522,7 +1522,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, /* found it! construct the final physical address */ if (mmap_state == pci_mmap_io) - *offset += hose->io_base_phys - _IO_BASE; + *offset += hose->io_base_phys - io_offset; return rp; } @@ -1739,6 +1739,23 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn) return result; } +void pci_resource_to_user(const struct pci_dev *dev, int bar, + const struct resource *rsrc, + u64 *start, u64 *end) +{ + struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); + unsigned long offset = 0; + + if (hose == NULL) + return; + + if (rsrc->flags & IORESOURCE_IO) + offset = ___IO_BASE - hose->io_base_virt + hose->io_base_phys; + + *start = rsrc->start + offset; + *end = rsrc->end + offset; +} + void __init pci_init_resource(struct resource *res, unsigned long start, unsigned long end, int flags, char *name) diff --git a/arch/ppc/kernel/relocate_kernel.S b/arch/ppc/kernel/relocate_kernel.S index 7ff69c4af920..9b2ad48e988c 100644 --- a/arch/ppc/kernel/relocate_kernel.S +++ b/arch/ppc/kernel/relocate_kernel.S @@ -34,9 +34,9 @@ relocate_new_kernel: mr r8, r0 ori r8, r8, MSR_RI|MSR_ME - mtspr SRR1, r8 + mtspr SPRN_SRR1, r8 addi r8, r4, 1f - relocate_new_kernel - mtspr SRR0, r8 + mtspr SPRN_SRR0, r8 sync rfi diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c index 735866559199..bf4ddca5e853 100644 --- a/arch/ppc/kernel/time.c +++ b/arch/ppc/kernel/time.c @@ -89,6 +89,9 @@ unsigned long tb_to_ns_scale; extern unsigned long wall_jiffies; +/* used for timezone offset */ +static long timezone_offset; + DEFINE_SPINLOCK(rtc_lock); EXPORT_SYMBOL(rtc_lock); @@ -170,7 +173,7 @@ void timer_interrupt(struct pt_regs * regs) xtime.tv_sec - last_rtc_update >= 659 && abs((xtime.tv_nsec / 1000) - (1000000-1000000/HZ)) < 500000/HZ && jiffies - wall_jiffies == 1) { - if (ppc_md.set_rtc_time(xtime.tv_sec+1 + time_offset) == 0) + if (ppc_md.set_rtc_time(xtime.tv_sec+1 + timezone_offset) == 0) last_rtc_update = xtime.tv_sec+1; else /* Try again one minute later */ @@ -286,7 +289,7 @@ void __init time_init(void) unsigned old_stamp, stamp, elapsed; if (ppc_md.time_init != NULL) - time_offset = ppc_md.time_init(); + timezone_offset = ppc_md.time_init(); if (__USE_RTC()) { /* 601 processor: dec counts down by 128 every 128ns */ @@ -331,10 +334,10 @@ void __init time_init(void) set_dec(tb_ticks_per_jiffy); /* If platform provided a timezone (pmac), we correct the time */ - if (time_offset) { - sys_tz.tz_minuteswest = -time_offset / 60; + if (timezone_offset) { + sys_tz.tz_minuteswest = -timezone_offset / 60; sys_tz.tz_dsttime = 0; - xtime.tv_sec -= time_offset; + xtime.tv_sec -= timezone_offset; } set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c index 334ef4150d92..6164a2b34733 100644 --- a/arch/ppc/mm/init.c +++ b/arch/ppc/mm/init.c @@ -606,9 +606,19 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, struct page *page = pfn_to_page(pfn); if (!PageReserved(page) && !test_bit(PG_arch_1, &page->flags)) { - if (vma->vm_mm == current->active_mm) + if (vma->vm_mm == current->active_mm) { +#ifdef CONFIG_8xx + /* On 8xx, cache control instructions (particularly + * "dcbst" from flush_dcache_icache) fault as write + * operation if there is an unpopulated TLB entry + * for the address in question. To workaround that, + * we invalidate the TLB here, thus avoiding dcbst + * misbehaviour. + */ + _tlbie(address); +#endif __flush_dcache_icache((void *) address); - else + } else flush_dcache_icache_page(page); set_bit(PG_arch_1, &page->flags); } diff --git a/arch/ppc/platforms/85xx/mpc8540_ads.c b/arch/ppc/platforms/85xx/mpc8540_ads.c index ddd2e9a5bb12..f761fdf160db 100644 --- a/arch/ppc/platforms/85xx/mpc8540_ads.c +++ b/arch/ppc/platforms/85xx/mpc8540_ads.c @@ -111,8 +111,8 @@ mpc8540ads_setup_arch(void) memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); } + pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_FEC); if (pdata) { - pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_FEC); pdata->board_flags = 0; pdata->interruptPHY = MPC85xx_IRQ_EXT5; pdata->phyid = 3; diff --git a/arch/ppc/platforms/fads.h b/arch/ppc/platforms/fads.h index 632b8178ce66..b60c56450b67 100644 --- a/arch/ppc/platforms/fads.h +++ b/arch/ppc/platforms/fads.h @@ -3,7 +3,18 @@ * the Motorola 860T FADS board. Copied from the MBX stuff. * * Copyright (c) 1998 Dan Malek (dmalek@jlc.net) + * + * Added MPC86XADS support. + * The MPC86xADS manual says the board "is compatible with the MPC8xxFADS + * for SW point of view". This is 99% correct. + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * 2005 (c) MontaVista Software, Inc. This file is licensed under the + * terms of the GNU General Public License version 2. This program is licensed + * "as is" without any warranty of any kind, whether express or implied. */ + #ifdef __KERNEL__ #ifndef __ASM_FADS_H__ #define __ASM_FADS_H__ @@ -12,18 +23,45 @@ #include <asm/ppcboot.h> +#if defined(CONFIG_MPC86XADS) + +/* U-Boot maps BCSR to 0xff080000 */ +#define BCSR_ADDR ((uint)0xff080000) + +/* MPC86XADS has one more CPLD and an additional BCSR. + */ +#define CFG_PHYDEV_ADDR ((uint)0xff0a0000) +#define BCSR5 ((uint)(CFG_PHYDEV_ADDR + 0x300)) + +#define BCSR5_T1_RST 0x10 +#define BCSR5_ATM155_RST 0x08 +#define BCSR5_ATM25_RST 0x04 +#define BCSR5_MII1_EN 0x02 +#define BCSR5_MII1_RST 0x01 + +/* There is no PHY link change interrupt */ +#define PHY_INTERRUPT (-1) + +#else /* FADS */ + /* Memory map is configured by the PROM startup. * I tried to follow the FADS manual, although the startup PROM * dictates this and we simply have to move some of the physical * addresses for Linux. */ #define BCSR_ADDR ((uint)0xff010000) + +/* PHY link change interrupt */ +#define PHY_INTERRUPT SIU_IRQ2 + +#endif /* CONFIG_MPC86XADS */ + #define BCSR_SIZE ((uint)(64 * 1024)) -#define BCSR0 ((uint)0xff010000) -#define BCSR1 ((uint)0xff010004) -#define BCSR2 ((uint)0xff010008) -#define BCSR3 ((uint)0xff01000c) -#define BCSR4 ((uint)0xff010010) +#define BCSR0 ((uint)(BCSR_ADDR + 0x00)) +#define BCSR1 ((uint)(BCSR_ADDR + 0x04)) +#define BCSR2 ((uint)(BCSR_ADDR + 0x08)) +#define BCSR3 ((uint)(BCSR_ADDR + 0x0c)) +#define BCSR4 ((uint)(BCSR_ADDR + 0x10)) #define IMAP_ADDR ((uint)0xff000000) #define IMAP_SIZE ((uint)(64 * 1024)) @@ -34,8 +72,17 @@ /* Bits of interest in the BCSRs. */ #define BCSR1_ETHEN ((uint)0x20000000) +#define BCSR1_IRDAEN ((uint)0x10000000) #define BCSR1_RS232EN_1 ((uint)0x01000000) +#define BCSR1_PCCEN ((uint)0x00800000) +#define BCSR1_PCCVCC0 ((uint)0x00400000) +#define BCSR1_PCCVPP0 ((uint)0x00200000) +#define BCSR1_PCCVPP1 ((uint)0x00100000) +#define BCSR1_PCCVPP_MASK (BCSR1_PCCVPP0 | BCSR1_PCCVPP1) #define BCSR1_RS232EN_2 ((uint)0x00040000) +#define BCSR1_PCCVCC1 ((uint)0x00010000) +#define BCSR1_PCCVCC_MASK (BCSR1_PCCVCC0 | BCSR1_PCCVCC1) + #define BCSR4_ETHLOOP ((uint)0x80000000) /* EEST Loopback */ #define BCSR4_EEFDX ((uint)0x40000000) /* EEST FDX enable */ #define BCSR4_FETH_EN ((uint)0x08000000) /* PHY enable */ @@ -44,14 +91,64 @@ #define BCSR4_FETHFDE ((uint)0x02000000) /* PHY FDX advertise */ #define BCSR4_FETHRST ((uint)0x00200000) /* PHY Reset */ +/* IO_BASE definition for pcmcia. + */ +#define _IO_BASE 0x80000000 +#define _IO_BASE_SIZE 0x1000 + +#ifdef CONFIG_IDE +#define MAX_HWIFS 1 +#endif + /* Interrupt level assignments. */ #define FEC_INTERRUPT SIU_LEVEL1 /* FEC interrupt */ -#define PHY_INTERRUPT SIU_IRQ2 /* PHY link change interrupt */ /* We don't use the 8259. */ #define NR_8259_INTS 0 +/* CPM Ethernet through SCC1 or SCC2 */ + +#ifdef CONFIG_SCC1_ENET /* Probably 860 variant */ +/* Bits in parallel I/O port registers that have to be set/cleared + * to configure the pins for SCC1 use. + * TCLK - CLK1, RCLK - CLK2. + */ +#define PA_ENET_RXD ((ushort)0x0001) +#define PA_ENET_TXD ((ushort)0x0002) +#define PA_ENET_TCLK ((ushort)0x0100) +#define PA_ENET_RCLK ((ushort)0x0200) +#define PB_ENET_TENA ((uint)0x00001000) +#define PC_ENET_CLSN ((ushort)0x0010) +#define PC_ENET_RENA ((ushort)0x0020) + +/* Control bits in the SICR to route TCLK (CLK1) and RCLK (CLK2) to + * SCC1. Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero. + */ +#define SICR_ENET_MASK ((uint)0x000000ff) +#define SICR_ENET_CLKRT ((uint)0x0000002c) +#endif /* CONFIG_SCC1_ENET */ + +#ifdef CONFIG_SCC2_ENET /* Probably 823/850 variant */ +/* Bits in parallel I/O port registers that have to be set/cleared + * to configure the pins for SCC1 use. + * TCLK - CLK1, RCLK - CLK2. + */ +#define PA_ENET_RXD ((ushort)0x0004) +#define PA_ENET_TXD ((ushort)0x0008) +#define PA_ENET_TCLK ((ushort)0x0400) +#define PA_ENET_RCLK ((ushort)0x0200) +#define PB_ENET_TENA ((uint)0x00002000) +#define PC_ENET_CLSN ((ushort)0x0040) +#define PC_ENET_RENA ((ushort)0x0080) + +/* Control bits in the SICR to route TCLK and RCLK to + * SCC2. Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero. + */ +#define SICR_ENET_MASK ((uint)0x0000ff00) +#define SICR_ENET_CLKRT ((uint)0x00002e00) +#endif /* CONFIG_SCC2_ENET */ + #endif /* __ASM_FADS_H__ */ #endif /* __KERNEL__ */ diff --git a/arch/ppc/platforms/mpc885ads.h b/arch/ppc/platforms/mpc885ads.h new file mode 100644 index 000000000000..eb386635b0fd --- /dev/null +++ b/arch/ppc/platforms/mpc885ads.h @@ -0,0 +1,92 @@ +/* + * A collection of structures, addresses, and values associated with + * the Freescale MPC885ADS board. + * Copied from the FADS stuff. + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * 2005 (c) MontaVista Software, Inc. This file is licensed under the + * terms of the GNU General Public License version 2. This program is licensed + * "as is" without any warranty of any kind, whether express or implied. + */ + +#ifdef __KERNEL__ +#ifndef __ASM_MPC885ADS_H__ +#define __ASM_MPC885ADS_H__ + +#include <linux/config.h> + +#include <asm/ppcboot.h> + +/* U-Boot maps BCSR to 0xff080000 */ +#define BCSR_ADDR ((uint)0xff080000) +#define BCSR_SIZE ((uint)32) +#define BCSR0 ((uint)(BCSR_ADDR + 0x00)) +#define BCSR1 ((uint)(BCSR_ADDR + 0x04)) +#define BCSR2 ((uint)(BCSR_ADDR + 0x08)) +#define BCSR3 ((uint)(BCSR_ADDR + 0x0c)) +#define BCSR4 ((uint)(BCSR_ADDR + 0x10)) + +#define CFG_PHYDEV_ADDR ((uint)0xff0a0000) +#define BCSR5 ((uint)(CFG_PHYDEV_ADDR + 0x300)) + +#define IMAP_ADDR ((uint)0xff000000) +#define IMAP_SIZE ((uint)(64 * 1024)) + +#define PCMCIA_MEM_ADDR ((uint)0xff020000) +#define PCMCIA_MEM_SIZE ((uint)(64 * 1024)) + +/* Bits of interest in the BCSRs. + */ +#define BCSR1_ETHEN ((uint)0x20000000) +#define BCSR1_IRDAEN ((uint)0x10000000) +#define BCSR1_RS232EN_1 ((uint)0x01000000) +#define BCSR1_PCCEN ((uint)0x00800000) +#define BCSR1_PCCVCC0 ((uint)0x00400000) +#define BCSR1_PCCVPP0 ((uint)0x00200000) +#define BCSR1_PCCVPP1 ((uint)0x00100000) +#define BCSR1_PCCVPP_MASK (BCSR1_PCCVPP0 | BCSR1_PCCVPP1) +#define BCSR1_RS232EN_2 ((uint)0x00040000) +#define BCSR1_PCCVCC1 ((uint)0x00010000) +#define BCSR1_PCCVCC_MASK (BCSR1_PCCVCC0 | BCSR1_PCCVCC1) + +#define BCSR4_ETH10_RST ((uint)0x80000000) /* 10Base-T PHY reset*/ +#define BCSR4_USB_LO_SPD ((uint)0x04000000) +#define BCSR4_USB_VCC ((uint)0x02000000) +#define BCSR4_USB_FULL_SPD ((uint)0x00040000) +#define BCSR4_USB_EN ((uint)0x00020000) + +#define BCSR5_MII2_EN 0x40 +#define BCSR5_MII2_RST 0x20 +#define BCSR5_T1_RST 0x10 +#define BCSR5_ATM155_RST 0x08 +#define BCSR5_ATM25_RST 0x04 +#define BCSR5_MII1_EN 0x02 +#define BCSR5_MII1_RST 0x01 + +/* Interrupt level assignments */ +#define PHY_INTERRUPT SIU_IRQ7 /* PHY link change interrupt */ +#define SIU_INT_FEC1 SIU_LEVEL1 /* FEC1 interrupt */ +#define SIU_INT_FEC2 SIU_LEVEL3 /* FEC2 interrupt */ +#define FEC_INTERRUPT SIU_INT_FEC1 /* FEC interrupt */ + +/* We don't use the 8259 */ +#define NR_8259_INTS 0 + +/* CPM Ethernet through SCC3 */ +#define PA_ENET_RXD ((ushort)0x0040) +#define PA_ENET_TXD ((ushort)0x0080) +#define PE_ENET_TCLK ((uint)0x00004000) +#define PE_ENET_RCLK ((uint)0x00008000) +#define PE_ENET_TENA ((uint)0x00000010) +#define PC_ENET_CLSN ((ushort)0x0400) +#define PC_ENET_RENA ((ushort)0x0800) + +/* Control bits in the SICR to route TCLK (CLK5) and RCLK (CLK6) to + * SCC3. Also, make sure GR3 (bit 8) and SC3 (bit 9) are zero */ +#define SICR_ENET_MASK ((uint)0x00ff0000) +#define SICR_ENET_CLKRT ((uint)0x002c0000) + +#endif /* __ASM_MPC885ADS_H__ */ +#endif /* __KERNEL__ */ diff --git a/arch/ppc/platforms/pmac_cpufreq.c b/arch/ppc/platforms/pmac_cpufreq.c index 5fdd4f607a40..c0605244edda 100644 --- a/arch/ppc/platforms/pmac_cpufreq.c +++ b/arch/ppc/platforms/pmac_cpufreq.c @@ -452,7 +452,7 @@ static u32 __pmac read_gpio(struct device_node *np) return offset; } -static int __pmac pmac_cpufreq_suspend(struct cpufreq_policy *policy, u32 state) +static int __pmac pmac_cpufreq_suspend(struct cpufreq_policy *policy, pm_message_t pmsg) { /* Ok, this could be made a bit smarter, but let's be robust for now. We * always force a speed change to high speed before sleep, to make sure diff --git a/arch/ppc/platforms/pmac_sleep.S b/arch/ppc/platforms/pmac_sleep.S index f459ade1bd63..016a74649155 100644 --- a/arch/ppc/platforms/pmac_sleep.S +++ b/arch/ppc/platforms/pmac_sleep.S @@ -46,7 +46,7 @@ .section .text .align 5 -#if defined(CONFIG_PMAC_PBOOK) || defined(CONFIG_CPU_FREQ_PMAC) +#if defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ_PMAC) /* This gets called by via-pmu.c late during the sleep process. * The PMU was already send the sleep command and will shut us down @@ -382,7 +382,7 @@ turn_on_mmu: isync rfi -#endif /* defined(CONFIG_PMAC_PBOOK) || defined(CONFIG_CPU_FREQ) */ +#endif /* defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ) */ .section .data .balign L1_CACHE_LINE_SIZE diff --git a/arch/ppc/platforms/pmac_time.c b/arch/ppc/platforms/pmac_time.c index de60ccc7db9f..778ce4fec368 100644 --- a/arch/ppc/platforms/pmac_time.c +++ b/arch/ppc/platforms/pmac_time.c @@ -206,7 +206,7 @@ via_calibrate_decr(void) return 1; } -#ifdef CONFIG_PMAC_PBOOK +#ifdef CONFIG_PM /* * Reset the time after a sleep. */ @@ -238,7 +238,7 @@ time_sleep_notify(struct pmu_sleep_notifier *self, int when) static struct pmu_sleep_notifier time_sleep_notifier __pmacdata = { time_sleep_notify, SLEEP_LEVEL_MISC, }; -#endif /* CONFIG_PMAC_PBOOK */ +#endif /* CONFIG_PM */ /* * Query the OF and get the decr frequency. @@ -251,9 +251,9 @@ pmac_calibrate_decr(void) struct device_node *cpu; unsigned int freq, *fp; -#ifdef CONFIG_PMAC_PBOOK +#ifdef CONFIG_PM pmu_register_sleep_notifier(&time_sleep_notifier); -#endif /* CONFIG_PMAC_PBOOK */ +#endif /* CONFIG_PM */ /* We assume MacRISC2 machines have correct device-tree * calibration. That's better since the VIA itself seems diff --git a/arch/ppc/platforms/sandpoint.c b/arch/ppc/platforms/sandpoint.c index 70e58f43f2b8..8b149c2fc54f 100644 --- a/arch/ppc/platforms/sandpoint.c +++ b/arch/ppc/platforms/sandpoint.c @@ -324,6 +324,7 @@ sandpoint_setup_arch(void) pdata[1].irq = 0; pdata[1].mapbase = 0; } + } printk(KERN_INFO "Motorola SPS Sandpoint Test Platform\n"); printk(KERN_INFO "Port by MontaVista Software, Inc. (source@mvista.com)\n"); diff --git a/arch/ppc/syslib/ipic.c b/arch/ppc/syslib/ipic.c index 580ed658e872..8f01e0f1d847 100644 --- a/arch/ppc/syslib/ipic.c +++ b/arch/ppc/syslib/ipic.c @@ -79,7 +79,7 @@ static struct ipic_info ipic_info[] = { .prio_mask = 7, }, [17] = { - .pend = IPIC_SIPNR_H, + .pend = IPIC_SEPNR, .mask = IPIC_SEMSR, .prio = IPIC_SMPRR_A, .force = IPIC_SEFCR, @@ -87,7 +87,7 @@ static struct ipic_info ipic_info[] = { .prio_mask = 5, }, [18] = { - .pend = IPIC_SIPNR_H, + .pend = IPIC_SEPNR, .mask = IPIC_SEMSR, .prio = IPIC_SMPRR_A, .force = IPIC_SEFCR, @@ -95,7 +95,7 @@ static struct ipic_info ipic_info[] = { .prio_mask = 6, }, [19] = { - .pend = IPIC_SIPNR_H, + .pend = IPIC_SEPNR, .mask = IPIC_SEMSR, .prio = IPIC_SMPRR_A, .force = IPIC_SEFCR, @@ -103,7 +103,7 @@ static struct ipic_info ipic_info[] = { .prio_mask = 7, }, [20] = { - .pend = IPIC_SIPNR_H, + .pend = IPIC_SEPNR, .mask = IPIC_SEMSR, .prio = IPIC_SMPRR_B, .force = IPIC_SEFCR, @@ -111,7 +111,7 @@ static struct ipic_info ipic_info[] = { .prio_mask = 4, }, [21] = { - .pend = IPIC_SIPNR_H, + .pend = IPIC_SEPNR, .mask = IPIC_SEMSR, .prio = IPIC_SMPRR_B, .force = IPIC_SEFCR, @@ -119,7 +119,7 @@ static struct ipic_info ipic_info[] = { .prio_mask = 5, }, [22] = { - .pend = IPIC_SIPNR_H, + .pend = IPIC_SEPNR, .mask = IPIC_SEMSR, .prio = IPIC_SMPRR_B, .force = IPIC_SEFCR, @@ -127,7 +127,7 @@ static struct ipic_info ipic_info[] = { .prio_mask = 6, }, [23] = { - .pend = IPIC_SIPNR_H, + .pend = IPIC_SEPNR, .mask = IPIC_SEMSR, .prio = IPIC_SMPRR_B, .force = IPIC_SEFCR, diff --git a/arch/ppc/syslib/of_device.c b/arch/ppc/syslib/of_device.c index 49c0e34e2d6b..1eb4f726ca9f 100644 --- a/arch/ppc/syslib/of_device.c +++ b/arch/ppc/syslib/of_device.c @@ -3,6 +3,7 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <asm/errno.h> #include <asm/of_device.h> @@ -15,20 +16,20 @@ * Used by a driver to check whether an of_device present in the * system is in its list of supported devices. */ -const struct of_match * of_match_device(const struct of_match *matches, +const struct of_device_id * of_match_device(const struct of_device_id *matches, const struct of_device *dev) { if (!dev->node) return NULL; - while (matches->name || matches->type || matches->compatible) { + while (matches->name[0] || matches->type[0] || matches->compatible[0]) { int match = 1; - if (matches->name && matches->name != OF_ANY_MATCH) + if (matches->name[0]) match &= dev->node->name && !strcmp(matches->name, dev->node->name); - if (matches->type && matches->type != OF_ANY_MATCH) + if (matches->type[0]) match &= dev->node->type && !strcmp(matches->type, dev->node->type); - if (matches->compatible && matches->compatible != OF_ANY_MATCH) + if (matches->compatible[0]) match &= device_is_compatible(dev->node, matches->compatible); if (match) @@ -42,7 +43,7 @@ static int of_platform_bus_match(struct device *dev, struct device_driver *drv) { struct of_device * of_dev = to_of_device(dev); struct of_platform_driver * of_drv = to_of_platform_driver(drv); - const struct of_match * matches = of_drv->match_table; + const struct of_device_id * matches = of_drv->match_table; if (!matches) return 0; @@ -75,7 +76,7 @@ static int of_device_probe(struct device *dev) int error = -ENODEV; struct of_platform_driver *drv; struct of_device *of_dev; - const struct of_match *match; + const struct of_device_id *match; drv = to_of_platform_driver(dev->driver); of_dev = to_of_device(dev); diff --git a/arch/ppc/syslib/open_pic.c b/arch/ppc/syslib/open_pic.c index b45d8268bf93..ad39b86ca92c 100644 --- a/arch/ppc/syslib/open_pic.c +++ b/arch/ppc/syslib/open_pic.c @@ -370,8 +370,9 @@ void __init openpic_init(int offset) /* Initialize IPI interrupts */ if ( ppc_md.progress ) ppc_md.progress("openpic: ipi",0x3bb); for (i = 0; i < OPENPIC_NUM_IPI; i++) { - /* Disabled, Priority 10..13 */ - openpic_initipi(i, 10+i, OPENPIC_VEC_IPI+i+offset); + /* Disabled, increased priorities 10..13 */ + openpic_initipi(i, OPENPIC_PRIORITY_IPI_BASE+i, + OPENPIC_VEC_IPI+i+offset); /* IPIs are per-CPU */ irq_desc[OPENPIC_VEC_IPI+i+offset].status |= IRQ_PER_CPU; irq_desc[OPENPIC_VEC_IPI+i+offset].handler = &open_pic_ipi; @@ -399,8 +400,9 @@ void __init openpic_init(int offset) if (sense & IRQ_SENSE_MASK) irq_desc[i+offset].status = IRQ_LEVEL; - /* Enabled, Priority 8 */ - openpic_initirq(i, 8, i+offset, (sense & IRQ_POLARITY_MASK), + /* Enabled, Default priority */ + openpic_initirq(i, OPENPIC_PRIORITY_DEFAULT, i+offset, + (sense & IRQ_POLARITY_MASK), (sense & IRQ_SENSE_MASK)); /* Processor 0 */ openpic_mapirq(i, CPU_MASK_CPU0, CPU_MASK_NONE); @@ -656,6 +658,18 @@ static void __init openpic_maptimer(u_int timer, cpumask_t cpumask) } /* + * Change the priority of an interrupt + */ +void __init +openpic_set_irq_priority(u_int irq, u_int pri) +{ + check_arg_irq(irq); + openpic_safe_writefield(&ISR[irq - open_pic_irq_offset]->Vector_Priority, + OPENPIC_PRIORITY_MASK, + pri << OPENPIC_PRIORITY_SHIFT); +} + +/* * Initalize the interrupt source which will generate an NMI. * This raises the interrupt's priority from 8 to 9. * @@ -665,9 +679,7 @@ void __init openpic_init_nmi_irq(u_int irq) { check_arg_irq(irq); - openpic_safe_writefield(&ISR[irq - open_pic_irq_offset]->Vector_Priority, - OPENPIC_PRIORITY_MASK, - 9 << OPENPIC_PRIORITY_SHIFT); + openpic_set_irq_priority(irq, OPENPIC_PRIORITY_NMI); } /* diff --git a/arch/ppc/syslib/ppc4xx_pic.c b/arch/ppc/syslib/ppc4xx_pic.c index 05686fa73545..40086212b9c3 100644 --- a/arch/ppc/syslib/ppc4xx_pic.c +++ b/arch/ppc/syslib/ppc4xx_pic.c @@ -110,6 +110,10 @@ static int ppc4xx_pic_get_irq(struct pt_regs *regs) static void __init ppc4xx_pic_impl_init(void) { +#if defined(CONFIG_440GX) + /* Disable 440GP compatibility mode if it was enabled in firmware */ + SDR_WRITE(DCRN_SDR_MFR, SDR_READ(DCRN_SDR_MFR) & ~DCRN_SDR_MFR_PCM); +#endif /* Configure Base UIC */ mtdcr(DCRN_UIC_CR(UICB), 0); mtdcr(DCRN_UIC_TR(UICB), 0); diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig index f804f25232ac..fdd8afba7152 100644 --- a/arch/ppc64/Kconfig +++ b/arch/ppc64/Kconfig @@ -429,6 +429,8 @@ config CMDLINE endmenu +source "net/Kconfig" + source "drivers/Kconfig" source "fs/Kconfig" diff --git a/arch/ppc64/boot/Makefile b/arch/ppc64/boot/Makefile index d3e1d6af9203..683b2d43c15f 100644 --- a/arch/ppc64/boot/Makefile +++ b/arch/ppc64/boot/Makefile @@ -52,7 +52,7 @@ obj-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.o, $(section))) src-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.c, $(section))) gz-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section))) -hostprogs-y := piggy addnote addRamDisk +hostprogs-y := addnote addRamDisk targets += zImage zImage.initrd imagesize.c \ $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \ $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \ @@ -78,9 +78,6 @@ addsection = $(CROSS32OBJCOPY) $(1) \ quiet_cmd_addnote = ADDNOTE $@ cmd_addnote = $(CROSS32LD) $(BOOTLFLAGS) -o $@ $(obj-boot) && $(obj)/addnote $@ -quiet_cmd_piggy = PIGGY $@ - cmd_piggy = $(obj)/piggyback $(@:.o=) < $< | $(CROSS32AS) -o $@ - $(call gz-sec, $(required)): $(obj)/kernel-%.gz: % FORCE $(call if_changed,gzip) diff --git a/arch/ppc64/boot/main.c b/arch/ppc64/boot/main.c index da12ea2ca464..199d9804f61c 100644 --- a/arch/ppc64/boot/main.c +++ b/arch/ppc64/boot/main.c @@ -17,7 +17,6 @@ extern void *finddevice(const char *); extern int getprop(void *, const char *, void *, int); -extern void printk(char *fmt, ...); extern void printf(const char *fmt, ...); extern int sprintf(char *buf, const char *fmt, ...); void gunzip(void *, int, unsigned char *, int *); @@ -147,10 +146,10 @@ void start(unsigned long a1, unsigned long a2, void *promptr) } a1 = initrd.addr; a2 = initrd.size; - printf("initial ramdisk moving 0x%lx <- 0x%lx (%lx bytes)\n\r", + printf("initial ramdisk moving 0x%lx <- 0x%lx (0x%lx bytes)\n\r", initrd.addr, (unsigned long)_initrd_start, initrd.size); memmove((void *)initrd.addr, (void *)_initrd_start, initrd.size); - printf("initrd head: 0x%lx\n\r", *((u32 *)initrd.addr)); + printf("initrd head: 0x%lx\n\r", *((unsigned long *)initrd.addr)); } /* Eventually gunzip the kernel */ @@ -201,9 +200,6 @@ void start(unsigned long a1, unsigned long a2, void *promptr) flush_cache((void *)vmlinux.addr, vmlinux.size); - if (a1) - printf("initrd head: 0x%lx\n\r", *((u32 *)initrd.addr)); - kernel_entry = (kernel_entry_t)vmlinux.addr; #ifdef DEBUG printf( "kernel:\n\r" diff --git a/arch/ppc64/boot/mknote.c b/arch/ppc64/boot/mknote.c deleted file mode 100644 index 120cc1d89739..000000000000 --- a/arch/ppc64/boot/mknote.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) Cort Dougan 1999. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Generate a note section as per the CHRP specification. - * - */ - -#include <stdio.h> - -#define PL(x) printf("%c%c%c%c", ((x)>>24)&0xff, ((x)>>16)&0xff, ((x)>>8)&0xff, (x)&0xff ); - -int main(void) -{ -/* header */ - /* namesz */ - PL(strlen("PowerPC")+1); - /* descrsz */ - PL(6*4); - /* type */ - PL(0x1275); - /* name */ - printf("PowerPC"); printf("%c", 0); - -/* descriptor */ - /* real-mode */ - PL(0xffffffff); - /* real-base */ - PL(0x00c00000); - /* real-size */ - PL(0xffffffff); - /* virt-base */ - PL(0xffffffff); - /* virt-size */ - PL(0xffffffff); - /* load-base */ - PL(0x4000); - return 0; -} diff --git a/arch/ppc64/boot/piggyback.c b/arch/ppc64/boot/piggyback.c deleted file mode 100644 index 235c7a87269c..000000000000 --- a/arch/ppc64/boot/piggyback.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2001 IBM Corp - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#include <stdio.h> -#include <unistd.h> -#include <string.h> - -extern long ce_exec_config[]; - -int main(int argc, char *argv[]) -{ - int i, cnt, pos, len; - unsigned int cksum, val; - unsigned char *lp; - unsigned char buf[8192]; - char *varname; - if (argc != 2) - { - fprintf(stderr, "usage: %s name <in-file >out-file\n", - argv[0]); - exit(1); - } - - varname = strrchr(argv[1], '/'); - if (varname) - varname++; - else - varname = argv[1]; - - fprintf(stdout, "#\n"); - fprintf(stdout, "# Miscellaneous data structures:\n"); - fprintf(stdout, "# WARNING - this file is automatically generated!\n"); - fprintf(stdout, "#\n"); - fprintf(stdout, "\n"); - fprintf(stdout, "\t.data\n"); - fprintf(stdout, "\t.globl %s_data\n", varname); - fprintf(stdout, "%s_data:\n", varname); - pos = 0; - cksum = 0; - while ((len = read(0, buf, sizeof(buf))) > 0) - { - cnt = 0; - lp = (unsigned char *)buf; - len = (len + 3) & ~3; /* Round up to longwords */ - for (i = 0; i < len; i += 4) - { - if (cnt == 0) - { - fprintf(stdout, "\t.long\t"); - } - fprintf(stdout, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]); - val = *(unsigned long *)lp; - cksum ^= val; - lp += 4; - if (++cnt == 4) - { - cnt = 0; - fprintf(stdout, " # %x \n", pos+i-12); - fflush(stdout); - } else - { - fprintf(stdout, ","); - } - } - if (cnt) - { - fprintf(stdout, "0\n"); - } - pos += len; - } - fprintf(stdout, "\t.globl %s_len\n", varname); - fprintf(stdout, "%s_len:\t.long\t0x%x\n", varname, pos); - fflush(stdout); - fclose(stdout); - fprintf(stderr, "cksum = %x\n", cksum); - exit(0); -} - diff --git a/arch/ppc64/boot/prom.c b/arch/ppc64/boot/prom.c index d5218b15824e..5e48b80ff5a0 100644 --- a/arch/ppc64/boot/prom.c +++ b/arch/ppc64/boot/prom.c @@ -40,7 +40,7 @@ void *finddevice(const char *name); int getprop(void *phandle, const char *name, void *buf, int buflen); void chrpboot(int a1, int a2, void *prom); /* in main.c */ -void printk(char *fmt, ...); +int printf(char *fmt, ...); /* there is no convenient header to get this from... -- paulus */ extern unsigned long strlen(const char *); @@ -220,7 +220,7 @@ readchar(void) case 1: return ch; case -1: - printk("read(stdin) returned -1\r\n"); + printf("read(stdin) returned -1\r\n"); return -1; } } @@ -627,18 +627,6 @@ int sprintf(char * buf, const char *fmt, ...) static char sprint_buf[1024]; -void -printk(char *fmt, ...) -{ - va_list args; - int n; - - va_start(args, fmt); - n = vsprintf(sprint_buf, fmt, args); - va_end(args); - write(stdout, sprint_buf, n); -} - int printf(char *fmt, ...) { diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index cdea00d7707f..4231861288a3 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -1,7 +1,7 @@ /* * ItLpQueue.c * Copyright (C) 2001 Mike Corrigan IBM Corporation - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -11,156 +11,252 @@ #include <linux/stddef.h> #include <linux/kernel.h> #include <linux/sched.h> +#include <linux/bootmem.h> +#include <linux/seq_file.h> +#include <linux/proc_fs.h> #include <asm/system.h> #include <asm/paca.h> #include <asm/iSeries/ItLpQueue.h> #include <asm/iSeries/HvLpEvent.h> #include <asm/iSeries/HvCallEvent.h> -static __inline__ int set_inUse( struct ItLpQueue * lpQueue ) -{ - int t; - u32 * inUseP = &(lpQueue->xInUseWord); - - __asm__ __volatile__("\n\ -1: lwarx %0,0,%2 \n\ - cmpwi 0,%0,0 \n\ - li %0,0 \n\ - bne- 2f \n\ - addi %0,%0,1 \n\ - stwcx. %0,0,%2 \n\ - bne- 1b \n\ -2: eieio" - : "=&r" (t), "=m" (lpQueue->xInUseWord) - : "r" (inUseP), "m" (lpQueue->xInUseWord) - : "cc"); - - return t; -} +/* + * The LpQueue is used to pass event data from the hypervisor to + * the partition. This is where I/O interrupt events are communicated. + * + * It is written to by the hypervisor so cannot end up in the BSS. + */ +struct hvlpevent_queue hvlpevent_queue __attribute__((__section__(".data"))); -static __inline__ void clear_inUse( struct ItLpQueue * lpQueue ) -{ - lpQueue->xInUseWord = 0; -} +DEFINE_PER_CPU(unsigned long[HvLpEvent_Type_NumTypes], hvlpevent_counts); + +static char *event_types[HvLpEvent_Type_NumTypes] = { + "Hypervisor", + "Machine Facilities", + "Session Manager", + "SPD I/O", + "Virtual Bus", + "PCI I/O", + "RIO I/O", + "Virtual Lan", + "Virtual I/O" +}; /* Array of LpEvent handler functions */ extern LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes]; -unsigned long ItLpQueueInProcess = 0; -struct HvLpEvent * ItLpQueue_getNextLpEvent( struct ItLpQueue * lpQueue ) +static struct HvLpEvent * get_next_hvlpevent(void) { - struct HvLpEvent * nextLpEvent = - (struct HvLpEvent *)lpQueue->xSlicCurEventPtr; - if ( nextLpEvent->xFlags.xValid ) { + struct HvLpEvent * event; + event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr; + + if (event->xFlags.xValid) { /* rmb() needed only for weakly consistent machines (regatta) */ rmb(); /* Set pointer to next potential event */ - lpQueue->xSlicCurEventPtr += ((nextLpEvent->xSizeMinus1 + - LpEventAlign ) / - LpEventAlign ) * - LpEventAlign; + hvlpevent_queue.xSlicCurEventPtr += ((event->xSizeMinus1 + + LpEventAlign) / LpEventAlign) * LpEventAlign; + /* Wrap to beginning if no room at end */ - if (lpQueue->xSlicCurEventPtr > lpQueue->xSlicLastValidEventPtr) - lpQueue->xSlicCurEventPtr = lpQueue->xSlicEventStackPtr; + if (hvlpevent_queue.xSlicCurEventPtr > + hvlpevent_queue.xSlicLastValidEventPtr) { + hvlpevent_queue.xSlicCurEventPtr = + hvlpevent_queue.xSlicEventStackPtr; + } + } else { + event = NULL; } - else - nextLpEvent = NULL; - return nextLpEvent; + return event; } -int ItLpQueue_isLpIntPending( struct ItLpQueue * lpQueue ) +static unsigned long spread_lpevents = NR_CPUS; + +int hvlpevent_is_pending(void) { - int retval = 0; - struct HvLpEvent * nextLpEvent; - if ( lpQueue ) { - nextLpEvent = (struct HvLpEvent *)lpQueue->xSlicCurEventPtr; - retval = nextLpEvent->xFlags.xValid | lpQueue->xPlicOverflowIntPending; - } - return retval; + struct HvLpEvent *next_event; + + if (smp_processor_id() >= spread_lpevents) + return 0; + + next_event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr; + + return next_event->xFlags.xValid | + hvlpevent_queue.xPlicOverflowIntPending; } -void ItLpQueue_clearValid( struct HvLpEvent * event ) +static void hvlpevent_clear_valid(struct HvLpEvent * event) { - /* Clear the valid bit of the event - * Also clear bits within this event that might - * look like valid bits (on 64-byte boundaries) - */ - unsigned extra = (( event->xSizeMinus1 + LpEventAlign ) / - LpEventAlign ) - 1; - switch ( extra ) { - case 3: - ((struct HvLpEvent*)((char*)event+3*LpEventAlign))->xFlags.xValid=0; - case 2: - ((struct HvLpEvent*)((char*)event+2*LpEventAlign))->xFlags.xValid=0; - case 1: - ((struct HvLpEvent*)((char*)event+1*LpEventAlign))->xFlags.xValid=0; - case 0: - ; + /* Tell the Hypervisor that we're done with this event. + * Also clear bits within this event that might look like valid bits. + * ie. on 64-byte boundaries. + */ + struct HvLpEvent *tmp; + unsigned extra = ((event->xSizeMinus1 + LpEventAlign) / + LpEventAlign) - 1; + + switch (extra) { + case 3: + tmp = (struct HvLpEvent*)((char*)event + 3 * LpEventAlign); + tmp->xFlags.xValid = 0; + case 2: + tmp = (struct HvLpEvent*)((char*)event + 2 * LpEventAlign); + tmp->xFlags.xValid = 0; + case 1: + tmp = (struct HvLpEvent*)((char*)event + 1 * LpEventAlign); + tmp->xFlags.xValid = 0; } + mb(); + event->xFlags.xValid = 0; } -unsigned ItLpQueue_process( struct ItLpQueue * lpQueue, struct pt_regs *regs ) +void process_hvlpevents(struct pt_regs *regs) { - unsigned numIntsProcessed = 0; - struct HvLpEvent * nextLpEvent; + struct HvLpEvent * event; /* If we have recursed, just return */ - if ( !set_inUse( lpQueue ) ) - return 0; - - if (ItLpQueueInProcess == 0) - ItLpQueueInProcess = 1; - else - BUG(); + if (!spin_trylock(&hvlpevent_queue.lock)) + return; for (;;) { - nextLpEvent = ItLpQueue_getNextLpEvent( lpQueue ); - if ( nextLpEvent ) { - /* Count events to return to caller - * and count processed events in lpQueue - */ - ++numIntsProcessed; - lpQueue->xLpIntCount++; - /* Call appropriate handler here, passing + event = get_next_hvlpevent(); + if (event) { + /* Call appropriate handler here, passing * a pointer to the LpEvent. The handler * must make a copy of the LpEvent if it * needs it in a bottom half. (perhaps for * an ACK) - * - * Handlers are responsible for ACK processing + * + * Handlers are responsible for ACK processing * * The Hypervisor guarantees that LpEvents will * only be delivered with types that we have * registered for, so no type check is necessary * here! - */ - if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes ) - lpQueue->xLpIntCountByType[nextLpEvent->xType]++; - if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes && - lpEventHandler[nextLpEvent->xType] ) - lpEventHandler[nextLpEvent->xType](nextLpEvent, regs); + */ + if (event->xType < HvLpEvent_Type_NumTypes) + __get_cpu_var(hvlpevent_counts)[event->xType]++; + if (event->xType < HvLpEvent_Type_NumTypes && + lpEventHandler[event->xType]) + lpEventHandler[event->xType](event, regs); else - printk(KERN_INFO "Unexpected Lp Event type=%d\n", nextLpEvent->xType ); - - ItLpQueue_clearValid( nextLpEvent ); - } else if ( lpQueue->xPlicOverflowIntPending ) + printk(KERN_INFO "Unexpected Lp Event type=%d\n", event->xType ); + + hvlpevent_clear_valid(event); + } else if (hvlpevent_queue.xPlicOverflowIntPending) /* * No more valid events. If overflow events are * pending process them */ - HvCallEvent_getOverflowLpEvents( lpQueue->xIndex); + HvCallEvent_getOverflowLpEvents(hvlpevent_queue.xIndex); else break; } - ItLpQueueInProcess = 0; - mb(); - clear_inUse( lpQueue ); + spin_unlock(&hvlpevent_queue.lock); +} + +static int set_spread_lpevents(char *str) +{ + unsigned long val = simple_strtoul(str, NULL, 0); + + /* + * The parameter is the number of processors to share in processing + * lp events. + */ + if (( val > 0) && (val <= NR_CPUS)) { + spread_lpevents = val; + printk("lpevent processing spread over %ld processors\n", val); + } else { + printk("invalid spread_lpevents %ld\n", val); + } - get_paca()->lpevent_count += numIntsProcessed; + return 1; +} +__setup("spread_lpevents=", set_spread_lpevents); + +void setup_hvlpevent_queue(void) +{ + void *eventStack; + + /* + * Allocate a page for the Event Stack. The Hypervisor needs the + * absolute real address, so we subtract out the KERNELBASE and add + * in the absolute real address of the kernel load area. + */ + eventStack = alloc_bootmem_pages(LpEventStackSize); + memset(eventStack, 0, LpEventStackSize); + + /* Invoke the hypervisor to initialize the event stack */ + HvCallEvent_setLpEventStack(0, eventStack, LpEventStackSize); + + hvlpevent_queue.xSlicEventStackPtr = (char *)eventStack; + hvlpevent_queue.xSlicCurEventPtr = (char *)eventStack; + hvlpevent_queue.xSlicLastValidEventPtr = (char *)eventStack + + (LpEventStackSize - LpEventMaxSize); + hvlpevent_queue.xIndex = 0; +} + +static int proc_lpevents_show(struct seq_file *m, void *v) +{ + int cpu, i; + unsigned long sum; + static unsigned long cpu_totals[NR_CPUS]; + + /* FIXME: do we care that there's no locking here? */ + sum = 0; + for_each_online_cpu(cpu) { + cpu_totals[cpu] = 0; + for (i = 0; i < HvLpEvent_Type_NumTypes; i++) { + cpu_totals[cpu] += per_cpu(hvlpevent_counts, cpu)[i]; + } + sum += cpu_totals[cpu]; + } + + seq_printf(m, "LpEventQueue 0\n"); + seq_printf(m, " events processed:\t%lu\n", sum); + + for (i = 0; i < HvLpEvent_Type_NumTypes; ++i) { + sum = 0; + for_each_online_cpu(cpu) { + sum += per_cpu(hvlpevent_counts, cpu)[i]; + } + + seq_printf(m, " %-20s %10lu\n", event_types[i], sum); + } + + seq_printf(m, "\n events processed by processor:\n"); + + for_each_online_cpu(cpu) { + seq_printf(m, " CPU%02d %10lu\n", cpu, cpu_totals[cpu]); + } + + return 0; +} + +static int proc_lpevents_open(struct inode *inode, struct file *file) +{ + return single_open(file, proc_lpevents_show, NULL); +} - return numIntsProcessed; +static struct file_operations proc_lpevents_operations = { + .open = proc_lpevents_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int __init proc_lpevents_init(void) +{ + struct proc_dir_entry *e; + + e = create_proc_entry("iSeries/lpevents", S_IFREG|S_IRUGO, NULL); + if (e) + e->proc_fops = &proc_lpevents_operations; + + return 0; } +__initcall(proc_lpevents_init); + diff --git a/arch/ppc64/kernel/LparData.c b/arch/ppc64/kernel/LparData.c index badc5a443614..6ffcf67dd507 100644 --- a/arch/ppc64/kernel/LparData.c +++ b/arch/ppc64/kernel/LparData.c @@ -28,13 +28,6 @@ #include <asm/iSeries/IoHriProcessorVpd.h> #include <asm/iSeries/ItSpCommArea.h> -/* The LpQueue is used to pass event data from the hypervisor to - * the partition. This is where I/O interrupt events are communicated. - */ - -/* May be filled in by the hypervisor so cannot end up in the BSS */ -struct ItLpQueue xItLpQueue __attribute__((__section__(".data"))); - /* The HvReleaseData is the root of the information shared between * the hypervisor and Linux. @@ -200,7 +193,7 @@ struct ItVpdAreas itVpdAreas = { 0,0,0, /* 13 - 15 */ sizeof(struct IoHriProcessorVpd),/* 16 length of Proc Vpd */ 0,0,0,0,0,0, /* 17 - 22 */ - sizeof(struct ItLpQueue),/* 23 length of Lp Queue */ + sizeof(struct hvlpevent_queue), /* 23 length of Lp Queue */ 0,0 /* 24 - 25 */ }, .xSlicVpdAdrs = { /* VPD addresses */ @@ -218,7 +211,7 @@ struct ItVpdAreas itVpdAreas = { 0,0,0, /* 13 - 15 */ &xIoHriProcessorVpd, /* 16 Proc Vpd */ 0,0,0,0,0,0, /* 17 - 22 */ - &xItLpQueue, /* 23 Lp Queue */ + &hvlpevent_queue, /* 23 Lp Queue */ 0,0 } }; diff --git a/arch/ppc64/kernel/cpu_setup_power4.S b/arch/ppc64/kernel/cpu_setup_power4.S index 42fc08cf87a0..0482c063c26e 100644 --- a/arch/ppc64/kernel/cpu_setup_power4.S +++ b/arch/ppc64/kernel/cpu_setup_power4.S @@ -31,10 +31,13 @@ _GLOBAL(__970_cpu_preinit) */ mfspr r0,SPRN_PVR srwi r0,r0,16 - cmpwi cr0,r0,0x39 - cmpwi cr1,r0,0x3c - cror 4*cr0+eq,4*cr0+eq,4*cr1+eq + cmpwi r0,0x39 + beq 1f + cmpwi r0,0x3c + beq 1f + cmpwi r0,0x44 bnelr +1: /* Make sure HID4:rm_ci is off before MMU is turned off, that large * pages are enabled with HID4:61 and clear HID5:DCBZ_size and @@ -133,12 +136,14 @@ _GLOBAL(__save_cpu_setup) /* We only deal with 970 for now */ mfspr r0,SPRN_PVR srwi r0,r0,16 - cmpwi cr0,r0,0x39 - cmpwi cr1,r0,0x3c - cror 4*cr0+eq,4*cr0+eq,4*cr1+eq - bne 1f - - /* Save HID0,1,4 and 5 */ + cmpwi r0,0x39 + beq 1f + cmpwi r0,0x3c + beq 1f + cmpwi r0,0x44 + bne 2f + +1: /* Save HID0,1,4 and 5 */ mfspr r3,SPRN_HID0 std r3,CS_HID0(r5) mfspr r3,SPRN_HID1 @@ -148,7 +153,7 @@ _GLOBAL(__save_cpu_setup) mfspr r3,SPRN_HID5 std r3,CS_HID5(r5) -1: +2: mtcr r7 blr @@ -165,12 +170,14 @@ _GLOBAL(__restore_cpu_setup) /* We only deal with 970 for now */ mfspr r0,SPRN_PVR srwi r0,r0,16 - cmpwi cr0,r0,0x39 - cmpwi cr1,r0,0x3c - cror 4*cr0+eq,4*cr0+eq,4*cr1+eq - bne 1f + cmpwi r0,0x39 + beq 1f + cmpwi r0,0x3c + beq 1f + cmpwi r0,0x44 + bnelr - /* Before accessing memory, we make sure rm_ci is clear */ +1: /* Before accessing memory, we make sure rm_ci is clear */ li r0,0 mfspr r3,SPRN_HID4 rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */ @@ -223,6 +230,5 @@ _GLOBAL(__restore_cpu_setup) mtspr SPRN_HID5,r3 sync isync -1: blr diff --git a/arch/ppc64/kernel/cputable.c b/arch/ppc64/kernel/cputable.c index 1d162c7c59df..77cec42f9525 100644 --- a/arch/ppc64/kernel/cputable.c +++ b/arch/ppc64/kernel/cputable.c @@ -49,160 +49,234 @@ extern void __setup_cpu_be(unsigned long offset, struct cpu_spec* spec); #endif struct cpu_spec cpu_specs[] = { - { /* Power3 */ - 0xffff0000, 0x00400000, "POWER3 (630)", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_IABR | CPU_FTR_PMC8, - COMMON_USER_PPC64, - 128, 128, - __setup_cpu_power3, - COMMON_PPC64_FW - }, - { /* Power3+ */ - 0xffff0000, 0x00410000, "POWER3 (630+)", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_IABR | CPU_FTR_PMC8, - COMMON_USER_PPC64, - 128, 128, - __setup_cpu_power3, - COMMON_PPC64_FW - }, - { /* Northstar */ - 0xffff0000, 0x00330000, "RS64-II (northstar)", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_IABR | CPU_FTR_PMC8 | CPU_FTR_MMCRA, - COMMON_USER_PPC64, - 128, 128, - __setup_cpu_power3, - COMMON_PPC64_FW - }, - { /* Pulsar */ - 0xffff0000, 0x00340000, "RS64-III (pulsar)", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_IABR | CPU_FTR_PMC8 | CPU_FTR_MMCRA, - COMMON_USER_PPC64, - 128, 128, - __setup_cpu_power3, - COMMON_PPC64_FW - }, - { /* I-star */ - 0xffff0000, 0x00360000, "RS64-III (icestar)", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_IABR | CPU_FTR_PMC8 | CPU_FTR_MMCRA, - COMMON_USER_PPC64, - 128, 128, - __setup_cpu_power3, - COMMON_PPC64_FW - }, - { /* S-star */ - 0xffff0000, 0x00370000, "RS64-IV (sstar)", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_IABR | CPU_FTR_PMC8 | CPU_FTR_MMCRA, - COMMON_USER_PPC64, - 128, 128, - __setup_cpu_power3, - COMMON_PPC64_FW - }, - { /* Power4 */ - 0xffff0000, 0x00350000, "POWER4 (gp)", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_PMC8 | CPU_FTR_MMCRA, - COMMON_USER_PPC64, - 128, 128, - __setup_cpu_power4, - COMMON_PPC64_FW - }, - { /* Power4+ */ - 0xffff0000, 0x00380000, "POWER4+ (gq)", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_PMC8 | CPU_FTR_MMCRA, - COMMON_USER_PPC64, - 128, 128, - __setup_cpu_power4, - COMMON_PPC64_FW - }, - { /* PPC970 */ - 0xffff0000, 0x00390000, "PPC970", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP | - CPU_FTR_CAN_NAP | CPU_FTR_PMC8 | CPU_FTR_MMCRA, - COMMON_USER_PPC64 | PPC_FEATURE_HAS_ALTIVEC_COMP, - 128, 128, - __setup_cpu_ppc970, - COMMON_PPC64_FW - }, - { /* PPC970FX */ - 0xffff0000, 0x003c0000, "PPC970FX", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP | - CPU_FTR_CAN_NAP | CPU_FTR_PMC8 | CPU_FTR_MMCRA, - COMMON_USER_PPC64 | PPC_FEATURE_HAS_ALTIVEC_COMP, - 128, 128, - __setup_cpu_ppc970, - COMMON_PPC64_FW - }, - { /* Power5 */ - 0xffff0000, 0x003a0000, "POWER5 (gr)", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA | CPU_FTR_SMT | - CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | - CPU_FTR_MMCRA_SIHV, - COMMON_USER_PPC64, - 128, 128, - __setup_cpu_power4, - COMMON_PPC64_FW - }, - { /* Power5 */ - 0xffff0000, 0x003b0000, "POWER5 (gs)", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA | CPU_FTR_SMT | - CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | - CPU_FTR_MMCRA_SIHV, - COMMON_USER_PPC64, - 128, 128, - __setup_cpu_power4, - COMMON_PPC64_FW - }, - { /* BE DD1.x */ - 0xffff0000, 0x00700000, "Broadband Engine", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP | - CPU_FTR_SMT, - COMMON_USER_PPC64 | PPC_FEATURE_HAS_ALTIVEC_COMP, - 128, 128, - __setup_cpu_be, - COMMON_PPC64_FW - }, - { /* default match */ - 0x00000000, 0x00000000, "POWER4 (compatible)", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_PPCAS_ARCH_V2, - COMMON_USER_PPC64, - 128, 128, - __setup_cpu_power4, - COMMON_PPC64_FW - } + { /* Power3 */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x00400000, + .cpu_name = "POWER3 (630)", + .cpu_features = CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR | + CPU_FTR_PMC8, + .cpu_user_features = COMMON_USER_PPC64, + .icache_bsize = 128, + .dcache_bsize = 128, + .cpu_setup = __setup_cpu_power3, + .firmware_features = COMMON_PPC64_FW, + }, + { /* Power3+ */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x00410000, + .cpu_name = "POWER3 (630+)", + .cpu_features = CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR | + CPU_FTR_PMC8, + .cpu_user_features = COMMON_USER_PPC64, + .icache_bsize = 128, + .dcache_bsize = 128, + .cpu_setup = __setup_cpu_power3, + .firmware_features = COMMON_PPC64_FW, + }, + { /* Northstar */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x00330000, + .cpu_name = "RS64-II (northstar)", + .cpu_features = CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR | + CPU_FTR_PMC8 | CPU_FTR_MMCRA | CPU_FTR_CTRL, + .cpu_user_features = COMMON_USER_PPC64, + .icache_bsize = 128, + .dcache_bsize = 128, + .cpu_setup = __setup_cpu_power3, + .firmware_features = COMMON_PPC64_FW, + }, + { /* Pulsar */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x00340000, + .cpu_name = "RS64-III (pulsar)", + .cpu_features = CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR | + CPU_FTR_PMC8 | CPU_FTR_MMCRA | CPU_FTR_CTRL, + .cpu_user_features = COMMON_USER_PPC64, + .icache_bsize = 128, + .dcache_bsize = 128, + .cpu_setup = __setup_cpu_power3, + .firmware_features = COMMON_PPC64_FW, + }, + { /* I-star */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x00360000, + .cpu_name = "RS64-III (icestar)", + .cpu_features = CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR | + CPU_FTR_PMC8 | CPU_FTR_MMCRA | CPU_FTR_CTRL, + .cpu_user_features = COMMON_USER_PPC64, + .icache_bsize = 128, + .dcache_bsize = 128, + .cpu_setup = __setup_cpu_power3, + .firmware_features = COMMON_PPC64_FW, + }, + { /* S-star */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x00370000, + .cpu_name = "RS64-IV (sstar)", + .cpu_features = CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR | + CPU_FTR_PMC8 | CPU_FTR_MMCRA | CPU_FTR_CTRL, + .cpu_user_features = COMMON_USER_PPC64, + .icache_bsize = 128, + .dcache_bsize = 128, + .cpu_setup = __setup_cpu_power3, + .firmware_features = COMMON_PPC64_FW, + }, + { /* Power4 */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x00350000, + .cpu_name = "POWER4 (gp)", + .cpu_features = CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | + CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_PMC8 | CPU_FTR_MMCRA, + .cpu_user_features = COMMON_USER_PPC64, + .icache_bsize = 128, + .dcache_bsize = 128, + .cpu_setup = __setup_cpu_power4, + .firmware_features = COMMON_PPC64_FW, + }, + { /* Power4+ */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x00380000, + .cpu_name = "POWER4+ (gq)", + .cpu_features = CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | + CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_PMC8 | CPU_FTR_MMCRA, + .cpu_user_features = COMMON_USER_PPC64, + .icache_bsize = 128, + .dcache_bsize = 128, + .cpu_setup = __setup_cpu_power4, + .firmware_features = COMMON_PPC64_FW, + }, + { /* PPC970 */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x00390000, + .cpu_name = "PPC970", + .cpu_features = CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | + CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP | + CPU_FTR_CAN_NAP | CPU_FTR_PMC8 | CPU_FTR_MMCRA, + .cpu_user_features = COMMON_USER_PPC64 | + PPC_FEATURE_HAS_ALTIVEC_COMP, + .icache_bsize = 128, + .dcache_bsize = 128, + .cpu_setup = __setup_cpu_ppc970, + .firmware_features = COMMON_PPC64_FW, + }, + { /* PPC970FX */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x003c0000, + .cpu_name = "PPC970FX", + .cpu_features = CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | + CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP | + CPU_FTR_CAN_NAP | CPU_FTR_PMC8 | CPU_FTR_MMCRA, + .cpu_user_features = COMMON_USER_PPC64 | + PPC_FEATURE_HAS_ALTIVEC_COMP, + .icache_bsize = 128, + .dcache_bsize = 128, + .cpu_setup = __setup_cpu_ppc970, + .firmware_features = COMMON_PPC64_FW, + }, + { /* PPC970MP */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x00440000, + .cpu_name = "PPC970MP", + .cpu_features = CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | + CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP | + CPU_FTR_CAN_NAP | CPU_FTR_PMC8 | CPU_FTR_MMCRA, + .cpu_user_features = COMMON_USER_PPC64 | + PPC_FEATURE_HAS_ALTIVEC_COMP, + .icache_bsize = 128, + .dcache_bsize = 128, + .cpu_setup = __setup_cpu_ppc970, + .firmware_features = COMMON_PPC64_FW, + }, + { /* Power5 */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x003a0000, + .cpu_name = "POWER5 (gr)", + .cpu_features = CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | + CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA | CPU_FTR_SMT | + CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | + CPU_FTR_MMCRA_SIHV, + .cpu_user_features = COMMON_USER_PPC64, + .icache_bsize = 128, + .dcache_bsize = 128, + .cpu_setup = __setup_cpu_power4, + .firmware_features = COMMON_PPC64_FW, + }, + { /* Power5 */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x003b0000, + .cpu_name = "POWER5 (gs)", + .cpu_features = CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | + CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA | CPU_FTR_SMT | + CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | + CPU_FTR_MMCRA_SIHV, + .cpu_user_features = COMMON_USER_PPC64, + .icache_bsize = 128, + .dcache_bsize = 128, + .cpu_setup = __setup_cpu_power4, + .firmware_features = COMMON_PPC64_FW, + }, + { /* BE DD1.x */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x00700000, + .cpu_name = "Broadband Engine", + .cpu_features = CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | + CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP | + CPU_FTR_SMT, + .cpu_user_features = COMMON_USER_PPC64 | + PPC_FEATURE_HAS_ALTIVEC_COMP, + .icache_bsize = 128, + .dcache_bsize = 128, + .cpu_setup = __setup_cpu_be, + .firmware_features = COMMON_PPC64_FW, + }, + { /* default match */ + .pvr_mask = 0x00000000, + .pvr_value = 0x00000000, + .cpu_name = "POWER4 (compatible)", + .cpu_features = CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | + CPU_FTR_PPCAS_ARCH_V2, + .cpu_user_features = COMMON_USER_PPC64, + .icache_bsize = 128, + .dcache_bsize = 128, + .cpu_setup = __setup_cpu_power4, + .firmware_features = COMMON_PPC64_FW, + } }; firmware_feature_t firmware_features_table[FIRMWARE_MAX_FEATURES] = { - {FW_FEATURE_PFT, "hcall-pft"}, - {FW_FEATURE_TCE, "hcall-tce"}, - {FW_FEATURE_SPRG0, "hcall-sprg0"}, - {FW_FEATURE_DABR, "hcall-dabr"}, - {FW_FEATURE_COPY, "hcall-copy"}, - {FW_FEATURE_ASR, "hcall-asr"}, - {FW_FEATURE_DEBUG, "hcall-debug"}, - {FW_FEATURE_PERF, "hcall-perf"}, - {FW_FEATURE_DUMP, "hcall-dump"}, - {FW_FEATURE_INTERRUPT, "hcall-interrupt"}, - {FW_FEATURE_MIGRATE, "hcall-migrate"}, - {FW_FEATURE_PERFMON, "hcall-perfmon"}, - {FW_FEATURE_CRQ, "hcall-crq"}, - {FW_FEATURE_VIO, "hcall-vio"}, - {FW_FEATURE_RDMA, "hcall-rdma"}, - {FW_FEATURE_LLAN, "hcall-lLAN"}, - {FW_FEATURE_BULK, "hcall-bulk"}, - {FW_FEATURE_XDABR, "hcall-xdabr"}, - {FW_FEATURE_MULTITCE, "hcall-multi-tce"}, - {FW_FEATURE_SPLPAR, "hcall-splpar"}, + {FW_FEATURE_PFT, "hcall-pft"}, + {FW_FEATURE_TCE, "hcall-tce"}, + {FW_FEATURE_SPRG0, "hcall-sprg0"}, + {FW_FEATURE_DABR, "hcall-dabr"}, + {FW_FEATURE_COPY, "hcall-copy"}, + {FW_FEATURE_ASR, "hcall-asr"}, + {FW_FEATURE_DEBUG, "hcall-debug"}, + {FW_FEATURE_PERF, "hcall-perf"}, + {FW_FEATURE_DUMP, "hcall-dump"}, + {FW_FEATURE_INTERRUPT, "hcall-interrupt"}, + {FW_FEATURE_MIGRATE, "hcall-migrate"}, + {FW_FEATURE_PERFMON, "hcall-perfmon"}, + {FW_FEATURE_CRQ, "hcall-crq"}, + {FW_FEATURE_VIO, "hcall-vio"}, + {FW_FEATURE_RDMA, "hcall-rdma"}, + {FW_FEATURE_LLAN, "hcall-lLAN"}, + {FW_FEATURE_BULK, "hcall-bulk"}, + {FW_FEATURE_XDABR, "hcall-xdabr"}, + {FW_FEATURE_MULTITCE, "hcall-multi-tce"}, + {FW_FEATURE_SPLPAR, "hcall-splpar"}, }; diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S index 675c2708588f..93ebcac0d5a2 100644 --- a/arch/ppc64/kernel/head.S +++ b/arch/ppc64/kernel/head.S @@ -308,6 +308,7 @@ exception_marker: label##_pSeries: \ HMT_MEDIUM; \ mtspr SPRG1,r13; /* save r13 */ \ + RUNLATCH_ON(r13); \ EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common) #define STD_EXCEPTION_ISERIES(n, label, area) \ @@ -315,6 +316,7 @@ label##_pSeries: \ label##_iSeries: \ HMT_MEDIUM; \ mtspr SPRG1,r13; /* save r13 */ \ + RUNLATCH_ON(r13); \ EXCEPTION_PROLOG_ISERIES_1(area); \ EXCEPTION_PROLOG_ISERIES_2; \ b label##_common @@ -324,6 +326,7 @@ label##_iSeries: \ label##_iSeries: \ HMT_MEDIUM; \ mtspr SPRG1,r13; /* save r13 */ \ + RUNLATCH_ON(r13); \ EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN); \ lbz r10,PACAPROCENABLED(r13); \ cmpwi 0,r10,0; \ @@ -393,6 +396,7 @@ __start_interrupts: _machine_check_pSeries: HMT_MEDIUM mtspr SPRG1,r13 /* save r13 */ + RUNLATCH_ON(r13) EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common) . = 0x300 @@ -419,6 +423,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB) data_access_slb_pSeries: HMT_MEDIUM mtspr SPRG1,r13 + RUNLATCH_ON(r13) mfspr r13,SPRG3 /* get paca address into r13 */ std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */ std r10,PACA_EXSLB+EX_R10(r13) @@ -439,6 +444,7 @@ data_access_slb_pSeries: instruction_access_slb_pSeries: HMT_MEDIUM mtspr SPRG1,r13 + RUNLATCH_ON(r13) mfspr r13,SPRG3 /* get paca address into r13 */ std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */ std r10,PACA_EXSLB+EX_R10(r13) @@ -464,6 +470,7 @@ instruction_access_slb_pSeries: .globl system_call_pSeries system_call_pSeries: HMT_MEDIUM + RUNLATCH_ON(r9) mr r9,r13 mfmsr r10 mfspr r13,SPRG3 @@ -707,11 +714,13 @@ fwnmi_data_area: system_reset_fwnmi: HMT_MEDIUM mtspr SPRG1,r13 /* save r13 */ + RUNLATCH_ON(r13) EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common) .globl machine_check_fwnmi machine_check_fwnmi: HMT_MEDIUM mtspr SPRG1,r13 /* save r13 */ + RUNLATCH_ON(r13) EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common) /* @@ -848,6 +857,7 @@ unrecov_fer: .align 7 .globl data_access_common data_access_common: + RUNLATCH_ON(r10) /* It wont fit in the 0x300 handler */ mfspr r10,DAR std r10,PACA_EXGEN+EX_DAR(r13) mfspr r10,DSISR diff --git a/arch/ppc64/kernel/hvconsole.c b/arch/ppc64/kernel/hvconsole.c index c72fb8ffe974..138e128a3886 100644 --- a/arch/ppc64/kernel/hvconsole.c +++ b/arch/ppc64/kernel/hvconsole.c @@ -27,7 +27,6 @@ #include <linux/module.h> #include <asm/hvcall.h> #include <asm/hvconsole.h> -#include <asm/prom.h> /** * hvc_get_chars - retrieve characters from firmware for denoted vterm adatper @@ -42,29 +41,14 @@ int hvc_get_chars(uint32_t vtermno, char *buf, int count) unsigned long got; if (plpar_hcall(H_GET_TERM_CHAR, vtermno, 0, 0, 0, &got, - (unsigned long *)buf, (unsigned long *)buf+1) == H_Success) { - /* - * Work around a HV bug where it gives us a null - * after every \r. -- paulus - */ - if (got > 0) { - int i; - for (i = 1; i < got; ++i) { - if (buf[i] == 0 && buf[i-1] == '\r') { - --got; - if (i < got) - memmove(&buf[i], &buf[i+1], - got - i); - } - } - } + (unsigned long *)buf, (unsigned long *)buf+1) == H_Success) return got; - } return 0; } EXPORT_SYMBOL(hvc_get_chars); + /** * hvc_put_chars: send characters to firmware for denoted vterm adapter * @vtermno: The vtermno or unit_address of the adapter from which the data @@ -88,34 +72,3 @@ int hvc_put_chars(uint32_t vtermno, const char *buf, int count) } EXPORT_SYMBOL(hvc_put_chars); - -/* - * We hope/assume that the first vty found corresponds to the first console - * device. - */ -int hvc_find_vtys(void) -{ - struct device_node *vty; - int num_found = 0; - - for (vty = of_find_node_by_name(NULL, "vty"); vty != NULL; - vty = of_find_node_by_name(vty, "vty")) { - uint32_t *vtermno; - - /* We have statically defined space for only a certain number of - * console adapters. */ - if (num_found >= MAX_NR_HVC_CONSOLES) - break; - - vtermno = (uint32_t *)get_property(vty, "reg", NULL); - if (!vtermno) - continue; - - if (device_is_compatible(vty, "hvterm1")) { - hvc_instantiate(*vtermno, num_found); - ++num_found; - } - } - - return num_found; -} diff --git a/arch/ppc64/kernel/iSeries_htab.c b/arch/ppc64/kernel/iSeries_htab.c index aa9e8fdd1a4f..b0250ae4a72a 100644 --- a/arch/ppc64/kernel/iSeries_htab.c +++ b/arch/ppc64/kernel/iSeries_htab.c @@ -38,11 +38,12 @@ static inline void iSeries_hunlock(unsigned long slot) } static long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va, - unsigned long prpn, int secondary, - unsigned long hpteflags, int bolted, int large) + unsigned long prpn, unsigned long vflags, + unsigned long rflags) { long slot; - HPTE lhpte; + hpte_t lhpte; + int secondary = 0; /* * The hypervisor tries both primary and secondary. @@ -50,13 +51,13 @@ static long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va, * it means we have already tried both primary and secondary, * so we return failure immediately. */ - if (secondary) + if (vflags & HPTE_V_SECONDARY) return -1; iSeries_hlock(hpte_group); slot = HvCallHpt_findValid(&lhpte, va >> PAGE_SHIFT); - BUG_ON(lhpte.dw0.dw0.v); + BUG_ON(lhpte.v & HPTE_V_VALID); if (slot == -1) { /* No available entry found in either group */ iSeries_hunlock(hpte_group); @@ -64,19 +65,13 @@ static long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va, } if (slot < 0) { /* MSB set means secondary group */ + vflags |= HPTE_V_VALID; secondary = 1; slot &= 0x7fffffffffffffff; } - lhpte.dw1.dword1 = 0; - lhpte.dw1.dw1.rpn = physRpn_to_absRpn(prpn); - lhpte.dw1.flags.flags = hpteflags; - - lhpte.dw0.dword0 = 0; - lhpte.dw0.dw0.avpn = va >> 23; - lhpte.dw0.dw0.h = secondary; - lhpte.dw0.dw0.bolted = bolted; - lhpte.dw0.dw0.v = 1; + lhpte.v = (va >> 23) << HPTE_V_AVPN_SHIFT | vflags | HPTE_V_VALID; + lhpte.r = (physRpn_to_absRpn(prpn) << HPTE_R_RPN_SHIFT) | rflags; /* Now fill in the actual HPTE */ HvCallHpt_addValidate(slot, secondary, &lhpte); @@ -88,20 +83,17 @@ static long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va, static unsigned long iSeries_hpte_getword0(unsigned long slot) { - unsigned long dword0; - HPTE hpte; + hpte_t hpte; HvCallHpt_get(&hpte, slot); - dword0 = hpte.dw0.dword0; - - return dword0; + return hpte.v; } static long iSeries_hpte_remove(unsigned long hpte_group) { unsigned long slot_offset; int i; - HPTE lhpte; + unsigned long hpte_v; /* Pick a random slot to start at */ slot_offset = mftb() & 0x7; @@ -109,10 +101,9 @@ static long iSeries_hpte_remove(unsigned long hpte_group) iSeries_hlock(hpte_group); for (i = 0; i < HPTES_PER_GROUP; i++) { - lhpte.dw0.dword0 = - iSeries_hpte_getword0(hpte_group + slot_offset); + hpte_v = iSeries_hpte_getword0(hpte_group + slot_offset); - if (!lhpte.dw0.dw0.bolted) { + if (! (hpte_v & HPTE_V_BOLTED)) { HvCallHpt_invalidateSetSwBitsGet(hpte_group + slot_offset, 0, 0); iSeries_hunlock(hpte_group); @@ -137,13 +128,13 @@ static long iSeries_hpte_remove(unsigned long hpte_group) static long iSeries_hpte_updatepp(unsigned long slot, unsigned long newpp, unsigned long va, int large, int local) { - HPTE hpte; + hpte_t hpte; unsigned long avpn = va >> 23; iSeries_hlock(slot); HvCallHpt_get(&hpte, slot); - if ((hpte.dw0.dw0.avpn == avpn) && (hpte.dw0.dw0.v)) { + if ((HPTE_V_AVPN_VAL(hpte.v) == avpn) && (hpte.v & HPTE_V_VALID)) { /* * Hypervisor expects bits as NPPP, which is * different from how they are mapped in our PP. @@ -167,7 +158,7 @@ static long iSeries_hpte_updatepp(unsigned long slot, unsigned long newpp, */ static long iSeries_hpte_find(unsigned long vpn) { - HPTE hpte; + hpte_t hpte; long slot; /* @@ -177,7 +168,7 @@ static long iSeries_hpte_find(unsigned long vpn) * 0x80000000xxxxxxxx : Entry found in secondary group, slot x */ slot = HvCallHpt_findValid(&hpte, vpn); - if (hpte.dw0.dw0.v) { + if (hpte.v & HPTE_V_VALID) { if (slot < 0) { slot &= 0x7fffffffffffffff; slot = -slot; @@ -212,7 +203,7 @@ static void iSeries_hpte_updateboltedpp(unsigned long newpp, unsigned long ea) static void iSeries_hpte_invalidate(unsigned long slot, unsigned long va, int large, int local) { - HPTE lhpte; + unsigned long hpte_v; unsigned long avpn = va >> 23; unsigned long flags; @@ -220,9 +211,9 @@ static void iSeries_hpte_invalidate(unsigned long slot, unsigned long va, iSeries_hlock(slot); - lhpte.dw0.dword0 = iSeries_hpte_getword0(slot); + hpte_v = iSeries_hpte_getword0(slot); - if ((lhpte.dw0.dw0.avpn == avpn) && lhpte.dw0.dw0.v) + if ((HPTE_V_AVPN_VAL(hpte_v) == avpn) && (hpte_v & HPTE_V_VALID)) HvCallHpt_invalidateSetSwBitsGet(slot, 0, 0); iSeries_hunlock(slot); diff --git a/arch/ppc64/kernel/iSeries_proc.c b/arch/ppc64/kernel/iSeries_proc.c index 356bd9931fcc..0fe3116eba29 100644 --- a/arch/ppc64/kernel/iSeries_proc.c +++ b/arch/ppc64/kernel/iSeries_proc.c @@ -40,50 +40,6 @@ static int __init iseries_proc_create(void) } core_initcall(iseries_proc_create); -static char *event_types[9] = { - "Hypervisor\t\t", - "Machine Facilities\t", - "Session Manager\t", - "SPD I/O\t\t", - "Virtual Bus\t\t", - "PCI I/O\t\t", - "RIO I/O\t\t", - "Virtual Lan\t\t", - "Virtual I/O\t\t" -}; - -static int proc_lpevents_show(struct seq_file *m, void *v) -{ - unsigned int i; - - seq_printf(m, "LpEventQueue 0\n"); - seq_printf(m, " events processed:\t%lu\n", - (unsigned long)xItLpQueue.xLpIntCount); - - for (i = 0; i < 9; ++i) - seq_printf(m, " %s %10lu\n", event_types[i], - (unsigned long)xItLpQueue.xLpIntCountByType[i]); - - seq_printf(m, "\n events processed by processor:\n"); - - for_each_online_cpu(i) - seq_printf(m, " CPU%02d %10u\n", i, paca[i].lpevent_count); - - return 0; -} - -static int proc_lpevents_open(struct inode *inode, struct file *file) -{ - return single_open(file, proc_lpevents_show, NULL); -} - -static struct file_operations proc_lpevents_operations = { - .open = proc_lpevents_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - static unsigned long startTitan = 0; static unsigned long startTb = 0; @@ -148,10 +104,6 @@ static int __init iseries_proc_init(void) { struct proc_dir_entry *e; - e = create_proc_entry("iSeries/lpevents", S_IFREG|S_IRUGO, NULL); - if (e) - e->proc_fops = &proc_lpevents_operations; - e = create_proc_entry("iSeries/titanTod", S_IFREG|S_IRUGO, NULL); if (e) e->proc_fops = &proc_titantod_operations; diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c index 86966ce76b58..a649edbb23b6 100644 --- a/arch/ppc64/kernel/iSeries_setup.c +++ b/arch/ppc64/kernel/iSeries_setup.c @@ -24,7 +24,6 @@ #include <linux/smp.h> #include <linux/param.h> #include <linux/string.h> -#include <linux/bootmem.h> #include <linux/initrd.h> #include <linux/seq_file.h> #include <linux/kdev_t.h> @@ -504,7 +503,7 @@ static void __init build_iSeries_Memory_Map(void) /* Fill in the hashed page table hash mask */ num_ptegs = hptSizePages * - (PAGE_SIZE / (sizeof(HPTE) * HPTES_PER_GROUP)); + (PAGE_SIZE / (sizeof(hpte_t) * HPTES_PER_GROUP)); htab_hash_mask = num_ptegs - 1; /* @@ -619,25 +618,23 @@ static void __init setup_iSeries_cache_sizes(void) static void iSeries_make_pte(unsigned long va, unsigned long pa, int mode) { - HPTE local_hpte, rhpte; + hpte_t local_hpte, rhpte; unsigned long hash, vpn; long slot; vpn = va >> PAGE_SHIFT; hash = hpt_hash(vpn, 0); - local_hpte.dw1.dword1 = pa | mode; - local_hpte.dw0.dword0 = 0; - local_hpte.dw0.dw0.avpn = va >> 23; - local_hpte.dw0.dw0.bolted = 1; /* bolted */ - local_hpte.dw0.dw0.v = 1; + local_hpte.r = pa | mode; + local_hpte.v = ((va >> 23) << HPTE_V_AVPN_SHIFT) + | HPTE_V_BOLTED | HPTE_V_VALID; slot = HvCallHpt_findValid(&rhpte, vpn); if (slot < 0) { /* Must find space in primary group */ panic("hash_page: hpte already exists\n"); } - HvCallHpt_addValidate(slot, 0, (HPTE *)&local_hpte ); + HvCallHpt_addValidate(slot, 0, &local_hpte); } /* @@ -647,7 +644,7 @@ static void __init iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr) { unsigned long pa; unsigned long mode_rw = _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX; - HPTE hpte; + hpte_t hpte; for (pa = saddr; pa < eaddr ;pa += PAGE_SIZE) { unsigned long ea = (unsigned long)__va(pa); @@ -660,7 +657,7 @@ static void __init iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr) if (!in_kernel_text(ea)) mode_rw |= HW_NO_EXEC; - if (hpte.dw0.dw0.v) { + if (hpte.v & HPTE_V_VALID) { /* HPTE exists, so just bolt it */ HvCallHpt_setSwBits(slot, 0x10, 0); /* And make sure the pp bits are correct */ @@ -676,7 +673,6 @@ static void __init iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr) */ static void __init iSeries_setup_arch(void) { - void *eventStack; unsigned procIx = get_paca()->lppaca.dyn_hv_phys_proc_index; /* Add an eye catcher and the systemcfg layout version number */ @@ -685,24 +681,7 @@ static void __init iSeries_setup_arch(void) systemcfg->version.minor = SYSTEMCFG_MINOR; /* Setup the Lp Event Queue */ - - /* Allocate a page for the Event Stack - * The hypervisor wants the absolute real address, so - * we subtract out the KERNELBASE and add in the - * absolute real address of the kernel load area - */ - eventStack = alloc_bootmem_pages(LpEventStackSize); - memset(eventStack, 0, LpEventStackSize); - - /* Invoke the hypervisor to initialize the event stack */ - HvCallEvent_setLpEventStack(0, eventStack, LpEventStackSize); - - /* Initialize fields in our Lp Event Queue */ - xItLpQueue.xSlicEventStackPtr = (char *)eventStack; - xItLpQueue.xSlicCurEventPtr = (char *)eventStack; - xItLpQueue.xSlicLastValidEventPtr = (char *)eventStack + - (LpEventStackSize - LpEventMaxSize); - xItLpQueue.xIndex = 0; + setup_hvlpevent_queue(); /* Compute processor frequency */ procFreqHz = ((1UL << 34) * 1000000) / @@ -853,27 +832,91 @@ static int __init iSeries_src_init(void) late_initcall(iSeries_src_init); -static int set_spread_lpevents(char *str) +static inline void process_iSeries_events(void) { - unsigned long i; - unsigned long val = simple_strtoul(str, NULL, 0); + asm volatile ("li 0,0x5555; sc" : : : "r0", "r3"); +} + +static void yield_shared_processor(void) +{ + unsigned long tb; + + HvCall_setEnabledInterrupts(HvCall_MaskIPI | + HvCall_MaskLpEvent | + HvCall_MaskLpProd | + HvCall_MaskTimeout); + + tb = get_tb(); + /* Compute future tb value when yield should expire */ + HvCall_yieldProcessor(HvCall_YieldTimed, tb+tb_ticks_per_jiffy); /* - * The parameter is the number of processors to share in processing - * lp events. + * The decrementer stops during the yield. Force a fake decrementer + * here and let the timer_interrupt code sort out the actual time. */ - if (( val > 0) && (val <= NR_CPUS)) { - for (i = 1; i < val; ++i) - paca[i].lpqueue_ptr = paca[0].lpqueue_ptr; + get_paca()->lppaca.int_dword.fields.decr_int = 1; + process_iSeries_events(); +} - printk("lpevent processing spread over %ld processors\n", val); - } else { - printk("invalid spread_lpevents %ld\n", val); +static int iseries_shared_idle(void) +{ + while (1) { + while (!need_resched() && !hvlpevent_is_pending()) { + local_irq_disable(); + ppc64_runlatch_off(); + + /* Recheck with irqs off */ + if (!need_resched() && !hvlpevent_is_pending()) + yield_shared_processor(); + + HMT_medium(); + local_irq_enable(); + } + + ppc64_runlatch_on(); + + if (hvlpevent_is_pending()) + process_iSeries_events(); + + schedule(); + } + + return 0; +} + +static int iseries_dedicated_idle(void) +{ + long oldval; + + while (1) { + oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED); + + if (!oldval) { + set_thread_flag(TIF_POLLING_NRFLAG); + + while (!need_resched()) { + ppc64_runlatch_off(); + HMT_low(); + + if (hvlpevent_is_pending()) { + HMT_medium(); + ppc64_runlatch_on(); + process_iSeries_events(); + } + } + + HMT_medium(); + clear_thread_flag(TIF_POLLING_NRFLAG); + } else { + set_need_resched(); + } + + ppc64_runlatch_on(); + schedule(); } - return 1; + return 0; } -__setup("spread_lpevents=", set_spread_lpevents); #ifndef CONFIG_PCI void __init iSeries_init_IRQ(void) { } @@ -900,5 +943,13 @@ void __init iSeries_early_setup(void) ppc_md.get_rtc_time = iSeries_get_rtc_time; ppc_md.calibrate_decr = iSeries_calibrate_decr; ppc_md.progress = iSeries_progress; + + if (get_paca()->lppaca.shared_proc) { + ppc_md.idle_loop = iseries_shared_idle; + printk(KERN_INFO "Using shared processor idle loop\n"); + } else { + ppc_md.idle_loop = iseries_dedicated_idle; + printk(KERN_INFO "Using dedicated idle loop\n"); + } } diff --git a/arch/ppc64/kernel/idle.c b/arch/ppc64/kernel/idle.c index bdf13b4dc1c8..954395d42636 100644 --- a/arch/ppc64/kernel/idle.c +++ b/arch/ppc64/kernel/idle.c @@ -20,109 +20,18 @@ #include <linux/kernel.h> #include <linux/smp.h> #include <linux/cpu.h> -#include <linux/module.h> #include <linux/sysctl.h> -#include <linux/smp.h> #include <asm/system.h> #include <asm/processor.h> -#include <asm/mmu.h> #include <asm/cputable.h> #include <asm/time.h> -#include <asm/iSeries/HvCall.h> -#include <asm/iSeries/ItLpQueue.h> -#include <asm/plpar_wrappers.h> #include <asm/systemcfg.h> +#include <asm/machdep.h> extern void power4_idle(void); -static int (*idle_loop)(void); - -#ifdef CONFIG_PPC_ISERIES -static unsigned long maxYieldTime = 0; -static unsigned long minYieldTime = 0xffffffffffffffffUL; - -static inline void process_iSeries_events(void) -{ - asm volatile ("li 0,0x5555; sc" : : : "r0", "r3"); -} - -static void yield_shared_processor(void) -{ - unsigned long tb; - unsigned long yieldTime; - - HvCall_setEnabledInterrupts(HvCall_MaskIPI | - HvCall_MaskLpEvent | - HvCall_MaskLpProd | - HvCall_MaskTimeout); - - tb = get_tb(); - /* Compute future tb value when yield should expire */ - HvCall_yieldProcessor(HvCall_YieldTimed, tb+tb_ticks_per_jiffy); - - yieldTime = get_tb() - tb; - if (yieldTime > maxYieldTime) - maxYieldTime = yieldTime; - - if (yieldTime < minYieldTime) - minYieldTime = yieldTime; - - /* - * The decrementer stops during the yield. Force a fake decrementer - * here and let the timer_interrupt code sort out the actual time. - */ - get_paca()->lppaca.int_dword.fields.decr_int = 1; - process_iSeries_events(); -} - -static int iSeries_idle(void) -{ - struct paca_struct *lpaca; - long oldval; - - /* ensure iSeries run light will be out when idle */ - ppc64_runlatch_off(); - - lpaca = get_paca(); - - while (1) { - if (lpaca->lppaca.shared_proc) { - if (ItLpQueue_isLpIntPending(lpaca->lpqueue_ptr)) - process_iSeries_events(); - if (!need_resched()) - yield_shared_processor(); - } else { - oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED); - - if (!oldval) { - set_thread_flag(TIF_POLLING_NRFLAG); - - while (!need_resched()) { - HMT_medium(); - if (ItLpQueue_isLpIntPending(lpaca->lpqueue_ptr)) - process_iSeries_events(); - HMT_low(); - } - - HMT_medium(); - clear_thread_flag(TIF_POLLING_NRFLAG); - } else { - set_need_resched(); - } - } - - ppc64_runlatch_on(); - schedule(); - ppc64_runlatch_off(); - } - - return 0; -} - -#else - -static int default_idle(void) +int default_idle(void) { long oldval; unsigned int cpu = smp_processor_id(); @@ -134,7 +43,8 @@ static int default_idle(void) set_thread_flag(TIF_POLLING_NRFLAG); while (!need_resched() && !cpu_is_offline(cpu)) { - barrier(); + ppc64_runlatch_off(); + /* * Go into low thread priority and possibly * low power mode. @@ -149,6 +59,7 @@ static int default_idle(void) set_need_resched(); } + ppc64_runlatch_on(); schedule(); if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) cpu_die(); @@ -157,127 +68,19 @@ static int default_idle(void) return 0; } -#ifdef CONFIG_PPC_PSERIES - -DECLARE_PER_CPU(unsigned long, smt_snooze_delay); - -int dedicated_idle(void) +int native_idle(void) { - long oldval; - struct paca_struct *lpaca = get_paca(), *ppaca; - unsigned long start_snooze; - unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay); - unsigned int cpu = smp_processor_id(); - - ppaca = &paca[cpu ^ 1]; - while (1) { - /* - * Indicate to the HV that we are idle. Now would be - * a good time to find other work to dispatch. - */ - lpaca->lppaca.idle = 1; - - oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED); - if (!oldval) { - set_thread_flag(TIF_POLLING_NRFLAG); - start_snooze = __get_tb() + - *smt_snooze_delay * tb_ticks_per_usec; - while (!need_resched() && !cpu_is_offline(cpu)) { - /* - * Go into low thread priority and possibly - * low power mode. - */ - HMT_low(); - HMT_very_low(); - - if (*smt_snooze_delay == 0 || - __get_tb() < start_snooze) - continue; - - HMT_medium(); - - if (!(ppaca->lppaca.idle)) { - local_irq_disable(); - - /* - * We are about to sleep the thread - * and so wont be polling any - * more. - */ - clear_thread_flag(TIF_POLLING_NRFLAG); - - /* - * SMT dynamic mode. Cede will result - * in this thread going dormant, if the - * partner thread is still doing work. - * Thread wakes up if partner goes idle, - * an interrupt is presented, or a prod - * occurs. Returning from the cede - * enables external interrupts. - */ - if (!need_resched()) - cede_processor(); - else - local_irq_enable(); - } else { - /* - * Give the HV an opportunity at the - * processor, since we are not doing - * any work. - */ - poll_pending(); - } - } - - clear_thread_flag(TIF_POLLING_NRFLAG); - } else { - set_need_resched(); - } - - HMT_medium(); - lpaca->lppaca.idle = 0; - schedule(); - if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) - cpu_die(); - } - return 0; -} - -static int shared_idle(void) -{ - struct paca_struct *lpaca = get_paca(); - unsigned int cpu = smp_processor_id(); - - while (1) { - /* - * Indicate to the HV that we are idle. Now would be - * a good time to find other work to dispatch. - */ - lpaca->lppaca.idle = 1; + ppc64_runlatch_off(); - while (!need_resched() && !cpu_is_offline(cpu)) { - local_irq_disable(); + if (!need_resched()) + power4_idle(); - /* - * Yield the processor to the hypervisor. We return if - * an external interrupt occurs (which are driven prior - * to returning here) or if a prod occurs from another - * processor. When returning here, external interrupts - * are enabled. - * - * Check need_resched() again with interrupts disabled - * to avoid a race. - */ - if (!need_resched()) - cede_processor(); - else - local_irq_enable(); + if (need_resched()) { + ppc64_runlatch_on(); + schedule(); } - HMT_medium(); - lpaca->lppaca.idle = 0; - schedule(); if (cpu_is_offline(smp_processor_id()) && system_state == SYSTEM_RUNNING) cpu_die(); @@ -286,29 +89,10 @@ static int shared_idle(void) return 0; } -#endif /* CONFIG_PPC_PSERIES */ - -static int native_idle(void) -{ - while(1) { - /* check CPU type here */ - if (!need_resched()) - power4_idle(); - if (need_resched()) - schedule(); - - if (cpu_is_offline(raw_smp_processor_id()) && - system_state == SYSTEM_RUNNING) - cpu_die(); - } - return 0; -} - -#endif /* CONFIG_PPC_ISERIES */ - void cpu_idle(void) { - idle_loop(); + BUG_ON(NULL == ppc_md.idle_loop); + ppc_md.idle_loop(); } int powersave_nap; @@ -342,42 +126,3 @@ register_powersave_nap_sysctl(void) } __initcall(register_powersave_nap_sysctl); #endif - -int idle_setup(void) -{ - /* - * Move that junk to each platform specific file, eventually define - * a pSeries_idle for shared processor stuff - */ -#ifdef CONFIG_PPC_ISERIES - idle_loop = iSeries_idle; - return 1; -#else - idle_loop = default_idle; -#endif -#ifdef CONFIG_PPC_PSERIES - if (systemcfg->platform & PLATFORM_PSERIES) { - if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) { - if (get_paca()->lppaca.shared_proc) { - printk(KERN_INFO "Using shared processor idle loop\n"); - idle_loop = shared_idle; - } else { - printk(KERN_INFO "Using dedicated idle loop\n"); - idle_loop = dedicated_idle; - } - } else { - printk(KERN_INFO "Using default idle loop\n"); - idle_loop = default_idle; - } - } -#endif /* CONFIG_PPC_PSERIES */ -#ifndef CONFIG_PPC_ISERIES - if (systemcfg->platform == PLATFORM_POWERMAC || - systemcfg->platform == PLATFORM_MAPLE) { - printk(KERN_INFO "Using native/NAP idle loop\n"); - idle_loop = native_idle; - } -#endif /* CONFIG_PPC_ISERIES */ - - return 1; -} diff --git a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c index 3defc8c33adf..f41afe545045 100644 --- a/arch/ppc64/kernel/irq.c +++ b/arch/ppc64/kernel/irq.c @@ -66,7 +66,6 @@ EXPORT_SYMBOL(irq_desc); int distribute_irqs = 1; int __irq_offset_value; int ppc_spurious_interrupts; -unsigned long lpevent_count; u64 ppc64_interrupt_controller; int show_interrupts(struct seq_file *p, void *v) @@ -245,7 +244,7 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq) spin_lock(&desc->lock); if (!noirqdebug) - note_interrupt(irq, desc, action_ret); + note_interrupt(irq, desc, action_ret, regs); if (likely(!(desc->status & IRQ_PENDING))) break; desc->status &= ~IRQ_PENDING; @@ -269,7 +268,6 @@ out: void do_IRQ(struct pt_regs *regs) { struct paca_struct *lpaca; - struct ItLpQueue *lpq; irq_enter(); @@ -295,9 +293,8 @@ void do_IRQ(struct pt_regs *regs) iSeries_smp_message_recv(regs); } #endif /* CONFIG_SMP */ - lpq = lpaca->lpqueue_ptr; - if (lpq && ItLpQueue_isLpIntPending(lpq)) - lpevent_count += ItLpQueue_process(lpq, regs); + if (hvlpevent_is_pending()) + process_hvlpevents(regs); irq_exit(); diff --git a/arch/ppc64/kernel/kprobes.c b/arch/ppc64/kernel/kprobes.c index 782ce3efa2c1..a3d519518fb8 100644 --- a/arch/ppc64/kernel/kprobes.c +++ b/arch/ppc64/kernel/kprobes.c @@ -36,6 +36,8 @@ #include <asm/kdebug.h> #include <asm/sstep.h> +static DECLARE_MUTEX(kprobe_mutex); + static struct kprobe *current_kprobe; static unsigned long kprobe_status, kprobe_saved_msr; static struct kprobe *kprobe_prev; @@ -54,6 +56,15 @@ int arch_prepare_kprobe(struct kprobe *p) printk("Cannot register a kprobe on rfid or mtmsrd\n"); ret = -EINVAL; } + + /* insn must be on a special executable page on ppc64 */ + if (!ret) { + up(&kprobe_mutex); + p->ainsn.insn = get_insn_slot(); + down(&kprobe_mutex); + if (!p->ainsn.insn) + ret = -ENOMEM; + } return ret; } @@ -79,16 +90,22 @@ void arch_disarm_kprobe(struct kprobe *p) void arch_remove_kprobe(struct kprobe *p) { + up(&kprobe_mutex); + free_insn_slot(p->ainsn.insn); + down(&kprobe_mutex); } static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) { + kprobe_opcode_t insn = *p->ainsn.insn; + regs->msr |= MSR_SE; - /*single step inline if it a breakpoint instruction*/ - if (p->opcode == BREAKPOINT_INSTRUCTION) + + /* single step inline if it is a trap variant */ + if (IS_TW(insn) || IS_TD(insn) || IS_TWI(insn) || IS_TDI(insn)) regs->nip = (unsigned long)p->addr; else - regs->nip = (unsigned long)&p->ainsn.insn; + regs->nip = (unsigned long)p->ainsn.insn; } static inline void save_previous_kprobe(void) @@ -105,6 +122,23 @@ static inline void restore_previous_kprobe(void) kprobe_saved_msr = kprobe_saved_msr_prev; } +void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs) +{ + struct kretprobe_instance *ri; + + if ((ri = get_free_rp_inst(rp)) != NULL) { + ri->rp = rp; + ri->task = current; + ri->ret_addr = (kprobe_opcode_t *)regs->link; + + /* Replace the return addr with trampoline addr */ + regs->link = (unsigned long)kretprobe_trampoline; + add_rp_inst(ri); + } else { + rp->nmissed++; + } +} + static inline int kprobe_handler(struct pt_regs *regs) { struct kprobe *p; @@ -195,6 +229,78 @@ no_kprobe: } /* + * Function return probe trampoline: + * - init_kprobes() establishes a probepoint here + * - When the probed function returns, this probe + * causes the handlers to fire + */ +void kretprobe_trampoline_holder(void) +{ + asm volatile(".global kretprobe_trampoline\n" + "kretprobe_trampoline:\n" + "nop\n"); +} + +/* + * Called when the probe at kretprobe trampoline is hit + */ +int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) +{ + struct kretprobe_instance *ri = NULL; + struct hlist_head *head; + struct hlist_node *node, *tmp; + unsigned long orig_ret_address = 0; + unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline; + + head = kretprobe_inst_table_head(current); + + /* + * It is possible to have multiple instances associated with a given + * task either because an multiple functions in the call path + * have a return probe installed on them, and/or more then one return + * return probe was registered for a target function. + * + * We can handle this because: + * - instances are always inserted at the head of the list + * - when multiple return probes are registered for the same + * function, the first instance's ret_addr will point to the + * real return address, and all the rest will point to + * kretprobe_trampoline + */ + hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { + if (ri->task != current) + /* another task is sharing our hash bucket */ + continue; + + if (ri->rp && ri->rp->handler) + ri->rp->handler(ri, regs); + + orig_ret_address = (unsigned long)ri->ret_addr; + recycle_rp_inst(ri); + + if (orig_ret_address != trampoline_address) + /* + * This is the real return address. Any other + * instances associated with this task are for + * other calls deeper on the call stack + */ + break; + } + + BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address)); + regs->nip = orig_ret_address; + + unlock_kprobes(); + + /* + * By returning a non-zero value, we are telling + * kprobe_handler() that we have handled unlocking + * and re-enabling preemption. + */ + return 1; +} + +/* * Called after single-stepping. p->addr is the address of the * instruction whose first byte has been replaced by the "breakpoint" * instruction. To avoid the SMP problems that can occur when we @@ -205,9 +311,10 @@ no_kprobe: static void resume_execution(struct kprobe *p, struct pt_regs *regs) { int ret; + unsigned int insn = *p->ainsn.insn; regs->nip = (unsigned long)p->addr; - ret = emulate_step(regs, p->ainsn.insn[0]); + ret = emulate_step(regs, insn); if (ret == 0) regs->nip = (unsigned long)p->addr + 4; } @@ -331,3 +438,13 @@ int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) memcpy(regs, &jprobe_saved_regs, sizeof(struct pt_regs)); return 1; } + +static struct kprobe trampoline_p = { + .addr = (kprobe_opcode_t *) &kretprobe_trampoline, + .pre_handler = trampoline_probe_handler +}; + +int __init arch_init_kprobes(void) +{ + return register_kprobe(&trampoline_p); +} diff --git a/arch/ppc64/kernel/maple_setup.c b/arch/ppc64/kernel/maple_setup.c index da8900b51f40..bb55b5a56910 100644 --- a/arch/ppc64/kernel/maple_setup.c +++ b/arch/ppc64/kernel/maple_setup.c @@ -177,6 +177,8 @@ void __init maple_setup_arch(void) #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; #endif + + printk(KERN_INFO "Using native/NAP idle loop\n"); } /* @@ -297,4 +299,5 @@ struct machdep_calls __initdata maple_md = { .get_rtc_time = maple_get_rtc_time, .calibrate_decr = generic_calibrate_decr, .progress = maple_progress, + .idle_loop = native_idle, }; diff --git a/arch/ppc64/kernel/mf.c b/arch/ppc64/kernel/mf.c index d98bebf7042f..ef4a338ebd01 100644 --- a/arch/ppc64/kernel/mf.c +++ b/arch/ppc64/kernel/mf.c @@ -801,10 +801,8 @@ int mf_get_boot_rtc(struct rtc_time *tm) return rc; /* We need to poll here as we are not yet taking interrupts */ while (rtc_data.busy) { - extern unsigned long lpevent_count; - struct ItLpQueue *lpq = get_paca()->lpqueue_ptr; - if (lpq && ItLpQueue_isLpIntPending(lpq)) - lpevent_count += ItLpQueue_process(lpq, NULL); + if (hvlpevent_is_pending()) + process_hvlpevents(NULL); } return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm); } diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S index f3dea0c5a88c..59f4f9973818 100644 --- a/arch/ppc64/kernel/misc.S +++ b/arch/ppc64/kernel/misc.S @@ -1124,9 +1124,11 @@ _GLOBAL(sys_call_table32) .llong .compat_sys_mq_getsetattr .llong .compat_sys_kexec_load .llong .sys32_add_key - .llong .sys32_request_key + .llong .sys32_request_key /* 270 */ .llong .compat_sys_keyctl .llong .compat_sys_waitid + .llong .sys32_ioprio_set + .llong .sys32_ioprio_get .balign 8 _GLOBAL(sys_call_table) @@ -1403,3 +1405,5 @@ _GLOBAL(sys_call_table) .llong .sys_request_key /* 270 */ .llong .sys_keyctl .llong .sys_waitid + .llong .sys_ioprio_set + .llong .sys_ioprio_get diff --git a/arch/ppc64/kernel/nvram.c b/arch/ppc64/kernel/nvram.c index 4e71781a4414..4fb1a9f5060d 100644 --- a/arch/ppc64/kernel/nvram.c +++ b/arch/ppc64/kernel/nvram.c @@ -338,9 +338,8 @@ static int nvram_remove_os_partition(void) */ static int nvram_create_os_partition(void) { - struct list_head * p; - struct nvram_partition *part = NULL; - struct nvram_partition *new_part = NULL; + struct nvram_partition *part; + struct nvram_partition *new_part; struct nvram_partition *free_part = NULL; int seq_init[2] = { 0, 0 }; loff_t tmp_index; @@ -349,8 +348,7 @@ static int nvram_create_os_partition(void) /* Find a free partition that will give us the maximum needed size If can't find one that will give us the minimum size needed */ - list_for_each(p, &nvram_part->partition) { - part = list_entry(p, struct nvram_partition, partition); + list_for_each_entry(part, &nvram_part->partition, partition) { if (part->header.signature != NVRAM_SIG_FREE) continue; diff --git a/arch/ppc64/kernel/of_device.c b/arch/ppc64/kernel/of_device.c index 66bd5ab7c25a..b80e81984ba8 100644 --- a/arch/ppc64/kernel/of_device.c +++ b/arch/ppc64/kernel/of_device.c @@ -3,6 +3,7 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <asm/errno.h> #include <asm/of_device.h> @@ -15,20 +16,20 @@ * Used by a driver to check whether an of_device present in the * system is in its list of supported devices. */ -const struct of_match * of_match_device(const struct of_match *matches, +const struct of_device_id *of_match_device(const struct of_device_id *matches, const struct of_device *dev) { if (!dev->node) return NULL; - while (matches->name || matches->type || matches->compatible) { + while (matches->name[0] || matches->type[0] || matches->compatible[0]) { int match = 1; - if (matches->name && matches->name != OF_ANY_MATCH) + if (matches->name[0]) match &= dev->node->name && !strcmp(matches->name, dev->node->name); - if (matches->type && matches->type != OF_ANY_MATCH) + if (matches->type[0]) match &= dev->node->type && !strcmp(matches->type, dev->node->type); - if (matches->compatible && matches->compatible != OF_ANY_MATCH) + if (matches->compatible[0]) match &= device_is_compatible(dev->node, matches->compatible); if (match) @@ -42,7 +43,7 @@ static int of_platform_bus_match(struct device *dev, struct device_driver *drv) { struct of_device * of_dev = to_of_device(dev); struct of_platform_driver * of_drv = to_of_platform_driver(drv); - const struct of_match * matches = of_drv->match_table; + const struct of_device_id * matches = of_drv->match_table; if (!matches) return 0; @@ -75,7 +76,7 @@ static int of_device_probe(struct device *dev) int error = -ENODEV; struct of_platform_driver *drv; struct of_device *of_dev; - const struct of_match *match; + const struct of_device_id *match; drv = to_of_platform_driver(dev->driver); of_dev = to_of_device(dev); diff --git a/arch/ppc64/kernel/pSeries_lpar.c b/arch/ppc64/kernel/pSeries_lpar.c index 6534812db437..74dd144dcce8 100644 --- a/arch/ppc64/kernel/pSeries_lpar.c +++ b/arch/ppc64/kernel/pSeries_lpar.c @@ -277,31 +277,20 @@ void vpa_init(int cpu) long pSeries_lpar_hpte_insert(unsigned long hpte_group, unsigned long va, unsigned long prpn, - int secondary, unsigned long hpteflags, - int bolted, int large) + unsigned long vflags, unsigned long rflags) { unsigned long arpn = physRpn_to_absRpn(prpn); unsigned long lpar_rc; unsigned long flags; unsigned long slot; - HPTE lhpte; + unsigned long hpte_v, hpte_r; unsigned long dummy0, dummy1; - /* Fill in the local HPTE with absolute rpn, avpn and flags */ - lhpte.dw1.dword1 = 0; - lhpte.dw1.dw1.rpn = arpn; - lhpte.dw1.flags.flags = hpteflags; + hpte_v = ((va >> 23) << HPTE_V_AVPN_SHIFT) | vflags | HPTE_V_VALID; + if (vflags & HPTE_V_LARGE) + hpte_v &= ~(1UL << HPTE_V_AVPN_SHIFT); - lhpte.dw0.dword0 = 0; - lhpte.dw0.dw0.avpn = va >> 23; - lhpte.dw0.dw0.h = secondary; - lhpte.dw0.dw0.bolted = bolted; - lhpte.dw0.dw0.v = 1; - - if (large) { - lhpte.dw0.dw0.l = 1; - lhpte.dw0.dw0.avpn &= ~0x1UL; - } + hpte_r = (arpn << HPTE_R_RPN_SHIFT) | rflags; /* Now fill in the actual HPTE */ /* Set CEC cookie to 0 */ @@ -312,11 +301,11 @@ long pSeries_lpar_hpte_insert(unsigned long hpte_group, flags = 0; /* XXX why is this here? - Anton */ - if (hpteflags & (_PAGE_GUARDED|_PAGE_NO_CACHE)) - lhpte.dw1.flags.flags &= ~_PAGE_COHERENT; + if (rflags & (_PAGE_GUARDED|_PAGE_NO_CACHE)) + hpte_r &= ~_PAGE_COHERENT; - lpar_rc = plpar_hcall(H_ENTER, flags, hpte_group, lhpte.dw0.dword0, - lhpte.dw1.dword1, &slot, &dummy0, &dummy1); + lpar_rc = plpar_hcall(H_ENTER, flags, hpte_group, hpte_v, + hpte_r, &slot, &dummy0, &dummy1); if (unlikely(lpar_rc == H_PTEG_Full)) return -1; @@ -332,7 +321,7 @@ long pSeries_lpar_hpte_insert(unsigned long hpte_group, /* Because of iSeries, we have to pass down the secondary * bucket bit here as well */ - return (slot & 7) | (secondary << 3); + return (slot & 7) | (!!(vflags & HPTE_V_SECONDARY) << 3); } static DEFINE_SPINLOCK(pSeries_lpar_tlbie_lock); @@ -427,22 +416,18 @@ static long pSeries_lpar_hpte_find(unsigned long vpn) unsigned long hash; unsigned long i, j; long slot; - union { - unsigned long dword0; - Hpte_dword0 dw0; - } hpte_dw0; - Hpte_dword0 dw0; + unsigned long hpte_v; hash = hpt_hash(vpn, 0); for (j = 0; j < 2; j++) { slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; for (i = 0; i < HPTES_PER_GROUP; i++) { - hpte_dw0.dword0 = pSeries_lpar_hpte_getword0(slot); - dw0 = hpte_dw0.dw0; + hpte_v = pSeries_lpar_hpte_getword0(slot); - if ((dw0.avpn == (vpn >> 11)) && dw0.v && - (dw0.h == j)) { + if ((HPTE_V_AVPN_VAL(hpte_v) == (vpn >> 11)) + && (hpte_v & HPTE_V_VALID) + && (!!(hpte_v & HPTE_V_SECONDARY) == j)) { /* HPTE matches */ if (j) slot = -slot; diff --git a/arch/ppc64/kernel/pSeries_setup.c b/arch/ppc64/kernel/pSeries_setup.c index 44d9af72d225..5bec956e44a0 100644 --- a/arch/ppc64/kernel/pSeries_setup.c +++ b/arch/ppc64/kernel/pSeries_setup.c @@ -19,6 +19,7 @@ #undef DEBUG #include <linux/config.h> +#include <linux/cpu.h> #include <linux/errno.h> #include <linux/sched.h> #include <linux/kernel.h> @@ -82,6 +83,9 @@ int fwnmi_active; /* TRUE if an FWNMI handler is present */ extern void pSeries_system_reset_exception(struct pt_regs *regs); extern int pSeries_machine_check_exception(struct pt_regs *regs); +static int pseries_shared_idle(void); +static int pseries_dedicated_idle(void); + static volatile void __iomem * chrp_int_ack_special; struct mpic *pSeries_mpic; @@ -229,6 +233,20 @@ static void __init pSeries_setup_arch(void) if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) vpa_init(boot_cpuid); + + /* Choose an idle loop */ + if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) { + if (get_paca()->lppaca.shared_proc) { + printk(KERN_INFO "Using shared processor idle loop\n"); + ppc_md.idle_loop = pseries_shared_idle; + } else { + printk(KERN_INFO "Using dedicated idle loop\n"); + ppc_md.idle_loop = pseries_dedicated_idle; + } + } else { + printk(KERN_INFO "Using default idle loop\n"); + ppc_md.idle_loop = default_idle; + } } static int __init pSeries_init_panel(void) @@ -418,6 +436,144 @@ static int __init pSeries_probe(int platform) return 1; } +DECLARE_PER_CPU(unsigned long, smt_snooze_delay); + +static inline void dedicated_idle_sleep(unsigned int cpu) +{ + struct paca_struct *ppaca = &paca[cpu ^ 1]; + + /* Only sleep if the other thread is not idle */ + if (!(ppaca->lppaca.idle)) { + local_irq_disable(); + + /* + * We are about to sleep the thread and so wont be polling any + * more. + */ + clear_thread_flag(TIF_POLLING_NRFLAG); + + /* + * SMT dynamic mode. Cede will result in this thread going + * dormant, if the partner thread is still doing work. Thread + * wakes up if partner goes idle, an interrupt is presented, or + * a prod occurs. Returning from the cede enables external + * interrupts. + */ + if (!need_resched()) + cede_processor(); + else + local_irq_enable(); + } else { + /* + * Give the HV an opportunity at the processor, since we are + * not doing any work. + */ + poll_pending(); + } +} + +static int pseries_dedicated_idle(void) +{ + long oldval; + struct paca_struct *lpaca = get_paca(); + unsigned int cpu = smp_processor_id(); + unsigned long start_snooze; + unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay); + + while (1) { + /* + * Indicate to the HV that we are idle. Now would be + * a good time to find other work to dispatch. + */ + lpaca->lppaca.idle = 1; + + oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED); + if (!oldval) { + set_thread_flag(TIF_POLLING_NRFLAG); + + start_snooze = __get_tb() + + *smt_snooze_delay * tb_ticks_per_usec; + + while (!need_resched() && !cpu_is_offline(cpu)) { + ppc64_runlatch_off(); + + /* + * Go into low thread priority and possibly + * low power mode. + */ + HMT_low(); + HMT_very_low(); + + if (*smt_snooze_delay != 0 && + __get_tb() > start_snooze) { + HMT_medium(); + dedicated_idle_sleep(cpu); + } + + } + + HMT_medium(); + clear_thread_flag(TIF_POLLING_NRFLAG); + } else { + set_need_resched(); + } + + lpaca->lppaca.idle = 0; + ppc64_runlatch_on(); + + schedule(); + + if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) + cpu_die(); + } +} + +static int pseries_shared_idle(void) +{ + struct paca_struct *lpaca = get_paca(); + unsigned int cpu = smp_processor_id(); + + while (1) { + /* + * Indicate to the HV that we are idle. Now would be + * a good time to find other work to dispatch. + */ + lpaca->lppaca.idle = 1; + + while (!need_resched() && !cpu_is_offline(cpu)) { + local_irq_disable(); + ppc64_runlatch_off(); + + /* + * Yield the processor to the hypervisor. We return if + * an external interrupt occurs (which are driven prior + * to returning here) or if a prod occurs from another + * processor. When returning here, external interrupts + * are enabled. + * + * Check need_resched() again with interrupts disabled + * to avoid a race. + */ + if (!need_resched()) + cede_processor(); + else + local_irq_enable(); + + HMT_medium(); + } + + lpaca->lppaca.idle = 0; + ppc64_runlatch_on(); + + schedule(); + + if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) + cpu_die(); + } + + return 0; +} + struct machdep_calls __initdata pSeries_md = { .probe = pSeries_probe, .setup_arch = pSeries_setup_arch, diff --git a/arch/ppc64/kernel/pacaData.c b/arch/ppc64/kernel/pacaData.c index a3e0975c26c1..6316188737b6 100644 --- a/arch/ppc64/kernel/pacaData.c +++ b/arch/ppc64/kernel/pacaData.c @@ -42,21 +42,7 @@ extern unsigned long __toc_start; * processors. The processor VPD array needs one entry per physical * processor (not thread). */ -#ifdef CONFIG_PPC_ISERIES -#define EXTRA_INITS(number, lpq) \ - .lppaca_ptr = &paca[number].lppaca, \ - .lpqueue_ptr = (lpq), /* &xItLpQueue, */ \ - .reg_save_ptr = &paca[number].reg_save, \ - .reg_save = { \ - .xDesc = 0xd397d9e2, /* "LpRS" */ \ - .xSize = sizeof(struct ItLpRegSave) \ - }, -#else -#define EXTRA_INITS(number, lpq) -#endif - -#define PACAINITDATA(number,start,lpq,asrr,asrv) \ -{ \ +#define PACA_INIT_COMMON(number, start, asrr, asrv) \ .lock_token = 0x8000, \ .paca_index = (number), /* Paca Index */ \ .default_decr = 0x00ff0000, /* Initial Decr */ \ @@ -74,147 +60,79 @@ extern unsigned long __toc_start; .end_of_quantum = 0xfffffffffffffffful, \ .slb_count = 64, \ }, \ - EXTRA_INITS((number), (lpq)) \ -} -struct paca_struct paca[] = { #ifdef CONFIG_PPC_ISERIES - PACAINITDATA( 0, 1, &xItLpQueue, 0, STAB0_VIRT_ADDR), +#define PACA_INIT_ISERIES(number) \ + .lppaca_ptr = &paca[number].lppaca, \ + .reg_save_ptr = &paca[number].reg_save, \ + .reg_save = { \ + .xDesc = 0xd397d9e2, /* "LpRS" */ \ + .xSize = sizeof(struct ItLpRegSave) \ + } + +#define PACA_INIT(number) \ +{ \ + PACA_INIT_COMMON(number, 0, 0, 0) \ + PACA_INIT_ISERIES(number) \ +} + +#define BOOTCPU_PACA_INIT(number) \ +{ \ + PACA_INIT_COMMON(number, 1, 0, STAB0_VIRT_ADDR) \ + PACA_INIT_ISERIES(number) \ +} + #else - PACAINITDATA( 0, 1, NULL, STAB0_PHYS_ADDR, STAB0_VIRT_ADDR), +#define PACA_INIT(number) \ +{ \ + PACA_INIT_COMMON(number, 0, 0, 0) \ +} + +#define BOOTCPU_PACA_INIT(number) \ +{ \ + PACA_INIT_COMMON(number, 1, STAB0_PHYS_ADDR, STAB0_VIRT_ADDR) \ +} #endif + +struct paca_struct paca[] = { + BOOTCPU_PACA_INIT(0), #if NR_CPUS > 1 - PACAINITDATA( 1, 0, NULL, 0, 0), - PACAINITDATA( 2, 0, NULL, 0, 0), - PACAINITDATA( 3, 0, NULL, 0, 0), + PACA_INIT( 1), PACA_INIT( 2), PACA_INIT( 3), #if NR_CPUS > 4 - PACAINITDATA( 4, 0, NULL, 0, 0), - PACAINITDATA( 5, 0, NULL, 0, 0), - PACAINITDATA( 6, 0, NULL, 0, 0), - PACAINITDATA( 7, 0, NULL, 0, 0), + PACA_INIT( 4), PACA_INIT( 5), PACA_INIT( 6), PACA_INIT( 7), #if NR_CPUS > 8 - PACAINITDATA( 8, 0, NULL, 0, 0), - PACAINITDATA( 9, 0, NULL, 0, 0), - PACAINITDATA(10, 0, NULL, 0, 0), - PACAINITDATA(11, 0, NULL, 0, 0), - PACAINITDATA(12, 0, NULL, 0, 0), - PACAINITDATA(13, 0, NULL, 0, 0), - PACAINITDATA(14, 0, NULL, 0, 0), - PACAINITDATA(15, 0, NULL, 0, 0), - PACAINITDATA(16, 0, NULL, 0, 0), - PACAINITDATA(17, 0, NULL, 0, 0), - PACAINITDATA(18, 0, NULL, 0, 0), - PACAINITDATA(19, 0, NULL, 0, 0), - PACAINITDATA(20, 0, NULL, 0, 0), - PACAINITDATA(21, 0, NULL, 0, 0), - PACAINITDATA(22, 0, NULL, 0, 0), - PACAINITDATA(23, 0, NULL, 0, 0), - PACAINITDATA(24, 0, NULL, 0, 0), - PACAINITDATA(25, 0, NULL, 0, 0), - PACAINITDATA(26, 0, NULL, 0, 0), - PACAINITDATA(27, 0, NULL, 0, 0), - PACAINITDATA(28, 0, NULL, 0, 0), - PACAINITDATA(29, 0, NULL, 0, 0), - PACAINITDATA(30, 0, NULL, 0, 0), - PACAINITDATA(31, 0, NULL, 0, 0), + PACA_INIT( 8), PACA_INIT( 9), PACA_INIT( 10), PACA_INIT( 11), + PACA_INIT( 12), PACA_INIT( 13), PACA_INIT( 14), PACA_INIT( 15), + PACA_INIT( 16), PACA_INIT( 17), PACA_INIT( 18), PACA_INIT( 19), + PACA_INIT( 20), PACA_INIT( 21), PACA_INIT( 22), PACA_INIT( 23), + PACA_INIT( 24), PACA_INIT( 25), PACA_INIT( 26), PACA_INIT( 27), + PACA_INIT( 28), PACA_INIT( 29), PACA_INIT( 30), PACA_INIT( 31), #if NR_CPUS > 32 - PACAINITDATA(32, 0, NULL, 0, 0), - PACAINITDATA(33, 0, NULL, 0, 0), - PACAINITDATA(34, 0, NULL, 0, 0), - PACAINITDATA(35, 0, NULL, 0, 0), - PACAINITDATA(36, 0, NULL, 0, 0), - PACAINITDATA(37, 0, NULL, 0, 0), - PACAINITDATA(38, 0, NULL, 0, 0), - PACAINITDATA(39, 0, NULL, 0, 0), - PACAINITDATA(40, 0, NULL, 0, 0), - PACAINITDATA(41, 0, NULL, 0, 0), - PACAINITDATA(42, 0, NULL, 0, 0), - PACAINITDATA(43, 0, NULL, 0, 0), - PACAINITDATA(44, 0, NULL, 0, 0), - PACAINITDATA(45, 0, NULL, 0, 0), - PACAINITDATA(46, 0, NULL, 0, 0), - PACAINITDATA(47, 0, NULL, 0, 0), - PACAINITDATA(48, 0, NULL, 0, 0), - PACAINITDATA(49, 0, NULL, 0, 0), - PACAINITDATA(50, 0, NULL, 0, 0), - PACAINITDATA(51, 0, NULL, 0, 0), - PACAINITDATA(52, 0, NULL, 0, 0), - PACAINITDATA(53, 0, NULL, 0, 0), - PACAINITDATA(54, 0, NULL, 0, 0), - PACAINITDATA(55, 0, NULL, 0, 0), - PACAINITDATA(56, 0, NULL, 0, 0), - PACAINITDATA(57, 0, NULL, 0, 0), - PACAINITDATA(58, 0, NULL, 0, 0), - PACAINITDATA(59, 0, NULL, 0, 0), - PACAINITDATA(60, 0, NULL, 0, 0), - PACAINITDATA(61, 0, NULL, 0, 0), - PACAINITDATA(62, 0, NULL, 0, 0), - PACAINITDATA(63, 0, NULL, 0, 0), + PACA_INIT( 32), PACA_INIT( 33), PACA_INIT( 34), PACA_INIT( 35), + PACA_INIT( 36), PACA_INIT( 37), PACA_INIT( 38), PACA_INIT( 39), + PACA_INIT( 40), PACA_INIT( 41), PACA_INIT( 42), PACA_INIT( 43), + PACA_INIT( 44), PACA_INIT( 45), PACA_INIT( 46), PACA_INIT( 47), + PACA_INIT( 48), PACA_INIT( 49), PACA_INIT( 50), PACA_INIT( 51), + PACA_INIT( 52), PACA_INIT( 53), PACA_INIT( 54), PACA_INIT( 55), + PACA_INIT( 56), PACA_INIT( 57), PACA_INIT( 58), PACA_INIT( 59), + PACA_INIT( 60), PACA_INIT( 61), PACA_INIT( 62), PACA_INIT( 63), #if NR_CPUS > 64 - PACAINITDATA(64, 0, NULL, 0, 0), - PACAINITDATA(65, 0, NULL, 0, 0), - PACAINITDATA(66, 0, NULL, 0, 0), - PACAINITDATA(67, 0, NULL, 0, 0), - PACAINITDATA(68, 0, NULL, 0, 0), - PACAINITDATA(69, 0, NULL, 0, 0), - PACAINITDATA(70, 0, NULL, 0, 0), - PACAINITDATA(71, 0, NULL, 0, 0), - PACAINITDATA(72, 0, NULL, 0, 0), - PACAINITDATA(73, 0, NULL, 0, 0), - PACAINITDATA(74, 0, NULL, 0, 0), - PACAINITDATA(75, 0, NULL, 0, 0), - PACAINITDATA(76, 0, NULL, 0, 0), - PACAINITDATA(77, 0, NULL, 0, 0), - PACAINITDATA(78, 0, NULL, 0, 0), - PACAINITDATA(79, 0, NULL, 0, 0), - PACAINITDATA(80, 0, NULL, 0, 0), - PACAINITDATA(81, 0, NULL, 0, 0), - PACAINITDATA(82, 0, NULL, 0, 0), - PACAINITDATA(83, 0, NULL, 0, 0), - PACAINITDATA(84, 0, NULL, 0, 0), - PACAINITDATA(85, 0, NULL, 0, 0), - PACAINITDATA(86, 0, NULL, 0, 0), - PACAINITDATA(87, 0, NULL, 0, 0), - PACAINITDATA(88, 0, NULL, 0, 0), - PACAINITDATA(89, 0, NULL, 0, 0), - PACAINITDATA(90, 0, NULL, 0, 0), - PACAINITDATA(91, 0, NULL, 0, 0), - PACAINITDATA(92, 0, NULL, 0, 0), - PACAINITDATA(93, 0, NULL, 0, 0), - PACAINITDATA(94, 0, NULL, 0, 0), - PACAINITDATA(95, 0, NULL, 0, 0), - PACAINITDATA(96, 0, NULL, 0, 0), - PACAINITDATA(97, 0, NULL, 0, 0), - PACAINITDATA(98, 0, NULL, 0, 0), - PACAINITDATA(99, 0, NULL, 0, 0), - PACAINITDATA(100, 0, NULL, 0, 0), - PACAINITDATA(101, 0, NULL, 0, 0), - PACAINITDATA(102, 0, NULL, 0, 0), - PACAINITDATA(103, 0, NULL, 0, 0), - PACAINITDATA(104, 0, NULL, 0, 0), - PACAINITDATA(105, 0, NULL, 0, 0), - PACAINITDATA(106, 0, NULL, 0, 0), - PACAINITDATA(107, 0, NULL, 0, 0), - PACAINITDATA(108, 0, NULL, 0, 0), - PACAINITDATA(109, 0, NULL, 0, 0), - PACAINITDATA(110, 0, NULL, 0, 0), - PACAINITDATA(111, 0, NULL, 0, 0), - PACAINITDATA(112, 0, NULL, 0, 0), - PACAINITDATA(113, 0, NULL, 0, 0), - PACAINITDATA(114, 0, NULL, 0, 0), - PACAINITDATA(115, 0, NULL, 0, 0), - PACAINITDATA(116, 0, NULL, 0, 0), - PACAINITDATA(117, 0, NULL, 0, 0), - PACAINITDATA(118, 0, NULL, 0, 0), - PACAINITDATA(119, 0, NULL, 0, 0), - PACAINITDATA(120, 0, NULL, 0, 0), - PACAINITDATA(121, 0, NULL, 0, 0), - PACAINITDATA(122, 0, NULL, 0, 0), - PACAINITDATA(123, 0, NULL, 0, 0), - PACAINITDATA(124, 0, NULL, 0, 0), - PACAINITDATA(125, 0, NULL, 0, 0), - PACAINITDATA(126, 0, NULL, 0, 0), - PACAINITDATA(127, 0, NULL, 0, 0), + PACA_INIT( 64), PACA_INIT( 65), PACA_INIT( 66), PACA_INIT( 67), + PACA_INIT( 68), PACA_INIT( 69), PACA_INIT( 70), PACA_INIT( 71), + PACA_INIT( 72), PACA_INIT( 73), PACA_INIT( 74), PACA_INIT( 75), + PACA_INIT( 76), PACA_INIT( 77), PACA_INIT( 78), PACA_INIT( 79), + PACA_INIT( 80), PACA_INIT( 81), PACA_INIT( 82), PACA_INIT( 83), + PACA_INIT( 84), PACA_INIT( 85), PACA_INIT( 86), PACA_INIT( 87), + PACA_INIT( 88), PACA_INIT( 89), PACA_INIT( 90), PACA_INIT( 91), + PACA_INIT( 92), PACA_INIT( 93), PACA_INIT( 94), PACA_INIT( 95), + PACA_INIT( 96), PACA_INIT( 97), PACA_INIT( 98), PACA_INIT( 99), + PACA_INIT(100), PACA_INIT(101), PACA_INIT(102), PACA_INIT(103), + PACA_INIT(104), PACA_INIT(105), PACA_INIT(106), PACA_INIT(107), + PACA_INIT(108), PACA_INIT(109), PACA_INIT(110), PACA_INIT(111), + PACA_INIT(112), PACA_INIT(113), PACA_INIT(114), PACA_INIT(115), + PACA_INIT(116), PACA_INIT(117), PACA_INIT(118), PACA_INIT(119), + PACA_INIT(120), PACA_INIT(121), PACA_INIT(122), PACA_INIT(123), + PACA_INIT(124), PACA_INIT(125), PACA_INIT(126), PACA_INIT(127), #endif #endif #endif diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c index 580676f87d23..ae6f579d3fa0 100644 --- a/arch/ppc64/kernel/pci.c +++ b/arch/ppc64/kernel/pci.c @@ -351,7 +351,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, *offset += hose->pci_mem_offset; res_bit = IORESOURCE_MEM; } else { - io_offset = (unsigned long)hose->io_base_virt; + io_offset = (unsigned long)hose->io_base_virt - pci_io_base; *offset += io_offset; res_bit = IORESOURCE_IO; } @@ -378,7 +378,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, /* found it! construct the final physical address */ if (mmap_state == pci_mmap_io) - *offset += hose->io_base_phys - io_offset; + *offset += hose->io_base_phys - io_offset; return rp; } @@ -944,4 +944,22 @@ int pci_read_irq_line(struct pci_dev *pci_dev) } EXPORT_SYMBOL(pci_read_irq_line); +void pci_resource_to_user(const struct pci_dev *dev, int bar, + const struct resource *rsrc, + u64 *start, u64 *end) +{ + struct pci_controller *hose = pci_bus_to_host(dev->bus); + unsigned long offset = 0; + + if (hose == NULL) + return; + + if (rsrc->flags & IORESOURCE_IO) + offset = pci_io_base - (unsigned long)hose->io_base_virt + + hose->io_base_phys; + + *start = rsrc->start + offset; + *end = rsrc->end + offset; +} + #endif /* CONFIG_PPC_MULTIPLATFORM */ diff --git a/arch/ppc64/kernel/pmac_setup.c b/arch/ppc64/kernel/pmac_setup.c index 6cf03d387b91..3013cdb5f933 100644 --- a/arch/ppc64/kernel/pmac_setup.c +++ b/arch/ppc64/kernel/pmac_setup.c @@ -186,6 +186,8 @@ void __init pmac_setup_arch(void) #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; #endif + + printk(KERN_INFO "Using native/NAP idle loop\n"); } #ifdef CONFIG_SCSI @@ -507,5 +509,6 @@ struct machdep_calls __initdata pmac_md = { .calibrate_decr = pmac_calibrate_decr, .feature_call = pmac_do_feature_call, .progress = pmac_progress, - .check_legacy_ioport = pmac_check_legacy_ioport + .check_legacy_ioport = pmac_check_legacy_ioport, + .idle_loop = native_idle, }; diff --git a/arch/ppc64/kernel/ppc_ksyms.c b/arch/ppc64/kernel/ppc_ksyms.c index b230a63fe4c8..705742f4eec6 100644 --- a/arch/ppc64/kernel/ppc_ksyms.c +++ b/arch/ppc64/kernel/ppc_ksyms.c @@ -75,6 +75,7 @@ EXPORT_SYMBOL(giveup_fpu); EXPORT_SYMBOL(giveup_altivec); #endif EXPORT_SYMBOL(__flush_icache_range); +EXPORT_SYMBOL(flush_dcache_range); #ifdef CONFIG_SMP #ifdef CONFIG_PPC_ISERIES diff --git a/arch/ppc64/kernel/process.c b/arch/ppc64/kernel/process.c index aba89554d89d..f7cae05e40fb 100644 --- a/arch/ppc64/kernel/process.c +++ b/arch/ppc64/kernel/process.c @@ -36,6 +36,7 @@ #include <linux/kallsyms.h> #include <linux/interrupt.h> #include <linux/utsname.h> +#include <linux/kprobes.h> #include <asm/pgtable.h> #include <asm/uaccess.h> @@ -307,6 +308,8 @@ void show_regs(struct pt_regs * regs) void exit_thread(void) { + kprobe_flush_task(current); + #ifndef CONFIG_SMP if (last_task_used_math == current) last_task_used_math = NULL; @@ -321,6 +324,7 @@ void flush_thread(void) { struct thread_info *t = current_thread_info(); + kprobe_flush_task(current); if (t->flags & _TIF_ABI_PENDING) t->flags ^= (_TIF_ABI_PENDING | _TIF_32BIT); diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c index d5e4866e9ac2..d1b33f0b26cb 100644 --- a/arch/ppc64/kernel/setup.c +++ b/arch/ppc64/kernel/setup.c @@ -96,7 +96,6 @@ extern void udbg_init_maple_realmode(void); extern unsigned long klimit; extern void mm_init_ppc64(void); -extern int idle_setup(void); extern void stab_initialize(unsigned long stab); extern void htab_initialize(void); extern void early_init_devtree(void *flat_dt); @@ -1081,8 +1080,11 @@ void __init setup_arch(char **cmdline_p) ppc_md.setup_arch(); - /* Select the correct idle loop for the platform. */ - idle_setup(); + /* Use the default idle loop if the platform hasn't provided one. */ + if (NULL == ppc_md.idle_loop) { + ppc_md.idle_loop = default_idle; + printk(KERN_INFO "Using default idle loop\n"); + } paging_init(); ppc64_boot_msg(0x15, "Setup Done"); diff --git a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c index 118436e8085a..206619080e66 100644 --- a/arch/ppc64/kernel/sys_ppc32.c +++ b/arch/ppc64/kernel/sys_ppc32.c @@ -30,47 +30,26 @@ #include <linux/sem.h> #include <linux/msg.h> #include <linux/shm.h> -#include <linux/slab.h> -#include <linux/uio.h> -#include <linux/aio.h> -#include <linux/nfs_fs.h> -#include <linux/module.h> -#include <linux/sunrpc/svc.h> -#include <linux/nfsd/nfsd.h> -#include <linux/nfsd/cache.h> -#include <linux/nfsd/xdr.h> -#include <linux/nfsd/syscall.h> #include <linux/poll.h> #include <linux/personality.h> #include <linux/stat.h> -#include <linux/filter.h> -#include <linux/highmem.h> -#include <linux/highuid.h> #include <linux/mman.h> -#include <linux/ipv6.h> #include <linux/in.h> -#include <linux/icmpv6.h> #include <linux/syscalls.h> #include <linux/unistd.h> #include <linux/sysctl.h> #include <linux/binfmts.h> -#include <linux/dnotify.h> #include <linux/security.h> #include <linux/compat.h> #include <linux/ptrace.h> -#include <linux/aio_abi.h> #include <linux/elf.h> -#include <net/scm.h> -#include <net/sock.h> - #include <asm/ptrace.h> #include <asm/types.h> #include <asm/ipc.h> #include <asm/uaccess.h> #include <asm/unistd.h> #include <asm/semaphore.h> -#include <asm/ppcdebug.h> #include <asm/time.h> #include <asm/mmu_context.h> #include <asm/systemcfg.h> @@ -350,8 +329,6 @@ asmlinkage long sys32_adjtimex(struct timex32 __user *utp) return ret; } - -/* These are here just in case some old sparc32 binary calls it. */ asmlinkage long sys32_pause(void) { current->state = TASK_INTERRUPTIBLE; @@ -360,8 +337,6 @@ asmlinkage long sys32_pause(void) return -ERESTARTNOHAND; } - - static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i) { long usec; @@ -847,16 +822,6 @@ asmlinkage long sys32_getpgid(u32 pid) } -/* Note: it is necessary to treat which and who as unsigned ints, - * with the corresponding cast to a signed int to insure that the - * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) - * and the register representation of a signed int (msr in 64-bit mode) is performed. - */ -asmlinkage long sys32_getpriority(u32 which, u32 who) -{ - return sys_getpriority((int)which, (int)who); -} - /* Note: it is necessary to treat pid as an unsigned int, * with the corresponding cast to a signed int to insure that the @@ -1048,6 +1013,11 @@ asmlinkage long sys32_setpgid(u32 pid, u32 pgid) return sys_setpgid((int)pid, (int)pgid); } +long sys32_getpriority(u32 which, u32 who) +{ + /* sign extend which and who */ + return sys_getpriority((int)which, (int)who); +} long sys32_setpriority(u32 which, u32 who, u32 niceval) { @@ -1055,6 +1025,18 @@ long sys32_setpriority(u32 which, u32 who, u32 niceval) return sys_setpriority((int)which, (int)who, (int)niceval); } +long sys32_ioprio_get(u32 which, u32 who) +{ + /* sign extend which and who */ + return sys_ioprio_get((int)which, (int)who); +} + +long sys32_ioprio_set(u32 which, u32 who, u32 ioprio) +{ + /* sign extend which, who and ioprio */ + return sys_ioprio_set((int)which, (int)who, (int)ioprio); +} + /* Note: it is necessary to treat newmask as an unsigned int, * with the corresponding cast to a signed int to insure that the * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) @@ -1273,8 +1255,6 @@ long ppc32_fadvise64_64(int fd, int advice, u32 offset_high, u32 offset_low, (u64)len_high << 32 | len_low, advice); } -extern asmlinkage long sys_timer_create(clockid_t, sigevent_t __user *, timer_t __user *); - long ppc32_timer_create(clockid_t clock, struct compat_sigevent __user *ev32, timer_t __user *timer_id) diff --git a/arch/ppc64/kernel/sysfs.c b/arch/ppc64/kernel/sysfs.c index c8fa6569b2fd..02b8ac4e0168 100644 --- a/arch/ppc64/kernel/sysfs.c +++ b/arch/ppc64/kernel/sysfs.c @@ -112,7 +112,6 @@ void ppc64_enable_pmcs(void) unsigned long hid0; #ifdef CONFIG_PPC_PSERIES unsigned long set, reset; - int ret; #endif /* CONFIG_PPC_PSERIES */ /* Only need to enable them once */ @@ -145,11 +144,7 @@ void ppc64_enable_pmcs(void) case PLATFORM_PSERIES_LPAR: set = 1UL << 63; reset = 0; - ret = plpar_hcall_norets(H_PERFMON, set, reset); - if (ret) - printk(KERN_ERR "H_PERFMON call on cpu %u " - "returned %d\n", - smp_processor_id(), ret); + plpar_hcall_norets(H_PERFMON, set, reset); break; #endif /* CONFIG_PPC_PSERIES */ @@ -161,13 +156,6 @@ void ppc64_enable_pmcs(void) /* instruct hypervisor to maintain PMCs */ if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) get_paca()->lppaca.pmcregs_in_use = 1; - - /* - * On SMT machines we have to set the run latch in the ctrl register - * in order to make PMC6 spin. - */ - if (cpu_has_feature(CPU_FTR_SMT)) - ppc64_runlatch_on(); #endif /* CONFIG_PPC_PSERIES */ } @@ -400,7 +388,12 @@ static int __init topology_init(void) struct cpu *c = &per_cpu(cpu_devices, cpu); #ifdef CONFIG_NUMA - parent = &node_devices[cpu_to_node(cpu)]; + /* The node to which a cpu belongs can't be known + * until the cpu is made present. + */ + parent = NULL; + if (cpu_present(cpu)) + parent = &node_devices[cpu_to_node(cpu)]; #endif /* * For now, we just see if the system supports making diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c index 2348a75e050d..909462e1adea 100644 --- a/arch/ppc64/kernel/time.c +++ b/arch/ppc64/kernel/time.c @@ -91,6 +91,7 @@ unsigned long tb_to_xs; unsigned tb_to_us; unsigned long processor_freq; DEFINE_SPINLOCK(rtc_lock); +EXPORT_SYMBOL_GPL(rtc_lock); unsigned long tb_to_ns_scale; unsigned long tb_to_ns_shift; @@ -98,7 +99,6 @@ unsigned long tb_to_ns_shift; struct gettimeofday_struct do_gtod; extern unsigned long wall_jiffies; -extern unsigned long lpevent_count; extern int smp_tb_synchronized; extern struct timezone sys_tz; @@ -366,11 +366,8 @@ int timer_interrupt(struct pt_regs * regs) set_dec(next_dec); #ifdef CONFIG_PPC_ISERIES - { - struct ItLpQueue *lpq = lpaca->lpqueue_ptr; - if (lpq && ItLpQueue_isLpIntPending(lpq)) - lpevent_count += ItLpQueue_process(lpq, regs); - } + if (hvlpevent_is_pending()) + process_hvlpevents(regs); #endif /* collect purr register values often, for accurate calculations */ diff --git a/arch/ppc64/kernel/vdso32/vdso32.lds.S b/arch/ppc64/kernel/vdso32/vdso32.lds.S index 11290c902ba3..6f87a916a394 100644 --- a/arch/ppc64/kernel/vdso32/vdso32.lds.S +++ b/arch/ppc64/kernel/vdso32/vdso32.lds.S @@ -40,9 +40,9 @@ SECTIONS .gcc_except_table : { *(.gcc_except_table) } .fixup : { *(.fixup) } - .got ALIGN(4) : { *(.got.plt) *(.got) } - .dynamic : { *(.dynamic) } :text :dynamic + .got : { *(.got) } + .plt : { *(.plt) } _end = .; __end = .; diff --git a/arch/ppc64/mm/hash_low.S b/arch/ppc64/mm/hash_low.S index c23d46956dd9..fbff24827ae7 100644 --- a/arch/ppc64/mm/hash_low.S +++ b/arch/ppc64/mm/hash_low.S @@ -170,9 +170,7 @@ htab_insert_pte: /* Call ppc_md.hpte_insert */ ld r7,STK_PARM(r4)(r1) /* Retreive new pp bits */ mr r4,r29 /* Retreive va */ - li r6,0 /* primary slot */ - li r8,0 /* not bolted and not large */ - li r9,0 + li r6,0 /* no vflags */ _GLOBAL(htab_call_hpte_insert1) bl . /* Will be patched by htab_finish_init() */ cmpdi 0,r3,0 @@ -192,9 +190,7 @@ _GLOBAL(htab_call_hpte_insert1) /* Call ppc_md.hpte_insert */ ld r7,STK_PARM(r4)(r1) /* Retreive new pp bits */ mr r4,r29 /* Retreive va */ - li r6,1 /* secondary slot */ - li r8,0 /* not bolted and not large */ - li r9,0 + li r6,HPTE_V_SECONDARY@l /* secondary slot */ _GLOBAL(htab_call_hpte_insert2) bl . /* Will be patched by htab_finish_init() */ cmpdi 0,r3,0 diff --git a/arch/ppc64/mm/hash_native.c b/arch/ppc64/mm/hash_native.c index 4fec05817d66..a6abd3a979bf 100644 --- a/arch/ppc64/mm/hash_native.c +++ b/arch/ppc64/mm/hash_native.c @@ -27,9 +27,9 @@ static DEFINE_SPINLOCK(native_tlbie_lock); -static inline void native_lock_hpte(HPTE *hptep) +static inline void native_lock_hpte(hpte_t *hptep) { - unsigned long *word = &hptep->dw0.dword0; + unsigned long *word = &hptep->v; while (1) { if (!test_and_set_bit(HPTE_LOCK_BIT, word)) @@ -39,32 +39,28 @@ static inline void native_lock_hpte(HPTE *hptep) } } -static inline void native_unlock_hpte(HPTE *hptep) +static inline void native_unlock_hpte(hpte_t *hptep) { - unsigned long *word = &hptep->dw0.dword0; + unsigned long *word = &hptep->v; asm volatile("lwsync":::"memory"); clear_bit(HPTE_LOCK_BIT, word); } long native_hpte_insert(unsigned long hpte_group, unsigned long va, - unsigned long prpn, int secondary, - unsigned long hpteflags, int bolted, int large) + unsigned long prpn, unsigned long vflags, + unsigned long rflags) { unsigned long arpn = physRpn_to_absRpn(prpn); - HPTE *hptep = htab_address + hpte_group; - Hpte_dword0 dw0; - HPTE lhpte; + hpte_t *hptep = htab_address + hpte_group; + unsigned long hpte_v, hpte_r; int i; for (i = 0; i < HPTES_PER_GROUP; i++) { - dw0 = hptep->dw0.dw0; - - if (!dw0.v) { + if (! (hptep->v & HPTE_V_VALID)) { /* retry with lock held */ native_lock_hpte(hptep); - dw0 = hptep->dw0.dw0; - if (!dw0.v) + if (! (hptep->v & HPTE_V_VALID)) break; native_unlock_hpte(hptep); } @@ -75,56 +71,45 @@ long native_hpte_insert(unsigned long hpte_group, unsigned long va, if (i == HPTES_PER_GROUP) return -1; - lhpte.dw1.dword1 = 0; - lhpte.dw1.dw1.rpn = arpn; - lhpte.dw1.flags.flags = hpteflags; - - lhpte.dw0.dword0 = 0; - lhpte.dw0.dw0.avpn = va >> 23; - lhpte.dw0.dw0.h = secondary; - lhpte.dw0.dw0.bolted = bolted; - lhpte.dw0.dw0.v = 1; - - if (large) { - lhpte.dw0.dw0.l = 1; - lhpte.dw0.dw0.avpn &= ~0x1UL; - } - - hptep->dw1.dword1 = lhpte.dw1.dword1; + hpte_v = (va >> 23) << HPTE_V_AVPN_SHIFT | vflags | HPTE_V_VALID; + if (vflags & HPTE_V_LARGE) + va &= ~(1UL << HPTE_V_AVPN_SHIFT); + hpte_r = (arpn << HPTE_R_RPN_SHIFT) | rflags; + hptep->r = hpte_r; /* Guarantee the second dword is visible before the valid bit */ __asm__ __volatile__ ("eieio" : : : "memory"); - /* * Now set the first dword including the valid bit * NOTE: this also unlocks the hpte */ - hptep->dw0.dword0 = lhpte.dw0.dword0; + hptep->v = hpte_v; __asm__ __volatile__ ("ptesync" : : : "memory"); - return i | (secondary << 3); + return i | (!!(vflags & HPTE_V_SECONDARY) << 3); } static long native_hpte_remove(unsigned long hpte_group) { - HPTE *hptep; - Hpte_dword0 dw0; + hpte_t *hptep; int i; int slot_offset; + unsigned long hpte_v; /* pick a random entry to start at */ slot_offset = mftb() & 0x7; for (i = 0; i < HPTES_PER_GROUP; i++) { hptep = htab_address + hpte_group + slot_offset; - dw0 = hptep->dw0.dw0; + hpte_v = hptep->v; - if (dw0.v && !dw0.bolted) { + if ((hpte_v & HPTE_V_VALID) && !(hpte_v & HPTE_V_BOLTED)) { /* retry with lock held */ native_lock_hpte(hptep); - dw0 = hptep->dw0.dw0; - if (dw0.v && !dw0.bolted) + hpte_v = hptep->v; + if ((hpte_v & HPTE_V_VALID) + && !(hpte_v & HPTE_V_BOLTED)) break; native_unlock_hpte(hptep); } @@ -137,15 +122,15 @@ static long native_hpte_remove(unsigned long hpte_group) return -1; /* Invalidate the hpte. NOTE: this also unlocks it */ - hptep->dw0.dword0 = 0; + hptep->v = 0; return i; } -static inline void set_pp_bit(unsigned long pp, HPTE *addr) +static inline void set_pp_bit(unsigned long pp, hpte_t *addr) { unsigned long old; - unsigned long *p = &addr->dw1.dword1; + unsigned long *p = &addr->r; __asm__ __volatile__( "1: ldarx %0,0,%3\n\ @@ -163,11 +148,11 @@ static inline void set_pp_bit(unsigned long pp, HPTE *addr) */ static long native_hpte_find(unsigned long vpn) { - HPTE *hptep; + hpte_t *hptep; unsigned long hash; unsigned long i, j; long slot; - Hpte_dword0 dw0; + unsigned long hpte_v; hash = hpt_hash(vpn, 0); @@ -175,10 +160,11 @@ static long native_hpte_find(unsigned long vpn) slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; for (i = 0; i < HPTES_PER_GROUP; i++) { hptep = htab_address + slot; - dw0 = hptep->dw0.dw0; + hpte_v = hptep->v; - if ((dw0.avpn == (vpn >> 11)) && dw0.v && - (dw0.h == j)) { + if ((HPTE_V_AVPN_VAL(hpte_v) == (vpn >> 11)) + && (hpte_v & HPTE_V_VALID) + && ( !!(hpte_v & HPTE_V_SECONDARY) == j)) { /* HPTE matches */ if (j) slot = -slot; @@ -195,20 +181,21 @@ static long native_hpte_find(unsigned long vpn) static long native_hpte_updatepp(unsigned long slot, unsigned long newpp, unsigned long va, int large, int local) { - HPTE *hptep = htab_address + slot; - Hpte_dword0 dw0; + hpte_t *hptep = htab_address + slot; + unsigned long hpte_v; unsigned long avpn = va >> 23; int ret = 0; if (large) - avpn &= ~0x1UL; + avpn &= ~1; native_lock_hpte(hptep); - dw0 = hptep->dw0.dw0; + hpte_v = hptep->v; /* Even if we miss, we need to invalidate the TLB */ - if ((dw0.avpn != avpn) || !dw0.v) { + if ((HPTE_V_AVPN_VAL(hpte_v) != avpn) + || !(hpte_v & HPTE_V_VALID)) { native_unlock_hpte(hptep); ret = -1; } else { @@ -244,7 +231,7 @@ static void native_hpte_updateboltedpp(unsigned long newpp, unsigned long ea) { unsigned long vsid, va, vpn, flags = 0; long slot; - HPTE *hptep; + hpte_t *hptep; int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE); vsid = get_kernel_vsid(ea); @@ -269,26 +256,27 @@ static void native_hpte_updateboltedpp(unsigned long newpp, unsigned long ea) static void native_hpte_invalidate(unsigned long slot, unsigned long va, int large, int local) { - HPTE *hptep = htab_address + slot; - Hpte_dword0 dw0; + hpte_t *hptep = htab_address + slot; + unsigned long hpte_v; unsigned long avpn = va >> 23; unsigned long flags; int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE); if (large) - avpn &= ~0x1UL; + avpn &= ~1; local_irq_save(flags); native_lock_hpte(hptep); - dw0 = hptep->dw0.dw0; + hpte_v = hptep->v; /* Even if we miss, we need to invalidate the TLB */ - if ((dw0.avpn != avpn) || !dw0.v) { + if ((HPTE_V_AVPN_VAL(hpte_v) != avpn) + || !(hpte_v & HPTE_V_VALID)) { native_unlock_hpte(hptep); } else { /* Invalidate the hpte. NOTE: this also unlocks it */ - hptep->dw0.dword0 = 0; + hptep->v = 0; } /* Invalidate the tlb */ @@ -315,8 +303,8 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long va, static void native_hpte_clear(void) { unsigned long slot, slots, flags; - HPTE *hptep = htab_address; - Hpte_dword0 dw0; + hpte_t *hptep = htab_address; + unsigned long hpte_v; unsigned long pteg_count; pteg_count = htab_hash_mask + 1; @@ -336,11 +324,11 @@ static void native_hpte_clear(void) * running, right? and for crash dump, we probably * don't want to wait for a maybe bad cpu. */ - dw0 = hptep->dw0.dw0; + hpte_v = hptep->v; - if (dw0.v) { - hptep->dw0.dword0 = 0; - tlbie(slot2va(dw0.avpn, dw0.l, dw0.h, slot), dw0.l); + if (hpte_v & HPTE_V_VALID) { + hptep->v = 0; + tlbie(slot2va(hpte_v, slot), hpte_v & HPTE_V_LARGE); } } @@ -353,8 +341,8 @@ static void native_flush_hash_range(unsigned long context, { unsigned long vsid, vpn, va, hash, secondary, slot, flags, avpn; int i, j; - HPTE *hptep; - Hpte_dword0 dw0; + hpte_t *hptep; + unsigned long hpte_v; struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch); /* XXX fix for large ptes */ @@ -390,14 +378,15 @@ static void native_flush_hash_range(unsigned long context, native_lock_hpte(hptep); - dw0 = hptep->dw0.dw0; + hpte_v = hptep->v; /* Even if we miss, we need to invalidate the TLB */ - if ((dw0.avpn != avpn) || !dw0.v) { + if ((HPTE_V_AVPN_VAL(hpte_v) != avpn) + || !(hpte_v & HPTE_V_VALID)) { native_unlock_hpte(hptep); } else { /* Invalidate the hpte. NOTE: this also unlocks it */ - hptep->dw0.dword0 = 0; + hptep->v = 0; } j++; diff --git a/arch/ppc64/mm/hash_utils.c b/arch/ppc64/mm/hash_utils.c index 1647b1c6f28e..623b5d130c31 100644 --- a/arch/ppc64/mm/hash_utils.c +++ b/arch/ppc64/mm/hash_utils.c @@ -75,8 +75,8 @@ extern unsigned long dart_tablebase; #endif /* CONFIG_U3_DART */ -HPTE *htab_address; -unsigned long htab_hash_mask; +hpte_t *htab_address; +unsigned long htab_hash_mask; extern unsigned long _SDR1; @@ -97,11 +97,15 @@ static inline void create_pte_mapping(unsigned long start, unsigned long end, unsigned long addr; unsigned int step; unsigned long tmp_mode; + unsigned long vflags; - if (large) + if (large) { step = 16*MB; - else + vflags = HPTE_V_BOLTED | HPTE_V_LARGE; + } else { step = 4*KB; + vflags = HPTE_V_BOLTED; + } for (addr = start; addr < end; addr += step) { unsigned long vpn, hash, hpteg; @@ -129,12 +133,12 @@ static inline void create_pte_mapping(unsigned long start, unsigned long end, if (systemcfg->platform & PLATFORM_LPAR) ret = pSeries_lpar_hpte_insert(hpteg, va, virt_to_abs(addr) >> PAGE_SHIFT, - 0, tmp_mode, 1, large); + vflags, tmp_mode); else #endif /* CONFIG_PPC_PSERIES */ ret = native_hpte_insert(hpteg, va, virt_to_abs(addr) >> PAGE_SHIFT, - 0, tmp_mode, 1, large); + vflags, tmp_mode); if (ret == -1) { ppc64_terminate_msg(0x20, "create_pte_mapping"); diff --git a/arch/ppc64/mm/hugetlbpage.c b/arch/ppc64/mm/hugetlbpage.c index fdcfe97c75c1..f9524602818d 100644 --- a/arch/ppc64/mm/hugetlbpage.c +++ b/arch/ppc64/mm/hugetlbpage.c @@ -583,7 +583,7 @@ int hash_huge_page(struct mm_struct *mm, unsigned long access, pte_t *ptep; unsigned long va, vpn; pte_t old_pte, new_pte; - unsigned long hpteflags, prpn; + unsigned long rflags, prpn; long slot; int err = 1; @@ -626,9 +626,9 @@ int hash_huge_page(struct mm_struct *mm, unsigned long access, old_pte = *ptep; new_pte = old_pte; - hpteflags = 0x2 | (! (pte_val(new_pte) & _PAGE_RW)); + rflags = 0x2 | (! (pte_val(new_pte) & _PAGE_RW)); /* _PAGE_EXEC -> HW_NO_EXEC since it's inverted */ - hpteflags |= ((pte_val(new_pte) & _PAGE_EXEC) ? 0 : HW_NO_EXEC); + rflags |= ((pte_val(new_pte) & _PAGE_EXEC) ? 0 : HW_NO_EXEC); /* Check if pte already has an hpte (case 2) */ if (unlikely(pte_val(old_pte) & _PAGE_HASHPTE)) { @@ -641,7 +641,7 @@ int hash_huge_page(struct mm_struct *mm, unsigned long access, slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; slot += (pte_val(old_pte) & _PAGE_GROUP_IX) >> 12; - if (ppc_md.hpte_updatepp(slot, hpteflags, va, 1, local) == -1) + if (ppc_md.hpte_updatepp(slot, rflags, va, 1, local) == -1) pte_val(old_pte) &= ~_PAGE_HPTEFLAGS; } @@ -661,10 +661,10 @@ repeat: /* Add in WIMG bits */ /* XXX We should store these in the pte */ - hpteflags |= _PAGE_COHERENT; + rflags |= _PAGE_COHERENT; - slot = ppc_md.hpte_insert(hpte_group, va, prpn, 0, - hpteflags, 0, 1); + slot = ppc_md.hpte_insert(hpte_group, va, prpn, + HPTE_V_LARGE, rflags); /* Primary is full, try the secondary */ if (unlikely(slot == -1)) { @@ -672,7 +672,7 @@ repeat: hpte_group = ((~hash & htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL; slot = ppc_md.hpte_insert(hpte_group, va, prpn, - 1, hpteflags, 0, 1); + HPTE_V_LARGE, rflags); if (slot == -1) { if (mftb() & 0x1) hpte_group = ((hash & htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL; diff --git a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c index b50b3a446dbe..e58a24d42879 100644 --- a/arch/ppc64/mm/init.c +++ b/arch/ppc64/mm/init.c @@ -180,9 +180,10 @@ static int map_io_page(unsigned long ea, unsigned long pa, int flags) hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP); /* Panic if a pte grpup is full */ - if (ppc_md.hpte_insert(hpteg, va, pa >> PAGE_SHIFT, 0, - _PAGE_NO_CACHE|_PAGE_GUARDED|PP_RWXX, - 1, 0) == -1) { + if (ppc_md.hpte_insert(hpteg, va, pa >> PAGE_SHIFT, + HPTE_V_BOLTED, + _PAGE_NO_CACHE|_PAGE_GUARDED|PP_RWXX) + == -1) { panic("map_io_page: could not insert mapping"); } } diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 6600ee87f896..477ac2758bd5 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -465,6 +465,8 @@ config KEXEC endmenu +source "net/Kconfig" + config PCMCIA bool default n @@ -475,7 +477,7 @@ source "drivers/scsi/Kconfig" source "drivers/s390/Kconfig" -source "net/Kconfig" +source "drivers/net/Kconfig" source "fs/Kconfig" diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 614056222875..18610cea03a2 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -58,6 +58,7 @@ #include <linux/compat.h> #include <linux/vfs.h> #include <linux/ptrace.h> +#include <linux/fadvise.h> #include <asm/types.h> #include <asm/ipc.h> @@ -1043,3 +1044,40 @@ sys32_timer_create(clockid_t which_clock, struct compat_sigevent *se32, return ret; } + +/* + * 31 bit emulation wrapper functions for sys_fadvise64/fadvise64_64. + * These need to rewrite the advise values for POSIX_FADV_{DONTNEED,NOREUSE} + * because the 31 bit values differ from the 64 bit values. + */ + +asmlinkage long +sys32_fadvise64(int fd, loff_t offset, size_t len, int advise) +{ + if (advise == 4) + advise = POSIX_FADV_DONTNEED; + else if (advise == 5) + advise = POSIX_FADV_NOREUSE; + return sys_fadvise64(fd, offset, len, advise); +} + +struct fadvise64_64_args { + int fd; + long long offset; + long long len; + int advice; +}; + +asmlinkage long +sys32_fadvise64_64(struct fadvise64_64_args __user *args) +{ + struct fadvise64_64_args a; + + if ( copy_from_user(&a, args, sizeof(a)) ) + return -EFAULT; + if (a.advice == 4) + a.advice = POSIX_FADV_DONTNEED; + else if (a.advice == 5) + a.advice = POSIX_FADV_NOREUSE; + return sys_fadvise64_64(a.fd, a.offset, a.len, a.advice); +} diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index bf529739c8ab..799a98eac92d 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -1251,12 +1251,12 @@ sys32_fadvise64_wrapper: or %r3,%r4 # get low word of 64bit loff_t llgfr %r4,%r5 # size_t (unsigned long) lgfr %r5,%r6 # int - jg sys_fadvise64 + jg sys32_fadvise64 .globl sys32_fadvise64_64_wrapper sys32_fadvise64_64_wrapper: llgtr %r2,%r2 # struct fadvise64_64_args * - jg s390_fadvise64_64 + jg sys32_fadvise64_64 .globl sys32_clock_settime_wrapper sys32_clock_settime_wrapper: diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index a7c8bfc11604..adc8109f8b77 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -784,6 +784,8 @@ config EMBEDDED_RAMDISK_IMAGE endmenu +source "net/Kconfig" + source "drivers/Kconfig" source "fs/Kconfig" diff --git a/arch/sh64/Kconfig b/arch/sh64/Kconfig index 708e59736a4d..4c3e5334adb3 100644 --- a/arch/sh64/Kconfig +++ b/arch/sh64/Kconfig @@ -268,6 +268,8 @@ source "fs/Kconfig.binfmt" endmenu +source "net/Kconfig" + source "drivers/Kconfig" source "fs/Kconfig" diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 262e13d086fe..aca028aa29bf 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -268,68 +268,14 @@ source "mm/Kconfig" endmenu -source "drivers/Kconfig" - -config PRINTER - tristate "Parallel printer support" - depends on PARPORT - ---help--- - If you intend to attach a printer to the parallel port of your Linux - box (as opposed to using a serial printer; if the connector at the - printer has 9 or 25 holes ["female"], then it's serial), say Y. - Also read the Printing-HOWTO, available from - <http://www.tldp.org/docs.html#howto>. - - It is possible to share one parallel port among several devices - (e.g. printer and ZIP drive) and it is safe to compile the - corresponding drivers into the kernel. If you want to compile this - driver as a module however, choose M here and read - <file:Documentation/parport.txt>. The module will be called lp. - - If you have several parallel ports, you can specify which ports to - use with the "lp" kernel command line option. (Try "man bootparam" - or see the documentation of your boot loader (silo) about how to pass - options to the kernel at boot time.) The syntax of the "lp" command - line option can be found in <file:drivers/char/lp.c>. - - If you have more than 8 printers, you need to increase the LP_NO - macro in lp.c and the PARPORT_MAX macro in parport.h. - -source "mm/Kconfig" - -endmenu - -source "drivers/base/Kconfig" - -source "drivers/video/Kconfig" - -source "drivers/mtd/Kconfig" +source "net/Kconfig" -source "drivers/serial/Kconfig" +source "drivers/Kconfig" if !SUN4 source "drivers/sbus/char/Kconfig" endif -source "drivers/block/Kconfig" - -# Don't frighten a common SBus user -if PCI - -source "drivers/ide/Kconfig" - -endif - -source "drivers/isdn/Kconfig" - -source "drivers/scsi/Kconfig" - -source "drivers/fc4/Kconfig" - -source "drivers/md/Kconfig" - -source "net/Kconfig" - # This one must be before the filesystem configs. -DaveM menu "Unix98 PTY support" diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S index 928ffeb0fabb..025f4516e651 100644 --- a/arch/sparc/kernel/systbls.S +++ b/arch/sparc/kernel/systbls.S @@ -57,11 +57,11 @@ sys_call_table: /*180*/ .long sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_sigpending, sys_ni_syscall /*185*/ .long sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sys_newuname /*190*/ .long sys_init_module, sys_personality, sparc_remap_file_pages, sys_epoll_create, sys_epoll_ctl -/*195*/ .long sys_epoll_wait, sys_nis_syscall, sys_getppid, sparc_sigaction, sys_sgetmask +/*195*/ .long sys_epoll_wait, sys_ioprio_set, sys_getppid, sparc_sigaction, sys_sgetmask /*200*/ .long sys_ssetmask, sys_sigsuspend, sys_newlstat, sys_uselib, old_readdir /*205*/ .long sys_readahead, sys_socketcall, sys_syslog, sys_lookup_dcookie, sys_fadvise64 /*210*/ .long sys_fadvise64_64, sys_tgkill, sys_waitpid, sys_swapoff, sys_sysinfo -/*215*/ .long sys_ipc, sys_sigreturn, sys_clone, sys_nis_syscall, sys_adjtimex +/*215*/ .long sys_ipc, sys_sigreturn, sys_clone, sys_ioprio_get, sys_adjtimex /*220*/ .long sys_sigprocmask, sys_ni_syscall, sys_delete_module, sys_ni_syscall, sys_getpgid /*225*/ .long sys_bdflush, sys_sysfs, sys_nis_syscall, sys_setfsuid16, sys_setfsgid16 /*230*/ .long sys_select, sys_time, sys_nis_syscall, sys_stime, sys_statfs64 diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index e2b050eb3b96..9afd28e2c4d5 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig @@ -43,6 +43,25 @@ config SPARC64_PAGE_SIZE_4MB endchoice +config SECCOMP + bool "Enable seccomp to safely compute untrusted bytecode" + depends on PROC_FS + default y + help + This kernel feature is useful for number crunching applications + that may need to compute untrusted bytecode during their + execution. By using pipes or other transports made available to + the process as file descriptors supporting the read/write + syscalls, it's possible to isolate those applications in + their own address space using seccomp. Once seccomp is + enabled via /proc/<pid>/seccomp, it cannot be disabled + and the task is only allowed to execute a few safe syscalls + defined by each seccomp mode. + + If unsure, say Y. Only embedded should say N here. + +source kernel/Kconfig.hz + source "init/Kconfig" config SYSVIPC_COMPAT @@ -444,6 +463,24 @@ config PRINTER If you have more than 8 printers, you need to increase the LP_NO macro in lp.c and the PARPORT_MAX macro in parport.h. +config PPDEV + tristate "Support for user-space parallel port device drivers" + depends on PARPORT + ---help--- + Saying Y to this adds support for /dev/parport device nodes. This + is needed for programs that want portable access to the parallel + port, for instance deviceid (which displays Plug-and-Play device + IDs). + + This is the parallel port equivalent of SCSI generic support (sg). + It is safe to say N to this -- it is not needed for normal printing + or parallel port CD-ROM/disk support. + + To compile this driver as a module, choose M here: the + module will be called ppdev. + + If unsure, say N. + config ENVCTRL tristate "SUNW, envctrl support" depends on PCI @@ -488,6 +525,8 @@ source "mm/Kconfig" endmenu +source "net/Kconfig" + source "drivers/base/Kconfig" source "drivers/video/Kconfig" @@ -514,7 +553,7 @@ endif source "drivers/ieee1394/Kconfig" -source "net/Kconfig" +source "drivers/net/Kconfig" source "drivers/isdn/Kconfig" @@ -610,6 +649,8 @@ source "drivers/input/Kconfig" source "drivers/i2c/Kconfig" +source "drivers/hwmon/Kconfig" + source "fs/Kconfig" source "drivers/media/Kconfig" diff --git a/arch/sparc64/kernel/auxio.c b/arch/sparc64/kernel/auxio.c index a0716ccc2f4a..8852c20c8d99 100644 --- a/arch/sparc64/kernel/auxio.c +++ b/arch/sparc64/kernel/auxio.c @@ -16,7 +16,7 @@ #include <asm/ebus.h> #include <asm/auxio.h> -/* This cannot be static, as it is referenced in entry.S */ +/* This cannot be static, as it is referenced in irq.c */ void __iomem *auxio_register = NULL; enum auxio_type { diff --git a/arch/sparc64/kernel/dtlb_backend.S b/arch/sparc64/kernel/dtlb_backend.S index b73a3c858770..538522848ad4 100644 --- a/arch/sparc64/kernel/dtlb_backend.S +++ b/arch/sparc64/kernel/dtlb_backend.S @@ -16,7 +16,7 @@ #elif PAGE_SHIFT == 19 #define SZ_BITS _PAGE_SZ512K #elif PAGE_SHIFT == 22 -#define SZ_BITS _PAGE_SZ4M +#define SZ_BITS _PAGE_SZ4MB #endif #define VALID_SZ_BITS (_PAGE_VALID | SZ_BITS) diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index a47f2d0b1a29..88332f00094a 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S @@ -22,8 +22,6 @@ #include <asm/estate.h> #include <asm/auxio.h> -/* #define SYSCALL_TRACING 1 */ - #define curptr g6 #define NR_SYSCALLS 284 /* Each OS is different... */ @@ -271,8 +269,9 @@ cplus_fptrap_insn_1: fmuld %f0, %f2, %f26 faddd %f0, %f2, %f28 fmuld %f0, %f2, %f30 + membar #Sync b,pt %xcc, fpdis_exit - membar #Sync + nop 2: andcc %g5, FPRS_DU, %g0 bne,pt %icc, 3f fzero %f32 @@ -301,8 +300,9 @@ cplus_fptrap_insn_2: fmuld %f32, %f34, %f58 faddd %f32, %f34, %f60 fmuld %f32, %f34, %f62 + membar #Sync ba,pt %xcc, fpdis_exit - membar #Sync + nop 3: mov SECONDARY_CONTEXT, %g3 add %g6, TI_FPREGS, %g1 ldxa [%g3] ASI_DMMU, %g5 @@ -551,13 +551,11 @@ do_ivec: sllx %g3, 5, %g3 or %g2, %lo(ivector_table), %g2 add %g2, %g3, %g3 - ldx [%g3 + 0x08], %g2 /* irq_info */ ldub [%g3 + 0x04], %g4 /* pil */ - brz,pn %g2, do_ivec_spurious - mov 1, %g2 - + mov 1, %g2 sllx %g2, %g4, %g2 sllx %g4, 2, %g4 + lduw [%g6 + %g4], %g5 /* g5 = irq_work(cpu, pil) */ stw %g5, [%g3 + 0x00] /* bucket->irq_chain = g5 */ stw %g3, [%g6 + %g4] /* irq_work(cpu, pil) = bucket */ @@ -565,9 +563,9 @@ do_ivec: retry do_ivec_xcall: mov 0x50, %g1 - ldxa [%g1 + %g0] ASI_INTR_R, %g1 srl %g3, 0, %g3 + mov 0x60, %g7 ldxa [%g7 + %g0] ASI_INTR_R, %g7 stxa %g0, [%g0] ASI_INTR_RECEIVE @@ -579,19 +577,6 @@ do_ivec_xcall: 1: jmpl %g3, %g0 nop -do_ivec_spurious: - stw %g3, [%g6 + 0x00] /* irq_work(cpu, 0) = bucket */ - rdpr %pstate, %g5 - - wrpr %g5, PSTATE_IG | PSTATE_AG, %pstate - sethi %hi(109f), %g7 - ba,pt %xcc, etrap -109: or %g7, %lo(109b), %g7 - call catch_disabled_ivec - add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - clr %l6 - .globl save_alternate_globals save_alternate_globals: /* %o0 = save_area */ rdpr %pstate, %o5 @@ -699,116 +684,6 @@ utrap_ill: ba,pt %xcc, rtrap clr %l6 -#ifdef CONFIG_BLK_DEV_FD - .globl floppy_hardint -floppy_hardint: - wr %g0, (1 << 11), %clear_softint - sethi %hi(doing_pdma), %g1 - ld [%g1 + %lo(doing_pdma)], %g2 - brz,pn %g2, floppy_dosoftint - sethi %hi(fdc_status), %g3 - ldx [%g3 + %lo(fdc_status)], %g3 - sethi %hi(pdma_vaddr), %g5 - ldx [%g5 + %lo(pdma_vaddr)], %g4 - sethi %hi(pdma_size), %g5 - ldx [%g5 + %lo(pdma_size)], %g5 - -next_byte: - lduba [%g3] ASI_PHYS_BYPASS_EC_E, %g7 - andcc %g7, 0x80, %g0 - be,pn %icc, floppy_fifo_emptied - andcc %g7, 0x20, %g0 - be,pn %icc, floppy_overrun - andcc %g7, 0x40, %g0 - be,pn %icc, floppy_write - sub %g5, 1, %g5 - - inc %g3 - lduba [%g3] ASI_PHYS_BYPASS_EC_E, %g7 - dec %g3 - orcc %g0, %g5, %g0 - stb %g7, [%g4] - bne,pn %xcc, next_byte - add %g4, 1, %g4 - - b,pt %xcc, floppy_tdone - nop - -floppy_write: - ldub [%g4], %g7 - orcc %g0, %g5, %g0 - inc %g3 - stba %g7, [%g3] ASI_PHYS_BYPASS_EC_E - dec %g3 - bne,pn %xcc, next_byte - add %g4, 1, %g4 - -floppy_tdone: - sethi %hi(pdma_vaddr), %g1 - stx %g4, [%g1 + %lo(pdma_vaddr)] - sethi %hi(pdma_size), %g1 - stx %g5, [%g1 + %lo(pdma_size)] - sethi %hi(auxio_register), %g1 - ldx [%g1 + %lo(auxio_register)], %g7 - lduba [%g7] ASI_PHYS_BYPASS_EC_E, %g5 - or %g5, AUXIO_AUX1_FTCNT, %g5 -/* andn %g5, AUXIO_AUX1_MASK, %g5 */ - stba %g5, [%g7] ASI_PHYS_BYPASS_EC_E - andn %g5, AUXIO_AUX1_FTCNT, %g5 -/* andn %g5, AUXIO_AUX1_MASK, %g5 */ - - nop; nop; nop; nop; nop; nop; - nop; nop; nop; nop; nop; nop; - - stba %g5, [%g7] ASI_PHYS_BYPASS_EC_E - sethi %hi(doing_pdma), %g1 - b,pt %xcc, floppy_dosoftint - st %g0, [%g1 + %lo(doing_pdma)] - -floppy_fifo_emptied: - sethi %hi(pdma_vaddr), %g1 - stx %g4, [%g1 + %lo(pdma_vaddr)] - sethi %hi(pdma_size), %g1 - stx %g5, [%g1 + %lo(pdma_size)] - sethi %hi(irq_action), %g1 - or %g1, %lo(irq_action), %g1 - ldx [%g1 + (11 << 3)], %g3 ! irqaction[floppy_irq] - ldx [%g3 + 0x08], %g4 ! action->flags>>48==ino - sethi %hi(ivector_table), %g3 - srlx %g4, 48, %g4 - or %g3, %lo(ivector_table), %g3 - sllx %g4, 5, %g4 - ldx [%g3 + %g4], %g4 ! &ivector_table[ino] - ldx [%g4 + 0x10], %g4 ! bucket->iclr - stwa %g0, [%g4] ASI_PHYS_BYPASS_EC_E ! ICLR_IDLE - membar #Sync ! probably not needed... - retry - -floppy_overrun: - sethi %hi(pdma_vaddr), %g1 - stx %g4, [%g1 + %lo(pdma_vaddr)] - sethi %hi(pdma_size), %g1 - stx %g5, [%g1 + %lo(pdma_size)] - sethi %hi(doing_pdma), %g1 - st %g0, [%g1 + %lo(doing_pdma)] - -floppy_dosoftint: - rdpr %pil, %g2 - wrpr %g0, 15, %pil - sethi %hi(109f), %g7 - b,pt %xcc, etrap_irq -109: or %g7, %lo(109b), %g7 - - mov 11, %o0 - mov 0, %o1 - call sparc_floppy_irq - add %sp, PTREGS_OFF, %o2 - - b,pt %xcc, rtrap_irq - nop - -#endif /* CONFIG_BLK_DEV_FD */ - /* XXX Here is stuff we still need to write... -DaveM XXX */ .globl netbsd_syscall netbsd_syscall: @@ -1677,11 +1552,12 @@ sys_ptrace: add %sp, PTREGS_OFF, %o0 nop .align 32 1: ldx [%curptr + TI_FLAGS], %l5 - andcc %l5, _TIF_SYSCALL_TRACE, %g0 + andcc %l5, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0 be,pt %icc, rtrap clr %l6 + add %sp, PTREGS_OFF, %o0 call syscall_trace - nop + mov 1, %o1 ba,pt %xcc, rtrap clr %l6 @@ -1724,11 +1600,11 @@ sys_clone: flushw ba,pt %xcc, sparc_do_fork add %sp, PTREGS_OFF, %o2 ret_from_syscall: - /* Clear SPARC_FLAG_NEWCHILD, switch_to leaves thread.flags in - * %o7 for us. Check performance counter stuff too. + /* Clear current_thread_info()->new_child, and + * check performance counter stuff too. */ - andn %o7, _TIF_NEWCHILD, %l0 - stx %l0, [%g6 + TI_FLAGS] + stb %g0, [%g6 + TI_NEW_CHILD] + ldx [%g6 + TI_FLAGS], %l0 call schedule_tail mov %g7, %o0 andcc %l0, _TIF_PERFCTR, %g0 @@ -1765,18 +1641,20 @@ linux_sparc_ni_syscall: or %l7, %lo(sys_ni_syscall), %l7 linux_syscall_trace32: + add %sp, PTREGS_OFF, %o0 call syscall_trace - nop + clr %o1 srl %i0, 0, %o0 - mov %i4, %o4 + srl %i4, 0, %o4 srl %i1, 0, %o1 srl %i2, 0, %o2 b,pt %xcc, 2f srl %i3, 0, %o3 linux_syscall_trace: + add %sp, PTREGS_OFF, %o0 call syscall_trace - nop + clr %o1 mov %i0, %o0 mov %i1, %o1 mov %i2, %o2 @@ -1794,11 +1672,6 @@ linux_sparc_syscall32: bgeu,pn %xcc, linux_sparc_ni_syscall ! CTI srl %i0, 0, %o0 ! IEU0 sll %g1, 2, %l4 ! IEU0 Group -#ifdef SYSCALL_TRACING - call syscall_trace_entry - add %sp, PTREGS_OFF, %o0 - srl %i0, 0, %o0 -#endif srl %i4, 0, %o4 ! IEU1 lduw [%l7 + %l4], %l7 ! Load srl %i1, 0, %o1 ! IEU0 Group @@ -1806,7 +1679,7 @@ linux_sparc_syscall32: srl %i5, 0, %o5 ! IEU1 srl %i2, 0, %o2 ! IEU0 Group - andcc %l0, _TIF_SYSCALL_TRACE, %g0 ! IEU0 Group + andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0 bne,pn %icc, linux_syscall_trace32 ! CTI mov %i0, %l5 ! IEU1 call %l7 ! CTI Group brk forced @@ -1822,11 +1695,6 @@ linux_sparc_syscall: bgeu,pn %xcc, linux_sparc_ni_syscall ! CTI mov %i0, %o0 ! IEU0 sll %g1, 2, %l4 ! IEU0 Group -#ifdef SYSCALL_TRACING - call syscall_trace_entry - add %sp, PTREGS_OFF, %o0 - mov %i0, %o0 -#endif mov %i1, %o1 ! IEU1 lduw [%l7 + %l4], %l7 ! Load 4: mov %i2, %o2 ! IEU0 Group @@ -1834,7 +1702,7 @@ linux_sparc_syscall: mov %i3, %o3 ! IEU1 mov %i4, %o4 ! IEU0 Group - andcc %l0, _TIF_SYSCALL_TRACE, %g0 ! IEU1 Group+1 bubble + andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0 bne,pn %icc, linux_syscall_trace ! CTI Group mov %i0, %l5 ! IEU0 2: call %l7 ! CTI Group brk forced @@ -1843,12 +1711,6 @@ linux_sparc_syscall: 3: stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] ret_sys_call: -#ifdef SYSCALL_TRACING - mov %o0, %o1 - call syscall_trace_exit - add %sp, PTREGS_OFF, %o0 - mov %o1, %o0 -#endif ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %g3 ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc sra %o0, 0, %o0 @@ -1858,17 +1720,16 @@ ret_sys_call: /* Check if force_successful_syscall_return() * was invoked. */ - ldx [%curptr + TI_FLAGS], %l0 - andcc %l0, _TIF_SYSCALL_SUCCESS, %g0 - be,pt %icc, 1f - andn %l0, _TIF_SYSCALL_SUCCESS, %l0 + ldub [%curptr + TI_SYS_NOERROR], %l0 + brz,pt %l0, 1f + nop ba,pt %xcc, 80f - stx %l0, [%curptr + TI_FLAGS] + stb %g0, [%curptr + TI_SYS_NOERROR] 1: cmp %o0, -ERESTART_RESTARTBLOCK bgeu,pn %xcc, 1f - andcc %l0, _TIF_SYSCALL_TRACE, %l6 + andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %l6 80: /* System call success, clear Carry condition code. */ andn %g3, %g2, %g3 @@ -1883,7 +1744,7 @@ ret_sys_call: /* System call failure, set Carry condition code. * Also, get abs(errno) to return to the process. */ - andcc %l0, _TIF_SYSCALL_TRACE, %l6 + andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %l6 sub %g0, %o0, %o0 or %g3, %g2, %g3 stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] @@ -1896,8 +1757,9 @@ ret_sys_call: b,pt %xcc, rtrap stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] linux_syscall_trace2: + add %sp, PTREGS_OFF, %o0 call syscall_trace - nop + mov 1, %o1 stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC] ba,pt %xcc, rtrap stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index 4dcb8af94090..c9b69167632a 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c @@ -37,6 +37,7 @@ #include <asm/uaccess.h> #include <asm/cache.h> #include <asm/cpudata.h> +#include <asm/auxio.h> #ifdef CONFIG_SMP static void distribute_irqs(void); @@ -70,31 +71,7 @@ struct irq_work_struct { struct irq_work_struct __irq_work[NR_CPUS]; #define irq_work(__cpu, __pil) &(__irq_work[(__cpu)].irq_worklists[(__pil)]) -#ifdef CONFIG_PCI -/* This is a table of physical addresses used to deal with IBF_DMA_SYNC. - * It is used for PCI only to synchronize DMA transfers with IRQ delivery - * for devices behind busses other than APB on Sabre systems. - * - * Currently these physical addresses are just config space accesses - * to the command register for that device. - */ -unsigned long pci_dma_wsync; -unsigned long dma_sync_reg_table[256]; -unsigned char dma_sync_reg_table_entry = 0; -#endif - -/* This is based upon code in the 32-bit Sparc kernel written mostly by - * David Redman (djhr@tadpole.co.uk). - */ -#define MAX_STATIC_ALLOC 4 -static struct irqaction static_irqaction[MAX_STATIC_ALLOC]; -static int static_irq_count; - -/* This is exported so that fast IRQ handlers can get at it... -DaveM */ -struct irqaction *irq_action[NR_IRQS+1] = { - NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL -}; +static struct irqaction *irq_action[NR_IRQS+1]; /* This only synchronizes entities which modify IRQ handler * state and some selected user-level spots that want to @@ -240,17 +217,22 @@ void disable_irq(unsigned int irq) * the CPU %tick register and not by some normal vectored interrupt * source. To handle this special case, we use this dummy INO bucket. */ +static struct irq_desc pil0_dummy_desc; static struct ino_bucket pil0_dummy_bucket = { - 0, /* irq_chain */ - 0, /* pil */ - 0, /* pending */ - 0, /* flags */ - 0, /* __unused */ - NULL, /* irq_info */ - 0UL, /* iclr */ - 0UL, /* imap */ + .irq_info = &pil0_dummy_desc, }; +static void build_irq_error(const char *msg, unsigned int ino, int pil, int inofixup, + unsigned long iclr, unsigned long imap, + struct ino_bucket *bucket) +{ + prom_printf("IRQ: INO %04x (%d:%016lx:%016lx) --> " + "(%d:%d:%016lx:%016lx), halting...\n", + ino, bucket->pil, bucket->iclr, bucket->imap, + pil, inofixup, iclr, imap); + prom_halt(); +} + unsigned int build_irq(int pil, int inofixup, unsigned long iclr, unsigned long imap) { struct ino_bucket *bucket; @@ -279,28 +261,35 @@ unsigned int build_irq(int pil, int inofixup, unsigned long iclr, unsigned long prom_halt(); } - /* Ok, looks good, set it up. Don't touch the irq_chain or - * the pending flag. - */ bucket = &ivector_table[ino]; - if ((bucket->flags & IBF_ACTIVE) || - (bucket->irq_info != NULL)) { - /* This is a gross fatal error if it happens here. */ - prom_printf("IRQ: Trying to reinit INO bucket, fatal error.\n"); - prom_printf("IRQ: Request INO %04x (%d:%d:%016lx:%016lx)\n", - ino, pil, inofixup, iclr, imap); - prom_printf("IRQ: Existing (%d:%016lx:%016lx)\n", - bucket->pil, bucket->iclr, bucket->imap); - prom_printf("IRQ: Cannot continue, halting...\n"); + if (bucket->flags & IBF_ACTIVE) + build_irq_error("IRQ: Trying to build active INO bucket.\n", + ino, pil, inofixup, iclr, imap, bucket); + + if (bucket->irq_info) { + if (bucket->imap != imap || bucket->iclr != iclr) + build_irq_error("IRQ: Trying to reinit INO bucket.\n", + ino, pil, inofixup, iclr, imap, bucket); + + goto out; + } + + bucket->irq_info = kmalloc(sizeof(struct irq_desc), GFP_ATOMIC); + if (!bucket->irq_info) { + prom_printf("IRQ: Error, kmalloc(irq_desc) failed.\n"); prom_halt(); } + memset(bucket->irq_info, 0, sizeof(struct irq_desc)); + + /* Ok, looks good, set it up. Don't touch the irq_chain or + * the pending flag. + */ bucket->imap = imap; bucket->iclr = iclr; bucket->pil = pil; bucket->flags = 0; - bucket->irq_info = NULL; - +out: return __irq(bucket); } @@ -318,26 +307,65 @@ static void atomic_bucket_insert(struct ino_bucket *bucket) __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate)); } +static int check_irq_sharing(int pil, unsigned long irqflags) +{ + struct irqaction *action, *tmp; + + action = *(irq_action + pil); + if (action) { + if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ)) { + for (tmp = action; tmp->next; tmp = tmp->next) + ; + } else { + return -EBUSY; + } + } + return 0; +} + +static void append_irq_action(int pil, struct irqaction *action) +{ + struct irqaction **pp = irq_action + pil; + + while (*pp) + pp = &((*pp)->next); + *pp = action; +} + +static struct irqaction *get_action_slot(struct ino_bucket *bucket) +{ + struct irq_desc *desc = bucket->irq_info; + int max_irq, i; + + max_irq = 1; + if (bucket->flags & IBF_PCI) + max_irq = MAX_IRQ_DESC_ACTION; + for (i = 0; i < max_irq; i++) { + struct irqaction *p = &desc->action[i]; + u32 mask = (1 << i); + + if (desc->action_active_mask & mask) + continue; + + desc->action_active_mask |= mask; + return p; + } + return NULL; +} + int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long irqflags, const char *name, void *dev_id) { - struct irqaction *action, *tmp = NULL; + struct irqaction *action; struct ino_bucket *bucket = __bucket(irq); unsigned long flags; int pending = 0; - if ((bucket != &pil0_dummy_bucket) && - (bucket < &ivector_table[0] || - bucket >= &ivector_table[NUM_IVECS])) { - unsigned int *caller; - - __asm__ __volatile__("mov %%i7, %0" : "=r" (caller)); - printk(KERN_CRIT "request_irq: Old style IRQ registry attempt " - "from %p, irq %08x.\n", caller, irq); + if (unlikely(!handler)) return -EINVAL; - } - if (!handler) - return -EINVAL; + + if (unlikely(!bucket->irq_info)) + return -ENODEV; if ((bucket != &pil0_dummy_bucket) && (irqflags & SA_SAMPLE_RANDOM)) { /* @@ -355,93 +383,20 @@ int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_ spin_lock_irqsave(&irq_action_lock, flags); - action = *(bucket->pil + irq_action); - if (action) { - if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ)) - for (tmp = action; tmp->next; tmp = tmp->next) - ; - else { - spin_unlock_irqrestore(&irq_action_lock, flags); - return -EBUSY; - } - action = NULL; /* Or else! */ + if (check_irq_sharing(bucket->pil, irqflags)) { + spin_unlock_irqrestore(&irq_action_lock, flags); + return -EBUSY; } - /* If this is flagged as statically allocated then we use our - * private struct which is never freed. - */ - if (irqflags & SA_STATIC_ALLOC) { - if (static_irq_count < MAX_STATIC_ALLOC) - action = &static_irqaction[static_irq_count++]; - else - printk("Request for IRQ%d (%s) SA_STATIC_ALLOC failed " - "using kmalloc\n", irq, name); - } - if (action == NULL) - action = (struct irqaction *)kmalloc(sizeof(struct irqaction), - GFP_ATOMIC); - + action = get_action_slot(bucket); if (!action) { spin_unlock_irqrestore(&irq_action_lock, flags); return -ENOMEM; } - if (bucket == &pil0_dummy_bucket) { - bucket->irq_info = action; - bucket->flags |= IBF_ACTIVE; - } else { - if ((bucket->flags & IBF_ACTIVE) != 0) { - void *orig = bucket->irq_info; - void **vector = NULL; - - if ((bucket->flags & IBF_PCI) == 0) { - printk("IRQ: Trying to share non-PCI bucket.\n"); - goto free_and_ebusy; - } - if ((bucket->flags & IBF_MULTI) == 0) { - vector = kmalloc(sizeof(void *) * 4, GFP_ATOMIC); - if (vector == NULL) - goto free_and_enomem; - - /* We might have slept. */ - if ((bucket->flags & IBF_MULTI) != 0) { - int ent; - - kfree(vector); - vector = (void **)bucket->irq_info; - for(ent = 0; ent < 4; ent++) { - if (vector[ent] == NULL) { - vector[ent] = action; - break; - } - } - if (ent == 4) - goto free_and_ebusy; - } else { - vector[0] = orig; - vector[1] = action; - vector[2] = NULL; - vector[3] = NULL; - bucket->irq_info = vector; - bucket->flags |= IBF_MULTI; - } - } else { - int ent; - - vector = (void **)orig; - for (ent = 0; ent < 4; ent++) { - if (vector[ent] == NULL) { - vector[ent] = action; - break; - } - } - if (ent == 4) - goto free_and_ebusy; - } - } else { - bucket->irq_info = action; - bucket->flags |= IBF_ACTIVE; - } + bucket->flags |= IBF_ACTIVE; + pending = 0; + if (bucket != &pil0_dummy_bucket) { pending = bucket->pending; if (pending) bucket->pending = 0; @@ -455,10 +410,7 @@ int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_ put_ino_in_irqaction(action, irq); put_smpaff_in_irqaction(action, CPU_MASK_NONE); - if (tmp) - tmp->next = action; - else - *(bucket->pil + irq_action) = action; + append_irq_action(bucket->pil, action); enable_irq(irq); @@ -467,147 +419,103 @@ int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_ atomic_bucket_insert(bucket); set_softint(1 << bucket->pil); } + spin_unlock_irqrestore(&irq_action_lock, flags); - if ((bucket != &pil0_dummy_bucket) && (!(irqflags & SA_STATIC_ALLOC))) + + if (bucket != &pil0_dummy_bucket) register_irq_proc(__irq_ino(irq)); #ifdef CONFIG_SMP distribute_irqs(); #endif return 0; - -free_and_ebusy: - kfree(action); - spin_unlock_irqrestore(&irq_action_lock, flags); - return -EBUSY; - -free_and_enomem: - kfree(action); - spin_unlock_irqrestore(&irq_action_lock, flags); - return -ENOMEM; } EXPORT_SYMBOL(request_irq); -void free_irq(unsigned int irq, void *dev_id) +static struct irqaction *unlink_irq_action(unsigned int irq, void *dev_id) { - struct irqaction *action; - struct irqaction *tmp = NULL; - unsigned long flags; - struct ino_bucket *bucket = __bucket(irq), *bp; - - if ((bucket != &pil0_dummy_bucket) && - (bucket < &ivector_table[0] || - bucket >= &ivector_table[NUM_IVECS])) { - unsigned int *caller; + struct ino_bucket *bucket = __bucket(irq); + struct irqaction *action, **pp; - __asm__ __volatile__("mov %%i7, %0" : "=r" (caller)); - printk(KERN_CRIT "free_irq: Old style IRQ removal attempt " - "from %p, irq %08x.\n", caller, irq); - return; - } - - spin_lock_irqsave(&irq_action_lock, flags); + pp = irq_action + bucket->pil; + action = *pp; + if (unlikely(!action)) + return NULL; - action = *(bucket->pil + irq_action); - if (!action->handler) { + if (unlikely(!action->handler)) { printk("Freeing free IRQ %d\n", bucket->pil); - return; - } - if (dev_id) { - for ( ; action; action = action->next) { - if (action->dev_id == dev_id) - break; - tmp = action; - } - if (!action) { - printk("Trying to free free shared IRQ %d\n", bucket->pil); - spin_unlock_irqrestore(&irq_action_lock, flags); - return; - } - } else if (action->flags & SA_SHIRQ) { - printk("Trying to free shared IRQ %d with NULL device ID\n", bucket->pil); - spin_unlock_irqrestore(&irq_action_lock, flags); - return; + return NULL; } - if (action->flags & SA_STATIC_ALLOC) { - printk("Attempt to free statically allocated IRQ %d (%s)\n", - bucket->pil, action->name); - spin_unlock_irqrestore(&irq_action_lock, flags); - return; + while (action && action->dev_id != dev_id) { + pp = &action->next; + action = *pp; } - if (action && tmp) - tmp->next = action->next; - else - *(bucket->pil + irq_action) = action->next; + if (likely(action)) + *pp = action->next; + + return action; +} + +void free_irq(unsigned int irq, void *dev_id) +{ + struct irqaction *action; + struct ino_bucket *bucket; + unsigned long flags; + + spin_lock_irqsave(&irq_action_lock, flags); + + action = unlink_irq_action(irq, dev_id); spin_unlock_irqrestore(&irq_action_lock, flags); + if (unlikely(!action)) + return; + synchronize_irq(irq); spin_lock_irqsave(&irq_action_lock, flags); + bucket = __bucket(irq); if (bucket != &pil0_dummy_bucket) { + struct irq_desc *desc = bucket->irq_info; unsigned long imap = bucket->imap; - void **vector, *orig; - int ent; - - orig = bucket->irq_info; - vector = (void **)orig; - - if ((bucket->flags & IBF_MULTI) != 0) { - int other = 0; - void *orphan = NULL; - for (ent = 0; ent < 4; ent++) { - if (vector[ent] == action) - vector[ent] = NULL; - else if (vector[ent] != NULL) { - orphan = vector[ent]; - other++; - } - } + int ent, i; - /* Only free when no other shared irq - * uses this bucket. - */ - if (other) { - if (other == 1) { - /* Convert back to non-shared bucket. */ - bucket->irq_info = orphan; - bucket->flags &= ~(IBF_MULTI); - kfree(vector); - } - goto out; + for (i = 0; i < MAX_IRQ_DESC_ACTION; i++) { + struct irqaction *p = &desc->action[i]; + + if (p == action) { + desc->action_active_mask &= ~(1 << i); + break; } - } else { - bucket->irq_info = NULL; } - /* This unique interrupt source is now inactive. */ - bucket->flags &= ~IBF_ACTIVE; + if (!desc->action_active_mask) { + /* This unique interrupt source is now inactive. */ + bucket->flags &= ~IBF_ACTIVE; - /* See if any other buckets share this bucket's IMAP - * and are still active. - */ - for (ent = 0; ent < NUM_IVECS; ent++) { - bp = &ivector_table[ent]; - if (bp != bucket && - bp->imap == imap && - (bp->flags & IBF_ACTIVE) != 0) - break; - } + /* See if any other buckets share this bucket's IMAP + * and are still active. + */ + for (ent = 0; ent < NUM_IVECS; ent++) { + struct ino_bucket *bp = &ivector_table[ent]; + if (bp != bucket && + bp->imap == imap && + (bp->flags & IBF_ACTIVE) != 0) + break; + } - /* Only disable when no other sub-irq levels of - * the same IMAP are active. - */ - if (ent == NUM_IVECS) - disable_irq(irq); + /* Only disable when no other sub-irq levels of + * the same IMAP are active. + */ + if (ent == NUM_IVECS) + disable_irq(irq); + } } -out: - kfree(action); spin_unlock_irqrestore(&irq_action_lock, flags); } @@ -646,99 +554,55 @@ void synchronize_irq(unsigned int irq) } #endif /* CONFIG_SMP */ -void catch_disabled_ivec(struct pt_regs *regs) +static void process_bucket(int irq, struct ino_bucket *bp, struct pt_regs *regs) { - int cpu = smp_processor_id(); - struct ino_bucket *bucket = __bucket(*irq_work(cpu, 0)); + struct irq_desc *desc = bp->irq_info; + unsigned char flags = bp->flags; + u32 action_mask, i; + int random; - /* We can actually see this on Ultra/PCI PCI cards, which are bridges - * to other devices. Here a single IMAP enabled potentially multiple - * unique interrupt sources (which each do have a unique ICLR register. - * - * So what we do is just register that the IVEC arrived, when registered - * for real the request_irq() code will check the bit and signal - * a local CPU interrupt for it. - */ -#if 0 - printk("IVEC: Spurious interrupt vector (%x) received at (%016lx)\n", - bucket - &ivector_table[0], regs->tpc); -#endif - *irq_work(cpu, 0) = 0; - bucket->pending = 1; -} + bp->flags |= IBF_INPROGRESS; -/* Tune this... */ -#define FORWARD_VOLUME 12 - -#ifdef CONFIG_SMP - -static inline void redirect_intr(int cpu, struct ino_bucket *bp) -{ - /* Ok, here is what is going on: - * 1) Retargeting IRQs on Starfire is very - * expensive so just forget about it on them. - * 2) Moving around very high priority interrupts - * is a losing game. - * 3) If the current cpu is idle, interrupts are - * useful work, so keep them here. But do not - * pass to our neighbour if he is not very idle. - * 4) If sysadmin explicitly asks for directed intrs, - * Just Do It. - */ - struct irqaction *ap = bp->irq_info; - cpumask_t cpu_mask; - unsigned int buddy, ticks; - - cpu_mask = get_smpaff_in_irqaction(ap); - cpus_and(cpu_mask, cpu_mask, cpu_online_map); - if (cpus_empty(cpu_mask)) - cpu_mask = cpu_online_map; - - if (this_is_starfire != 0 || - bp->pil >= 10 || current->pid == 0) + if (unlikely(!(flags & IBF_ACTIVE))) { + bp->pending = 1; goto out; - - /* 'cpu' is the MID (ie. UPAID), calculate the MID - * of our buddy. - */ - buddy = cpu + 1; - if (buddy >= NR_CPUS) - buddy = 0; - - ticks = 0; - while (!cpu_isset(buddy, cpu_mask)) { - if (++buddy >= NR_CPUS) - buddy = 0; - if (++ticks > NR_CPUS) { - put_smpaff_in_irqaction(ap, CPU_MASK_NONE); - goto out; - } } - if (buddy == cpu) - goto out; + if (desc->pre_handler) + desc->pre_handler(bp, + desc->pre_handler_arg1, + desc->pre_handler_arg2); - /* Voo-doo programming. */ - if (cpu_data(buddy).idle_volume < FORWARD_VOLUME) - goto out; + action_mask = desc->action_active_mask; + random = 0; + for (i = 0; i < MAX_IRQ_DESC_ACTION; i++) { + struct irqaction *p = &desc->action[i]; + u32 mask = (1 << i); - /* This just so happens to be correct on Cheetah - * at the moment. - */ - buddy <<= 26; + if (!(action_mask & mask)) + continue; - /* Push it to our buddy. */ - upa_writel(buddy | IMAP_VALID, bp->imap); + action_mask &= ~mask; + if (p->handler(__irq(bp), p->dev_id, regs) == IRQ_HANDLED) + random |= p->flags; + + if (!action_mask) + break; + } + if (bp->pil != 0) { + upa_writel(ICLR_IDLE, bp->iclr); + /* Test and add entropy */ + if (random & SA_SAMPLE_RANDOM) + add_interrupt_randomness(irq); + } out: - return; + bp->flags &= ~IBF_INPROGRESS; } -#endif - void handler_irq(int irq, struct pt_regs *regs) { - struct ino_bucket *bp, *nbp; + struct ino_bucket *bp; int cpu = smp_processor_id(); #ifndef CONFIG_SMP @@ -756,8 +620,6 @@ void handler_irq(int irq, struct pt_regs *regs) clear_softint(clr_mask); } #else - int should_forward = 0; - clear_softint(1 << irq); #endif @@ -772,199 +634,76 @@ void handler_irq(int irq, struct pt_regs *regs) #else bp = __bucket(xchg32(irq_work(cpu, irq), 0)); #endif - for ( ; bp != NULL; bp = nbp) { - unsigned char flags = bp->flags; - unsigned char random = 0; + while (bp) { + struct ino_bucket *nbp = __bucket(bp->irq_chain); - nbp = __bucket(bp->irq_chain); bp->irq_chain = 0; - - bp->flags |= IBF_INPROGRESS; - - if ((flags & IBF_ACTIVE) != 0) { -#ifdef CONFIG_PCI - if ((flags & IBF_DMA_SYNC) != 0) { - upa_readl(dma_sync_reg_table[bp->synctab_ent]); - upa_readq(pci_dma_wsync); - } -#endif - if ((flags & IBF_MULTI) == 0) { - struct irqaction *ap = bp->irq_info; - int ret; - - ret = ap->handler(__irq(bp), ap->dev_id, regs); - if (ret == IRQ_HANDLED) - random |= ap->flags; - } else { - void **vector = (void **)bp->irq_info; - int ent; - for (ent = 0; ent < 4; ent++) { - struct irqaction *ap = vector[ent]; - if (ap != NULL) { - int ret; - - ret = ap->handler(__irq(bp), - ap->dev_id, - regs); - if (ret == IRQ_HANDLED) - random |= ap->flags; - } - } - } - /* Only the dummy bucket lacks IMAP/ICLR. */ - if (bp->pil != 0) { -#ifdef CONFIG_SMP - if (should_forward) { - redirect_intr(cpu, bp); - should_forward = 0; - } -#endif - upa_writel(ICLR_IDLE, bp->iclr); - - /* Test and add entropy */ - if (random & SA_SAMPLE_RANDOM) - add_interrupt_randomness(irq); - } - } else - bp->pending = 1; - - bp->flags &= ~IBF_INPROGRESS; + process_bucket(irq, bp, regs); + bp = nbp; } irq_exit(); } #ifdef CONFIG_BLK_DEV_FD -extern void floppy_interrupt(int irq, void *dev_cookie, struct pt_regs *regs); +extern irqreturn_t floppy_interrupt(int, void *, struct pt_regs *);; -void sparc_floppy_irq(int irq, void *dev_cookie, struct pt_regs *regs) -{ - struct irqaction *action = *(irq + irq_action); - struct ino_bucket *bucket; - int cpu = smp_processor_id(); - - irq_enter(); - kstat_this_cpu.irqs[irq]++; - - *(irq_work(cpu, irq)) = 0; - bucket = get_ino_in_irqaction(action) + ivector_table; - - bucket->flags |= IBF_INPROGRESS; - - floppy_interrupt(irq, dev_cookie, regs); - upa_writel(ICLR_IDLE, bucket->iclr); - - bucket->flags &= ~IBF_INPROGRESS; - - irq_exit(); -} -#endif - -/* The following assumes that the branch lies before the place we - * are branching to. This is the case for a trap vector... - * You have been warned. - */ -#define SPARC_BRANCH(dest_addr, inst_addr) \ - (0x10800000 | ((((dest_addr)-(inst_addr))>>2)&0x3fffff)) +/* XXX No easy way to include asm/floppy.h XXX */ +extern unsigned char *pdma_vaddr; +extern unsigned long pdma_size; +extern volatile int doing_pdma; +extern unsigned long fdc_status; -#define SPARC_NOP (0x01000000) - -static void install_fast_irq(unsigned int cpu_irq, - irqreturn_t (*handler)(int, void *, struct pt_regs *)) -{ - extern unsigned long sparc64_ttable_tl0; - unsigned long ttent = (unsigned long) &sparc64_ttable_tl0; - unsigned int *insns; - - ttent += 0x820; - ttent += (cpu_irq - 1) << 5; - insns = (unsigned int *) ttent; - insns[0] = SPARC_BRANCH(((unsigned long) handler), - ((unsigned long)&insns[0])); - insns[1] = SPARC_NOP; - __asm__ __volatile__("membar #StoreStore; flush %0" : : "r" (ttent)); -} - -int request_fast_irq(unsigned int irq, - irqreturn_t (*handler)(int, void *, struct pt_regs *), - unsigned long irqflags, const char *name, void *dev_id) +irqreturn_t sparc_floppy_irq(int irq, void *dev_cookie, struct pt_regs *regs) { - struct irqaction *action; - struct ino_bucket *bucket = __bucket(irq); - unsigned long flags; - - /* No pil0 dummy buckets allowed here. */ - if (bucket < &ivector_table[0] || - bucket >= &ivector_table[NUM_IVECS]) { - unsigned int *caller; - - __asm__ __volatile__("mov %%i7, %0" : "=r" (caller)); - printk(KERN_CRIT "request_fast_irq: Old style IRQ registry attempt " - "from %p, irq %08x.\n", caller, irq); - return -EINVAL; - } - - if (!handler) - return -EINVAL; + if (likely(doing_pdma)) { + void __iomem *stat = (void __iomem *) fdc_status; + unsigned char *vaddr = pdma_vaddr; + unsigned long size = pdma_size; + u8 val; + + while (size) { + val = readb(stat); + if (unlikely(!(val & 0x80))) { + pdma_vaddr = vaddr; + pdma_size = size; + return IRQ_HANDLED; + } + if (unlikely(!(val & 0x20))) { + pdma_vaddr = vaddr; + pdma_size = size; + doing_pdma = 0; + goto main_interrupt; + } + if (val & 0x40) { + /* read */ + *vaddr++ = readb(stat + 1); + } else { + unsigned char data = *vaddr++; - if ((bucket->pil == 0) || (bucket->pil == 14)) { - printk("request_fast_irq: Trying to register shared IRQ 0 or 14.\n"); - return -EBUSY; - } + /* write */ + writeb(data, stat + 1); + } + size--; + } - spin_lock_irqsave(&irq_action_lock, flags); + pdma_vaddr = vaddr; + pdma_size = size; - action = *(bucket->pil + irq_action); - if (action) { - if (action->flags & SA_SHIRQ) - panic("Trying to register fast irq when already shared.\n"); - if (irqflags & SA_SHIRQ) - panic("Trying to register fast irq as shared.\n"); - printk("request_fast_irq: Trying to register yet already owned.\n"); - spin_unlock_irqrestore(&irq_action_lock, flags); - return -EBUSY; - } + /* Send Terminal Count pulse to floppy controller. */ + val = readb(auxio_register); + val |= AUXIO_AUX1_FTCNT; + writeb(val, auxio_register); + val &= AUXIO_AUX1_FTCNT; + writeb(val, auxio_register); - /* - * We do not check for SA_SAMPLE_RANDOM in this path. Neither do we - * support smp intr affinity in this path. - */ - if (irqflags & SA_STATIC_ALLOC) { - if (static_irq_count < MAX_STATIC_ALLOC) - action = &static_irqaction[static_irq_count++]; - else - printk("Request for IRQ%d (%s) SA_STATIC_ALLOC failed " - "using kmalloc\n", bucket->pil, name); - } - if (action == NULL) - action = (struct irqaction *)kmalloc(sizeof(struct irqaction), - GFP_ATOMIC); - if (!action) { - spin_unlock_irqrestore(&irq_action_lock, flags); - return -ENOMEM; + doing_pdma = 0; } - install_fast_irq(bucket->pil, handler); - bucket->irq_info = action; - bucket->flags |= IBF_ACTIVE; - - action->handler = handler; - action->flags = irqflags; - action->dev_id = NULL; - action->name = name; - action->next = NULL; - put_ino_in_irqaction(action, irq); - put_smpaff_in_irqaction(action, CPU_MASK_NONE); - - *(bucket->pil + irq_action) = action; - enable_irq(irq); - - spin_unlock_irqrestore(&irq_action_lock, flags); - -#ifdef CONFIG_SMP - distribute_irqs(); -#endif - return 0; +main_interrupt: + return floppy_interrupt(irq, dev_cookie, regs); } +EXPORT_SYMBOL(sparc_floppy_irq); +#endif /* We really don't need these at all on the Sparc. We only have * stubs here because they are exported to modules. @@ -1030,7 +769,10 @@ static void distribute_irqs(void) */ for (level = 1; level < NR_IRQS; level++) { struct irqaction *p = irq_action[level]; - if (level == 12) continue; + + if (level == 12) + continue; + while(p) { cpu = retarget_one_irq(p, cpu); p = p->next; @@ -1040,8 +782,14 @@ static void distribute_irqs(void) } #endif +struct sun5_timer { + u64 count0; + u64 limit0; + u64 count1; + u64 limit1; +}; -struct sun5_timer *prom_timers; +static struct sun5_timer *prom_timers; static u64 prom_limit0, prom_limit1; static void map_prom_timers(void) @@ -1097,18 +845,6 @@ static void kill_prom_timer(void) : "g1", "g2"); } -void enable_prom_timer(void) -{ - if (!prom_timers) - return; - - /* Set it to whatever was there before. */ - prom_timers->limit1 = prom_limit1; - prom_timers->count1 = 0; - prom_timers->limit0 = prom_limit0; - prom_timers->count0 = 0; -} - void init_irqwork_curcpu(void) { register struct irq_work_struct *workp asm("o2"); @@ -1175,7 +911,8 @@ static int irq_affinity_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) { struct ino_bucket *bp = ivector_table + (long)data; - struct irqaction *ap = bp->irq_info; + struct irq_desc *desc = bp->irq_info; + struct irqaction *ap = desc->action; cpumask_t mask; int len; @@ -1193,11 +930,13 @@ static int irq_affinity_read_proc (char *page, char **start, off_t off, static inline void set_intr_affinity(int irq, cpumask_t hw_aff) { struct ino_bucket *bp = ivector_table + irq; + struct irq_desc *desc = bp->irq_info; + struct irqaction *ap = desc->action; /* Users specify affinity in terms of hw cpu ids. * As soon as we do this, handler_irq() might see and take action. */ - put_smpaff_in_irqaction((struct irqaction *)bp->irq_info, hw_aff); + put_smpaff_in_irqaction(ap, hw_aff); /* Migration is simply done by the next cpu to service this * interrupt. diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c index bdac631cf011..bbf11f85dab1 100644 --- a/arch/sparc64/kernel/kprobes.c +++ b/arch/sparc64/kernel/kprobes.c @@ -433,3 +433,8 @@ int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) return 0; } +/* architecture specific initialization */ +int arch_init_kprobes(void) +{ + return 0; +} diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index 534320ef0db2..91ab466d6c66 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c @@ -1303,8 +1303,7 @@ static void psycho_controller_hwinit(struct pci_controller_info *p) { u64 tmp; - /* PROM sets the IRQ retry value too low, increase it. */ - psycho_write(p->pbm_A.controller_regs + PSYCHO_IRQ_RETRY, 0xff); + psycho_write(p->pbm_A.controller_regs + PSYCHO_IRQ_RETRY, 5); /* Enable arbiter for all PCI slots. */ tmp = psycho_read(p->pbm_A.controller_regs + PSYCHO_PCIA_CTRL); diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index 53d333b4a4e8..52bf3431a422 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c @@ -595,6 +595,23 @@ static int __init sabre_ino_to_pil(struct pci_dev *pdev, unsigned int ino) return ret; } +/* When a device lives behind a bridge deeper in the PCI bus topology + * than APB, a special sequence must run to make sure all pending DMA + * transfers at the time of IRQ delivery are visible in the coherency + * domain by the cpu. This sequence is to perform a read on the far + * side of the non-APB bridge, then perform a read of Sabre's DMA + * write-sync register. + */ +static void sabre_wsync_handler(struct ino_bucket *bucket, void *_arg1, void *_arg2) +{ + struct pci_dev *pdev = _arg1; + unsigned long sync_reg = (unsigned long) _arg2; + u16 _unused; + + pci_read_config_word(pdev, PCI_VENDOR_ID, &_unused); + sabre_read(sync_reg); +} + static unsigned int __init sabre_irq_build(struct pci_pbm_info *pbm, struct pci_dev *pdev, unsigned int ino) @@ -639,24 +656,14 @@ static unsigned int __init sabre_irq_build(struct pci_pbm_info *pbm, if (pdev) { struct pcidev_cookie *pcp = pdev->sysdata; - /* When a device lives behind a bridge deeper in the - * PCI bus topology than APB, a special sequence must - * run to make sure all pending DMA transfers at the - * time of IRQ delivery are visible in the coherency - * domain by the cpu. This sequence is to perform - * a read on the far side of the non-APB bridge, then - * perform a read of Sabre's DMA write-sync register. - * - * Currently, the PCI_CONFIG register for the device - * is used for this read from the far side of the bridge. - */ if (pdev->bus->number != pcp->pbm->pci_first_busno) { - bucket->flags |= IBF_DMA_SYNC; - bucket->synctab_ent = dma_sync_reg_table_entry++; - dma_sync_reg_table[bucket->synctab_ent] = - (unsigned long) sabre_pci_config_mkaddr( - pcp->pbm, - pdev->bus->number, pdev->devfn, PCI_COMMAND); + struct pci_controller_info *p = pcp->pbm->parent; + struct irq_desc *d = bucket->irq_info; + + d->pre_handler = sabre_wsync_handler; + d->pre_handler_arg1 = pdev; + d->pre_handler_arg2 = (void *) + p->pbm_A.controller_regs + SABRE_WRSYNC; } } return __irq(bucket); @@ -1626,10 +1633,9 @@ void __init sabre_init(int pnode, char *model_name) */ p->pbm_A.controller_regs = pr_regs[0].phys_addr; p->pbm_B.controller_regs = pr_regs[0].phys_addr; - pci_dma_wsync = p->pbm_A.controller_regs + SABRE_WRSYNC; - printk("PCI: Found SABRE, main regs at %016lx, wsync at %016lx\n", - p->pbm_A.controller_regs, pci_dma_wsync); + printk("PCI: Found SABRE, main regs at %016lx\n", + p->pbm_A.controller_regs); /* Clear interrupts */ diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index 5753175b94e6..6a182bb66281 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c @@ -15,6 +15,7 @@ #include <asm/iommu.h> #include <asm/irq.h> #include <asm/upa.h> +#include <asm/pstate.h> #include "pci_impl.h" #include "iommu_common.h" @@ -326,6 +327,44 @@ static int __init schizo_ino_to_pil(struct pci_dev *pdev, unsigned int ino) return ret; } +static void tomatillo_wsync_handler(struct ino_bucket *bucket, void *_arg1, void *_arg2) +{ + unsigned long sync_reg = (unsigned long) _arg2; + u64 mask = 1 << (__irq_ino(__irq(bucket)) & IMAP_INO); + u64 val; + int limit; + + schizo_write(sync_reg, mask); + + limit = 100000; + val = 0; + while (--limit) { + val = schizo_read(sync_reg); + if (!(val & mask)) + break; + } + if (limit <= 0) { + printk("tomatillo_wsync_handler: DMA won't sync [%lx:%lx]\n", + val, mask); + } + + if (_arg1) { + static unsigned char cacheline[64] + __attribute__ ((aligned (64))); + + __asm__ __volatile__("rd %%fprs, %0\n\t" + "or %0, %4, %1\n\t" + "wr %1, 0x0, %%fprs\n\t" + "stda %%f0, [%5] %6\n\t" + "wr %0, 0x0, %%fprs\n\t" + "membar #Sync" + : "=&r" (mask), "=&r" (val) + : "0" (mask), "1" (val), + "i" (FPRS_FEF), "r" (&cacheline[0]), + "i" (ASI_BLK_COMMIT_P)); + } +} + static unsigned int schizo_irq_build(struct pci_pbm_info *pbm, struct pci_dev *pdev, unsigned int ino) @@ -369,6 +408,15 @@ static unsigned int schizo_irq_build(struct pci_pbm_info *pbm, bucket = __bucket(build_irq(pil, ign_fixup, iclr, imap)); bucket->flags |= IBF_PCI; + if (pdev && pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) { + struct irq_desc *p = bucket->irq_info; + + p->pre_handler = tomatillo_wsync_handler; + p->pre_handler_arg1 = ((pbm->chip_version <= 4) ? + (void *) 1 : (void *) 0); + p->pre_handler_arg2 = (void *) pbm->sync_reg; + } + return __irq(bucket); } @@ -885,6 +933,7 @@ static irqreturn_t schizo_ce_intr(int irq, void *dev_id, struct pt_regs *regs) #define SCHIZO_PCI_CTRL (0x2000UL) #define SCHIZO_PCICTRL_BUS_UNUS (1UL << 63UL) /* Safari */ +#define SCHIZO_PCICTRL_DTO_INT (1UL << 61UL) /* Tomatillo */ #define SCHIZO_PCICTRL_ARB_PRIO (0x1ff << 52UL) /* Tomatillo */ #define SCHIZO_PCICTRL_ESLCK (1UL << 51UL) /* Safari */ #define SCHIZO_PCICTRL_ERRSLOT (7UL << 48UL) /* Safari */ @@ -1887,37 +1936,27 @@ static void __init schizo_pbm_hw_init(struct pci_pbm_info *pbm) { u64 tmp; - /* Set IRQ retry to infinity. */ - schizo_write(pbm->pbm_regs + SCHIZO_PCI_IRQ_RETRY, - SCHIZO_IRQ_RETRY_INF); + schizo_write(pbm->pbm_regs + SCHIZO_PCI_IRQ_RETRY, 5); - /* Enable arbiter for all PCI slots. Also, disable PCI interval - * timer so that DTO (Discard TimeOuts) are not reported because - * some Schizo revisions report them erroneously. - */ tmp = schizo_read(pbm->pbm_regs + SCHIZO_PCI_CTRL); - if (pbm->chip_type == PBM_CHIP_TYPE_SCHIZO_PLUS && - pbm->chip_version == 0x5 && - pbm->chip_revision == 0x1) - tmp |= 0x0f; - else - tmp |= 0xff; - tmp &= ~SCHIZO_PCICTRL_PTO; + /* Enable arbiter for all PCI slots. */ + tmp |= 0xff; + if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO && pbm->chip_version >= 0x2) tmp |= 0x3UL << SCHIZO_PCICTRL_PTO_SHIFT; - else - tmp |= 0x1UL << SCHIZO_PCICTRL_PTO_SHIFT; if (!prom_getbool(pbm->prom_node, "no-bus-parking")) tmp |= SCHIZO_PCICTRL_PARK; + else + tmp &= ~SCHIZO_PCICTRL_PARK; if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO && pbm->chip_version <= 0x1) - tmp |= (1UL << 61); + tmp |= SCHIZO_PCICTRL_DTO_INT; else - tmp &= ~(1UL << 61); + tmp &= ~SCHIZO_PCICTRL_DTO_INT; if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) tmp |= (SCHIZO_PCICTRL_MRM_PREF | @@ -2015,6 +2054,9 @@ static void __init schizo_pbm_init(struct pci_controller_info *p, pbm->pbm_regs = pr_regs[0].phys_addr; pbm->controller_regs = pr_regs[1].phys_addr - 0x10000UL; + if (chip_type == PBM_CHIP_TYPE_TOMATILLO) + pbm->sync_reg = pr_regs[3].phys_addr + 0x1a18UL; + sprintf(pbm->name, (chip_type == PBM_CHIP_TYPE_TOMATILLO ? "TOMATILLO%d PBM%c" : diff --git a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c index 52f14e399b1c..533104c7907d 100644 --- a/arch/sparc64/kernel/power.c +++ b/arch/sparc64/kernel/power.c @@ -4,6 +4,8 @@ * Copyright (C) 1999 David S. Miller (davem@redhat.com) */ +#define __KERNEL_SYSCALLS__ + #include <linux/config.h> #include <linux/kernel.h> #include <linux/module.h> @@ -17,7 +19,6 @@ #include <asm/ebus.h> #include <asm/auxio.h> -#define __KERNEL_SYSCALLS__ #include <linux/unistd.h> /* diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c index a0cd2b2494d6..cffb1c8ab4fc 100644 --- a/arch/sparc64/kernel/process.c +++ b/arch/sparc64/kernel/process.c @@ -621,8 +621,8 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, memcpy(child_trap_frame, (((struct sparc_stackf *)regs)-1), (TRACEREG_SZ+STACKFRAME_SZ)); t->flags = (t->flags & ~((0xffUL << TI_FLAG_CWP_SHIFT) | (0xffUL << TI_FLAG_CURRENT_DS_SHIFT))) | - _TIF_NEWCHILD | (((regs->tstate + 1) & TSTATE_CWP) << TI_FLAG_CWP_SHIFT); + t->new_child = 1; t->ksp = ((unsigned long) child_trap_frame) - STACK_BIAS; t->kregs = (struct pt_regs *)(child_trap_frame+sizeof(struct sparc_stackf)); t->fpsaved[0] = 0; diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c index 80a76e2ad732..23ad839d113f 100644 --- a/arch/sparc64/kernel/ptrace.c +++ b/arch/sparc64/kernel/ptrace.c @@ -19,6 +19,8 @@ #include <linux/smp.h> #include <linux/smp_lock.h> #include <linux/security.h> +#include <linux/seccomp.h> +#include <linux/audit.h> #include <linux/signal.h> #include <asm/asi.h> @@ -628,15 +630,27 @@ out: unlock_kernel(); } -asmlinkage void syscall_trace(void) +asmlinkage void syscall_trace(struct pt_regs *regs, int syscall_exit_p) { -#ifdef DEBUG_PTRACE - printk("%s [%d]: syscall_trace\n", current->comm, current->pid); -#endif - if (!test_thread_flag(TIF_SYSCALL_TRACE)) - return; + /* do the secure computing check first */ + secure_computing(regs->u_regs[UREG_G1]); + + if (unlikely(current->audit_context) && syscall_exit_p) { + unsigned long tstate = regs->tstate; + int result = AUDITSC_SUCCESS; + + if (unlikely(tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) + result = AUDITSC_FAILURE; + + audit_syscall_exit(current, result, regs->u_regs[UREG_I0]); + } + if (!(current->ptrace & PT_PTRACED)) - return; + goto out; + + if (!test_thread_flag(TIF_SYSCALL_TRACE)) + goto out; + ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0)); @@ -645,12 +659,20 @@ asmlinkage void syscall_trace(void) * for normal use. strace only continues with a signal if the * stopping signal is not SIGTRAP. -brl */ -#ifdef DEBUG_PTRACE - printk("%s [%d]: syscall_trace exit= %x\n", current->comm, - current->pid, current->exit_code); -#endif if (current->exit_code) { - send_sig (current->exit_code, current, 1); + send_sig(current->exit_code, current, 1); current->exit_code = 0; } + +out: + if (unlikely(current->audit_context) && !syscall_exit_p) + audit_syscall_entry(current, + (test_thread_flag(TIF_32BIT) ? + AUDIT_ARCH_SPARC : + AUDIT_ARCH_SPARC64), + regs->u_regs[UREG_G1], + regs->u_regs[UREG_I0], + regs->u_regs[UREG_I1], + regs->u_regs[UREG_I2], + regs->u_regs[UREG_I3]); } diff --git a/arch/sparc64/kernel/semaphore.c b/arch/sparc64/kernel/semaphore.c index 63496c43fe17..a809e63f03ef 100644 --- a/arch/sparc64/kernel/semaphore.c +++ b/arch/sparc64/kernel/semaphore.c @@ -32,8 +32,9 @@ static __inline__ int __sem_update_count(struct semaphore *sem, int incr) " add %1, %4, %1\n" " cas [%3], %0, %1\n" " cmp %0, %1\n" +" membar #StoreLoad | #StoreStore\n" " bne,pn %%icc, 1b\n" -" membar #StoreLoad | #StoreStore\n" +" nop\n" : "=&r" (old_count), "=&r" (tmp), "=m" (sem->count) : "r" (&sem->count), "r" (incr), "m" (sem->count) : "cc"); @@ -71,8 +72,9 @@ void up(struct semaphore *sem) " cmp %%g1, %%g7\n" " bne,pn %%icc, 1b\n" " addcc %%g7, 1, %%g0\n" +" membar #StoreLoad | #StoreStore\n" " ble,pn %%icc, 3f\n" -" membar #StoreLoad | #StoreStore\n" +" nop\n" "2:\n" " .subsection 2\n" "3: mov %0, %%g1\n" @@ -128,8 +130,9 @@ void __sched down(struct semaphore *sem) " cmp %%g1, %%g7\n" " bne,pn %%icc, 1b\n" " cmp %%g7, 1\n" +" membar #StoreLoad | #StoreStore\n" " bl,pn %%icc, 3f\n" -" membar #StoreLoad | #StoreStore\n" +" nop\n" "2:\n" " .subsection 2\n" "3: mov %0, %%g1\n" @@ -233,8 +236,9 @@ int __sched down_interruptible(struct semaphore *sem) " cmp %%g1, %%g7\n" " bne,pn %%icc, 1b\n" " cmp %%g7, 1\n" +" membar #StoreLoad | #StoreStore\n" " bl,pn %%icc, 3f\n" -" membar #StoreLoad | #StoreStore\n" +" nop\n" "2:\n" " .subsection 2\n" "3: mov %2, %%g1\n" diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index e5b9c7a27789..b9b42491e118 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -45,8 +45,8 @@ extern void calibrate_delay(void); /* Please don't make this stuff initdata!!! --DaveM */ static unsigned char boot_cpu_id; -cpumask_t cpu_online_map = CPU_MASK_NONE; -cpumask_t phys_cpu_present_map = CPU_MASK_NONE; +cpumask_t cpu_online_map __read_mostly = CPU_MASK_NONE; +cpumask_t phys_cpu_present_map __read_mostly = CPU_MASK_NONE; static cpumask_t smp_commenced_mask; static cpumask_t cpu_callout_map; @@ -137,7 +137,7 @@ void __init smp_callin(void) /* Clear this or we will die instantly when we * schedule back to this idler... */ - clear_thread_flag(TIF_NEWCHILD); + current_thread_info()->new_child = 0; /* Attach to the address space of init_task. */ atomic_inc(&init_mm.mm_count); @@ -155,7 +155,7 @@ void cpu_panic(void) panic("SMP bolixed\n"); } -static unsigned long current_tick_offset; +static unsigned long current_tick_offset __read_mostly; /* This tick register synchronization scheme is taken entirely from * the ia64 port, see arch/ia64/kernel/smpboot.c for details and credit. @@ -1193,8 +1193,8 @@ void smp_send_stop(void) { } -unsigned long __per_cpu_base; -unsigned long __per_cpu_shift; +unsigned long __per_cpu_base __read_mostly; +unsigned long __per_cpu_shift __read_mostly; EXPORT_SYMBOL(__per_cpu_base); EXPORT_SYMBOL(__per_cpu_shift); diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index e78cc53594fa..9202d925a9ce 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c @@ -79,7 +79,7 @@ extern void linux_sparc_syscall(void); extern void rtrap(void); extern void show_regs(struct pt_regs *); extern void solaris_syscall(void); -extern void syscall_trace(void); +extern void syscall_trace(struct pt_regs *, int); extern u32 sunos_sys_table[], sys_call_table32[]; extern void tl0_solaris(void); extern void sys_sigsuspend(void); @@ -227,7 +227,6 @@ EXPORT_SYMBOL(__flush_dcache_range); EXPORT_SYMBOL(mostek_lock); EXPORT_SYMBOL(mstk48t02_regs); -EXPORT_SYMBOL(request_fast_irq); #ifdef CONFIG_SUN_AUXIO EXPORT_SYMBOL(auxio_set_led); EXPORT_SYMBOL(auxio_set_lte); diff --git a/arch/sparc64/kernel/sys32.S b/arch/sparc64/kernel/sys32.S index 5a95e98c5317..5f9e4fae612e 100644 --- a/arch/sparc64/kernel/sys32.S +++ b/arch/sparc64/kernel/sys32.S @@ -135,6 +135,8 @@ SIGN2(sys32_shutdown, sys_shutdown, %o0, %o1) SIGN3(sys32_socketpair, sys_socketpair, %o0, %o1, %o2) SIGN1(sys32_getpeername, sys_getpeername, %o0) SIGN1(sys32_getsockname, sys_getsockname, %o0) +SIGN2(sys32_ioprio_get, sys_ioprio_get, %o0, %o1) +SIGN3(sys32_ioprio_set, sys_ioprio_set, %o0, %o1, %o2) .globl sys32_mmap2 sys32_mmap2: diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S index a5e36a4c8924..bceb91a8a2bd 100644 --- a/arch/sparc64/kernel/systbls.S +++ b/arch/sparc64/kernel/systbls.S @@ -59,11 +59,11 @@ sys_call_table32: /*180*/ .word sys32_flistxattr, sys_removexattr, sys_lremovexattr, compat_sys_sigpending, sys_ni_syscall .word sys32_setpgid, sys32_fremovexattr, sys32_tkill, sys32_exit_group, sparc64_newuname /*190*/ .word sys32_init_module, sparc64_personality, sys_remap_file_pages, sys32_epoll_create, sys32_epoll_ctl - .word sys32_epoll_wait, sys_nis_syscall, sys_getppid, sys32_sigaction, sys_sgetmask + .word sys32_epoll_wait, sys32_ioprio_set, sys_getppid, sys32_sigaction, sys_sgetmask /*200*/ .word sys32_ssetmask, sys_sigsuspend, compat_sys_newlstat, sys_uselib, compat_sys_old_readdir .word sys32_readahead, sys32_socketcall, sys32_syslog, sys32_lookup_dcookie, sys32_fadvise64 /*210*/ .word sys32_fadvise64_64, sys32_tgkill, sys32_waitpid, sys_swapoff, sys32_sysinfo - .word sys32_ipc, sys32_sigreturn, sys_clone, sys_nis_syscall, sys32_adjtimex + .word sys32_ipc, sys32_sigreturn, sys_clone, sys32_ioprio_get, sys32_adjtimex /*220*/ .word sys32_sigprocmask, sys_ni_syscall, sys32_delete_module, sys_ni_syscall, sys32_getpgid .word sys32_bdflush, sys32_sysfs, sys_nis_syscall, sys32_setfsuid16, sys32_setfsgid16 /*230*/ .word sys32_select, compat_sys_time, sys_nis_syscall, compat_sys_stime, compat_sys_statfs64 @@ -125,11 +125,11 @@ sys_call_table: /*180*/ .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_ni_syscall .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sparc64_newuname /*190*/ .word sys_init_module, sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl - .word sys_epoll_wait, sys_nis_syscall, sys_getppid, sys_nis_syscall, sys_sgetmask + .word sys_epoll_wait, sys_ioprio_set, sys_getppid, sys_nis_syscall, sys_sgetmask /*200*/ .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall .word sys_readahead, sys_socketcall, sys_syslog, sys_lookup_dcookie, sys_fadvise64 /*210*/ .word sys_fadvise64_64, sys_tgkill, sys_waitpid, sys_swapoff, sys_sysinfo - .word sys_ipc, sys_nis_syscall, sys_clone, sys_nis_syscall, sys_adjtimex + .word sys_ipc, sys_nis_syscall, sys_clone, sys_ioprio_get, sys_adjtimex /*220*/ .word sys_nis_syscall, sys_ni_syscall, sys_delete_module, sys_ni_syscall, sys_getpgid .word sys_bdflush, sys_sysfs, sys_nis_syscall, sys_setfsuid, sys_setfsgid /*230*/ .word sys_select, sys_nis_syscall, sys_nis_syscall, sys_stime, sys_statfs64 diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index 71b4e3807694..362b9c26871b 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c @@ -73,7 +73,7 @@ static __initdata struct sparc64_tick_ops dummy_tick_ops = { .get_tick = dummy_get_tick, }; -struct sparc64_tick_ops *tick_ops = &dummy_tick_ops; +struct sparc64_tick_ops *tick_ops __read_mostly = &dummy_tick_ops; #define TICK_PRIV_BIT (1UL << 63) @@ -195,7 +195,7 @@ static unsigned long tick_add_tick(unsigned long adj, unsigned long offset) return new_tick; } -static struct sparc64_tick_ops tick_operations = { +static struct sparc64_tick_ops tick_operations __read_mostly = { .init_tick = tick_init_tick, .get_tick = tick_get_tick, .get_compare = tick_get_compare, @@ -276,7 +276,7 @@ static unsigned long stick_add_compare(unsigned long adj) return new_compare; } -static struct sparc64_tick_ops stick_operations = { +static struct sparc64_tick_ops stick_operations __read_mostly = { .init_tick = stick_init_tick, .get_tick = stick_get_tick, .get_compare = stick_get_compare, @@ -422,7 +422,7 @@ static unsigned long hbtick_add_compare(unsigned long adj) return val; } -static struct sparc64_tick_ops hbtick_operations = { +static struct sparc64_tick_ops hbtick_operations __read_mostly = { .init_tick = hbtick_init_tick, .get_tick = hbtick_get_tick, .get_compare = hbtick_get_compare, @@ -437,10 +437,9 @@ static struct sparc64_tick_ops hbtick_operations = { * NOTE: On SUN5 systems the ticker interrupt comes in using 2 * interrupts, one at level14 and one with softint bit 0. */ -unsigned long timer_tick_offset; -unsigned long timer_tick_compare; +unsigned long timer_tick_offset __read_mostly; -static unsigned long timer_ticks_per_nsec_quotient; +static unsigned long timer_ticks_per_nsec_quotient __read_mostly; #define TICK_SIZE (tick_nsec / 1000) @@ -464,7 +463,7 @@ static inline void timer_check_rtc(void) static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) { - unsigned long ticks, pstate; + unsigned long ticks, compare, pstate; write_seqlock(&xtime_lock); @@ -483,14 +482,14 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) : "=r" (pstate) : "i" (PSTATE_IE)); - timer_tick_compare = tick_ops->add_compare(timer_tick_offset); + compare = tick_ops->add_compare(timer_tick_offset); ticks = tick_ops->get_tick(); /* Restore PSTATE_IE. */ __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : /* no outputs */ : "r" (pstate)); - } while (time_after_eq(ticks, timer_tick_compare)); + } while (time_after_eq(ticks, compare)); timer_check_rtc(); @@ -506,11 +505,6 @@ void timer_tick_interrupt(struct pt_regs *regs) do_timer(regs); - /* - * Only keep timer_tick_offset uptodate, but don't set TICK_CMPR. - */ - timer_tick_compare = tick_ops->get_compare() + timer_tick_offset; - timer_check_rtc(); write_sequnlock(&xtime_lock); @@ -973,7 +967,7 @@ static void sparc64_start_timers(irqreturn_t (*cfunc)(int, void *, struct pt_reg int err; /* Register IRQ handler. */ - err = request_irq(build_irq(0, 0, 0UL, 0UL), cfunc, SA_STATIC_ALLOC, + err = request_irq(build_irq(0, 0, 0UL, 0UL), cfunc, 0, "timer", NULL); if (err) { diff --git a/arch/sparc64/kernel/trampoline.S b/arch/sparc64/kernel/trampoline.S index 2c8f9344b4ee..3a145fc39cf2 100644 --- a/arch/sparc64/kernel/trampoline.S +++ b/arch/sparc64/kernel/trampoline.S @@ -98,8 +98,9 @@ startup_continue: sethi %hi(prom_entry_lock), %g2 1: ldstub [%g2 + %lo(prom_entry_lock)], %g1 + membar #StoreLoad | #StoreStore brnz,pn %g1, 1b - membar #StoreLoad | #StoreStore + nop sethi %hi(p1275buf), %g2 or %g2, %lo(p1275buf), %g2 diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index a9f4596d7c2b..100b0107c4be 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c @@ -2125,6 +2125,8 @@ void __init trap_init(void) TI_PCR != offsetof(struct thread_info, pcr_reg) || TI_CEE_STUFF != offsetof(struct thread_info, cee_stuff) || TI_PRE_COUNT != offsetof(struct thread_info, preempt_count) || + TI_NEW_CHILD != offsetof(struct thread_info, new_child) || + TI_SYS_NOERROR != offsetof(struct thread_info, syscall_noerror) || TI_FPREGS != offsetof(struct thread_info, fpregs) || (TI_FPREGS & (64 - 1))) thread_info_offsets_are_bolixed_dave(); diff --git a/arch/sparc64/kernel/vmlinux.lds.S b/arch/sparc64/kernel/vmlinux.lds.S index 382fd6798bb9..950423da8a6a 100644 --- a/arch/sparc64/kernel/vmlinux.lds.S +++ b/arch/sparc64/kernel/vmlinux.lds.S @@ -32,6 +32,8 @@ SECTIONS .data1 : { *(.data1) } . = ALIGN(64); .data.cacheline_aligned : { *(.data.cacheline_aligned) } + . = ALIGN(64); + .data.read_mostly : { *(.data.read_mostly) } _edata = .; PROVIDE (edata = .); .fixup : { *(.fixup) } diff --git a/arch/sparc64/lib/U1memcpy.S b/arch/sparc64/lib/U1memcpy.S index da9b520c7189..bafd2fc07acb 100644 --- a/arch/sparc64/lib/U1memcpy.S +++ b/arch/sparc64/lib/U1memcpy.S @@ -87,14 +87,17 @@ #define LOOP_CHUNK3(src, dest, len, branch_dest) \ MAIN_LOOP_CHUNK(src, dest, f32, f48, len, branch_dest) +#define DO_SYNC membar #Sync; #define STORE_SYNC(dest, fsrc) \ EX_ST(STORE_BLK(%fsrc, %dest)); \ - add %dest, 0x40, %dest; + add %dest, 0x40, %dest; \ + DO_SYNC #define STORE_JUMP(dest, fsrc, target) \ EX_ST(STORE_BLK(%fsrc, %dest)); \ add %dest, 0x40, %dest; \ - ba,pt %xcc, target; + ba,pt %xcc, target; \ + nop; #define FINISH_VISCHUNK(dest, f0, f1, left) \ subcc %left, 8, %left;\ @@ -239,17 +242,17 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ ba,pt %xcc, 1b+4 faligndata %f0, %f2, %f48 1: FREG_FROB(f16,f18,f20,f22,f24,f26,f28,f30,f32) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f32,f34,f36,f38,f40,f42,f44,f46,f0) - STORE_JUMP(o0, f48, 40f) membar #Sync + STORE_JUMP(o0, f48, 40f) 2: FREG_FROB(f32,f34,f36,f38,f40,f42,f44,f46,f0) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f0, f2, f4, f6, f8, f10,f12,f14,f16) - STORE_JUMP(o0, f48, 48f) membar #Sync + STORE_JUMP(o0, f48, 48f) 3: FREG_FROB(f0, f2, f4, f6, f8, f10,f12,f14,f16) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f16,f18,f20,f22,f24,f26,f28,f30,f32) - STORE_JUMP(o0, f48, 56f) membar #Sync + STORE_JUMP(o0, f48, 56f) 1: FREG_FROB(f2, f4, f6, f8, f10,f12,f14,f16,f18) LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f) @@ -260,17 +263,17 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ ba,pt %xcc, 1b+4 faligndata %f2, %f4, %f48 1: FREG_FROB(f18,f20,f22,f24,f26,f28,f30,f32,f34) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f34,f36,f38,f40,f42,f44,f46,f0, f2) - STORE_JUMP(o0, f48, 41f) membar #Sync + STORE_JUMP(o0, f48, 41f) 2: FREG_FROB(f34,f36,f38,f40,f42,f44,f46,f0, f2) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f2, f4, f6, f8, f10,f12,f14,f16,f18) - STORE_JUMP(o0, f48, 49f) membar #Sync + STORE_JUMP(o0, f48, 49f) 3: FREG_FROB(f2, f4, f6, f8, f10,f12,f14,f16,f18) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f18,f20,f22,f24,f26,f28,f30,f32,f34) - STORE_JUMP(o0, f48, 57f) membar #Sync + STORE_JUMP(o0, f48, 57f) 1: FREG_FROB(f4, f6, f8, f10,f12,f14,f16,f18,f20) LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f) @@ -281,17 +284,17 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ ba,pt %xcc, 1b+4 faligndata %f4, %f6, %f48 1: FREG_FROB(f20,f22,f24,f26,f28,f30,f32,f34,f36) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f36,f38,f40,f42,f44,f46,f0, f2, f4) - STORE_JUMP(o0, f48, 42f) membar #Sync + STORE_JUMP(o0, f48, 42f) 2: FREG_FROB(f36,f38,f40,f42,f44,f46,f0, f2, f4) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f4, f6, f8, f10,f12,f14,f16,f18,f20) - STORE_JUMP(o0, f48, 50f) membar #Sync + STORE_JUMP(o0, f48, 50f) 3: FREG_FROB(f4, f6, f8, f10,f12,f14,f16,f18,f20) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f20,f22,f24,f26,f28,f30,f32,f34,f36) - STORE_JUMP(o0, f48, 58f) membar #Sync + STORE_JUMP(o0, f48, 58f) 1: FREG_FROB(f6, f8, f10,f12,f14,f16,f18,f20,f22) LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f) @@ -302,17 +305,17 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ ba,pt %xcc, 1b+4 faligndata %f6, %f8, %f48 1: FREG_FROB(f22,f24,f26,f28,f30,f32,f34,f36,f38) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f38,f40,f42,f44,f46,f0, f2, f4, f6) - STORE_JUMP(o0, f48, 43f) membar #Sync + STORE_JUMP(o0, f48, 43f) 2: FREG_FROB(f38,f40,f42,f44,f46,f0, f2, f4, f6) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f6, f8, f10,f12,f14,f16,f18,f20,f22) - STORE_JUMP(o0, f48, 51f) membar #Sync + STORE_JUMP(o0, f48, 51f) 3: FREG_FROB(f6, f8, f10,f12,f14,f16,f18,f20,f22) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f22,f24,f26,f28,f30,f32,f34,f36,f38) - STORE_JUMP(o0, f48, 59f) membar #Sync + STORE_JUMP(o0, f48, 59f) 1: FREG_FROB(f8, f10,f12,f14,f16,f18,f20,f22,f24) LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f) @@ -323,17 +326,17 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ ba,pt %xcc, 1b+4 faligndata %f8, %f10, %f48 1: FREG_FROB(f24,f26,f28,f30,f32,f34,f36,f38,f40) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f40,f42,f44,f46,f0, f2, f4, f6, f8) - STORE_JUMP(o0, f48, 44f) membar #Sync + STORE_JUMP(o0, f48, 44f) 2: FREG_FROB(f40,f42,f44,f46,f0, f2, f4, f6, f8) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f8, f10,f12,f14,f16,f18,f20,f22,f24) - STORE_JUMP(o0, f48, 52f) membar #Sync + STORE_JUMP(o0, f48, 52f) 3: FREG_FROB(f8, f10,f12,f14,f16,f18,f20,f22,f24) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f24,f26,f28,f30,f32,f34,f36,f38,f40) - STORE_JUMP(o0, f48, 60f) membar #Sync + STORE_JUMP(o0, f48, 60f) 1: FREG_FROB(f10,f12,f14,f16,f18,f20,f22,f24,f26) LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f) @@ -344,17 +347,17 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ ba,pt %xcc, 1b+4 faligndata %f10, %f12, %f48 1: FREG_FROB(f26,f28,f30,f32,f34,f36,f38,f40,f42) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f42,f44,f46,f0, f2, f4, f6, f8, f10) - STORE_JUMP(o0, f48, 45f) membar #Sync + STORE_JUMP(o0, f48, 45f) 2: FREG_FROB(f42,f44,f46,f0, f2, f4, f6, f8, f10) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f10,f12,f14,f16,f18,f20,f22,f24,f26) - STORE_JUMP(o0, f48, 53f) membar #Sync + STORE_JUMP(o0, f48, 53f) 3: FREG_FROB(f10,f12,f14,f16,f18,f20,f22,f24,f26) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f26,f28,f30,f32,f34,f36,f38,f40,f42) - STORE_JUMP(o0, f48, 61f) membar #Sync + STORE_JUMP(o0, f48, 61f) 1: FREG_FROB(f12,f14,f16,f18,f20,f22,f24,f26,f28) LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f) @@ -365,17 +368,17 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ ba,pt %xcc, 1b+4 faligndata %f12, %f14, %f48 1: FREG_FROB(f28,f30,f32,f34,f36,f38,f40,f42,f44) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f44,f46,f0, f2, f4, f6, f8, f10,f12) - STORE_JUMP(o0, f48, 46f) membar #Sync + STORE_JUMP(o0, f48, 46f) 2: FREG_FROB(f44,f46,f0, f2, f4, f6, f8, f10,f12) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f12,f14,f16,f18,f20,f22,f24,f26,f28) - STORE_JUMP(o0, f48, 54f) membar #Sync + STORE_JUMP(o0, f48, 54f) 3: FREG_FROB(f12,f14,f16,f18,f20,f22,f24,f26,f28) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f28,f30,f32,f34,f36,f38,f40,f42,f44) - STORE_JUMP(o0, f48, 62f) membar #Sync + STORE_JUMP(o0, f48, 62f) 1: FREG_FROB(f14,f16,f18,f20,f22,f24,f26,f28,f30) LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f) @@ -386,17 +389,17 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ ba,pt %xcc, 1b+4 faligndata %f14, %f16, %f48 1: FREG_FROB(f30,f32,f34,f36,f38,f40,f42,f44,f46) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f46,f0, f2, f4, f6, f8, f10,f12,f14) - STORE_JUMP(o0, f48, 47f) membar #Sync + STORE_JUMP(o0, f48, 47f) 2: FREG_FROB(f46,f0, f2, f4, f6, f8, f10,f12,f14) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f14,f16,f18,f20,f22,f24,f26,f28,f30) - STORE_JUMP(o0, f48, 55f) membar #Sync + STORE_JUMP(o0, f48, 55f) 3: FREG_FROB(f14,f16,f18,f20,f22,f24,f26,f28,f30) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f30,f32,f34,f36,f38,f40,f42,f44,f46) - STORE_JUMP(o0, f48, 63f) membar #Sync + STORE_JUMP(o0, f48, 63f) 40: FINISH_VISCHUNK(o0, f0, f2, g3) 41: FINISH_VISCHUNK(o0, f2, f4, g3) diff --git a/arch/sparc64/lib/VISsave.S b/arch/sparc64/lib/VISsave.S index 65e328d600a8..4e18989bd602 100644 --- a/arch/sparc64/lib/VISsave.S +++ b/arch/sparc64/lib/VISsave.S @@ -72,7 +72,11 @@ vis1: ldub [%g6 + TI_FPSAVED], %g3 stda %f48, [%g3 + %g1] ASI_BLK_P 5: membar #Sync - jmpl %g7 + %g0, %g0 + ba,pt %xcc, 80f + nop + + .align 32 +80: jmpl %g7 + %g0, %g0 nop 6: ldub [%g3 + TI_FPSAVED], %o5 @@ -87,8 +91,11 @@ vis1: ldub [%g6 + TI_FPSAVED], %g3 stda %f32, [%g2 + %g1] ASI_BLK_P stda %f48, [%g3 + %g1] ASI_BLK_P membar #Sync - jmpl %g7 + %g0, %g0 + ba,pt %xcc, 80f + nop + .align 32 +80: jmpl %g7 + %g0, %g0 nop .align 32 @@ -126,6 +133,10 @@ VISenterhalf: stda %f0, [%g2 + %g1] ASI_BLK_P stda %f16, [%g3 + %g1] ASI_BLK_P membar #Sync + ba,pt %xcc, 4f + nop + + .align 32 4: and %o5, FPRS_DU, %o5 jmpl %g7 + %g0, %g0 wr %o5, FPRS_FEF, %fprs diff --git a/arch/sparc64/lib/atomic.S b/arch/sparc64/lib/atomic.S index e528b8d1a3e6..faf87c31598b 100644 --- a/arch/sparc64/lib/atomic.S +++ b/arch/sparc64/lib/atomic.S @@ -7,18 +7,6 @@ #include <linux/config.h> #include <asm/asi.h> - /* On SMP we need to use memory barriers to ensure - * correct memory operation ordering, nop these out - * for uniprocessor. - */ -#ifdef CONFIG_SMP -#define ATOMIC_PRE_BARRIER membar #StoreLoad | #LoadLoad -#define ATOMIC_POST_BARRIER membar #StoreLoad | #StoreStore -#else -#define ATOMIC_PRE_BARRIER nop -#define ATOMIC_POST_BARRIER nop -#endif - .text /* Two versions of the atomic routines, one that @@ -52,6 +40,24 @@ atomic_sub: /* %o0 = decrement, %o1 = atomic_ptr */ nop .size atomic_sub, .-atomic_sub + /* On SMP we need to use memory barriers to ensure + * correct memory operation ordering, nop these out + * for uniprocessor. + */ +#ifdef CONFIG_SMP + +#define ATOMIC_PRE_BARRIER membar #StoreLoad | #LoadLoad; +#define ATOMIC_POST_BARRIER \ + ba,pt %xcc, 80b; \ + membar #StoreLoad | #StoreStore + +80: retl + nop +#else +#define ATOMIC_PRE_BARRIER +#define ATOMIC_POST_BARRIER +#endif + .globl atomic_add_ret .type atomic_add_ret,#function atomic_add_ret: /* %o0 = increment, %o1 = atomic_ptr */ @@ -62,9 +68,10 @@ atomic_add_ret: /* %o0 = increment, %o1 = atomic_ptr */ cmp %g1, %g7 bne,pn %icc, 1b add %g7, %o0, %g7 + sra %g7, 0, %o0 ATOMIC_POST_BARRIER retl - sra %g7, 0, %o0 + nop .size atomic_add_ret, .-atomic_add_ret .globl atomic_sub_ret @@ -77,9 +84,10 @@ atomic_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */ cmp %g1, %g7 bne,pn %icc, 1b sub %g7, %o0, %g7 + sra %g7, 0, %o0 ATOMIC_POST_BARRIER retl - sra %g7, 0, %o0 + nop .size atomic_sub_ret, .-atomic_sub_ret .globl atomic64_add @@ -118,9 +126,10 @@ atomic64_add_ret: /* %o0 = increment, %o1 = atomic_ptr */ cmp %g1, %g7 bne,pn %xcc, 1b add %g7, %o0, %g7 + mov %g7, %o0 ATOMIC_POST_BARRIER retl - mov %g7, %o0 + nop .size atomic64_add_ret, .-atomic64_add_ret .globl atomic64_sub_ret @@ -133,7 +142,8 @@ atomic64_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */ cmp %g1, %g7 bne,pn %xcc, 1b sub %g7, %o0, %g7 + mov %g7, %o0 ATOMIC_POST_BARRIER retl - mov %g7, %o0 + nop .size atomic64_sub_ret, .-atomic64_sub_ret diff --git a/arch/sparc64/lib/bitops.S b/arch/sparc64/lib/bitops.S index 886dcd2b376a..31afbfe6c1e8 100644 --- a/arch/sparc64/lib/bitops.S +++ b/arch/sparc64/lib/bitops.S @@ -7,20 +7,26 @@ #include <linux/config.h> #include <asm/asi.h> + .text + /* On SMP we need to use memory barriers to ensure * correct memory operation ordering, nop these out * for uniprocessor. */ + #ifdef CONFIG_SMP #define BITOP_PRE_BARRIER membar #StoreLoad | #LoadLoad -#define BITOP_POST_BARRIER membar #StoreLoad | #StoreStore +#define BITOP_POST_BARRIER \ + ba,pt %xcc, 80b; \ + membar #StoreLoad | #StoreStore + +80: retl + nop #else -#define BITOP_PRE_BARRIER nop -#define BITOP_POST_BARRIER nop +#define BITOP_PRE_BARRIER +#define BITOP_POST_BARRIER #endif - .text - .globl test_and_set_bit .type test_and_set_bit,#function test_and_set_bit: /* %o0=nr, %o1=addr */ @@ -37,10 +43,11 @@ test_and_set_bit: /* %o0=nr, %o1=addr */ cmp %g7, %g1 bne,pn %xcc, 1b and %g7, %o2, %g2 - BITOP_POST_BARRIER clr %o0 + movrne %g2, 1, %o0 + BITOP_POST_BARRIER retl - movrne %g2, 1, %o0 + nop .size test_and_set_bit, .-test_and_set_bit .globl test_and_clear_bit @@ -59,10 +66,11 @@ test_and_clear_bit: /* %o0=nr, %o1=addr */ cmp %g7, %g1 bne,pn %xcc, 1b and %g7, %o2, %g2 - BITOP_POST_BARRIER clr %o0 + movrne %g2, 1, %o0 + BITOP_POST_BARRIER retl - movrne %g2, 1, %o0 + nop .size test_and_clear_bit, .-test_and_clear_bit .globl test_and_change_bit @@ -81,10 +89,11 @@ test_and_change_bit: /* %o0=nr, %o1=addr */ cmp %g7, %g1 bne,pn %xcc, 1b and %g7, %o2, %g2 - BITOP_POST_BARRIER clr %o0 + movrne %g2, 1, %o0 + BITOP_POST_BARRIER retl - movrne %g2, 1, %o0 + nop .size test_and_change_bit, .-test_and_change_bit .globl set_bit diff --git a/arch/sparc64/lib/debuglocks.c b/arch/sparc64/lib/debuglocks.c index c421e0c65325..f03344cf784e 100644 --- a/arch/sparc64/lib/debuglocks.c +++ b/arch/sparc64/lib/debuglocks.c @@ -252,8 +252,9 @@ wlock_again: " andn %%g1, %%g3, %%g7\n" " casx [%0], %%g1, %%g7\n" " cmp %%g1, %%g7\n" +" membar #StoreLoad | #StoreStore\n" " bne,pn %%xcc, 1b\n" -" membar #StoreLoad | #StoreStore" +" nop" : /* no outputs */ : "r" (&(rw->lock)) : "g3", "g1", "g7", "cc", "memory"); @@ -351,8 +352,9 @@ int _do_write_trylock (rwlock_t *rw, char *str) " andn %%g1, %%g3, %%g7\n" " casx [%0], %%g1, %%g7\n" " cmp %%g1, %%g7\n" +" membar #StoreLoad | #StoreStore\n" " bne,pn %%xcc, 1b\n" -" membar #StoreLoad | #StoreStore" +" nop" : /* no outputs */ : "r" (&(rw->lock)) : "g3", "g1", "g7", "cc", "memory"); diff --git a/arch/sparc64/lib/dec_and_lock.S b/arch/sparc64/lib/dec_and_lock.S index 7e6fdaebedba..8ee288dd0afc 100644 --- a/arch/sparc64/lib/dec_and_lock.S +++ b/arch/sparc64/lib/dec_and_lock.S @@ -48,8 +48,9 @@ start_to_zero: #endif to_zero: ldstub [%o1], %g3 + membar #StoreLoad | #StoreStore brnz,pn %g3, spin_on_lock - membar #StoreLoad | #StoreStore + nop loop2: cas [%o0], %g2, %g7 /* ASSERT(g7 == 0) */ cmp %g2, %g7 @@ -71,8 +72,9 @@ loop2: cas [%o0], %g2, %g7 /* ASSERT(g7 == 0) */ nop spin_on_lock: ldub [%o1], %g3 + membar #LoadLoad brnz,pt %g3, spin_on_lock - membar #LoadLoad + nop ba,pt %xcc, to_zero nop nop diff --git a/arch/sparc64/lib/rwsem.S b/arch/sparc64/lib/rwsem.S index 174ff7b9164c..75f0e6b951d6 100644 --- a/arch/sparc64/lib/rwsem.S +++ b/arch/sparc64/lib/rwsem.S @@ -17,8 +17,9 @@ __down_read: bne,pn %icc, 1b add %g7, 1, %g7 cmp %g7, 0 + membar #StoreLoad | #StoreStore bl,pn %icc, 3f - membar #StoreLoad | #StoreStore + nop 2: retl nop @@ -57,8 +58,9 @@ __down_write: cmp %g3, %g7 bne,pn %icc, 1b cmp %g7, 0 + membar #StoreLoad | #StoreStore bne,pn %icc, 3f - membar #StoreLoad | #StoreStore + nop 2: retl nop 3: @@ -97,8 +99,9 @@ __up_read: cmp %g1, %g7 bne,pn %icc, 1b cmp %g7, 0 + membar #StoreLoad | #StoreStore bl,pn %icc, 3f - membar #StoreLoad | #StoreStore + nop 2: retl nop 3: sethi %hi(RWSEM_ACTIVE_MASK), %g1 @@ -126,8 +129,9 @@ __up_write: bne,pn %icc, 1b sub %g7, %g1, %g7 cmp %g7, 0 + membar #StoreLoad | #StoreStore bl,pn %icc, 3f - membar #StoreLoad | #StoreStore + nop 2: retl nop @@ -151,8 +155,9 @@ __downgrade_write: bne,pn %icc, 1b sub %g7, %g1, %g7 cmp %g7, 0 + membar #StoreLoad | #StoreStore bl,pn %icc, 3f - membar #StoreLoad | #StoreStore + nop 2: retl nop diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c index 3ffee7b51aed..52e9375288a9 100644 --- a/arch/sparc64/mm/fault.c +++ b/arch/sparc64/mm/fault.c @@ -34,22 +34,6 @@ extern struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS]; /* - * To debug kernel during syscall entry. - */ -void syscall_trace_entry(struct pt_regs *regs) -{ - printk("scall entry: %s[%d]/cpu%d: %d\n", current->comm, current->pid, smp_processor_id(), (int) regs->u_regs[UREG_G1]); -} - -/* - * To debug kernel during syscall exit. - */ -void syscall_trace_exit(struct pt_regs *regs) -{ - printk("scall exit: %s[%d]/cpu%d: %d\n", current->comm, current->pid, smp_processor_id(), (int) regs->u_regs[UREG_G1]); -} - -/* * To debug kernel to catch accesses to certain virtual/physical addresses. * Mode = 0 selects physical watchpoints, mode = 1 selects virtual watchpoints. * flags = VM_READ watches memread accesses, flags = VM_WRITE watches memwrite accesses. diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 9c5222075da9..8fc413cb6acd 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -136,8 +136,9 @@ static __inline__ void set_dcache_dirty(struct page *page, int this_cpu) "or %%g1, %0, %%g1\n\t" "casx [%2], %%g7, %%g1\n\t" "cmp %%g7, %%g1\n\t" + "membar #StoreLoad | #StoreStore\n\t" "bne,pn %%xcc, 1b\n\t" - " membar #StoreLoad | #StoreStore" + " nop" : /* no outputs */ : "r" (mask), "r" (non_cpu_bits), "r" (&page->flags) : "g1", "g7"); @@ -157,8 +158,9 @@ static __inline__ void clear_dcache_dirty_cpu(struct page *page, unsigned long c " andn %%g7, %1, %%g1\n\t" "casx [%2], %%g7, %%g1\n\t" "cmp %%g7, %%g1\n\t" + "membar #StoreLoad | #StoreStore\n\t" "bne,pn %%xcc, 1b\n\t" - " membar #StoreLoad | #StoreStore\n" + " nop\n" "2:" : /* no outputs */ : "r" (cpu), "r" (mask), "r" (&page->flags), diff --git a/arch/sparc64/mm/ultra.S b/arch/sparc64/mm/ultra.S index 7a0934321010..363770893797 100644 --- a/arch/sparc64/mm/ultra.S +++ b/arch/sparc64/mm/ultra.S @@ -72,6 +72,7 @@ __flush_tlb_pending: flush %g6 retl wrpr %g7, 0x0, %pstate + nop .align 32 .globl __flush_tlb_kernel_range @@ -249,7 +250,7 @@ __cheetah_flush_tlb_mm: /* 15 insns */ retl wrpr %g7, 0x0, %pstate -__cheetah_flush_tlb_pending: /* 22 insns */ +__cheetah_flush_tlb_pending: /* 23 insns */ /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ rdpr %pstate, %g7 sllx %o1, 3, %o1 @@ -266,8 +267,9 @@ __cheetah_flush_tlb_pending: /* 22 insns */ andn %o3, 1, %o3 stxa %g0, [%o3] ASI_IMMU_DEMAP 2: stxa %g0, [%o3] ASI_DMMU_DEMAP + membar #Sync brnz,pt %o1, 1b - membar #Sync + nop stxa %g2, [%o4] ASI_DMMU flush %g6 wrpr %g0, 0, %tl @@ -316,7 +318,7 @@ cheetah_patch_cachetlbops: sethi %hi(__cheetah_flush_tlb_pending), %o1 or %o1, %lo(__cheetah_flush_tlb_pending), %o1 call cheetah_patch_one - mov 22, %o2 + mov 23, %o2 #ifdef DCACHE_ALIASING_POSSIBLE sethi %hi(__flush_dcache_page), %o0 diff --git a/arch/sparc64/solaris/entry64.S b/arch/sparc64/solaris/entry64.S index 0cc9dad75c5e..4b6ae583c0a3 100644 --- a/arch/sparc64/solaris/entry64.S +++ b/arch/sparc64/solaris/entry64.S @@ -24,8 +24,9 @@ .text solaris_syscall_trace: + add %sp, PTREGS_OFF, %o0 call syscall_trace - nop + mov 0, %o1 srl %i0, 0, %o0 mov %i4, %o4 srl %i1, 0, %o1 @@ -159,8 +160,10 @@ ret_from_solaris: stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] !npc = npc+4 solaris_syscall_trace2: + add %sp, PTREGS_OFF, %o0 call syscall_trace - add %l1, 0x4, %l2 /* npc = npc+4 */ + mov 1, %o1 + add %l1, 0x4, %l2 /* npc = npc+4 */ andcc %l1, 1, %g0 bne,pn %icc, 2b nop diff --git a/arch/um/Kconfig b/arch/um/Kconfig index 9469e77303e6..f945444df49c 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig @@ -128,7 +128,6 @@ config HOSTFS config HPPFS tristate "HoneyPot ProcFS (EXPERIMENTAL)" - depends on BROKEN help hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc entries to be overridden, removed, or fabricated from the host. @@ -141,8 +140,9 @@ config HPPFS You only need this if you are setting up a UML honeypot. Otherwise, it is safe to say 'N' here. - If you are actively using it, please ask for it to be fixed. In this - moment, it does not work on 2.6 (it works somehow on 2.4). + If you are actively using it, please report any problems, since it's + getting fixed. In this moment, it is experimental on 2.6 (it works on + 2.4). config MCONSOLE bool "Management console" @@ -275,6 +275,8 @@ endmenu source "init/Kconfig" +source "net/Kconfig" + source "drivers/base/Kconfig" source "arch/um/Kconfig_char" @@ -287,7 +289,7 @@ config NETDEVICES source "arch/um/Kconfig_net" -source "net/Kconfig" +source "drivers/net/Kconfig" source "fs/Kconfig" diff --git a/arch/um/Kconfig_i386 b/arch/um/Kconfig_i386 index e41f3748d30f..27c18a8d9d17 100644 --- a/arch/um/Kconfig_i386 +++ b/arch/um/Kconfig_i386 @@ -19,6 +19,18 @@ config 3_LEVEL_PGTABLES memory. All the memory that can't be mapped directly will be treated as high memory. +config STUB_CODE + hex + default 0xbfffe000 + +config STUB_DATA + hex + default 0xbffff000 + +config STUB_START + hex + default STUB_CODE + config ARCH_HAS_SC_SIGNALS bool default y diff --git a/arch/um/Kconfig_net b/arch/um/Kconfig_net index 1c2f9a70d91d..fa2ab2dd78b7 100644 --- a/arch/um/Kconfig_net +++ b/arch/um/Kconfig_net @@ -135,7 +135,7 @@ config UML_NET_MCAST config UML_NET_PCAP bool "pcap transport" - depends on UML_NET && BROKEN + depends on UML_NET && EXPERIMENTAL help The pcap transport makes a pcap packet stream on the host look like an ethernet device inside UML. This is useful for making diff --git a/arch/um/Kconfig_x86_64 b/arch/um/Kconfig_x86_64 index f162f50f0b17..735a047c890c 100644 --- a/arch/um/Kconfig_x86_64 +++ b/arch/um/Kconfig_x86_64 @@ -14,6 +14,18 @@ config 3_LEVEL_PGTABLES bool default y +config STUB_CODE + hex + default 0x7fbfffe000 + +config STUB_DATA + hex + default 0x7fbffff000 + +config STUB_START + hex + default STUB_CODE + config ARCH_HAS_SC_SIGNALS bool default n diff --git a/arch/um/Makefile b/arch/um/Makefile index 3f073902351f..eb4ac403bd93 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -51,25 +51,26 @@ MRPROPER_DIRS += $(ARCH_DIR)/include2 endif SYS_DIR := $(ARCH_DIR)/include/sysdep-$(SUBARCH) -include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH) +# -Dvmap=kernel_vmap affects everything, and prevents anything from +# referencing the libpcap.o symbol so named. + +CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \ + $(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap -core-y += $(SUBARCH_CORE) -libs-y += $(SUBARCH_LIBS) +USER_CFLAGS := $(patsubst -I%,,$(CFLAGS)) +USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \ + $(MODE_INCLUDE) # -Derrno=kernel_errno - This turns all kernel references to errno into # kernel_errno to separate them from the libc errno. This allows -fno-common # in CFLAGS. Otherwise, it would cause ld to complain about the two different # errnos. -CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \ - $(ARCH_INCLUDE) $(MODE_INCLUDE) - -USER_CFLAGS := $(patsubst -I%,,$(CFLAGS)) -USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \ - $(MODE_INCLUDE) $(ARCH_USER_CFLAGS) CFLAGS += -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask CFLAGS += $(call cc-option,-fno-unit-at-a-time,) +include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH) + #This will adjust *FLAGS accordingly to the platform. include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS) @@ -116,18 +117,19 @@ CONFIG_KERNEL_STACK_ORDER ?= 2 STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] ) ifndef START - START = $$(($(TOP_ADDR) - $(SIZE))) + START = $(shell echo $$[ $(TOP_ADDR) - $(SIZE) ] ) endif -CPPFLAGS_vmlinux.lds = $(shell echo -U$(SUBARCH) \ +CPPFLAGS_vmlinux.lds = -U$(SUBARCH) \ -DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \ - -DELF_FORMAT=\"$(ELF_FORMAT)\" $(CPP_MODE-y) \ - -DKERNEL_STACK_SIZE=$(STACK_SIZE) -DSUBARCH=$(SUBARCH)) + -DELF_FORMAT="$(ELF_FORMAT)" $(CPP_MODE-y) \ + -DKERNEL_STACK_SIZE=$(STACK_SIZE) \ + -DUNMAP_PATH=arch/um/sys-$(SUBARCH)/unmap_fin.o #The wrappers will select whether using "malloc" or the kernel allocator. LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc -CFLAGS_vmlinux = $(LINK-y) $(LINK_WRAPS) +CFLAGS_vmlinux := $(LINK-y) $(LINK_WRAPS) define cmd_vmlinux__ $(CC) $(CFLAGS_vmlinux) -o $@ \ -Wl,-T,$(vmlinux-lds) $(vmlinux-init) \ @@ -140,7 +142,8 @@ endef #When cleaning we don't include .config, so we don't include #TT or skas makefiles and don't clean skas_ptregs.h. CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/include/uml-config.h \ - $(GEN_HEADERS) $(ARCH_DIR)/include/skas_ptregs.h + $(GEN_HEADERS) $(ARCH_DIR)/include/skas_ptregs.h \ + $(ARCH_DIR)/include/user_constants.h MRPROPER_FILES += $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) \ $(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS)) $(ARCH_DIR)/os \ diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386 index 29e182d5a83a..93d0818fa816 100644 --- a/arch/um/Makefile-i386 +++ b/arch/um/Makefile-i386 @@ -1,4 +1,4 @@ -SUBARCH_CORE := arch/um/sys-i386/ arch/i386/crypto/ +core-y += arch/um/sys-i386/ arch/i386/crypto/ TOP_ADDR := $(CONFIG_TOP_ADDR) @@ -8,21 +8,32 @@ ifeq ($(CONFIG_MODE_SKAS),y) endif endif -CFLAGS += -U__$(SUBARCH)__ -U$(SUBARCH) -ARCH_USER_CFLAGS := +LDFLAGS += -m elf_i386 +ELF_ARCH := $(SUBARCH) +ELF_FORMAT := elf32-$(SUBARCH) +OBJCOPYFLAGS := -O binary -R .note -R .comment -S + +ifeq ("$(origin SUBARCH)", "command line") +ifneq ("$(shell uname -m | sed -e s/i.86/i386/)", "$(SUBARCH)") +CFLAGS += $(call cc-option,-m32) +USER_CFLAGS += $(call cc-option,-m32) +HOSTCFLAGS += $(call cc-option,-m32) +HOSTLDFLAGS += $(call cc-option,-m32) +AFLAGS += $(call cc-option,-m32) +LINK-y += $(call cc-option,-m32) +UML_OBJCOPYFLAGS += -F $(ELF_FORMAT) + +export LDFLAGS HOSTCFLAGS HOSTLDFLAGS UML_OBJCOPYFLAGS +endif +endif + +CFLAGS += -U__$(SUBARCH)__ -U$(SUBARCH) $(STUB_CFLAGS) ifneq ($(CONFIG_GPROF),y) ARCH_CFLAGS += -DUM_FASTCALL endif -ELF_ARCH := $(SUBARCH) -ELF_FORMAT := elf32-$(SUBARCH) - -OBJCOPYFLAGS := -O binary -R .note -R .comment -S - -SYS_UTIL_DIR := $(ARCH_DIR)/sys-i386/util - -SYS_HEADERS := $(SYS_DIR)/sc.h $(SYS_DIR)/thread.h +SYS_HEADERS := $(SYS_DIR)/sc.h $(SYS_DIR)/thread.h prepare: $(SYS_HEADERS) diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64 index 32144562c279..aa2f7174ebca 100644 --- a/arch/um/Makefile-x86_64 +++ b/arch/um/Makefile-x86_64 @@ -1,11 +1,13 @@ # Copyright 2003 - 2004 Pathscale, Inc # Released under the GPL -SUBARCH_LIBS := arch/um/sys-x86_64/ +libs-y += arch/um/sys-x86_64/ START := 0x60000000 -CFLAGS += -U__$(SUBARCH)__ -fno-builtin -ARCH_USER_CFLAGS := -D__x86_64__ +#We #undef __x86_64__ for kernelspace, not for userspace where +#it's needed for headers to work! +CFLAGS += -U__$(SUBARCH)__ -fno-builtin $(STUB_CFLAGS) +USER_CFLAGS += -fno-builtin ELF_ARCH := i386:x86-64 ELF_FORMAT := elf64-x86-64 diff --git a/arch/um/defconfig b/arch/um/defconfig index 4067c3aa5b60..80d30d19d750 100644 --- a/arch/um/defconfig +++ b/arch/um/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc3-skas3-v9-pre2 -# Sun Apr 24 19:46:10 2005 +# Linux kernel version: 2.6.12-rc6-mm1 +# Tue Jun 14 18:22:21 2005 # CONFIG_GENERIC_HARDIRQS=y CONFIG_UML=y @@ -13,23 +13,32 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y # # UML-specific options # -CONFIG_MODE_TT=y +# CONFIG_MODE_TT is not set +# CONFIG_STATIC_LINK is not set CONFIG_MODE_SKAS=y CONFIG_UML_X86=y # CONFIG_64BIT is not set CONFIG_TOP_ADDR=0xc0000000 # CONFIG_3_LEVEL_PGTABLES is not set +CONFIG_STUB_CODE=0xbfffe000 +CONFIG_STUB_DATA=0xbffff000 +CONFIG_STUB_START=0xbfffe000 CONFIG_ARCH_HAS_SC_SIGNALS=y CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA=y -CONFIG_LD_SCRIPT_STATIC=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_LD_SCRIPT_DYN=y CONFIG_NET=y CONFIG_BINFMT_ELF=y CONFIG_BINFMT_MISC=m -CONFIG_HOSTFS=y +# CONFIG_HOSTFS is not set CONFIG_MCONSOLE=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_HOST_2G_2G is not set -# CONFIG_SMP is not set CONFIG_NEST_LEVEL=0 CONFIG_KERNEL_HALF_GIGS=1 # CONFIG_HIGHMEM is not set @@ -63,6 +72,8 @@ CONFIG_IKCONFIG_PROC=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set CONFIG_KALLSYMS_EXTRA_PASS=y +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -81,6 +92,7 @@ CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y @@ -115,6 +127,7 @@ CONFIG_UML_SOUND=m CONFIG_SOUND=m CONFIG_HOSTAUDIO=m CONFIG_UML_RANDOM=y +# CONFIG_MMAPPER is not set # # Block devices @@ -176,6 +189,17 @@ CONFIG_INET=y # CONFIG_INET_TUNNEL is not set CONFIG_IP_TCPDIAG=y # CONFIG_IP_TCPDIAG_IPV6 is not set + +# +# TCP congestion control +# +CONFIG_TCP_CONG_BIC=y +CONFIG_TCP_CONG_WESTWOOD=y +CONFIG_TCP_CONG_HTCP=y +# CONFIG_TCP_CONG_HSTCP is not set +# CONFIG_TCP_CONG_HYBLA is not set +# CONFIG_TCP_CONG_VEGAS is not set +# CONFIG_TCP_CONG_SCALABLE is not set # CONFIG_IPV6 is not set # CONFIG_NETFILTER is not set @@ -206,11 +230,15 @@ CONFIG_IP_TCPDIAG=y # Network testing # # CONFIG_NET_PKTGEN is not set +# CONFIG_KGDBOE is not set # CONFIG_NETPOLL is not set +# CONFIG_NETPOLL_RX is not set +# CONFIG_NETPOLL_TRAP is not set # CONFIG_NET_POLL_CONTROLLER is not set # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set +# CONFIG_IEEE80211 is not set CONFIG_DUMMY=m # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set @@ -227,6 +255,7 @@ CONFIG_PPP=m # CONFIG_PPP_SYNC_TTY is not set # CONFIG_PPP_DEFLATE is not set # CONFIG_PPP_BSDCOMP is not set +# CONFIG_PPP_MPPE is not set # CONFIG_PPPOE is not set CONFIG_SLIP=m # CONFIG_SLIP_COMPRESSED is not set @@ -240,10 +269,12 @@ CONFIG_SLIP=m # CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y # CONFIG_EXT3_FS_XATTR is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set +# CONFIG_REISER4_FS is not set CONFIG_REISERFS_FS=y # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set @@ -256,6 +287,7 @@ CONFIG_REISERFS_FS=y # CONFIG_XFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y CONFIG_QUOTA=y # CONFIG_QFMT_V1 is not set # CONFIG_QFMT_V2 is not set @@ -265,6 +297,12 @@ CONFIG_AUTOFS_FS=m CONFIG_AUTOFS4_FS=m # +# Caches +# +# CONFIG_FSCACHE is not set +# CONFIG_FUSE_FS is not set + +# # CD-ROM/DVD Filesystems # CONFIG_ISO9660_FS=m @@ -291,6 +329,8 @@ CONFIG_TMPFS=y # CONFIG_TMPFS_XATTR is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set +# CONFIG_RELAYFS_FS is not set # # Miscellaneous filesystems @@ -319,6 +359,7 @@ CONFIG_RAMFS=y # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set # # Partition Types @@ -404,14 +445,15 @@ CONFIG_CRC32=m # CONFIG_PRINTK_TIME is not set CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set -# CONFIG_DEBUG_SLAB is not set +CONFIG_DEBUG_SLAB=y # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_FS is not set CONFIG_FRAME_POINTER=y -CONFIG_PT_PROXY=y +# CONFIG_GPROF is not set # CONFIG_GCOV is not set # CONFIG_SYSCALL_DEBUG is not set diff --git a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile index b2de9916c32c..d6c31a95b887 100644 --- a/arch/um/drivers/Makefile +++ b/arch/um/drivers/Makefile @@ -10,7 +10,6 @@ slip-objs := slip_kern.o slip_user.o slirp-objs := slirp_kern.o slirp_user.o daemon-objs := daemon_kern.o daemon_user.o mcast-objs := mcast_kern.o mcast_user.o -#pcap-objs := pcap_kern.o pcap_user.o $(PCAP) net-objs := net_kern.o net_user.o mconsole-objs := mconsole_kern.o mconsole_user.o hostaudio-objs := hostaudio_kern.o @@ -18,6 +17,17 @@ ubd-objs := ubd_kern.o ubd_user.o port-objs := port_kern.o port_user.o harddog-objs := harddog_kern.o harddog_user.o +LDFLAGS_pcap.o := -r $(shell $(CC) $(CFLAGS) -print-file-name=libpcap.a) + +$(obj)/pcap.o: $(obj)/pcap_kern.o $(obj)/pcap_user.o + $(LD) -r -dp -o $@ $^ $(LDFLAGS) $(LDFLAGS_pcap.o) +#XXX: The call below does not work because the flags are added before the +# object name, so nothing from the library gets linked. +#$(call if_changed,ld) + +# When the above is fixed, don't forget to add this too! +#targets := $(obj)/pcap.o + obj-y := stdio_console.o fd.o chan_kern.o chan_user.o line.o obj-$(CONFIG_SSL) += ssl.o obj-$(CONFIG_STDERR_CONSOLE) += stderr_console.o @@ -26,7 +36,7 @@ obj-$(CONFIG_UML_NET_SLIP) += slip.o slip_common.o obj-$(CONFIG_UML_NET_SLIRP) += slirp.o slip_common.o obj-$(CONFIG_UML_NET_DAEMON) += daemon.o obj-$(CONFIG_UML_NET_MCAST) += mcast.o -#obj-$(CONFIG_UML_NET_PCAP) += pcap.o $(PCAP) +obj-$(CONFIG_UML_NET_PCAP) += pcap.o obj-$(CONFIG_UML_NET) += net.o obj-$(CONFIG_MCONSOLE) += mconsole.o obj-$(CONFIG_MMAPPER) += mmapper_kern.o @@ -41,6 +51,7 @@ obj-$(CONFIG_UML_WATCHDOG) += harddog.o obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o obj-$(CONFIG_UML_RANDOM) += random.o -USER_OBJS := fd.o null.o pty.o tty.o xterm.o slip_common.o +# pcap_user.o must be added explicitly. +USER_OBJS := fd.o null.o pty.o tty.o xterm.o slip_common.o pcap_user.o include arch/um/scripts/Makefile.rules diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 2bb4c4f5dec4..e0fdffa2d542 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -663,11 +663,15 @@ struct tty_driver *line_register_devfs(struct lines *set, return driver; } +static spinlock_t winch_handler_lock; +LIST_HEAD(winch_handlers); + void lines_init(struct line *lines, int nlines) { struct line *line; int i; + spin_lock_init(&winch_handler_lock); for(i = 0; i < nlines; i++){ line = &lines[i]; INIT_LIST_HEAD(&line->chan_list); @@ -724,31 +728,30 @@ irqreturn_t winch_interrupt(int irq, void *data, struct pt_regs *unused) return IRQ_HANDLED; } -DECLARE_MUTEX(winch_handler_sem); -LIST_HEAD(winch_handlers); - void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty) { struct winch *winch; - down(&winch_handler_sem); winch = kmalloc(sizeof(*winch), GFP_KERNEL); if (winch == NULL) { printk("register_winch_irq - kmalloc failed\n"); - goto out; + return; } + *winch = ((struct winch) { .list = LIST_HEAD_INIT(winch->list), .fd = fd, .tty_fd = tty_fd, .pid = pid, .tty = tty }); + + spin_lock(&winch_handler_lock); list_add(&winch->list, &winch_handlers); + spin_unlock(&winch_handler_lock); + if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, "winch", winch) < 0) printk("register_winch_irq - failed to register IRQ\n"); - out: - up(&winch_handler_sem); } static void unregister_winch(struct tty_struct *tty) @@ -756,7 +759,7 @@ static void unregister_winch(struct tty_struct *tty) struct list_head *ele; struct winch *winch, *found = NULL; - down(&winch_handler_sem); + spin_lock(&winch_handler_lock); list_for_each(ele, &winch_handlers){ winch = list_entry(ele, struct winch, list); if(winch->tty == tty){ @@ -764,20 +767,25 @@ static void unregister_winch(struct tty_struct *tty) break; } } - if(found == NULL) - goto out; + goto err; + + list_del(&winch->list); + spin_unlock(&winch_handler_lock); if(winch->pid != -1) os_kill_process(winch->pid, 1); free_irq(WINCH_IRQ, winch); - list_del(&winch->list); kfree(winch); - out: - up(&winch_handler_sem); + + return; +err: + spin_unlock(&winch_handler_lock); } +/* XXX: No lock as it's an exitcall... is this valid? Depending on cleanup + * order... are we sure that nothing else is done on the list? */ static void winch_cleanup(void) { struct list_head *ele; @@ -786,6 +794,9 @@ static void winch_cleanup(void) list_for_each(ele, &winch_handlers){ winch = list_entry(ele, struct winch, list); if(winch->fd != -1){ + /* Why is this different from the above free_irq(), + * which deactivates SIGIO? This searches the FD + * somewhere else and removes it from the list... */ deactivate_fd(winch->fd, WINCH_IRQ); os_close_file(winch->fd); } diff --git a/arch/um/include/mem.h b/arch/um/include/mem.h index 10c46c38949a..99d3ad4a03e5 100644 --- a/arch/um/include/mem.h +++ b/arch/um/include/mem.h @@ -13,6 +13,7 @@ extern int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w); extern int is_remapped(void *virt); extern int physmem_remove_mapping(void *virt); extern void physmem_forget_descriptor(int fd); +extern unsigned long to_phys(void *virt); #endif diff --git a/arch/um/include/registers.h b/arch/um/include/registers.h index 8744abb5224f..0a35e6d0baa0 100644 --- a/arch/um/include/registers.h +++ b/arch/um/include/registers.h @@ -14,6 +14,7 @@ extern int restore_fp_registers(int pid, unsigned long *fp_regs); extern void save_registers(int pid, union uml_pt_regs *regs); extern void restore_registers(int pid, union uml_pt_regs *regs); extern void init_registers(int pid); +extern void get_safe_registers(unsigned long * regs); #endif diff --git a/arch/um/include/sysdep-i386/ptrace_user.h b/arch/um/include/sysdep-i386/ptrace_user.h index eca8066e7a43..899aa4b2a78d 100644 --- a/arch/um/include/sysdep-i386/ptrace_user.h +++ b/arch/um/include/sysdep-i386/ptrace_user.h @@ -20,11 +20,24 @@ #define PT_SYSCALL_ARG3_OFFSET PT_OFFSET(EDX) #define PT_SYSCALL_ARG4_OFFSET PT_OFFSET(ESI) #define PT_SYSCALL_ARG5_OFFSET PT_OFFSET(EDI) +#define PT_SYSCALL_ARG6_OFFSET PT_OFFSET(EBP) #define PT_SYSCALL_RET_OFFSET PT_OFFSET(EAX) +#define REGS_SYSCALL_NR EAX /* This is used before a system call */ +#define REGS_SYSCALL_ARG1 EBX +#define REGS_SYSCALL_ARG2 ECX +#define REGS_SYSCALL_ARG3 EDX +#define REGS_SYSCALL_ARG4 ESI +#define REGS_SYSCALL_ARG5 EDI +#define REGS_SYSCALL_ARG6 EBP + +#define REGS_IP_INDEX EIP +#define REGS_SP_INDEX UESP + #define PT_IP_OFFSET PT_OFFSET(EIP) #define PT_IP(regs) ((regs)[EIP]) +#define PT_SP_OFFSET PT_OFFSET(UESP) #define PT_SP(regs) ((regs)[UESP]) #ifndef FRAME_SIZE diff --git a/arch/um/include/sysdep-i386/stub.h b/arch/um/include/sysdep-i386/stub.h new file mode 100644 index 000000000000..d3699fe1c613 --- /dev/null +++ b/arch/um/include/sysdep-i386/stub.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) + * Licensed under the GPL + */ + +#ifndef __SYSDEP_STUB_H +#define __SYSDEP_STUB_H + +#include <asm/ptrace.h> +#include <asm/unistd.h> + +extern void stub_segv_handler(int sig); +extern void stub_clone_handler(void); + +#define STUB_SYSCALL_RET EAX +#define STUB_MMAP_NR __NR_mmap2 +#define MMAP_OFFSET(o) ((o) >> PAGE_SHIFT) + +static inline long stub_syscall2(long syscall, long arg1, long arg2) +{ + long ret; + + __asm__("movl %0, %%ecx; " : : "g" (arg2) : "%ecx"); + __asm__("movl %0, %%ebx; " : : "g" (arg1) : "%ebx"); + __asm__("movl %0, %%eax; " : : "g" (syscall) : "%eax"); + __asm__("int $0x80;" : : : "%eax"); + __asm__ __volatile__("movl %%eax, %0; " : "=g" (ret) :); + return(ret); +} + +static inline long stub_syscall3(long syscall, long arg1, long arg2, long arg3) +{ + __asm__("movl %0, %%edx; " : : "g" (arg3) : "%edx"); + return(stub_syscall2(syscall, arg1, arg2)); +} + +static inline long stub_syscall4(long syscall, long arg1, long arg2, long arg3, + long arg4) +{ + __asm__("movl %0, %%esi; " : : "g" (arg4) : "%esi"); + return(stub_syscall3(syscall, arg1, arg2, arg3)); +} + +static inline long stub_syscall6(long syscall, long arg1, long arg2, long arg3, + long arg4, long arg5, long arg6) +{ + long ret; + __asm__("movl %0, %%eax; " : : "g" (syscall) : "%eax"); + __asm__("movl %0, %%ebx; " : : "g" (arg1) : "%ebx"); + __asm__("movl %0, %%ecx; " : : "g" (arg2) : "%ecx"); + __asm__("movl %0, %%edx; " : : "g" (arg3) : "%edx"); + __asm__("movl %0, %%esi; " : : "g" (arg4) : "%esi"); + __asm__("movl %0, %%edi; " : : "g" (arg5) : "%edi"); + __asm__ __volatile__("pushl %%ebp ; movl %1, %%ebp; " + "int $0x80; popl %%ebp ; " + "movl %%eax, %0; " : "=g" (ret) : "g" (arg6) : "%eax"); + return(ret); +} + +static inline void trap_myself(void) +{ + __asm("int3"); +} + +#endif diff --git a/arch/um/include/sysdep-x86_64/ptrace_user.h b/arch/um/include/sysdep-x86_64/ptrace_user.h index 31729973fb14..128faf027364 100644 --- a/arch/um/include/sysdep-x86_64/ptrace_user.h +++ b/arch/um/include/sysdep-x86_64/ptrace_user.h @@ -55,6 +55,20 @@ #define PTRACE_OLDSETOPTIONS 21 #endif +/* These are before the system call, so the the system call number is RAX + * rather than ORIG_RAX, and arg4 is R10 rather than RCX + */ +#define REGS_SYSCALL_NR PT_INDEX(RAX) +#define REGS_SYSCALL_ARG1 PT_INDEX(RDI) +#define REGS_SYSCALL_ARG2 PT_INDEX(RSI) +#define REGS_SYSCALL_ARG3 PT_INDEX(RDX) +#define REGS_SYSCALL_ARG4 PT_INDEX(R10) +#define REGS_SYSCALL_ARG5 PT_INDEX(R8) +#define REGS_SYSCALL_ARG6 PT_INDEX(R9) + +#define REGS_IP_INDEX PT_INDEX(RIP) +#define REGS_SP_INDEX PT_INDEX(RSP) + #endif /* diff --git a/arch/um/include/sysdep-x86_64/stub.h b/arch/um/include/sysdep-x86_64/stub.h new file mode 100644 index 000000000000..f599058d8263 --- /dev/null +++ b/arch/um/include/sysdep-x86_64/stub.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) + * Licensed under the GPL + */ + +#ifndef __SYSDEP_STUB_H +#define __SYSDEP_STUB_H + +#include <asm/ptrace.h> +#include <asm/unistd.h> +#include <sysdep/ptrace_user.h> + +extern void stub_segv_handler(int sig); +extern void stub_clone_handler(void); + +#define STUB_SYSCALL_RET PT_INDEX(RAX) +#define STUB_MMAP_NR __NR_mmap +#define MMAP_OFFSET(o) (o) + +static inline long stub_syscall2(long syscall, long arg1, long arg2) +{ + long ret; + + __asm__("movq %0, %%rsi; " : : "g" (arg2) : "%rsi"); + __asm__("movq %0, %%rdi; " : : "g" (arg1) : "%rdi"); + __asm__("movq %0, %%rax; " : : "g" (syscall) : "%rax"); + __asm__("syscall;" : : : "%rax", "%r11", "%rcx"); + __asm__ __volatile__("movq %%rax, %0; " : "=g" (ret) :); + return(ret); +} + +static inline long stub_syscall3(long syscall, long arg1, long arg2, long arg3) +{ + __asm__("movq %0, %%rdx; " : : "g" (arg3) : "%rdx"); + return(stub_syscall2(syscall, arg1, arg2)); +} + +static inline long stub_syscall4(long syscall, long arg1, long arg2, long arg3, + long arg4) +{ + __asm__("movq %0, %%r10; " : : "g" (arg4) : "%r10"); + return(stub_syscall3(syscall, arg1, arg2, arg3)); +} + +static inline long stub_syscall6(long syscall, long arg1, long arg2, long arg3, + long arg4, long arg5, long arg6) +{ + __asm__("movq %0, %%r9; " : : "g" (arg6) : "%r9"); + __asm__("movq %0, %%r8; " : : "g" (arg5) : "%r8"); + return(stub_syscall4(syscall, arg1, arg2, arg3, arg4)); +} + +static inline void trap_myself(void) +{ + __asm("int3"); +} + +#endif diff --git a/arch/um/include/time_user.h b/arch/um/include/time_user.h index f64ef77019a3..17d7ef2141f4 100644 --- a/arch/um/include/time_user.h +++ b/arch/um/include/time_user.h @@ -10,6 +10,7 @@ extern void timer(void); extern void switch_timers(int to_real); extern void idle_sleep(int secs); extern void enable_timer(void); +extern void prepare_timer(void * ptr); extern void disable_timer(void); extern unsigned long time_lock(void); extern void time_unlock(unsigned long); diff --git a/arch/um/include/tlb.h b/arch/um/include/tlb.h index da1097285b8c..c6f9628f39bf 100644 --- a/arch/um/include/tlb.h +++ b/arch/um/include/tlb.h @@ -37,31 +37,25 @@ struct host_vm_op { extern void mprotect_kernel_vm(int w); extern void force_flush_all(void); extern void fix_range_common(struct mm_struct *mm, unsigned long start_addr, - unsigned long end_addr, int force, int data, - void (*do_ops)(int, struct host_vm_op *, int)); + unsigned long end_addr, int force, + void (*do_ops)(union mm_context *, + struct host_vm_op *, int)); extern int flush_tlb_kernel_range_common(unsigned long start, unsigned long end); extern int add_mmap(unsigned long virt, unsigned long phys, unsigned long len, int r, int w, int x, struct host_vm_op *ops, int index, - int last_filled, int data, - void (*do_ops)(int, struct host_vm_op *, int)); + int last_filled, union mm_context *mmu, + void (*do_ops)(union mm_context *, struct host_vm_op *, + int)); extern int add_munmap(unsigned long addr, unsigned long len, struct host_vm_op *ops, int index, int last_filled, - int data, void (*do_ops)(int, struct host_vm_op *, int)); + union mm_context *mmu, + void (*do_ops)(union mm_context *, struct host_vm_op *, + int)); extern int add_mprotect(unsigned long addr, unsigned long len, int r, int w, int x, struct host_vm_op *ops, int index, - int last_filled, int data, - void (*do_ops)(int, struct host_vm_op *, int)); + int last_filled, union mm_context *mmu, + void (*do_ops)(union mm_context *, struct host_vm_op *, + int)); #endif - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S index 715b0838a68c..3942a5f245de 100644 --- a/arch/um/kernel/dyn.lds.S +++ b/arch/um/kernel/dyn.lds.S @@ -67,6 +67,12 @@ SECTIONS *(.stub .text.* .gnu.linkonce.t.*) /* .gnu.warning sections are handled specially by elf32.em. */ *(.gnu.warning) + + . = ALIGN(4096); + __syscall_stub_start = .; + *(.__syscall_stub*) + __syscall_stub_end = .; + . = ALIGN(4096); } =0x90909090 .fini : { KEEP (*(.fini)) diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c index 420e6d51fa0f..a24e3b7f4bf0 100644 --- a/arch/um/kernel/physmem.c +++ b/arch/um/kernel/physmem.c @@ -353,6 +353,8 @@ void map_memory(unsigned long virt, unsigned long phys, unsigned long len, #define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) +extern int __syscall_stub_start, __binary_start; + void setup_physmem(unsigned long start, unsigned long reserve_end, unsigned long len, unsigned long highmem) { @@ -371,6 +373,12 @@ void setup_physmem(unsigned long start, unsigned long reserve_end, exit(1); } + /* Special kludge - This page will be mapped in to userspace processes + * from physmem_fd, so it needs to be written out there. + */ + os_seek_file(physmem_fd, __pa(&__syscall_stub_start)); + os_write_file(physmem_fd, &__syscall_stub_start, PAGE_SIZE); + bootmap_size = init_bootmem(pfn, pfn + delta); free_bootmem(__pa(reserve_end) + bootmap_size, len - bootmap_size - reserve); diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 1b5ef3e96c71..c45a60e9c92d 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -32,6 +32,7 @@ #include "uml-config.h" #include "choose-mode.h" #include "mode.h" +#include "tempfile.h" #ifdef UML_CONFIG_MODE_SKAS #include "skas.h" #include "skas_ptrace.h" @@ -358,11 +359,16 @@ void forward_pending_sigio(int target) kill(target, SIGIO); } +int ptrace_faultinfo = 0; +int proc_mm = 1; + +extern void *__syscall_stub_start, __syscall_stub_end; + #ifdef UML_CONFIG_MODE_SKAS -static inline int check_skas3_ptrace_support(void) +static inline void check_skas3_ptrace_support(void) { struct ptrace_faultinfo fi; - int pid, n, ret = 1; + int pid, n; printf("Checking for the skas3 patch in the host..."); pid = start_ptraced_child(); @@ -374,33 +380,31 @@ static inline int check_skas3_ptrace_support(void) else { perror("not found"); } - ret = 0; - } else { + } + else { + ptrace_faultinfo = 1; printf("found\n"); } init_registers(pid); stop_ptraced_child(pid, 1, 1); - - return(ret); } int can_do_skas(void) { - int ret = 1; - printf("Checking for /proc/mm..."); if (os_access("/proc/mm", OS_ACC_W_OK) < 0) { + proc_mm = 0; printf("not found\n"); - ret = 0; goto out; - } else { + } + else { printf("found\n"); } - ret = check_skas3_ptrace_support(); out: - return ret; + check_skas3_ptrace_support(); + return 1; } #else int can_do_skas(void) diff --git a/arch/um/kernel/skas/Makefile b/arch/um/kernel/skas/Makefile index ff69c4b312c0..d296d55ade4b 100644 --- a/arch/um/kernel/skas/Makefile +++ b/arch/um/kernel/skas/Makefile @@ -3,11 +3,14 @@ # Licensed under the GPL # -obj-y := exec_kern.o mem.o mem_user.o mmu.o process.o process_kern.o \ +obj-y := clone.o exec_kern.o mem.o mem_user.o mmu.o process.o process_kern.o \ syscall_kern.o syscall_user.o tlb.o trap_user.o uaccess.o \ subdir- := util -USER_OBJS := process.o +USER_OBJS := process.o clone.o include arch/um/scripts/Makefile.rules + +# clone.o is in the stub, so it can't be built with profiling +$(obj)/clone.o : c_flags = -Wp,-MD,$(depfile) $(call unprofile,$(USER_CFLAGS)) diff --git a/arch/um/kernel/skas/clone.c b/arch/um/kernel/skas/clone.c new file mode 100644 index 000000000000..4dc55f10cd18 --- /dev/null +++ b/arch/um/kernel/skas/clone.c @@ -0,0 +1,44 @@ +#include <sched.h> +#include <signal.h> +#include <sys/mman.h> +#include <sys/time.h> +#include <asm/unistd.h> +#include <asm/page.h> +#include "ptrace_user.h" +#include "skas.h" +#include "stub-data.h" +#include "uml-config.h" +#include "sysdep/stub.h" + +/* This is in a separate file because it needs to be compiled with any + * extraneous gcc flags (-pg, -fprofile-arcs, -ftest-coverage) disabled + */ +void __attribute__ ((__section__ (".__syscall_stub"))) +stub_clone_handler(void) +{ + long err; + struct stub_data *from = (struct stub_data *) UML_CONFIG_STUB_DATA; + + err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD, + UML_CONFIG_STUB_DATA + PAGE_SIZE / 2 - + sizeof(void *)); + if(err != 0) + goto out; + + err = stub_syscall4(__NR_ptrace, PTRACE_TRACEME, 0, 0, 0); + if(err) + goto out; + + err = stub_syscall3(__NR_setitimer, ITIMER_VIRTUAL, + (long) &from->timer, 0); + if(err) + goto out; + + err = stub_syscall6(STUB_MMAP_NR, UML_CONFIG_STUB_DATA, PAGE_SIZE, + PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, + from->fd, from->offset); + out: + /* save current result. Parent: pid; child: retcode of mmap */ + from->err = err; + trap_myself(); +} diff --git a/arch/um/kernel/skas/exec_kern.c b/arch/um/kernel/skas/exec_kern.c index c6b4d5dba789..77ed7bbab219 100644 --- a/arch/um/kernel/skas/exec_kern.c +++ b/arch/um/kernel/skas/exec_kern.c @@ -18,7 +18,7 @@ void flush_thread_skas(void) { force_flush_all(); - switch_mm_skas(current->mm->context.skas.mm_fd); + switch_mm_skas(¤t->mm->context.skas.id); } void start_thread_skas(struct pt_regs *regs, unsigned long eip, diff --git a/arch/um/kernel/skas/include/mm_id.h b/arch/um/kernel/skas/include/mm_id.h new file mode 100644 index 000000000000..48dd0989ddaa --- /dev/null +++ b/arch/um/kernel/skas/include/mm_id.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2005 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __MM_ID_H +#define __MM_ID_H + +struct mm_id { + union { + int mm_fd; + int pid; + } u; + unsigned long stack; +}; + +#endif diff --git a/arch/um/kernel/skas/include/mmu-skas.h b/arch/um/kernel/skas/include/mmu-skas.h index 4cd60d7213f3..278b72f1d9ad 100644 --- a/arch/um/kernel/skas/include/mmu-skas.h +++ b/arch/um/kernel/skas/include/mmu-skas.h @@ -6,10 +6,15 @@ #ifndef __SKAS_MMU_H #define __SKAS_MMU_H +#include "mm_id.h" + struct mmu_context_skas { - int mm_fd; + struct mm_id id; + unsigned long last_page_table; }; +extern void switch_mm_skas(struct mm_id * mm_idp); + #endif /* diff --git a/arch/um/kernel/skas/include/skas.h b/arch/um/kernel/skas/include/skas.h index 96b51dba3471..d983ea842547 100644 --- a/arch/um/kernel/skas/include/skas.h +++ b/arch/um/kernel/skas/include/skas.h @@ -6,9 +6,11 @@ #ifndef __SKAS_H #define __SKAS_H +#include "mm_id.h" #include "sysdep/ptrace.h" extern int userspace_pid[]; +extern int proc_mm, ptrace_faultinfo; extern void switch_threads(void *me, void *next); extern void thread_wait(void *sw, void *fb); @@ -22,16 +24,18 @@ extern void new_thread_proc(void *stack, void (*handler)(int sig)); extern void remove_sigstack(void); extern void new_thread_handler(int sig); extern void handle_syscall(union uml_pt_regs *regs); -extern void map(int fd, unsigned long virt, unsigned long len, int r, int w, - int x, int phys_fd, unsigned long long offset); -extern int unmap(int fd, void *addr, unsigned long len); -extern int protect(int fd, unsigned long addr, unsigned long len, - int r, int w, int x); +extern int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, + int r, int w, int x, int phys_fd, unsigned long long offset); +extern int unmap(struct mm_id * mm_idp, void *addr, unsigned long len); +extern int protect(struct mm_id * mm_idp, unsigned long addr, + unsigned long len, int r, int w, int x); extern void user_signal(int sig, union uml_pt_regs *regs, int pid); extern int new_mm(int from); -extern void start_userspace(int cpu); +extern int start_userspace(unsigned long stub_stack); +extern int copy_context_skas0(unsigned long stack, int pid); extern void get_skas_faultinfo(int pid, struct faultinfo * fi); extern long execute_syscall_skas(void *r); +extern unsigned long current_stub_stack(void); #endif diff --git a/arch/um/kernel/skas/include/stub-data.h b/arch/um/kernel/skas/include/stub-data.h new file mode 100644 index 000000000000..f6ed92c3727d --- /dev/null +++ b/arch/um/kernel/skas/include/stub-data.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2005 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __STUB_DATA_H +#define __STUB_DATA_H + +#include <sys/time.h> + +struct stub_data { + long offset; + int fd; + struct itimerval timer; + long err; +}; + +#endif diff --git a/arch/um/kernel/skas/mem.c b/arch/um/kernel/skas/mem.c index 438db2f43456..147466d7ff4f 100644 --- a/arch/um/kernel/skas/mem.c +++ b/arch/um/kernel/skas/mem.c @@ -5,7 +5,9 @@ #include "linux/config.h" #include "linux/mm.h" +#include "asm/pgtable.h" #include "mem_user.h" +#include "skas.h" unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out, unsigned long *task_size_out) @@ -18,7 +20,9 @@ unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out, *task_size_out = CONFIG_HOST_TASK_SIZE; #else *host_size_out = top; - *task_size_out = top; + if (proc_mm && ptrace_faultinfo) + *task_size_out = top; + else *task_size_out = CONFIG_STUB_START & PGDIR_MASK; #endif return(((unsigned long) set_task_sizes_skas) & ~0xffffff); } diff --git a/arch/um/kernel/skas/mem_user.c b/arch/um/kernel/skas/mem_user.c index 1310bf1e88d1..b0980ff3bd95 100644 --- a/arch/um/kernel/skas/mem_user.c +++ b/arch/um/kernel/skas/mem_user.c @@ -3,100 +3,171 @@ * Licensed under the GPL */ +#include <signal.h> #include <errno.h> #include <sys/mman.h> +#include <sys/wait.h> +#include <asm/page.h> +#include <asm/unistd.h> #include "mem_user.h" #include "mem.h" +#include "mm_id.h" #include "user.h" #include "os.h" #include "proc_mm.h" - -void map(int fd, unsigned long virt, unsigned long len, int r, int w, - int x, int phys_fd, unsigned long long offset) +#include "ptrace_user.h" +#include "user_util.h" +#include "kern_util.h" +#include "task.h" +#include "registers.h" +#include "uml-config.h" +#include "sysdep/ptrace.h" +#include "sysdep/stub.h" +#include "skas.h" + +extern unsigned long syscall_stub, __syscall_stub_start; + +extern void wait_stub_done(int pid, int sig, char * fname); + +static long run_syscall_stub(struct mm_id * mm_idp, int syscall, + unsigned long *args) { - struct proc_mm_op map; - int prot, n; - - prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | - (x ? PROT_EXEC : 0); - - map = ((struct proc_mm_op) { .op = MM_MMAP, - .u = - { .mmap = - { .addr = virt, - .len = len, - .prot = prot, - .flags = MAP_SHARED | - MAP_FIXED, - .fd = phys_fd, - .offset = offset - } } } ); - n = os_write_file(fd, &map, sizeof(map)); - if(n != sizeof(map)) - printk("map : /proc/mm map failed, err = %d\n", -n); + int n, pid = mm_idp->u.pid; + unsigned long regs[MAX_REG_NR]; + + get_safe_registers(regs); + regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE + + ((unsigned long) &syscall_stub - + (unsigned long) &__syscall_stub_start); + /* XXX Don't have a define for starting a syscall */ + regs[REGS_SYSCALL_NR] = syscall; + regs[REGS_SYSCALL_ARG1] = args[0]; + regs[REGS_SYSCALL_ARG2] = args[1]; + regs[REGS_SYSCALL_ARG3] = args[2]; + regs[REGS_SYSCALL_ARG4] = args[3]; + regs[REGS_SYSCALL_ARG5] = args[4]; + regs[REGS_SYSCALL_ARG6] = args[5]; + n = ptrace_setregs(pid, regs); + if(n < 0){ + printk("run_syscall_stub : PTRACE_SETREGS failed, " + "errno = %d\n", n); + return(n); + } + + wait_stub_done(pid, 0, "run_syscall_stub"); + + return(*((unsigned long *) mm_idp->stack)); } -int unmap(int fd, void *addr, unsigned long len) +int map(struct mm_id *mm_idp, unsigned long virt, unsigned long len, + int r, int w, int x, int phys_fd, unsigned long long offset) { - struct proc_mm_op unmap; - int n; - - unmap = ((struct proc_mm_op) { .op = MM_MUNMAP, - .u = - { .munmap = - { .addr = (unsigned long) addr, - .len = len } } } ); - n = os_write_file(fd, &unmap, sizeof(unmap)); - if(n != sizeof(unmap)) { - if(n < 0) - return(n); - else if(n > 0) - return(-EIO); - } - - return(0); + int prot, n; + + prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | + (x ? PROT_EXEC : 0); + + if(proc_mm){ + struct proc_mm_op map; + int fd = mm_idp->u.mm_fd; + map = ((struct proc_mm_op) { .op = MM_MMAP, + .u = + { .mmap = + { .addr = virt, + .len = len, + .prot = prot, + .flags = MAP_SHARED | + MAP_FIXED, + .fd = phys_fd, + .offset= offset + } } } ); + n = os_write_file(fd, &map, sizeof(map)); + if(n != sizeof(map)) + printk("map : /proc/mm map failed, err = %d\n", -n); + } + else { + long res; + unsigned long args[] = { virt, len, prot, + MAP_SHARED | MAP_FIXED, phys_fd, + MMAP_OFFSET(offset) }; + + res = run_syscall_stub(mm_idp, STUB_MMAP_NR, args); + if((void *) res == MAP_FAILED) + printk("mmap stub failed, errno = %d\n", res); + } + + return 0; } -int protect(int fd, unsigned long addr, unsigned long len, int r, int w, - int x, int must_succeed) +int unmap(struct mm_id *mm_idp, void *addr, unsigned long len) { - struct proc_mm_op protect; - int prot, n; - - prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | - (x ? PROT_EXEC : 0); - - protect = ((struct proc_mm_op) { .op = MM_MPROTECT, - .u = - { .mprotect = - { .addr = (unsigned long) addr, - .len = len, - .prot = prot } } } ); - - n = os_write_file(fd, &protect, sizeof(protect)); - if(n != sizeof(protect)) { - if(n == 0) return(0); - - if(must_succeed) - panic("protect failed, err = %d", -n); - - return(-EIO); - } + int n; + + if(proc_mm){ + struct proc_mm_op unmap; + int fd = mm_idp->u.mm_fd; + unmap = ((struct proc_mm_op) { .op = MM_MUNMAP, + .u = + { .munmap = + { .addr = + (unsigned long) addr, + .len = len } } } ); + n = os_write_file(fd, &unmap, sizeof(unmap)); + if(n != sizeof(unmap)) { + if(n < 0) + return(n); + else if(n > 0) + return(-EIO); + } + } + else { + int res; + unsigned long args[] = { (unsigned long) addr, len, 0, 0, 0, + 0 }; + + res = run_syscall_stub(mm_idp, __NR_munmap, args); + if(res < 0) + printk("munmap stub failed, errno = %d\n", res); + } + + return(0); +} - return(0); +int protect(struct mm_id *mm_idp, unsigned long addr, unsigned long len, + int r, int w, int x) +{ + struct proc_mm_op protect; + int prot, n; + + prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | + (x ? PROT_EXEC : 0); + + if(proc_mm){ + int fd = mm_idp->u.mm_fd; + protect = ((struct proc_mm_op) { .op = MM_MPROTECT, + .u = + { .mprotect = + { .addr = + (unsigned long) addr, + .len = len, + .prot = prot } } } ); + + n = os_write_file(fd, &protect, sizeof(protect)); + if(n != sizeof(protect)) + panic("protect failed, err = %d", -n); + } + else { + int res; + unsigned long args[] = { addr, len, prot, 0, 0, 0 }; + + res = run_syscall_stub(mm_idp, __NR_mprotect, args); + if(res < 0) + panic("mprotect stub failed, errno = %d\n", res); + } + + return(0); } void before_mem_skas(unsigned long unused) { } - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c index 6cb9a6d028a9..d232daa42c31 100644 --- a/arch/um/kernel/skas/mmu.c +++ b/arch/um/kernel/skas/mmu.c @@ -3,46 +3,143 @@ * Licensed under the GPL */ +#include "linux/config.h" #include "linux/sched.h" #include "linux/list.h" #include "linux/spinlock.h" #include "linux/slab.h" +#include "linux/errno.h" +#include "linux/mm.h" #include "asm/current.h" #include "asm/segment.h" #include "asm/mmu.h" +#include "asm/pgalloc.h" +#include "asm/pgtable.h" #include "os.h" #include "skas.h" +extern int __syscall_stub_start; + +static int init_stub_pte(struct mm_struct *mm, unsigned long proc, + unsigned long kernel) +{ + pgd_t *pgd; + pud_t *pud; + pmd_t *pmd; + pte_t *pte; + + spin_lock(&mm->page_table_lock); + pgd = pgd_offset(mm, proc); + pud = pud_alloc(mm, pgd, proc); + if (!pud) + goto out; + + pmd = pmd_alloc(mm, pud, proc); + if (!pmd) + goto out_pmd; + + pte = pte_alloc_map(mm, pmd, proc); + if (!pte) + goto out_pte; + + /* There's an interaction between the skas0 stub pages, stack + * randomization, and the BUG at the end of exit_mmap. exit_mmap + * checks that the number of page tables freed is the same as had + * been allocated. If the stack is on the last page table page, + * then the stack pte page will be freed, and if not, it won't. To + * avoid having to know where the stack is, or if the process mapped + * something at the top of its address space for some other reason, + * we set TASK_SIZE to end at the start of the last page table. + * This keeps exit_mmap off the last page, but introduces a leak + * of that page. So, we hang onto it here and free it in + * destroy_context_skas. + */ + + mm->context.skas.last_page_table = pmd_page_kernel(*pmd); + + *pte = mk_pte(virt_to_page(kernel), __pgprot(_PAGE_PRESENT)); + *pte = pte_mkexec(*pte); + *pte = pte_wrprotect(*pte); + spin_unlock(&mm->page_table_lock); + return(0); + + out_pmd: + pud_free(pud); + out_pte: + pmd_free(pmd); + out: + spin_unlock(&mm->page_table_lock); + return(-ENOMEM); +} + int init_new_context_skas(struct task_struct *task, struct mm_struct *mm) { - int from; + struct mm_struct *cur_mm = current->mm; + struct mm_id *cur_mm_id = &cur_mm->context.skas.id; + struct mm_id *mm_id = &mm->context.skas.id; + unsigned long stack; + int from, ret; - if((current->mm != NULL) && (current->mm != &init_mm)) - from = current->mm->context.skas.mm_fd; - else from = -1; + if(proc_mm){ + if((cur_mm != NULL) && (cur_mm != &init_mm)) + from = cur_mm->context.skas.id.u.mm_fd; + else from = -1; - mm->context.skas.mm_fd = new_mm(from); - if(mm->context.skas.mm_fd < 0){ - printk("init_new_context_skas - new_mm failed, errno = %d\n", - mm->context.skas.mm_fd); - return(mm->context.skas.mm_fd); + ret = new_mm(from); + if(ret < 0){ + printk("init_new_context_skas - new_mm failed, " + "errno = %d\n", ret); + return ret; + } + mm_id->u.mm_fd = ret; } + else { + /* This zeros the entry that pgd_alloc didn't, needed since + * we are about to reinitialize it, and want mm.nr_ptes to + * be accurate. + */ + mm->pgd[USER_PTRS_PER_PGD] = __pgd(0); - return(0); + ret = init_stub_pte(mm, CONFIG_STUB_CODE, + (unsigned long) &__syscall_stub_start); + if(ret) + goto out; + + ret = -ENOMEM; + stack = get_zeroed_page(GFP_KERNEL); + if(stack == 0) + goto out; + mm_id->stack = stack; + + ret = init_stub_pte(mm, CONFIG_STUB_DATA, stack); + if(ret) + goto out_free; + + mm->nr_ptes--; + + if((cur_mm != NULL) && (cur_mm != &init_mm)) + mm_id->u.pid = copy_context_skas0(stack, + cur_mm_id->u.pid); + else mm_id->u.pid = start_userspace(stack); + } + + return 0; + + out_free: + free_page(mm_id->stack); + out: + return ret; } void destroy_context_skas(struct mm_struct *mm) { - os_close_file(mm->context.skas.mm_fd); -} + struct mmu_context_skas *mmu = &mm->context.skas; -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ + if(proc_mm) + os_close_file(mmu->id.u.mm_fd); + else { + os_kill_ptraced_process(mmu->id.u.pid, 1); + free_page(mmu->id.stack); + free_page(mmu->last_page_table); + } +} diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c index 773cd2b525fc..ba671dab8878 100644 --- a/arch/um/kernel/skas/process.c +++ b/arch/um/kernel/skas/process.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2002- 2004 Jeff Dike (jdike@addtoit.com) * Licensed under the GPL */ @@ -13,7 +13,9 @@ #include <sys/wait.h> #include <sys/mman.h> #include <sys/user.h> +#include <sys/time.h> #include <asm/unistd.h> +#include <asm/types.h> #include "user.h" #include "ptrace_user.h" #include "time_user.h" @@ -21,13 +23,18 @@ #include "user_util.h" #include "kern_util.h" #include "skas.h" +#include "stub-data.h" +#include "mm_id.h" #include "sysdep/sigcontext.h" +#include "sysdep/stub.h" #include "os.h" #include "proc_mm.h" #include "skas_ptrace.h" #include "chan_user.h" #include "signal_user.h" #include "registers.h" +#include "mem.h" +#include "uml-config.h" #include "process.h" int is_skas_winch(int pid, int fd, void *data) @@ -39,20 +46,55 @@ int is_skas_winch(int pid, int fd, void *data) return(1); } -void get_skas_faultinfo(int pid, struct faultinfo * fi) +void wait_stub_done(int pid, int sig, char * fname) { - int err; - - err = ptrace(PTRACE_FAULTINFO, pid, 0, fi); - if(err) - panic("get_skas_faultinfo - PTRACE_FAULTINFO failed, " - "errno = %d\n", errno); + int n, status, err; + + do { + if ( sig != -1 ) { + err = ptrace(PTRACE_CONT, pid, 0, sig); + if(err) + panic("%s : continue failed, errno = %d\n", + fname, errno); + } + sig = 0; + + CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); + } while((n >= 0) && WIFSTOPPED(status) && + (WSTOPSIG(status) == SIGVTALRM)); + + if((n < 0) || !WIFSTOPPED(status) || + (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status != SIGTRAP))){ + panic("%s : failed to wait for SIGUSR1/SIGTRAP, " + "pid = %d, n = %d, errno = %d, status = 0x%x\n", + fname, pid, n, errno, status); + } +} - /* Special handling for i386, which has different structs */ - if (sizeof(struct ptrace_faultinfo) < sizeof(struct faultinfo)) - memset((char *)fi + sizeof(struct ptrace_faultinfo), 0, - sizeof(struct faultinfo) - - sizeof(struct ptrace_faultinfo)); +void get_skas_faultinfo(int pid, struct faultinfo * fi) +{ + int err; + + if(ptrace_faultinfo){ + err = ptrace(PTRACE_FAULTINFO, pid, 0, fi); + if(err) + panic("get_skas_faultinfo - PTRACE_FAULTINFO failed, " + "errno = %d\n", errno); + + /* Special handling for i386, which has different structs */ + if (sizeof(struct ptrace_faultinfo) < sizeof(struct faultinfo)) + memset((char *)fi + sizeof(struct ptrace_faultinfo), 0, + sizeof(struct faultinfo) - + sizeof(struct ptrace_faultinfo)); + } + else { + wait_stub_done(pid, SIGSEGV, "get_skas_faultinfo"); + + /* faultinfo is prepared by the stub-segv-handler at start of + * the stub stack page. We just have to copy it. + */ + memcpy(fi, (void *)current_stub_stack(), sizeof(*fi)); + } } static void handle_segv(int pid, union uml_pt_regs * regs) @@ -91,11 +133,56 @@ static void handle_trap(int pid, union uml_pt_regs *regs, int local_using_sysemu handle_syscall(regs); } -static int userspace_tramp(void *arg) +extern int __syscall_stub_start; + +static int userspace_tramp(void *stack) { - init_new_thread_signals(0); - enable_timer(); + void *addr; + ptrace(PTRACE_TRACEME, 0, 0, 0); + + init_new_thread_signals(1); + enable_timer(); + + if(!proc_mm){ + /* This has a pte, but it can't be mapped in with the usual + * tlb_flush mechanism because this is part of that mechanism + */ + int fd; + __u64 offset; + + fd = phys_mapping(to_phys(&__syscall_stub_start), &offset); + addr = mmap64((void *) UML_CONFIG_STUB_CODE, page_size(), + PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fd, offset); + if(addr == MAP_FAILED){ + printk("mapping mmap stub failed, errno = %d\n", + errno); + exit(1); + } + + if(stack != NULL){ + fd = phys_mapping(to_phys(stack), &offset); + addr = mmap((void *) UML_CONFIG_STUB_DATA, page_size(), + PROT_READ | PROT_WRITE, + MAP_FIXED | MAP_SHARED, fd, offset); + if(addr == MAP_FAILED){ + printk("mapping segfault stack failed, " + "errno = %d\n", errno); + exit(1); + } + } + } + if(!ptrace_faultinfo && (stack != NULL)){ + unsigned long v = UML_CONFIG_STUB_CODE + + (unsigned long) stub_segv_handler - + (unsigned long) &__syscall_stub_start; + + set_sigstack((void *) UML_CONFIG_STUB_DATA, page_size()); + set_handler(SIGSEGV, (void *) v, SA_ONSTACK, + SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, + SIGUSR1, -1); + } + os_stop_process(os_getpid()); return(0); } @@ -105,11 +192,11 @@ static int userspace_tramp(void *arg) #define NR_CPUS 1 int userspace_pid[NR_CPUS]; -void start_userspace(int cpu) +int start_userspace(unsigned long stub_stack) { void *stack; unsigned long sp; - int pid, status, n; + int pid, status, n, flags; stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); @@ -117,8 +204,9 @@ void start_userspace(int cpu) panic("start_userspace : mmap failed, errno = %d", errno); sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *); - pid = clone(userspace_tramp, (void *) sp, - CLONE_FILES | CLONE_VM | SIGCHLD, NULL); + flags = CLONE_FILES | SIGCHLD; + if(proc_mm) flags |= CLONE_VM; + pid = clone(userspace_tramp, (void *) sp, flags, (void *) stub_stack); if(pid < 0) panic("start_userspace : clone failed, errno = %d", errno); @@ -140,7 +228,7 @@ void start_userspace(int cpu) if(munmap(stack, PAGE_SIZE) < 0) panic("start_userspace : munmap failed, errno = %d\n", errno); - userspace_pid[cpu] = pid; + return(pid); } void userspace(union uml_pt_regs *regs) @@ -174,7 +262,9 @@ void userspace(union uml_pt_regs *regs) if(WIFSTOPPED(status)){ switch(WSTOPSIG(status)){ case SIGSEGV: - handle_segv(pid, regs); + if(PTRACE_FULL_FAULTINFO || !ptrace_faultinfo) + user_signal(SIGSEGV, regs, pid); + else handle_segv(pid, regs); break; case SIGTRAP + 0x80: handle_trap(pid, regs, local_using_sysemu); @@ -194,6 +284,7 @@ void userspace(union uml_pt_regs *regs) printk("userspace - child stopped with signal " "%d\n", WSTOPSIG(status)); } + pid = userspace_pid[0]; interrupt_end(); /* Avoid -ERESTARTSYS handling in host */ @@ -207,6 +298,67 @@ void userspace(union uml_pt_regs *regs) #define INIT_JMP_HALT 3 #define INIT_JMP_REBOOT 4 + +int copy_context_skas0(unsigned long new_stack, int pid) +{ + int err; + unsigned long regs[MAX_REG_NR]; + unsigned long current_stack = current_stub_stack(); + struct stub_data *data = (struct stub_data *) current_stack; + struct stub_data *child_data = (struct stub_data *) new_stack; + __u64 new_offset; + int new_fd = phys_mapping(to_phys((void *)new_stack), &new_offset); + + /* prepare offset and fd of child's stack as argument for parent's + * and child's mmap2 calls + */ + *data = ((struct stub_data) { .offset = MMAP_OFFSET(new_offset), + .fd = new_fd, + .timer = ((struct itimerval) + { { 0, 1000000 / hz() }, + { 0, 1000000 / hz() }})}); + get_safe_registers(regs); + + /* Set parent's instruction pointer to start of clone-stub */ + regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE + + (unsigned long) stub_clone_handler - + (unsigned long) &__syscall_stub_start; + regs[REGS_SP_INDEX] = UML_CONFIG_STUB_DATA + PAGE_SIZE - + sizeof(void *); + err = ptrace_setregs(pid, regs); + if(err < 0) + panic("copy_context_skas0 : PTRACE_SETREGS failed, " + "pid = %d, errno = %d\n", pid, errno); + + /* set a well known return code for detection of child write failure */ + child_data->err = 12345678; + + /* Wait, until parent has finished its work: read child's pid from + * parent's stack, and check, if bad result. + */ + wait_stub_done(pid, 0, "copy_context_skas0"); + + pid = data->err; + if(pid < 0) + panic("copy_context_skas0 - stub-parent reports error %d\n", + pid); + + /* Wait, until child has finished too: read child's result from + * child's stack and check it. + */ + wait_stub_done(pid, -1, "copy_context_skas0"); + if (child_data->err != UML_CONFIG_STUB_DATA) + panic("copy_context_skas0 - stub-child reports error %d\n", + child_data->err); + + if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, + (void *)PTRACE_O_TRACESYSGOOD) < 0) + panic("copy_context_skas0 : PTRACE_SETOPTIONS failed, " + "errno = %d\n", errno); + + return pid; +} + void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, void (*handler)(int)) { @@ -334,21 +486,19 @@ void reboot_skas(void) siglongjmp(initial_jmpbuf, INIT_JMP_REBOOT); } -void switch_mm_skas(int mm_fd) +void switch_mm_skas(struct mm_id *mm_idp) { int err; #warning need cpu pid in switch_mm_skas - err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0, mm_fd); - if(err) - panic("switch_mm_skas - PTRACE_SWITCH_MM failed, errno = %d\n", - errno); -} - -void kill_off_processes_skas(void) -{ -#warning need to loop over userspace_pids in kill_off_processes_skas - os_kill_ptraced_process(userspace_pid[0], 1); + if(proc_mm){ + err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0, + mm_idp->u.mm_fd); + if(err) + panic("switch_mm_skas - PTRACE_SWITCH_MM failed, " + "errno = %d\n", errno); + } + else userspace_pid[0] = mm_idp->u.pid; } /* diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c index 0a7b8aa55db8..cbabab104ac3 100644 --- a/arch/um/kernel/skas/process_kern.c +++ b/arch/um/kernel/skas/process_kern.c @@ -175,9 +175,12 @@ static int start_kernel_proc(void *unused) return(0); } +extern int userspace_pid[]; + int start_uml_skas(void) { - start_userspace(0); + if(proc_mm) + userspace_pid[0] = start_userspace(0); init_new_thread_signals(1); @@ -199,3 +202,31 @@ int thread_pid_skas(struct task_struct *task) #warning Need to look up userspace_pid by cpu return(userspace_pid[0]); } + +void kill_off_processes_skas(void) +{ + if(proc_mm) +#warning need to loop over userspace_pids in kill_off_processes_skas + os_kill_ptraced_process(userspace_pid[0], 1); + else { + struct task_struct *p; + int pid, me; + + me = os_getpid(); + for_each_process(p){ + if(p->mm == NULL) + continue; + + pid = p->mm->context.skas.id.u.pid; + os_kill_ptraced_process(pid, 1); + } + } +} + +unsigned long current_stub_stack(void) +{ + if(current->mm == NULL) + return(0); + + return(current->mm->context.skas.id.stack); +} diff --git a/arch/um/kernel/skas/tlb.c b/arch/um/kernel/skas/tlb.c index b8c5e71763d1..6230999c672c 100644 --- a/arch/um/kernel/skas/tlb.c +++ b/arch/um/kernel/skas/tlb.c @@ -6,6 +6,7 @@ #include "linux/stddef.h" #include "linux/sched.h" +#include "linux/config.h" #include "linux/mm.h" #include "asm/page.h" #include "asm/pgtable.h" @@ -17,7 +18,7 @@ #include "os.h" #include "tlb.h" -static void do_ops(int fd, struct host_vm_op *ops, int last) +static void do_ops(union mm_context *mmu, struct host_vm_op *ops, int last) { struct host_vm_op *op; int i; @@ -26,18 +27,18 @@ static void do_ops(int fd, struct host_vm_op *ops, int last) op = &ops[i]; switch(op->type){ case MMAP: - map(fd, op->u.mmap.addr, op->u.mmap.len, + map(&mmu->skas.id, op->u.mmap.addr, op->u.mmap.len, op->u.mmap.r, op->u.mmap.w, op->u.mmap.x, op->u.mmap.fd, op->u.mmap.offset); break; case MUNMAP: - unmap(fd, (void *) op->u.munmap.addr, + unmap(&mmu->skas.id, (void *) op->u.munmap.addr, op->u.munmap.len); break; case MPROTECT: - protect(fd, op->u.mprotect.addr, op->u.mprotect.len, - op->u.mprotect.r, op->u.mprotect.w, - op->u.mprotect.x); + protect(&mmu->skas.id, op->u.mprotect.addr, + op->u.mprotect.len, op->u.mprotect.r, + op->u.mprotect.w, op->u.mprotect.x); break; default: printk("Unknown op type %d in do_ops\n", op->type); @@ -46,12 +47,15 @@ static void do_ops(int fd, struct host_vm_op *ops, int last) } } +extern int proc_mm; + static void fix_range(struct mm_struct *mm, unsigned long start_addr, unsigned long end_addr, int force) { - int fd = mm->context.skas.mm_fd; + if(!proc_mm && (end_addr > CONFIG_STUB_START)) + end_addr = CONFIG_STUB_START; - fix_range_common(mm, start_addr, end_addr, force, fd, do_ops); + fix_range_common(mm, start_addr, end_addr, force, do_ops); } void __flush_tlb_one_skas(unsigned long addr) @@ -69,17 +73,20 @@ void flush_tlb_range_skas(struct vm_area_struct *vma, unsigned long start, void flush_tlb_mm_skas(struct mm_struct *mm) { + unsigned long end; + /* Don't bother flushing if this address space is about to be * destroyed. */ if(atomic_read(&mm->mm_users) == 0) return; - fix_range(mm, 0, host_task_size, 0); - flush_tlb_kernel_range_common(start_vm, end_vm); + end = proc_mm ? task_size : CONFIG_STUB_START; + fix_range(mm, 0, end, 0); } void force_flush_all_skas(void) { - fix_range(current->mm, 0, host_task_size, 1); + unsigned long end = proc_mm ? task_size : CONFIG_STUB_START; + fix_range(current->mm, 0, end, 1); } diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c index f829b309b63c..c40b611e3d93 100644 --- a/arch/um/kernel/time.c +++ b/arch/um/kernel/time.c @@ -48,6 +48,13 @@ void enable_timer(void) set_interval(ITIMER_VIRTUAL); } +void prepare_timer(void * ptr) +{ + int usec = 1000000/hz(); + *(struct itimerval *)ptr = ((struct itimerval) { { 0, usec }, + { 0, usec }}); +} + void disable_timer(void) { struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }}); diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index eda477edfdf5..83ec8d4747fd 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c @@ -18,13 +18,15 @@ #define ADD_ROUND(n, inc) (((n) + (inc)) & ~((inc) - 1)) void fix_range_common(struct mm_struct *mm, unsigned long start_addr, - unsigned long end_addr, int force, int data, - void (*do_ops)(int, struct host_vm_op *, int)) + unsigned long end_addr, int force, + void (*do_ops)(union mm_context *, struct host_vm_op *, + int)) { pgd_t *npgd; pud_t *npud; pmd_t *npmd; pte_t *npte; + union mm_context *mmu = &mm->context; unsigned long addr, end; int r, w, x; struct host_vm_op ops[16]; @@ -40,7 +42,7 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr, end = end_addr; if(force || pgd_newpage(*npgd)){ op_index = add_munmap(addr, end - addr, ops, - op_index, last_op, data, + op_index, last_op, mmu, do_ops); pgd_mkuptodate(*npgd); } @@ -55,7 +57,7 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr, end = end_addr; if(force || pud_newpage(*npud)){ op_index = add_munmap(addr, end - addr, ops, - op_index, last_op, data, + op_index, last_op, mmu, do_ops); pud_mkuptodate(*npud); } @@ -70,7 +72,7 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr, end = end_addr; if(force || pmd_newpage(*npmd)){ op_index = add_munmap(addr, end - addr, ops, - op_index, last_op, data, + op_index, last_op, mmu, do_ops); pmd_mkuptodate(*npmd); } @@ -93,21 +95,21 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr, op_index = add_mmap(addr, pte_val(*npte) & PAGE_MASK, PAGE_SIZE, r, w, x, ops, - op_index, last_op, data, + op_index, last_op, mmu, do_ops); else op_index = add_munmap(addr, PAGE_SIZE, ops, - op_index, last_op, data, + op_index, last_op, mmu, do_ops); } else if(pte_newprot(*npte)) op_index = add_mprotect(addr, PAGE_SIZE, r, w, x, ops, - op_index, last_op, data, + op_index, last_op, mmu, do_ops); *npte = pte_mkuptodate(*npte); addr += PAGE_SIZE; } - (*do_ops)(data, ops, op_index); + (*do_ops)(mmu, ops, op_index); } int flush_tlb_kernel_range_common(unsigned long start, unsigned long end) @@ -195,51 +197,6 @@ int flush_tlb_kernel_range_common(unsigned long start, unsigned long end) return(updated); } -void flush_tlb_page(struct vm_area_struct *vma, unsigned long address) -{ - address &= PAGE_MASK; - flush_tlb_range(vma, address, address + PAGE_SIZE); -} - -void flush_tlb_all(void) -{ - flush_tlb_mm(current->mm); -} - -void flush_tlb_kernel_range(unsigned long start, unsigned long end) -{ - CHOOSE_MODE_PROC(flush_tlb_kernel_range_tt, - flush_tlb_kernel_range_common, start, end); -} - -void flush_tlb_kernel_vm(void) -{ - CHOOSE_MODE(flush_tlb_kernel_vm_tt(), - flush_tlb_kernel_range_common(start_vm, end_vm)); -} - -void __flush_tlb_one(unsigned long addr) -{ - CHOOSE_MODE_PROC(__flush_tlb_one_tt, __flush_tlb_one_skas, addr); -} - -void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, - unsigned long end) -{ - CHOOSE_MODE_PROC(flush_tlb_range_tt, flush_tlb_range_skas, vma, start, - end); -} - -void flush_tlb_mm(struct mm_struct *mm) -{ - CHOOSE_MODE_PROC(flush_tlb_mm_tt, flush_tlb_mm_skas, mm); -} - -void force_flush_all(void) -{ - CHOOSE_MODE(force_flush_all_tt(), force_flush_all_skas()); -} - pgd_t *pgd_offset_proc(struct mm_struct *mm, unsigned long address) { return(pgd_offset(mm, address)); @@ -270,9 +227,9 @@ pte_t *addr_pte(struct task_struct *task, unsigned long addr) } int add_mmap(unsigned long virt, unsigned long phys, unsigned long len, - int r, int w, int x, struct host_vm_op *ops, int index, - int last_filled, int data, - void (*do_ops)(int, struct host_vm_op *, int)) + int r, int w, int x, struct host_vm_op *ops, int index, + int last_filled, union mm_context *mmu, + void (*do_ops)(union mm_context *, struct host_vm_op *, int)) { __u64 offset; struct host_vm_op *last; @@ -292,7 +249,7 @@ int add_mmap(unsigned long virt, unsigned long phys, unsigned long len, } if(index == last_filled){ - (*do_ops)(data, ops, last_filled); + (*do_ops)(mmu, ops, last_filled); index = -1; } @@ -310,8 +267,8 @@ int add_mmap(unsigned long virt, unsigned long phys, unsigned long len, } int add_munmap(unsigned long addr, unsigned long len, struct host_vm_op *ops, - int index, int last_filled, int data, - void (*do_ops)(int, struct host_vm_op *, int)) + int index, int last_filled, union mm_context *mmu, + void (*do_ops)(union mm_context *, struct host_vm_op *, int)) { struct host_vm_op *last; @@ -325,7 +282,7 @@ int add_munmap(unsigned long addr, unsigned long len, struct host_vm_op *ops, } if(index == last_filled){ - (*do_ops)(data, ops, last_filled); + (*do_ops)(mmu, ops, last_filled); index = -1; } @@ -337,8 +294,9 @@ int add_munmap(unsigned long addr, unsigned long len, struct host_vm_op *ops, } int add_mprotect(unsigned long addr, unsigned long len, int r, int w, int x, - struct host_vm_op *ops, int index, int last_filled, int data, - void (*do_ops)(int, struct host_vm_op *, int)) + struct host_vm_op *ops, int index, int last_filled, + union mm_context *mmu, + void (*do_ops)(union mm_context *, struct host_vm_op *, int)) { struct host_vm_op *last; @@ -354,7 +312,7 @@ int add_mprotect(unsigned long addr, unsigned long len, int r, int w, int x, } if(index == last_filled){ - (*do_ops)(data, ops, last_filled); + (*do_ops)(mmu, ops, last_filled); index = -1; } @@ -367,3 +325,49 @@ int add_mprotect(unsigned long addr, unsigned long len, int r, int w, int x, .x = x } } }); return(index); } + +void flush_tlb_page(struct vm_area_struct *vma, unsigned long address) +{ + address &= PAGE_MASK; + flush_tlb_range(vma, address, address + PAGE_SIZE); +} + +void flush_tlb_all(void) +{ + flush_tlb_mm(current->mm); +} + +void flush_tlb_kernel_range(unsigned long start, unsigned long end) +{ + CHOOSE_MODE_PROC(flush_tlb_kernel_range_tt, + flush_tlb_kernel_range_common, start, end); +} + +void flush_tlb_kernel_vm(void) +{ + CHOOSE_MODE(flush_tlb_kernel_vm_tt(), + flush_tlb_kernel_range_common(start_vm, end_vm)); +} + +void __flush_tlb_one(unsigned long addr) +{ + CHOOSE_MODE_PROC(__flush_tlb_one_tt, __flush_tlb_one_skas, addr); +} + +void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, + unsigned long end) +{ + CHOOSE_MODE_PROC(flush_tlb_range_tt, flush_tlb_range_skas, vma, start, + end); +} + +void flush_tlb_mm(struct mm_struct *mm) +{ + CHOOSE_MODE_PROC(flush_tlb_mm_tt, flush_tlb_mm_skas, mm); +} + +void force_flush_all(void) +{ + CHOOSE_MODE(force_flush_all_tt(), force_flush_all_skas()); +} + diff --git a/arch/um/kernel/tt/tlb.c b/arch/um/kernel/tt/tlb.c index 203216ad86f1..2eefb43bc9c2 100644 --- a/arch/um/kernel/tt/tlb.c +++ b/arch/um/kernel/tt/tlb.c @@ -17,7 +17,7 @@ #include "os.h" #include "tlb.h" -static void do_ops(int unused, struct host_vm_op *ops, int last) +static void do_ops(union mm_context *mmu, struct host_vm_op *ops, int last) { struct host_vm_op *op; int i; @@ -55,7 +55,7 @@ static void fix_range(struct mm_struct *mm, unsigned long start_addr, panic("fix_range fixing wrong address space, current = 0x%p", current); - fix_range_common(mm, start_addr, end_addr, force, 0, do_ops); + fix_range_common(mm, start_addr, end_addr, force, do_ops); } atomic_t vmchange_seq = ATOMIC_INIT(1); diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S index 61dfd4fef752..b03326d391c9 100644 --- a/arch/um/kernel/uml.lds.S +++ b/arch/um/kernel/uml.lds.S @@ -16,8 +16,8 @@ SECTIONS __binary_start = .; #ifdef MODE_TT - .remap_data : { arch/um/sys-SUBARCH/unmap_fin.o (.data .bss) } - .remap : { arch/um/sys-SUBARCH/unmap_fin.o (.text) } + .remap_data : { UNMAP_PATH (.data .bss) } + .remap : { UNMAP_PATH (.text) } . = ALIGN(4096); /* Init code and data */ #endif @@ -30,6 +30,7 @@ SECTIONS _einittext = .; } . = ALIGN(4096); + .text : { *(.text) @@ -39,6 +40,12 @@ SECTIONS /* .gnu.warning sections are handled specially by elf32.em. */ *(.gnu.warning) *(.gnu.linkonce.t*) + + . = ALIGN(4096); + __syscall_stub_start = .; + *(.__syscall_stub*) + __syscall_stub_end = .; + . = ALIGN(4096); } #include "asm/common.lds.S" diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c index 9a0ad094d926..3125d320722c 100644 --- a/arch/um/os-Linux/sys-i386/registers.c +++ b/arch/um/os-Linux/sys-i386/registers.c @@ -121,6 +121,11 @@ void init_registers(int pid) err); } +void get_safe_registers(unsigned long *regs) +{ + memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long)); +} + /* * Overrides for Emacs so that we follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically diff --git a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c index 6286c974bbeb..44438d15c3d6 100644 --- a/arch/um/os-Linux/sys-x86_64/registers.c +++ b/arch/um/os-Linux/sys-x86_64/registers.c @@ -69,6 +69,11 @@ void init_registers(int pid) err); } +void get_safe_registers(unsigned long *regs) +{ + memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long)); +} + /* * Overrides for Emacs so that we follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules index 7459d09c233e..17f305b6bade 100644 --- a/arch/um/scripts/Makefile.rules +++ b/arch/um/scripts/Makefile.rules @@ -16,6 +16,11 @@ define unprofile endef +# The stubs and unmap.o can't try to call mcount or update basic block data +define unprofile + $(patsubst -pg,,$(patsubst -fprofile-arcs -ftest-coverage,,$(1))) +endef + quiet_cmd_make_link = SYMLINK $@ cmd_make_link = ln -sf $(srctree)/arch/$(SUBARCH)/$($(notdir $@)-dir)/$(notdir $@) $@ diff --git a/arch/um/scripts/Makefile.unmap b/arch/um/scripts/Makefile.unmap index 37a8f9765295..802d027a1e13 100644 --- a/arch/um/scripts/Makefile.unmap +++ b/arch/um/scripts/Makefile.unmap @@ -12,8 +12,8 @@ $(obj)/unmap.o: _c_flags = $(call unprofile,$(CFLAGS)) quiet_cmd_wrapld = LD $@ define cmd_wrapld - $(LD) -r -o $(obj)/unmap_tmp.o $< $(shell $(CC) -print-file-name=libc.a); \ - $(OBJCOPY) $(obj)/unmap_tmp.o $@ -G switcheroo + $(LD) $(LDFLAGS) -r -o $(obj)/unmap_tmp.o $< $(shell $(CC) $(CFLAGS) -print-file-name=libc.a); \ + $(OBJCOPY) $(UML_OBJCOPYFLAGS) $(obj)/unmap_tmp.o $@ -G switcheroo endef $(obj)/unmap_fin.o : $(obj)/unmap.o FORCE diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile index 095bcdb0b9cc..77c3c4d29f55 100644 --- a/arch/um/sys-i386/Makefile +++ b/arch/um/sys-i386/Makefile @@ -1,6 +1,6 @@ obj-y = bitops.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ - ptrace_user.o semaphore.o signal.o sigcontext.o syscalls.o sysrq.o \ - sys_call_table.o + ptrace_user.o semaphore.o signal.o sigcontext.o stub.o stub_segv.o \ + syscalls.o sysrq.o sys_call_table.o obj-$(CONFIG_HIGHMEM) += highmem.o obj-$(CONFIG_MODULES) += module.o @@ -16,6 +16,14 @@ semaphore.c-dir = kernel highmem.c-dir = mm module.c-dir = kernel +STUB_CFLAGS = -Wp,-MD,$(depfile) $(call unprofile,$(USER_CFLAGS)) + +# _cflags works with kernel files, not with userspace ones, but c_flags does, +# why ask why? +$(obj)/stub_segv.o : c_flags = $(STUB_CFLAGS) + +$(obj)/stub.o : a_flags = $(STUB_CFLAGS) + subdir- := util include arch/um/scripts/Makefile.unmap diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c index dc755b0b9db8..bd3c34aa52e5 100644 --- a/arch/um/sys-i386/ldt.c +++ b/arch/um/sys-i386/ldt.c @@ -4,96 +4,106 @@ */ #include "linux/config.h" +#include "linux/sched.h" #include "linux/slab.h" +#include "linux/types.h" #include "asm/uaccess.h" #include "asm/ptrace.h" +#include "asm/smp.h" +#include "asm/ldt.h" #include "choose-mode.h" #include "kern.h" +#include "mode_kern.h" #ifdef CONFIG_MODE_TT -extern int modify_ldt(int func, void *ptr, unsigned long bytecount); -/* XXX this needs copy_to_user and copy_from_user */ +extern int modify_ldt(int func, void *ptr, unsigned long bytecount); -int sys_modify_ldt_tt(int func, void __user *ptr, unsigned long bytecount) +static int do_modify_ldt_tt(int func, void *ptr, unsigned long bytecount) { - if (!access_ok(VERIFY_READ, ptr, bytecount)) - return -EFAULT; - return modify_ldt(func, ptr, bytecount); } + #endif #ifdef CONFIG_MODE_SKAS -extern int userspace_pid[]; +#include "skas.h" #include "skas_ptrace.h" -int sys_modify_ldt_skas(int func, void __user *ptr, unsigned long bytecount) +static int do_modify_ldt_skas(int func, void *ptr, unsigned long bytecount) { struct ptrace_ldt ldt; - void *buf; - int res, n; + u32 cpu; + int res; - buf = kmalloc(bytecount, GFP_KERNEL); - if(buf == NULL) - return(-ENOMEM); + ldt = ((struct ptrace_ldt) { .func = func, + .ptr = ptr, + .bytecount = bytecount }); - res = 0; + cpu = get_cpu(); + res = ptrace(PTRACE_LDT, userspace_pid[cpu], 0, (unsigned long) &ldt); + put_cpu(); + + return res; +} +#endif + +int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount) +{ + struct user_desc info; + int res = 0; + void *buf = NULL; + void *p = NULL; /* What we pass to host. */ switch(func){ case 1: - case 0x11: - res = copy_from_user(buf, ptr, bytecount); - break; - } + case 0x11: /* write_ldt */ + /* Do this check now to avoid overflows. */ + if (bytecount != sizeof(struct user_desc)) { + res = -EINVAL; + goto out; + } + + if(copy_from_user(&info, ptr, sizeof(info))) { + res = -EFAULT; + goto out; + } - if(res != 0){ - res = -EFAULT; + p = &info; + break; + case 0: + case 2: /* read_ldt */ + + /* The use of info avoids kmalloc on the write case, not on the + * read one. */ + buf = kmalloc(bytecount, GFP_KERNEL); + if (!buf) { + res = -ENOMEM; + goto out; + } + p = buf; + default: + res = -ENOSYS; goto out; } - ldt = ((struct ptrace_ldt) { .func = func, - .ptr = buf, - .bytecount = bytecount }); -#warning Need to look up userspace_pid by cpu - res = ptrace(PTRACE_LDT, userspace_pid[0], 0, (unsigned long) &ldt); + res = CHOOSE_MODE_PROC(do_modify_ldt_tt, do_modify_ldt_skas, func, + p, bytecount); if(res < 0) goto out; switch(func){ case 0: case 2: - n = res; - res = copy_to_user(ptr, buf, n); - if(res != 0) + /* Modify_ldt was for reading and returned the number of read + * bytes.*/ + if(copy_to_user(ptr, p, res)) res = -EFAULT; - else - res = n; break; } - out: +out: kfree(buf); - return(res); -} -#endif - -int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount) -{ - return(CHOOSE_MODE_PROC(sys_modify_ldt_tt, sys_modify_ldt_skas, func, - ptr, bytecount)); + return res; } - - - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/sys-i386/stub.S b/arch/um/sys-i386/stub.S new file mode 100644 index 000000000000..2f2c70a8f043 --- /dev/null +++ b/arch/um/sys-i386/stub.S @@ -0,0 +1,8 @@ +#include "uml-config.h" + + .globl syscall_stub +.section .__syscall_stub, "x" +syscall_stub: + int $0x80 + mov %eax, UML_CONFIG_STUB_DATA + int3 diff --git a/arch/um/sys-i386/stub_segv.c b/arch/um/sys-i386/stub_segv.c new file mode 100644 index 000000000000..b251442ad0b1 --- /dev/null +++ b/arch/um/sys-i386/stub_segv.c @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) + * Licensed under the GPL + */ + +#include <signal.h> +#include <asm/sigcontext.h> +#include <asm/unistd.h> +#include "uml-config.h" +#include "sysdep/sigcontext.h" +#include "sysdep/faultinfo.h" + +void __attribute__ ((__section__ (".__syscall_stub"))) +stub_segv_handler(int sig) +{ + struct sigcontext *sc = (struct sigcontext *) (&sig + 1); + + GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA), + sc); + + __asm__("movl %0, %%eax ; int $0x80": : "g" (__NR_getpid)); + __asm__("movl %%eax, %%ebx ; movl %0, %%eax ; movl %1, %%ecx ;" + "int $0x80": : "g" (__NR_kill), "g" (SIGUSR1)); + /* Pop the frame pointer and return address since we need to leave + * the stack in its original form when we do the sigreturn here, by + * hand. + */ + __asm__("popl %%eax ; popl %%eax ; popl %%eax ; movl %0, %%eax ; " + "int $0x80" : : "g" (__NR_sigreturn)); +} diff --git a/arch/um/sys-i386/unmap.c b/arch/um/sys-i386/unmap.c index 136875263d27..1b0ad0e4adcd 100644 --- a/arch/um/sys-i386/unmap.c +++ b/arch/um/sys-i386/unmap.c @@ -15,7 +15,7 @@ int switcheroo(int fd, int prot, void *from, void *to, int size) if(munmap(to, size) < 0){ return(-1); } - if(mmap2(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) != to){ + if(mmap2(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){ return(-1); } if(munmap(from, size) < 0){ diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile index 2bc6f6849010..7488206ce6f4 100644 --- a/arch/um/sys-x86_64/Makefile +++ b/arch/um/sys-x86_64/Makefile @@ -6,8 +6,8 @@ #XXX: why into lib-y? lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o mem.o memcpy.o \ - ptrace.o ptrace_user.o semaphore.o sigcontext.o signal.o \ - syscalls.o sysrq.o thunk.o syscall_table.o + ptrace.o ptrace_user.o semaphore.o sigcontext.o signal.o stub.o \ + stub_segv.o syscalls.o syscall_table.o sysrq.o thunk.o obj-y := ksyms.o obj-$(CONFIG_MODULES) += module.o um_module.o @@ -28,6 +28,14 @@ semaphore.c-dir = kernel thunk.S-dir = lib module.c-dir = kernel +STUB_CFLAGS = -Wp,-MD,$(depfile) $(call unprofile,$(USER_CFLAGS)) + +# _cflags works with kernel files, not with userspace ones, but c_flags does, +# why ask why? +$(obj)/stub_segv.o : c_flags = $(STUB_CFLAGS) + +$(obj)/stub.o : a_flags = $(STUB_CFLAGS) + subdir- := util include arch/um/scripts/Makefile.unmap diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c index 73a7926f7370..8fdaed06c10d 100644 --- a/arch/um/sys-x86_64/signal.c +++ b/arch/um/sys-x86_64/signal.c @@ -168,7 +168,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, frame = (struct rt_sigframe __user *) round_down(stack_top - sizeof(struct rt_sigframe), 16) - 8; - ((unsigned char *) frame) -= 128; + frame = (struct rt_sigframe *) ((unsigned long) frame - 128); if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate))) goto out; diff --git a/arch/um/sys-x86_64/stub.S b/arch/um/sys-x86_64/stub.S new file mode 100644 index 000000000000..31c14925716b --- /dev/null +++ b/arch/um/sys-x86_64/stub.S @@ -0,0 +1,15 @@ +#include "uml-config.h" + + .globl syscall_stub +.section .__syscall_stub, "x" +syscall_stub: + syscall + /* We don't have 64-bit constants, so this constructs the address + * we need. + */ + movq $(UML_CONFIG_STUB_DATA >> 32), %rbx + salq $32, %rbx + movq $(UML_CONFIG_STUB_DATA & 0xffffffff), %rcx + or %rcx, %rbx + movq %rax, (%rbx) + int3 diff --git a/arch/um/sys-x86_64/stub_segv.c b/arch/um/sys-x86_64/stub_segv.c new file mode 100644 index 000000000000..161d1fe9c034 --- /dev/null +++ b/arch/um/sys-x86_64/stub_segv.c @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) + * Licensed under the GPL + */ + +#include <signal.h> +#include <linux/compiler.h> +#include <asm/unistd.h> +#include "uml-config.h" +#include "sysdep/sigcontext.h" +#include "sysdep/faultinfo.h" + +void __attribute__ ((__section__ (".__syscall_stub"))) +stub_segv_handler(int sig) +{ + struct ucontext *uc; + + __asm__("movq %%rdx, %0" : "=g" (uc) :); + GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA), + &uc->uc_mcontext); + + __asm__("movq %0, %%rax ; syscall": : "g" (__NR_getpid)); + __asm__("movq %%rax, %%rdi ; movq %0, %%rax ; movq %1, %%rsi ;" + "syscall": : "g" (__NR_kill), "g" (SIGUSR1)); + /* Two popqs to restore the stack to the state just before entering + * the handler, one pops the return address, the other pops the frame + * pointer. + */ + __asm__("popq %%rax ; popq %%rax ; movq %0, %%rax ; syscall" : : "g" + (__NR_rt_sigreturn)); +} diff --git a/arch/um/sys-x86_64/unmap.c b/arch/um/sys-x86_64/unmap.c index bc7094cce47e..f4a4bffd8a18 100644 --- a/arch/um/sys-x86_64/unmap.c +++ b/arch/um/sys-x86_64/unmap.c @@ -15,7 +15,7 @@ int switcheroo(int fd, int prot, void *from, void *to, int size) if(munmap(to, size) < 0){ return(-1); } - if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) != to){ + if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){ return(-1); } if(munmap(from, size) < 0){ diff --git a/arch/v850/Kconfig b/arch/v850/Kconfig index 27febd6ffa80..89c053b6c2c4 100644 --- a/arch/v850/Kconfig +++ b/arch/v850/Kconfig @@ -250,6 +250,8 @@ source "fs/Kconfig.binfmt" endmenu +source "net/Kconfig" + ############################################################################# source "drivers/base/Kconfig" @@ -283,7 +285,7 @@ source "drivers/ieee1394/Kconfig" source "drivers/message/i2o/Kconfig" -source "net/Kconfig" +source "drivers/net/Kconfig" source "drivers/isdn/Kconfig" diff --git a/arch/v850/kernel/vmlinux.lds.S b/arch/v850/kernel/vmlinux.lds.S index bbd3429bcffc..c366a8b326ee 100644 --- a/arch/v850/kernel/vmlinux.lds.S +++ b/arch/v850/kernel/vmlinux.lds.S @@ -1,8 +1,8 @@ /* * arch/v850/vmlinux.lds.S -- kernel linker script for v850 platforms * - * Copyright (C) 2002,03,04 NEC Electronics Corporation - * Copyright (C) 2002,03,04 Miles Bader <miles@gnu.org> + * Copyright (C) 2002,03,04,05 NEC Electronics Corporation + * Copyright (C) 2002,03,04,05 Miles Bader <miles@gnu.org> * * This file is subject to the terms and conditions of the GNU General * Public License. See the file COPYING in the main directory of this @@ -61,6 +61,7 @@ *(__kcrctab_gpl) \ ___stop___kcrctab_gpl = .; \ /* Built-in module parameters */ \ + . = ALIGN (4) ; \ ___start___param = .; \ *(__param) \ ___stop___param = .; diff --git a/arch/v850/lib/checksum.c b/arch/v850/lib/checksum.c index d308b724c023..fa5872633075 100644 --- a/arch/v850/lib/checksum.c +++ b/arch/v850/lib/checksum.c @@ -138,7 +138,8 @@ unsigned int csum_partial_copy(const unsigned char *src, unsigned char *dst, * Copy from userspace and compute checksum. If we catch an exception * then zero the rest of the buffer. */ -unsigned int csum_partial_copy_from_user (const unsigned char *src, unsigned char *dst, +unsigned int csum_partial_copy_from_user (const unsigned char *src, + unsigned char *dst, int len, unsigned int sum, int *err_ptr) { diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index d09437b5c48f..4b8326177c52 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig @@ -515,6 +515,8 @@ config UID16 endmenu +source "net/Kconfig" + source drivers/Kconfig source "drivers/firmware/Kconfig" diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile index 8a73794f9b90..428915697675 100644 --- a/arch/x86_64/Makefile +++ b/arch/x86_64/Makefile @@ -65,7 +65,9 @@ CFLAGS += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,) head-y := arch/x86_64/kernel/head.o arch/x86_64/kernel/head64.o arch/x86_64/kernel/init_task.o libs-y += arch/x86_64/lib/ -core-y += arch/x86_64/kernel/ arch/x86_64/mm/ +core-y += arch/x86_64/kernel/ \ + arch/x86_64/mm/ \ + arch/x86_64/crypto/ core-$(CONFIG_IA32_EMULATION) += arch/x86_64/ia32/ drivers-$(CONFIG_PCI) += arch/x86_64/pci/ drivers-$(CONFIG_OPROFILE) += arch/x86_64/oprofile/ diff --git a/arch/x86_64/crypto/Makefile b/arch/x86_64/crypto/Makefile new file mode 100644 index 000000000000..426d20f4b72e --- /dev/null +++ b/arch/x86_64/crypto/Makefile @@ -0,0 +1,9 @@ +# +# x86_64/crypto/Makefile +# +# Arch-specific CryptoAPI modules. +# + +obj-$(CONFIG_CRYPTO_AES_X86_64) += aes-x86_64.o + +aes-x86_64-y := aes-x86_64-asm.o aes.o diff --git a/arch/x86_64/crypto/aes-x86_64-asm.S b/arch/x86_64/crypto/aes-x86_64-asm.S new file mode 100644 index 000000000000..483cbb23ab8d --- /dev/null +++ b/arch/x86_64/crypto/aes-x86_64-asm.S @@ -0,0 +1,186 @@ +/* AES (Rijndael) implementation (FIPS PUB 197) for x86_64 + * + * Copyright (C) 2005 Andreas Steinmetz, <ast@domdv.de> + * + * License: + * This code can be distributed under the terms of the GNU General Public + * License (GPL) Version 2 provided that the above header down to and + * including this sentence is retained in full. + */ + +.extern aes_ft_tab +.extern aes_it_tab +.extern aes_fl_tab +.extern aes_il_tab + +.text + +#define R1 %rax +#define R1E %eax +#define R1X %ax +#define R1H %ah +#define R1L %al +#define R2 %rbx +#define R2E %ebx +#define R2X %bx +#define R2H %bh +#define R2L %bl +#define R3 %rcx +#define R3E %ecx +#define R3X %cx +#define R3H %ch +#define R3L %cl +#define R4 %rdx +#define R4E %edx +#define R4X %dx +#define R4H %dh +#define R4L %dl +#define R5 %rsi +#define R5E %esi +#define R6 %rdi +#define R6E %edi +#define R7 %rbp +#define R7E %ebp +#define R8 %r8 +#define R9 %r9 +#define R10 %r10 +#define R11 %r11 + +#define prologue(FUNC,BASE,B128,B192,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11) \ + .global FUNC; \ + .type FUNC,@function; \ + .align 8; \ +FUNC: movq r1,r2; \ + movq r3,r4; \ + leaq BASE+52(r8),r9; \ + movq r10,r11; \ + movl (r7),r5 ## E; \ + movl 4(r7),r1 ## E; \ + movl 8(r7),r6 ## E; \ + movl 12(r7),r7 ## E; \ + movl (r8),r10 ## E; \ + xorl -48(r9),r5 ## E; \ + xorl -44(r9),r1 ## E; \ + xorl -40(r9),r6 ## E; \ + xorl -36(r9),r7 ## E; \ + cmpl $24,r10 ## E; \ + jb B128; \ + leaq 32(r9),r9; \ + je B192; \ + leaq 32(r9),r9; + +#define epilogue(r1,r2,r3,r4,r5,r6,r7,r8,r9) \ + movq r1,r2; \ + movq r3,r4; \ + movl r5 ## E,(r9); \ + movl r6 ## E,4(r9); \ + movl r7 ## E,8(r9); \ + movl r8 ## E,12(r9); \ + ret; + +#define round(TAB,OFFSET,r1,r2,r3,r4,r5,r6,r7,r8,ra,rb,rc,rd) \ + movzbl r2 ## H,r5 ## E; \ + movzbl r2 ## L,r6 ## E; \ + movl TAB+1024(,r5,4),r5 ## E;\ + movw r4 ## X,r2 ## X; \ + movl TAB(,r6,4),r6 ## E; \ + roll $16,r2 ## E; \ + shrl $16,r4 ## E; \ + movzbl r4 ## H,r7 ## E; \ + movzbl r4 ## L,r4 ## E; \ + xorl OFFSET(r8),ra ## E; \ + xorl OFFSET+4(r8),rb ## E; \ + xorl TAB+3072(,r7,4),r5 ## E;\ + xorl TAB+2048(,r4,4),r6 ## E;\ + movzbl r1 ## L,r7 ## E; \ + movzbl r1 ## H,r4 ## E; \ + movl TAB+1024(,r4,4),r4 ## E;\ + movw r3 ## X,r1 ## X; \ + roll $16,r1 ## E; \ + shrl $16,r3 ## E; \ + xorl TAB(,r7,4),r5 ## E; \ + movzbl r3 ## H,r7 ## E; \ + movzbl r3 ## L,r3 ## E; \ + xorl TAB+3072(,r7,4),r4 ## E;\ + xorl TAB+2048(,r3,4),r5 ## E;\ + movzbl r1 ## H,r7 ## E; \ + movzbl r1 ## L,r3 ## E; \ + shrl $16,r1 ## E; \ + xorl TAB+3072(,r7,4),r6 ## E;\ + movl TAB+2048(,r3,4),r3 ## E;\ + movzbl r1 ## H,r7 ## E; \ + movzbl r1 ## L,r1 ## E; \ + xorl TAB+1024(,r7,4),r6 ## E;\ + xorl TAB(,r1,4),r3 ## E; \ + movzbl r2 ## H,r1 ## E; \ + movzbl r2 ## L,r7 ## E; \ + shrl $16,r2 ## E; \ + xorl TAB+3072(,r1,4),r3 ## E;\ + xorl TAB+2048(,r7,4),r4 ## E;\ + movzbl r2 ## H,r1 ## E; \ + movzbl r2 ## L,r2 ## E; \ + xorl OFFSET+8(r8),rc ## E; \ + xorl OFFSET+12(r8),rd ## E; \ + xorl TAB+1024(,r1,4),r3 ## E;\ + xorl TAB(,r2,4),r4 ## E; + +#define move_regs(r1,r2,r3,r4) \ + movl r3 ## E,r1 ## E; \ + movl r4 ## E,r2 ## E; + +#define entry(FUNC,BASE,B128,B192) \ + prologue(FUNC,BASE,B128,B192,R2,R8,R7,R9,R1,R3,R4,R6,R10,R5,R11) + +#define return epilogue(R8,R2,R9,R7,R5,R6,R3,R4,R11) + +#define encrypt_round(TAB,OFFSET) \ + round(TAB,OFFSET,R1,R2,R3,R4,R5,R6,R7,R10,R5,R6,R3,R4) \ + move_regs(R1,R2,R5,R6) + +#define encrypt_final(TAB,OFFSET) \ + round(TAB,OFFSET,R1,R2,R3,R4,R5,R6,R7,R10,R5,R6,R3,R4) + +#define decrypt_round(TAB,OFFSET) \ + round(TAB,OFFSET,R2,R1,R4,R3,R6,R5,R7,R10,R5,R6,R3,R4) \ + move_regs(R1,R2,R5,R6) + +#define decrypt_final(TAB,OFFSET) \ + round(TAB,OFFSET,R2,R1,R4,R3,R6,R5,R7,R10,R5,R6,R3,R4) + +/* void aes_encrypt(void *ctx, u8 *out, const u8 *in) */ + + entry(aes_encrypt,0,enc128,enc192) + encrypt_round(aes_ft_tab,-96) + encrypt_round(aes_ft_tab,-80) +enc192: encrypt_round(aes_ft_tab,-64) + encrypt_round(aes_ft_tab,-48) +enc128: encrypt_round(aes_ft_tab,-32) + encrypt_round(aes_ft_tab,-16) + encrypt_round(aes_ft_tab, 0) + encrypt_round(aes_ft_tab, 16) + encrypt_round(aes_ft_tab, 32) + encrypt_round(aes_ft_tab, 48) + encrypt_round(aes_ft_tab, 64) + encrypt_round(aes_ft_tab, 80) + encrypt_round(aes_ft_tab, 96) + encrypt_final(aes_fl_tab,112) + return + +/* void aes_decrypt(void *ctx, u8 *out, const u8 *in) */ + + entry(aes_decrypt,240,dec128,dec192) + decrypt_round(aes_it_tab,-96) + decrypt_round(aes_it_tab,-80) +dec192: decrypt_round(aes_it_tab,-64) + decrypt_round(aes_it_tab,-48) +dec128: decrypt_round(aes_it_tab,-32) + decrypt_round(aes_it_tab,-16) + decrypt_round(aes_it_tab, 0) + decrypt_round(aes_it_tab, 16) + decrypt_round(aes_it_tab, 32) + decrypt_round(aes_it_tab, 48) + decrypt_round(aes_it_tab, 64) + decrypt_round(aes_it_tab, 80) + decrypt_round(aes_it_tab, 96) + decrypt_final(aes_il_tab,112) + return diff --git a/arch/x86_64/crypto/aes.c b/arch/x86_64/crypto/aes.c new file mode 100644 index 000000000000..2b5c4010ce38 --- /dev/null +++ b/arch/x86_64/crypto/aes.c @@ -0,0 +1,324 @@ +/* + * Cryptographic API. + * + * AES Cipher Algorithm. + * + * Based on Brian Gladman's code. + * + * Linux developers: + * Alexander Kjeldaas <astor@fast.no> + * Herbert Valerio Riedel <hvr@hvrlab.org> + * Kyle McMartin <kyle@debian.org> + * Adam J. Richter <adam@yggdrasil.com> (conversion to 2.5 API). + * Andreas Steinmetz <ast@domdv.de> (adapted to x86_64 assembler) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * --------------------------------------------------------------------------- + * Copyright (c) 2002, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK. + * All rights reserved. + * + * LICENSE TERMS + * + * The free distribution and use of this software in both source and binary + * form is allowed (with or without changes) provided that: + * + * 1. distributions of this source code include the above copyright + * notice, this list of conditions and the following disclaimer; + * + * 2. distributions in binary form include the above copyright + * notice, this list of conditions and the following disclaimer + * in the documentation and/or other associated materials; + * + * 3. the copyright holder's name is not used to endorse products + * built using this software without specific written permission. + * + * ALTERNATIVELY, provided that this notice is retained in full, this product + * may be distributed under the terms of the GNU General Public License (GPL), + * in which case the provisions of the GPL apply INSTEAD OF those given above. + * + * DISCLAIMER + * + * This software is provided 'as is' with no explicit or implied warranties + * in respect of its properties, including, but not limited to, correctness + * and/or fitness for purpose. + * --------------------------------------------------------------------------- + */ + +/* Some changes from the Gladman version: + s/RIJNDAEL(e_key)/E_KEY/g + s/RIJNDAEL(d_key)/D_KEY/g +*/ + +#include <asm/byteorder.h> +#include <linux/bitops.h> +#include <linux/crypto.h> +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/types.h> + +#define AES_MIN_KEY_SIZE 16 +#define AES_MAX_KEY_SIZE 32 + +#define AES_BLOCK_SIZE 16 + +/* + * #define byte(x, nr) ((unsigned char)((x) >> (nr*8))) + */ +static inline u8 byte(const u32 x, const unsigned n) +{ + return x >> (n << 3); +} + +#define u32_in(x) le32_to_cpu(*(const __le32 *)(x)) + +struct aes_ctx +{ + u32 key_length; + u32 E[60]; + u32 D[60]; +}; + +#define E_KEY ctx->E +#define D_KEY ctx->D + +static u8 pow_tab[256] __initdata; +static u8 log_tab[256] __initdata; +static u8 sbx_tab[256] __initdata; +static u8 isb_tab[256] __initdata; +static u32 rco_tab[10]; +u32 aes_ft_tab[4][256]; +u32 aes_it_tab[4][256]; + +u32 aes_fl_tab[4][256]; +u32 aes_il_tab[4][256]; + +static inline u8 f_mult(u8 a, u8 b) +{ + u8 aa = log_tab[a], cc = aa + log_tab[b]; + + return pow_tab[cc + (cc < aa ? 1 : 0)]; +} + +#define ff_mult(a, b) (a && b ? f_mult(a, b) : 0) + +#define ls_box(x) \ + (aes_fl_tab[0][byte(x, 0)] ^ \ + aes_fl_tab[1][byte(x, 1)] ^ \ + aes_fl_tab[2][byte(x, 2)] ^ \ + aes_fl_tab[3][byte(x, 3)]) + +static void __init gen_tabs(void) +{ + u32 i, t; + u8 p, q; + + /* log and power tables for GF(2**8) finite field with + 0x011b as modular polynomial - the simplest primitive + root is 0x03, used here to generate the tables */ + + for (i = 0, p = 1; i < 256; ++i) { + pow_tab[i] = (u8)p; + log_tab[p] = (u8)i; + + p ^= (p << 1) ^ (p & 0x80 ? 0x01b : 0); + } + + log_tab[1] = 0; + + for (i = 0, p = 1; i < 10; ++i) { + rco_tab[i] = p; + + p = (p << 1) ^ (p & 0x80 ? 0x01b : 0); + } + + for (i = 0; i < 256; ++i) { + p = (i ? pow_tab[255 - log_tab[i]] : 0); + q = ((p >> 7) | (p << 1)) ^ ((p >> 6) | (p << 2)); + p ^= 0x63 ^ q ^ ((q >> 6) | (q << 2)); + sbx_tab[i] = p; + isb_tab[p] = (u8)i; + } + + for (i = 0; i < 256; ++i) { + p = sbx_tab[i]; + + t = p; + aes_fl_tab[0][i] = t; + aes_fl_tab[1][i] = rol32(t, 8); + aes_fl_tab[2][i] = rol32(t, 16); + aes_fl_tab[3][i] = rol32(t, 24); + + t = ((u32)ff_mult(2, p)) | + ((u32)p << 8) | + ((u32)p << 16) | ((u32)ff_mult(3, p) << 24); + + aes_ft_tab[0][i] = t; + aes_ft_tab[1][i] = rol32(t, 8); + aes_ft_tab[2][i] = rol32(t, 16); + aes_ft_tab[3][i] = rol32(t, 24); + + p = isb_tab[i]; + + t = p; + aes_il_tab[0][i] = t; + aes_il_tab[1][i] = rol32(t, 8); + aes_il_tab[2][i] = rol32(t, 16); + aes_il_tab[3][i] = rol32(t, 24); + + t = ((u32)ff_mult(14, p)) | + ((u32)ff_mult(9, p) << 8) | + ((u32)ff_mult(13, p) << 16) | + ((u32)ff_mult(11, p) << 24); + + aes_it_tab[0][i] = t; + aes_it_tab[1][i] = rol32(t, 8); + aes_it_tab[2][i] = rol32(t, 16); + aes_it_tab[3][i] = rol32(t, 24); + } +} + +#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b) + +#define imix_col(y, x) \ + u = star_x(x); \ + v = star_x(u); \ + w = star_x(v); \ + t = w ^ (x); \ + (y) = u ^ v ^ w; \ + (y) ^= ror32(u ^ t, 8) ^ \ + ror32(v ^ t, 16) ^ \ + ror32(t, 24) + +/* initialise the key schedule from the user supplied key */ + +#define loop4(i) \ +{ \ + t = ror32(t, 8); t = ls_box(t) ^ rco_tab[i]; \ + t ^= E_KEY[4 * i]; E_KEY[4 * i + 4] = t; \ + t ^= E_KEY[4 * i + 1]; E_KEY[4 * i + 5] = t; \ + t ^= E_KEY[4 * i + 2]; E_KEY[4 * i + 6] = t; \ + t ^= E_KEY[4 * i + 3]; E_KEY[4 * i + 7] = t; \ +} + +#define loop6(i) \ +{ \ + t = ror32(t, 8); t = ls_box(t) ^ rco_tab[i]; \ + t ^= E_KEY[6 * i]; E_KEY[6 * i + 6] = t; \ + t ^= E_KEY[6 * i + 1]; E_KEY[6 * i + 7] = t; \ + t ^= E_KEY[6 * i + 2]; E_KEY[6 * i + 8] = t; \ + t ^= E_KEY[6 * i + 3]; E_KEY[6 * i + 9] = t; \ + t ^= E_KEY[6 * i + 4]; E_KEY[6 * i + 10] = t; \ + t ^= E_KEY[6 * i + 5]; E_KEY[6 * i + 11] = t; \ +} + +#define loop8(i) \ +{ \ + t = ror32(t, 8); ; t = ls_box(t) ^ rco_tab[i]; \ + t ^= E_KEY[8 * i]; E_KEY[8 * i + 8] = t; \ + t ^= E_KEY[8 * i + 1]; E_KEY[8 * i + 9] = t; \ + t ^= E_KEY[8 * i + 2]; E_KEY[8 * i + 10] = t; \ + t ^= E_KEY[8 * i + 3]; E_KEY[8 * i + 11] = t; \ + t = E_KEY[8 * i + 4] ^ ls_box(t); \ + E_KEY[8 * i + 12] = t; \ + t ^= E_KEY[8 * i + 5]; E_KEY[8 * i + 13] = t; \ + t ^= E_KEY[8 * i + 6]; E_KEY[8 * i + 14] = t; \ + t ^= E_KEY[8 * i + 7]; E_KEY[8 * i + 15] = t; \ +} + +static int aes_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len, + u32 *flags) +{ + struct aes_ctx *ctx = ctx_arg; + u32 i, j, t, u, v, w; + + if (key_len != 16 && key_len != 24 && key_len != 32) { + *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; + return -EINVAL; + } + + ctx->key_length = key_len; + + D_KEY[key_len + 24] = E_KEY[0] = u32_in(in_key); + D_KEY[key_len + 25] = E_KEY[1] = u32_in(in_key + 4); + D_KEY[key_len + 26] = E_KEY[2] = u32_in(in_key + 8); + D_KEY[key_len + 27] = E_KEY[3] = u32_in(in_key + 12); + + switch (key_len) { + case 16: + t = E_KEY[3]; + for (i = 0; i < 10; ++i) + loop4(i); + break; + + case 24: + E_KEY[4] = u32_in(in_key + 16); + t = E_KEY[5] = u32_in(in_key + 20); + for (i = 0; i < 8; ++i) + loop6 (i); + break; + + case 32: + E_KEY[4] = u32_in(in_key + 16); + E_KEY[5] = u32_in(in_key + 20); + E_KEY[6] = u32_in(in_key + 24); + t = E_KEY[7] = u32_in(in_key + 28); + for (i = 0; i < 7; ++i) + loop8(i); + break; + } + + D_KEY[0] = E_KEY[key_len + 24]; + D_KEY[1] = E_KEY[key_len + 25]; + D_KEY[2] = E_KEY[key_len + 26]; + D_KEY[3] = E_KEY[key_len + 27]; + + for (i = 4; i < key_len + 24; ++i) { + j = key_len + 24 - (i & ~3) + (i & 3); + imix_col(D_KEY[j], E_KEY[i]); + } + + return 0; +} + +extern void aes_encrypt(void *ctx_arg, u8 *out, const u8 *in); +extern void aes_decrypt(void *ctx_arg, u8 *out, const u8 *in); + +static struct crypto_alg aes_alg = { + .cra_name = "aes", + .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct aes_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(aes_alg.cra_list), + .cra_u = { + .cipher = { + .cia_min_keysize = AES_MIN_KEY_SIZE, + .cia_max_keysize = AES_MAX_KEY_SIZE, + .cia_setkey = aes_set_key, + .cia_encrypt = aes_encrypt, + .cia_decrypt = aes_decrypt + } + } +}; + +static int __init aes_init(void) +{ + gen_tabs(); + return crypto_register_alg(&aes_alg); +} + +static void __exit aes_fini(void) +{ + crypto_unregister_alg(&aes_alg); +} + +module_init(aes_init); +module_exit(aes_fini); + +MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm"); +MODULE_LICENSE("GPL"); diff --git a/arch/x86_64/ia32/syscall32.c b/arch/x86_64/ia32/syscall32.c index 01d8db1a1c09..816a3b89f13d 100644 --- a/arch/x86_64/ia32/syscall32.c +++ b/arch/x86_64/ia32/syscall32.c @@ -57,6 +57,7 @@ int syscall32_setup_pages(struct linux_binprm *bprm, int exstack) int npages = (VSYSCALL32_END - VSYSCALL32_BASE) >> PAGE_SHIFT; struct vm_area_struct *vma; struct mm_struct *mm = current->mm; + int ret; vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); if (!vma) @@ -78,7 +79,11 @@ int syscall32_setup_pages(struct linux_binprm *bprm, int exstack) vma->vm_mm = mm; down_write(&mm->mmap_sem); - insert_vm_struct(mm, vma); + if ((ret = insert_vm_struct(mm, vma))) { + up_write(&mm->mmap_sem); + kmem_cache_free(vm_area_cachep, vma); + return ret; + } mm->total_vm += npages; up_write(&mm->mmap_sem); return 0; diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 157190d986bb..d206d7e49cf5 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -1064,7 +1064,6 @@ void print_all_local_APICs (void) void __apicdebuginit print_PIC(void) { - extern spinlock_t i8259A_lock; unsigned int v; unsigned long flags; diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c index 4e680f87a75f..5c6dc7051482 100644 --- a/arch/x86_64/kernel/kprobes.c +++ b/arch/x86_64/kernel/kprobes.c @@ -38,7 +38,7 @@ #include <linux/string.h> #include <linux/slab.h> #include <linux/preempt.h> -#include <linux/moduleloader.h> + #include <asm/cacheflush.h> #include <asm/pgtable.h> #include <asm/kdebug.h> @@ -51,8 +51,6 @@ static struct kprobe *kprobe_prev; static unsigned long kprobe_status_prev, kprobe_old_rflags_prev, kprobe_saved_rflags_prev; static struct pt_regs jprobe_saved_regs; static long *jprobe_saved_rsp; -static kprobe_opcode_t *get_insn_slot(void); -static void free_insn_slot(kprobe_opcode_t *slot); void jprobe_return_end(void); /* copy of the kernel stack at the probe fire time */ @@ -274,48 +272,23 @@ static void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) regs->rip = (unsigned long)p->ainsn.insn; } -struct task_struct *arch_get_kprobe_task(void *ptr) -{ - return ((struct thread_info *) (((unsigned long) ptr) & - (~(THREAD_SIZE -1))))->task; -} - void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs) { unsigned long *sara = (unsigned long *)regs->rsp; - struct kretprobe_instance *ri; - static void *orig_ret_addr; + struct kretprobe_instance *ri; + + if ((ri = get_free_rp_inst(rp)) != NULL) { + ri->rp = rp; + ri->task = current; + ri->ret_addr = (kprobe_opcode_t *) *sara; - /* - * Save the return address when the return probe hits - * the first time, and use it to populate the (krprobe - * instance)->ret_addr for subsequent return probes at - * the same addrress since stack address would have - * the kretprobe_trampoline by then. - */ - if (((void*) *sara) != kretprobe_trampoline) - orig_ret_addr = (void*) *sara; - - if ((ri = get_free_rp_inst(rp)) != NULL) { - ri->rp = rp; - ri->stack_addr = sara; - ri->ret_addr = orig_ret_addr; - add_rp_inst(ri); /* Replace the return addr with trampoline addr */ *sara = (unsigned long) &kretprobe_trampoline; - } else { - rp->nmissed++; - } -} -void arch_kprobe_flush_task(struct task_struct *tk) -{ - struct kretprobe_instance *ri; - while ((ri = get_rp_inst_tsk(tk)) != NULL) { - *((unsigned long *)(ri->stack_addr)) = - (unsigned long) ri->ret_addr; - recycle_rp_inst(ri); - } + add_rp_inst(ri); + } else { + rp->nmissed++; + } } /* @@ -428,36 +401,59 @@ no_kprobe: */ int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) { - struct task_struct *tsk; - struct kretprobe_instance *ri; - struct hlist_head *head; - struct hlist_node *node; - unsigned long *sara = (unsigned long *)regs->rsp - 1; - - tsk = arch_get_kprobe_task(sara); - head = kretprobe_inst_table_head(tsk); - - hlist_for_each_entry(ri, node, head, hlist) { - if (ri->stack_addr == sara && ri->rp) { - if (ri->rp->handler) - ri->rp->handler(ri, regs); - } - } - return 0; -} + struct kretprobe_instance *ri = NULL; + struct hlist_head *head; + struct hlist_node *node, *tmp; + unsigned long orig_ret_address = 0; + unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline; -void trampoline_post_handler(struct kprobe *p, struct pt_regs *regs, - unsigned long flags) -{ - struct kretprobe_instance *ri; - /* RA already popped */ - unsigned long *sara = ((unsigned long *)regs->rsp) - 1; + head = kretprobe_inst_table_head(current); - while ((ri = get_rp_inst(sara))) { - regs->rip = (unsigned long)ri->ret_addr; + /* + * It is possible to have multiple instances associated with a given + * task either because an multiple functions in the call path + * have a return probe installed on them, and/or more then one return + * return probe was registered for a target function. + * + * We can handle this because: + * - instances are always inserted at the head of the list + * - when multiple return probes are registered for the same + * function, the first instance's ret_addr will point to the + * real return address, and all the rest will point to + * kretprobe_trampoline + */ + hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { + if (ri->task != current) + /* another task is sharing our hash bucket */ + continue; + + if (ri->rp && ri->rp->handler) + ri->rp->handler(ri, regs); + + orig_ret_address = (unsigned long)ri->ret_addr; recycle_rp_inst(ri); + + if (orig_ret_address != trampoline_address) + /* + * This is the real return address. Any other + * instances associated with this task are for + * other calls deeper on the call stack + */ + break; } - regs->eflags &= ~TF_MASK; + + BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address)); + regs->rip = orig_ret_address; + + unlock_kprobes(); + preempt_enable_no_resched(); + + /* + * By returning a non-zero value, we are telling + * kprobe_handler() that we have handled unlocking + * and re-enabling preemption. + */ + return 1; } /* @@ -550,8 +546,7 @@ int post_kprobe_handler(struct pt_regs *regs) current_kprobe->post_handler(current_kprobe, regs, 0); } - if (current_kprobe->post_handler != trampoline_post_handler) - resume_execution(current_kprobe, regs); + resume_execution(current_kprobe, regs); regs->eflags |= kprobe_saved_rflags; /* Restore the original saved kprobes variables and continue. */ @@ -682,111 +677,12 @@ int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) return 0; } -/* - * kprobe->ainsn.insn points to the copy of the instruction to be single-stepped. - * By default on x86_64, pages we get from kmalloc or vmalloc are not - * executable. Single-stepping an instruction on such a page yields an - * oops. So instead of storing the instruction copies in their respective - * kprobe objects, we allocate a page, map it executable, and store all the - * instruction copies there. (We can allocate additional pages if somebody - * inserts a huge number of probes.) Each page can hold up to INSNS_PER_PAGE - * instruction slots, each of which is MAX_INSN_SIZE*sizeof(kprobe_opcode_t) - * bytes. - */ -#define INSNS_PER_PAGE (PAGE_SIZE/(MAX_INSN_SIZE*sizeof(kprobe_opcode_t))) -struct kprobe_insn_page { - struct hlist_node hlist; - kprobe_opcode_t *insns; /* page of instruction slots */ - char slot_used[INSNS_PER_PAGE]; - int nused; +static struct kprobe trampoline_p = { + .addr = (kprobe_opcode_t *) &kretprobe_trampoline, + .pre_handler = trampoline_probe_handler }; -static struct hlist_head kprobe_insn_pages; - -/** - * get_insn_slot() - Find a slot on an executable page for an instruction. - * We allocate an executable page if there's no room on existing ones. - */ -static kprobe_opcode_t *get_insn_slot(void) -{ - struct kprobe_insn_page *kip; - struct hlist_node *pos; - - hlist_for_each(pos, &kprobe_insn_pages) { - kip = hlist_entry(pos, struct kprobe_insn_page, hlist); - if (kip->nused < INSNS_PER_PAGE) { - int i; - for (i = 0; i < INSNS_PER_PAGE; i++) { - if (!kip->slot_used[i]) { - kip->slot_used[i] = 1; - kip->nused++; - return kip->insns + (i*MAX_INSN_SIZE); - } - } - /* Surprise! No unused slots. Fix kip->nused. */ - kip->nused = INSNS_PER_PAGE; - } - } - - /* All out of space. Need to allocate a new page. Use slot 0.*/ - kip = kmalloc(sizeof(struct kprobe_insn_page), GFP_KERNEL); - if (!kip) { - return NULL; - } - - /* - * For the %rip-relative displacement fixups to be doable, we - * need our instruction copy to be within +/- 2GB of any data it - * might access via %rip. That is, within 2GB of where the - * kernel image and loaded module images reside. So we allocate - * a page in the module loading area. - */ - kip->insns = module_alloc(PAGE_SIZE); - if (!kip->insns) { - kfree(kip); - return NULL; - } - INIT_HLIST_NODE(&kip->hlist); - hlist_add_head(&kip->hlist, &kprobe_insn_pages); - memset(kip->slot_used, 0, INSNS_PER_PAGE); - kip->slot_used[0] = 1; - kip->nused = 1; - return kip->insns; -} - -/** - * free_insn_slot() - Free instruction slot obtained from get_insn_slot(). - */ -static void free_insn_slot(kprobe_opcode_t *slot) +int __init arch_init_kprobes(void) { - struct kprobe_insn_page *kip; - struct hlist_node *pos; - - hlist_for_each(pos, &kprobe_insn_pages) { - kip = hlist_entry(pos, struct kprobe_insn_page, hlist); - if (kip->insns <= slot - && slot < kip->insns+(INSNS_PER_PAGE*MAX_INSN_SIZE)) { - int i = (slot - kip->insns) / MAX_INSN_SIZE; - kip->slot_used[i] = 0; - kip->nused--; - if (kip->nused == 0) { - /* - * Page is no longer in use. Free it unless - * it's the last one. We keep the last one - * so as not to have to set it up again the - * next time somebody inserts a probe. - */ - hlist_del(&kip->hlist); - if (hlist_empty(&kprobe_insn_pages)) { - INIT_HLIST_NODE(&kip->hlist); - hlist_add_head(&kip->hlist, - &kprobe_insn_pages); - } else { - module_free(NULL, kip->insns); - kfree(kip); - } - } - return; - } - } + return register_kprobe(&trampoline_p); } diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c index 1d91271796e5..7577f9d7a75d 100644 --- a/arch/x86_64/kernel/process.c +++ b/arch/x86_64/kernel/process.c @@ -482,6 +482,33 @@ out: } /* + * This function selects if the context switch from prev to next + * has to tweak the TSC disable bit in the cr4. + */ +static inline void disable_tsc(struct task_struct *prev_p, + struct task_struct *next_p) +{ + struct thread_info *prev, *next; + + /* + * gcc should eliminate the ->thread_info dereference if + * has_secure_computing returns 0 at compile time (SECCOMP=n). + */ + prev = prev_p->thread_info; + next = next_p->thread_info; + + if (has_secure_computing(prev) || has_secure_computing(next)) { + /* slow path here */ + if (has_secure_computing(prev) && + !has_secure_computing(next)) { + write_cr4(read_cr4() & ~X86_CR4_TSD); + } else if (!has_secure_computing(prev) && + has_secure_computing(next)) + write_cr4(read_cr4() | X86_CR4_TSD); + } +} + +/* * This special macro can be used to load a debugging register */ #define loaddebug(thread,r) set_debug(thread->debugreg ## r, r) @@ -599,6 +626,8 @@ struct task_struct *__switch_to(struct task_struct *prev_p, struct task_struct * } } + disable_tsc(prev_p, next_p); + return prev_p; } diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index b02d921da4f7..5fd03225058a 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c @@ -1076,6 +1076,10 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c) #ifdef CONFIG_X86_MCE mcheck_init(c); #endif + if (c == &boot_cpu_data) + mtrr_bp_init(); + else + mtrr_ap_init(); #ifdef CONFIG_NUMA if (c != &boot_cpu_data) numa_add_cpu(c - cpu_data); diff --git a/arch/x86_64/kernel/suspend.c b/arch/x86_64/kernel/suspend.c index 6c0f402e3a88..0612640d91b1 100644 --- a/arch/x86_64/kernel/suspend.c +++ b/arch/x86_64/kernel/suspend.c @@ -119,6 +119,7 @@ void __restore_processor_state(struct saved_context *ctxt) fix_processor_context(); do_fpu_end(); + mtrr_ap_init(); } void restore_processor_state(void) diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S index 73389f51c4e5..2a94f9b60b2d 100644 --- a/arch/x86_64/kernel/vmlinux.lds.S +++ b/arch/x86_64/kernel/vmlinux.lds.S @@ -56,10 +56,14 @@ SECTIONS .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) { *(.data.cacheline_aligned) } + . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); + .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { + *(.data.read_mostly) + } #define VSYSCALL_ADDR (-10*1024*1024) -#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.cacheline_aligned) + SIZEOF(.data.cacheline_aligned) + 4095) & ~(4095)) -#define VSYSCALL_VIRT_ADDR ((ADDR(.data.cacheline_aligned) + SIZEOF(.data.cacheline_aligned) + 4095) & ~(4095)) +#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095)) +#define VSYSCALL_VIRT_ADDR ((ADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095)) #define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR) #define VLOAD(x) (ADDR(x) - VLOAD_OFFSET) diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c index b693c232fd07..657e88aa0902 100644 --- a/arch/x86_64/pci/mmconfig.c +++ b/arch/x86_64/pci/mmconfig.c @@ -7,25 +7,50 @@ #include <linux/pci.h> #include <linux/init.h> +#include <linux/acpi.h> #include "pci.h" #define MMCONFIG_APER_SIZE (256*1024*1024) -/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ -u32 pci_mmcfg_base_addr; - /* Static virtual mapping of the MMCONFIG aperture */ -char *pci_mmcfg_virt; +struct mmcfg_virt { + struct acpi_table_mcfg_config *cfg; + char *virt; +}; +static struct mmcfg_virt *pci_mmcfg_virt; -static inline char *pci_dev_base(unsigned int bus, unsigned int devfn) +static char *get_virt(unsigned int seg, int bus) { - return pci_mmcfg_virt + ((bus << 20) | (devfn << 12)); + int cfg_num = -1; + struct acpi_table_mcfg_config *cfg; + + while (1) { + ++cfg_num; + if (cfg_num >= pci_mmcfg_config_num) { + /* something bad is going on, no cfg table is found. */ + /* so we fall back to the old way we used to do this */ + /* and just rely on the first entry to be correct. */ + return pci_mmcfg_virt[0].virt; + } + cfg = pci_mmcfg_virt[cfg_num].cfg; + if (cfg->pci_segment_group_number != seg) + continue; + if ((cfg->start_bus_number <= bus) && + (cfg->end_bus_number >= bus)) + return pci_mmcfg_virt[cfg_num].virt; + } +} + +static inline char *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn) +{ + + return get_virt(seg, bus) + ((bus << 20) | (devfn << 12)); } static int pci_mmcfg_read(unsigned int seg, unsigned int bus, unsigned int devfn, int reg, int len, u32 *value) { - char *addr = pci_dev_base(bus, devfn); + char *addr = pci_dev_base(seg, bus, devfn); if (unlikely(!value || (bus > 255) || (devfn > 255) || (reg > 4095))) return -EINVAL; @@ -48,7 +73,7 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus, static int pci_mmcfg_write(unsigned int seg, unsigned int bus, unsigned int devfn, int reg, int len, u32 value) { - char *addr = pci_dev_base(bus,devfn); + char *addr = pci_dev_base(seg, bus, devfn); if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) return -EINVAL; @@ -75,9 +100,15 @@ static struct pci_raw_ops pci_mmcfg = { static int __init pci_mmcfg_init(void) { + int i; + if ((pci_probe & PCI_PROBE_MMCONF) == 0) return 0; - if (!pci_mmcfg_base_addr) + + acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); + if ((pci_mmcfg_config_num == 0) || + (pci_mmcfg_config == NULL) || + (pci_mmcfg_config[0].base_address == 0)) return 0; /* Kludge for now. Don't use mmconfig on AMD systems because @@ -88,13 +119,22 @@ static int __init pci_mmcfg_init(void) return 0; /* RED-PEN i386 doesn't do _nocache right now */ - pci_mmcfg_virt = ioremap_nocache(pci_mmcfg_base_addr, MMCONFIG_APER_SIZE); - if (!pci_mmcfg_virt) { - printk("PCI: Cannot map mmconfig aperture\n"); + pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL); + if (pci_mmcfg_virt == NULL) { + printk("PCI: Can not allocate memory for mmconfig structures\n"); return 0; - } + } + for (i = 0; i < pci_mmcfg_config_num; ++i) { + pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i]; + pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address, MMCONFIG_APER_SIZE); + if (!pci_mmcfg_virt[i].virt) { + printk("PCI: Cannot map mmconfig aperture for segment %d\n", + pci_mmcfg_config[i].pci_segment_group_number); + return 0; + } + printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_config[i].base_address); + } - printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_base_addr); raw_pci_ops = &pci_mmcfg; pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 3e89767cea72..2b6257bec4c3 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -132,7 +132,7 @@ config XTENSA_CPU_CLOCK config GENERIC_CALIBRATE_DELAY bool "Auto calibration of the BogoMIPS value" ---help--- - The BogoMIPS value can easily derived from the CPU frequency. + The BogoMIPS value can easily be derived from the CPU frequency. config CMDLINE_BOOL bool "Default bootloader kernel arguments" @@ -158,6 +158,8 @@ config XTENSA_ISS_NETWORK depends on XTENSA_PLATFORM_ISS default y +source "mm/Kconfig" + endmenu menu "Bus options" @@ -226,6 +228,8 @@ source "fs/Kconfig.binfmt" endmenu +source "net/Kconfig" + source "drivers/Kconfig" source "fs/Kconfig" diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile index 4fa27453b1f9..27847e4ffcbf 100644 --- a/arch/xtensa/Makefile +++ b/arch/xtensa/Makefile @@ -21,23 +21,17 @@ export CPU # Platform configuration -platform-y := common platform-$(CONFIG_XTENSA_PLATFORM_XT2000) := xt2000 platform-$(CONFIG_XTENSA_PLATFORM_ISS) := iss PLATFORM = $(platform-y) export PLATFORM -#LDFLAGS_vmlinux := -T$(word 1,$(LINKSCRIPT)) -AFLAGS_vmlinux.lds.o := -Uxtensa -CPPFLAGS += -Iarch/xtensa -Iinclude/asm -mlongcalls -g -AFLAGS += -Iarch/xtensa -Iinclude/asm -CPP = $(CC) -E $(CFLAGS) +CPPFLAGS += $(if $(KBUILD_SRC),-I$(srctree)/include/asm-xtensa/) +CPPFLAGS += -Iinclude/asm +CFLAGS += -pipe -mlongcalls -cflags-y += -Iarch/xtensa -pipe -mlongcalls - - -KBUILD_DEFCONFIG := common_defconfig +KBUILD_DEFCONFIG := iss_defconfig # ramdisk/initrd support # You need a compressed ramdisk image, named ramdisk.gz in @@ -62,30 +56,36 @@ endif LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) head-y := arch/xtensa/kernel/head.o -core-y += arch/xtensa/kernel/ \ - arch/xtensa/mm/ arch/xtensa/platform-$(PLATFORM)/ +core-y += arch/xtensa/kernel/ arch/xtensa/mm/ +ifneq ($(PLATFORM),) +core-y += arch/xtensa/platform-$(PLATFORM)/ +endif libs-y += arch/xtensa/lib/ $(LIBGCC) -boot := arch/xtensa/boot +boot := arch/xtensa/boot + +archinc := include/asm-xtensa arch/xtensa/kernel/asm-offsets.s: \ - arch/xtensa/kernel/asm-offsets.c \ - include/asm-xtensa/.platform + arch/xtensa/kernel/asm-offsets.c $(archinc)/.platform include/asm-xtensa/offsets.h: arch/xtensa/kernel/asm-offsets.s $(call filechk,gen-asm-offsets) -prepare: include/asm-xtensa/.platform include/asm-xtensa/offsets.h +prepare: $(archinc)/.platform $(archinc)/offsets.h # Update machine cpu and platform symlinks if something which affects # them changed. -include/asm-xtensa/.platform: $(wildcard include/config/arch/*.h) - @echo ' Setting up cpu ($(CPU)) and platform ($(PLATFORM)) symlinks' - $(Q)rm -f include/asm-xtensa/platform - $(Q)rm -f include/asm-xtensa/xtensa/config - $(Q)(cd include/asm-xtensa/; ln -sf platform-$(PLATFORM) platform) - $(Q)(cd include/asm-xtensa/xtensa; ln -sf config-$(CPU) config) +$(archinc)/.platform: $(wildcard include/config/arch/*.h) include/config/MARKER + @echo ' SYMLINK $(archinc)/xtensa/config -> $(archinc)/xtensa/config-$(CPU)' + $(Q)mkdir -p $(archinc) + $(Q)mkdir -p $(archinc)/xtensa + $(Q)ln -fsn $(srctree)/$(archinc)/xtensa/config-$(CPU) $(archinc)/xtensa/config + @echo ' SYMLINK $(archinc)/platform -> $(archinc)/platform-$(PLATFORM)' + $(Q)ln -fsn $(srctree)/$(archinc)/platform-$(PLATFORM) $(archinc)/platform + @touch $@ + all: zImage @@ -94,7 +94,9 @@ bzImage : zImage zImage zImage.initrd: vmlinux $(Q)$(MAKE) $(build)=$(boot) $@ -CLEAN_FILES += arch/xtensa/vmlinux.lds include/asm-xtensa/offset.h +CLEAN_FILES += arch/xtensa/vmlinux.lds $(archinc)/offset.h \ + $(archinc)/platform $(archinc)/xtensa/config \ + $(archinc)/.platform define archhelp @echo '* zImage - Compressed kernel image (arch/xtensa/boot/images/zImage.*)' diff --git a/arch/xtensa/boot/Makefile b/arch/xtensa/boot/Makefile index 260f456ccf0b..820b31d10ae4 100644 --- a/arch/xtensa/boot/Makefile +++ b/arch/xtensa/boot/Makefile @@ -11,21 +11,19 @@ CFLAGS += -fno-builtin -Iarch/$(ARCH)/boot/include HOSTFLAGS += -Iarch/$(ARCH)/boot/include -BIG_ENDIAN := $(shell echo -e "\#ifdef __XTENSA_EL__\nint little;\n\#else\nint big;\n\#endif" | $(CC) -E -|grep -c big) - +BIG_ENDIAN := $(shell echo -e __XTENSA_EB__ | $(CC) -E - | grep -v "\#") export CFLAGS export AFLAGS export BIG_ENDIAN +subdir-y := lib + # Subdirs for the boot loader(s) bootdir-$(CONFIG_XTENSA_PLATFORM_ISS) += boot-elf bootdir-$(CONFIG_XTENSA_PLATFORM_XT2000) += boot-redboot boot-elf -subdir-y := lib/ - -subdir-y += boot-elf/ boot-redboot/ zImage zImage.initrd Image Image.initrd: $(bootdir-y) @@ -33,5 +31,3 @@ $(bootdir-y): $(addprefix $(obj)/,$(subdir-y)) \ $(addprefix $(obj)/,$(host-progs)) $(Q)$(MAKE) $(build)=$(obj)/$@ $(MAKECMDGOALS) - - diff --git a/arch/xtensa/boot/boot-elf/Makefile b/arch/xtensa/boot/boot-elf/Makefile index f6ef6a369667..734db7f76583 100644 --- a/arch/xtensa/boot/boot-elf/Makefile +++ b/arch/xtensa/boot/boot-elf/Makefile @@ -27,7 +27,7 @@ Image: vmlinux $(OBJS) --set-section-flags image=contents,alloc,load,load,data \ $(OBJS) $@.tmp $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \ - -T arch/$(ARCH)/boot/boot-elf/boot.ld \ + -T $(srctree)/arch/$(ARCH)/boot/boot-elf/boot.ld \ -o arch/$(ARCH)/boot/$@.elf $@.tmp rm -f $@.tmp vmlinux.tmp @@ -41,7 +41,7 @@ Image.initrd: vmlinux $(OBJS) --set-section-flags image=contents,alloc,load,load,data \ $(OBJS) $@.tmp $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \ - -T arch/$(ARCH)/boot/boot-elf/boot.ld \ + -T $(srctree)/arch/$(ARCH)/boot/boot-elf/boot.ld \ -o arch/$(ARCH)/boot/$@.elf $@.tmp rm -f $@.tmp vmlinux.tmp diff --git a/arch/xtensa/boot/boot-redboot/Makefile b/arch/xtensa/boot/boot-redboot/Makefile index ca8a68bc8472..f53262c2e1f3 100644 --- a/arch/xtensa/boot/boot-redboot/Makefile +++ b/arch/xtensa/boot/boot-redboot/Makefile @@ -12,24 +12,24 @@ else OBJCOPY_ARGS := -O elf32-xtensa-le endif -LD_ARGS = -T $(obj)/boot.ld +LD_ARGS = -T $(srctree)/$(obj)/boot.ld boot-y := bootstrap.o OBJS := $(addprefix $(obj)/,$(boot-y)) -LIBS := arch/$(ARCH)/boot/lib/lib.a arch/$(ARCH)/lib/lib.a +LIBS := arch/xtensa/boot/lib/lib.a arch/xtensa/lib/lib.a LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) zImage: vmlinux $(OBJS) $(LIBS) $(OBJCOPY) --strip-all -R .comment -R .xt.insn -O binary \ - $(TOPDIR)/vmlinux vmlinux.tmp + vmlinux vmlinux.tmp gzip -vf9 vmlinux.tmp $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ --add-section image=vmlinux.tmp.gz \ --set-section-flags image=contents,alloc,load,load,data \ $(OBJS) $@.tmp $(LD) $(LD_ARGS) -o $@.elf $@.tmp $(LIBS) -L/xtensa-elf/lib $(LIBGCC) - $(OBJCOPY) -S -O binary $@.elf arch/$(ARCH)/boot/images/$@.redboot -# rm -f $@.tmp $@.elf vmlinux.tmp.gz + $(OBJCOPY) -S -O binary $@.elf arch/$(ARCH)/boot/$@.redboot + rm -f $@.tmp $@.elf vmlinux.tmp.gz diff --git a/arch/xtensa/boot/include/zlib.h b/arch/xtensa/boot/include/zlib.h deleted file mode 100644 index ea29b6237852..000000000000 --- a/arch/xtensa/boot/include/zlib.h +++ /dev/null @@ -1,433 +0,0 @@ -/* - * BK Id: SCCS/s.zlib.h 1.8 05/18/01 15:17:23 cort - */ -/* - * This file is derived from zlib.h and zconf.h from the zlib-0.95 - * distribution by Jean-loup Gailly and Mark Adler, with some additions - * by Paul Mackerras to aid in implementing Deflate compression and - * decompression for PPP packets. - */ - -/* - * ==FILEVERSION 960122== - * - * This marker is used by the Linux installation script to determine - * whether an up-to-date version of this file is already installed. - */ - -/* zlib.h -- interface of the 'zlib' general purpose compression library - version 0.95, Aug 16th, 1995. - - Copyright (C) 1995 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - gzip@prep.ai.mit.edu madler@alumni.caltech.edu - */ - -#ifndef _ZLIB_H -#define _ZLIB_H - -/* #include "zconf.h" */ /* included directly here */ - -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* From: zconf.h,v 1.12 1995/05/03 17:27:12 jloup Exp */ - -/* - The library does not install any signal handler. It is recommended to - add at least a handler for SIGSEGV when decompressing; the library checks - the consistency of the input data whenever possible but may go nuts - for some forms of corrupted input. - */ - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - * Compile with -DUNALIGNED_OK if it is OK to access shorts or ints - * at addresses which are not a multiple of their size. - * Under DOS, -DFAR=far or -DFAR=__far may be needed. - */ - -#ifndef STDC -# if defined(MSDOS) || defined(__STDC__) || defined(__cplusplus) -# define STDC -# endif -#endif - -#ifdef __MWERKS__ /* Metrowerks CodeWarrior declares fileno() in unix.h */ -# include <unix.h> -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -#ifndef FAR -# define FAR -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2 */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - 1 << (windowBits+2) + 1 << (memLevel+9) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -typedef unsigned char Byte; /* 8 bits */ -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -typedef Byte FAR Bytef; -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -/* end of original zconf.h */ - -#define ZLIB_VERSION "0.95P" - -/* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed - data. This version of the library supports only one compression method - (deflation) but other algorithms may be added later and will have the same - stream interface. - - For compression the application must provide the output buffer and - may optionally provide the input buffer for optimization. For decompression, - the application must provide the input buffer and may optionally provide - the output buffer for optimization. - - Compression can be done in a single step if the buffers are large - enough (for example if an input file is mmap'ed), or can be done by - repeated calls of the compression function. In the latter case, the - application must provide more input and/or consume the output - (providing more output space) before each call. -*/ - -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address, uInt nbytes)); - -struct internal_state; - -typedef struct z_stream_s { - Bytef *next_in; /* next input byte */ - uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total nb of input bytes read so far */ - - Bytef *next_out; /* next output byte should be put there */ - uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total nb of bytes output so far */ - - char *msg; /* last error message, NULL if no error */ - struct internal_state FAR *state; /* not visible by applications */ - - alloc_func zalloc; /* used to allocate the internal state */ - free_func zfree; /* used to free the internal state */ - voidp opaque; /* private data object passed to zalloc and zfree */ - - Byte data_type; /* best guess about the data type: ascii or binary */ - -} z_stream; - -/* - The application must update next_in and avail_in when avail_in has - dropped to zero. It must update next_out and avail_out when avail_out - has dropped to zero. The application must initialize zalloc, zfree and - opaque before calling the init function. All other fields are set by the - compression library and must not be updated by the application. - - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the - opaque value. - - zalloc must return Z_NULL if there is not enough memory for the object. - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this - if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, - pointers returned by zalloc for objects of exactly 65536 bytes *must* - have their offset normalized to zero. The default allocation function - provided by this library ensures this (see zutil.c). To reduce memory - requirements and avoid any allocation of 64K objects, at the expense of - compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). - - The fields total_in and total_out can be used for statistics or - progress reports. After compression, total_in holds the total size of - the uncompressed data and may be saved for use in the decompressor - (particularly if the decompressor wants to decompress everything in - a single step). -*/ - - /* constants */ - -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 -#define Z_FULL_FLUSH 2 -#define Z_SYNC_FLUSH 3 /* experimental: partial_flush + byte align */ -#define Z_FINISH 4 -#define Z_PACKET_FLUSH 5 -/* See deflate() below for the usage of these constants */ - -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_ERRNO (-1) -#define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) -/* error codes for the compression/decompression functions */ - -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ - -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_DEFAULT_STRATEGY 0 - -#define Z_BINARY 0 -#define Z_ASCII 1 -#define Z_UNKNOWN 2 -/* Used to set the data_type field */ - -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ - -extern char *zlib_version; -/* The application can compare zlib_version and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is - not compatible with the zlib.h header file used by the application. - */ - - /* basic functions */ - -extern int inflateInit OF((z_stream *strm)); -/* - Initializes the internal stream state for decompression. The fields - zalloc and zfree must be initialized before by the caller. If zalloc and - zfree are set to Z_NULL, inflateInit updates them to use default allocation - functions. - - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory. msg is set to null if there is no error message. - inflateInit does not perform any decompression: this will be done by - inflate(). -*/ - - -extern int inflate OF((z_stream *strm, int flush)); -/* - Performs one or both of the following actions: - - - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in is updated and processing - will resume at this point for the next call of inflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. inflate() always provides as much output as possible - (until there is no more input data or no more space in the output buffer). - - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating the next_* and avail_* values accordingly. - The application can consume the uncompressed output when it wants, for - example when the output buffer is full (avail_out == 0), or after each - call of inflate(). - - If the parameter flush is set to Z_PARTIAL_FLUSH or Z_PACKET_FLUSH, - inflate flushes as much output as possible to the output buffer. The - flushing behavior of inflate is not specified for values of the flush - parameter other than Z_PARTIAL_FLUSH, Z_PACKET_FLUSH or Z_FINISH, but the - current implementation actually flushes as much output as possible - anyway. For Z_PACKET_FLUSH, inflate checks that once all the input data - has been consumed, it is expecting to see the length field of a stored - block; if not, it returns Z_DATA_ERROR. - - inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step - (a single call of inflate), the parameter flush should be set to - Z_FINISH. In this case all pending input is processed and all pending - output is flushed; avail_out must be large enough to hold all the - uncompressed data. (The size of the uncompressed data may have been saved - by the compressor for this purpose.) The next operation on this stream must - be inflateEnd to deallocate the decompression state. The use of Z_FINISH - is never required, but can be used to inform inflate that a faster routine - may be used for the single inflate() call. - - inflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if the end of the - compressed data has been reached and all uncompressed output has been - produced, Z_DATA_ERROR if the input data was corrupted, Z_STREAM_ERROR if - the stream structure was inconsistent (for example if next_in or next_out - was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no - progress is possible or if there was not enough room in the output buffer - when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then - call inflateSync to look for a good compression block. */ - - -extern int inflateEnd OF((z_stream *strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. - - inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state - was inconsistent. In the error case, msg may be set but then points to a - static string (which must not be deallocated). -*/ - - /* advanced functions */ - -extern int inflateInit2 OF((z_stream *strm, - int windowBits)); -/* - This is another version of inflateInit with more compression options. The - fields next_out, zalloc and zfree must be initialized before by the caller. - - The windowBits parameter is the base two logarithm of the maximum window - size (the size of the history buffer). It should be in the range 8..15 for - this version of the library (the value 16 will be allowed soon). The - default value is 15 if inflateInit is used instead. If a compressed stream - with a larger window size is given as input, inflate() will return with - the error code Z_DATA_ERROR instead of trying to allocate a larger window. - - If next_out is not null, the library will use this buffer for the history - buffer; the buffer must either be large enough to hold the entire output - data, or have at least 1<<windowBits bytes. If next_out is null, the - library will allocate its own buffer (and leave next_out null). next_in - need not be provided here but must be provided by the application for the - next call of inflate(). - - If the history buffer is provided by the application, next_out must - never be changed by the application since the decompressor maintains - history information inside this buffer from call to call; the application - can only reset next_out to the beginning of the history buffer when - avail_out is zero and all output has been consumed. - - inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was - not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as - windowBits < 8). msg is set to null if there is no error message. - inflateInit2 does not perform any decompression: this will be done by - inflate(). -*/ - -extern int inflateSync OF((z_stream *strm)); -/* - Skips invalid compressed data until the special marker (see deflate() - above) can be found, or until all available input is skipped. No output - is provided. - - inflateSync returns Z_OK if the special marker has been found, Z_BUF_ERROR - if no more input was provided, Z_DATA_ERROR if no marker has been found, - or Z_STREAM_ERROR if the stream structure was inconsistent. In the success - case, the application may save the current current value of total_in which - indicates where valid compressed data was found. In the error case, the - application may repeatedly call inflateSync, providing more input each time, - until success or end of the input data. -*/ - -extern int inflateReset OF((z_stream *strm)); -/* - This function is equivalent to inflateEnd followed by inflateInit, - but does not free and reallocate all the internal decompression state. - The stream will keep attributes that may have been set by inflateInit2. - - inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being NULL). -*/ - -extern int inflateIncomp OF((z_stream *strm)); -/* - This function adds the data at next_in (avail_in bytes) to the output - history without performing any output. There must be no pending output, - and the decompressor must be expecting to see the start of a block. - Calling this function is equivalent to decompressing a stored block - containing the data at next_in (except that the data is not output). -*/ - - /* checksum functions */ - -/* - This function is not related to compression but is exported - anyway because it might be useful in applications using the - compression library. -*/ - -extern uLong adler32 OF((uLong adler, Bytef *buf, uInt len)); - -/* - Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. If buf is NULL, this function returns - the required initial value for the checksum. - An Adler-32 checksum is almost as reliable as a CRC32 but can be computed - much faster. Usage example: - - uLong adler = adler32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - adler = adler32(adler, buffer, length); - } - if (adler != original_adler) error(); -*/ - -#ifndef _Z_UTIL_H - struct internal_state {int dummy;}; /* hack for buggy compilers */ -#endif - -#endif /* _ZLIB_H */ diff --git a/arch/xtensa/boot/lib/Makefile b/arch/xtensa/boot/lib/Makefile index c0a74dc3a0df..9e73bb8aeb7a 100644 --- a/arch/xtensa/boot/lib/Makefile +++ b/arch/xtensa/boot/lib/Makefile @@ -2,5 +2,16 @@ # Makefile for some libs needed by zImage. # +zlib := infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c -lib-y := zlib.o zmem.o +lib-y += $(zlib:.c=.o) zmem.o + +EXTRA_CFLAGS += -Ilib/zlib_inflate + +quiet_cmd_copy_zlib = COPY $@ + cmd_copy_zlib = cat $< > $@ + +$(addprefix $(obj)/,$(zlib)): $(obj)/%: $(srctree)/lib/zlib_inflate/% + $(call cmd,copy_zlib) + +clean-files := $(zlib) diff --git a/arch/xtensa/boot/lib/memcpy.S b/arch/xtensa/boot/lib/memcpy.S deleted file mode 100644 index a029f5df2d5c..000000000000 --- a/arch/xtensa/boot/lib/memcpy.S +++ /dev/null @@ -1,36 +0,0 @@ -/* - * arch/xtensa/lib/memcpy.S - * - * ANSI C standard library function memcpy - * - * This file is subject to the terms and conditions of the GNU General - * Public License. See the file "COPYING" in the main directory of - * this archive for more details. - * - * Copyright (C) 2002 Tensilica Inc. - */ - -#define _ASMLANGUAGE -#include <xtensa/config/core.h> - -.text -.align 4 -.global bcopy -.type bcopy,@function -bcopy: - movi a14, xthal_bcopy // a14 safe to use regardless of whether caller - // used call4 or call8 (can't have used call12) - jx a14 // let the Core HAL do the work - -.text -.align 4 -.global memcpy -.type memcpy,@function -memcpy: -.global memmove -.type memmove,@function -memmove: - movi a14, xthal_memcpy // a14 safe to use regardless of whether caller - // used call4 or call8 (can't have used call12) - jx a14 // let the Core HAL do the work - diff --git a/arch/xtensa/boot/lib/zlib.c b/arch/xtensa/boot/lib/zlib.c deleted file mode 100644 index e3859f631077..000000000000 --- a/arch/xtensa/boot/lib/zlib.c +++ /dev/null @@ -1,2150 +0,0 @@ -/* - * BK Id: SCCS/s.zlib.c 1.8 05/18/01 15:17:24 cort - */ -/* - * This file is derived from various .h and .c files from the zlib-0.95 - * distribution by Jean-loup Gailly and Mark Adler, with some additions - * by Paul Mackerras to aid in implementing Deflate compression and - * decompression for PPP packets. See zlib.h for conditions of - * distribution and use. - * - * Changes that have been made include: - * - changed functions not used outside this file to "local" - * - added minCompression parameter to deflateInit2 - * - added Z_PACKET_FLUSH (see zlib.h for details) - * - added inflateIncomp - * - */ - -/*+++++*/ -/* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* From: zutil.h,v 1.9 1995/05/03 17:27:12 jloup Exp */ - -#define _Z_UTIL_H - -#include "zlib.h" - -#ifndef local -# define local static -#endif -/* compile with -Dlocal if your debugger can't find static symbols */ - -#define FAR - -typedef unsigned char uch; -typedef uch FAR uchf; -typedef unsigned short ush; -typedef ush FAR ushf; -typedef unsigned long ulg; - -extern char *z_errmsg[]; /* indexed by 1-zlib_error */ - -#define ERR_RETURN(strm,err) return (strm->msg=z_errmsg[1-err], err) -/* To be used only when the state is known to be valid */ - -#ifndef NULL -#define NULL ((void *) 0) -#endif - - /* common constants */ - -#define DEFLATED 8 - -#ifndef DEF_WBITS -# define DEF_WBITS MAX_WBITS -#endif -/* default windowBits for decompression. MAX_WBITS is for compression only */ - -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif -/* default memLevel */ - -#define STORED_BLOCK 0 -#define STATIC_TREES 1 -#define DYN_TREES 2 -/* The three kinds of block type */ - -#define MIN_MATCH 3 -#define MAX_MATCH 258 -/* The minimum and maximum match lengths */ - - /* functions */ - -#include <linux/string.h> -#define zmemcpy memcpy -#define zmemzero(dest, len) memset(dest, 0, len) - -/* Diagnostic functions */ -#ifdef DEBUG_ZLIB -# include <stdio.h> -# ifndef verbose -# define verbose 0 -# endif -# define Assert(cond,msg) {if(!(cond)) z_error(msg);} -# define Trace(x) fprintf x -# define Tracev(x) {if (verbose) fprintf x ;} -# define Tracevv(x) {if (verbose>1) fprintf x ;} -# define Tracec(c,x) {if (verbose && (c)) fprintf x ;} -# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} -#else -# define Assert(cond,msg) -# define Trace(x) -# define Tracev(x) -# define Tracevv(x) -# define Tracec(c,x) -# define Tracecv(c,x) -#endif - - -typedef uLong (*check_func) OF((uLong check, Bytef *buf, uInt len)); - -/* voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); */ -/* void zcfree OF((voidpf opaque, voidpf ptr)); */ - -#define ZALLOC(strm, items, size) \ - (*((strm)->zalloc))((strm)->opaque, (items), (size)) -#define ZFREE(strm, addr, size) \ - (*((strm)->zfree))((strm)->opaque, (voidpf)(addr), (size)) -#define TRY_FREE(s, p, n) {if (p) ZFREE(s, p, n);} - -/* deflate.h -- internal compression state - * Copyright (C) 1995 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/*+++++*/ -/* infblock.h -- header to use infblock.c - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -struct inflate_blocks_state; -typedef struct inflate_blocks_state FAR inflate_blocks_statef; - -local inflate_blocks_statef * inflate_blocks_new OF(( - z_stream *z, - check_func c, /* check function */ - uInt w)); /* window size */ - -local int inflate_blocks OF(( - inflate_blocks_statef *, - z_stream *, - int)); /* initial return code */ - -local void inflate_blocks_reset OF(( - inflate_blocks_statef *, - z_stream *, - uLongf *)); /* check value on output */ - -local int inflate_blocks_free OF(( - inflate_blocks_statef *, - z_stream *, - uLongf *)); /* check value on output */ - -local int inflate_addhistory OF(( - inflate_blocks_statef *, - z_stream *)); - -local int inflate_packet_flush OF(( - inflate_blocks_statef *)); - -/*+++++*/ -/* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* Huffman code lookup table entry--this entry is four bytes for machines - that have 16-bit pointers (e.g. PC's in the small or medium model). */ - -typedef struct inflate_huft_s FAR inflate_huft; - -struct inflate_huft_s { - union { - struct { - Byte Exop; /* number of extra bits or operation */ - Byte Bits; /* number of bits in this code or subcode */ - } what; - uInt Nalloc; /* number of these allocated here */ - Bytef *pad; /* pad structure to a power of 2 (4 bytes for */ - } word; /* 16-bit, 8 bytes for 32-bit machines) */ - union { - uInt Base; /* literal, length base, or distance base */ - inflate_huft *Next; /* pointer to next level of table */ - } more; -}; - -#ifdef DEBUG_ZLIB - local uInt inflate_hufts; -#endif - -local int inflate_trees_bits OF(( - uIntf *, /* 19 code lengths */ - uIntf *, /* bits tree desired/actual depth */ - inflate_huft * FAR *, /* bits tree result */ - z_stream *)); /* for zalloc, zfree functions */ - -local int inflate_trees_dynamic OF(( - uInt, /* number of literal/length codes */ - uInt, /* number of distance codes */ - uIntf *, /* that many (total) code lengths */ - uIntf *, /* literal desired/actual bit depth */ - uIntf *, /* distance desired/actual bit depth */ - inflate_huft * FAR *, /* literal/length tree result */ - inflate_huft * FAR *, /* distance tree result */ - z_stream *)); /* for zalloc, zfree functions */ - -local int inflate_trees_fixed OF(( - uIntf *, /* literal desired/actual bit depth */ - uIntf *, /* distance desired/actual bit depth */ - inflate_huft * FAR *, /* literal/length tree result */ - inflate_huft * FAR *)); /* distance tree result */ - -local int inflate_trees_free OF(( - inflate_huft *, /* tables to free */ - z_stream *)); /* for zfree function */ - - -/*+++++*/ -/* infcodes.h -- header to use infcodes.c - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -struct inflate_codes_state; -typedef struct inflate_codes_state FAR inflate_codes_statef; - -local inflate_codes_statef *inflate_codes_new OF(( - uInt, uInt, - inflate_huft *, inflate_huft *, - z_stream *)); - -local int inflate_codes OF(( - inflate_blocks_statef *, - z_stream *, - int)); - -local void inflate_codes_free OF(( - inflate_codes_statef *, - z_stream *)); - - -/*+++++*/ -/* inflate.c -- zlib interface to inflate modules - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* inflate private state */ -struct internal_state { - - /* mode */ - enum { - METHOD, /* waiting for method byte */ - FLAG, /* waiting for flag byte */ - BLOCKS, /* decompressing blocks */ - CHECK4, /* four check bytes to go */ - CHECK3, /* three check bytes to go */ - CHECK2, /* two check bytes to go */ - CHECK1, /* one check byte to go */ - DONE, /* finished check, done */ - BAD} /* got an error--stay here */ - mode; /* current inflate mode */ - - /* mode dependent information */ - union { - uInt method; /* if FLAGS, method byte */ - struct { - uLong was; /* computed check value */ - uLong need; /* stream check value */ - } check; /* if CHECK, check values to compare */ - uInt marker; /* if BAD, inflateSync's marker bytes count */ - } sub; /* submode */ - - /* mode independent information */ - int nowrap; /* flag for no wrapper */ - uInt wbits; /* log2(window size) (8..15, defaults to 15) */ - inflate_blocks_statef - *blocks; /* current inflate_blocks state */ - -}; - - -int inflateReset(z) -z_stream *z; -{ - uLong c; - - if (z == Z_NULL || z->state == Z_NULL) - return Z_STREAM_ERROR; - z->total_in = z->total_out = 0; - z->msg = Z_NULL; - z->state->mode = z->state->nowrap ? BLOCKS : METHOD; - inflate_blocks_reset(z->state->blocks, z, &c); - Trace((stderr, "inflate: reset\n")); - return Z_OK; -} - - -int inflateEnd(z) -z_stream *z; -{ - uLong c; - - if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) - return Z_STREAM_ERROR; - if (z->state->blocks != Z_NULL) - inflate_blocks_free(z->state->blocks, z, &c); - ZFREE(z, z->state, sizeof(struct internal_state)); - z->state = Z_NULL; - Trace((stderr, "inflate: end\n")); - return Z_OK; -} - - -int inflateInit2(z, w) -z_stream *z; -int w; -{ - /* initialize state */ - if (z == Z_NULL) - return Z_STREAM_ERROR; -/* if (z->zalloc == Z_NULL) z->zalloc = zcalloc; */ -/* if (z->zfree == Z_NULL) z->zfree = zcfree; */ - if ((z->state = (struct internal_state FAR *) - ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) - return Z_MEM_ERROR; - z->state->blocks = Z_NULL; - - /* handle undocumented nowrap option (no zlib header or check) */ - z->state->nowrap = 0; - if (w < 0) - { - w = - w; - z->state->nowrap = 1; - } - - /* set window size */ - if (w < 8 || w > 15) - { - inflateEnd(z); - return Z_STREAM_ERROR; - } - z->state->wbits = (uInt)w; - - /* create inflate_blocks state */ - if ((z->state->blocks = - inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, 1 << w)) - == Z_NULL) - { - inflateEnd(z); - return Z_MEM_ERROR; - } - Trace((stderr, "inflate: allocated\n")); - - /* reset state */ - inflateReset(z); - return Z_OK; -} - - -int inflateInit(z) -z_stream *z; -{ - return inflateInit2(z, DEF_WBITS); -} - - -#define NEEDBYTE {if(z->avail_in==0)goto empty;r=Z_OK;} -#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) - -int inflate(z, f) -z_stream *z; -int f; -{ - int r; - uInt b; - - if (z == Z_NULL || z->next_in == Z_NULL) - return Z_STREAM_ERROR; - r = Z_BUF_ERROR; - while (1) switch (z->state->mode) - { - case METHOD: - NEEDBYTE - if (((z->state->sub.method = NEXTBYTE) & 0xf) != DEFLATED) - { - z->state->mode = BAD; - z->msg = "unknown compression method"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - if ((z->state->sub.method >> 4) + 8 > z->state->wbits) - { - z->state->mode = BAD; - z->msg = "invalid window size"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - z->state->mode = FLAG; - case FLAG: - NEEDBYTE - if ((b = NEXTBYTE) & 0x20) - { - z->state->mode = BAD; - z->msg = "invalid reserved bit"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - if (((z->state->sub.method << 8) + b) % 31) - { - z->state->mode = BAD; - z->msg = "incorrect header check"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - Trace((stderr, "inflate: zlib header ok\n")); - z->state->mode = BLOCKS; - case BLOCKS: - r = inflate_blocks(z->state->blocks, z, r); - if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0) - r = inflate_packet_flush(z->state->blocks); - if (r == Z_DATA_ERROR) - { - z->state->mode = BAD; - z->state->sub.marker = 0; /* can try inflateSync */ - break; - } - if (r != Z_STREAM_END) - return r; - r = Z_OK; - inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); - if (z->state->nowrap) - { - z->state->mode = DONE; - break; - } - z->state->mode = CHECK4; - case CHECK4: - NEEDBYTE - z->state->sub.check.need = (uLong)NEXTBYTE << 24; - z->state->mode = CHECK3; - case CHECK3: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE << 16; - z->state->mode = CHECK2; - case CHECK2: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE << 8; - z->state->mode = CHECK1; - case CHECK1: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE; - - if (z->state->sub.check.was != z->state->sub.check.need) - { - z->state->mode = BAD; - z->msg = "incorrect data check"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - Trace((stderr, "inflate: zlib check ok\n")); - z->state->mode = DONE; - case DONE: - return Z_STREAM_END; - case BAD: - return Z_DATA_ERROR; - default: - return Z_STREAM_ERROR; - } - - empty: - if (f != Z_PACKET_FLUSH) - return r; - z->state->mode = BAD; - z->state->sub.marker = 0; /* can try inflateSync */ - return Z_DATA_ERROR; -} - -/* - * This subroutine adds the data at next_in/avail_in to the output history - * without performing any output. The output buffer must be "caught up"; - * i.e. no pending output (hence s->read equals s->write), and the state must - * be BLOCKS (i.e. we should be willing to see the start of a series of - * BLOCKS). On exit, the output will also be caught up, and the checksum - * will have been updated if need be. - */ - -int inflateIncomp(z) -z_stream *z; -{ - if (z->state->mode != BLOCKS) - return Z_DATA_ERROR; - return inflate_addhistory(z->state->blocks, z); -} - - -int inflateSync(z) -z_stream *z; -{ - uInt n; /* number of bytes to look at */ - Bytef *p; /* pointer to bytes */ - uInt m; /* number of marker bytes found in a row */ - uLong r, w; /* temporaries to save total_in and total_out */ - - /* set up */ - if (z == Z_NULL || z->state == Z_NULL) - return Z_STREAM_ERROR; - if (z->state->mode != BAD) - { - z->state->mode = BAD; - z->state->sub.marker = 0; - } - if ((n = z->avail_in) == 0) - return Z_BUF_ERROR; - p = z->next_in; - m = z->state->sub.marker; - - /* search */ - while (n && m < 4) - { - if (*p == (Byte)(m < 2 ? 0 : 0xff)) - m++; - else if (*p) - m = 0; - else - m = 4 - m; - p++, n--; - } - - /* restore */ - z->total_in += p - z->next_in; - z->next_in = p; - z->avail_in = n; - z->state->sub.marker = m; - - /* return no joy or set up to restart on a new block */ - if (m != 4) - return Z_DATA_ERROR; - r = z->total_in; w = z->total_out; - inflateReset(z); - z->total_in = r; z->total_out = w; - z->state->mode = BLOCKS; - return Z_OK; -} - -#undef NEEDBYTE -#undef NEXTBYTE - -/*+++++*/ -/* infutil.h -- types and macros common to blocks and codes - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* inflate blocks semi-private state */ -struct inflate_blocks_state { - - /* mode */ - enum { - TYPE, /* get type bits (3, including end bit) */ - LENS, /* get lengths for stored */ - STORED, /* processing stored block */ - TABLE, /* get table lengths */ - BTREE, /* get bit lengths tree for a dynamic block */ - DTREE, /* get length, distance trees for a dynamic block */ - CODES, /* processing fixed or dynamic block */ - DRY, /* output remaining window bytes */ - DONEB, /* finished last block, done */ - BADB} /* got a data error--stuck here */ - mode; /* current inflate_block mode */ - - /* mode dependent information */ - union { - uInt left; /* if STORED, bytes left to copy */ - struct { - uInt table; /* table lengths (14 bits) */ - uInt index; /* index into blens (or border) */ - uIntf *blens; /* bit lengths of codes */ - uInt bb; /* bit length tree depth */ - inflate_huft *tb; /* bit length decoding tree */ - int nblens; /* # elements allocated at blens */ - } trees; /* if DTREE, decoding info for trees */ - struct { - inflate_huft *tl, *td; /* trees to free */ - inflate_codes_statef - *codes; - } decode; /* if CODES, current state */ - } sub; /* submode */ - uInt last; /* true if this block is the last block */ - - /* mode independent information */ - uInt bitk; /* bits in bit buffer */ - uLong bitb; /* bit buffer */ - Bytef *window; /* sliding window */ - Bytef *end; /* one byte after sliding window */ - Bytef *read; /* window read pointer */ - Bytef *write; /* window write pointer */ - check_func checkfn; /* check function */ - uLong check; /* check on output */ - -}; - - -/* defines for inflate input/output */ -/* update pointers and return */ -#define UPDBITS {s->bitb=b;s->bitk=k;} -#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} -#define UPDOUT {s->write=q;} -#define UPDATE {UPDBITS UPDIN UPDOUT} -#define LEAVE {UPDATE return inflate_flush(s,z,r);} -/* get bytes and bits */ -#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} -#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} -#define NEXTBYTE (n--,*p++) -#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}} -#define DUMPBITS(j) {b>>=(j);k-=(j);} -/* output bytes */ -#define WAVAIL (q<s->read?s->read-q-1:s->end-q) -#define LOADOUT {q=s->write;m=WAVAIL;} -#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=WAVAIL;}} -#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} -#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} -#define OUTBYTE(a) {*q++=(Byte)(a);m--;} -/* load local pointers */ -#define LOAD {LOADIN LOADOUT} - -/* - * The IBM 150 firmware munges the data right after _etext[]. This - * protects it. -- Cort - */ -local uInt protect_mask[] = {0, 0, 0, 0, 0, 0, 0, 0, 0 ,0 ,0 ,0}; -/* And'ing with mask[n] masks the lower n bits */ -local uInt inflate_mask[] = { - 0x0000, - 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, - 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff -}; - -/* copy as much as possible from the sliding window to the output area */ -local int inflate_flush OF(( - inflate_blocks_statef *, - z_stream *, - int)); - -/*+++++*/ -/* inffast.h -- header to use inffast.c - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -local int inflate_fast OF(( - uInt, - uInt, - inflate_huft *, - inflate_huft *, - inflate_blocks_statef *, - z_stream *)); - - -/*+++++*/ -/* infblock.c -- interpret and process block types to last block - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* Table for deflate from PKZIP's appnote.txt. */ -local uInt border[] = { /* Order of the bit length code lengths */ - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - -/* - Notes beyond the 1.93a appnote.txt: - - 1. Distance pointers never point before the beginning of the output - stream. - 2. Distance pointers can point back across blocks, up to 32k away. - 3. There is an implied maximum of 7 bits for the bit length table and - 15 bits for the actual data. - 4. If only one code exists, then it is encoded using one bit. (Zero - would be more efficient, but perhaps a little confusing.) If two - codes exist, they are coded using one bit each (0 and 1). - 5. There is no way of sending zero distance codes--a dummy must be - sent if there are none. (History: a pre 2.0 version of PKZIP would - store blocks with no distance codes, but this was discovered to be - too harsh a criterion.) Valid only for 1.93a. 2.04c does allow - zero distance codes, which is sent as one code of zero bits in - length. - 6. There are up to 286 literal/length codes. Code 256 represents the - end-of-block. Note however that the static length tree defines - 288 codes just to fill out the Huffman codes. Codes 286 and 287 - cannot be used though, since there is no length base or extra bits - defined for them. Similarily, there are up to 30 distance codes. - However, static trees define 32 codes (all 5 bits) to fill out the - Huffman codes, but the last two had better not show up in the data. - 7. Unzip can check dynamic Huffman blocks for complete code sets. - The exception is that a single code would not be complete (see #4). - 8. The five bits following the block type is really the number of - literal codes sent minus 257. - 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits - (1+6+6). Therefore, to output three times the length, you output - three codes (1+1+1), whereas to output four times the same length, - you only need two codes (1+3). Hmm. - 10. In the tree reconstruction algorithm, Code = Code + Increment - only if BitLength(i) is not zero. (Pretty obvious.) - 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) - 12. Note: length code 284 can represent 227-258, but length code 285 - really is 258. The last length deserves its own, short code - since it gets used a lot in very redundant files. The length - 258 is special since 258 - 3 (the min match length) is 255. - 13. The literal/length and distance code bit lengths are read as a - single stream of lengths. It is possible (and advantageous) for - a repeat code (16, 17, or 18) to go across the boundary between - the two sets of lengths. - */ - - -local void inflate_blocks_reset(s, z, c) -inflate_blocks_statef *s; -z_stream *z; -uLongf *c; -{ - if (s->checkfn != Z_NULL) - *c = s->check; - if (s->mode == BTREE || s->mode == DTREE) - ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt)); - if (s->mode == CODES) - { - inflate_codes_free(s->sub.decode.codes, z); - inflate_trees_free(s->sub.decode.td, z); - inflate_trees_free(s->sub.decode.tl, z); - } - s->mode = TYPE; - s->bitk = 0; - s->bitb = 0; - s->read = s->write = s->window; - if (s->checkfn != Z_NULL) - s->check = (*s->checkfn)(0L, Z_NULL, 0); - Trace((stderr, "inflate: blocks reset\n")); -} - - -local inflate_blocks_statef *inflate_blocks_new(z, c, w) -z_stream *z; -check_func c; -uInt w; -{ - inflate_blocks_statef *s; - - if ((s = (inflate_blocks_statef *)ZALLOC - (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) - return s; - if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL) - { - ZFREE(z, s, sizeof(struct inflate_blocks_state)); - return Z_NULL; - } - s->end = s->window + w; - s->checkfn = c; - s->mode = TYPE; - Trace((stderr, "inflate: blocks allocated\n")); - inflate_blocks_reset(s, z, &s->check); - return s; -} - - -local int inflate_blocks(s, z, r) -inflate_blocks_statef *s; -z_stream *z; -int r; -{ - uInt t; /* temporary storage */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - - /* copy input/output information to locals (UPDATE macro restores) */ - LOAD - - /* process input based on current state */ - while (1) switch (s->mode) - { - case TYPE: - NEEDBITS(3) - t = (uInt)b & 7; - s->last = t & 1; - switch (t >> 1) - { - case 0: /* stored */ - Trace((stderr, "inflate: stored block%s\n", - s->last ? " (last)" : "")); - DUMPBITS(3) - t = k & 7; /* go to byte boundary */ - DUMPBITS(t) - s->mode = LENS; /* get length of stored block */ - break; - case 1: /* fixed */ - Trace((stderr, "inflate: fixed codes block%s\n", - s->last ? " (last)" : "")); - { - uInt bl, bd; - inflate_huft *tl, *td; - - inflate_trees_fixed(&bl, &bd, &tl, &td); - s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); - if (s->sub.decode.codes == Z_NULL) - { - r = Z_MEM_ERROR; - LEAVE - } - s->sub.decode.tl = Z_NULL; /* don't try to free these */ - s->sub.decode.td = Z_NULL; - } - DUMPBITS(3) - s->mode = CODES; - break; - case 2: /* dynamic */ - Trace((stderr, "inflate: dynamic codes block%s\n", - s->last ? " (last)" : "")); - DUMPBITS(3) - s->mode = TABLE; - break; - case 3: /* illegal */ - DUMPBITS(3) - s->mode = BADB; - z->msg = "invalid block type"; - r = Z_DATA_ERROR; - LEAVE - } - break; - case LENS: - NEEDBITS(32) - if (((~b) >> 16) != (b & 0xffff)) - { - s->mode = BADB; - z->msg = "invalid stored block lengths"; - r = Z_DATA_ERROR; - LEAVE - } - s->sub.left = (uInt)b & 0xffff; - b = k = 0; /* dump bits */ - Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); - s->mode = s->sub.left ? STORED : TYPE; - break; - case STORED: - if (n == 0) - LEAVE - NEEDOUT - t = s->sub.left; - if (t > n) t = n; - if (t > m) t = m; - zmemcpy(q, p, t); - p += t; n -= t; - q += t; m -= t; - if ((s->sub.left -= t) != 0) - break; - Tracev((stderr, "inflate: stored end, %lu total out\n", - z->total_out + (q >= s->read ? q - s->read : - (s->end - s->read) + (q - s->window)))); - s->mode = s->last ? DRY : TYPE; - break; - case TABLE: - NEEDBITS(14) - s->sub.trees.table = t = (uInt)b & 0x3fff; -#ifndef PKZIP_BUG_WORKAROUND - if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) - { - s->mode = BADB; - z->msg = "too many length or distance symbols"; - r = Z_DATA_ERROR; - LEAVE - } -#endif - t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); - if (t < 19) - t = 19; - if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) - { - r = Z_MEM_ERROR; - LEAVE - } - s->sub.trees.nblens = t; - DUMPBITS(14) - s->sub.trees.index = 0; - Tracev((stderr, "inflate: table sizes ok\n")); - s->mode = BTREE; - case BTREE: - while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) - { - NEEDBITS(3) - s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; - DUMPBITS(3) - } - while (s->sub.trees.index < 19) - s->sub.trees.blens[border[s->sub.trees.index++]] = 0; - s->sub.trees.bb = 7; - t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, - &s->sub.trees.tb, z); - if (t != Z_OK) - { - r = t; - if (r == Z_DATA_ERROR) - s->mode = BADB; - LEAVE - } - s->sub.trees.index = 0; - Tracev((stderr, "inflate: bits tree ok\n")); - s->mode = DTREE; - case DTREE: - while (t = s->sub.trees.table, - s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) - { - inflate_huft *h; - uInt i, j, c; - - t = s->sub.trees.bb; - NEEDBITS(t) - h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); - t = h->word.what.Bits; - c = h->more.Base; - if (c < 16) - { - DUMPBITS(t) - s->sub.trees.blens[s->sub.trees.index++] = c; - } - else /* c == 16..18 */ - { - i = c == 18 ? 7 : c - 14; - j = c == 18 ? 11 : 3; - NEEDBITS(t + i) - DUMPBITS(t) - j += (uInt)b & inflate_mask[i]; - DUMPBITS(i) - i = s->sub.trees.index; - t = s->sub.trees.table; - if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || - (c == 16 && i < 1)) - { - s->mode = BADB; - z->msg = "invalid bit length repeat"; - r = Z_DATA_ERROR; - LEAVE - } - c = c == 16 ? s->sub.trees.blens[i - 1] : 0; - do { - s->sub.trees.blens[i++] = c; - } while (--j); - s->sub.trees.index = i; - } - } - inflate_trees_free(s->sub.trees.tb, z); - s->sub.trees.tb = Z_NULL; - { - uInt bl, bd; - inflate_huft *tl, *td; - inflate_codes_statef *c; - - bl = 9; /* must be <= 9 for lookahead assumptions */ - bd = 6; /* must be <= 9 for lookahead assumptions */ - t = s->sub.trees.table; - t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), - s->sub.trees.blens, &bl, &bd, &tl, &td, z); - if (t != Z_OK) - { - if (t == (uInt)Z_DATA_ERROR) - s->mode = BADB; - r = t; - LEAVE - } - Tracev((stderr, "inflate: trees ok\n")); - if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) - { - inflate_trees_free(td, z); - inflate_trees_free(tl, z); - r = Z_MEM_ERROR; - LEAVE - } - ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt)); - s->sub.decode.codes = c; - s->sub.decode.tl = tl; - s->sub.decode.td = td; - } - s->mode = CODES; - case CODES: - UPDATE - if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) - return inflate_flush(s, z, r); - r = Z_OK; - inflate_codes_free(s->sub.decode.codes, z); - inflate_trees_free(s->sub.decode.td, z); - inflate_trees_free(s->sub.decode.tl, z); - LOAD - Tracev((stderr, "inflate: codes end, %lu total out\n", - z->total_out + (q >= s->read ? q - s->read : - (s->end - s->read) + (q - s->window)))); - if (!s->last) - { - s->mode = TYPE; - break; - } - if (k > 7) /* return unused byte, if any */ - { - Assert(k < 16, "inflate_codes grabbed too many bytes") - k -= 8; - n++; - p--; /* can always return one */ - } - s->mode = DRY; - case DRY: - FLUSH - if (s->read != s->write) - LEAVE - s->mode = DONEB; - case DONEB: - r = Z_STREAM_END; - LEAVE - case BADB: - r = Z_DATA_ERROR; - LEAVE - default: - r = Z_STREAM_ERROR; - LEAVE - } -} - - -local int inflate_blocks_free(s, z, c) -inflate_blocks_statef *s; -z_stream *z; -uLongf *c; -{ - inflate_blocks_reset(s, z, c); - ZFREE(z, s->window, s->end - s->window); - ZFREE(z, s, sizeof(struct inflate_blocks_state)); - Trace((stderr, "inflate: blocks freed\n")); - return Z_OK; -} - -/* - * This subroutine adds the data at next_in/avail_in to the output history - * without performing any output. The output buffer must be "caught up"; - * i.e. no pending output (hence s->read equals s->write), and the state must - * be BLOCKS (i.e. we should be willing to see the start of a series of - * BLOCKS). On exit, the output will also be caught up, and the checksum - * will have been updated if need be. - */ -local int inflate_addhistory(s, z) -inflate_blocks_statef *s; -z_stream *z; -{ - uLong b; /* bit buffer */ /* NOT USED HERE */ - uInt k; /* bits in bit buffer */ /* NOT USED HERE */ - uInt t; /* temporary storage */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - - if (s->read != s->write) - return Z_STREAM_ERROR; - if (s->mode != TYPE) - return Z_DATA_ERROR; - - /* we're ready to rock */ - LOAD - /* while there is input ready, copy to output buffer, moving - * pointers as needed. - */ - while (n) { - t = n; /* how many to do */ - /* is there room until end of buffer? */ - if (t > m) t = m; - /* update check information */ - if (s->checkfn != Z_NULL) - s->check = (*s->checkfn)(s->check, q, t); - zmemcpy(q, p, t); - q += t; - p += t; - n -= t; - z->total_out += t; - s->read = q; /* drag read pointer forward */ -/* WRAP */ /* expand WRAP macro by hand to handle s->read */ - if (q == s->end) { - s->read = q = s->window; - m = WAVAIL; - } - } - UPDATE - return Z_OK; -} - - -/* - * At the end of a Deflate-compressed PPP packet, we expect to have seen - * a `stored' block type value but not the (zero) length bytes. - */ -local int inflate_packet_flush(s) - inflate_blocks_statef *s; -{ - if (s->mode != LENS) - return Z_DATA_ERROR; - s->mode = TYPE; - return Z_OK; -} - - -/*+++++*/ -/* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* simplify the use of the inflate_huft type with some defines */ -#define base more.Base -#define next more.Next -#define exop word.what.Exop -#define bits word.what.Bits - - -local int huft_build OF(( - uIntf *, /* code lengths in bits */ - uInt, /* number of codes */ - uInt, /* number of "simple" codes */ - uIntf *, /* list of base values for non-simple codes */ - uIntf *, /* list of extra bits for non-simple codes */ - inflate_huft * FAR*,/* result: starting table */ - uIntf *, /* maximum lookup bits (returns actual) */ - z_stream *)); /* for zalloc function */ - -local voidpf falloc OF(( - voidpf, /* opaque pointer (not used) */ - uInt, /* number of items */ - uInt)); /* size of item */ - -local void ffree OF(( - voidpf q, /* opaque pointer (not used) */ - voidpf p, /* what to free (not used) */ - uInt n)); /* number of bytes (not used) */ - -/* Tables for deflate from PKZIP's appnote.txt. */ -local uInt cplens[] = { /* Copy lengths for literal codes 257..285 */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - /* actually lengths - 2; also see note #13 above about 258 */ -local uInt cplext[] = { /* Extra bits for literal codes 257..285 */ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 192, 192}; /* 192==invalid */ -local uInt cpdist[] = { /* Copy offsets for distance codes 0..29 */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577}; -local uInt cpdext[] = { /* Extra bits for distance codes */ - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, - 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, - 12, 12, 13, 13}; - -/* - Huffman code decoding is performed using a multi-level table lookup. - The fastest way to decode is to simply build a lookup table whose - size is determined by the longest code. However, the time it takes - to build this table can also be a factor if the data being decoded - is not very long. The most common codes are necessarily the - shortest codes, so those codes dominate the decoding time, and hence - the speed. The idea is you can have a shorter table that decodes the - shorter, more probable codes, and then point to subsidiary tables for - the longer codes. The time it costs to decode the longer codes is - then traded against the time it takes to make longer tables. - - This results of this trade are in the variables lbits and dbits - below. lbits is the number of bits the first level table for literal/ - length codes can decode in one step, and dbits is the same thing for - the distance codes. Subsequent tables are also less than or equal to - those sizes. These values may be adjusted either when all of the - codes are shorter than that, in which case the longest code length in - bits is used, or when the shortest code is *longer* than the requested - table size, in which case the length of the shortest code in bits is - used. - - There are two different values for the two tables, since they code a - different number of possibilities each. The literal/length table - codes 286 possible values, or in a flat code, a little over eight - bits. The distance table codes 30 possible values, or a little less - than five bits, flat. The optimum values for speed end up being - about one bit more than those, so lbits is 8+1 and dbits is 5+1. - The optimum values may differ though from machine to machine, and - possibly even between compilers. Your mileage may vary. - */ - - -/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ -#define BMAX 15 /* maximum bit length of any code */ -#define N_MAX 288 /* maximum number of codes in any set */ - -#ifdef DEBUG_ZLIB - uInt inflate_hufts; -#endif - -local int huft_build(b, n, s, d, e, t, m, zs) -uIntf *b; /* code lengths in bits (all assumed <= BMAX) */ -uInt n; /* number of codes (assumed <= N_MAX) */ -uInt s; /* number of simple-valued codes (0..s-1) */ -uIntf *d; /* list of base values for non-simple codes */ -uIntf *e; /* list of extra bits for non-simple codes */ -inflate_huft * FAR *t; /* result: starting table */ -uIntf *m; /* maximum lookup bits, returns actual */ -z_stream *zs; /* for zalloc function */ -/* Given a list of code lengths and a maximum table size, make a set of - tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR - if the given code set is incomplete (the tables are still built in this - case), Z_DATA_ERROR if the input is invalid (all zero length codes or an - over-subscribed set of lengths), or Z_MEM_ERROR if not enough memory. */ -{ - - uInt a; /* counter for codes of length k */ - uInt c[BMAX+1]; /* bit length count table */ - uInt f; /* i repeats in table every f entries */ - int g; /* maximum code length */ - int h; /* table level */ - register uInt i; /* counter, current code */ - register uInt j; /* counter */ - register int k; /* number of bits in current code */ - int l; /* bits per table (returned in m) */ - register uIntf *p; /* pointer into c[], b[], or v[] */ - inflate_huft *q; /* points to current table */ - struct inflate_huft_s r; /* table entry for structure assignment */ - inflate_huft *u[BMAX]; /* table stack */ - uInt v[N_MAX]; /* values in order of bit length */ - register int w; /* bits before this table == (l * h) */ - uInt x[BMAX+1]; /* bit offsets, then code stack */ - uIntf *xp; /* pointer into x */ - int y; /* number of dummy codes added */ - uInt z; /* number of entries in current table */ - - - /* Generate counts for each bit length */ - p = c; -#define C0 *p++ = 0; -#define C2 C0 C0 C0 C0 -#define C4 C2 C2 C2 C2 - C4 /* clear c[]--assume BMAX+1 is 16 */ - p = b; i = n; - do { - c[*p++]++; /* assume all entries <= BMAX */ - } while (--i); - if (c[0] == n) /* null input--all zero length codes */ - { - *t = (inflate_huft *)Z_NULL; - *m = 0; - return Z_OK; - } - - - /* Find minimum and maximum length, bound *m by those */ - l = *m; - for (j = 1; j <= BMAX; j++) - if (c[j]) - break; - k = j; /* minimum code length */ - if ((uInt)l < j) - l = j; - for (i = BMAX; i; i--) - if (c[i]) - break; - g = i; /* maximum code length */ - if ((uInt)l > i) - l = i; - *m = l; - - - /* Adjust last length count to fill out codes, if needed */ - for (y = 1 << j; j < i; j++, y <<= 1) - if ((y -= c[j]) < 0) - return Z_DATA_ERROR; - if ((y -= c[i]) < 0) - return Z_DATA_ERROR; - c[i] += y; - - - /* Generate starting offsets into the value table for each length */ - x[1] = j = 0; - p = c + 1; xp = x + 2; - while (--i) { /* note that i == g from above */ - *xp++ = (j += *p++); - } - - - /* Make a table of values in order of bit lengths */ - p = b; i = 0; - do { - if ((j = *p++) != 0) - v[x[j]++] = i; - } while (++i < n); - - - /* Generate the Huffman codes and for each, make the table entries */ - x[0] = i = 0; /* first Huffman code is zero */ - p = v; /* grab values in bit order */ - h = -1; /* no tables yet--level -1 */ - w = -l; /* bits decoded == (l * h) */ - u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ - q = (inflate_huft *)Z_NULL; /* ditto */ - z = 0; /* ditto */ - - /* go through the bit lengths (k already is bits in shortest code) */ - for (; k <= g; k++) - { - a = c[k]; - while (a--) - { - /* here i is the Huffman code of length k bits for value *p */ - /* make tables up to required level */ - while (k > w + l) - { - h++; - w += l; /* previous table always l bits */ - - /* compute minimum size table less than or equal to l bits */ - z = (z = g - w) > (uInt)l ? l : z; /* table size upper limit */ - if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ - { /* too few codes for k-w bit table */ - f -= a + 1; /* deduct codes from patterns left */ - xp = c + k; - if (j < z) - while (++j < z) /* try smaller tables up to z bits */ - { - if ((f <<= 1) <= *++xp) - break; /* enough codes to use up j bits */ - f -= *xp; /* else deduct codes from patterns */ - } - } - z = 1 << j; /* table entries for j-bit table */ - - /* allocate and link in new table */ - if ((q = (inflate_huft *)ZALLOC - (zs,z + 1,sizeof(inflate_huft))) == Z_NULL) - { - if (h) - inflate_trees_free(u[0], zs); - return Z_MEM_ERROR; /* not enough memory */ - } - q->word.Nalloc = z + 1; -#ifdef DEBUG_ZLIB - inflate_hufts += z + 1; -#endif - *t = q + 1; /* link to list for huft_free() */ - *(t = &(q->next)) = Z_NULL; - u[h] = ++q; /* table starts after link */ - - /* connect to last table, if there is one */ - if (h) - { - x[h] = i; /* save pattern for backing up */ - r.bits = (Byte)l; /* bits to dump before this table */ - r.exop = (Byte)j; /* bits in this table */ - r.next = q; /* pointer to this table */ - j = i >> (w - l); /* (get around Turbo C bug) */ - u[h-1][j] = r; /* connect to last table */ - } - } - - /* set up table entry in r */ - r.bits = (Byte)(k - w); - if (p >= v + n) - r.exop = 128 + 64; /* out of values--invalid code */ - else if (*p < s) - { - r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ - r.base = *p++; /* simple code is just the value */ - } - else - { - r.exop = (Byte)e[*p - s] + 16 + 64; /* non-simple--look up in lists */ - r.base = d[*p++ - s]; - } - - /* fill code-like entries with r */ - f = 1 << (k - w); - for (j = i >> w; j < z; j += f) - q[j] = r; - - /* backwards increment the k-bit code i */ - for (j = 1 << (k - 1); i & j; j >>= 1) - i ^= j; - i ^= j; - - /* backup over finished tables */ - while ((i & ((1 << w) - 1)) != x[h]) - { - h--; /* don't need to update q */ - w -= l; - } - } - } - - - /* Return Z_BUF_ERROR if we were given an incomplete table */ - return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; -} - - -local int inflate_trees_bits(c, bb, tb, z) -uIntf *c; /* 19 code lengths */ -uIntf *bb; /* bits tree desired/actual depth */ -inflate_huft * FAR *tb; /* bits tree result */ -z_stream *z; /* for zfree function */ -{ - int r; - - r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z); - if (r == Z_DATA_ERROR) - z->msg = "oversubscribed dynamic bit lengths tree"; - else if (r == Z_BUF_ERROR) - { - inflate_trees_free(*tb, z); - z->msg = "incomplete dynamic bit lengths tree"; - r = Z_DATA_ERROR; - } - return r; -} - - -local int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, z) -uInt nl; /* number of literal/length codes */ -uInt nd; /* number of distance codes */ -uIntf *c; /* that many (total) code lengths */ -uIntf *bl; /* literal desired/actual bit depth */ -uIntf *bd; /* distance desired/actual bit depth */ -inflate_huft * FAR *tl; /* literal/length tree result */ -inflate_huft * FAR *td; /* distance tree result */ -z_stream *z; /* for zfree function */ -{ - int r; - - /* build literal/length tree */ - if ((r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z)) != Z_OK) - { - if (r == Z_DATA_ERROR) - z->msg = "oversubscribed literal/length tree"; - else if (r == Z_BUF_ERROR) - { - inflate_trees_free(*tl, z); - z->msg = "incomplete literal/length tree"; - r = Z_DATA_ERROR; - } - return r; - } - - /* build distance tree */ - if ((r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z)) != Z_OK) - { - if (r == Z_DATA_ERROR) - z->msg = "oversubscribed literal/length tree"; - else if (r == Z_BUF_ERROR) { -#ifdef PKZIP_BUG_WORKAROUND - r = Z_OK; - } -#else - inflate_trees_free(*td, z); - z->msg = "incomplete literal/length tree"; - r = Z_DATA_ERROR; - } - inflate_trees_free(*tl, z); - return r; -#endif - } - - /* done */ - return Z_OK; -} - - -/* build fixed tables only once--keep them here */ -local int fixed_lock = 0; -local int fixed_built = 0; -#define FIXEDH 530 /* number of hufts used by fixed tables */ -local uInt fixed_left = FIXEDH; -local inflate_huft fixed_mem[FIXEDH]; -local uInt fixed_bl; -local uInt fixed_bd; -local inflate_huft *fixed_tl; -local inflate_huft *fixed_td; - - -local voidpf falloc(q, n, s) -voidpf q; /* opaque pointer (not used) */ -uInt n; /* number of items */ -uInt s; /* size of item */ -{ - Assert(s == sizeof(inflate_huft) && n <= fixed_left, - "inflate_trees falloc overflow"); - if (q) s++; /* to make some compilers happy */ - fixed_left -= n; - return (voidpf)(fixed_mem + fixed_left); -} - - -local void ffree(q, p, n) -voidpf q; -voidpf p; -uInt n; -{ - Assert(0, "inflate_trees ffree called!"); - if (q) q = p; /* to make some compilers happy */ -} - - -local int inflate_trees_fixed(bl, bd, tl, td) -uIntf *bl; /* literal desired/actual bit depth */ -uIntf *bd; /* distance desired/actual bit depth */ -inflate_huft * FAR *tl; /* literal/length tree result */ -inflate_huft * FAR *td; /* distance tree result */ -{ - /* build fixed tables if not built already--lock out other instances */ - while (++fixed_lock > 1) - fixed_lock--; - if (!fixed_built) - { - int k; /* temporary variable */ - unsigned c[288]; /* length list for huft_build */ - z_stream z; /* for falloc function */ - - /* set up fake z_stream for memory routines */ - z.zalloc = falloc; - z.zfree = ffree; - z.opaque = Z_NULL; - - /* literal table */ - for (k = 0; k < 144; k++) - c[k] = 8; - for (; k < 256; k++) - c[k] = 9; - for (; k < 280; k++) - c[k] = 7; - for (; k < 288; k++) - c[k] = 8; - fixed_bl = 7; - huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, &z); - - /* distance table */ - for (k = 0; k < 30; k++) - c[k] = 5; - fixed_bd = 5; - huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z); - - /* done */ - fixed_built = 1; - } - fixed_lock--; - *bl = fixed_bl; - *bd = fixed_bd; - *tl = fixed_tl; - *td = fixed_td; - return Z_OK; -} - - -local int inflate_trees_free(t, z) -inflate_huft *t; /* table to free */ -z_stream *z; /* for zfree function */ -/* Free the malloc'ed tables built by huft_build(), which makes a linked - list of the tables it made, with the links in a dummy first entry of - each table. */ -{ - register inflate_huft *p, *q; - - /* Go through linked list, freeing from the malloced (t[-1]) address. */ - p = t; - while (p != Z_NULL) - { - q = (--p)->next; - ZFREE(z, p, p->word.Nalloc * sizeof(inflate_huft)); - p = q; - } - return Z_OK; -} - -/*+++++*/ -/* infcodes.c -- process literals and length/distance pairs - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* simplify the use of the inflate_huft type with some defines */ -#define base more.Base -#define next more.Next -#define exop word.what.Exop -#define bits word.what.Bits - -/* inflate codes private state */ -struct inflate_codes_state { - - /* mode */ - enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ - START, /* x: set up for LEN */ - LEN, /* i: get length/literal/eob next */ - LENEXT, /* i: getting length extra (have base) */ - DIST, /* i: get distance next */ - DISTEXT, /* i: getting distance extra */ - COPY, /* o: copying bytes in window, waiting for space */ - LIT, /* o: got literal, waiting for output space */ - WASH, /* o: got eob, possibly still output waiting */ - END, /* x: got eob and all data flushed */ - BADCODE} /* x: got error */ - mode; /* current inflate_codes mode */ - - /* mode dependent information */ - uInt len; - union { - struct { - inflate_huft *tree; /* pointer into tree */ - uInt need; /* bits needed */ - } code; /* if LEN or DIST, where in tree */ - uInt lit; /* if LIT, literal */ - struct { - uInt get; /* bits to get for extra */ - uInt dist; /* distance back to copy from */ - } copy; /* if EXT or COPY, where and how much */ - } sub; /* submode */ - - /* mode independent information */ - Byte lbits; /* ltree bits decoded per branch */ - Byte dbits; /* dtree bits decoder per branch */ - inflate_huft *ltree; /* literal/length/eob tree */ - inflate_huft *dtree; /* distance tree */ - -}; - - -local inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z) -uInt bl, bd; -inflate_huft *tl, *td; -z_stream *z; -{ - inflate_codes_statef *c; - - if ((c = (inflate_codes_statef *) - ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) - { - c->mode = START; - c->lbits = (Byte)bl; - c->dbits = (Byte)bd; - c->ltree = tl; - c->dtree = td; - Tracev((stderr, "inflate: codes new\n")); - } - return c; -} - - -local int inflate_codes(s, z, r) -inflate_blocks_statef *s; -z_stream *z; -int r; -{ - uInt j; /* temporary storage */ - inflate_huft *t; /* temporary pointer */ - uInt e; /* extra bits or operation */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - Bytef *f; /* pointer to copy strings from */ - inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ - - /* copy input/output information to locals (UPDATE macro restores) */ - LOAD - - /* process input and output based on current state */ - while (1) switch (c->mode) - { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ - case START: /* x: set up for LEN */ -#ifndef SLOW - if (m >= 258 && n >= 10) - { - UPDATE - r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); - LOAD - if (r != Z_OK) - { - c->mode = r == Z_STREAM_END ? WASH : BADCODE; - break; - } - } -#endif /* !SLOW */ - c->sub.code.need = c->lbits; - c->sub.code.tree = c->ltree; - c->mode = LEN; - case LEN: /* i: get length/literal/eob next */ - j = c->sub.code.need; - NEEDBITS(j) - t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); - DUMPBITS(t->bits) - e = (uInt)(t->exop); - if (e == 0) /* literal */ - { - c->sub.lit = t->base; - Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", t->base)); - c->mode = LIT; - break; - } - if (e & 16) /* length */ - { - c->sub.copy.get = e & 15; - c->len = t->base; - c->mode = LENEXT; - break; - } - if ((e & 64) == 0) /* next table */ - { - c->sub.code.need = e; - c->sub.code.tree = t->next; - break; - } - if (e & 32) /* end of block */ - { - Tracevv((stderr, "inflate: end of block\n")); - c->mode = WASH; - break; - } - c->mode = BADCODE; /* invalid code */ - z->msg = "invalid literal/length code"; - r = Z_DATA_ERROR; - LEAVE - case LENEXT: /* i: getting length extra (have base) */ - j = c->sub.copy.get; - NEEDBITS(j) - c->len += (uInt)b & inflate_mask[j]; - DUMPBITS(j) - c->sub.code.need = c->dbits; - c->sub.code.tree = c->dtree; - Tracevv((stderr, "inflate: length %u\n", c->len)); - c->mode = DIST; - case DIST: /* i: get distance next */ - j = c->sub.code.need; - NEEDBITS(j) - t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); - DUMPBITS(t->bits) - e = (uInt)(t->exop); - if (e & 16) /* distance */ - { - c->sub.copy.get = e & 15; - c->sub.copy.dist = t->base; - c->mode = DISTEXT; - break; - } - if ((e & 64) == 0) /* next table */ - { - c->sub.code.need = e; - c->sub.code.tree = t->next; - break; - } - c->mode = BADCODE; /* invalid code */ - z->msg = "invalid distance code"; - r = Z_DATA_ERROR; - LEAVE - case DISTEXT: /* i: getting distance extra */ - j = c->sub.copy.get; - NEEDBITS(j) - c->sub.copy.dist += (uInt)b & inflate_mask[j]; - DUMPBITS(j) - Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); - c->mode = COPY; - case COPY: /* o: copying bytes in window, waiting for space */ -#ifndef __TURBOC__ /* Turbo C bug for following expression */ - f = (uInt)(q - s->window) < c->sub.copy.dist ? - s->end - (c->sub.copy.dist - (q - s->window)) : - q - c->sub.copy.dist; -#else - f = q - c->sub.copy.dist; - if ((uInt)(q - s->window) < c->sub.copy.dist) - f = s->end - (c->sub.copy.dist - (q - s->window)); -#endif - while (c->len) - { - NEEDOUT - OUTBYTE(*f++) - if (f == s->end) - f = s->window; - c->len--; - } - c->mode = START; - break; - case LIT: /* o: got literal, waiting for output space */ - NEEDOUT - OUTBYTE(c->sub.lit) - c->mode = START; - break; - case WASH: /* o: got eob, possibly more output */ - FLUSH - if (s->read != s->write) - LEAVE - c->mode = END; - case END: - r = Z_STREAM_END; - LEAVE - case BADCODE: /* x: got error */ - r = Z_DATA_ERROR; - LEAVE - default: - r = Z_STREAM_ERROR; - LEAVE - } -} - - -local void inflate_codes_free(c, z) -inflate_codes_statef *c; -z_stream *z; -{ - ZFREE(z, c, sizeof(struct inflate_codes_state)); - Tracev((stderr, "inflate: codes free\n")); -} - -/*+++++*/ -/* inflate_util.c -- data and routines common to blocks and codes - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* copy as much as possible from the sliding window to the output area */ -local int inflate_flush(s, z, r) -inflate_blocks_statef *s; -z_stream *z; -int r; -{ - uInt n; - Bytef *p, *q; - - /* local copies of source and destination pointers */ - p = z->next_out; - q = s->read; - - /* compute number of bytes to copy as far as end of window */ - n = (uInt)((q <= s->write ? s->write : s->end) - q); - if (n > z->avail_out) n = z->avail_out; - if (n && r == Z_BUF_ERROR) r = Z_OK; - - /* update counters */ - z->avail_out -= n; - z->total_out += n; - - /* update check information */ - if (s->checkfn != Z_NULL) - s->check = (*s->checkfn)(s->check, q, n); - - /* copy as far as end of window */ - zmemcpy(p, q, n); - p += n; - q += n; - - /* see if more to copy at beginning of window */ - if (q == s->end) - { - /* wrap pointers */ - q = s->window; - if (s->write == s->end) - s->write = s->window; - - /* compute bytes to copy */ - n = (uInt)(s->write - q); - if (n > z->avail_out) n = z->avail_out; - if (n && r == Z_BUF_ERROR) r = Z_OK; - - /* update counters */ - z->avail_out -= n; - z->total_out += n; - - /* update check information */ - if (s->checkfn != Z_NULL) - s->check = (*s->checkfn)(s->check, q, n); - - /* copy */ - zmemcpy(p, q, n); - p += n; - q += n; - } - - /* update pointers */ - z->next_out = p; - s->read = q; - - /* done */ - return r; -} - - -/*+++++*/ -/* inffast.c -- process literals and length/distance pairs fast - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* simplify the use of the inflate_huft type with some defines */ -#define base more.Base -#define next more.Next -#define exop word.what.Exop -#define bits word.what.Bits - -/* macros for bit input with no checking and for returning unused bytes */ -#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}} -#define UNGRAB {n+=(c=k>>3);p-=c;k&=7;} - -/* Called with number of bytes left to write in window at least 258 - (the maximum string length) and number of input bytes available - at least ten. The ten bytes are six bytes for the longest length/ - distance pair plus four bytes for overloading the bit buffer. */ - -local int inflate_fast(bl, bd, tl, td, s, z) -uInt bl, bd; -inflate_huft *tl, *td; -inflate_blocks_statef *s; -z_stream *z; -{ - inflate_huft *t; /* temporary pointer */ - uInt e; /* extra bits or operation */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - uInt ml; /* mask for literal/length tree */ - uInt md; /* mask for distance tree */ - uInt c; /* bytes to copy */ - uInt d; /* distance back to copy from */ - Bytef *r; /* copy source pointer */ - - /* load input, output, bit values */ - LOAD - - /* initialize masks */ - ml = inflate_mask[bl]; - md = inflate_mask[bd]; - - /* do until not enough input or output space for fast loop */ - do { /* assume called with m >= 258 && n >= 10 */ - /* get literal/length code */ - GRABBITS(20) /* max bits for literal/length code */ - if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) - { - DUMPBITS(t->bits) - Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? - "inflate: * literal '%c'\n" : - "inflate: * literal 0x%02x\n", t->base)); - *q++ = (Byte)t->base; - m--; - continue; - } - do { - DUMPBITS(t->bits) - if (e & 16) - { - /* get extra bits for length */ - e &= 15; - c = t->base + ((uInt)b & inflate_mask[e]); - DUMPBITS(e) - Tracevv((stderr, "inflate: * length %u\n", c)); - - /* decode distance base of block to copy */ - GRABBITS(15); /* max bits for distance code */ - e = (t = td + ((uInt)b & md))->exop; - do { - DUMPBITS(t->bits) - if (e & 16) - { - /* get extra bits to add to distance base */ - e &= 15; - GRABBITS(e) /* get extra bits (up to 13) */ - d = t->base + ((uInt)b & inflate_mask[e]); - DUMPBITS(e) - Tracevv((stderr, "inflate: * distance %u\n", d)); - - /* do the copy */ - m -= c; - if ((uInt)(q - s->window) >= d) /* offset before dest */ - { /* just copy */ - r = q - d; - *q++ = *r++; c--; /* minimum count is three, */ - *q++ = *r++; c--; /* so unroll loop a little */ - } - else /* else offset after destination */ - { - e = d - (q - s->window); /* bytes from offset to end */ - r = s->end - e; /* pointer to offset */ - if (c > e) /* if source crosses, */ - { - c -= e; /* copy to end of window */ - do { - *q++ = *r++; - } while (--e); - r = s->window; /* copy rest from start of window */ - } - } - do { /* copy all or what's left */ - *q++ = *r++; - } while (--c); - break; - } - else if ((e & 64) == 0) - e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop; - else - { - z->msg = "invalid distance code"; - UNGRAB - UPDATE - return Z_DATA_ERROR; - } - } while (1); - break; - } - if ((e & 64) == 0) - { - if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0) - { - DUMPBITS(t->bits) - Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? - "inflate: * literal '%c'\n" : - "inflate: * literal 0x%02x\n", t->base)); - *q++ = (Byte)t->base; - m--; - break; - } - } - else if (e & 32) - { - Tracevv((stderr, "inflate: * end of block\n")); - UNGRAB - UPDATE - return Z_STREAM_END; - } - else - { - z->msg = "invalid literal/length code"; - UNGRAB - UPDATE - return Z_DATA_ERROR; - } - } while (1); - } while (m >= 258 && n >= 10); - - /* not enough input or output--restore pointers and return */ - UNGRAB - UPDATE - return Z_OK; -} - - -/*+++++*/ -/* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* From: zutil.c,v 1.8 1995/05/03 17:27:12 jloup Exp */ - -char *zlib_version = ZLIB_VERSION; - -char *z_errmsg[] = { -"stream end", /* Z_STREAM_END 1 */ -"", /* Z_OK 0 */ -"file error", /* Z_ERRNO (-1) */ -"stream error", /* Z_STREAM_ERROR (-2) */ -"data error", /* Z_DATA_ERROR (-3) */ -"insufficient memory", /* Z_MEM_ERROR (-4) */ -"buffer error", /* Z_BUF_ERROR (-5) */ -""}; - - -/*+++++*/ -/* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* From: adler32.c,v 1.6 1995/05/03 17:27:08 jloup Exp */ - -#define BASE 65521L /* largest prime smaller than 65536 */ -#define NMAX 5552 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ - -#define DO1(buf) {s1 += *buf++; s2 += s1;} -#define DO2(buf) DO1(buf); DO1(buf); -#define DO4(buf) DO2(buf); DO2(buf); -#define DO8(buf) DO4(buf); DO4(buf); -#define DO16(buf) DO8(buf); DO8(buf); - -/* ========================================================================= */ -uLong adler32(adler, buf, len) - uLong adler; - Bytef *buf; - uInt len; -{ - unsigned long s1 = adler & 0xffff; - unsigned long s2 = (adler >> 16) & 0xffff; - int k; - - if (buf == Z_NULL) return 1L; - - while (len > 0) { - k = len < NMAX ? len : NMAX; - len -= k; - while (k >= 16) { - DO16(buf); - k -= 16; - } - if (k != 0) do { - DO1(buf); - } while (--k); - s1 %= BASE; - s2 %= BASE; - } - return (s2 << 16) | s1; -} diff --git a/arch/xtensa/boot/lib/zmem.c b/arch/xtensa/boot/lib/zmem.c index 7848f126d67d..d9862aa8ca25 100644 --- a/arch/xtensa/boot/lib/zmem.c +++ b/arch/xtensa/boot/lib/zmem.c @@ -1,4 +1,4 @@ -#include "zlib.h" +#include <linux/zlib.h> /* bits taken from ppc */ @@ -9,11 +9,10 @@ void exit (void) for (;;); } -void *zalloc(void *x, unsigned items, unsigned size) +void *zalloc(unsigned size) { void *p = avail_ram; - size *= items; size = (size + 7) & -8; avail_ram += size; if (avail_ram > end_avail) { @@ -24,11 +23,6 @@ void *zalloc(void *x, unsigned items, unsigned size) return p; } -void zfree(void *x, void *addr, unsigned nb) -{ -} - - #define HEAD_CRC 2 #define EXTRA_FIELD 4 #define ORIG_NAME 8 @@ -43,7 +37,6 @@ void gunzip (void *dst, int dstlen, unsigned char *src, int *lenp) int r, i, flags; /* skip header */ - i = 10; flags = src[3]; if (src[2] != DEFLATED || (flags & RESERVED) != 0) { @@ -65,9 +58,8 @@ void gunzip (void *dst, int dstlen, unsigned char *src, int *lenp) exit(); } - s.zalloc = zalloc; - s.zfree = zfree; - r = inflateInit2(&s, -MAX_WBITS); + s.workspace = zalloc(zlib_inflate_workspacesize()); + r = zlib_inflateInit2(&s, -MAX_WBITS); if (r != Z_OK) { //puts("inflateInit2 returned "); puthex(r); puts("\n"); exit(); @@ -76,12 +68,12 @@ void gunzip (void *dst, int dstlen, unsigned char *src, int *lenp) s.avail_in = *lenp - i; s.next_out = dst; s.avail_out = dstlen; - r = inflate(&s, Z_FINISH); + r = zlib_inflate(&s, Z_FINISH); if (r != Z_OK && r != Z_STREAM_END) { //puts("inflate returned "); puthex(r); puts("\n"); exit(); } *lenp = s.next_out - (unsigned char *) dst; - inflateEnd(&s); + zlib_inflateEnd(&s); } diff --git a/arch/xtensa/kernel/asm-offsets.c b/arch/xtensa/kernel/asm-offsets.c index 840cd9a1d3d2..7cd1d7f8f608 100644 --- a/arch/xtensa/kernel/asm-offsets.c +++ b/arch/xtensa/kernel/asm-offsets.c @@ -15,7 +15,6 @@ #include <asm/processor.h> #include <linux/types.h> -#include <linux/sched.h> #include <linux/stddef.h> #include <linux/thread_info.h> #include <linux/ptrace.h> diff --git a/arch/xtensa/kernel/pci.c b/arch/xtensa/kernel/pci.c index d29a81648637..09887c96e9a1 100644 --- a/arch/xtensa/kernel/pci.c +++ b/arch/xtensa/kernel/pci.c @@ -57,50 +57,6 @@ struct pci_controller** pci_ctrl_tail = &pci_ctrl_head; static int pci_bus_count; -static void pcibios_fixup_resources(struct pci_dev* dev); - -#if 0 // FIXME -struct pci_fixup pcibios_fixups[] = { - { DECLARE_PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources }, - { 0 } -}; -#endif - -void -pcibios_update_resource(struct pci_dev *dev, struct resource *root, - struct resource *res, int resource) -{ - u32 new, check, mask; - int reg; - struct pci_controller* pci_ctrl = dev->sysdata; - - new = res->start; - if (pci_ctrl && res->flags & IORESOURCE_IO) { - new -= pci_ctrl->io_space.base; - } - new |= (res->flags & PCI_REGION_FLAG_MASK); - if (resource < 6) { - reg = PCI_BASE_ADDRESS_0 + 4*resource; - } else if (resource == PCI_ROM_RESOURCE) { - res->flags |= PCI_ROM_ADDRESS_ENABLE; - reg = dev->rom_base_reg; - } else { - /* Somebody might have asked allocation of a non-standard resource */ - return; - } - - pci_write_config_dword(dev, reg, new); - pci_read_config_dword(dev, reg, &check); - mask = (new & PCI_BASE_ADDRESS_SPACE_IO) ? - PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK; - - if ((new ^ check) & mask) { - printk(KERN_ERR "PCI: Error while updating region " - "%s/%d (%08x != %08x)\n", dev->slot_name, resource, - new, check); - } -} - /* * We need to avoid collisions with `mirrored' VGA ports * and other strange ISA hardware, so we always want the @@ -125,7 +81,7 @@ pcibios_align_resource(void *data, struct resource *res, unsigned long size, if (size > 0x100) { printk(KERN_ERR "PCI: I/O Region %s/%d too large" - " (%ld bytes)\n", dev->slot_name, + " (%ld bytes)\n", pci_name(dev), dev->resource - res, size); } @@ -149,7 +105,7 @@ pcibios_enable_resources(struct pci_dev *dev, int mask) r = &dev->resource[idx]; if (!r->start && r->end) { printk (KERN_ERR "PCI: Device %s not available because " - "of resource collisions\n", dev->slot_name); + "of resource collisions\n", pci_name(dev)); return -EINVAL; } if (r->flags & IORESOURCE_IO) @@ -161,7 +117,7 @@ pcibios_enable_resources(struct pci_dev *dev, int mask) cmd |= PCI_COMMAND_MEMORY; if (cmd != old_cmd) { printk("PCI: Enabling device %s (%04x -> %04x)\n", - dev->slot_name, old_cmd, cmd); + pci_name(dev), old_cmd, cmd); pci_write_config_word(dev, PCI_COMMAND, cmd); } return 0; @@ -293,7 +249,7 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) r = &dev->resource[idx]; if (!r->start && r->end) { printk(KERN_ERR "PCI: Device %s not available because " - "of resource collisions\n", dev->slot_name); + "of resource collisions\n", pci_name(dev)); return -EINVAL; } if (r->flags & IORESOURCE_IO) @@ -303,7 +259,7 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) } if (cmd != old_cmd) { printk("PCI: Enabling device %s (%04x -> %04x)\n", - dev->slot_name, old_cmd, cmd); + pci_name(dev), old_cmd, cmd); pci_write_config_word(dev, PCI_COMMAND, cmd); } @@ -325,47 +281,6 @@ pci_controller_num(struct pci_dev *dev) #endif /* CONFIG_PROC_FS */ - -static void -pcibios_fixup_resources(struct pci_dev *dev) -{ - struct pci_controller* pci_ctrl = (struct pci_controller *)dev->sysdata; - int i; - unsigned long offset; - - if (!pci_ctrl) { - printk(KERN_ERR "No pci_ctrl for PCI dev %s!\n",dev->slot_name); - return; - } - for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { - struct resource *res = dev->resource + i; - if (!res->start || !res->flags) - continue; - if (res->end == 0xffffffff) { - DBG("PCI:%s Resource %d [%08lx-%08lx] is unassigned\n", - dev->slot_name, i, res->start, res->end); - res->end -= res->start; - res->start = 0; - continue; - } - offset = 0; - if (res->flags & IORESOURCE_IO) - offset = (unsigned long) pci_ctrl->io_space.base; - else if (res->flags & IORESOURCE_MEM) - offset = (unsigned long) pci_ctrl->mem_space.base; - - if (offset != 0) { - res->start += offset; - res->end += offset; -#ifdef DEBUG - printk("Fixup res %d (%lx) of dev %s: %lx -> %lx\n", - i, res->flags, dev->slot_name, - res->start - offset, res->start); -#endif - } - } -} - /* * Platform support for /proc/bus/pci/X/Y mmap()s, * modelled on the sparc64 implementation by Dave Miller. diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c index 9ef07a4dd2a2..2659efdd4e99 100644 --- a/arch/xtensa/kernel/ptrace.c +++ b/arch/xtensa/kernel/ptrace.c @@ -22,6 +22,7 @@ #include <linux/smp.h> #include <linux/smp_lock.h> #include <linux/security.h> +#include <linux/signal.h> #include <asm/pgtable.h> #include <asm/page.h> @@ -239,7 +240,7 @@ int sys_ptrace(long request, long pid, long addr, long data) case PTRACE_CONT: /* restart after signal. */ { ret = -EIO; - if ((unsigned long) data > _NSIG) + if (!valid_signal(data)) break; if (request == PTRACE_SYSCALL) set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); @@ -269,7 +270,7 @@ int sys_ptrace(long request, long pid, long addr, long data) case PTRACE_SINGLESTEP: ret = -EIO; - if ((unsigned long) data > _NSIG) + if (!valid_signal(data)) break; clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); child->ptrace |= PT_SINGLESTEP; diff --git a/arch/xtensa/kernel/syscalls.c b/arch/xtensa/kernel/syscalls.c index abc8ed6c7026..f20c6494c518 100644 --- a/arch/xtensa/kernel/syscalls.c +++ b/arch/xtensa/kernel/syscalls.c @@ -42,12 +42,9 @@ #include <asm/mman.h> #include <asm/shmparam.h> #include <asm/page.h> -#include <asm/ipc.h> extern void do_syscall_trace(void); typedef int (*syscall_t)(void *a0,...); -extern int (*do_syscalls)(struct pt_regs *regs, syscall_t fun, - int narg); extern syscall_t sys_call_table[]; extern unsigned char sys_narg_table[]; @@ -72,10 +69,8 @@ int sys_pipe(int __user *userfds) /* * Common code for old and new mmaps. */ - -static inline long do_mmap2(unsigned long addr, unsigned long len, - unsigned long prot, unsigned long flags, - unsigned long fd, unsigned long pgoff) +long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, + unsigned long flags, unsigned long fd, unsigned long pgoff) { int error = -EBADF; struct file * file = NULL; @@ -97,29 +92,6 @@ out: return error; } -unsigned long old_mmap(unsigned long addr, size_t len, int prot, - int flags, int fd, off_t offset) -{ - return do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); -} - -long sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot, - unsigned long flags, unsigned long fd, unsigned long pgoff) -{ - return do_mmap2(addr, len, prot, flags, fd, pgoff); -} - -int sys_fork(struct pt_regs *regs) -{ - return do_fork(SIGCHLD, regs->areg[1], regs, 0, NULL, NULL); -} - -int sys_vfork(struct pt_regs *regs) -{ - return do_fork(CLONE_VFORK|CLONE_VM|SIGCHLD, regs->areg[1], - regs, 0, NULL, NULL); -} - int sys_clone(struct pt_regs *regs) { unsigned long clone_flags; @@ -162,30 +134,6 @@ int sys_uname(struct old_utsname * name) return -EFAULT; } -int sys_olduname(struct oldold_utsname * name) -{ - int error; - - if (!name) - return -EFAULT; - if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) - return -EFAULT; - - error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN); - error -= __put_user(0,name->sysname+__OLD_UTS_LEN); - error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN); - error -= __put_user(0,name->nodename+__OLD_UTS_LEN); - error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN); - error -= __put_user(0,name->release+__OLD_UTS_LEN); - error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN); - error -= __put_user(0,name->version+__OLD_UTS_LEN); - error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN); - error -= __put_user(0,name->machine+__OLD_UTS_LEN); - - return error ? -EFAULT : 0; -} - - /* * Build the string table for the builtin "poor man's strace". */ @@ -319,100 +267,3 @@ void system_call (struct pt_regs *regs) regs->areg[2] = res; do_syscall_trace(); } - -/* - * sys_ipc() is the de-multiplexer for the SysV IPC calls.. - * - * This is really horribly ugly. - */ - -int sys_ipc (uint call, int first, int second, - int third, void __user *ptr, long fifth) -{ - int version, ret; - - version = call >> 16; /* hack for backward compatibility */ - call &= 0xffff; - ret = -ENOSYS; - - switch (call) { - case SEMOP: - ret = sys_semtimedop (first, (struct sembuf __user *)ptr, - second, NULL); - break; - - case SEMTIMEDOP: - ret = sys_semtimedop (first, (struct sembuf __user *)ptr, - second, (const struct timespec *) fifth); - break; - - case SEMGET: - ret = sys_semget (first, second, third); - break; - - case SEMCTL: { - union semun fourth; - - if (ptr && !get_user(fourth.__pad, (void *__user *) ptr)) - ret = sys_semctl (first, second, third, fourth); - break; - } - - case MSGSND: - ret = sys_msgsnd (first, (struct msgbuf __user*) ptr, - second, third); - break; - - case MSGRCV: - switch (version) { - case 0: { - struct ipc_kludge tmp; - - if (ptr && !copy_from_user(&tmp, - (struct ipc_kludge *) ptr, - sizeof (tmp))) - ret = sys_msgrcv (first, tmp.msgp, second, - tmp.msgtyp, third); - break; - } - - default: - ret = sys_msgrcv (first, (struct msgbuf __user *) ptr, - second, 0, third); - break; - } - break; - - case MSGGET: - ret = sys_msgget ((key_t) first, second); - break; - - case MSGCTL: - ret = sys_msgctl (first, second, (struct msqid_ds __user*) ptr); - break; - - case SHMAT: { - ulong raddr; - ret = do_shmat (first, (char __user *) ptr, second, &raddr); - - if (!ret) - ret = put_user (raddr, (ulong __user *) third); - - break; - } - - case SHMDT: - ret = sys_shmdt ((char __user *)ptr); - break; - - case SHMGET: - ret = sys_shmget (first, second, third); - break; - - case SHMCTL: - ret = sys_shmctl (first, second, (struct shmid_ds __user*) ptr); - break; - } - return ret; -} - diff --git a/arch/xtensa/kernel/syscalls.h b/arch/xtensa/kernel/syscalls.h index 5b3f75f50feb..216c10a31501 100644 --- a/arch/xtensa/kernel/syscalls.h +++ b/arch/xtensa/kernel/syscalls.h @@ -25,41 +25,40 @@ */ SYSCALL(0, 0) /* 00 */ - SYSCALL(sys_exit, 1) -SYSCALL(sys_fork, 0) +SYSCALL(sys_ni_syscall, 0) SYSCALL(sys_read, 3) SYSCALL(sys_write, 3) SYSCALL(sys_open, 3) /* 05 */ SYSCALL(sys_close, 1) -SYSCALL(sys_waitpid, 3) +SYSCALL(sys_ni_syscall, 3) SYSCALL(sys_creat, 2) SYSCALL(sys_link, 2) SYSCALL(sys_unlink, 1) /* 10 */ SYSCALL(sys_execve, 0) SYSCALL(sys_chdir, 1) -SYSCALL(sys_time, 1) +SYSCALL(sys_ni_syscall, 1) SYSCALL(sys_mknod, 3) SYSCALL(sys_chmod, 2) /* 15 */ SYSCALL(sys_lchown, 3) SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_stat, 2) +SYSCALL(sys_newstat, 2) SYSCALL(sys_lseek, 3) SYSCALL(sys_getpid, 0) /* 20 */ SYSCALL(sys_mount, 5) -SYSCALL(sys_oldumount, 1) +SYSCALL(sys_ni_syscall, 1) SYSCALL(sys_setuid, 1) SYSCALL(sys_getuid, 0) -SYSCALL(sys_stime, 1) /* 25 */ +SYSCALL(sys_ni_syscall, 1) /* 25 */ SYSCALL(sys_ptrace, 4) -SYSCALL(sys_alarm, 1) -SYSCALL(sys_fstat, 2) -SYSCALL(sys_pause, 0) +SYSCALL(sys_ni_syscall, 1) +SYSCALL(sys_newfstat, 2) +SYSCALL(sys_ni_syscall, 0) SYSCALL(sys_utime, 2) /* 30 */ SYSCALL(sys_ni_syscall, 0) SYSCALL(sys_ni_syscall, 0) SYSCALL(sys_access, 2) -SYSCALL(sys_nice, 1) +SYSCALL(sys_ni_syscall, 1) SYSCALL(sys_ni_syscall, 0) /* 35 */ SYSCALL(sys_sync, 0) SYSCALL(sys_kill, 2) @@ -73,7 +72,7 @@ SYSCALL(sys_ni_syscall, 0) SYSCALL(sys_brk, 1) /* 45 */ SYSCALL(sys_setgid, 1) SYSCALL(sys_getgid, 0) -SYSCALL(sys_ni_syscall, 0) /* was signal(2) */ +SYSCALL(sys_ni_syscall, 0) SYSCALL(sys_geteuid, 0) SYSCALL(sys_getegid, 0) /* 50 */ SYSCALL(sys_acct, 1) @@ -84,21 +83,21 @@ SYSCALL(sys_fcntl, 3) /* 55 */ SYSCALL(sys_ni_syscall, 2) SYSCALL(sys_setpgid, 2) SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_olduname, 1) +SYSCALL(sys_ni_syscall, 0) SYSCALL(sys_umask, 1) /* 60 */ SYSCALL(sys_chroot, 1) SYSCALL(sys_ustat, 2) SYSCALL(sys_dup2, 2) SYSCALL(sys_getppid, 0) -SYSCALL(sys_getpgrp, 0) /* 65 */ +SYSCALL(sys_ni_syscall, 0) /* 65 */ SYSCALL(sys_setsid, 0) SYSCALL(sys_sigaction, 3) -SYSCALL(sys_sgetmask, 0) -SYSCALL(sys_ssetmask, 1) +SYSCALL(sys_ni_syscall, 0) +SYSCALL(sys_ni_syscall, 1) SYSCALL(sys_setreuid, 2) /* 70 */ SYSCALL(sys_setregid, 2) SYSCALL(sys_sigsuspend, 0) -SYSCALL(sys_sigpending, 1) +SYSCALL(sys_ni_syscall, 1) SYSCALL(sys_sethostname, 2) SYSCALL(sys_setrlimit, 2) /* 75 */ SYSCALL(sys_getrlimit, 2) @@ -107,15 +106,15 @@ SYSCALL(sys_gettimeofday, 2) SYSCALL(sys_settimeofday, 2) SYSCALL(sys_getgroups, 2) /* 80 */ SYSCALL(sys_setgroups, 2) -SYSCALL(sys_ni_syscall, 0) /* old_select */ +SYSCALL(sys_ni_syscall, 0) SYSCALL(sys_symlink, 2) -SYSCALL(sys_lstat, 2) +SYSCALL(sys_newlstat, 2) SYSCALL(sys_readlink, 3) /* 85 */ SYSCALL(sys_uselib, 1) SYSCALL(sys_swapon, 2) SYSCALL(sys_reboot, 3) -SYSCALL(old_readdir, 3) -SYSCALL(old_mmap, 6) /* 90 */ +SYSCALL(sys_ni_syscall, 3) +SYSCALL(sys_ni_syscall, 6) /* 90 */ SYSCALL(sys_munmap, 2) SYSCALL(sys_truncate, 2) SYSCALL(sys_ftruncate, 2) @@ -127,7 +126,7 @@ SYSCALL(sys_ni_syscall, 0) SYSCALL(sys_statfs, 2) SYSCALL(sys_fstatfs, 2) /* 100 */ SYSCALL(sys_ni_syscall, 3) -SYSCALL(sys_socketcall, 2) +SYSCALL(sys_ni_syscall, 2) SYSCALL(sys_syslog, 3) SYSCALL(sys_setitimer, 3) SYSCALL(sys_getitimer, 2) /* 105 */ @@ -137,32 +136,32 @@ SYSCALL(sys_newfstat, 2) SYSCALL(sys_uname, 1) SYSCALL(sys_ni_syscall, 0) /* 110 */ SYSCALL(sys_vhangup, 0) -SYSCALL(sys_ni_syscall, 0) /* was sys_idle() */ +SYSCALL(sys_ni_syscall, 0) SYSCALL(sys_ni_syscall, 0) SYSCALL(sys_wait4, 4) SYSCALL(sys_swapoff, 1) /* 115 */ SYSCALL(sys_sysinfo, 1) -SYSCALL(sys_ipc, 5) /* 6 really, but glibc uses only 5) */ +SYSCALL(sys_ni_syscall, 0) SYSCALL(sys_fsync, 1) SYSCALL(sys_sigreturn, 0) SYSCALL(sys_clone, 0) /* 120 */ SYSCALL(sys_setdomainname, 2) SYSCALL(sys_newuname, 1) -SYSCALL(sys_ni_syscall, 0) /* sys_modify_ldt */ +SYSCALL(sys_ni_syscall, 0) SYSCALL(sys_adjtimex, 1) SYSCALL(sys_mprotect, 3) /* 125 */ -SYSCALL(sys_sigprocmask, 3) -SYSCALL(sys_ni_syscall, 2) /* old sys_create_module */ +SYSCALL(sys_ni_syscall, 3) +SYSCALL(sys_ni_syscall, 2) SYSCALL(sys_init_module, 2) SYSCALL(sys_delete_module, 1) -SYSCALL(sys_ni_syscall, 1) /* old sys_get_kernel_sysm */ /* 130 */ +SYSCALL(sys_ni_syscall, 1) /* 130 */ SYSCALL(sys_quotactl, 0) SYSCALL(sys_getpgid, 1) SYSCALL(sys_fchdir, 1) SYSCALL(sys_bdflush, 2) SYSCALL(sys_sysfs, 3) /* 135 */ SYSCALL(sys_personality, 1) -SYSCALL(sys_ni_syscall, 0) /* for afs_syscall */ +SYSCALL(sys_ni_syscall, 0) SYSCALL(sys_setfsuid, 1) SYSCALL(sys_setfsgid, 1) SYSCALL(sys_llseek, 5) /* 140 */ @@ -212,7 +211,7 @@ SYSCALL(sys_socket, 3) SYSCALL(sys_socketpair, 4) SYSCALL(sys_setresuid, 3) /* 185 */ SYSCALL(sys_getresuid, 3) -SYSCALL(sys_ni_syscall, 5) /* old sys_query_module */ +SYSCALL(sys_ni_syscall, 5) SYSCALL(sys_poll, 3) SYSCALL(sys_nfsservctl, 3) SYSCALL(sys_setresgid, 3) /* 190 */ @@ -235,7 +234,7 @@ SYSCALL(sys_sigaltstack, 0) SYSCALL(sys_sendfile, 4) SYSCALL(sys_ni_syscall, 0) SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_mmap2, 6) /* 210 */ +SYSCALL(sys_mmap, 6) /* 210 */ SYSCALL(sys_truncate64, 2) SYSCALL(sys_ftruncate64, 2) SYSCALL(sys_stat64, 2) @@ -245,4 +244,4 @@ SYSCALL(sys_pivot_root, 2) SYSCALL(sys_mincore, 3) SYSCALL(sys_madvise, 3) SYSCALL(sys_getdents64, 3) -SYSCALL(sys_vfork, 0) /* 220 */ +SYSCALL(sys_ni_syscall, 0) /* 220 */ diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c index 804246e743b1..225d64d73f04 100644 --- a/arch/xtensa/kernel/traps.c +++ b/arch/xtensa/kernel/traps.c @@ -29,6 +29,7 @@ #include <linux/module.h> #include <linux/stringify.h> #include <linux/kallsyms.h> +#include <linux/delay.h> #include <asm/ptrace.h> #include <asm/timex.h> @@ -488,8 +489,7 @@ void die(const char * str, struct pt_regs * regs, long err) if (panic_on_oops) { printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n"); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(5 * HZ); + ssleep(5); panic("Fatal exception"); } do_exit(err); diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S index 476b2b53cd01..5ed71dfc8110 100644 --- a/arch/xtensa/kernel/vmlinux.lds.S +++ b/arch/xtensa/kernel/vmlinux.lds.S @@ -90,10 +90,10 @@ SECTIONS *(.literal .text) *(.srom.text) VMLINUX_SYMBOL(__sched_text_start) = .; - *(.sched.text.literal .sched.text) + *(.sched.literal .sched.text) VMLINUX_SYMBOL(__sched_text_end) = .; VMLINUX_SYMBOL(__lock_text_start) = .; - *(.spinlock.text.literal .spinlock.text) + *(.spinlock.literal .spinlock.text) VMLINUX_SYMBOL(__lock_text_end) = .; } @@ -164,7 +164,7 @@ SECTIONS __init_begin = .; .init.text : { _sinittext = .; - *(.init.text.literal) *(.init.text) + *(.init.literal) *(.init.text) _einittext = .; } |