summaryrefslogtreecommitdiffstats
path: root/arch/sparc
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc')
-rw-r--r--arch/sparc/Kconfig13
-rw-r--r--arch/sparc/Kconfig.debug14
-rw-r--r--arch/sparc/Makefile2
-rw-r--r--arch/sparc/configs/sparc32_defconfig87
-rw-r--r--arch/sparc/configs/sparc64_defconfig131
-rw-r--r--arch/sparc/include/asm/asm-offsets.h1
-rw-r--r--arch/sparc/include/asm/btext.h6
-rw-r--r--arch/sparc/include/asm/cacheflush_32.h1
-rw-r--r--arch/sparc/include/asm/cacheflush_64.h1
-rw-r--r--arch/sparc/include/asm/elf_32.h2
-rw-r--r--arch/sparc/include/asm/elf_64.h14
-rw-r--r--arch/sparc/include/asm/fcntl.h19
-rw-r--r--arch/sparc/include/asm/io_32.h2
-rw-r--r--arch/sparc/include/asm/leon.h45
-rw-r--r--arch/sparc/include/asm/page_32.h2
-rw-r--r--arch/sparc/include/asm/param.h19
-rw-r--r--arch/sparc/include/asm/pci_64.h2
-rw-r--r--arch/sparc/include/asm/prom.h55
-rw-r--r--arch/sparc/include/asm/rwsem.h4
-rw-r--r--arch/sparc/include/asm/smp_32.h9
-rw-r--r--arch/sparc/include/asm/socket.h2
-rw-r--r--arch/sparc/include/asm/spinlock_32.h62
-rw-r--r--arch/sparc/include/asm/spinlock_64.h54
-rw-r--r--arch/sparc/include/asm/spinlock_types.h8
-rw-r--r--arch/sparc/include/asm/string_32.h78
-rw-r--r--arch/sparc/include/asm/string_64.h25
-rw-r--r--arch/sparc/include/asm/thread_info_64.h6
-rw-r--r--arch/sparc/include/asm/timex_32.h1
-rw-r--r--arch/sparc/include/asm/topology_64.h4
-rw-r--r--arch/sparc/include/asm/uaccess_32.h15
-rw-r--r--arch/sparc/include/asm/uaccess_64.h23
-rw-r--r--arch/sparc/include/asm/unistd.h3
-rw-r--r--arch/sparc/kernel/Makefile3
-rw-r--r--arch/sparc/kernel/apc.c37
-rw-r--r--arch/sparc/kernel/auxio_32.c1
-rw-r--r--arch/sparc/kernel/btext.c673
-rw-r--r--arch/sparc/kernel/central.c4
-rw-r--r--arch/sparc/kernel/cpu.c11
-rw-r--r--arch/sparc/kernel/entry.S35
-rw-r--r--arch/sparc/kernel/ftrace.c11
-rw-r--r--arch/sparc/kernel/head_32.S22
-rw-r--r--arch/sparc/kernel/iommu.c3
-rw-r--r--arch/sparc/kernel/ioport.c5
-rw-r--r--arch/sparc/kernel/irq_64.c57
-rw-r--r--arch/sparc/kernel/kprobes.c3
-rw-r--r--arch/sparc/kernel/ldc.c20
-rw-r--r--arch/sparc/kernel/leon_kernel.c84
-rw-r--r--arch/sparc/kernel/leon_smp.c468
-rw-r--r--arch/sparc/kernel/mdesc.c21
-rw-r--r--arch/sparc/kernel/nmi.c11
-rw-r--r--arch/sparc/kernel/of_device_64.c14
-rw-r--r--arch/sparc/kernel/pci.c8
-rw-r--r--arch/sparc/kernel/pci_msi.c2
-rw-r--r--arch/sparc/kernel/pcic.c103
-rw-r--r--arch/sparc/kernel/perf_event.c638
-rw-r--r--arch/sparc/kernel/process_64.c8
-rw-r--r--arch/sparc/kernel/ptrace_64.c10
-rw-r--r--arch/sparc/kernel/setup_64.c6
-rw-r--r--arch/sparc/kernel/smp_32.c10
-rw-r--r--arch/sparc/kernel/sparc_ksyms_64.c12
-rw-r--r--arch/sparc/kernel/sys_sparc32.c84
-rw-r--r--arch/sparc/kernel/sys_sparc_32.c64
-rw-r--r--arch/sparc/kernel/sys_sparc_64.c56
-rw-r--r--arch/sparc/kernel/syscalls.S14
-rw-r--r--arch/sparc/kernel/systbls.h1
-rw-r--r--arch/sparc/kernel/systbls_32.S6
-rw-r--r--arch/sparc/kernel/systbls_64.S10
-rw-r--r--arch/sparc/kernel/time_32.c119
-rw-r--r--arch/sparc/kernel/time_64.c26
-rw-r--r--arch/sparc/kernel/trampoline_32.S69
-rw-r--r--arch/sparc/kernel/unaligned_32.c15
-rw-r--r--arch/sparc/kernel/unaligned_64.c23
-rw-r--r--arch/sparc/kernel/visemul.c3
-rw-r--r--arch/sparc/lib/Makefile1
-rw-r--r--arch/sparc/lib/bzero.S5
-rw-r--r--arch/sparc/lib/checksum_32.S2
-rw-r--r--arch/sparc/lib/ksyms.c2
-rw-r--r--arch/sparc/lib/mcount.S5
-rw-r--r--arch/sparc/lib/memcpy.S3
-rw-r--r--arch/sparc/lib/memset.S3
-rw-r--r--arch/sparc/lib/usercopy.c8
-rw-r--r--arch/sparc/math-emu/math_32.c3
-rw-r--r--arch/sparc/math-emu/math_64.c2
-rw-r--r--arch/sparc/mm/fault_32.c12
-rw-r--r--arch/sparc/mm/fault_64.c37
-rw-r--r--arch/sparc/mm/srmmu.c9
-rw-r--r--arch/sparc/mm/sun4c.c17
87 files changed, 2525 insertions, 1064 deletions
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 05ef5380a68..4097f6a1086 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -43,6 +43,7 @@ config SPARC64
select HAVE_SYSCALL_WRAPPERS
select HAVE_DYNAMIC_FTRACE
select HAVE_FTRACE_MCOUNT_RECORD
+ select HAVE_SYSCALL_TRACEPOINTS
select USE_GENERIC_SMP_HELPERS if SMP
select RTC_DRV_CMOS
select RTC_DRV_BQ4802
@@ -63,8 +64,11 @@ config BITS
default 64 if SPARC64
config GENERIC_TIME
+ def_bool y
+
+config ARCH_USES_GETTIMEOFFSET
bool
- default y if SPARC64
+ default y if SPARC32
config GENERIC_CMOS_UPDATE
bool
@@ -221,6 +225,13 @@ config SPARC64_SMP
default y
depends on SPARC64 && SMP
+config EARLYFB
+ bool "Support for early boot text console"
+ default y
+ depends on SPARC64
+ help
+ Say Y here to enable a faster early framebuffer boot console.
+
choice
prompt "Kernel page size" if SPARC64
default SPARC64_PAGE_SIZE_8KB
diff --git a/arch/sparc/Kconfig.debug b/arch/sparc/Kconfig.debug
index 90d5fe223a7..9d3c889718a 100644
--- a/arch/sparc/Kconfig.debug
+++ b/arch/sparc/Kconfig.debug
@@ -33,4 +33,18 @@ config FRAME_POINTER
depends on MCOUNT
default y
+config DEBUG_STRICT_USER_COPY_CHECKS
+ bool "Strict copy size checks"
+ depends on DEBUG_KERNEL && !TRACE_BRANCH_PROFILING
+ ---help---
+ Enabling this option turns a certain set of sanity checks for user
+ copy operations into compile time failures.
+
+ The copy_from_user() etc checks are there to help test if there
+ are sufficient security checks on the length argument of
+ the copy operation, by having gcc prove that the argument is
+ within bounds.
+
+ If unsure, or if you run an older (pre 4.4) gcc, say N.
+
endmenu
diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile
index dfe272d1446..113225b241e 100644
--- a/arch/sparc/Makefile
+++ b/arch/sparc/Makefile
@@ -27,6 +27,7 @@ AS := $(AS) -32
LDFLAGS := -m elf32_sparc
CHECKFLAGS += -D__sparc__
export BITS := 32
+UTS_MACHINE := sparc
#KBUILD_CFLAGS += -g -pipe -fcall-used-g5 -fcall-used-g7
KBUILD_CFLAGS += -m32 -pipe -mno-fpu -fcall-used-g5 -fcall-used-g7
@@ -46,6 +47,7 @@ CHECKFLAGS += -D__sparc__ -D__sparc_v9__ -D__arch64__ -m64
LDFLAGS := -m elf64_sparc
export BITS := 64
+UTS_MACHINE := sparc64
KBUILD_CFLAGS += -m64 -pipe -mno-fpu -mcpu=ultrasparc -mcmodel=medlow \
-ffixed-g4 -ffixed-g5 -fcall-used-g7 -Wno-sign-compare \
diff --git a/arch/sparc/configs/sparc32_defconfig b/arch/sparc/configs/sparc32_defconfig
index 983d59824a2..99a1f191497 100644
--- a/arch/sparc/configs/sparc32_defconfig
+++ b/arch/sparc/configs/sparc32_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Wed Sep 16 00:03:43 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan 11 23:20:31 2010
#
# CONFIG_64BIT is not set
CONFIG_SPARC=y
@@ -41,6 +41,7 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y
#
CONFIG_TREE_RCU=y
# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
# CONFIG_RCU_TRACE is not set
CONFIG_RCU_FANOUT=32
# CONFIG_RCU_FANOUT_EXACT is not set
@@ -88,21 +89,21 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_DMA_ATTRS=y
@@ -131,14 +132,41 @@ CONFIG_LBDAF=y
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
# CONFIG_DEFAULT_DEADLINE is not set
CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
# CONFIG_FREEZER is not set
#
@@ -168,8 +196,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=1
CONFIG_BOUNCE=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_SUN_PM=y
# CONFIG_SPARC_LED is not set
@@ -257,6 +284,7 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m
CONFIG_INET6_XFRM_MODE_BEET=m
# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
CONFIG_IPV6_SIT=m
+# CONFIG_IPV6_SIT_6RD is not set
CONFIG_IPV6_NDISC_NODETYPE=y
CONFIG_IPV6_TUNNEL=m
# CONFIG_IPV6_MULTIPLE_TABLES is not set
@@ -295,9 +323,6 @@ CONFIG_NET_PKTGEN=m
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
#
@@ -335,6 +360,10 @@ CONFIG_BLK_DEV=y
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=m
CONFIG_BLK_DEV_CRYPTOLOOP=m
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_SX8 is not set
CONFIG_BLK_DEV_RAM=y
@@ -398,8 +427,11 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_CXGB3_ISCSI is not set
# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
# CONFIG_SCSI_ACARD is not set
# CONFIG_SCSI_AACRAID is not set
# CONFIG_SCSI_AIC7XXX is not set
@@ -434,7 +466,9 @@ CONFIG_SCSI_QLOGICPTI=m
# CONFIG_SCSI_DEBUG is not set
CONFIG_SCSI_SUNESP=y
# CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
@@ -450,7 +484,7 @@ CONFIG_SCSI_SUNESP=y
#
#
-# See the help texts for more information.
+# The newer stack is recommended.
#
# CONFIG_FIREWIRE is not set
# CONFIG_IEEE1394 is not set
@@ -487,6 +521,7 @@ CONFIG_SUNQE=m
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_ATL2 is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
@@ -546,6 +581,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_NETCONSOLE is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
# CONFIG_ISDN is not set
# CONFIG_PHONE is not set
@@ -555,6 +591,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
CONFIG_INPUT=y
# CONFIG_INPUT_FF_MEMLESS is not set
# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
#
# Userland interfaces
@@ -574,6 +611,7 @@ CONFIG_INPUT_KEYBOARD=y
CONFIG_KEYBOARD_ATKBD=m
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
# CONFIG_KEYBOARD_STOWAWAY is not set
CONFIG_KEYBOARD_SUNKBD=m
# CONFIG_KEYBOARD_XTKBD is not set
@@ -604,6 +642,7 @@ CONFIG_SERIO_SERPORT=m
# CONFIG_SERIO_PCIPS2 is not set
CONFIG_SERIO_LIBPS2=m
# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
# CONFIG_GAMEPORT is not set
#
@@ -636,6 +675,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_CONSOLE_POLL=y
# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
CONFIG_LEGACY_PTYS=y
@@ -661,6 +701,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_I5K_AMB is not set
# CONFIG_SENSORS_F71805F is not set
# CONFIG_SENSORS_F71882FG is not set
@@ -675,9 +720,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_VT8231 is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -699,6 +742,7 @@ CONFIG_SSB_POSSIBLE=y
#
# Graphics support
#
+CONFIG_VGA_ARB=y
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
# CONFIG_FB is not set
@@ -776,7 +820,9 @@ CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_DRV_M48T86 is not set
# CONFIG_RTC_DRV_M48T35 is not set
CONFIG_RTC_DRV_M48T59=y
+# CONFIG_RTC_DRV_MSM6242 is not set
# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
# CONFIG_RTC_DRV_V3020 is not set
#
@@ -955,6 +1001,7 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
@@ -1003,9 +1050,9 @@ CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
CONFIG_KGDB_TESTS=y
# CONFIG_KGDB_TESTS_ON_BOOT is not set
-# CONFIG_KMEMCHECK is not set
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_STACK_DEBUG is not set
+# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set
#
# Security options
@@ -1013,7 +1060,11 @@ CONFIG_KGDB_TESTS=y
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
# CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
CONFIG_CRYPTO=y
#
diff --git a/arch/sparc/configs/sparc64_defconfig b/arch/sparc/configs/sparc64_defconfig
index f80b881dfea..41c5a56aa6f 100644
--- a/arch/sparc/configs/sparc64_defconfig
+++ b/arch/sparc/configs/sparc64_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Tue Sep 15 17:06:03 2009
+# Linux kernel version: 2.6.33-rc2
+# Wed Jan 20 16:31:47 2010
#
CONFIG_64BIT=y
CONFIG_SPARC=y
@@ -20,6 +20,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
CONFIG_AUDIT_ARCH=y
CONFIG_HAVE_SETUP_PER_CPU_AREA=y
CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
+CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_MMU=y
CONFIG_ARCH_NO_VIRT_TO_BUS=y
@@ -50,6 +51,7 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y
#
CONFIG_TREE_RCU=y
# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
# CONFIG_RCU_TRACE is not set
CONFIG_RCU_FANOUT=64
# CONFIG_RCU_FANOUT_EXACT is not set
@@ -62,8 +64,7 @@ CONFIG_RT_GROUP_SCHED=y
CONFIG_USER_SCHED=y
# CONFIG_CGROUP_SCHED is not set
# CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
CONFIG_RELAY=y
CONFIG_NAMESPACES=y
# CONFIG_UTS_NS is not set
@@ -97,24 +98,25 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
-CONFIG_PERF_COUNTERS=y
+CONFIG_PERF_EVENTS=y
CONFIG_EVENT_PROFILE=y
+CONFIG_PERF_COUNTERS=y
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_COMPAT_BRK is not set
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_PROFILING=y
CONFIG_TRACEPOINTS=y
-CONFIG_MARKERS=y
CONFIG_OPROFILE=m
CONFIG_HAVE_OPROFILE=y
CONFIG_KPROBES=y
@@ -152,14 +154,41 @@ CONFIG_BLOCK_COMPAT=y
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+CONFIG_MUTEX_SPIN_ON_OWNER=y
# CONFIG_FREEZER is not set
#
@@ -179,6 +208,7 @@ CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_SPARC64_SMP=y
+CONFIG_EARLYFB=y
CONFIG_SPARC64_PAGE_SIZE_8KB=y
# CONFIG_SPARC64_PAGE_SIZE_64KB is not set
CONFIG_SECCOMP=y
@@ -216,8 +246,7 @@ CONFIG_MIGRATION=y
CONFIG_PHYS_ADDR_T_64BIT=y
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=1
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=8192
CONFIG_SCHED_SMT=y
CONFIG_SCHED_MC=y
@@ -315,6 +344,7 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m
CONFIG_INET6_XFRM_MODE_BEET=m
# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
CONFIG_IPV6_SIT=m
+# CONFIG_IPV6_SIT_6RD is not set
CONFIG_IPV6_NDISC_NODETYPE=y
CONFIG_IPV6_TUNNEL=m
# CONFIG_IPV6_MULTIPLE_TABLES is not set
@@ -356,9 +386,6 @@ CONFIG_NET_TCPPROBE=m
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
#
@@ -376,6 +403,7 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
CONFIG_FW_LOADER=y
@@ -397,6 +425,11 @@ CONFIG_BLK_DEV=y
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=m
CONFIG_BLK_DEV_CRYPTOLOOP=m
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_DRBD is not set
CONFIG_BLK_DEV_NBD=m
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_UB is not set
@@ -408,6 +441,7 @@ CONFIG_ATA_OVER_ETH=m
CONFIG_SUNVDC=m
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
# CONFIG_PHANTOM is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
@@ -415,6 +449,7 @@ CONFIG_MISC_DEVICES=y
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_HP_ILO is not set
# CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
# CONFIG_C2PORT is not set
#
@@ -522,8 +557,11 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_CXGB3_ISCSI is not set
# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
# CONFIG_SCSI_ACARD is not set
# CONFIG_SCSI_AACRAID is not set
# CONFIG_SCSI_AIC7XXX is not set
@@ -557,7 +595,9 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_SUNESP is not set
# CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
@@ -568,7 +608,9 @@ CONFIG_MD_RAID0=m
CONFIG_MD_RAID1=m
CONFIG_MD_RAID10=m
CONFIG_MD_RAID456=m
+# CONFIG_MULTICORE_RAID456 is not set
CONFIG_MD_RAID6_PQ=m
+# CONFIG_ASYNC_RAID6_TEST is not set
CONFIG_MD_MULTIPATH=m
# CONFIG_MD_FAULTY is not set
CONFIG_BLK_DEV_DM=m
@@ -592,7 +634,7 @@ CONFIG_DM_ZERO=m
#
#
-# See the help texts for more information.
+# The newer stack is recommended.
#
# CONFIG_FIREWIRE is not set
# CONFIG_IEEE1394 is not set
@@ -664,6 +706,7 @@ CONFIG_NET_PCI=y
# CONFIG_SUNDANCE is not set
# CONFIG_TLAN is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_VIA_RHINE is not set
# CONFIG_SC92031 is not set
# CONFIG_ATL2 is not set
@@ -745,6 +788,7 @@ CONFIG_SLHC=m
# CONFIG_NETCONSOLE is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
# CONFIG_ISDN is not set
# CONFIG_PHONE is not set
@@ -754,6 +798,7 @@ CONFIG_SLHC=m
CONFIG_INPUT=y
# CONFIG_INPUT_FF_MEMLESS is not set
# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
#
# Userland interfaces
@@ -770,9 +815,13 @@ CONFIG_INPUT_EVDEV=y
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_QT2160 is not set
CONFIG_KEYBOARD_LKKBD=m
+# CONFIG_KEYBOARD_MAX7359 is not set
# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
# CONFIG_KEYBOARD_STOWAWAY is not set
CONFIG_KEYBOARD_SUNKBD=y
# CONFIG_KEYBOARD_XTKBD is not set
@@ -812,6 +861,7 @@ CONFIG_SERIO_I8042=y
CONFIG_SERIO_PCIPS2=m
CONFIG_SERIO_LIBPS2=y
CONFIG_SERIO_RAW=m
+# CONFIG_SERIO_ALTERA_PS2 is not set
# CONFIG_GAMEPORT is not set
#
@@ -844,6 +894,7 @@ CONFIG_SERIAL_SUNHV=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
# CONFIG_LEGACY_PTYS is not set
@@ -858,6 +909,7 @@ CONFIG_HW_RANDOM_N2RNG=m
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
# CONFIG_I2C_CHARDEV is not set
CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_ALGOBIT=y
@@ -898,11 +950,6 @@ CONFIG_I2C_ALGOBIT=y
# CONFIG_I2C_TINY_USB is not set
#
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
# Other I2C/SMBus bus drivers
#
# CONFIG_I2C_PCA_PLATFORM is not set
@@ -911,10 +958,6 @@ CONFIG_I2C_ALGOBIT=y
#
# Miscellaneous I2C Chip support
#
-# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -932,6 +975,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
@@ -955,6 +1003,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_GL520SM is not set
# CONFIG_SENSORS_IT87 is not set
# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
# CONFIG_SENSORS_LM75 is not set
# CONFIG_SENSORS_LM77 is not set
# CONFIG_SENSORS_LM78 is not set
@@ -981,6 +1030,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
@@ -993,9 +1043,8 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
# CONFIG_SENSORS_ULTRA45 is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -1013,16 +1062,20 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_TWL4030_CORE is not set
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
#
# Graphics support
#
+CONFIG_VGA_ARB=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1176,6 +1229,7 @@ CONFIG_SND_ALI5451=m
# CONFIG_SND_OXYGEN is not set
# CONFIG_SND_CS4281 is not set
# CONFIG_SND_CS46XX is not set
+# CONFIG_SND_CS5535AUDIO is not set
# CONFIG_SND_CTXFI is not set
# CONFIG_SND_DARLA20 is not set
# CONFIG_SND_GINA20 is not set
@@ -1311,6 +1365,7 @@ CONFIG_USB_EHCI_HCD=m
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
CONFIG_USB_OHCI_HCD=y
# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
@@ -1426,6 +1481,7 @@ CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_DRV_PCF8563 is not set
# CONFIG_RTC_DRV_PCF8583 is not set
# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
# CONFIG_RTC_DRV_S35390A is not set
# CONFIG_RTC_DRV_FM3130 is not set
# CONFIG_RTC_DRV_RX8581 is not set
@@ -1447,7 +1503,9 @@ CONFIG_RTC_DRV_CMOS=y
# CONFIG_RTC_DRV_M48T86 is not set
# CONFIG_RTC_DRV_M48T35 is not set
CONFIG_RTC_DRV_M48T59=y
+# CONFIG_RTC_DRV_MSM6242 is not set
CONFIG_RTC_DRV_BQ4802=y
+# CONFIG_RTC_DRV_RP5C01 is not set
# CONFIG_RTC_DRV_V3020 is not set
#
@@ -1625,6 +1683,7 @@ CONFIG_PRINTK_TIME=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=2048
CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
@@ -1678,9 +1737,11 @@ CONFIG_NOP_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_RING_BUFFER=y
CONFIG_EVENT_TRACING=y
CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=y
CONFIG_TRACING=y
CONFIG_GENERIC_TRACER=y
CONFIG_TRACING_SUPPORT=y
@@ -1688,6 +1749,7 @@ CONFIG_FTRACE=y
# CONFIG_FUNCTION_TRACER is not set
# CONFIG_IRQSOFF_TRACER is not set
# CONFIG_SCHED_TRACER is not set
+# CONFIG_FTRACE_SYSCALLS is not set
# CONFIG_BOOT_TRACER is not set
CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
@@ -1706,6 +1768,7 @@ CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_DEBUG_DCFLUSH is not set
# CONFIG_STACK_DEBUG is not set
+# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set
#
# Security options
@@ -1714,11 +1777,17 @@ CONFIG_KEYS=y
# CONFIG_KEYS_DEBUG_PROC_KEYS is not set
# CONFIG_SECURITY is not set
# CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
CONFIG_XOR_BLOCKS=m
CONFIG_ASYNC_CORE=m
CONFIG_ASYNC_MEMCPY=m
CONFIG_ASYNC_XOR=m
+CONFIG_ASYNC_PQ=m
+CONFIG_ASYNC_RAID6_RECOV=m
CONFIG_CRYPTO=y
#
diff --git a/arch/sparc/include/asm/asm-offsets.h b/arch/sparc/include/asm/asm-offsets.h
new file mode 100644
index 00000000000..d370ee36a18
--- /dev/null
+++ b/arch/sparc/include/asm/asm-offsets.h
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff --git a/arch/sparc/include/asm/btext.h b/arch/sparc/include/asm/btext.h
new file mode 100644
index 00000000000..9b2bc6b6ed0
--- /dev/null
+++ b/arch/sparc/include/asm/btext.h
@@ -0,0 +1,6 @@
+#ifndef _SPARC_BTEXT_H
+#define _SPARC_BTEXT_H
+
+extern int btext_find_display(void);
+
+#endif /* _SPARC_BTEXT_H */
diff --git a/arch/sparc/include/asm/cacheflush_32.h b/arch/sparc/include/asm/cacheflush_32.h
index 68ac1091027..2e468773f25 100644
--- a/arch/sparc/include/asm/cacheflush_32.h
+++ b/arch/sparc/include/asm/cacheflush_32.h
@@ -75,6 +75,7 @@ BTFIXUPDEF_CALL(void, flush_sig_insns, struct mm_struct *, unsigned long)
extern void sparc_flush_page_to_ram(struct page *page);
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
#define flush_dcache_page(page) sparc_flush_page_to_ram(page)
#define flush_dcache_mmap_lock(mapping) do { } while (0)
#define flush_dcache_mmap_unlock(mapping) do { } while (0)
diff --git a/arch/sparc/include/asm/cacheflush_64.h b/arch/sparc/include/asm/cacheflush_64.h
index c43321729b3..b95384033e8 100644
--- a/arch/sparc/include/asm/cacheflush_64.h
+++ b/arch/sparc/include/asm/cacheflush_64.h
@@ -37,6 +37,7 @@ extern void flush_dcache_page_all(struct mm_struct *mm, struct page *page);
#endif
extern void __flush_dcache_range(unsigned long start, unsigned long end);
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
extern void flush_dcache_page(struct page *page);
#define flush_icache_page(vma, pg) do { } while(0)
diff --git a/arch/sparc/include/asm/elf_32.h b/arch/sparc/include/asm/elf_32.h
index 381a1b5256d..4269ca6ad18 100644
--- a/arch/sparc/include/asm/elf_32.h
+++ b/arch/sparc/include/asm/elf_32.h
@@ -104,8 +104,6 @@ typedef struct {
#define ELF_CLASS ELFCLASS32
#define ELF_DATA ELFDATA2MSB
-#define USE_ELF_CORE_DUMP
-
#define ELF_EXEC_PAGESIZE 4096
diff --git a/arch/sparc/include/asm/elf_64.h b/arch/sparc/include/asm/elf_64.h
index d42e393078c..e67880381b8 100644
--- a/arch/sparc/include/asm/elf_64.h
+++ b/arch/sparc/include/asm/elf_64.h
@@ -152,7 +152,6 @@ typedef struct {
(x)->e_machine == EM_SPARC32PLUS)
#define compat_start_thread start_thread32
-#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE PAGE_SIZE
/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
@@ -196,17 +195,10 @@ static inline unsigned int sparc64_elf_hwcap(void)
#define ELF_PLATFORM (NULL)
#define SET_PERSONALITY(ex) \
-do { unsigned long new_flags = current_thread_info()->flags; \
- new_flags &= _TIF_32BIT; \
- if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
- new_flags |= _TIF_32BIT; \
+do { if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
+ set_thread_flag(TIF_32BIT); \
else \
- new_flags &= ~_TIF_32BIT; \
- if ((current_thread_info()->flags & _TIF_32BIT) \
- != new_flags) \
- set_thread_flag(TIF_ABI_PENDING); \
- else \
- clear_thread_flag(TIF_ABI_PENDING); \
+ clear_thread_flag(TIF_32BIT); \
/* flush_thread will update pgd cache */ \
if (personality(current->personality) != PER_LINUX32) \
set_personality(PER_LINUX | \
diff --git a/arch/sparc/include/asm/fcntl.h b/arch/sparc/include/asm/fcntl.h
index d4d9c9d852c..38f37b333cc 100644
--- a/arch/sparc/include/asm/fcntl.h
+++ b/arch/sparc/include/asm/fcntl.h
@@ -1,14 +1,12 @@
#ifndef _SPARC_FCNTL_H
#define _SPARC_FCNTL_H
-/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
- located on an ext2 file system */
#define O_APPEND 0x0008
#define FASYNC 0x0040 /* fcntl, for BSD compatibility */
#define O_CREAT 0x0200 /* not fcntl */
#define O_TRUNC 0x0400 /* not fcntl */
#define O_EXCL 0x0800 /* not fcntl */
-#define O_SYNC 0x2000
+#define O_DSYNC 0x2000 /* used to be O_SYNC, see below */
#define O_NONBLOCK 0x4000
#if defined(__sparc__) && defined(__arch64__)
#define O_NDELAY 0x0004
@@ -20,6 +18,21 @@
#define O_DIRECT 0x100000 /* direct disk access hint */
#define O_NOATIME 0x200000
#define O_CLOEXEC 0x400000
+/*
+ * Before Linux 2.6.33 only O_DSYNC semantics were implemented, but using
+ * the O_SYNC flag. We continue to use the existing numerical value
+ * for O_DSYNC semantics now, but using the correct symbolic name for it.
+ * This new value is used to request true Posix O_SYNC semantics. It is
+ * defined in this strange way to make sure applications compiled against
+ * new headers get at least O_DSYNC semantics on older kernels.
+ *
+ * This has the nice side-effect that we can simply test for O_DSYNC
+ * wherever we do not care if O_DSYNC or O_SYNC is used.
+ *
+ * Note: __O_SYNC must never be used directly.
+ */
+#define __O_SYNC 0x800000
+#define O_SYNC (__O_SYNC|O_DSYNC)
#define F_GETOWN 5 /* for sockets. */
#define F_SETOWN 6 /* for sockets. */
diff --git a/arch/sparc/include/asm/io_32.h b/arch/sparc/include/asm/io_32.h
index 93fe21e02c8..679c7504625 100644
--- a/arch/sparc/include/asm/io_32.h
+++ b/arch/sparc/include/asm/io_32.h
@@ -8,7 +8,7 @@
#include <asm/page.h> /* IO address mapping routines need this */
#include <asm/system.h>
-#define page_to_phys(page) (((page) - mem_map) << PAGE_SHIFT)
+#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
static inline u32 flip_dword (u32 l)
{
diff --git a/arch/sparc/include/asm/leon.h b/arch/sparc/include/asm/leon.h
index 28a42b73f64..3ea5964c43b 100644
--- a/arch/sparc/include/asm/leon.h
+++ b/arch/sparc/include/asm/leon.h
@@ -148,7 +148,7 @@ static inline unsigned long leon_load_reg(unsigned long paddr)
return retval;
}
-extern inline void leon_srmmu_disabletlb(void)
+static inline void leon_srmmu_disabletlb(void)
{
unsigned int retval;
__asm__ __volatile__("lda [%%g0] %2, %0\n\t" : "=r"(retval) : "r"(0),
@@ -158,7 +158,7 @@ extern inline void leon_srmmu_disabletlb(void)
"i"(ASI_LEON_MMUREGS) : "memory");
}
-extern inline void leon_srmmu_enabletlb(void)
+static inline void leon_srmmu_enabletlb(void)
{
unsigned int retval;
__asm__ __volatile__("lda [%%g0] %2, %0\n\t" : "=r"(retval) : "r"(0),
@@ -190,7 +190,7 @@ extern void leon_init_IRQ(void);
extern unsigned long last_valid_pfn;
-extern inline unsigned long sparc_leon3_get_dcachecfg(void)
+static inline unsigned long sparc_leon3_get_dcachecfg(void)
{
unsigned int retval;
__asm__ __volatile__("lda [%1] %2, %0\n\t" :
@@ -201,7 +201,7 @@ extern inline unsigned long sparc_leon3_get_dcachecfg(void)
}
/* enable snooping */
-extern inline void sparc_leon3_enable_snooping(void)
+static inline void sparc_leon3_enable_snooping(void)
{
__asm__ __volatile__ ("lda [%%g0] 2, %%l1\n\t"
"set 0x800000, %%l2\n\t"
@@ -209,7 +209,14 @@ extern inline void sparc_leon3_enable_snooping(void)
"sta %%l2, [%%g0] 2\n\t" : : : "l1", "l2");
};
-extern inline void sparc_leon3_disable_cache(void)
+static inline int sparc_leon3_snooping_enabled(void)
+{
+ u32 cctrl;
+ __asm__ __volatile__("lda [%%g0] 2, %0\n\t" : "=r"(cctrl));
+ return (cctrl >> 23) & 1;
+};
+
+static inline void sparc_leon3_disable_cache(void)
{
__asm__ __volatile__ ("lda [%%g0] 2, %%l1\n\t"
"set 0x00000f, %%l2\n\t"
@@ -340,6 +347,30 @@ extern int leon_flush_needed(void);
extern void leon_switch_mm(void);
extern int srmmu_swprobe_trace;
+#ifdef CONFIG_SMP
+extern int leon_smp_nrcpus(void);
+extern void leon_clear_profile_irq(int cpu);
+extern void leon_smp_done(void);
+extern void leon_boot_cpus(void);
+extern int leon_boot_one_cpu(int i);
+void leon_init_smp(void);
+extern void cpu_probe(void);
+extern void cpu_idle(void);
+extern void init_IRQ(void);
+extern void cpu_panic(void);
+extern int __leon_processor_id(void);
+void leon_enable_irq_cpu(unsigned int irq_nr, unsigned int cpu);
+
+extern unsigned int real_irq_entry[], smpleon_ticker[];
+extern unsigned int patchme_maybe_smp_msg[];
+extern unsigned long trapbase_cpu1[];
+extern unsigned long trapbase_cpu2[];
+extern unsigned long trapbase_cpu3[];
+extern unsigned int t_nmi[], linux_trap_ipi15_leon[];
+extern unsigned int linux_trap_ipi15_sun4m[];
+
+#endif /* CONFIG_SMP */
+
#endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */
@@ -356,6 +387,10 @@ extern int srmmu_swprobe_trace;
#define leon_switch_mm() do {} while (0)
#define leon_init_IRQ() do {} while (0)
#define init_leon() do {} while (0)
+#define leon_smp_done() do {} while (0)
+#define leon_boot_cpus() do {} while (0)
+#define leon_boot_one_cpu(i) 1
+#define leon_init_smp() do {} while (0)
#endif /* !defined(CONFIG_SPARC_LEON) */
diff --git a/arch/sparc/include/asm/page_32.h b/arch/sparc/include/asm/page_32.h
index f72080bdda9..156707b0f18 100644
--- a/arch/sparc/include/asm/page_32.h
+++ b/arch/sparc/include/asm/page_32.h
@@ -143,7 +143,7 @@ extern unsigned long pfn_base;
#define phys_to_virt __va
#define ARCH_PFN_OFFSET (pfn_base)
-#define virt_to_page(kaddr) (mem_map + ((((unsigned long)(kaddr)-PAGE_OFFSET)>>PAGE_SHIFT)))
+#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
#define pfn_valid(pfn) (((pfn) >= (pfn_base)) && (((pfn)-(pfn_base)) < max_mapnr))
#define virt_addr_valid(kaddr) ((((unsigned long)(kaddr)-PAGE_OFFSET)>>PAGE_SHIFT) < max_mapnr)
diff --git a/arch/sparc/include/asm/param.h b/arch/sparc/include/asm/param.h
index 9836d9a3cb9..0bc356bf8c5 100644
--- a/arch/sparc/include/asm/param.h
+++ b/arch/sparc/include/asm/param.h
@@ -1,22 +1,7 @@
#ifndef _ASMSPARC_PARAM_H
#define _ASMSPARC_PARAM_H
-#ifdef __KERNEL__
-# define HZ CONFIG_HZ /* Internal kernel timer frequency */
-# define USER_HZ 100 /* .. some user interfaces are in "ticks" */
-# define CLOCKS_PER_SEC (USER_HZ)
-#endif
-
-#ifndef HZ
-#define HZ 100
-#endif
-
#define EXEC_PAGESIZE 8192 /* Thanks for sun4's we carry baggage... */
+#include <asm-generic/param.h>
-#ifndef NOGROUP
-#define NOGROUP (-1)
-#endif
-
-#define MAXHOSTNAMELEN 64 /* max length of hostname */
-
-#endif
+#endif /* _ASMSPARC_PARAM_H */
diff --git a/arch/sparc/include/asm/pci_64.h b/arch/sparc/include/asm/pci_64.h
index b63e51c3c3e..b0576df6ec8 100644
--- a/arch/sparc/include/asm/pci_64.h
+++ b/arch/sparc/include/asm/pci_64.h
@@ -16,8 +16,6 @@
#define PCI_IRQ_NONE 0xffffffff
-#define PCI_CACHE_LINE_BYTES 64
-
static inline void pcibios_set_master(struct pci_dev *dev)
{
/* No special bus mastering setup handling */
diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h
index 82a190d7efc..f845828ca4c 100644
--- a/arch/sparc/include/asm/prom.h
+++ b/arch/sparc/include/asm/prom.h
@@ -1,3 +1,4 @@
+#include <linux/of.h> /* linux/of.h gets to determine #include ordering */
#ifndef _SPARC_PROM_H
#define _SPARC_PROM_H
#ifdef __KERNEL__
@@ -28,50 +29,11 @@
#define of_prop_cmp(s1, s2) strcasecmp((s1), (s2))
#define of_node_cmp(s1, s2) strcmp((s1), (s2))
-typedef u32 phandle;
-typedef u32 ihandle;
-
-struct property {
- char *name;
- int length;
- void *value;
- struct property *next;
- unsigned long _flags;
- unsigned int unique_id;
-};
-
-struct of_irq_controller;
-struct device_node {
- const char *name;
- const char *type;
- phandle node;
- char *path_component_name;
- char *full_name;
-
- struct property *properties;
- struct property *deadprops; /* removed properties */
- struct device_node *parent;
- struct device_node *child;
- struct device_node *sibling;
- struct device_node *next; /* next device of same type */
- struct device_node *allnext; /* next in list of all nodes */
- struct proc_dir_entry *pde; /* this node's proc directory */
- struct kref kref;
- unsigned long _flags;
- void *data;
- unsigned int unique_id;
-
- struct of_irq_controller *irq_trans;
-};
-
struct of_irq_controller {
unsigned int (*irq_build)(struct device_node *, unsigned int, void *);
void *data;
};
-#define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags)
-#define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags)
-
extern struct device_node *of_find_node_by_cpuid(int cpuid);
extern int of_set_property(struct device_node *node, const char *name, void *val, int len);
extern struct mutex of_set_property_mutex;
@@ -89,15 +51,6 @@ extern void prom_build_devicetree(void);
extern void of_populate_present_mask(void);
extern void of_fill_in_cpu_data(void);
-/* Dummy ref counting routines - to be implemented later */
-static inline struct device_node *of_node_get(struct device_node *node)
-{
- return node;
-}
-static inline void of_node_put(struct device_node *node)
-{
-}
-
/* These routines are here to provide compatibility with how powerpc
* handles IRQ mapping for OF device nodes. We precompute and permanently
* register them in the of_device objects, whereas powerpc computes them
@@ -108,12 +61,6 @@ static inline void irq_dispose_mapping(unsigned int virq)
{
}
-/*
- * NB: This is here while we transition from using asm/prom.h
- * to linux/of.h
- */
-#include <linux/of.h>
-
extern struct device_node *of_console_device;
extern char *of_console_path;
extern char *of_console_options;
diff --git a/arch/sparc/include/asm/rwsem.h b/arch/sparc/include/asm/rwsem.h
index 1dc129ac2fe..6e5621006f8 100644
--- a/arch/sparc/include/asm/rwsem.h
+++ b/arch/sparc/include/asm/rwsem.h
@@ -35,8 +35,8 @@ struct rw_semaphore {
#endif
#define __RWSEM_INITIALIZER(name) \
-{ RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, LIST_HEAD_INIT((name).wait_list) \
- __RWSEM_DEP_MAP_INIT(name) }
+{ RWSEM_UNLOCKED_VALUE, __SPIN_LOCK_UNLOCKED((name).wait_lock), \
+ LIST_HEAD_INIT((name).wait_list) __RWSEM_DEP_MAP_INIT(name) }
#define DECLARE_RWSEM(name) \
struct rw_semaphore name = __RWSEM_INITIALIZER(name)
diff --git a/arch/sparc/include/asm/smp_32.h b/arch/sparc/include/asm/smp_32.h
index 58101dc7049..841905c1021 100644
--- a/arch/sparc/include/asm/smp_32.h
+++ b/arch/sparc/include/asm/smp_32.h
@@ -106,6 +106,15 @@ static inline int hard_smp4d_processor_id(void)
return cpuid;
}
+extern inline int hard_smpleon_processor_id(void)
+{
+ int cpuid;
+ __asm__ __volatile__("rd %%asr17,%0\n\t"
+ "srl %0,28,%0" :
+ "=&r" (cpuid) : );
+ return cpuid;
+}
+
#ifndef MODULE
static inline int hard_smp_processor_id(void)
{
diff --git a/arch/sparc/include/asm/socket.h b/arch/sparc/include/asm/socket.h
index 3a5ae3d1208..9d3fefcff2f 100644
--- a/arch/sparc/include/asm/socket.h
+++ b/arch/sparc/include/asm/socket.h
@@ -56,6 +56,8 @@
#define SO_TIMESTAMPING 0x0023
#define SCM_TIMESTAMPING SO_TIMESTAMPING
+#define SO_RXQ_OVFL 0x0024
+
/* Security levels - as per NRL IPv6 - don't actually do anything */
#define SO_SECURITY_AUTHENTICATION 0x5001
#define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002
diff --git a/arch/sparc/include/asm/spinlock_32.h b/arch/sparc/include/asm/spinlock_32.h
index 857630cff63..7f9b9dba38a 100644
--- a/arch/sparc/include/asm/spinlock_32.h
+++ b/arch/sparc/include/asm/spinlock_32.h
@@ -10,12 +10,12 @@
#include <asm/psr.h>
-#define __raw_spin_is_locked(lock) (*((volatile unsigned char *)(lock)) != 0)
+#define arch_spin_is_locked(lock) (*((volatile unsigned char *)(lock)) != 0)
-#define __raw_spin_unlock_wait(lock) \
- do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0)
+#define arch_spin_unlock_wait(lock) \
+ do { while (arch_spin_is_locked(lock)) cpu_relax(); } while (0)
-static inline void __raw_spin_lock(raw_spinlock_t *lock)
+static inline void arch_spin_lock(arch_spinlock_t *lock)
{
__asm__ __volatile__(
"\n1:\n\t"
@@ -35,7 +35,7 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock)
: "g2", "memory", "cc");
}
-static inline int __raw_spin_trylock(raw_spinlock_t *lock)
+static inline int arch_spin_trylock(arch_spinlock_t *lock)
{
unsigned int result;
__asm__ __volatile__("ldstub [%1], %0"
@@ -45,7 +45,7 @@ static inline int __raw_spin_trylock(raw_spinlock_t *lock)
return (result == 0);
}
-static inline void __raw_spin_unlock(raw_spinlock_t *lock)
+static inline void arch_spin_unlock(arch_spinlock_t *lock)
{
__asm__ __volatile__("stb %%g0, [%0]" : : "r" (lock) : "memory");
}
@@ -65,7 +65,7 @@ static inline void __raw_spin_unlock(raw_spinlock_t *lock)
* Sort of like atomic_t's on Sparc, but even more clever.
*
* ------------------------------------
- * | 24-bit counter | wlock | raw_rwlock_t
+ * | 24-bit counter | wlock | arch_rwlock_t
* ------------------------------------
* 31 8 7 0
*
@@ -76,9 +76,9 @@ static inline void __raw_spin_unlock(raw_spinlock_t *lock)
*
* Unfortunately this scheme limits us to ~16,000,000 cpus.
*/
-static inline void arch_read_lock(raw_rwlock_t *rw)
+static inline void __arch_read_lock(arch_rwlock_t *rw)
{
- register raw_rwlock_t *lp asm("g1");
+ register arch_rwlock_t *lp asm("g1");
lp = rw;
__asm__ __volatile__(
"mov %%o7, %%g4\n\t"
@@ -89,16 +89,16 @@ static inline void arch_read_lock(raw_rwlock_t *rw)
: "g2", "g4", "memory", "cc");
}
-#define __raw_read_lock(lock) \
+#define arch_read_lock(lock) \
do { unsigned long flags; \
local_irq_save(flags); \
- arch_read_lock(lock); \
+ __arch_read_lock(lock); \
local_irq_restore(flags); \
} while(0)
-static inline void arch_read_unlock(raw_rwlock_t *rw)
+static inline void __arch_read_unlock(arch_rwlock_t *rw)
{
- register raw_rwlock_t *lp asm("g1");
+ register arch_rwlock_t *lp asm("g1");
lp = rw;
__asm__ __volatile__(
"mov %%o7, %%g4\n\t"
@@ -109,16 +109,16 @@ static inline void arch_read_unlock(raw_rwlock_t *rw)
: "g2", "g4", "memory", "cc");
}
-#define __raw_read_unlock(lock) \
+#define arch_read_unlock(lock) \
do { unsigned long flags; \
local_irq_save(flags); \
- arch_read_unlock(lock); \
+ __arch_read_unlock(lock); \
local_irq_restore(flags); \
} while(0)
-static inline void __raw_write_lock(raw_rwlock_t *rw)
+static inline void arch_write_lock(arch_rwlock_t *rw)
{
- register raw_rwlock_t *lp asm("g1");
+ register arch_rwlock_t *lp asm("g1");
lp = rw;
__asm__ __volatile__(
"mov %%o7, %%g4\n\t"
@@ -130,7 +130,7 @@ static inline void __raw_write_lock(raw_rwlock_t *rw)
*(volatile __u32 *)&lp->lock = ~0U;
}
-static inline int __raw_write_trylock(raw_rwlock_t *rw)
+static inline int arch_write_trylock(arch_rwlock_t *rw)
{
unsigned int val;
@@ -150,9 +150,9 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw)
return (val == 0);
}
-static inline int arch_read_trylock(raw_rwlock_t *rw)
+static inline int __arch_read_trylock(arch_rwlock_t *rw)
{
- register raw_rwlock_t *lp asm("g1");
+ register arch_rwlock_t *lp asm("g1");
register int res asm("o0");
lp = rw;
__asm__ __volatile__(
@@ -165,27 +165,27 @@ static inline int arch_read_trylock(raw_rwlock_t *rw)
return res;
}
-#define __raw_read_trylock(lock) \
+#define arch_read_trylock(lock) \
({ unsigned long flags; \
int res; \
local_irq_save(flags); \
- res = arch_read_trylock(lock); \
+ res = __arch_read_trylock(lock); \
local_irq_restore(flags); \
res; \
})
-#define __raw_write_unlock(rw) do { (rw)->lock = 0; } while(0)
+#define arch_write_unlock(rw) do { (rw)->lock = 0; } while(0)
-#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
-#define __raw_read_lock_flags(rw, flags) __raw_read_lock(rw)
-#define __raw_write_lock_flags(rw, flags) __raw_write_lock(rw)
+#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)
+#define arch_read_lock_flags(rw, flags) arch_read_lock(rw)
+#define arch_write_lock_flags(rw, flags) arch_write_lock(rw)
-#define _raw_spin_relax(lock) cpu_relax()
-#define _raw_read_relax(lock) cpu_relax()
-#define _raw_write_relax(lock) cpu_relax()
+#define arch_spin_relax(lock) cpu_relax()
+#define arch_read_relax(lock) cpu_relax()
+#define arch_write_relax(lock) cpu_relax()
-#define __raw_read_can_lock(rw) (!((rw)->lock & 0xff))
-#define __raw_write_can_lock(rw) (!(rw)->lock)
+#define arch_read_can_lock(rw) (!((rw)->lock & 0xff))
+#define arch_write_can_lock(rw) (!(rw)->lock)
#endif /* !(__ASSEMBLY__) */
diff --git a/arch/sparc/include/asm/spinlock_64.h b/arch/sparc/include/asm/spinlock_64.h
index 43e51478358..073936a8b27 100644
--- a/arch/sparc/include/asm/spinlock_64.h
+++ b/arch/sparc/include/asm/spinlock_64.h
@@ -21,13 +21,13 @@
* the spinner sections must be pre-V9 branches.
*/
-#define __raw_spin_is_locked(lp) ((lp)->lock != 0)
+#define arch_spin_is_locked(lp) ((lp)->lock != 0)
-#define __raw_spin_unlock_wait(lp) \
+#define arch_spin_unlock_wait(lp) \
do { rmb(); \
} while((lp)->lock)
-static inline void __raw_spin_lock(raw_spinlock_t *lock)
+static inline void arch_spin_lock(arch_spinlock_t *lock)
{
unsigned long tmp;
@@ -46,7 +46,7 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock)
: "memory");
}
-static inline int __raw_spin_trylock(raw_spinlock_t *lock)
+static inline int arch_spin_trylock(arch_spinlock_t *lock)
{
unsigned long result;
@@ -59,7 +59,7 @@ static inline int __raw_spin_trylock(raw_spinlock_t *lock)
return (result == 0UL);
}
-static inline void __raw_spin_unlock(raw_spinlock_t *lock)
+static inline void arch_spin_unlock(arch_spinlock_t *lock)
{
__asm__ __volatile__(
" stb %%g0, [%0]"
@@ -68,7 +68,7 @@ static inline void __raw_spin_unlock(raw_spinlock_t *lock)
: "memory");
}
-static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags)
+static inline void arch_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags)
{
unsigned long tmp1, tmp2;
@@ -92,7 +92,7 @@ static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long fla
/* Multi-reader locks, these are much saner than the 32-bit Sparc ones... */
-static void inline arch_read_lock(raw_rwlock_t *lock)
+static void inline arch_read_lock(arch_rwlock_t *lock)
{
unsigned long tmp1, tmp2;
@@ -115,7 +115,7 @@ static void inline arch_read_lock(raw_rwlock_t *lock)
: "memory");
}
-static int inline arch_read_trylock(raw_rwlock_t *lock)
+static int inline arch_read_trylock(arch_rwlock_t *lock)
{
int tmp1, tmp2;
@@ -136,7 +136,7 @@ static int inline arch_read_trylock(raw_rwlock_t *lock)
return tmp1;
}
-static void inline arch_read_unlock(raw_rwlock_t *lock)
+static void inline arch_read_unlock(arch_rwlock_t *lock)
{
unsigned long tmp1, tmp2;
@@ -152,7 +152,7 @@ static void inline arch_read_unlock(raw_rwlock_t *lock)
: "memory");
}
-static void inline arch_write_lock(raw_rwlock_t *lock)
+static void inline arch_write_lock(arch_rwlock_t *lock)
{
unsigned long mask, tmp1, tmp2;
@@ -177,7 +177,7 @@ static void inline arch_write_lock(raw_rwlock_t *lock)
: "memory");
}
-static void inline arch_write_unlock(raw_rwlock_t *lock)
+static void inline arch_write_unlock(arch_rwlock_t *lock)
{
__asm__ __volatile__(
" stw %%g0, [%0]"
@@ -186,7 +186,7 @@ static void inline arch_write_unlock(raw_rwlock_t *lock)
: "memory");
}
-static int inline arch_write_trylock(raw_rwlock_t *lock)
+static int inline arch_write_trylock(arch_rwlock_t *lock)
{
unsigned long mask, tmp1, tmp2, result;
@@ -210,21 +210,21 @@ static int inline arch_write_trylock(raw_rwlock_t *lock)
return result;
}
-#define __raw_read_lock(p) arch_read_lock(p)
-#define __raw_read_lock_flags(p, f) arch_read_lock(p)
-#define __raw_read_trylock(p) arch_read_trylock(p)
-#define __raw_read_unlock(p) arch_read_unlock(p)
-#define __raw_write_lock(p) arch_write_lock(p)
-#define __raw_write_lock_flags(p, f) arch_write_lock(p)
-#define __raw_write_unlock(p) arch_write_unlock(p)
-#define __raw_write_trylock(p) arch_write_trylock(p)
-
-#define __raw_read_can_lock(rw) (!((rw)->lock & 0x80000000UL))
-#define __raw_write_can_lock(rw) (!(rw)->lock)
-
-#define _raw_spin_relax(lock) cpu_relax()
-#define _raw_read_relax(lock) cpu_relax()
-#define _raw_write_relax(lock) cpu_relax()
+#define arch_read_lock(p) arch_read_lock(p)
+#define arch_read_lock_flags(p, f) arch_read_lock(p)
+#define arch_read_trylock(p) arch_read_trylock(p)
+#define arch_read_unlock(p) arch_read_unlock(p)
+#define arch_write_lock(p) arch_write_lock(p)
+#define arch_write_lock_flags(p, f) arch_write_lock(p)
+#define arch_write_unlock(p) arch_write_unlock(p)
+#define arch_write_trylock(p) arch_write_trylock(p)
+
+#define arch_read_can_lock(rw) (!((rw)->lock & 0x80000000UL))
+#define arch_write_can_lock(rw) (!(rw)->lock)
+
+#define arch_spin_relax(lock) cpu_relax()
+#define arch_read_relax(lock) cpu_relax()
+#define arch_write_relax(lock) cpu_relax()
#endif /* !(__ASSEMBLY__) */
diff --git a/arch/sparc/include/asm/spinlock_types.h b/arch/sparc/include/asm/spinlock_types.h
index 37cbe01c585..9c454fdeaad 100644
--- a/arch/sparc/include/asm/spinlock_types.h
+++ b/arch/sparc/include/asm/spinlock_types.h
@@ -7,14 +7,14 @@
typedef struct {
volatile unsigned char lock;
-} raw_spinlock_t;
+} arch_spinlock_t;
-#define __RAW_SPIN_LOCK_UNLOCKED { 0 }
+#define __ARCH_SPIN_LOCK_UNLOCKED { 0 }
typedef struct {
volatile unsigned int lock;
-} raw_rwlock_t;
+} arch_rwlock_t;
-#define __RAW_RW_LOCK_UNLOCKED { 0 }
+#define __ARCH_RW_LOCK_UNLOCKED { 0 }
#endif
diff --git a/arch/sparc/include/asm/string_32.h b/arch/sparc/include/asm/string_32.h
index 6c5fddb7e6b..edf196ee4ef 100644
--- a/arch/sparc/include/asm/string_32.h
+++ b/arch/sparc/include/asm/string_32.h
@@ -16,8 +16,6 @@
#ifdef __KERNEL__
extern void __memmove(void *,const void *,__kernel_size_t);
-extern __kernel_size_t __memcpy(void *,const void *,__kernel_size_t);
-extern __kernel_size_t __memset(void *,int,__kernel_size_t);
#ifndef EXPORT_SYMTAB_STROPS
@@ -32,82 +30,10 @@ extern __kernel_size_t __memset(void *,int,__kernel_size_t);
})
#define __HAVE_ARCH_MEMCPY
-
-static inline void *__constant_memcpy(void *to, const void *from, __kernel_size_t n)
-{
- extern void __copy_1page(void *, const void *);
-
- if(n <= 32) {
- __builtin_memcpy(to, from, n);
- } else if (((unsigned int) to & 7) != 0) {
- /* Destination is not aligned on the double-word boundary */
- __memcpy(to, from, n);
- } else {
- switch(n) {
- case PAGE_SIZE:
- __copy_1page(to, from);
- break;
- default:
- __memcpy(to, from, n);
- break;
- }
- }
- return to;
-}
-
-static inline void *__nonconstant_memcpy(void *to, const void *from, __kernel_size_t n)
-{
- __memcpy(to, from, n);
- return to;
-}
-
-#undef memcpy
-#define memcpy(t, f, n) \
-(__builtin_constant_p(n) ? \
- __constant_memcpy((t),(f),(n)) : \
- __nonconstant_memcpy((t),(f),(n)))
+#define memcpy(t, f, n) __builtin_memcpy(t, f, n)
#define __HAVE_ARCH_MEMSET
-
-static inline void *__constant_c_and_count_memset(void *s, char c, __kernel_size_t count)
-{
- extern void bzero_1page(void *);
- extern __kernel_size_t __bzero(void *, __kernel_size_t);
-
- if(!c) {
- if(count == PAGE_SIZE)
- bzero_1page(s);
- else
- __bzero(s, count);
- } else {
- __memset(s, c, count);
- }
- return s;
-}
-
-static inline void *__constant_c_memset(void *s, char c, __kernel_size_t count)
-{
- extern __kernel_size_t __bzero(void *, __kernel_size_t);
-
- if(!c)
- __bzero(s, count);
- else
- __memset(s, c, count);
- return s;
-}
-
-static inline void *__nonconstant_memset(void *s, char c, __kernel_size_t count)
-{
- __memset(s, c, count);
- return s;
-}
-
-#undef memset
-#define memset(s, c, count) \
-(__builtin_constant_p(c) ? (__builtin_constant_p(count) ? \
- __constant_c_and_count_memset((s), (c), (count)) : \
- __constant_c_memset((s), (c), (count))) \
- : __nonconstant_memset((s), (c), (count)))
+#define memset(s, c, count) __builtin_memset(s, c, count)
#define __HAVE_ARCH_MEMSCAN
diff --git a/arch/sparc/include/asm/string_64.h b/arch/sparc/include/asm/string_64.h
index 43161f2d17e..9623bc21315 100644
--- a/arch/sparc/include/asm/string_64.h
+++ b/arch/sparc/include/asm/string_64.h
@@ -15,8 +15,6 @@
#include <asm/asi.h>
-extern void *__memset(void *,int,__kernel_size_t);
-
#ifndef EXPORT_SYMTAB_STROPS
/* First the mem*() things. */
@@ -24,29 +22,10 @@ extern void *__memset(void *,int,__kernel_size_t);
extern void *memmove(void *, const void *, __kernel_size_t);
#define __HAVE_ARCH_MEMCPY
-extern void *memcpy(void *, const void *, __kernel_size_t);
+#define memcpy(t, f, n) __builtin_memcpy(t, f, n)
#define __HAVE_ARCH_MEMSET
-extern void *__builtin_memset(void *,int,__kernel_size_t);
-
-static inline void *__constant_memset(void *s, int c, __kernel_size_t count)
-{
- extern __kernel_size_t __bzero(void *, __kernel_size_t);
-
- if (!c) {
- __bzero(s, count);
- return s;
- } else
- return __memset(s, c, count);
-}
-
-#undef memset
-#define memset(s, c, count) \
-((__builtin_constant_p(count) && (count) <= 32) ? \
- __builtin_memset((s), (c), (count)) : \
- (__builtin_constant_p(c) ? \
- __constant_memset((s), (c), (count)) : \
- __memset((s), (c), (count))))
+#define memset(s, c, count) __builtin_memset(s, c, count)
#define __HAVE_ARCH_MEMSCAN
diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h
index 1b45a7bbe40..39be9f256e5 100644
--- a/arch/sparc/include/asm/thread_info_64.h
+++ b/arch/sparc/include/asm/thread_info_64.h
@@ -227,12 +227,12 @@ register struct thread_info *current_thread_info_reg asm("g6");
/* flag bit 8 is available */
#define TIF_SECCOMP 9 /* secure computing */
#define TIF_SYSCALL_AUDIT 10 /* syscall auditing active */
-/* flag bit 11 is available */
+#define TIF_SYSCALL_TRACEPOINT 11 /* syscall tracepoint instrumentation */
/* NOTE: Thread flags >= 12 should be ones we have no interest
* in using in assembly, else we can't use the mask as
* an immediate value in instructions such as andcc.
*/
-#define TIF_ABI_PENDING 12
+/* flag bit 12 is available */
#define TIF_MEMDIE 13
#define TIF_POLLING_NRFLAG 14
#define TIF_FREEZE 15 /* is freezing for suspend */
@@ -246,7 +246,7 @@ register struct thread_info *current_thread_info_reg asm("g6");
#define _TIF_32BIT (1<<TIF_32BIT)
#define _TIF_SECCOMP (1<<TIF_SECCOMP)
#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
-#define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING)
+#define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_FREEZE (1<<TIF_FREEZE)
diff --git a/arch/sparc/include/asm/timex_32.h b/arch/sparc/include/asm/timex_32.h
index b6ccdb0d6f7..a254750e4c0 100644
--- a/arch/sparc/include/asm/timex_32.h
+++ b/arch/sparc/include/asm/timex_32.h
@@ -12,4 +12,5 @@
typedef unsigned long cycles_t;
#define get_cycles() (0)
+extern u32 (*do_arch_gettimeoffset)(void);
#endif
diff --git a/arch/sparc/include/asm/topology_64.h b/arch/sparc/include/asm/topology_64.h
index 600a79035fa..1c79f32734a 100644
--- a/arch/sparc/include/asm/topology_64.h
+++ b/arch/sparc/include/asm/topology_64.h
@@ -12,7 +12,9 @@ static inline int cpu_to_node(int cpu)
#define parent_node(node) (node)
-#define cpumask_of_node(node) (&numa_cpumask_lookup_table[node])
+#define cpumask_of_node(node) ((node) == -1 ? \
+ cpu_all_mask : \
+ &numa_cpumask_lookup_table[node])
struct pci_bus;
#ifdef CONFIG_PCI
diff --git a/arch/sparc/include/asm/uaccess_32.h b/arch/sparc/include/asm/uaccess_32.h
index 8303ac48103..25f1d10155e 100644
--- a/arch/sparc/include/asm/uaccess_32.h
+++ b/arch/sparc/include/asm/uaccess_32.h
@@ -260,8 +260,23 @@ static inline unsigned long __copy_to_user(void __user *to, const void *from, un
return __copy_user(to, (__force void __user *) from, n);
}
+extern void copy_from_user_overflow(void)
+#ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS
+ __compiletime_error("copy_from_user() buffer size is not provably correct")
+#else
+ __compiletime_warning("copy_from_user() buffer size is not provably correct")
+#endif
+;
+
static inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n)
{
+ int sz = __compiletime_object_size(to);
+
+ if (unlikely(sz != -1 && sz < n)) {
+ copy_from_user_overflow();
+ return n;
+ }
+
if (n && __access_ok((unsigned long) from, n))
return __copy_user((__force void __user *) to, from, n);
else
diff --git a/arch/sparc/include/asm/uaccess_64.h b/arch/sparc/include/asm/uaccess_64.h
index 9ea271e19c7..2406788bfe5 100644
--- a/arch/sparc/include/asm/uaccess_64.h
+++ b/arch/sparc/include/asm/uaccess_64.h
@@ -6,6 +6,7 @@
*/
#ifdef __KERNEL__
+#include <linux/errno.h>
#include <linux/compiler.h>
#include <linux/string.h>
#include <linux/thread_info.h>
@@ -204,6 +205,14 @@ __asm__ __volatile__( \
extern int __get_user_bad(void);
+extern void copy_from_user_overflow(void)
+#ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS
+ __compiletime_error("copy_from_user() buffer size is not provably correct")
+#else
+ __compiletime_warning("copy_from_user() buffer size is not provably correct")
+#endif
+;
+
extern unsigned long __must_check ___copy_from_user(void *to,
const void __user *from,
unsigned long size);
@@ -212,10 +221,16 @@ extern unsigned long copy_from_user_fixup(void *to, const void __user *from,
static inline unsigned long __must_check
copy_from_user(void *to, const void __user *from, unsigned long size)
{
- unsigned long ret = ___copy_from_user(to, from, size);
-
- if (unlikely(ret))
- ret = copy_from_user_fixup(to, from, size);
+ int sz = __compiletime_object_size(to);
+ unsigned long ret = size;
+
+ if (likely(sz == -1 || sz >= size)) {
+ ret = ___copy_from_user(to, from, size);
+ if (unlikely(ret))
+ ret = copy_from_user_fixup(to, from, size);
+ } else {
+ copy_from_user_overflow();
+ }
return ret;
}
#define __copy_from_user copy_from_user
diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unistd.h
index 42f2316c3ea..cb4b9bfd0d8 100644
--- a/arch/sparc/include/asm/unistd.h
+++ b/arch/sparc/include/asm/unistd.h
@@ -396,8 +396,9 @@
#define __NR_pwritev 325
#define __NR_rt_tgsigqueueinfo 326
#define __NR_perf_event_open 327
+#define __NR_recvmmsg 328
-#define NR_SYSCALLS 328
+#define NR_syscalls 329
#ifdef __32bit_syscall_numbers__
/* Sparc 32-bit only has the "setresuid32", "getresuid32" variants,
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index 5b47fab9966..c6316142db4 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -72,7 +72,7 @@ obj-y += dma.o
obj-$(CONFIG_SPARC32_PCI) += pcic.o
obj-$(CONFIG_SMP) += trampoline_$(BITS).o smp_$(BITS).o
-obj-$(CONFIG_SPARC32_SMP) += sun4m_smp.o sun4d_smp.o
+obj-$(CONFIG_SPARC32_SMP) += sun4m_smp.o sun4d_smp.o leon_smp.o
obj-$(CONFIG_SPARC64_SMP) += hvtramp.o
obj-y += auxio_$(BITS).o
@@ -87,6 +87,7 @@ obj-$(CONFIG_KGDB) += kgdb_$(BITS).o
obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
CFLAGS_REMOVE_ftrace.o := -pg
+obj-$(CONFIG_EARLYFB) += btext.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
# sparc64 PCI
obj-$(CONFIG_SPARC64_PCI) += pci.o pci_common.o psycho_common.o
diff --git a/arch/sparc/kernel/apc.c b/arch/sparc/kernel/apc.c
index 9c115823c4b..71ec90b9e31 100644
--- a/arch/sparc/kernel/apc.c
+++ b/arch/sparc/kernel/apc.c
@@ -10,7 +10,6 @@
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
-#include <linux/smp_lock.h>
#include <linux/pm.h>
#include <linux/of.h>
#include <linux/of_device.h>
@@ -76,7 +75,6 @@ static inline void apc_free(struct of_device *op)
static int apc_open(struct inode *inode, struct file *f)
{
- cycle_kernel_lock();
return 0;
}
@@ -87,61 +85,46 @@ static int apc_release(struct inode *inode, struct file *f)
static long apc_ioctl(struct file *f, unsigned int cmd, unsigned long __arg)
{
- __u8 inarg, __user *arg;
-
- arg = (__u8 __user *) __arg;
-
- lock_kernel();
+ __u8 inarg, __user *arg = (__u8 __user *) __arg;
switch (cmd) {
case APCIOCGFANCTL:
- if (put_user(apc_readb(APC_FANCTL_REG) & APC_REGMASK, arg)) {
- unlock_kernel();
+ if (put_user(apc_readb(APC_FANCTL_REG) & APC_REGMASK, arg))
return -EFAULT;
- }
break;
case APCIOCGCPWR:
- if (put_user(apc_readb(APC_CPOWER_REG) & APC_REGMASK, arg)) {
- unlock_kernel();
+ if (put_user(apc_readb(APC_CPOWER_REG) & APC_REGMASK, arg))
return -EFAULT;
- }
break;
case APCIOCGBPORT:
- if (put_user(apc_readb(APC_BPORT_REG) & APC_BPMASK, arg)) {
- unlock_kernel();
+ if (put_user(apc_readb(APC_BPORT_REG) & APC_BPMASK, arg))
return -EFAULT;
- }
break;
case APCIOCSFANCTL:
- if (get_user(inarg, arg)) {
- unlock_kernel();
+ if (get_user(inarg, arg))
return -EFAULT;
- }
apc_writeb(inarg & APC_REGMASK, APC_FANCTL_REG);
break;
+
case APCIOCSCPWR:
- if (get_user(inarg, arg)) {
- unlock_kernel();
+ if (get_user(inarg, arg))
return -EFAULT;
- }
apc_writeb(inarg & APC_REGMASK, APC_CPOWER_REG);
break;
+
case APCIOCSBPORT:
- if (get_user(inarg, arg)) {
- unlock_kernel();
+ if (get_user(inarg, arg))
return -EFAULT;
- }
apc_writeb(inarg & APC_BPMASK, APC_BPORT_REG);
break;
+
default:
- unlock_kernel();
return -EINVAL;
};
- unlock_kernel();
return 0;
}
diff --git a/arch/sparc/kernel/auxio_32.c b/arch/sparc/kernel/auxio_32.c
index 45c41232fc4..ee8d214cae1 100644
--- a/arch/sparc/kernel/auxio_32.c
+++ b/arch/sparc/kernel/auxio_32.c
@@ -28,6 +28,7 @@ void __init auxio_probe(void)
struct resource r;
switch (sparc_cpu_model) {
+ case sparc_leon:
case sun4d:
case sun4:
return;
diff --git a/arch/sparc/kernel/btext.c b/arch/sparc/kernel/btext.c
new file mode 100644
index 00000000000..8cc2d56ffe9
--- /dev/null
+++ b/arch/sparc/kernel/btext.c
@@ -0,0 +1,673 @@
+/*
+ * Procedures for drawing on the screen early on in the boot process.
+ *
+ * Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ */
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/console.h>
+
+#include <asm/btext.h>
+#include <asm/oplib.h>
+#include <asm/io.h>
+
+#define NO_SCROLL
+
+#ifndef NO_SCROLL
+static void scrollscreen(void);
+#endif
+
+static void draw_byte(unsigned char c, long locX, long locY);
+static void draw_byte_32(unsigned char *bits, unsigned int *base, int rb);
+static void draw_byte_16(unsigned char *bits, unsigned int *base, int rb);
+static void draw_byte_8(unsigned char *bits, unsigned int *base, int rb);
+
+#define __force_data __attribute__((__section__(".data")))
+
+static int g_loc_X __force_data;
+static int g_loc_Y __force_data;
+static int g_max_loc_X __force_data;
+static int g_max_loc_Y __force_data;
+
+static int dispDeviceRowBytes __force_data;
+static int dispDeviceDepth __force_data;
+static int dispDeviceRect[4] __force_data;
+static unsigned char *dispDeviceBase __force_data;
+
+#define cmapsz (16*256)
+
+static unsigned char vga_font[cmapsz];
+
+static int __init btext_initialize(unsigned int node)
+{
+ unsigned int width, height, depth, pitch;
+ unsigned long address = 0;
+ u32 prop;
+
+ if (prom_getproperty(node, "width", (char *)&width, 4) < 0)
+ return -EINVAL;
+ if (prom_getproperty(node, "height", (char *)&height, 4) < 0)
+ return -EINVAL;
+ if (prom_getproperty(node, "depth", (char *)&depth, 4) < 0)
+ return -EINVAL;
+ pitch = width * ((depth + 7) / 8);
+
+ if (prom_getproperty(node, "linebytes", (char *)&prop, 4) >= 0 &&
+ prop != 0xffffffffu)
+ pitch = prop;
+
+ if (pitch == 1)
+ pitch = 0x1000;
+
+ if (prom_getproperty(node, "address", (char *)&prop, 4) >= 0)
+ address = prop;
+
+ /* FIXME: Add support for PCI reg properties. Right now, only
+ * reliable on macs
+ */
+ if (address == 0)
+ return -EINVAL;
+
+ g_loc_X = 0;
+ g_loc_Y = 0;
+ g_max_loc_X = width / 8;
+ g_max_loc_Y = height / 16;
+ dispDeviceBase = (unsigned char *)address;
+ dispDeviceRowBytes = pitch;
+ dispDeviceDepth = depth == 15 ? 16 : depth;
+ dispDeviceRect[0] = dispDeviceRect[1] = 0;
+ dispDeviceRect[2] = width;
+ dispDeviceRect[3] = height;
+
+ return 0;
+}
+
+/* Calc the base address of a given point (x,y) */
+static unsigned char * calc_base(int x, int y)
+{
+ unsigned char *base = dispDeviceBase;
+
+ base += (x + dispDeviceRect[0]) * (dispDeviceDepth >> 3);
+ base += (y + dispDeviceRect[1]) * dispDeviceRowBytes;
+ return base;
+}
+
+static void btext_clearscreen(void)
+{
+ unsigned int *base = (unsigned int *)calc_base(0, 0);
+ unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) *
+ (dispDeviceDepth >> 3)) >> 2;
+ int i,j;
+
+ for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1]); i++)
+ {
+ unsigned int *ptr = base;
+ for(j=width; j; --j)
+ *(ptr++) = 0;
+ base += (dispDeviceRowBytes >> 2);
+ }
+}
+
+#ifndef NO_SCROLL
+static void scrollscreen(void)
+{
+ unsigned int *src = (unsigned int *)calc_base(0,16);
+ unsigned int *dst = (unsigned int *)calc_base(0,0);
+ unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) *
+ (dispDeviceDepth >> 3)) >> 2;
+ int i,j;
+
+ for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1] - 16); i++)
+ {
+ unsigned int *src_ptr = src;
+ unsigned int *dst_ptr = dst;
+ for(j=width; j; --j)
+ *(dst_ptr++) = *(src_ptr++);
+ src += (dispDeviceRowBytes >> 2);
+ dst += (dispDeviceRowBytes >> 2);
+ }
+ for (i=0; i<16; i++)
+ {
+ unsigned int *dst_ptr = dst;
+ for(j=width; j; --j)
+ *(dst_ptr++) = 0;
+ dst += (dispDeviceRowBytes >> 2);
+ }
+}
+#endif /* ndef NO_SCROLL */
+
+void btext_drawchar(char c)
+{
+ int cline = 0;
+#ifdef NO_SCROLL
+ int x;
+#endif
+ switch (c) {
+ case '\b':
+ if (g_loc_X > 0)
+ --g_loc_X;
+ break;
+ case '\t':
+ g_loc_X = (g_loc_X & -8) + 8;
+ break;
+ case '\r':
+ g_loc_X = 0;
+ break;
+ case '\n':
+ g_loc_X = 0;
+ g_loc_Y++;
+ cline = 1;
+ break;
+ default:
+ draw_byte(c, g_loc_X++, g_loc_Y);
+ }
+ if (g_loc_X >= g_max_loc_X) {
+ g_loc_X = 0;
+ g_loc_Y++;
+ cline = 1;
+ }
+#ifndef NO_SCROLL
+ while (g_loc_Y >= g_max_loc_Y) {
+ scrollscreen();
+ g_loc_Y--;
+ }
+#else
+ /* wrap around from bottom to top of screen so we don't
+ waste time scrolling each line. -- paulus. */
+ if (g_loc_Y >= g_max_loc_Y)
+ g_loc_Y = 0;
+ if (cline) {
+ for (x = 0; x < g_max_loc_X; ++x)
+ draw_byte(' ', x, g_loc_Y);
+ }
+#endif
+}
+
+static void btext_drawtext(const char *c, unsigned int len)
+{
+ while (len--)
+ btext_drawchar(*c++);
+}
+
+static void draw_byte(unsigned char c, long locX, long locY)
+{
+ unsigned char *base = calc_base(locX << 3, locY << 4);
+ unsigned char *font = &vga_font[((unsigned int)c) * 16];
+ int rb = dispDeviceRowBytes;
+
+ switch(dispDeviceDepth) {
+ case 24:
+ case 32:
+ draw_byte_32(font, (unsigned int *)base, rb);
+ break;
+ case 15:
+ case 16:
+ draw_byte_16(font, (unsigned int *)base, rb);
+ break;
+ case 8:
+ draw_byte_8(font, (unsigned int *)base, rb);
+ break;
+ }
+}
+
+static unsigned int expand_bits_8[16] = {
+ 0x00000000,
+ 0x000000ff,
+ 0x0000ff00,
+ 0x0000ffff,
+ 0x00ff0000,
+ 0x00ff00ff,
+ 0x00ffff00,
+ 0x00ffffff,
+ 0xff000000,
+ 0xff0000ff,
+ 0xff00ff00,
+ 0xff00ffff,
+ 0xffff0000,
+ 0xffff00ff,
+ 0xffffff00,
+ 0xffffffff
+};
+
+static unsigned int expand_bits_16[4] = {
+ 0x00000000,
+ 0x0000ffff,
+ 0xffff0000,
+ 0xffffffff
+};
+
+
+static void draw_byte_32(unsigned char *font, unsigned int *base, int rb)
+{
+ int l, bits;
+ int fg = 0xFFFFFFFFUL;
+ int bg = 0x00000000UL;
+
+ for (l = 0; l < 16; ++l)
+ {
+ bits = *font++;
+ base[0] = (-(bits >> 7) & fg) ^ bg;
+ base[1] = (-((bits >> 6) & 1) & fg) ^ bg;
+ base[2] = (-((bits >> 5) & 1) & fg) ^ bg;
+ base[3] = (-((bits >> 4) & 1) & fg) ^ bg;
+ base[4] = (-((bits >> 3) & 1) & fg) ^ bg;
+ base[5] = (-((bits >> 2) & 1) & fg) ^ bg;
+ base[6] = (-((bits >> 1) & 1) & fg) ^ bg;
+ base[7] = (-(bits & 1) & fg) ^ bg;
+ base = (unsigned int *) ((char *)base + rb);
+ }
+}
+
+static void draw_byte_16(unsigned char *font, unsigned int *base, int rb)
+{
+ int l, bits;
+ int fg = 0xFFFFFFFFUL;
+ int bg = 0x00000000UL;
+ unsigned int *eb = (int *)expand_bits_16;
+
+ for (l = 0; l < 16; ++l)
+ {
+ bits = *font++;
+ base[0] = (eb[bits >> 6] & fg) ^ bg;
+ base[1] = (eb[(bits >> 4) & 3] & fg) ^ bg;
+ base[2] = (eb[(bits >> 2) & 3] & fg) ^ bg;
+ base[3] = (eb[bits & 3] & fg) ^ bg;
+ base = (unsigned int *) ((char *)base + rb);
+ }
+}
+
+static void draw_byte_8(unsigned char *font, unsigned int *base, int rb)
+{
+ int l, bits;
+ int fg = 0x0F0F0F0FUL;
+ int bg = 0x00000000UL;
+ unsigned int *eb = (int *)expand_bits_8;
+
+ for (l = 0; l < 16; ++l)
+ {
+ bits = *font++;
+ base[0] = (eb[bits >> 4] & fg) ^ bg;
+ base[1] = (eb[bits & 0xf] & fg) ^ bg;
+ base = (unsigned int *) ((char *)base + rb);
+ }
+}
+
+static void btext_console_write(struct console *con, const char *s,
+ unsigned int n)
+{
+ btext_drawtext(s, n);
+}
+
+static struct console btext_console = {
+ .name = "btext",
+ .write = btext_console_write,
+ .flags = CON_PRINTBUFFER | CON_ENABLED | CON_BOOT | CON_ANYTIME,
+ .index = 0,
+};
+
+int __init btext_find_display(void)
+{
+ unsigned int node;
+ char type[32];
+ int ret;
+
+ node = prom_inst2pkg(prom_stdout);
+ if (prom_getproperty(node, "device_type", type, 32) < 0)
+ return -ENODEV;
+ if (strcmp(type, "display"))
+ return -ENODEV;
+
+ ret = btext_initialize(node);
+ if (!ret) {
+ btext_clearscreen();
+ register_console(&btext_console);
+ }
+ return ret;
+}
+
+static unsigned char vga_font[cmapsz] = {
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd,
+0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff,
+0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe,
+0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c,
+0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd,
+0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e,
+0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30,
+0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63,
+0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8,
+0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0e,
+0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb,
+0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6,
+0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c,
+0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0,
+0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c,
+0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c,
+0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c,
+0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18,
+0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c,
+0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30,
+0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18,
+0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e,
+0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
+0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe,
+0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0,
+0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18,
+0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
+0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
+0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
+0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
+0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde,
+0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38,
+0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0,
+0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x6c,
+0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68,
+0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
+0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c,
+0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60,
+0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xe7,
+0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66,
+0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c,
+0x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c,
+0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
+0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3,
+0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18,
+0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3,
+0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30,
+0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
+0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60,
+0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc,
+0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xe0, 0x60,
+0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06,
+0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60,
+0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb,
+0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66,
+0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60,
+0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30,
+0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3,
+0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6,
+0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18,
+0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6,
+0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
+0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00,
+0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe,
+0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c,
+0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38,
+0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06,
+0x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe,
+0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00,
+0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66,
+0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6,
+0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00,
+0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b,
+0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c,
+0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6,
+0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18,
+0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00,
+0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00,
+0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e,
+0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18,
+0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66,
+0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18,
+0xd8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30,
+0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc,
+0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
+0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c,
+0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0,
+0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06,
+0x0c, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30,
+0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
+0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36,
+0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44,
+0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
+0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
+0x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
+0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36,
+0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36,
+0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0,
+0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0,
+0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8,
+0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66,
+0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
+0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66,
+0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60,
+0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c,
+0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18,
+0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
+0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x1b, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00,
+0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c,
+0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c,
+0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00,
+};
diff --git a/arch/sparc/kernel/central.c b/arch/sparc/kernel/central.c
index f3b5466c389..4589ca33220 100644
--- a/arch/sparc/kernel/central.c
+++ b/arch/sparc/kernel/central.c
@@ -99,7 +99,7 @@ static int __devinit clock_board_probe(struct of_device *op,
p->leds_resource.start = (unsigned long)
(p->clock_regs + CLOCK_CTRL);
- p->leds_resource.end = p->leds_resource.end;
+ p->leds_resource.end = p->leds_resource.start;
p->leds_resource.name = "leds";
p->leds_pdev.name = "sunfire-clockboard-leds";
@@ -194,7 +194,7 @@ static int __devinit fhc_probe(struct of_device *op,
if (!p->central) {
p->leds_resource.start = (unsigned long)
(p->pregs + FHC_PREGS_CTRL);
- p->leds_resource.end = p->leds_resource.end;
+ p->leds_resource.end = p->leds_resource.start;
p->leds_resource.name = "leds";
p->leds_pdev.name = "sunfire-fhc-leds";
diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c
index 1446df90ef8..e447938d39c 100644
--- a/arch/sparc/kernel/cpu.c
+++ b/arch/sparc/kernel/cpu.c
@@ -185,6 +185,17 @@ static const struct manufacturer_info __initconst manufacturer_info[] = {
FPU(-1, NULL)
}
},{
+ 0xF, /* Aeroflex Gaisler */
+ .cpu_info = {
+ CPU(3, "LEON"),
+ CPU(-1, NULL)
+ },
+ .fpu_info = {
+ FPU(2, "GRFPU"),
+ FPU(3, "GRFPU-Lite"),
+ FPU(-1, NULL)
+ }
+},{
0x17,
.cpu_info = {
CPU_PMU(0x10, "TI UltraSparc I (SpitFire)", "ultra12"),
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index f41ecc5ac0b..1504df8ddf7 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -400,6 +400,39 @@ linux_trap_ipi15_sun4d:
/* FIXME */
1: b,a 1b
+#ifdef CONFIG_SPARC_LEON
+
+ .globl smpleon_ticker
+ /* SMP per-cpu ticker interrupts are handled specially. */
+smpleon_ticker:
+ SAVE_ALL
+ or %l0, PSR_PIL, %g2
+ wr %g2, 0x0, %psr
+ WRITE_PAUSE
+ wr %g2, PSR_ET, %psr
+ WRITE_PAUSE
+ call leon_percpu_timer_interrupt
+ add %sp, STACKFRAME_SZ, %o0
+ wr %l0, PSR_ET, %psr
+ WRITE_PAUSE
+ RESTORE_ALL
+
+ .align 4
+ .globl linux_trap_ipi15_leon
+linux_trap_ipi15_leon:
+ SAVE_ALL
+ or %l0, PSR_PIL, %l4
+ wr %l4, 0x0, %psr
+ WRITE_PAUSE
+ wr %l4, PSR_ET, %psr
+ WRITE_PAUSE
+ call leon_cross_call_irq
+ nop
+ b ret_trap_lockless_ipi
+ clr %l6
+
+#endif /* CONFIG_SPARC_LEON */
+
#endif /* CONFIG_SMP */
/* This routine handles illegal instructions and privileged
@@ -1261,7 +1294,7 @@ linux_sparc_syscall:
sethi %hi(PSR_SYSCALL), %l4
or %l0, %l4, %l0
/* Direct access to user regs, must faster. */
- cmp %g1, NR_SYSCALLS
+ cmp %g1, NR_syscalls
bgeu linux_sparc_ni_syscall
sll %g1, 2, %l4
ld [%l7 + %l4], %l7
diff --git a/arch/sparc/kernel/ftrace.c b/arch/sparc/kernel/ftrace.c
index d3b1a307656..29973daa993 100644
--- a/arch/sparc/kernel/ftrace.c
+++ b/arch/sparc/kernel/ftrace.c
@@ -4,6 +4,7 @@
#include <linux/percpu.h>
#include <linux/init.h>
#include <linux/list.h>
+#include <trace/syscall.h>
#include <asm/ftrace.h>
@@ -91,3 +92,13 @@ int __init ftrace_dyn_arch_init(void *data)
}
#endif
+#ifdef CONFIG_FTRACE_SYSCALLS
+
+extern unsigned int sys_call_table[];
+
+unsigned long __init arch_syscall_addr(int nr)
+{
+ return (unsigned long)sys_call_table[nr];
+}
+
+#endif
diff --git a/arch/sparc/kernel/head_32.S b/arch/sparc/kernel/head_32.S
index 439d82a95ac..21bb2590d4a 100644
--- a/arch/sparc/kernel/head_32.S
+++ b/arch/sparc/kernel/head_32.S
@@ -811,9 +811,31 @@ found_version:
got_prop:
#ifdef CONFIG_SPARC_LEON
/* no cpu-type check is needed, it is a SPARC-LEON */
+#ifdef CONFIG_SMP
+ ba leon_smp_init
+ nop
+
+ .global leon_smp_init
+leon_smp_init:
+ sethi %hi(boot_cpu_id), %g1 ! master always 0
+ stb %g0, [%g1 + %lo(boot_cpu_id)]
+ sethi %hi(boot_cpu_id4), %g1 ! master always 0
+ stb %g0, [%g1 + %lo(boot_cpu_id4)]
+
+ rd %asr17,%g1
+ srl %g1,28,%g1
+
+ cmp %g0,%g1
+ beq sun4c_continue_boot !continue with master
+ nop
+
+ ba leon_smp_cpu_startup
+ nop
+#else
ba sun4c_continue_boot
nop
#endif
+#endif
set cputypval, %o2
ldub [%o2 + 0x4], %l1
diff --git a/arch/sparc/kernel/iommu.c b/arch/sparc/kernel/iommu.c
index 7690cc219ec..5fad94950e7 100644
--- a/arch/sparc/kernel/iommu.c
+++ b/arch/sparc/kernel/iommu.c
@@ -11,6 +11,7 @@
#include <linux/dma-mapping.h>
#include <linux/errno.h>
#include <linux/iommu-helper.h>
+#include <linux/bitmap.h>
#ifdef CONFIG_PCI
#include <linux/pci.h>
@@ -169,7 +170,7 @@ void iommu_range_free(struct iommu *iommu, dma_addr_t dma_addr, unsigned long np
entry = (dma_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT;
- iommu_area_free(arena->map, entry, npages);
+ bitmap_clear(arena->map, entry, npages);
}
int iommu_table_init(struct iommu *iommu, int tsbsize,
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index 9f61fd8cbb7..3c8c44f6a41 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -48,8 +48,13 @@
#include <asm/dma.h>
#include <asm/iommu.h>
#include <asm/io-unit.h>
+#include <asm/leon.h>
+#ifdef CONFIG_SPARC_LEON
+#define mmu_inval_dma_area(p, l) leon_flush_dcache_all()
+#else
#define mmu_inval_dma_area(p, l) /* Anton pulled it out for 2.4.0-xx */
+#endif
static struct resource *_sparc_find_resource(struct resource *r,
unsigned long);
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c
index 8ab1d4728a4..e1cbdb94d97 100644
--- a/arch/sparc/kernel/irq_64.c
+++ b/arch/sparc/kernel/irq_64.c
@@ -176,7 +176,7 @@ int show_interrupts(struct seq_file *p, void *v)
}
if (i < NR_IRQS) {
- spin_lock_irqsave(&irq_desc[i].lock, flags);
+ raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
action = irq_desc[i].action;
if (!action)
goto skip;
@@ -187,7 +187,7 @@ int show_interrupts(struct seq_file *p, void *v)
for_each_online_cpu(j)
seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
#endif
- seq_printf(p, " %9s", irq_desc[i].chip->typename);
+ seq_printf(p, " %9s", irq_desc[i].chip->name);
seq_printf(p, " %s", action->name);
for (action=action->next; action; action = action->next)
@@ -195,7 +195,7 @@ int show_interrupts(struct seq_file *p, void *v)
seq_putc(p, '\n');
skip:
- spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+ raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
} else if (i == NR_IRQS) {
seq_printf(p, "NMI: ");
for_each_online_cpu(j)
@@ -250,12 +250,12 @@ struct irq_handler_data {
};
#ifdef CONFIG_SMP
-static int irq_choose_cpu(unsigned int virt_irq)
+static int irq_choose_cpu(unsigned int virt_irq, const struct cpumask *affinity)
{
cpumask_t mask;
int cpuid;
- cpumask_copy(&mask, irq_desc[virt_irq].affinity);
+ cpumask_copy(&mask, affinity);
if (cpus_equal(mask, cpu_online_map)) {
cpuid = map_to_cpu(virt_irq);
} else {
@@ -268,10 +268,8 @@ static int irq_choose_cpu(unsigned int virt_irq)
return cpuid;
}
#else
-static int irq_choose_cpu(unsigned int virt_irq)
-{
- return real_hard_smp_processor_id();
-}
+#define irq_choose_cpu(virt_irq, affinity) \
+ real_hard_smp_processor_id()
#endif
static void sun4u_irq_enable(unsigned int virt_irq)
@@ -282,7 +280,8 @@ static void sun4u_irq_enable(unsigned int virt_irq)
unsigned long cpuid, imap, val;
unsigned int tid;
- cpuid = irq_choose_cpu(virt_irq);
+ cpuid = irq_choose_cpu(virt_irq,
+ irq_desc[virt_irq].affinity);
imap = data->imap;
tid = sun4u_compute_tid(imap, cpuid);
@@ -299,7 +298,24 @@ static void sun4u_irq_enable(unsigned int virt_irq)
static int sun4u_set_affinity(unsigned int virt_irq,
const struct cpumask *mask)
{
- sun4u_irq_enable(virt_irq);
+ struct irq_handler_data *data = get_irq_chip_data(virt_irq);
+
+ if (likely(data)) {
+ unsigned long cpuid, imap, val;
+ unsigned int tid;
+
+ cpuid = irq_choose_cpu(virt_irq, mask);
+ imap = data->imap;
+
+ tid = sun4u_compute_tid(imap, cpuid);
+
+ val = upa_readq(imap);
+ val &= ~(IMAP_TID_UPA | IMAP_TID_JBUS |
+ IMAP_AID_SAFARI | IMAP_NID_SAFARI);
+ val |= tid | IMAP_VALID;
+ upa_writeq(val, imap);
+ upa_writeq(ICLR_IDLE, data->iclr);
+ }
return 0;
}
@@ -340,7 +356,8 @@ static void sun4u_irq_eoi(unsigned int virt_irq)
static void sun4v_irq_enable(unsigned int virt_irq)
{
unsigned int ino = virt_irq_table[virt_irq].dev_ino;
- unsigned long cpuid = irq_choose_cpu(virt_irq);
+ unsigned long cpuid = irq_choose_cpu(virt_irq,
+ irq_desc[virt_irq].affinity);
int err;
err = sun4v_intr_settarget(ino, cpuid);
@@ -361,7 +378,7 @@ static int sun4v_set_affinity(unsigned int virt_irq,
const struct cpumask *mask)
{
unsigned int ino = virt_irq_table[virt_irq].dev_ino;
- unsigned long cpuid = irq_choose_cpu(virt_irq);
+ unsigned long cpuid = irq_choose_cpu(virt_irq, mask);
int err;
err = sun4v_intr_settarget(ino, cpuid);
@@ -403,7 +420,7 @@ static void sun4v_virq_enable(unsigned int virt_irq)
unsigned long cpuid, dev_handle, dev_ino;
int err;
- cpuid = irq_choose_cpu(virt_irq);
+ cpuid = irq_choose_cpu(virt_irq, irq_desc[virt_irq].affinity);
dev_handle = virt_irq_table[virt_irq].dev_handle;
dev_ino = virt_irq_table[virt_irq].dev_ino;
@@ -433,7 +450,7 @@ static int sun4v_virt_set_affinity(unsigned int virt_irq,
unsigned long cpuid, dev_handle, dev_ino;
int err;
- cpuid = irq_choose_cpu(virt_irq);
+ cpuid = irq_choose_cpu(virt_irq, mask);
dev_handle = virt_irq_table[virt_irq].dev_handle;
dev_ino = virt_irq_table[virt_irq].dev_ino;
@@ -484,7 +501,7 @@ static void sun4v_virq_eoi(unsigned int virt_irq)
}
static struct irq_chip sun4u_irq = {
- .typename = "sun4u",
+ .name = "sun4u",
.enable = sun4u_irq_enable,
.disable = sun4u_irq_disable,
.eoi = sun4u_irq_eoi,
@@ -492,7 +509,7 @@ static struct irq_chip sun4u_irq = {
};
static struct irq_chip sun4v_irq = {
- .typename = "sun4v",
+ .name = "sun4v",
.enable = sun4v_irq_enable,
.disable = sun4v_irq_disable,
.eoi = sun4v_irq_eoi,
@@ -500,7 +517,7 @@ static struct irq_chip sun4v_irq = {
};
static struct irq_chip sun4v_virq = {
- .typename = "vsun4v",
+ .name = "vsun4v",
.enable = sun4v_virq_enable,
.disable = sun4v_virq_disable,
.eoi = sun4v_virq_eoi,
@@ -785,14 +802,14 @@ void fixup_irqs(void)
for (irq = 0; irq < NR_IRQS; irq++) {
unsigned long flags;
- spin_lock_irqsave(&irq_desc[irq].lock, flags);
+ raw_spin_lock_irqsave(&irq_desc[irq].lock, flags);
if (irq_desc[irq].action &&
!(irq_desc[irq].status & IRQ_PER_CPU)) {
if (irq_desc[irq].chip->set_affinity)
irq_desc[irq].chip->set_affinity(irq,
irq_desc[irq].affinity);
}
- spin_unlock_irqrestore(&irq_desc[irq].lock, flags);
+ raw_spin_unlock_irqrestore(&irq_desc[irq].lock, flags);
}
tick_ops->disable_irq();
diff --git a/arch/sparc/kernel/kprobes.c b/arch/sparc/kernel/kprobes.c
index 3bc6527c95a..6716584e48a 100644
--- a/arch/sparc/kernel/kprobes.c
+++ b/arch/sparc/kernel/kprobes.c
@@ -46,6 +46,9 @@ struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}};
int __kprobes arch_prepare_kprobe(struct kprobe *p)
{
+ if ((unsigned long) p->addr & 0x3UL)
+ return -EILSEQ;
+
p->ainsn.insn[0] = *p->addr;
flushi(&p->ainsn.insn[0]);
diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c
index cb3c72c45aa..df39a0f0d27 100644
--- a/arch/sparc/kernel/ldc.c
+++ b/arch/sparc/kernel/ldc.c
@@ -14,6 +14,7 @@
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/init.h>
+#include <linux/bitmap.h>
#include <asm/hypervisor.h>
#include <asm/iommu.h>
@@ -1242,13 +1243,13 @@ int ldc_bind(struct ldc_channel *lp, const char *name)
snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name);
err = request_irq(lp->cfg.rx_irq, ldc_rx,
- IRQF_SAMPLE_RANDOM | IRQF_DISABLED | IRQF_SHARED,
+ IRQF_SAMPLE_RANDOM | IRQF_DISABLED,
lp->rx_irq_name, lp);
if (err)
return err;
err = request_irq(lp->cfg.tx_irq, ldc_tx,
- IRQF_SAMPLE_RANDOM | IRQF_DISABLED | IRQF_SHARED,
+ IRQF_SAMPLE_RANDOM | IRQF_DISABLED,
lp->tx_irq_name, lp);
if (err) {
free_irq(lp->cfg.rx_irq, lp);
@@ -1875,7 +1876,7 @@ EXPORT_SYMBOL(ldc_read);
static long arena_alloc(struct ldc_iommu *iommu, unsigned long npages)
{
struct iommu_arena *arena = &iommu->arena;
- unsigned long n, i, start, end, limit;
+ unsigned long n, start, end, limit;
int pass;
limit = arena->limit;
@@ -1883,7 +1884,7 @@ static long arena_alloc(struct ldc_iommu *iommu, unsigned long npages)
pass = 0;
again:
- n = find_next_zero_bit(arena->map, limit, start);
+ n = bitmap_find_next_zero_area(arena->map, limit, start, npages, 0);
end = n + npages;
if (unlikely(end >= limit)) {
if (likely(pass < 1)) {
@@ -1896,16 +1897,7 @@ again:
return -1;
}
}
-
- for (i = n; i < end; i++) {
- if (test_bit(i, arena->map)) {
- start = i + 1;
- goto again;
- }
- }
-
- for (i = n; i < end; i++)
- __set_bit(i, arena->map);
+ bitmap_set(arena->map, n, npages);
arena->hint = end;
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c
index 54d8a5bd482..87f1760c0aa 100644
--- a/arch/sparc/kernel/leon_kernel.c
+++ b/arch/sparc/kernel/leon_kernel.c
@@ -12,11 +12,14 @@
#include <linux/of_platform.h>
#include <linux/interrupt.h>
#include <linux/of_device.h>
+
#include <asm/oplib.h>
#include <asm/timer.h>
#include <asm/prom.h>
#include <asm/leon.h>
#include <asm/leon_amba.h>
+#include <asm/traps.h>
+#include <asm/cacheflush.h>
#include "prom.h"
#include "irq.h"
@@ -115,6 +118,21 @@ void __init leon_init_timers(irq_handler_t counter_fn)
(((1000000 / 100) - 1)));
LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl, 0);
+#ifdef CONFIG_SMP
+ leon_percpu_timer_dev[0].start = (int)leon3_gptimer_regs;
+ leon_percpu_timer_dev[0].irq = leon3_gptimer_irq+1;
+
+ if (!(LEON3_BYPASS_LOAD_PA(&leon3_gptimer_regs->config) &
+ (1<<LEON3_GPTIMER_SEPIRQ))) {
+ prom_printf("irq timer not configured with seperate irqs \n");
+ BUG();
+ }
+
+ LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].val, 0);
+ LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].rld, (((1000000/100) - 1)));
+ LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl, 0);
+# endif
+
} else {
printk(KERN_ERR "No Timer/irqctrl found\n");
BUG();
@@ -130,11 +148,41 @@ void __init leon_init_timers(irq_handler_t counter_fn)
prom_halt();
}
+# ifdef CONFIG_SMP
+ {
+ unsigned long flags;
+ struct tt_entry *trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (leon_percpu_timer_dev[0].irq - 1)];
+
+ /* For SMP we use the level 14 ticker, however the bootup code
+ * has copied the firmwares level 14 vector into boot cpu's
+ * trap table, we must fix this now or we get squashed.
+ */
+ local_irq_save(flags);
+
+ patchme_maybe_smp_msg[0] = 0x01000000; /* NOP out the branch */
+
+ /* Adjust so that we jump directly to smpleon_ticker */
+ trap_table->inst_three += smpleon_ticker - real_irq_entry;
+
+ local_flush_cache_all();
+ local_irq_restore(flags);
+ }
+# endif
+
if (leon3_gptimer_regs) {
LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl,
LEON3_GPTIMER_EN |
LEON3_GPTIMER_RL |
LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN);
+
+#ifdef CONFIG_SMP
+ LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl,
+ LEON3_GPTIMER_EN |
+ LEON3_GPTIMER_RL |
+ LEON3_GPTIMER_LD |
+ LEON3_GPTIMER_IRQEN);
+#endif
+
}
}
@@ -175,6 +223,42 @@ void __init leon_node_init(struct device_node *dp, struct device_node ***nextp)
}
}
+#ifdef CONFIG_SMP
+
+void leon_set_cpu_int(int cpu, int level)
+{
+ unsigned long mask;
+ mask = get_irqmask(level);
+ LEON3_BYPASS_STORE_PA(&leon3_irqctrl_regs->force[cpu], mask);
+}
+
+static void leon_clear_ipi(int cpu, int level)
+{
+ unsigned long mask;
+ mask = get_irqmask(level);
+ LEON3_BYPASS_STORE_PA(&leon3_irqctrl_regs->force[cpu], mask<<16);
+}
+
+static void leon_set_udt(int cpu)
+{
+}
+
+void leon_clear_profile_irq(int cpu)
+{
+}
+
+void leon_enable_irq_cpu(unsigned int irq_nr, unsigned int cpu)
+{
+ unsigned long mask, flags, *addr;
+ mask = get_irqmask(irq_nr);
+ local_irq_save(flags);
+ addr = (unsigned long *)&(leon3_irqctrl_regs->mask[cpu]);
+ LEON3_BYPASS_STORE_PA(addr, (LEON3_BYPASS_LOAD_PA(addr) | (mask)));
+ local_irq_restore(flags);
+}
+
+#endif
+
void __init leon_init_IRQ(void)
{
sparc_init_timers = leon_init_timers;
diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c
new file mode 100644
index 00000000000..05c0dadd637
--- /dev/null
+++ b/arch/sparc/kernel/leon_smp.c
@@ -0,0 +1,468 @@
+/* leon_smp.c: Sparc-Leon SMP support.
+ *
+ * based on sun4m_smp.c
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 2009 Daniel Hellstrom (daniel@gaisler.com) Aeroflex Gaisler AB
+ * Copyright (C) 2009 Konrad Eisele (konrad@gaisler.com) Aeroflex Gaisler AB
+ */
+
+#include <asm/head.h>
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/threads.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/profile.h>
+#include <linux/pm.h>
+#include <linux/delay.h>
+
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+
+#include <asm/ptrace.h>
+#include <asm/atomic.h>
+#include <asm/irq_regs.h>
+
+#include <asm/delay.h>
+#include <asm/irq.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+#include <asm/oplib.h>
+#include <asm/cpudata.h>
+#include <asm/asi.h>
+#include <asm/leon.h>
+#include <asm/leon_amba.h>
+
+#ifdef CONFIG_SPARC_LEON
+
+#include "irq.h"
+
+extern ctxd_t *srmmu_ctx_table_phys;
+static int smp_processors_ready;
+extern volatile unsigned long cpu_callin_map[NR_CPUS];
+extern unsigned char boot_cpu_id;
+extern cpumask_t smp_commenced_mask;
+void __init leon_configure_cache_smp(void);
+
+static inline unsigned long do_swap(volatile unsigned long *ptr,
+ unsigned long val)
+{
+ __asm__ __volatile__("swapa [%1] %2, %0\n\t" : "=&r"(val)
+ : "r"(ptr), "i"(ASI_LEON_DCACHE_MISS)
+ : "memory");
+ return val;
+}
+
+static void smp_setup_percpu_timer(void);
+
+void __cpuinit leon_callin(void)
+{
+ int cpuid = hard_smpleon_processor_id();
+
+ local_flush_cache_all();
+ local_flush_tlb_all();
+ leon_configure_cache_smp();
+
+ /* Get our local ticker going. */
+ smp_setup_percpu_timer();
+
+ calibrate_delay();
+ smp_store_cpu_info(cpuid);
+
+ local_flush_cache_all();
+ local_flush_tlb_all();
+
+ /*
+ * Unblock the master CPU _only_ when the scheduler state
+ * of all secondary CPUs will be up-to-date, so after
+ * the SMP initialization the master will be just allowed
+ * to call the scheduler code.
+ * Allow master to continue.
+ */
+ do_swap(&cpu_callin_map[cpuid], 1);
+
+ local_flush_cache_all();
+ local_flush_tlb_all();
+
+ cpu_probe();
+
+ /* Fix idle thread fields. */
+ __asm__ __volatile__("ld [%0], %%g6\n\t" : : "r"(&current_set[cpuid])
+ : "memory" /* paranoid */);
+
+ /* Attach to the address space of init_task. */
+ atomic_inc(&init_mm.mm_count);
+ current->active_mm = &init_mm;
+
+ while (!cpu_isset(cpuid, smp_commenced_mask))
+ mb();
+
+ local_irq_enable();
+ cpu_set(cpuid, cpu_online_map);
+}
+
+/*
+ * Cycle through the processors asking the PROM to start each one.
+ */
+
+extern struct linux_prom_registers smp_penguin_ctable;
+
+void __init leon_configure_cache_smp(void)
+{
+ unsigned long cfg = sparc_leon3_get_dcachecfg();
+ int me = smp_processor_id();
+
+ if (ASI_LEON3_SYSCTRL_CFG_SSIZE(cfg) > 4) {
+ printk(KERN_INFO "Note: SMP with snooping only works on 4k cache, found %dk(0x%x) on cpu %d, disabling caches\n",
+ (unsigned int)ASI_LEON3_SYSCTRL_CFG_SSIZE(cfg),
+ (unsigned int)cfg, (unsigned int)me);
+ sparc_leon3_disable_cache();
+ } else {
+ if (cfg & ASI_LEON3_SYSCTRL_CFG_SNOOPING) {
+ sparc_leon3_enable_snooping();
+ } else {
+ printk(KERN_INFO "Note: You have to enable snooping in the vhdl model cpu %d, disabling caches\n",
+ me);
+ sparc_leon3_disable_cache();
+ }
+ }
+
+ local_flush_cache_all();
+ local_flush_tlb_all();
+}
+
+void leon_smp_setbroadcast(unsigned int mask)
+{
+ int broadcast =
+ ((LEON3_BYPASS_LOAD_PA(&(leon3_irqctrl_regs->mpstatus)) >>
+ LEON3_IRQMPSTATUS_BROADCAST) & 1);
+ if (!broadcast) {
+ prom_printf("######## !!!! The irqmp-ctrl must have broadcast enabled, smp wont work !!!!! ####### nr cpus: %d\n",
+ leon_smp_nrcpus());
+ if (leon_smp_nrcpus() > 1) {
+ BUG();
+ } else {
+ prom_printf("continue anyway\n");
+ return;
+ }
+ }
+ LEON_BYPASS_STORE_PA(&(leon3_irqctrl_regs->mpbroadcast), mask);
+}
+
+unsigned int leon_smp_getbroadcast(void)
+{
+ unsigned int mask;
+ mask = LEON_BYPASS_LOAD_PA(&(leon3_irqctrl_regs->mpbroadcast));
+ return mask;
+}
+
+int leon_smp_nrcpus(void)
+{
+ int nrcpu =
+ ((LEON3_BYPASS_LOAD_PA(&(leon3_irqctrl_regs->mpstatus)) >>
+ LEON3_IRQMPSTATUS_CPUNR) & 0xf) + 1;
+ return nrcpu;
+}
+
+void __init leon_boot_cpus(void)
+{
+ int nrcpu = leon_smp_nrcpus();
+ int me = smp_processor_id();
+
+ printk(KERN_INFO "%d:(%d:%d) cpus mpirq at 0x%x \n", (unsigned int)me,
+ (unsigned int)nrcpu, (unsigned int)NR_CPUS,
+ (unsigned int)&(leon3_irqctrl_regs->mpstatus));
+
+ leon_enable_irq_cpu(LEON3_IRQ_CROSS_CALL, me);
+ leon_enable_irq_cpu(LEON3_IRQ_TICKER, me);
+ leon_enable_irq_cpu(LEON3_IRQ_RESCHEDULE, me);
+
+ leon_smp_setbroadcast(1 << LEON3_IRQ_TICKER);
+
+ leon_configure_cache_smp();
+ smp_setup_percpu_timer();
+ local_flush_cache_all();
+
+}
+
+int __cpuinit leon_boot_one_cpu(int i)
+{
+
+ struct task_struct *p;
+ int timeout;
+
+ /* Cook up an idler for this guy. */
+ p = fork_idle(i);
+
+ current_set[i] = task_thread_info(p);
+
+ /* See trampoline.S:leon_smp_cpu_startup for details...
+ * Initialize the contexts table
+ * Since the call to prom_startcpu() trashes the structure,
+ * we need to re-initialize it for each cpu
+ */
+ smp_penguin_ctable.which_io = 0;
+ smp_penguin_ctable.phys_addr = (unsigned int)srmmu_ctx_table_phys;
+ smp_penguin_ctable.reg_size = 0;
+
+ /* whirrr, whirrr, whirrrrrrrrr... */
+ printk(KERN_INFO "Starting CPU %d : (irqmp: 0x%x)\n", (unsigned int)i,
+ (unsigned int)&leon3_irqctrl_regs->mpstatus);
+ local_flush_cache_all();
+
+ LEON_BYPASS_STORE_PA(&(leon3_irqctrl_regs->mpstatus), 1 << i);
+
+ /* wheee... it's going... */
+ for (timeout = 0; timeout < 10000; timeout++) {
+ if (cpu_callin_map[i])
+ break;
+ udelay(200);
+ }
+ printk(KERN_INFO "Started CPU %d \n", (unsigned int)i);
+
+ if (!(cpu_callin_map[i])) {
+ printk(KERN_ERR "Processor %d is stuck.\n", i);
+ return -ENODEV;
+ } else {
+ leon_enable_irq_cpu(LEON3_IRQ_CROSS_CALL, i);
+ leon_enable_irq_cpu(LEON3_IRQ_TICKER, i);
+ leon_enable_irq_cpu(LEON3_IRQ_RESCHEDULE, i);
+ }
+
+ local_flush_cache_all();
+ return 0;
+}
+
+void __init leon_smp_done(void)
+{
+
+ int i, first;
+ int *prev;
+
+ /* setup cpu list for irq rotation */
+ first = 0;
+ prev = &first;
+ for (i = 0; i < NR_CPUS; i++) {
+ if (cpu_online(i)) {
+ *prev = i;
+ prev = &cpu_data(i).next;
+ }
+ }
+ *prev = first;
+ local_flush_cache_all();
+
+ /* Free unneeded trap tables */
+ if (!cpu_isset(1, cpu_present_map)) {
+ ClearPageReserved(virt_to_page(trapbase_cpu1));
+ init_page_count(virt_to_page(trapbase_cpu1));
+ free_page((unsigned long)trapbase_cpu1);
+ totalram_pages++;
+ num_physpages++;
+ }
+ if (!cpu_isset(2, cpu_present_map)) {
+ ClearPageReserved(virt_to_page(trapbase_cpu2));
+ init_page_count(virt_to_page(trapbase_cpu2));
+ free_page((unsigned long)trapbase_cpu2);
+ totalram_pages++;
+ num_physpages++;
+ }
+ if (!cpu_isset(3, cpu_present_map)) {
+ ClearPageReserved(virt_to_page(trapbase_cpu3));
+ init_page_count(virt_to_page(trapbase_cpu3));
+ free_page((unsigned long)trapbase_cpu3);
+ totalram_pages++;
+ num_physpages++;
+ }
+ /* Ok, they are spinning and ready to go. */
+ smp_processors_ready = 1;
+
+}
+
+void leon_irq_rotate(int cpu)
+{
+}
+
+static struct smp_funcall {
+ smpfunc_t func;
+ unsigned long arg1;
+ unsigned long arg2;
+ unsigned long arg3;
+ unsigned long arg4;
+ unsigned long arg5;
+ unsigned long processors_in[NR_CPUS]; /* Set when ipi entered. */
+ unsigned long processors_out[NR_CPUS]; /* Set when ipi exited. */
+} ccall_info;
+
+static DEFINE_SPINLOCK(cross_call_lock);
+
+/* Cross calls must be serialized, at least currently. */
+static void leon_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
+ unsigned long arg2, unsigned long arg3,
+ unsigned long arg4)
+{
+ if (smp_processors_ready) {
+ register int high = NR_CPUS - 1;
+ unsigned long flags;
+
+ spin_lock_irqsave(&cross_call_lock, flags);
+
+ {
+ /* If you make changes here, make sure gcc generates proper code... */
+ register smpfunc_t f asm("i0") = func;
+ register unsigned long a1 asm("i1") = arg1;
+ register unsigned long a2 asm("i2") = arg2;
+ register unsigned long a3 asm("i3") = arg3;
+ register unsigned long a4 asm("i4") = arg4;
+ register unsigned long a5 asm("i5") = 0;
+
+ __asm__ __volatile__("std %0, [%6]\n\t"
+ "std %2, [%6 + 8]\n\t"
+ "std %4, [%6 + 16]\n\t" : :
+ "r"(f), "r"(a1), "r"(a2), "r"(a3),
+ "r"(a4), "r"(a5),
+ "r"(&ccall_info.func));
+ }
+
+ /* Init receive/complete mapping, plus fire the IPI's off. */
+ {
+ register int i;
+
+ cpu_clear(smp_processor_id(), mask);
+ cpus_and(mask, cpu_online_map, mask);
+ for (i = 0; i <= high; i++) {
+ if (cpu_isset(i, mask)) {
+ ccall_info.processors_in[i] = 0;
+ ccall_info.processors_out[i] = 0;
+ set_cpu_int(i, LEON3_IRQ_CROSS_CALL);
+
+ }
+ }
+ }
+
+ {
+ register int i;
+
+ i = 0;
+ do {
+ if (!cpu_isset(i, mask))
+ continue;
+
+ while (!ccall_info.processors_in[i])
+ barrier();
+ } while (++i <= high);
+
+ i = 0;
+ do {
+ if (!cpu_isset(i, mask))
+ continue;
+
+ while (!ccall_info.processors_out[i])
+ barrier();
+ } while (++i <= high);
+ }
+
+ spin_unlock_irqrestore(&cross_call_lock, flags);
+ }
+}
+
+/* Running cross calls. */
+void leon_cross_call_irq(void)
+{
+ int i = smp_processor_id();
+
+ ccall_info.processors_in[i] = 1;
+ ccall_info.func(ccall_info.arg1, ccall_info.arg2, ccall_info.arg3,
+ ccall_info.arg4, ccall_info.arg5);
+ ccall_info.processors_out[i] = 1;
+}
+
+void leon_percpu_timer_interrupt(struct pt_regs *regs)
+{
+ struct pt_regs *old_regs;
+ int cpu = smp_processor_id();
+
+ old_regs = set_irq_regs(regs);
+
+ leon_clear_profile_irq(cpu);
+
+ profile_tick(CPU_PROFILING);
+
+ if (!--prof_counter(cpu)) {
+ int user = user_mode(regs);
+
+ irq_enter();
+ update_process_times(user);
+ irq_exit();
+
+ prof_counter(cpu) = prof_multiplier(cpu);
+ }
+ set_irq_regs(old_regs);
+}
+
+static void __init smp_setup_percpu_timer(void)
+{
+ int cpu = smp_processor_id();
+
+ prof_counter(cpu) = prof_multiplier(cpu) = 1;
+}
+
+void __init leon_blackbox_id(unsigned *addr)
+{
+ int rd = *addr & 0x3e000000;
+ int rs1 = rd >> 11;
+
+ /* patch places where ___b_hard_smp_processor_id appears */
+ addr[0] = 0x81444000 | rd; /* rd %asr17, reg */
+ addr[1] = 0x8130201c | rd | rs1; /* srl reg, 0x1c, reg */
+ addr[2] = 0x01000000; /* nop */
+}
+
+void __init leon_blackbox_current(unsigned *addr)
+{
+ int rd = *addr & 0x3e000000;
+ int rs1 = rd >> 11;
+
+ /* patch LOAD_CURRENT macro where ___b_load_current appears */
+ addr[0] = 0x81444000 | rd; /* rd %asr17, reg */
+ addr[2] = 0x8130201c | rd | rs1; /* srl reg, 0x1c, reg */
+ addr[4] = 0x81282002 | rd | rs1; /* sll reg, 0x2, reg */
+
+}
+
+/*
+ * CPU idle callback function
+ * See .../arch/sparc/kernel/process.c
+ */
+void pmc_leon_idle(void)
+{
+ __asm__ volatile ("mov %g0, %asr19");
+}
+
+void __init leon_init_smp(void)
+{
+ /* Patch ipi15 trap table */
+ t_nmi[1] = t_nmi[1] + (linux_trap_ipi15_leon - linux_trap_ipi15_sun4m);
+
+ BTFIXUPSET_BLACKBOX(hard_smp_processor_id, leon_blackbox_id);
+ BTFIXUPSET_BLACKBOX(load_current, leon_blackbox_current);
+ BTFIXUPSET_CALL(smp_cross_call, leon_cross_call, BTFIXUPCALL_NORM);
+ BTFIXUPSET_CALL(__hard_smp_processor_id, __leon_processor_id,
+ BTFIXUPCALL_NORM);
+
+#ifndef PMC_NO_IDLE
+ /* Assign power management IDLE handler */
+ pm_idle = pmc_leon_idle;
+ printk(KERN_INFO "leon: power management initialized\n");
+#endif
+
+}
+
+#endif /* CONFIG_SPARC_LEON */
diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c
index 938da19dc06..cdc91d919e9 100644
--- a/arch/sparc/kernel/mdesc.c
+++ b/arch/sparc/kernel/mdesc.c
@@ -10,6 +10,7 @@
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/miscdevice.h>
+#include <linux/bootmem.h>
#include <asm/cpudata.h>
#include <asm/hypervisor.h>
@@ -108,25 +109,15 @@ static struct mdesc_handle * __init mdesc_lmb_alloc(unsigned int mdesc_size)
static void mdesc_lmb_free(struct mdesc_handle *hp)
{
- unsigned int alloc_size, handle_size = hp->handle_size;
- unsigned long start, end;
+ unsigned int alloc_size;
+ unsigned long start;
BUG_ON(atomic_read(&hp->refcnt) != 0);
BUG_ON(!list_empty(&hp->list));
- alloc_size = PAGE_ALIGN(handle_size);
-
- start = (unsigned long) hp;
- end = start + alloc_size;
-
- while (start < end) {
- struct page *p;
-
- p = virt_to_page(start);
- ClearPageReserved(p);
- __free_page(p);
- start += PAGE_SIZE;
- }
+ alloc_size = PAGE_ALIGN(hp->handle_size);
+ start = __pa(hp);
+ free_bootmem_late(start, alloc_size);
}
static struct mdesc_mem_ops lmb_mdesc_ops = {
diff --git a/arch/sparc/kernel/nmi.c b/arch/sparc/kernel/nmi.c
index b129611590a..d242a734054 100644
--- a/arch/sparc/kernel/nmi.c
+++ b/arch/sparc/kernel/nmi.c
@@ -47,7 +47,7 @@ static DEFINE_PER_CPU(short, wd_enabled);
static int endflag __initdata;
static DEFINE_PER_CPU(unsigned int, last_irq_sum);
-static DEFINE_PER_CPU(local_t, alert_counter);
+static DEFINE_PER_CPU(long, alert_counter);
static DEFINE_PER_CPU(int, nmi_touch);
void touch_nmi_watchdog(void)
@@ -96,7 +96,6 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
int cpu = smp_processor_id();
clear_softint(1 << irq);
- pcr_ops->write(PCR_PIC_PRIV);
local_cpu_data().__nmi_count++;
@@ -105,6 +104,8 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
if (notify_die(DIE_NMI, "nmi", regs, 0,
pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP)
touched = 1;
+ else
+ pcr_ops->write(PCR_PIC_PRIV);
sum = kstat_irqs_cpu(0, cpu);
if (__get_cpu_var(nmi_touch)) {
@@ -112,13 +113,13 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
touched = 1;
}
if (!touched && __get_cpu_var(last_irq_sum) == sum) {
- local_inc(&__get_cpu_var(alert_counter));
- if (local_read(&__get_cpu_var(alert_counter)) == 30 * nmi_hz)
+ __this_cpu_inc(per_cpu_var(alert_counter));
+ if (__this_cpu_read(per_cpu_var(alert_counter)) == 30 * nmi_hz)
die_nmi("BUG: NMI Watchdog detected LOCKUP",
regs, panic_on_timeout);
} else {
__get_cpu_var(last_irq_sum) = sum;
- local_set(&__get_cpu_var(alert_counter), 0);
+ __this_cpu_write(per_cpu_var(alert_counter), 0);
}
if (__get_cpu_var(wd_enabled)) {
write_pic(picl_value(nmi_hz));
diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c
index 881947e59e9..0a6f2d1798d 100644
--- a/arch/sparc/kernel/of_device_64.c
+++ b/arch/sparc/kernel/of_device_64.c
@@ -104,9 +104,19 @@ static int of_bus_pci_map(u32 *addr, const u32 *range,
int i;
/* Check address type match */
- if ((addr[0] ^ range[0]) & 0x03000000)
- return -EINVAL;
+ if (!((addr[0] ^ range[0]) & 0x03000000))
+ goto type_match;
+
+ /* Special exception, we can map a 64-bit address into
+ * a 32-bit range.
+ */
+ if ((addr[0] & 0x03000000) == 0x03000000 &&
+ (range[0] & 0x03000000) == 0x02000000)
+ goto type_match;
+
+ return -EINVAL;
+type_match:
if (of_out_of_range(addr + 1, range + 1, range + na + pna,
na - 1, ns))
return -EINVAL;
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index c6864866280..539e83f8e08 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -1064,7 +1064,6 @@ int pci64_dma_supported(struct pci_dev *pdev, u64 device_mask)
return (device_mask & dma_addr_mask) == dma_addr_mask;
}
-EXPORT_SYMBOL(pci_dma_supported);
void pci_resource_to_user(const struct pci_dev *pdev, int bar,
const struct resource *rp, resource_size_t *start,
@@ -1081,3 +1080,10 @@ void pci_resource_to_user(const struct pci_dev *pdev, int bar,
*start = rp->start - offset;
*end = rp->end - offset;
}
+
+static int __init pcibios_init(void)
+{
+ pci_dfl_cache_line_size = 64 >> 2;
+ return 0;
+}
+subsys_initcall(pcibios_init);
diff --git a/arch/sparc/kernel/pci_msi.c b/arch/sparc/kernel/pci_msi.c
index f1be37a7b12..e1b0541feb1 100644
--- a/arch/sparc/kernel/pci_msi.c
+++ b/arch/sparc/kernel/pci_msi.c
@@ -112,7 +112,7 @@ static void free_msi(struct pci_pbm_info *pbm, int msi_num)
}
static struct irq_chip msi_irq = {
- .typename = "PCI-MSI",
+ .name = "PCI-MSI",
.mask = mask_msi_irq,
.unmask = unmask_msi_irq,
.enable = unmask_msi_irq,
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
index 85e7037429b..4e2724ec2bb 100644
--- a/arch/sparc/kernel/pcic.c
+++ b/arch/sparc/kernel/pcic.c
@@ -30,6 +30,7 @@
#include <asm/oplib.h>
#include <asm/prom.h>
#include <asm/pcic.h>
+#include <asm/timex.h>
#include <asm/timer.h>
#include <asm/uaccess.h>
#include <asm/irq_regs.h>
@@ -163,8 +164,6 @@ void __iomem *pcic_regs;
volatile int pcic_speculative;
volatile int pcic_trapped;
-static void pci_do_gettimeofday(struct timeval *tv);
-static int pci_do_settimeofday(struct timespec *tv);
#define CONFIG_CMD(bus, device_fn, where) (0x80000000 | (((unsigned int)bus) << 16) | (((unsigned int)device_fn) << 8) | (where & ~3))
@@ -716,19 +715,27 @@ static irqreturn_t pcic_timer_handler (int irq, void *h)
#define USECS_PER_JIFFY 10000 /* We have 100HZ "standard" timer for sparc */
#define TICK_TIMER_LIMIT ((100*1000000/4)/100)
+u32 pci_gettimeoffset(void)
+{
+ /*
+ * We divide all by 100
+ * to have microsecond resolution and to avoid overflow
+ */
+ unsigned long count =
+ readl(pcic0.pcic_regs+PCI_SYS_COUNTER) & ~PCI_SYS_COUNTER_OVERFLOW;
+ count = ((count/100)*USECS_PER_JIFFY) / (TICK_TIMER_LIMIT/100);
+ return count * 1000;
+}
+
+
void __init pci_time_init(void)
{
struct linux_pcic *pcic = &pcic0;
unsigned long v;
int timer_irq, irq;
- /* A hack until do_gettimeofday prototype is moved to arch specific headers
- and btfixupped. Patch do_gettimeofday with ba pci_do_gettimeofday; nop */
- ((unsigned int *)do_gettimeofday)[0] =
- 0x10800000 | ((((unsigned long)pci_do_gettimeofday -
- (unsigned long)do_gettimeofday) >> 2) & 0x003fffff);
- ((unsigned int *)do_gettimeofday)[1] = 0x01000000;
- BTFIXUPSET_CALL(bus_do_settimeofday, pci_do_settimeofday, BTFIXUPCALL_NORM);
+ do_arch_gettimeoffset = pci_gettimeoffset;
+
btfixup();
writel (TICK_TIMER_LIMIT, pcic->pcic_regs+PCI_SYS_LIMIT);
@@ -746,84 +753,6 @@ void __init pci_time_init(void)
local_irq_enable();
}
-static inline unsigned long do_gettimeoffset(void)
-{
- /*
- * We divide all by 100
- * to have microsecond resolution and to avoid overflow
- */
- unsigned long count =
- readl(pcic0.pcic_regs+PCI_SYS_COUNTER) & ~PCI_SYS_COUNTER_OVERFLOW;
- count = ((count/100)*USECS_PER_JIFFY) / (TICK_TIMER_LIMIT/100);
- return count;
-}
-
-static void pci_do_gettimeofday(struct timeval *tv)
-{
- unsigned long flags;
- unsigned long seq;
- unsigned long usec, sec;
- unsigned long max_ntp_tick = tick_usec - tickadj;
-
- do {
- seq = read_seqbegin_irqsave(&xtime_lock, flags);
- usec = do_gettimeoffset();
-
- /*
- * If time_adjust is negative then NTP is slowing the clock
- * so make sure not to go into next possible interval.
- * Better to lose some accuracy than have time go backwards..
- */
- if (unlikely(time_adjust < 0))
- usec = min(usec, max_ntp_tick);
-
- sec = xtime.tv_sec;
- usec += (xtime.tv_nsec / 1000);
- } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
-
- while (usec >= 1000000) {
- usec -= 1000000;
- sec++;
- }
-
- tv->tv_sec = sec;
- tv->tv_usec = usec;
-}
-
-static int pci_do_settimeofday(struct timespec *tv)
-{
- if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
- return -EINVAL;
-
- /*
- * This is revolting. We need to set "xtime" correctly. However, the
- * value in this location is the value at the most recent update of
- * wall time. Discover what correction gettimeofday() would have
- * made, and then undo it!
- */
- tv->tv_nsec -= 1000 * do_gettimeoffset();
- while (tv->tv_nsec < 0) {
- tv->tv_nsec += NSEC_PER_SEC;
- tv->tv_sec--;
- }
-
- wall_to_monotonic.tv_sec += xtime.tv_sec - tv->tv_sec;
- wall_to_monotonic.tv_nsec += xtime.tv_nsec - tv->tv_nsec;
-
- if (wall_to_monotonic.tv_nsec > NSEC_PER_SEC) {
- wall_to_monotonic.tv_nsec -= NSEC_PER_SEC;
- wall_to_monotonic.tv_sec++;
- }
- if (wall_to_monotonic.tv_nsec < 0) {
- wall_to_monotonic.tv_nsec += NSEC_PER_SEC;
- wall_to_monotonic.tv_sec--;
- }
-
- xtime.tv_sec = tv->tv_sec;
- xtime.tv_nsec = tv->tv_nsec;
- ntp_clear();
- return 0;
-}
#if 0
static void watchdog_reset() {
diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c
index fa5936e1c3b..e856456ec02 100644
--- a/arch/sparc/kernel/perf_event.c
+++ b/arch/sparc/kernel/perf_event.c
@@ -1,6 +1,6 @@
/* Performance event support for sparc64.
*
- * Copyright (C) 2009 David S. Miller <davem@davemloft.net>
+ * Copyright (C) 2009, 2010 David S. Miller <davem@davemloft.net>
*
* This code is based almost entirely upon the x86 perf event
* code, which is:
@@ -18,11 +18,15 @@
#include <linux/kdebug.h>
#include <linux/mutex.h>
+#include <asm/stacktrace.h>
#include <asm/cpudata.h>
+#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <asm/nmi.h>
#include <asm/pcr.h>
+#include "kstack.h"
+
/* Sparc64 chips have two performance counters, 32-bits each, with
* overflow interrupts generated on transition from 0xffffffff to 0.
* The counters are accessed in one go using a 64-bit register.
@@ -51,16 +55,49 @@
#define PIC_UPPER_INDEX 0
#define PIC_LOWER_INDEX 1
+#define PIC_NO_INDEX -1
struct cpu_hw_events {
- struct perf_event *events[MAX_HWEVENTS];
- unsigned long used_mask[BITS_TO_LONGS(MAX_HWEVENTS)];
- unsigned long active_mask[BITS_TO_LONGS(MAX_HWEVENTS)];
+ /* Number of events currently scheduled onto this cpu.
+ * This tells how many entries in the arrays below
+ * are valid.
+ */
+ int n_events;
+
+ /* Number of new events added since the last hw_perf_disable().
+ * This works because the perf event layer always adds new
+ * events inside of a perf_{disable,enable}() sequence.
+ */
+ int n_added;
+
+ /* Array of events current scheduled on this cpu. */
+ struct perf_event *event[MAX_HWEVENTS];
+
+ /* Array of encoded longs, specifying the %pcr register
+ * encoding and the mask of PIC counters this even can
+ * be scheduled on. See perf_event_encode() et al.
+ */
+ unsigned long events[MAX_HWEVENTS];
+
+ /* The current counter index assigned to an event. When the
+ * event hasn't been programmed into the cpu yet, this will
+ * hold PIC_NO_INDEX. The event->hw.idx value tells us where
+ * we ought to schedule the event.
+ */
+ int current_idx[MAX_HWEVENTS];
+
+ /* Software copy of %pcr register on this cpu. */
u64 pcr;
+
+ /* Enabled/disable state. */
int enabled;
};
DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { .enabled = 1, };
+/* An event map describes the characteristics of a performance
+ * counter event. In particular it gives the encoding as well as
+ * a mask telling which counters the event can be measured on.
+ */
struct perf_event_map {
u16 encoding;
u8 pic_mask;
@@ -69,15 +106,20 @@ struct perf_event_map {
#define PIC_LOWER 0x02
};
+/* Encode a perf_event_map entry into a long. */
static unsigned long perf_event_encode(const struct perf_event_map *pmap)
{
return ((unsigned long) pmap->encoding << 16) | pmap->pic_mask;
}
-static void perf_event_decode(unsigned long val, u16 *enc, u8 *msk)
+static u8 perf_event_get_msk(unsigned long val)
{
- *msk = val & 0xff;
- *enc = val >> 16;
+ return val & 0xff;
+}
+
+static u64 perf_event_get_enc(unsigned long val)
+{
+ return val >> 16;
}
#define C(x) PERF_COUNT_HW_CACHE_##x
@@ -491,53 +533,6 @@ static inline void sparc_pmu_disable_event(struct cpu_hw_events *cpuc, struct hw
pcr_ops->write(cpuc->pcr);
}
-void hw_perf_enable(void)
-{
- struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
- u64 val;
- int i;
-
- if (cpuc->enabled)
- return;
-
- cpuc->enabled = 1;
- barrier();
-
- val = cpuc->pcr;
-
- for (i = 0; i < MAX_HWEVENTS; i++) {
- struct perf_event *cp = cpuc->events[i];
- struct hw_perf_event *hwc;
-
- if (!cp)
- continue;
- hwc = &cp->hw;
- val |= hwc->config_base;
- }
-
- cpuc->pcr = val;
-
- pcr_ops->write(cpuc->pcr);
-}
-
-void hw_perf_disable(void)
-{
- struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
- u64 val;
-
- if (!cpuc->enabled)
- return;
-
- cpuc->enabled = 0;
-
- val = cpuc->pcr;
- val &= ~(PCR_UTRACE | PCR_STRACE |
- sparc_pmu->hv_bit | sparc_pmu->irq_bit);
- cpuc->pcr = val;
-
- pcr_ops->write(cpuc->pcr);
-}
-
static u32 read_pmc(int idx)
{
u64 val;
@@ -566,6 +561,30 @@ static void write_pmc(int idx, u64 val)
write_pic(pic);
}
+static u64 sparc_perf_event_update(struct perf_event *event,
+ struct hw_perf_event *hwc, int idx)
+{
+ int shift = 64 - 32;
+ u64 prev_raw_count, new_raw_count;
+ s64 delta;
+
+again:
+ prev_raw_count = atomic64_read(&hwc->prev_count);
+ new_raw_count = read_pmc(idx);
+
+ if (atomic64_cmpxchg(&hwc->prev_count, prev_raw_count,
+ new_raw_count) != prev_raw_count)
+ goto again;
+
+ delta = (new_raw_count << shift) - (prev_raw_count << shift);
+ delta >>= shift;
+
+ atomic64_add(delta, &event->count);
+ atomic64_sub(delta, &hwc->period_left);
+
+ return new_raw_count;
+}
+
static int sparc_perf_event_set_period(struct perf_event *event,
struct hw_perf_event *hwc, int idx)
{
@@ -598,81 +617,166 @@ static int sparc_perf_event_set_period(struct perf_event *event,
return ret;
}
-static int sparc_pmu_enable(struct perf_event *event)
+/* If performance event entries have been added, move existing
+ * events around (if necessary) and then assign new entries to
+ * counters.
+ */
+static u64 maybe_change_configuration(struct cpu_hw_events *cpuc, u64 pcr)
{
- struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
- struct hw_perf_event *hwc = &event->hw;
- int idx = hwc->idx;
+ int i;
- if (test_and_set_bit(idx, cpuc->used_mask))
- return -EAGAIN;
+ if (!cpuc->n_added)
+ goto out;
- sparc_pmu_disable_event(cpuc, hwc, idx);
+ /* Read in the counters which are moving. */
+ for (i = 0; i < cpuc->n_events; i++) {
+ struct perf_event *cp = cpuc->event[i];
- cpuc->events[idx] = event;
- set_bit(idx, cpuc->active_mask);
+ if (cpuc->current_idx[i] != PIC_NO_INDEX &&
+ cpuc->current_idx[i] != cp->hw.idx) {
+ sparc_perf_event_update(cp, &cp->hw,
+ cpuc->current_idx[i]);
+ cpuc->current_idx[i] = PIC_NO_INDEX;
+ }
+ }
- sparc_perf_event_set_period(event, hwc, idx);
- sparc_pmu_enable_event(cpuc, hwc, idx);
- perf_event_update_userpage(event);
- return 0;
+ /* Assign to counters all unassigned events. */
+ for (i = 0; i < cpuc->n_events; i++) {
+ struct perf_event *cp = cpuc->event[i];
+ struct hw_perf_event *hwc = &cp->hw;
+ int idx = hwc->idx;
+ u64 enc;
+
+ if (cpuc->current_idx[i] != PIC_NO_INDEX)
+ continue;
+
+ sparc_perf_event_set_period(cp, hwc, idx);
+ cpuc->current_idx[i] = idx;
+
+ enc = perf_event_get_enc(cpuc->events[i]);
+ pcr |= event_encoding(enc, idx);
+ }
+out:
+ return pcr;
}
-static u64 sparc_perf_event_update(struct perf_event *event,
- struct hw_perf_event *hwc, int idx)
+void hw_perf_enable(void)
{
- int shift = 64 - 32;
- u64 prev_raw_count, new_raw_count;
- s64 delta;
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ u64 pcr;
-again:
- prev_raw_count = atomic64_read(&hwc->prev_count);
- new_raw_count = read_pmc(idx);
+ if (cpuc->enabled)
+ return;
- if (atomic64_cmpxchg(&hwc->prev_count, prev_raw_count,
- new_raw_count) != prev_raw_count)
- goto again;
+ cpuc->enabled = 1;
+ barrier();
- delta = (new_raw_count << shift) - (prev_raw_count << shift);
- delta >>= shift;
+ pcr = cpuc->pcr;
+ if (!cpuc->n_events) {
+ pcr = 0;
+ } else {
+ pcr = maybe_change_configuration(cpuc, pcr);
- atomic64_add(delta, &event->count);
- atomic64_sub(delta, &hwc->period_left);
+ /* We require that all of the events have the same
+ * configuration, so just fetch the settings from the
+ * first entry.
+ */
+ cpuc->pcr = pcr | cpuc->event[0]->hw.config_base;
+ }
- return new_raw_count;
+ pcr_ops->write(cpuc->pcr);
+}
+
+void hw_perf_disable(void)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ u64 val;
+
+ if (!cpuc->enabled)
+ return;
+
+ cpuc->enabled = 0;
+ cpuc->n_added = 0;
+
+ val = cpuc->pcr;
+ val &= ~(PCR_UTRACE | PCR_STRACE |
+ sparc_pmu->hv_bit | sparc_pmu->irq_bit);
+ cpuc->pcr = val;
+
+ pcr_ops->write(cpuc->pcr);
}
static void sparc_pmu_disable(struct perf_event *event)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
struct hw_perf_event *hwc = &event->hw;
- int idx = hwc->idx;
+ unsigned long flags;
+ int i;
- clear_bit(idx, cpuc->active_mask);
- sparc_pmu_disable_event(cpuc, hwc, idx);
+ local_irq_save(flags);
+ perf_disable();
+
+ for (i = 0; i < cpuc->n_events; i++) {
+ if (event == cpuc->event[i]) {
+ int idx = cpuc->current_idx[i];
+
+ /* Shift remaining entries down into
+ * the existing slot.
+ */
+ while (++i < cpuc->n_events) {
+ cpuc->event[i - 1] = cpuc->event[i];
+ cpuc->events[i - 1] = cpuc->events[i];
+ cpuc->current_idx[i - 1] =
+ cpuc->current_idx[i];
+ }
+
+ /* Absorb the final count and turn off the
+ * event.
+ */
+ sparc_pmu_disable_event(cpuc, hwc, idx);
+ barrier();
+ sparc_perf_event_update(event, hwc, idx);
- barrier();
+ perf_event_update_userpage(event);
- sparc_perf_event_update(event, hwc, idx);
- cpuc->events[idx] = NULL;
- clear_bit(idx, cpuc->used_mask);
+ cpuc->n_events--;
+ break;
+ }
+ }
- perf_event_update_userpage(event);
+ perf_enable();
+ local_irq_restore(flags);
+}
+
+static int active_event_index(struct cpu_hw_events *cpuc,
+ struct perf_event *event)
+{
+ int i;
+
+ for (i = 0; i < cpuc->n_events; i++) {
+ if (cpuc->event[i] == event)
+ break;
+ }
+ BUG_ON(i == cpuc->n_events);
+ return cpuc->current_idx[i];
}
static void sparc_pmu_read(struct perf_event *event)
{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ int idx = active_event_index(cpuc, event);
struct hw_perf_event *hwc = &event->hw;
- sparc_perf_event_update(event, hwc, hwc->idx);
+ sparc_perf_event_update(event, hwc, idx);
}
static void sparc_pmu_unthrottle(struct perf_event *event)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ int idx = active_event_index(cpuc, event);
struct hw_perf_event *hwc = &event->hw;
- sparc_pmu_enable_event(cpuc, hwc, hwc->idx);
+ sparc_pmu_enable_event(cpuc, hwc, idx);
}
static atomic_t active_events = ATOMIC_INIT(0);
@@ -750,43 +854,75 @@ static void hw_perf_event_destroy(struct perf_event *event)
/* Make sure all events can be scheduled into the hardware at
* the same time. This is simplified by the fact that we only
* need to support 2 simultaneous HW events.
+ *
+ * As a side effect, the evts[]->hw.idx values will be assigned
+ * on success. These are pending indexes. When the events are
+ * actually programmed into the chip, these values will propagate
+ * to the per-cpu cpuc->current_idx[] slots, see the code in
+ * maybe_change_configuration() for details.
*/
-static int sparc_check_constraints(unsigned long *events, int n_ev)
+static int sparc_check_constraints(struct perf_event **evts,
+ unsigned long *events, int n_ev)
{
- if (n_ev <= perf_max_events) {
- u8 msk1, msk2;
- u16 dummy;
-
- if (n_ev == 1)
- return 0;
- BUG_ON(n_ev != 2);
- perf_event_decode(events[0], &dummy, &msk1);
- perf_event_decode(events[1], &dummy, &msk2);
-
- /* If both events can go on any counter, OK. */
- if (msk1 == (PIC_UPPER | PIC_LOWER) &&
- msk2 == (PIC_UPPER | PIC_LOWER))
- return 0;
-
- /* If one event is limited to a specific counter,
- * and the other can go on both, OK.
- */
- if ((msk1 == PIC_UPPER || msk1 == PIC_LOWER) &&
- msk2 == (PIC_UPPER | PIC_LOWER))
- return 0;
- if ((msk2 == PIC_UPPER || msk2 == PIC_LOWER) &&
- msk1 == (PIC_UPPER | PIC_LOWER))
- return 0;
-
- /* If the events are fixed to different counters, OK. */
- if ((msk1 == PIC_UPPER && msk2 == PIC_LOWER) ||
- (msk1 == PIC_LOWER && msk2 == PIC_UPPER))
- return 0;
-
- /* Otherwise, there is a conflict. */
+ u8 msk0 = 0, msk1 = 0;
+ int idx0 = 0;
+
+ /* This case is possible when we are invoked from
+ * hw_perf_group_sched_in().
+ */
+ if (!n_ev)
+ return 0;
+
+ if (n_ev > perf_max_events)
+ return -1;
+
+ msk0 = perf_event_get_msk(events[0]);
+ if (n_ev == 1) {
+ if (msk0 & PIC_LOWER)
+ idx0 = 1;
+ goto success;
+ }
+ BUG_ON(n_ev != 2);
+ msk1 = perf_event_get_msk(events[1]);
+
+ /* If both events can go on any counter, OK. */
+ if (msk0 == (PIC_UPPER | PIC_LOWER) &&
+ msk1 == (PIC_UPPER | PIC_LOWER))
+ goto success;
+
+ /* If one event is limited to a specific counter,
+ * and the other can go on both, OK.
+ */
+ if ((msk0 == PIC_UPPER || msk0 == PIC_LOWER) &&
+ msk1 == (PIC_UPPER | PIC_LOWER)) {
+ if (msk0 & PIC_LOWER)
+ idx0 = 1;
+ goto success;
}
+ if ((msk1 == PIC_UPPER || msk1 == PIC_LOWER) &&
+ msk0 == (PIC_UPPER | PIC_LOWER)) {
+ if (msk1 & PIC_UPPER)
+ idx0 = 1;
+ goto success;
+ }
+
+ /* If the events are fixed to different counters, OK. */
+ if ((msk0 == PIC_UPPER && msk1 == PIC_LOWER) ||
+ (msk0 == PIC_LOWER && msk1 == PIC_UPPER)) {
+ if (msk0 & PIC_LOWER)
+ idx0 = 1;
+ goto success;
+ }
+
+ /* Otherwise, there is a conflict. */
return -1;
+
+success:
+ evts[0]->hw.idx = idx0;
+ if (n_ev == 2)
+ evts[1]->hw.idx = idx0 ^ 1;
+ return 0;
}
static int check_excludes(struct perf_event **evts, int n_prev, int n_new)
@@ -818,7 +954,8 @@ static int check_excludes(struct perf_event **evts, int n_prev, int n_new)
}
static int collect_events(struct perf_event *group, int max_count,
- struct perf_event *evts[], unsigned long *events)
+ struct perf_event *evts[], unsigned long *events,
+ int *current_idx)
{
struct perf_event *event;
int n = 0;
@@ -827,7 +964,8 @@ static int collect_events(struct perf_event *group, int max_count,
if (n >= max_count)
return -1;
evts[n] = group;
- events[n++] = group->hw.event_base;
+ events[n] = group->hw.event_base;
+ current_idx[n++] = PIC_NO_INDEX;
}
list_for_each_entry(event, &group->sibling_list, group_entry) {
if (!is_software_event(event) &&
@@ -835,20 +973,100 @@ static int collect_events(struct perf_event *group, int max_count,
if (n >= max_count)
return -1;
evts[n] = event;
- events[n++] = event->hw.event_base;
+ events[n] = event->hw.event_base;
+ current_idx[n++] = PIC_NO_INDEX;
}
}
return n;
}
+static void event_sched_in(struct perf_event *event, int cpu)
+{
+ event->state = PERF_EVENT_STATE_ACTIVE;
+ event->oncpu = cpu;
+ event->tstamp_running += event->ctx->time - event->tstamp_stopped;
+ if (is_software_event(event))
+ event->pmu->enable(event);
+}
+
+int hw_perf_group_sched_in(struct perf_event *group_leader,
+ struct perf_cpu_context *cpuctx,
+ struct perf_event_context *ctx, int cpu)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ struct perf_event *sub;
+ int n0, n;
+
+ if (!sparc_pmu)
+ return 0;
+
+ n0 = cpuc->n_events;
+ n = collect_events(group_leader, perf_max_events - n0,
+ &cpuc->event[n0], &cpuc->events[n0],
+ &cpuc->current_idx[n0]);
+ if (n < 0)
+ return -EAGAIN;
+ if (check_excludes(cpuc->event, n0, n))
+ return -EINVAL;
+ if (sparc_check_constraints(cpuc->event, cpuc->events, n + n0))
+ return -EAGAIN;
+ cpuc->n_events = n0 + n;
+ cpuc->n_added += n;
+
+ cpuctx->active_oncpu += n;
+ n = 1;
+ event_sched_in(group_leader, cpu);
+ list_for_each_entry(sub, &group_leader->sibling_list, group_entry) {
+ if (sub->state != PERF_EVENT_STATE_OFF) {
+ event_sched_in(sub, cpu);
+ n++;
+ }
+ }
+ ctx->nr_active += n;
+
+ return 1;
+}
+
+static int sparc_pmu_enable(struct perf_event *event)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ int n0, ret = -EAGAIN;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ perf_disable();
+
+ n0 = cpuc->n_events;
+ if (n0 >= perf_max_events)
+ goto out;
+
+ cpuc->event[n0] = event;
+ cpuc->events[n0] = event->hw.event_base;
+ cpuc->current_idx[n0] = PIC_NO_INDEX;
+
+ if (check_excludes(cpuc->event, n0, 1))
+ goto out;
+ if (sparc_check_constraints(cpuc->event, cpuc->events, n0 + 1))
+ goto out;
+
+ cpuc->n_events++;
+ cpuc->n_added++;
+
+ ret = 0;
+out:
+ perf_enable();
+ local_irq_restore(flags);
+ return ret;
+}
+
static int __hw_perf_event_init(struct perf_event *event)
{
struct perf_event_attr *attr = &event->attr;
struct perf_event *evts[MAX_HWEVENTS];
struct hw_perf_event *hwc = &event->hw;
unsigned long events[MAX_HWEVENTS];
+ int current_idx_dmy[MAX_HWEVENTS];
const struct perf_event_map *pmap;
- u64 enc;
int n;
if (atomic_read(&nmi_active) < 0)
@@ -865,10 +1083,7 @@ static int __hw_perf_event_init(struct perf_event *event)
} else
return -EOPNOTSUPP;
- /* We save the enable bits in the config_base. So to
- * turn off sampling just write 'config', and to enable
- * things write 'config | config_base'.
- */
+ /* We save the enable bits in the config_base. */
hwc->config_base = sparc_pmu->irq_bit;
if (!attr->exclude_user)
hwc->config_base |= PCR_UTRACE;
@@ -879,13 +1094,11 @@ static int __hw_perf_event_init(struct perf_event *event)
hwc->event_base = perf_event_encode(pmap);
- enc = pmap->encoding;
-
n = 0;
if (event->group_leader != event) {
n = collect_events(event->group_leader,
perf_max_events - 1,
- evts, events);
+ evts, events, current_idx_dmy);
if (n < 0)
return -EINVAL;
}
@@ -895,9 +1108,11 @@ static int __hw_perf_event_init(struct perf_event *event)
if (check_excludes(evts, n, 1))
return -EINVAL;
- if (sparc_check_constraints(events, n + 1))
+ if (sparc_check_constraints(evts, events, n + 1))
return -EINVAL;
+ hwc->idx = PIC_NO_INDEX;
+
/* Try to do all error checking before this point, as unwinding
* state after grabbing the PMC is difficult.
*/
@@ -910,15 +1125,6 @@ static int __hw_perf_event_init(struct perf_event *event)
atomic64_set(&hwc->period_left, hwc->sample_period);
}
- if (pmap->pic_mask & PIC_UPPER) {
- hwc->idx = PIC_UPPER_INDEX;
- enc <<= sparc_pmu->upper_shift;
- } else {
- hwc->idx = PIC_LOWER_INDEX;
- enc <<= sparc_pmu->lower_shift;
- }
-
- hwc->config |= enc;
return 0;
}
@@ -968,7 +1174,7 @@ static int __kprobes perf_event_nmi_handler(struct notifier_block *self,
struct perf_sample_data data;
struct cpu_hw_events *cpuc;
struct pt_regs *regs;
- int idx;
+ int i;
if (!atomic_read(&active_events))
return NOTIFY_DONE;
@@ -986,13 +1192,23 @@ static int __kprobes perf_event_nmi_handler(struct notifier_block *self,
data.addr = 0;
cpuc = &__get_cpu_var(cpu_hw_events);
- for (idx = 0; idx < MAX_HWEVENTS; idx++) {
- struct perf_event *event = cpuc->events[idx];
+
+ /* If the PMU has the TOE IRQ enable bits, we need to do a
+ * dummy write to the %pcr to clear the overflow bits and thus
+ * the interrupt.
+ *
+ * Do this before we peek at the counters to determine
+ * overflow so we don't lose any events.
+ */
+ if (sparc_pmu->irq_bit)
+ pcr_ops->write(cpuc->pcr);
+
+ for (i = 0; i < cpuc->n_events; i++) {
+ struct perf_event *event = cpuc->event[i];
+ int idx = cpuc->current_idx[i];
struct hw_perf_event *hwc;
u64 val;
- if (!test_bit(idx, cpuc->active_mask))
- continue;
hwc = &event->hw;
val = sparc_perf_event_update(event, hwc, idx);
if (val & (1ULL << 31))
@@ -1044,10 +1260,122 @@ void __init init_hw_perf_events(void)
pr_cont("Supported PMU type is '%s'\n", sparc_pmu_type);
- /* All sparc64 PMUs currently have 2 events. But this simple
- * driver only supports one active event at a time.
- */
- perf_max_events = 1;
+ /* All sparc64 PMUs currently have 2 events. */
+ perf_max_events = 2;
register_die_notifier(&perf_event_nmi_notifier);
}
+
+static inline void callchain_store(struct perf_callchain_entry *entry, u64 ip)
+{
+ if (entry->nr < PERF_MAX_STACK_DEPTH)
+ entry->ip[entry->nr++] = ip;
+}
+
+static void perf_callchain_kernel(struct pt_regs *regs,
+ struct perf_callchain_entry *entry)
+{
+ unsigned long ksp, fp;
+
+ callchain_store(entry, PERF_CONTEXT_KERNEL);
+ callchain_store(entry, regs->tpc);
+
+ ksp = regs->u_regs[UREG_I6];
+ fp = ksp + STACK_BIAS;
+ do {
+ struct sparc_stackf *sf;
+ struct pt_regs *regs;
+ unsigned long pc;
+
+ if (!kstack_valid(current_thread_info(), fp))
+ break;
+
+ sf = (struct sparc_stackf *) fp;
+ regs = (struct pt_regs *) (sf + 1);
+
+ if (kstack_is_trap_frame(current_thread_info(), regs)) {
+ if (user_mode(regs))
+ break;
+ pc = regs->tpc;
+ fp = regs->u_regs[UREG_I6] + STACK_BIAS;
+ } else {
+ pc = sf->callers_pc;
+ fp = (unsigned long)sf->fp + STACK_BIAS;
+ }
+ callchain_store(entry, pc);
+ } while (entry->nr < PERF_MAX_STACK_DEPTH);
+}
+
+static void perf_callchain_user_64(struct pt_regs *regs,
+ struct perf_callchain_entry *entry)
+{
+ unsigned long ufp;
+
+ callchain_store(entry, PERF_CONTEXT_USER);
+ callchain_store(entry, regs->tpc);
+
+ ufp = regs->u_regs[UREG_I6] + STACK_BIAS;
+ do {
+ struct sparc_stackf *usf, sf;
+ unsigned long pc;
+
+ usf = (struct sparc_stackf *) ufp;
+ if (__copy_from_user_inatomic(&sf, usf, sizeof(sf)))
+ break;
+
+ pc = sf.callers_pc;
+ ufp = (unsigned long)sf.fp + STACK_BIAS;
+ callchain_store(entry, pc);
+ } while (entry->nr < PERF_MAX_STACK_DEPTH);
+}
+
+static void perf_callchain_user_32(struct pt_regs *regs,
+ struct perf_callchain_entry *entry)
+{
+ unsigned long ufp;
+
+ callchain_store(entry, PERF_CONTEXT_USER);
+ callchain_store(entry, regs->tpc);
+
+ ufp = regs->u_regs[UREG_I6];
+ do {
+ struct sparc_stackf32 *usf, sf;
+ unsigned long pc;
+
+ usf = (struct sparc_stackf32 *) ufp;
+ if (__copy_from_user_inatomic(&sf, usf, sizeof(sf)))
+ break;
+
+ pc = sf.callers_pc;
+ ufp = (unsigned long)sf.fp;
+ callchain_store(entry, pc);
+ } while (entry->nr < PERF_MAX_STACK_DEPTH);
+}
+
+/* Like powerpc we can't get PMU interrupts within the PMU handler,
+ * so no need for seperate NMI and IRQ chains as on x86.
+ */
+static DEFINE_PER_CPU(struct perf_callchain_entry, callchain);
+
+struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
+{
+ struct perf_callchain_entry *entry = &__get_cpu_var(callchain);
+
+ entry->nr = 0;
+ if (!user_mode(regs)) {
+ stack_trace_flush();
+ perf_callchain_kernel(regs, entry);
+ if (current->mm)
+ regs = task_pt_regs(current);
+ else
+ regs = NULL;
+ }
+ if (regs) {
+ flushw_user();
+ if (test_thread_flag(TIF_32BIT))
+ perf_callchain_user_32(regs, entry);
+ else
+ perf_callchain_user_64(regs, entry);
+ }
+ return entry;
+}
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c
index 18d67854a1b..c3f1cce0e95 100644
--- a/arch/sparc/kernel/process_64.c
+++ b/arch/sparc/kernel/process_64.c
@@ -365,14 +365,6 @@ void flush_thread(void)
struct thread_info *t = current_thread_info();
struct mm_struct *mm;
- if (test_ti_thread_flag(t, TIF_ABI_PENDING)) {
- clear_ti_thread_flag(t, TIF_ABI_PENDING);
- if (test_ti_thread_flag(t, TIF_32BIT))
- clear_ti_thread_flag(t, TIF_32BIT);
- else
- set_ti_thread_flag(t, TIF_32BIT);
- }
-
mm = t->task->mm;
if (mm)
tsb_context_switch(mm);
diff --git a/arch/sparc/kernel/ptrace_64.c b/arch/sparc/kernel/ptrace_64.c
index 4ae91dc2feb..2f6524d1a81 100644
--- a/arch/sparc/kernel/ptrace_64.c
+++ b/arch/sparc/kernel/ptrace_64.c
@@ -23,6 +23,7 @@
#include <linux/signal.h>
#include <linux/regset.h>
#include <linux/tracehook.h>
+#include <trace/syscall.h>
#include <linux/compat.h>
#include <linux/elf.h>
@@ -37,6 +38,9 @@
#include <asm/cpudata.h>
#include <asm/cacheflush.h>
+#define CREATE_TRACE_POINTS
+#include <trace/events/syscalls.h>
+
#include "entry.h"
/* #define ALLOW_INIT_TRACING */
@@ -1059,6 +1063,9 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs)
if (test_thread_flag(TIF_SYSCALL_TRACE))
ret = tracehook_report_syscall_entry(regs);
+ if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
+ trace_sys_enter(regs, regs->u_regs[UREG_G1]);
+
if (unlikely(current->audit_context) && !ret)
audit_syscall_entry((test_thread_flag(TIF_32BIT) ?
AUDIT_ARCH_SPARC :
@@ -1084,6 +1091,9 @@ asmlinkage void syscall_trace_leave(struct pt_regs *regs)
audit_syscall_exit(result, regs->u_regs[UREG_I0]);
}
+ if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
+ trace_sys_exit(regs, regs->u_regs[UREG_G1]);
+
if (test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall_exit(regs, 0);
}
diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c
index 21180339cb0..a2a79e76344 100644
--- a/arch/sparc/kernel/setup_64.c
+++ b/arch/sparc/kernel/setup_64.c
@@ -46,6 +46,7 @@
#include <asm/setup.h>
#include <asm/mmu.h>
#include <asm/ns87303.h>
+#include <asm/btext.h>
#ifdef CONFIG_IP_PNP
#include <net/ipconfig.h>
@@ -286,7 +287,10 @@ void __init setup_arch(char **cmdline_p)
parse_early_param();
boot_flags_init(*cmdline_p);
- register_console(&prom_early_console);
+#ifdef CONFIG_EARLYFB
+ if (btext_find_display())
+#endif
+ register_console(&prom_early_console);
if (tlb_type == hypervisor)
printk("ARCH: SUN4V\n");
diff --git a/arch/sparc/kernel/smp_32.c b/arch/sparc/kernel/smp_32.c
index 132d81fb261..91c10fb7085 100644
--- a/arch/sparc/kernel/smp_32.c
+++ b/arch/sparc/kernel/smp_32.c
@@ -32,6 +32,7 @@
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
#include <asm/cpudata.h>
+#include <asm/leon.h>
#include "irq.h"
@@ -96,6 +97,9 @@ void __init smp_cpus_done(unsigned int max_cpus)
case sun4d:
smp4d_smp_done();
break;
+ case sparc_leon:
+ leon_smp_done();
+ break;
case sun4e:
printk("SUN4E\n");
BUG();
@@ -306,6 +310,9 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
case sun4d:
smp4d_boot_cpus();
break;
+ case sparc_leon:
+ leon_boot_cpus();
+ break;
case sun4e:
printk("SUN4E\n");
BUG();
@@ -376,6 +383,9 @@ int __cpuinit __cpu_up(unsigned int cpu)
case sun4d:
ret = smp4d_boot_one_cpu(cpu);
break;
+ case sparc_leon:
+ ret = leon_boot_one_cpu(cpu);
+ break;
case sun4e:
printk("SUN4E\n");
BUG();
diff --git a/arch/sparc/kernel/sparc_ksyms_64.c b/arch/sparc/kernel/sparc_ksyms_64.c
index 0f26066a08d..372ad59c4cb 100644
--- a/arch/sparc/kernel/sparc_ksyms_64.c
+++ b/arch/sparc/kernel/sparc_ksyms_64.c
@@ -38,17 +38,5 @@ EXPORT_SYMBOL(sun4v_niagara_setperf);
EXPORT_SYMBOL(sun4v_niagara2_getperf);
EXPORT_SYMBOL(sun4v_niagara2_setperf);
-#ifdef CONFIG_PCI
-/* inline functions in asm/pci_64.h */
-EXPORT_SYMBOL(pci_alloc_consistent);
-EXPORT_SYMBOL(pci_free_consistent);
-EXPORT_SYMBOL(pci_map_single);
-EXPORT_SYMBOL(pci_unmap_single);
-EXPORT_SYMBOL(pci_map_sg);
-EXPORT_SYMBOL(pci_unmap_sg);
-EXPORT_SYMBOL(pci_dma_sync_single_for_cpu);
-EXPORT_SYMBOL(pci_dma_sync_sg_for_cpu);
-#endif
-
/* Exporting a symbol from /init/main.c */
EXPORT_SYMBOL(saved_command_line);
diff --git a/arch/sparc/kernel/sys_sparc32.c b/arch/sparc/kernel/sys_sparc32.c
index 04e28b2671c..dc0ac197e7e 100644
--- a/arch/sparc/kernel/sys_sparc32.c
+++ b/arch/sparc/kernel/sys_sparc32.c
@@ -26,11 +26,6 @@
#include <linux/nfs_fs.h>
#include <linux/quota.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>
@@ -569,85 +564,6 @@ asmlinkage long sparc32_open(const char __user *filename,
return do_sys_open(AT_FDCWD, filename, flags, mode);
}
-extern unsigned long do_mremap(unsigned long addr,
- unsigned long old_len, unsigned long new_len,
- unsigned long flags, unsigned long new_addr);
-
-asmlinkage unsigned long sys32_mremap(unsigned long addr,
- unsigned long old_len, unsigned long new_len,
- unsigned long flags, u32 __new_addr)
-{
- unsigned long ret = -EINVAL;
- unsigned long new_addr = __new_addr;
-
- if (unlikely(sparc_mmap_check(addr, old_len)))
- goto out;
- if (unlikely(sparc_mmap_check(new_addr, new_len)))
- goto out;
- down_write(&current->mm->mmap_sem);
- ret = do_mremap(addr, old_len, new_len, flags, new_addr);
- up_write(&current->mm->mmap_sem);
-out:
- return ret;
-}
-
-struct __sysctl_args32 {
- u32 name;
- int nlen;
- u32 oldval;
- u32 oldlenp;
- u32 newval;
- u32 newlen;
- u32 __unused[4];
-};
-
-asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args)
-{
-#ifndef CONFIG_SYSCTL_SYSCALL
- return -ENOSYS;
-#else
- struct __sysctl_args32 tmp;
- int error;
- size_t oldlen, __user *oldlenp = NULL;
- unsigned long addr = (((unsigned long)&args->__unused[0]) + 7UL) & ~7UL;
-
- if (copy_from_user(&tmp, args, sizeof(tmp)))
- return -EFAULT;
-
- if (tmp.oldval && tmp.oldlenp) {
- /* Duh, this is ugly and might not work if sysctl_args
- is in read-only memory, but do_sysctl does indirectly
- a lot of uaccess in both directions and we'd have to
- basically copy the whole sysctl.c here, and
- glibc's __sysctl uses rw memory for the structure
- anyway. */
- if (get_user(oldlen, (u32 __user *)(unsigned long)tmp.oldlenp) ||
- put_user(oldlen, (size_t __user *)addr))
- return -EFAULT;
- oldlenp = (size_t __user *)addr;
- }
-
- lock_kernel();
- error = do_sysctl((int __user *)(unsigned long) tmp.name,
- tmp.nlen,
- (void __user *)(unsigned long) tmp.oldval,
- oldlenp,
- (void __user *)(unsigned long) tmp.newval,
- tmp.newlen);
- unlock_kernel();
- if (oldlenp) {
- if (!error) {
- if (get_user(oldlen, (size_t __user *)addr) ||
- put_user(oldlen, (u32 __user *)(unsigned long) tmp.oldlenp))
- error = -EFAULT;
- }
- if (copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused)))
- error = -EFAULT;
- }
- return error;
-#endif
-}
-
long sys32_lookup_dcookie(unsigned long cookie_high,
unsigned long cookie_low,
char __user *buf, size_t len)
diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c
index 03035c852a4..3a82e65d8db 100644
--- a/arch/sparc/kernel/sys_sparc_32.c
+++ b/arch/sparc/kernel/sys_sparc_32.c
@@ -45,7 +45,8 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
/* We do not accept a shared mapping if it would violate
* cache aliasing constraints.
*/
- if ((flags & MAP_SHARED) && (addr & (SHMLBA - 1)))
+ if ((flags & MAP_SHARED) &&
+ ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
return -EINVAL;
return addr;
}
@@ -79,15 +80,6 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
}
}
-asmlinkage unsigned long sparc_brk(unsigned long brk)
-{
- if(ARCH_SUN4C) {
- if ((brk & 0xe0000000) != (current->mm->brk & 0xe0000000))
- return current->mm->brk;
- }
- return sys_brk(brk);
-}
-
/*
* sys_pipe() is the normal C calling standard for creating
* a pipe. It's not the way unix traditionally does this, though.
@@ -234,31 +226,6 @@ int sparc_mmap_check(unsigned long addr, unsigned long len)
}
/* Linux version of mmap */
-static unsigned long do_mmap2(unsigned long addr, unsigned long len,
- unsigned long prot, unsigned long flags, unsigned long fd,
- unsigned long pgoff)
-{
- struct file * file = NULL;
- unsigned long retval = -EBADF;
-
- if (!(flags & MAP_ANONYMOUS)) {
- file = fget(fd);
- if (!file)
- goto out;
- }
-
- len = PAGE_ALIGN(len);
- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-
- down_write(&current->mm->mmap_sem);
- retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
- up_write(&current->mm->mmap_sem);
-
- if (file)
- fput(file);
-out:
- return retval;
-}
asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags, unsigned long fd,
@@ -266,14 +233,16 @@ asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len,
{
/* Make sure the shift for mmap2 is constant (12), no matter what PAGE_SIZE
we have. */
- return do_mmap2(addr, len, prot, flags, fd, pgoff >> (PAGE_SHIFT - 12));
+ return sys_mmap_pgoff(addr, len, prot, flags, fd,
+ pgoff >> (PAGE_SHIFT - 12));
}
asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags, unsigned long fd,
unsigned long off)
{
- return do_mmap2(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
+ /* no alignment check? */
+ return sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
}
long sparc_remap_file_pages(unsigned long start, unsigned long size,
@@ -287,27 +256,6 @@ long sparc_remap_file_pages(unsigned long start, unsigned long size,
(pgoff >> (PAGE_SHIFT - 12)), flags);
}
-extern unsigned long do_mremap(unsigned long addr,
- unsigned long old_len, unsigned long new_len,
- unsigned long flags, unsigned long new_addr);
-
-asmlinkage unsigned long sparc_mremap(unsigned long addr,
- unsigned long old_len, unsigned long new_len,
- unsigned long flags, unsigned long new_addr)
-{
- unsigned long ret = -EINVAL;
-
- if (unlikely(sparc_mmap_check(addr, old_len)))
- goto out;
- if (unlikely(sparc_mmap_check(new_addr, new_len)))
- goto out;
- down_write(&current->mm->mmap_sem);
- ret = do_mremap(addr, old_len, new_len, flags, new_addr);
- up_write(&current->mm->mmap_sem);
-out:
- return ret;
-}
-
/* we come to here via sys_nis_syscall so it can setup the regs argument */
asmlinkage unsigned long
c_sys_nis_syscall (struct pt_regs *regs)
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c
index e2d102447a4..d77f5431694 100644
--- a/arch/sparc/kernel/sys_sparc_64.c
+++ b/arch/sparc/kernel/sys_sparc_64.c
@@ -317,10 +317,14 @@ bottomup:
unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, unsigned long len, unsigned long pgoff, unsigned long flags)
{
unsigned long align_goal, addr = -ENOMEM;
+ unsigned long (*get_area)(struct file *, unsigned long,
+ unsigned long, unsigned long, unsigned long);
+
+ get_area = current->mm->get_unmapped_area;
if (flags & MAP_FIXED) {
/* Ok, don't mess with it. */
- return get_unmapped_area(NULL, orig_addr, len, pgoff, flags);
+ return get_area(NULL, orig_addr, len, pgoff, flags);
}
flags &= ~MAP_SHARED;
@@ -333,7 +337,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u
align_goal = (64UL * 1024);
do {
- addr = get_unmapped_area(NULL, orig_addr, len + (align_goal - PAGE_SIZE), pgoff, flags);
+ addr = get_area(NULL, orig_addr, len + (align_goal - PAGE_SIZE), pgoff, flags);
if (!(addr & ~PAGE_MASK)) {
addr = (addr + (align_goal - 1UL)) & ~(align_goal - 1UL);
break;
@@ -351,7 +355,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u
* be obtained.
*/
if (addr & ~PAGE_MASK)
- addr = get_unmapped_area(NULL, orig_addr, len, pgoff, flags);
+ addr = get_area(NULL, orig_addr, len, pgoff, flags);
return addr;
}
@@ -361,6 +365,7 @@ EXPORT_SYMBOL(get_fb_unmapped_area);
void arch_pick_mmap_layout(struct mm_struct *mm)
{
unsigned long random_factor = 0UL;
+ unsigned long gap;
if (current->flags & PF_RANDOMIZE) {
random_factor = get_random_int();
@@ -375,9 +380,10 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
* Fall back to the standard layout if the personality
* bit is set, or if the expected stack growth is unlimited:
*/
+ gap = rlimit(RLIMIT_STACK);
if (!test_thread_flag(TIF_32BIT) ||
(current->personality & ADDR_COMPAT_LAYOUT) ||
- current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
+ gap == RLIM_INFINITY ||
sysctl_legacy_va_layout) {
mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
mm->get_unmapped_area = arch_get_unmapped_area;
@@ -385,9 +391,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
} else {
/* We know it's 32-bit */
unsigned long task_size = STACK_TOP32;
- unsigned long gap;
- gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
if (gap < 128 * 1024 * 1024)
gap = 128 * 1024 * 1024;
if (gap > (task_size / 6 * 5))
@@ -399,18 +403,6 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
}
}
-SYSCALL_DEFINE1(sparc_brk, unsigned long, brk)
-{
- /* People could try to be nasty and use ta 0x6d in 32bit programs */
- if (test_thread_flag(TIF_32BIT) && brk >= STACK_TOP32)
- return current->mm->brk;
-
- if (unlikely(straddles_64bit_va_hole(current->mm->brk, brk)))
- return current->mm->brk;
-
- return sys_brk(brk);
-}
-
/*
* sys_pipe() is the normal C calling standard for creating
* a pipe. It's not the way unix traditionally does this, though.
@@ -568,23 +560,13 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
unsigned long, prot, unsigned long, flags, unsigned long, fd,
unsigned long, off)
{
- struct file * file = NULL;
- unsigned long retval = -EBADF;
-
- if (!(flags & MAP_ANONYMOUS)) {
- file = fget(fd);
- if (!file)
- goto out;
- }
- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- len = PAGE_ALIGN(len);
+ unsigned long retval = -EINVAL;
- down_write(&current->mm->mmap_sem);
- retval = do_mmap(file, addr, len, prot, flags, off);
- up_write(&current->mm->mmap_sem);
-
- if (file)
- fput(file);
+ if ((off + PAGE_ALIGN(len)) < off)
+ goto out;
+ if (off & ~PAGE_MASK)
+ goto out;
+ retval = sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
out:
return retval;
}
@@ -614,12 +596,6 @@ SYSCALL_DEFINE5(64_mremap, unsigned long, addr, unsigned long, old_len,
if (test_thread_flag(TIF_32BIT))
goto out;
- if (unlikely(new_len >= VA_EXCLUDE_START))
- goto out;
- if (unlikely(sparc_mmap_check(addr, old_len)))
- goto out;
- if (unlikely(sparc_mmap_check(new_addr, new_len)))
- goto out;
down_write(&current->mm->mmap_sem);
ret = do_mremap(addr, old_len, new_len, flags, new_addr);
diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S
index d150c2aa98d..dc4a458f74d 100644
--- a/arch/sparc/kernel/syscalls.S
+++ b/arch/sparc/kernel/syscalls.S
@@ -62,7 +62,7 @@ sys32_rt_sigreturn:
#endif
.align 32
1: ldx [%g6 + TI_FLAGS], %l5
- andcc %l5, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0
+ andcc %l5, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0
be,pt %icc, rtrap
nop
call syscall_trace_leave
@@ -187,7 +187,7 @@ linux_syscall_trace:
.globl linux_sparc_syscall32
linux_sparc_syscall32:
/* Direct access to user regs, much faster. */
- cmp %g1, NR_SYSCALLS ! IEU1 Group
+ cmp %g1, NR_syscalls ! IEU1 Group
bgeu,pn %xcc, linux_sparc_ni_syscall ! CTI
srl %i0, 0, %o0 ! IEU0
sll %g1, 2, %l4 ! IEU0 Group
@@ -198,7 +198,7 @@ linux_sparc_syscall32:
srl %i5, 0, %o5 ! IEU1
srl %i2, 0, %o2 ! IEU0 Group
- andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0
+ andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0
bne,pn %icc, linux_syscall_trace32 ! CTI
mov %i0, %l5 ! IEU1
call %l7 ! CTI Group brk forced
@@ -210,7 +210,7 @@ linux_sparc_syscall32:
.globl linux_sparc_syscall
linux_sparc_syscall:
/* Direct access to user regs, much faster. */
- cmp %g1, NR_SYSCALLS ! IEU1 Group
+ cmp %g1, NR_syscalls ! IEU1 Group
bgeu,pn %xcc, linux_sparc_ni_syscall ! CTI
mov %i0, %o0 ! IEU0
sll %g1, 2, %l4 ! IEU0 Group
@@ -221,7 +221,7 @@ linux_sparc_syscall:
mov %i3, %o3 ! IEU1
mov %i4, %o4 ! IEU0 Group
- andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0
+ andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0
bne,pn %icc, linux_syscall_trace ! CTI Group
mov %i0, %l5 ! IEU0
2: call %l7 ! CTI Group brk forced
@@ -245,7 +245,7 @@ ret_sys_call:
cmp %o0, -ERESTART_RESTARTBLOCK
bgeu,pn %xcc, 1f
- andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %l6
+ andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %l6
80:
/* System call success, clear Carry condition code. */
andn %g3, %g2, %g3
@@ -260,7 +260,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|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %l6
+ andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %l6
sub %g0, %o0, %o0
or %g3, %g2, %g3
stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
diff --git a/arch/sparc/kernel/systbls.h b/arch/sparc/kernel/systbls.h
index a63c5d2d984..d2f999ae2b8 100644
--- a/arch/sparc/kernel/systbls.h
+++ b/arch/sparc/kernel/systbls.h
@@ -9,7 +9,6 @@
struct new_utsname;
extern asmlinkage unsigned long sys_getpagesize(void);
-extern asmlinkage unsigned long sparc_brk(unsigned long brk);
extern asmlinkage long sparc_pipe(struct pt_regs *regs);
extern asmlinkage long sys_ipc(unsigned int call, int first,
unsigned long second,
diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S
index 0f1658d3749..801fc8e5a0e 100644
--- a/arch/sparc/kernel/systbls_32.S
+++ b/arch/sparc/kernel/systbls_32.S
@@ -19,7 +19,7 @@ sys_call_table:
/*0*/ .long sys_restart_syscall, sys_exit, sys_fork, sys_read, sys_write
/*5*/ .long sys_open, sys_close, sys_wait4, sys_creat, sys_link
/*10*/ .long sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys_mknod
-/*15*/ .long sys_chmod, sys_lchown16, sparc_brk, sys_nis_syscall, sys_lseek
+/*15*/ .long sys_chmod, sys_lchown16, sys_brk, sys_nis_syscall, sys_lseek
/*20*/ .long sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16
/*25*/ .long sys_vmsplice, sys_ptrace, sys_alarm, sys_sigaltstack, sys_pause
/*30*/ .long sys_utime, sys_lchown, sys_fchown, sys_access, sys_nice
@@ -67,7 +67,7 @@ sys_call_table:
/*235*/ .long sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall
/*240*/ .long sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler
/*245*/ .long sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep
-/*250*/ .long sparc_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
+/*250*/ .long sys_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
/*255*/ .long sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep
/*260*/ .long sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun
/*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy
@@ -82,5 +82,5 @@ sys_call_table:
/*310*/ .long sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate
/*315*/ .long sys_timerfd_settime, sys_timerfd_gettime, sys_signalfd4, sys_eventfd2, sys_epoll_create1
/*320*/ .long sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv
-/*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open
+/*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg
diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S
index 009825f6e73..e575b46bd7a 100644
--- a/arch/sparc/kernel/systbls_64.S
+++ b/arch/sparc/kernel/systbls_64.S
@@ -21,7 +21,7 @@ sys_call_table32:
/*0*/ .word sys_restart_syscall, sys32_exit, sys_fork, sys_read, sys_write
/*5*/ .word sys32_open, sys_close, sys32_wait4, sys32_creat, sys_link
/*10*/ .word sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys32_mknod
-/*15*/ .word sys_chmod, sys_lchown16, sys_sparc_brk, sys32_perfctr, sys32_lseek
+/*15*/ .word sys_chmod, sys_lchown16, sys_brk, sys32_perfctr, sys32_lseek
/*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16
/*25*/ .word sys32_vmsplice, compat_sys_ptrace, sys_alarm, sys32_sigaltstack, sys_pause
/*30*/ .word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice
@@ -68,7 +68,7 @@ sys_call_table32:
.word compat_sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys32_mlockall
/*240*/ .word sys_munlockall, sys32_sched_setparam, sys32_sched_getparam, sys32_sched_setscheduler, sys32_sched_getscheduler
.word sys_sched_yield, sys32_sched_get_priority_max, sys32_sched_get_priority_min, sys32_sched_rr_get_interval, compat_sys_nanosleep
-/*250*/ .word sys32_mremap, sys32_sysctl, sys32_getsid, sys_fdatasync, sys32_nfsservctl
+/*250*/ .word sys_mremap, compat_sys_sysctl, sys32_getsid, sys_fdatasync, sys32_nfsservctl
.word sys32_sync_file_range, compat_sys_clock_settime, compat_sys_clock_gettime, compat_sys_clock_getres, sys32_clock_nanosleep
/*260*/ .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, sys32_timer_settime, compat_sys_timer_gettime, sys_timer_getoverrun
.word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy
@@ -83,7 +83,7 @@ sys_call_table32:
/*310*/ .word compat_sys_utimensat, compat_sys_signalfd, sys_timerfd_create, sys_eventfd, compat_sys_fallocate
.word compat_sys_timerfd_settime, compat_sys_timerfd_gettime, compat_sys_signalfd4, sys_eventfd2, sys_epoll_create1
/*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, compat_sys_preadv
- .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open
+ .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg
#endif /* CONFIG_COMPAT */
@@ -96,7 +96,7 @@ sys_call_table:
/*0*/ .word sys_restart_syscall, sparc_exit, sys_fork, sys_read, sys_write
/*5*/ .word sys_open, sys_close, sys_wait4, sys_creat, sys_link
/*10*/ .word sys_unlink, sys_nis_syscall, sys_chdir, sys_chown, sys_mknod
-/*15*/ .word sys_chmod, sys_lchown, sys_sparc_brk, sys_perfctr, sys_lseek
+/*15*/ .word sys_chmod, sys_lchown, sys_brk, sys_perfctr, sys_lseek
/*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid, sys_getuid
/*25*/ .word sys_vmsplice, sys_ptrace, sys_alarm, sys_sigaltstack, sys_nis_syscall
/*30*/ .word sys_utime, sys_nis_syscall, sys_nis_syscall, sys_access, sys_nice
@@ -158,4 +158,4 @@ sys_call_table:
/*310*/ .word sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate
.word sys_timerfd_settime, sys_timerfd_gettime, sys_signalfd4, sys_eventfd2, sys_epoll_create1
/*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv
- .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open
+ .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg
diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c
index 614ac7b4a9d..0d4c09b15ef 100644
--- a/arch/sparc/kernel/time_32.c
+++ b/arch/sparc/kernel/time_32.c
@@ -35,6 +35,7 @@
#include <linux/platform_device.h>
#include <asm/oplib.h>
+#include <asm/timex.h>
#include <asm/timer.h>
#include <asm/system.h>
#include <asm/irq.h>
@@ -51,7 +52,6 @@ DEFINE_SPINLOCK(rtc_lock);
EXPORT_SYMBOL(rtc_lock);
static int set_rtc_mmss(unsigned long);
-static int sbus_do_settimeofday(struct timespec *tv);
unsigned long profile_pc(struct pt_regs *regs)
{
@@ -76,6 +76,8 @@ EXPORT_SYMBOL(profile_pc);
__volatile__ unsigned int *master_l10_counter;
+u32 (*do_arch_gettimeoffset)(void);
+
/*
* timer_interrupt() needs to keep up the real-time clock,
* as well as call the "do_timer()" routine every clocktick
@@ -196,38 +198,14 @@ static int __init clock_init(void)
{
return of_register_driver(&clock_driver, &of_platform_bus_type);
}
-
/* Must be after subsys_initcall() so that busses are probed. Must
* be before device_initcall() because things like the RTC driver
* need to see the clock registers.
*/
fs_initcall(clock_init);
-static void __init sbus_time_init(void)
-{
-
- BTFIXUPSET_CALL(bus_do_settimeofday, sbus_do_settimeofday, BTFIXUPCALL_NORM);
- btfixup();
-
- sparc_init_timers(timer_interrupt);
-
- /* Now that OBP ticker has been silenced, it is safe to enable IRQ. */
- local_irq_enable();
-}
-
-void __init time_init(void)
-{
-#ifdef CONFIG_PCI
- extern void pci_time_init(void);
- if (pcic_present()) {
- pci_time_init();
- return;
- }
-#endif
- sbus_time_init();
-}
-static inline unsigned long do_gettimeoffset(void)
+u32 sbus_do_gettimeoffset(void)
{
unsigned long val = *master_l10_counter;
unsigned long usec = (val >> 10) & 0x1fffff;
@@ -236,86 +214,39 @@ static inline unsigned long do_gettimeoffset(void)
if (val & 0x80000000)
usec += 1000000 / HZ;
- return usec;
+ return usec * 1000;
}
-/* Ok, my cute asm atomicity trick doesn't work anymore.
- * There are just too many variables that need to be protected
- * now (both members of xtime, et al.)
- */
-void do_gettimeofday(struct timeval *tv)
-{
- unsigned long flags;
- unsigned long seq;
- unsigned long usec, sec;
- unsigned long max_ntp_tick = tick_usec - tickadj;
-
- do {
- seq = read_seqbegin_irqsave(&xtime_lock, flags);
- usec = do_gettimeoffset();
-
- /*
- * If time_adjust is negative then NTP is slowing the clock
- * so make sure not to go into next possible interval.
- * Better to lose some accuracy than have time go backwards..
- */
- if (unlikely(time_adjust < 0))
- usec = min(usec, max_ntp_tick);
-
- sec = xtime.tv_sec;
- usec += (xtime.tv_nsec / 1000);
- } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
-
- while (usec >= 1000000) {
- usec -= 1000000;
- sec++;
- }
- tv->tv_sec = sec;
- tv->tv_usec = usec;
-}
-
-EXPORT_SYMBOL(do_gettimeofday);
-
-int do_settimeofday(struct timespec *tv)
+u32 arch_gettimeoffset(void)
{
- int ret;
-
- write_seqlock_irq(&xtime_lock);
- ret = bus_do_settimeofday(tv);
- write_sequnlock_irq(&xtime_lock);
- clock_was_set();
- return ret;
+ if (unlikely(!do_arch_gettimeoffset))
+ return 0;
+ return do_arch_gettimeoffset();
}
-EXPORT_SYMBOL(do_settimeofday);
-
-static int sbus_do_settimeofday(struct timespec *tv)
+static void __init sbus_time_init(void)
{
- time_t wtm_sec, sec = tv->tv_sec;
- long wtm_nsec, nsec = tv->tv_nsec;
+ do_arch_gettimeoffset = sbus_do_gettimeoffset;
- if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
- return -EINVAL;
-
- /*
- * This is revolting. We need to set "xtime" correctly. However, the
- * value in this location is the value at the most recent update of
- * wall time. Discover what correction gettimeofday() would have
- * made, and then undo it!
- */
- nsec -= 1000 * do_gettimeoffset();
-
- wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
- wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
+ btfixup();
- set_normalized_timespec(&xtime, sec, nsec);
- set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
+ sparc_init_timers(timer_interrupt);
+}
- ntp_clear();
- return 0;
+void __init time_init(void)
+{
+#ifdef CONFIG_PCI
+ extern void pci_time_init(void);
+ if (pcic_present()) {
+ pci_time_init();
+ return;
+ }
+#endif
+ sbus_time_init();
}
+
static int set_rtc_mmss(unsigned long secs)
{
struct rtc_device *rtc = rtc_class_open("rtc0");
diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c
index da1218e8ee8..67e16510288 100644
--- a/arch/sparc/kernel/time_64.c
+++ b/arch/sparc/kernel/time_64.c
@@ -774,26 +774,9 @@ void __devinit setup_sparc64_timer(void)
static struct clocksource clocksource_tick = {
.rating = 100,
.mask = CLOCKSOURCE_MASK(64),
- .shift = 16,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
-static void __init setup_clockevent_multiplier(unsigned long hz)
-{
- unsigned long mult, shift = 32;
-
- while (1) {
- mult = div_sc(hz, NSEC_PER_SEC, shift);
- if (mult && (mult >> 32UL) == 0UL)
- break;
-
- shift--;
- }
-
- sparc64_clockevent.shift = shift;
- sparc64_clockevent.mult = mult;
-}
-
static unsigned long tb_ticks_per_usec __read_mostly;
void __delay(unsigned long loops)
@@ -828,9 +811,7 @@ void __init time_init(void)
clocksource_hz2mult(freq, SPARC64_NSEC_PER_CYC_SHIFT);
clocksource_tick.name = tick_ops->name;
- clocksource_tick.mult =
- clocksource_hz2mult(freq,
- clocksource_tick.shift);
+ clocksource_calc_mult_shift(&clocksource_tick, freq, 4);
clocksource_tick.read = clocksource_tick_read;
printk("clocksource: mult[%x] shift[%d]\n",
@@ -839,15 +820,14 @@ void __init time_init(void)
clocksource_register(&clocksource_tick);
sparc64_clockevent.name = tick_ops->name;
-
- setup_clockevent_multiplier(freq);
+ clockevents_calc_mult_shift(&sparc64_clockevent, freq, 4);
sparc64_clockevent.max_delta_ns =
clockevent_delta2ns(0x7fffffffffffffffUL, &sparc64_clockevent);
sparc64_clockevent.min_delta_ns =
clockevent_delta2ns(0xF, &sparc64_clockevent);
- printk("clockevent: mult[%lx] shift[%d]\n",
+ printk("clockevent: mult[%x] shift[%d]\n",
sparc64_clockevent.mult, sparc64_clockevent.shift);
setup_sparc64_timer();
diff --git a/arch/sparc/kernel/trampoline_32.S b/arch/sparc/kernel/trampoline_32.S
index 5e235c52d66..691f484e03b 100644
--- a/arch/sparc/kernel/trampoline_32.S
+++ b/arch/sparc/kernel/trampoline_32.S
@@ -15,7 +15,7 @@
#include <asm/contregs.h>
#include <asm/thread_info.h>
- .globl sun4m_cpu_startup, __smp4m_processor_id
+ .globl sun4m_cpu_startup, __smp4m_processor_id, __leon_processor_id
.globl sun4d_cpu_startup, __smp4d_processor_id
__CPUINIT
@@ -106,6 +106,12 @@ __smp4d_processor_id:
retl
mov %g1, %o7
+__leon_processor_id:
+ rd %asr17,%g2
+ srl %g2,28,%g2
+ retl
+ mov %g1, %o7
+
/* CPUID in bootbus can be found at PA 0xff0140000 */
#define SUN4D_BOOTBUS_CPUID 0xf0140000
@@ -160,3 +166,64 @@ sun4d_cpu_startup:
nop
b,a smp_do_cpu_idle
+
+#ifdef CONFIG_SPARC_LEON
+
+ __CPUINIT
+ .align 4
+ .global leon_smp_cpu_startup, smp_penguin_ctable
+
+leon_smp_cpu_startup:
+
+ set smp_penguin_ctable,%g1
+ ld [%g1+4],%g1
+ srl %g1,4,%g1
+ set 0x00000100,%g5 /* SRMMU_CTXTBL_PTR */
+ sta %g1, [%g5] ASI_M_MMUREGS
+
+ /* Set up a sane %psr -- PIL<0xf> S<0x1> PS<0x1> CWP<0x0> */
+ set (PSR_PIL | PSR_S | PSR_PS), %g1
+ wr %g1, 0x0, %psr ! traps off though
+ WRITE_PAUSE
+
+ /* Our %wim is one behind CWP */
+ mov 2, %g1
+ wr %g1, 0x0, %wim
+ WRITE_PAUSE
+
+ /* Set tbr - we use just one trap table. */
+ set trapbase, %g1
+ wr %g1, 0x0, %tbr
+ WRITE_PAUSE
+
+ /* Get our CPU id */
+ rd %asr17,%g3
+
+ /* Give ourselves a stack and curptr. */
+ set current_set, %g5
+ srl %g3, 28, %g4
+ sll %g4, 2, %g4
+ ld [%g5 + %g4], %g6
+
+ sethi %hi(THREAD_SIZE - STACKFRAME_SZ), %sp
+ or %sp, %lo(THREAD_SIZE - STACKFRAME_SZ), %sp
+ add %g6, %sp, %sp
+
+ /* Turn on traps (PSR_ET). */
+ rd %psr, %g1
+ wr %g1, PSR_ET, %psr ! traps on
+ WRITE_PAUSE
+
+ /* Init our caches, etc. */
+ set poke_srmmu, %g5
+ ld [%g5], %g5
+ call %g5
+ nop
+
+ /* Start this processor. */
+ call leon_callin
+ nop
+
+ b,a smp_do_cpu_idle
+
+#endif
diff --git a/arch/sparc/kernel/unaligned_32.c b/arch/sparc/kernel/unaligned_32.c
index 6b1e6cde6ff..f8514e291e1 100644
--- a/arch/sparc/kernel/unaligned_32.c
+++ b/arch/sparc/kernel/unaligned_32.c
@@ -17,8 +17,7 @@
#include <asm/uaccess.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
-
-/* #define DEBUG_MNA */
+#include <linux/perf_event.h>
enum direction {
load, /* ld, ldd, ldh, ldsh */
@@ -29,12 +28,6 @@ enum direction {
invalid,
};
-#ifdef DEBUG_MNA
-static char *dirstrings[] = {
- "load", "store", "both", "fpload", "fpstore", "invalid"
-};
-#endif
-
static inline enum direction decode_direction(unsigned int insn)
{
unsigned long tmp = (insn >> 21) & 1;
@@ -255,10 +248,7 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn)
unsigned long addr = compute_effective_address(regs, insn);
int err;
-#ifdef DEBUG_MNA
- printk("KMNA: pc=%08lx [dir=%s addr=%08lx size=%d] retpc[%08lx]\n",
- regs->pc, dirstrings[dir], addr, size, regs->u_regs[UREG_RETPC]);
-#endif
+ perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, addr);
switch (dir) {
case load:
err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f),
@@ -350,6 +340,7 @@ asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn)
}
addr = compute_effective_address(regs, insn);
+ perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, addr);
switch(dir) {
case load:
err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f),
diff --git a/arch/sparc/kernel/unaligned_64.c b/arch/sparc/kernel/unaligned_64.c
index 379209982a0..378ca82b9cc 100644
--- a/arch/sparc/kernel/unaligned_64.c
+++ b/arch/sparc/kernel/unaligned_64.c
@@ -20,10 +20,9 @@
#include <asm/uaccess.h>
#include <linux/smp.h>
#include <linux/bitops.h>
+#include <linux/perf_event.h>
#include <asm/fpumacro.h>
-/* #define DEBUG_MNA */
-
enum direction {
load, /* ld, ldd, ldh, ldsh */
store, /* st, std, sth, stsh */
@@ -33,12 +32,6 @@ enum direction {
invalid,
};
-#ifdef DEBUG_MNA
-static char *dirstrings[] = {
- "load", "store", "both", "fpload", "fpstore", "invalid"
-};
-#endif
-
static inline enum direction decode_direction(unsigned int insn)
{
unsigned long tmp = (insn >> 21) & 1;
@@ -327,12 +320,7 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn)
addr = compute_effective_address(regs, insn,
((insn >> 25) & 0x1f));
-#ifdef DEBUG_MNA
- printk("KMNA: pc=%016lx [dir=%s addr=%016lx size=%d] "
- "retpc[%016lx]\n",
- regs->tpc, dirstrings[dir], addr, size,
- regs->u_regs[UREG_RETPC]);
-#endif
+ perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, addr);
switch (asi) {
case ASI_NL:
case ASI_AIUPL:
@@ -399,6 +387,7 @@ int handle_popc(u32 insn, struct pt_regs *regs)
int ret, i, rd = ((insn >> 25) & 0x1f);
int from_kernel = (regs->tstate & TSTATE_PRIV) != 0;
+ perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0);
if (insn & 0x2000) {
maybe_flush_windows(0, 0, rd, from_kernel);
value = sign_extend_imm13(insn);
@@ -445,6 +434,8 @@ int handle_ldf_stq(u32 insn, struct pt_regs *regs)
int asi = decode_asi(insn, regs);
int flag = (freg < 32) ? FPRS_DL : FPRS_DU;
+ perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0);
+
save_and_clear_fpu();
current_thread_info()->xfsr[0] &= ~0x1c000;
if (freg & 3) {
@@ -566,6 +557,8 @@ void handle_ld_nf(u32 insn, struct pt_regs *regs)
int from_kernel = (regs->tstate & TSTATE_PRIV) != 0;
unsigned long *reg;
+ perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0);
+
maybe_flush_windows(0, 0, rd, from_kernel);
reg = fetch_reg_addr(rd, regs);
if (from_kernel || rd < 16) {
@@ -596,6 +589,7 @@ void handle_lddfmna(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr
if (tstate & TSTATE_PRIV)
die_if_kernel("lddfmna from kernel", regs);
+ perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, sfar);
if (test_thread_flag(TIF_32BIT))
pc = (u32)pc;
if (get_user(insn, (u32 __user *) pc) != -EFAULT) {
@@ -657,6 +651,7 @@ void handle_stdfmna(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr
if (tstate & TSTATE_PRIV)
die_if_kernel("stdfmna from kernel", regs);
+ perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, sfar);
if (test_thread_flag(TIF_32BIT))
pc = (u32)pc;
if (get_user(insn, (u32 __user *) pc) != -EFAULT) {
diff --git a/arch/sparc/kernel/visemul.c b/arch/sparc/kernel/visemul.c
index d231cbd5c52..9dfd2ebcb15 100644
--- a/arch/sparc/kernel/visemul.c
+++ b/arch/sparc/kernel/visemul.c
@@ -5,6 +5,7 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/thread_info.h>
+#include <linux/perf_event.h>
#include <asm/ptrace.h>
#include <asm/pstate.h>
@@ -801,6 +802,8 @@ int vis_emul(struct pt_regs *regs, unsigned int insn)
BUG_ON(regs->tstate & TSTATE_PRIV);
+ perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0);
+
if (test_thread_flag(TIF_32BIT))
pc = (u32)pc;
diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile
index e75faf0e59a..c4b5e03af11 100644
--- a/arch/sparc/lib/Makefile
+++ b/arch/sparc/lib/Makefile
@@ -44,3 +44,4 @@ obj-y += iomap.o
obj-$(CONFIG_SPARC32) += atomic32.o
obj-y += ksyms.o
obj-$(CONFIG_SPARC64) += PeeCeeI.o
+obj-y += usercopy.o
diff --git a/arch/sparc/lib/bzero.S b/arch/sparc/lib/bzero.S
index b6557297440..615f401edf6 100644
--- a/arch/sparc/lib/bzero.S
+++ b/arch/sparc/lib/bzero.S
@@ -6,10 +6,6 @@
.text
- .globl __memset
- .type __memset, #function
-__memset: /* %o0=buf, %o1=pat, %o2=len */
-
.globl memset
.type memset, #function
memset: /* %o0=buf, %o1=pat, %o2=len */
@@ -83,7 +79,6 @@ __bzero_done:
retl
mov %o3, %o0
.size __bzero, .-__bzero
- .size __memset, .-__memset
.size memset, .-memset
#define EX_ST(x,y) \
diff --git a/arch/sparc/lib/checksum_32.S b/arch/sparc/lib/checksum_32.S
index 77f228533d4..3632cb34e91 100644
--- a/arch/sparc/lib/checksum_32.S
+++ b/arch/sparc/lib/checksum_32.S
@@ -560,7 +560,7 @@ __csum_partial_copy_end:
mov %i0, %o1
mov %i1, %o0
5:
- call __memcpy
+ call memcpy
mov %i2, %o2
tst %o0
bne,a 2f
diff --git a/arch/sparc/lib/ksyms.c b/arch/sparc/lib/ksyms.c
index 704b1266838..1b30bb3bfdb 100644
--- a/arch/sparc/lib/ksyms.c
+++ b/arch/sparc/lib/ksyms.c
@@ -30,7 +30,6 @@ EXPORT_SYMBOL(__memscan_generic);
EXPORT_SYMBOL(memcmp);
EXPORT_SYMBOL(memcpy);
EXPORT_SYMBOL(memset);
-EXPORT_SYMBOL(__memset);
EXPORT_SYMBOL(memmove);
EXPORT_SYMBOL(__bzero);
@@ -81,7 +80,6 @@ EXPORT_SYMBOL(__csum_partial_copy_sparc_generic);
/* Special internal versions of library functions. */
EXPORT_SYMBOL(__copy_1page);
-EXPORT_SYMBOL(__memcpy);
EXPORT_SYMBOL(__memmove);
EXPORT_SYMBOL(bzero_1page);
diff --git a/arch/sparc/lib/mcount.S b/arch/sparc/lib/mcount.S
index 7ce9c65f359..24b8b12deed 100644
--- a/arch/sparc/lib/mcount.S
+++ b/arch/sparc/lib/mcount.S
@@ -64,8 +64,9 @@ mcount:
2: sethi %hi(softirq_stack), %g3
or %g3, %lo(softirq_stack), %g3
ldx [%g3 + %g1], %g7
+ sub %g7, STACK_BIAS, %g7
cmp %sp, %g7
- bleu,pt %xcc, 2f
+ bleu,pt %xcc, 3f
sethi %hi(THREAD_SIZE), %g3
add %g7, %g3, %g7
cmp %sp, %g7
@@ -75,7 +76,7 @@ mcount:
* again, we are already trying to output the stack overflow
* message.
*/
- sethi %hi(ovstack), %g7 ! cant move to panic stack fast enough
+3: sethi %hi(ovstack), %g7 ! cant move to panic stack fast enough
or %g7, %lo(ovstack), %g7
add %g7, OVSTACKSIZE, %g3
sub %g3, STACK_BIAS + 192, %g3
diff --git a/arch/sparc/lib/memcpy.S b/arch/sparc/lib/memcpy.S
index ce10bc869af..34fe6575173 100644
--- a/arch/sparc/lib/memcpy.S
+++ b/arch/sparc/lib/memcpy.S
@@ -543,9 +543,6 @@ FUNC(memmove)
b 3f
add %o0, 2, %o0
-#ifdef __KERNEL__
-FUNC(__memcpy)
-#endif
FUNC(memcpy) /* %o0=dst %o1=src %o2=len */
sub %o0, %o1, %o4
diff --git a/arch/sparc/lib/memset.S b/arch/sparc/lib/memset.S
index 1c37ea892de..99c017be871 100644
--- a/arch/sparc/lib/memset.S
+++ b/arch/sparc/lib/memset.S
@@ -60,11 +60,10 @@
.globl __bzero_begin
__bzero_begin:
- .globl __bzero, __memset,
+ .globl __bzero
.globl memset
.globl __memset_start, __memset_end
__memset_start:
-__memset:
memset:
and %o1, 0xff, %g3
sll %g3, 8, %g2
diff --git a/arch/sparc/lib/usercopy.c b/arch/sparc/lib/usercopy.c
new file mode 100644
index 00000000000..14b363fec8a
--- /dev/null
+++ b/arch/sparc/lib/usercopy.c
@@ -0,0 +1,8 @@
+#include <linux/module.h>
+#include <linux/bug.h>
+
+void copy_from_user_overflow(void)
+{
+ WARN(1, "Buffer overflow detected!\n");
+}
+EXPORT_SYMBOL(copy_from_user_overflow);
diff --git a/arch/sparc/math-emu/math_32.c b/arch/sparc/math-emu/math_32.c
index e13f65da17d..a3fccde894e 100644
--- a/arch/sparc/math-emu/math_32.c
+++ b/arch/sparc/math-emu/math_32.c
@@ -67,6 +67,7 @@
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/mm.h>
+#include <linux/perf_event.h>
#include <asm/uaccess.h>
#include "sfp-util_32.h"
@@ -163,6 +164,8 @@ int do_mathemu(struct pt_regs *regs, struct task_struct *fpt)
int retcode = 0; /* assume all succeed */
unsigned long insn;
+ perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0);
+
#ifdef DEBUG_MATHEMU
printk("In do_mathemu()... pc is %08lx\n", regs->pc);
printk("fpqdepth is %ld\n", fpt->thread.fpqdepth);
diff --git a/arch/sparc/math-emu/math_64.c b/arch/sparc/math-emu/math_64.c
index 6863c9bde25..56d2c44747b 100644
--- a/arch/sparc/math-emu/math_64.c
+++ b/arch/sparc/math-emu/math_64.c
@@ -11,6 +11,7 @@
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/errno.h>
+#include <linux/perf_event.h>
#include <asm/fpumacro.h>
#include <asm/ptrace.h>
@@ -183,6 +184,7 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f)
if (tstate & TSTATE_PRIV)
die_if_kernel("unfinished/unimplemented FPop from kernel", regs);
+ perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0);
if (test_thread_flag(TIF_32BIT))
pc = (u32)pc;
if (get_user(insn, (u32 __user *) pc) != -EFAULT) {
diff --git a/arch/sparc/mm/fault_32.c b/arch/sparc/mm/fault_32.c
index b99f81c4906..a3413acb8f1 100644
--- a/arch/sparc/mm/fault_32.c
+++ b/arch/sparc/mm/fault_32.c
@@ -18,6 +18,7 @@
#include <linux/signal.h>
#include <linux/mm.h>
#include <linux/smp.h>
+#include <linux/perf_event.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/kdebug.h>
@@ -203,6 +204,8 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
if (in_atomic() || !mm)
goto no_context;
+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address);
+
down_read(&mm->mmap_sem);
/*
@@ -249,10 +252,15 @@ good_area:
goto do_sigbus;
BUG();
}
- if (fault & VM_FAULT_MAJOR)
+ if (fault & VM_FAULT_MAJOR) {
current->maj_flt++;
- else
+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0,
+ regs, address);
+ } else {
current->min_flt++;
+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0,
+ regs, address);
+ }
up_read(&mm->mmap_sem);
return;
diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c
index 43b0da96a4f..b9d4ff02b8f 100644
--- a/arch/sparc/mm/fault_64.c
+++ b/arch/sparc/mm/fault_64.c
@@ -16,6 +16,7 @@
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/perf_event.h>
#include <linux/interrupt.h>
#include <linux/kprobes.h>
#include <linux/kdebug.h>
@@ -31,13 +32,12 @@
#include <asm/sections.h>
#include <asm/mmu_context.h>
-#ifdef CONFIG_KPROBES
-static inline int notify_page_fault(struct pt_regs *regs)
+static inline __kprobes int notify_page_fault(struct pt_regs *regs)
{
int ret = 0;
/* kprobe_running() needs smp_processor_id() */
- if (!user_mode(regs)) {
+ if (kprobes_built_in() && !user_mode(regs)) {
preempt_disable();
if (kprobe_running() && kprobe_fault_handler(regs, 0))
ret = 1;
@@ -45,12 +45,6 @@ static inline int notify_page_fault(struct pt_regs *regs)
}
return ret;
}
-#else
-static inline int notify_page_fault(struct pt_regs *regs)
-{
- return 0;
-}
-#endif
static void __kprobes unhandled_fault(unsigned long address,
struct task_struct *tsk,
@@ -73,7 +67,7 @@ static void __kprobes unhandled_fault(unsigned long address,
die_if_kernel("Oops", regs);
}
-static void bad_kernel_pc(struct pt_regs *regs, unsigned long vaddr)
+static void __kprobes bad_kernel_pc(struct pt_regs *regs, unsigned long vaddr)
{
printk(KERN_CRIT "OOPS: Bogus kernel PC [%016lx] in fault handler\n",
regs->tpc);
@@ -170,8 +164,9 @@ static unsigned int get_fault_insn(struct pt_regs *regs, unsigned int insn)
return insn;
}
-static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code,
- unsigned int insn, unsigned long address)
+static void __kprobes do_kernel_fault(struct pt_regs *regs, int si_code,
+ int fault_code, unsigned int insn,
+ unsigned long address)
{
unsigned char asi = ASI_P;
@@ -225,7 +220,7 @@ cannot_handle:
unhandled_fault (address, current, regs);
}
-static void noinline bogus_32bit_fault_tpc(struct pt_regs *regs)
+static void noinline __kprobes bogus_32bit_fault_tpc(struct pt_regs *regs)
{
static int times;
@@ -237,8 +232,8 @@ static void noinline bogus_32bit_fault_tpc(struct pt_regs *regs)
show_regs(regs);
}
-static void noinline bogus_32bit_fault_address(struct pt_regs *regs,
- unsigned long addr)
+static void noinline __kprobes bogus_32bit_fault_address(struct pt_regs *regs,
+ unsigned long addr)
{
static int times;
@@ -302,6 +297,8 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
if (in_atomic() || !mm)
goto intr_or_no_mm;
+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address);
+
if (!down_read_trylock(&mm->mmap_sem)) {
if ((regs->tstate & TSTATE_PRIV) &&
!search_exception_tables(regs->tpc)) {
@@ -406,11 +403,15 @@ good_area:
goto do_sigbus;
BUG();
}
- if (fault & VM_FAULT_MAJOR)
+ if (fault & VM_FAULT_MAJOR) {
current->maj_flt++;
- else
+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0,
+ regs, address);
+ } else {
current->min_flt++;
-
+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0,
+ regs, address);
+ }
up_read(&mm->mmap_sem);
mm_rss = get_mm_rss(mm);
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index 509b1ffeba6..367321a030d 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -1990,7 +1990,7 @@ void __init poke_leonsparc(void)
void __init init_leon(void)
{
- srmmu_name = "Leon";
+ srmmu_name = "LEON";
BTFIXUPSET_CALL(flush_cache_all, leon_flush_cache_all,
BTFIXUPCALL_NORM);
@@ -2037,8 +2037,6 @@ static void __init get_srmmu_type(void)
/* First, check for sparc-leon. */
if (sparc_cpu_model == sparc_leon) {
- psr_typ = 0xf; /* hardcoded ids for older models/simulators */
- psr_vers = 2;
init_leon();
return;
}
@@ -2301,7 +2299,8 @@ void __init ld_mmu_srmmu(void)
BTFIXUPSET_CALL(flush_cache_mm, smp_flush_cache_mm, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(flush_cache_range, smp_flush_cache_range, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(flush_cache_page, smp_flush_cache_page, BTFIXUPCALL_NORM);
- if (sparc_cpu_model != sun4d) {
+ if (sparc_cpu_model != sun4d &&
+ sparc_cpu_model != sparc_leon) {
BTFIXUPSET_CALL(flush_tlb_all, smp_flush_tlb_all, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(flush_tlb_mm, smp_flush_tlb_mm, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(flush_tlb_range, smp_flush_tlb_range, BTFIXUPCALL_NORM);
@@ -2330,6 +2329,8 @@ void __init ld_mmu_srmmu(void)
#ifdef CONFIG_SMP
if (sparc_cpu_model == sun4d)
sun4d_init_smp();
+ else if (sparc_cpu_model == sparc_leon)
+ leon_init_smp();
else
sun4m_init_smp();
#endif
diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c
index 2ffacd67c42..a89baf0d875 100644
--- a/arch/sparc/mm/sun4c.c
+++ b/arch/sparc/mm/sun4c.c
@@ -17,6 +17,7 @@
#include <linux/fs.h>
#include <linux/seq_file.h>
#include <linux/scatterlist.h>
+#include <linux/bitmap.h>
#include <asm/sections.h>
#include <asm/page.h>
@@ -1021,20 +1022,12 @@ static char *sun4c_lockarea(char *vaddr, unsigned long size)
npages = (((unsigned long)vaddr & ~PAGE_MASK) +
size + (PAGE_SIZE-1)) >> PAGE_SHIFT;
- scan = 0;
local_irq_save(flags);
- for (;;) {
- scan = find_next_zero_bit(sun4c_iobuffer_map,
- iobuffer_map_size, scan);
- if ((base = scan) + npages > iobuffer_map_size) goto abend;
- for (;;) {
- if (scan >= base + npages) goto found;
- if (test_bit(scan, sun4c_iobuffer_map)) break;
- scan++;
- }
- }
+ base = bitmap_find_next_zero_area(sun4c_iobuffer_map, iobuffer_map_size,
+ 0, npages, 0);
+ if (base >= iobuffer_map_size)
+ goto abend;
-found:
high = ((base + npages) << PAGE_SHIFT) + sun4c_iobuffer_start;
high = SUN4C_REAL_PGDIR_ALIGN(high);
while (high > sun4c_iobuffer_high) {